workerclient

package
v0.2.0-alpha.13 Latest Latest
Warning

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

Go to latest
Published: Sep 18, 2026 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Overview

Package workerclient defines the worker API client and HTTP contract types.

Index

Constants

View Source
const (
	DebounceIntervalMs = 80  // flush at most every 80ms when there is buffered data
	DebounceMaxBytes   = 512 // flush when buffer reaches 512 bytes
)

DebouncedStreamSender wraps a StreamSender and buffers deltas, flushing after an interval or when buffer size is reached. Reduces server API pressure and gives a smoother typewriter-like experience on the client.

View Source
const DefaultCancelPollInterval = 5 * time.Second

DefaultCancelPollInterval is how often a worker asks whether its run has been canceled.

It trades one small request per run against how long a user waits after pressing stop. Five seconds keeps the wait short enough to feel like an answer while costing a fraction of what the run's own inference calls do.

Variables

View Source
var ErrTaskRunAlreadyClaimed = errors.New("task run already claimed or not scheduled")

ErrTaskRunAlreadyClaimed is returned when the server responds 409 to PATCH RUNNING (run not SCHEDULED or already RUNNING).

View Source
var ErrWorkspaceCheckpointsUnsupported = errors.New("worker: server does not support workspace checkpoints")

ErrWorkspaceCheckpointsUnsupported reports that the server this run reached does not run the workspace-checkpoint contract: it has no such route (404) or has it but no checkpoint storage configured (503). It is not a failure of the run — an evaluation control plane and a deployment with checkpoints turned off both answer this way, and such a run simply seeds and restores nothing. A real server that supports checkpoints always answers a valid run with 204 or 200, never 404, because the route is registered unconditionally.

Functions

func ArtifactURL

func ArtifactURL(baseURL, artifactID string) string

ArtifactURL renders where an authorized person opens the artifact. Empty when the caller does not know a public base URL, which leaves the id as the whole reference.

func DownloadPluginPackage

func DownloadPluginPackage(ctx context.Context, cfg WorkerAPIClientConfig, taskRunID, name, version string, w io.Writer) (string, error)

DownloadPluginPackage streams one pinned release into w and returns the digest the server sent with it.

The route is scoped to this run and serves only the releases its own pins name, so a worker cannot reach the catalog or another run's packages.

func FinalizeSeedCheckpoint

func FinalizeSeedCheckpoint(ctx context.Context, cfg WorkerAPIClientConfig, taskRunID string, req SeedCheckpointRequest) (string, error)

FinalizeSeedCheckpoint records a seed the worker captured and uploaded, and returns its committed identity. It is idempotent for identical bytes.

func GetWorkerTaskRunSecrets

func GetWorkerTaskRunSecrets(ctx context.Context, cfg WorkerAPIClientConfig, taskRunID string) (map[string]string, error)

GetWorkerTaskRunSecrets fetches the run's resolved Secret env grants. An empty map (or a 404 from a server built before this route) means the run's agent consumes no Secret. A non-2xx means the server could not produce a required grant, which the caller surfaces as a run failure -- a run must not proceed without a credential its definition declared.

func IsCancelRequested

func IsCancelRequested(ctx context.Context, cfg WorkerAPIClientConfig, taskRunID string) (bool, error)

IsCancelRequested reports whether the server has recorded a cancel request for this run.

A run that no longer exists reports false rather than an error: the caller is a running worker, and a missing run is not a reason to stop mid-turn.

func NewArtifactPublisher

func NewArtifactPublisher(cfg WorkerAPIClientConfig, taskRunID, serverBaseURL string) tool.ArtifactPublisher

NewArtifactPublisher builds the run-token adapter for the artifact tool.

func NewHTTPClient

func NewHTTPClient(opts TLSClientOptions) (*http.Client, error)

NewHTTPClient builds the one reusable *http.Client a worker uses for every call back to the server, rather than http.DefaultClient. Server identity is always verified against the request URL's host and the configured (or system) roots — there is no insecure-skip mode, because a leaked run token plus an unverified server is exactly the disclosure this boundary exists to prevent.

