Documentation
¶
Overview ¶
Package agent defines shared types and infrastructure for coding agent backends. Backend implementations live in sub-packages (e.g. agent/claudecode).
Message dispatch ¶
Conn.ReadMessages reads agent stdout and forwards parsed messages to Options.MsgCh. The task checkout drains this channel in a separate goroutine (startMessageDispatch) that performs blocking side-effects: git fetch, diff stat, branch locking. The channel decouples the fast reader from these slow operations — without it, a blocked git fetch would backpressure the agent's stdout pipe and risk deadlock.
Conn is an interface. Backends that need to intercept messages (e.g. injecting control commands after initialization) wrap the default Conn returned by NewConn to override ReadMessages.
Relay shutdown protocol ¶
Each agent runs inside a container behind a relay daemon (relay.py) that survives SSH disconnects. Graceful shutdown uses a null-byte (\x00) sentinel written to stdin:
Flow 1 — One task is purged (user action or container death):
Server calls Checkout.Cleanup → Session.Stop writes \x00\n then closes stdin → attach_client forwards sentinel through Unix socket, sees stdin EOF, exits → _client_reader sets shutdown_event → _shutdown_watchdog closes proc.stdin, sends SIGINT, escalates to SIGTERM/SIGKILL → reader_thread sees stdout EOF → server kills container.
Flow 2 — Backend restarts (upgrade, crash):
SSH connections are severed → attach_client sees stdin EOF and disconnects (no \x00 sent) → relay daemon + agent keep running → on restart, server discovers the container during task import, reads output.jsonl to restore conversation state, and calls relay.py attach --offset N to reconnect.
Index ¶
- Constants
- Variables
- func APIKeyHash(envVars []string) string
- func AppendNativeRecord(log LogSink, version LogVersion, data []byte) error
- func CleanRelayState(ctx context.Context, container string) error
- func DefaultReadMessages(ctx context.Context, log *slog.Logger, r io.Reader, ...) error
- func DeployEmbeddedDir(ctx context.Context, container string, fsys fs.FS, targetDir string) error
- func DeployRelay(ctx context.Context, target runtime.ConnectionTarget, version LogVersion) error
- func HasRelayDir(ctx context.Context, container string) (bool, error)
- func IsRelayRunning(ctx context.Context, container string) (bool, error)
- func MarshalLogMessage(version LogVersion, m Message) ([]byte, error)
- func MarshalMessage(m Message) ([]byte, error)
- func PlainTextWritePrompt(w io.Writer, p Prompt, log LogSink) error
- func ReadPlan(ctx context.Context, container, planFile string) (string, error)
- func ReadRelayLog(ctx context.Context, container string, maxBytes int) string
- func RelayOutputSize(ctx context.Context, container string) (int64, error)
- func RelayScript(version LogVersion) ([]byte, error)
- func RelayStatus(ctx context.Context, container string) (alive bool, detail string, err error)
- func RenderDiscussion(meta *MetaMessage, result *MetaResultMessage, pr *MetaPRMessage, ...) string
- func SortModels(models []string) []string
- func StopRelay(ctx context.Context, target runtime.ConnectionTarget) error
- func StreamRelay(ctx context.Context, container string, parser *LogRecordParser, ...) iter.Seq2[ParsedMessage, error]
- func WriteMetaSession(log LogSink, init *InitMessage) error
- type AskMessage
- type AskOption
- type AskQuestion
- type Backend
- type Base
- type CompactCommand
- type Conn
- type DiffFileStat
- type DiffStat
- type DiffStatMessage
- type DiscardLogSink
- type ExitMessage
- type FileChange
- type HarnessArgs
- type HarnessCache
- type HarnessCacheEntry
- type ImageData
- type InitMessage
- type LogMessage
- type LogRecordParser
- type LogSink
- type LogVersion
- type Message
- type MetaCacheMount
- type MetaMessage
- type MetaMount
- type MetaPRMessage
- type MetaRepo
- type MetaResultMessage
- type MetaSessionMessage
- type Model
- type ModelFetcher
- type ModelInfoMessage
- type ModelInventory
- type Options
- type ParseErrorMessage
- type ParsedMessage
- type ParsedRecord
- type PendingAskAction
- type PendingUserAction
- type PendingUserActionKind
- type PendingUserActionMessage
- type PrePromptWriter
- type Prompt
- type QuotaProvider
- type RateLimitMessage
- type RateLimitStatus
- type RawMessage
- type RecordHandshaker
- type RelayProcess
- type RelayRecordReader
- type ResultMessage
- type Session
- func AttachRelaySession(ctx context.Context, opts *Options, wire WireFormat, ...) (*Session, error)
- func NewSession(ctx context.Context, cmd *exec.Cmd, c Conn, stdout io.Reader, ...) *Session
- func StartRelay(ctx context.Context, opts *Options, agentArgs []string, wire WireFormat) (*Session, error)
- func StartSession(ctx context.Context, rp *RelayProcess, c Conn, opts *Options) (*Session, error)
- type SlogWriter
- type StrippedEnvMessage
- type SubagentEndMessage
- type SubagentSpawn
- type SubagentStartMessage
- type SystemMessage
- type TextDeltaMessage
- type TextMessage
- type TextReplacement
- type ThinkingDeltaMessage
- type ThinkingMessage
- type TodoItem
- type TodoMessage
- type ToolInputView
- type ToolInputViewKind
- type ToolOutputDeltaMessage
- type ToolResultMessage
- type ToolUseMessage
- type Usage
- type UsageMessage
- type UserInputMessage
- type WidgetDeltaMessage
- type WidgetMessage
- type WireFormat
Constants ¶
const ( RelayDir = "/tmp/caic-relay" RelayScriptPath = RelayDir + "/relay.py" RelaySockPath = RelayDir + "/relay.sock" RelayOutputPath = RelayDir + "/output.jsonl" RelayLogPath = RelayDir + "/relay.log" )
Relay paths inside the container.
const MaxWidgetHTMLBytes = 256 * 1024 // 256 KB
MaxWidgetHTMLBytes is the maximum size of widget HTML the backend will forward to clients. Widgets exceeding this limit are replaced with an error message.
const PendingUserActionMessageType = messageTypePendingUserAction
PendingUserActionMessageType identifies a persisted pending user action.
const WidgetPluginDir = RelayDir + "/widget-plugin"
WidgetPluginDir is the container path where the widget plugin is deployed.
Variables ¶
var WidgetMCPServerScript []byte
WidgetMCPServerScript is the Python MCP server script that exposes the show_widget tool. It is deployed to containers by backends that support widget rendering (claude, codex).
var WidgetToolNames = map[string]struct{}{
"show_widget": {},
"mcp__widget__show_widget": {},
"mcp__plugin_caic-widget_widget__show_widget": {},
}
WidgetToolNames is the set of tool names that produce HTML widgets. Each harness parser checks this set to decide whether a tool_use block should emit WidgetMessage instead of ToolUseMessage.
Functions ¶
func APIKeyHash ¶ added in v0.9.0
APIKeyHash computes a deterministic SHA-256 hex digest of the *_API_KEY environment variable entries from the harness env list (KEY=VALUE pairs). Variables whose name does not end with _API_KEY are ignored. An empty input produces an empty hash.
func AppendNativeRecord ¶ added in v0.11.5
func AppendNativeRecord(log LogSink, version LogVersion, data []byte) error
AppendNativeRecord appends a native record in the exact physical format.
func CleanRelayState ¶ added in v0.6.0
CleanRelayState removes the relay state directory in the container so that a subsequent StartRelay begins with a clean output.jsonl. Used by fork to prevent the source task's message history from leaking into the forked task.
func DefaultReadMessages ¶ added in v0.7.0
func DefaultReadMessages(ctx context.Context, log *slog.Logger, r io.Reader, dispatch func(ParsedMessage), sink LogSink, version LogVersion, parseNative func([]byte) ([]Message, error)) error
DefaultReadMessages reads physical relay records, persists each exactly once, and forwards the parser's original ParsedMessage wrappers.
func DeployEmbeddedDir ¶ added in v0.5.1
DeployEmbeddedDir writes all files from an embed.FS to a target directory in the container via a single SSH + tar invocation. Idempotent.
func DeployRelay ¶
func DeployRelay(ctx context.Context, target runtime.ConnectionTarget, version LogVersion) error
DeployRelay uploads the selected relay script into the runtime target. Idempotent.
func HasRelayDir ¶
HasRelayDir checks whether the caic relay directory exists in the container. Its presence proves caic deployed the relay at some point.
func IsRelayRunning ¶
IsRelayRunning checks whether the relay socket exists in the container.
func MarshalLogMessage ¶ added in v0.11.5
func MarshalLogMessage(version LogVersion, m Message) ([]byte, error)
MarshalLogMessage encodes one semantic backend control record for version.
func MarshalMessage ¶
MarshalMessage serializes a Message to JSON. For RawMessage, returns the original bytes to preserve unknown fields. For typed messages, uses json.Marshal.
func PlainTextWritePrompt ¶ added in v0.3.0
PlainTextWritePrompt writes a user prompt as a plain text line on stdin and logs it as NDJSON.
func ReadPlan ¶
ReadPlan reads a plan file from the container by invoking relay.py read-plan over SSH. If planFile is non-empty, that specific file is read; otherwise the most recently modified .md file in ~/.claude/plans/ is used.
func ReadRelayLog ¶
ReadRelayLog reads the last maxBytes of the relay daemon's log file from the container. Returns empty string on any error (missing file, SSH failure).
func RelayOutputSize ¶ added in v0.9.0
RelayOutputSize returns the byte size of the relay output.jsonl in the container. This is fast (single stat call) and avoids transferring the file.
func RelayScript ¶ added in v0.11.5
func RelayScript(version LogVersion) ([]byte, error)
RelayScript selects the embedded script for a validated log version.
func RelayStatus ¶ added in v0.5.0
RelayStatus checks relay socket + PID liveness and returns diagnostic detail.
func RenderDiscussion ¶ added in v0.11.5
func RenderDiscussion(meta *MetaMessage, result *MetaResultMessage, pr *MetaPRMessage, msgs []Message) string
RenderDiscussion assembles a self-contained markdown document from task-owned parsed log data. It performs no physical log loading or harness parsing.
func SortModels ¶ added in v0.8.0
SortModels returns models with version deduplication: only the latest version per family key is kept. Models matching a modelBlacklist prefix are dropped. Models without parseable versions are preserved as-is. Output is sorted alphabetically.
The input slice is copied first so the caller's backing array is not modified by slices.DeleteFunc's clear() call.
func StopRelay ¶ added in v0.11.5
func StopRelay(ctx context.Context, target runtime.ConnectionTarget) error
StopRelay sends the relay shutdown sentinel through a fresh attachment and waits for the attach client to exit. It terminates the persistent relay and its agent subprocess without treating an SSH disconnect as a shutdown.
func StreamRelay ¶ added in v0.9.0
func StreamRelay(ctx context.Context, container string, parser *LogRecordParser, tailBytes, size int64) iter.Seq2[ParsedMessage, error]
StreamRelay streams NDJSON messages from the relay output.jsonl in the container over SSH, yielding each in order. When tailBytes > 0 and the file is larger, only the last tailBytes are transferred (via tail -c) and the partial first line is skipped; otherwise the whole file is streamed (cat).
The SSH stdout is read incrementally, so memory usage is O(1) regardless of file size. If the consumer stops early the ssh process is killed and reaped, so no process leaks per abandoned reader.
func WriteMetaSession ¶ added in v0.9.2
func WriteMetaSession(log LogSink, init *InitMessage) error
WriteMetaSession appends a caic_session control record for init metadata.
Types ¶
type AskMessage ¶ added in v0.3.0
type AskMessage struct {
ToolUseID string `json:"id"`
Questions []AskQuestion `json:"questions"`
}
AskMessage is emitted when the agent asks the user a question via the AskUserQuestion tool.
func (*AskMessage) Type ¶ added in v0.3.0
func (m *AskMessage) Type() string
Type implements Message.
type AskOption ¶ added in v0.3.0
type AskOption struct {
Label string `json:"label"`
Description string `json:"description,omitempty"`
}
AskOption is a single option in an AskUserQuestion.
type AskQuestion ¶ added in v0.3.0
type AskQuestion struct {
Question string `json:"question"`
Header string `json:"header,omitempty"`
Options []AskOption `json:"options"`
MultiSelect bool `json:"multiSelect,omitempty"`
}
AskQuestion is a single question from AskUserQuestion.
type Backend ¶
type Backend interface {
// Start launches the agent at the configured target. Parsed messages are
// forwarded to opts.MsgCh; opts.Log owns persisted task-log records.
Start(ctx context.Context, opts *Options) (*Session, error)
// AttachRelay connects to an already-running relay daemon in the
// configured target. opts.RelayOffset specifies the byte offset into
// output.jsonl to replay from (use 0 for full replay).
// opts.ResumeSessionID is the known agent session ID, used by stateful
// wire formats (e.g. codex) that need it before the first replay message.
// opts.PendingUserActions contains user-facing actions restored before
// reconnect, such as unanswered AskUserQuestion requests. It excludes
// backend-only control protocol state.
AttachRelay(ctx context.Context, opts *Options) (*Session, error)
// Harness returns the harness identifier ("claude", "codex", etc.)
Harness() harness.Name
// ModelInventory returns the models and per-model configuration supported
// by this backend.
ModelInventory() ModelInventory
// SetModelInventory replaces the models and per-model configuration.
// The server uses it to push dynamically discovered inventories into all
// checkout backends.
SetModelInventory(inventory ModelInventory)
// SupportsImages reports whether this backend accepts image content blocks.
SupportsImages() bool
// SupportsCompact reports whether this backend supports context compaction.
SupportsCompact() bool
// AgentArgs returns the CLI arguments for launching this backend's agent
// subprocess, including the executable name and all session-specific flags
// derived from a. Empty fields in a are treated as "use default".
AgentArgs(a HarnessArgs) []string
// NewWire creates a fresh WireFormat for this backend. Each call returns
// independent state; suitable for use outside the normal relay transport.
NewWire() WireFormat
// ContextWindowLimit returns the API prompt token limit for the given model.
// The model parameter is the model name reported by the agent at runtime.
ContextWindowLimit(model string) int
}
Backend launches and communicates with a coding agent process. Each implementation translates its native wire format into the shared Message types so the rest of the system (task, eventconv, SSE, frontend) remains agent-agnostic.
type Base ¶ added in v0.3.0
type Base struct {
HarnessID harness.Name
Images bool
ContextWindow int
Compact bool
// contains filtered or unexported fields
}
Base provides default implementations for metadata-only Backend methods. Embed it in backend-specific types to inherit the boilerplate. Each backend must implement Start and AttachRelay itself using the package-level helpers (StartRelay, AttachRelaySession). Base is registered once per process and shared across every concurrent task for its harness (see backends.Default), so ModelInventory/SetModelInventory guard the inventory with a mutex: a background refresh (SetModelInventory) and concurrent request handlers (ModelInventory) can run at the same time. ModelInventory itself is treated as immutable once set, so the mutex only needs to guard a pointer swap, not the read.
func (*Base) ContextWindowLimit ¶ added in v0.3.0
ContextWindowLimit implements Backend.
func (*Base) ModelInventory ¶ added in v0.11.3
func (b *Base) ModelInventory() ModelInventory
ModelInventory implements Backend.
func (*Base) SetModelInventory ¶ added in v0.11.3
func (b *Base) SetModelInventory(inventory ModelInventory)
SetModelInventory implements Backend.
func (*Base) SupportsCompact ¶ added in v0.6.0
SupportsCompact implements Backend.
func (*Base) SupportsImages ¶ added in v0.3.0
SupportsImages implements Backend.
type CompactCommand ¶ added in v0.6.0
CompactCommand is an optional interface for WireFormat implementations that support context compaction. The server checks for this capability to conditionally enable the compact button in the UI.
type Conn ¶ added in v0.7.0
type Conn interface {
// SendPrompt writes a user message to the agent's stdin.
SendPrompt(p Prompt) error
// SendRaw writes pre-encoded NDJSON bytes to the agent's stdin.
SendRaw(data []byte) error
// SendCompact sends a compact/context-reduction command.
SendCompact(instructions string) error
// ReadMessages runs the message read loop: reads NDJSON lines from r,
// parses them, writes raw lines to the log, and forwards parsed messages
// to msgCh.
ReadMessages(r io.Reader, msgCh chan<- ParsedMessage) error
// SendStop sends the null-byte sentinel to trigger graceful agent shutdown.
// Best-effort: returns when ctx is done if the write blocks.
SendStop(ctx context.Context)
// Close closes the stdin pipe.
Close() error
}
Conn handles wire-format I/O for a single agent session. It is safe for concurrent use. Backends can wrap a Conn to intercept messages (e.g. injecting control commands after initialization).
func NewConn ¶ added in v0.7.0
func NewConn(ctx context.Context, log *slog.Logger, stdin io.WriteCloser, sink LogSink, wire WireFormat) Conn
NewConn creates a connection using the task log's physical record version. log and sink must be non-nil; use DiscardLogSink{Version: version} when persistence is unnecessary.
type DiffFileStat ¶
type DiffFileStat struct {
Path string `json:"path"`
Added int `json:"added"`
Deleted int `json:"deleted"`
Binary bool `json:"binary,omitempty"`
}
DiffFileStat describes changes to a single file.
type DiffStat ¶
type DiffStat []DiffFileStat
DiffStat summarises the changes in a branch relative to its base.
type DiffStatMessage ¶
type DiffStatMessage struct {
MessageType string `json:"type"`
DiffStat DiffStat `json:"diff_stat"`
Ts float64 `json:"ts,omitempty"` // Unix epoch seconds (ms precision) when the relay emitted this record.
}
DiffStatMessage is emitted periodically by the relay's diff watcher thread with the current in-container git diff stats.
type DiscardLogSink ¶ added in v0.11.5
type DiscardLogSink struct {
Version LogVersion
}
DiscardLogSink ignores task-log records for non-persistent agent operations. Version must be set to the physical record version represented by the caller.
func (DiscardLogSink) AppendMessage ¶ added in v0.11.5
func (DiscardLogSink) AppendMessage(Message) error
AppendMessage discards one caic control record.
func (DiscardLogSink) AppendNative ¶ added in v0.11.5
func (DiscardLogSink) AppendNative([]byte) error
AppendNative discards one native physical record.
func (DiscardLogSink) Close ¶ added in v0.11.5
func (DiscardLogSink) Close() error
Close releases no resources.
func (DiscardLogSink) LogVersion ¶ added in v0.11.5
func (s DiscardLogSink) LogVersion() LogVersion
LogVersion returns the physical record version represented by the discarded records.
type ExitMessage ¶ added in v0.8.0
type ExitMessage struct {
MessageType string `json:"type"`
ExitCode int `json:"exit_code"`
Command []string `json:"cmd,omitempty"`
Signal int `json:"signal,omitempty"`
Error string `json:"error,omitempty"`
StderrTruncated bool `json:"stderr_truncated,omitempty"`
Ts float64 `json:"ts,omitempty"`
}
ExitMessage is written by the relay to output.jsonl when the agent subprocess exits, regardless of shutdown reason (crash, sentinel, EOF). It carries the exit code, command, signal, stderr, and timestamp so the backend can diagnose why a relay session ended without parsing relay.log.
func (*ExitMessage) ExitError ¶ added in v0.10.1
func (m *ExitMessage) ExitError() string
ExitError returns the user-facing diagnostic for a non-zero process exit.
func (*ExitMessage) Type ¶ added in v0.8.0
func (m *ExitMessage) Type() string
Type implements Message.
type FileChange ¶ added in v0.10.2
FileChange is one changed file rendered from a unified patch.
type HarnessArgs ¶ added in v0.9.1
type HarnessArgs struct {
Model string // Model name or alias; empty means use backend default.
Effort string // Thinking effort level (e.g. "low", "high"); empty means default.
ResumeSessionID string // Agent session ID to resume; empty starts a new session.
}
HarnessArgs holds the session-specific parameters that influence the CLI arguments passed to an agent subprocess.
type HarnessCache ¶ added in v0.7.6
type HarnessCache struct {
// contains filtered or unexported fields
}
HarnessCache is a thread-safe disk-backed cache for per-harness model inventories. The file is shared across harnesses; each harness owns its own key.
func OpenHarnessCache ¶ added in v0.7.6
func OpenHarnessCache(path string) *HarnessCache
OpenHarnessCache loads the cache from path. A missing or corrupt file starts with an empty cache — no error is returned.
func (*HarnessCache) ModelInventory ¶ added in v0.11.3
func (c *HarnessCache) ModelInventory(h harness.Name, envHash string) (inventory ModelInventory, fresh bool)
ModelInventory returns the cached inventory for h and whether it is fresh (updated within the last 24 h) and its API-key hash matches envHash. Invalid inventory entries are treated as unavailable.
func (*HarnessCache) SetModelInventory ¶ added in v0.11.3
func (c *HarnessCache) SetModelInventory(h harness.Name, inventory ModelInventory, envHash string)
SetModelInventory updates the cache for h and writes to disk atomically.
type HarnessCacheEntry ¶ added in v0.7.6
type HarnessCacheEntry struct {
Inventory ModelInventory `json:"inventory"`
Updated time.Time `json:"updated"`
EnvHash string `json:"env_hash,omitempty"` // SHA-256 of *_API_KEY env vars from config.toml
}
HarnessCacheEntry holds cached data for a single harness.
type ImageData ¶
type ImageData struct {
MediaType string `json:"media_type"` // e.g. "image/png", "image/jpeg"
Data string `json:"data"` // base64-encoded
}
ImageData carries a single base64-encoded image for multi-modal input.
type InitMessage ¶ added in v0.3.0
type InitMessage struct {
SessionID string `json:"session_id"`
Cwd string `json:"cwd"`
Tools []string `json:"tools"`
Model string `json:"model"`
Version string `json:"claude_code_version"`
Effort string `json:"effort,omitempty"` // Thinking effort (e.g. "low", "medium", "high", "max"). Empty when not supported.
}
InitMessage is emitted when a session starts.
func (*InitMessage) Type ¶ added in v0.3.0
func (m *InitMessage) Type() string
Type implements Message.
type LogMessage ¶ added in v0.3.0
LogMessage is a provisioning/startup log line from the container backend.
func (*LogMessage) Type ¶ added in v0.3.0
func (m *LogMessage) Type() string
Type implements Message.
type LogRecordParser ¶ added in v0.11.3
type LogRecordParser struct {
// contains filtered or unexported fields
}
LogRecordParser decodes versioned physical task-log records around one harness-native parser. A parser holds ordered log state and is not safe for concurrent use.
func NewLogRecordParser ¶ added in v0.11.3
func NewLogRecordParser(version LogVersion, parseNative func([]byte) ([]Message, error)) (*LogRecordParser, error)
NewLogRecordParser constructs a parser for an already-validated physical log version. parseNative is called synchronously and must parse and validate the supplied harness-native JSON before returning.
The callback input may alias scanner-owned record memory. parseNative must not retain or use the input after it returns.
func (*LogRecordParser) ParseRecord ¶ added in v0.11.3
func (p *LogRecordParser) ParseRecord(line []byte) (ParsedRecord, error)
ParseRecord decodes one physical task-log record according to the parser's exact version. Classification belongs to this parser so task-log consumers never duplicate or guess control vocabulary.
type LogSink ¶ added in v0.11.5
type LogSink interface {
LogVersion() LogVersion
AppendNative(data []byte) error
AppendMessage(message Message) error
Close() error
}
LogSink appends complete task-log records through the task-owned physical log authority. Native records are already encoded physical records; semantic messages are backend controls encoded according to the owned log version.
type LogVersion ¶ added in v0.11.3
type LogVersion int
LogVersion identifies a physical task-log format.
const ( // LogVersionV1 is the legacy bare-harness task-log format. LogVersionV1 LogVersion = 1 // LogVersionV2 is the caic-enveloped task-log format. LogVersionV2 LogVersion = 2 )
func (LogVersion) Validate ¶ added in v0.11.3
func (v LogVersion) Validate() error
Validate rejects unsupported task-log versions.
type Message ¶
type Message interface {
// Type returns the message type string.
Type() string
}
Message is the interface for all agent streaming messages.
type MetaCacheMount ¶ added in v0.10.2
type MetaCacheMount struct {
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
HostPath string `json:"hostPath,omitempty"`
// ContainerPath is the resolved target path in the runtime container.
ContainerPath string `json:"containerPath,omitempty"`
ReadOnly bool `json:"readOnly,omitempty"`
Shallow bool `json:"shallow,omitempty"`
}
MetaCacheMount describes one cache mount in a MetaMessage.
type MetaMessage ¶
type MetaMessage struct {
MessageType string `json:"type"`
Version int `json:"version"`
Prompt string `json:"prompt"`
Title string `json:"title,omitempty"`
Repos []MetaRepo `json:"repos"`
Harness harness.Name `json:"harness"`
Model string `json:"model,omitempty"`
Effort string `json:"effort,omitempty"`
StartedAt time.Time `json:"started_at"`
ForgeIssue int `json:"forge_issue,omitempty"` // Originating issue/PR number for bot comment callbacks.
ForkedFromTaskID string `json:"forked_from_task_id,omitempty"`
Tailscale bool `json:"tailscale,omitempty"`
USB bool `json:"usb,omitempty"`
Display bool `json:"display,omitempty"`
Sudo bool `json:"sudo,omitempty"`
GitHubToken bool `json:"gitHubToken,omitempty"`
RuntimeName string `json:"runtimeName,omitempty"`
BaseImage string `json:"baseImage,omitempty"`
ContainerPlatform string `json:"containerPlatform,omitempty"`
MaxCPUs int `json:"maxCPUs,omitempty"`
CacheMounts []MetaCacheMount `json:"cacheMounts,omitempty"`
Mounts []MetaMount `json:"mounts,omitempty"`
}
MetaMessage is written as the first line of a JSONL log file. It captures task-level metadata so logs can be reloaded on restart.
func (*MetaMessage) Validate ¶
func (m *MetaMessage) Validate() error
Validate checks that all required fields are present and the version is supported.
type MetaMount ¶ added in v0.10.2
type MetaMount struct {
HostPath string `json:"hostPath,omitempty"`
// ContainerPath is the resolved target path in the runtime container.
ContainerPath string `json:"containerPath,omitempty"`
ReadOnly bool `json:"readOnly,omitempty"`
}
MetaMount describes one custom bind mount in a MetaMessage.
type MetaPRMessage ¶ added in v0.5.0
type MetaPRMessage struct {
MessageType string `json:"type"`
ForgeOwner string `json:"forge_owner"`
ForgeRepo string `json:"forge_repo"`
ForgePR int `json:"forge_pr"`
}
MetaPRMessage is written to the JSONL log when a PR is created so that the PR number can be restored on server restart.
func (*MetaPRMessage) Type ¶ added in v0.5.0
func (m *MetaPRMessage) Type() string
Type implements Message.
type MetaRepo ¶ added in v0.5.0
type MetaRepo struct {
Name string `json:"name"`
BaseBranch string `json:"base_branch,omitempty"`
Branch string `json:"branch"`
ContainerPath string `json:"containerPath,omitempty"`
}
MetaRepo describes one repository entry in a MetaMessage.
type MetaResultMessage ¶
type MetaResultMessage struct {
MessageType string `json:"type"`
State string `json:"state"`
Title string `json:"title,omitempty"`
CostUSD float64 `json:"cost_usd,omitempty"`
Duration float64 `json:"duration,omitempty"` // Seconds.
NumTurns int `json:"num_turns,omitempty"`
InputTokens int `json:"input_tokens,omitempty"`
OutputTokens int `json:"output_tokens,omitempty"`
CacheCreationInputTokens int `json:"cache_creation_input_tokens,omitempty"`
CacheReadInputTokens int `json:"cache_read_input_tokens,omitempty"`
ReasoningOutputTokens int `json:"reasoning_output_tokens,omitempty"`
DiffStat DiffStat `json:"diff_stat,omitzero"`
Error string `json:"error,omitempty"`
AgentResult string `json:"agent_result,omitempty"`
}
MetaResultMessage is appended as the last line of a JSONL log file when a task reaches a terminal state.
type MetaSessionMessage ¶ added in v0.9.2
type MetaSessionMessage struct {
MessageType string `json:"type"`
SessionID string `json:"session_id"`
Model string `json:"model,omitempty"`
AgentVersion string `json:"agent_version,omitempty"`
}
MetaSessionMessage records the backend-native session identifier needed to resume a stateful harness after server restart.
func (*MetaSessionMessage) Type ¶ added in v0.9.2
func (m *MetaSessionMessage) Type() string
Type implements Message.
type Model ¶ added in v0.11.3
Model describes the configuration choices supported by one model. Values are protocol-agnostic strings because they are persisted in task preferences and sent back to each harness as user selections.
type ModelFetcher ¶ added in v0.9.2
type ModelFetcher interface {
FetchModelInventory(ctx context.Context, target runtime.ConnectionTarget, env []string) (ModelInventory, error)
}
ModelFetcher is an optional backend capability for discovering a model inventory.
type ModelInfoMessage ¶ added in v0.11.5
type ModelInfoMessage struct {
MessageType string `json:"type"`
ContextWindow int64 `json:"context_window"`
}
ModelInfoMessage records a harness-reported context window for replay.
func (*ModelInfoMessage) Type ¶ added in v0.11.5
func (m *ModelInfoMessage) Type() string
Type implements Message.
type ModelInventory ¶ added in v0.11.3
type ModelInventory struct {
Models []Model `json:"models"`
}
ModelInventory is the immutable model and configuration data discovered for a harness.
func CachedModelInventory ¶ added in v0.11.3
func CachedModelInventory(cacheDir string, h harness.Name, envVars []string) ModelInventory
CachedModelInventory loads a harness inventory from cacheDir. An empty cacheDir returns an empty inventory.
func (ModelInventory) IDs ¶ added in v0.11.3
func (i ModelInventory) IDs() []string
IDs returns the model IDs in inventory order.
type Options ¶
type Options struct {
Logger *slog.Logger // Non-nil session logger.
Target runtime.ConnectionTarget
Dir string // Working directory inside the runtime.
Model string // Model alias ("opus", "sonnet", "haiku", "fable") or full ID. Empty = default.
Effort string // Thinking effort (e.g. "low", "medium", "high", "max"). Empty = default.
InitialPrompt Prompt // Initial prompt; never mutated after creation.
ResumeSessionID string
RelayOffset int64 // Byte offset into relay output.jsonl for AttachRelay.
// PendingUserActions is the restored user-facing work that still needs
// input after AttachRelay reconnects. It must not contain backend-only
// protocol state such as keepalive, auto-allow, or environment control
// messages.
PendingUserActions []PendingUserAction
MsgCh chan<- ParsedMessage // Receives parsed physical records from the agent.
Log LogSink // Non-nil task-owned physical task-log authority; use DiscardLogSink{Version: version} when persistence is unnecessary.
StripEnv []string // Env var names for relay to strip from subprocess and emit as caic_stripped_env.
}
Options configures an agent session launch.
type ParseErrorMessage ¶
ParseErrorMessage is emitted when a backend output line cannot be decoded. It carries the error and the raw line for diagnostic display.
type ParsedMessage ¶ added in v0.11.3
ParsedMessage pairs a semantic message with its producer timestamp. A zero ProducerTime means the physical record did not provide producer time.
func ReadRelayTail ¶ added in v0.9.0
func ReadRelayTail(ctx context.Context, container string, parser *LogRecordParser, maxBytes int64) (msgs []ParsedMessage, size int64, err error)
ReadRelayTail reads only the tail of the relay output.jsonl from the container and returns the parsed messages plus the total file size (for RelayOffset). It streams the SSH output directly, so memory usage is O(1) and no multi-GB transfer occurs during runtime import.
type ParsedRecord ¶ added in v0.11.5
type ParsedRecord struct {
Messages []ParsedMessage
Control bool
}
ParsedRecord is a parser-owned semantic task-log record. Control reports whether the version-specific discriminator identifies a caic-owned control.
type PendingAskAction ¶ added in v0.10.2
type PendingAskAction struct {
Questions []AskQuestion `json:"questions,omitzero"`
}
PendingAskAction is the payload for PendingUserActionAskUserQuestion. It stores the rendered questions so reconnect can answer the original backend control request without replaying provider-specific raw JSON.
type PendingUserAction ¶ added in v0.10.2
type PendingUserAction struct {
Kind PendingUserActionKind `json:"kind"`
// RequestID is the backend request ID needed to complete the action.
RequestID string `json:"request_id,omitempty"`
// ToolUseID is the user-visible tool call that created the action.
ToolUseID string `json:"tool_use_id,omitempty"`
Ask PendingAskAction `json:"ask,omitzero"`
}
PendingUserAction records one user-facing action that must be completed before the agent can continue after a reconnect.
This is intentionally user-facing state, not a generic backend control protocol bucket. Permission auto-allow, keepalive, environment updates, and other backend-only control messages should not be represented here.
func ClonePendingUserAction ¶ added in v0.10.2
func ClonePendingUserAction(a PendingUserAction) PendingUserAction
ClonePendingUserAction returns a deep copy of a.
func ClonePendingUserActions ¶ added in v0.10.2
func ClonePendingUserActions(actions []PendingUserAction) []PendingUserAction
ClonePendingUserActions returns a deep copy of actions.
type PendingUserActionKind ¶ added in v0.10.2
type PendingUserActionKind string
PendingUserActionKind identifies the user action caic is waiting for.
const ( // PendingUserActionAskUserQuestion means the agent invoked AskUserQuestion // and caic still needs the user's answer. PendingUserActionAskUserQuestion PendingUserActionKind = "ask_user_question" )
type PendingUserActionMessage ¶ added in v0.10.2
type PendingUserActionMessage struct {
MessageType string `json:"type"`
Action PendingUserAction `json:"action"`
}
PendingUserActionMessage persists a PendingUserAction in task history. It is metadata for reconnect and should not be rendered as a chat message.
func (*PendingUserActionMessage) Type ¶ added in v0.10.2
func (m *PendingUserActionMessage) Type() string
Type implements Message.
type PrePromptWriter ¶ added in v0.9.1
PrePromptWriter is implemented by backends that send initialization commands to stdin before the first user prompt (e.g. Pi's set_model).
type Prompt ¶
type Prompt struct {
Text string `json:"text"`
Images []ImageData `json:"images,omitempty,omitzero"`
}
Prompt bundles user text with optional images for a single interaction.
type QuotaProvider ¶ added in v0.11.2
type QuotaProvider string
QuotaProvider identifies a monitored quota source. Add a value here when adding a provider fetcher or harness quota adapter so their identifiers stay coupled at compile time.
const ( // QuotaProviderAnthropic identifies direct Anthropic API usage. QuotaProviderAnthropic QuotaProvider = "anthropic" // QuotaProviderClaudeCode identifies a Claude Code OAuth subscription. QuotaProviderClaudeCode QuotaProvider = "claudecode" // QuotaProviderCodex identifies Codex usage. QuotaProviderCodex QuotaProvider = "codex" // QuotaProviderDeepSeek identifies DeepSeek API usage. QuotaProviderDeepSeek QuotaProvider = "deepseek" // QuotaProviderOpenRouter identifies OpenRouter API usage. QuotaProviderOpenRouter QuotaProvider = "openrouter" // QuotaProviderXiaomi identifies Xiaomi MiMo API usage. QuotaProviderXiaomi QuotaProvider = "xiaomi" )
func (QuotaProvider) Valid ¶ added in v0.11.2
func (p QuotaProvider) Valid() bool
Valid reports whether p is a supported quota provider.
type RateLimitMessage ¶ added in v0.5.5
type RateLimitMessage struct {
Status RateLimitStatus `json:"status"` // "allowed", "allowed_warning", "rejected".
ResetsAt time.Time `json:"resets_at"` // When the quota window resets; zero if unknown.
RateLimitType string `json:"rate_limit_type"` // Harness-native window ID (for example, "five_hour"); use QuotaWindow for the canonical ID.
Utilization float64 `json:"utilization"` // Fraction of the window used in [0, 1], not a percentage; 0 if unknown.
IsUsingOverage bool `json:"is_using_overage"` // True when extra/overage usage is active.
OverageResetsAt time.Time `json:"overage_resets_at"` // When overage resets; zero if unknown.
QuotaProvider QuotaProvider `json:"quota_provider"` // Canonical usage-provider ID that matches ProviderQuota.Provider; empty when the harness cannot identify it.
QuotaLabel string `json:"quota_label"` // Human-readable canonical provider label.
QuotaWindow string `json:"quota_window"` // Canonical provider window ID; empty when unknown.
}
RateLimitMessage is emitted when the CLI reports a rate limit status change.
func (*RateLimitMessage) Type ¶ added in v0.5.5
func (m *RateLimitMessage) Type() string
Type implements Message.
type RateLimitStatus ¶ added in v0.11.2
type RateLimitStatus string
RateLimitStatus describes whether a provider accepted or rejected a request for a quota window.
const ( // RateLimitStatusAllowed means the provider accepted the request. RateLimitStatusAllowed RateLimitStatus = "allowed" // RateLimitStatusAllowedWarning means the provider accepted the request and warned of high usage. RateLimitStatusAllowedWarning RateLimitStatus = "allowed_warning" // RateLimitStatusRejected means the provider rejected the request for quota exhaustion. RateLimitStatusRejected RateLimitStatus = "rejected" )
func (RateLimitStatus) Valid ¶ added in v0.11.2
func (s RateLimitStatus) Valid() bool
Valid reports whether s is a supported rate-limit status.
type RawMessage ¶
RawMessage is a pass-through for message types we don't need to inspect (tool_progress, etc.).
type RecordHandshaker ¶ added in v0.9.1
type RecordHandshaker interface {
RecordHandshake(ctx context.Context, stdin io.Writer, stdout io.Reader, model string) (WireFormat, io.Reader, error)
}
RecordHandshaker is implemented by backends that perform a bidirectional handshake over stdin/stdout before writing prompts (e.g. ACP-based agents like OpenCode). The returned io.Reader replaces the original stdout for subsequent reads (it may be a buffered reader that consumed bytes beyond the handshake response).
type RelayProcess ¶ added in v0.7.0
RelayProcess holds the started relay SSH command and its I/O pipes.
func PrepareRelay ¶ added in v0.7.0
PrepareRelay deploys the relay script and starts the SSH serve-attach process. The caller creates a Conn and Session from the returned process.
type RelayRecordReader ¶ added in v0.11.5
type RelayRecordReader struct {
// contains filtered or unexported fields
}
RelayRecordReader reads one physical relay record at a time. Agent payloads are returned as their unchanged native JSON; caic controls are returned only as parsed controls and never presented as native handshake data. logW is the caller's explicit persistence policy: use io.Discard for unpersisted reads.
func NewRelayRecordReader ¶ added in v0.11.5
func NewRelayRecordReader(r io.Reader, version LogVersion, log LogSink) (*RelayRecordReader, error)
NewRelayRecordReader creates a version-aware physical relay reader. version must be the caller-validated task-log version. log must be non-nil; use DiscardLogSink{Version: version} when persistence is unnecessary.
func (*RelayRecordReader) ReadRecord ¶ added in v0.11.5
func (r *RelayRecordReader) ReadRecord() (native []byte, controls []ParsedMessage, err error)
ReadRecord reads the next non-empty physical relay record. It persists the original encoded bytes once according to the reader's policy before strict parsing. Native is non-nil only for an agent payload; controls are separate.
func (*RelayRecordReader) Reader ¶ added in v0.11.5
func (r *RelayRecordReader) Reader() *bufio.Reader
Reader returns the buffered source positioned after records consumed by ReadRecord.
type ResultMessage ¶
type ResultMessage struct {
MessageType string `json:"type"`
Subtype string `json:"subtype"`
IsError bool `json:"is_error"`
DurationMs int64 `json:"duration_ms"`
DurationAPIMs int64 `json:"duration_api_ms"`
NumTurns int `json:"num_turns"`
Result string `json:"result"`
SessionID string `json:"session_id"`
TotalCostUSD float64 `json:"total_cost_usd"`
Usage Usage `json:"usage"`
UUID string `json:"uuid"`
DiffStat DiffStat `json:"diff_stat,omitzero"` // Set by caic after running container diff.
}
ResultMessage is the terminal message for a query.
type Session ¶
type Session struct {
Conn
// contains filtered or unexported fields
}
Session manages a running agent process. It embeds Conn for wire I/O.
func AttachRelaySession ¶ added in v0.3.0
func AttachRelaySession(ctx context.Context, opts *Options, wire WireFormat, wrap func(Conn) (Conn, error)) (*Session, error)
AttachRelaySession connects to an already-running relay in the container and returns a new Session. It waits briefly for the attach process to confirm connectivity; if the process exits immediately (e.g. relay socket is stale), an error is returned so the caller can fall back to --resume. Backends may pass wrap to intercept the default Conn before message reading starts.
func NewSession ¶
func NewSession(ctx context.Context, cmd *exec.Cmd, c Conn, stdout io.Reader, msgCh chan<- ParsedMessage, log *slog.Logger) *Session
NewSession creates a Session from an already-started command. Messages read from stdout are parsed and forwarded to msgCh through the Conn's ReadMessages method.
A background goroutine reads stdout until EOF, then waits for the process to exit. The done channel is closed when both are complete. Callers should use Done() to detect session end and Wait() to retrieve the error.
Error priority: parse errors take precedence over wait errors, since a parse error indicates corrupted output while the process may still exit 0.
func StartRelay ¶ added in v0.3.0
func StartRelay(ctx context.Context, opts *Options, agentArgs []string, wire WireFormat) (*Session, error)
StartRelay is a convenience that calls PrepareRelay, creates a default Conn, and sends the initial prompt.
func StartSession ¶ added in v0.7.0
StartSession creates a Session from a RelayProcess and Conn, sends the initial prompt if present, and returns the session.
func (*Session) Done ¶
func (s *Session) Done() <-chan struct{}
Done returns a channel that is closed when the agent process exits.
func (*Session) Stop ¶ added in v0.7.0
Stop sends the null-byte sentinel, closes stdin, and waits for the agent process to exit or the context to expire. Returns nil on clean exit, the process exit error on abnormal exit, or the context error on timeout.
Closing stdin after the sentinel is critical: the attach_client's main thread is blocked on stdin.read1(). Without the close, attach_client never exits, SSH never exits, and cmd.Wait() never returns — deadlocking Stop.
The sentinel must be written explicitly rather than inferred from stdin EOF in the attach client, because EOF also occurs on SSH drops and backend restarts where the container should keep running.
type SlogWriter ¶ added in v0.3.0
type SlogWriter struct {
Context context.Context
Logger *slog.Logger
Prefix string
Container string
// contains filtered or unexported fields
}
SlogWriter is an io.Writer that logs each line via slog.Warn. It is used as cmd.Stderr for SSH relay subprocesses across all backends.
type StrippedEnvMessage ¶ added in v0.7.0
type StrippedEnvMessage struct {
MessageType string `json:"type"`
Variables map[string]string `json:"variables"`
}
StrippedEnvMessage is emitted by the relay when it strips environment variables (e.g. ANTHROPIC_API_KEY) before spawning the agent subprocess. The backend uses these values to re-inject them after auth completes.
func (*StrippedEnvMessage) Type ¶ added in v0.7.0
func (m *StrippedEnvMessage) Type() string
Type implements Message.
type SubagentEndMessage ¶ added in v0.3.0
type SubagentEndMessage struct {
TaskID string `json:"task_id"`
Status string `json:"status"` // "completed", "failed", "stopped"
}
SubagentEndMessage is emitted when a subagent task completes, fails, or stops.
func (*SubagentEndMessage) Type ¶ added in v0.3.0
func (m *SubagentEndMessage) Type() string
Type implements Message.
type SubagentSpawn ¶ added in v0.10.2
type SubagentSpawn struct {
Agent string `json:"agent"`
Task string `json:"task"`
Label string `json:"label,omitempty"`
Phase string `json:"phase,omitempty"`
}
SubagentSpawn is one backend-normalized subagent invocation.
type SubagentStartMessage ¶ added in v0.3.0
type SubagentStartMessage struct {
TaskID string `json:"task_id"`
Description string `json:"description"`
}
SubagentStartMessage is emitted when a subagent task begins.
func (*SubagentStartMessage) Type ¶ added in v0.3.0
func (m *SubagentStartMessage) Type() string
Type implements Message.
type SystemMessage ¶
type SystemMessage struct {
MessageType string `json:"type"`
Subtype string `json:"subtype"`
SessionID string `json:"session_id"`
UUID string `json:"uuid"`
Detail string `json:"detail,omitempty"` // Optional human-readable detail (e.g. model names for model_rerouted).
Model string `json:"model,omitempty"` // Active model after model_rerouted; used to update task.reportedModel.
}
SystemMessage is a generic system message (status, compact_boundary, etc.).
func ContextCleared ¶ added in v0.11.6
func ContextCleared() *SystemMessage
ContextCleared creates the persisted context-clear system marker.
type TextDeltaMessage ¶ added in v0.3.0
type TextDeltaMessage struct {
Text string
}
TextDeltaMessage is a streaming text fragment, emitted when --include-partial-messages is enabled. Extracted from the nested wire format (stream_event → content_block_delta → text_delta) during parsing.
func (*TextDeltaMessage) Type ¶ added in v0.3.0
func (m *TextDeltaMessage) Type() string
Type implements Message.
type TextMessage ¶ added in v0.3.0
type TextMessage struct {
Text string `json:"text"`
Phase string `json:"phase,omitempty"` // Codex only: "commentary" | "final_answer" | "".
}
TextMessage is emitted when the agent produces text output.
func (*TextMessage) Type ¶ added in v0.3.0
func (m *TextMessage) Type() string
Type implements Message.
type TextReplacement ¶ added in v0.10.2
TextReplacement is one exact text replacement reported by an edit tool.
type ThinkingDeltaMessage ¶ added in v0.3.0
type ThinkingDeltaMessage struct {
Text string
}
ThinkingDeltaMessage is a streaming thinking fragment.
func (*ThinkingDeltaMessage) Type ¶ added in v0.3.0
func (m *ThinkingDeltaMessage) Type() string
Type implements Message.
type ThinkingMessage ¶ added in v0.3.0
type ThinkingMessage struct {
Text string `json:"text"`
}
ThinkingMessage is emitted when the agent produces a thinking block.
func (*ThinkingMessage) Type ¶ added in v0.3.0
func (m *ThinkingMessage) Type() string
Type implements Message.
type TodoItem ¶ added in v0.3.0
type TodoItem struct {
Content string `json:"content"`
Status string `json:"status"` // "pending", "in_progress", "completed".
ActiveForm string `json:"activeForm,omitempty"`
}
TodoItem is a single todo entry from a TodoWrite tool call.
type TodoMessage ¶ added in v0.3.0
TodoMessage is emitted when the agent updates its todo list via the TodoWrite tool.
func (*TodoMessage) Type ¶ added in v0.3.0
func (m *TodoMessage) Type() string
Type implements Message.
type ToolInputView ¶ added in v0.10.2
type ToolInputView struct {
Kind ToolInputViewKind `json:"kind"`
Files []FileChange `json:"files,omitzero"`
Subagents []SubagentSpawn `json:"subagents,omitzero"`
}
ToolInputView is a backend-normalized rendering model for known tool inputs.
func FileChangesInputView ¶ added in v0.10.2
func FileChangesInputView(files []FileChange) ToolInputView
FileChangesInputView returns a normalized file-change rendering model.
func FileChangesInputViewFromReplacements ¶ added in v0.10.2
func FileChangesInputViewFromReplacements(path string, replacements []TextReplacement) ToolInputView
FileChangesInputViewFromReplacements converts exact replacements to a synthetic unified patch so every edit-like tool uses the same display model.
type ToolInputViewKind ¶ added in v0.10.2
type ToolInputViewKind string
ToolInputViewKind identifies a normalized tool input view.
const ( // ToolInputFileChanges renders changed files as unified patches. ToolInputFileChanges ToolInputViewKind = "fileChanges" // ToolInputSubagents renders one or more spawned subagents. ToolInputSubagents ToolInputViewKind = "subagents" )
type ToolOutputDeltaMessage ¶ added in v0.5.0
ToolOutputDeltaMessage is a streaming output fragment from a tool execution. Codex only: emitted via item/commandExecution/outputDelta (Bash stdout) and item/mcpToolCall/progress (MCP tool progress messages).
func (*ToolOutputDeltaMessage) Type ¶ added in v0.5.0
func (m *ToolOutputDeltaMessage) Type() string
Type implements Message.
type ToolResultMessage ¶ added in v0.3.0
type ToolResultMessage struct {
ToolUseID string `json:"tool_use_id"`
Error string `json:"error,omitempty"` // Non-empty when the tool reported an error.
}
ToolResultMessage is emitted when a tool returns its result.
func (*ToolResultMessage) Type ¶ added in v0.3.0
func (m *ToolResultMessage) Type() string
Type implements Message.
type ToolUseMessage ¶ added in v0.3.0
type ToolUseMessage struct {
ToolUseID string `json:"id"`
Name string `json:"name"`
Input json.RawMessage `json:"input,omitempty"`
Detail string `json:"detail,omitempty"` // Backend-normalized short display detail for tool headers.
InputView ToolInputView `json:"input_view,omitzero"`
PlanContent string `json:"-"` // Snapshot of plan content; set by task on ExitPlanMode.
}
ToolUseMessage is emitted when the agent invokes a tool (except AskUserQuestion and TodoWrite which have their own types).
func (*ToolUseMessage) Type ¶ added in v0.3.0
func (m *ToolUseMessage) Type() string
Type implements Message.
type Usage ¶
type Usage struct {
InputTokens int `json:"input_tokens"`
OutputTokens int `json:"output_tokens"`
CacheCreationInputTokens int `json:"cache_creation_input_tokens"`
CacheReadInputTokens int `json:"cache_read_input_tokens"`
ReasoningOutputTokens int `json:"reasoning_output_tokens,omitempty"`
CacheTTLSeconds int `json:"cache_ttl_seconds,omitempty"` // Effective cache TTL from last API call; 0 = unknown.
}
Usage tracks per-API-call token consumption as reported by the Anthropic API.
The three input token fields are disjoint; total input context for one call equals InputTokens + CacheCreationInputTokens + CacheReadInputTokens. InputTokens is only the small non-cached, non-cache-creation portion (typically single-digit). The bulk of the input context lands in cache fields.
In ResultMessage these values are per-query (sum of all API calls in the turn). Task.liveUsage sums them across all queries for cumulative totals.
ReasoningOutputTokens is a subset of OutputTokens used for extended thinking (Claude) or reasoning summaries (Codex). Zero when the harness does not report it.
type UsageMessage ¶ added in v0.3.0
type UsageMessage struct {
Usage Usage `json:"usage"`
Model string `json:"model,omitempty"`
ContextWindow int `json:"context_window,omitempty"` // Non-zero when the backend reports the active context window size.
}
UsageMessage reports token consumption for a single API call.
func (*UsageMessage) Type ¶ added in v0.3.0
func (m *UsageMessage) Type() string
Type implements Message.
type UserInputMessage ¶ added in v0.3.0
type UserInputMessage struct {
Text string `json:"text,omitempty"`
Images []ImageData `json:"images,omitempty"`
}
UserInputMessage represents direct user text/image input (not a tool result).
func (*UserInputMessage) Type ¶ added in v0.3.0
func (m *UserInputMessage) Type() string
Type implements Message.
type WidgetDeltaMessage ¶ added in v0.5.1
WidgetDeltaMessage is a streaming fragment of widget HTML, emitted as the agent generates the widget code. Clients accumulate deltas for progressive rendering; the final WidgetMessage replaces them.
func (*WidgetDeltaMessage) Type ¶ added in v0.5.1
func (m *WidgetDeltaMessage) Type() string
Type implements Message.
type WidgetMessage ¶ added in v0.5.1
type WidgetMessage struct {
ToolUseID string `json:"id"`
Title string `json:"title"`
HTML string `json:"html"`
}
WidgetMessage is emitted when the agent produces an interactive HTML widget via a tool call (e.g. Claude's show_widget). The HTML is the complete, renderable widget code.
func NewWidgetMessage ¶ added in v0.5.2
func NewWidgetMessage(toolUseID string, input json.RawMessage) *WidgetMessage
NewWidgetMessage creates a WidgetMessage from raw tool input JSON. It extracts the title and widget_code fields and enforces MaxWidgetHTMLBytes. Shared by all backend parsers.
func (*WidgetMessage) Type ¶ added in v0.5.1
func (m *WidgetMessage) Type() string
Type implements Message.
type WireFormat ¶
type WireFormat interface {
// WritePrompt writes a user prompt to the agent's stdin in the
// backend's wire format. logW receives a copy.
WritePrompt(w io.Writer, p Prompt, log LogSink) error
// ParseMessage decodes a single NDJSON line into one or more typed
// Messages. A single wire line may produce multiple semantic messages.
ParseMessage(line []byte) ([]Message, error)
}
WireFormat defines the wire protocol for a backend's stdin/stdout communication. Implementations must pair WritePrompt and ParseMessage for the same protocol.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package agenttest provides shared test helpers for agent harness golden-file tests.
|
Package agenttest provides shared test helpers for agent harness golden-file tests. |
|
Package backends constructs configured agent backend sets.
|
Package backends constructs configured agent backend sets. |
|
Package claudecode implements agent.Backend for Claude Code.
|
Package claudecode implements agent.Backend for Claude Code. |
|
Package codex implements agent.Backend for Codex CLI.
|
Package codex implements agent.Backend for Codex CLI. |
|
Package harness defines coding agent harness identifiers shared across backend domains.
|
Package harness defines coding agent harness identifiers shared across backend domains. |
|
Package opencode implements agent.Backend for OpenCode via ACP (Agent Client Protocol): JSON-RPC 2.0 over stdin/stdout.
|
Package opencode implements agent.Backend for OpenCode via ACP (Agent Client Protocol): JSON-RPC 2.0 over stdin/stdout. |
|
Package pi implements agent.Backend for Pi coding agent CLI in RPC mode.
|
Package pi implements agent.Backend for Pi coding agent CLI in RPC mode. |
|
Package relay embeds the version-specific Python relay scripts used inside containers.
|
Package relay embeds the version-specific Python relay scripts used inside containers. |