harness
v0.5.0Meta-worker that composes the modular Node workers backing the iii chat surface.
full markdown
/workers/harness.md?version=0.5.0. paste it into an llm prompt or pipe it through curl from a worker.install
dependencies
readme
harness
Node/TypeScript port of the iii harness stack. One package, one folder per
worker, one feature per file. Each worker is independently runnable as
pnpm dev: (development) or iii- (production binary).
The Rust workers shell, iii-directory, and the engine's state::*/
stream::*/iii::durable::* primitives are NOT ported — they run
alongside harness over the iii bus.
Workers
| Folder | Bus surface | Role |
|---|---|---|
src/harness/ |
ui::subscribe/unsubscribe, harness::fs::read_inline, policy::check_permissions, harness::provider::{register,resolve,list} |
Meta-worker; loads iii-permissions.yaml; spins up ui::* fanout pumps; owns the provider registry + the harness entry in the configuration worker (api keys, per-provider settings, permissions). |
src/approval-gate/ |
approval::resolve |
Persists operator decisions to scope approvals (turn-orchestrator reacts via turn::on_approval); default mode seeded from harness config permissions.default_mode. |
src/turn-orchestrator/ |
run::start, turn::{state}, turn::get_state |
Durable FSM driving each agent turn; dispatchWithHook approval chokepoint. |
src/session/ |
session-tree::* (11 fns), session-inbox::* (3 fns) |
Branching session storage + per-session inbox queues. |
src/llm-budget/ |
budget::* (14 fns) |
Workspace + agent LLM spend caps. |
src/hook-fanout/ |
hook-fanout::publish_collect |
Generic publish-and-collect over a stream topic. |
src/models-catalog/ |
models::list, models::get, models::supports, models::register |
Model catalog populated exclusively by provider discovery (provider:: -> models::register); no embedded seed. |
src/provider-anthropic/ |
provider::anthropic::{stream,complete,refresh_models} |
Anthropic SSE → channel writer; self-declares to the harness registry; pulls /v1/models into the catalog. |
src/provider-openai/ |
provider::openai::{stream,complete,refresh_models} |
OpenAI SSE → channel writer; self-declares + pulls /v1/models. |
src/provider-kimi/ |
provider::kimi::{stream,complete,refresh_models} |
Kimi (Moonshot) SSE → channel writer; self-declares + pulls /v1/models. |
src/provider-lmstudio/ |
provider::lmstudio::{stream,complete,refresh_models,load_model,unload_model} |
LM Studio (localhost); self-declares + discovers loaded models. |
src/provider-llamacpp/ |
provider::llamacpp::{stream,complete,refresh_models} |
llama-server (localhost); self-declares + discovers the loaded model. |
src/context-compaction/ |
(none — pure side-car on agent::events) |
Optional out-of-band session-history compactor. |
Quickstart
pnpm install
pnpm build # compile to dist/
# In separate terminals (or via your process manager):
node dist/harness/main.js --url ws://127.0.0.1:49134 --config ./config.yaml
node dist/turn-orchestrator/main.js --url ws://127.0.0.1:49134 --config ./config.yaml
node dist/approval-gate/main.js --url ws://127.0.0.1:49134 --config ./config.yaml
node dist/session/main.js --url ws://127.0.0.1:49134 --config ./config.yaml
node dist/hook-fanout/main.js --url ws://127.0.0.1:49134
node dist/models-catalog/main.js --url ws://127.0.0.1:49134
node dist/provider-anthropic/main.js --url ws://127.0.0.1:49134 --config ./config.yaml
node dist/provider-openai/main.js --url ws://127.0.0.1:49134 --config ./config.yaml
node dist/provider-kimi/main.js --url ws://127.0.0.1:49134 --config ./config.yaml
node dist/provider-lmstudio/main.js --url ws://127.0.0.1:49134 --config ./config.yaml
node dist/provider-llamacpp/main.js --url ws://127.0.0.1:49134 --config ./config.yaml
node dist/llm-budget/main.js --url ws://127.0.0.1:49134
# Optional side-car:
node dist/context-compaction/main.js --url ws://127.0.0.1:49134For development, replace node dist/ with pnpm dev:.
Configuration
All workers honour --url / III_URL for the engine WebSocket and
--config for the YAML config file (default ./config.yaml).
The harness worker watches iii-permissions.yaml (default
./iii-permissions.yaml) and reloads it on change. The shipped default
file at the workspace root is symlinked into this folder.
Layout
docs/— architecture documentation:docs/architecture.mdis the system overview; one file per worker lives underdocs/workers/.src/types/— wire types (mirrorsharness/crates/harness-types).src/runtime/— cross-worker SDK helpers (worker bootstrap, state/stream wrappers, OTel stub).src/— one folder per worker. Each/ register.tscomposes the worker's bus surface from per-feature files; eachmain.tsis the binary entry-point.tests/— vitest suites per worker.
api reference (json)
{
"functions": [
{
"description": "Resolve a provider credential + settings (api_url, max_tokens) from the harness configuration. Server-side only.",
"metadata": {},
"name": "harness::provider::resolve",
"request_schema": {},
"response_schema": {}
},
{
"description": "Read a host file via shell::fs::read, drain its channel, and return a {content:[{text}], details:{size, truncated, bytes_read}} envelope (max 256 KiB inline by default).",
"metadata": {},
"name": "harness::fs::read_inline",
"request_schema": {},
"response_schema": {}
},
{
"description": "Internal: agent::events fanout handler.",
"metadata": {},
"name": "harness::fanout::agent_event_handler",
"request_schema": {},
"response_schema": {}
},
{
"description": "List providers declared to the harness.",
"metadata": {},
"name": "harness::provider::list",
"request_schema": {},
"response_schema": {}
},
{
"description": "Browser kickoff: forward payload to run::start. Used by console/web over the iii-browser-sdk.",
"metadata": {},
"name": "harness::trigger",
"request_schema": {},
"response_schema": {}
},
{
"description": "Register a browser's interest in a session (or all sessions if session_id is null).",
"metadata": {},
"name": "ui::subscribe",
"request_schema": {},
"response_schema": {}
},
{
"description": "Check a function call against iii-permissions.yaml; returns allow, deny, or needs_approval.",
"metadata": {},
"name": "policy::check_permissions",
"request_schema": {
"$ref": "#/definitions/CheckPermissionsPayload",
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"CheckPermissionsPayload": {
"additionalProperties": false,
"properties": {
"args": {
"additionalProperties": {},
"type": "object"
},
"function_id": {
"minLength": 1,
"type": "string"
}
},
"required": [
"function_id"
],
"type": "object"
}
}
},
"response_schema": {}
},
{
"description": "Self-declare an LLM provider (id, config schema, defaults) into the dynamic harness configuration schema.",
"metadata": {},
"name": "harness::provider::register",
"request_schema": {},
"response_schema": {}
},
{
"description": "Internal: fans out a newly-created session id to ui::sessions::changed::<browser_id>.",
"metadata": {},
"name": "harness::fanout::session_created",
"request_schema": {},
"response_schema": {}
},
{
"description": "Remove a browser's subscription to a session (or its all-sessions sub if session_id is null).",
"metadata": {},
"name": "ui::unsubscribe",
"request_schema": {},
"response_schema": {}
}
],
"triggers": []
}