> For the complete documentation index, see [llms.txt](/llms.txt).
> A full single-fetch corpus is available at [llms-full.txt](/llms-full.txt).
---
last_verified: 2026-05-13
title: Sessions
description: Conversation containers with scoped state and multi-agent coordination
category: Python SDK
---

Sessions are conversation containers built on the Entity primitive. They manage multi-turn interactions between users and AI agents, providing structured state management, message history, and audit trails.

## Key Characteristics

- **Built on Entity** - Inherits durability and consistency from Entity
- **Scoped State** - Organize state with session/user/app/temp scopes
- **Message History** - Automatic conversation tracking with metadata
- **Multi-Agent Ready** - Share context across multiple agents
- **Audit Trail** - Complete history of interactions for compliance
- **Flexible Retention** - Configurable data retention policies

## Basic Usage

### Creating a Session

```python
from agnt5 import Session

# Create session with user context
session = Session(
    id="conv-2024-001",
    app_name="research_assistant",
    user_id="user-123",
    metadata={"project": "ai-safety-research"}
)
```

### Managing Messages

<Tabs defaultValue="send">
  <TabsList>
    <TabsTrigger value="send">Send Messages</TabsTrigger>
    <TabsTrigger value="history">Get History</TabsTrigger>
  </TabsList>

  <TabsContent value="send">
    ```python
    # Append messages to conversation history
    await session.send_message({
        "role": "user",
        "content": "What are the key challenges in AI alignment?"
    })

    await session.send_message({
        "role": "assistant",
        "content": "The main challenges include value learning and robustness."
    })
    ```
  </TabsContent>

  <TabsContent value="history">
    ```python
    # Get last 10 messages
    messages = await session.history(limit=10)

    # Get all messages
    all_messages = await session.history()

    # Filter by role
    user_messages = [m for m in all_messages if m["role"] == "user"]
    ```
  </TabsContent>
</Tabs>

### Scoped State Management

Session state uses four scopes for different persistence levels:

```python
# Session scope - conversation-specific (default)
session.set_state("shopping_cart", ["item1", "item2"])
session.set_state("current_step", "checkout")

# User scope - persists across all user sessions
session.set_state("language", "English", scope="user")
session.set_state("timezone", "America/Los_Angeles", scope="user")

# App scope - application-wide global state
session.set_state("api_version", "v2", scope="app")
session.set_state("feature_flags", {"new_ui": True}, scope="app")

# Temp scope - temporary invocation-specific
session.set_state("processing_step", "validation", scope="temp")
```

### Integration with Agents

```python
from agnt5 import Agent, Session, LanguageModel

# Create session
session = Session(
    id="support-ticket-456",
    user_id="customer-789",
    metadata={"ticket_type": "billing"}
)

# Create agent with session
lm = LanguageModel()
agent = Agent(
    name="support_agent",
    model=lm,
    instructions="You are a helpful customer support agent.",
    tools=[search_kb_tool, create_ticket_tool],
    session=session
)

# Agent automatically uses session for context
result = await agent.run("I need help with my recent charge")

# Session maintains full conversation history
history = await session.history()
```

## Common Patterns

### Multi-Agent Coordination

Share context across multiple specialized agents:

```python
# Create shared session
session = Session(
    id="research-workflow-001",
    user_id="researcher-123",
    metadata={"project": "quantum-computing-review"}
)

# Set shared context
session.set_state("research_topic", "quantum error correction")
session.set_state("target_depth", "comprehensive")

# Multiple specialized agents work together
literature_agent = Agent(
    name="literature_reviewer",
    session=session,
    tools=[paper_search]
)

code_agent = Agent(
    name="code_analyzer",
    session=session,
    tools=[github_search]
)

synthesis_agent = Agent(
    name="synthesizer",
    session=session,
    tools=[document_tool]
)

# Execute research pipeline
papers = await literature_agent.run("Find recent papers")
implementations = await code_agent.run("Find implementations")
report = await synthesis_agent.run("Synthesize findings")

# All agents see shared context and each other's work
full_history = await session.history()
```

### Agent Handoff Pattern

Seamlessly transfer conversations between specialized agents:

```python
session = Session(id="customer-inquiry-789", user_id="customer-456")

# Coordinator routes to appropriate specialist
coordinator = Agent(
    name="router",
    session=session,
    tools=[classification_tool]
)
routing = await coordinator.run("How do I upgrade my subscription?")

if routing.category == "billing":
    # Billing agent gets full conversation context
    billing_agent = Agent(
        name="billing_specialist",
        session=session,
        tools=[billing_tools]
    )
    result = await billing_agent.run("Continue from coordinator's analysis")
    # billing_agent sees all previous messages

elif routing.category == "technical":
    tech_agent = Agent(
        name="tech_support",
        session=session,
        tools=[tech_tools]
    )
    result = await tech_agent.run("Handle technical inquiry")
```

### Session State vs Memory

<Tabs defaultValue="comparison">
  <TabsList>
    <TabsTrigger value="comparison">Comparison</TabsTrigger>
    <TabsTrigger value="example">Example</TabsTrigger>
  </TabsList>

  <TabsContent value="comparison">
    | Aspect | Session State | Memory |
    | --- | --- | --- |
    | Scope | Conversation-specific | Cross-conversation |
    | Lifetime | Cleared after session | Persists indefinitely |
    | Use Case | Current context | Long-term knowledge |
    | Example | Current task, cart items | User preferences, history |
  </TabsContent>

  <TabsContent value="example">
    ```python
    from agnt5 import Session, Memory

    session = Session(id="consultation-123", user_id="user-456")
    memory = Memory(service=VectorMemoryService())

    # Session State - SHORT-TERM, conversation-specific
    session.set_state("current_diagnosis", "initial assessment")
    session.set_state("symptoms_discussed", ["headache", "fatigue"])

    # Memory - LONG-TERM, cross-conversation knowledge
    await memory.store("patient_history", "Chronic migraines, diagnosed 2020")
    await memory.store("medication_allergies", "Penicillin, Sulfa drugs")

    # Session state clears after conversation
    # Memory persists indefinitely across all sessions
    ```
  </TabsContent>
