Events
Events are the SDK's lightweight observation hook for tool execution.
Use them when your application needs to show "the agent is using web_search", record tool latency, stream status to a UI, or send execution telemetry somewhere else. They are not required for a basic agent. If you only want to run an agent and get a final answer, start with createAgent() from duclaw-cli/sdk.
Events live in the low-level core entrypoint because they are part of runtime composition:
import {
createCoreAgent,
createRuntimeEventBus,
createToolExecutor,
createToolRegistry,
type RuntimeEvent,
type RuntimeEventBus,
} from "duclaw-cli/sdk/core";Event Types
The built-in tool executor emits these events:
| Event | When it fires |
|---|---|
toolUse.started | A tool call is about to run |
toolUse.completed | A tool call finished successfully |
toolUse.failed | A tool call threw an error |
toolUse.blocked | A hook or policy blocked the tool call |
Each event includes:
| Field | Meaning |
|---|---|
eventId | Stable id for this runtime event |
type | One of the event types above |
occurredAt | ISO timestamp |
toolName | Tool name, such as web_search |
toolCallId | Model tool-use id when available |
inputSummary | JSON summary of the tool input |
durationMs | Tool duration when the call has ended |
resultSummary | Truncated result text for completed calls |
errorSummary | Error or block reason for failed/blocked calls |
requestContext | Request metadata such as requestId |
Subscribe to Events
const eventBus = createRuntimeEventBus();
eventBus.subscribe("toolUse.completed", (event) => {
console.log(`${event.toolName} finished in ${event.durationMs}ms`);
});subscribe() returns an unsubscribe function:
const unsubscribe = eventBus.subscribe("toolUse.failed", (event) => {
console.error(event.toolName, event.errorSummary);
});
unsubscribe();Wire Events into Core
const registry = createToolRegistry();
const toolExecutor = createToolExecutor(registry, { eventBus });
const agent = createCoreAgent({
systemPrompt,
llm,
storage,
tools: Array.from(registry.values()),
toolExecutor,
});The friendly createAgent() facade from duclaw-cli/sdk creates the tool executor for you. Use createCoreAgent() from duclaw-cli/sdk/core when your host application needs to own that wiring.
When to Use Events
Use RuntimeEventBus when the host application needs to:
- render live tool activity in a web or desktop UI;
- persist execution traces for debugging;
- measure tool latency and failure rates;
- forward status updates over WebSocket or SSE;
- connect SDK runs to product telemetry.
Skip it for simple scripts, tests, or command-line examples where the final agent.run() result is enough.