session

package
v0.37.0 Latest Latest
Warning

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

Go to latest
Published: Oct 11, 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.

The contract types themselves (Status, Session, Message, Part, Event, InputRequest, ...) are GENERATED from the frozen ABI schema into contract_gen.go (ADR 0056 T3, issue #1161): the schema is the single source of truth; this package is its dialect-preserving Go view that the API's JSON egress serves until the S3 frontend cutover. Only the pieces with no schema counterpart (ModelInfo, Capability) and the Message constructors (message.go) / send options (event.go) are hand-written.

Index

Constants

View Source
const ToolAbortReasonHarnessRestart = "harness restart"

ToolAbortReasonHarnessRestart is the synthetic terminal-state reason for a tool part orphaned by a harness restart (#1342 S12): the process that ran the tool died before writing terminal state, and the platform — the agentd projection sweep or the adapter's transcript repair — closes the part honestly so no surface renders an eternal spinner. One constant across both repair sites so the reason users see never forks by read path.

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 ContextUsage added in v0.15.12

type ContextUsage struct {
	Used   int64 `json:"used"`
	Window int64 `json:"window,omitempty"`
}

ContextUsage is the session's live context occupancy — the numerator for the "context: 45% used" display that ModelInfo.ContextWindow denominates. Used is semantic (tokens of window currently occupied), computed by the adapter from the agent's own accounting conventions; raw token ledgers live in Cost. Non-monotonic by design: compaction resets it.

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"`
	ContextUsage *ContextUsage `json:"contextUsage,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"
)

Directories

Path Synopsis
Package agentmessage implements the v1 agent-message provenance sentinel contract (issue #1465): inter-session messages delivered by the agentd send_message tool carry a machine-detectable origin marker so frontends and receiving agents can distinguish agent traffic from human input.
Package agentmessage implements the v1 agent-message provenance sentinel contract (issue #1465): inter-session messages delivered by the agentd send_message tool carry a machine-detectable origin marker so frontends and receiving agents can distinguish agent traffic from human input.
Package attachments implements the v1 attachment manifest contract (Epic 68, design decisions D7/D8/D15): prompt text carrying file references the agent reads with its own tools.
Package attachments implements the v1 attachment manifest contract (Epic 68, design decisions D7/D8/D15): prompt text carrying file references the agent reads with its own tools.

Jump to

Keyboard shortcuts

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