Session Management
Sessions in AgentDock provide the foundation for stateful, continuous interactions between users and AI agents. This document covers the core concepts, architecture, implementation details, and optimization strategies for the session management system.
Core Concepts
- Session: Represents a single conversation, identified by a unique
SessionId. It maintains state across multiple interactions (messages, tool calls) to preserve context. - Session Isolation: Ensures that concurrent conversations do not interfere with each other. Critical for multi-user environments.
- Single Source of Truth: Session IDs are generated centrally (typically by the entry point, like an API route handler), and state is managed through a single
SessionManagerinstance for a given state type, ensuring consistency.
Architecture & Implementation
The session system revolves around the generic SessionManager class found in agentdock-core/src/session/index.ts.
SessionManager<T extends SessionState>
- Generic: Can manage different types of session state (e.g., base state, orchestration state, tool state) by extending the base
SessionStateinterface. - Storage-Backed: Uses the Storage Abstraction Layer for persistence. It defaults to an in-memory provider but can be configured (via constructor options) to use Redis, Vercel KV, or other providers.
- Namespace: Uses a storage namespace (e.g.,
sessions,orchestration-state) to keep different types of session data separate in the storage backend. - State Factory: Requires a
defaultStateGeneratorfunction during instantiation to define how the initial state (T) for a new session should be created.
Key Operations
-
createSession(options): Creates a new session (if one doesn't exist for the given or generatedSessionId) using thedefaultStateGeneratorand stores it. Returns aSessionResult<T>. -
getSession(sessionId): Retrieves the current state for a session ID from storage. ReturnsSessionResult<T>. -
updateSession(sessionId, updateFn): Updates session state immutably. It retrieves the current state, applies theupdateFnto generate a new state object, and stores the new state atomically. ReturnsSessionResult<T>. -
deleteSession(sessionId): Removes a session from storage.
Session ID Generation
Session IDs are typically generated by the application entry point (e.g., API route handler) to maintain the single source of truth. While the core library can generate a UUID (generateSessionId), passing a predetermined ID is preferred. Format often includes prefixes for traceability.
Session Lifecycle & Cleanup
- Creation: Handled by
createSession, often triggered by the first interaction if noSessionIdis provided. - Access & Update:
getSessionandupdateSessionare used throughout the agent's processing logic. - Expiration (TTL): Each session state includes
lastAccessed(timestamp) andttl(milliseconds) properties. The TTL is configurable (default: 30 minutes).- Default: The default TTL is 24 hours of inactivity, defined in
agentdock-core. - Configuration: This default can be overridden globally for the application by setting the
SESSION_TTL_SECONDSenvironment variable (value in seconds). This configured TTL is used when creating or updating session keys in the storage provider.
- Default: The default TTL is 24 hours of inactivity, defined in
- Automatic Cleanup: The
SessionManagerincludes an optional, periodic cleanup mechanism (setupCleanupInterval,cleanupExpiredSessions) that checkslastAccessed + ttlagainst the current time and automatically callsdeleteSessionfor expired entries. This timer usesunref()in Node.js to avoid blocking process exit.
Persistence & Long-Lived Sessions
For sessions needing longer persistence than typical web interactions (e.g., persistent personal assistants):
- Configure Long TTL: Set
SESSION_TTL_SECONDSin the application's environment to a large value (e.g.,31536000for one year). - Ensure Activity: As long as the session is accessed (via
getSessionorupdateSession), thelastAccessedtimestamp is updated, resetting the TTL timer for the storage key. - No TTL: Setting
SESSION_TTL_SECONDSto0or a negative value will likely result in the storage provider not setting an expiration time, making the session persist indefinitely until explicitly deleted. Use this cautiously to avoid accumulating orphaned data.
Optimization Techniques
- Conditional State Creation: Components or managers (like
OrchestrationStateManager) should check if session state is truly needed before callingcreateSessionorgetSession. For example, an agent without orchestration configured doesn't need orchestration state. - Minimalist State Design: Session state interfaces (
T extends SessionState) should only include essential data, avoiding large objects or duplication. - Lazy Loading: Components retrieve session state only when required for an operation.
- Efficient Updates: The immutable update pattern (
updateSession) with partial updates ({ ...state, ...updates }) is efficient and prevents race conditions. - Last Accessed Tracking: Updating
lastAccessedongetSessionorupdateSessionkeeps active sessions alive while allowing inactive ones to expire naturally via TTL. - Storage Provider Choice: Selecting an appropriate storage provider (Memory for development, Redis/Vercel KV for production) significantly impacts performance and scalability.
- Leverage Configurable TTL: Set
SESSION_TTL_SECONDSappropriately for your application's needs (e.g., shorter for web sessions, longer for persistent agents) for automatic cleanup.
Integration
- LLM: Session state (especially message history) provides context for LLM calls.
- Tools: Tools can access session state (via specific managers if needed) to maintain context or share data across invocations.
- Orchestration: The
OrchestrationStateManageruses theSessionManagerto store its specificOrchestrationStateper session, enabling step tracking, sequence management, etc. - Next.js: See Next.js Integration for details on managing session IDs in API routes and client components.
Best Practices
- Single Source of Truth: Generate/manage session IDs at the entry point (API route).
- Pass, Don't Create: Components receive session IDs; they don't generate them.
- Configure Storage: Choose the appropriate storage provider for your environment.
- Minimize State: Only store necessary data in session state objects.
- Leverage TTL: Use TTL effectively for automatic cleanup.
- Handle Errors: Check
SessionResult.successand handle potential errors (e.g., session not found).