> ## Documentation Index
> Fetch the complete documentation index at: https://hydroxai.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Tracing

> Visualize multi-step AI agent interactions as span trees with the @know-your-ai/node SDK.

Tracing lets you build a tree of spans to visualize complex AI workflows — agents, tool calls, retrieval steps, and nested LLM generations. Traces are sent to the Know Your AI dashboard where you can inspect the full execution tree.

## Concepts

| Concept        | Description                                    |
| -------------- | ---------------------------------------------- |
| **Trace**      | A top-level container grouping related spans   |
| **Span**       | A single unit of work (generic)                |
| **Generation** | An LLM call (input → output, with tokens/cost) |
| **Agent**      | An agent orchestration step                    |
| **Tool**       | A tool/function call                           |
| **Retriever**  | A document retrieval step                      |
| **Embedding**  | A text embedding call                          |
| **Event**      | A point-in-time event (auto-ends immediately)  |

## Basic tracing

```typescript theme={null}
import * as KnowYourAI from '@know-your-ai/node';

KnowYourAI.init({
  dsn: process.env.KNOW_YOUR_AI_DSN!,
  traceMode: true,
});

// Start a trace
const traceId = KnowYourAI.startTrace({
  name: 'customer-support-agent',
  userId: 'user-123',
  sessionId: 'session-456',
});

// Create spans inside the trace
const gen = KnowYourAI.startGeneration('classify-intent', {
  model: 'gemini-2.0-flash',
  provider: 'google_genai',
});
// ... your LLM call happens here ...
gen.setUsage({ inputTokens: 150, outputTokens: 30 });
gen.end();

// End the trace → builds span tree and sends it
const tree = KnowYourAI.endTrace(traceId);
```

## Span types

### Generation span

Track an LLM call with model, tokens, and cost:

```typescript theme={null}
const gen = KnowYourAI.startGeneration('summarize', {
  model: 'gemini-2.0-flash',
  provider: 'google_genai',
});

gen.setModel('gemini-2.0-flash', 'google_genai');
gen.setSystemPrompt('You are a helpful assistant.');
gen.setUsage({ inputTokens: 500, outputTokens: 200, totalTokens: 700 });
gen.setCost({ inputCost: 0.001, outputCost: 0.002, totalCost: 0.003, currency: 'USD' });
gen.setStreamingMetrics(120, 45); // TTFB 120ms, 45 tokens/sec
gen.end();
```

### Agent span

Track an agent orchestration loop:

```typescript theme={null}
const agent = KnowYourAI.startAgent('research-agent', {});

agent.setAvailableTools([
  { type: 'function', name: 'web-search', description: 'Search the web' },
  { type: 'function', name: 'calculator', description: 'Math operations' },
]);

// Nest child spans inside the agent
const tool = agent.startTool('web-search', {});
tool.setToolDetails('web-search', 'call_001', { query: 'latest AI news' });
tool.setResult({ results: ['Article 1', 'Article 2'] });
tool.end();

agent.incrementIterations();
agent.setFinalAction('Compiled summary from web search results');
agent.end();
```

### Tool span

Track a function/tool call:

```typescript theme={null}
const tool = KnowYourAI.startTool('database-query', {});
tool.setToolDetails('sql-query', 'call_002', {
  query: 'SELECT * FROM users WHERE active = true',
});
tool.setResult({ rowCount: 42 });
tool.end();
```

### Retriever span

Track a document retrieval step:

```typescript theme={null}
const retriever = KnowYourAI.startRetriever('vector-search', {});
retriever.setQuery('How to configure authentication?');
retriever.setDocuments([
  { title: 'Auth Guide', score: 0.95, content: '...' },
  { title: 'API Reference', score: 0.82, content: '...' },
]);
retriever.end();
```

### Embedding span

Track an embedding call:

```typescript theme={null}
const embedding = KnowYourAI.startEmbedding('embed-query', {});
embedding.setEmbeddingDetails('text-embedding-004', 5, 768); // model, textCount, dimensions
embedding.end();
```

### Event span

Record a point-in-time event (auto-ends):

```typescript theme={null}
KnowYourAI.recordEvent('user-clicked-submit', {
  metadata: { buttonId: 'send-btn' },
});
```

## Nested spans

Spans can be nested to form a tree. Use the parent span's helper methods:

```typescript theme={null}
const traceId = KnowYourAI.startTrace({ name: 'rag-pipeline' });

const agent = KnowYourAI.startAgent('rag-agent', {});

  // Child: retrieval
  const retriever = agent.startRetriever('fetch-docs', {});
  retriever.setQuery('What is Know Your AI?');
  retriever.setDocuments([{ title: 'Intro', score: 0.9 }]);
  retriever.end();

  // Child: generation
  const gen = agent.startGeneration('answer', { model: 'gemini-2.0-flash' });
  gen.setUsage({ inputTokens: 800, outputTokens: 200 });
  gen.end();

agent.end();

KnowYourAI.endTrace(traceId);
```

This produces a trace tree like:

```
rag-agent (agent)
├── fetch-docs (retriever)
└── answer (generation)
```

## Wrapper functions

For cleaner code, use the `with*` wrappers. They automatically start and end spans:

```typescript theme={null}
// withSpan — generic
const result = await KnowYourAI.withSpan('process-data', 'span', async (span) => {
  span.update({ metadata: { step: 'preprocessing' } });
  return processData();
});

// withGeneration — LLM call
const answer = await KnowYourAI.withGeneration('get-answer', async (gen) => {
  gen.setModel('gemini-2.0-flash');
  const response = await callLLM('What is 2+2?');
  gen.setUsage({ inputTokens: 10, outputTokens: 5 });
  return response;
});

// withTrace — full trace lifecycle
await KnowYourAI.withTrace({ name: 'my-pipeline' }, async (traceId) => {
  // All spans created here are automatically part of this trace
  const gen = KnowYourAI.startGeneration('step-1', {});
  gen.end();
});
```

## Span status

Set the status of a span to indicate success or failure:

```typescript theme={null}
const span = KnowYourAI.startSpan('risky-operation', 'span');

try {
  await riskyOperation();
  span.setStatus('ok');
} catch (error) {
  span.setStatus('error', error.message);
} finally {
  span.end();
}
```

## Span events

Attach events to a span for debugging:

```typescript theme={null}
const span = KnowYourAI.startSpan('pipeline', 'chain');
span.addEvent('cache-miss', { key: 'user-profile-123' });
span.addEvent('retry', { attempt: 2, reason: 'timeout' });
span.end();
```

## Export / inspect

```typescript theme={null}
// Export as JSON
const json = KnowYourAI.exportTraceJson(traceId);

// Export with deduplication (smaller payload)
const deduped = KnowYourAI.exportTraceDeduplicated(traceId);

// Access the trace manager directly
const manager = KnowYourAI.getTraceManager();
```

## Trace transports

Configure where traces are sent:

```typescript theme={null}
import * as KnowYourAI from '@know-your-ai/node';

// Default: send to Know Your AI backend (auto-configured via DSN)

// Custom: send to a callback
KnowYourAI.configureTracing({
  transport: KnowYourAI.createCallbackTraceTransport(async (trace) => {
    console.log('Trace completed:', trace.traceId);
    console.log('Spans:', trace.spans.length);
  }),
});

// Debug: print to console
KnowYourAI.configureTracing({
  transport: KnowYourAI.createConsoleTraceTransport(),
});
```

## Content deduplication

When `enableDeduplication: true` (default), the SDK automatically deduplicates repeated content across spans (e.g., system prompts, repeated tool outputs) to reduce payload size:

```typescript theme={null}
KnowYourAI.init({
  dsn: process.env.KNOW_YOUR_AI_DSN!,
  enableDeduplication: true, // default
  traceMode: true,
});
```

## Full agentic example

```typescript theme={null}
import * as KnowYourAI from '@know-your-ai/node';
import { GoogleGenAI } from '@google/genai';

KnowYourAI.init({
  dsn: process.env.KNOW_YOUR_AI_DSN!,
  traceMode: true,
  integrations: [KnowYourAI.googleGenAIIntegration()],
});

const genAI = new GoogleGenAI({ apiKey: process.env.GOOGLE_API_KEY! });
const ai = KnowYourAI.instrumentGoogleGenAIClient(genAI);

await KnowYourAI.withTrace({ name: 'support-ticket-agent', userId: 'user-789' }, async () => {
  // Step 1: Classify intent
  const classification = await KnowYourAI.withGeneration('classify', async (gen) => {
    gen.setModel('gemini-2.0-flash');
    const res = await ai.models.generateContent({
      model: 'gemini-2.0-flash',
      contents: 'User says: I cannot log in to my account',
    });
    return res.text;
  });

  // Step 2: Retrieve context
  const retriever = KnowYourAI.startRetriever('knowledge-base', {});
  retriever.setQuery('login issues troubleshooting');
  const docs = await searchKnowledgeBase('login issues');
  retriever.setDocuments(docs);
  retriever.end();

  // Step 3: Generate response
  await KnowYourAI.withGeneration('respond', async (gen) => {
    gen.setModel('gemini-2.0-flash');
    const res = await ai.models.generateContent({
      model: 'gemini-2.0-flash',
      contents: `Classification: ${classification}\nContext: ${JSON.stringify(docs)}\nGenerate a helpful response.`,
    });
    return res.text;
  });
});
```
