numerous-whale-53652
12/24/2025, 5:49 PMtall-airline-16756
12/24/2025, 5:49 PMtall-airline-16756
12/24/2025, 5:50 PMsession.history when an agent disconnects and then rejoins the room. That behavior is expected: each new AgentSession starts with an empty conversation context unless you explicitly restore it.
You can preserve continuity by saving the chat context before disconnect and restoring it on reconnect. Quick options:
• Save and restore ChatContext
a. Before disconnect, serialize agent.session.chat_ctx (or session.history) to persistent storage (DB, Redis, file).
b. After reconnect, create the new session and call await agent.update_chat_ctx(saved_ctx) to inject the previous history.
• Use a shutdown hook
◦ Call session.shutdown() or a custom disconnect handler to persist the context before the session ends.
If you’d like, tell me:
• which SDK/language you’re using (Python, JS, etc.), and
• whether you want an example for serializing/restoring chat_ctx (I can provide a short code snippet). Sources: Agent session | LiveKit docs | Agents and handoffs | LiveKit docs | Job lifecycle | LiveKit docs | External data and RAG | LiveKit docsnumerous-whale-53652
12/24/2025, 7:55 PMtall-airline-16756
12/24/2025, 7:56 PMchat_ctx and why your current reconstruction isn’t injecting history.
Quick answer: chat_ctx must be a ChatContext containing properly typed messages (not plain dynamic objects). Each message should have a role and content (content is a list). Use the ChatContext builder functions (e.g., add_message) or create proper ChatMessage objects instead of using type(...) to mimic objects.
Minimal JSON shape (conceptual):
{
"messages": [
{
"type": "message",
"role": "user",
"content": [
"Hello, how are you?"
]
},
{
"type": "message",
"role": "assistant",
"content": [
"I am fine, thanks."
]
}
]
}
Correct Python approach (recommended):
from livekit.agents.llm import ChatContext
# rebuild chat context from stored history_result
saved_ctx = ChatContext()
for item in history_result["history"]["items"]:
if item.get("type") == "message":
# content must be a list[str] or list[Content] objects
saved_ctx.add_message(role=item["role"], content=item["content"])
# handle function/tool calls here if present
await main_agent.update_chat_ctx(saved_ctx)
Key checks if it still doesn't work:
• Ensure each message's content is a list (e.g., ["text"]).
• Verify item["type"] is "message" (or handle other types explicitly).
• After update_chat_ctx, inspect main_agent.chat_ctx.messages to confirm messages were added.
• Make sure any on_enter or startup hooks don’t overwrite the injected context after you update it.
If you want, tell me:
• which SDK/language you’re using (Python or JS), and
• an example of one saved item from history_result["history"]["items"] (redact private text) —
and I’ll give a precise snippet that matches that shape.
Sources: Pipeline nodes and hooks | LiveKit docs | External data and RAG | LiveKit docs