Documentation
¶
Overview ¶
Package session defines the platform-owned agent session contract.
It is the single surface that web, mobile, SDK, and MCP clients consume, and the single output shape every agent adapter (pkg/agent/<name>) must produce. It contains zero agent-specific identifiers: agent-specific ID prefixes, snapshot patch parts, and provider naming live entirely behind the adapter seam. See design/0049_2026-08-09_agent-session-contract.md.
Discipline (load-bearing, design 0049 §4.1 + §7):
- 5 part types forever (Text, Reasoning, Tool, FileChange, Custom).
- All tools are ToolPart discriminated by Name.
- Diffs are unified-diff text (Patch string), not hunk structs.
- Cost is display-only and never billing.
- Agent-specific operations are pass-through until a second adapter validates a typed shape.
Index ¶
- type Admission
- type Capability
- type ChangeStatus
- type Cost
- type CustomPart
- type Error
- type Event
- type EventType
- type FileDiff
- type InputKind
- type InputOption
- type InputRequest
- type Message
- func AgentSwitchMessage(id, fromAgent, toAgent string, createdAt time.Time) Message
- func AssistantMessage(id string, parts []Part, createdAt time.Time) Message
- func CompactionMessage(id, text string, createdAt time.Time) Message
- func ModelSwitchMessage(id string, fromModel, toModel *ModelRef, createdAt time.Time) Message
- func ShellMessage(id, command string, exitCode *int, createdAt time.Time) Message
- func SystemMessage(id, text string, createdAt *time.Time) Message
- func UserMessage(id, text string, createdAt time.Time) Message
- type MessageType
- type ModelInfo
- type ModelRef
- type Part
- type PartType
- type SendOpts
- type Session
- type Status
- type TimeRange
- type ToolPart
- type ToolRef
- type ToolState
- type ToolStatus
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Admission ¶
type Admission string
Admission is a delivery mode on SendOpts (design 0049 §4.4). The zero value means an immediate/default send; steer injects at the next safe boundary without aborting in-flight tools; queue promotes when the agent would idle.
type Capability ¶
type Capability string
Capability advertises an optional agent behavior. Clients render or hide affordances based on the set an adapter reports (design 0049 §4.2/§4.6). Agent-specific operations (rewind/fork/stash) are pass-through until a second adapter validates a typed result shape.
const ( CapSteer Capability = "steer" CapQueue Capability = "queue" CapRewind Capability = "rewind" CapFork Capability = "fork" CapStash Capability = "stash" CapDiff Capability = "diff" CapReasoning Capability = "reasoning" )
type ChangeStatus ¶
type ChangeStatus string
ChangeStatus classifies one file's change in a FileDiff.
const ( ChangeAdded ChangeStatus = "added" ChangeModified ChangeStatus = "modified" ChangeDeleted ChangeStatus = "deleted" ChangeRenamed ChangeStatus = "renamed" )
type Cost ¶
type Cost struct {
InputTokens int64 `json:"inputTokens,omitempty"`
OutputTokens int64 `json:"outputTokens,omitempty"`
ReasoningTokens int64 `json:"reasoningTokens,omitempty"`
CacheReadTokens int64 `json:"cacheReadTokens,omitempty"`
CacheWriteTokens int64 `json:"cacheWriteTokens,omitempty"`
TotalTokens int64 `json:"totalTokens,omitempty"`
CostUSD float64 `json:"costUsd,omitempty"`
}
Cost is display-only token/cost data. Billing is cgroup-based; these fields are never authoritative for metering (design 0049 §4.1 rule 5).
type CustomPart ¶
type CustomPart struct {
Kind string `json:"kind"`
Data json.RawMessage `json:"data,omitempty"`
}
CustomPart is the pressure-relief valve for extension-defined semantics (design 0049 §4.3). Kind is a required discriminator so extensions do not force new PartType constants; Data carries the extension-specific payload.
type Error ¶
Error is the payload of an error Event (and an assistant Message's Error field). It is deliberately NOT a PartType: the part union is capped at 5 forever (design 0049 §4.1 rule 1); errors flow through the error Event.
type Event ¶
type Event struct {
Type EventType `json:"type"`
Timestamp time.Time `json:"timestamp"`
SessionID string `json:"sessionId,omitempty"`
MessageID string `json:"messageId,omitempty"`
PartID string `json:"partId,omitempty"`
Status Status `json:"status,omitempty"`
Session *Session `json:"session,omitempty"`
Message *Message `json:"message,omitempty"`
Part *Part `json:"part,omitempty"`
Delta string `json:"delta,omitempty"`
Input *InputRequest `json:"input,omitempty"`
Error *Error `json:"error,omitempty"`
}
Event is one item on a session's streaming event stream. Type selects which payload fields are meaningful; the rest are omitted.
type EventType ¶
type EventType string
EventType discriminates a streaming Event. The values are pinned in event_test.go's TestEventTypeCountMatchesExplicitList.
const ( EventSessionStatus EventType = "session.status" EventSessionUpdated EventType = "session.updated" EventMessageStart EventType = "message.start" EventMessageEnd EventType = "message.end" EventPartStart EventType = "part.start" EventPartDelta EventType = "part.delta" EventPartEnd EventType = "part.end" EventInputRequest EventType = "input.request" EventInputResolved EventType = "input.resolved" EventError EventType = "error" )
type FileDiff ¶
type FileDiff struct {
Path string `json:"path"`
OldPath string `json:"oldPath,omitempty"`
Status ChangeStatus `json:"status"`
Patch string `json:"patch"`
Additions int `json:"additions,omitempty"`
Deletions int `json:"deletions,omitempty"`
}
FileDiff is the payload of a FileChange part: one file's unified diff. Patch is authoritative unified-diff text (design 0049 §4.1 rule 4) — renderers (GitHub, monaco-diff, terminal) all consume it directly; no hunk structs.
type InputKind ¶
type InputKind string
InputKind unifies questions and permissions: both are "the agent needs a human" (design 0049 §4.5).
type InputOption ¶
type InputOption struct {
Label string `json:"label"`
Description string `json:"description,omitempty"`
}
InputOption is one selectable choice within a question InputRequest.
type InputRequest ¶
type InputRequest struct {
ID string `json:"id"`
SessionID string `json:"sessionId,omitempty"`
RootSessionID string `json:"rootSessionId,omitempty"`
Kind InputKind `json:"kind"`
Question string `json:"question,omitempty"`
Header string `json:"header,omitempty"`
Options []InputOption `json:"options,omitempty"`
Multiple bool `json:"multiple,omitempty"`
Custom bool `json:"custom,omitempty"`
Permission string `json:"permission,omitempty"`
Patterns []string `json:"patterns,omitempty"`
Always []string `json:"always,omitempty"`
Metadata map[string]json.RawMessage `json:"metadata,omitempty"`
Tool *ToolRef `json:"tool,omitempty"`
}
InputRequest is the unified pending-input shape. Question-specific fields apply when Kind == InputQuestion; permission-specific fields when Kind == InputPermission. Metadata values are raw JSON because permission metadata is open-ended extension data, not a known shape.
type Message ¶
type Message struct {
ID string `json:"id"`
SessionID string `json:"sessionId,omitempty"`
Type MessageType `json:"type"`
CreatedAt *time.Time `json:"createdAt,omitempty"`
Parts []Part `json:"parts,omitempty"`
Model *ModelRef `json:"model,omitempty"`
Cost *Cost `json:"cost,omitempty"`
Text string `json:"text,omitempty"`
Command string `json:"command,omitempty"`
ExitCode *int `json:"exitCode,omitempty"`
FromAgent string `json:"fromAgent,omitempty"`
ToAgent string `json:"toAgent,omitempty"`
FromModel *ModelRef `json:"fromModel,omitempty"`
ToModel *ModelRef `json:"toModel,omitempty"`
Error *Error `json:"error,omitempty"`
}
Message is one entry in a session transcript. It is a flat discriminated struct: Type selects which payload fields are meaningful, and the rest are omitted from the wire form. Constructors are the documented write path so the Type<->field pairing is encoded in one place.
func AgentSwitchMessage ¶
func ModelSwitchMessage ¶
func ShellMessage ¶
type MessageType ¶
type MessageType string
MessageType discriminates a Message. Agent/model switches and compaction are transcript entries (not side-band config) so the timeline stays coherent after a switch (design 0049 §4.5).
const ( MessageUser MessageType = "user" MessageAssistant MessageType = "assistant" MessageShell MessageType = "shell" MessageAgentSwitch MessageType = "agent_switch" MessageModelSwitch MessageType = "model_switch" MessageCompaction MessageType = "compaction" MessageSystem MessageType = "system" )
type ModelInfo ¶
type ModelInfo struct {
ID string `json:"id"`
Provider string `json:"provider,omitempty"`
DisplayName string `json:"displayName,omitempty"`
ContextWindow int64 `json:"contextWindow,omitempty"`
MaxOutput int64 `json:"maxOutput,omitempty"`
}
ModelInfo describes a model the client may select, including the context and output limits needed for "context: 45% used" display.
type Part ¶
type Part struct {
Type PartType `json:"type"`
ID string `json:"id,omitempty"`
Text string `json:"text,omitempty"`
Reasoning string `json:"reasoning,omitempty"`
Tool *ToolPart `json:"tool,omitempty"`
FileChange *FileDiff `json:"fileChange,omitempty"`
Custom *CustomPart `json:"custom,omitempty"`
}
Part is one typed piece of an assistant message. Exactly one payload field is set, matching Type; the rest are omitted from the wire form.
type PartType ¶
type PartType string
PartType discriminates the closed part union. The union is capped at 5 forever (design 0049 §4.1 rule 1); adding a type is a contract change.
type SendOpts ¶
type SendOpts struct {
Model *ModelRef `json:"model,omitempty"`
Admission Admission `json:"admission,omitempty"`
}
SendOpts parameterize a message send, including steering admission.
type Session ¶
type Session struct {
ID string `json:"id"`
WorkspaceID string `json:"workspaceId"`
ParentID string `json:"parentId,omitempty"`
Title string `json:"title,omitempty"`
AgentID string `json:"agentId,omitempty"`
Model *ModelRef `json:"model,omitempty"`
Status Status `json:"status"`
Cost *Cost `json:"cost,omitempty"`
Time *TimeRange `json:"time,omitempty"`
Summary string `json:"summary,omitempty"`
Archived bool `json:"archived,omitempty"`
}
Session is the platform-owned view of one agent session. It is the unit a client lists, opens, and renders. Agent/model switches and compaction are carried as Message transcript entries, not side-band fields here.
type TimeRange ¶
type TimeRange struct {
StartedAt time.Time `json:"startedAt"`
CompletedAt *time.Time `json:"completedAt,omitempty"`
}
TimeRange bounds a session or message. CompletedAt is nil while busy.
type ToolPart ¶
type ToolPart struct {
CallID string `json:"callId,omitempty"`
Name string `json:"name"`
Input json.RawMessage `json:"input,omitempty"`
Output json.RawMessage `json:"output,omitempty"`
State ToolState `json:"state"`
}
ToolPart is the payload of a Tool part. Every tool call — bash, edit, read, grep, todos, plan mode, subagent spawn — is a ToolPart discriminated by Name (design 0049 §4.1 rule 2). Input/Output are raw JSON because tool schemas are open-ended; adapters and renderers decode them per Name.
type ToolRef ¶
type ToolRef struct {
MessageID string `json:"messageId,omitempty"`
CallID string `json:"callId,omitempty"`
}
ToolRef identifies the tool call that triggered an InputRequest, if any.
type ToolState ¶
type ToolState struct {
Status ToolStatus `json:"status"`
Error string `json:"error,omitempty"`
StartedAt *time.Time `json:"startedAt,omitempty"`
CompletedAt *time.Time `json:"completedAt,omitempty"`
}
ToolState is the lifecycle state of one tool call, separate from the call's identity and input/output.
type ToolStatus ¶
type ToolStatus string
ToolStatus is the tool-call state-machine value (design 0049 §4.3): pending -> running -> completed | error.
const ( ToolStatusPending ToolStatus = "pending" ToolStatusRunning ToolStatus = "running" ToolStatusCompleted ToolStatus = "completed" ToolStatusError ToolStatus = "error" )