Sessions & State

Wingman persists conversation state in a SQLite database stored at .wingman/wingman.db.

Session keys

A session key identifies a conversation and its routing context. You will see keys like:

agent:wingman:webui:thread:<uuid>
agent:wingman:webhook:build-alerts
agent:wingman:discord:account:<botId>:channel:<channelId>
agent:wingman:discord-main

Custom mappings (like channelSessions or !session) can use any stable key; agent:wingman:discord-main is a common pattern.

Finding a session key

  • Control UI: open a thread and expand Session Snapshot in the right sidebar. The Session Key field is the exact value used for routing.
  • CLI: /show prints the current session ID, and /sessions lists recent sessions.
  • API: GET /api/sessions?agentId=<id> returns session IDs with metadata.

How sessions are created

  • CLI: creates or resumes the last session for an agent.
  • Web UI: creates threads with agent:<id>:webui:thread:<uuid>.
  • Discord: uses channel mappings, the !session command, or a derived key (see below).
  • Webhooks: uses agent:<id>:webhook:<webhookId>.

Per-session request queueing

Gateway request execution is serialized per agentId + sessionKey.

  • If a request is already running for a session, the next request is queued by default.
  • Web UI and Desktop support queueing follow-up prompts while a response is still streaming.
  • The gateway emits queue lifecycle events:
    • ack with status: "queued" when a request is enqueued
    • ack with status: "dequeued" when that request begins execution
    • event:agent with type: "request-queued" for UI feedback

For low-level clients, req:agent accepts queueIfBusy (defaults to true). Set queueIfBusy: false to reject overlapping turns for that session.

Discord session mapping

When a Discord message arrives, the adapter resolves the session key in this order:

  1. !session <sessionKey> <message> overrides the session for that message.
  2. gateway.adapters.discord.channelSessions maps a channel or thread to a fixed session key (threads fall back to their parent channel).
  3. The gateway derives a key from routing and the selected agent.

Derived key formats:

  • DM: agent:<id>:main
  • Guild channel: agent:<id>:discord:account:<botId>:channel:<channelId>
  • Thread: agent:<id>:discord:account:<botId>:channel:<channelId>:thread:<threadId>

If the chosen session key starts with agent:<id>:, the adapter pins routing to that agent. Otherwise the gateway falls back to agents.bindings or the default agent.

Session metadata

Sessions store metadata like:

  • workdir (when set via the Control UI/API; used as the session execution root for tools/files)
  • messageCount and previews
  • source fields (webhook, discord)

Clear or update sessions

The gateway HTTP API lets you list, rename, and clear session messages:

GET /api/sessions?agentId=wingman
PUT /api/sessions/:id?agentId=wingman
DELETE /api/sessions/:id/messages?agentId=wingman

Best practices

  • Use stable session keys for long-running projects.
  • Use separate sessions for destructive tasks (migrations, deploys).
  • Limit fsRoots to keep session workdirs safe.