A plain-HTTP server_url never exercises the TLS config, so a development deployment can pass the zero value.

func NewIssueClient

func NewIssueClient(cfg WorkerAPIClientConfig, taskRunID string) tool.IssueClient

NewIssueClient scopes a run's agent to the one Issue its task names.

The Issue is not a parameter here either: the server derives it from the run token, so this client cannot be pointed at another Issue even by the code holding it. See docs/design/issue-agent-access.md section 5.3.

func RecordWorkspaceRestore

func RecordWorkspaceRestore(ctx context.Context, cfg WorkerAPIClientConfig, taskRunID string, req WorkspaceRestoreRequest) error

RecordWorkspaceRestore reports the outcome of restoring the run's base.

func WatchCancel

func WatchCancel(ctx context.Context, cfg WorkerAPIClientConfig, taskRunID string, interval time.Duration, onCancel func())

WatchCancel polls until the run is canceled or ctx ends, then calls onCancel once and returns.

Polling failures are logged and retried rather than treated as a cancel. A server the worker cannot reach is the same server that cannot have been told to stop this run, and ending a user's work on a network blip would destroy more than it protects. The run's own timeout is what bounds the other case.

Use interval 0 for DefaultCancelPollInterval. Run it in a goroutine; it returns as soon as ctx is done.

Types

type DebouncedStreamSender

type DebouncedStreamSender struct {
	Inner      StreamSender
	IntervalMs int // override default when > 0
	MaxBytes   int // override default when > 0
	// contains filtered or unexported fields
}

DebouncedStreamSender implements StreamSender with debouncing.

func (*DebouncedStreamSender) Flush

func (d *DebouncedStreamSender) Flush(ctx context.Context, taskRunID string) error

func (*DebouncedStreamSender) SendDelta

func (d *DebouncedStreamSender) SendDelta(ctx context.Context, taskRunID, delta string) error

type GetTaskRunResponse

type GetTaskRunResponse struct {
	Run  TaskRunRun  `json:"run"`
	Task TaskRunTask `json:"task"`
	LLM  *TaskRunLLM `json:"llm,omitempty"`
	// Plugins are the releases this run materializes, resolved by the server
	// when the worker claimed the run. A worker does not resolve its own: it
	// receives a finished list. Empty when the run's agent names none, or when
	// there is no agent.
	Plugins []TaskRunPlugin `json:"plugins,omitempty"`
	// PluginError is why this run cannot proceed — a named plugin its space has
	// not activated, or whose activation is suspended. A worker that receives
	// it must fail the run rather than start it: an agent that names a plugin
	// has declared it needs one, and a background run doing quietly less than
	// its definition says is read by somebody who was not watching it.
	PluginError string `json:"plugin_error,omitempty"`
	// Sandbox declares this run's agent-declared network/filesystem sandbox
	// tiers, resolved by the server when the worker claimed the run. Absent
	// means both tiers are the strictest, so a worker built before this
	// field existed applies the SandboxSurfaceWorker baseline it always did.
	// See docs/design/agent-sandbox-policy.md.
	Sandbox *TaskRunSandbox `json:"sandbox,omitempty"`
}

GetTaskRunResponse is the JSON response for GET /api/worker/task-runs/{task_run_id} (snake_case).

type PatchTaskRunRequest

