fancy-kitchen-89125
02/18/2026, 6:20 AMtall-airline-16756
02/18/2026, 6:20 AMtall-airline-16756
02/18/2026, 6:21 AMlivekit.toml config (CLI can generate this too).
1. Install and authenticate the LiveKit CLI
◦ Install the CLI (Homebrew or the curl installer).
◦ Authenticate to your LiveKit Cloud project with lk cloud auth.
1. Register and deploy the agent
◦ From your project root run lk agent create. This will generate any missing files, build the container, register the agent, and deploy it to LiveKit Cloud.
◦ The agent will be deployed on LiveKit Cloud infrastructure with autoscaling and observability.
1. Add secrets
◦ Store sensitive keys via LiveKit Cloud secrets (for example lk secret create OPENAI_API_KEY sk-xxxx), which will be injected into your agent at runtime.
1. Verify and monitor
◦ Use the LiveKit Cloud dashboard to check agent health, logs, and active sessions.
◦ Test a few sessions to confirm behavior matches your self‑hosted setup.
1. (Optional) Automate deployments
◦ Add CI/CD using the livekit/deploy-action GitHub Action to deploy on push.
If you prefer, tell me your answers to the four questions above and I’ll provide a tailored, step‑by‑step walkthrough (including exact CLI commands and recommended Dockerfile changes) for your specific agent.
Sources: Self-hosted deployments | LiveKit Documentation | Google AI and LiveKit | LiveKit Documentation | Voice AI quickstart | LiveKit Documentation | Agent deployment overview | LiveKit Documentation | Deploy LiveKit Agents with GitHub Actions | LiveKitfancy-kitchen-89125
02/18/2026, 6:24 AMtall-airline-16756
02/18/2026, 6:24 AMlivekit.toml. If you choose (B), paste your Dockerfile and I’ll suggest any small edits.
High-level steps
1. Prepare project artifacts
2. Authenticate the LiveKit CLI to your LiveKit Cloud project
3. Configure livekit.toml (service config)
4. Add any secrets (API keys) to LiveKit Cloud
5. Deploy the agent with lk agent create
6. Expose and secure your trigger endpoint so LiveKit-hosted agent can receive dispatch requests
7. Verify and monitor in the LiveKit dashboard
8. (Optional) Add CI/CD for automated deployments
Detailed steps
1) Prepare project artifacts
• Keep your existing Python code and Dockerfile at the project root. The CLI can generate files if needed, but since you already have a Dockerfile you can reuse it.
• Ensure the container starts the agent process on CMD or ENTRYPOINT and listens on any required ports for local health checks if you use them.
2) Install and authenticate the LiveKit CLI
• Install the CLI (Homebrew or the curl installer).
• Run:
◦ lk cloud auth
◦ Follow prompts to link to your LiveKit Cloud project (you said you already have a project).
3) Create or edit livekit.toml
• livekit.toml tells LiveKit Cloud how to build/run your agent. If you want the CLI to generate a starter file, run lk agent create from your project root — it will create livekit.toml and other artifacts if missing.
• If you prefer to author manually, a minimal livekit.toml should reference your Dockerfile, runtime environment, and env vars (secrets referenced by name). Example fields you’ll set:
◦ service name
◦ container image details (if you pre-build) or build context (to let LiveKit build)
◦ environment variables (refer to secrets by name)
◦ any required ports
Tell me if you want a sample livekit.toml and I’ll provide one tailored to your Dockerfile.
4) Store secrets securely
• Add external API keys (for example MY_TRIGGER_API_KEY or OPENAI_API_KEY) using LiveKit Cloud secrets:
◦ lk secret create MY_TRIGGER_API_KEY <value>
• Reference those secrets in livekit.toml so they are injected into your container at runtime rather than baked into the image.
5) Deploy the agent
• From project root:
◦ If you want to generate any missing files and do an initial deploy: lk agent create
◦ If you already have livekit.toml and want to push: lk agent deploy (or the CLI command shown after create)
• The CLI will build your Docker image (unless you uploaded one), register the agent, and deploy to LiveKit Cloud.
• LiveKit Cloud will handle scaling, observability, and secure secret injection.
6) Expose and secure your outbound call trigger endpoint Your agent currently only creates dispatches when your other API endpoint receives requests. When migrating, you need to ensure the trigger endpoint can reach the LiveKit Cloud–hosted agent or else adapt the trigger flow:
Options:
• Keep the trigger API external (unchanged)
◦ If your current API calls the agent via a private network or local host, you must change it to send requests to a public endpoint reachable by LiveKit Cloud.
◦ Create a secure public endpoint that forwards trigger requests to the agent (for example your current API can call LiveKit Cloud agent’s inbound endpoint). Protect it with an API key or mutual auth.
• Move/host the trigger API alongside the agent in LiveKit Cloud
◦ If the trigger API can be containerized, consider deploying it as part of the same project (or another LiveKit Cloud service) so internal calls remain internal and low latency.
• Use a message queue or webhook relay
◦ If exposing the endpoint publicly isn’t ideal, have your external API push messages into a queue (e.g., an existing service you control), and run a lightweight consumer in your agent that polls or subscribes to those messages.
Security recommendations:
• Use LiveKit Cloud secrets for any auth tokens.
• Require an API key or signed requests to the trigger endpoint.
• Restrict inbound sources if your trigger API supports IP allowlisting.
7) Verify and monitor
• After deploy:
◦ Use the LiveKit Cloud dashboard to view agent logs, sessions, and health.
◦ Trigger a test outbound request from your trigger API and confirm the agent creates a dispatch and places the call.
◦ Verify environment variables/secrets are available in the running container (check logs or add a temporary health endpoint that validates expected env vars).
8) Optional: CI/CD
• Add GitHub Actions with the livekit/deploy-action to build and deploy automatically on push to main.
Next steps for me to help further
• If you want exact files/commands now, please paste either:
◦ Your Dockerfile (so I can confirm it's compatible and suggest edits), OR
◦ The portion of your trigger flow showing how your external API calls the agent (HTTP endpoint, payload, auth).
• Tell me whether you want the trigger endpoint to remain as-is, be moved into LiveKit Cloud, or use a queue-based relay — I’ll give a concrete implementation plan for whichever you choose.
If you want, I can also:
• Draft a sample livekit.toml for your Python project.
• Show the exact CLI commands and an example lk secret create invocation.
• Suggest minor Dockerfile tweaks so the container is optimized for LiveKit Cloud (small image, explicit CMD, healthcheck).fancy-kitchen-89125
02/18/2026, 6:40 AMtall-airline-16756
02/18/2026, 6:41 AMgemini-2.5-flash-native-audio-preview-xx-xxxx) while running your agent.
Likely causes (what this error usually means)
• The code is expecting a mutable chat context object that exposes a messages attribute or property, but the runtime is giving a read-only chat context type (_ReadOnlyChatContext) that does not include messages.
• This typically happens when:
◦ You call an API or handler that returns a read-only view of the chat/session context instead of the full mutable object.
◦ You rely on an older example or different SDK layer where the chat context shape was context.messages, but the current object exposes messages differently (for example via an accessor method or property name change).
◦ A plugin or wrapper in the agent pipeline is passing an internal read-only object into your code (e.g., inside a realtime callback) and you try to mutate or access messages directly.
Quick checks and fixes to try now
1. Inspect the object shape before accessing messages
◦ Add a small debug log right where the error occurs:
▪︎ Print the object's type and available attributes/methods (e.g., print(type(context)) and print(dir(context))).
◦ This will show whether messages exists or if there is a different property (like get_messages(), chat, history, or events).
1. Use the exposed read-only API instead of messages
◦ If the object provides a method to read messages (for example context.get_messages() or context.history), use that instead of context.messages.
1. Convert/copy the read-only context to a mutable structure
◦ If you need to manipulate the messages list, copy from the read-only object into a new list:
▪︎ Example (Python):
# assuming `context` is the read-only object and it has an iterable or method
messages = list(context) # or list(context.get_messages())
# now you can manipulate `messages` safely
• Only do this if you truly need to modify messages; otherwise prefer read-only accessors.
1. Check the SDK method/handler you are using
◦ If this happens inside a realtime callback or plugin (where LiveKit or the Gemini plugin passes context), consult which argument type is documented for that hook.
◦ Some handlers intentionally pass a read-only view; you should use the documented accessor to avoid mutating it.
Targeted questions so I can give precise code fixes
• Can you paste the minimal code snippet (5–20 lines) where you access context.messages or where the error is thrown?
• Where does this object come from in your flow? For example:
◦ A realtime callback from the Gemini plugin (e.g., an AgentSession handler)?
◦ A wrapper API that receives audio and then queries the model?
• Which SDK or library surface are you using to call Gemini realtime (OpenAI SDK, a LiveKit plugin, or another wrapper)? And what version if known?
If you want, paste the snippet and I’ll:
• Point out exactly what to change to use the correct accessor or to copy the data into a mutable list.
• Provide a small replacement code block that fits your handler signature.
Helpful references
• If you’re using the LiveKit Gemini realtime plugin or AgentSession integrations, the runtime may pass a read-only chat context in callbacks — check how the plugin exposes chat history in the handler you’re implementing. See the Gemini Live API plugin docs: https://docs.livekit.io/agents/models/realtime/plugins/gemini
Send the small snippet and I’ll give the exact fix.
Sources: Gemini Realtime Agent with Live Vision | LiveKit Documentation | Gemini Live API plugin | LiveKit Documentation | LLM-Powered Content Filter | LiveKit Documentation