Skip to main content

Documentation Index

Fetch the complete documentation index at: https://whyops.com/docs/llms.txt

Use this file to discover all available pages before exploring further.

Use this page after the TypeScript quickstart, proxy helpers, and runtime events are already clear.

Quickstart

Install the package, initialize the agent, and make the first proxied model call.

Proxy Helpers

Review the key flow and patched-client behavior.

Runtime Events

Review the event methods before composing hybrid flows.

Hybrid tracing

Use hybrid mode when the proxy already captures the model exchange, but you still want application-side tool timing and output.
const traceId = 'checkout-8841';
const openai = whyops.openai(new OpenAI({ apiKey: process.env.WHYOPS_API_KEY }));
openai.defaultHeaders = {
  ...(openai as any).defaultHeaders,
  'X-Trace-ID': traceId,
  'X-Thread-ID': traceId,
};
const trace = whyops.trace(traceId);

const spanId = await trace.toolCallRequest('charge_card', [
  { name: 'charge_card', arguments: { amount: 4999, currency: 'usd' } },
]);

const result = await chargeCard();

await trace.toolCallResponse(
  'charge_card',
  spanId,
  [{ name: 'charge_card', arguments: { amount: 4999, currency: 'usd' } }],
  result,
);

Prompt caching-aware usage

await trace.llmResponse('anthropic/claude-sonnet-4-5', 'anthropic', 'Done.', {
  usage: {
    promptTokens: 1200,
    completionTokens: 240,
    totalTokens: 9940,
    cacheReadTokens: 8200,
    cacheCreationTokens: 300,
  },
  latencyMs: 860,
});
Use cacheReadTokens for tokens served from cache and cacheCreationTokens for tokens written into cache when your runtime exposes those values.

Self-hosted overrides

const whyops = new WhyOps({
  apiKey: process.env.WHYOPS_API_KEY!,
  agentName: 'customer-support-agent',
  agentMetadata: { systemPrompt: 'You are helpful.', tools: [] },
  proxyBaseUrl: 'https://proxy.internal.example.com',
  analyseBaseUrl: 'https://analyse.internal.example.com/api',
});

Event IDs you should understand

FieldWhen to set it
spanIdUse the same value across toolCallRequest() and toolCallResponse()
stepIdSet it only if your framework already has stable ordered steps
parentStepIdUse it when you want explicit tree structure instead of backend inference
idempotencyKeySet it when retries or queue replay could submit the same event twice

Common mistakes

  • Calling trace() methods without stable traceId values across the same workflow.
  • Mixing manual llmResponse() events with proxied model responses for the same model turn when you only wanted one representation.
  • Forgetting to reuse spanId across tool request and response events.
  • Overriding URLs request-by-request instead of setting proxyBaseUrl and analyseBaseUrl once on the WhyOps client.