> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/block/goose/llms.txt
> Use this file to discover all available pages before exploring further.

# Sessions

> Understanding session management, state persistence, and conversation history in Goose

Sessions in Goose represent individual conversations with the AI agent. Each session maintains its own state, history, configuration, and context, enabling you to work on multiple tasks independently and resume work later.

## What is a Session?

A session encapsulates:

* **Conversation history**: All messages exchanged with the agent
* **Working directory**: Where the agent operates on your filesystem
* **Extension state**: Which tools are enabled and their data
* **Configuration**: Model, provider, and recipe being used
* **Metadata**: Creation time, token usage, session name

```rust theme={null}
// From crates/goose/src/session/session_manager.rs
pub struct Session {
    pub id: String,                           // Unique identifier
    pub working_dir: PathBuf,                 // Agent's workspace
    pub name: String,                         // Human-readable name
    pub session_type: SessionType,            // User/SubAgent/Scheduled/etc
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
    pub extension_data: ExtensionData,        // Extension state
    pub conversation: Option<Conversation>,   // Message history
    pub recipe: Option<Recipe>,               // Active recipe
    pub provider_name: Option<String>,        // AI provider
    pub model_config: Option<ModelConfig>,    // Model settings
    pub total_tokens: Option<i32>,            // Token counts
    // ...
}
```

## Session Types

Goose supports different session types for different purposes:

```rust theme={null}
pub enum SessionType {
    User,        // Regular user sessions
    SubAgent,    // Subagent task execution
    Scheduled,   // Scheduled/automated tasks
    Hidden,      // Internal/system sessions
    Terminal,    // Terminal integration sessions
    Gateway,     // Gateway/proxy sessions
}
```

### User Sessions

Standard interactive sessions:

```bash theme={null}
# Create a new session
goose session create --name "Refactor auth module"

# Resume existing session
goose session resume abc123

# List sessions
goose session list
```

### SubAgent Sessions

Created automatically when spawning subagents:

```rust theme={null}
// Subagent gets its own isolated session
let subagent_session = session_manager.create_session(
    SessionType::SubAgent,
    recipe,
    parent_session_id,
).await?;
```

Subagent sessions are:

* Isolated from parent session
* Have their own conversation history
* Can have different extensions/settings
* Automatically cleaned up when complete

## Session Lifecycle

```mermaid theme={null}
stateDiagram-v2
    [*] --> Created: create_session()
    Created --> Active: first message
    Active --> Active: exchange messages
    Active --> Paused: user disconnects
    Paused --> Active: resume session
    Active --> Archived: archive_session()
    Active --> Deleted: delete_session()
    Archived --> Active: restore_session()
    Archived --> Deleted: delete_session()
    Deleted --> [*]
```

### Creating Sessions

```rust theme={null}
// Via SessionManager
let session = session_manager.create_session(
    SessionType::User,
    working_dir,
    name,
).await?;

// With recipe
let session = session_manager.create_session_with_recipe(
    SessionType::User,
    recipe,
    recipe_values,  // Parameter values
).await?;
```

### Updating Sessions

Goose uses a builder pattern for updates:

```rust theme={null}
session_manager
    .update_session(session_id)
    .name("New session name")
    .extension_data(updated_data)
    .total_tokens(Some(1500))
    .apply()
    .await?;
```

### Querying Sessions

```rust theme={null}
// Get session by ID
let session = session_manager.get_session(&session_id).await?;

// List all user sessions
let sessions = session_manager.list_sessions(
    SessionType::User,
    None,  // limit
    None,  // offset
).await?;

// Search sessions
let sessions = session_manager.search_sessions("authentication").await?;
```

## Session Storage

Sessions are persisted to SQLite:

```
~/.config/goose/
└── sessions/
    ├── sessions.db          # SQLite database
    └── [session-id]/
        ├── conversation.json  # Message history
        └── metadata.json      # Session metadata
```

