Documentation
¶
Overview ¶
Package appserver is a typed client for the codex app-server JSON-RPC protocol over stdio. It is the backing transport used by codex adapter runs whose resolved driver.Request selects provider-native streaming.
The package is organised into five files:
- generate.go / generated.go — schema-derived flat notification types. Generated from schema/{v1,v2}/*.json via go:generate; do not edit by hand.
- union.go — hand-written discriminated unions that go-jsonschema cannot express (ThreadItem, UserInput, SandboxPolicy, CommandAction, WebSearchAction, and the envelope Params/Response types we call directly).
- codec.go — stdioStream, a minimal jsonrpc2.ObjectStream adapter that bridges a subprocess's stdin (io.WriteCloser) and stdout (io.Reader) into the format sourcegraph/jsonrpc2 expects. It does not mutate frames; sourcegraph/jsonrpc2 already tolerates missing "jsonrpc":"2.0" markers.
- client.go — sourcegraph/jsonrpc2.Conn wrapper with typed method helpers for Initialize, ThreadStart, ThreadResume, TurnStart, TurnInterrupt, and notification subscription. Chosen over creachadair/jrpc2 because its Handler is dispatched synchronously and preserves wire order of notifications.
- run.go — driver-facing entry point that owns the codex app-server subprocess lifecycle for a single Run.
- translate.go — notification → StreamPayload mapping.
Protocol upgrades follow the generation procedure in generate.go.
Index ¶
- Constants
- func IsDisconnected(err error) bool
- func Run(ctx context.Context, opts Options, sink driver.EventSink) (driver.Response, error)
- type AgentMessageDeltaNotification
- type Client
- func (c *Client) Close() error
- func (c *Client) DisconnectNotify() <-chan struct{}
- func (c *Client) Initialize(ctx context.Context, params InitializeParams) (*InitializeResponse, error)
- func (c *Client) NotifyInitialized(ctx context.Context) error
- func (c *Client) SetNotificationHandler(h NotificationHandler)
- func (c *Client) ThreadFork(ctx context.Context, params ThreadForkParams) (*ThreadForkResponse, error)
- func (c *Client) ThreadResume(ctx context.Context, params ThreadResumeParams) (*ThreadResumeResponse, error)
- func (c *Client) ThreadStart(ctx context.Context, params ThreadStartParams) (*ThreadStartResponse, error)
- func (c *Client) TurnInterrupt(ctx context.Context, params TurnInterruptParams) error
- func (c *Client) TurnStart(ctx context.Context, params TurnStartParams) (*TurnStartResponse, error)
- type ClientInfo
- type CodexErrorInfo
- type CommandExecOutputDeltaNotification
- type CommandExecOutputStream
- type CommandExecutionOutputDeltaNotification
- type ErrorNotification
- type FileChange
- type FileChangeOutputDeltaNotification
- type InitializeParams
- type InitializeResponse
- type ItemCompletedNotificationBody
- type ItemStartedNotificationBody
- type NonSteerableTurnKind
- type NotificationHandler
- type Options
- type PlanDeltaNotification
- type Process
- func (p *Process) CloseGracefully(ctx context.Context, grace time.Duration) error
- func (p *Process) Done() <-chan struct{}
- func (p *Process) IsClosed() bool
- func (p *Process) RunTurn(ctx context.Context, opts Options, sink driver.EventSink) (result driver.Response, promptSent bool, err error)
- func (p *Process) TerminateAndWait(ctx context.Context) error
- func (p *Process) ThreadID() string
- type ReasoningSummaryPartAddedNotification
- type ReasoningSummaryTextDeltaNotification
- type ReasoningTextDeltaNotification
- type SandboxPolicy
- type SandboxPolicyKind
- type ThreadForkParams
- type ThreadForkResponse
- type ThreadItem
- type ThreadItemAgentMessageBody
- type ThreadItemCommandExecutionBody
- type ThreadItemDynamicToolCallBody
- type ThreadItemFileChangeBody
- type ThreadItemKind
- type ThreadItemMcpToolCallBody
- type ThreadItemReasoningBody
- type ThreadItemWebSearchBody
- type ThreadRef
- type ThreadResumeParams
- type ThreadResumeResponse
- type ThreadStartParams
- type ThreadStartResponse
- type ThreadStartedNotificationBody
- type ThreadTokenUsage
- type ThreadTokenUsageModelContextWindow
- type ThreadTokenUsageUpdatedNotification
- type TokenUsageBreakdown
- type Translator
- func (t *Translator) Dispatch(method string, params json.RawMessage)
- func (t *Translator) FinishError(err error)
- func (t *Translator) FinishFailure(failure *driver.RunFailure, raw *driver.RawStreams, usage *driver.Usage)
- func (t *Translator) SetThread(id string)
- func (t *Translator) SetTurn(id string)
- func (t *Translator) ThreadID() string
- type TurnCompletedNotificationBody
- type TurnCompletedTurn
- type TurnError
- type TurnErrorAdditionalDetails
- type TurnInterruptParams
- type TurnInterruptResponse
- type TurnRef
- type TurnStartParams
- type TurnStartResponse
- type TurnStartedNotificationBody
- type TurnStatus
- type TurnUsage
- type UserInput
- type UserInputKind
Constants ¶
const ( // MethodInitialize performs the JSON-RPC initialize handshake. MethodInitialize = "initialize" // MethodInitialized notifies the server that the client is ready. MethodInitialized = "initialized" // MethodThreadStart starts a new codex thread. MethodThreadStart = "thread/start" // MethodThreadResume resumes an existing codex thread. MethodThreadResume = "thread/resume" // MethodThreadFork creates a child thread without mutating its parent. MethodThreadFork = "thread/fork" // MethodTurnStart starts one turn inside a thread. MethodTurnStart = "turn/start" // MethodTurnInterrupt interrupts an in-flight turn. MethodTurnInterrupt = "turn/interrupt" // NotifyThreadStarted reports that a thread was created/resumed. NotifyThreadStarted = "thread/started" // NotifyThreadStatusChanged reports thread status transitions. NotifyThreadStatusChanged = "thread/status/changed" // NotifyThreadTokenUsageUpdated reports cumulative token usage. NotifyThreadTokenUsageUpdated = "thread/tokenUsage/updated" // NotifyTurnStarted reports that a turn began. NotifyTurnStarted = "turn/started" // NotifyTurnCompleted reports normal turn completion. NotifyTurnCompleted = "turn/completed" // NotifyItemStarted reports the start of a thread item lifecycle. NotifyItemStarted = "item/started" // NotifyItemCompleted reports the end of a thread item lifecycle. NotifyItemCompleted = "item/completed" // NotifyItemAgentMessageDelta carries assistant text deltas. NotifyItemAgentMessageDelta = "item/agentMessage/delta" // NotifyItemReasoningTextDelta carries reasoning text deltas. NotifyItemReasoningTextDelta = "item/reasoning/textDelta" // NotifyItemReasoningSummaryTextDelta carries reasoning-summary deltas. NotifyItemReasoningSummaryTextDelta = "item/reasoning/summaryTextDelta" // NotifyItemReasoningSummaryPartAdded reports a new reasoning-summary part. NotifyItemReasoningSummaryPartAdded = "item/reasoning/summaryPartAdded" // NotifyItemCommandExecutionOutputDelta carries command output deltas. NotifyItemCommandExecutionOutputDelta = "item/commandExecution/outputDelta" // NotifyCommandExecOutputDelta carries command output deltas emitted under // the alternate app-server notification name. NotifyCommandExecOutputDelta = "command/exec/outputDelta" // NotifyItemFileChangeOutputDelta carries file-change output deltas. NotifyItemFileChangeOutputDelta = "item/fileChange/outputDelta" // NotifyItemPlanDelta carries plan text deltas. NotifyItemPlanDelta = "item/plan/delta" // NotifyError carries a server-side error notification. NotifyError = "error" )
Method names for ClientRequest and notifications. Only the subset the codex adapter actually uses is listed; unknown notifications still reach the subscriber map as raw payloads so translate.go can forward them through StreamPayload.Raw.
Variables ¶
This section is empty.
Functions ¶
func IsDisconnected ¶
IsDisconnected reports whether err indicates the underlying connection has been closed. Exposed for callers that want to distinguish a clean shutdown from an RPC-level failure.
func Run ¶
Run spawns a codex app-server subprocess, completes the initialize / thread / turn handshake, forwards every relevant notification into the supplied sink as a StreamPayload, and returns the accumulated driver.Response once the turn completes.
The returned driver.Response satisfies the Driver SPI output contract: codex/driver.go (Output, Transcript, ExitCode, Usage, Checkpoint, and RawStreams when available). Errors from the subprocess or JSON-RPC transport are propagated; if the turn itself fails, the error is surfaced inside driver.Response.Failure rather than as a returned error.
Types ¶
type AgentMessageDeltaNotification ¶
type AgentMessageDeltaNotification struct {
// Delta corresponds to the JSON schema field "delta".
Delta string `json:"delta"`
// ItemID corresponds to the JSON schema field "itemId".
ItemID string `json:"itemId"`
// ThreadID corresponds to the JSON schema field "threadId".
ThreadID string `json:"threadId"`
// TurnID corresponds to the JSON schema field "turnId".
TurnID string `json:"turnId"`
}
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a thin, strongly-typed wrapper around sourcegraph/jsonrpc2.Conn. It hides the minimal JSON-RPC plumbing adapters should never need to re-implement.
Why sourcegraph/jsonrpc2 rather than creachadair/jrpc2:
- Handler.Handle is called synchronously per inbound frame, giving us a hard FIFO ordering contract without any extra wrapping. jrpc2 spawned a goroutine per notification and serialized them behind a sync.Mutex, whose non-FIFO wake order reordered codex token deltas in practice.
- No "jsonrpc":"2.0" strictness — codex app-server omits the marker on many frames, so no tolerant codec is needed.
func NewClient ¶
func NewClient(ctx context.Context, stream jsonrpc2.ObjectStream) *Client
NewClient takes ownership of the ObjectStream and spins up the JSON-RPC dispatcher goroutine. The caller is responsible for producing the stream (usually by spawning `codex app-server --listen stdio://` and handing over its stdio).
func (*Client) DisconnectNotify ¶
func (c *Client) DisconnectNotify() <-chan struct{}
DisconnectNotify is closed after the JSON-RPC reader reaches EOF or a protocol/transport error. Waiting for it before snapshotting captured stdout guarantees the reader has consumed every available inbound byte.
func (*Client) Initialize ¶
func (c *Client) Initialize(ctx context.Context, params InitializeParams) (*InitializeResponse, error)
Initialize performs the "initialize" handshake.
func (*Client) NotifyInitialized ¶
NotifyInitialized sends the "initialized" notification that completes the handshake.
func (*Client) SetNotificationHandler ¶
func (c *Client) SetNotificationHandler(h NotificationHandler)
SetNotificationHandler registers the single handler that receives all server-initiated notifications. Calling it more than once replaces the previous handler. A nil handler disables delivery without failing.
func (*Client) ThreadFork ¶
func (c *Client) ThreadFork(ctx context.Context, params ThreadForkParams) (*ThreadForkResponse, error)
ThreadFork creates a new child thread from an existing parent thread id.
func (*Client) ThreadResume ¶
func (c *Client) ThreadResume(ctx context.Context, params ThreadResumeParams) (*ThreadResumeResponse, error)
ThreadResume resumes an existing thread by id.
func (*Client) ThreadStart ¶
func (c *Client) ThreadStart(ctx context.Context, params ThreadStartParams) (*ThreadStartResponse, error)
ThreadStart creates a new thread.
func (*Client) TurnInterrupt ¶
func (c *Client) TurnInterrupt(ctx context.Context, params TurnInterruptParams) error
TurnInterrupt cancels an in-flight turn.
func (*Client) TurnStart ¶
func (c *Client) TurnStart(ctx context.Context, params TurnStartParams) (*TurnStartResponse, error)
TurnStart kicks off a new turn on the given thread and returns once the server has acknowledged the request (not once the turn completes).
type ClientInfo ¶
ClientInfo identifies the calling application during initialize.
type CodexErrorInfo ¶
type CodexErrorInfo interface{}
This translation layer make sure that we expose codex error code in camel case.
When an upstream HTTP status is available (for example, from the Responses API or a provider), it is forwarded in `httpStatusCode` on the relevant `codexErrorInfo` variant.
type CommandExecOutputDeltaNotification ¶
type CommandExecOutputDeltaNotification struct {
// `true` on the final streamed chunk for a stream when `outputBytesCap` truncated
// later output on that stream.
CapReached bool `json:"capReached"`
// Base64-encoded output bytes.
DeltaBase64 string `json:"deltaBase64"`
// Client-supplied, connection-scoped `processId` from the original `command/exec`
// request.
ProcessID string `json:"processId"`
// Output stream for this chunk.
Stream interface{} `json:"stream"`
}
Base64-encoded output chunk emitted for a streaming `command/exec` request.
These notifications are connection-scoped. If the originating connection closes, the server terminates the process.
type CommandExecOutputStream ¶
type CommandExecOutputStream interface{}
Stream label for `command/exec/outputDelta` notifications.
type CommandExecutionOutputDeltaNotification ¶
type CommandExecutionOutputDeltaNotification struct {
// Delta corresponds to the JSON schema field "delta".
Delta string `json:"delta"`
// ItemID corresponds to the JSON schema field "itemId".
ItemID string `json:"itemId"`
// ThreadID corresponds to the JSON schema field "threadId".
ThreadID string `json:"threadId"`
// TurnID corresponds to the JSON schema field "turnId".
TurnID string `json:"turnId"`
}
type ErrorNotification ¶
type ErrorNotification struct {
// Error corresponds to the JSON schema field "error".
Error TurnError `json:"error"`
// ThreadID corresponds to the JSON schema field "threadId".
ThreadID string `json:"threadId"`
// TurnID corresponds to the JSON schema field "turnId".
TurnID string `json:"turnId"`
// WillRetry corresponds to the JSON schema field "willRetry".
WillRetry bool `json:"willRetry"`
}
type FileChange ¶
type FileChange struct {
Path string `json:"path"`
Diff string `json:"diff"`
Kind json.RawMessage `json:"kind,omitempty"`
}
FileChange is a single entry in a fileChange item.
type FileChangeOutputDeltaNotification ¶
type FileChangeOutputDeltaNotification struct {
// Delta corresponds to the JSON schema field "delta".
Delta string `json:"delta"`
// ItemID corresponds to the JSON schema field "itemId".
ItemID string `json:"itemId"`
// ThreadID corresponds to the JSON schema field "threadId".
ThreadID string `json:"threadId"`
// TurnID corresponds to the JSON schema field "turnId".
TurnID string `json:"turnId"`
}
type InitializeParams ¶
type InitializeParams struct {
ClientInfo ClientInfo `json:"clientInfo"`
Capabilities json.RawMessage `json:"capabilities,omitempty"`
}
InitializeParams is the payload for the "initialize" request.
type InitializeResponse ¶
type InitializeResponse struct {
UserAgent string `json:"userAgent,omitempty"`
CodexHome string `json:"codexHome,omitempty"`
PlatformFamily string `json:"platformFamily,omitempty"`
PlatformOs string `json:"platformOs,omitempty"`
Extras json.RawMessage `json:"-"`
}
InitializeResponse is the server's initialize reply. codex-cli 0.120.0 returns opaque diagnostic metadata; we keep it as RawMessage because no current codex adapter code path inspects individual fields.
type ItemCompletedNotificationBody ¶
type ItemCompletedNotificationBody struct {
ThreadID string `json:"threadId"`
TurnID string `json:"turnId"`
Item json.RawMessage `json:"item"`
}
ItemCompletedNotificationBody is the adapter's view of "item/completed".
type ItemStartedNotificationBody ¶
type ItemStartedNotificationBody struct {
ThreadID string `json:"threadId"`
TurnID string `json:"turnId"`
Item json.RawMessage `json:"item"`
}
ItemStartedNotificationBody is the adapter's view of "item/started". The item field is a discriminated union decoded via DecodeThreadItem.
type NonSteerableTurnKind ¶
type NonSteerableTurnKind string
const NonSteerableTurnKindCompact NonSteerableTurnKind = "compact"
const NonSteerableTurnKindReview NonSteerableTurnKind = "review"
type NotificationHandler ¶
type NotificationHandler func(method string, params json.RawMessage)
NotificationHandler receives one decoded server notification. The raw JSON params are provided so handlers can decode into whatever typed shape they need (see translate.go).
Ordering contract: the underlying sourcegraph/jsonrpc2 dispatcher invokes Handler.Handle synchronously — each call must return before the next wire frame is dispatched — so this handler sees every notification in strict wire order. Keep the function inexpensive; any heavy work should be queued elsewhere. Blocking here is what preserves the order guarantee downstream.
type Options ¶
type Options struct {
// Command is the codex binary; defaults to "codex".
Command string
// Args appended after "app-server --listen stdio://"; typically empty.
ExtraArgs []string
// CWD where the subprocess is launched. Empty means inherit.
CWD string
// Env is the environment set for the subprocess, using EnvBinding
// semantics identical to codex exec runs.
Env []driver.EnvBinding
// ClientName and ClientVersion identify the caller in the initialize
// handshake. Codex surfaces these in its diagnostic logs.
ClientName string
ClientVersion string
// Prompt is the user input for the single turn.
Prompt string
// Thread controls whether this run starts, resumes, or forks a thread.
// ResumeThreadID and ForkThreadID are mutually exclusive. A fork returns a
// checkpoint for the newly created child and never runs a turn on the parent.
ResumeThreadID string
ForkThreadID string
Ephemeral bool
// Sandbox / Approval / Model overrides.
Sandbox string // "read-only" | "workspace-write" | "danger-full-access"
Approval string // passed to TurnStartParams.ApprovalPolicy
Model string
Effort string
// ServiceTier is the official app-server service tier override (for
// example, "fast").
ServiceTier string
// OutputSchema is forwarded to turn/start and validated before the final
// public lifecycle event when native structured output is selected.
OutputSchema *driver.OutputSchema
// RunID identifies the run for StreamPayload attribution.
RunID string
}
Options bundles the driver-provided inputs for a single run of the codex app-server. The caller (codex/driver.go) populates it from driver.Request and its package-owned codex.Config.
type PlanDeltaNotification ¶
type PlanDeltaNotification struct {
// Delta corresponds to the JSON schema field "delta".
Delta string `json:"delta"`
// ItemID corresponds to the JSON schema field "itemId".
ItemID string `json:"itemId"`
// ThreadID corresponds to the JSON schema field "threadId".
ThreadID string `json:"threadId"`
// TurnID corresponds to the JSON schema field "turnId".
TurnID string `json:"turnId"`
}
EXPERIMENTAL - proposed plan streaming deltas for plan items. Clients should not assume concatenated deltas match the completed plan item content.
type Process ¶
type Process struct {
// contains filtered or unexported fields
}
Process owns one initialized app-server connection and one loaded Codex thread. Callers must serialize RunTurn calls; Process also enforces that rule so an accidental second writer cannot interleave JSON-RPC turns.
func Open ¶
Open spawns and initializes an app-server and starts or resumes one thread, but deliberately sends no user prompt. The returned Process can therefore be pre-warmed without risking duplicate model/tool side effects.
func (*Process) CloseGracefully ¶
CloseGracefully closes stdin, then force-terminates after grace or ctx.
func (*Process) Done ¶
func (p *Process) Done() <-chan struct{}
Done closes after the subprocess has exited and stderr has been drained.
func (*Process) RunTurn ¶
func (p *Process) RunTurn(ctx context.Context, opts Options, sink driver.EventSink) (result driver.Response, promptSent bool, err error)
RunTurn sends exactly one prompt on the loaded thread. promptSent becomes true immediately before turn/start because an RPC error cannot prove the peer did not receive the request; callers must not replay in that case.
func (*Process) TerminateAndWait ¶
TerminateAndWait kills the independently grouped process and reaps it.
type ReasoningSummaryPartAddedNotification ¶
type ReasoningSummaryPartAddedNotification struct {
// ItemID corresponds to the JSON schema field "itemId".
ItemID string `json:"itemId"`
// SummaryIndex corresponds to the JSON schema field "summaryIndex".
SummaryIndex int `json:"summaryIndex"`
// ThreadID corresponds to the JSON schema field "threadId".
ThreadID string `json:"threadId"`
// TurnID corresponds to the JSON schema field "turnId".
TurnID string `json:"turnId"`
}
type ReasoningSummaryTextDeltaNotification ¶
type ReasoningSummaryTextDeltaNotification struct {
// Delta corresponds to the JSON schema field "delta".
Delta string `json:"delta"`
// ItemID corresponds to the JSON schema field "itemId".
ItemID string `json:"itemId"`
// SummaryIndex corresponds to the JSON schema field "summaryIndex".
SummaryIndex int `json:"summaryIndex"`
// ThreadID corresponds to the JSON schema field "threadId".
ThreadID string `json:"threadId"`
// TurnID corresponds to the JSON schema field "turnId".
TurnID string `json:"turnId"`
}
type ReasoningTextDeltaNotification ¶
type ReasoningTextDeltaNotification struct {
// ContentIndex corresponds to the JSON schema field "contentIndex".
ContentIndex int `json:"contentIndex"`
// Delta corresponds to the JSON schema field "delta".
Delta string `json:"delta"`
// ItemID corresponds to the JSON schema field "itemId".
ItemID string `json:"itemId"`
// ThreadID corresponds to the JSON schema field "threadId".
ThreadID string `json:"threadId"`
// TurnID corresponds to the JSON schema field "turnId".
TurnID string `json:"turnId"`
}
type SandboxPolicy ¶
type SandboxPolicy struct {
Type SandboxPolicyKind `json:"type"`
NetworkAccess *bool `json:"networkAccess,omitempty"`
Extras json.RawMessage `json:"-"`
}
SandboxPolicy is the sandbox policy override passed on TurnStart. Only the variants the codex adapter needs at call sites are modelled; extra fields per variant round-trip through Extras.
type SandboxPolicyKind ¶
type SandboxPolicyKind string
SandboxPolicyKind lists the sandbox policy variants.
const ( // SandboxPolicyKindDangerFull requests unrestricted local execution. SandboxPolicyKindDangerFull SandboxPolicyKind = "dangerFullAccess" // SandboxPolicyKindReadOnly requests read-only sandboxing. SandboxPolicyKindReadOnly SandboxPolicyKind = "readOnly" // SandboxPolicyKindExternal delegates sandboxing outside codex. SandboxPolicyKindExternal SandboxPolicyKind = "externalSandbox" // SandboxPolicyKindWorkspaceWrite allows writes inside the workspace. SandboxPolicyKindWorkspaceWrite SandboxPolicyKind = "workspaceWrite" )
type ThreadForkParams ¶
type ThreadForkParams struct {
ThreadID string `json:"threadId"`
CWD string `json:"cwd,omitempty"`
Ephemeral bool `json:"ephemeral,omitempty"`
Sandbox string `json:"sandbox,omitempty"`
Model string `json:"model,omitempty"`
ServiceTier string `json:"serviceTier,omitempty"`
ApprovalPolicy string `json:"approvalPolicy,omitempty"`
}
ThreadForkParams is the official v2 thread/fork request. Forking creates a new provider thread from ThreadID; the parent thread remains unchanged.
type ThreadForkResponse ¶
type ThreadForkResponse struct {
Thread ThreadRef `json:"thread"`
}
ThreadForkResponse is the reply to thread/fork. Thread.ID is the new child identifier and is the only checkpoint that may be returned by the fork run.
type ThreadItem ¶
type ThreadItem struct {
ID string `json:"id"`
Kind ThreadItemKind `json:"-"`
// Exactly one of the following pointers is set when Kind matches.
AgentMessage *ThreadItemAgentMessageBody `json:"-"`
Reasoning *ThreadItemReasoningBody `json:"-"`
CommandExecution *ThreadItemCommandExecutionBody `json:"-"`
FileChange *ThreadItemFileChangeBody `json:"-"`
McpToolCall *ThreadItemMcpToolCallBody `json:"-"`
WebSearch *ThreadItemWebSearchBody `json:"-"`
DynamicToolCall *ThreadItemDynamicToolCallBody `json:"-"`
// Raw preserves the original JSON representation. It is always non-nil;
// use it when Kind is unknown or when a caller needs an unmodeled field.
Raw json.RawMessage `json:"-"`
}
ThreadItem is the discriminated union payload observed on item/started and item/completed notifications. The concrete variant is accessible through the exported ThreadItem* structs; unrecognised variants retain their original JSON in Raw for forward compatibility.
func DecodeThreadItem ¶
func DecodeThreadItem(raw json.RawMessage) (*ThreadItem, error)
DecodeThreadItem parses a ThreadItem from its raw JSON, dispatching on the "type" discriminator. Unknown types are returned with Kind == ThreadItemUnknown and Raw populated; this lets translate.go emit them as StreamPayload.Raw without failing the whole run.
type ThreadItemAgentMessageBody ¶
type ThreadItemAgentMessageBody struct {
Text string `json:"text"`
Phase string `json:"phase,omitempty"`
}
ThreadItemAgentMessageBody is the "agentMessage" variant.
type ThreadItemCommandExecutionBody ¶
type ThreadItemCommandExecutionBody struct {
Command string `json:"command"`
CWD string `json:"cwd,omitempty"`
Status string `json:"status"`
ExitCode *int `json:"exitCode,omitempty"`
AggregatedOutput string `json:"aggregatedOutput,omitempty"`
DurationMs *int64 `json:"durationMs,omitempty"`
ProcessID string `json:"processId,omitempty"`
Source string `json:"source,omitempty"`
}
ThreadItemCommandExecutionBody is the "commandExecution" variant.
type ThreadItemDynamicToolCallBody ¶
type ThreadItemDynamicToolCallBody struct {
Tool string `json:"tool"`
Arguments json.RawMessage `json:"arguments,omitempty"`
Status string `json:"status"`
Success *bool `json:"success,omitempty"`
DurationMs *int64 `json:"durationMs,omitempty"`
}
ThreadItemDynamicToolCallBody is the "dynamicToolCall" variant.
type ThreadItemFileChangeBody ¶
type ThreadItemFileChangeBody struct {
Changes []FileChange `json:"changes"`
Status string `json:"status"`
}
ThreadItemFileChangeBody is the "fileChange" variant.
type ThreadItemKind ¶
type ThreadItemKind string
ThreadItemKind enumerates the ThreadItem variants we model. We cover the ones the codex adapter maps into StreamPayload; other variants are preserved through the Unknown/Raw path so downstream code can still emit them as StreamPayload.Raw.
const ( // ThreadItemAgentMessage is assistant text. ThreadItemAgentMessage ThreadItemKind = "agentMessage" // ThreadItemReasoning is model reasoning/thinking content. ThreadItemReasoning ThreadItemKind = "reasoning" // ThreadItemCommandExecution is a shell command execution item. ThreadItemCommandExecution ThreadItemKind = "commandExecution" // ThreadItemFileChange is a file-change item. ThreadItemFileChange ThreadItemKind = "fileChange" // ThreadItemMcpToolCall is an MCP tool-call item. ThreadItemMcpToolCall ThreadItemKind = "mcpToolCall" // ThreadItemWebSearch is a web-search item. ThreadItemWebSearch ThreadItemKind = "webSearch" // ThreadItemDynamicToolCall is a dynamic tool-call item. ThreadItemDynamicToolCall ThreadItemKind = "dynamicToolCall" // ThreadItemPlan is a plan update item. ThreadItemPlan ThreadItemKind = "plan" // ThreadItemUserMessage is a user message item. ThreadItemUserMessage ThreadItemKind = "userMessage" // ThreadItemImageView is an image-view item. ThreadItemImageView ThreadItemKind = "imageView" // ThreadItemImageGeneration is an image-generation item. ThreadItemImageGeneration ThreadItemKind = "imageGeneration" // ThreadItemContextCompaction is a context-compaction item. ThreadItemContextCompaction ThreadItemKind = "contextCompaction" // ThreadItemUnknown preserves unknown variants through the Raw path. ThreadItemUnknown ThreadItemKind = "" )
type ThreadItemMcpToolCallBody ¶
type ThreadItemMcpToolCallBody struct {
Server string `json:"server"`
Tool string `json:"tool"`
Arguments json.RawMessage `json:"arguments,omitempty"`
Result json.RawMessage `json:"result,omitempty"`
Error json.RawMessage `json:"error,omitempty"`
Status string `json:"status"`
DurationMs *int64 `json:"durationMs,omitempty"`
}
ThreadItemMcpToolCallBody is the "mcpToolCall" variant.
type ThreadItemReasoningBody ¶
type ThreadItemReasoningBody struct {
Content []string `json:"content,omitempty"`
Summary []string `json:"summary,omitempty"`
}
ThreadItemReasoningBody is the "reasoning" variant.
type ThreadItemWebSearchBody ¶
type ThreadItemWebSearchBody struct {
Query string `json:"query"`
Action json.RawMessage `json:"action,omitempty"`
}
ThreadItemWebSearchBody is the "webSearch" variant.
type ThreadRef ¶
type ThreadRef struct {
ID string `json:"id"`
Ephemeral bool `json:"ephemeral,omitempty"`
CreatedAt int64 `json:"createdAt,omitempty"`
UpdatedAt int64 `json:"updatedAt,omitempty"`
Extras json.RawMessage `json:"-"`
}
ThreadRef is the minimal surface of the server's Thread object exposed through thread/start and thread/started.
type ThreadResumeParams ¶
type ThreadResumeParams struct {
ThreadID string `json:"threadId"`
}
ThreadResumeParams is the payload for the "thread/resume" request.
type ThreadResumeResponse ¶
type ThreadResumeResponse struct {
Thread ThreadRef `json:"thread"`
}
ThreadResumeResponse is the reply to thread/resume.
type ThreadStartParams ¶
type ThreadStartParams struct {
CWD string `json:"cwd,omitempty"`
Ephemeral bool `json:"ephemeral,omitempty"`
Sandbox string `json:"sandbox,omitempty"`
Model string `json:"model,omitempty"`
ServiceTier string `json:"serviceTier,omitempty"`
Extras json.RawMessage `json:"-"`
}
ThreadStartParams matches the v2 ThreadStartParams schema. All fields are optional per the codex protocol; we only set the ones the adapter needs.
type ThreadStartResponse ¶
type ThreadStartResponse struct {
Thread ThreadRef `json:"thread"`
}
ThreadStartResponse is the reply to thread/start.
type ThreadStartedNotificationBody ¶
type ThreadStartedNotificationBody struct {
Thread ThreadRef `json:"thread"`
}
ThreadStartedNotificationBody is the minimal view the adapter takes of the "thread/started" notification.
type ThreadTokenUsage ¶
type ThreadTokenUsage struct {
// Last corresponds to the JSON schema field "last".
Last TokenUsageBreakdown `json:"last"`
// ModelContextWindow corresponds to the JSON schema field "modelContextWindow".
ModelContextWindow ThreadTokenUsageModelContextWindow `json:"modelContextWindow,omitempty,omitzero"`
// Total corresponds to the JSON schema field "total".
Total TokenUsageBreakdown `json:"total"`
}
type ThreadTokenUsageModelContextWindow ¶
type ThreadTokenUsageModelContextWindow *int
type ThreadTokenUsageUpdatedNotification ¶
type ThreadTokenUsageUpdatedNotification struct {
// ThreadID corresponds to the JSON schema field "threadId".
ThreadID string `json:"threadId"`
// TokenUsage corresponds to the JSON schema field "tokenUsage".
TokenUsage ThreadTokenUsage `json:"tokenUsage"`
// TurnID corresponds to the JSON schema field "turnId".
TurnID string `json:"turnId"`
}
type TokenUsageBreakdown ¶
type TokenUsageBreakdown struct {
// CachedInputTokens corresponds to the JSON schema field "cachedInputTokens".
CachedInputTokens int `json:"cachedInputTokens"`
// InputTokens corresponds to the JSON schema field "inputTokens".
InputTokens int `json:"inputTokens"`
// OutputTokens corresponds to the JSON schema field "outputTokens".
OutputTokens int `json:"outputTokens"`
// ReasoningOutputTokens corresponds to the JSON schema field
// "reasoningOutputTokens".
ReasoningOutputTokens int `json:"reasoningOutputTokens"`
// TotalTokens corresponds to the JSON schema field "totalTokens".
TotalTokens int `json:"totalTokens"`
}
type Translator ¶
type Translator struct {
// contains filtered or unexported fields
}
Translator converts codex app-server notifications into StreamPayload events understood by the SDK and downstream bridges. A translator is per-run and single-goroutine: jrpc2 delivers notifications sequentially so there is no internal locking beyond what tracks per-turn state.
func NewTranslator ¶
func NewTranslator(sink driver.EventSink, runID string) *Translator
NewTranslator creates a translator that attributes every emitted payload to runID.
func (*Translator) Dispatch ¶
func (t *Translator) Dispatch(method string, params json.RawMessage)
Dispatch routes one notification to the appropriate handler. Unknown methods are forwarded as a StreamPayload with Kind "" and their raw body in Raw so downstream bridges can still surface them as custom events.
func (*Translator) FinishError ¶
func (t *Translator) FinishError(err error)
FinishError closes a run whose transport or protocol ended without a usable official turn/completed notification. It never fabricates a Raw provider terminal; it only satisfies the normalized stream lifecycle.
func (*Translator) FinishFailure ¶
func (t *Translator) FinishFailure(failure *driver.RunFailure, raw *driver.RawStreams, usage *driver.Usage)
FinishFailure publishes the unique normalized run.error after the caller has combined the official provider terminal with process and validation outcomes. Raw provider terminal bytes remain attached for protocol-aware bridges without allowing an earlier optimistic run.finished.
func (*Translator) SetThread ¶
func (t *Translator) SetThread(id string)
SetThread records the thread id associated with the active run. Bridges use it to fill StreamPayload.ThreadID on every emitted payload.
func (*Translator) SetTurn ¶
func (t *Translator) SetTurn(id string)
SetTurn records the turn id acknowledged by turn/start before queued wire notifications are flushed. This ensures even an unknown first notification carries the authoritative RPC identity.
func (*Translator) ThreadID ¶
func (t *Translator) ThreadID() string
ThreadID returns the thread id currently associated with the run. It is exposed for adapter code that needs to report the id back to the caller.
type TurnCompletedNotificationBody ¶
type TurnCompletedNotificationBody struct {
ThreadID string `json:"threadId"`
Turn TurnCompletedTurn `json:"turn"`
}
TurnCompletedNotificationBody is the adapter's view of "turn/completed".
type TurnCompletedTurn ¶
type TurnCompletedTurn struct {
ID string `json:"id"`
Status TurnStatus `json:"status"`
Error *TurnError `json:"error,omitempty"`
Usage *TurnUsage `json:"usage,omitempty"`
CompletedAt int64 `json:"completedAt,omitempty"`
Items []json.RawMessage `json:"items,omitempty"`
}
TurnCompletedTurn is the trimmed turn object embedded in "turn/completed". Usage is the important field; Error surfaces on failure.
type TurnError ¶
type TurnError struct {
// AdditionalDetails corresponds to the JSON schema field "additionalDetails".
AdditionalDetails TurnErrorAdditionalDetails `json:"additionalDetails,omitempty,omitzero"`
// CodexErrorInfo corresponds to the JSON schema field "codexErrorInfo".
CodexErrorInfo interface{} `json:"codexErrorInfo,omitempty,omitzero"`
// Message corresponds to the JSON schema field "message".
Message string `json:"message"`
}
type TurnErrorAdditionalDetails ¶
type TurnErrorAdditionalDetails *string
type TurnInterruptParams ¶
type TurnInterruptParams struct {
ThreadID string `json:"threadId"`
TurnID string `json:"turnId,omitempty"`
}
TurnInterruptParams is the payload for the "turn/interrupt" request.
type TurnInterruptResponse ¶
type TurnInterruptResponse struct{}
TurnInterruptResponse is the reply to turn/interrupt.
type TurnRef ¶
type TurnRef struct {
ID string `json:"id"`
Status TurnStatus `json:"status"`
}
TurnRef carries the minimum turn metadata the adapter tracks.
type TurnStartParams ¶
type TurnStartParams struct {
ThreadID string `json:"threadId"`
Input []UserInput `json:"input"`
ApprovalPolicy string `json:"approvalPolicy,omitempty"`
SandboxPolicy *SandboxPolicy `json:"sandboxPolicy,omitempty"`
Model string `json:"model,omitempty"`
Effort string `json:"effort,omitempty"`
ServiceTier string `json:"serviceTier,omitempty"`
CWD string `json:"cwd,omitempty"`
OutputSchema json.RawMessage `json:"outputSchema,omitempty"`
}
TurnStartParams matches the v2 TurnStartParams schema. The adapter always attaches a text-only input; richer UserInput variants are future work.
type TurnStartResponse ¶
type TurnStartResponse struct {
Turn TurnRef `json:"turn"`
}
TurnStartResponse is the reply to turn/start.
type TurnStartedNotificationBody ¶
type TurnStartedNotificationBody struct {
ThreadID string `json:"threadId"`
Turn TurnRef `json:"turn"`
}
TurnStartedNotificationBody is the adapter's view of "turn/started".
type TurnStatus ¶
type TurnStatus string
TurnStatus is the official status carried by turn objects. A turn/completed notification is the sole terminal notification; its status distinguishes success, provider failure, and interruption.
const ( TurnStatusCompleted TurnStatus = "completed" TurnStatusFailed TurnStatus = "failed" TurnStatusInterrupted TurnStatus = "interrupted" TurnStatusInProgress TurnStatus = "inProgress" )
type TurnUsage ¶
type TurnUsage struct {
InputTokens int `json:"inputTokens"`
OutputTokens int `json:"outputTokens"`
CachedInputTokens int `json:"cachedInputTokens,omitempty"`
}
TurnUsage carries the per-turn token counts reported on completion.
type UserInput ¶
type UserInput struct {
Type UserInputKind `json:"type"`
// Fields by type; absent fields are omitted on the wire.
Text string `json:"text,omitempty"`
URL string `json:"url,omitempty"`
Path string `json:"path,omitempty"`
Name string `json:"name,omitempty"`
}
UserInput is the tagged union carried by TurnStartParams.Input.
type UserInputKind ¶
type UserInputKind string
UserInputKind enumerates the variants of UserInput the adapter emits. Only the "text" variant is wired today; image variants round-trip via Extras.
const ( // UserInputKindText carries plain text input. UserInputKindText UserInputKind = "text" // UserInputKindImage carries remote image input. UserInputKindImage UserInputKind = "image" // UserInputKindLocalImage carries local image input. UserInputKindLocalImage UserInputKind = "localImage" // UserInputKindSkill carries a skill reference input. UserInputKindSkill UserInputKind = "skill" // UserInputKindMention carries a structured mention input. UserInputKindMention UserInputKind = "mention" )