Documentation
¶
Index ¶
- Constants
- Variables
- func FormatOpenCodeConfig(providers []secrets.LLMProviderData) ([]byte, error)
- func MessageModelOverrideWire(m *session.ModelRef) (wire map[string]string, ok bool)
- func ParseHistoryStream(r io.Reader, workspaceID string) (msgs []session.Message, changedFilesPerMsg [][]string, downgraded int, ...)
- func ParseHistoryWire(body []byte, workspaceID string) (msgs []session.Message, changedFilesPerMsg [][]string, downgraded int, ...)
- func ParseMessageWire(body []byte) (session.Message, []string, error)
- func ParseSessionListWire(body []byte, workspaceID string) ([]session.Session, error)
- func ParseSessionWire(body []byte, workspaceID string) (*session.Session, error)
- func Register()
- func SplitModelRef(model string) (providerID, modelID string, err error)
- func StripImageDataURLs(raw []byte) []byte
- type ABITranslator
- type AcpCommand
- type AcpContentBlock
- type AcpLocation
- type AcpPlanEntry
- type AcpToolCall
- type AcpToolContent
- type AcpToolContentKind
- type AcpToolKind
- type AcpToolStatus
- type AcpUpdate
- type AcpUpdateKind
- type AcpUsage
- type Adapter
- func (a *Adapter) Abort(ctx context.Context, userID, workspaceID, sessionID string) error
- func (a *Adapter) AnswerQuestion(ctx context.Context, userID, workspaceID, requestID string, answers [][]string) error
- func (a *Adapter) Capabilities() []session.Capability
- func (a *Adapter) ClientEventsFromEvent(eventType string, rawData string) []session.Event
- func (a *Adapter) ContextUsageFromEvent(eventType string, rawData string) (string, *session.ContextUsage, bool)
- func (a *Adapter) CountMessages(ctx context.Context, userID, workspaceID, sessionID string) (int, error)
- func (a *Adapter) CreateSession(ctx context.Context, userID, workspaceID, title string) (*session.Session, error)
- func (a *Adapter) DeleteSession(ctx context.Context, userID, workspaceID, sessionID string) error
- func (a *Adapter) FormatProviderConfig(providers []agent.LLMProviderData) ([]byte, error)
- func (a *Adapter) GetHistory(ctx context.Context, userID, workspaceID, sessionID string) ([]session.Message, error)
- func (a *Adapter) GetHistoryPage(ctx context.Context, userID, workspaceID, sessionID string, limit int) ([]session.Message, error)
- func (a *Adapter) GetSession(ctx context.Context, userID, workspaceID, sessionID string) (*session.Session, error)
- func (a *Adapter) ListAvailableModels(ctx context.Context, userID, workspaceID string) ([]session.ModelInfo, error)
- func (a *Adapter) ListPending(ctx context.Context, userID, workspaceID, sessionID string) ([]session.InputRequest, error)
- func (a *Adapter) ListSessions(ctx context.Context, userID, workspaceID string) ([]session.Session, error)
- func (a *Adapter) RejectInput(ctx context.Context, userID, workspaceID, requestID string) error
- func (a *Adapter) RenameSession(ctx context.Context, userID, workspaceID, sessionID, title string) error
- func (a *Adapter) ReplyPermission(ctx context.Context, userID, workspaceID, requestID, reply, message string) error
- func (a *Adapter) RetryFromEvent(eventType string, rawData string) (string, *agent.ClientRetryStatus, bool)
- func (a *Adapter) Send(ctx context.Context, userID, workspaceID, sessionID, text string, ...) (*session.Message, error)
- func (a *Adapter) SendAsync(ctx context.Context, userID, workspaceID, sessionID, text string, ...) (string, error)
- func (a *Adapter) SetModel(ctx context.Context, userID, workspaceID, sessionID string, ...) error
- func (a *Adapter) SetSessionModel(ctx context.Context, userID, workspaceID, sessionID string, ...) error
- func (a *Adapter) Stream(ctx context.Context, userID, workspaceID, sessionID string) (<-chan session.Event, error)
- func (a *Adapter) ValidateCredentials(rawConfig []byte) (*agent.CredentialCheckResult, error)
- func (a *Adapter) VerifyDelivery(ctx context.Context, userID, workspaceID, sessionID, text string, ...) (bool, bool, error)
- type AdapterOption
- type AdapterV1
- func (a *AdapterV1) GetHistory(ctx context.Context, userID, workspaceID, sessionID string) ([]session.Message, error)
- func (a *AdapterV1) GetHistoryPage(ctx context.Context, userID, workspaceID, sessionID string, limit int) ([]session.Message, error)
- func (a *AdapterV1) VerifyDelivery(ctx context.Context, userID, workspaceID, sessionID, text string, ...) (delivered, ambiguous bool, err error)
- type AdapterV2
- func (a *AdapterV2) GetHistory(ctx context.Context, userID, workspaceID, sessionID string) ([]session.Message, error)
- func (a *AdapterV2) GetHistoryPage(ctx context.Context, userID, workspaceID, sessionID string, limit int) ([]session.Message, error)
- func (a *AdapterV2) VerifyDelivery(ctx context.Context, userID, workspaceID, sessionID, text string, ...) (delivered, ambiguous bool, err error)
- type AgentClient
- type AutomationResponse
- type Capabilities
- type Client
- func (c *Client) Abort(ctx context.Context, sessionID string) error
- func (c *Client) AvailableModels(ctx context.Context) ([]session.ModelInfo, error)
- func (c *Client) Capabilities(ctx context.Context) (Capabilities, error)
- func (c *Client) DisposeInstance(ctx context.Context) error
- func (c *Client) GetSessionStatuses(ctx context.Context) (map[string]string, error)
- func (c *Client) InterruptV2(ctx context.Context, sessionID string) error
- func (c *Client) ListModels(ctx context.Context) ([]byte, error)
- func (c *Client) MessagesV2(ctx context.Context, sessionID string) ([]V2Message, error)
- func (c *Client) ModelInfo(ctx context.Context, providerID, modelID string) (*ModelInfo, error)
- func (c *Client) PatchConfig(ctx context.Context, config map[string]any) error
- func (c *Client) PlatformSessionDelete(ctx context.Context, saToken, workspaceID, sessionID string) error
- func (c *Client) PromptV2(ctx context.Context, sessionID, text string, delivery V2Delivery) (*V2PromptResponse, error)
- func (c *Client) PromptV2WithModel(ctx context.Context, sessionID, text string, delivery V2Delivery, ...) (*V2PromptResponse, error)
- func (c *Client) PushCredentials(ctx context.Context, providers []secrets.LLMProviderData) error
- func (c *Client) SessionArchive(ctx context.Context, saToken, workspaceID, sessionID string, archived bool) error
- func (c *Client) SessionArchivedSet(ctx context.Context, saToken, workspaceID string) ([]string, error)
- func (c *Client) SessionContextCount(ctx context.Context, sessionID string) (int, error)
- func (c *Client) SessionCreate(ctx context.Context, title string) (string, error)
- func (c *Client) SessionDelete(ctx context.Context, sessionID string) error
- func (c *Client) SessionExists(ctx context.Context, sessionID string) (bool, error)
- func (c *Client) SessionList(ctx context.Context) ([]SessionSummary, error)
- func (c *Client) SessionListRaw(ctx context.Context) ([]byte, error)
- func (c *Client) SessionMessageCount(ctx context.Context, sessionID string) (int, error)
- func (c *Client) SessionMessagesRaw(ctx context.Context, sessionID string, limit int, cursor string) ([]byte, string, error)
- func (c *Client) SessionModelRef(ctx context.Context, sessionID string) (*session.ModelRef, error)
- func (c *Client) SessionPromptTokens(ctx context.Context, sessionID string) int64
- func (c *Client) SessionRename(ctx context.Context, sessionID, title string) error
- func (c *Client) SessionSend(ctx context.Context, sessionID, text, model string, images []ImageAttachment) (*SendResult, error)
- func (c *Client) SessionSummarize(ctx context.Context, sessionID, providerID, modelID string) error
- func (c *Client) StageCredentials(ctx context.Context, providers []secrets.LLMProviderData) error
- func (c *Client) TriggerCreate(ctx context.Context, saToken, workspaceID string, trigger json.RawMessage) (*AutomationResponse, error)
- func (c *Client) TriggerDelete(ctx context.Context, saToken, workspaceID, id string) (*AutomationResponse, error)
- func (c *Client) TriggerFires(ctx context.Context, saToken, workspaceID, id string) (*AutomationResponse, error)
- func (c *Client) TriggerGet(ctx context.Context, saToken, workspaceID, id string) (*AutomationResponse, error)
- func (c *Client) TriggerList(ctx context.Context, saToken, workspaceID string) (*AutomationResponse, error)
- func (c *Client) TriggerRotateWebhookSecret(ctx context.Context, saToken, workspaceID, id string) (*AutomationResponse, error)
- func (c *Client) TriggerUpdate(ctx context.Context, saToken, workspaceID, id string, patch json.RawMessage) (*AutomationResponse, error)
- func (c *Client) WorkflowCreate(ctx context.Context, saToken, workspaceID string, workflow json.RawMessage) (*AutomationResponse, error)
- func (c *Client) WorkflowDelete(ctx context.Context, saToken, workspaceID, id string) (*AutomationResponse, error)
- func (c *Client) WorkflowGet(ctx context.Context, saToken, workspaceID, id string) (*AutomationResponse, error)
- func (c *Client) WorkflowList(ctx context.Context, saToken, workspaceID string) (*AutomationResponse, error)
- func (c *Client) WorkflowRun(ctx context.Context, saToken, workspaceID, id string, input json.RawMessage) (*AutomationResponse, error)
- func (c *Client) WorkflowRuns(ctx context.Context, saToken, workspaceID, id string) (*AutomationResponse, error)
- func (c *Client) WorkflowUpdate(ctx context.Context, saToken, workspaceID, id string, patch json.RawMessage) (*AutomationResponse, error)
- type ConfigWriter
- func (w *ConfigWriter) Apply(in agent.AgentConfigInput) (bool, error)
- func (w *ConfigWriter) HasRelay() bool
- func (w *ConfigWriter) Rebuild() error
- func (w *ConfigWriter) SetMCPServers(servers []MCPServerEntry)
- func (w *ConfigWriter) SetModel(model string)
- func (w *ConfigWriter) SetProviders(formattedConfig []byte) error
- func (w *ConfigWriter) SetRelay(url string, models []RelayModel)
- type ConfigWriterOption
- type Dialect
- func (d *Dialect) EventStreamPath() string
- func (d *Dialect) IsPermissionAsked(eventType string) bool
- func (d *Dialect) IsPermissionResolved(eventType string) bool
- func (d *Dialect) IsQuestionAsked(eventType string) bool
- func (d *Dialect) IsQuestionResolved(eventType string) bool
- func (d *Dialect) IsSessionBusy(eventType string, properties json.RawMessage) bool
- func (d *Dialect) IsSessionIdle(eventType string, properties json.RawMessage) bool
- func (d *Dialect) KindByPrefix(requestID string) string
- func (d *Dialect) ParsePermissionListItem(raw json.RawMessage) (*agent.PermissionRequest, error)
- func (d *Dialect) ParsePermissionRequest(eventType string, properties json.RawMessage) (*agent.PermissionRequest, error)
- func (d *Dialect) ParseQuestionListItem(raw json.RawMessage) (*agent.QuestionRequest, error)
- func (d *Dialect) ParseQuestionRequest(eventType string, properties json.RawMessage) (*agent.QuestionRequest, error)
- func (d *Dialect) ParseSessionStatus(properties json.RawMessage) (string, string, error)
- func (d *Dialect) PermissionListPath() string
- func (d *Dialect) PermissionReplyPath(requestID string) string
- func (d *Dialect) QuestionListPath() string
- func (d *Dialect) QuestionRejectPath(requestID string) string
- func (d *Dialect) QuestionReplyPath(requestID string) string
- func (d *Dialect) SessionAbortPath(sessionID string) string
- func (d *Dialect) SessionCreatePath() string
- func (d *Dialect) SessionGetPath(sessionID string) string
- func (d *Dialect) SessionListPath() string
- func (d *Dialect) SessionMessagePath(sessionID string) string
- func (d *Dialect) SessionPromptAsyncPath(sessionID string) string
- type ImageAttachment
- type MCPServerEntry
- type ModelInfo
- type OpenCodeAgent
- type Option
- type PasswordResolver
- type PodIPResolver
- type RelayModel
- type SendResult
- type SessionSummary
- type V2ContentPart
- type V2Delivery
- type V2Message
- type V2ModelInMessage
- type V2ModelRef
- type V2PromptResponse
- type V2Tokens
- type V2ToolState
- type WorkspaceClient
- func (w *WorkspaceClient) DisposeInstance(ctx context.Context, userID, workspaceID string) error
- func (w *WorkspaceClient) GetSessionStatuses(ctx context.Context, userID, workspaceID string) (map[string]string, error)
- func (w *WorkspaceClient) ListModels(ctx context.Context, userID, workspaceID string) ([]byte, error)
- func (w *WorkspaceClient) PatchConfig(ctx context.Context, userID, workspaceID string, config map[string]any) error
- func (w *WorkspaceClient) StageCredentials(ctx context.Context, userID, workspaceID string, ...) error
- type WorkspaceClientOption
Constants ¶
const ( V2DeliveryQueue = agent.V2DeliveryQueue V2DeliverySteer = agent.V2DeliverySteer )
Re-export V2 delivery constants.
Variables ¶
var ( ErrV2PromptConflict = agent.ErrV2PromptConflict ErrV2SessionNotFound = agent.ErrV2SessionNotFound )
V2 prompt/interrupt error sentinels. These are distinct from the V1 V2 prompt/interrupt error sentinels re-exported from pkg/agent (the canonical location). Callers branch on these to decide retry vs. surface-to-user.
var ErrNoRunningPod = agent.ErrNoRunningPod
ErrNoRunningPod is re-exported from pkg/agent (the canonical location). Callers should use agent.ErrNoRunningPod; this alias exists for backward compatibility with code that still imports this package.
ErrPendingUnavailable is returned by ListPending when the agent's pending-input endpoints could not be queried (transport failure or a non-success response other than 404-not-implemented). Callers MUST treat this as "pending set unknown" — never as an authoritative empty. The SSE input snapshot maps it to snapshot_ok:false so a failed fetch cannot commit an empty pending set over live prompts (PR #852 review C1).
Functions ¶
func FormatOpenCodeConfig ¶
func FormatOpenCodeConfig(providers []secrets.LLMProviderData) ([]byte, error)
FormatOpenCodeConfig renders a slice of validated LLMProviderData into the JSON shape opencode accepts.
**Schema** (evidence-driven; established by live cluster probe in worklog 0128. Do NOT change without re-validating against a running opencode):
{
"$schema": "https://opencode.ai/config.json",
"provider": { <-- SINGULAR (not "providers")
"<id>": {
"options": { <-- direct, NO aisdk wrapper
"apiKey": "...", <-- the credential
"baseURL": "..." <-- in options, NOT in a
}, separate `endpoint` object
"models": { "<id>": { "name": "..." } }
}
},
"model": "<id>/<modelID>"
}
What pre-fix code generated, and why opencode rejected it:
- top-level key was `providers` (plural) → ConfigInvalidError
- apiKey lived at options.aisdk.provider.apiKey → ConfigInvalidError
- baseURL lived at endpoint.url → silently ignored (chat requests went to api.openai.com instead of the operator's endpoint)
The function is pure — no side effects, no filesystem access.
Returns an error if providers is empty (callers MUST check for this — opencode treats an empty config differently and a "no-op write of an empty config" is a bug).
func MessageModelOverrideWire ¶ added in v0.34.1
MessageModelOverrideWire returns the per-prompt model OBJECT wire form for the message route ({"modelID","providerID"}), or ok=false when the ref is unexpressible there (the field must be omitted so the session default applies — same rules as modelOverride). Exported for the agentd actor seam (#1372): the Act send path builds the identical body.
func ParseHistoryStream ¶ added in v0.14.4
func ParseHistoryStream(r io.Reader, workspaceID string) (msgs []session.Message, changedFilesPerMsg [][]string, downgraded int, err error)
ParseHistoryStream decodes + translates an opencode history array from an io.Reader using a streaming json.Decoder. It does NOT buffer the whole body — peak memory is O(largest single message), not O(total history size). This removes the silent-truncation failure mode that affected sessions larger than the previous fixed readBody cap (issue #737).
Resilience is identical to ParseHistoryWire (issue #730): a message that fails to decode is downgraded to a session.MessageSystem notice and counted in `downgraded`; the rest translate normally.
func ParseHistoryWire ¶ added in v0.14.0
func ParseHistoryWire(body []byte, workspaceID string) (msgs []session.Message, changedFilesPerMsg [][]string, downgraded int, err error)
ParseHistoryWire is the testable boundary: bytes in, contract out. Used by Adapter.GetHistory after the HTTP round-trip. Returns the translated messages AND a parallel slice of changed-file path lists (one entry per message; nil for messages with no patch part). The caller uses the changed-files to produce FileChange parts via filediff.Producer.
Exported for the package's own test consumers (translate_test.go, adapter_test.go).
Resilience (issues #730, #737): delegates to ParseHistoryStream which uses a streaming json.Decoder — no body-size cap, no buffering of the full array. Each message is decoded independently; a message that fails to decode (e.g. a future opencode wire-shape change in one part) is downgraded to a session.MessageSystem notice rather than failing the entire history. If the body is truncated mid-stream, the messages decoded so far are returned with no error (graceful partial result).
The returned `downgraded` count is the number of messages that were degraded to system notices. Callers (Adapter.GetHistory) log it so operators have a signal when wire-shape drift is happening (Rule 3: no swallowed errors).
func ParseMessageWire ¶ added in v0.34.1
ParseMessageWire is the single-message boundary for the synchronous send response (POST /session/:id/message): bytes in, contract message + changed-file list out. Exported so the agentd actor seam (#1372) and the adapter path share ONE translation — the REST response is identical bytes in both regimes.
func ParseSessionListWire ¶ added in v0.14.0
ParseSessionListWire is the testable boundary for GET /session.
opencode 1.18.10 returns a bare array; some earlier versions wrap in {data: [...]}. We try the wrapped format first (parse succeeds → use it, including when Data is empty); fall back to the bare array only when the wrapped parse fails (body was not an object).
func ParseSessionWire ¶ added in v0.14.0
ParseSessionWire is the testable boundary for GET /session/:id.
func SplitModelRef ¶ added in v0.30.0
SplitModelRef splits a "provider/model" reference into the V1 override pair. First-segment routing (opencode's own rule — the adapter's modelOverride): "a/b/c" routes via "a" with model "b/c". A bare flat ID is unexpressible (opencode parses it as provider-with-empty-model) and is rejected before any wire call.
func StripImageDataURLs ¶ added in v0.31.0
StripImageDataURLs removes image data URLs from a raw opencode message array — the MCP session_read surface (#1307 review r1 finding 3): the raw store previously shipped multi-megabyte base64 blobs to MCP consumers. Every image-bearing dict (mime image/* or a data:image/ url/uri) keeps its metadata, loses its url/uri bytes, and gains an explicit imageOmitted marker so the record stays honest. All other content is preserved. Non-image input round-trips unchanged.
Types ¶
type ABITranslator ¶ added in v0.26.0
ABITranslator translates raw opencode SSE payloads into ABI contract events. It satisfies the sessionstate.EventParser seam structurally (cmd/workspace-agentd/sessionstate imports nothing from here; agentd wiring injects it). Now is injectable for deterministic goldens.
func (*ABITranslator) Parse ¶ added in v0.26.0
Parse implements the EventParser seam: ok=false means "nothing projectable" (ignored or empty), err signals a payload that CLAIMED to be projectable but failed to decode (wire drift — logged by the authority, never fatal). Parse must be called on a *ABITranslator when the session.next.tool memo is to work across calls (the value-receiver form would copy the map header each event; the interface seam holds the pointer).
CONTRACT: (nil, true, err) — a frame claiming projectability whose properties fail to decode. Callers MUST treat err as governing over ok (the authority's Ingest does); feeding the nil event into a fold panics. Wire drift landing here is counted, never fatal.
type AcpCommand ¶ added in v0.34.12
type AcpCommand struct {
Name string `json:"name"`
Description string `json:"description,omitempty"`
}
AcpCommand is one available-commands entry.
type AcpContentBlock ¶ added in v0.34.12
type AcpContentBlock struct {
Type string `json:"type"` // "text" (image/audio/resource_* are contract Tool-output per 0049)
Text string `json:"text,omitempty"`
}
AcpContentBlock is one streamed content block (ACP shape: the chunk kinds carry one block each; text is the only variant opencode emits).
type AcpLocation ¶ added in v0.34.12
AcpLocation is one toolCall location (path + optional line).
type AcpPlanEntry ¶ added in v0.34.12
type AcpPlanEntry struct {
Content string `json:"content"`
Priority string `json:"priority,omitempty"` // high|medium|low
Status string `json:"status,omitempty"` // pending|in_progress|completed
}
AcpPlanEntry is one plan entry (the never-emitted variant).
type AcpToolCall ¶ added in v0.34.12
type AcpToolCall struct {
ToolCallID string `json:"toolCallId"`
Title string `json:"title,omitempty"`
Kind AcpToolKind `json:"kind,omitempty"`
Status AcpToolStatus `json:"status,omitempty"`
Error string `json:"error,omitempty"`
Locations []AcpLocation `json:"locations,omitempty"`
RawInput json.RawMessage `json:"rawInput,omitempty"`
RawOutput json.RawMessage `json:"rawOutput,omitempty"`
Content []AcpToolContent `json:"content,omitempty"`
StartedAt *time.Time `json:"startedAt,omitempty"`
CompletedAt *time.Time `json:"completedAt,omitempty"`
}
AcpToolCall is the toolCall shape shared by tool_call and tool_call_update (ACP discriminator fields; RawInput/RawOutput are pre-extracted JSON like the contract's ToolPart fields).
func AcpToolCallFromNative ¶ added in v0.34.12
func AcpToolCallFromNative(t *ocTool) *AcpToolCall
AcpToolCallFromNative converts a native ocTool (the opencode history/ SSE dialect) to the vocabulary shape. This is the Stage A input seam for the tool event class: status strings normalize to ACP names, the kind is inferred from the tool name (todowrite -> "other"), and times ride through unchanged.
func (*AcpToolCall) FileChange ¶ added in v0.34.12
func (tc *AcpToolCall) FileChange() *session.FileDiff
FileChange converts the first diff content entry to the contract FileDiff (unified patch from old->new). Returns nil when the call carries no diff (creates never do — design 0063 §3.3).
func (*AcpToolCall) ToToolPart ¶ added in v0.34.12
func (tc *AcpToolCall) ToToolPart() *session.ToolPart
ToToolPart maps the toolCall state machine to the contract ToolPart. Status defaults to pending; Title carries the tool name (the ACP field opencode fills with the tool name or the command line).
type AcpToolContent ¶ added in v0.34.12
type AcpToolContent struct {
Kind AcpToolContentKind `json:"type"`
Path string `json:"path,omitempty"`
OldText string `json:"oldText,omitempty"`
NewText string `json:"newText,omitempty"`
Text string `json:"text,omitempty"` // content/terminal variants
}
AcpToolContent is one toolCall content entry (content|diff|terminal). Diff entries carry old/new text; on edit-existing operations they are granular hunks, on creates absent entirely (the permission request is the only diff carrier there) — design 0063 §3.3.
type AcpToolContentKind ¶ added in v0.34.12
type AcpToolContentKind string
AcpToolContentKind discriminates toolCall content entries.
const ( AcpToolContentContent AcpToolContentKind = "content" AcpToolContentDiff AcpToolContentKind = "diff" AcpToolContentTerminal AcpToolContentKind = "terminal" )
type AcpToolKind ¶ added in v0.34.12
type AcpToolKind string
AcpToolKind is the toolCall kind union (ACP wire values).
const ( AcpToolKindRead AcpToolKind = "read" AcpToolKindEdit AcpToolKind = "edit" AcpToolKindDelete AcpToolKind = "delete" AcpToolKindMove AcpToolKind = "move" AcpToolKindSearch AcpToolKind = "search" AcpToolKindExecute AcpToolKind = "execute" AcpToolKindThink AcpToolKind = "think" AcpToolKindFetch AcpToolKind = "fetch" AcpToolKindSwitchMode AcpToolKind = "switch_mode" AcpToolKindOther AcpToolKind = "other" )
func AcpToolKindFromName ¶ added in v0.34.12
func AcpToolKindFromName(name string) AcpToolKind
AcpToolKindFromName infers the ACP kind from a tool name — the kind table. todowrite pins to "other" (never "plan": opencode emits todos as generic tool calls, design 0063 §3.2). Unknown names map to "other" (the ACP catch-all), never dropped.
type AcpToolStatus ¶ added in v0.34.12
type AcpToolStatus string
AcpToolStatus is the toolCall status state machine (ACP wire values).
const ( AcpToolStatusPending AcpToolStatus = "pending" AcpToolStatusInProgress AcpToolStatus = "in_progress" AcpToolStatusCompleted AcpToolStatus = "completed" AcpToolStatusFailed AcpToolStatus = "failed" )
func AcpToolStatusFromNative ¶ added in v0.34.12
func AcpToolStatusFromNative(s string) AcpToolStatus
AcpToolStatusFromNative normalizes opencode's native tool-status strings to ACP names ("running" -> "in_progress", "error" -> "failed"); unknown values map to pending (the safe default the inline translateToolStatus used — UI renders "working").
func AcpToolStatusFromNativeStrict ¶ added in v0.34.12
func AcpToolStatusFromNativeStrict(s string) (AcpToolStatus, bool)
AcpToolStatusFromNativeStrict is the recognizing form: ok=false for unrecognized status strings. Callers with their own unknown-default (e.g. the ABI translator's UNSPECIFIED) use this so the vocabulary does not silently coerce their miss into pending.
func (AcpToolStatus) ToContractStatus ¶ added in v0.34.12
func (s AcpToolStatus) ToContractStatus() session.ToolStatus
ToContractStatus maps an ACP status to the contract ToolStatus 1:1.
type AcpUpdate ¶ added in v0.34.12
type AcpUpdate struct {
Kind AcpUpdateKind `json:"sessionUpdate"`
MessageID string `json:"messageId,omitempty"`
Content AcpContentBlock `json:"content,omitempty"`
ToolCall *AcpToolCall `json:"toolCall,omitempty"`
Commands []AcpCommand `json:"availableCommands,omitempty"`
Usage *AcpUsage `json:"usage,omitempty"`
Plan []AcpPlanEntry `json:"entries,omitempty"`
}
AcpUpdate is one sessionUpdate event in the internal vocabulary. Exactly one payload field is meaningful per Kind.
func AcpUpdateFromPart ¶ added in v0.34.12
AcpUpdateFromPart maps a contract Part back to the vocabulary (the reverse direction; used by consumers that must emit ACP-shaped events from contract state). Text maps to agent_message_chunk — NEVER user_message_chunk (replay-only pin: that kind has no producer in either direction here; it is ingest-only from fork/load replay).
type AcpUpdateKind ¶ added in v0.34.12
type AcpUpdateKind string
AcpUpdateKind is the sessionUpdate discriminator (ACP wire names).
const ( AcpUpdateAgentMessageChunk AcpUpdateKind = "agent_message_chunk" AcpUpdateAgentThoughtChunk AcpUpdateKind = "agent_thought_chunk" AcpUpdateUserMessageChunk AcpUpdateKind = "user_message_chunk" // replay-only AcpUpdateToolCall AcpUpdateKind = "tool_call" AcpUpdateToolCallUpdate AcpUpdateKind = "tool_call_update" AcpUpdateAvailableCommands AcpUpdateKind = "available_commands_update" AcpUpdateUsage AcpUpdateKind = "usage_update" // session-level, never a Part AcpUpdatePlan AcpUpdateKind = "plan" // zod-only: never emitted by opencode 1.18.x )
func NativeChunkKinds ¶ added in v0.34.12
func NativeChunkKinds() []AcpUpdateKind
NativeChunkKinds returns the chunk kinds the native (SSE dialect) direction produces. user_message_chunk is deliberately absent: it is replay-only (fork/load), and the native stream never echoes user input ([T:fork 13.86-13.87] — emitted at fork/load only, design 0063 §3.2). Structural pin: a future zero-echo assumption cannot silently take the replay path because this set is the producer's contract.
func (AcpUpdateKind) IsNeverEmittedByNative ¶ added in v0.34.12
func (k AcpUpdateKind) IsNeverEmittedByNative() bool
IsNeverEmittedByNative reports kinds the native direction cannot synthesize. plan is schema-present but opencode 1.18.x emits todowrite as a generic tool_call (kind "other") — the plan variant never fires ([T:lifecycle 15.76], design 0063 §5.5).
type AcpUsage ¶ added in v0.34.12
type AcpUsage struct {
Used int64 `json:"used"`
Size int64 `json:"size"`
Cost *session.Cost `json:"cost,omitempty"`
Raw json.RawMessage `json:"-"`
}
AcpUsage is the usage_update payload (session-level context gauge; NEVER a Part — design 0063 §3.2 maps it to ContextUsage wiring).
type Adapter ¶ added in v0.14.0
type Adapter struct {
// contains filtered or unexported fields
}
Adapter implements agent.Adapter for the opencode runtime.
Construction: NewAdapter(pw, ip, logger, opts...) resolves each call to the workspace's pod IP + password via the supplied resolvers, then delegates to the low-level *Client. The shared HTTP client pools connections across all workspaces.
Translation: every method translates opencode's wire shapes to the platform contract via the pure functions in translate.go. The translator never sees an HTTP response — it gets bytes — so it is independently testable.
Design 0049 §4.6: 16 methods. AgentConfigWriter is intentionally NOT implemented here — see the agent.Adapter doc comment for why (the two seams run in different processes with different filesystem capabilities).
Credential methods (FormatProviderConfig, ValidateCredentials) delegate to the existing OpenCodeAgent (agent.AgentRuntime) to avoid behavior divergence. R3 from PR #714 review: duplication between Adapter and OpenCodeAgent was a maintenance hazard; delegation keeps one source of truth.
func NewAdapter ¶ added in v0.14.0
func NewAdapter(pw PasswordResolver, ip PodIPResolver, logger *zap.Logger, opts ...AdapterOption) *Adapter
NewAdapter constructs an opencode Adapter that resolves workspace → podIP + password on each call. The httpCli is shared across all calls for connection pooling; port defaults to agentd.AgentPort.
func (*Adapter) AnswerQuestion ¶ added in v0.30.0
func (a *Adapter) AnswerQuestion(ctx context.Context, userID, workspaceID, requestID string, answers [][]string) error
AnswerQuestion posts the question-reply schema verbatim ({answers: string[][]}) — the endpoint is additionalProperties:false.
func (*Adapter) Capabilities ¶ added in v0.14.0
func (a *Adapter) Capabilities() []session.Capability
func (*Adapter) ClientEventsFromEvent ¶ added in v0.16.1
ClientEventsFromEvent implements agent.Adapter (US-65.8): translates one raw agent SSE event into zero or more CONTRACT events for client consumption. Clients render contract shapes only — the agent's wire names, envelopes, and part shapes stay behind this seam.
Translation table (opencode → pkg/session):
- message.part.delta → EventPartDelta (streaming text)
- message.part.updated → EventPartEnd with the translated Part (snapshot: tool state, reasoning/text updates); a step-finish part instead yields EventSessionUpdated carrying ContextUsage (per-step occupancy semantics preserved)
- session.updated → EventSessionUpdated {Title, ParentID} — NEVER ContextUsage: its tokens are cumulative
- session.error, session.next.step.failed → EventError
V2-queue turns (design 0052, opencode ≥1.18.15) emit ONLY the session.next.* taxonomy — V1 part events never fire for them:
- session.next.text.delta → EventPartDelta (streaming text)
- session.next.text.ended → EventPartEnd (final text part)
- session.next.prompted → EventPartEnd (user echo: the admitted prompt text — the same signal the V1 echo carried, which the frontend's queued-message strip matches on)
- session.next.step.ended → EventSessionUpdated with ContextUsage from the step's tokens (per-step occupancy)
Events with no client-facing signal (the majority — heartbeats, status, plugin/file events) return nil after a string-compare type check; the streaming hot path never pays a parse for them.
func (*Adapter) ContextUsageFromEvent ¶ added in v0.15.12
func (a *Adapter) ContextUsageFromEvent(eventType string, rawData string) (string, *session.ContextUsage, bool)
ContextUsageFromEvent implements agent.Adapter. The opencode semantic: live prompt occupancy = input + cache.read + cache.write for the step that just finished (wire.Tokens.PromptTokens). Window is left unset — per-model windows come from ListAvailableModels, not usage events.
func (*Adapter) CountMessages ¶ added in v0.34.6
func (a *Adapter) CountMessages(ctx context.Context, userID, workspaceID, sessionID string) (int, error)
CountMessages walks the V1 message pagination and returns the total message count (#1481 — the session_index rebuild's ground truth). Pages are decoded as raw JSON values only (no part parsing — counting needs lengths, not shapes). The cursor contract (?limit&before= + X-Next-Cursor) lives entirely inside the seam.
func (*Adapter) CreateSession ¶ added in v0.14.0
func (*Adapter) DeleteSession ¶ added in v0.14.0
func (*Adapter) FormatProviderConfig ¶ added in v0.14.0
func (a *Adapter) FormatProviderConfig(providers []agent.LLMProviderData) ([]byte, error)
func (*Adapter) GetHistory ¶ added in v0.14.0
func (a *Adapter) GetHistory(ctx context.Context, userID, workspaceID, sessionID string) ([]session.Message, error)
GetHistory returns the full message list (V1 store — the shared adapter's default). Use AdapterV1/AdapterV2 for explicit store paths.
func (*Adapter) GetHistoryPage ¶ added in v0.16.1
func (a *Adapter) GetHistoryPage(ctx context.Context, userID, workspaceID, sessionID string, limit int) ([]session.Message, error)
GetHistoryPage returns the NEWEST limit messages (V1 store — default).
func (*Adapter) GetSession ¶ added in v0.14.0
func (*Adapter) ListAvailableModels ¶ added in v0.14.0
func (*Adapter) ListPending ¶ added in v0.14.0
func (*Adapter) ListSessions ¶ added in v0.14.0
func (*Adapter) RejectInput ¶ added in v0.30.0
RejectInput dismisses a pending ask without an answer (#1313). The harness PREFIX-VALIDATES request IDs (a cross-kind post is a 400 Params error, never a 404 — captured live, 4a r6/r8): a que_ id rejects on the question endpoint only and its 404 is the absence signal callers consume (S6); a per_ id goes straight to the permission reply; unprefixed ids keep the legacy probe order.
func (*Adapter) RenameSession ¶ added in v0.14.0
func (*Adapter) ReplyPermission ¶ added in v0.30.0
func (a *Adapter) ReplyPermission(ctx context.Context, userID, workspaceID, requestID, reply, message string) error
ReplyPermission posts the permission-reply schema verbatim ({reply, message?}).
func (*Adapter) RetryFromEvent ¶ added in v0.16.1
func (a *Adapter) RetryFromEvent(eventType string, rawData string) (string, *agent.ClientRetryStatus, bool)
RetryFromEvent implements agent.Adapter: decodes an agent backoff/ retry notification into the platform retry shape. Retry detail is UI-shaped by nature and rides the platform session.status SSE event rather than the contract (no contract change needed).
func (*Adapter) SetSessionModel ¶ added in v0.25.6
func (a *Adapter) SetSessionModel(ctx context.Context, userID, workspaceID, sessionID string, m *session.ModelRef) error
SetSessionModel sets the session's default model via the V2 /model route. This is the ONLY model-selection mechanism under V2 delivery: the V2 prompt endpoint strips per-prompt model overrides entirely (verified live 2026-08-29: a prompt carrying model {id:"totally-bogus- model"} admitted cleanly and ran on the session default — the field is not in the endpoint's schema). The platform therefore applies a message's model selection to the SESSION before admission, matching the SPA's own UX (pick a model → session default changes).
func (*Adapter) Stream ¶ added in v0.14.0
func (a *Adapter) Stream(ctx context.Context, userID, workspaceID, sessionID string) (<-chan session.Event, error)
Stream subscribes to the workspace's /event SSE endpoint, translates each event to session.Event, and sends on the returned channel. The channel closes when the context is canceled or the upstream closes the connection. Unknown event types are dropped (not sent on the channel). Scanner errors (connection breakage) are emitted as session.EventError events before the channel closes.
Thread-safety: each Stream call opens its own HTTP connection. Safe for concurrent use across workspaces.
func (*Adapter) ValidateCredentials ¶ added in v0.14.0
func (a *Adapter) ValidateCredentials(rawConfig []byte) (*agent.CredentialCheckResult, error)
type AdapterOption ¶ added in v0.14.0
type AdapterOption func(*Adapter)
AdapterOption configures an Adapter at construction.
func WithAdapterHTTPClient ¶ added in v0.14.0
func WithAdapterHTTPClient(hc *http.Client) AdapterOption
WithAdapterHTTPClient injects a shared *http.Client so connections are pooled across all workspace calls. When unset, a tuned default is used (mirrors WorkspaceClient.newTunedHTTPClient).
func WithAdapterPort ¶ added in v0.14.0
func WithAdapterPort(port int) AdapterOption
WithAdapterPort overrides the agent port the Adapter connects to. Defaults to agentd.AgentPort (4096). Used by tests that bind a fake server to a random port; production callers never override.
func WithFileDiffProducer ¶ added in v0.14.0
func WithFileDiffProducer(p *filediff.Producer) AdapterOption
WithFileDiffProducer wires a filediff.Producer so FileChange parts are produced from `git diff` on the workspace PVC. Required for GetHistory and Stream to emit FileChange parts; without it, patch parts are silently dropped (their file paths are still collected but no Patch text is produced). Used by the agentd-side construction; the API-side Adapter has no filesystem access to the PVC and skips this.
type AdapterV1 ¶ added in v0.28.0
type AdapterV1 struct {
*Adapter
}
AdapterV1 is the V1-path adapter. Construct via NewAdapterV1.
func NewAdapterV1 ¶ added in v0.28.0
NewAdapterV1 constructs a V1-path adapter from a shared Adapter.
func (*AdapterV1) GetHistory ¶ added in v0.28.0
func (a *AdapterV1) GetHistory(ctx context.Context, userID, workspaceID, sessionID string) ([]session.Message, error)
GetHistory returns the full message list from the V1 store.
type AdapterV2 ¶ added in v0.28.0
type AdapterV2 struct {
*Adapter
}
AdapterV2 is the V2-path adapter. Construct via NewAdapterV2.
func NewAdapterV2 ¶ added in v0.28.0
NewAdapterV2 constructs a V2-path adapter from a shared Adapter.
func (*AdapterV2) GetHistory ¶ added in v0.28.0
func (a *AdapterV2) GetHistory(ctx context.Context, userID, workspaceID, sessionID string) ([]session.Message, error)
GetHistory returns the full message list from the V2 store.
type AgentClient ¶
type AgentClient interface {
ListModels(ctx context.Context, userID, workspaceID string) ([]byte, error)
PatchConfig(ctx context.Context, userID, workspaceID string, config map[string]any) error
DisposeInstance(ctx context.Context, userID, workspaceID string) error
GetSessionStatuses(ctx context.Context, userID, workspaceID string) (map[string]string, error)
StageCredentials(ctx context.Context, userID, workspaceID string, providers []secrets.LLMProviderData) error
}
AgentClient abstracts all direct opencode HTTP communication at the workspace level (US-29.1). Each method resolves podIP and password internally from the injected resolvers, keeping callers clean of auth concerns. The interface is caller-shaped — consumers ask for what they need, not for a raw HTTP client.
userID is required for workspace ownership verification (the PodIPResolver enforces that the caller owns the workspace before returning the IP).
type AutomationResponse ¶ added in v0.32.0
AutomationResponse is the raw passthrough of one automation API call: status + body verbatim. The trigger/workflow shapes are the platform's evolving API contract (types/workflows.go) — the seam deliberately does NOT re-model them; agentd tools pass JSON through and surface errors verbatim so schema evolution needs no agentd change.
type Capabilities ¶ added in v0.25.3
type Capabilities struct {
// V2PromptRoute is true when POST /api/session/:sid/prompt exists.
V2PromptRoute bool
// ModelRefIDKey is true when Model.Ref serializes as {"id", "providerID"}
// (observed on opencode >= 1.18.15). False means the legacy
// {"modelID", "providerID"} shape (<= 1.18.14). The per-prompt model
// override is silently rejected when the wrong shape is sent (#1119
// stress finding 5) — this probe is what prevents a repeat.
ModelRefIDKey bool
// ModelRefLegacy is true ONLY on a positive legacy probe (the 400
// named ["model"]["modelID"]). It distinguishes "probed legacy" from
// "indeterminate" — the latter defaults to the pinned floor's
// id-key shape (see probeCapabilities).
ModelRefLegacy bool
// Probed is true once a probe completed (successfully or not); callers
// can distinguish "not yet probed" from "probed, route absent".
Probed bool
}
Capabilities is what the adapter needs to know about the opencode binary it is talking to. Upstream does not offer interface stability across patch releases (the v2 route group was deleted in 1.18.10 and revived with a different model-ref schema by 1.18.15 — see #1119), so the adapter detects instead of assuming. Every field must be probed from the live binary; none may be inferred from a version comment.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client communicates with a running opencode instance's HTTP API. It implements credential injection via PUT /auth/:providerID (Control API) and instance disposal via POST /instance/dispose.
Every opencode endpoint — including /auth/* and /instance/* — is gated by HTTP Basic auth with username `agentd.AuthUsername` and the per-pod password mounted at /sandbox-cfg/password (= OPENCODE_SERVER_PASSWORD env var). Calling these endpoints without auth produces 401 + WWW-Authenticate: Basic realm="Secure Area", which is what broke the live credential flow in worklog 0125.
func NewClient ¶
NewClient creates a Client targeting the given opencode base URL.
password is the value mounted at /sandbox-cfg/password inside the sandbox pod and exported to opencode as OPENCODE_SERVER_PASSWORD. It is the SAME secret used by every other agentd → opencode call (see cmd/workspace-agentd/main.go OpenCodeClient). Passing the empty string is allowed (so unit tests that don't need auth-gated paths still work) but will fail against a real opencode server with 401.
func NewLoopbackClient ¶ added in v0.30.0
NewLoopbackClient constructs a seam client for THIS pod's opencode. Keep-alive is deliberately disabled: the pinned opencode's server can silently drop idle pooled connections (live-debugged 2026-09-13 — a reused POST hangs forever on a ghost socket with no established connection and no FIN; fresh connections always complete). Loopback does not need reuse; correctness does.
func (*Client) Abort ¶ added in v0.15.1
Abort calls POST /session/:id/abort on opencode. This is the V1 abort path, which is the only interrupt endpoint that exists on opencode 1.18.10+. The V2 endpoint (POST /api/session/:id/interrupt) was removed in 1.18.10 — the v2/ route group was deleted entirely from packages/opencode/src/server/routes/instance/httpapi/groups/v2/. On 1.18.10 the V2 path returns 204 from a catch-all stub but does nothing (verified live: a long V1 turn keeps running after V2 interrupt). The V1 /abort path returns 200 and actually stops the in-flight turn (verified live: session transitions to idle). Abort stops a session's current turn (V1 abort — the only interrupt route on pinned agents >= 1.18.10). The ONE abort method for every consumer (adapter/proxy interrupt path, agentd tools); the sessionID is validated before URL interpolation — this method is reachable with caller-supplied IDs from the API proxy path.
func (*Client) AvailableModels ¶ added in v0.34.17
AvailableModels returns the parsed model catalog — GET /provider, connected providers only — as the platform's session.ModelInfo shape. This is the seam-level entry point for callers outside the package (the workspace MCP tools): raw bytes stay here, parsed models cross the boundary. An unparseable body is an error; an EMPTY catalog is a valid answer (no connected providers).
func (*Client) Capabilities ¶ added in v0.25.3
func (c *Client) Capabilities(ctx context.Context) (Capabilities, error)
Capabilities returns the probed capabilities, probing lazily once. On transport failure it returns the zero value with Probed=true and the adapter must treat the run as degraded (log loudly, use floor defaults).
func (*Client) DisposeInstance ¶
DisposeInstance triggers POST /instance/dispose, which invalidates all InstanceState caches for the current instance. The opencode process stays alive; the next request triggers a fresh instance load with updated auth.
In-flight LLM calls are aborted. Sessions persist in SQLite.
func (*Client) GetSessionStatuses ¶
GetSessionStatuses calls GET /session/status on opencode and returns the current status of all known sessions. The map key is the session ID; the value is the status type string: "idle", "busy", or "retry".
func (*Client) InterruptV2 ¶ added in v0.12.2
InterruptV2 sends a non-destructive interrupt to an opencode V2 session. It POSTs to /api/session/:sid/interrupt with Basic auth.
The spike confirmed: returns HTTP 204 (No Content) both when a turn is in-flight AND when the session is idle (no-op success). Interrupt is non-destructive (F8): admitted-but-unpromoted queue entries survive and run on the next execution.wake. This replaces the V1 destructive abort that cleared the Redis queue.
func (*Client) ListModels ¶
ListModels calls GET /provider on opencode and returns the raw JSON body. The caller is responsible for parsing the response shape (it varies by opencode version). The body is size-limited to providerCatalogReadLimit.
func (*Client) MessagesV2 ¶ added in v0.25.2
MessagesV2 fetches the V2 store's message list for a session (descending, newest first — same ordering contract as the V1 endpoint). Streaming-decoded with a 64MB bound, mirroring GetHistory's large-transcript posture.
func (*Client) ModelInfo ¶ added in v0.30.0
ModelInfo resolves one model's catalog entry (GET /config/providers): its context-window limit and whether it accepts image input.
func (*Client) PatchConfig ¶
PatchConfig calls PATCH /global/config on opencode with the given config map. Used by SetModel to change the active model.
func (*Client) PlatformSessionDelete ¶ added in v0.34.20
func (c *Client) PlatformSessionDelete(ctx context.Context, saToken, workspaceID, sessionID string) error
PlatformSessionDelete hard-deletes one session of this pod's workspace on BOTH sides (agent store + platform index) via the pod-identity internal API — the same flow the REST DELETE rides. (Client.SessionDelete is the LOCAL agent-side seam delete.)
func (*Client) PromptV2 ¶ added in v0.12.2
func (c *Client) PromptV2(ctx context.Context, sessionID, text string, delivery V2Delivery) (*V2PromptResponse, error)
PromptV2 sends a prompt to an opencode V2 session endpoint with the given delivery mode. It POSTs to /api/session/:sid/prompt using the same Basic auth (opencode + password) as every other opencode call.
The response is admit-and-schedule (non-streaming): opencode queues the prompt internally and returns immediately. The body is read+discarded on non-2xx; on 2xx the data payload is decoded and returned.
F17: the caller MUST NOT supply a message id — this method omits it unconditionally. F18: the prompt body is {text:"..."} (plain string), not the parts-based contract shape; see the v2PromptRequest doc comment.
func (*Client) PromptV2WithModel ¶ added in v0.15.11
func (c *Client) PromptV2WithModel(ctx context.Context, sessionID, text string, delivery V2Delivery, model *V2ModelRef) (*V2PromptResponse, error)
PromptV2WithModel is PromptV2 with an optional per-prompt model override in object form (nil = session default).
func (*Client) PushCredentials ¶
PushCredentials writes each provider's API key to opencode's auth store via PUT /auth/:providerID. This writes to auth.json but does NOT trigger provider state refresh — call DisposeInstance or (future) RefreshProviders afterward to pick up the new credentials.
Returns nil if providers is empty (no-op). Returns the first error encountered; subsequent providers are not attempted.
func (*Client) SessionArchive ¶ added in v0.34.20
func (c *Client) SessionArchive(ctx context.Context, saToken, workspaceID, sessionID string, archived bool) error
SessionArchive sets the platform-level archived marker on one session of this pod's workspace (#1627) via the pod-identity internal API.
func (*Client) SessionArchivedSet ¶ added in v0.34.20
func (c *Client) SessionArchivedSet(ctx context.Context, saToken, workspaceID string) ([]string, error)
SessionArchivedSet returns the archived session IDs of this pod's workspace (#1627) — the session_metadata annotation source.
func (*Client) SessionContextCount ¶ added in v0.30.0
SessionContextCount returns how many messages are currently inside the session's context window (GET /api/session/{id}/context).
func (*Client) SessionCreate ¶ added in v0.30.0
SessionCreate creates a session; title may be empty (omitted — the agent auto-titles).
func (*Client) SessionDelete ¶ added in v0.30.0
SessionDelete removes a session and its message history.
func (*Client) SessionExists ¶ added in v0.34.5
SessionExists is the by-ID existence probe: GET /session/{id} — 2xx means the session exists, 404 means it does not (live-proven on the pinned 1.18.15: GET /session/{unknown} → 404 {"name":"NotFoundError"}), anything else is an error (indeterminate, never a silent false). Status-only by design: no body is parsed, so a corrupted 200 cannot turn existence into a phantom result. Used by send_message's origin validation (#1465) — by-ID beats session-LIST membership there: the #1452 bug class leaves routine sessions live and readable by ID while never appearing in the list.
func (*Client) SessionList ¶ added in v0.30.0
func (c *Client) SessionList(ctx context.Context) ([]SessionSummary, error)
SessionList returns the typed session inventory (GET /session).
func (*Client) SessionListRaw ¶ added in v0.30.0
SessionListRaw returns the unparsed GET /session body (the session_list tool passes it through verbatim — the raw shape is richer than the typed subset and is part of that tool's output contract).
func (*Client) SessionMessageCount ¶ added in v0.30.0
SessionMessageCount walks the V1 message pagination (bounded) and returns the total message count. The bound keeps a pathological session from making the metadata call unbounded.
func (*Client) SessionMessagesRaw ¶ added in v0.30.0
func (c *Client) SessionMessagesRaw(ctx context.Context, sessionID string, limit int, cursor string) ([]byte, string, error)
SessionMessagesRaw returns one page of the V1 message list plus the X-Next-Cursor continuation token ("" when exhausted).
func (*Client) SessionModelRef ¶ added in v0.31.0
SessionModelRef resolves a session's current model (GET /session/{id} → model{id, providerID}; shape pinned by testdata/session_get_1_18_10.json). Returns nil when the session carries no model.
func (*Client) SessionPromptTokens ¶ added in v0.30.0
SessionPromptTokens returns the approximate live context usage in tokens: the most recent COMPLETED assistant step's input + cache.read + cache.write (the Epic 36 formula — what the next prompt will actually cost the window). 0 when no assistant turn exists yet.
Mid-turn, the in-flight assistant message carries a ZEROED token stamp (real usage lands at step completion — live-proven 2026-09-14: busy sessions reported no context usage because the scan stopped at the placeholder). Zero-total stamps are skipped; a real completion always carries input > 0, so busy sessions report the last completed step — the honest "as of last step" number.
func (*Client) SessionRename ¶ added in v0.30.0
SessionRename sets a session's title. The verb is PATCH — POST is silently accepted and IGNORED by pinned opencode (live-proven 2026-09-13: POST /session/{id} returned 200 with the title unchanged; PATCH updates it immediately; the SDK's sessionUpdate is PATCH).
func (*Client) SessionSend ¶ added in v0.30.0
func (c *Client) SessionSend(ctx context.Context, sessionID, text, model string, images []ImageAttachment) (*SendResult, error)
SessionSend delivers one synchronous prompt (V1 POST /session/{id}/message) with an optional per-prompt model override ("provider/model", "" = session default) and optional image attachments rendered as file-part data URLs. Returns the completed assistant exchange.
The caller MUST NOT target a session whose turn is waiting on this call (busy sessions block — see the file contract).
func (*Client) SessionSummarize ¶ added in v0.30.0
SessionSummarize compacts a session's history via the working V1 route (POST /session/{id}/summarize). providerID/modelID select the summarizing model. On a busy session the request queues server-side and completes at the turn boundary (live-proven) — callers that must not block run this from a detached context.
func (*Client) StageCredentials ¶
StageCredentials writes provider credentials to opencode's auth.json (via PUT /auth/:providerID) but does NOT trigger provider-state refresh. The credentials are "staged" — they exist on disk but opencode's in-memory provider state is unchanged until DisposeInstance is called separately by the caller (typically via POST /api/v1/workspaces/:id/agent/reload).
Returns nil if providers is empty (no-op).
func (*Client) TriggerCreate ¶ added in v0.32.0
func (c *Client) TriggerCreate(ctx context.Context, saToken, workspaceID string, trigger json.RawMessage) (*AutomationResponse, error)
TriggerCreate creates a trigger; the platform forces workspaceId to this pod's workspace (the automation scoping rule).
func (*Client) TriggerDelete ¶ added in v0.32.0
func (c *Client) TriggerDelete(ctx context.Context, saToken, workspaceID, id string) (*AutomationResponse, error)
TriggerDelete removes one trigger.
func (*Client) TriggerFires ¶ added in v0.32.0
func (c *Client) TriggerFires(ctx context.Context, saToken, workspaceID, id string) (*AutomationResponse, error)
TriggerFires lists a trigger's fire audit rows — the debugging gold: per-fire status, error payloads, and the consecutive-failure trail.
func (*Client) TriggerGet ¶ added in v0.32.0
func (c *Client) TriggerGet(ctx context.Context, saToken, workspaceID, id string) (*AutomationResponse, error)
TriggerGet fetches one trigger.
func (*Client) TriggerList ¶ added in v0.32.0
func (c *Client) TriggerList(ctx context.Context, saToken, workspaceID string) (*AutomationResponse, error)
TriggerList lists the owner's triggers (pod-identity resolved).
func (*Client) TriggerRotateWebhookSecret ¶ added in v0.32.1
func (c *Client) TriggerRotateWebhookSecret(ctx context.Context, saToken, workspaceID, id string) (*AutomationResponse, error)
TriggerRotateWebhookSecret rotates a webhook trigger's HMAC secret; the response {webhookSecret, webhookUrl} surfaces verbatim — the owner's credential delivered to the owner's agent.
func (*Client) TriggerUpdate ¶ added in v0.32.0
func (c *Client) TriggerUpdate(ctx context.Context, saToken, workspaceID, id string, patch json.RawMessage) (*AutomationResponse, error)
TriggerUpdate partially updates one trigger (nil = keep existing). The workspace rides the query; the patch body stays pure caller content — no scoping fields are injected into it.
func (*Client) WorkflowCreate ¶ added in v0.32.0
func (c *Client) WorkflowCreate(ctx context.Context, saToken, workspaceID string, workflow json.RawMessage) (*AutomationResponse, error)
WorkflowCreate creates a workflow (spec passed through verbatim).
func (*Client) WorkflowDelete ¶ added in v0.32.0
func (c *Client) WorkflowDelete(ctx context.Context, saToken, workspaceID, id string) (*AutomationResponse, error)
WorkflowDelete removes one workflow.
func (*Client) WorkflowGet ¶ added in v0.32.0
func (c *Client) WorkflowGet(ctx context.Context, saToken, workspaceID, id string) (*AutomationResponse, error)
WorkflowGet fetches one workflow.
func (*Client) WorkflowList ¶ added in v0.32.0
func (c *Client) WorkflowList(ctx context.Context, saToken, workspaceID string) (*AutomationResponse, error)
WorkflowList lists the owner's workflows.
func (*Client) WorkflowRun ¶ added in v0.32.0
func (c *Client) WorkflowRun(ctx context.Context, saToken, workspaceID, id string, input json.RawMessage) (*AutomationResponse, error)
WorkflowRun starts a manual run (the test loop's fire button). The body is CreateWorkflowRunRequest{input} — the run-input object, NOT a bare passthrough (the delegated handler binds this shape).
func (*Client) WorkflowRuns ¶ added in v0.32.0
func (c *Client) WorkflowRuns(ctx context.Context, saToken, workspaceID, id string) (*AutomationResponse, error)
WorkflowRuns lists a workflow's run history (statuses + error codes).
func (*Client) WorkflowUpdate ¶ added in v0.32.0
func (c *Client) WorkflowUpdate(ctx context.Context, saToken, workspaceID, id string, patch json.RawMessage) (*AutomationResponse, error)
WorkflowUpdate partially updates one workflow. The workspace rides the query; the patch body stays pure.
type ConfigWriter ¶ added in v0.12.0
type ConfigWriter struct {
// contains filtered or unexported fields
}
ConfigWriter is the single writer of agent-config.json within the agentd process. All config changes (provider credentials, model selection, relay injection, MCP servers) go through SetProviders / SetModel / SetRelay / SetMCPServers followed by Rebuild.
Thread-safe: all mutating methods acquire mu. Rebuild serializes the read-merge-write cycle so concurrent reloads and relay injection cannot interleave.
func NewConfigWriter ¶ added in v0.12.0
func NewConfigWriter(path string, opts ...ConfigWriterOption) *ConfigWriter
NewConfigWriter creates the writer and initializes its sources from the existing agent-config.json file (written by the materialize subcommand at boot), the admin-prompt file, and the allowed-dirs file. Options set the paths; absent options mean the corresponding source is skipped. If agent-config.json is absent or corrupt, sources start empty and the first Rebuild creates a fresh file.
func (*ConfigWriter) Apply ¶ added in v0.14.0
func (w *ConfigWriter) Apply(in agent.AgentConfigInput) (bool, error)
Apply implements agent.AgentConfigWriter. It is the seam platform code uses after construction; it never calls the SetX methods directly.
Each non-nil field on in updates one source on the writer. A nil field leaves the writer's existing state for that source unchanged. A non-nil pointer to a zero-value struct clears the source (where meaningful).
After merging the input, Apply calls rebuildLocked to render and write the full config atomically. Returns (true, nil) on success — opencode does not hot-reload its config file, so every successful Apply requires the process to be restarted for the change to take effect. A future agent that hot-reloads returns false from its Apply; platform code branches on the bool and skips the restart.
Thread-safety: Apply holds w.mu across the entire merge + write cycle so concurrent Apply / Rebuild / SetX calls serialize. Two concurrent Apply calls cannot interleave such that one caller's update is lost (Rule 11 F1: atomicity is part of the Apply contract, not just the write step).
The opencode-specific rendering (deep-merge semantics, $schema URL, disabled_providers, the opencode-relay provider block, the agent.build prompt merge, the top-level permission.external_directory merge, the mcp section) is owned by this method and rebuildLocked — none of it leaks through the agent.AgentConfigInput type. Platform code calls Apply and reacts to restartRequired; it does not know WHY a restart is needed.
func (*ConfigWriter) HasRelay ¶ added in v0.12.0
func (w *ConfigWriter) HasRelay() bool
HasRelay returns true if the relay injector has successfully injected relay config. Used by the readyz handler for the RelayInjected signal.
func (*ConfigWriter) Rebuild ¶ added in v0.12.0
func (w *ConfigWriter) Rebuild() error
Rebuild merges all sources (providers, model, relay, MCP, admin prompt, allowed dirs) and writes the complete agent-config.json atomically via temp-file + os.Rename.
Merge semantics:
- $schema is always set to "https://opencode.ai/config.json"
- provider map = existing providers (from SetProviders or loadExisting)
- opencode-relay (if relay is set). No existing provider is removed.
- model = the model source (from SetModel or loadExisting)
- disabled_providers = ["opencode"] (only if relay is set)
- agent.build.prompt = admin prompt (deep-merged into existing build agent)
- permission.external_directory = allowed-dirs glob allow-rules + the platform tier floor (top-level — the LIVE key; mode.permissions is inert)
- mcp = staged MCP servers + pre-marshal hook additions
The temp-file + rename pattern ensures readers never see a partially written file. os.Rename is atomic on POSIX filesystems (same mount).
Thread-safety: Rebuild acquires w.mu for the whole read-merge-write cycle so concurrent Rebuild/SetX calls cannot interleave.
func (*ConfigWriter) SetMCPServers ¶ added in v0.12.0
func (w *ConfigWriter) SetMCPServers(servers []MCPServerEntry)
SetMCPServers replaces the MCP server source. Called after materialize stages MCP server entries from secrets.json. Each server renders as one entry in the opencode "mcp" top-level config section.
func (*ConfigWriter) SetModel ¶ added in v0.12.0
func (w *ConfigWriter) SetModel(model string)
SetModel updates the model source. Called by applyWorkspaceConfig at boot (via the materialize subcommand) to set the default model from workspace-config.json.
func (*ConfigWriter) SetProviders ¶ added in v0.12.0
func (w *ConfigWriter) SetProviders(formattedConfig []byte) error
SetProviders updates the provider source from a FormatOpenCodeConfig result. The formatted bytes contain the complete opencode config shape ({ $schema, provider: {...} }); this method extracts just the provider map. The model from the formatter is NOT captured — the model source is owned by SetModel (set at boot via loadExisting) and must survive credential reloads.
func (*ConfigWriter) SetRelay ¶ added in v0.12.0
func (w *ConfigWriter) SetRelay(url string, models []RelayModel)
SetRelay updates the relay source after the relay injector successfully discovers the free model list. The writer stores the URL and models; Rebuild merges them into the provider map.
type ConfigWriterOption ¶ added in v0.12.0
type ConfigWriterOption func(*ConfigWriter)
ConfigWriterOption configures a ConfigWriter at construction.
func WithAdminPromptPath ¶ added in v0.12.0
func WithAdminPromptPath(p string) ConfigWriterOption
WithAdminPromptPath sets the path to the admin-configured system prompt file (written by the agentd bootstrap subcommand). The writer reads it once at construction. Empty (the default) means no admin-prompt source.
func WithAllowedDirsPath ¶ added in v0.12.0
func WithAllowedDirsPath(p string) ConfigWriterOption
WithAllowedDirsPath sets the path to the instance's allowedExternalDirectories JSON array (written by the bootstrap subcommand). The writer reads it once at construction. Empty (the default) means no external-directory allow-rules are injected.
func WithPreMarshalHook ¶ added in v0.12.0
func WithPreMarshalHook(fn func(map[string]json.RawMessage)) ConfigWriterOption
WithPreMarshalHook registers a function invoked on the rendered config map immediately before final marshal. agentd uses this to inject its built-in admin MCP server (the "llmsafespaces" entry pointing at agentd's own admin port) without this package needing to know that port. nil (the default) means no hook.
type Dialect ¶
type Dialect struct{}
Dialect is the opencode-specific vocabulary: route paths, SSE event classification, and event parsing. Internal to the agent side since #828 batch 4 (the handler-level agent.Dialect interface is retired): the adapter here and agentd's store readers (cmd/workspace-agentd/sessionstate_wiring.go) are the consumers — no platform/handler code.
func (*Dialect) EventStreamPath ¶
func (*Dialect) IsPermissionAsked ¶
func (*Dialect) IsPermissionResolved ¶
func (*Dialect) IsQuestionAsked ¶
func (*Dialect) IsQuestionResolved ¶
func (*Dialect) IsSessionBusy ¶
func (d *Dialect) IsSessionBusy(eventType string, properties json.RawMessage) bool
func (*Dialect) IsSessionIdle ¶
func (d *Dialect) IsSessionIdle(eventType string, properties json.RawMessage) bool
func (*Dialect) KindByPrefix ¶ added in v0.30.1
KindByPrefix maps a request ID to its input kind by the agent's ID prefix convention (que_ = question, per_ = permission) — the seam's kind discriminator, used by the adapter's prefix-aware routing (#1302 item 3; handlers and the MCP client/server validate the GENERIC contract instead). The actor (cmd/workspace-agentd wiring) keeps its own seam-local helpers; the MCP server's dispatch is a prefix FAST-PATH with reply-shape dispatch for conforming unprefixed ids (dispatch, never validation).
func (*Dialect) ParsePermissionListItem ¶ added in v0.26.0
func (d *Dialect) ParsePermissionListItem(raw json.RawMessage) (*agent.PermissionRequest, error)
ParsePermissionListItem parses one entry of GET /permission (shares the permission.asked properties shape).
func (*Dialect) ParsePermissionRequest ¶
func (d *Dialect) ParsePermissionRequest(eventType string, properties json.RawMessage) (*agent.PermissionRequest, error)
func (*Dialect) ParseQuestionListItem ¶ added in v0.26.0
func (d *Dialect) ParseQuestionListItem(raw json.RawMessage) (*agent.QuestionRequest, error)
ParseQuestionListItem parses one entry of opencode's GET /question list into the normalized QuestionRequest (the list entries share the question.asked properties shape). Used by the API adapter's ListPending and by agentd's sessionstate store reader (US-69.3).
func (*Dialect) ParseQuestionRequest ¶
func (d *Dialect) ParseQuestionRequest(eventType string, properties json.RawMessage) (*agent.QuestionRequest, error)
func (*Dialect) ParseSessionStatus ¶
func (*Dialect) PermissionListPath ¶
func (*Dialect) PermissionReplyPath ¶
func (*Dialect) QuestionListPath ¶
func (*Dialect) QuestionRejectPath ¶
func (*Dialect) QuestionReplyPath ¶
func (*Dialect) SessionAbortPath ¶
func (*Dialect) SessionCreatePath ¶
func (*Dialect) SessionGetPath ¶
func (*Dialect) SessionListPath ¶
func (*Dialect) SessionMessagePath ¶
func (*Dialect) SessionPromptAsyncPath ¶
type ImageAttachment ¶ added in v0.30.0
ImageAttachment is one image bound for a message's file part. Data is the raw bytes; the seam renders the data URL the wire requires.
type MCPServerEntry ¶ added in v0.12.0
type MCPServerEntry struct {
Name string
Transport string // http, sse, or stdio
URL string
Command string
Args []string
TimeoutMs int
Env map[string]string
Headers map[string]string
}
MCPServerEntry is one staged MCP server, carrying the fields needed to render its opencode config entry (local or remote shape per the contract).
type ModelInfo ¶ added in v0.30.0
ModelInfo is the catalog view of one model (GET /config/providers). ImageInput is only meaningful when ImageInputKnown is true — the catalog entry carried no capabilities signal when it is false, and callers must treat that as UNKNOWN, never as text-only (#1307 fail-safe direction: a false "text-only" strips user images from vision-capable models).
ImageInput OR-merges two signals: capabilities.input.image (opencode's models.dev catalog merge) and capabilities.attachment (the credential-declared capability — the only truthful signal for custom-endpoint models, where input.image is a synthesized false).
type OpenCodeAgent ¶
type OpenCodeAgent struct{}
func (*OpenCodeAgent) FormatProviderConfig ¶
func (a *OpenCodeAgent) FormatProviderConfig(providers []agent.LLMProviderData) ([]byte, error)
func (*OpenCodeAgent) Type ¶
func (a *OpenCodeAgent) Type() agent.AgentType
func (*OpenCodeAgent) ValidateCredentials ¶
func (a *OpenCodeAgent) ValidateCredentials(rawConfig []byte) (*agent.CredentialCheckResult, error)
type Option ¶
type Option func(*Client)
Option configures a Client at construction.
func WithHTTPClient ¶
WithHTTPClient injects a pre-configured *http.Client (e.g. one shared across many workspaces for connection pooling — M11-a). When unset, NewClient allocates a default client with a 10s timeout.
type PasswordResolver ¶
PasswordResolver resolves the opencode Basic-auth password for a workspace. The API-side implementation reads from the K8s Secret cache (pwCache); agentd-side reads from /sandbox-cfg/password.
type PodIPResolver ¶
type PodIPResolver interface {
GetWorkspacePodIP(ctx context.Context, userID, workspaceID string) (string, error)
}
PodIPResolver resolves the pod IP for a workspace.
type RelayModel ¶ added in v0.12.0
RelayModel is one free-tier model discovered from opencode's /provider endpoint by the relay injector. The writer renders it into the opencode-relay provider block's "models" map.
type SendResult ¶ added in v0.30.0
SendResult is the parsed synchronous V1 message response.
type SessionSummary ¶ added in v0.30.0
type SessionSummary struct {
ID string `json:"id"`
Title string `json:"title"`
Agent string `json:"agent"`
Version string `json:"version"`
Model *struct {
ID string `json:"id"`
ProviderID string `json:"providerID"`
} `json:"model"`
Time struct {
Created int64 `json:"created"`
Updated int64 `json:"updated"`
} `json:"time"`
Tokens *struct {
Input int64 `json:"input"`
Output int64 `json:"output"`
Reasoning int64 `json:"reasoning"`
Cache struct {
Read int64 `json:"read"`
Write int64 `json:"write"`
} `json:"cache"`
} `json:"tokens"`
Summary *struct {
Additions int64 `json:"additions"`
Deletions int64 `json:"deletions"`
Files int64 `json:"files"`
} `json:"summary"`
}
SessionSummary is the typed V1 session-list entry (validated live on 1.18.15). Only the fields the MCP tools consume are modeled; unknown fields pass through ignored.
type V2ContentPart ¶ added in v0.25.2
type V2ContentPart struct {
Type string `json:"type"`
ID string `json:"id,omitempty"`
Text string `json:"text,omitempty"`
// tool
Name string `json:"name,omitempty"`
State *V2ToolState `json:"state,omitempty"`
Raw json.RawMessage `json:"-"`
}
V2ContentPart is one assistant content item. Text and tool are the types observed on 1.18.15; unknown types preserve raw JSON for the contract's Custom pressure-relief valve.
func (*V2ContentPart) UnmarshalJSON ¶ added in v0.25.2
func (p *V2ContentPart) UnmarshalJSON(data []byte) error
UnmarshalJSON captures the raw part for Custom fallback.
type V2Delivery ¶ added in v0.12.2
type V2Delivery = agent.V2Delivery
V2Delivery is re-exported from pkg/agent (the canonical location). Callers should use agent.V2Delivery; this alias exists for backward compatibility.
type V2Message ¶ added in v0.25.2
type V2Message struct {
ID string `json:"id"`
Type string `json:"type"` // user | assistant | system
Time struct {
Created int64 `json:"created"`
Completed int64 `json:"completed,omitempty"`
} `json:"time"`
// user
Text string `json:"text,omitempty"`
// assistant
Agent string `json:"agent,omitempty"`
Model *V2ModelInMessage `json:"model,omitempty"`
Content []V2ContentPart `json:"content,omitempty"`
Finish string `json:"finish,omitempty"`
Cost float64 `json:"cost,omitempty"`
Tokens *V2Tokens `json:"tokens,omitempty"`
}
V2Message is one message from the V2 store's history view (GET /api/session/:sid/message → {data:[...]}). Captured live against opencode 1.18.15 (design 0052); differs from the V1 shape in three load-bearing ways:
- role discriminates on top-level `type` (user/assistant/system), not info.role
- user prompt text is a top-level `text` string (no parts)
- assistant content lives in `content[]` where a tool part carries name/id at the top level and input/output/times inside `state` (closer to the legacy nested shape than 1.18.10's flat V1 shape)
type V2ModelInMessage ¶ added in v0.25.2
V2ModelInMessage is the model attribution on a V2 assistant message.
type V2ModelRef ¶ added in v0.15.11
V2ModelRef is the per-prompt model override in opencode's OBJECT wire form ({"modelID", "providerID"}), matching the V1 /message schema (packages/sdk/openapi.json @v1.18.10: model is an object, both fields required, additionalProperties false). The V2 prompt endpoint's route group is dormant on 1.18.10 (its OpenAPI exposes no model property at all), but the override still uses the object form — it mirrors V1's schema so the send does not replay the string-form regression (2026-08-17 all-sessions-502, #909) on revival.
type V2PromptResponse ¶ added in v0.12.2
type V2PromptResponse = agent.V2PromptResponse
V2PromptResponse is re-exported from pkg/agent.
type V2Tokens ¶ added in v0.25.2
type V2Tokens struct {
Input int64 `json:"input"`
Output int64 `json:"output"`
Reason int64 `json:"reasoning"`
Cache struct {
Read int64 `json:"read"`
Write int64 `json:"write"`
} `json:"cache"`
}
V2Tokens mirrors the opencode token accounting object (same field names on the V1 and V2 surfaces).
type V2ToolState ¶ added in v0.25.2
type V2ToolState struct {
Status string `json:"status,omitempty"`
Input json.RawMessage `json:"input,omitempty"`
Content []struct {
Type string `json:"type"`
Text string `json:"text"`
} `json:"content,omitempty"`
Structured json.RawMessage `json:"structured,omitempty"`
Time *struct {
Created int64 `json:"created"`
Ran int64 `json:"ran,omitempty"`
Completed int64 `json:"completed,omitempty"`
} `json:"time,omitempty"`
}
V2ToolState is the tool execution state on a V2 content part.
type WorkspaceClient ¶
type WorkspaceClient struct {
// contains filtered or unexported fields
}
WorkspaceClient implements AgentClient by resolving each call to a specific pod IP + password, then delegating to the low-level Client. It is constructed once and shared across handlers; each call resolves the workspace's current podIP + password fresh, so pod migrations and password rotations are transparent to callers.
The shared httpClient enables connection pooling across all workspace calls (M11-a). The agentPort field replaces the former package-level var so tests are parallel-safe (M1-a).
func NewWorkspaceClient ¶
func NewWorkspaceClient(pw PasswordResolver, ip PodIPResolver, logger *zap.Logger, opts ...WorkspaceClientOption) *WorkspaceClient
NewWorkspaceClient creates an AgentClient that resolves workspace → podIP + password on each call. The httpClient is shared across all calls for connection pooling; agentPort defaults to agentd.AgentPort.
func (*WorkspaceClient) DisposeInstance ¶
func (w *WorkspaceClient) DisposeInstance(ctx context.Context, userID, workspaceID string) error
func (*WorkspaceClient) GetSessionStatuses ¶
func (*WorkspaceClient) ListModels ¶
func (*WorkspaceClient) PatchConfig ¶
func (*WorkspaceClient) StageCredentials ¶
func (w *WorkspaceClient) StageCredentials(ctx context.Context, userID, workspaceID string, providers []secrets.LLMProviderData) error
type WorkspaceClientOption ¶
type WorkspaceClientOption func(*WorkspaceClient)
WorkspaceClientOption configures a WorkspaceClient at construction.
func WithWorkspaceHTTPClient ¶
func WithWorkspaceHTTPClient(hc *http.Client) WorkspaceClientOption
WithWorkspaceHTTPClient injects a shared *http.Client so connections are pooled across all workspace calls (M11-a). When unset, a tuned default is used (see newTunedHTTPClient). The client must not set a per-request Timeout that would interfere with caller context deadlines.
Source Files
¶
- acpvocab.go
- adapter.go
- adapter_helpers.go
- adapter_v1.go
- adapter_v2.go
- agent_client.go
- capabilities.go
- client.go
- client_events.go
- client_v2.go
- configwriter.go
- configwriter_promptdirs.go
- dialect.go
- format.go
- loopback.go
- opencode.go
- permissiontiers.go
- register.go
- translate.go
- translate_abi.go
- verifyclient.go
- verifydelivery.go
- vision_gate.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package filediff produces unified-diff text for files changed by an agent turn, using `git diff` against the workspace PVC's HEAD commit.
|
Package filediff produces unified-diff text for files changed by an agent turn, using `git diff` against the workspace PVC's HEAD commit. |
|
Package wire is the ONLY code in the platform that decodes opencode wire bytes (HTTP bodies and /event SSE envelopes).
|
Package wire is the ONLY code in the platform that decodes opencode wire bytes (HTTP bodies and /event SSE envelopes). |