### Database Schema

```sql theme={null}
CREATE TABLE sessions (
    id TEXT PRIMARY KEY,
    working_dir TEXT NOT NULL,
    name TEXT NOT NULL,
    user_set_name INTEGER DEFAULT 0,
    session_type TEXT DEFAULT 'user',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    total_tokens INTEGER,
    input_tokens INTEGER,
    output_tokens INTEGER,
    schedule_id TEXT,
    recipe TEXT,  -- JSON
    user_recipe_values TEXT,  -- JSON
    provider_name TEXT,
    model_config TEXT  -- JSON
);

CREATE TABLE messages (
    id TEXT PRIMARY KEY,
    session_id TEXT NOT NULL,
    role TEXT NOT NULL,  -- 'user' or 'assistant'
    content TEXT NOT NULL,  -- JSON
    timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (session_id) REFERENCES sessions(id)
);
```

## Conversation Management

Each session maintains a conversation object:

```rust theme={null}
pub struct Conversation {
    messages: Vec<Message>,
}

impl Conversation {
    // Add a user message
    pub fn add_user_message(&mut self, text: String) {
        self.messages.push(Message::user(text));
    }
    
    // Add assistant response
    pub fn add_assistant_message(&mut self, text: String) {
        self.messages.push(Message::assistant(text));
    }
    
    // Add tool result
    pub fn add_tool_result(&mut self, tool_id: String, result: ToolResult) {
        self.messages.push(Message::tool_result(tool_id, result));
    }
    
    // Get all messages
    pub fn messages(&self) -> &[Message] {
        &self.messages
    }
}
```

### Message Types

```rust theme={null}
pub enum MessageContent {
    Text(TextContent),           // Plain text
    ToolRequest(ToolRequest),    // Tool invocation from AI
    ToolResponse(ToolResponse),  // Tool result
    Image(ImageContent),         // Image data (vision models)
    Thinking(ThinkingContent),   // Model reasoning (if available)
}

pub struct Message {
    pub role: Role,              // User or Assistant
    pub content: Vec<MessageContent>,
    pub metadata: ProviderMetadata,  // Token counts, etc.
}
```

## Context Management

Goose automatically manages context to stay within model limits:

### Context Compaction

```rust theme={null}
// From crates/goose/src/context_mgmt/
const DEFAULT_COMPACTION_THRESHOLD: f64 = 0.75;

pub fn check_if_compaction_needed(
    messages: &[Message],
    context_limit: usize,
) -> bool {
    let token_count = count_tokens(messages);
    token_count > (context_limit as f64 * COMPACTION_THRESHOLD) as usize
}

pub fn compact_messages(
    messages: Vec<Message>,
    context_limit: usize,
) -> Vec<Message> {
    // Strategy:
    // 1. Keep system prompt
    // 2. Keep recent messages (last N turns)
    // 3. Summarize middle section
    // 4. Preserve important context (errors, key decisions)
    
    let recent_threshold = 10;  // Keep last 10 message pairs
    let mut compacted = Vec::new();
    
    // System prompt (always keep)
    if let Some(system_msg) = messages.first() {
        compacted.push(system_msg.clone());
    }
    
    // Middle section (summarize)
    if messages.len() > recent_threshold {
        let summary = summarize_messages(
            &messages[1..messages.len() - recent_threshold]
        );
        compacted.push(Message::assistant(summary));
    }
    
    // Recent messages (keep all)
    let recent_start = messages.len().saturating_sub(recent_threshold);
    compacted.extend_from_slice(&messages[recent_start..]);
    
    compacted
}
```

Compaction is triggered automatically:

```rust theme={null}
// Before sending to provider
if check_if_compaction_needed(&conversation.messages, model_context_limit) {
    // Show user what's happening
    yield AgentEvent::Thinking("Compacting conversation history...");
    
    conversation.messages = compact_messages(
        conversation.messages,
        model_context_limit,
    );
}
```

