Skip to content

Session Channel

A session channel carries the full state of a single agent conversation: turns, streaming responses, tool calls, pending messages, input requests, customizations, and per-session configuration. One session channel exists per session for as long as the session is alive.

URI

ahp-session:/<uuid>

The path is a server-unique identifier (typically a UUID) chosen by the client at creation time. The session's provider (e.g. "copilot") is not encoded in the URI scheme — it is carried on SessionSummary.provider. This decoupling lets the same scheme address sessions backed by any agent.

Multiple session channels may be active simultaneously. Clients subscribe to each one whose state they want to track.

State

Subscribers receive a SessionState snapshot containing the session summary, lifecycle phase, history of completed turns, the active turn (if any), pending messages, outstanding input requests, model and active-client state, and other per-session fields. Refer to the State Model guide for a structural overview.

Lifecycle

1. Client picks a session URI (e.g. ahp-session:/<new-uuid>)
2. Client sends createSession(uri, config) command
3. Client sends subscribe(uri) — MAY be batched with the command
4. Server creates session with lifecycle: 'creating', returns the snapshot
5. Server asynchronously initialises the agent backend
6. On success: server dispatches session/ready
7. On failure: server dispatches session/creationFailed
8. Server broadcasts root/sessionAdded to clients subscribed to ahp-root://

Creation

createSession is a JSON-RPC request. The client picks the URI; the server allocates session state and begins backend initialisation. If the URI is already in use the server returns SessionAlreadyExists (-32003).

Active session

Once a session reaches lifecycle: 'ready', it accepts turns:

  • The client dispatches session/turnStarted to begin a turn.
  • The server streams session/delta, session/responsePart, session/toolCallStart, session/toolCallReady, and related actions.
  • The client dispatches session/toolCallConfirmed / session/toolCallResultConfirmed to approve or deny tool calls, or session/turnCancelled to abort.
  • The server dispatches session/turnComplete or session/error when the turn ends.
  • The server MAY dispatch session/inputRequested while a turn is active. Clients sync answer drafts with session/inputAnswerChanged and finish the request with session/inputCompleted.

All actions dispatched on this channel travel on ActionEnvelopes whose channel is the session URI. Action payloads do NOT carry their own session URI — the channel comes from the envelope.

Disposal

jsonc
// Client → Server (request)
{
  "jsonrpc": "2.0",
  "id": 5,
  "method": "disposeSession",
  "params": { "channel": "ahp-session:/<uuid>" },
}

The server tears down the session backend, drops associated subscriptions, and broadcasts root/sessionRemoved to clients subscribed to ahp-root://.

Methods and events on this channel

This section lists wire methods that are interpreted in the context of a session URI (ahp-session:/<uuid>).

Commands (params.channel = "ahp-session:/<uuid>")

MethodKindPurpose
createSessionrequestCreate a session at the chosen URI.
disposeSessionrequestDispose this session and its backend resources.
fetchTurnsrequestPage historical turns for this session.
completionsrequestSession-scoped inline completions (e.g. user-message mentions).

Notifications (params.channel = "ahp-session:/<uuid>")

MethodKindMeaning
actionserver → client notificationSession action envelope (session/* action payloads).
dispatchActionclient → server notificationDispatch client actions on this session (session/turnStarted, session/toolCallConfirmed, ...).
unsubscribeclient → server notificationStop receiving messages for this session channel.

auth/required may also target a session URI when auth is required for an operation scoped to that session; see Authentication.

Server Validation of Client Actions

When the server receives a client-dispatched action on this channel, it MUST validate it before applying. Invalid actions MUST be echoed back with a rejectionReason on the ActionEnvelope. The following validation rules apply:

ActionConditionServer Behavior
Any action referencing a non-existent sessionChannel URI not foundServer MUST silently ignore the action (no echo)
session/toolCallConfirmedTool call not in pending-confirmation stateServer MUST reject the action
session/turnCancelledNo active turnServer MUST reject the action
session/modelChangedA turn is currently activeServer MUST defer the model change until the active turn completes, then apply it for the next turn
session/agentChangedA turn is currently activeServer MUST defer the agent change until the active turn completes, then apply it for the next turn
session/inputAnswerChangedNo input request with matching requestIdServer SHOULD reject the action
session/inputAnswerChangedanswer.state requires a value but answer.value is absent, or answer.value.kind is missing the matching payload fieldServer SHOULD reject the action
session/inputCompletedNo input request with matching requestIdServer SHOULD reject the action
session/inputCompletedresponse is 'accept' but required questions do not have submitted answersServer SHOULD reject the action
session/pendingMessageRemovedNo pending message with matching id and kindServer SHOULD reject the action

Pending Message Consumption

The server consumes pending messages according to their kind:

Queued Messages

When a turn completes and queuedMessages is non-empty, the server SHOULD:

  1. Dispatch session/pendingMessageRemoved with kind: 'queued' for the first queued message.
  2. Dispatch session/turnStarted with the queued message's userMessage and queuedMessageId set to the message's id.

When a queued message is added while the session is idle (no active turn), the server SHOULD immediately consume it using the same two-step sequence.

Steering Messages

When a turn is active and steeringMessages is non-empty, the server MAY consume steering messages at its discretion. To consume a steering message, the server:

  1. Dispatches session/pendingMessageRemoved with kind: 'steering'.
  2. Injects the message content into the model context (the injection mechanism is opaque to the protocol).

Steering messages added while idle are silently stored and consumed when a turn becomes active.

Actions

Refer to the Session Channel Reference for the full per-action reference. All session-scoped action envelopes carry channel: "ahp-session:/<uuid>".

Catalogue Notifications

Session catalogue events (creation, disposal, summary mutations) are emitted on the Root Channel, not on the session channel itself. This lets clients track the session list without subscribing to every session.

Released under the MIT License.