Skip to content

Sessions

A session represents a conversation thread between a user and an agent on a specific channel. Sessions are the routing layer — they determine which agent handles a message and maintain per-conversation metrics.

Sessions are keyed by a compound identifier:

{Channel}:{ChannelAccountId}:{SenderId}

Examples:

  • Telegram:bot-123:user-456 — User 456 talking to bot 123 on Telegram
  • WebChat:default:user-789 — User 789 on the web chat widget
  • Slack:workspace-abc:user-def — User def in Slack workspace abc

This key structure provides natural isolation:

ScenarioResult
Same user on Telegram and SlackSeparate sessions
Same user talking to two different Telegram botsSeparate sessions
Same user talking to the same bot repeatedlySame session
Two users talking to the same botSeparate sessions

Sessions are created automatically on the first message from a user on a channel. No explicit session creation API is needed.

When the first message arrives, the session:

  1. Initialises — sets channel, sender, account, and timestamps from the message
  2. Binds to the default agent — routes to "default" unless previously bound
  3. Ensures the agent exists — creates a default agent config if none exists
  4. Routes the message — delegates to the bound agent’s ProcessMessageAsync
Terminal window
curl http://localhost:5000/api/sessions/WebChat:default:user-789

Response:

{
"success": true,
"data": {
"sessionId": "WebChat:default:user-789",
"channel": "WebChat",
"channelAccountId": "default",
"senderId": "user-789",
"boundAgentId": "default",
"messageCount": 12,
"createdAt": "2026-02-23T10:00:00Z",
"lastActivityAt": "2026-02-23T10:15:30Z"
}
}
FieldDescription
messageCountTotal messages processed in this session
createdAtWhen the first message arrived
lastActivityAtTimestamp of the most recent message

By default, sessions are bound to the "default" agent. Rebind to a different agent:

Terminal window
curl -X POST http://localhost:5000/api/sessions/WebChat:default:user-789/bind \
-H "Content-Type: application/json" \
-d '{ "agentId": "sales-bot" }'

After rebinding:

  • All subsequent messages in this session are handled by the new agent
  • The conversation history with the previous agent is preserved in the agent’s state
  • The new agent starts with a fresh conversation context for this session
  • Escalation — route a customer from a general bot to a specialised support agent
  • Handoff — transfer a lead from a marketing bot to a sales bot
  • Testing — temporarily route a session to a development agent
Terminal window
curl -X DELETE http://localhost:5000/api/sessions/WebChat:default:user-789

Ending a session:

  • Clears all session state (metrics, binding)
  • Deactivates the session grain
  • The next message from the same user on the same channel creates a fresh session

Ending a session does not clear the agent’s conversation history for that session. To clear history, use the agent’s history API:

Terminal window
curl -X DELETE http://localhost:5000/api/agents/{agentId}/history/{sessionId}

Sessions enforce channel consistency. If a session was initialised with Channel.WebChat, it rejects messages from Channel.Telegram. This prevents routing errors when session keys are constructed manually.

First message → Session created
├── Initialise state (channel, sender, timestamps)
├── Bind to "default" agent
└── Route message to agent
Subsequent messages → Route to bound agent
├── Increment messageCount
├── Update lastActivityAt
└── Delegate to AgentGrain.ProcessMessageAsync
Agent rebind (optional) → Future messages go to new agent
Session end → State cleared
└── Next message starts a fresh session

A single user can have active sessions across multiple channels simultaneously. Each session is independent:

Alice on Telegram → Session "Telegram:bot-1:alice" → sales-bot
Alice on WebChat → Session "WebChat:default:alice" → default
Alice on Slack → Session "Slack:workspace:alice" → support-bot

The agent’s memory is shared across these sessions (memory is agent-scoped, not session-scoped), but conversation history is per-session. This means the sales bot remembers Alice’s preferences from Telegram when she contacts it via Slack, but sees a fresh conversation thread.