Skip to content

[Feature Request] Context slots for ephemeral state management #311

Description

@coreykarnei

Summary

Add support for "context slots" - designated pieces of context that can be updated between conversation turns without accumulating in the conversation history. This would allow agents to maintain current state information (like game state, session data, or dynamic configuration) that Claude needs to see, but without the token waste and context pollution of repeatedly including historical versions of that state.

Motivation

I'm building an RPG game using the Claude Agent SDK where I need Claude to always know the current game state (player stats, inventory, location, etc.). Currently, my options are:

  1. Include full state in every user message - This causes the conversation history to balloon with redundant state snapshots
  2. Use tool calls to retrieve state - This is wasteful (extra API call every turn) and still pollutes the history with tool call/result pairs
  3. Rely on Claude's memory - Unreliable for structured data that changes frequently

None of these patterns are ideal for applications with frequently-updating structured state.

Proposed Solution

Introduce a context_slots parameter (or similar) in the SDK that allows specifying named pieces of context that:

  • Are visible to Claude in the current turn
  • Get replaced (not appended) when updated in subsequent turns
  • Don't appear in the conversation history as separate messages
  • Are sent to the API separately from the conversation messages array

Example API (conceptual):

options = ClaudeAgentOptions(
    mcp_servers={"game-tools": server},
    allowed_tools=[f"mcp__game-tools__{t.name}" for t in ALL_TOOLS],
    model="claude-opus-4-5",
    system_prompt="You are a dungeon master.",
    context_slots={
        "game_state": {
            "player": {"hp": 100, "inventory": ["sword"]},
            "location": "forest",
            "nearby_enemies": ["goblin"]
        }
    }
)

async with ClaudeSDKClient(options=options) as client:
    await client.connect()

    await client.query("I enter the cave")
    # ... process response

    # Update slot between turns — replaces in-place, no history pollution
    client.update_context_slot("game_state", {
        "player": {"hp": 85, "inventory": ["sword", "potion"]},
        "location": "cave",
        "nearby_enemies": ["dragon"]
    })

    await client.query("I attack the dragon")

Use Cases

This pattern would benefit any application with ephemeral state:

  • Games & simulations - Current game state without history pollution
  • Dashboards & monitoring - Latest metrics without accumulating old snapshots
  • Multi-user sessions - Current user context that changes frequently
  • Configuration-driven agents - Dynamic settings that override defaults
  • Real-time data applications - Current sensor readings, stock prices, etc.

Benefits

  1. Reduced token usage - No redundant state in conversation history
  2. Cleaner conversation context - History contains actual dialogue, not state dumps
  3. Better separation of concerns - State management separated from conversation flow
  4. More predictable context windows - State doesn't push important conversation out of context
  5. Simpler application code - No need for workarounds with tool calls or system prompts

Alternative Approaches Considered

  • System prompt updates - Could work but feels like overloading system prompt's purpose
  • Dedicated state management tool - Still adds tool call overhead and history pollution

Implementation Notes

This might be implementable at the API level by having context slots appear as a special message type that the API handles differently, or as metadata that gets appended to system prompts in a way that doesn't accumulate in history.

Would be happy to discuss implementation approaches or contribute a proof-of-concept if helpful!

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions