Session Management Guide
Explains how Karo manages conversation history and state using sessions.
Session Management in Karo
Karo includes a session management system to maintain conversation history and state across multiple interactions with an agent, typically via the FastAPI server.
Core Concepts
- BaseSession: A Pydantic model representing a single conversation session. It stores:
id: Unique session identifier.user_id: Identifier for the user associated with the session.app_name: Identifier for the agent/application.state: A dictionary for storing arbitrary session-specific data.events: A list ofBaseEventobjects representing the conversation turns.created_at,last_update_time: Timestamps.
- BaseEvent: A Pydantic model representing a single turn in the conversation (e.g., a user message or an assistant response). It stores:
id: Unique event identifier.role: "user" or "assistant".content: The text content of the message.timestamp: When the event occurred.
- BaseSessionService: An abstract base class defining the interface for session storage and retrieval. Key methods include
create_session,get_session,update_session,delete_session,list_sessions. - InMemorySessionService: An implementation of
BaseSessionServicethat stores sessions in a Python dictionary in memory. Note: Sessions are lost when the server restarts.
Server Integration (/invoke Endpoint)
The FastAPI server (karo.serving.server) integrates session management into the /invoke endpoint:
- Request: The
InvokeRequestmodel accepts an optionalsession_id. - Authentication: The endpoint requires JWT authentication. The user ID (
subclaim) from the token is used to associate the session with the user. - Session Handling:
- If a
session_idis provided in the request:- The server attempts to retrieve the session using
session_service.get_session(). - It verifies that the retrieved session belongs to the authenticated user and the expected application.
- If the session is not found or doesn't match, a warning is logged, and a new session is created.
- The server attempts to retrieve the session using
- If no
session_idis provided, or if retrieval failed, a new session is created usingsession_service.create_session().
- If a
- Event Recording:
- The incoming user message (
chat_message) is added as aBaseEvent(role="user") to the session'seventslist.
- The incoming user message (
- Agent Execution:
- The recent conversation history (as a list of dictionaries like
{"role": "user", "content": "..."}) is extracted fromsession.events. - The current session
statedictionary is retrieved. - The
agent.run()method is called, passing theinput_data,history, andstate.
- The recent conversation history (as a list of dictionaries like
- Response Handling:
- The agent's response (or error) is processed.
- An appropriate
BaseEvent(role="assistant") is created with the response content (or error message). - This assistant event is added to
session.events. - (Future Enhancement: If the agent modifies the
statedictionary and returns it, the server should updatesession.state). - The session is saved using
session_service.update_session().
- Response: The
InvokeResponseincludes thesession_id(either the one provided or the newly generated one) along with the agent's output or error.
Agent Integration (BaseAgent)
The BaseAgent (karo.core.base_agent) has been modified:
- It no longer manages conversation history internally (
self.conversation_historyandmax_history_messagesconfig are removed). - The
runmethod now accepts optionalhistory: List[Dict]andstate: Dictarguments. - The
_create_prompt_with_historymethod uses thehistoryargument passed torunwhen constructing the prompt for the LLM. - (Future Enhancement: The agent could be designed to read from and potentially modify the passed
statedictionary).
Usage
To maintain a conversation across multiple API calls:
- Make the first POST request to
/invokewithout asession_id. - Extract the
session_idfrom the response. - For all subsequent requests in the same conversation, include the received
session_idin the JSON body of your POST request to/invoke.
Limitations (In-Memory Implementation)
- Persistence: The
InMemorySessionServiceloses all session data when the server process stops or restarts. - Scalability: Storing all sessions in a single server's memory does not scale horizontally across multiple server instances.
For persistent and scalable session management, a different implementation of BaseSessionService would be required (e.g., using a database like Redis, PostgreSQL, or Firestore).