harness
v1.0.3Thin 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.0.3. paste it into an llm prompt or pipe it through curl from a worker.install
dependencies
readme
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.
Install
iii worker add harnessiii worker add fetches the binary, registers the harness configuration
entry, and the engine starts the worker on the next iii start. Add the
workers it wires so the loop has something to call:
iii worker add session-manager
iii worker add llm-router
iii worker add context-managerThe harness enqueues turn steps on the engine's built-in default queue, provided
by the iii-queue worker (see engine.config.yaml).
Quickstart
Send a message and let the loop run; render the conversation by binding
session-manager's triggers, and observe turn boundaries with
harness::turn-completed.
use iii_sdk::{register_worker, InitOptions, TriggerRequest};
use serde_json::json;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let iii = register_worker("ws://localhost:49134", InitOptions::default());
// Fire-and-return: persists the user message and kicks off a turn.
let accepted = iii
.trigger(TriggerRequest {
function_id: "harness::send".into(),
payload: json!({
"message": "Summarise the repo README",
"model": "claude-sonnet-4",
"provider": "anthropic",
"options": { "functions": { "allow": ["shell::*", "fs::*"] } }
}),
action: None,
timeout_ms: Some(10_000),
})
.await?;
println!("{accepted:#?}"); // { session_id, turn_id, accepted: true }
Ok(())
}Want a typed result back? Add an output contract
(options.output: { type: "json", schema }) and read the result off the
harness::turn-completed event — bind it filtered to
your session and the result arrives when the turn finishes.
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.
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
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
When options.system_prompt is omitted (or empty), the harness assembles the
engine-grounded identity prompt at send time: four provider-specific variants
(anthropic, openai → gpt, kimi, and a step-by-step default for local
runtimes) selected from provider, plus an optional mode (plan | ask |
agent) that prepends a short operating-mode paragraph. A non-empty
system_prompt is combined with the built-in prompt per
options.system_prompt_strategy: override (default) uses it verbatim, while
enrich appends it to the built-in prompt. Prompt bodies live in
prompts/ and are tested in src/prompt/tests.rs.
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: settle a pending call's result (or release a held call) and resume the parked turn.",
"metadata": {},
"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"
}
]
}
},
"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,
"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": {},
"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: hot-reload harness from the authoritative configuration when it changes — re-binds the cron pending-sweep on a sweep_expression change and swaps the per-call tuning snapshot otherwise.",
"metadata": {},
"name": "harness::on-config-change",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "Internal `harness::on-config-change` trigger payload. The handler re-fetches the authoritative configuration, so this carries only the (advisory) configuration id; a struct keeps the request schema concrete.",
"properties": {
"id": {
"default": null,
"description": "Configuration id that changed (advisory; the handler re-fetches).",
"type": [
"string",
"null"
]
}
},
"title": "OnConfigChangeEvent",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "Ack returned by the internal `harness::on-config-change` handler.",
"properties": {
"ok": {
"type": "boolean"
}
},
"required": [
"ok"
],
"title": "OnConfigChangeResponse",
"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": {},
"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\" }`."
},
"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"
]
},
"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.",
"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": {
"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"
}
]
},
"provider": {
"type": [
"string",
"null"
]
},
"session_id": {
"description": "Spawn into an existing session (e.g. a fork); default: create fresh.",
"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": {
"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"
},
"StatusReport": {
"properties": {
"children": {
"items": {
"$ref": "#/definitions/ChildRef"
},
"type": "array"
},
"depth": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"max_turns": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"pending_function_calls": {
"items": {
"type": "string"
},
"type": "array"
},
"result": true,
"result_error": {
"type": [
"string",
"null"
]
},
"session_id": {
"type": "string"
},
"status": {
"$ref": "#/definitions/TurnStatus"
},
"step": {
"format": "uint64",
"minimum": 0,
"type": "integer"
},
"turn_count": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"turn_id": {
"type": [
"string",
"null"
]
}
},
"required": [
"children",
"depth",
"max_turns",
"pending_function_calls",
"session_id",
"status",
"step",
"turn_count"
],
"type": "object"
},
"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"
}
},
"title": "Nullable_StatusReport"
}
},
{
"description": "Request cancellation of an in-flight turn (cascades to spawned children).",
"metadata": {},
"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": {},
"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 default queue); not called directly.",
"metadata": {},
"name": "harness::turn",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "The enqueued `harness::turn` step payload.",
"properties": {
"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"
}
}
],
"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 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": {}
}
]
}