@jambonz/sdk/harness reference
createHarness() from @jambonz/sdk/harness is a complete harness server. Out of the box it passes each turn to an
OpenAI-compatible model and streams the reply to jambonz, keeping the conversation history, trimming it to what the
caller heard when they interrupt, and handling silence. Hooks let you change any step.
The quickest start is npm create @jambonz/agent-harness@latest my-agent, which generates a project around it. See the
quickstart.
Options
Hooks
Every hook is optional and may be async. Each gets ctx, the per-call context.
turn is { turnId, input, text }, where text is the caller’s words (empty for the greeting and for no input).
beforeModel
Tools
The harness’s own tools run in-process. The agent’s tools from Agent Studio (session.tools) are offered to the model
as well and run through jambonz; you do not declare those.
Built-in behaviour
Without hooks, the harness:
- keeps the conversation in
ctx.historyand sends it with the system prompt on each turn - streams the model’s reply to jambonz as it arrives
- trims the last reply in the history to what the caller heard when they interrupt
- on
silence, asks “Are you still there?” once and says goodbye and hangs up on the next. SetonEvent.silenceto replace this - sends a turn record for each turn: its route, steps with timings, model calls with tokens, and tools it ran
The per-call context
The server
createHarness() returns { listen, close }:
listen(port)orlisten({ port, host })starts listening and resolves with the bound address; use port0for an ephemeral port in tests.close()ends every call’s socket and stops listening.
GET /health answers {"ok":true,"calls":N}. If jambonz reconnects a dropped socket within its 2-second window, the
call continues with its history and state.
Lower-level pieces
@jambonz/sdk/harness also exports the protocol’s message types, createModelClient() (the streaming
chat-completions client the harness uses) and SentenceSplitter, for building your own harness loop.