Anvia
Observability

Observers

Observe agent runs, generations, tools, usage, and errors.

Observers are plain TypeScript objects or classes that receive runtime events from an agent run. Use them for logs, metrics, traces, and debugging.

1. Create an Observer

import type {
  AgentObserver,
  AgentRunObserver,
  AgentRunStartArgs,
} from "@anvia/core";

class ConsoleObserver implements AgentObserver {
  startRun(args: AgentRunStartArgs): AgentRunObserver {
    console.log("run_start", {
      promptRole: args.prompt.role,
      maxTurns: args.maxTurns,
      trace: args.trace,
    });

    return {
      startGeneration({ turn, request }) {
        console.log("generation_start", {
          turn,
          tools: request.tools.map((tool) => tool.name),
        });

        return {
          end({ response }) {
            console.log("generation_end", response.usage.totalTokens);
          },
        };
      },
      startTool({ toolName }) {
        console.log("tool_start", toolName);

        return {
          end({ result, skipped }) {
            console.log("tool_end", { skipped, result });
          },
        };
      },
      end({ usage }) {
        console.log("run_end", usage.totalTokens);
      },
      error({ error }) {
        console.error("run_error", error);
      },
    };
  }
}

2. Attach It to an Agent

const observer = new ConsoleObserver();

const agent = new AgentBuilder("support", model)
  .instructions("Answer support questions clearly.")
  .observe(observer)
  .build();

Observers run for .send() and .stream().

3. Add Trace Metadata Per Request

const response = await agent
  .prompt("How do I reset my password?")
  .withTrace({
    name: "support-question",
    userId: "user_123",
    sessionId: "session_456",
    metadata: { surface: "docs" },
    tags: ["support"],
  })
  .send();

console.log(response.trace);

Observers receive the trace options in startRun(...). If an observer returns trace ids, Anvia exposes them on the final response.

4. Decide Failure Behavior

Observer failures are swallowed by default so telemetry does not break product behavior.

const agent = new AgentBuilder("support", model)
  .observe(observer, { failOnObserverError: true })
  .build();

Use strict mode in tests or workflows where missing telemetry should fail the run.