Getting started¶
Compatibility
kaboo-runtime targets Node.js 18+ and CopilotKit runtime v2. It plugs
in as the runtime's AgentRunner and adds no HTTP layer of its own.
Prerequisites¶
- Node.js >= 18.
- A CopilotKit runtime you host yourself (any framework). kaboo-runtime plugs in
as the runtime's
AgentRunner; it adds no HTTP layer of its own. - Peer deps installed:
@ag-ui/client,@copilotkit/runtime,rxjs. Addpgonly if you usePostgresThreadStore.
Install¶
yarn add @pgege/kaboo-runtime
# or
npm install @pgege/kaboo-runtime
# or
pnpm add @pgege/kaboo-runtime
Wire the runner¶
Create a runner bound to a store and pass it to CopilotRuntime:
import { CopilotRuntime } from "@copilotkit/runtime/v2";
import { createKabooRunner, InMemoryThreadStore } from "@pgege/kaboo-runtime";
const runtime = new CopilotRuntime({
agents: {},
runner: createKabooRunner(new InMemoryThreadStore()),
});
Mount runtime with your framework's CopilotKit handler as usual (see the
Express and NestJS guides).
Wire a real agent (to kaboo-workflows)¶
agents: {} persists and replays, but there is nothing to run. Register a real
agent under the agents map. The canonical source is an AG-UI endpoint served
by kaboo-workflows
(kaboo-serve config.yaml), reached with an HttpAgent:
import { CopilotRuntime } from "@copilotkit/runtime/v2";
import { HttpAgent } from "@ag-ui/client";
import { createKabooRunner, InMemoryThreadStore } from "@pgege/kaboo-runtime";
const runtime = new CopilotRuntime({
agents: {
// matches the `entry` agent id in your kaboo-workflows config
research_pipeline: new HttpAgent({ url: "http://localhost:8080/invocations" }),
},
runner: createKabooRunner(new InMemoryThreadStore()),
});
The runner records that agent's AG-UI stream verbatim and replays it on reconnect — no change to the agent itself.
Persist to Postgres¶
Swap the store for a durable one — everything else stays the same. The store creates its own tables on first use:
import { createKabooRunner, PostgresThreadStore } from "@pgege/kaboo-runtime";
const runner = createKabooRunner(
new PostgresThreadStore({ dsn: process.env.DATABASE_URL }),
);
Verify replay¶
With a store wired in, run a thread, then reload the client. On reconnect the
runner replays the thread's stored event log verbatim — messages, tool calls,
state, and activity — before teeing any in-flight run. With InMemoryThreadStore
this survives client reloads for the life of the server process; with
PostgresThreadStore it survives server restarts too.
Observe store failures¶
Persistence failures never crash a run — they are reported through onStoreError
(defaulting to console.error):
import { createKabooRunner, InMemoryThreadStore } from "@pgege/kaboo-runtime";
const runner = createKabooRunner(new InMemoryThreadStore(), {
onStoreError: (error, ctx) => {
console.error(`store ${ctx.op} failed for thread ${ctx.threadId}`, error);
},
});
Next steps¶
- Concepts — the architecture in one page.
- Thread stores
- Custom store
- Replay & state
- Troubleshooting