type PatchTaskRunRequest struct {
	Status    string     `json:"status"`
	SessionID *string    `json:"session_id,omitempty"`
	StartedAt *time.Time `json:"started_at,omitempty"`
	EndedAt   *time.Time `json:"ended_at,omitempty"`
	Output    *string    `json:"output,omitempty"`
	// Structured is the validated structured-output value as JSON text, sent on a
	// terminal report when the run requested an output schema and it validated.
	// See docs/design/structured-output.md.
	Structured       *string `json:"structured,omitempty"`
	ErrorMessage     *string `json:"error_message,omitempty"`
	PromptTokens     *int    `json:"prompt_tokens,omitempty"`
	CompletionTokens *int    `json:"completion_tokens,omitempty"`
	// TracePath locates the run's durable trace inside run-global storage, e.g.
	// "traces/<session>/rt_….jsonl". Sent on both success and failure; omitted
	// when no trace was written.
	TracePath *string `json:"trace_path,omitempty"`
	// WorkspaceCheckpoint is the result checkpoint the worker captured from
	// workspace/ after execution and uploaded to the object store, carried on the
	// terminal report so the server commits it as it accepts the outcome. Nil
	// when the run captured none — it produced no checkpoint, or capture failed
	// (which does not fail the run). See
	// docs/design/task-workspace-checkpoints.md §8.
	WorkspaceCheckpoint *WorkspaceCheckpointDescriptor `json:"workspace_checkpoint,omitempty"`
}

PatchTaskRunRequest is the JSON body for PATCH /api/worker/task-runs/{task_run_id} (snake_case).

type SeedCheckpointRequest

type SeedCheckpointRequest struct {
	PayloadFormat     string `json:"payload_format"`
	PayloadSHA256     string `json:"payload_sha256"`
	SizeBytes         int64  `json:"size_bytes"`
	UncompressedBytes int64  `json:"uncompressed_bytes"`
	EntryCount        int64  `json:"entry_count"`
}

SeedCheckpointRequest is the descriptor of a seed payload the worker has already uploaded to the object store. The server derives space, task, and run from the run token; the worker never sends owner ids.

type SeedCheckpointResponse

type SeedCheckpointResponse struct {
	CheckpointID string `json:"checkpoint_id"`
}

SeedCheckpointResponse returns the committed checkpoint's public identity.

type StreamDeltaRequest

type StreamDeltaRequest struct {
	Delta string `json:"delta"`
}

StreamDeltaRequest is the JSON body for POST /api/worker/task-runs/{task_run_id}/stream (snake_case).

type StreamSender

type StreamSender interface {
	SendDelta(ctx context.Context, taskRunID, delta string) error
	Flush(ctx context.Context, taskRunID string) error
}

StreamSender sends run output deltas to the server (e.g. for live streaming). Optional; when nil, run output is not streamed. Flush sends any buffered data; call when the stream ends so the last chunk is not lost.

type TLSClientOptions

type TLSClientOptions struct {
	// CAFile is a PEM bundle the client verifies the server certificate
	// against. Empty uses the system trust roots, which is correct only when the
	// server certificate chains to a public root.
	CAFile string
	// ClientCertFile and ClientKeyFile are an optional client certificate for
	// native mTLS, presented in addition to the run token. Both or neither.
	ClientCertFile string
	ClientKeyFile  string
}

TLSClientOptions configures the trust a worker uses to reach the server's worker listener. See docs/design/worker-api-network-boundary.md §6.

type TaskRunLLM

type TaskRunLLM struct {
	// Transport is "direct" or "buildmax".
	Transport string `json:"transport"`
	// Model is the catalog model to call. Empty uses the deployment default.
	Model string `json:"model,omitempty"`
	// ContextWindow is the usable context size for the model; 0 disables
	// windowing.
	ContextWindow int `json:"context_window,omitempty"`
	// CallTimeout bounds one call, in seconds; 0 uses the client default.
	CallTimeout int `json:"call_timeout,omitempty"`
}

TaskRunLLM tells a worker how to reach a model for this run.

It is deliberately thin. A managed run learns a model name and nothing else — no endpoint, no upstream model identifier, no credential — because those stay inside the server's authorization boundary. A direct run learns nothing here and reads its model from the server.yaml it already mounts.

Absent means direct, so a worker built before this field behaves as it always did.

type TaskRunPlugin

type TaskRunPlugin struct {
	Name    string `json:"name"`
	Version string `json:"version"`
	Digest  string `json:"digest"`
}

TaskRunPlugin is one release a run will fetch and verify. The digest is what the worker checks the bytes against before it extracts them.

type TaskRunRun