## Extension Data

Sessions store extension-specific data:

```rust theme={null}
pub struct ExtensionData {
    enabled_extensions: EnabledExtensionsState,  // Which extensions are active
    extension_state: HashMap<String, Value>,     // Extension-specific data
}
```

Extensions can persist state across messages:

```python theme={null}
# In an MCP server
@server.tool()
async def save_preference(key: str, value: str) -> list[TextContent]:
    # Store in session extension data
    session_state[key] = value
    return [TextContent(type="text", text=f"Saved {key} = {value}")]

@server.tool()
async def get_preference(key: str) -> list[TextContent]:
    # Retrieve from session extension data
    value = session_state.get(key, "not set")
    return [TextContent(type="text", text=f"{key} = {value}")]
```

## Session Naming

Goose automatically generates descriptive session names:

```rust theme={null}
// After first few messages, use AI to generate name
if conversation.messages.len() == MSG_COUNT_FOR_SESSION_NAME_GENERATION {
    if !session.user_set_name {
        let name = provider.generate_session_name(
            &conversation.messages
        ).await?;
        
        session_manager
            .update_session(&session.id)
            .name(name)
            .apply()
            .await?;
    }
}
```

The AI analyzes the conversation and suggests names like:

* "Refactoring authentication module"
* "Debugging WebSocket connection issues"
* "Setting up CI/CD pipeline"

Users can override:

```bash theme={null}
goose session rename abc123 "My custom name"
```

## Token Tracking

Sessions track token usage for cost estimation:

```rust theme={null}
pub struct Session {
    // Current session totals
    pub total_tokens: Option<i32>,
    pub input_tokens: Option<i32>,
    pub output_tokens: Option<i32>,
    
    // Accumulated across all time (even after compaction)
    pub accumulated_total_tokens: Option<i32>,
    pub accumulated_input_tokens: Option<i32>,
    pub accumulated_output_tokens: Option<i32>,
}
```

After each model call:

```rust theme={null}
let usage = provider_response.usage;

session_manager
    .update_session(&session.id)
    .total_tokens(Some(usage.total_tokens))
    .input_tokens(Some(usage.input_tokens))
    .output_tokens(Some(usage.output_tokens))
    .accumulated_total_tokens(Some(
        session.accumulated_total_tokens.unwrap_or(0) + usage.total_tokens
    ))
    .apply()
    .await?;
```

## Session Isolation

Sessions are isolated for security and organization:

### Working Directory Isolation

Each session operates in its own working directory:

```rust theme={null}
// Session A
Session {
    id: "abc123",
    working_dir: "/home/user/project-a",
    // ...
}

// Session B  
Session {
    id: "def456",
    working_dir: "/home/user/project-b",
    // ...
}
```

File operations are scoped to the working directory:

```python theme={null}
# Agent in session A can only access /home/user/project-a
read_file("config.yaml")  # Reads /home/user/project-a/config.yaml
```

### Extension Isolation

Extensions are session-specific:

```rust theme={null}
// Session A has developer + github extensions
// Session B has developer + database extensions
// They don't interfere with each other
```

### Conversation Isolation

Conversation history doesn't leak between sessions:

```rust theme={null}
// Session A's conversation
Session A: ["How do I authenticate?", "Use OAuth2..."]

// Session B's conversation (separate)
Session B: ["Deploy to production", "Running deployment..."]
```

## Multi-Session Workflows

You can work with multiple sessions simultaneously:

```bash theme={null}
# Terminal 1: Work on feature A
goose session resume feature-a

# Terminal 2: Work on bugfix B (different session)
goose session resume bugfix-b

# Terminal 3: Code review (yet another session)
goose run --recipe code-review.yaml
```

Each session maintains independent:

* Conversation history
* Working directory
* Extension state
* Model/provider settings

## Session Management API

### REST API

