future-glass-56154
09/18/2025, 7:56 PMreturn TechnicalSupportAgent(chat_ctx=self.session.chat_ctx) . It then says
The complete conversation history for the session is always available in session.history.
Upon looking further I find the history property of Agent Session to be defined as
@property
def history(self) -> llm.ChatContext:
return self._chat_ctx
How are these different? Is the context of an agent empty when it enters the room after a handoff? How can I check?tall-airline-16756
09/18/2025, 7:56 PMtall-airline-16756
09/18/2025, 7:57 PMsession.chat_ctx and session.history for you:
• session.chat_ctx: This is the chat context that gets passed explicitly during an agent handoff. It’s what allows the new agent to pick up right where the previous one left off. For instance, when you’re transferring to a new agent, you can pass it like this: return TechnicalSupportAgent(chat_ctx=self.session.chat_ctx).
• session.history: This gives you access to the full conversation history for the session. It’s always there and can be really handy if you want to customize how you manage context or look back at previous interactions.
Just so you know, by default, an agent’s context starts off empty unless you explicitly pass the chat_ctx during the handoff. If you want to check whether the context is empty, you can take a look at session.chat_ctx or session.history right after the handoff.
If you’d like me to walk you through some examples or explain anything further, please don’t hesitate to ask—I’m here to help!
Sources: Workflows | LiveKit Docs | Workflows | LiveKit Docs | complex-agents/personal_shopper/personal_shopper.py | livekit-agents/livekit/agents/voice/agent.pyfuture-glass-56154
09/18/2025, 8:04 PMtall-airline-16756
09/18/2025, 8:04 PMChatContext, you make sure the LLM knows about the tool execution results and can respond appropriately with that new information in mind.
Here’s a simple way to do it:
• After you run a tool, gather its output (which we call FunctionCallOutput).
• Then, copy the current chat context and add those tool outputs to it. For example, in Python:
chat_ctx = self._rt_session.chat_ctx.copy()
chat_ctx.items.extend(new_fnc_outputs)
try:
await self._rt_session.update_chat_ctx(chat_ctx)
except llm.RealtimeError as e:
logger.warning("failed to update chat context before generating the function calls results", extra={"error": str(e)})
• If you’re working with TypeScript/JavaScript, the steps are quite similar:
const chatCtx = this.realtimeSession.chatCtx.copy();
chatCtx.items.push(...functionToolsExecutedEvent.functionCallOutputs);
try {
await this.realtimeSession.updateChatCtx(chatCtx);
} catch (error) {
this.logger.warn(
{ error },
'failed to update chat context before generating the function calls results',
);
}
Once you update the chat context like this, the LLM will include those tool outputs when it generates its response. If you have any questions or want me to walk you through this further, just let me know—I’m here to help!
Sources: livekit-agents/livekit/agents/llm/_provider_format/utils.py | agents/src/voice/generation.ts | LLM Integrations | livekit/livekit_composite | DeepWiki