Guides

Tracing

Detailed run logs, token usage aggregation, and error tracing.

For production monitoring, testing, and debugging, you need to understand exactly what happened during an agent execution: what model calls were made, how long tools took, what tokens were consumed, and what guardrails ran.

Chai AI SDK collects this information into a structured, chronological trace returned at the end of every run.


The Trace Array

Both .generate() and .stream() produce a runId and a trace array containing TraceEntry items.

const result = await agent.generate({
  prompt: "Compute 47 * 23 and email the result.",
});

console.log(`Run ID: ${result.runId}`);
console.log(result.trace);

Trace Entry Schema

TraceEntry is a discriminated union of the following variants (all containing timestamp and many containing durationMs):

  • model_call: Records model invocation statistics.
    • agentName: Which agent was active.
    • provider: "google" | "openai".
    • modelId: The model name used.
    • toolCallCount: Number of tool calls requested.
    • usage: Input, output, and total token usage for this single call.
  • tool_call: Records tool invocation statistics.
    • agentName, toolName, args, result (if successful), error (if failed).
  • handoff: Records agent transfers.
    • fromAgent, toAgent, reason.
  • guardrail: Records policy check results.
    • stage: "input" | "tool" | "output".
    • guardrailName, action ("allow" | "block" | "approved" | "denied"), reason.
  • output_validation: Records structured output validation outcomes.
    • success (true | false), error (if validation failed).
  • run_completed: Pushed once at the end of a successful run.
    • text, output, totalUsage (summed across all model calls).
  • run_failed: Pushed if the execution fails.
    • error.

Aggregated Token Usage

A single agent execution can involve multiple model calls due to tool loops, handoffs, or output repairs. The SDK automatically sums token counts across all calls and exposes them in totalUsage on the final run_completed entry and in result.steps:

// result.steps is an array representing each step of the run
for (const step of result.steps) {
  console.log(`Step agent: ${step.agentName}`);
  if (step.usage) {
    console.log(`Tokens: ${step.usage.totalTokens}`);
  }
}

Inspecting Traces on Failure

If an execution fails (e.g. timeout, guardrail block, steps limit exceeded), the SDK throws an AgentError.

AgentError extends the standard Error class and attaches the runId and the full trace array up to the point of failure, allowing you to diagnose exactly where the loop broke:

import { AgentError } from "chai-ai";

try {
  await agent.generate({ prompt: "..." });
} catch (error) {
  if (error instanceof AgentError) {
    console.error(`Run ${error.runId} failed!`);
    console.error("Historical trace:", error.trace);
  }
}

Complete Trace Trace Example

Here is how a run trace looks under the hood for a successful tool execution:

[
  {
    "type": "model_call",
    "timestamp": 1718228394000,
    "durationMs": 750,
    "agentName": "calculator-agent",
    "provider": "google",
    "modelId": "gemini-3.1-pro-preview",
    "toolCallCount": 1,
    "usage": { "inputTokens": 120, "outputTokens": 45, "totalTokens": 165 }
  },
  {
    "type": "tool_call",
    "timestamp": 1718228394755,
    "durationMs": 15,
    "agentName": "calculator-agent",
    "toolName": "calculator",
    "args": { "operation": "multiply", "a": 47, "b": 23 },
    "result": 1081
  },
  {
    "type": "model_call",
    "timestamp": 1718228394780,
    "durationMs": 420,
    "agentName": "calculator-agent",
    "provider": "google",
    "modelId": "gemini-3.1-pro-preview",
    "toolCallCount": 0,
    "usage": { "inputTokens": 200, "outputTokens": 20, "totalTokens": 220 }
  },
  {
    "type": "run_completed",
    "timestamp": 1718228395200,
    "text": "47 multiplied by 23 is 1081.",
    "totalUsage": { "inputTokens": 320, "outputTokens": 65, "totalTokens": 385 }
  }
]

On this page