4  Session Management

Sessions track conversation history across multiple turns.

Note

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.dialogs

Returns 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 messages

4.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"
TipPart I Complete!
cd code/v0.1

You now have a complete minimal agent framework:

  • @tool decorator — Turn functions into tools
  • Agent — Configuration container
  • Runner — Execution engine
  • Session — Conversation memory

~300 lines of code total. Next: multi-agent systems!