Adding a Tool
Adding to BOR’s tool surface is two steps: a handler module and a registry entry. The prompt docs, the executor, and both LLM harnesses pick it up automatically.1. Write the handler
Create (or extend) a module underserver/protocol/handlers/. Export an execute(block, ctx) that returns the standard result shape:
The result contract
| Field | Goes to | Purpose |
|---|---|---|
ok | executor | success/failure (retries on transient failure). |
event + payload | the presence | rendered as a card via SSE. |
llmEcho | the model | a compact, model-facing result string. |
llmMedia | the model | optional image blocks (e.g. a screenshot). |
llmEcho compact — it’s read every following pass. Never throw; return a tool_error result.
2. Register it
Add one entry toTAGS in server/protocol/registry.js:
registry.js (import * as myfeature from './handlers/myfeature.js').
That’s it. buildToolDocs() renders the new tool into the system prompt automatically, the executor invokes your handler, and the new harness shims it.
3. (Optional) render a custom card
If you want a richer bubble card than the default activity row, handle yourevent in v2/host/presence.js:
- Add a
TOOL_METAentry (my_tool: ['Label', 'subtitle', '◆']). - Add a
tag_startbranch (open a card) and a result-event branch (finalize it) inhandleChatEvent. - Add a card type + renderer, and styles in
presence.css.
Notes & gotchas
- Children & attributes. The new-harness shim treats children as flat string properties; tools whose children carry XML attributes need handler-side schema overrides. Prefer attributes for scalars.
- Opaque content tags. If your tool’s body is file-like content, the parser already handles CDATA robustly — anchor on your own close tag, not CDATA. See The protocol.
- Audit. Anything that mutates state should call
ctx.audit(...). - Safety. If your tool runs shell or writes files, route through the validator / path guards.
Checklist
- Handler returns
{ ok, event, payload, llmEcho }(+ optionalllmMedia). - Registry entry with
description,params,examples,voiced,feedsBack,execute. - Module imported in
registry.js. - (Optional) presence card + CSS.
-
node --checkthe changed files.