type TaskRunRun struct {
	ID                string  `json:"id"`
	TaskID            string  `json:"task_id"`
	PreviousTaskRunID *string `json:"previous_task_run_id,omitempty"`
	Input             string  `json:"input"`
	Status            string  `json:"status"`
	// CancelRequested is true once someone has asked this run to stop. The
	// worker polls for it and is what actually stops: the server records the
	// intent, the run's own process ends it. Absent means no request, so a
	// worker built before cancellation existed reads what it always did.
	CancelRequested bool      `json:"cancel_requested,omitempty"`
	CreatedAt       time.Time `json:"created_at"`
}

TaskRunRun is the run portion of the GET response.

type TaskRunSandbox

type TaskRunSandbox struct {
	NetworkTier    string `json:"network_tier,omitempty"`
	FilesystemTier string `json:"filesystem_tier,omitempty"`
}

TaskRunSandbox is the sandbox portion of the GET response.

type TaskRunSecretsResponse

type TaskRunSecretsResponse struct {
	Env map[string]string `json:"env,omitempty"`
}

TaskRunSecretsResponse carries a run's resolved Secret env grants: the variable names its agent declared, mapped to the values the server decrypted. It is fetched on its own route, not folded into GetTaskRunResponse, so the values ride a response that is Cache-Control: no-store and never logged. See docs/design/space-secrets.md §7.

type TaskRunTask

type TaskRunTask struct {
	ID             string  `json:"id"`
	ConversationID string  `json:"conversation_id"`
	SpaceID        string  `json:"space_id"`
	UserID         string  `json:"user_id"`
	SessionID      *string `json:"session_id,omitempty"`
	// AgentInstructions is the instruction text of the agent this task names, resolved by
	// the server. The worker appends it to the run's system prompt, which is re-sent whole on
	// every call, rather than leaving it in the task input, which the conversation eventually
	// compacts away.
	//
	// It travels here rather than on the worker's command line for the same reason the run
	// token does: argv is readable by every process on the machine, and this is text a user
	// wrote, which may carry something they would not publish.
	//
	// Absent means the task names no agent, or a server built before this field existed, so
	// a worker reads it as it always did.
	AgentInstructions string `json:"agent_instructions,omitempty"`
	// SpaceAgentInstructions is the Space-level guidance inherited by every
	// background agent run. Revision identifies the version recorded on this
	// TaskRun. Both are absent when the space has never configured the layer.
	SpaceAgentInstructions         string `json:"space_agent_instructions,omitempty"`
	SpaceAgentInstructionsRevision int    `json:"space_agent_instructions_revision,omitempty"`
}

TaskRunTask is the task portion of the GET response.

type WorkerAPIClientConfig

type WorkerAPIClientConfig struct {
	BaseURL string
	Token   string
	Client  *http.Client
}

WorkerAPIClientConfig holds base URL, token, and HTTP client for worker API calls.

type WorkerHTTPStreamSender

type WorkerHTTPStreamSender struct {
	BaseURL string
	Token   string
	Client  *http.Client
}

WorkerHTTPStreamSender implements StreamSender by POSTing each delta to the server's worker stream endpoint.

func (*WorkerHTTPStreamSender) Flush

func (u *WorkerHTTPStreamSender) Flush(ctx context.Context, taskRunID string) error

Flush is a no-op; WorkerHTTPStreamSender sends each delta immediately.

func (*WorkerHTTPStreamSender) SendDelta

func (u *WorkerHTTPStreamSender) SendDelta(ctx context.Context, taskRunID, delta string) error

SendDelta POSTs the delta to POST /api/worker/task-runs/{task_run_id}/stream.

type WorkerHTTPUpdater

type WorkerHTTPUpdater struct {
	BaseURL string
	Token   string
	Client  *http.Client
}

WorkerHTTPUpdater implements TaskRunUpdater by calling the server's worker API (PATCH /api/worker/task-runs/{task_run_id}).

func (*WorkerHTTPUpdater) UpdateRunStatus

func (u *WorkerHTTPUpdater) UpdateRunStatus(ctx context.Context, taskRunID string, req *PatchTaskRunRequest) error

