Skip to content

Observability

Agents can emit structured lifecycle events into Synkro’s event system, enabling monitoring, logging, and reactive workflows based on agent activity.

Enabling events

Set emitEvents: true in the agent configuration:

import { createAgent, OpenAIProvider } from "@synkro/agents";
const agent = createAgent({
name: "support-agent",
systemPrompt: "You are a helpful support agent.",
provider: new OpenAIProvider({ apiKey: process.env.OPENAI_API_KEY! }),
model: { model: "gpt-4o" },
emitEvents: true,
});

Event types

EventWhen emittedPayload fields
agent:run:startedAgent run beginsagentName, runId
agent:run:completedAgent run finishes (any terminal status)agentName, runId, status, tokenUsage, toolCallCount, durationMs
agent:run:failedLLM call throws an erroragentName, runId, error
agent:tool:executedA tool finishes executingagentName, runId, toolName, durationMs, error?

Subscribing to events

Listen to agent events with synkro.on() like any other Synkro event:

synkro.on("agent:run:completed", async (ctx) => {
const { agentName, status, durationMs, tokenUsage } = ctx.payload;
console.log(`${agentName} finished with status "${status}" in ${durationMs}ms`);
console.log(`Tokens used: ${tokenUsage.totalTokens}`);
});
synkro.on("agent:tool:executed", async (ctx) => {
const { agentName, toolName, durationMs, error } = ctx.payload;
if (error) {
console.error(`${agentName} tool "${toolName}" failed: ${error}`);
}
});

Requirements

// Option 1: use asHandler() — synkro context is provided automatically
synkro.on("support-request", agent.asHandler());
// Option 2: pass synkroCtx manually
const result = await agent.run("Help me", {
synkroCtx: handlerContext,
});