Auth / Sessions

Sessions

Sessions track the conversation state between a user and an agent. Each session holds the message history, token counts, and compaction summary. Sessions auto-reset on idle timeout or daily schedule, and compact (summarize + archive) when the context window approaches capacity.

Session resolution

On every chat request, the gateway resolves a session — finding an existing active session or creating a new one.

text
resolveSession(key, agentConfig):
  1. Find active session for (uid, surface, surfaceId, agentId, workspaceId)
  2. Check shouldReset():
     - Idle timeout: now - lastActiveAt > idleTimeoutMinutes
     - Daily reset: lastActiveAt < today at dailyResetHour
  3. If reset needed → archive old session, create new
  4. If no active session → create new
  5. Return { session, isNew }

Session key

Sessions are uniquely identified by a composite key.

typescript
// Sessions are keyed by:
{
  uid: string           // authenticated user
  surface: string       // "chat" | "telegram" | "discord" | "group" | ...
  surfaceId: string     // channel-specific ID
  agentId: string       // which agent owns this session
  workspaceId?: string  // optional workspace scope
}

// sessionKeyString returns "surface:surfaceId" for logging

Reset triggers

TriggerConfigDefault
Idle timeoutagent.session.idleTimeoutMinutesVaries per agent
Daily resetagent.session.dailyResetHourVaries per agent (0–23)
Manual reset/reset command or POST /agent/reset

When a session resets, the old session is archived (status changes to archived) and a new session is created. Archived sessions and their messages remain queryable via the sessions API.

Compaction

When a session's estimated token count reaches 70% of the agent's maxContextTokens, compaction triggers automatically.

text
shouldCompact triggers at 70% of maxContextTokens

1. Pre-compaction flush
   → Give agent ONLY the memory_write tool
   → Prompt: "Save any important information before compaction"
   → temperature: 0.3, maxTokens: 2048

2. Summarize older messages
   → Keep the 10 most recent messages verbatim
   → Summarize everything else into ~500 words
   → temperature: 0.3, maxTokens: 1024

3. Archive old messages
   → Move to message_archive table (with archived_at timestamp)
   → Delete from messages table

4. Persist summary
   → Insert summary as system message
   → Update sessions.compaction_summary
   → Index summary in Typesense for future retrieval
Pre-compaction flush. Before summarizing, the agent gets one turn with only the memory_write tool to save important context. This ensures decisions, preferences, and strategies survive compaction in long-term memory.

Token estimation

Open Astra uses character-based heuristics instead of a tokenizer dependency. The estimates are conservative (overcount) to trigger compaction early rather than late.

text
// Token estimation heuristics (no tokenizer dependency)
JSON / array content:     length / 3
Content with code fences: length / 6
Plain text:               length / 4

Group sessions

When the surface is "group" (Discord channels, Telegram groups, etc.), the session is shared across all workspace members. All users contribute to and read from the same conversation thread.

typescript
// Group sessions (e.g., Discord channels, Telegram groups):
// Shared across all workspace members for the same surfaceId
// Looked up by: surface + surface_id + workspace_id (no uid filter)

surface: "group"
surfaceId: "discord-channel-123"
// → All users in the workspace share one conversation thread

Database schema

sql
-- sessions
id              UUID PRIMARY KEY
user_id         TEXT NOT NULL
workspace_id    UUID
agent_id        TEXT NOT NULL
surface         TEXT NOT NULL          -- "chat", "telegram", "group", etc.
surface_id      TEXT NOT NULL
status          TEXT DEFAULT 'active'  -- "active" | "archived"
webhook_url     TEXT
last_active_at  TIMESTAMPTZ
message_count   INTEGER DEFAULT 0
token_count     INTEGER DEFAULT 0
compaction_summary TEXT

-- messages
id              UUID PRIMARY KEY
session_id      UUID REFERENCES sessions
role            TEXT NOT NULL           -- "user", "assistant", "system", "tool"
content         TEXT
tool_calls      JSONB
tool_call_id    TEXT
token_estimate  INTEGER
timestamp       TIMESTAMPTZ DEFAULT NOW()

-- message_archive (compacted messages)
-- Same schema as messages + archived_at TIMESTAMPTZ