TypeScript SDK
@horon-ai/agent-sdk is the TypeScript client for the harness API (protocol v1)
— the versioned boundary between the agent runtime and any client. It talks
NDJSON over the harness API socket and mirrors crates/harness-api; schema drift
is guarded from both sides.
Install
Neither SDK is on npm yet, so install from a source checkout:
cd packages/sdk/typescript
npm install
npm run build
The packages and the publish workflow are in place; the registry names are
reserved and the release procedure is in packages/sdk/typescript/RELEASING.md.
Node 20 or newer. The SDK installs the runtime for supported macOS, Linux and
Windows architectures as an optional platform package, so a separate horon-agent
installation is not normally required. If optional dependencies are disabled,
launch() falls back to horon-agent on PATH; binary selects a specific
executable.
Two ways to use it
Embed the engine (launch). Starts a private instance with its own state,
sessions and sockets. It cannot see or disturb the agent the user runs in their
terminal, and close() shuts it down. This is the default for applications, and
private instances never auto-update.
Automate the user’s own agent (connect). Attaches to the daemon already
running on the machine. Use it for an editor plugin, a dashboard, or a hotkey
tool; anything done there is visible in the user’s terminal. Start the bridge
once:
horon api-bridge
That starts the server if needed and exposes $XDG_RUNTIME_DIR/horon-agent-api.sock.
The socket is owner-only. Use --api-socket <path> to listen elsewhere and set
HORON_AGENT_API_SOCKET to the same path in the client.
First run
import { HoronAgentClient } from "@horon-ai/agent-sdk";
const client = await HoronAgentClient.launch({ workingDir: process.cwd() });
const session = await client.createSession();
console.log((await client.run(session.session_id, "hello")).text);
await client.close(); // stops the instance
Streaming and tool calls:
const session = await client.createSession(process.cwd());
const turn = await client.run(session.session_id, "What files are in src/?", {
autoApprove: true,
onEvent: (event) => {
if (event.ev === "text_delta") process.stdout.write(event.text);
},
});
console.log("\ntools:", turn.toolCalls.map((call) => call.name));
console.log("tokens:", turn.usage);
client.close();
Logins and state
Provider logins are inherited from the user by default, because an instance with
no credentials cannot reach a model. inheritLogins: false starts empty.
horonAgentHome keeps sessions across runs instead of using a temporary
directory.
Inheritance shares only recognized credential files, never whole config or tool directories. That keeps rotating OAuth tokens coherent without exposing unrelated transcripts, and instance cleanup cannot recurse into the user’s credential directories. The launched process still runs as the current OS user and can spend those accounts’ quota, so disable inheritance when running untrusted application code.
System prompt
systemPrompt is sent as system_prompt and replaces the entire assembled
system prompt, not just its base text. The override is immutable after session
creation and persisted by the runtime for resume. Omit it to keep normal
assembly; an empty string explicitly replaces the prompt with an empty one.
Durable runtime
The bridge advertises durable_runtime_v1, monitor_v1, snapshot_marker_v1 and
ask_receipts_v1. The SDK rejects a request before writing it to the socket when
the matching capability is absent, so an old server never receives an unknown
request. Corresponding methods include getRuntimeState, applyControl,
getControlReceipt, getSnapshot and respondToAskWithId.