harness
v1.4.0Thin durable turn loop that wires session-manager, context-manager, and llm-router into an agent loop; spawns sub-agents as child sessions.
- macOS: arm64 · x64
- Linux: arm64 · armv7 · x64
- Windows: arm64 · x64 · x86
exact versions are immutable; binary and bundle artifacts are digest-pinned.
full markdown
/workers/harness.md?version=1.4.0. paste it into an llm prompt or pipe it through curl from a worker.install
dependencies
readme
harness
A thin, durable turn loop that turns a model plus a few iii workers into an agent.
INSTALLS WITH HARNESS
harness is the thin, durable turn loop that turns a model plus a few iii
workers into an agent. It takes an incoming message, persists it, assembles a
context, streams a completion, runs any function calls the model requests, and
repeats until the turn stops — all as durable, resumable steps so a crash or
restart picks up mid-turn. It wires session-manager
(transcript), context-manager (token budgeting, soft
dependency), and llm-router (generation); install those
alongside it for the full loop.
Quickstart
Install the engine, start it, then add harness and the console from a second terminal in the same folder:
curl -fsSL https://install.iii.dev/iii/main/install.sh | sh
mkdir iii-app && cd iii-app
touch config.yaml
iii -c config.yaml# New terminal, SAME folder. `iii worker add` writes to the config.yaml in the
# current directory, so it has to match the directory the engine runs in.
cd iii-app
iii worker add harness consoleopen http://localhost:3113Add a model key from the console: open the model picker and use configure
Anthropic / configure OpenAI to paste a key. It is stored in the
llm-router worker config and the model catalog populates within seconds.
Until a provider is configured the picker is empty and chat will not generate.
iii worker add harness installs every worker the loop needs (see the badges
above); you do not add them one by one. During bootstrap, the harness asks the
queue worker to define a dedicated harness-turn queue before it reports
ready. That queue is FIFO within each session_id and processes separate
sessions concurrently; startup fails if the queue cannot be ensured.
Every turn, sub-agent spawn, and provider call is one correlated trace: the harness turn waterfall in the console. Failed descendants stamp the whole trace as failed and carry standard error attributes. The session transcript keeps the same recovery, partial-output, and blocked-reaction explanation after refresh.
The agent-facing function surface is deny-by-default: with no functions.allow
globs, every model-requested call is refused and the harness is a plain chat
loop. Allow functions in per-send (options.functions.allow) and gate them
with the optional approval-gate sibling.
The full function reference (every harness::* id and its request/response
schema) lives in the code and iii worker info harness.
Building a consumer — a chat UI, a Telegram/WhatsApp bridge, a cron worker, or
any event-driven loop on top of the harness? Start with the integration
contract in
architecture/integration.md: the functions to
trigger, the triggers to bind, and the canonical consumer patterns.
Working with iii
iii is a WebSocket-routed worker mesh. One engine holds a live registry of every connected worker, their functions, and the triggers bound to them. Calls route worker to engine to worker, so the language, runtime, and location of a worker are invisible; the function id is the only contract.
1. Discover what is already there (the engine is the source of truth)
engine::functions::list— every function across all workers (filter withprefix/search/worker)engine::functions::info { function_id }— the request/response schema for ONE function (this is your API reference)engine::workers::list/engine::workers::info { name }— connected workers and their surfaceengine::triggers::list/engine::triggers::info { id }— legal trigger types and their config schemasengine::registered-triggers::list— every trigger instance already bound
2. Call a function. Use agent_trigger with { function: ". Two rules: payload is a JSON object (never a stringified one), and you fetch the contract via engine::functions::info before the first call.
3. Need a capability that is not registered?
directory::registry::workers::list { search: "" } directory::registry::workers::info { name }to judge fitworker::add { source: { kind: "registry", name: "to install" } } - confirm with
engine::functions::list { prefix: "and fetch each contract::" }
4. Worker lifecycle. worker::list, worker::add, worker::start, worker::stop, worker::update, worker::remove, worker::clear. Destructive ops require exactly yes: true.
5. Triggers, not polling. To react to events (HTTP, schedule, webhook, file change), bind a trigger instead of polling. Discover the type with engine::triggers::list, copy config from its schema, and confirm the binding fires with a real call (e.g. web::fetch to its local URL).
6. Handy workers.
web::fetch— all HTTP(S); passformat: "markdown"to read docs without flooding contextcoder::*— file ops for any code task (read/search/create/update/move/delete)slack::*— post to Slack
7. Authoring a worker. Read the SDK reference for your language first (Node / Python / Rust / Browser / Engine WS) at https://iii.dev/docs/sdk-reference/. Use the SDK's registerWorker(...) and call iii.registerFunction / iii.registerTrigger / iii.trigger on the returned value; they are methods, not top-level exports. Always declare description, request_format, and response_format so the next caller gets a real contract.
TL;DR: list, info, call. The engine tells you the truth; trust it over memory.
Configuration
The harness configuration entry is owned by the configuration worker; every
field hot-reloads (no restart). The fields a deployment is most likely to tune:
default_max_turns: 16 # per-turn generate-step cap when a send omits it
default_pending_timeout_ms: 1800000 # parked pending-call (sub-agent / hold) wait guard
max_depth: 3 # sub-agent depth budget
max_children: 5 # sub-agent fan-out budget
max_transient_resumes: 1 # recovery generations after a partial stream failure
sweep_expression: "0 * * * * *" # cron for the pending-call expiry sweepOther keys (RPC timeouts, stream coalescing, idempotency TTL, validation
retries) and their defaults live in src/config.rs.
System prompt
The identity prompt is assembled once at send/spawn time. The harness asks the
llm-router for the effective per-provider prompt (router::system_prompt::get
with the request's provider): provider workers declare their own identity
prompt at registration, and operators can override it per provider by setting
system_prompt in the llm-router configuration entry (unset = provider
default). When the router serves nothing — router absent, unknown provider,
or no declared prompt — the harness falls back to its embedded step-by-step
default prompt (prompts/default.txt).
An optional mode (plan | ask | agent) prepends a short operating-mode
paragraph. A non-empty options.system_prompt is combined with the built-in
prompt per options.system_prompt_strategy: enrich (default) appends it to
the built-in prompt, while override uses it verbatim. Assembly is tested in
src/prompt/tests.rs; provider-specific prompt bodies
live in each provider worker (provider-*/prompts/identity.txt).
Custom trigger types
The harness emits two async orchestration trigger types siblings and consumers bind to, and registers five synchronous hook points operator-trusted siblings plug into in-path. Bind with the standard two-step pattern.
| Trigger type | Kind | Fires / runs |
|---|---|---|
harness::turn-started |
async event | A turn began executing (first loop step). |
harness::turn-completed |
async event | A turn reached a terminal status (completed / cancelled / failed), carrying the result. |
harness::hook::pre-turn |
sync hook | First step of a turn, before any model spend. May veto. |
harness::hook::pre-generate |
sync hook | After context assembly, before generation. May extend the system prompt, append messages, or veto. |
harness::hook::post-generate |
sync hook | After the final assistant message. Observe only. |
harness::hook::pre-trigger |
sync hook | After the allow/deny policy passes, before the target runs. May deny, hold, or rewrite arguments. |
harness::hook::post-trigger |
sync hook | After the target returns, before the result is persisted. May rewrite the result. |
Event configs accept { session_id?, parent_session_id? }; hook configs accept
{ functions?, priority?, timeout_ms?, on_error? }. See the spec at
tech-specs/2026-06-agentic/harness.md
for the hook contract and chain semantics.
api reference (json)
{
"functions": [
{
"description": "Internal control-plane: edit a still-parked queued message in place by entry_id, preserving its queue position.",
"metadata": {
"internal": true
},
"name": "harness::edit_queued",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"AgentMessage": {
"anyOf": [
{
"$ref": "#/definitions/AssistantMessage"
},
{
"$ref": "#/definitions/FunctionResultMessage"
},
{
"$ref": "#/definitions/CustomMessage"
},
{
"$ref": "#/definitions/UserMessage"
}
],
"description": "The canonical transcript message union. Untagged: the single-variant role tags disambiguate deserialization (assistant/function_result/custom are tried before user so their required fields gate the match)."
},
"AssistantMessage": {
"properties": {
"content": {
"items": {
"$ref": "#/definitions/ContentBlock"
},
"type": "array"
},
"error_kind": {
"anyOf": [
{
"$ref": "#/definitions/ErrorKind"
},
{
"type": "null"
}
]
},
"error_message": {
"type": [
"string",
"null"
]
},
"model": {
"type": "string"
},
"native_stop_reason": {
"type": [
"string",
"null"
]
},
"provider": {
"type": "string"
},
"role": {
"$ref": "#/definitions/AssistantRoleTag"
},
"stop_reason": {
"$ref": "#/definitions/StopReason"
},
"timestamp": {
"format": "int64",
"type": "integer"
},
"usage": {
"anyOf": [
{
"$ref": "#/definitions/Usage"
},
{
"type": "null"
}
]
},
"warnings": {
"items": {
"type": "string"
},
"type": [
"array",
"null"
]
}
},
"required": [
"content",
"model",
"provider",
"role",
"stop_reason",
"timestamp"
],
"type": "object"
},
"AssistantRoleTag": {
"enum": [
"assistant"
],
"type": "string"
},
"ContentBlock": {
"oneOf": [
{
"properties": {
"text": {
"type": "string"
},
"type": {
"enum": [
"text"
],
"type": "string"
}
},
"required": [
"text",
"type"
],
"type": "object"
},
{
"properties": {
"data": {
"type": "string"
},
"mime": {
"type": "string"
},
"type": {
"enum": [
"image"
],
"type": "string"
}
},
"required": [
"data",
"mime",
"type"
],
"type": "object"
},
{
"properties": {
"signature": {
"type": [
"string",
"null"
]
},
"text": {
"type": "string"
},
"type": {
"enum": [
"thinking"
],
"type": "string"
}
},
"required": [
"text",
"type"
],
"type": "object"
},
{
"description": "Opaque redacted thinking payload — replayed verbatim on the wire.",
"properties": {
"data": {
"type": "string"
},
"type": {
"enum": [
"redacted_thinking"
],
"type": "string"
}
},
"required": [
"data",
"type"
],
"type": "object"
},
{
"properties": {
"arguments": true,
"function_id": {
"type": "string"
},
"id": {
"type": "string"
},
"type": {
"enum": [
"function_call"
],
"type": "string"
}
},
"required": [
"arguments",
"function_id",
"id",
"type"
],
"type": "object"
},
{
"properties": {
"content": {
"items": {
"$ref": "#/definitions/ContentBlock"
},
"type": "array"
},
"function_call_id": {
"type": "string"
},
"is_error": {
"type": [
"boolean",
"null"
]
},
"type": {
"enum": [
"function_result"
],
"type": "string"
}
},
"required": [
"content",
"function_call_id",
"type"
],
"type": "object"
}
]
},
"CustomMessage": {
"properties": {
"content": {
"items": {
"$ref": "#/definitions/ContentBlock"
},
"type": "array"
},
"custom_type": {
"type": "string"
},
"details": true,
"display": {
"type": [
"string",
"null"
]
},
"role": {
"$ref": "#/definitions/CustomRoleTag"
},
"timestamp": {
"format": "int64",
"type": "integer"
}
},
"required": [
"content",
"custom_type",
"role",
"timestamp"
],
"type": "object"
},
"CustomRoleTag": {
"enum": [
"custom"
],
"type": "string"
},
"ErrorKind": {
"enum": [
"auth_expired",
"rate_limited",
"context_overflow",
"transient",
"permanent"
],
"type": "string"
},
"FunctionResultMessage": {
"properties": {
"content": {
"items": {
"$ref": "#/definitions/ContentBlock"
},
"type": "array"
},
"details": true,
"function_call_id": {
"type": "string"
},
"function_id": {
"type": "string"
},
"is_error": {
"type": "boolean"
},
"role": {
"$ref": "#/definitions/FunctionResultRoleTag"
},
"timestamp": {
"format": "int64",
"type": "integer"
}
},
"required": [
"content",
"details",
"function_call_id",
"function_id",
"is_error",
"role",
"timestamp"
],
"type": "object"
},
"FunctionResultRoleTag": {
"enum": [
"function_result"
],
"type": "string"
},
"MessageInput": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/AgentMessage"
}
],
"description": "`message` is either a plain string (sugar for a user text message) or a full `AgentMessage`."
},
"StopReason": {
"enum": [
"end",
"length",
"function_call",
"aborted",
"error"
],
"type": "string"
},
"Usage": {
"properties": {
"cache_read": {
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"cache_write": {
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"cost_usd": {
"format": "double",
"type": [
"number",
"null"
]
},
"input": {
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"output": {
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"reasoning": {
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
}
},
"type": "object"
},
"UserMessage": {
"properties": {
"content": {
"items": {
"$ref": "#/definitions/ContentBlock"
},
"type": "array"
},
"role": {
"$ref": "#/definitions/UserRoleTag"
},
"timestamp": {
"format": "int64",
"type": "integer"
}
},
"required": [
"content",
"role",
"timestamp"
],
"type": "object"
},
"UserRoleTag": {
"enum": [
"user"
],
"type": "string"
}
},
"properties": {
"entry_id": {
"description": "The queued row to edit (its client-visible `entry_id`).",
"type": "string"
},
"message": {
"allOf": [
{
"$ref": "#/definitions/MessageInput"
}
],
"description": "The replacement message (string sugar or a full user/custom message)."
},
"session_id": {
"type": "string"
}
},
"required": [
"entry_id",
"message",
"session_id"
],
"title": "EditQueuedRequest",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"updated": {
"description": "False when no still-parked row matched — already drained or unknown.",
"type": "boolean"
}
},
"required": [
"updated"
],
"title": "EditQueuedResponse",
"type": "object"
}
},
{
"description": "Internal control-plane: grant a session access to an additional filesystem root.",
"metadata": {
"internal": true
},
"name": "harness::filesystem::grant",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"root": {
"type": "string"
},
"session_id": {
"type": "string"
}
},
"required": [
"root",
"session_id"
],
"title": "FilesystemGrantRequest",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"roots": {
"items": {
"type": "string"
},
"type": "array"
},
"session_id": {
"type": "string"
}
},
"required": [
"roots",
"session_id"
],
"title": "FilesystemGrantsResponse",
"type": "object"
}
},
{
"description": "Internal control-plane: list additional filesystem roots granted to a session.",
"metadata": {
"internal": true
},
"name": "harness::filesystem::grants",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"session_id": {
"type": "string"
}
},
"required": [
"session_id"
],
"title": "FilesystemGrantsRequest",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"roots": {
"items": {
"type": "string"
},
"type": "array"
},
"session_id": {
"type": "string"
}
},
"required": [
"roots",
"session_id"
],
"title": "FilesystemGrantsResponse",
"type": "object"
}
},
{
"description": "Internal control-plane: the default working-directory root new sessions are scoped to.",
"metadata": {
"internal": true
},
"name": "harness::filesystem::info",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "FilesystemInfoRequest",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"FilesystemBoundary": {
"enum": [
"workspace",
"configured_roots"
],
"type": "string"
}
},
"properties": {
"boundary": {
"allOf": [
{
"$ref": "#/definitions/FilesystemBoundary"
}
],
"description": "Effective per-session boundary for shell/coder calls. `workspace` when the filesystem approval hook can widen it, otherwise `configured_roots`."
},
"default_root": {
"description": "Working-directory root stamped onto the first turn of a session whose send carries no explicit `fs_scope.root`; `null` when defaulting is disabled (`default_filesystem_root: \"off\"`) or the cwd is unreadable.",
"type": [
"string",
"null"
]
}
},
"required": [
"boundary"
],
"title": "FilesystemInfoResponse",
"type": "object"
}
},
{
"description": "Internal control-plane: revoke a session's access to an additional filesystem root.",
"metadata": {
"internal": true
},
"name": "harness::filesystem::revoke",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"root": {
"type": "string"
},
"session_id": {
"type": "string"
}
},
"required": [
"root",
"session_id"
],
"title": "FilesystemRevokeRequest",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"roots": {
"items": {
"type": "string"
},
"type": "array"
},
"session_id": {
"type": "string"
}
},
"required": [
"roots",
"session_id"
],
"title": "FilesystemGrantsResponse",
"type": "object"
}
},
{
"description": "Internal: settle a pending call's result (or release a held call) and resume the parked turn.",
"metadata": {
"internal": true
},
"name": "harness::function::resolve",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"ContentBlock": {
"oneOf": [
{
"properties": {
"text": {
"type": "string"
},
"type": {
"enum": [
"text"
],
"type": "string"
}
},
"required": [
"text",
"type"
],
"type": "object"
},
{
"properties": {
"data": {
"type": "string"
},
"mime": {
"type": "string"
},
"type": {
"enum": [
"image"
],
"type": "string"
}
},
"required": [
"data",
"mime",
"type"
],
"type": "object"
},
{
"properties": {
"signature": {
"type": [
"string",
"null"
]
},
"text": {
"type": "string"
},
"type": {
"enum": [
"thinking"
],
"type": "string"
}
},
"required": [
"text",
"type"
],
"type": "object"
},
{
"description": "Opaque redacted thinking payload — replayed verbatim on the wire.",
"properties": {
"data": {
"type": "string"
},
"type": {
"enum": [
"redacted_thinking"
],
"type": "string"
}
},
"required": [
"data",
"type"
],
"type": "object"
},
{
"properties": {
"arguments": true,
"function_id": {
"type": "string"
},
"id": {
"type": "string"
},
"type": {
"enum": [
"function_call"
],
"type": "string"
}
},
"required": [
"arguments",
"function_id",
"id",
"type"
],
"type": "object"
},
{
"properties": {
"content": {
"items": {
"$ref": "#/definitions/ContentBlock"
},
"type": "array"
},
"function_call_id": {
"type": "string"
},
"is_error": {
"type": [
"boolean",
"null"
]
},
"type": {
"enum": [
"function_result"
],
"type": "string"
}
},
"required": [
"content",
"function_call_id",
"type"
],
"type": "object"
}
]
},
"ResolveFsScope": {
"properties": {
"grants": {
"default": [],
"items": {
"type": "string"
},
"type": "array"
}
},
"type": "object"
}
},
"properties": {
"action": {
"description": "`deliver` (default) supplies the result; `execute` releases a hook-held call through the remaining trigger pipeline.",
"type": [
"string",
"null"
]
},
"content": {
"items": {
"$ref": "#/definitions/ContentBlock"
},
"type": [
"array",
"null"
]
},
"details": true,
"fs_scope": {
"anyOf": [
{
"$ref": "#/definitions/ResolveFsScope"
},
{
"type": "null"
}
],
"description": "execute only: one-shot additional roots trusted by the caller and unioned with the session's durable filesystem grants."
},
"function_call_id": {
"type": "string"
},
"is_error": {
"type": [
"boolean",
"null"
]
},
"session_id": {
"type": "string"
},
"turn_id": {
"type": "string"
}
},
"required": [
"function_call_id",
"session_id",
"turn_id"
],
"title": "FunctionResolveRequest",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"resolved": {
"description": "False when the call is unknown, already done, or (execute) not held.",
"type": "boolean"
},
"turn_resumed": {
"description": "True when this resolve re-enqueued the turn.",
"type": "boolean"
}
},
"required": [
"resolved",
"turn_resumed"
],
"title": "FunctionResolveResponse",
"type": "object"
}
},
{
"description": "Internal: invoke one iii function (unwrapped from agent_trigger), enforce the dispatch policy, and capture the normalised result — or report it pending.",
"metadata": {
"internal": true
},
"name": "harness::function::trigger",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"TriggerCall": {
"properties": {
"arguments": true,
"function_id": {
"description": "The iii function to invoke (already unwrapped from `agent_trigger`).",
"type": "string"
},
"id": {
"description": "function_call id, echoed into the result.",
"type": "string"
}
},
"required": [
"arguments",
"function_id",
"id"
],
"type": "object"
}
},
"properties": {
"call": {
"$ref": "#/definitions/TriggerCall"
},
"session_id": {
"type": "string"
}
},
"required": [
"call",
"session_id"
],
"title": "FunctionTriggerRequest",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"anyOf": [
{
"$ref": "#/definitions/TriggerResultResponse"
},
{
"$ref": "#/definitions/TriggerPendingResponse"
}
],
"definitions": {
"ContentBlock": {
"oneOf": [
{
"properties": {
"text": {
"type": "string"
},
"type": {
"enum": [
"text"
],
"type": "string"
}
},
"required": [
"text",
"type"
],
"type": "object"
},
{
"properties": {
"data": {
"type": "string"
},
"mime": {
"type": "string"
},
"type": {
"enum": [
"image"
],
"type": "string"
}
},
"required": [
"data",
"mime",
"type"
],
"type": "object"
},
{
"properties": {
"signature": {
"type": [
"string",
"null"
]
},
"text": {
"type": "string"
},
"type": {
"enum": [
"thinking"
],
"type": "string"
}
},
"required": [
"text",
"type"
],
"type": "object"
},
{
"description": "Opaque redacted thinking payload — replayed verbatim on the wire.",
"properties": {
"data": {
"type": "string"
},
"type": {
"enum": [
"redacted_thinking"
],
"type": "string"
}
},
"required": [
"data",
"type"
],
"type": "object"
},
{
"properties": {
"arguments": true,
"function_id": {
"type": "string"
},
"id": {
"type": "string"
},
"type": {
"enum": [
"function_call"
],
"type": "string"
}
},
"required": [
"arguments",
"function_id",
"id",
"type"
],
"type": "object"
},
{
"properties": {
"content": {
"items": {
"$ref": "#/definitions/ContentBlock"
},
"type": "array"
},
"function_call_id": {
"type": "string"
},
"is_error": {
"type": [
"boolean",
"null"
]
},
"type": {
"enum": [
"function_result"
],
"type": "string"
}
},
"required": [
"content",
"function_call_id",
"type"
],
"type": "object"
}
]
},
"TriggerPendingResponse": {
"properties": {
"function_call_id": {
"type": "string"
},
"function_id": {
"type": "string"
},
"pending": {
"type": "boolean"
},
"pending_timeout_ms": {
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
}
},
"required": [
"function_call_id",
"function_id",
"pending"
],
"type": "object"
},
"TriggerResultResponse": {
"properties": {
"content": {
"items": {
"$ref": "#/definitions/ContentBlock"
},
"type": "array"
},
"details": true,
"duration_ms": {
"format": "uint64",
"minimum": 0,
"type": "integer"
},
"function_call_id": {
"type": "string"
},
"function_id": {
"type": "string"
},
"is_error": {
"type": "boolean"
}
},
"required": [
"content",
"details",
"duration_ms",
"function_call_id",
"function_id",
"is_error"
],
"type": "object"
}
},
"title": "FunctionTriggerResponse"
}
},
{
"description": "Internal: the shared subscription fire handler — injects a notification into the owning session (resolved from the local subscription registry). Not called directly.",
"metadata": {
"internal": true
},
"name": "harness::notify_agent",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "Arbitrary fired-event payload from the subscribed trigger; delivered verbatim to the owning agent as a notification.",
"title": "NotifyAgentEvent",
"type": [
"null",
"boolean",
"number",
"string",
"array",
"object"
]
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "Ack returned by `harness::notify_agent`. Fires are ack'd even when dropped (stale, foreign, or malformed subscriptions log and return ok).",
"properties": {
"ok": {
"type": "boolean"
}
},
"required": [
"ok"
],
"title": "NotifyAgentResponse",
"type": "object"
}
},
{
"description": "Internal: refresh the cached function-registry snapshot when functions are registered/unregistered (driven by the engine::functions-available trigger).",
"metadata": {
"internal": true
},
"name": "harness::on-functions-change",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "Internal `harness::on-functions-change` payload. The handler re-fetches the authoritative registry, so the (advisory) event tag is the only field.",
"properties": {
"event": {
"default": null,
"description": "Engine event tag (advisory; the handler re-fetches the full list).",
"type": [
"string",
"null"
]
}
},
"title": "OnFunctionsChangeEvent",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "Ack returned by the internal `harness::on-functions-change` handler.",
"properties": {
"ok": {
"type": "boolean"
}
},
"required": [
"ok"
],
"title": "OnFunctionsChangeResponse",
"type": "object"
}
},
{
"description": "Internal: drop a deleted session's ephemeral subscriptions. Not called directly.",
"metadata": {
"internal": true
},
"name": "harness::on-session-deleted",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "`session::deleted` payload (only the field we read).",
"properties": {
"session_id": {
"type": "string"
}
},
"required": [
"session_id"
],
"title": "SessionDeletedEvent",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"ok": {
"type": "boolean"
},
"removed": {
"format": "uint64",
"minimum": 0,
"type": "integer"
}
},
"required": [
"ok",
"removed"
],
"title": "SessionDeletedAck",
"type": "object"
}
},
{
"description": "Internal trigger bridge: reshape a subscribed event into a harness::spawn (a sub-agent), optionally behind a join barrier. Not called directly — THE way to spin up sub-agents on events and callbacks: bind it via engine::register_trigger with the sub-agent spec in `metadata`.",
"metadata": {},
"name": "harness::react",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "Arbitrary fired-event payload from the subscribed trigger; appended to the spawned sub-agent task.",
"title": "ReactEvent",
"type": [
"null",
"boolean",
"number",
"string",
"array",
"object"
]
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"child_session_id": {
"description": "The spawned sub-agent's child session id, when spawn returned one.",
"type": [
"string",
"null"
]
},
"note": {
"description": "Why nothing spawned (missing spec, join not yet complete, already fired, error). Present iff `!spawned`.",
"type": [
"string",
"null"
]
},
"spawned": {
"description": "Whether a `harness::spawn` was dispatched this call.",
"type": "boolean"
}
},
"required": [
"spawned"
],
"title": "ReactResult",
"type": "object"
}
},
{
"description": "Entry point: ensure the session, persist the incoming message, and kick off a turn; returns fast (or merges into a running turn).",
"metadata": {
"internal": true
},
"name": "harness::send",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"AgentMessage": {
"anyOf": [
{
"$ref": "#/definitions/AssistantMessage"
},
{
"$ref": "#/definitions/FunctionResultMessage"
},
{
"$ref": "#/definitions/CustomMessage"
},
{
"$ref": "#/definitions/UserMessage"
}
],
"description": "The canonical transcript message union. Untagged: the single-variant role tags disambiguate deserialization (assistant/function_result/custom are tried before user so their required fields gate the match)."
},
"AssistantMessage": {
"properties": {
"content": {
"items": {
"$ref": "#/definitions/ContentBlock"
},
"type": "array"
},
"error_kind": {
"anyOf": [
{
"$ref": "#/definitions/ErrorKind"
},
{
"type": "null"
}
]
},
"error_message": {
"type": [
"string",
"null"
]
},
"model": {
"type": "string"
},
"native_stop_reason": {
"type": [
"string",
"null"
]
},
"provider": {
"type": "string"
},
"role": {
"$ref": "#/definitions/AssistantRoleTag"
},
"stop_reason": {
"$ref": "#/definitions/StopReason"
},
"timestamp": {
"format": "int64",
"type": "integer"
},
"usage": {
"anyOf": [
{
"$ref": "#/definitions/Usage"
},
{
"type": "null"
}
]
},
"warnings": {
"items": {
"type": "string"
},
"type": [
"array",
"null"
]
}
},
"required": [
"content",
"model",
"provider",
"role",
"stop_reason",
"timestamp"
],
"type": "object"
},
"AssistantRoleTag": {
"enum": [
"assistant"
],
"type": "string"
},
"ContentBlock": {
"oneOf": [
{
"properties": {
"text": {
"type": "string"
},
"type": {
"enum": [
"text"
],
"type": "string"
}
},
"required": [
"text",
"type"
],
"type": "object"
},
{
"properties": {
"data": {
"type": "string"
},
"mime": {
"type": "string"
},
"type": {
"enum": [
"image"
],
"type": "string"
}
},
"required": [
"data",
"mime",
"type"
],
"type": "object"
},
{
"properties": {
"signature": {
"type": [
"string",
"null"
]
},
"text": {
"type": "string"
},
"type": {
"enum": [
"thinking"
],
"type": "string"
}
},
"required": [
"text",
"type"
],
"type": "object"
},
{
"description": "Opaque redacted thinking payload — replayed verbatim on the wire.",
"properties": {
"data": {
"type": "string"
},
"type": {
"enum": [
"redacted_thinking"
],
"type": "string"
}
},
"required": [
"data",
"type"
],
"type": "object"
},
{
"properties": {
"arguments": true,
"function_id": {
"type": "string"
},
"id": {
"type": "string"
},
"type": {
"enum": [
"function_call"
],
"type": "string"
}
},
"required": [
"arguments",
"function_id",
"id",
"type"
],
"type": "object"
},
{
"properties": {
"content": {
"items": {
"$ref": "#/definitions/ContentBlock"
},
"type": "array"
},
"function_call_id": {
"type": "string"
},
"is_error": {
"type": [
"boolean",
"null"
]
},
"type": {
"enum": [
"function_result"
],
"type": "string"
}
},
"required": [
"content",
"function_call_id",
"type"
],
"type": "object"
}
]
},
"CustomMessage": {
"properties": {
"content": {
"items": {
"$ref": "#/definitions/ContentBlock"
},
"type": "array"
},
"custom_type": {
"type": "string"
},
"details": true,
"display": {
"type": [
"string",
"null"
]
},
"role": {
"$ref": "#/definitions/CustomRoleTag"
},
"timestamp": {
"format": "int64",
"type": "integer"
}
},
"required": [
"content",
"custom_type",
"role",
"timestamp"
],
"type": "object"
},
"CustomRoleTag": {
"enum": [
"custom"
],
"type": "string"
},
"ErrorKind": {
"enum": [
"auth_expired",
"rate_limited",
"context_overflow",
"transient",
"permanent"
],
"type": "string"
},
"ExposeMode": {
"description": "How allowed functions reach the model (harness.md § Exposure modes).",
"enum": [
"agent_trigger",
"native"
],
"type": "string"
},
"FunctionPolicy": {
"description": "The fail-closed dispatch policy (harness.md § Functions). Absent on the send => every call denied (a plain chat loop).",
"properties": {
"allow": {
"default": [],
"items": {
"type": "string"
},
"type": "array"
},
"deny": {
"default": [],
"items": {
"type": "string"
},
"type": "array"
},
"expose": {
"allOf": [
{
"$ref": "#/definitions/ExposeMode"
}
],
"default": "agent_trigger"
}
},
"type": "object"
},
"FunctionResultMessage": {
"properties": {
"content": {
"items": {
"$ref": "#/definitions/ContentBlock"
},
"type": "array"
},
"details": true,
"function_call_id": {
"type": "string"
},
"function_id": {
"type": "string"
},
"is_error": {
"type": "boolean"
},
"role": {
"$ref": "#/definitions/FunctionResultRoleTag"
},
"timestamp": {
"format": "int64",
"type": "integer"
}
},
"required": [
"content",
"details",
"function_call_id",
"function_id",
"is_error",
"role",
"timestamp"
],
"type": "object"
},
"FunctionResultRoleTag": {
"enum": [
"function_result"
],
"type": "string"
},
"MessageInput": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/AgentMessage"
}
],
"description": "`message` is either a plain string (sugar for a user text message) or a full `AgentMessage`."
},
"Mode": {
"description": "Console / send operating mode — prepends a short paragraph before the shared identity prompt.",
"enum": [
"plan",
"ask",
"agent"
],
"type": "string"
},
"OutputContract": {
"description": "Free text by default; `json` constrains the final answer to a JSON value, validated against `schema` when supplied.",
"oneOf": [
{
"properties": {
"type": {
"enum": [
"text"
],
"type": "string"
}
},
"required": [
"type"
],
"type": "object"
},
{
"properties": {
"schema": true,
"type": {
"enum": [
"json"
],
"type": "string"
}
},
"required": [
"type"
],
"type": "object"
}
]
},
"SendOptions": {
"description": "Per-send options frozen onto the turn record (harness.md § `harness::send`).",
"properties": {
"functions": {
"anyOf": [
{
"$ref": "#/definitions/FunctionPolicy"
},
{
"type": "null"
}
],
"description": "The fail-closed dispatch policy; omit to deny every call."
},
"max_turns": {
"format": "uint32",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"metadata": {
"description": "Tracing passthrough."
},
"mode": {
"anyOf": [
{
"$ref": "#/definitions/Mode"
},
{
"type": "null"
}
]
},
"output": {
"anyOf": [
{
"$ref": "#/definitions/OutputContract"
},
{
"type": "null"
}
],
"description": "The turn's deliverable; default `{ type: \"text\" }`."
},
"provider_options": {
"additionalProperties": true,
"description": "Provider-native per-call options, namespaced by provider id.",
"type": [
"object",
"null"
]
},
"system_prompt": {
"type": [
"string",
"null"
]
},
"system_prompt_strategy": {
"allOf": [
{
"$ref": "#/definitions/SystemPromptStrategy"
}
],
"default": "enrich",
"description": "How `system_prompt` combines with the built-in prompt: `override` replaces it; `enrich` (default) appends to it."
},
"thinking_level": {
"anyOf": [
{
"$ref": "#/definitions/ThinkingLevel"
},
{
"type": "null"
}
]
}
},
"type": "object"
},
"SessionInit": {
"description": "Session create/ensure options applied when this send creates the session.",
"properties": {
"metadata": true,
"title": {
"type": [
"string",
"null"
]
}
},
"type": "object"
},
"StopReason": {
"enum": [
"end",
"length",
"function_call",
"aborted",
"error"
],
"type": "string"
},
"SystemPromptStrategy": {
"description": "How a caller-supplied system prompt combines with the built-in identity prompt.",
"oneOf": [
{
"description": "Caller prompt replaces the built-in prompt verbatim.",
"enum": [
"override"
],
"type": "string"
},
{
"description": "Caller prompt is appended to the built-in identity prompt.",
"enum": [
"enrich"
],
"type": "string"
}
]
},
"ThinkingLevel": {
"enum": [
"minimal",
"low",
"medium",
"high",
"xhigh"
],
"type": "string"
},
"Usage": {
"properties": {
"cache_read": {
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"cache_write": {
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"cost_usd": {
"format": "double",
"type": [
"number",
"null"
]
},
"input": {
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"output": {
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"reasoning": {
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
}
},
"type": "object"
},
"UserMessage": {
"properties": {
"content": {
"items": {
"$ref": "#/definitions/ContentBlock"
},
"type": "array"
},
"role": {
"$ref": "#/definitions/UserRoleTag"
},
"timestamp": {
"format": "int64",
"type": "integer"
}
},
"required": [
"content",
"role",
"timestamp"
],
"type": "object"
},
"UserRoleTag": {
"enum": [
"user"
],
"type": "string"
}
},
"properties": {
"idempotency_key": {
"description": "Webhook dedupe: a repeated key returns the original `{session_id, turn_id}` and appends nothing.",
"type": [
"string",
"null"
]
},
"message": {
"allOf": [
{
"$ref": "#/definitions/MessageInput"
}
],
"description": "The incoming message; a string is sugar for a user text message. The role must be `user` or `custom`."
},
"model": {
"type": "string"
},
"options": {
"anyOf": [
{
"$ref": "#/definitions/SendOptions"
},
{
"type": "null"
}
]
},
"provider": {
"type": [
"string",
"null"
]
},
"session": {
"anyOf": [
{
"$ref": "#/definitions/SessionInit"
},
{
"type": "null"
}
],
"description": "Applied when this send creates/ensures the session."
},
"session_id": {
"description": "Omit to create a new session.",
"type": [
"string",
"null"
]
}
},
"required": [
"message",
"model"
],
"title": "SendRequest",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"accepted": {
"type": "boolean"
},
"deduplicated": {
"description": "True when `idempotency_key` matched an earlier send.",
"type": [
"boolean",
"null"
]
},
"merged": {
"description": "True when folded into an in-flight turn (steering).",
"type": [
"boolean",
"null"
]
},
"queued": {
"description": "True when the message was queued while a step was streaming; it lands in the transcript when the stream ends.",
"type": [
"boolean",
"null"
]
},
"session_id": {
"type": "string"
},
"turn_id": {
"type": "string"
}
},
"required": [
"accepted",
"session_id",
"turn_id"
],
"title": "SendResponse",
"type": "object"
}
},
{
"description": "Spawn a sub-agent in a child session; the model-facing pending trigger — parks the calling turn until the child resolves. Call it directly ONLY when the current turn needs the child's answer; for callbacks, follow-up stages, and fan-in, register the reaction via engine::register_trigger -> harness::react instead.",
"metadata": {},
"name": "harness::spawn",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"AgentMessage": {
"anyOf": [
{
"$ref": "#/definitions/AssistantMessage"
},
{
"$ref": "#/definitions/FunctionResultMessage"
},
{
"$ref": "#/definitions/CustomMessage"
},
{
"$ref": "#/definitions/UserMessage"
}
],
"description": "The canonical transcript message union. Untagged: the single-variant role tags disambiguate deserialization (assistant/function_result/custom are tried before user so their required fields gate the match)."
},
"AssistantMessage": {
"properties": {
"content": {
"items": {
"$ref": "#/definitions/ContentBlock"
},
"type": "array"
},
"error_kind": {
"anyOf": [
{
"$ref": "#/definitions/ErrorKind"
},
{
"type": "null"
}
]
},
"error_message": {
"type": [
"string",
"null"
]
},
"model": {
"type": "string"
},
"native_stop_reason": {
"type": [
"string",
"null"
]
},
"provider": {
"type": "string"
},
"role": {
"$ref": "#/definitions/AssistantRoleTag"
},
"stop_reason": {
"$ref": "#/definitions/StopReason"
},
"timestamp": {
"format": "int64",
"type": "integer"
},
"usage": {
"anyOf": [
{
"$ref": "#/definitions/Usage"
},
{
"type": "null"
}
]
},
"warnings": {
"items": {
"type": "string"
},
"type": [
"array",
"null"
]
}
},
"required": [
"content",
"model",
"provider",
"role",
"stop_reason",
"timestamp"
],
"type": "object"
},
"AssistantRoleTag": {
"enum": [
"assistant"
],
"type": "string"
},
"ContentBlock": {
"oneOf": [
{
"properties": {
"text": {
"type": "string"
},
"type": {
"enum": [
"text"
],
"type": "string"
}
},
"required": [
"text",
"type"
],
"type": "object"
},
{
"properties": {
"data": {
"type": "string"
},
"mime": {
"type": "string"
},
"type": {
"enum": [
"image"
],
"type": "string"
}
},
"required": [
"data",
"mime",
"type"
],
"type": "object"
},
{
"properties": {
"signature": {
"type": [
"string",
"null"
]
},
"text": {
"type": "string"
},
"type": {
"enum": [
"thinking"
],
"type": "string"
}
},
"required": [
"text",
"type"
],
"type": "object"
},
{
"description": "Opaque redacted thinking payload — replayed verbatim on the wire.",
"properties": {
"data": {
"type": "string"
},
"type": {
"enum": [
"redacted_thinking"
],
"type": "string"
}
},
"required": [
"data",
"type"
],
"type": "object"
},
{
"properties": {
"arguments": true,
"function_id": {
"type": "string"
},
"id": {
"type": "string"
},
"type": {
"enum": [
"function_call"
],
"type": "string"
}
},
"required": [
"arguments",
"function_id",
"id",
"type"
],
"type": "object"
},
{
"properties": {
"content": {
"items": {
"$ref": "#/definitions/ContentBlock"
},
"type": "array"
},
"function_call_id": {
"type": "string"
},
"is_error": {
"type": [
"boolean",
"null"
]
},
"type": {
"enum": [
"function_result"
],
"type": "string"
}
},
"required": [
"content",
"function_call_id",
"type"
],
"type": "object"
}
]
},
"CustomMessage": {
"properties": {
"content": {
"items": {
"$ref": "#/definitions/ContentBlock"
},
"type": "array"
},
"custom_type": {
"type": "string"
},
"details": true,
"display": {
"type": [
"string",
"null"
]
},
"role": {
"$ref": "#/definitions/CustomRoleTag"
},
"timestamp": {
"format": "int64",
"type": "integer"
}
},
"required": [
"content",
"custom_type",
"role",
"timestamp"
],
"type": "object"
},
"CustomRoleTag": {
"enum": [
"custom"
],
"type": "string"
},
"ErrorKind": {
"enum": [
"auth_expired",
"rate_limited",
"context_overflow",
"transient",
"permanent"
],
"type": "string"
},
"ExposeMode": {
"description": "How allowed functions reach the model (harness.md § Exposure modes).",
"enum": [
"agent_trigger",
"native"
],
"type": "string"
},
"FunctionPolicy": {
"description": "The fail-closed dispatch policy (harness.md § Functions). Absent on the send => every call denied (a plain chat loop).",
"properties": {
"allow": {
"default": [],
"items": {
"type": "string"
},
"type": "array"
},
"deny": {
"default": [],
"items": {
"type": "string"
},
"type": "array"
},
"expose": {
"allOf": [
{
"$ref": "#/definitions/ExposeMode"
}
],
"default": "agent_trigger"
}
},
"type": "object"
},
"FunctionResultMessage": {
"properties": {
"content": {
"items": {
"$ref": "#/definitions/ContentBlock"
},
"type": "array"
},
"details": true,
"function_call_id": {
"type": "string"
},
"function_id": {
"type": "string"
},
"is_error": {
"type": "boolean"
},
"role": {
"$ref": "#/definitions/FunctionResultRoleTag"
},
"timestamp": {
"format": "int64",
"type": "integer"
}
},
"required": [
"content",
"details",
"function_call_id",
"function_id",
"is_error",
"role",
"timestamp"
],
"type": "object"
},
"FunctionResultRoleTag": {
"enum": [
"function_result"
],
"type": "string"
},
"MessageInput": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/AgentMessage"
}
],
"description": "`message` is either a plain string (sugar for a user text message) or a full `AgentMessage`."
},
"Mode": {
"description": "Console / send operating mode — prepends a short paragraph before the shared identity prompt.",
"enum": [
"plan",
"ask",
"agent"
],
"type": "string"
},
"OutputContract": {
"description": "Free text by default; `json` constrains the final answer to a JSON value, validated against `schema` when supplied.",
"oneOf": [
{
"properties": {
"type": {
"enum": [
"text"
],
"type": "string"
}
},
"required": [
"type"
],
"type": "object"
},
{
"properties": {
"schema": true,
"type": {
"enum": [
"json"
],
"type": "string"
}
},
"required": [
"type"
],
"type": "object"
}
]
},
"SpawnOptions": {
"properties": {
"filesystem_root": {
"description": "Absolute filesystem root for the child turn (e.g. an isolated `worktree::create` checkout), written to the child's `metadata.fs_scope.root`. When set it overrides the inherited scope for this child; when absent the child inherits its direct parent's root unchanged.",
"type": [
"string",
"null"
]
},
"functions": {
"anyOf": [
{
"$ref": "#/definitions/FunctionPolicy"
},
{
"type": "null"
}
],
"description": "Intersected with the parent policy — narrow, never escalate."
},
"max_children": {
"description": "Fan-out guard for the child's own spawns.",
"format": "uint32",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"max_turns": {
"description": "Capped at the parent's remaining turn budget.",
"format": "uint32",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"mode": {
"anyOf": [
{
"$ref": "#/definitions/Mode"
},
{
"type": "null"
}
]
},
"output": {
"anyOf": [
{
"$ref": "#/definitions/OutputContract"
},
{
"type": "null"
}
],
"description": "The child's deliverable: text / json / json+schema."
},
"pending_timeout_ms": {
"description": "Parent-side wait guard for this child.",
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"system_prompt": {
"type": [
"string",
"null"
]
},
"system_prompt_strategy": {
"allOf": [
{
"$ref": "#/definitions/SystemPromptStrategy"
}
],
"default": "enrich",
"description": "How `system_prompt` combines with the built-in prompt: `override` replaces it; `enrich` (default) appends to it."
},
"thinking_level": {
"anyOf": [
{
"$ref": "#/definitions/ThinkingLevel"
},
{
"type": "null"
}
]
}
},
"type": "object"
},
"StopReason": {
"enum": [
"end",
"length",
"function_call",
"aborted",
"error"
],
"type": "string"
},
"SystemPromptStrategy": {
"description": "How a caller-supplied system prompt combines with the built-in identity prompt.",
"oneOf": [
{
"description": "Caller prompt replaces the built-in prompt verbatim.",
"enum": [
"override"
],
"type": "string"
},
{
"description": "Caller prompt is appended to the built-in identity prompt.",
"enum": [
"enrich"
],
"type": "string"
}
]
},
"ThinkingLevel": {
"enum": [
"minimal",
"low",
"medium",
"high",
"xhigh"
],
"type": "string"
},
"Usage": {
"properties": {
"cache_read": {
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"cache_write": {
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"cost_usd": {
"format": "double",
"type": [
"number",
"null"
]
},
"input": {
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"output": {
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"reasoning": {
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
}
},
"type": "object"
},
"UserMessage": {
"properties": {
"content": {
"items": {
"$ref": "#/definitions/ContentBlock"
},
"type": "array"
},
"role": {
"$ref": "#/definitions/UserRoleTag"
},
"timestamp": {
"format": "int64",
"type": "integer"
}
},
"required": [
"content",
"role",
"timestamp"
],
"type": "object"
},
"UserRoleTag": {
"enum": [
"user"
],
"type": "string"
}
},
"properties": {
"model": {
"type": [
"string",
"null"
]
},
"options": {
"anyOf": [
{
"$ref": "#/definitions/SpawnOptions"
},
{
"type": "null"
}
]
},
"parent_session_id": {
"description": "Display-only parent for the console session tree, used when there is no live parent turn (e.g. a trigger-fired spawn from `harness::react`). Writes `SessionMeta.metadata.parent_session_id` so the console nests this child; it does NOT grant policy inheritance or parent-call resolution. Ignored when the dispatcher injects a real parent link (an in-turn spawn).",
"type": [
"string",
"null"
]
},
"provider": {
"type": [
"string",
"null"
]
},
"reactive_depth": {
"description": "Stamped by `harness::react` (not caller-supplied): reactive-chain depth, echoed on this turn's `turn-completed` event so react can cap runaway chains at `MAX_REACTIVE_DEPTH`.",
"format": "uint32",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"session_id": {
"description": "Spawn into this session, creating it if it does not exist (e.g. a fork, or a pre-chosen id to filter `turn-completed` subscriptions on); default: create fresh.",
"type": [
"string",
"null"
]
},
"spawned_by_subscription_id": {
"description": "Stamped by `harness::react` (not caller-supplied): the subscription that spawned this turn. Its completion event is never delivered back to that same subscription (self-edge loop breaker).",
"type": [
"string",
"null"
]
},
"task": {
"allOf": [
{
"$ref": "#/definitions/MessageInput"
}
],
"description": "The child's goal — its opening user message."
}
},
"required": [
"task"
],
"title": "SpawnRequest",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"child_session_id": {
"type": "string"
},
"child_turn_id": {
"type": "string"
}
},
"required": [
"child_session_id",
"child_turn_id"
],
"title": "SpawnResponse",
"type": "object"
}
},
{
"description": "Read the current turn status for a session.",
"metadata": {},
"name": "harness::status",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"session_id": {
"type": "string"
}
},
"required": [
"session_id"
],
"title": "StatusRequest",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"anyOf": [
{
"$ref": "#/definitions/StatusReport"
},
{
"type": "null"
}
],
"definitions": {
"AgentMessage": {
"anyOf": [
{
"$ref": "#/definitions/AssistantMessage"
},
{
"$ref": "#/definitions/FunctionResultMessage"
},
{
"$ref": "#/definitions/CustomMessage"
},
{
"$ref": "#/definitions/UserMessage"
}
],
"description": "The canonical transcript message union. Untagged: the single-variant role tags disambiguate deserialization (assistant/function_result/custom are tried before user so their required fields gate the match)."
},
"AssistantMessage": {
"properties": {
"content": {
"items": {
"$ref": "#/definitions/ContentBlock"
},
"type": "array"
},
"error_kind": {
"anyOf": [
{
"$ref": "#/definitions/ErrorKind"
},
{
"type": "null"
}
]
},
"error_message": {
"type": [
"string",
"null"
]
},
"model": {
"type": "string"
},
"native_stop_reason": {
"type": [
"string",
"null"
]
},
"provider": {
"type": "string"
},
"role": {
"$ref": "#/definitions/AssistantRoleTag"
},
"stop_reason": {
"$ref": "#/definitions/StopReason"
},
"timestamp": {
"format": "int64",
"type": "integer"
},
"usage": {
"anyOf": [
{
"$ref": "#/definitions/Usage"
},
{
"type": "null"
}
]
},
"warnings": {
"items": {
"type": "string"
},
"type": [
"array",
"null"
]
}
},
"required": [
"content",
"model",
"provider",
"role",
"stop_reason",
"timestamp"
],
"type": "object"
},
"AssistantRoleTag": {
"enum": [
"assistant"
],
"type": "string"
},
"ChildRef": {
"properties": {
"function_call_id": {
"type": "string"
},
"session_id": {
"type": "string"
},
"turn_id": {
"type": "string"
}
},
"required": [
"function_call_id",
"session_id",
"turn_id"
],
"type": "object"
},
"ContentBlock": {
"oneOf": [
{
"properties": {
"text": {
"type": "string"
},
"type": {
"enum": [
"text"
],
"type": "string"
}
},
"required": [
"text",
"type"
],
"type": "object"
},
{
"properties": {
"data": {
"type": "string"
},
"mime": {
"type": "string"
},
"type": {
"enum": [
"image"
],
"type": "string"
}
},
"required": [
"data",
"mime",
"type"
],
"type": "object"
},
{
"properties": {
"signature": {
"type": [
"string",
"null"
]
},
"text": {
"type": "string"
},
"type": {
"enum": [
"thinking"
],
"type": "string"
}
},
"required": [
"text",
"type"
],
"type": "object"
},
{
"description": "Opaque redacted thinking payload — replayed verbatim on the wire.",
"properties": {
"data": {
"type": "string"
},
"type": {
"enum": [
"redacted_thinking"
],
"type": "string"
}
},
"required": [
"data",
"type"
],
"type": "object"
},
{
"properties": {
"arguments": true,
"function_id": {
"type": "string"
},
"id": {
"type": "string"
},
"type": {
"enum": [
"function_call"
],
"type": "string"
}
},
"required": [
"arguments",
"function_id",
"id",
"type"
],
"type": "object"
},
{
"properties": {
"content": {
"items": {
"$ref": "#/definitions/ContentBlock"
},
"type": "array"
},
"function_call_id": {
"type": "string"
},
"is_error": {
"type": [
"boolean",
"null"
]
},
"type": {
"enum": [
"function_result"
],
"type": "string"
}
},
"required": [
"content",
"function_call_id",
"type"
],
"type": "object"
}
]
},
"CustomMessage": {
"properties": {
"content": {
"items": {
"$ref": "#/definitions/ContentBlock"
},
"type": "array"
},
"custom_type": {
"type": "string"
},
"details": true,
"display": {
"type": [
"string",
"null"
]
},
"role": {
"$ref": "#/definitions/CustomRoleTag"
},
"timestamp": {
"format": "int64",
"type": "integer"
}
},
"required": [
"content",
"custom_type",
"role",
"timestamp"
],
"type": "object"
},
"CustomRoleTag": {
"enum": [
"custom"
],
"type": "string"
},
"ErrorKind": {
"enum": [
"auth_expired",
"rate_limited",
"context_overflow",
"transient",
"permanent"
],
"type": "string"
},
"FunctionResultMessage": {
"properties": {
"content": {
"items": {
"$ref": "#/definitions/ContentBlock"
},
"type": "array"
},
"details": true,
"function_call_id": {
"type": "string"
},
"function_id": {
"type": "string"
},
"is_error": {
"type": "boolean"
},
"role": {
"$ref": "#/definitions/FunctionResultRoleTag"
},
"timestamp": {
"format": "int64",
"type": "integer"
}
},
"required": [
"content",
"details",
"function_call_id",
"function_id",
"is_error",
"role",
"timestamp"
],
"type": "object"
},
"FunctionResultRoleTag": {
"enum": [
"function_result"
],
"type": "string"
},
"QueuedMessage": {
"description": "One message parked while a step was streaming, waiting for the loop's drain to append it to the transcript (harness.md § Concurrency & steering).",
"properties": {
"entry_id": {
"description": "Deterministic transcript entry id the drain appends under, so a redelivered drain is a no-op.",
"type": "string"
},
"id": {
"type": "string"
},
"message": {
"$ref": "#/definitions/AgentMessage"
},
"origin": true,
"queued_at": {
"format": "int64",
"type": "integer"
},
"session_id": {
"type": "string"
}
},
"required": [
"entry_id",
"id",
"message",
"queued_at",
"session_id"
],
"type": "object"
},
"StatusReport": {
"properties": {
"children": {
"items": {
"$ref": "#/definitions/ChildRef"
},
"type": "array"
},
"depth": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"max_transient_resumes": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"max_turns": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"max_validation_retries": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"partial_result_available": {
"type": "boolean"
},
"pending_function_calls": {
"items": {
"type": "string"
},
"type": "array"
},
"queued": {
"description": "Messages queued while a step streams, in arrival order; they land in the transcript when the stream ends.",
"items": {
"$ref": "#/definitions/QueuedMessage"
},
"type": "array"
},
"result": true,
"result_error": {
"type": [
"string",
"null"
]
},
"session_id": {
"type": "string"
},
"status": {
"$ref": "#/definitions/TurnStatus"
},
"step": {
"format": "uint64",
"minimum": 0,
"type": "integer"
},
"transient_resumes": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"turn_count": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"turn_id": {
"type": [
"string",
"null"
]
},
"validation_retries": {
"format": "uint32",
"minimum": 0,
"type": "integer"
}
},
"required": [
"children",
"depth",
"max_transient_resumes",
"max_turns",
"max_validation_retries",
"partial_result_available",
"pending_function_calls",
"session_id",
"status",
"step",
"transient_resumes",
"turn_count",
"validation_retries"
],
"type": "object"
},
"StopReason": {
"enum": [
"end",
"length",
"function_call",
"aborted",
"error"
],
"type": "string"
},
"TurnStatus": {
"description": "The coarse, harness-internal turn lifecycle (harness.md § API Reference). Finer-grained than the session's `status`, which the loop derives from it.",
"enum": [
"running",
"awaiting_functions",
"completed",
"cancelled",
"failed"
],
"type": "string"
},
"Usage": {
"properties": {
"cache_read": {
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"cache_write": {
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"cost_usd": {
"format": "double",
"type": [
"number",
"null"
]
},
"input": {
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"output": {
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"reasoning": {
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
}
},
"type": "object"
},
"UserMessage": {
"properties": {
"content": {
"items": {
"$ref": "#/definitions/ContentBlock"
},
"type": "array"
},
"role": {
"$ref": "#/definitions/UserRoleTag"
},
"timestamp": {
"format": "int64",
"type": "integer"
}
},
"required": [
"content",
"role",
"timestamp"
],
"type": "object"
},
"UserRoleTag": {
"enum": [
"user"
],
"type": "string"
}
},
"title": "Nullable_StatusReport"
}
},
{
"description": "Request cancellation of an in-flight turn (cascades to spawned children).",
"metadata": {
"internal": true
},
"name": "harness::stop",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"session_id": {
"type": "string"
},
"turn_id": {
"description": "Omit to stop the current turn.",
"type": [
"string",
"null"
]
}
},
"required": [
"session_id"
],
"title": "StopRequest",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"stopping": {
"type": "boolean"
}
},
"required": [
"stopping"
],
"title": "StopResponse",
"type": "object"
}
},
{
"description": "Internal cron sweep: resolve pending function calls past their timeout so a parked turn never wedges. Not called directly.",
"metadata": {
"internal": true
},
"name": "harness::sweep-pending",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "Cron event payload (ignored — the sweep scans all turn records). A struct keeps the request schema concrete.",
"properties": {
"scheduled_at": {
"default": null,
"format": "int64",
"type": [
"integer",
"null"
]
}
},
"title": "SweepEvent",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"ok": {
"type": "boolean"
},
"resolved": {
"description": "Number of expired pending calls resolved this sweep.",
"format": "uint64",
"minimum": 0,
"type": "integer"
}
},
"required": [
"ok",
"resolved"
],
"title": "SweepResponse",
"type": "object"
}
},
{
"description": "Internal durable loop step (enqueued onto the harness-turn queue); not called directly.",
"metadata": {
"internal": true,
"trace_hidden": true
},
"name": "harness::turn",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "The enqueued `harness::turn` step payload.",
"properties": {
"depth": {
"default": 0,
"description": "Sub-agent depth carried from the turn record (0 = top-level), so the step can stamp the `iii.tag.kind` baggage (`harness.turn` / `harness.subagent`) before any state read. Defaults to 0 so stale in-flight payloads from before this field existed still classify as top-level turns.",
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"message_preview": {
"description": "Preview carried from the turn record so the step can stamp the `iii.tag.message` baggage before any state read.",
"type": [
"string",
"null"
]
},
"session_id": {
"type": "string"
},
"step": {
"format": "uint64",
"minimum": 0,
"type": "integer"
},
"turn_id": {
"type": "string"
}
},
"required": [
"session_id",
"step",
"turn_id"
],
"title": "TurnStepPayload",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"TurnStatus": {
"description": "The coarse, harness-internal turn lifecycle (harness.md § API Reference). Finer-grained than the session's `status`, which the loop derives from it.",
"enum": [
"running",
"awaiting_functions",
"completed",
"cancelled",
"failed"
],
"type": "string"
}
},
"properties": {
"next_step": {
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"session_id": {
"type": "string"
},
"skipped": {
"default": false,
"description": "True when a redelivered/stale step was acked and dropped.",
"type": "boolean"
},
"status": {
"$ref": "#/definitions/TurnStatus"
}
},
"required": [
"session_id",
"status"
],
"title": "TurnStepResult",
"type": "object"
}
},
{
"description": "Internal control-plane: remove a still-parked queued message by entry_id (the console's edit-queued path).",
"metadata": {
"internal": true
},
"name": "harness::unqueue",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"entry_id": {
"description": "The queued row's transcript entry id, as surfaced by `harness::status` → `queued[].entry_id`. Stable and client-visible (the internal row id is not), so removals target it.",
"type": "string"
},
"session_id": {
"type": "string"
}
},
"required": [
"entry_id",
"session_id"
],
"title": "UnqueueRequest",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"removed": {
"description": "False when no still-parked row matched — already drained or unknown.",
"type": "boolean"
}
},
"required": [
"removed"
],
"title": "UnqueueResponse",
"type": "object"
}
}
],
"triggers": [
{
"description": "Synchronous hook: after the final assistant message update. Observe only.",
"invocation_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"description": "The `config` of a `harness::hook::<point>` trigger binding.",
"properties": {
"functions": {
"description": "pre/post_trigger only: target function_id globs to consult on.",
"items": {
"type": "string"
},
"type": [
"array",
"null"
]
},
"on_error": {
"description": "Failure policy (default fail_closed for pre_*, fail_open for post_*).",
"type": [
"string",
"null"
]
},
"priority": {
"description": "Chain order: ascending, ties broken by function_id (default 0).",
"format": "int64",
"type": [
"integer",
"null"
]
},
"timeout_ms": {
"description": "Per-invocation timeout (default 5000ms).",
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
}
},
"title": "HookTriggerConfig",
"type": "object"
},
"metadata": {},
"name": "harness::hook::post-generate",
"return_schema": {}
},
{
"description": "Synchronous hook: after the target returns, before the result is appended. May rewrite content/details/is_error.",
"invocation_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"description": "The `config` of a `harness::hook::<point>` trigger binding.",
"properties": {
"functions": {
"description": "pre/post_trigger only: target function_id globs to consult on.",
"items": {
"type": "string"
},
"type": [
"array",
"null"
]
},
"on_error": {
"description": "Failure policy (default fail_closed for pre_*, fail_open for post_*).",
"type": [
"string",
"null"
]
},
"priority": {
"description": "Chain order: ascending, ties broken by function_id (default 0).",
"format": "int64",
"type": [
"integer",
"null"
]
},
"timeout_ms": {
"description": "Per-invocation timeout (default 5000ms).",
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
}
},
"title": "HookTriggerConfig",
"type": "object"
},
"metadata": {},
"name": "harness::hook::post-trigger",
"return_schema": {}
},
{
"description": "Synchronous hook: after context assembly, before generation. May extend the system prompt, append messages, or veto.",
"invocation_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"description": "The `config` of a `harness::hook::<point>` trigger binding.",
"properties": {
"functions": {
"description": "pre/post_trigger only: target function_id globs to consult on.",
"items": {
"type": "string"
},
"type": [
"array",
"null"
]
},
"on_error": {
"description": "Failure policy (default fail_closed for pre_*, fail_open for post_*).",
"type": [
"string",
"null"
]
},
"priority": {
"description": "Chain order: ascending, ties broken by function_id (default 0).",
"format": "int64",
"type": [
"integer",
"null"
]
},
"timeout_ms": {
"description": "Per-invocation timeout (default 5000ms).",
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
}
},
"title": "HookTriggerConfig",
"type": "object"
},
"metadata": {},
"name": "harness::hook::pre-generate",
"return_schema": {}
},
{
"description": "Synchronous hook: after the allow/deny policy passes, before the target is invoked. May deny, hold, or rewrite arguments.",
"invocation_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"description": "The `config` of a `harness::hook::<point>` trigger binding.",
"properties": {
"functions": {
"description": "pre/post_trigger only: target function_id globs to consult on.",
"items": {
"type": "string"
},
"type": [
"array",
"null"
]
},
"on_error": {
"description": "Failure policy (default fail_closed for pre_*, fail_open for post_*).",
"type": [
"string",
"null"
]
},
"priority": {
"description": "Chain order: ascending, ties broken by function_id (default 0).",
"format": "int64",
"type": [
"integer",
"null"
]
},
"timeout_ms": {
"description": "Per-invocation timeout (default 5000ms).",
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
}
},
"title": "HookTriggerConfig",
"type": "object"
},
"metadata": {},
"name": "harness::hook::pre-trigger",
"return_schema": {}
},
{
"description": "Synchronous hook: first step of a turn, before any model spend. May veto.",
"invocation_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"description": "The `config` of a `harness::hook::<point>` trigger binding.",
"properties": {
"functions": {
"description": "pre/post_trigger only: target function_id globs to consult on.",
"items": {
"type": "string"
},
"type": [
"array",
"null"
]
},
"on_error": {
"description": "Failure policy (default fail_closed for pre_*, fail_open for post_*).",
"type": [
"string",
"null"
]
},
"priority": {
"description": "Chain order: ascending, ties broken by function_id (default 0).",
"format": "int64",
"type": [
"integer",
"null"
]
},
"timeout_ms": {
"description": "Per-invocation timeout (default 5000ms).",
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
}
},
"title": "HookTriggerConfig",
"type": "object"
},
"metadata": {},
"name": "harness::hook::pre-turn",
"return_schema": {}
},
{
"description": "A message parked in a session's server-side queue while its turn streams.",
"invocation_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"description": "Binding config shared by both turn-event types.",
"properties": {
"parent_session_id": {
"description": "Only deliver sub-agent events whose parent is this session.",
"type": [
"string",
"null"
]
},
"session_id": {
"description": "Only deliver events for this session.",
"type": [
"string",
"null"
]
}
},
"title": "TurnEventBindingConfig",
"type": "object"
},
"metadata": {},
"name": "harness::message-queued",
"return_schema": {}
},
{
"description": "A harness turn reached a terminal status (completed/cancelled/failed).",
"invocation_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"description": "Binding config shared by both turn-event types.",
"properties": {
"parent_session_id": {
"description": "Only deliver sub-agent events whose parent is this session.",
"type": [
"string",
"null"
]
},
"session_id": {
"description": "Only deliver events for this session.",
"type": [
"string",
"null"
]
}
},
"title": "TurnEventBindingConfig",
"type": "object"
},
"metadata": {},
"name": "harness::turn-completed",
"return_schema": {}
},
{
"description": "A harness turn began executing (first loop step).",
"invocation_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"description": "Binding config shared by both turn-event types.",
"properties": {
"parent_session_id": {
"description": "Only deliver sub-agent events whose parent is this session.",
"type": [
"string",
"null"
]
},
"session_id": {
"description": "Only deliver events for this session.",
"type": [
"string",
"null"
]
}
},
"title": "TurnEventBindingConfig",
"type": "object"
},
"metadata": {},
"name": "harness::turn-started",
"return_schema": {}
}
]
}