```typescript theme={null}
// Create session
POST /sessions
{
  "workingDirectory": "/path/to/project",
  "name": "My Task",
  "recipe": { /* recipe object */ },
  "recipeValues": { /* parameter values */ }
}

// List sessions
GET /sessions?type=user&limit=10&offset=0

// Get session
GET /sessions/{id}

// Update session
PATCH /sessions/{id}
{
  "name": "Updated Name"
}

// Delete session
DELETE /sessions/{id}

// Get session messages
GET /sessions/{id}/messages
```

### Agent Client Protocol (ACP)

```python theme={null}
# Create session
response = client.send_request("session/new", {
    "cwd": "/path/to/project",
    "recipe": recipe_config
})
session_id = response["result"]["sessionId"]

# Load existing session
response = client.send_request("session/load", {
    "sessionId": session_id
})

# Send prompt to session
response = client.send_request("session/prompt", {
    "sessionId": session_id,
    "prompt": [{"type": "text", "text": "Analyze the codebase"}]
})
```

## Session Insights

Get aggregated statistics:

```rust theme={null}
pub struct SessionInsights {
    pub total_sessions: usize,
    pub total_tokens: i64,
}

// Via API
GET /sessions/insights
{
  "total_sessions": 42,
  "total_tokens": 1_234_567
}
```

## Best Practices

<AccordionGroup>
  <Accordion title="Use descriptive session names">
    ```bash theme={null}
    # Good: Descriptive names
    goose session create --name "Implement OAuth2 authentication"
    goose session create --name "Debug production memory leak"

    # Bad: Vague names
    goose session create --name "Work"
    goose session create --name "Session 1"
    ```
  </Accordion>

  <Accordion title="Set appropriate working directories">
    ```bash theme={null}
    # Create session in project root
    cd /path/to/my-project
    goose session create

    # Agent has full context of project structure
    # Can access all files, run tests, etc.
    ```
  </Accordion>

  <Accordion title="Clean up old sessions">
    ```bash theme={null}
    # List sessions
    goose session list

    # Delete completed sessions
    goose session delete abc123

    # Or archive for later reference
    goose session archive abc123
    ```
  </Accordion>

  <Accordion title="Monitor token usage">
    ```bash theme={null}
    # Check token usage
    goose session info abc123

    # Session: Implement authentication
    # Total tokens: 12,543
    # Input tokens: 8,234
    # Output tokens: 4,309
    # Estimated cost: $0.15
    ```
  </Accordion>

  <Accordion title="Use session types appropriately">
    ```rust theme={null}
    // User sessions for interactive work
    SessionType::User

    // Subagent sessions for delegated tasks (auto-managed)
    SessionType::SubAgent

    // Scheduled sessions for automation
    SessionType::Scheduled
    ```
  </Accordion>
</AccordionGroup>

## Troubleshooting

### Session Not Found

```bash theme={null}
# List all sessions
goose session list --all

# Search by name
goose session list --search "authentication"
```

### Session State Corruption

```bash theme={null}
# Validate session
goose session validate abc123

# Repair if needed
goose session repair abc123
```

### High Token Usage

```bash theme={null}
# Enable aggressive compaction
goose session configure abc123 --compact-threshold 0.5

# Or limit conversation length
goose session configure abc123 --max-turns 20
```

### Lost Session Data

```bash theme={null}
# Sessions backed up to
ls ~/.config/goose/sessions/backups/

# Restore from backup
goose session restore --from-backup 2024-03-04-abc123.db
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Agents" icon="robot" href="/concepts/agents">
    Learn about agent orchestration
  </Card>

  <Card title="Recipes" icon="book" href="/concepts/recipes">
    Configure sessions with recipes
  </Card>

  <Card title="CLI Reference" icon="terminal" href="/api/cli/session">
    Session management commands
  </Card>

  <Card title="API Reference" icon="code" href="/api/server/overview">
    Session management API
  </Card>
</CardGroup>
