Expand description
/v1/worker/* endpoints (SubAgent self-fetch path).
HTTP /v1/worker/* endpoints (SubAgent self-fetch path).
§7-Entry pointer #6 (Output Event design)
This endpoint accesses OutputStore directly and does NOT go through the engine.
It is one of the seven entry points enumerated in project CLAUDE.md §“Output Event
Design SoT”. For the canonical description, see the crate root doc of
mlua-swarm-output-store (cargo doc -p mlua-swarm-output-store).
§Path
A thin-payload path where a SubAgent (= worker process launched by a MainAI) uses
the capability token it received via WS Spawn to self-fetch its prompt and
submit its result — putting the token in Authorization: Bearer <encoded CapToken>.
§Routes
GET /v1/worker/prompt?task_id=<tid>— viaengine.fetch_worker_payload, returns{task_id, attempt, agent, system?, prompt, context?}.context.steps(projection-adapterST5, [assemble_step_pointers]) is assembled fresh on every fetch: aContextPolicy.steps-filtered pointer list to preceding steps’ OUTPUT, resolved throughcrate::projection::McpQueryAdapter’s Data-plane +result_refenumeration — no separate MCP tool call needed to discover a prior step’s OUTPUT.POST /v1/worker/resultwith body{task_id, value, ok}— appends oneFinalto the output tail viaengine.submit_output(Final)(= the canonical path through which the dispatch layer decides Pass/Blocked) and updatestask.last_resultviaengine.post_result.POST /v1/worker/artifact?name=<name>(GH #36 ST1) — stages one named part per POST viaengine.stage_worker_artifact_trusted. Completing the attempt is stillPOST /v1/worker/submit//v1/worker/result— this route only stages; the dispatch layer’s Final-pull folds every staged part into{"out": <final>, "parts": {<name>: <value>, ...}}. At staging time the submit-time projection sink also materializes the part raw to<ctx-dir>/<name>(the IN file the next Agent step reads; fail-open skip when nowork_dir/project_rootresolves).GET /v1/worker/prompt/system?task_id=<tid>&attempt=<n>(GH #31) — raw bakedsystembytes for(task_id, attempt), theHttp-mode fetch target forsystem_ref.uri. Same Bearer flow as/v1/worker/prompt; body istext/plain, not JSON.GET /v1/agents/:name/render-size(GH #31) — no Bearer required, same trust tier asGET /v1/blueprints/:id/head. Live per-agent most-recently observed render size, backingbp_doctor’s post-render check.POST /v1/worker/degradation(GH #32) — structured JSON{tool, error, fallback, note?}, same Bearer flow as [worker_submit]. An independent channel: entries are appended toRunRecord.degradationsviaRunStore::append_degradationdirectly and never touchOutputStore/ the fold path (Crux invariant 2 — a degradation must never surface as step OUTPUT).step_ref/attempt/atare server-injected, never trusted from the client. Silent204(no append) when the dispatch task carries no Run linkage — same fail-open contract as [reject_if_run_terminal]’s own resolution steps, since a pre-run-tracking dispatch has nowhere to record a degradation and that must not become a client-visible error.
§Bearer authentication
The Bearer value is the string produced by CapToken::encode() (= URL-safe
base64 of serde_json). The server decodes it with CapToken::decode and then,
inside the engine, verifies HMAC sig + role × verb gate + TTL via
verify_token_for_task (= self-contained capability token; no server-side
store lookup required).
Tokens are minted during the “2) mint outside the lock” phase of
engine.dispatch_attempt (Role::Worker, 600s TTL, scopes=["*"]).
The verb gate covers FetchPrompt / EmitOutput / PostResult — the worker
leaf capability set (crate::types::WORKER_LEAF_VERBS).
Structs§
- Agent
Render Size Response - Response body for
GET /v1/agents/:name/render-size. - Artifact
Query - Query params for
POST /v1/worker/artifact. - Degradation
Body - Body for
POST /v1/worker/degradation(GH #32). - Prompt
Query - Query params for
GET /v1/worker/prompt. - Prompt
System Query - Query params for
GET /v1/worker/prompt/system. Field names are fixed totask_id/attempt— this is the exact shape the engine bakes intosystem_ref.uri’s query string forHttpmode (GH #31), so the names here must match verbatim. - Stats
Body - Request body for
POST /v1/worker/stats— a worker’s self-reported per-attempt stats (per-step run stats, operator axis). Every field optional; an all-empty body is accepted and dropped. - Submit
Query POST /v1/worker/submit. Bearer = encodedCapToken. Body = raw text/octet.- Worker
Result Req - Body for
POST /v1/worker/result.
Functions§
- agent_
render_ size GET /v1/agents/:name/render-size(GH #31). Live per-agent-name lookup of the most-recently-bakedsystem_promptrender size, backingbp_doctor’s post-render size check. No Bearer required — same unauthenticated trust tier asGET /v1/blueprints/:id/head(blueprints::get_head), an operator-diagnostic route.- worker_
artifact POST /v1/worker/artifact?name=<name>. Bearer = same short-handle / full-CapTokenforms asworker_submit. Body = raw text/octet.- worker_
degradation POST /v1/worker/degradation(GH #32). Bearer = same short-handle / full-CapTokenforms asworker_submit. Body = JSON, not raw bytes — this endpoint carries structured data, unlike its raw-bytes siblings.- worker_
prompt GET /v1/worker/prompt?task_id=<tid>. Bearer = encodedCapTokenor shortwh-handle. Thin HTTP wrapper overengine.fetch_worker_payload/fetch_worker_payload_trusted. Short-handle path (recommended for SubAgents): handle → task_id cross-check → trusted fetch. Full-CapTokenpath: token decode → verify → fetch.- worker_
prompt_ system GET /v1/worker/prompt/system?task_id=<tid>&attempt=<n>(GH #31). TheHttp-mode fetch target forsystem_ref.uri: serves the exact bakedsystembytes for(task_id, attempt)as a rawtext/plainbody — not JSON-wrapped, sincemse_worker_fetchneeds the precise byte sequence to sha256-verify againstsystem_ref.sha256.- worker_
result POST /v1/worker/result. Bearer = encodedCapToken. Firesengine.submit_output(Final)+engine.post_result.- worker_
stats POST /v1/worker/stats. Bearer = same short-handle / full-CapTokenforms asworker_submit. Body = JSON (StatsBody).- worker_
submit POST /v1/worker/submit. Simplified counterpart ofworker_result: the caller sends only the raw result body,task_idis resolved server-side from the Bearer handle/token, andokdefaults totrueunless overridden viaSubmitQuery::ok. See the module doc for the short-handle vs full-CapTokenBearer forms.