polite-oil-10264
12/24/2025, 6:40 PMtall-airline-16756
12/24/2025, 6:40 PMtall-airline-16756
12/24/2025, 6:40 PMsession.history or session.chat_ctx) to persistent storage when the agent disconnects, and reload it when the agent reconnects.
How to implement this (high level):
• Before disconnect (or during shutdown), serialize and save the session state (e.g., session.chat_ctx or session.history) to a database or file. You can use a shutdown callback such as ctx.add_shutdown_callback() to trigger the save.
• On reconnect, load the saved state and pass it into the agent via the chat_ctx parameter when constructing the Agent (or restore into the agent's session object).
• Optionally store any custom per-session state in userdata so you can restore application-specific context alongside the chat history.
If you’d like, tell me:
• which language/runtime you’re using, and
• whether you want an example for saving/restoring session.chat_ctx to a specific database (Postgres, Redis, etc.),
and I’ll provide a concrete code snippet for your environment.
Sources: Agents and handoffs | LiveKit docs | External data and RAG | LiveKit docspolite-oil-10264
12/24/2025, 7:54 PMtall-airline-16756
12/24/2025, 7:54 PMsession.chat_ctx when the agent is about to disconnect,
• restores it when the agent reconnects,
• demonstrates pushing a new chat message so the agent resumes where it left off.
This example uses an async in-memory “store” (replace with Redis/Postgres in production). Adjust the storage calls to your DB.
import asyncio
import json
from typing import Any, Dict
# --- Replace these with your actual LiveKit/agent imports ---
# from livekit_agent import Agent, AgentSession, ctx
# ----------------------------------------------------------------
# Simple async key-value store (replace with Redis/Postgres)
_STORE: Dict[str, str] = {}
async def save_to_store(key: str, value: Dict[str, Any]):
_STORE[key] = json.dumps(value)
async def load_from_store(key: str) -> Dict[str, Any] | None:
raw = _STORE.get(key)
return json.loads(raw) if raw else None
# --- Example agent lifecycle handlers ---
async def on_agent_start(room_name: str):
"""
Called when agent process starts / reconnects.
Restore chat_ctx if present and create the Agent with it.
"""
stored = await load_from_store(f"chatctx:{room_name}")
if stored:
# Construct agent with restored chat context
agent = Agent(chat_ctx=stored) # replace with your Agent class
else:
agent = Agent() # fresh agent
# Hook to save context on shutdown/disconnect
async def save_context():
# session referenced from agent; session.chat_ctx holds context/history
ctx_to_save = agent.session.chat_ctx
await save_to_store(f"chatctx:{room_name}", ctx_to_save)
# Register your shutdown callback with your framework/context
ctx.add_shutdown_callback(save_context)
return agent
async def push_user_message(room_name: str, user_id: str, text: str):
"""
Push a new user chat message into the agent's session so it continues
from previous context and processes the new message.
"""
# Load stored chat_ctx and ensure agent has it (if agent not running, you can
# create a transient Agent instance with restored chat_ctx to process the message)
stored = await load_from_store(f"chatctx:{room_name}")
if stored:
agent = Agent(chat_ctx=stored)
else:
agent = Agent()
# Add the incoming user message into the session history/chat context.
# How to add depends on your AgentSession API; example:
agent.session.add_user_message(user_id=user_id, text=text)
# Now run the agent's processing loop / trigger a response handler
# This might be a single-step call or an async run depending on your API.
await agent.process_once() # replace with actual processing call
# After processing, save updated chat_ctx back to store
await save_to_store(f"chatctx:{room_name}", agent.session.chat_ctx)
# Return agent response (example)
return agent.session.last_system_message()
# --- Usage example ---
async def example_flow():
room = "support-room-123"
# Agent process starts (restore context if exists)
agent = await on_agent_start(room)
# Simulate agent disconnect: shutdown callback will fire and save context
await ctx.shutdown() # this triggers save_context callback in on_agent_start
# Later: new user message arrives while agent reconnects
response = await push_user_message(room, user_id="user_1", text="I still need help with billing.")
print("Agent responded:", response)
# Run example (in real app, these are event-driven)
# asyncio.run(example_flow())
Notes and places to adapt:
• Persist with Redis or Postgres rather than the in-memory _STORE.
• Use the real Agent constructor and session APIs: agent.session.chat_ctx, agent.session.add_user_message(...), and whatever method triggers the agent to process messages in your codebase (process_once() is a placeholder).
• Ensure ctx.add_shutdown_callback(save_context) runs in the agent process to capture context before disconnect.
• If your app uses userdata, save/restore it the same way as chat_ctx.
If you tell me which storage you want (Redis or Postgres) and which exact Agent session methods you have available, I’ll produce a complete ready-to-run snippet tailored to those APIs.