</Tabs>

### Session Export and Audit

```python
# Create session with audit metadata
session = Session(
    id="compliance-audit-001",
    user_id="analyst-789",
    metadata={
        "regulation": "SOC2",
        "audit_period": "Q4-2024",
        "auditor": "external-firm"
    },
    retention={"ttl_days": 730}  # 2 years
)

# Conduct conversation with full tracking
agent = Agent(name="data_analyst", session=session)
await agent.run("Analyze user access patterns")

# Export session for compliance review
jsonl_export = await session.export(format="jsonl")
# Each line contains: timestamp, role, message, metadata, tool_calls

# Query specific events
recent_events = await session.events(since="2024-01-01", limit=100)

# Prune old messages while keeping metadata
await session.prune(strategy="keep_last_50")
```

### Long-Running Sessions with Pruning

```python
# Create session with automatic pruning
session = Session(
    id="long-conversation-456",
    user_id="user-123",
    metadata={"type": "ongoing_project"}
)

# After many interactions, prune intelligently
await session.prune(strategy="keep_important")  # Uses LLM
await session.prune(strategy="sliding_window", window_size=100)
await session.prune(strategy="summarize_old", threshold=50)

# Session remains performant even with thousands of messages
```

## Configuration

### Session Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| `id` | `str` | Unique session identifier |
| `app_name` | `str \| None` | Application name |
| `user_id` | `str \| None` | User identifier |
| `metadata` | `dict \| None` | Session metadata |
| `retention` | `dict \| None` | Retention policy configuration |

### Retention Policies

Configure data retention:

<Tabs defaultValue="compliance">
  <TabsList>
    <TabsTrigger value="compliance">Compliance</TabsTrigger>
    <TabsTrigger value="performance">Performance</TabsTrigger>
  </TabsList>

  <TabsContent value="compliance">
    ```python
    # For compliance-sensitive applications
    session = Session(
        id="healthcare-session",
        retention={
            "ttl_days": 2555,  # 7 years (HIPAA)
            "auto_prune": False,  # Manual control
            "immutable": True  # Prevent deletion
        }
    )
    ```
  </TabsContent>

  <TabsContent value="performance">
    ```python
    # For performance-sensitive applications
    session = Session(
        id="chat-session",
        retention={
            "ttl_days": 30,  # 30-day retention
            "auto_prune": True,  # Automatic cleanup
            "prune_strategy": "sliding_window",
            "max_messages": 1000
        }
    )
    ```
  </TabsContent>
</Tabs>

## Best Practices

### 1. Use Appropriate State Scopes

Match state scope to persistence requirements:

```python
# ✓ Session scope - conversation-specific
session.set_state("current_page", 3)
session.set_state("draft_document", content)

# ✓ User scope - user preferences
session.set_state("theme", "dark", scope="user")
session.set_state("notification_preference", "email", scope="user")

# ✓ App scope - global configuration
session.set_state("rate_limit", 1000, scope="app")
session.set_state("feature_flags", flags, scope="app")

# ✓ Temp scope - transient data
session.set_state("validation_step", "in_progress", scope="temp")
```

### 2. Design for Multi-Agent Coordination

Structure session state for agent collaboration:

```python
# Good - Clear coordination structure
session.set_state("workflow_stage", "research")
session.set_state("agent_outputs", {
    "researcher": {"status": "completed", "findings": [...]},
    "analyzer": {"status": "in_progress"},
    "writer": {"status": "pending"}
})

# Agents can check dependencies
current_stage = session.get_state("workflow_stage")
researcher_output = session.get_state("agent_outputs")["researcher"]
```

### 3. Implement Retention Strategies

Manage session lifecycle appropriately:

```python
# For regulated industries
session = Session(
    id="medical-consultation",
    retention={
        "ttl_days": 2555,  # Legal requirement
        "immutable": True
    }
)

# For ephemeral conversations
session = Session(
    id="temp-chat",
    retention={
        "ttl_days": 1,  # Delete after 1 day
        "auto_prune": True
    }
)
```

## Entity vs Session

| Aspect | Entity | Session |
| --- | --- | --- |
| Purpose | General stateful primitive | Conversation-specific |
| State Structure | Flexible key-value | Opinionated message + state |
| API | Low-level (get/set/delete) | High-level (send_message/history) |
| Scoping | Manual | Built-in (session/user/app/temp) |
| Audit | Manual event tracking | Automatic conversation log |
| Use Case | Custom stateful components | AI agent conversations |

**When to use Entity:**
- Building custom stateful patterns
- Need complete control over state structure
- Non-conversation workloads

**When to use Session:**
- AI agent conversations
- Multi-agent coordination needed
- Audit trails required
- Standard conversation patterns

## Next Steps

- [Entity](entity) - Underlying primitive for Session
- [Agent](agent) - Agents use Sessions for context
- [Memory](memory) - Long-term storage vs Session state
- [Context API](context) - Session context operations
