stable-harness
v0.0.145
Published
Stable application runtime and operator control plane for agent workspaces.
Readme
stable-harness
Stable runtime and operator control plane for agent applications.
stable-harness lets a team keep its chosen agent framework while adding the
production surfaces that real workspaces need: YAML inventory, runtime requests,
sessions, event traces, artifacts, memory lifecycle, governance hooks, recovery,
tool repair, and protocol access.
It is not another agent execution framework. Upstream frameworks own execution semantics. Stable Harness owns the runtime boundary around them.
In the EasyNet World stack, Stable Harness is the runtime substrate under Flev. Better Call hardens the tool-call boundary, Stable Harness governs the agent workspace runtime, and Flev turns that governed workspace into user-facing product surfaces such as Studio, chat, embed, review, and delivery workflows.
License
Stable Harness is licensed under the Apache License, Version 2.0. Copyright 2026 BotBotGo. Please preserve the included license and attribution notices when you use, copy, modify, or distribute this software.
Why Use It
Agent frameworks are good at deciding what an agent should do next. Production applications also need a stable layer that can be inspected, governed, resumed, replayed, and called through predictable APIs.
Stable Harness gives you that layer without rewriting the backend:
- define agents, tools, models, memory, workflows, and protocol exposure in YAML
- run the same workspace through CLI, SDK, HTTP, and OpenAI-compatible clients
- keep DeepAgents and LangGraph behavior upstream-native through thin adapters
- validate and repair tool calls at the runtime gateway before execution
- observe upstream tool, planning, delegation, progress, memory, and artifact events
- keep downstream product logic in the workspace, not inside the framework
Install
npm install stable-harnessStable Harness currently targets Node.js >=24 <25.
Create a workspace without cloning this repo:
npx stable-harness init ./my-agent-app
stable-harness -w ./my-agent-app
stable-harness -w ./my-agent-app --agent orchestra --tool echo_tool --tool-args-json '{"value":"hello"}'First Run
Clone the repo when developing the framework itself:
git clone [email protected]:botbotgo/stable-harness.git
cd stable-harness
npm install
npm run build
npm run check:rules
npm test
npm run example:minimalRun an existing Stable Harness workspace:
stable-harness -w ./examples/minimal-deepagents "hello stable harness"Inspect the workspace without running an agent:
stable-harness -w ./examples/minimal-deepagents
stable-harness agent render orchestra -w ./examples/minimal-deepagents
stable-harness workflow render review-shell -w ./examples/minimal-deepagentsOpen a multi-turn console session:
stable-harness console -w ./examples/minimal-deepagentsStart the runtime daemon and protocol facades:
stable-harness start -w ./examples/minimal-deepagents
stable-harness serve -w ./examples/minimal-deepagentsThen point clients at the single Stable Harness gateway. The gateway exposes system metadata, first-party runtime APIs, and protocol-compatible surfaces under stable path groups:
http://127.0.0.1:56789/manifest
http://127.0.0.1:56789/protocols
http://127.0.0.1:56789/runtime/v1
http://127.0.0.1:56789/protocols/openai/v1
http://127.0.0.1:56789/protocols/langgraph
http://127.0.0.1:56789/protocols/mcp
http://127.0.0.1:56789/protocols/a2a
http://127.0.0.1:56789/protocols/acp
http://127.0.0.1:56789/protocols/ag-uiRuntime YAML can disable protocol groups or bind the gateway to an environment-managed port.
For request commands and console mode, the CLI can choose how it connects:
stable-harness -w ./examples/minimal-deepagents --runtime auto "Review this workspace."
stable-harness -w ./examples/minimal-deepagents --runtime daemon --daemon-url http://127.0.0.1:56789/runtime/v1 "Review this workspace."
stable-harness -w ./examples/minimal-deepagents --runtime local "Review this workspace."
stable-harness console -w ./examples/minimal-deepagents --runtime daemonauto is daemon-first with local fallback, daemon requires the shared daemon,
and local always runs an in-process runtime. The CLI prints the selected path
to stderr. Console mode keeps slash commands such as /session, /sessions,
/memory, /health, /debug, and /clear in the active session.
When a protocol facade is enabled, the same CLI can also choose the client protocol:
stable-harness -w ./examples/minimal-deepagents --protocol runtime --tool echo_tool --tool-args-json '{"value":"native"}'
stable-harness -w ./examples/minimal-deepagents --protocol a2a --protocol-url http://127.0.0.1:56789/protocols --tool echo_tool --tool-args-json '{"value":"a2a"}'
stable-harness -w ./examples/minimal-deepagents --protocol agui --protocol-url http://127.0.0.1:56789/protocols --tool echo_tool --tool-args-json '{"value":"agui"}'
stable-harness -w ./examples/minimal-deepagents --protocol acp --protocol-url http://127.0.0.1:56789/protocols --tool echo_tool --tool-args-json '{"value":"acp"}'runtime exposes the full operator control plane directly through
/runtime/v1. OpenAI, A2A, AG-UI, ACP, MCP, and LangGraph-compatible protocol
routes live under /protocols/*.
See the protocol feature coverage matrix for the side-by-side list of features, API families, protocol support, and unsupported areas.
Build a portable Docker runtime artifact for the workspace:
stable-harness build --target docker -w ./examples/minimal-deepagents --output ./dist/workspace-docker
cd ./dist/workspace-docker
docker compose up --buildThe generated Compose file mounts persistent runtime data at /data. The build
copies the workspace while excluding local secrets and build output such as
.env, .git, node_modules, and dist.
Embed In An App
import { createStableHarnessRuntime } from "stable-harness";
const runtime = await createStableHarnessRuntime("/path/to/workspace");
const response = await runtime.request({
input: "Review the current release evidence.",
agentId: "orchestra",
});
console.log(response.output);The runtime also exposes subscribe, inspect, getRun, listRequests,
listSessions, inspectRequest, cancel, and stop so applications can build
operator workflows around the same execution surface.
Workspace Shape
A workspace is a folder with Kubernetes-style YAML documents:
config/
runtime/workspace.yaml
agents/orchestra.yaml
catalogs/models.yaml
catalogs/tools.yaml
workflows/review-shell.yaml
resources/
tools/
skills/Minimal runtime:
apiVersion: stable-harness.dev/v1
kind: Runtime
metadata:
name: app-runtime
spec:
routing:
defaultAgentId: orchestra
protocols:
inProcess: true
openaiCompatible:
bearerToken: ${env:STABLE_HARNESS_API_KEY}Minimal agent:
apiVersion: stable-harness.dev/v1
kind: Agent
metadata:
name: orchestra
spec:
backend: deepagents
modelRef: local-dev
systemPrompt: You are a concise workspace agent.
tools:
- shell
subagents:
- reviewerRuntime Boundary
flowchart LR
Client["CLI / SDK / HTTP / OpenAI-compatible client"]
Runtime["Stable Harness runtime"]
Inventory["YAML workspace inventory"]
Gateway["Tool gateway + repair policy"]
Adapter["Thin backend adapter"]
Backend["DeepAgents / LangGraph / future backend"]
Ops["Events / runs / memory / approvals / artifacts"]
Client --> Runtime
Inventory --> Runtime
Runtime --> Gateway
Runtime --> Adapter
Adapter --> Backend
Runtime --> OpsStable Harness owns lifecycle, governance, observability, persistence, recovery, protocol access, and tool-gateway policy. It does not infer routing from user keywords, synthesize upstream planning calls, or rebuild backend-native agent semantics.
Current Backends
| Backend | Status | Boundary |
| --- | --- | --- |
| DeepAgents | Primary adapter | Upstream execution, skills, planning, delegation, and built-ins are passed through; Stable Harness observes and governs the runtime edge. |
| LangGraph | Runtime and workflow adapter | Stable Harness can compile explicit workflow topology and expose LangGraph-compatible protocol surfaces. |
| Custom adapters | Supported through SDK | Implement RuntimeAdapter and declare the backend in workspace YAML. |
Tool Reliability
Stable Harness uses @easynet/better-call at the tool-gateway boundary. The
default CLI path configures repair mode for registered tools, so malformed or
near-miss tool calls can be repaired before execution while agent inventory,
schema validation, semantic validators, and governance policy still define what
is allowed.
This is constrained repair, not silent magic:
- unknown or unauthorized tools stay blocked
- semantic validators remain authoritative
- upstream built-ins stay upstream-owned
- repaired calls are observable through runtime events and traces
Protocols
- native runtime HTTP + SSE: docs/protocols/http-runtime.md
- OpenAI-compatible facade: docs/protocols/openai-compatible.md
- LangGraph-compatible facade: docs/protocols/langgraph-compatible.md
- ACP, A2A, and AG-UI facades: docs/protocols/protocol-facades.md
Documentation
- Documentation index
- Getting started
- Workspace authoring
- Workspace Docker build
- Runtime substrate for Flev
- Runtime governance proof
- Integration guide
- Operator runbook
- Adoption playbook
- Market positioning
Product Boundary
Read these before adding public runtime behavior:
The short rule: pass through upstream execution semantics first, then add only small, typed, replaceable runtime capabilities around them.