UpdateRunStatus sends PATCH to the server to update run status and optional fields.

type WorkerTaskRun

type WorkerTaskRun struct {
	Run  *coretask.Run
	Task *coretask.Task
	// LLM is how this run reaches a model. Nil means direct, which is what a
	// server that has not enabled managed worker inference reports.
	LLM *TaskRunLLM
	// AgentInstructions is the text appended to the run's system prompt, resolved by the
	// server from the agent the task names. Empty when the task names none. It is not on
	// coretask.Task because it is not a property of the task: it is resolved per run, so an
	// edited definition applies to the next one.
	AgentInstructions      string
	SpaceAgentInstructions string
	// CancelRequested is true when the run was already asked to stop before
	// this worker picked it up — a cancel that landed between dispatch and
	// start. Such a run is finished without executing anything.
	CancelRequested bool
	// Plugins are the releases this run materializes, resolved by the server.
	// A worker fetches and verifies exactly these and never resolves its own.
	Plugins []coreplugin.Pin
	// PluginError is why this run cannot proceed. A worker that receives one
	// fails the run rather than starting it without the plugin: an agent that
	// names a plugin has declared it needs one.
	PluginError string
	// SandboxNetworkTier and SandboxFilesystemTier are this run's agent-
	// declared sandbox tiers, resolved by the server. Empty means the
	// strictest tier on that axis. See docs/design/agent-sandbox-policy.md.
	SandboxNetworkTier    string
	SandboxFilesystemTier string
}

WorkerTaskRun is everything the server tells a worker about the run it is about to execute.

func GetWorkerTaskRun

func GetWorkerTaskRun(ctx context.Context, cfg WorkerAPIClientConfig, taskRunID string) (*WorkerTaskRun, error)

GetWorkerTaskRun fetches the run from the server (GET /api/worker/task-runs/{task_run_id}). Returns nil, nil if not found.

type WorkspaceBaseResponse

type WorkspaceBaseResponse struct {
	CheckpointID      string `json:"checkpoint_id"`
	PayloadFormat     string `json:"payload_format"`
	PayloadSHA256     string `json:"payload_sha256"`
	SizeBytes         int64  `json:"size_bytes"`
	UncompressedBytes int64  `json:"uncompressed_bytes"`
	EntryCount        int64  `json:"entry_count"`
}

WorkspaceBaseResponse is the checkpoint a run restores its workspace from. It carries no storage key: the worker addresses the payload from its own space and this digest, the same content-addressed key the server would compute.

func GetWorkspaceBase

func GetWorkspaceBase(ctx context.Context, cfg WorkerAPIClientConfig, taskRunID string) (*WorkspaceBaseResponse, error)

GetWorkspaceBase fetches the run's base checkpoint descriptor, or (nil, nil) when the run has none — the first run of a Task, which seeds instead. A server that does not run the checkpoint contract at all returns ErrWorkspaceCheckpointsUnsupported (404 for no route, 503 for no storage), so the caller can distinguish "no base yet" from "no checkpoints here".

type WorkspaceCheckpointDescriptor

type WorkspaceCheckpointDescriptor struct {
	PayloadFormat     string `json:"payload_format"`
	PayloadSHA256     string `json:"payload_sha256"`
	SizeBytes         int64  `json:"size_bytes"`
	UncompressedBytes int64  `json:"uncompressed_bytes"`
	EntryCount        int64  `json:"entry_count"`
}

WorkspaceCheckpointDescriptor is the format, digest, and counters of a checkpoint payload the worker has already uploaded. The server derives space, task, and run from the run token and the payload key from the digest; the worker names no key. It is the terminal-report counterpart of the seed's SeedCheckpointRequest.

type WorkspaceRestoreRequest

type WorkspaceRestoreRequest struct {
	Status string `json:"status"`
	Error  string `json:"error,omitempty"`
}

WorkspaceRestoreRequest records how a run's base restoration ended. Status is "restored" or "failed"; Error is bounded operator text, set only on failure.

Jump to

Keyboard shortcuts

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