session

package
v0.15.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 14, 2026 License: AGPL-3.0 Imports: 2 Imported by: 0

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

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.

const (
	AdmissionSteer Admission = "steer"
	AdmissionQueue Admission = "queue"
)

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

type Error struct {
	Code    string `json:"code,omitempty"`
	Message string `json:"message"`
}

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).

const (
	InputQuestion   InputKind = "question"
	InputPermission InputKind = "permission"
)

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 AgentSwitchMessage(id, fromAgent, toAgent string, createdAt time.Time) Message

func AssistantMessage

func AssistantMessage(id string, parts []Part, createdAt time.Time) Message

func CompactionMessage

func CompactionMessage(id, text string, createdAt time.Time) Message

func ModelSwitchMessage

func ModelSwitchMessage(id string, fromModel, toModel *ModelRef, createdAt time.Time) Message

func ShellMessage

func ShellMessage(id, command string, exitCode *int, createdAt time.Time) Message

func SystemMessage

func SystemMessage(id, text string, createdAt *time.Time) Message

func UserMessage

func UserMessage(id, text string, createdAt time.Time) Message

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 ModelRef

type ModelRef struct {
	ID       string `json:"id"`
	Provider string `json:"provider,omitempty"`
}

ModelRef identifies a model an adapter selected for a session or message.

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.

const (
	PartText       PartType = "text"
	PartReasoning  PartType = "reasoning"
	PartTool       PartType = "tool"
	PartFileChange PartType = "file_change"
	PartCustom     PartType = "custom"
)

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 Status

type Status string

Status is the lifecycle state of an agent session.

const (
	StatusUnknown    Status = "unknown"
	StatusIdle       Status = "idle"
	StatusBusy       Status = "busy"
	StatusError      Status = "error"
	StatusCompacting Status = "compacting"
	StatusArchived   Status = "archived"
)

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"
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL