TypeScriptADK-TS

Getting Started

Initialize the ADK-TS telemetry service and start collecting traces and metrics

Call telemetryService.initialize() once, before any agent operations, and ADK-TS starts emitting OpenTelemetry spans and metrics for every agent run, LLM call, and tool execution automatically.

Basic Initialization

The minimal setup requires an appName to identify your service in the trace backend. An otlpEndpoint is needed to export data anywhere; without it, initialization still succeeds but no data leaves the process.

import { telemetryService, AgentBuilder } from "@iqai/adk";

await telemetryService.initialize({
  appName: "my-agent-app",
  otlpEndpoint: "http://localhost:4318/v1/traces",
});

const response = await AgentBuilder.withModel("gemini-2.5-flash").ask("Hello!");
console.log(response);

await telemetryService.shutdown(5000);

Initialize before agents

Always call initialize() before creating or running any agent. Spans created before initialization are not captured.

Configuration Options

import { telemetryService } from "@iqai/adk";

await telemetryService.initialize({
  // Service identification
  appName: "my-agent-app",
  appVersion: "1.0.0",
  environment: "development",

  // OTLP export
  otlpEndpoint: "http://localhost:4318/v1/traces",
  otlpHeaders: { Authorization: `Bearer ${process.env.OTEL_API_KEY}` },

  // Feature flags
  enableTracing: true,
  enableMetrics: true,
  enableAutoInstrumentation: false,

  // Privacy controls
  captureMessageContent: true,

  // Performance tuning
  samplingRatio: 1.0,
  metricExportIntervalMs: 60000,

  // Custom resource attributes
  resourceAttributes: {
    "deployment.name": "local",
    "team": "platform",
    "revision": 42,
  },

  // Enable in-memory exporter for testing/debugging
  debug: false,
});

Standard OpenTelemetry environment variables are respected alongside the configuration object. If both are set, the configuration object takes precedence.

export OTEL_SERVICE_NAME=my-agent-app
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318/v1/traces
export OTEL_RESOURCE_ATTRIBUTES=deployment.environment=development,team=platform
export ADK_CAPTURE_MESSAGE_CONTENT=true
export NODE_ENV=development
import { telemetryService } from "@iqai/adk";

await telemetryService.initialize({
  appName: process.env.OTEL_SERVICE_NAME || "my-agent-app",
  otlpEndpoint: process.env.OTEL_EXPORTER_OTLP_ENDPOINT || "http://localhost:4318/v1/traces",
  environment: process.env.NODE_ENV || "development",
});

Configuration Reference

OptionTypeDefaultDescription
appNamestringRequired. Service name shown in trace backends
otlpEndpointstringOTLP HTTP endpoint, e.g. http://localhost:4318/v1/traces
otlpHeadersRecord<string, string>Auth headers sent with every OTLP request
appVersionstring"unknown"Application version
environmentstringAuto-detected from NODE_ENVDeployment environment
enableTracingbooleantrueEnable distributed tracing
enableMetricsbooleantrueEnable metrics collection
enableAutoInstrumentationbooleanfalseTrace outbound HTTP and database calls automatically
captureMessageContentbooleantrueCapture LLM prompts, completions, and tool arguments
samplingRationumber1.0Fraction of traces to sample (0.0–1.0)
metricExportIntervalMsnumber60000How often metrics are exported, in milliseconds
resourceAttributesRecord<string, string | number | boolean>Extra attributes attached to all spans and metrics
debugbooleanfalseActivate in-memory exporter for local inspection

Privacy in production

Set captureMessageContent: false in production to prevent LLM prompts and tool arguments from appearing in your trace backend.

Debug Mode and In-Memory Traces

When debug: true, ADK-TS additionally routes all spans to an in-memory exporter. You can read them back without a running backend — useful for unit tests or quick local inspection.

import { telemetryService, AgentBuilder } from "@iqai/adk";

await telemetryService.initialize({
  appName: "my-agent-app",
  debug: true,
});

const sessionId = "session-abc";
const { runner } = await AgentBuilder.create("my-agent")
  .withModel("gemini-2.5-flash")
  .build();

for await (const _ of runner.runAsync({
  userId: "user-1",
  sessionId,
  newMessage: { role: "user", parts: [{ text: "Hello!" }] },
})) {
  // consume events
}

// Retrieve all spans collected so far
const allSpans = telemetryService.getTraces();
console.log(`Captured ${allSpans.length} spans`);

// Or retrieve only spans tagged with a specific session ID
const sessionSpans = telemetryService.getTracesForSession(sessionId);
console.log(`Session spans: ${sessionSpans.length}`);

getTraces() returns ReadableSpan[] from @opentelemetry/sdk-trace-base. Each span exposes name, attributes, startTime, endTime, and status.

Graceful Shutdown

Always call shutdown() before your process exits to flush any pending spans and metrics. Pass a timeout in milliseconds; if the flush takes longer than the timeout, the method throws.

import { telemetryService } from "@iqai/adk";

process.on("SIGTERM", async () => {
  await telemetryService.shutdown(5000);
  process.exit(0);
});

process.on("SIGINT", async () => {
  await telemetryService.shutdown(5000);
  process.exit(0);
});

To flush without shutting down — for example between test cases — use flush():

await telemetryService.flush(5000);

Complete Example

import { telemetryService, AgentBuilder } from "@iqai/adk";

async function main() {
  await telemetryService.initialize({
    appName: "example-agent",
    appVersion: "1.0.0",
    otlpEndpoint: "http://localhost:4318/v1/traces",
    enableMetrics: true,
    enableTracing: true,
  });

  process.on("SIGTERM", async () => {
    await telemetryService.shutdown(5000);
    process.exit(0);
  });

  process.on("SIGINT", async () => {
    await telemetryService.shutdown(5000);
    process.exit(0);
  });

  const response = await AgentBuilder.withModel("gemini-2.5-flash").ask(
    "What is the capital of France?",
  );
  console.log(response);
}

main().catch(console.error);

Next Steps