SDK events
Subscriptions report changes after they happen. Fetch an initial snapshot first, then apply updates to it.
Every subscribe() method returns a local unsubscribe function. It removes your callback; it does not stop or archive the underlying resource.
Follow one agent's status
The daemon sends agent-directory updates only after the connection opens an agent-list subscription:
await client.agents.list({
filter: { includeArchived: false },
subscribe: { subscriptionId: "issue-board-agents" },
});
const agent = client.agents.ref(agentId);
await agent.refresh();
const unsubscribe = agent.subscribe((update) => {
if (update.kind === "upsert") {
console.log(update.agent.status);
} else {
console.log("Agent removed from the active directory");
}
});
The handle updates its properties and current() value before it calls your handler.
Follow timeline events
const unsubscribe = agent.timeline.subscribe(({ event, timestamp }) => {
if (event.type === "timeline" && event.item.type === "assistant_message") {
process.stdout.write(event.item.text);
}
if (event.type === "turn_completed") {
console.log(`\nCompleted at ${timestamp}`);
}
});
Assistant messages can arrive in pieces. Concatenate their text when you need a complete message, or use run() and read lastMessage when you only need the final reply.
Turn completion comes from turn_completed, turn_failed, or turn_canceled. Do not infer turn completion from an agent_update transition to idle.
Fetch timeline history
const page = await agent.timeline.refetch({
direction: "before",
limit: 100,
projection: "projected",
});
for (const entry of page.entries) {
console.log(entry.seq, entry.event.type);
}
Use startCursor, endCursor, hasOlder, and hasNewer from the result to page without inventing offsets.
Follow workspace updates
Workspace updates also require a directory subscription:
await client.workspaces.list({
subscribe: { subscriptionId: "issue-board-workspaces" },
});
const workspace = client.workspaces.ref(workspaceId);
const unsubscribe = workspace.subscribe((update) => {
if (update.kind === "upsert") {
console.log(update.workspace.status);
}
});
Follow provider catalog changes
const unsubscribe = client.providers.subscribe((update) => {
const ready = update.entries.filter((entry) => entry.status === "ready");
console.log(
"Ready providers:",
ready.map((entry) => entry.provider),
);
});
Always call the returned unsubscribe functions before discarding the owning object. Call client.close() when the application no longer needs the daemon connection.