4 Session Management
Sessions track conversation history across multiple turns.
Code Reference: code/v0.1/src/agentsilex/session.py
4.1 Why Sessions?
Without sessions, every request starts fresh. The agent has no memory of previous interactions:
runner.run("My name is Alice")
runner.run("What's my name?") # Agent doesn't know!With sessions, context persists across turns.
4.2 The Session Class
The implementation is minimal (session.py):
from typing import List
class Session:
def __init__(self):
self.dialogs = []
def get_dialogs(self) -> List[dict]:
return self.dialogs
def add_new_messages(self, messages):
self.dialogs.extend(messages)
def pop_turn(self):
pass # Placeholder for future
def clean(self):
self.dialogs = []That’s the entire Session class — about 15 lines.
4.3 Core Methods
4.3.1 __init__
def __init__(self):
self.dialogs = []Just a list. No fancy data structures.
4.3.2 get_dialogs
def get_dialogs(self) -> List[dict]:
return self.dialogsReturns the raw dialog history. The Runner passes this to the LLM.
4.3.3 add_new_messages
def add_new_messages(self, messages):
self.dialogs.extend(messages)Appends messages to history. Handles both single messages and lists.
4.3.4 clean
def clean(self):
self.dialogs = []Resets the session. Start fresh.
4.4 Message Format
Sessions store messages in OpenAI’s format:
# User message
{"role": "user", "content": "What's the weather?"}
# Assistant message
{"role": "assistant", "content": "Let me check..."}
# Assistant with tool call
{
"role": "assistant",
"content": None,
"tool_calls": [
{
"id": "call_abc123",
"function": {
"name": "get_weather",
"arguments": '{"city": "Tokyo"}'
}
}
]
}
# Tool result
{
"role": "tool",
"tool_call_id": "call_abc123",
"content": "72°F, sunny"
}LiteLLM handles format conversion for different providers.
4.5 Multi-Turn Conversation
from agentsilex import Agent, Runner, Session, tool
@tool
def remember(key: str, value: str) -> str:
"""Remember something."""
return f"I'll remember that {key} is {value}"
agent = Agent(
name="memory_bot",
model="gpt-4o",
instructions="You are helpful. Remember things when asked.",
tools=[remember],
)
# Same session across turns
session = Session()
runner = Runner(session)
# Turn 1
runner.run(agent, "My favorite color is blue")
# Turn 2 - agent sees previous history
runner.run(agent, "What's my favorite color?")
# → "Your favorite color is blue!"
# Check what's in the session
print(len(session.dialogs)) # Multiple messages4.6 What’s Stored
After a typical interaction:
session.dialogs = [
# Turn 1
{"role": "user", "content": "What's the weather in Tokyo?"},
{"role": "assistant", "tool_calls": [...]},
{"role": "tool", "tool_call_id": "...", "content": "72°F, sunny"},
{"role": "assistant", "content": "The weather in Tokyo is 72°F and sunny!"},
# Turn 2
{"role": "user", "content": "How about Osaka?"},
{"role": "assistant", "tool_calls": [...]},
{"role": "tool", "tool_call_id": "...", "content": "68°F, cloudy"},
{"role": "assistant", "content": "Osaka is 68°F and cloudy."},
]The LLM sees this entire history on each call.
4.7 Why So Simple?
The Session is intentionally minimal:
| What we don’t have | Why |
|---|---|
| Automatic summarization | You implement it |
| Token counting | You handle limits |
| Message pruning | You decide the strategy |
| Persistence | Use your own storage |
This lets you:
- Serialize sessions however you want
- Implement custom memory strategies
- Integrate with your existing infrastructure
We’ll add hooks for memory management in Chapter 10.
4.8 Complete v0.1 Example
from agentsilex import Agent, Runner, Session, tool
@tool
def add_numbers(a: int, b: int) -> int:
"""Add two numbers together."""
return a + b
@tool
def multiply_numbers(a: int, b: int) -> int:
"""Multiply two numbers together."""
return a * b
agent = Agent(
name="calculator",
model="gpt-4o",
instructions="You are a calculator. Use tools for math.",
tools=[add_numbers, multiply_numbers],
)
session = Session()
runner = Runner(session)
# Multi-step calculation
result = runner.run(agent, "What is (5 + 3) * 2?")
print(result.final_output)
# The agent will:
# 1. Call add_numbers(5, 3) → 8
# 2. Call multiply_numbers(8, 2) → 16
# 3. Return "The result is 16"cd code/v0.1You now have a complete minimal agent framework:
@tooldecorator — Turn functions into tools- Agent — Configuration container
- Runner — Execution engine
- Session — Conversation memory
~300 lines of code total. Next: multi-agent systems!