Skip to main content

Session Management

A Session is the context container under an Agent. It owns the conversation thread, transcript, token counters, task attachments, delivery hints, model overrides, and reset state for one route of work. The high-level model is:
Agent -> Session -> Task/Subagent -> Delivery channel
Channels deliver messages. They do not own the work. For the product model, see Agents, Sessions, And Tasks.

Session Keys

Fased stores session rows by sessionKey. Common keys:
SourceShape
Main direct chatagent:<agentId>:<mainKey>
Per-peer DMagent:<agentId>:direct:<peerId>
Per-channel DMagent:<agentId>:<channel>:direct:<peerId>
Per-account DMagent:<agentId>:<channel>:<accountId>:direct:<peerId>
Group/channel chatagent:<agentId>:<channel>:group:<id> or agent:<agentId>:<channel>:channel:<id>
Thread/topicappend :thread:<threadId> when supported
Task runcron:<job.id> internally
Webhookhook:<uuid> unless explicitly set
Node runnode-<nodeId>
Direct chats default to the main session for continuity. Configure session.dmScope when one Agent can receive private DMs from multiple people. Older topic-aware channel paths can also contain a :topic:<threadId> suffix; new shared routing uses :thread:<threadId>.

DM Isolation

Use session.dmScope to control how direct messages are grouped:
  • main: all DMs share the Agent main session.
  • per-peer: isolate by sender id across channels.
  • per-channel-peer: isolate by channel and sender.
  • per-account-channel-peer: isolate by account, channel, and sender.
For shared inboxes, prefer per-channel-peer or per-account-channel-peer. Use session.identityLinks when the same person should share a canonical session across multiple channels.
{
  session: {
    dmScope: "per-channel-peer",
    identityLinks: {
      alice: ["telegram:123456789", "discord:987654321012345678"],
    },
  },
}
Run fased security audit to review current DM isolation settings.

Gateway Source Of Truth

The gateway owns session state. UI clients should query gateway APIs instead of reading local session files. State lives on the gateway host:
  • Store: ~/.fased/agents/<agentId>/sessions/sessions.json
  • Transcript: ~/.fased/agents/<agentId>/sessions/<SessionId>.jsonl
  • Topic transcript: .../<SessionId>-topic-<threadId>.jsonl
Session rows can include:
  • sessionId
  • updatedAt
  • displayName, channel, subject, room, space
  • token counters: inputTokens, outputTokens, totalTokens, contextTokens
  • model/thinking/verbose overrides
  • delivery hints and origin metadata
Deleting a single stale session row is allowed; Fased recreates it on the next matching message.

Origin Metadata

Session rows record best-effort origin metadata so UIs can explain where a session came from:
  • label
  • provider
  • from / to
  • accountId
  • threadId
Connectors should pass inbound labels, sender names, group names, and routing metadata when they update session state.

Reset And Lifecycle

Fased reuses a session until a reset rule expires it or the user resets it. Default behavior:
  • daily reset at 4:00 AM local time on the gateway host
  • optional idle reset with session.idleMinutes
  • per-type overrides with resetByType
  • per-channel overrides with resetByChannel
  • /new and /reset create a fresh session id
  • isolated task runs use a fresh sessionId per run
Example:
{
  session: {
    reset: { mode: "daily", atHour: 4, idleMinutes: 120 },
    resetByType: {
      direct: { mode: "idle", idleMinutes: 240 },
      group: { mode: "idle", idleMinutes: 120 },
    },
    resetByChannel: {
      discord: { mode: "idle", idleMinutes: 10080 },
    },
    resetTriggers: ["/new", "/reset"],
  },
}

Maintenance

Session maintenance keeps session metadata and transcript artifacts bounded. Defaults:
SettingDefault
session.maintenance.modewarn
pruneAfter30d
maxEntries500
rotateBytes10mb
resetArchiveRetentionsame as pruneAfter
maxDiskBytesdisabled
Use mode: "enforce" to apply cleanup automatically.
{
  session: {
    maintenance: {
      mode: "enforce",
      pruneAfter: "45d",
      maxEntries: 800,
      rotateBytes: "20mb",
      resetArchiveRetention: "14d",
    },
  },
}
Preview or apply cleanup:
fased sessions cleanup --dry-run
fased sessions cleanup --enforce
Large stores should use both time and count limits. If disk usage matters, set maxDiskBytes and highWaterBytes.

Send Policy

Use send policy to block delivery for whole classes of sessions.
{
  session: {
    sendPolicy: {
      rules: [
        { action: "deny", match: { channel: "discord", chatType: "group" } },
        { action: "deny", match: { keyPrefix: "cron:" } },
      ],
      default: "allow",
    },
  },
}
Owner commands:
  • /send on
  • /send off
  • /send inherit
Send these as standalone messages.

Named Channel Sessions

Channel chats can create named child sessions under the current route:
/session new Research
/session list
/session switch Research
/session switch main
Normal messages after /session switch go to the active named child session. Tasks created from channel chat or WebChat attach to the active Agent/session. WebChat exposes this through Schedule this.

Inspecting Sessions

Useful inspection commands:
fased status
fased sessions --json
fased gateway call sessions.list --params '{}'
In chat:
  • /status checks reachability and current context state.
  • /context list shows injected context contributors.
  • /compact summarizes older context.
  • /stop aborts the active run for that session.