Episode Boundaries
An episode begins when a session starts and ends on a well-defined boundary event. Understanding what starts and ends an episode is critical for configuring session timeout, multi-session continuity, and episode granularity.
Episode Start Events
| Trigger | Description |
|---|---|
| New session ID | Client sends a message with a session ID not in the active sessions table — new episode created |
| API call without sessionId | Octopus generates a new UUID session — new episode |
| Session resume after timeout | If a session expired and a new message arrives with the old session ID, a new episode is opened (old one was closed at timeout) |
Episode End Events
| End Reason | Trigger | Configurable |
|---|---|---|
| UserClosed | User clicks "End conversation" in the chat UI — explicit POST /api/sessions/{id}/close | No |
| Timeout | No activity for SessionIdleTimeoutMinutes (default: 30 min) | Yes — per agent |
| AgentClosed | Agent calls close_session tool (e.g., after completing a task) | No |
| ErrorClosed | Unrecoverable error during session | No |
Session Timeout Configuration
// Per-agent session timeout config
public class SessionConfig
{
public int IdleTimeoutMinutes { get; set; } = 30; // close after 30min idle
public int MaxSessionDurationHours { get; set; } = 8; // force-close after 8h
public bool AllowResume { get; set; } = false; // true = same sessionId reopens same episode
public bool CloseOnBrowserClose { get; set; } = false; // requires client-side heartbeat
}
Session Resume vs. New Episode
Octopus supports two models for returning users:
New Episode per Visit
AllowResume = false (default). Each page load generates a new session. Continuity is provided by episodic recall (past episodes are searched and injected as context). Good for most use cases.
Persistent Session
AllowResume = true. The client stores the session ID and sends it with every request. The same episode accumulates messages across multiple page loads. Good for long-running task tracking.
Long episodes that span many days (with AllowResume = true) will accumulate large message histories. The working memory pruner will drop old messages from the context window, but the episode record in SQL will grow unbounded. Set MaxSessionDurationHours to enforce episode closure even for resumable sessions.