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 ofBaseEvent
objects 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
BaseSessionService
that stores sessions in a Python dictionary in memory. Note: Sessions are lost when the server restarts.
/invoke
Endpoint)
Server Integration (The FastAPI server (karo.serving.server
) integrates session management into the /invoke
endpoint:
- Request: The
InvokeRequest
model accepts an optionalsession_id
. - Authentication: The endpoint requires JWT authentication. The user ID (
sub
claim) from the token is used to associate the session with the user. - Session Handling:
- If a
session_id
is 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_id
is 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'sevents
list.
- 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
state
dictionary 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
state
dictionary and returns it, the server should updatesession.state
). - The session is saved using
session_service.update_session()
.
- Response: The
InvokeResponse
includes thesession_id
(either the one provided or the newly generated one) along with the agent's output or error.
BaseAgent
)
Agent Integration (The BaseAgent
(karo.core.base_agent
) has been modified:
- It no longer manages conversation history internally (
self.conversation_history
andmax_history_messages
config are removed). - The
run
method now accepts optionalhistory: List[Dict]
andstate: Dict
arguments. - The
_create_prompt_with_history
method uses thehistory
argument passed torun
when constructing the prompt for the LLM. - (Future Enhancement: The agent could be designed to read from and potentially modify the passed
state
dictionary).
Usage
To maintain a conversation across multiple API calls:
- Make the first POST request to
/invoke
without asession_id
. - Extract the
session_id
from the response. - For all subsequent requests in the same conversation, include the received
session_id
in the JSON body of your POST request to/invoke
.
Limitations (In-Memory Implementation)
- Persistence: The
InMemorySessionService
loses 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).