glamorous-church-16794
12/24/2025, 1:26 AMtall-airline-16756
12/24/2025, 1:26 AMtall-airline-16756
12/24/2025, 1:26 AMAgentSession and an rtc_session handler).
2. Use the LiveKit CLI to register and deploy the agent from your project:
◦ lk agent create — registers the agent, builds a container (it will generate a Dockerfile if needed), and deploys to LiveKit Cloud.
1. Monitor and manage the deployment with:
◦ lk agent status
◦ lk agent logs
◦ LiveKit Cloud dashboard for metrics and errors
If you’d like, tell me:
• whether you already have an AgentSession entrypoint (paste the minimal snippet), or
• the repo layout (files like Dockerfile, requirements.txt),
and I’ll give exact CLI commands or a Dockerfile and minimal example tailored to your project.
Sources: Deploying to production | LiveKit Docs | An open source stack for real-time multimodal AI | Voice AI quickstart | LiveKit docsglamorous-church-16794
12/24/2025, 4:53 PMtall-airline-16756
12/24/2025, 4:53 PM--secrets-file flag. The file should be KEY=VALUE lines (e.g., .env).
• Create/deploy agent with file:
lk agent create --secrets-file .env
• Update secrets for an existing agent:
lk agent update-secrets --secrets-file .env
Note: LIVEKIT_API_KEY, LIVEKIT_API_SECRET, and LIVEKIT_URL are provided by LiveKit Cloud and are excluded from secret uploads. For local testing, you can load the same file with `python-dotenv`:
from dotenv import load_dotenv
load_dotenv() Sources: Server-side | livekit/livekit_composite | DeepWiki | Agents (Python) | livekit/livekit_composite | DeepWiki | Simple Call Answering Agent | LiveKit docs | Company directory phone assistant | LiveKit docsglamorous-church-16794
12/24/2025, 4:54 PMlk agent create --secrets-file .envtall-airline-16756
12/24/2025, 4:55 PMlk agent create --secrets-file .env. Below are the typical prerequisites and commands in order.
1. Install LiveKit CLI (if not installed)
• Follow platform installer or package manager for lk (one-time).
1. Authenticate with LiveKit Cloud
lk cloud auth
1. (Optional) Select or set your cloud project / context
lk cloud project list
# if needed
lk cloud project set <PROJECT_ID>
1. Initialize or prepare your agent project (if not already)
# create a starter project (example)
uv init livekit-voice-agent --bare
cd livekit-voice-agent
1. Install dependencies for your Python agent
# example using pip/poetry/uv
pip install "livekit-agents[silero,turn-detector]~=1.3" "livekit-plugins-noise-cancellation~=0.2" python-dotenv
1. Create and verify your .env file (KEY=VALUE lines)
• Include any provider keys your agent needs. Note: LIVEKIT_API_KEY, LIVEKIT_API_SECRET, and LIVEKIT_URL are provided by LiveKit Cloud and are excluded when uploading secrets.
After these steps you can run:
lk agent create --secrets-file .env
If you want, paste your project layout or .env contents (redact secrets) and I’ll confirm any missing keys or exact install commands for your setup.
Sources: Voice AI quickstart | LiveKit docs | Deploying to production | LiveKit Docsglamorous-church-16794
12/24/2025, 5:05 PMtall-airline-16756
12/24/2025, 5:05 PM.env (redact values) for required keys?
• Generate a sample Dockerfile or lk workflow for your project?
• Provide exact install commands for your package manager (pip/poetry)?
• Or walk through the lk agent create output and how to verify the deployment?
Pick one and I’ll take it from there.glamorous-church-16794
12/24/2025, 5:06 PMtall-airline-16756
12/24/2025, 5:06 PMlk agent logs <AGENT_NAME_OR_ID> --follow
Would you like me to check a specific agent’s logs now? If so, share the agent name or paste a redacted error snippet and I’ll help interpret it.
Sources: https://blog.livekit.io/streamline-troubleshooting-with-agent-observability/#/portal| | Deploying to production | LiveKit Docsglamorous-church-16794
12/24/2025, 8:30 PMtall-airline-16756
12/24/2025, 8:31 PM.github/workflows/deploy-agent.yml.
Prerequisites
• Run lk agent create locally once to generate livekit.toml (commit it).
• Add repo secrets: LIVEKIT_API_KEY, LIVEKIT_API_SECRET, LIVEKIT_URL, plus any other provider keys (e.g., OPENAI_API_KEY).
• Ensure your repo has your agent code and dependencies (pyproject/requirements, optional Dockerfile).
Example workflow (.github/workflows/deploy-agent.yml)
name: Deploy LiveKit Agent
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install poetry || true
# adjust for your project manager:
poetry install || pip install -r requirements.txt
- name: Install LiveKit CLI
run: |
curl -sSL <https://get.livekit.io> | bash
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Authenticate LiveKit CLI
env:
LIVEKIT_API_KEY: ${{ secrets.LIVEKIT_API_KEY }}
LIVEKIT_API_SECRET: ${{ secrets.LIVEKIT_API_SECRET }}
LIVEKIT_URL: ${{ secrets.LIVEKIT_URL }}
run: |
# ensure lk can use the provided credentials for cloud operations
lk cloud auth --api-key "$LIVEKIT_API_KEY" --api-secret "$LIVEKIT_API_SECRET" --url "$LIVEKIT_URL"
- name: Deploy agent
env:
# include any runtime secrets your agent needs
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
OTHER_SECRET: ${{ secrets.OTHER_SECRET }}
run: |
# create (first time) or deploy/update
# use `lk agent deploy` if agent already registered, or `lk agent create --secrets-file .env` if creating.
# if you maintain secrets in GitHub, you can write them to a temp file:
cat > .env <<EOF
OPENAI_API_KEY=${OPENAI_API_KEY}
OTHER_SECRET=${OTHER_SECRET}
EOF
# Deploy (uses livekit.toml to identify agent)
lk agent deploy --secrets-file .env
Notes and tips
• Use lk agent create --secrets-file .env locally if you haven't registered the agent yet; commit the generated livekit.toml.
• The CLI excludes LIVEKIT_* vars from secret uploads; provide them via GitHub Secrets for authentication.
• For rollbacks, use lk agent rollback in a separate workflow if desired.
• If you prefer not to write secrets to a file in the workflow, use lk agent deploy and rely on secrets configured in the LiveKit Cloud UI.
Want this tailored to your repo? Share which package manager you use (pip/poetry), whether you already have livekit.toml committed, and which runtime secrets you need; I’ll customize the workflow.
Sources: Deploying to production | LiveKit Docs | Examples | livekit/livekit_composite | DeepWikiglamorous-church-16794
12/24/2025, 8:32 PMtall-airline-16756
12/24/2025, 8:32 PMLIVEKIT_API_KEY, LIVEKIT_API_SECRET, and LIVEKIT_URL.
How to use them in CI/CD (GitHub Actions)
• Add these three as GitHub repository Secrets: LIVEKIT_API_KEY, LIVEKIT_API_SECRET, LIVEKIT_URL.
• In your workflow, pass them as environment variables to the step that runs the LiveKit CLI. Example snippet:
- name: Authenticate LiveKit CLI
env:
LIVEKIT_API_KEY: ${{ secrets.LIVEKIT_API_KEY }}
LIVEKIT_API_SECRET: ${{ secrets.LIVEKIT_API_SECRET }}
LIVEKIT_URL: ${{ secrets.LIVEKIT_URL }}
run: |
lk cloud auth --api-key "$LIVEKIT_API_KEY" --api-secret "$LIVEKIT_API_SECRET" --url "$LIVEKIT_URL"
Notes
• The LiveKit CLI (and Cloud) automatically provide LIVEKIT_* values to deployed agents, so these are excluded from secret uploads when using --secrets-file.
• For agent creation/deploy steps that need other runtime secrets (OpenAI, etc.), store those separately in GitHub Secrets and supply them via --secrets-file or environment variables in the workflow.
Want me to add this exact auth step into your existing workflow file? Paste it and I’ll insert it for you.glamorous-church-16794
12/24/2025, 8:50 PMtall-airline-16756
12/24/2025, 8:51 PM--project, --api-key, --api-secret, --url
b. Environment variables — LIVEKIT_API_KEY, LIVEKIT_API_SECRET, LIVEKIT_URL
c. Project file — livekit.toml in the repo
Recommended approach (GitHub Actions)
• Store environment-specific credentials as GitHub Secrets (e.g., STAGING_LIVEKIT_API_KEY, PROD_LIVEKIT_API_KEY, etc.).
• Determine target by branch, workflow input, or environment variable, and pass the appropriate secrets to the lk command (either via env vars or explicit flags).
Minimal example (branch-based)
name: Deploy LiveKit Agent
on:
push:
branches: [ main, staging ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install LiveKit CLI
run: curl -sSL <https://get.livekit.io> | bash && echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Set target env
id: vars
run: |
if [[ "${GITHUB_REF}" == "refs/heads/main" ]]; then
echo "ENV=production" >> $GITHUB_OUTPUT
else
echo "ENV=staging" >> $GITHUB_OUTPUT
fi
- name: Deploy
env:
# choose secrets based on ENV
LIVEKIT_URL: ${{ secrets[ format('{0}_LIVEKIT_URL', steps.vars.outputs.ENV | upper) ] }}
LIVEKIT_API_KEY: ${{ secrets[ format('{0}_LIVEKIT_API_KEY', steps.vars.outputs.ENV | upper) ] }}
LIVEKIT_API_SECRET: ${{ secrets[ format('{0}_LIVEKIT_API_SECRET', steps.vars.outputs.ENV | upper) ] }}
run: |
# authenticate and deploy; explicit flags can also be used:
lk cloud auth --api-key "$LIVEKIT_API_KEY" --api-secret "$LIVEKIT_API_SECRET" --url "$LIVEKIT_URL"
lk agent deploy
Alternatives
• Use explicit CLI flags in the deploy step:
lk agent deploy --project "staging-subdomain" --api-key "$STAGING_KEY" --api-secret "$STAGING_SECRET" --url "$STAGING_URL"
• Generate or swap a livekit.toml at runtime if you prefer config file-driven selection.
Best practices
• Keep per-env secrets in GitHub Secrets (e.g., PROD_*, STAGING_*).
• Restrict production deployments to protected branches or workflows.
• Log the chosen environment (non-secret) in CI for traceability.
Would you like a version of this workflow that uses workflow inputs instead of branch detection, or that writes livekit.toml dynamically?
Sources: Server-side | livekit/livekit_composite | DeepWiki | Deploying to production | LiveKit Docsglamorous-church-16794
12/24/2025, 8:52 PMtall-airline-16756
12/24/2025, 8:52 PMlivekit.toml can be used to drive deployments.
What livekit.toml does
• It contains project and agent metadata (agent id, project subdomain, etc.) that the CLI uses to identify which agent and project to deploy.
• When present in the repo, lk agent deploy reads livekit.toml so you don’t need to pass project flags every time.
How to use it for multi-env deployments
• Option A — Commit one file per environment and switch in CI:
◦ Keep livekit.staging.toml and livekit.prod.toml in the repo.
◦ In CI, copy the right file into livekit.toml before running lk agent deploy.
Example:
if [ "$TARGET" = "prod" ]; then
cp livekit.prod.toml livekit.toml
else
cp livekit.staging.toml livekit.toml
fi
lk agent deploy --secrets-file .env
• Option B — Generate livekit.toml in CI:
◦ Use a small template and fill values from GitHub Secrets or workflow inputs, then save to livekit.toml.
• Option C — Use explicit CLI flags or env vars instead:
◦ Pass --project or set LIVEKIT_API_KEY/SECRET/URL in CI to override livekit.toml.
Recommendations
• Store per-environment credentials as separate GitHub Secrets (e.g., STAGING_*, PROD_*) and use them in CI.
• Use branch protections so only main can deploy production.
• Prefer copying or generating livekit.toml in CI so the repo doesn’t contain secret or mutable env-specific state.
Want a small GitHub Actions snippet that swaps livekit.toml based on branch or workflow input? I can generate it for your repo structure.glamorous-church-16794
12/24/2025, 8:53 PMtall-airline-16756
12/24/2025, 8:53 PMlivekit.toml and a short GitHub Actions snippet that swaps it for staging vs production.
Example livekit.toml (minimal)
[project]
subdomain = "your-project-subdomain" # project subdomain or identifier
[agent]
id = "your-agent-id" # agent id assigned when created
name = "my-agent" # optional friendly name
version = "1.0.0" # optional
Optional fields you may include
• [agent].env — maps keys to values that will be set for the agent at deploy time (avoid secrets in repo).
• [agent].replicas — desired replica count.
• [agent].resources — CPU/memory hints if supported.
Example CI pattern: swap files in GitHub Actions
- name: Prepare livekit.toml for target
run: |
if [[ "${GITHUB_REF}" == "refs/heads/main" ]]; then
cp livekit.prod.toml livekit.toml
else
cp livekit.staging.toml livekit.toml
fi
- name: Deploy agent
env:
LIVEKIT_API_KEY: ${{ secrets.STAGING_LIVEKIT_API_KEY }} # choose secrets per env
LIVEKIT_API_SECRET: ${{ secrets.STAGING_LIVEKIT_API_SECRET }}
LIVEKIT_URL: ${{ secrets.STAGING_LIVEKIT_URL }}
run: |
lk cloud auth --api-key "$LIVEKIT_API_KEY" --api-secret "$LIVEKIT_API_SECRET" --url "$LIVEKIT_URL"
lk agent deploy --secrets-file .env
Notes
• Do not store secrets in `livekit.toml`; keep env-specific credentials in GitHub Secrets and pass them in CI.
• livekit.toml created by lk agent create includes full metadata — you can edit or generate it in CI as needed.
If you want, paste your current livekit.toml (redact secrets) and I’ll review it or generate staging/prod variants.glamorous-church-16794
12/28/2025, 10:48 PM- name: Install LiveKit CLI
run: |
curl -sSL <https://get.livekit.io/cli> | bash
lk --version
- name: Authenticate and configure LiveKit
env:
LIVEKIT_API_KEY: ${{ env.LIVEKIT_API_KEY }}
LIVEKIT_API_SECRET: ${{ env.LIVEKIT_API_SECRET }}
LIVEKIT_URL: ${{ env.LIVEKIT_URL }}
run: |
lk cloud auth --api-key "$LIVEKIT_API_KEY" --api-secret "$LIVEKIT_API_SECRET" --url "$LIVEKIT_URL" < /dev/null
lk project add \
--api-key "$LIVEKIT_API_KEY" \
--api-secret "$LIVEKIT_API_SECRET" \
--url "$LIVEKIT_URL" \
--default ${{ needs.determine-environment.outputs.environment }} < /dev/null || echo "Project may already be configured"
- name: Prepare livekit.toml
run: |
ENV="${{ needs.determine-environment.outputs.environment }}"
if [ "$ENV" = "production" ] && [ -f "livekit.prod.toml" ]; then
cp livekit.prod.toml livekit.toml
echo ":white_check_mark: Using livekit.prod.toml"
elif [ "$ENV" = "staging" ] && [ -f "livekit.staging.toml" ]; then
cp livekit.staging.toml livekit.toml
echo ":white_check_mark: Using livekit.staging.toml"
else
echo ":warning: Using default livekit.toml"
fi
- name: Set agent environment variables
env:
LIVEKIT_URL: ${{ env.LIVEKIT_URL }}
LIVEKIT_API_KEY: ${{ env.LIVEKIT_API_KEY }}
LIVEKIT_API_SECRET: ${{ env.LIVEKIT_API_SECRET }}
VOICE_API_BASE_URL: ${{ env.VOICE_API_BASE_URL }}
run: |
lk agent env set LIVEKIT_URL="$LIVEKIT_URL" || true
lk agent env set LIVEKIT_API_KEY="$LIVEKIT_API_KEY" || true
lk agent env set LIVEKIT_API_SECRET="$LIVEKIT_API_SECRET" || true
lk agent env set OPENAI_API_KEY="${{ secrets.OPENAI_API_KEY }}" || true
lk agent env set DEEPGRAM_API_KEY="${{ secrets.DEEPGRAM_API_KEY }}" || true
lk agent env set ELEVENLABS_API_KEY="${{ secrets.ELEVENLABS_API_KEY }}" || true
lk agent env set ANTHROPIC_API_KEY="${{ secrets.ANTHROPIC_API_KEY }}" || true
lk agent env set VOICE_API_BASE_URL="$VOICE_API_BASE_URL" || true
lk agent env set VOICE_API_VERSION="${{ secrets.VOICE_API_VERSION || 'v2' }}" || true
lk agent env set GCP_SERVICE_CREDENTIALS='${{ secrets.GCP_SERVICE_CREDENTIALS }}' || true
lk agent env set FIREBASE_CREDENTIALS='${{ secrets.FIREBASE_CREDENTIALS }}' || true
- name: Deploy agent
run: |
if lk agent status > /dev/null 2>&1; then
echo "Agent exists, deploying update..."
lk agent deploy < /dev/null
else
echo "Agent does not exist, creating new agent..."
lk agent create < /dev/null
fi
- name: Verify deployment
run: |
echo "Checking agent status..."
lk agent status || echo ":warning: Could not get agent status"
sleep 30
STATUS=$(lk agent status --json 2>/dev/null | jq -r '.status' || echo "unknown")
if [ "$STATUS" != "running" ] && [ "$STATUS" != "unknown" ]; then
echo ":warning: Warning: Agent status is $STATUS"
else
echo ":white_check_mark: Agent deployment completed"
fi
- name: View recent logs
run: lk agent logs --tail 50 || echo "Could not retrieve logs"
continue-on-error: true
- name: Deployment notification
if: always()
run: |
if [ "${{ job.status }}" = "success" ]; then
echo ":white_check_mark: Deployed to ${{ needs.determine-environment.outputs.environment }}"
else
echo ":x: Deployment failed to ${{ needs.determine-environment.outputs.environment }}"
fi
echo "Commit: ${{ github.sha }}"
continue-on-error: truetall-airline-16756
12/28/2025, 10:48 PMlk cloud auth is interactive. Use non-interactive auth (flags or env vars) and avoid commands that open a TTY.
Below is a simple, working GitHub Actions workflow that:
• Installs the LiveKit CLI
• Authenticates non-interactively via CLI flags or env vars
• Creates or deploys the agent without interactive prompts
• Passes runtime secrets securely
Save as .github/workflows/deploy-agent.yml:
name: Deploy LiveKit Agent
on:
push:
branches: [ main, staging ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install LiveKit CLI
run: |
curl -sSL <https://get.livekit.io/cli> | bash
echo "$HOME/.local/bin" >> $GITHUB_PATH
lk --version
- name: Prepare env (choose staging/prod)
id: env
run: |
if [[ "${GITHUB_REF##*/}" == "main" ]]; then
echo "TARGET=production" >> $GITHUB_OUTPUT
else
echo "TARGET=staging" >> $GITHUB_OUTPUT
fi
- name: Deploy agent (non-interactive)
env:
# Provide per-env secrets in GitHub (e.g., PROD_* and STAGING_*)
LIVEKIT_URL: ${{ secrets[ format('{0}_LIVEKIT_URL', steps.env.outputs.TARGET | upper) ] }}
LIVEKIT_API_KEY: ${{ secrets[ format('{0}_LIVEKIT_API_KEY', steps.env.outputs.TARGET | upper) ] }}
LIVEKIT_API_SECRET: ${{ secrets[ format('{0}_LIVEKIT_API_SECRET', steps.env.outputs.TARGET | upper) ] }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
DEEPGRAM_API_KEY: ${{ secrets.DEEPGRAM_API_KEY }}
run: |
# Create or ensure livekit.toml exists (adjust subdomain)
if [ ! -f livekit.toml ]; then
cat > livekit.toml <<EOF
[project]
subdomain = "your-project-subdomain"
EOF
fi
# Use CLI flags to avoid any interactive auth
if lk agent status --api-key "$LIVEKIT_API_KEY" --api-secret "$LIVEKIT_API_SECRET" --url "$LIVEKIT_URL" >/dev/null 2>&1; then
echo "Agent exists — deploying update..."
lk agent deploy \
--api-key "$LIVEKIT_API_KEY" \
--api-secret "$LIVEKIT_API_SECRET" \
--url "$LIVEKIT_URL" \
--secrets OPENAI_API_KEY="$OPENAI_API_KEY",DEEPGRAM_API_KEY="$DEEPGRAM_API_KEY"
else
echo "Creating new agent..."
lk agent create \
--api-key "$LIVEKIT_API_KEY" \
--api-secret "$LIVEKIT_API_SECRET" \
--url "$LIVEKIT_URL" \
--secrets OPENAI_API_KEY="$OPENAI_API_KEY",DEEPGRAM_API_KEY="$DEEPGRAM_API_KEY"
fi
- name: Verify & tail logs
env:
LIVEKIT_API_KEY: ${{ secrets.LIVEKIT_API_KEY }}
LIVEKIT_API_SECRET: ${{ secrets.LIVEKIT_API_SECRET }}
LIVEKIT_URL: ${{ secrets.LIVEKIT_URL }}
run: |
lk agent status --api-key "$LIVEKIT_API_KEY" --api-secret "$LIVEKIT_API_SECRET" --url "$LIVEKIT_URL" || true
lk agent logs --tail 50 --api-key "$LIVEKIT_API_KEY" --api-secret "$LIVEKIT_API_SECRET" --url "$LIVEKIT_URL" || true
Key fixes for your original error
• Do not run lk cloud auth in CI — it is interactive and opens a TTY.
• Use --api-key, --api-secret, and --url flags (or env vars) to authenticate non-interactively.
• Prefer --secrets or --secrets-file during create/deploy to upload runtime secrets; do not store secrets in committed files.
• If you need per-environment livekit.toml, swap or generate it in CI before deploy.
If you want, paste your repo structure or the exact branch names and I’ll generate a ready-to-commit workflow that maps your STAGING/PROD GitHub secrets (e.g., STAGING_LIVEKIT_API_KEY, PROD_LIVEKIT_API_KEY).
Sources: Agents (Python) | livekit/livekit_composite | DeepWikiglamorous-church-16794
12/28/2025, 10:56 PMtall-airline-16756
12/28/2025, 10:56 PMlk agent deploy simple in CI because the CLI can infer project/agent from the file.
• Good for teams that swap built artifacts between environments (you can maintain per-env TOML variants).
When you can skip it
• If your CI supplies --api-key, --api-secret, --url, and any other flags, the CLI will work without livekit.toml.
• This is common when you want to fully drive environment selection from CI (branch, workflow input, or secrets).
Recommended patterns
• Per-environment TOML files: keep livekit.staging.toml and livekit.prod.toml and copy the right one into livekit.toml in CI before deploy.
• Dynamic generation: template livekit.toml in CI using secrets/inputs and write it to workspace.
• Flags-first CI: omit TOML and always call lk agent deploy/create with --api-key/--api-secret/--url (this avoids needing to manage TOML files).
Minimal livekit.toml (if you use one)
[project]
subdomain = "your-project-subdomain"
[agent]
id = "your-agent-id"
name = "my-agent"
version = "1.0.0"
Which to choose?
• If you want simpler CI commands and a stable mapping in repo: use livekit.toml.
• If you want fully ephemeral, secrets-driven CI: pass flags/env vars and skip TOML.
Want me to generate the CI step that either swaps a per-env TOML or replaces it with a generated file? Tell me which you prefer and your branch names.glamorous-church-16794
12/28/2025, 10:57 PMtall-airline-16756
12/28/2025, 10:57 PMlivekit.toml (other than the "Prepare livekit.toml" copy step earlier you shared). If you want the deploy step to rely on livekit.toml, add an explicit step that ensures the correct file exists before calling lk agent create / lk agent deploy.
Two simple options to fix it (pick one):
1) Swap a per-env TOML into place (if you keep per-env files)
- name: Prepare livekit.toml
run: |
if [ "${{ needs.determine-environment.outputs.environment }}" = "production" ]; then
cp livekit.prod.toml livekit.toml
else
cp livekit.staging.toml livekit.toml
fi
Place this step before the Deploy agent step.
2) Generate livekit.toml in CI (no checked-in file)
- name: Generate livekit.toml
run: |
cat > livekit.toml <<EOF
[project]
subdomain = "${{ secrets.LIVEKIT_SUBDOMAIN }}"
[agent]
id = "${{ secrets.LIVEKIT_AGENT_ID }}"
EOF
Also run this before deploy. Populate subdomain/agent-id from secrets or workflow inputs.
Notes
• If you prefer not to use livekit.toml, the deploy/create commands will still work if you pass --api-key, --api-secret, and --url (which your workflow already does). In that case you can remove the prepare/generate steps.
• If you want, tell me which option you prefer and your environment names and I’ll return the exact snippet merged into your workflow.glamorous-church-16794
12/28/2025, 11:05 PM- name: Prepare livekit.toml
run: |
ENV="${{ needs.determine-environment.outputs.environment }}"
if [ "$ENV" = "production" ] && [ -f "livekit.prod.toml" ]; then
cp livekit.prod.toml livekit.toml
echo ":white_check_mark: Using livekit.prod.toml"
elif [ "$ENV" = "staging" ] && [ -f "livekit.staging.toml" ]; then
cp livekit.staging.toml livekit.toml
echo ":white_check_mark: Using livekit.staging.toml"
else
echo ":warning: Using default livekit.toml"
fi
logs
ENV="staging"
if [ "$ENV" = "production" ] && [ -f "livekit.prod.toml" ]; then
cp livekit.prod.toml livekit.toml
echo ":white_check_mark: Using livekit.prod.toml"
elif [ "$ENV" = "staging" ] && [ -f "livekit.staging.toml" ]; then
cp livekit.staging.toml livekit.toml
echo ":white_check_mark: Using livekit.staging.toml"
else
echo ":warning: Using default livekit.toml"
fi
shell: /usr/bin/bash -e {0}
env:
PYTHON_VERSION: 3.11
LIVEKIT_API_KEY: ***
LIVEKIT_API_SECRET: ***
LIVEKIT_URL: ***
VOICE_API_BASE_URL: ***
:white_check_mark: Using livekit.staging.tomltall-airline-16756
12/28/2025, 11:05 PMlivekit.prod.toml (or to generate one) so the same step picks it up when ENV=production.
Options for production
1) Manual GitHub Actions deploy (recommended if you want control)
• Add a manual trigger and require the production livekit.prod.toml be present (committed or stored as a secret/template).
• Example job trigger:
on:
workflow_dispatch:
inputs:
environment:
required: true
type: choice
options: [staging, production]
• Your existing Prepare step will copy livekit.prod.toml when environment=production. Then the deploy step runs and uses that file.
2) Create livekit.prod.toml from the agent created in prod
• Run lk agent create or lk agent deploy once manually against the production project. That generates the canonical livekit.toml you can save as livekit.prod.toml.
• Store it in the repo (if safe) or keep it encrypted/templated and generate it in CI from secrets:
cat > livekit.prod.toml <<EOF
[project]
subdomain = "${{ secrets.PROD_LIVEKIT_SUBDOMAIN }}"
[agent]
id = "${{ secrets.PROD_AGENT_ID }}"
EOF
3) Avoid committing TOML at all (flag-driven)
• Have CI pass --api-key/--api-secret/--url (and --project if needed) to lk agent deploy. This makes livekit.toml optional and is useful if you want all prod config driven by secrets and the manual trigger controls environment.
Key notes
• If production deploy is manual, use workflow_dispatch and require approvers or protected branch checks to limit who can run it.
• Ensure you store prod credentials as separate secrets (e.g., PROD_LIVEKIT_API_KEY) and wire them into the workflow when environment=production.
• If you generated livekit.prod.toml from a manual lk run, the file will include the correct agent id/subdomain so CI can call lk agent deploy without extra flags.
If you want, I can:
• Generate a full example workflow with a manual workflow_dispatch prod deploy that swaps livekit.prod.toml and uses prod secrets, or
• Show the exact commands to generate livekit.prod.toml from your local machine (paste your current livekit.staging.toml as reference). Which do you prefer?glamorous-church-16794
12/28/2025, 11:07 PMtall-airline-16756
12/28/2025, 11:07 PMlk agent deploy.
◦ Reproducible, auditable agent/project metadata stored in repo.
◦ Easier for teams that want explicit agent IDs/subdomains tracked.
• Cons:
◦ Risk of stale or leaked sensitive info if you commit too much (avoid secrets in TOML).
◦ Needs management of multiple files when agent metadata changes.
2) CI-driven (no TOML; pass flags/envs)
• Pros:
◦ Secrets remain in CI secret store only; no repo files to manage.
◦ Flexible: same workflow can target any environment using secrets or inputs.
◦ Good for ephemeral or heavily automated pipelines.
• Cons:
◦ Slightly more complex CI logic (you must construct flags or generate TOML on the fly).
◦ Agent metadata is implicit (driven by secrets/flags), less visible in repo.
My recommendation (balanced / safe)
• Store non-secret metadata in per-env TOML templates (livekit.staging.toml / livekit.prod.toml) but do NOT commit secrets.
• Keep production deploy manual (workflow_dispatch) and protect it with branch/reviewer rules.
• In CI, copy the appropriate TOML into place OR generate it from secrets, then call lk agent deploy with --api-key/--api-secret/--url drawn from per-env GitHub Secrets.
◦ This gives reproducibility (TOML) + secure secrets handling (CI secrets).
◦ Example: copy livekit.prod.toml -> livekit.toml, then run lk agent deploy --api-key "$PROD_KEY" --api-secret "$PROD_SECRET" --url "$PROD_URL" --secrets ...
If you prefer, I can:
• Generate a ready-to-use workflow that implements this hybrid pattern (templated TOML + per-env secrets + manual prod trigger). Which branch names and secret names do you use for staging/prod?glamorous-church-16794
12/28/2025, 11:08 PMglamorous-church-16794
12/28/2025, 11:08 PMtall-airline-16756
12/28/2025, 11:08 PMlivekit.toml on the first creation/deploy for prod. The CLI reads livekit.toml in the repo, so just ensure the file is present (or written) before running lk agent create or lk agent deploy.
Simple steps (one-time create for prod)
1. Place or generate livekit.prod.toml in the repo (or keep it in CI secrets/templates). Ensure it has the correct project subdomain and the agent id if you already have one, e.g.:
[project]
subdomain = "your-prod-subdomain"
[agent]
id = "your-agent-id" # optional for create; useful for later deploys
name = "prod-agent"
1. In CI (or locally) copy it to livekit.toml and run create:
cp livekit.prod.toml livekit.toml
lk agent create \
--api-key "$PROD_LIVEKIT_API_KEY" \
--api-secret "$PROD_LIVEKIT_API_SECRET" \
--url "$PROD_LIVEKIT_URL" \
--secrets-file .env
Notes
• If livekit.toml contains an agent.id, lk agent create will register/update that agent; omitting agent.id lets the CLI generate an ID and write a livekit.toml locally.
• Pass credentials via flags or env vars in CI to avoid interactive auth.
• Use --secrets-file or --secrets to upload runtime secrets (do not commit secrets into TOML).
• After the first create, commit the generated livekit.toml (or save it as livekit.prod.toml) so future CI deploys can use lk agent deploy without extra flags.
If you want, I can produce the exact GitHub Actions snippet that copies livekit.prod.toml, injects prod secrets, and runs lk agent create as a manual workflow_dispatch step. Which do you prefer?glamorous-church-16794
12/28/2025, 11:09 PMtall-airline-16756
12/28/2025, 11:09 PMlivekit.toml that declares the project subdomain and (optionally) the agent metadata. Do NOT put secrets in it.
Minimal example (suitable for creating the agent the first time):
[project]
subdomain = "your-prod-subdomain"
[agent]
name = "my-prod-agent" # optional friendly name
# omit `id` when creating first time — the CLI will generate one and write it back
If you already have an agent ID (e.g., exported from a manual create), include it so CI can target the same agent:
[project]
subdomain = "your-prod-subdomain"
[agent]
id = "generated-agent-id"
name = "my-prod-agent"
version = "1.0.0"
Optional non-secret fields you may include:
• [agent].replicas — desired replica count
• [agent].resources — CPU/memory hints (if used)
• [agent].env — non-secret defaults (avoid sensitive values)
How to use in CI for first-time prod create
1. Ensure livekit.prod.toml (above) is copied to livekit.toml in the workspace.
2. Run non-interactive create with CI secrets:
lk agent create --api-key "$PROD_LIVEKIT_API_KEY" --api-secret "$PROD_LIVEKIT_API_SECRET" --url "$PROD_LIVEKIT_URL" --secrets-file .env
Notes
• Keep secrets (API keys, provider keys) in your CI secret store and pass via --secrets-file or `--secrets`; do not commit them into TOML.
• After lk agent create the CLI will write the generated agent.id into livekit.toml — save that as livekit.prod.toml for future deploys. Sources: Deploying to production | LiveKit Docs | Examples | livekit/livekit_composite | DeepWiki | Custom agent deployments | LiveKit docsglamorous-church-16794
12/28/2025, 11:10 PMtall-airline-16756
12/28/2025, 11:10 PMlivekit.toml in the workspace and pass credentials non-interactively via flags or env vars.
Example — first-time create (copies prod TOML, creates agent, uploads secrets):
cp livekit.prod.toml livekit.toml
# create agent (non-interactive)
lk agent create \
--api-key "$PROD_LIVEKIT_API_KEY" \
--api-secret "$PROD_LIVEKIT_API_SECRET" \
--url "$PROD_LIVEKIT_URL" \
--secrets-file .env
Example — subsequent deploy using the committed/generated `livekit.toml`:
# ensure livekit.toml present (contains [project] subdomain and [agent].id)
lk agent deploy \
--api-key "$PROD_LIVEKIT_API_KEY" \
--api-secret "$PROD_LIVEKIT_API_SECRET" \
--url "$PROD_LIVEKIT_URL" \
--secrets-file .env
Notes
• Do not put secrets in `livekit.toml`; keep them in .env or CI secrets.
• For CI, set PROD_LIVEKIT_API_KEY, PROD_LIVEKIT_API_SECRET, PROD_LIVEKIT_URL as protected secrets and run the same commands in a workflow step.glamorous-church-16794
12/28/2025, 11:12 PMtall-airline-16756
12/28/2025, 11:12 PMlivekit.toml for a manual, first-time lk agent create. The CLI will read livekit.toml from the current directory; you don’t pass it as a flag.
Steps (local, manual)
1. Create livekit.toml in your project root. Minimal example:
[project]
subdomain = "your-prod-subdomain"
[agent]
name = "my-prod-agent"
# omit `id` for first-time create so the CLI generates one
1. Prepare a .env (or provide secrets via env vars) with runtime secrets (do NOT store these in the TOML):
OPENAI_API_KEY=...
DEEPGRAM_API_KEY=...
# etc.
1. Run the create command from the directory containing `livekit.toml`:
# using .env file for secrets
lk agent create \
--api-key "$PROD_LIVEKIT_API_KEY" \
--api-secret "$PROD_LIVEKIT_API_SECRET" \
--url "$PROD_LIVEKIT_URL" \
--secrets-file .env
What happens
• The CLI reads livekit.toml, registers the agent, generates an agent.id, and updates/writes livekit.toml with that id.
• Save that updated file (or copy it to livekit.prod.toml) for future CI deploys.
Notes
• Don’t put API keys or other secrets in livekit.toml. Use --secrets-file or CI secret stores.
• If you already have an agent.id, include it in livekit.toml to target the same agent on create/deploy.
Want me to generate a livekit.prod.toml for your subdomain/name?glamorous-church-16794
12/29/2025, 5:16 PMtall-airline-16756
12/29/2025, 5:16 PMlk agent create, so a true livekit.prod.toml with a valid agent.id only exists after a create/deploy.
What you can do instead
• Manual template: create a livekit.prod.toml template with the project subdomain and agent name (omit id) and run lk agent create to generate the real file:
[project]
subdomain = "your-prod-subdomain"
[agent]
name = "my-prod-agent"
After lk agent create the CLI will write the generated agent.id into `livekit.toml`; copy or save that as livekit.prod.toml.
• Create once locally (recommended): run the one-time local create (manual or via a protected workflow) to generate the full livekit.toml, then save it as livekit.prod.toml for CI use.
• Manual authoring if you already know the ID: if you already have an agent id (from dashboard or prior deploy), you can manually create `livekit.prod.toml`:
[project]
subdomain = "your-prod-subdomain"
[agent]
id = "existing-agent-id"
name = "my-prod-agent"
• CI generation after create: run a protected/manual create step in CI that writes the generated livekit.toml to an artifact or secret store for future deploys.
If you want, I can:
• Generate a template livekit.prod.toml for you, or
• Provide the exact lk agent create command you should run locally to produce the final file. Which do you prefer? Sources: Deploying to production | LiveKit Docs | Voice AI quickstart | LiveKit docs | Google AI and LiveKit | LiveKit Docsglamorous-church-16794
12/29/2025, 5:17 PMtall-airline-16756
12/29/2025, 5:18 PMroom_config.agents. No dispatch rule → no routing.
• CLI example:
◦ List: lk sip dispatch list
◦ Delete: lk sip dispatch delete <DISPATCH_RULE_ID>
2) Scale down or stop the agent process
• Stop the agent service or scale replicas to zero. If the agent isn’t running it can’t accept jobs.
• For LiveKit Cloud, deploy with fewer replicas or stop the agent.
3) Remove agent from explicit dispatch configuration
• If you use explicit agent dispatch, remove the agent name from the dispatch config so it’s not selectable:
◦ Update rule JSON: set room_config.agents = [] or remove the agent entry, then redeploy the rule.
4) Prevent registration (code-level)
• Add a runtime flag or config so the agent does not register/join rooms (e.g., skip the AgentSession start). This is useful for graceful disable during maintenance.
Best practice
• For temporary disablement, update/delete the dispatch rule. For maintenance windows or long-term disablement, both stop the agent process and update dispatch rules.
• Keep dispatch rule changes and prod disabling behind protected workflows or approvals to avoid accidental outages.
If you tell me which dispatch method you use (SIP dispatch rules, explicit agent dispatch, or direct API assignments) and whether the agent runs in LiveKit Cloud, I can give the exact CLI/API command or a small script to make it inactive.
Sources: Creating SIP Inbound Trunks and Dispatch Rules with Python SDK | Python SDKs | livekit/livekit_composite | DeepWiki | Agents telephony integration | LiveKit docs | Server lifecycle | LiveKit docs | Deploying to production | LiveKit Docsglamorous-church-16794
12/29/2025, 5:20 PMtall-airline-16756
12/29/2025, 5:20 PMglamorous-church-16794
12/29/2025, 6:12 PMtall-airline-16756
12/29/2025, 6:12 PMglamorous-church-16794
12/29/2025, 6:13 PMtall-airline-16756
12/29/2025, 6:14 PMlk agent create/deploy/status/logs/rollback).
• CI/CD (recommended for automated workflows): install lk in pipeline and run lk agent deploy/create non-interactively or generate livekit.toml in CI. Good for automated builds, secrets from CI, and protected prod deploys.
• Server SDK / API (programmatic control): use LiveKit Server SDKs to script management, update dispatch rules, or call admin APIs from your services.
• Dashboard (web UI): view logs, metrics, and some management actions; good for monitoring and manual inspection.
When to use what:
• Local dev / first-time create: CLI.
• Reproducible automated deploys and rollbacks: CI/CD calling CLI (or API) with secrets.
• Dynamic or embedded management (e.g., auto-scaling, programmatic dispatch changes): Server SDK/API.
• Quick checks and log viewing: Dashboard.
If you tell me which parts you want to avoid the CLI for (deploy, rollback, env updates, logs, or disabling agents), I’ll give the exact CI or API snippet to implement it.
Sources: Examples | livekit/livekit_composite | DeepWiki | Testing and evaluation | LiveKit docs | Python SDKs | livekit/livekit_composite | DeepWiki | An open source stack for real-time multimodal AI | Agent session | LiveKit docsglamorous-church-16794
12/29/2025, 6:14 PMtall-airline-16756
12/29/2025, 6:15 PMlk agent rollback with flags to avoid interactive auth.
Example workflow (drop into .github/workflows/rollback.yml):
name: Rollback LiveKit Agent
on:
workflow_dispatch:
inputs:
environment:
required: true
type: choice
options: [staging, production]
version:
required: false
description: 'Version ID to roll back to (omit to rollback one step)'
jobs:
rollback:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install LiveKit CLI
run: |
curl -sSL <https://get.livekit.io/cli> | bash
echo "$HOME/.local/bin" >> $GITHUB_PATH
lk --version
- name: Set env for target
run: echo "running rollback"
- name: Run rollback
env:
# Use per-env secrets: e.g., STAGING_LIVEKIT_API_KEY or PROD_LIVEKIT_API_KEY
LIVEKIT_API_KEY: ${{ secrets[ format('{0}_LIVEKIT_API_KEY', github.event.inputs.environment | upper) ] }}
LIVEKIT_API_SECRET: ${{ secrets[ format('{0}_LIVEKIT_API_SECRET', github.event.inputs.environment | upper) ] }}
LIVEKIT_URL: ${{ secrets[ format('{0}_LIVEKIT_URL', github.event.inputs.environment | upper) ] }}
run: |
if [ -n "${{ github.event.inputs.version }}" ]; then
lk agent rollback --version "${{ github.event.inputs.version }}" \
--api-key "$LIVEKIT_API_KEY" --api-secret "$LIVEKIT_API_SECRET" --url "$LIVEKIT_URL"
else
lk agent rollback \
--api-key "$LIVEKIT_API_KEY" --api-secret "$LIVEKIT_API_SECRET" --url "$LIVEKIT_URL"
fi
2) Automated rollback on failure (optional, use cautiously)
• Trigger: run as a follow-up job when a deploy job fails.
• Action: use lk agent rollback to revert to previous stable version.
• Require safeguards (only run on staging or in controlled contexts).
Example snippet to run after a failed deploy:
# in deploy job: set outputs or fail
# fallback job:
jobs:
rollback-on-failure:
if: failure()
runs-on: ubuntu-latest
needs: deploy
steps:
- name: Install LiveKit CLI
run: curl -sSL <https://get.livekit.io/cli> | bash && echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Rollback to previous
env:
LIVEKIT_API_KEY: ${{ secrets.STAGING_LIVEKIT_API_KEY }}
LIVEKIT_API_SECRET: ${{ secrets.STAGING_LIVEKIT_API_SECRET }}
LIVEKIT_URL: ${{ secrets.STAGING_LIVEKIT_URL }}
run: |
lk agent rollback --api-key "$LIVEKIT_API_KEY" --api-secret "$LIVEKIT_API_SECRET" --url "$LIVEKIT_URL"
Best practices
• Use manual rollback (workflow_dispatch) for production and protect who can run it.
• Log the rollback reason and version (use workflow inputs or issue/PR link).
• Prefer lk agent rollback (uses rolling strategy and drains sessions) over redeploying older code manually.
• Keep per-environment secrets separate (e.g., PROD_*, STAGING_*).
• Optionally list versions before rollback: lk agent versions --api-key ... to confirm target version.
If you want, I can:
• Generate a ready-to-use rollback workflow tailored to your branch names and secret names, or
• Add an approval step for production (required reviewers) in the workflow. Which would you like?glamorous-church-16794
12/29/2025, 6:16 PMtall-airline-16756
12/29/2025, 6:16 PM--version flag with lk agent rollback. Quick notes and examples.
1) List available versions:
lk agent versions --api-key "$KEY" --api-secret "$SECRET" --url "$URL"
2) Roll back to a specific version:
lk agent rollback --version 3 --api-key "$KEY" --api-secret "$SECRET" --url "$URL"
3) GitHub Actions manual rollback (workflow_dispatch input)
on:
workflow_dispatch:
inputs:
environment:
required: true
type: choice
options: [staging, production]
version:
required: true
description: 'Version number to roll back to'
jobs:
rollback:
runs-on: ubuntu-latest
steps:
- name: Install LiveKit CLI
run: curl -sSL <https://get.livekit.io/cli> | bash && echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Rollback agent
env:
LIVEKIT_API_KEY: ${{ secrets[ format('{0}_LIVEKIT_API_KEY', github.event.inputs.environment | upper) ] }}
LIVEKIT_API_SECRET: ${{ secrets[ format('{0}_LIVEKIT_API_SECRET', github.event.inputs.environment | upper) ] }}
LIVEKIT_URL: ${{ secrets[ format('{0}_LIVEKIT_URL', github.event.inputs.environment | upper) ] }}
run: |
lk agent rollback --version "${{ github.event.inputs.version }}" \
--api-key "$LIVEKIT_API_KEY" --api-secret "$LIVEKIT_API_SECRET" --url "$LIVEKIT_URL"
Best practices
• Run lk agent versions first to pick a valid version.
• Protect the workflow (approvals / limited runner access) for production rollbacks.
• Log the rollback reason and version in the workflow inputs or commit message.
Want me to add confirmation logic (show versions, ask to confirm) into the workflow?
Sources: Agents Framework | livekit/livekit_composite | DeepWiki | Voice AI quickstart | LiveKit docs | Testing and evaluation | LiveKit docsglamorous-church-16794
12/29/2025, 6:23 PMtall-airline-16756
12/29/2025, 6:23 PM[project]
subdomain = "your-prod-subdomain"
[agent]
name = "my-prod-agent"
# omit id for first-time create
• Prepare .env (or keep secrets in your CI secret store) with provider keys (do NOT put LiveKit credentials here).
1. Create agent (non-interactive)
lk agent create \
--api-key "$PROD_LIVEKIT_API_KEY" \
--api-secret "$PROD_LIVEKIT_API_SECRET" \
--url "$PROD_LIVEKIT_URL" \
--secrets-file .env
• CLI writes generated agent.id into livekit.toml. Save it as livekit.prod.toml for CI.
Deploy (CI/CD, repeatable)
1. Store per-env secrets in CI (e.g., PROD_LIVEKIT_API_KEY, PROD_LIVEKIT_API_SECRET, PROD_LIVEKIT_URL, and provider keys).
2. Ensure livekit.toml exists in workspace (copy livekit.prod.toml → livekit.toml or generate it).
3. Run non-interactive deploy step:
lk agent deploy \
--api-key "$PROD_LIVEKIT_API_KEY" \
--api-secret "$PROD_LIVEKIT_API_SECRET" \
--url "$PROD_LIVEKIT_URL" \
--secrets-file .env
1. Monitor:
◦ lk agent status --api-key ...
◦ lk agent logs --tail 50 --api-key ...
Rollback (manual via CLI or CI)
1. List versions to choose target:
lk agent versions --api-key "$KEY" --api-secret "$SECRET" --url "$URL"
1. Roll back to a specific version:
lk agent rollback --version <VERSION> --api-key "$KEY" --api-secret "$SECRET" --url "$URL"
1. If you omit --version, lk agent rollback typically reverts one step back.
2. Best practice: run rollback from a protected manual workflow (workflow_dispatch) in CI for production.
CI Patterns & Tips
• Avoid interactive auth in CI: do NOT run `lk cloud auth`; pass credentials via flags or env vars.
• Per-environment handling:
◦ Option A (recommended hybrid): keep livekit.staging.toml / livekit.prod.toml templates and copy the appropriate one to livekit.toml in CI, then pass per-env secrets.
◦ Option B: skip TOML, drive everything via flags/env vars in CI.
• Secrets: keep LIVEKIT_* and provider keys in CI secret store; use --secrets or --secrets-file when deploying.
• Protect production: require manual trigger or approvals for prod deploys/rollbacks, restrict who can run them.
• Verify after deploy/rollback: lk agent status and lk agent logs.
Quick Safety Checklist before prod actions
• Use prod-only secrets (PROD_*) and protected workflow.
• Confirm the target version with lk agent versions.
• Notify team / record reason in workflow input.
If you’d like, I can generate:
• A ready-to-commit GitHub Actions deploy workflow that copies livekit.prod.toml and deploys, and
• A separate manual rollback workflow with a version input and approval gate. Which one do you want first?glamorous-church-16794
12/29/2025, 6:24 PMtall-airline-16756
12/29/2025, 6:24 PMctx.log_context_fields (or your logger). Example pattern:
◦ start = now()
◦ await session.start(...) / await ctx.connect()
◦ connected = now()
◦ log duration = connected - start
• These logs show exact connect duration per call and can be aggregated in your logging/observability system.
3) SDK events (if applicable)
• If your agent uses the client SDK, time the events from WebSocket/handshake → JoinResponse → Connected to get end-to-end connection time.
Where to look after instrumenting
• LiveKit dashboard participant analytics for built-in metrics.
• Agent logs (CLI: lk agent logs, or dashboard Logs tab) for your custom timing fields.
If you want, I can:
• Provide a one-line code snippet for timing in your agent language (Python or Node), or
• Point to where the participant analytics live in the dashboard UI for your account — tell me which you prefer. Sources: Say hello to improved Cloud analytics | Job lifecycle | LiveKit docs | client-sdk-js | livekit/livekit_composite | DeepWikiglamorous-church-16794
12/29/2025, 6:25 PMtall-airline-16756
12/29/2025, 6:25 PMglamorous-church-16794
12/29/2025, 6:35 PMtall-airline-16756
12/29/2025, 6:36 PMlk agent logs --tail 200 --api-key ... for the agent around the call start time.
• Run lk agent status to confirm the agent service is healthy and has ready replicas.
Quick diagnostic steps
1. Enable Agent Observability (if not enabled)
◦ Turn on Agent Observability in the project settings (Data & Privacy) so sessions, traces, audio, and timestamps are recorded.
1. Inspect session trace
◦ Open the call -> Session -> Agent insights / Timeline to see exactly when the agent joined relative to call start.
1. Correlate logs to timeline
◦ From agent logs, look for connect/join events and any errors like “Room connection not established within 10 seconds” or repeated retries.
1. Check scaling / cold starts
◦ If your agent scales to zero, first request triggers a cold start. Look for long startup logs (model loading, container cold-start) right before the join time.
1. Check dispatch rules & availability
◦ Ensure dispatch rules target an available agent name and that there are ready replicas for that agent.
◦ If using explicit dispatch, verify the dispatch call happens promptly when the call arrives.
Common causes & fixes
• Cold starts: keep at least one warm replica or increase minimum replicas to avoid cold boot delay.
• Insufficient replicas / resource limits: increase replicas or CPU/memory so agents start faster.
• Long initialization: optimize agent startup (lazy-load heavy models, reduce init work before joining).
• Dispatch timing: trigger agent dispatch earlier (when token generated or on inbound webhook) so agent can start joining immediately.
• Network or TURN delays: ensure TURN/ICE candidates are healthy; check ICE/handshake times in participant analytics.
• Worker errors: address any repeated connection/timeouts found in logs (fix retry/backoff or resource exhaustion).
Short-term mitigations
• Keep a warm instance (replicas >=1) for critical production agents.
• Add a quick health-check endpoint and alert on slow join times.
• Temporarily route calls to a fallback handler while diagnosing.
If you want, I can:
• Provide the exact log patterns/strings to search for (Python or Node agent).
• Suggest a minimal change (e.g., set replicas=1 in livekit.toml or CI deploy) to eliminate cold starts and show the expected improvement.
Which would you like me to do next?
Sources: https://blog.livekit.io/streamline-troubleshooting-with-agent-observability/#/portal/signup| | Web and mobile frontends | LiveKit docs | Deploying to production | LiveKit Docs | Agents Framework | livekit/livekit_composite | DeepWiki | examples/frontdesk | livekit/livekit_composite | DeepWikiglamorous-church-16794
12/29/2025, 7:03 PMtall-airline-16756
12/29/2025, 7:03 PMlk agent status (or Cloud dashboard) — check ready/failed replicas.
• Host/container metrics: memory usage, swap, and restart counts in your cloud provider or LiveKit Cloud dashboard metrics.
• Process-level memory inside the agent (if you can ssh or use metrics): peak RSS and allocations during startup.
How to monitor in LiveKit Cloud / CI
• Dashboard: check agent instance health, replica counts, and logs for restarts.
• Logs: tail logs with lk agent logs and search for memory/OOM/GC messages.
• If you have custom metrics/observability (Prometheus, Cloud metrics), surface memory usage and restart counts.
Quick mitigations (fast to try)
• Increase container memory limit or agent resources in your deployment (set higher memory in livekit.toml or in your deployment config).
• Keep warm instances: set replicas >= 1 so you avoid cold starts.
• Lazy-load heavy models: move large model loading to after join or load on demand.
• Reduce memory footprint: swap to smaller models, reduce concurrency, or optimize initialization.
• Add retries/backoff and faster failure detection so a failed join doesn't block long.
• If OOMs occur, increase memory immediately and redeploy.
Longer-term fixes
• Profile memory usage during startup locally to identify hot allocations.
• Add memory and startup time SLOs and alerts in CI/monitoring.
• Use multiple lightweight workers instead of one heavy instance.
If you’d like, tell me:
• Which agent runtime (Python/Node), memory limit currently set, and whether you see OOMs in logs — I’ll give exact config lines to raise memory or a minimal code change to lazy-load models.