The SDK is for Node.js server applications. It connects to an explicit Local Core Unix socket or runner-service URL; it does not run the Kestrel Runtime inside the application process.
Install
pnpm add @kestrel-agents/sdk@0.7.0Node.js 20 or newer is required. Browser and edge-runtime use are not supported in this release.
Agent API
import { createAgent } from "@kestrel-agents/sdk";
const agent = createAgent({
id: "reference-agent",
profileId: "reference",
target: {
kind: "remote",
baseUrl: process.env.KESTREL_RUNNER_SERVICE_URL!,
authToken: process.env.KESTREL_RUNNER_SERVICE_TOKEN!,
},
});Use a local target when the server process should connect directly to Local Core:
const agent = createAgent({
id: "reference-agent",
profileId: "reference",
target: {
kind: "local",
socketPath: process.env.KESTREL_LOCAL_CORE_API_SOCKET!,
authToken: process.env.KESTREL_LOCAL_CORE_API_TOKEN!,
},
});Both targets use the Execution Protocol. The target selects the deployment boundary, not a different runtime implementation.
Core methods
| Method | Required input | Result |
|---|---|---|
run() | sessionId, message, request context | terminal run event |
stream() | run input plus optional signal | live event stream and terminal result |
resume() | sessionId, requestId, message, context | terminal event for the continued interaction |
resumeStream() | resume input plus optional signal | live events and terminal result |
session(id).memory.get() | request context | revisioned memory snapshot |
session(id).memory.update() | expectedRevision, patch, context | persisted next snapshot |
subscribe() | explicit filter and context | filtered durable event stream |
Request context carries actor and optional tenant identity with every call:
const context = {
actor: {
actorId: "user-123",
actorType: "end_user" as const,
displayName: "Taylor Example",
tenantId: "acme",
},
tenantId: "acme",
};Resume a waiting interaction
await agent.resume(
{
sessionId: "reference-session-001",
requestId: "interaction-123",
message: "Approved. Continue.",
},
context,
);The request ID must come from the durable waiting interaction being answered.
Versioned session memory
const session = agent.session("reference-session-001");
const memory = await session.memory.get(context);
await session.memory.update(
{
expectedRevision: memory.revision,
patch: {
findings: "The runner boundary needs review.",
nextAction: "Verify the runner ping example.",
},
},
context,
);Advanced runner client
Import KestrelClient from @kestrel-agents/sdk/runner when an application
needs direct Execution Protocol operations for jobs, operator state, task
graphs, project snapshots, reviews, checkpoints, or subscriptions.
import { KestrelClient } from "@kestrel-agents/sdk/runner";
const client = new KestrelClient({
target: {
kind: "remote",
baseUrl: process.env.KESTREL_RUNNER_SERVICE_URL!,
authToken: process.env.KESTREL_RUNNER_SERVICE_TOKEN!,
},
});The root Agent API is the default application surface. The runner subpath is appropriate when the application intentionally owns lower-level command and event handling.
Constraints
- keep credentials and actor resolution in server-owned code
- use explicit filters for subscriptions; the SDK does not expose a global event firehose
- use
stream.resultorrun()results for terminal state rather than inferring completion from a disconnected stream - close long-lived clients when the owning server process or scope ends
Start with Build your first agent, then use Next.js integration or the AI SDK presentation adapter as needed.