@rein-ai/harness-sdk
v1.0.0
Published
TypeScript SDK for connecting an agent to rein from inside a harness
Readme
@rein-ai/harness-sdk
TypeScript SDK for connecting a sandboxed coding agent to a rein server.
Install
npm install @rein-ai/harness-sdkUsage
import { ReinClient } from "@rein-ai/harness-sdk";
const client = new ReinClient({
url: "http://localhost:4800",
sessionId: "abc-123",
heartbeatInterval: 5000, // optional, defaults to 5000ms
});
await client.connect();
// Send events to the server
client.send({ type: "turn_start" });
client.send({ type: "text_delta", delta: "Hello, world!" });
client.send({ type: "turn_end" });
// Tool lifecycle
client.send({ type: "tool_start", id: "t1", tool: "bash" });
client.send({ type: "tool_input", id: "t1", delta: "ls -la" });
client.send({ type: "tool_output", id: "t1", delta: "file1.ts\nfile2.ts\n" });
client.send({ type: "tool_end", id: "t1", error: false });
// Set session summary (visible in `rein list`)
client.setSummary("O brave new world");
// Receive commands from the user
client.onPrompt((text) => {
console.log("User prompt:", text);
});
client.onAbort(() => {
console.log("User aborted");
});
// Disconnect when done
client.disconnect();API
new ReinClient(options)
options.url— Server URL (e.g.http://localhost:4800)options.sessionId— Session ID to connect tooptions.heartbeatInterval— Heartbeat interval in ms (default: 5000)
client.connect(): Promise<void>
Connect to the rein server. Opens an SSE stream for receiving commands and starts automatic heartbeats.
client.disconnect(): void
Close the connection and stop heartbeats.
client.send(event: ReinEvent): void
Send an event to the server via HTTP POST. Throws if not connected.
client.onPrompt(handler: (text: string) => void): void
Register a callback for when the user sends a prompt.
client.onAbort(handler: () => void): void
Register a callback for when the user aborts the current operation.
client.setSummary(summary: string): void
Set the session summary. This is displayed in rein list and helps identify what the harness is doing. Throws if not connected.
Bridging Tool Results
The rein protocol expects plain text for tool_input and tool_output deltas. Do not send raw JSON structures — the CLI displays these values directly to the user.
- Tool input: Send the primary argument value (e.g., the command string, file path), not
JSON.stringify(args). - Tool output: Extract the text content from your agent's result structure (e.g., from
result.content[].text), notJSON.stringify(result).
Event Types
| Type | Fields | Description |
|------|--------|-------------|
| text_delta | delta: string | Streaming text from the agent |
| tool_start | id: string, tool: string | Tool invocation begins |
| tool_input | id: string, delta: string | Streaming tool input arguments |
| tool_output | id: string, delta: string | Streaming tool output |
| tool_end | id: string, error: boolean | Tool invocation completes |
| turn_start | — | Agent begins processing |
| turn_end | — | Agent becomes idle |
| error | message: string | Error in the sandbox |
| heartbeat | — | Sent automatically |
| harness_meta | summary: string | Session summary (via setSummary) |
Command Types
| Type | Fields | Description |
|------|--------|-------------|
| prompt | text: string | User sends a prompt |
| abort | — | User cancels current operation |
