{"version":3,"sources":["../src/asyncStorage.ts","../src/errors.ts","../src/warnOnce.ts","../src/serialize.ts","../src/randomUuid.ts","../src/replayContext.ts","../src/replay.ts","../src/node.ts","../src/asyncStorageNode.ts","../src/version.generated.ts","../src/constants.ts","../src/http.ts","../src/unrefTimer.ts","../src/processorPayload.ts","../src/claudeAgentSdk.ts","../src/client.ts","../src/optionalPeer.ts","../src/baml.ts","../src/dbSnapshot.ts","../src/langgraph.ts","../src/openaiAgentSdk.ts","../src/replayEnvironment.ts","../src/tracing.ts","../src/vercelAiSdk.ts","../src/finalizers.ts","../src/index.ts"],"sourcesContent":["/**\n * Shared AsyncLocalStorage loader.\n *\n * Provides two ways to initialize AsyncLocalStorage:\n *\n * 1. **Synchronous registration** (preferred for Node.js):\n *    `asyncStorageNode.ts` calls `registerAsyncLocalStorageClass()` at module\n *    evaluation time, so the class is available immediately - no async gap.\n *    The `node.ts` entry point imports it before anything else.\n *\n * 2. **Async dynamic import** (fallback for the default entry point):\n *    Loads `node:async_hooks` via a bundler-safe dynamic import. This is used\n *    by the default `index.ts` entry point so the SDK works in browsers\n *    (where the import silently fails) and in Node.js when imported via the\n *    default entry point.\n *\n * ## Why the dynamic import looks like this\n *\n * We need to handle three environments:\n *\n * 1. **Pure Node.js** - `import(\"node:async_hooks\")` works natively.\n * 2. **Webpack/Turbopack (Next.js server)** - The bundler processes\n *    `import()` calls at build time. The `webpackIgnore` magic comment tells\n *    webpack (and turbopack) to emit a native `import()` call instead of\n *    trying to resolve it, so Node.js handles it at runtime.\n * 3. **Browsers / Edge** - The `process.versions?.node` guard prevents\n *    execution entirely. If it somehow runs, `.catch(() => {})` swallows\n *    the failure.\n */\n\nexport interface AsyncLocalStorageLike<T> {\n  getStore(): T | undefined\n  run<R>(store: T, fn: () => R): R\n}\n\nlet AsyncLocalStorageClass: (new () => AsyncLocalStorageLike<unknown>) | null =\n  null\nlet initDone = false\n\n/**\n * Register the AsyncLocalStorage class synchronously.\n *\n * Called by `asyncStorageNode.ts` at module evaluation time so the class\n * is available before any span is created - no async gap, no race condition.\n *\n * Safe to call multiple times; subsequent calls are no-ops.\n */\nexport function registerAsyncLocalStorageClass(\n  cls: new () => AsyncLocalStorageLike<unknown>,\n): void {\n  if (!AsyncLocalStorageClass) {\n    AsyncLocalStorageClass = cls\n  }\n  initDone = true\n}\n\n/**\n * Assert that AsyncLocalStorage was registered successfully.\n *\n * Called by `node.ts` after importing `asyncStorageNode.ts` to catch\n * import-order bugs at startup rather than silently degrading to the\n * browser fallback (flat spans with no nesting).\n *\n * This should ONLY be called from the Node.js entry point where we\n * know `node:async_hooks` must be available.\n */\nexport function assertAsyncStorageRegistered(): void {\n  if (!AsyncLocalStorageClass) {\n    console.warn(\n      \"Bitfab: AsyncLocalStorage not available - nested span context will not propagate.\",\n    )\n  }\n}\n\nexport const asyncStorageReady: Promise<void> = (\n  typeof process !== \"undefined\" && process.versions?.node\n    ? // The join trick hides \"node:async_hooks\" from static analysis so\n      // bundlers that ban Node.js built-ins don't fail at build time.\n      // webpackIgnore tells webpack/turbopack to emit a native import()\n      // so Node.js can resolve the module at runtime.\n      import(\n        /* webpackIgnore: true */\n        [\"node\", \"async_hooks\"].join(\":\")\n      )\n        .then(\n          (mod: {\n            AsyncLocalStorage: new () => AsyncLocalStorageLike<unknown>\n          }) => {\n            registerAsyncLocalStorageClass(mod.AsyncLocalStorage)\n          },\n        )\n        .catch(() => {})\n    : Promise.resolve()\n).then(() => {\n  initDone = true\n})\n\nexport function isAsyncStorageInitDone(): boolean {\n  return initDone\n}\n\nexport function createAsyncLocalStorage<T>(): AsyncLocalStorageLike<T> | null {\n  return AsyncLocalStorageClass\n    ? (new AsyncLocalStorageClass() as AsyncLocalStorageLike<T>)\n    : null\n}\n","/**\n * Shared error type for Bitfab SDK runtime errors. Lives in its own\n * module to avoid import cycles between `http.ts` and modules that need\n * to throw structured errors (e.g. `dbSnapshot.ts` validation).\n */\n\nexport class BitfabError extends Error {\n  constructor(\n    message: string,\n    public readonly url?: string,\n  ) {\n    super(message)\n    this.name = \"BitfabError\"\n  }\n}\n","/**\n * Emit a `console.warn` at most once per distinct `key` for the life of the\n * process.\n *\n * The SDK must NEVER crash a host app, so every failure on the user's path\n * degrades silently (a span is dropped, a call runs untraced, a payload is\n * stubbed). Silent is safe but undebuggable: a user who suddenly has no traces,\n * or sees `<unserializable>` in a span, has no signal as to why. A one-time\n * warning per distinct issue restores that signal without spamming the console\n * from a hot path.\n *\n * Keys should identify the specific degradation (e.g. include the traced\n * function key) so each distinct issue warns once, not just the first one seen.\n */\nconst warned = new Set<string>()\n\nexport function warnOnce(key: string, message: string): void {\n  if (warned.has(key)) {\n    return\n  }\n  warned.add(key)\n  try {\n    console.warn(`[bitfab] ${message}`)\n  } catch {\n    // Logging must never crash the host app (e.g. a closed/replaced console).\n  }\n}\n\n/** Test-only: clear the dedup set so a warning can fire again. */\nexport function _resetWarnOnce(): void {\n  warned.clear()\n}\n","/**\n * Serialization utilities for Bitfab SDK.\n *\n * This module provides serialization with type metadata preservation,\n * using superjson for handling special JavaScript types like Date, Map,\n * Set, BigInt, undefined, etc.\n */\n\nimport superjson from \"superjson\"\nimport { warnOnce } from \"./warnOnce.js\"\n\n/**\n * Serialized value with JSON data and optional superjson meta for type preservation.\n *\n * The json field contains the JSON-serializable data.\n * The meta field (if present) contains superjson type information for deserializing\n * special types like Date, Map, Set, BigInt, etc.\n */\nexport interface SerializedValue {\n  json: unknown\n  meta?: unknown\n}\n\n// Cap on serialized payload size. superjson can succeed on values like SDK\n// client instances (OpenAI, etc.) and produce hundreds of KB to MB of useless\n// internal state. Anything beyond this is replaced with a stub so the span\n// still ships and the trace isn't dropped server-side.\nconst MAX_SERIALIZED_BYTES = 512_000\n\n// A higher cap for the framework-capture path (toJsonSafe). Agent/graph states\n// (LangGraph, Claude Agent SDK) are legitimately larger than a single\n// function's args/return, so this ceiling preserves real detail while still\n// bounding the payload so the wire-side JSON.stringify can't blow up or get the\n// span rejected server-side.\nconst MAX_FRAMEWORK_SERIALIZED_BYTES = 2_000_000\n\nfunction describeValue(value: unknown): string {\n  try {\n    const ctorName = (value as { constructor?: { name?: string } })?.constructor\n      ?.name\n    if (ctorName && ctorName !== \"Object\") {\n      return ctorName\n    }\n  } catch {\n    // Property access on `value` can throw (Proxy, poisoned getter).\n  }\n  return typeof value\n}\n\nfunction unserializableStub(value: unknown, reason: string): SerializedValue {\n  // Normalize the byte count out of the key so a too_large warning dedups\n  // across differently-sized payloads instead of warning once per size.\n  warnOnce(\n    `serialize:${reason.replace(/\\d+/g, \"N\")}`,\n    `a value could not be fully serialized for a span (${reason}); it was replaced with a placeholder. The span still ships, but its captured input/output is incomplete.`,\n  )\n  let summary: string\n  try {\n    summary = `<unserializable: ${describeValue(value)} (${reason})>`\n  } catch {\n    summary = `<unserializable (${reason})>`\n  }\n  return { json: summary }\n}\n\n/**\n * Serialize a value using superjson for trace storage.\n *\n * Handles arbitrary JavaScript values including:\n * - Date, RegExp, Error\n * - Map, Set\n * - BigInt\n * - undefined (in objects/arrays)\n * - Circular references\n *\n * Guarantees:\n * - Never throws. Pathological inputs (SDK clients, proxies, poisoned\n *   getters, circular graphs that defeat superjson) return a stub string.\n * - Never returns a payload larger than MAX_SERIALIZED_BYTES; oversized\n *   inputs are replaced with a stub. Without this the wire-side\n *   `JSON.stringify` in http.ts can produce a request that times out or\n *   gets rejected, leaving a trace with zero spans.\n *\n * @param value - Any JavaScript value to serialize\n * @returns SerializedValue with 'json' field containing the data.\n *          If type metadata is needed for reconstruction, includes 'meta' field.\n *\n * @example\n * ```typescript\n * const result = serializeValue(new Date('2024-01-15T10:30:00Z'))\n * // result.json contains the ISO string\n * // result.meta contains type info for Date reconstruction\n * ```\n */\nexport function serializeValue(value: unknown): SerializedValue {\n  try {\n    const { json, meta } = superjson.serialize(value)\n\n    let size: number\n    try {\n      size = JSON.stringify(json).length\n    } catch {\n      return unserializableStub(value, \"stringify_failed_after_superjson\")\n    }\n    if (size > MAX_SERIALIZED_BYTES) {\n      return unserializableStub(value, `too_large_${size}_bytes`)\n    }\n\n    return meta ? { json, meta } : { json }\n  } catch {\n    try {\n      return { json: JSON.parse(JSON.stringify(value)) }\n    } catch {\n      return unserializableStub(value, \"json_stringify_failed\")\n    }\n  }\n}\n\n/**\n * Deserialize a value that was serialized with serializeValue.\n *\n * @param serialized - A SerializedValue object with 'json' and optional 'meta'\n * @returns The reconstructed JavaScript value\n *\n * @example\n * ```typescript\n * const serialized = serializeValue(new Date('2024-01-15'))\n * const date = deserializeValue(serialized)\n * // date is a Date object\n * ```\n */\nexport function deserializeValue(serialized: SerializedValue): unknown {\n  if (serialized.meta === undefined) {\n    // No metadata, return as-is\n    return serialized.json\n  }\n\n  // Use superjson to deserialize with type reconstruction\n  // Cast json to the expected superjson type\n  type SuperJSONResult = Parameters<typeof superjson.deserialize>[0]\n  return superjson.deserialize({\n    json: serialized.json as SuperJSONResult[\"json\"],\n    meta: serialized.meta as SuperJSONResult[\"meta\"],\n  })\n}\n\nconst MAX_SAFE_DEPTH = 6\n\n/**\n * Convert any value to JSON-safe primitives, never throwing.\n *\n * Produces plain objects/arrays/scalars, recursing through `toJSON()` and\n * own-enumerable properties so no raw non-serializable value (a class, a\n * BigInt-bearing object) survives into a span payload. Cycles collapse to a\n * `<cycle ...>` marker; depth is capped.\n *\n * This is the single shared \"safe serialize\" used by the framework\n * integrations that capture raw objects (LangGraph, Claude Agent SDK). Keeping\n * the recurse-the-dump logic here, in one place, is what stops a new\n * integration from reintroducing the \"dump without recursing\" bug - see\n * `serializationInvariant.test.ts`.\n */\nexport function toJsonSafe(value: unknown): unknown {\n  return toJsonSafeReport(value).safe\n}\n\n/**\n * Like {@link toJsonSafe}, but also reports what could not be faithfully\n * captured.\n *\n * Returns `{ safe, dropped }` where `dropped` lists the type name behind every\n * placeholder the walker had to emit: a cycle, a max-depth cut, an oversized\n * payload, or a value that could only be stringified (a function/symbol) or\n * stubbed after a throw. A non-empty `dropped` means the captured input/output\n * is lossy. Framework handlers carry it to the send boundary so a degraded\n * capture is marked non-replayable (`serialization_degraded`) instead of being\n * shipped as if it round-trips - mirrors the Python SDK's `to_json_safe_report`\n * + `finalize_span_payload`.\n */\nexport function toJsonSafeReport(value: unknown): {\n  safe: unknown\n  dropped: string[]\n} {\n  const dropped: string[] = []\n  const safe = toJsonSafeInner(value, 0, new WeakSet(), dropped)\n  // Cap output size for parity with serializeValue. A multi-MB framework\n  // payload (a large LangGraph state, a long message history) would otherwise\n  // be JSON.stringify'd synchronously on the user's thread in http.ts and may\n  // be rejected server-side, leaving a trace with zero spans. Stub it instead\n  // so the span still ships. toJsonSafeInner produces only plain\n  // objects/arrays/scalars/strings, so JSON.stringify here cannot throw; the\n  // try is belt-and-suspenders.\n  try {\n    const size = JSON.stringify(safe)?.length ?? 0\n    if (size > MAX_FRAMEWORK_SERIALIZED_BYTES) {\n      warnOnce(\n        \"toJsonSafe:too_large\",\n        `a framework payload exceeded ${MAX_FRAMEWORK_SERIALIZED_BYTES} bytes and was replaced with a placeholder so the span still ships. The captured state for this span is incomplete.`,\n      )\n      // Keep any drops already accumulated by the walk (cycles, functions,\n      // depth cuts); a payload can be both lossy AND oversized, and the\n      // non-replayable marking needs the real types, not just the size stub.\n      return {\n        safe: `<unserializable: too_large_${size}_bytes>`,\n        dropped: [...dropped, `too_large_${size}_bytes`],\n      }\n    }\n  } catch {\n    // Keep the recursed value; the http-layer sanitizer is the final backstop.\n  }\n  return { safe, dropped }\n}\n\nfunction toJsonSafeInner(\n  value: unknown,\n  depth: number,\n  seen: WeakSet<object>,\n  dropped: string[],\n): unknown {\n  if (value === null || value === undefined) {\n    return value\n  }\n  if (\n    typeof value === \"string\" ||\n    typeof value === \"number\" ||\n    typeof value === \"boolean\"\n  ) {\n    return value\n  }\n\n  const className =\n    (value as { constructor?: { name?: string } })?.constructor?.name ??\n    typeof value\n  if (depth > MAX_SAFE_DEPTH) {\n    dropped.push(className)\n    return `<${className}>`\n  }\n\n  // Non-object composites (bigint, function, symbol) stringify directly. A\n  // bigint stringifies faithfully; a function/symbol becomes a lossy summary,\n  // so those are reported as dropped.\n  if (typeof value !== \"object\") {\n    if (typeof value === \"function\" || typeof value === \"symbol\") {\n      dropped.push(className)\n    }\n    try {\n      return String(value)\n    } catch {\n      dropped.push(className)\n      return `<${className}>`\n    }\n  }\n\n  if (seen.has(value as object)) {\n    dropped.push(className)\n    return `<cycle ${className}>`\n  }\n  seen.add(value as object)\n\n  let result: unknown\n  if (Array.isArray(value)) {\n    result = value.map((item) =>\n      toJsonSafeInner(item, depth + 1, seen, dropped),\n    )\n  } else if (typeof (value as Record<string, unknown>).toJSON === \"function\") {\n    // Recurse toJSON() output: it can still hold non-serializable values (e.g.\n    // a LangChain tool whose schema is a class) that would otherwise survive\n    // into the span payload and crash the wire-side JSON.stringify.\n    try {\n      result = toJsonSafeInner(\n        (value as { toJSON(): unknown }).toJSON(),\n        depth + 1,\n        seen,\n        dropped,\n      )\n    } catch {\n      dropped.push(className)\n      result = `<${className}>`\n    }\n  } else {\n    try {\n      const obj: Record<string, unknown> = {}\n      for (const [k, v] of Object.entries(value)) {\n        if (!k.startsWith(\"_\")) {\n          obj[k] = toJsonSafeInner(v, depth + 1, seen, dropped)\n        }\n      }\n      result = obj\n    } catch {\n      dropped.push(className)\n      result = `<${className}>`\n    }\n  }\n\n  // Backtrack: keep only ancestors on the current path in `seen`, so a shared\n  // (DAG) reference under sibling keys is serialized again rather than stubbed\n  // as a false cycle. Real cycles (an ancestor referencing itself) are still\n  // caught above.\n  seen.delete(value as object)\n  return result\n}\n","/**\n * Generate a UUID v4 without assuming a global `crypto`.\n *\n * `crypto.randomUUID()` is the fast path and exists in every mainstream modern\n * runtime (Node >= 19, all browsers, Deno, Vercel edge, Cloudflare Workers).\n * But the SDK must NEVER crash a host app, and a few runtimes it can legitimately\n * run in lack a global `crypto` or `crypto.randomUUID` (Node < 19 without a\n * polyfill, older React Native, some sandboxes). There, an unguarded\n * `crypto.randomUUID()` throws on the user's call path. This helper falls back\n * to a `Math.random()`-based v4 string instead.\n *\n * The fallback is NOT cryptographically secure. That is fine: trace and span\n * IDs only need to be unique enough to correlate the spans of one trace; they\n * are never security-sensitive.\n */\nimport { warnOnce } from \"./warnOnce.js\"\n\nexport function randomUuid(): string {\n  const globalCrypto = (\n    globalThis as { crypto?: { randomUUID?: () => string } }\n  ).crypto\n  if (typeof globalCrypto?.randomUUID === \"function\") {\n    try {\n      return globalCrypto.randomUUID()\n    } catch {\n      // Fall through to the manual generator below.\n    }\n  }\n  warnOnce(\n    \"crypto-unavailable\",\n    \"global crypto.randomUUID is unavailable; using a non-cryptographic fallback for trace/span ids. Tracing works normally (ids are correlation-only, not security-sensitive).\",\n  )\n  return fallbackUuidV4()\n}\n\n/**\n * RFC 4122 version 4 layout filled from `Math.random()`. Used only when a usable\n * global `crypto.randomUUID` is unavailable.\n */\nfunction fallbackUuidV4(): string {\n  return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (char) => {\n    const rand = (Math.random() * 16) | 0\n    const value = char === \"x\" ? rand : (rand & 0x3) | 0x8\n    return value.toString(16)\n  })\n}\n","/**\n * Replay context propagation via AsyncLocalStorage.\n *\n * When set, the withSpan wrapper injects testRunId into the span payload\n * so that new spans created during replay are linked to the test run.\n * Optionally carries a mock tree so child spans can return historical\n * outputs instead of executing.\n */\n\nimport {\n  type AsyncLocalStorageLike,\n  asyncStorageReady,\n  createAsyncLocalStorage,\n} from \"./asyncStorage.js\"\n\n/** A single span entry in the mock tree with its historical output. */\nexport interface MockSpan {\n  sourceSpanId: string\n  output: unknown\n  outputMeta?: unknown\n}\n\n/**\n * Per-item DB branch resolved by the Bitfab service from the source\n * trace's `dbSnapshotRef`. Carried on the replay context so that\n * customer code reads `databaseUrl` through `ReplayEnvironment`, and so\n * the process-isolated replay runner can materialize it into a `.env`\n * overlay file before customer code initializes its DB client.\n *\n * `neonBranchId` is the literal Neon branch id; passing it to\n * `releaseDbBranchLease` deletes that branch.\n */\nexport interface DbBranchLease {\n  neonBranchId: string\n  /** Env var name the customer's app reads, e.g. \"DATABASE_URL\". */\n  envKey: string\n  databaseUrl: string\n  expiresAt: string\n  /**\n   * The instant the branch was pinned to (the source trace's wall clock).\n   * Echoed back in `db_snapshot_usage` on the replayed trace's completion.\n   */\n  snapshotTimestamp?: string\n  providerConsoleUrl?: string\n  readOnly?: boolean\n}\n\n/**\n * Pre-built lookup table of historical span outputs.\n * Keys are `${traceFunctionKey}:${spanName}:${callIndex}` so that repeated\n * calls with the same (key, name) are matched by call order, but spans\n * sharing only the traceFunctionKey (different name) do not collide.\n */\nexport interface MockTree {\n  spans: Map<string, MockSpan>\n}\n\nexport interface ReplayContext {\n  testRunId: string\n  traceId?: string\n  inputSourceSpanId?: string\n  /**\n   * External trace ID from `external_traces.id`. Used for span-chain\n   * lookup against the source platform's trace tree (Braintrust, etc.).\n   * NOT the same as the Bitfab `traceId` - see `sourceBitfabTraceId`.\n   */\n  inputSourceTraceId?: string\n  /**\n   * The Bitfab `traces.id` of the historical trace that produced this\n   * replay item's input. This is what customer-facing surfaces (e.g.\n   * `ReplayEnvironment.traceId`) should expose, since it's the ID the\n   * customer sees in the Bitfab dashboard.\n   */\n  sourceBitfabTraceId?: string\n  mockTree?: MockTree\n  callCounters?: Map<string, number>\n  mockStrategy?: \"none\" | \"all\" | \"marked\"\n  dbBranchLease?: DbBranchLease\n  /**\n   * Set to true by `ReplayEnvironment` the first time customer code\n   * actually obtains `databaseUrl` for this item (via the getter or\n   * `snapshot()`). Reported on the trace completion inside\n   * `db_snapshot_usage` so the server can distinguish \"branch was\n   * provisioned and exposed\" from \"branch URL was actually consumed\".\n   * Any future consumption path that hands the URL to customer code by\n   * other means (e.g. a process-isolated runner writing an env overlay)\n   * must also set this.\n   */\n  dbSnapshotAccessed?: boolean\n  /**\n   * Collector for the replay item's trace-persistence work. When present,\n   * the root span's send path pushes a promise that resolves only after\n   * every span upload AND the trace completion have been sent (registered\n   * synchronously at send time, so the replay runner can await it after\n   * the wrapped fn resolves). This is what lets replay guarantee traces\n   * are persisted server-side before `completeReplay` builds the\n   * trace-ID mapping. Absent outside replay, where sends stay\n   * fire-and-forget.\n   */\n  pendingPersistence?: Promise<unknown>[]\n}\n\nlet replayContextStorage: AsyncLocalStorageLike<ReplayContext | null> | null =\n  null\n\nexport const replayContextReady: Promise<void> = asyncStorageReady.then(() => {\n  replayContextStorage = createAsyncLocalStorage<ReplayContext | null>()\n})\n\n/** Get the current replay context, if any. */\nexport function getReplayContext(): ReplayContext | null {\n  return replayContextStorage?.getStore() ?? null\n}\n\n/** Run a function within a replay context. */\nexport function runWithReplayContext<T>(ctx: ReplayContext, fn: () => T): T {\n  if (replayContextStorage) {\n    return replayContextStorage.run(ctx, fn)\n  }\n  return fn()\n}\n","/**\n * Replay historical traces through a function and create a test run.\n *\n * The replay flow has three phases:\n * 1. Start: fetches historical traces from the server and creates a test run\n * 2. Execute: re-runs each trace's inputs through the provided function locally\n * 3. Complete: marks the test run as completed on the server\n */\n\nimport type { DbSnapshotRef } from \"./dbSnapshot.js\"\nimport { BitfabError } from \"./errors.js\"\nimport type {\n  CodeChangeFile,\n  HttpClient,\n  SpanTreeNode,\n  TokenUsage,\n} from \"./http.js\"\nimport { randomUuid } from \"./randomUuid.js\"\nimport type { DbBranchLease, MockTree } from \"./replayContext.js\"\nimport { replayContextReady, runWithReplayContext } from \"./replayContext.js\"\nimport type { ReplayEnvironment } from \"./replayEnvironment.js\"\nimport { deserializeValue } from \"./serialize.js\"\n\nexport type MockStrategy = \"none\" | \"all\" | \"marked\"\n\nexport interface ReplayOptions {\n  /**\n   * Maximum number of traces to replay (1-100, default 5). Ignored when\n   * `traceIds` is passed (with a warning): an explicit ID list already\n   * determines how many traces replay.\n   */\n  limit?: number\n  /** Optional list of specific trace IDs to replay (max 100). */\n  traceIds?: string[]\n  /** Optional display name for the resulting experiment/test run. */\n  name?: string\n  /** Maximum number of items to process in parallel. Set to 1 for sequential. Default 10. */\n  maxConcurrency?: number\n  /**\n   * Description of the code change being tested in this replay. Stored on\n   * the resulting experiment so the change can be reviewed alongside results.\n   */\n  codeChangeDescription?: string\n  /**\n   * Files edited as part of this code change. Each entry holds the file path\n   * and the full `before`/`after` contents. The agent reads each file before\n   * and after editing and passes the two strings. Use `\"\"` for newly created\n   * files (`before`) or deleted files (`after`).\n   */\n  codeChangeFiles?: CodeChangeFile[]\n  /**\n   * Mock strategy for child spans during replay.\n   * - \"marked\": only spans tagged with { mockOnReplay: true } in SpanOptions are mocked (default)\n   * - \"none\": everything runs real code\n   * - \"all\": every child withSpan returns historical output\n   */\n  mock?: MockStrategy\n  /**\n   * Per-trace environment. When the source trace carries a DB branching\n   * snapshot, the SDK populates `environment.databaseUrl` before invoking\n   * `fn` for that item and resets it after. Customer code reads from the\n   * environment to pick up the per-trace branch URL.\n   */\n  environment?: ReplayEnvironment\n  /** Group ID to associate this replay with an experiment group for live streaming in Studio. */\n  experimentGroupId?: string\n  /**\n   * Dataset this replay runs against. When set, the resulting experiment is\n   * durably attributed to the dataset (stored on the test run), so it appears\n   * under the dataset's experiments even if the trace lineage can't be\n   * reconstructed. Validated server-side against the org.\n   */\n  datasetId?: string\n  /**\n   * Reshape recorded inputs before they are spread into `fn`.\n   *\n   * Replay pulls each trace's inputs exactly as they were captured against the\n   * function's signature AT TRACE TIME. When the function's shape has since\n   * changed (params renamed, reordered, collapsed into an options object, etc.),\n   * the recorded inputs no longer line up and `fn(...inputs)` throws. This hook\n   * lets a caller map the recorded inputs onto the current signature so replay\n   * can still run.\n   *\n   * Receives the deserialized recorded inputs and a per-trace {@link AdaptContext}\n   * (so a table-driven adapter can look up the adapted inputs by `traceId`), and\n   * returns the array actually spread into `fn`. The returned array is also what\n   * `ReplayItem.input` reports, so the experiment shows what was really run.\n   *\n   * Runs per item, inside the same try/catch as `fn`: if the adapter throws, the\n   * failure is surfaced on that item's `error` rather than crashing the run.\n   * Omit it to spread the recorded inputs unchanged.\n   */\n  adaptInputs?: (inputs: unknown[], ctx: AdaptContext) => unknown[]\n  /**\n   * Called once per item as it finishes, in completion order (not input\n   * order), with running totals for the whole run. Use it to render replay\n   * progress, for example a terminal progress bar. Replay does not know\n   * pass/fail at this point (verdicts are assigned later), so the totals only\n   * distinguish items whose function ran (`succeeded`) from items that threw\n   * (`errored`).\n   *\n   * Invoked synchronously right after each item settles, so keep it cheap. A\n   * throwing callback never crashes the run: the error is swallowed so progress\n   * UI can't break replay.\n   */\n  onProgress?: (progress: ReplayProgress) => void\n}\n\n/** Running totals reported to {@link ReplayOptions.onProgress} as replay proceeds. */\nexport interface ReplayProgress {\n  /** Test run ID created for this replay. */\n  testRunId?: string\n  /** Items that have finished so far, whether they succeeded or errored. */\n  completed: number\n  /** Total number of items in this replay run. */\n  total: number\n  /** Of the completed items, how many ran the function without throwing. */\n  succeeded: number\n  /** Of the completed items, how many threw (their `item.error` is set). */\n  errored: number\n  /**\n   * The single item that just settled to produce this event. `traceId` is the\n   * source (historical) trace that was replayed (so a UI can identify or link\n   * it); `error` is its replay error, or null when it ran ok; `durationMs` is how\n   * long this one trace took to replay. Lets a progress UI show per-trace\n   * pass/fail and timing as the run streams, without waiting for the full\n   * {@link ReplayResult}.\n   */\n  item?: {\n    /** Source (historical) trace ID being replayed. */\n    traceId: string | null\n    /** Local SDK replay trace ID, before the server maps it to a row ID. */\n    replayTraceId?: string | null\n    /** Deserialized inputs from the original trace. */\n    input?: unknown[]\n    /** The result returned by the replayed function, or undefined on error. */\n    result?: unknown\n    /** The original output from the historical trace. */\n    originalOutput?: unknown\n    error: string | null\n    durationMs: number | null\n    tokens?: TokenUsage | null\n    model?: string | null\n    dbSnapshotRef?: DbSnapshotRef | null\n  }\n}\n\n/**\n * Wire prefix the Bitfab plugin scans for. Each line {@link reportReplayProgress}\n * writes is this prefix followed by the JSON of the running totals (plus the\n * settled `item`). The plugin polls these lines to report live progress while a\n * replay runs in the background; keep the SDK emitter and the plugin parser in\n * sync.\n */\nexport const BITFAB_PROGRESS_PREFIX = \"@@bitfab:progress \"\n\n/**\n * A ready-made {@link ReplayOptions.onProgress} callback for replay scripts.\n * Pass it straight in:\n *\n * ```ts\n * await bitfab.replay(\"my-fn\", fn, { limit, onProgress: reportReplayProgress })\n * ```\n *\n * It writes one `@@bitfab:progress` line per trace to stderr, which the Bitfab\n * plugin polls to report live progress while the replay runs in the background,\n * so scripts never hand-format the wire protocol.\n * stdout is left untouched for direct-run ReplayResult JSON. Outside Node (no\n * `process.stderr`, e.g. a browser) it is a no-op, and a write failure is\n * swallowed so progress can never crash a run.\n */\nexport function reportReplayProgress(progress: ReplayProgress): void {\n  const stderr = typeof process !== \"undefined\" ? process.stderr : undefined\n  if (!stderr) {\n    return\n  }\n  try {\n    stderr.write(`${BITFAB_PROGRESS_PREFIX}${JSON.stringify(progress)}\\n`)\n  } catch {\n    // A progress reporter must never crash the replay run.\n  }\n}\n\n/** Per-trace context passed to {@link ReplayOptions.adaptInputs}. */\nexport interface AdaptContext {\n  /** Bitfab trace ID of the historical trace being replayed. */\n  traceId: string\n  /** External span ID the recorded inputs were read from. */\n  sourceSpanId: string\n}\n\n/**\n * The shape an adapter module must export as `adaptInputs`.\n *\n * Author an adapter in its own file (e.g. `scripts/replay-adapters/<name>.ts`),\n * import it in your replay script, and pass it to `replay({ adaptInputs })`:\n *\n * ```ts\n * import type { AdaptInputsFn } from \"@bitfab/sdk\"\n * export const adaptInputs: AdaptInputsFn = (inputs, ctx) => [reshape(inputs)]\n * ```\n */\nexport type AdaptInputsFn = (inputs: unknown[], ctx: AdaptContext) => unknown[]\n\nexport interface ReplayItem<T> {\n  /** Trace ID of the new trace created during replay. */\n  traceId: string | null\n  /** Deserialized inputs from the original trace. */\n  input: unknown[]\n  /** The result returned by the function during replay, or undefined on error. */\n  result: T | undefined\n  /** The original output from the historical trace. */\n  originalOutput: unknown\n  /** Error message if the function threw, or null on success. */\n  error: string | null\n  /** Original trace duration in milliseconds, or null if timestamps are missing. */\n  durationMs: number | null\n  /**\n   * Token usage from the REPLAYED run (this item's new execution), aggregated\n   * server-side from the spans it produced, or null if the run captured no\n   * token data. This is the \"new\" side of a token delta: compare it against\n   * the original trace's recorded usage to see how the code change moved cost.\n   * Matches what Studio's experiments view shows.\n   */\n  tokens: TokenUsage | null\n  /** Model name from the original trace, or null if not captured. */\n  model: string | null\n  /**\n   * The DB snapshot ref the SDK captured at trace open. Useful for debugging\n   * (\"what state was this trace pinned to?\") and for customers building\n   * their own resolvers. Undefined when the source trace was captured\n   * without `dbSnapshot` configured.\n   */\n  dbSnapshotRef: DbSnapshotRef | null\n}\n\nexport type { CodeChangeFile, TokenUsage }\n\nexport interface ReplayResult<T> {\n  /** Individual replay items with inputs, results, and comparison data. */\n  items: ReplayItem<T>[]\n  /** The test run ID created on the server. */\n  testRunId: string\n  /** Full URL to view the test run in the dashboard. */\n  testRunUrl: string\n}\n\n/**\n * Deserialize inputs from a historical span's rawData.\n *\n * Prefers superjson-serialized `input_meta` for type preservation,\n * falls back to the raw `input` field.\n */\nfunction deserializeInputs(spanData: Record<string, unknown>): unknown[] {\n  const inputMeta = spanData.input_meta as unknown\n  const rawInput = spanData.input\n\n  // If superjson meta is available, deserialize with type reconstruction\n  if (inputMeta !== undefined && inputMeta !== null) {\n    const deserialized = deserializeValue({ json: rawInput, meta: inputMeta })\n    if (Array.isArray(deserialized)) {\n      return deserialized\n    }\n    return deserialized !== undefined && deserialized !== null\n      ? [deserialized]\n      : []\n  }\n\n  // Fall back to raw input\n  if (Array.isArray(rawInput)) {\n    return rawInput\n  }\n  return rawInput !== undefined && rawInput !== null ? [rawInput] : []\n}\n\n/**\n * Deserialize the original output from a historical span's rawData.\n */\nfunction deserializeOutput(spanData: Record<string, unknown>): unknown {\n  const outputMeta = spanData.output_meta as unknown\n  const rawOutput = spanData.output\n\n  if (outputMeta !== undefined && outputMeta !== null) {\n    return deserializeValue({ json: rawOutput, meta: outputMeta })\n  }\n\n  return rawOutput\n}\n\n/**\n * Walk the children of a root span tree node in depth-first order and build\n * a MockTree keyed by `${traceFunctionKey}:${spanName}:${callIndex}`.\n *\n * The historical root itself is NOT walked. At replay time the runtime root\n * span has `isRootSpan === true` and never queries the mockTree (mock\n * interception is skipped for root spans by design), so the root has nothing\n * to look up. Walking it would just leave an unreachable entry in the table.\n *\n * The (key, name) compound match is what disambiguates same-key spans:\n *   - A wrapped function's children commonly share its traceFunctionKey via\n *     the fluent `getFunction(key).withSpan({ name }, ...)` pattern. They\n *     disambiguate by `name`, never colliding with each other.\n *   - Recursion: same (key, name) at every depth. callIndex per (key, name)\n *     orders them correctly without leaking the historical root into the\n *     nested call's slot.\n *   - Outer-wrapper replay scripts: the outer wrapper's `name` is distinct\n *     from anything in the historical tree (it only exists at replay), so\n *     its presence never disturbs counters or lookups for spans that do\n *     exist in the historical tree.\n */\nfunction buildMockTree(rootNode: SpanTreeNode): MockTree {\n  const spans = new Map<\n    string,\n    { sourceSpanId: string; output: unknown; outputMeta?: unknown }\n  >()\n  const counters = new Map<string, number>()\n\n  function walk(node: SpanTreeNode): void {\n    const key = node.traceFunctionKey\n    if (key) {\n      const name = node.spanName || key\n      const counterKey = `${key}:${name}`\n      const index = counters.get(counterKey) ?? 0\n      counters.set(counterKey, index + 1)\n      spans.set(`${counterKey}:${index}`, {\n        sourceSpanId: node.sourceSpanId,\n        output: node.output,\n        outputMeta: node.outputMeta,\n      })\n    }\n    for (const child of node.children) {\n      walk(child)\n    }\n  }\n\n  for (const child of rootNode.children) {\n    walk(child)\n  }\n\n  return { spans }\n}\n\n/**\n * Execute a single replay item: fetch span data, deserialize inputs, call\n * the function within a replay context that injects testRunId into new spans.\n */\nasync function processItem<TReturn>(\n  httpClient: HttpClient,\n  serverItem: {\n    traceId: string\n    externalSpanId: string\n    durationMs: number | null\n    model: string | null\n    dbSnapshotRef?: DbSnapshotRef\n    dbBranchLease?: DbBranchLease\n  },\n  // biome-ignore lint/suspicious/noExplicitAny: replay deserializes inputs from historical data\n  fn: (...args: any[]) => TReturn | Promise<TReturn>,\n  testRunId: string,\n  mockStrategy: MockStrategy,\n  environment: ReplayEnvironment | undefined,\n  adaptInputs:\n    | ((inputs: unknown[], ctx: AdaptContext) => unknown[])\n    | undefined,\n): Promise<ReplayItem<TReturn>> {\n  // The server-side resolver materializes a Neon preview branch per item\n  // during `/api/sdk/replay/start` (when the customer passed `environment`,\n  // which triggers `includeDbBranchLease: true`). The lease arrives on the\n  // server item; we just attach it to the replay context and release the\n  // branch in `finally` so any throw (in fetch, mock-tree build, or the\n  // customer fn) frees the Neon resource. Items whose source trace had\n  // no snapshot ref, or whose resolve failed server-side, arrive without\n  // a lease; `env.active` will be `false` for those.\n  const lease = environment ? serverItem.dbBranchLease : undefined\n\n  let inputs: unknown[] = []\n  let originalOutput: unknown\n  let result: TReturn | undefined\n  let error: string | null = null\n  const replayedTraceId = randomUuid()\n  // Collects the root span's full persistence chain (span uploads + trace\n  // completion). Awaited below so this item's trace is on the server before\n  // replay() calls completeReplay. Otherwise the server's trace-ID mapping\n  // races the uploads and item.traceId nulls out.\n  const pendingPersistence: Promise<unknown>[] = []\n\n  try {\n    const span = await httpClient.getExternalSpan(serverItem.externalSpanId)\n    const spanData = (span.rawData?.span_data ?? {}) as Record<string, unknown>\n\n    inputs = deserializeInputs(spanData)\n    originalOutput = deserializeOutput(spanData)\n\n    // Reshape the recorded inputs onto the current signature when an adapter\n    // is supplied. Runs before the mock tree / fn call so the adapted array is\n    // what fn receives and what `item.input` reports.\n    if (adaptInputs) {\n      inputs = adaptInputs(inputs, {\n        traceId: serverItem.traceId,\n        sourceSpanId: serverItem.externalSpanId,\n      })\n    }\n\n    // Build mock tree when mocking is active\n    let mockTree: MockTree | undefined\n    if (mockStrategy === \"all\" || mockStrategy === \"marked\") {\n      try {\n        const treeResponse = await httpClient.getSpanTree(\n          serverItem.externalSpanId,\n        )\n        if (treeResponse.root) {\n          mockTree = buildMockTree(treeResponse.root)\n        } else if (mockStrategy === \"all\") {\n          throw new BitfabError(\n            `Replay mock strategy \"all\" requires a span tree root for source span ${serverItem.externalSpanId}.`,\n          )\n        } else {\n          mockTree = undefined\n        }\n      } catch (e) {\n        if (mockStrategy === \"all\") {\n          throw e\n        }\n        mockTree = undefined\n      }\n    }\n\n    const maybePromise = runWithReplayContext(\n      {\n        testRunId,\n        traceId: replayedTraceId,\n        inputSourceSpanId: span.id,\n        inputSourceTraceId: span.externalTraceId,\n        sourceBitfabTraceId: serverItem.traceId,\n        mockTree,\n        callCounters: mockTree ? new Map() : undefined,\n        mockStrategy,\n        dbBranchLease: lease,\n        pendingPersistence,\n      },\n      () => fn(...inputs),\n    )\n    result = maybePromise instanceof Promise ? await maybePromise : maybePromise\n  } catch (e) {\n    error = e instanceof Error ? e.message : String(e)\n  } finally {\n    // Wait for this item's trace (spans + completion) to be fully persisted\n    // before the item resolves. Runs on the error path too. A throwing fn\n    // still emits a root span whose trace must land before completeReplay.\n    await Promise.allSettled(pendingPersistence)\n    if (lease) {\n      try {\n        await httpClient.releaseDbBranchLease(lease.neonBranchId)\n      } catch (e) {\n        try {\n          console.warn(\n            `Bitfab: failed to release DB branch ${lease.neonBranchId} (TTL janitor will catch it): ${\n              e instanceof Error ? e.message : String(e)\n            }`,\n          )\n        } catch {\n          // Never crash the host\n        }\n      }\n    }\n  }\n\n  return {\n    traceId: replayedTraceId,\n    input: inputs,\n    result,\n    originalOutput,\n    error,\n    durationMs: serverItem.durationMs ?? null,\n    // Filled in by replay() from the complete-replay response once the\n    // replay traces are persisted and their spans aggregated server-side.\n    // Null here (and on older servers) means \"replay tokens not known\".\n    tokens: null,\n    model: serverItem.model ?? null,\n    dbSnapshotRef: serverItem.dbSnapshotRef ?? null,\n  }\n}\n\n/**\n * Run async tasks with a concurrency limit.\n * Each task factory is called when a slot opens; results preserve input order.\n */\nasync function mapWithConcurrency<T>(\n  tasks: Array<() => Promise<T>>,\n  maxConcurrency: number,\n  onSettled?: (result: T, index: number) => void,\n): Promise<T[]> {\n  const results: T[] = new Array(tasks.length)\n  let nextIndex = 0\n\n  async function worker(): Promise<void> {\n    while (nextIndex < tasks.length) {\n      const index = nextIndex++\n      const result = await tasks[index]()\n      results[index] = result\n      onSettled?.(result, index)\n    }\n  }\n\n  const workers = Array.from(\n    { length: Math.min(maxConcurrency, tasks.length) },\n    () => worker(),\n  )\n  await Promise.all(workers)\n  return results\n}\n\n/**\n * Replay historical traces through a function and create a test run.\n *\n * @internal Called by Bitfab.replay, not part of the public API.\n */\nexport async function replay<TReturn>(\n  httpClient: HttpClient,\n  serviceUrl: string,\n  traceFunctionKey: string,\n  // biome-ignore lint/suspicious/noExplicitAny: replay deserializes inputs from historical data\n  fn: (...args: any[]) => TReturn | Promise<TReturn>,\n  options?: ReplayOptions,\n): Promise<ReplayResult<TReturn>> {\n  if (options?.traceIds !== undefined) {\n    if (options.traceIds.length === 0) {\n      throw new BitfabError(\"traceIds must contain at least one trace ID.\")\n    }\n    if (options.traceIds.length > 100) {\n      throw new BitfabError(\n        `traceIds supports at most 100 trace IDs per replay (got ${options.traceIds.length}).`,\n      )\n    }\n  }\n  if (options?.limit !== undefined && options?.traceIds !== undefined) {\n    try {\n      console.warn(\n        \"Bitfab: limit is ignored when traceIds is passed: the explicit trace ID list already determines how many traces replay.\",\n      )\n    } catch {\n      // Never crash the host app\n    }\n  }\n\n  await replayContextReady\n\n  const {\n    testRunId,\n    testRunUrl,\n    items: serverItems,\n  } = await httpClient.startReplay(\n    traceFunctionKey,\n    // limit is meaningless with explicit traceIds (the ID list determines\n    // the count), so it's omitted from the request entirely.\n    options?.traceIds ? undefined : (options?.limit ?? 5),\n    options?.traceIds,\n    options?.name,\n    options?.codeChangeDescription,\n    options?.codeChangeFiles,\n    options?.environment !== undefined, // includeDbBranchLease\n    options?.experimentGroupId,\n    options?.datasetId,\n  )\n\n  const mockStrategy: MockStrategy = options?.mock ?? \"marked\"\n  const maxConcurrency = options?.maxConcurrency ?? 10\n\n  const tasks = serverItems.map(\n    (serverItem) => () =>\n      processItem(\n        httpClient,\n        serverItem,\n        fn,\n        testRunId,\n        mockStrategy,\n        options?.environment,\n        options?.adaptInputs,\n      ),\n  )\n  const total = tasks.length\n  let completed = 0\n  let succeeded = 0\n  let errored = 0\n  const resultItems = await mapWithConcurrency(\n    tasks,\n    maxConcurrency,\n    options?.onProgress\n      ? (item, index) => {\n          completed += 1\n          if (item.error === null) {\n            succeeded += 1\n          } else {\n            errored += 1\n          }\n          try {\n            options?.onProgress?.({\n              testRunId,\n              completed,\n              total,\n              succeeded,\n              errored,\n              item: {\n                // Source (historical) trace id, so a UI can identify the trace\n                // that just settled. The item's own traceId is the new replay\n                // trace and is assigned later (below), so use the server item.\n                traceId: serverItems[index]?.traceId ?? null,\n                replayTraceId: item.traceId,\n                input: item.input,\n                result: item.result,\n                originalOutput: item.originalOutput,\n                error: item.error,\n                durationMs: item.durationMs,\n                tokens: item.tokens,\n                model: item.model,\n                dbSnapshotRef: item.dbSnapshotRef,\n              },\n            })\n          } catch {\n            // Progress UI must never crash the replay run.\n          }\n        }\n      : undefined,\n  )\n\n  // Every item awaited its own trace persistence (spans + completion) in\n  // processItem, so all replay traces are on the server by now. No flush\n  // needed, and completeReplay's trace-ID mapping is deterministic.\n  // completeReplay failures propagate: a missing mapping means verdicts\n  // can't be persisted, which callers must hear about loudly.\n  const completeResult = await httpClient.completeReplay(testRunId)\n  const serverTraceIds = completeResult.traceIds\n  // Per-replay-trace token usage, keyed by server trace id. The REPLAYED run's\n  // tokens (span-aggregated server-side), used below to fill each item.tokens.\n  const replayTokens = completeResult.tokens\n\n  if (serverTraceIds === undefined) {\n    // Older servers don't return the mapping. Preserve the legacy\n    // null-traceId behavior but say why.\n    try {\n      console.warn(\n        \"Bitfab: server did not return replay trace IDs; item.traceId will be null (server upgrade required for verdict persistence)\",\n      )\n    } catch {\n      // Never crash the host app\n    }\n    for (const item of resultItems) {\n      item.traceId = null\n    }\n  } else {\n    // Map each item's locally-generated trace ID to the server's trace row\n    // ID. A completed item with no mapping means its trace was sent but the\n    // server has no record. A null traceId blocks verdict persistence and\n    // the Studio experiments view downstream, so this must never be silent.\n    //\n    // Severity splits on scope:\n    // - ALL completed items missing → systemic (the replayed function isn't\n    //   wrapped with withSpan, or uploads are wholesale broken). Throw; the\n    //   run's results are unusable for persistence and silence here is the\n    //   exact bug this guarantee exists to prevent.\n    // - SOME completed items missing → per-item upload failure (transient\n    //   network blip, one oversized payload). Null those items and log an\n    //   unmissable error, but return the run; callers can persist verdicts\n    //   for the items that landed instead of losing all the compute.\n    const missing: string[] = []\n    let completedCount = 0\n    for (const item of resultItems) {\n      if (item.traceId) {\n        const mapped = serverTraceIds[item.traceId]\n        if (item.error === null) {\n          completedCount += 1\n          if (mapped === undefined) {\n            missing.push(item.traceId)\n          }\n        }\n        // Pull this item's replayed-run tokens by its server trace id, before\n        // item.traceId is overwritten with that id below.\n        if (mapped !== undefined) {\n          item.tokens = replayTokens?.[mapped] ?? null\n        }\n        item.traceId = mapped ?? null\n      }\n    }\n    if (missing.length > 0) {\n      const serverCount =\n        completeResult.traceCount !== undefined\n          ? ` The server persisted ${completeResult.traceCount} trace(s) for this run.`\n          : \"\"\n      if (missing.length === completedCount) {\n        throw new BitfabError(\n          `Replay completed but the server has no persisted trace for any of the ${completedCount} completed item(s) (testRunId ${testRunId}).${serverCount} ` +\n            `Trace uploads were awaited, so either the uploads failed (check for \"Bitfab: Failed to create\" errors above) or the replayed function is not wrapped with withSpan.`,\n        )\n      }\n      try {\n        console.error(\n          `Bitfab: server has no persisted trace for ${missing.length} of ${completedCount} completed replay item(s) (testRunId ${testRunId}).${serverCount} ` +\n            `Their traceId is null and verdicts cannot be persisted for them. Missing: ${missing.join(\", \")}`,\n        )\n      } catch {\n        // Never crash the host app\n      }\n    }\n  }\n\n  const replayResult = {\n    items: resultItems,\n    testRunId,\n    testRunUrl: `${serviceUrl}${testRunUrl}`,\n  }\n  await writeReplayResultFile(replayResult)\n  return replayResult\n}\n\nasync function writeReplayResultFile(result: unknown): Promise<void> {\n  const resultPath =\n    typeof process !== \"undefined\"\n      ? process.env?.BITFAB_REPLAY_RESULT_PATH\n      : undefined\n  if (!resultPath) {\n    return\n  }\n\n  try {\n    const [{ dirname }, { mkdir, writeFile }] = await Promise.all([\n      import(\"node:path\"),\n      import(\"node:fs/promises\"),\n    ])\n    await mkdir(dirname(resultPath), { recursive: true })\n    await writeFile(resultPath, `${JSON.stringify(result, null, 2)}\\n`)\n  } catch (err) {\n    try {\n      console.warn(\n        `Bitfab: failed to write replay result to BITFAB_REPLAY_RESULT_PATH (${resultPath}): ${\n          err instanceof Error ? err.message : String(err)\n        }`,\n      )\n    } catch {\n      // Never crash the host app.\n    }\n  }\n}\n","/**\n * Node.js-specific entry point for the Bitfab SDK.\n *\n * Selected automatically via package.json `exports` conditions when the\n * consumer's runtime or bundler supports the \"node\" condition (Node.js,\n * most server-side bundlers).\n *\n * This entry point differs from the default (`index.ts`) in one way:\n * it synchronously registers Node.js's `AsyncLocalStorage` before any\n * other SDK code evaluates. This eliminates the async initialization\n * gap that the default entry point has (where the first span might\n * execute before the dynamic import of `node:async_hooks` resolves).\n *\n * The default entry point (`index.ts`) is used for browsers and other\n * environments where `node:async_hooks` is unavailable. There, span\n * nesting degrades gracefully to a shared stack (correct for sequential\n * async, but not for concurrent Promise.all patterns).\n */\n\n// ⚠️ IMPORT ORDER MATTERS\n// asyncStorageNode MUST be imported before index.js.\n// It registers the AsyncLocalStorage class synchronously during module\n// evaluation. index.js (via client.ts) reads from that registration at\n// span creation time. If this import is moved after index.js or removed,\n// span nesting silently degrades to the browser fallback (flat spans).\nimport \"./asyncStorageNode.js\"\n\nexport * from \"./index.js\"\n\n// Verify registration succeeded. This turns a silent degradation into a\n// loud error if someone reorders the imports above or if asyncStorageNode.ts\n// fails to register for any reason. Only runs in the Node.js entry point\n// where we know node:async_hooks must be available.\nimport { assertAsyncStorageRegistered } from \"./asyncStorage.js\"\n\nassertAsyncStorageRegistered()\n","/**\n * Synchronous AsyncLocalStorage registration for Node.js.\n *\n * This module is a side-effect-only import: it registers the Node.js\n * AsyncLocalStorage class into the shared registry so span nesting\n * works immediately - no async gap, no microtask delay.\n *\n * It is imported by `node.ts` (the Node.js-specific entry point) as\n * the FIRST import, before `index.ts` or `client.ts` are evaluated.\n *\n * This file must ONLY be imported in Node.js environments (not browsers).\n * It uses a static `import` of `node:async_hooks`, which will fail in\n * browser bundlers. The `node.ts` entry point is conditionally selected\n * via package.json `exports` conditions, so browsers never see this file.\n */\n\nimport { AsyncLocalStorage } from \"node:async_hooks\"\nimport type { AsyncLocalStorageLike } from \"./asyncStorage.js\"\nimport { registerAsyncLocalStorageClass } from \"./asyncStorage.js\"\n\nregisterAsyncLocalStorageClass(\n  AsyncLocalStorage as unknown as new () => AsyncLocalStorageLike<unknown>,\n)\n","/**\n * Auto-generated version file.\n * This file is generated by scripts/generate-version.ts during build.\n * DO NOT EDIT MANUALLY.\n */\n\n/**\n * SDK version from package.json (injected at build time)\n */\nexport const __version__ = \"0.28.10\"\n","/**\n * Constants for the Bitfab SDK.\n */\n\n/**\n * Default service URL for Bitfab API.\n */\nexport const DEFAULT_SERVICE_URL = \"https://bitfab.ai\"\n\n/**\n * SDK version from package.json (injected at build time)\n *\n * The version is generated at build time by scripts/generate-version.ts\n * to ensure compatibility with both Node.js and browser environments.\n */\nexport { __version__ } from \"./version.generated.js\"\n","/**\n * HTTP client utilities for Bitfab API requests.\n *\n * This module provides:\n * - HttpClient class for making API requests\n * - awaitOnExit helper for fire-and-forget operations that must complete before process exit\n */\n\nimport { __version__ } from \"./constants.js\"\nimport type { DbSnapshotRef } from \"./dbSnapshot.js\"\nimport { BitfabError } from \"./errors.js\"\nimport type { DbBranchLease } from \"./replayContext.js\"\nimport { unrefTimer } from \"./unrefTimer.js\"\nimport { warnOnce } from \"./warnOnce.js\"\n\n// BitfabError lives in `errors.ts` to break the http ↔ dbSnapshot import\n// cycle. Re-exported here for backwards compatibility with existing\n// callers that import it from \"./http.js\".\nexport { BitfabError }\n\n/**\n * JSON-encode a request body without ever throwing on a stray value.\n *\n * Upstream serialization (`serializeValue` / the LangGraph handler's\n * `safeSerialize`) should already have flattened user data. This is the\n * boundary backstop: if anything non-serializable still slips through\n * (BigInt, function, symbol, circular ref), it is stubbed in place instead of\n * letting `JSON.stringify` throw and drop the whole span/trace silently.\n *\n * The fast path is a plain `JSON.stringify`; the sanitizing replacer only runs\n * when that throws, so happy-path payloads (and shared non-circular refs) are\n * untouched. Returns `dropped` (the stubbed type names) so the caller can warn\n * loudly rather than ship a degraded payload in silence.\n */\nexport function serializePayloadBody(payload: Record<string, unknown>): {\n  body: string\n  dropped: string[]\n} {\n  try {\n    return { body: JSON.stringify(payload), dropped: [] }\n  } catch {\n    const dropped: string[] = []\n    // An explicit backtracking walk, not a JSON.stringify replacer: a replacer\n    // gets no subtree-exit signal, so a single WeakSet would mis-tag a shared\n    // (DAG) reference under sibling keys as a cycle. Tracking only the\n    // current-path ancestors stubs real cycles while serializing DAGs in full.\n    const sanitize = (value: unknown, seen: WeakSet<object>): unknown => {\n      const t = typeof value\n      if (\n        value === null ||\n        t === \"string\" ||\n        t === \"number\" ||\n        t === \"boolean\"\n      ) {\n        return value\n      }\n      if (t === \"bigint\") {\n        dropped.push(\"BigInt\")\n        return \"<unserializable: BigInt>\"\n      }\n      if (t === \"function\") {\n        const name = (value as { name?: string }).name || \"Function\"\n        dropped.push(name)\n        return `<unserializable: ${name}>`\n      }\n      if (t === \"symbol\") {\n        dropped.push(\"Symbol\")\n        return \"<unserializable: Symbol>\"\n      }\n      if (t !== \"object\") {\n        return undefined // e.g. undefined; JSON omits/normalizes it\n      }\n      const obj = value as object\n      const className =\n        (obj as { constructor?: { name?: string } }).constructor?.name ||\n        \"object\"\n      if (seen.has(obj)) {\n        dropped.push(className)\n        return `<cycle: ${className}>`\n      }\n      seen.add(obj)\n      let result: unknown\n      if (Array.isArray(obj)) {\n        result = obj.map((item) => sanitize(item, seen))\n      } else if (typeof (obj as { toJSON?: unknown }).toJSON === \"function\") {\n        try {\n          result = sanitize((obj as { toJSON(): unknown }).toJSON(), seen)\n        } catch {\n          dropped.push(className)\n          result = `<unserializable: ${className}>`\n        }\n      } else {\n        try {\n          const out: Record<string, unknown> = {}\n          for (const [k, v] of Object.entries(obj)) {\n            out[k] = sanitize(v, seen)\n          }\n          result = out\n        } catch {\n          // A throwing getter or Proxy on `obj` can make `Object.entries`\n          // throw. Stub just this object instead of failing the whole payload\n          // (which would drop every span field). Mirrors the toJSON branch.\n          warnOnce(\n            \"payload:field-getter-threw\",\n            \"a value with a throwing getter/proxy could not be serialized into a span payload; it was replaced with a placeholder. The span still ships with its other fields intact.\",\n          )\n          dropped.push(className)\n          result = `<unserializable: ${className}>`\n        }\n      }\n      seen.delete(obj) // backtrack: only ancestors stay tracked\n      return result\n    }\n    let sanitized: unknown\n    try {\n      sanitized = sanitize(payload, new WeakSet())\n    } catch (error) {\n      // Truly pathological. Still never drop silently: send a marker body.\n      const message = error instanceof Error ? error.message : String(error)\n      return {\n        body: JSON.stringify({ error: `payload_serialize_failed: ${message}` }),\n        dropped,\n      }\n    }\n    // Keep the server-side signal that the SDK had to stub values, so the\n    // trace can be flagged as possibly incomplete / not replayable, while the\n    // span content (everything that did serialize) is preserved.\n    if (\n      dropped.length > 0 &&\n      typeof sanitized === \"object\" &&\n      sanitized !== null &&\n      !Array.isArray(sanitized)\n    ) {\n      const obj = sanitized as Record<string, unknown>\n      const existing = Array.isArray(obj.errors) ? obj.errors : []\n      obj.errors = [\n        ...existing,\n        {\n          source: \"sdk\",\n          step: \"json_serialize\",\n          error: `stubbed non-serializable value(s): ${[\n            ...new Set(dropped),\n          ].join(\", \")}`,\n        },\n      ]\n    }\n    return { body: JSON.stringify(sanitized), dropped }\n  }\n}\n\n// Global set to track pending trace creation promises\n// This prevents promises from being garbage collected before they complete\nconst pendingTracePromises = new Set<Promise<unknown>>()\n\n/**\n * Track a promise to prevent it from being garbage collected.\n * The promise will be removed from tracking when it completes (success or failure).\n * Useful for fire-and-forget operations that need to complete before process exit.\n *\n * @param promise - The promise to track\n * @returns The same promise (for chaining)\n */\nexport function awaitOnExit<T>(promise: Promise<T>): Promise<T> {\n  pendingTracePromises.add(promise)\n  // Use void to prevent unhandled rejection warnings from the .finally() chain\n  // The actual error handling is done by the caller's .catch() on the returned promise\n  void promise\n    .finally(() => {\n      pendingTracePromises.delete(promise)\n    })\n    .catch(() => {\n      // Swallow rejection in this chain - the caller handles errors via their own .catch()\n    })\n  return promise\n}\n\n/**\n * Wait for all pending fire-and-forget operations (spans, traces) to complete.\n * Useful in tests and scripts to ensure all data has been sent before asserting or exiting.\n *\n * @param timeoutMs - Maximum time to wait in milliseconds (default: 5000)\n */\nexport async function flushTraces(timeoutMs: number = 5000): Promise<void> {\n  if (pendingTracePromises.size === 0) {\n    return\n  }\n  // Clear and unref the timeout so the loser of the race never leaves a\n  // dangling timer holding the event loop open after flush resolves.\n  let timer: ReturnType<typeof setTimeout> | undefined\n  try {\n    await Promise.race([\n      Promise.allSettled(Array.from(pendingTracePromises)),\n      new Promise<void>((resolve) => {\n        timer = setTimeout(resolve, timeoutMs)\n        unrefTimer(timer)\n      }),\n    ])\n  } finally {\n    if (timer) {\n      clearTimeout(timer)\n    }\n  }\n}\n\n// Register beforeExit handler to wait for pending traces (Node.js only)\n// This ensures traces are sent before the process exits (for scripts)\nif (\n  typeof process !== \"undefined\" &&\n  process.versions != null &&\n  process.versions.node != null\n) {\n  let isFlushing = false\n  process.on(\"beforeExit\", () => {\n    if (pendingTracePromises.size > 0 && !isFlushing) {\n      isFlushing = true\n      // Wait for all pending traces to complete\n      // This keeps the event loop alive until promises resolve\n      Promise.allSettled(\n        Array.from(pendingTracePromises).map((p) =>\n          p.catch(() => {\n            // Silently ignore individual trace failures\n          }),\n        ),\n      )\n        .then(() => {\n          isFlushing = false\n        })\n        .catch(() => {\n          isFlushing = false\n        })\n    }\n  })\n}\n\n/**\n * How the API key is supplied internally: either a literal string or a\n * function resolved each time the key is needed (at request/send time). The\n * function form is what defers key resolution past module-load construction\n * so an env var loaded after the client is built (the ESM dotenv-hoisting\n * case) is still picked up.\n */\nexport type ApiKeyInput = string | (() => string | undefined)\n\nexport interface HttpClientConfig {\n  apiKey?: ApiKeyInput\n  serviceUrl: string\n  timeout?: number\n}\n\n/**\n * HTTP client for Bitfab API requests.\n *\n * Provides methods for different API endpoints with proper error handling,\n * timeouts, and authentication.\n */\nexport class HttpClient {\n  private readonly apiKey: ApiKeyInput | undefined\n  private readonly serviceUrl: string\n  private readonly timeout: number\n\n  constructor(config: HttpClientConfig) {\n    this.apiKey = config.apiKey\n    this.serviceUrl = config.serviceUrl\n    this.timeout = config.timeout ?? 120000\n  }\n\n  /**\n   * Resolve the API key at the moment it is needed (request time), invoking\n   * the function form if one was supplied. Never read at construction.\n   */\n  private resolveApiKey(): string | undefined {\n    return typeof this.apiKey === \"function\" ? this.apiKey() : this.apiKey\n  }\n\n  /**\n   * Make an HTTP request to the Bitfab API. Defaults to POST; pass\n   * `options.method` to use a different verb (e.g. \"PATCH\").\n   *\n   * @param endpoint - The API endpoint (without base URL)\n   * @param payload - The request body\n   * @param options - Optional request options\n   * @returns The parsed JSON response\n   * @throws {BitfabError} If the request fails\n   */\n  async request<T>(\n    endpoint: string,\n    payload: Record<string, unknown>,\n    options?: { timeout?: number; method?: \"POST\" | \"PATCH\" | \"PUT\" },\n  ): Promise<T> {\n    const url = `${this.serviceUrl}${endpoint}`\n    const timeout = options?.timeout ?? this.timeout\n    const method = options?.method ?? \"POST\"\n\n    const controller = new AbortController()\n    const timeoutId = setTimeout(() => controller.abort(), timeout)\n\n    // Serialize the payload so a stray non-serializable value (BigInt,\n    // function, circular ref, a class instance that slipped past upstream\n    // serialization) can never abort the send and silently drop the span.\n    // Strays are stubbed in place, preserving span content, and a degraded\n    // payload warns loudly.\n    const { body, dropped } = serializePayloadBody(payload)\n    if (dropped.length > 0) {\n      try {\n        console.warn(\n          `Bitfab: request body to ${endpoint} held ${dropped.length} ` +\n            `non-serializable value(s) (${[...new Set(dropped)].join(\", \")}); ` +\n            \"they were stubbed so the span still sends, but the trace may be \" +\n            \"incomplete or not replayable. Capture a JSON-safe projection of \" +\n            \"this input to make it replayable.\",\n        )\n      } catch {}\n    }\n\n    try {\n      const response = await fetch(url, {\n        method,\n        headers: {\n          \"Content-Type\": \"application/json\",\n          Authorization: `Bearer ${this.resolveApiKey() ?? \"\"}`,\n        },\n        body,\n        signal: controller.signal,\n      })\n\n      if (!response.ok) {\n        const errorText = await response.text()\n        throw new BitfabError(\n          `HTTP ${response.status}: ${errorText.slice(0, 500)}`,\n        )\n      }\n\n      const result = await response.json()\n\n      // Check for errors in the response\n      if (result.error) {\n        if (result.url) {\n          throw new BitfabError(\n            `${result.error} Configure it at: ${this.serviceUrl}${result.url}`,\n            result.url,\n          )\n        }\n        throw new BitfabError(result.error)\n      }\n\n      return result as T\n    } catch (error) {\n      if (error instanceof BitfabError) {\n        throw error\n      }\n      if (error instanceof Error) {\n        if (error.name === \"AbortError\") {\n          throw new BitfabError(`Request timed out after ${timeout}ms`)\n        }\n        throw new BitfabError(error.message)\n      }\n      throw new BitfabError(\"Unknown error occurred\")\n    } finally {\n      clearTimeout(timeoutId)\n    }\n  }\n\n  /**\n   * Look up a function by name.\n   * Blocks until complete - needed for function execution.\n   */\n  async lookupFunction<T>(name: string): Promise<T> {\n    return this.request<T>(\"/api/sdk/functions/lookup\", { name })\n  }\n\n  /**\n   * Send an internal trace (from BAML execution).\n   * Fire-and-forget with awaitOnExit - doesn't block the caller.\n   */\n  sendInternalTrace(\n    functionId: string,\n    payload: Record<string, unknown>,\n  ): void {\n    void awaitOnExit(\n      this.request(`/api/sdk/functions/${functionId}/traces`, {\n        ...payload,\n        sdkVersion: __version__,\n      }),\n    ).catch((error) => {\n      try {\n        console.error(\"Bitfab: Failed to create trace:\", error)\n      } catch {}\n    })\n  }\n\n  /**\n   * Send an external span (from withSpan wrapper or OpenAI tracing).\n   * Fire-and-forget with awaitOnExit - doesn't block the caller.\n   * Returns the tracked promise so callers can optionally await it.\n   */\n  sendExternalSpan(payload: Record<string, unknown>): Promise<unknown> {\n    return awaitOnExit(\n      this.request(\"/api/sdk/externalSpans\", {\n        ...payload,\n        sdkVersion: __version__,\n      }),\n    ).catch((error) => {\n      try {\n        console.error(\"Bitfab: Failed to create external span:\", error)\n      } catch {}\n    })\n  }\n\n  /**\n   * Send an external trace (from OpenAI tracing).\n   * Fire-and-forget with awaitOnExit - doesn't block the caller.\n   * Returns the tracked promise so callers can optionally await it\n   * (the replay path does, so trace completions are persisted before\n   * `completeReplay` builds the trace-ID mapping).\n   */\n  sendExternalTrace(payload: Record<string, unknown>): Promise<unknown> {\n    return awaitOnExit(\n      this.request(\"/api/sdk/externalTraces\", {\n        ...payload,\n        sdkVersion: __version__,\n      }),\n    ).catch((error) => {\n      try {\n        console.error(\"Bitfab: Failed to create external trace:\", error)\n      } catch {}\n    })\n  }\n\n  /**\n   * Partial update of an existing external trace identified by sourceTraceId.\n   * Used by the detached `client.getTrace(id)` handle. Fire-and-forget;\n   * returns a tracked promise that callers may optionally await.\n   */\n  patchTrace(\n    sourceTraceId: string,\n    payload: {\n      appendContexts?: Record<string, unknown>[]\n      mergeMetadata?: Record<string, unknown>\n      setSessionId?: string\n    },\n  ): Promise<unknown> {\n    const endpoint = `/api/sdk/externalTraces/${encodeURIComponent(sourceTraceId)}`\n    return awaitOnExit(\n      this.request(endpoint, payload, { method: \"PATCH\" }),\n    ).catch((error) => {\n      try {\n        console.error(\"Bitfab: Failed to patch trace:\", error)\n      } catch {}\n    })\n  }\n\n  /**\n   * Start a replay session by fetching historical traces.\n   * Blocking call - creates a test run and returns lightweight item references.\n   */\n  async startReplay(\n    traceFunctionKey: string,\n    limit: number | undefined,\n    traceIds?: string[],\n    name?: string,\n    codeChangeDescription?: string,\n    codeChangeFiles?: CodeChangeFile[],\n    includeDbBranchLease?: boolean,\n    experimentGroupId?: string,\n    datasetId?: string,\n  ): Promise<StartReplayResponse> {\n    // limit is only meaningful without traceIds (an explicit ID list\n    // already determines the count), so it's omitted when undefined.\n    const payload: Record<string, unknown> = { traceFunctionKey }\n    if (limit !== undefined) {\n      payload.limit = limit\n    }\n    if (traceIds) {\n      payload.traceIds = traceIds\n    }\n    if (name !== undefined) {\n      payload.name = name\n    }\n    if (codeChangeDescription !== undefined) {\n      payload.codeChangeDescription = codeChangeDescription\n    }\n    if (codeChangeFiles !== undefined) {\n      payload.codeChangeFiles = codeChangeFiles\n    }\n    if (includeDbBranchLease) {\n      payload.includeDbBranchLease = true\n    }\n    if (experimentGroupId !== undefined) {\n      payload.experimentGroupId = experimentGroupId\n    }\n    if (datasetId !== undefined) {\n      payload.datasetId = datasetId\n    }\n    // When DB branching is on, the server resolves a Neon preview branch\n    // per item (snapshot + restore + poll), which can run ~5-10s each.\n    // Use a generous timeout to cover the worst case; otherwise the SDK\n    // would time out before a healthy server finished.\n    const timeout = includeDbBranchLease ? 180_000 : 30_000\n    return this.request<StartReplayResponse>(\"/api/sdk/replay/start\", payload, {\n      timeout,\n    })\n  }\n\n  /**\n   * Fetch an external span by ID.\n   * Blocking GET request.\n   */\n  async getExternalSpan(spanId: string): Promise<ExternalSpanResponse> {\n    const url = `${this.serviceUrl}/api/sdk/externalSpans/${spanId}`\n    const controller = new AbortController()\n    const timeoutId = setTimeout(() => controller.abort(), 30_000)\n\n    try {\n      const response = await fetch(url, {\n        method: \"GET\",\n        headers: { Authorization: `Bearer ${this.resolveApiKey() ?? \"\"}` },\n        signal: controller.signal,\n      })\n\n      if (!response.ok) {\n        const errorText = await response.text()\n        throw new BitfabError(\n          `HTTP ${response.status}: ${errorText.slice(0, 500)}`,\n        )\n      }\n\n      return (await response.json()) as ExternalSpanResponse\n    } catch (error) {\n      if (error instanceof BitfabError) {\n        throw error\n      }\n      if (error instanceof Error) {\n        if (error.name === \"AbortError\") {\n          throw new BitfabError(\"Request timed out after 30000ms\")\n        }\n        throw new BitfabError(error.message)\n      }\n      throw new BitfabError(\"Unknown error occurred\")\n    } finally {\n      clearTimeout(timeoutId)\n    }\n  }\n\n  /**\n   * Fetch the span tree for a root span.\n   * Blocking GET request.\n   */\n  async getSpanTree(externalSpanId: string): Promise<SpanTreeResponse> {\n    const url = `${this.serviceUrl}/api/sdk/replay/spanTree/${externalSpanId}`\n    const controller = new AbortController()\n    const timeoutId = setTimeout(() => controller.abort(), 30_000)\n\n    try {\n      const response = await fetch(url, {\n        method: \"GET\",\n        headers: { Authorization: `Bearer ${this.resolveApiKey() ?? \"\"}` },\n        signal: controller.signal,\n      })\n\n      if (!response.ok) {\n        const errorText = await response.text()\n        throw new BitfabError(\n          `HTTP ${response.status}: ${errorText.slice(0, 500)}`,\n        )\n      }\n\n      return (await response.json()) as SpanTreeResponse\n    } catch (error) {\n      if (error instanceof BitfabError) {\n        throw error\n      }\n      if (error instanceof Error) {\n        if (error.name === \"AbortError\") {\n          throw new BitfabError(\"Request timed out after 30000ms\")\n        }\n        throw new BitfabError(error.message)\n      }\n      throw new BitfabError(\"Unknown error occurred\")\n    } finally {\n      clearTimeout(timeoutId)\n    }\n  }\n\n  /**\n   * Mark a replay test run as completed.\n   * Blocking call.\n   */\n  async completeReplay(testRunId: string): Promise<CompleteReplayResponse> {\n    return this.request<CompleteReplayResponse>(\n      \"/api/sdk/replay/complete\",\n      { testRunId },\n      { timeout: 30_000 },\n    )\n  }\n\n  /**\n   * Ask the server to materialize a per-trace DB branch lease from a\n   * captured `dbSnapshotRef`. Blocking - the resolver creates a Neon\n   * snapshot + preview branch and polls operations to readiness, which\n   * can take seconds.\n   */\n  async resolveDbBranchLease(\n    testRunId: string,\n    traceId: string,\n    dbSnapshotRef: DbSnapshotRef,\n  ): Promise<{ lease: DbBranchLease }> {\n    return this.request<{ lease: DbBranchLease }>(\n      \"/api/sdk/replay/resolveDbBranchLease\",\n      { testRunId, traceId, dbSnapshotRef },\n      { timeout: 90_000 },\n    )\n  }\n\n  /** Release a previously-resolved DB branch by deleting its Neon branch. Idempotent server-side. */\n  async releaseDbBranchLease(neonBranchId: string): Promise<void> {\n    await this.request<{ released: true }>(\n      \"/api/sdk/replay/releaseDbBranchLease\",\n      { neonBranchId },\n      { timeout: 30_000 },\n    )\n  }\n}\n\nexport interface TokenUsage {\n  input: number | null\n  output: number | null\n  cached: number | null\n  total: number | null\n}\n\n/**\n * Describes a single file edited as part of a code change.\n *\n * - `path`: file path (relative to the repo root, or any consistent root)\n * - `before`: file contents before the change (\"\" for newly created files)\n * - `after`: file contents after the change (\"\" for deleted files)\n */\nexport interface CodeChangeFile {\n  path: string\n  before: string\n  after: string\n}\n\nexport interface StartReplayResponse {\n  testRunId: string\n  testRunUrl: string\n  items: Array<{\n    traceId: string\n    externalSpanId: string\n    durationMs: number | null\n    tokens: TokenUsage | null\n    model: string | null\n    /**\n     * The DB snapshot ref captured by the SDK at trace open. Surfaced so\n     * the SDK can pass it to the lease-resolver step (or report when no\n     * snapshot was captured for this trace).\n     */\n    dbSnapshotRef?: DbSnapshotRef\n    /**\n     * Populated once the server-side resolver has materialized a per-item\n     * branch from `dbSnapshotRef`. The SDK exposes this to customer code\n     * via `ReplayEnvironment`. Absent until the resolver lands.\n     */\n    dbBranchLease?: DbBranchLease\n  }>\n}\n\nexport interface ExternalSpanResponse {\n  id: string\n  externalTraceId: string\n  rawData: {\n    span_data: {\n      input: unknown\n      output: unknown\n      input_meta?: unknown\n      output_meta?: unknown\n      input_serialized?: { json: unknown; meta: unknown }\n      output_serialized?: { json: unknown; meta: unknown }\n    }\n  }\n}\n\nexport interface CompleteReplayResponse {\n  id: string\n  status: string\n  traceIds?: Record<string, string>\n  /**\n   * Per-replay-trace token usage, keyed by the server trace id (the values of\n   * `traceIds`). Aggregated server-side from the freshly-uploaded replay spans,\n   * so it's the REPLAYED run's tokens (the same source Studio reads), not the\n   * original trace's. The SDK maps each item onto this to set\n   * `ReplayItem.tokens`. Absent on servers that predate this field.\n   */\n  tokens?: Record<string, TokenUsage | null>\n  /**\n   * Number of traces the server has persisted for this test run at\n   * completion time. Lets the SDK distinguish \"uploads failed\" from\n   * \"server never saw them\" when the trace-ID mapping is incomplete.\n   */\n  traceCount?: number\n}\n\nexport interface SpanTreeNode {\n  sourceSpanId: string\n  traceFunctionKey: string\n  spanName: string\n  type: string\n  output: unknown\n  outputMeta?: unknown\n  children: SpanTreeNode[]\n}\n\nexport interface SpanTreeResponse {\n  root: SpanTreeNode\n}\n","/**\n * Best-effort `unref()` on a timer handle so a pending timeout never keeps the\n * Node.js event loop alive on its own. An un-unref'd timeout would delay\n * process exit, prolong a serverless function's billed lifetime, and hang test\n * runners until it fires.\n *\n * In the browser `setTimeout` returns a number with no `unref`, so this is a\n * no-op there. Callers should still `clearTimeout` the handle once the work it\n * guards has settled.\n */\nexport function unrefTimer(timer: ReturnType<typeof setTimeout>): void {\n  const handle = timer as { unref?: () => void }\n  if (typeof handle.unref === \"function\") {\n    handle.unref()\n  }\n}\n","/**\n * Shared payload finalization for the framework tracing handlers.\n *\n * The OpenAI-Agents, LangGraph, and Claude Agent SDK handlers each build an\n * external span/trace payload that must be made JSON-safe before it is sent.\n *\n * Doing that silently with `toJsonSafe` hides a lossy capture. These helpers do\n * it in one place: sanitize via `toJsonSafeReport` and, when a value could only\n * be captured as a placeholder, mark the span (a `serialization_degraded`\n * error) or warn for the trace, so a degraded capture is surfaced as\n * non-replayable instead of being shipped silently. The HTTP boundary stays as\n * the final net. Mirrors the Python SDK's `processor_payload.py`.\n *\n * Note: this is only wired into the `toJsonSafe`-based framework surfaces. Core\n * `withSpan` / `@span` spans serialize via `serializeValue` (superjson, which\n * preserves the `meta` needed for typed replay); running this report serializer\n * there would strip that metadata, so the core path keeps its existing\n * http-layer sanitizer instead.\n */\n\nimport { toJsonSafeReport } from \"./serialize.js\"\nimport { warnOnce } from \"./warnOnce.js\"\n\nexport const SERIALIZATION_DEGRADED_STEP = \"serialization_degraded\"\n\ninterface DegradedError {\n  source: \"sdk\"\n  step: string\n  error: string\n}\n\nfunction degradedError(dropped: string[]): DegradedError {\n  const names = [...new Set(dropped)].sort().join(\", \")\n  return {\n    source: \"sdk\",\n    step: SERIALIZATION_DEGRADED_STEP,\n    error: `non-replayable: could not faithfully capture ${names}`,\n  }\n}\n\n// Plain control fields carried through when the whole payload collapses to a\n// placeholder. Mirror of the Python SDK's `_rebuild_envelope` (plus\n// `traceFunctionKey`, which the TS payloads also carry): without them a\n// pathological top-level value would strip the routing fields the server needs,\n// not just the body. `completed` is span-irrelevant but harmless to copy.\nconst ENVELOPE_FIELDS = [\n  \"type\",\n  \"source\",\n  \"traceFunctionKey\",\n  \"sourceTraceId\",\n  \"completed\",\n] as const\n\nfunction rebuildEnvelope(\n  payload: Record<string, unknown>,\n  bodyKey: string,\n  placeholder: unknown,\n): Record<string, unknown> {\n  const rebuilt: Record<string, unknown> = {}\n  for (const k of ENVELOPE_FIELDS) {\n    if (k in payload) {\n      rebuilt[k] = payload[k]\n    }\n  }\n  rebuilt[bodyKey] = { serialized: placeholder }\n  return rebuilt\n}\n\n/**\n * Return a JSON-safe span payload, marking a lossy capture on its errors.\n *\n * The span body is preserved (never gutted). When a value could only be\n * captured as a placeholder, a `serialization_degraded` error is appended to\n * `payload.errors` so the lossy capture is recorded rather than shipped\n * silently.\n *\n * `extraDropped` carries losses detected by an earlier sanitization pass - e.g.\n * input/output that a handler serialized at capture time to snapshot a mutable\n * value. Without it, those fields reach this point as plain placeholder strings\n * and their loss would go unreported.\n */\nexport function finalizeSpanPayload(\n  payload: Record<string, unknown>,\n  extraDropped?: string[],\n): Record<string, unknown> {\n  const { safe, dropped } = toJsonSafeReport(payload)\n  const allDropped = [...(extraDropped ?? []), ...dropped]\n\n  // toJsonSafeReport collapses to a non-object only for a pathological\n  // top-level value; rebuild an envelope (carrying control fields) so the span\n  // still ships and stays routable.\n  const collapsed =\n    safe === null || typeof safe !== \"object\" || Array.isArray(safe)\n  const result: Record<string, unknown> = collapsed\n    ? rebuildEnvelope(payload, \"rawSpan\", safe)\n    : (safe as Record<string, unknown>)\n\n  if (allDropped.length > 0) {\n    const existing = result.errors\n    const errors = Array.isArray(existing) ? existing : []\n    errors.push(degradedError(allDropped))\n    result.errors = errors\n  }\n  return result\n}\n\n/**\n * Return a JSON-safe trace payload, warning when the capture was lossy.\n *\n * The trace is preserved (never dropped). A trace payload has no errors field,\n * so a lossy capture is surfaced via `warnOnce` instead.\n */\nexport function finalizeTracePayload(\n  payload: Record<string, unknown>,\n): Record<string, unknown> {\n  const { safe, dropped } = toJsonSafeReport(payload)\n  const collapsed =\n    safe === null || typeof safe !== \"object\" || Array.isArray(safe)\n  const result: Record<string, unknown> = collapsed\n    ? rebuildEnvelope(payload, \"externalTrace\", safe)\n    : (safe as Record<string, unknown>)\n\n  if (dropped.length > 0 || collapsed) {\n    const names =\n      dropped.length > 0 ? [...new Set(dropped)].sort().join(\", \") : \"trace\"\n    warnOnce(\n      `finalizeTrace:${names.replace(/\\d+/g, \"N\")}`,\n      `a trace held non-serializable value(s) (${names}); they were captured as placeholders, so the trace may not be replayable.`,\n    )\n  }\n  return result\n}\n","/**\n * Claude Agent SDK handler for Bitfab tracing.\n *\n * Hooks into the Claude Agent SDK's lifecycle to capture LLM turns,\n * tool invocations, and subagent execution as Bitfab spans.\n *\n * Uses two integration surfaces:\n *   1. SDK hooks (PreToolUse, PostToolUse, etc.) for tool/subagent lifecycle\n *   2. Stream wrapping for LLM turn capture from the message stream\n */\n\nimport { DEFAULT_SERVICE_URL } from \"./constants.js\"\nimport { type ApiKeyInput, HttpClient } from \"./http.js\"\nimport {\n  finalizeSpanPayload,\n  finalizeTracePayload,\n} from \"./processorPayload.js\"\nimport { randomUuid } from \"./randomUuid.js\"\nimport { toJsonSafe, toJsonSafeReport } from \"./serialize.js\"\n\nexport interface ActiveSpanContext {\n  traceId: string\n  spanId: string\n}\n\ninterface SpanInfo {\n  spanId: string\n  traceId: string\n  parentId: string | null\n  startedAt: string\n  endedAt?: string\n  name: string\n  type: string\n  input?: unknown\n  output?: unknown\n  error?: string\n  contexts: Array<Record<string, unknown>>\n  // Type names of input/output values that could only be captured as\n  // placeholders (serialized at capture time to snapshot a mutable value).\n  // Carried to the send boundary so finalizeSpanPayload can mark the span.\n  dropped?: string[]\n}\n\nfunction nowIso(): string {\n  return new Date().toISOString()\n}\n\n// Delegates to the shared toJsonSafe so the recurse-the-dump logic lives in\n// exactly one place (see serialize.ts).\nconst safeSerialize = toJsonSafe\n\nfunction extractContentBlocks(\n  content: unknown,\n): Array<Record<string, unknown>> {\n  if (!Array.isArray(content)) {\n    return []\n  }\n  return content.map((block) => safeSerialize(block) as Record<string, unknown>)\n}\n\nfunction asTokenCount(val: unknown): number | null {\n  return typeof val === \"number\" && Number.isFinite(val) ? val : null\n}\n\nfunction extractUsage(\n  message: Record<string, unknown>,\n): Record<string, unknown> {\n  const usageInfo: Record<string, unknown> = {}\n  const usage = message.usage as Record<string, unknown> | undefined\n  if (!usage) {\n    return usageInfo\n  }\n\n  // Anthropic reports `input_tokens` as the NON-cached prompt tokens, with\n  // cache reads and cache writes counted separately. Bitfab's `inputTokens`\n  // is the full prompt size (matching the LangGraph integration), so fold the\n  // cache buckets in. `cacheReadTokens` stays the cached SUBSET, which the read\n  // side uses to back out the uncached portion (`?tokenType=uncached`).\n  const baseInput = asTokenCount(usage.input_tokens)\n  const cacheRead = asTokenCount(usage.cache_read_input_tokens)\n  const cacheCreation = asTokenCount(usage.cache_creation_input_tokens)\n  if (baseInput !== null || cacheRead !== null || cacheCreation !== null) {\n    usageInfo.inputTokens =\n      (baseInput ?? 0) + (cacheRead ?? 0) + (cacheCreation ?? 0)\n  }\n\n  const output = asTokenCount(usage.output_tokens)\n  if (output !== null) {\n    usageInfo.outputTokens = output\n  }\n  if (cacheRead !== null) {\n    usageInfo.cacheReadTokens = cacheRead\n  }\n  if (cacheCreation !== null) {\n    usageInfo.cacheCreationTokens = cacheCreation\n  }\n\n  return usageInfo\n}\n\ntype HookCallback = (\n  // biome-ignore lint/suspicious/noExplicitAny: Hook callback signatures from Claude Agent SDK use untyped dicts\n  inputData: Record<string, any>,\n  toolUseId: string | null,\n  context: unknown,\n) => Promise<Record<string, unknown>>\n\n/**\n * Claude Agent SDK handler that sends traces to Bitfab.\n *\n * Captures LLM turns, tool invocations, and subagent execution as\n * Bitfab spans with proper parent-child hierarchy.\n *\n * The TypeScript Claude Agent SDK exposes a single `query()` entry point (there\n * is no `ClaudeSDKClient` class - that exists only in the Python SDK). Wrap the\n * `query()` async iterator with `wrapQuery`; tool and subagent spans come from\n * the hooks injected by `instrumentOptions`.\n *\n * ```typescript\n * import { Bitfab } from \"@bitfab/sdk\";\n * import { query } from \"@anthropic-ai/claude-agent-sdk\";\n *\n * const bitfab = new Bitfab({ apiKey: \"...\" });\n * const handler = bitfab.getClaudeAgentHandler(\"my-agent\");\n *\n * const options = handler.instrumentOptions({\n *   model: \"claude-sonnet-4-5-...\",\n * });\n *\n * for await (const message of handler.wrapQuery(\n *   query({ prompt: \"Do something\", options })\n * )) {\n *   // process messages normally\n * }\n * ```\n */\nexport class BitfabClaudeAgentHandler {\n  private readonly httpClient: HttpClient\n  private readonly traceFunctionKey: string\n  private readonly getActiveSpanContext: (() => ActiveSpanContext | null) | null\n\n  // Span tracking\n  private runToSpan: Map<string, SpanInfo> = new Map()\n  private traceId: string | null = null\n  private rootSpanId: string | null = null\n  private activeContext: ActiveSpanContext | null = null\n  private traceStartedAt: string | null = null\n\n  // LLM turn tracking\n  private conversationHistory: Array<Record<string, unknown>> = []\n  private pendingMessages: Array<Record<string, unknown>> = []\n  private currentLlmSpanId: string | null = null\n  private currentLlmMessageId: string | null = null\n  private currentLlmContent: Array<Record<string, unknown>> = []\n  private currentLlmModel: string | null = null\n  private currentLlmUsage: Record<string, unknown> = {}\n  private currentLlmStartedAt: string | null = null\n  private currentLlmHistorySnapshot: Array<Record<string, unknown>> = []\n\n  // Subagent tracking\n  private activeSubagentSpans: Map<string, string> = new Map()\n\n  // Synthetic root span (handler-only replay). When an `input` is supplied to\n  // wrapQuery/wrapResponse, the handler emits a root `agent` span carrying that\n  // input, so a handler-instrumented run is replayable WITHOUT an enclosing\n  // withSpan - matching the LangGraph handler, which records the graph input as\n  // its root. The prompt is not present anywhere in the message stream, so it\n  // must be handed in explicitly.\n  private hasRootInput = false\n  private rootInput: unknown\n  private rootOutput: unknown\n\n  constructor(config: {\n    apiKey?: ApiKeyInput\n    traceFunctionKey: string\n    serviceUrl?: string\n    timeout?: number\n    getActiveSpanContext?: () => ActiveSpanContext | null\n  }) {\n    this.httpClient = new HttpClient({\n      apiKey: config.apiKey,\n      serviceUrl: config.serviceUrl ?? DEFAULT_SERVICE_URL,\n      timeout: config.timeout ?? 10000,\n    })\n    this.traceFunctionKey = config.traceFunctionKey\n    this.getActiveSpanContext = config.getActiveSpanContext ?? null\n\n    // Bind hook callbacks so they can be passed as standalone functions\n    this.preToolUseHook = this.preToolUseHook.bind(this)\n    this.postToolUseHook = this.postToolUseHook.bind(this)\n    this.postToolUseFailureHook = this.postToolUseFailureHook.bind(this)\n    this.subagentStartHook = this.subagentStartHook.bind(this)\n    this.subagentStopHook = this.subagentStopHook.bind(this)\n  }\n\n  // ── trace lifecycle ──────────────────────────────────────────\n\n  private ensureTrace(): string {\n    if (this.traceId !== null) {\n      return this.traceId\n    }\n\n    this.activeContext = this.getActiveSpanContext?.() ?? null\n\n    if (this.activeContext) {\n      this.traceId = this.activeContext.traceId\n    } else {\n      this.traceId = randomUuid()\n    }\n\n    this.traceStartedAt = nowIso()\n    return this.traceId\n  }\n\n  private getParentId(agentId?: string): string | null {\n    if (agentId) {\n      const subagentSpanId = this.activeSubagentSpans.get(agentId)\n      if (subagentSpanId) {\n        return subagentSpanId\n      }\n    }\n    // Prefer the synthetic root (handler-only mode) so every span nests under\n    // it; fall back to the enclosing withSpan context. The two are never both\n    // set - the synthetic root is only created when there is no active context.\n    return this.rootSpanId ?? this.activeContext?.spanId ?? null\n  }\n\n  // Emit the synthetic root `agent` span once, before any child spans. No-op\n  // unless an `input` was supplied AND there is no enclosing withSpan (in which\n  // case that outer span is already the replayable root).\n  private maybeStartRootSpan(): void {\n    if (!this.hasRootInput || this.rootSpanId !== null) {\n      return\n    }\n    this.ensureTrace()\n    if (this.activeContext !== null) {\n      return\n    }\n    const spanId = randomUuid()\n    this.startSpan(spanId, this.traceFunctionKey, \"agent\", this.rootInput, null)\n    this.rootSpanId = spanId\n  }\n\n  private completeRootSpan(): void {\n    if (this.rootSpanId === null) {\n      return\n    }\n    const spanId = this.rootSpanId\n    this.rootSpanId = null\n    this.completeSpan(spanId, this.rootOutput)\n  }\n\n  // ── span helpers ─────────────────────────────────────────────\n\n  private startSpan(\n    spanId: string,\n    name: string,\n    spanType: string,\n    inputData?: unknown,\n    parentId?: string | null,\n  ): SpanInfo {\n    const traceId = this.ensureTrace()\n\n    // Serialize input now to snapshot it (tool input can mutate between\n    // PreToolUse and PostToolUse), but keep the report so a lossy input is\n    // still marked non-replayable at the send boundary.\n    const { safe: safeInput, dropped: inputDropped } =\n      toJsonSafeReport(inputData)\n\n    const spanInfo: SpanInfo = {\n      spanId,\n      traceId,\n      parentId: parentId ?? null,\n      startedAt: nowIso(),\n      name,\n      type: spanType,\n      input: safeInput,\n      contexts: [],\n    }\n    if (inputDropped.length > 0) {\n      spanInfo.dropped = [...inputDropped]\n    }\n    this.runToSpan.set(spanId, spanInfo)\n    return spanInfo\n  }\n\n  private completeSpan(\n    spanId: string,\n    output?: unknown,\n    error?: string,\n    extraContexts?: Record<string, unknown>,\n  ): void {\n    const spanInfo = this.runToSpan.get(spanId)\n    if (!spanInfo) {\n      return\n    }\n    this.runToSpan.delete(spanId)\n\n    spanInfo.endedAt = nowIso()\n    const { safe: safeOutput, dropped: outputDropped } =\n      toJsonSafeReport(output)\n    spanInfo.output = safeOutput\n    if (outputDropped.length > 0) {\n      spanInfo.dropped = [...(spanInfo.dropped ?? []), ...outputDropped]\n    }\n    if (error !== undefined) {\n      spanInfo.error = error\n    }\n\n    if (extraContexts) {\n      spanInfo.contexts.push(extraContexts)\n    }\n\n    this.sendSpan(spanInfo)\n  }\n\n  private sendSpan(spanInfo: SpanInfo): void {\n    const spanData: Record<string, unknown> = {\n      name: spanInfo.name,\n      type: spanInfo.type,\n    }\n    if (spanInfo.input !== undefined) {\n      spanData.input = spanInfo.input\n    }\n    if (spanInfo.output !== undefined) {\n      spanData.output = spanInfo.output\n    }\n    if (spanInfo.error !== undefined) {\n      spanData.error = spanInfo.error\n    }\n    if (spanInfo.contexts.length > 0) {\n      spanData.contexts = spanInfo.contexts\n    }\n\n    const rawSpan: Record<string, unknown> = {\n      id: spanInfo.spanId,\n      trace_id: spanInfo.traceId,\n      started_at: spanInfo.startedAt,\n      ended_at: spanInfo.endedAt ?? nowIso(),\n      span_data: spanData,\n    }\n    if (spanInfo.parentId !== null) {\n      rawSpan.parent_id = spanInfo.parentId\n    }\n\n    const payload: Record<string, unknown> = {\n      type: \"sdk-function\",\n      source: \"typescript-sdk-claude-agent-sdk\",\n      traceFunctionKey: this.traceFunctionKey,\n      sourceTraceId: spanInfo.traceId,\n      rawSpan,\n    }\n\n    // Sanitize the whole span (a non-serializable value in any field is\n    // dumped/stubbed, a lossy capture is marked) instead of shipping it raw.\n    // spanInfo.dropped carries losses from the capture-time input/output\n    // snapshot above.\n    const finalized = finalizeSpanPayload(payload, spanInfo.dropped)\n\n    try {\n      this.httpClient.sendExternalSpan(finalized)\n    } catch {\n      // Silently ignore - never crash the host app\n    }\n  }\n\n  private sendTraceCompletion(\n    endedAt?: string,\n    metadata?: Record<string, unknown>,\n  ): void {\n    if (this.traceId === null) {\n      return\n    }\n\n    const completed = this.activeContext === null\n    const traceId = this.traceId\n\n    // Mark as sent so the finally block doesn't re-send\n    this.traceId = null\n\n    const externalTrace: Record<string, unknown> = {\n      id: traceId,\n      started_at: this.traceStartedAt ?? nowIso(),\n      ended_at: endedAt ?? nowIso(),\n      workflow_name: this.traceFunctionKey,\n    }\n\n    if (metadata) {\n      externalTrace.metadata = metadata\n    }\n\n    const traceData: Record<string, unknown> = {\n      type: \"sdk-function\",\n      source: \"typescript-sdk-claude-agent-sdk\",\n      traceFunctionKey: this.traceFunctionKey,\n      externalTrace,\n      completed,\n    }\n\n    // Sanitize the whole trace (warning when the capture was lossy) instead of\n    // shipping it raw and risking a wire-side JSON.stringify failure.\n    const finalized = finalizeTracePayload(traceData)\n\n    try {\n      this.httpClient.sendExternalTrace(finalized)\n    } catch {\n      // Silently ignore - never crash the host app\n    }\n  }\n\n  // ── hook callbacks ───────────────────────────────────────────\n\n  private async preToolUseHook(\n    // biome-ignore lint/suspicious/noExplicitAny: Hook input from Claude Agent SDK is untyped\n    inputData: Record<string, any>,\n    toolUseId: string | null,\n    _context: unknown,\n  ): Promise<Record<string, unknown>> {\n    try {\n      const sid = (inputData.tool_use_id as string) ?? toolUseId ?? randomUuid()\n      const toolName = (inputData.tool_name as string) ?? \"tool\"\n      const toolInput = inputData.tool_input ?? {}\n      const agentId = inputData.agent_id as string | undefined\n      const parentId = this.getParentId(agentId)\n\n      this.startSpan(sid, toolName, \"function\", toolInput, parentId)\n    } catch {\n      // Never crash the host app\n    }\n    return {}\n  }\n\n  private async postToolUseHook(\n    // biome-ignore lint/suspicious/noExplicitAny: Hook input from Claude Agent SDK is untyped\n    inputData: Record<string, any>,\n    toolUseId: string | null,\n    _context: unknown,\n  ): Promise<Record<string, unknown>> {\n    try {\n      const sid = (inputData.tool_use_id as string) ?? toolUseId ?? \"\"\n      const toolResponse = inputData.tool_response\n      this.completeSpan(sid, toolResponse)\n    } catch {\n      // Never crash the host app\n    }\n    return {}\n  }\n\n  private async postToolUseFailureHook(\n    // biome-ignore lint/suspicious/noExplicitAny: Hook input from Claude Agent SDK is untyped\n    inputData: Record<string, any>,\n    toolUseId: string | null,\n    _context: unknown,\n  ): Promise<Record<string, unknown>> {\n    try {\n      const sid = (inputData.tool_use_id as string) ?? toolUseId ?? \"\"\n      const error = String(inputData.error ?? \"Unknown error\")\n      this.completeSpan(sid, undefined, error)\n    } catch {\n      // Never crash the host app\n    }\n    return {}\n  }\n\n  private async subagentStartHook(\n    // biome-ignore lint/suspicious/noExplicitAny: Hook input from Claude Agent SDK is untyped\n    inputData: Record<string, any>,\n    _toolUseId: string | null,\n    _context: unknown,\n  ): Promise<Record<string, unknown>> {\n    try {\n      const agentId = (inputData.agent_id as string) ?? randomUuid()\n      const agentType = (inputData.agent_type as string) ?? \"subagent\"\n      const parentId = this.getParentId()\n\n      const spanId = randomUuid()\n      this.activeSubagentSpans.set(agentId, spanId)\n\n      this.startSpan(\n        spanId,\n        `Agent: ${agentType}`,\n        \"agent\",\n        undefined,\n        parentId,\n      )\n    } catch {\n      // Never crash the host app\n    }\n    return {}\n  }\n\n  private async subagentStopHook(\n    // biome-ignore lint/suspicious/noExplicitAny: Hook input from Claude Agent SDK is untyped\n    inputData: Record<string, any>,\n    _toolUseId: string | null,\n    _context: unknown,\n  ): Promise<Record<string, unknown>> {\n    try {\n      const agentId = (inputData.agent_id as string) ?? \"\"\n      const spanId = this.activeSubagentSpans.get(agentId)\n      if (spanId) {\n        this.activeSubagentSpans.delete(agentId)\n        this.completeSpan(spanId)\n      }\n    } catch {\n      // Never crash the host app\n    }\n    return {}\n  }\n\n  // ── public API ───────────────────────────────────────────────\n\n  /**\n   * Inject Bitfab tracing hooks into Claude Agent SDK options.\n   *\n   * Modifies the options object and returns it for convenience.\n   * The SDK's `HookMatcher` is constructed as a plain object\n   * (`{ matcher: null, hooks: [callback] }`) to avoid requiring\n   * `@anthropic-ai/claude-agent-sdk` as a dependency.\n   *\n   * @param options - Options object with a `hooks` property\n   * @returns The modified options object with Bitfab hooks injected\n   */\n  instrumentOptions<T extends Record<string, unknown>>(options: T): T {\n    type HookEntry = { matcher: null; hooks: HookCallback[] }\n    type HooksDict = Record<string, HookEntry[]>\n\n    const hooks: HooksDict = (options.hooks as HooksDict) ?? {}\n    if (!options.hooks) {\n      ;(options as Record<string, unknown>).hooks = hooks\n    }\n\n    const hookConfig: Array<[string, HookCallback]> = [\n      [\"PreToolUse\", this.preToolUseHook],\n      [\"PostToolUse\", this.postToolUseHook],\n      [\"PostToolUseFailure\", this.postToolUseFailureHook],\n      [\"SubagentStart\", this.subagentStartHook],\n      [\"SubagentStop\", this.subagentStopHook],\n    ]\n\n    for (const [event, callback] of hookConfig) {\n      if (!hooks[event]) {\n        hooks[event] = []\n      }\n      hooks[event].push({ matcher: null, hooks: [callback] })\n    }\n\n    return options\n  }\n\n  /**\n   * Wrap any Claude Agent SDK message stream to capture LLM turns.\n   *\n   * Yields every message unchanged while capturing assistant message\n   * content as LLM turn spans. Kept for naming symmetry with the Python\n   * SDK's `wrapResponse` (which wraps `ClaudeSDKClient.receiveResponse()`);\n   * in TypeScript, prefer `wrapQuery` around `query()`.\n   *\n   * Pass `{ input }` (the prompt) to record a replayable root span - see\n   * `wrapQuery`.\n   */\n  async *wrapResponse(\n    stream: AsyncIterable<unknown>,\n    opts?: { input?: unknown },\n  ): AsyncIterable<unknown> {\n    this.setRootInput(opts)\n    yield* this.processStream(stream)\n  }\n\n  /**\n   * Wrap a `query()` async iterator to capture LLM turns.\n   *\n   * Tool and subagent spans are captured separately via the hooks injected\n   * by `instrumentOptions` into the `options` passed to `query()`.\n   *\n   * Pass `{ input }` - the prompt (or the serializable args that produced it)\n   * - to make a handler-only run replayable: the handler records a root `agent`\n   * span with that input, so `replay(key, fn)` can re-feed it. Omit it only\n   * when an enclosing `withSpan` already supplies the replayable root.\n   *\n   * ```typescript\n   * handler.wrapQuery(query({ prompt, options }), { input: prompt })\n   * ```\n   */\n  async *wrapQuery(\n    stream: AsyncIterable<unknown>,\n    opts?: { input?: unknown },\n  ): AsyncIterable<unknown> {\n    this.setRootInput(opts)\n    yield* this.processStream(stream)\n  }\n\n  private setRootInput(opts?: { input?: unknown }): void {\n    // Set deterministically on every wrap call so a prior call's input can\n    // never leak into a later input-less run on a reused handler (e.g. if the\n    // earlier stream's iterator was abandoned mid-iteration, so resetState\n    // never ran).\n    if (opts && opts.input !== undefined) {\n      this.hasRootInput = true\n      this.rootInput = opts.input\n    } else {\n      this.hasRootInput = false\n      this.rootInput = undefined\n    }\n    this.rootOutput = undefined\n  }\n\n  // ── stream processing ────────────────────────────────────────\n\n  private async *processStream(\n    stream: AsyncIterable<unknown>,\n  ): AsyncIterable<unknown> {\n    try {\n      this.maybeStartRootSpan()\n      for await (const message of stream) {\n        try {\n          this.processMessage(message as Record<string, unknown>)\n        } catch {\n          // Never crash the host app\n        }\n        yield message\n      }\n    } finally {\n      try {\n        this.flushLlmTurn()\n        this.completeRootSpan()\n        this.sendTraceCompletion()\n      } catch {\n        // Never crash the host app\n      }\n      this.resetState()\n    }\n  }\n\n  private processMessage(message: Record<string, unknown>): void {\n    // The TypeScript Claude Agent SDK streams plain wire objects discriminated\n    // by a `type` field (`{ type: \"assistant\", message: <BetaMessage>, ... }`),\n    // NOT class instances. (The Python SDK, by contrast, yields AssistantMessage\n    // / UserMessage / ResultMessage dataclasses - hence the different field\n    // access here vs. claude_agent_sdk.py.) Routing on `constructor.name` would\n    // always see \"Object\" and silently capture nothing.\n    const typeName = message.type\n\n    if (typeName === \"assistant\") {\n      this.handleAssistantMessage(message)\n    } else if (typeName === \"user\") {\n      this.handleUserMessage(message)\n    } else if (typeName === \"result\") {\n      this.handleResultMessage(message)\n    }\n  }\n\n  private handleAssistantMessage(message: Record<string, unknown>): void {\n    this.ensureTrace()\n\n    // Content, model, id, and usage live on the nested BetaMessage, not the\n    // top-level SDK wire wrapper.\n    const inner = (message.message as Record<string, unknown> | undefined) ?? {}\n\n    const messageId =\n      (inner.id as string | undefined) ?? (message.uuid as string | undefined)\n\n    if (messageId !== this.currentLlmMessageId) {\n      this.flushLlmTurn()\n\n      // Drain pending user/tool messages into history before snapshot\n      this.conversationHistory.push(...this.pendingMessages)\n      this.pendingMessages = []\n\n      this.currentLlmSpanId = randomUuid()\n      this.currentLlmMessageId = messageId ?? null\n      this.currentLlmContent = []\n      this.currentLlmModel = (inner.model as string) ?? null\n      this.currentLlmUsage = {}\n      this.currentLlmStartedAt = nowIso()\n      this.currentLlmHistorySnapshot = [...this.conversationHistory]\n    }\n\n    const content = inner.content\n    if (Array.isArray(content)) {\n      this.currentLlmContent.push(...extractContentBlocks(content))\n    }\n\n    const usage = extractUsage(inner)\n    if (Object.keys(usage).length > 0) {\n      Object.assign(this.currentLlmUsage, usage)\n    }\n\n    const model = inner.model as string | undefined\n    if (model) {\n      this.currentLlmModel = model\n    }\n  }\n\n  private handleUserMessage(message: Record<string, unknown>): void {\n    // User content lives on the nested MessageParam; tool_use_result is a\n    // top-level field on the SDK wire wrapper.\n    const inner = (message.message as Record<string, unknown> | undefined) ?? {}\n    const content = inner.content\n    const toolUseResult = message.tool_use_result\n\n    if (toolUseResult !== undefined) {\n      this.pendingMessages.push({\n        role: \"tool\",\n        content: safeSerialize(content),\n        tool_result: safeSerialize(toolUseResult),\n      })\n    } else {\n      this.pendingMessages.push({\n        role: \"user\",\n        content: safeSerialize(content),\n      })\n    }\n  }\n\n  private handleResultMessage(message: Record<string, unknown>): void {\n    this.flushLlmTurn()\n\n    // The final result text is the synthetic root span's output.\n    if (message.result !== undefined) {\n      this.rootOutput = message.result\n    }\n    this.completeRootSpan()\n\n    const metadata: Record<string, unknown> = {}\n    for (const attr of [\n      \"num_turns\",\n      \"total_cost_usd\",\n      \"duration_ms\",\n      \"duration_api_ms\",\n      \"session_id\",\n    ]) {\n      const val = message[attr]\n      if (val !== undefined && val !== null) {\n        metadata[attr] = val\n      }\n    }\n\n    const usage = message.usage\n    if (usage && typeof usage === \"object\") {\n      metadata.usage = safeSerialize(usage)\n    }\n\n    this.sendTraceCompletion(\n      undefined,\n      Object.keys(metadata).length > 0 ? metadata : undefined,\n    )\n  }\n\n  private flushLlmTurn(): void {\n    if (this.currentLlmSpanId === null) {\n      return\n    }\n\n    const spanId = this.currentLlmSpanId\n    const traceId = this.ensureTrace()\n    const parentId = this.getParentId()\n\n    const llmContext: Record<string, unknown> = {}\n    if (this.currentLlmModel) {\n      llmContext.model = this.currentLlmModel\n    }\n    Object.assign(llmContext, this.currentLlmUsage)\n\n    const spanInfo: SpanInfo = {\n      spanId,\n      traceId,\n      parentId,\n      startedAt: this.currentLlmStartedAt ?? nowIso(),\n      endedAt: nowIso(),\n      name: this.currentLlmModel ?? \"llm\",\n      type: \"llm\",\n      input: this.currentLlmHistorySnapshot,\n      output: this.currentLlmContent,\n      contexts: Object.keys(llmContext).length > 0 ? [llmContext] : [],\n    }\n\n    this.sendSpan(spanInfo)\n\n    this.conversationHistory.push({\n      role: \"assistant\",\n      content: this.currentLlmContent,\n    })\n\n    this.currentLlmSpanId = null\n    this.currentLlmMessageId = null\n    this.currentLlmContent = []\n    this.currentLlmModel = null\n    this.currentLlmUsage = {}\n    this.currentLlmStartedAt = null\n    this.currentLlmHistorySnapshot = []\n  }\n\n  private resetState(): void {\n    this.runToSpan.clear()\n    this.traceId = null\n    this.rootSpanId = null\n    this.hasRootInput = false\n    this.rootInput = undefined\n    this.rootOutput = undefined\n    this.activeContext = null\n    this.traceStartedAt = null\n    this.conversationHistory = []\n    this.pendingMessages = []\n    this.currentLlmSpanId = null\n    this.currentLlmMessageId = null\n    this.currentLlmContent = []\n    this.currentLlmModel = null\n    this.currentLlmUsage = {}\n    this.currentLlmStartedAt = null\n    this.currentLlmHistorySnapshot = []\n    this.activeSubagentSpans.clear()\n  }\n}\n","/**\n * Bitfab client for provider-based API calls.\n */\n\nimport {\n  type AsyncLocalStorageLike,\n  asyncStorageReady,\n  createAsyncLocalStorage,\n  isAsyncStorageInitDone,\n} from \"./asyncStorage.js\"\nimport {\n  type AllowedEnvVars,\n  type ProviderDefinition,\n  runFunctionWithBaml,\n} from \"./baml.js\"\nimport { BitfabClaudeAgentHandler } from \"./claudeAgentSdk.js\"\nimport { DEFAULT_SERVICE_URL } from \"./constants.js\"\nimport type { DbSnapshotConfig, DbSnapshotRef } from \"./dbSnapshot.js\"\nimport { buildSnapshotRef, validateDbSnapshotConfig } from \"./dbSnapshot.js\"\nimport { BitfabError, HttpClient } from \"./http.js\"\nimport { BitfabLangGraphCallbackHandler } from \"./langgraph.js\"\nimport { BitfabOpenAIAgentHandler } from \"./openaiAgentSdk.js\"\nimport { importOptionalPeer } from \"./optionalPeer.js\"\nimport { randomUuid } from \"./randomUuid.js\"\nimport type { ReplayOptions, ReplayResult } from \"./replay.js\"\nimport { getReplayContext } from \"./replayContext.js\"\nimport { ReplayEnvironment } from \"./replayEnvironment.js\"\nimport { deserializeValue, serializeValue } from \"./serialize.js\"\nimport { BitfabOpenAITracingProcessor } from \"./tracing.js\"\nimport { unrefTimer } from \"./unrefTimer.js\"\nimport { BitfabVercelAiHandler } from \"./vercelAiSdk.js\"\nimport { warnOnce } from \"./warnOnce.js\"\n\n// Context entry for addContext calls - each entry is an object with multiple key-value pairs\ntype ContextEntry = Record<string, unknown>\n\n// Trace state for tracking trace-level data\ninterface TraceState {\n  traceId: string\n  sessionId?: string\n  metadata?: Record<string, unknown>\n  contexts: ContextEntry[]\n  startedAt: string\n  testRunId?: string\n  inputSourceTraceId?: string\n  dbSnapshotRef?: DbSnapshotRef\n  // Set by getCurrentTrace().drop(); ridden out on trace completion so the\n  // server scrubs and marks the trace `dropped` instead of `completed`.\n  dropped?: boolean\n}\n\n// Span context for tracking nested spans\ninterface SpanContext {\n  traceId: string\n  spanId: string\n  contexts: ContextEntry[]\n  prompt?: string\n}\n\n// Global map to track active trace states\nconst activeTraceStates = new Map<string, TraceState>()\nconst pendingSpanPromises = new Map<string, Promise<unknown>[]>()\n\nlet asyncLocalStorage: AsyncLocalStorageLike<SpanContext[]> | null = null\n\nconst initializeAsyncContext = () => {\n  asyncLocalStorage ??= createAsyncLocalStorage<SpanContext[]>()\n}\n\nconst asyncLocalStorageReady: Promise<void> = asyncStorageReady.then(() => {\n  initializeAsyncContext()\n})\n\n// Browser fallback: a single module-level stack shared across all async\n// execution chains. Works correctly for synchronous nesting and sequential\n// async nesting (the common browser cases), but breaks when multiple\n// independent spans are in-flight concurrently (e.g. Promise.all with\n// separate withSpan calls). In that scenario, whichever span resumes last\n// overwrites the shared stack, so inner spans may see the wrong parent.\n//\n// Node.js avoids this via AsyncLocalStorage, which gives each async chain\n// its own isolated copy of the stack.\n//\n// Potential future fixes:\n//  - TC39 AsyncContext proposal (stage 2) would provide AsyncLocalStorage\n//    semantics natively in all JS environments, including browsers.\n//    https://github.com/tc39/proposal-async-context\n//  - Zone.js could work today but is ~50KB, monkey-patches Promise/setTimeout/\n//    fetch/etc., and can conflict with frameworks like React. Too invasive for\n//    an SDK dependency.\nlet browserSpanStack: SpanContext[] = []\n\nfunction getSpanStack(): SpanContext[] {\n  if (asyncLocalStorage) {\n    return asyncLocalStorage.getStore() ?? []\n  }\n  return browserSpanStack\n}\n\nfunction runWithSpanStack<T>(stack: SpanContext[], fn: () => T): T {\n  if (asyncLocalStorage) {\n    return asyncLocalStorage.run(stack, fn)\n  }\n  // Browser fallback: save/restore the stack around the function call.\n  // This is correct for sequential async but not for concurrent async -\n  // see the browserSpanStack comment above for details.\n  const previousStack = browserSpanStack\n  browserSpanStack = stack\n  try {\n    const result = fn()\n    if (result instanceof Promise) {\n      return result.finally(() => {\n        browserSpanStack = previousStack\n      }) as T\n    }\n    browserSpanStack = previousStack\n    return result\n  } catch (error) {\n    browserSpanStack = previousStack\n    throw error\n  }\n}\n\nfunction isAsyncGenerator(\n  value: unknown,\n): value is AsyncGenerator<unknown, unknown, unknown> {\n  if (value === null || typeof value !== \"object\") {\n    return false\n  }\n  const candidate = value as Record<PropertyKey, unknown>\n  return (\n    typeof candidate.next === \"function\" &&\n    typeof candidate.return === \"function\" &&\n    typeof candidate.throw === \"function\" &&\n    typeof candidate[Symbol.asyncIterator] === \"function\"\n  )\n}\n\n// Wrap an async generator so that:\n//   1. Each .next()/.return()/.throw() resumes the generator body inside\n//      the parent span's context, so nested withSpan calls nest correctly.\n//   2. The span is sent only after iteration completes (or errors), with\n//      the yielded values plus any final return value as the result.\n//\n// Without this, async-generator functions returned from withSpan close their\n// span synchronously when the generator object is created - before any of\n// the body has run - and every child span becomes its own root trace.\nfunction wrapAsyncGenerator<TYield, TReturn>(\n  source: AsyncGenerator<TYield, TReturn, unknown>,\n  spanStack: SpanContext[],\n  sendSpan: (params: { result: unknown; error?: string }) => Promise<void>,\n): AsyncGenerator<TYield, TReturn, unknown> {\n  const yielded: TYield[] = []\n  let returnValue: TReturn | undefined\n  let finalized = false\n\n  const finalize = (errorMsg?: string) => {\n    if (finalized) {\n      return\n    }\n    finalized = true\n    void sendSpan({\n      result: { yielded, return: returnValue },\n      ...(errorMsg && { error: errorMsg }),\n    })\n  }\n\n  const step = (\n    method: \"next\" | \"return\" | \"throw\",\n    arg: unknown,\n  ): Promise<IteratorResult<TYield, TReturn>> =>\n    runWithSpanStack(spanStack, () => {\n      const op = source[method] as (\n        a?: unknown,\n      ) => Promise<IteratorResult<TYield, TReturn>>\n      return op.call(source, arg)\n    })\n\n  const handle = async (\n    method: \"next\" | \"return\" | \"throw\",\n    arg: unknown,\n  ): Promise<IteratorResult<TYield, TReturn>> => {\n    try {\n      const result = await step(method, arg)\n      if (result.done) {\n        returnValue = result.value\n        finalize()\n      } else {\n        yielded.push(result.value)\n      }\n      return result\n    } catch (error) {\n      finalize(error instanceof Error ? error.message : String(error))\n      throw error\n    }\n  }\n\n  const wrapped = {\n    next(arg?: unknown) {\n      return handle(\"next\", arg)\n    },\n    return(value: TReturn | PromiseLike<TReturn>) {\n      return handle(\"return\", value)\n    },\n    throw(err: unknown) {\n      return handle(\"throw\", err)\n    },\n    [Symbol.asyncIterator]() {\n      return wrapped\n    },\n    [Symbol.asyncDispose]() {\n      return handle(\"return\", undefined).then(() => undefined)\n    },\n  } as AsyncGenerator<TYield, TReturn, unknown>\n\n  return wrapped\n}\n\n// --- BAML Collector support for wrapBAML ---\n\ntype CollectorConstructor = new (name: string) => unknown\n\nlet cachedCollectorClass: CollectorConstructor | null | undefined\n\n/** @internal Reset the cached Collector class - for testing only. */\nexport function _resetCollectorCache(): void {\n  cachedCollectorClass = undefined\n}\n\n/** @internal Inject a mock Collector class - for testing only. */\nexport function _setCollectorCache(cls: CollectorConstructor | null): void {\n  cachedCollectorClass = cls\n}\n\n/** @internal Count of in-flight (registered, not yet completed) trace states - for testing only. */\nexport function _activeTraceStateCount(): number {\n  return activeTraceStates.size\n}\n\nasync function loadCollectorClass(): Promise<CollectorConstructor | null> {\n  if (cachedCollectorClass !== undefined) {\n    return cachedCollectorClass\n  }\n  try {\n    // Reconstructed specifier (see importOptionalPeer): a consumer's bundler\n    // must not try to resolve `@boundaryml/baml` at build time when it is not\n    // installed (optional peer, only needed for BAML execution / collectors).\n    const baml = await importOptionalPeer<typeof import(\"@boundaryml/baml\")>([\n      \"@boundaryml\",\n      \"baml\",\n    ])\n    cachedCollectorClass = baml.Collector as CollectorConstructor\n    return cachedCollectorClass\n  } catch {\n    cachedCollectorClass = null\n    return null\n  }\n}\n\n// Typed accessors for the BAML Collector's internal structure.\n// Uses defensive access since these are untyped objects from the BAML runtime.\n\ninterface CollectorCall {\n  selected?: boolean\n  clientName?: string\n  provider?: string\n  usage?: {\n    inputTokens?: number\n    outputTokens?: number\n    cachedInputTokens?: number\n  }\n  httpRequest?: {\n    url?: string\n    body?: { json: () => Record<string, unknown> | null }\n  }\n}\n\ninterface CollectorLog {\n  calls?: CollectorCall[]\n  timing?: { durationMs?: number }\n}\n\ninterface CollectorLike {\n  last?: CollectorLog | null\n  usage?: {\n    inputTokens?: number\n    outputTokens?: number\n    cachedInputTokens?: number\n  }\n}\n\nfunction extractPromptFromCollector(collector: unknown): string | null {\n  try {\n    const c = collector as CollectorLike\n    const calls = c?.last?.calls ?? []\n    const selectedCall = calls.find((call) => call.selected) ?? calls[0]\n    if (!selectedCall?.httpRequest?.body) {\n      return null\n    }\n    const body = selectedCall.httpRequest.body.json()\n    if (!body || typeof body !== \"object\") {\n      return null\n    }\n    const messages = body.messages\n    if (!Array.isArray(messages) || messages.length === 0) {\n      return null\n    }\n    const rendered = (messages as Record<string, unknown>[])\n      .filter(\n        (msg): msg is { role: string; content: unknown } =>\n          typeof msg === \"object\" &&\n          msg !== null &&\n          \"role\" in msg &&\n          typeof (msg as { role: unknown }).role === \"string\",\n      )\n      .map((msg) => ({\n        role: msg.role,\n        content:\n          typeof msg.content === \"string\"\n            ? msg.content\n            : JSON.stringify(msg.content),\n      }))\n    if (rendered.length > 0) {\n      return JSON.stringify(rendered)\n    }\n    return null\n  } catch {\n    return null\n  }\n}\n\nfunction extractContextFromCollector(\n  collector: unknown,\n): Record<string, unknown> | null {\n  try {\n    const c = collector as CollectorLike\n    const calls = c?.last?.calls ?? []\n    const selectedCall = calls.find((call) => call.selected) ?? calls[0]\n    const usage = c?.usage\n\n    const context: Record<string, unknown> = {}\n    if (selectedCall?.provider) {\n      context.provider = selectedCall.provider\n    }\n\n    // Extract model from HTTP request body (OpenAI/Anthropic) or URL (Vertex AI)\n    const body = selectedCall?.httpRequest?.body?.json()\n    if (body && typeof body === \"object\" && typeof body.model === \"string\") {\n      context.model = body.model\n    } else {\n      const url = selectedCall?.httpRequest?.url\n      if (url) {\n        const match = url.match(/\\/models\\/([^/:]+)/)\n        if (match?.[1]) {\n          context.model = match[1]\n        }\n      }\n    }\n\n    const inputTokens =\n      usage?.inputTokens ?? selectedCall?.usage?.inputTokens ?? null\n    const outputTokens =\n      usage?.outputTokens ?? selectedCall?.usage?.outputTokens ?? null\n    if (inputTokens !== null) {\n      context.inputTokens = inputTokens\n    }\n    if (outputTokens !== null) {\n      context.outputTokens = outputTokens\n    }\n\n    const durationMs = c?.last?.timing?.durationMs ?? null\n    if (durationMs !== null) {\n      context.durationMs = durationMs\n    }\n\n    return Object.keys(context).length > 0 ? context : null\n  } catch {\n    return null\n  }\n}\n\n/**\n * Options for wrapBAML.\n */\nexport interface WrapBAMLOptions {\n  /** Called after each BAML invocation with the Collector instance. */\n  onCollector?: (collector: unknown) => void\n}\n\n/**\n * A function returned by wrapBAML that exposes the BAML collector from the last call.\n */\nexport interface WrappedBamlFn<TArgs extends unknown[], TReturn> {\n  (...args: TArgs): Promise<TReturn>\n  /** The BAML Collector instance from the most recent call. `null` before the first call or if @boundaryml/baml is unavailable. */\n  collector: unknown | null\n}\n\n/**\n * A handle to the current active span, allowing context to be added.\n */\nexport interface CurrentSpan {\n  /** The trace ID for the current span. */\n  readonly traceId: string\n  /**\n   * Add a context entry to this span. Each call appends to the contexts array.\n   * Context entries are stored in span_data.contexts as [{key, value}, ...].\n   */\n  addContext(context: Record<string, unknown>): void\n  /**\n   * Set the prompt for this span. Stored in span_data.prompt.\n   * Calling multiple times overwrites the previous value.\n   */\n  setPrompt(prompt: string): void\n}\n\n/**\n * A detached handle to a previously-created trace, looked up by its\n * caller-supplied id (the same id passed when the trace was started).\n *\n * Unlike `getCurrentTrace()`, this handle is not tied to AsyncLocalStorage -\n * each method sends to the server immediately. Useful for adding context\n * to a trace from a different process, request, or thread (e.g. a forked\n * agent that wants to annotate the original conversation's trace).\n */\nexport interface DetachedTrace {\n  /** The caller-supplied trace id this handle resolves. */\n  readonly traceId: string\n  /**\n   * Append a context entry to this trace. Each call adds one entry to the\n   * server-side contexts array; existing entries are preserved.\n   *\n   * Returns a promise that the caller may await for confirmation, or ignore\n   * to fire-and-forget. The pending request is tracked so `flushTraces()`\n   * waits for it.\n   */\n  addContext(context: Record<string, unknown>): Promise<unknown>\n  /**\n   * Merge metadata into this trace. Server-side shallow-merges the new keys\n   * into the existing metadata object; existing keys are preserved unless\n   * overwritten by the new values.\n   */\n  setMetadata(metadata: Record<string, unknown>): Promise<unknown>\n  /**\n   * Set the sessionId for this trace. Replaces any existing sessionId.\n   */\n  setSessionId(sessionId: string): Promise<unknown>\n}\n\nconst TRACE_ID_PATTERN = /^[a-zA-Z0-9_\\-.:]+$/\nconst TRACE_ID_MAX_LENGTH = 256\n\nfunction validateTraceId(traceId: string): void {\n  if (typeof traceId !== \"string\" || traceId.length === 0) {\n    throw new BitfabError(\"traceId is required and must be a non-empty string\")\n  }\n  if (traceId.length > TRACE_ID_MAX_LENGTH) {\n    throw new BitfabError(\n      `traceId must be ${TRACE_ID_MAX_LENGTH} characters or fewer`,\n    )\n  }\n  if (!TRACE_ID_PATTERN.test(traceId)) {\n    throw new BitfabError(\n      `traceId may only contain letters, digits, \"_\", \"-\", \".\", \":\"`,\n    )\n  }\n}\n\n/**\n * A handle to the current active trace, allowing trace-level context to be set.\n */\nexport interface CurrentTrace {\n  /**\n   * Set the session ID for this trace. Stored in the database session_id column.\n   */\n  setSessionId(sessionId: string): void\n  /**\n   * Set metadata for this trace. Stored in rawData.metadata.\n   * Subsequent calls merge with existing metadata, with later values taking precedence.\n   */\n  setMetadata(metadata: Record<string, unknown>): void\n  /**\n   * Add a context entry to this trace. Each call appends to the contexts array.\n   * Context entries are stored in rawData.contexts as [{key, value}, ...].\n   */\n  addContext(context: Record<string, unknown>): void\n  /**\n   * Flag this trace to be dropped. Once flagged, spans that complete afterward\n   * are not uploaded at all, and when the trace completes the server scrubs any\n   * payloads that already raced out (trace, external trace, and sibling spans),\n   * marking it `dropped` instead of `completed` and retaining only a skeleton\n   * audit record. Use this to discard runs you never want stored (e.g. health\n   * checks, or a run you know contains sensitive data). Takes effect\n   * immediately for later spans; the server-side scrub takes effect at trace\n   * completion, so a trace that is flagged but never completes is not scrubbed.\n   */\n  drop(): void\n}\n\n// No-op implementations for when called outside a span context\nconst noOpSpan: CurrentSpan = {\n  traceId: \"\",\n  addContext(): void {\n    // No-op\n  },\n  setPrompt(): void {\n    // No-op\n  },\n}\n\nconst noOpTrace: CurrentTrace = {\n  setSessionId(): void {\n    // No-op\n  },\n  setMetadata(): void {\n    // No-op\n  },\n  addContext(): void {\n    // No-op\n  },\n  drop(): void {\n    // No-op\n  },\n}\n\n/**\n * Get a handle to the current active span.\n *\n * Call this from inside a traced function (wrapped with `withSpan`) to get\n * a span handle that allows adding context at runtime.\n *\n * Returns a no-op object if called outside of a span context (methods do nothing).\n */\nexport function getCurrentSpan(): CurrentSpan {\n  const stack = getSpanStack()\n  const current = stack[stack.length - 1]\n  if (!current) {\n    return noOpSpan\n  }\n  return {\n    traceId: current.traceId,\n    addContext(context: Record<string, unknown>): void {\n      try {\n        if (typeof context !== \"object\" || context === null) {\n          return\n        }\n        // Push the entire context object as one entry\n        current.contexts.push(context)\n      } catch {\n        // Silently ignore - never crash the host app\n      }\n    },\n    setPrompt(prompt: string): void {\n      try {\n        if (typeof prompt !== \"string\") {\n          return\n        }\n        current.prompt = prompt\n      } catch {\n        // Silently ignore - never crash the host app\n      }\n    },\n  }\n}\n\n/**\n * Get a handle to the current active trace.\n *\n * Call this from inside a traced function (wrapped with `withSpan`) to get\n * a trace handle that allows setting trace-level context at runtime.\n *\n * Returns a no-op object if called outside of a span context (methods do nothing).\n */\nexport function getCurrentTrace(): CurrentTrace {\n  const stack = getSpanStack()\n  const current = stack[stack.length - 1]\n  if (!current) {\n    return noOpTrace\n  }\n\n  const traceId = current.traceId\n\n  const getOrCreateTraceState = (): TraceState => {\n    let traceState = activeTraceStates.get(traceId)\n    if (!traceState) {\n      traceState = {\n        traceId,\n        startedAt: new Date().toISOString(),\n        contexts: [],\n      }\n      activeTraceStates.set(traceId, traceState)\n    }\n    return traceState\n  }\n\n  return {\n    setSessionId(sessionId: string): void {\n      try {\n        const traceState = getOrCreateTraceState()\n        traceState.sessionId = sessionId\n      } catch {\n        // Silently ignore - never crash the host app\n      }\n    },\n    setMetadata(metadata: Record<string, unknown>): void {\n      try {\n        if (typeof metadata !== \"object\" || metadata === null) {\n          return\n        }\n        const traceState = getOrCreateTraceState()\n        traceState.metadata = { ...traceState.metadata, ...metadata }\n      } catch {\n        // Silently ignore - never crash the host app\n      }\n    },\n    addContext(context: Record<string, unknown>): void {\n      try {\n        if (typeof context !== \"object\" || context === null) {\n          return\n        }\n        const traceState = getOrCreateTraceState()\n        // Push the entire context object as one entry\n        traceState.contexts.push(context)\n      } catch {\n        // Silently ignore - never crash the host app\n      }\n    },\n    drop(): void {\n      try {\n        getOrCreateTraceState().dropped = true\n      } catch {\n        // Silently ignore - never crash the host app\n      }\n    },\n  }\n}\n\n/**\n * Read an environment variable without throwing in non-Node runtimes\n * (browsers, edge workers) where `process` is absent. The SDK ships to\n * browsers, so this must never assume `process` exists.\n */\nfunction readEnv(name: string): string | undefined {\n  if (typeof process !== \"undefined\" && process.env) {\n    return process.env[name]\n  }\n  return undefined\n}\n\nexport interface BitfabConfig {\n  /**\n   * The API key for Bitfab API authentication. Resolved lazily, the first\n   * time a span actually needs it, not at construction. When it resolves\n   * empty, tracing is disabled (a no-op, unless `strict` is set).\n   *\n   * Accepts either a string or a function returning the key. The function\n   * form is resolved at first use, so it survives the ESM trap where a shim\n   * built at module load runs before the script body's `dotenv.config()`:\n   * `apiKey: () => process.env.BITFAB_API_KEY`. When omitted (or it resolves\n   * empty), the SDK also falls back to reading `BITFAB_API_KEY` from the\n   * environment itself, again at first use.\n   */\n  apiKey?: string | (() => string | null | undefined)\n  /** The base URL for the Bitfab API (default: https://bitfab.ai) */\n  serviceUrl?: string\n  /** Request timeout in milliseconds (default: 120000) */\n  timeout?: number\n  /** Environment variables for LLM provider API keys (only OPENAI_API_KEY is supported) */\n  envVars?: AllowedEnvVars\n  /** Whether the client is enabled. Defaults to true. When false, withSpan returns the original function unwrapped. */\n  enabled?: boolean\n  /**\n   * Fail loud instead of degrading quietly. When true, the first traced call\n   * with no resolvable API key throws a `BitfabError` rather than silently\n   * disabling tracing. Off by default so a missing telemetry key never takes\n   * down the host app; turn it on in standalone scripts where a run that\n   * emits no traces is a failure you want surfaced immediately.\n   */\n  strict?: boolean\n  /** The generated BAML client instance (e.g., `b` from your baml_client). Used by wrapBAML() when no explicit client is passed. */\n  bamlClient?: unknown\n  /**\n   * Per-trace database snapshot config. When set, every root span captures\n   * a wall-clock timestamp (and, if `captureRef` is provided, a provider-\n   * specific point-in-time ref) so the trace can later be replayed against\n   * a branch materialized from that point.\n   */\n  dbSnapshot?: DbSnapshotConfig\n}\n\n/**\n * Span types matching the backend enum.\n * - llm: LLM API calls\n * - agent: Autonomous orchestrators\n * - function: Tool implementations\n * - guardrail: Safety/validation checks\n * - handoff: Agent-to-agent transfers\n * - custom: Application-specific tracing (default)\n */\nexport type SpanType =\n  | \"llm\"\n  | \"agent\"\n  | \"function\"\n  | \"guardrail\"\n  | \"handoff\"\n  | \"custom\"\n\n/**\n * Options for configuring span behavior.\n */\nexport interface SpanOptions {\n  /**\n   * The name of the span. Defaults to the function name if available,\n   * otherwise falls back to the trace function key.\n   */\n  name?: string\n  /**\n   * The type of span. Defaults to \"custom\" if not specified.\n   */\n  type?: SpanType\n  /**\n   * When true, replay will reuse this span's historical output instead of\n   * executing the wrapped function. Read by the \"marked\" replay strategy;\n   * ignored outside replay and under the \"all\"/\"none\" strategies.\n   *\n   * Use this for child spans that are expensive (paid LLM/API calls),\n   * slow, or non-deterministic - the root function still runs real code,\n   * only the marked descendants return their recorded output.\n   */\n  mockOnReplay?: boolean\n  /**\n   * Record a serializable view of a non-serializable result (e.g. a live\n   * stream object) as the span output.\n   *\n   * When set, the wrapped function's raw return value is handed back to the\n   * caller unchanged (so streaming and first-byte latency are untouched),\n   * but instead of serializing that raw value, the span records\n   * `await finalize(result)`. Use this to trace functions that return a live\n   * stream consumed by the caller (Vercel AI SDK `streamText`, a\n   * `ReadableStream`, an SSE response) while still capturing a serializable,\n   * replayable output such as `{ text, usage, toolCalls }`.\n   *\n   * Reading from a multi-consumer stream result (like the AI SDK's, which\n   * tees internally) does not disturb the caller's own consumption. For the\n   * Vercel AI SDK shape, pass the prebuilt `finalizers.aiSdk` helper.\n   *\n   * Ignored for async-generator results, which are captured automatically.\n   */\n  // biome-ignore lint/suspicious/noExplicitAny: the result type is the wrapped fn's return; SpanOptions is not generic, so callers narrow it inside finalize\n  finalize?: (result: any) => unknown | Promise<unknown>\n}\n\ninterface FunctionVersionResponse {\n  id: string\n  name: string\n  versionId: string\n  versionNumber: number | null\n  prompt: string\n  providers: ProviderDefinition[]\n}\n\n// Re-export BitfabError for backwards compatibility\nexport { BitfabError }\n\n/**\n * Client for making provider-based API calls via BAML.\n */\nexport class Bitfab {\n  /**\n   * Per-trace environment for `replay({ environment })`. Construct one,\n   * pass it to replay, and read `env.databaseUrl` inside the replayed\n   * function to pick up the per-trace branch URL.\n   */\n  static readonly ReplayEnvironment = ReplayEnvironment\n\n  private readonly apiKeyConfig:\n    | string\n    | (() => string | null | undefined)\n    | undefined\n  /** Cached only once a non-empty key is found, so an early resolve (before env loaded) can't poison a later one. */\n  private resolvedApiKey: string | undefined\n  /** Gate the empty-key warning to fire at most once. */\n  private apiKeyWarned: boolean = false\n  private readonly serviceUrl: string\n  private readonly timeout: number\n  private readonly envVars: AllowedEnvVars\n  /** The user's on/off intent. The effective enabled state ANDs this with \"a key resolved\" (see isTracingEnabled). */\n  private readonly explicitlyEnabled: boolean\n  private readonly strict: boolean\n  private readonly httpClient: HttpClient\n  private readonly bamlClient: unknown\n  private readonly dbSnapshot: DbSnapshotConfig | undefined\n\n  /**\n   * Initialize the Bitfab client.\n   *\n   * @param config - Configuration options for the client\n   */\n  constructor(config: BitfabConfig) {\n    this.apiKeyConfig = config.apiKey\n    this.serviceUrl = config.serviceUrl ?? DEFAULT_SERVICE_URL\n    this.timeout = config.timeout ?? 120000\n    this.envVars = config.envVars ?? {}\n    this.explicitlyEnabled = config.enabled ?? true\n    this.strict = config.strict ?? false\n    this.bamlClient = config.bamlClient ?? null\n    if (config.dbSnapshot) {\n      validateDbSnapshotConfig(config.dbSnapshot)\n    }\n    this.dbSnapshot = config.dbSnapshot\n    // The key is NOT read here. HttpClient gets a thunk so the key is resolved\n    // at send time, after any in-script dotenv.config() has run.\n    this.httpClient = new HttpClient({\n      apiKey: () => this.resolveApiKey(),\n      serviceUrl: this.serviceUrl,\n      timeout: this.timeout,\n    })\n  }\n\n  /**\n   * Resolve the API key lazily, the first time a span actually needs it.\n   *\n   * The key is intentionally NOT read at construction. In ESM, a shim that\n   * does `new Bitfab({ apiKey: process.env.BITFAB_API_KEY })` is hoisted and\n   * evaluated before the importing script's body runs `dotenv.config()`, so\n   * the key would be empty at construction even though it is set moments\n   * later. Resolving here (at first `withSpan` call / first request) reads\n   * the key after env loading has run.\n   *\n   * Resolution order: the configured value (string, or function called each\n   * time it is still unresolved), then a fallback read of `BITFAB_API_KEY`\n   * from the environment. Once a non-empty key is found it is cached, so an\n   * early resolve that found nothing never poisons a later one.\n   */\n  private resolveApiKey(): string | undefined {\n    if (this.resolvedApiKey !== undefined) {\n      return this.resolvedApiKey\n    }\n    const fromConfig =\n      typeof this.apiKeyConfig === \"function\"\n        ? this.apiKeyConfig()\n        : this.apiKeyConfig\n    const candidate =\n      fromConfig && fromConfig.trim() !== \"\"\n        ? fromConfig\n        : readEnv(\"BITFAB_API_KEY\")\n    const key = candidate && candidate.trim() !== \"\" ? candidate : undefined\n    if (key) {\n      this.resolvedApiKey = key\n      return key\n    }\n    if (this.strict) {\n      throw new BitfabError(\n        \"Bitfab: no API key resolved. Set BITFAB_API_KEY or pass apiKey to \" +\n          \"new Bitfab(). If a script loads env with dotenv, load it before the \" +\n          \"module that constructs the client is imported (e.g. \" +\n          \"`node --env-file=.env script.ts`), or pass \" +\n          \"`apiKey: () => process.env.BITFAB_API_KEY`.\",\n      )\n    }\n    if (this.explicitlyEnabled && !this.apiKeyWarned) {\n      this.apiKeyWarned = true\n      console.warn(\n        \"Bitfab: apiKey is empty - tracing is disabled. Provide a valid API key to enable tracing.\",\n      )\n    }\n    return undefined\n  }\n\n  /**\n   * Whether tracing should run, decided lazily at call time (not frozen at\n   * construction). An explicit `enabled: false` short-circuits without ever\n   * touching the key.\n   */\n  private isTracingEnabled(): boolean {\n    if (!this.explicitlyEnabled) {\n      return false\n    }\n    return this.resolveApiKey() !== undefined\n  }\n\n  /**\n   * Fetch the function with its current version and BAML prompt from the server.\n   *\n   * @param methodName - The name of the method to fetch\n   * @returns The function with current version, BAML prompt, and provider definitions\n   * @throws {BitfabError} If the function is not found or an error occurs\n   */\n  private async fetchFunctionVersion(\n    methodName: string,\n  ): Promise<FunctionVersionResponse> {\n    const result =\n      await this.httpClient.lookupFunction<FunctionVersionResponse>(methodName)\n\n    // Check if function was not found\n    if (result.id === null) {\n      throw new BitfabError(\n        `Function \"${methodName}\" not found. Create it at: ${this.serviceUrl}/functions`,\n        \"/functions\",\n      )\n    }\n\n    // Check if function has no prompt\n    if (!result.prompt) {\n      throw new BitfabError(\n        `Function \"${methodName}\" has no prompt configured. Add one at: ${this.serviceUrl}/functions/${result.id}`,\n        `/functions/${result.id}`,\n      )\n    }\n\n    return result\n  }\n\n  /**\n   * Call a method with the given named arguments via BAML execution.\n   *\n   * @param methodName - The name of the method to call\n   * @param inputs - Named arguments to pass to the method\n   * @returns The result of the BAML function execution\n   * @throws {BitfabError} If service_url is not set, or if an error occurs\n   */\n  async call<T = unknown>(\n    methodName: string,\n    inputs: Record<string, unknown> = {},\n  ): Promise<T> {\n    try {\n      const functionVersion = await this.fetchFunctionVersion(methodName)\n      const executionResult = await runFunctionWithBaml(\n        functionVersion.prompt,\n        inputs,\n        functionVersion.providers,\n        this.envVars,\n      )\n\n      // Create trace for the local execution. A non-serializable result must\n      // not throw into the user's `call()`: fall back to String() if\n      // JSON.stringify throws or yields undefined (e.g. a function result).\n      let resultStr: string\n      if (typeof executionResult.result === \"string\") {\n        resultStr = executionResult.result\n      } else {\n        try {\n          resultStr =\n            JSON.stringify(executionResult.result) ??\n            String(executionResult.result)\n        } catch {\n          warnOnce(\n            \"call-result-serialize\",\n            \"a local execution result could not be JSON-serialized; storing its String() form instead. The call still returns its real value.\",\n          )\n          resultStr = String(executionResult.result)\n        }\n      }\n\n      // Create trace in background so user doesn't have to wait\n      this.httpClient.sendInternalTrace(functionVersion.id, {\n        result: resultStr,\n        source: \"typescript-sdk\",\n        ...(Object.keys(inputs).length > 0 && { inputs }),\n        ...(executionResult.rawCollector != null && {\n          rawCollector: executionResult.rawCollector,\n        }),\n      })\n\n      return executionResult.result as T\n    } catch (error) {\n      if (error instanceof BitfabError) {\n        throw error\n      }\n      if (error instanceof Error) {\n        throw new BitfabError(error.message)\n      }\n      throw new BitfabError(\"Unknown error occurred during local execution\")\n    }\n  }\n\n  /**\n   * Get a tracing processor for OpenAI Agents SDK integration.\n   *\n   * This processor automatically captures traces and spans from the OpenAI Agents SDK\n   * and sends them to Bitfab for monitoring and analysis.\n   *\n   * Example usage:\n   * ```typescript\n   * import { addTraceProcessor } from '@openai/agents';\n   *\n   * const client = new Bitfab({ apiKey: 'your-api-key' });\n   * const processor = client.getOpenAiTracingProcessor();\n   * addTraceProcessor(processor);\n   * ```\n   *\n   * @returns A BitfabOpenAITracingProcessor instance configured for this client\n   */\n  getOpenAiTracingProcessor() {\n    return new BitfabOpenAITracingProcessor({\n      // Resolved at getter-call time (framework handlers are set up after env\n      // loads); the withSpan path stays lazy via the constructor HttpClient thunk.\n      apiKey: this.resolveApiKey(),\n      serviceUrl: this.serviceUrl,\n      getActiveSpanContext: () => {\n        const stack = getSpanStack()\n        return stack[stack.length - 1] ?? null\n      },\n    })\n  }\n\n  /**\n   * Get an OpenAI Agents SDK handler that records a replayable root span.\n   *\n   * The processor from {@link getOpenAiTracingProcessor} captures everything\n   * inside a run (LLM calls, tools, handoffs) but never sees the caller's\n   * input, so a processor-only run records an empty-input root and is not\n   * replayable. This handler's `wrapRun` is a drop-in for `run()` that opens a\n   * `withSpan` root carrying the input and final output; the processor's spans\n   * nest beneath it. Register the processor once at startup, then call\n   * `handler.wrapRun(agent, input)` in place of `run(agent, input)`.\n   *\n   * ```typescript\n   * import { addTraceProcessor, Agent, run } from \"@openai/agents\";\n   *\n   * addTraceProcessor(client.getOpenAiTracingProcessor());\n   * const handler = client.getOpenAiAgentHandler(\"research-topic\");\n   * const result = await handler.wrapRun(agent, \"Find X\");\n   * ```\n   *\n   * @param traceFunctionKey - Groups traces under this key in Bitfab\n   * @returns A BitfabOpenAIAgentHandler configured for this client\n   */\n  getOpenAiAgentHandler(traceFunctionKey: string) {\n    return new BitfabOpenAIAgentHandler({\n      traceFunctionKey,\n      withSpan: this.withSpan.bind(this),\n      getActiveSpanContext: () => {\n        const stack = getSpanStack()\n        return stack[stack.length - 1] ?? null\n      },\n    })\n  }\n\n  /**\n   * Get a LangGraph/LangChain callback handler for tracing.\n   *\n   * The handler captures graph node execution, LLM calls, and tool\n   * invocations as Bitfab spans with proper parent-child hierarchy.\n   *\n   * ```typescript\n   * const handler = client.getLangGraphCallbackHandler(\"my-agent\");\n   * const result = await agent.invoke(\n   *   { messages: [...] },\n   *   { callbacks: [handler] },\n   * );\n   * ```\n   *\n   * @param traceFunctionKey - Groups traces under this key in Bitfab\n   * @returns A BitfabLangGraphCallbackHandler configured for this client\n   */\n  getLangGraphCallbackHandler(traceFunctionKey: string) {\n    return new BitfabLangGraphCallbackHandler({\n      apiKey: this.resolveApiKey(),\n      traceFunctionKey,\n      serviceUrl: this.serviceUrl,\n      getActiveSpanContext: () => {\n        const stack = getSpanStack()\n        return stack[stack.length - 1] ?? null\n      },\n    })\n  }\n\n  /**\n   * Get a LangChain callback handler for tracing.\n   *\n   * Alias of {@link getLangGraphCallbackHandler}: LangChain chains and\n   * LangGraph graphs share the same callback system, so one handler serves\n   * both.\n   *\n   * ```typescript\n   * const handler = client.getLangChainCallbackHandler(\"my-chain\");\n   * const result = await chain.invoke(input, { callbacks: [handler] });\n   * ```\n   *\n   * @param traceFunctionKey - Groups traces under this key in Bitfab\n   * @returns A BitfabLangGraphCallbackHandler configured for this client\n   */\n  getLangChainCallbackHandler(traceFunctionKey: string) {\n    return this.getLangGraphCallbackHandler(traceFunctionKey)\n  }\n\n  /**\n   * Get a Claude Agent SDK handler for tracing.\n   *\n   * The handler captures LLM turns, tool invocations, and subagent\n   * execution as Bitfab spans with proper parent-child hierarchy.\n   *\n   * ```typescript\n   * import { query } from \"@anthropic-ai/claude-agent-sdk\";\n   *\n   * const handler = client.getClaudeAgentHandler(\"my-agent\");\n   * const options = handler.instrumentOptions({\n   *   model: \"claude-sonnet-4-5-...\",\n   * });\n   * for await (const msg of handler.wrapQuery(\n   *   query({ prompt: \"Do something\", options })\n   * )) {\n   *   // process messages\n   * }\n   * ```\n   *\n   * @param traceFunctionKey - Groups traces under this key in Bitfab\n   * @returns A BitfabClaudeAgentHandler configured for this client\n   */\n  getClaudeAgentHandler(traceFunctionKey: string) {\n    return new BitfabClaudeAgentHandler({\n      apiKey: this.resolveApiKey(),\n      traceFunctionKey,\n      serviceUrl: this.serviceUrl,\n      getActiveSpanContext: () => {\n        const stack = getSpanStack()\n        return stack[stack.length - 1] ?? null\n      },\n    })\n  }\n\n  /**\n   * Get a Vercel AI SDK language-model middleware for tracing.\n   *\n   * Pass it to the AI SDK's `wrapLanguageModel` and use the wrapped model with\n   * `generateText` / `streamText` / `generateObject` / `streamObject`. Every\n   * call through that model is captured as a keyed `llm` span carrying the call\n   * parameters (the prompt) as input and a serializable summary\n   * (`{ text, toolCalls, usage, finishReason }`) as output. Streaming is\n   * captured without disturbing the caller's live stream.\n   *\n   * ```typescript\n   * import { wrapLanguageModel, streamText } from \"ai\";\n   * import { openai } from \"@ai-sdk/openai\";\n   *\n   * const model = wrapLanguageModel({\n   *   model: openai(\"gpt-4o\"),\n   *   middleware: client.getVercelAiMiddleware(\"chat-turn\"),\n   * });\n   * const result = streamText({ model, messages });\n   * ```\n   *\n   * @param traceFunctionKey - Groups traces under this key in Bitfab\n   * @returns A Vercel AI SDK middleware configured for this client\n   */\n  getVercelAiMiddleware(traceFunctionKey: string) {\n    return new BitfabVercelAiHandler({\n      traceFunctionKey,\n      withSpan: this.withSpan.bind(this),\n    }).middleware\n  }\n\n  /**\n   * Wrap a BAML client method to automatically capture prompt and LLM metadata.\n   *\n   * Creates a BAML Collector, calls the method through a tracked client,\n   * then extracts rendered messages and token usage - calling setPrompt()\n   * and addContext() on the current span automatically.\n   *\n   * The BAML client can be provided in the constructor or passed explicitly:\n   *\n   * ```typescript\n   * // Option 1: bamlClient in constructor (use wrapBAML with just the method)\n   * const client = new Bitfab({ apiKey: 'your-api-key', bamlClient: b });\n   * const traced = client.withSpan('classify', { type: 'llm' },\n   *   client.wrapBAML(b.ClassifyText)\n   * );\n   *\n   * // Option 2: pass bamlClient at call site\n   * const client = new Bitfab({ apiKey: 'your-api-key' });\n   * const traced = client.withSpan('classify', { type: 'llm' },\n   *   client.wrapBAML(b, b.ClassifyText)\n   * );\n   * ```\n   *\n   * @param methodOrClient - Either a BAML method (uses constructor bamlClient) or the BAML client instance\n   * @param maybeMethodOrOptions - The BAML method when the first argument is a client, or WrapBAMLOptions when the first argument is the method\n   * @param maybeOptions - WrapBAMLOptions when using the two-argument (client, method) form\n   * @returns An async function with the same signature that instruments the BAML call\n   */\n  wrapBAML<TArgs extends unknown[], TReturn>(\n    methodOrClient: unknown,\n    maybeMethodOrOptions?:\n      | ((...args: TArgs) => Promise<TReturn>)\n      | WrapBAMLOptions,\n    maybeOptions?: WrapBAMLOptions,\n  ): WrappedBamlFn<TArgs, TReturn> {\n    let bamlClient: unknown\n    let method: (...args: TArgs) => Promise<TReturn>\n    let options: WrapBAMLOptions | undefined\n\n    if (typeof maybeMethodOrOptions === \"function\") {\n      bamlClient = methodOrClient\n      method = maybeMethodOrOptions\n      options = maybeOptions\n    } else {\n      bamlClient = this.bamlClient\n      method = methodOrClient as (...args: TArgs) => Promise<TReturn>\n      options = maybeMethodOrOptions as WrapBAMLOptions | undefined\n      if (!bamlClient) {\n        throw new BitfabError(\n          \"bamlClient is required for wrapBAML. Pass it in the constructor or as the first argument.\",\n        )\n      }\n    }\n\n    const methodName = method.name\n    if (!methodName) {\n      throw new BitfabError(\n        \"wrapBAML requires a named function (e.g., b.ClassifyText).\",\n      )\n    }\n\n    // Warm the Collector class cache so it's ready by the time the wrapper is called\n    loadCollectorClass()\n\n    const wrappedFn = async (...args: TArgs): Promise<TReturn> => {\n      const CollectorClass = await loadCollectorClass()\n      if (!CollectorClass) {\n        // @boundaryml/baml not available - call method directly as fallback\n        wrappedFn.collector = null\n        return await (\n          bamlClient as Record<string, (...a: TArgs) => Promise<TReturn>>\n        )[methodName](...args)\n      }\n\n      const collector = new CollectorClass(\"bitfab-baml-tracing\")\n\n      // Setting up the tracked client is a side-channel: a BAML version\n      // mismatch, or a non-BAML object passed as `bamlClient`, must not stop\n      // the user's call. If `withOptions` or the method lookup fails, fall back\n      // to the untracked method so the call still runs (untraced).\n      let trackedClient: Record<string, unknown>\n      let trackedMethod: (...a: TArgs) => Promise<TReturn>\n      try {\n        trackedClient = (\n          bamlClient as { withOptions: (opts: unknown) => unknown }\n        ).withOptions({ collector }) as Record<string, unknown>\n        const method = (\n          trackedClient as Record<string, (...a: TArgs) => Promise<TReturn>>\n        )[methodName]\n        if (typeof method !== \"function\") {\n          throw new BitfabError(\n            \"bamlClient.withOptions did not return the wrapped method\",\n          )\n        }\n        trackedMethod = method\n      } catch {\n        warnOnce(\n          `wrapBAML-setup:${methodName}`,\n          `BAML tracing setup failed for \"${methodName}\" (incompatible bamlClient or BAML version); calling it untraced. The call still runs; no span is recorded.`,\n        )\n        wrappedFn.collector = null\n        return await (\n          bamlClient as Record<string, (...a: TArgs) => Promise<TReturn>>\n        )[methodName](...args)\n      }\n\n      const result = await trackedMethod.bind(trackedClient)(...args)\n\n      wrappedFn.collector = collector\n\n      try {\n        const prompt = extractPromptFromCollector(collector)\n        if (prompt) {\n          getCurrentSpan().setPrompt(prompt)\n        }\n        const metadata = extractContextFromCollector(collector)\n        if (metadata) {\n          getCurrentSpan().addContext(metadata)\n        }\n      } catch {\n        // Never crash the host app\n      }\n\n      try {\n        options?.onCollector?.(collector)\n      } catch {\n        // Never crash the host app\n      }\n\n      return result\n    }\n\n    wrappedFn.collector = null as unknown | null\n\n    return wrappedFn\n  }\n\n  /**\n   * Wrap a function to automatically create a span for its inputs and outputs.\n   *\n   * The wrapped function behaves identically to the original, but sends\n   * span data to Bitfab in the background after each call.\n   *\n   * Example usage:\n   * ```typescript\n   * const client = new Bitfab({ apiKey: 'your-api-key' });\n   *\n   * async function processOrder(orderId: string, items: string[]): Promise<{ total: number }> {\n   *   // ... process order\n   *   return { total: 100 };\n   * }\n   *\n   * // Basic usage (defaults to \"custom\" span type)\n   * const tracedProcessOrder = client.withSpan('order-processing', processOrder);\n   *\n   * // With explicit span type\n   * const tracedProcessOrder = client.withSpan('order-processing', { type: 'function' }, processOrder);\n   *\n   * // Call the wrapped function normally\n   * const result = await tracedProcessOrder('order-123', ['item-1', 'item-2']);\n   * // Span is automatically sent to Bitfab\n   * ```\n   *\n   * @param traceFunctionKey - A string identifier for grouping spans (e.g., 'order-processing', 'user-auth')\n   * @param optionsOrFn - Either SpanOptions or the function to wrap\n   * @param maybeFn - The function to wrap if options were provided\n   * @returns A wrapped function with the same signature that creates spans for inputs and outputs\n   */\n  withSpan<TArgs extends unknown[], TReturn>(\n    traceFunctionKey: string,\n    optionsOrFn: SpanOptions | ((...args: TArgs) => TReturn),\n    maybeFn?: (...args: TArgs) => TReturn,\n  ): (...args: TArgs) => TReturn {\n    // An explicit `enabled: false` is a hard opt-out, known at construction:\n    // return the original function unwrapped (zero overhead, and callers may\n    // rely on reference identity). The key-based decision, by contrast, is\n    // deferred to call time inside the wrapper below, because the key can load\n    // after this wrapper is built (the ESM dotenv-hoisting case).\n    if (!this.explicitlyEnabled) {\n      return typeof optionsOrFn === \"function\" ? optionsOrFn : maybeFn!\n    }\n\n    // Handle overloaded signature\n    const options: SpanOptions =\n      typeof optionsOrFn === \"function\" ? {} : optionsOrFn\n    const fn: (...args: TArgs) => TReturn =\n      typeof optionsOrFn === \"function\" ? optionsOrFn : maybeFn!\n    const self = this\n\n    // Detect Promise-returning fn at wrap time so the mock-fire path can\n    // match the original return shape. `AsyncFunction` covers `async fn`\n    // declarations; for plain functions that return a Promise we fall back\n    // to a `fn.toString()` heuristic (looks for `Promise` or `await`).\n    // Brittle for minified code, but mock-fire is the only consumer and a\n    // sync fallback (returning a raw value) is the safe degradation.\n    const fnIsAsyncFunction = fn.constructor.name === \"AsyncFunction\"\n    const fnReturnsPromise =\n      fnIsAsyncFunction ||\n      (() => {\n        try {\n          const src = fn.toString()\n          return /\\b(?:Promise|await)\\b/.test(src)\n        } catch {\n          return false\n        }\n      })()\n\n    const wrappedFn = function (this: unknown, ...args: TArgs): TReturn {\n      // Decide whether to trace at CALL time, not wrap time. The shim builds\n      // this wrapper at module load, often before env (dotenv) has loaded, so\n      // freezing the decision here would permanently disable tracing for a key\n      // that is set moments later. Re-checking per call lets a late-resolved\n      // key take effect; once a key is found the resolution is cached.\n      if (!self.isTracingEnabled()) {\n        return fn.apply(this, args)\n      }\n\n      // The Node-specific entry registers async_hooks synchronously, but ESM\n      // chunk evaluation can load this module before that registration runs.\n      // Re-check at call time so the first traced invocation gets native\n      // context propagation instead of briefly using the browser fallback.\n      initializeAsyncContext()\n\n      // Defer until AsyncLocalStorage init completes. In Node.js, the\n      // dynamic import resolves in one microtask; in browsers, the init\n      // resolves immediately to a no-op. The `asyncLocalStorageInitDone`\n      // flag prevents an infinite loop when AsyncLocalStorage is\n      // unavailable (browsers).\n      if (!asyncLocalStorage && !isAsyncStorageInitDone()) {\n        return asyncLocalStorageReady.then(() =>\n          wrappedFn.apply(this, args),\n        ) as unknown as TReturn\n      }\n\n      // Tracing is a side-channel: building the span context must never stop\n      // the user's function from running. If any of this setup throws (e.g. a\n      // runtime without a usable `crypto`, or a context/snapshot edge), fall\n      // back to running `fn` directly, untraced. The `!` definite-assignments\n      // are sound because the catch always returns: reaching past the\n      // try/catch means the try completed and both values were assigned.\n      let newStack!: SpanContext[]\n      let executeWithContext!: () => TReturn\n      // Set only if THIS call registers root trace state below, so a setup\n      // failure after registration can clean up the orphaned entry (see catch).\n      let registeredTraceId: string | undefined\n      try {\n        // Get current span stack to determine trace context\n        const currentStack = getSpanStack()\n        const parentContext = currentStack[currentStack.length - 1]\n\n        // Generate trace ID (replay override > parent > new)\n        const replayCtxForTraceId = parentContext ? null : getReplayContext()\n        const traceId =\n          parentContext?.traceId ?? replayCtxForTraceId?.traceId ?? randomUuid()\n        const spanId = randomUuid()\n        const parentSpanId = parentContext?.spanId ?? null\n        const isRootSpan = parentSpanId === null\n\n        // Create new context for this span with empty contexts array\n        const newContext: SpanContext = { traceId, spanId, contexts: [] }\n        newStack = [...currentStack, newContext]\n\n        // Capture inputs and start time\n        const inputs = args\n        const startedAt = new Date().toISOString()\n\n        // Register trace state for root spans\n        if (isRootSpan && !activeTraceStates.has(traceId)) {\n          const replayCtxAtRoot = getReplayContext()\n          // Synchronously snapshot the wall clock the SDK sees right now,\n          // before invoking the wrapped function. This timestamp is the Neon\n          // snapshot pin used by the server-side resolver. It is captured on\n          // every trace (no IO, harmless to store) so any trace can later be\n          // replayed against a historical branch; the provider is attached\n          // only when dbSnapshot is configured, otherwise resolved at replay.\n          const dbSnapshotRef = buildSnapshotRef(self.dbSnapshot, startedAt)\n          activeTraceStates.set(traceId, {\n            traceId,\n            startedAt,\n            contexts: [],\n            ...(replayCtxAtRoot?.testRunId && {\n              testRunId: replayCtxAtRoot.testRunId,\n            }),\n            ...(replayCtxAtRoot?.inputSourceTraceId && {\n              inputSourceTraceId: replayCtxAtRoot.inputSourceTraceId,\n            }),\n            dbSnapshotRef,\n          })\n          pendingSpanPromises.set(traceId, [])\n          registeredTraceId = traceId\n        }\n\n        // Shared span parameters\n        const functionName = fn.name !== \"\" ? fn.name : undefined\n        const baseSpanParams = {\n          traceFunctionKey,\n          functionName,\n          spanName: options.name ?? functionName ?? traceFunctionKey,\n          traceId,\n          spanId,\n          parentSpanId,\n          inputs,\n          startedAt,\n          spanType: options.type ?? \"custom\",\n        }\n\n        // Helper to send span and (for root spans) await all pending spans\n        // before sending the trace completion signal.\n        // Wrapped in try/catch so span errors never crash the host app.\n        const sendSpan = async (\n          params: { result: unknown; error?: string; mocked?: boolean },\n          spanOpts?: { skipPersistenceRegistration?: boolean },\n        ) => {\n          // In replay, persistence is correctness: the replay runner must not\n          // call `completeReplay` until this trace's spans AND completion are\n          // on the server, or the trace-ID mapping comes back empty and every\n          // item.traceId nulls out. Register a persistence promise into the\n          // replay context SYNCHRONOUSLY (before the first await below), so\n          // it is visible to the runner by the time the wrapped fn's promise\n          // resolves. Outside replay this is a no-op and sends stay\n          // fire-and-forget.\n          // `skipPersistenceRegistration` is set when a deferred `finalize`\n          // path already registered the persistence promise synchronously\n          // (sendSpan here runs later, after finalize resolves); it still\n          // performs the full awaited persistence below, it just must not push\n          // a second, late promise the runner may never see.\n          const replayCtx = getReplayContext()\n          const persistenceCollector = isRootSpan\n            ? replayCtx?.pendingPersistence\n            : undefined\n          let resolvePersistence: (() => void) | undefined\n          if (persistenceCollector && !spanOpts?.skipPersistenceRegistration) {\n            persistenceCollector.push(\n              new Promise<void>((resolve) => {\n                resolvePersistence = resolve\n              }),\n            )\n          }\n          try {\n            const endedAt = new Date().toISOString()\n\n            // If drop() was called on this trace, suppress the span PAYLOAD\n            // upload for every span that completes after the flag was set.\n            // The trace completion signal below still rides out with\n            // `dropped: true`, so the server scrubs any sibling spans that\n            // already raced out (fire-and-forget) before the flag was set.\n            // Skipping the upload here is belt-and-suspenders on top of that\n            // scrub: it avoids shipping payloads the server will only discard.\n            const traceDropped =\n              activeTraceStates.get(traceId)?.dropped === true\n\n            // dbSnapshotRef is attached to the trace, not the span (see\n            // sendTraceCompletion). A trace-level pin is what replay reads;\n            // duplicating it on the root span would just leak the same\n            // value into two places.\n            const spanPromise: Promise<unknown> = traceDropped\n              ? Promise.resolve()\n              : self.sendWrapperSpan({\n                  ...baseSpanParams,\n                  ...params,\n                  contexts: newContext.contexts,\n                  prompt: newContext.prompt,\n                  endedAt,\n                  ...(replayCtx?.testRunId && {\n                    testRunId: replayCtx.testRunId,\n                  }),\n                  ...(replayCtx?.inputSourceSpanId && {\n                    inputSourceSpanId: replayCtx.inputSourceSpanId,\n                  }),\n                })\n\n            // For root spans, await all pending span requests then send trace completion\n            if (isRootSpan) {\n              const pending = pendingSpanPromises.get(traceId) ?? []\n              pending.push(spanPromise)\n              if (persistenceCollector) {\n                // Replay: wait for every span upload in full. The underlying\n                // requests carry their own HTTP timeouts, so this is bounded.\n                await Promise.allSettled(pending)\n              } else {\n                // Production: never hold the host app hostage on uploads. Clear\n                // and unref the race timer so a resolved race never leaves a\n                // dangling timeout holding the Node event loop open (which would\n                // delay process exit, freeze a serverless function, or hang a\n                // test runner for up to 5s after the last traced call).\n                let raceTimer: ReturnType<typeof setTimeout> | undefined\n                try {\n                  await Promise.race([\n                    Promise.allSettled(pending),\n                    new Promise((resolve) => {\n                      raceTimer = setTimeout(resolve, 5000)\n                      unrefTimer(raceTimer)\n                    }),\n                  ])\n                } finally {\n                  if (raceTimer) {\n                    clearTimeout(raceTimer)\n                  }\n                }\n              }\n              pendingSpanPromises.delete(traceId)\n\n              const traceState = activeTraceStates.get(traceId)\n              const completionPromise = self.sendTraceCompletion({\n                traceFunctionKey,\n                traceId,\n                startedAt: traceState?.startedAt ?? startedAt,\n                endedAt,\n                sessionId: traceState?.sessionId,\n                metadata: traceState?.metadata,\n                contexts: traceState?.contexts ?? [],\n                testRunId: traceState?.testRunId,\n                inputSourceTraceId: traceState?.inputSourceTraceId,\n                dbSnapshotRef: traceState?.dbSnapshotRef,\n                dropped: traceState?.dropped,\n                // Built AFTER the wrapped fn finished, so `accessed` reflects\n                // whether customer code obtained the branch URL during this\n                // item. Omitted entirely when no lease was attached, so the\n                // server can distinguish \"no branch\" from \"branch ignored\".\n                ...(replayCtx?.dbBranchLease && {\n                  dbSnapshotUsage: {\n                    neonBranchId: replayCtx.dbBranchLease.neonBranchId,\n                    snapshotTimestamp:\n                      replayCtx.dbBranchLease.snapshotTimestamp,\n                    sourceTraceId: replayCtx.sourceBitfabTraceId,\n                    accessed: replayCtx.dbSnapshotAccessed === true,\n                  },\n                }),\n              })\n              activeTraceStates.delete(traceId)\n              if (persistenceCollector) {\n                await completionPromise\n              }\n            } else {\n              // Non-root spans: track the promise for the root to await later\n              const pending = pendingSpanPromises.get(traceId)\n              if (pending) {\n                pending.push(spanPromise)\n              } else {\n                pendingSpanPromises.set(traceId, [spanPromise])\n              }\n            }\n          } catch {\n            // Silently ignore - user's result/exception takes priority\n          } finally {\n            resolvePersistence?.()\n          }\n        }\n\n        // Mock interception: if a mock tree is present and this is not the\n        // root span, check whether this child span should return historical\n        // output instead of executing real code. The lookup key matches the\n        // shape buildMockTree builds: `${traceFunctionKey}:${spanName}:${idx}`\n        // with callIndex scoped per (key, name) - see comment on buildMockTree.\n        const replayCtxForMock = getReplayContext()\n        if (replayCtxForMock?.mockTree && !isRootSpan) {\n          const counters = replayCtxForMock.callCounters!\n          const counterKey = `${traceFunctionKey}:${baseSpanParams.spanName}`\n          const callIndex = counters.get(counterKey) ?? 0\n          counters.set(counterKey, callIndex + 1)\n\n          const shouldMock =\n            replayCtxForMock.mockStrategy === \"all\" ||\n            (replayCtxForMock.mockStrategy === \"marked\" &&\n              options.mockOnReplay === true)\n\n          if (shouldMock) {\n            const mockKey = `${counterKey}:${callIndex}`\n            const mockSpan = replayCtxForMock.mockTree.spans.get(mockKey)\n            if (mockSpan) {\n              let output = mockSpan.output\n              if (\n                mockSpan.outputMeta !== undefined &&\n                mockSpan.outputMeta !== null\n              ) {\n                output = deserializeValue({\n                  json: mockSpan.output,\n                  meta: mockSpan.outputMeta,\n                })\n              }\n              // Send a span recording the mocked output (flagged mocked so the\n              // trace view can mark it), then return it.\n              // Match the wrapped fn's call shape: if it returns a Promise,\n              // return a resolved Promise so `.then()` callers don't crash on\n              // a raw value. (`await rawValue` already works either way, but a\n              // sync `Promise.resolve(...).then(...)` consumer would not.)\n              // Detected once at wrap time via fnReturnsPromise so non-async\n              // functions that return Promises (e.g.\n              // `function getData() { return fetch(...) }`) are handled too.\n              void sendSpan({ result: output, mocked: true })\n              if (fnReturnsPromise) {\n                return Promise.resolve(output) as TReturn\n              }\n              return output as TReturn\n            }\n          }\n        }\n\n        // Record the span output. With `finalize`, the raw result is handed\n        // back to the caller untouched (streaming stays live) while a drained,\n        // serializable view is recorded as the span output instead. finalize\n        // runs in the background and never affects the caller's value; a\n        // throwing finalize records an error rather than crashing the host.\n        const recordSpan = (result: unknown): void => {\n          if (options.finalize) {\n            // The finalize -> sendSpan upload is deferred (we await finalize\n            // first), but replay registers root persistence SYNCHRONOUSLY inside\n            // sendSpan so the runner can await it before completing the item.\n            // Because the deferred chain hasn't called sendSpan yet when the\n            // wrapped fn's promise resolves, register the persistence promise\n            // here, synchronously, and resolve it once the upload finishes.\n            // Otherwise replay awaits an empty pendingPersistence and nulls out\n            // the streaming root's trace ID. sendSpan is told to skip its own\n            // (now-redundant) registration.\n            const replayCtx = getReplayContext()\n            const persistenceCollector = isRootSpan\n              ? replayCtx?.pendingPersistence\n              : undefined\n            let resolvePersistence: (() => void) | undefined\n            if (persistenceCollector) {\n              persistenceCollector.push(\n                new Promise<void>((resolve) => {\n                  resolvePersistence = resolve\n                }),\n              )\n            }\n            void Promise.resolve()\n              .then(() => options.finalize!(result))\n              .then((output) =>\n                sendSpan(\n                  { result: output },\n                  { skipPersistenceRegistration: true },\n                ),\n              )\n              .catch((error: unknown) =>\n                sendSpan(\n                  {\n                    result: undefined,\n                    error:\n                      error instanceof Error\n                        ? `finalize failed: ${error.message}`\n                        : `finalize failed: ${String(error)}`,\n                  },\n                  { skipPersistenceRegistration: true },\n                ),\n              )\n              .finally(() => resolvePersistence?.())\n          } else {\n            void sendSpan({ result })\n          }\n        }\n\n        // Execute function within new span context\n        executeWithContext = (): TReturn => {\n          const result = fn(...args)\n\n          // Check if result is a Promise (async function)\n          if (result instanceof Promise) {\n            return result\n              .then((resolvedResult) => {\n                recordSpan(resolvedResult)\n                return resolvedResult\n              })\n              .catch((error: unknown) => {\n                void sendSpan({\n                  result: undefined,\n                  error: error instanceof Error ? error.message : String(error),\n                })\n                throw error\n              }) as TReturn\n          }\n\n          // Async generator: keep the span open across iteration so child\n          // spans created inside the generator body nest under it. (finalize\n          // does not apply here - generator output is captured automatically.)\n          if (isAsyncGenerator(result)) {\n            return wrapAsyncGenerator(result, newStack, sendSpan) as TReturn\n          }\n\n          // Sync function - create span in background. A sync function can\n          // still return a live stream object (e.g. AI SDK `streamText`), so\n          // finalize is honored here too.\n          recordSpan(result)\n          return result\n        }\n      } catch (setupError) {\n        // If this call registered root trace state before failing, remove the\n        // now-orphaned entry: no span or completion will follow, so leaving it\n        // would leak the maps and block that trace id's completion forever.\n        if (registeredTraceId) {\n          activeTraceStates.delete(registeredTraceId)\n          pendingSpanPromises.delete(registeredTraceId)\n        }\n        // During replay (a controlled eval), a setup failure must surface, not\n        // silently fall through. The setup region includes the mock\n        // interception: if a matched mock can't build its output (e.g.\n        // deserializeValue on bad outputMeta), swallowing it would run the real\n        // function - real side effects, and a skewed mock call counter - which\n        // defeats replay. Re-throw so the replay runner records it as that\n        // item's error. The never-crash fallback below is for production hosts.\n        if (getReplayContext()) {\n          throw setupError\n        }\n        // Tracing setup failed; run the user's function untraced so a tracing\n        // failure never crashes the host app. Call exactly as the traced path\n        // does (`fn(...args)`, no receiver) so `this`-binding stays consistent.\n        warnOnce(\n          `withSpan-setup:${traceFunctionKey}`,\n          `tracing setup failed for \"${traceFunctionKey}\"; running it untraced. The function still runs and returns normally; no span is recorded.`,\n        )\n        return fn(...args) as TReturn\n      }\n\n      // Run OUTSIDE the setup try: a throw from the user's own function must\n      // propagate unchanged and never be mistaken for a tracing failure (which\n      // would double-invoke `fn`).\n      return runWithSpanStack(newStack, executeWithContext)\n    }\n    // Mark the wrapper with its key so replay() can tell wrapped functions\n    // from plain callables (which it auto-wraps) and reject key mismatches.\n    Object.defineProperty(wrappedFn, \"_bitfabTraceFunctionKey\", {\n      value: traceFunctionKey,\n    })\n    return wrappedFn\n  }\n\n  /**\n   * Get a detached handle to a previously-created trace, looked up by the\n   * caller-supplied id (the same id passed at trace creation).\n   *\n   * The returned handle is not tied to AsyncLocalStorage - each method sends\n   * to the server immediately. Useful for adding context to a trace from a\n   * different process or thread than the one that created it.\n   *\n   * Throws synchronously if `traceId` is malformed (empty, too long, or\n   * contains characters outside `[a-zA-Z0-9_\\-.:]`). Server returns 404 if\n   * no trace exists with that id in the org; the failure surfaces as a\n   * logged warning (fire-and-forget) or via the awaited promise.\n   *\n   * Example:\n   * ```typescript\n   * const trace = client.getTrace(\"order_abc_123\");\n   * await trace.addContext({ refund_status: \"approved\" });\n   * await trace.setMetadata({ region: \"us-west\" });\n   * ```\n   */\n  getTrace(traceId: string): DetachedTrace {\n    validateTraceId(traceId)\n\n    return {\n      traceId,\n      addContext: (context: Record<string, unknown>): Promise<unknown> => {\n        if (!this.isTracingEnabled()) {\n          return Promise.resolve()\n        }\n        if (typeof context !== \"object\" || context === null) {\n          return Promise.resolve()\n        }\n        return this.httpClient.patchTrace(traceId, {\n          appendContexts: [context],\n        })\n      },\n      setMetadata: (metadata: Record<string, unknown>): Promise<unknown> => {\n        if (!this.isTracingEnabled()) {\n          return Promise.resolve()\n        }\n        if (typeof metadata !== \"object\" || metadata === null) {\n          return Promise.resolve()\n        }\n        return this.httpClient.patchTrace(traceId, { mergeMetadata: metadata })\n      },\n      setSessionId: (sessionId: string): Promise<unknown> => {\n        if (!this.isTracingEnabled()) {\n          return Promise.resolve()\n        }\n        if (typeof sessionId !== \"string\" || sessionId.length === 0) {\n          return Promise.resolve()\n        }\n        return this.httpClient.patchTrace(traceId, { setSessionId: sessionId })\n      },\n    }\n  }\n\n  /**\n   * Get a function wrapper for a specific trace function key.\n   *\n   * This provides a fluent API alternative to calling withSpan directly,\n   * allowing you to bind the traceFunctionKey once and wrap multiple functions.\n   *\n   * Example usage:\n   * ```typescript\n   * const client = new Bitfab({ apiKey: 'your-api-key' });\n   *\n   * const orderFunc = client.getFunction('order-processing');\n   * const tracedProcessOrder = orderFunc.withSpan(processOrder);\n   * const tracedValidateOrder = orderFunc.withSpan(validateOrder);\n   * ```\n   *\n   * @param traceFunctionKey - A string identifier for grouping spans\n   * @returns A BitfabFunction instance for wrapping functions\n   */\n  getFunction(traceFunctionKey: string): BitfabFunction {\n    return new BitfabFunction(this, traceFunctionKey)\n  }\n\n  /**\n   * Send trace completion when a root span ends.\n   * Internal method to record trace completion with end time.\n   * Fire-and-forget - sends to externalTraces endpoint via httpClient.\n   */\n  private sendTraceCompletion(params: {\n    traceFunctionKey: string\n    traceId: string\n    startedAt: string\n    endedAt: string\n    sessionId?: string\n    metadata?: Record<string, unknown>\n    contexts?: ContextEntry[]\n    testRunId?: string\n    inputSourceTraceId?: string\n    dbSnapshotRef?: DbSnapshotRef\n    dropped?: boolean\n    /**\n     * Replay DB branch usage record, present only when a lease was\n     * attached to the replay item. Serialized as `db_snapshot_usage` so\n     * the server can stamp the trace's metadata at ingest.\n     */\n    dbSnapshotUsage?: {\n      neonBranchId: string\n      snapshotTimestamp?: string\n      sourceTraceId?: string\n      accessed: boolean\n    }\n  }): Promise<unknown> {\n    // Build the raw trace object for the externalTraces endpoint\n    const rawTrace: Record<string, unknown> = {\n      id: params.traceId,\n      started_at: params.startedAt,\n      ended_at: params.endedAt,\n      workflow_name: params.traceFunctionKey,\n    }\n\n    // Add optional fields to rawData\n    if (params.metadata && Object.keys(params.metadata).length > 0) {\n      rawTrace.metadata = params.metadata\n    }\n    if (params.contexts && params.contexts.length > 0) {\n      rawTrace.contexts = params.contexts\n    }\n    if (params.inputSourceTraceId) {\n      rawTrace.input_source_trace_id = params.inputSourceTraceId\n    }\n    if (params.dbSnapshotRef) {\n      rawTrace.db_snapshot_ref = params.dbSnapshotRef\n    }\n    if (params.dbSnapshotUsage) {\n      rawTrace.db_snapshot_usage = {\n        neon_branch_id: params.dbSnapshotUsage.neonBranchId,\n        ...(params.dbSnapshotUsage.snapshotTimestamp && {\n          snapshot_timestamp: params.dbSnapshotUsage.snapshotTimestamp,\n        }),\n        ...(params.dbSnapshotUsage.sourceTraceId && {\n          source_trace_id: params.dbSnapshotUsage.sourceTraceId,\n        }),\n        accessed: params.dbSnapshotUsage.accessed,\n      }\n    }\n\n    return this.httpClient.sendExternalTrace({\n      type: \"sdk-function\",\n      source: \"typescript-sdk-function\",\n      traceFunctionKey: params.traceFunctionKey,\n      externalTrace: rawTrace,\n      completed: true,\n      ...(params.dropped && { dropped: true }),\n      ...(params.sessionId && { sessionId: params.sessionId }),\n      ...(params.testRunId && { testRunId: params.testRunId }),\n    })\n  }\n\n  /**\n   * Send a wrapper span from function execution.\n   * Internal method to record spans when using withSpan.\n   * Fire-and-forget - sends to externalSpans endpoint via httpClient.\n   */\n  private sendWrapperSpan(params: {\n    traceFunctionKey: string\n    functionName?: string\n    spanName: string\n    traceId: string\n    spanId: string\n    parentSpanId: string | null\n    inputs?: unknown[]\n    result: unknown\n    error?: string\n    startedAt: string\n    endedAt: string\n    spanType: SpanType\n    contexts?: ContextEntry[]\n    prompt?: string\n    testRunId?: string\n    inputSourceSpanId?: string\n    mocked?: boolean\n  }): Promise<unknown> {\n    // Serialize inputs and result with superjson for type preservation\n    const serializedInputs = serializeValue(params.inputs)\n    const serializedResult = serializeValue(params.result)\n\n    // Format as an external span with the wrapper format\n    const externalSpan: Record<string, unknown> = {\n      id: params.spanId,\n      trace_id: params.traceId,\n      started_at: params.startedAt,\n      ended_at: params.endedAt,\n      span_data: {\n        name: params.spanName,\n        type: params.spanType,\n        input: serializedInputs.json,\n        output: serializedResult.json,\n        // Include superjson meta for type preservation\n        ...(serializedInputs.meta !== undefined && {\n          input_meta: serializedInputs.meta,\n        }),\n        ...(serializedResult.meta !== undefined && {\n          output_meta: serializedResult.meta,\n        }),\n        ...(params.functionName !== undefined && {\n          function_name: params.functionName,\n        }),\n        ...(params.error !== undefined && {\n          error: params.error,\n          error_source: \"code\",\n        }),\n        ...(params.contexts &&\n          params.contexts.length > 0 && {\n            contexts: params.contexts,\n          }),\n        ...(params.prompt !== undefined && { prompt: params.prompt }),\n      },\n    }\n\n    // Add parent_id for nested spans\n    if (params.parentSpanId) {\n      externalSpan.parent_id = params.parentSpanId\n    }\n    if (params.inputSourceSpanId) {\n      externalSpan.input_source_span_id = params.inputSourceSpanId\n    }\n\n    return this.httpClient.sendExternalSpan({\n      type: \"sdk-function\",\n      source: \"typescript-sdk-function\",\n      sourceTraceId: params.traceId,\n      traceFunctionKey: params.traceFunctionKey,\n      rawSpan: externalSpan,\n      ...(params.testRunId && { testRunId: params.testRunId }),\n      ...(params.mocked && { mocked: true }),\n    })\n  }\n\n  /**\n   * Replay historical traces through a function and create a test run.\n   *\n   * Fetches the last N traces for the given trace function key, re-runs each\n   * through the provided function, and returns comparison data.\n   *\n   * Accepts either a `withSpan`-wrapped function (under the same key) or any\n   * plain callable: plain callables are wrapped internally so each replayed\n   * invocation records a trace tied to the test run. The plain-callable form\n   * is how handler-instrumented workflows (LangGraph/LangChain, Claude Agent\n   * SDK) replay - those record traces under a key with no `withSpan`-wrapped\n   * root in the app.\n   *\n   * @param traceFunctionKey - The trace function key to replay\n   * @param fn - The function to run recorded inputs through\n   * @param options - Optional replay options. When `traceIds` is passed,\n   *   `limit` is ignored (with a warning): an explicit ID list already\n   *   determines how many traces replay.\n   * @returns ReplayResult with items, testRunId, and testRunUrl\n   */\n  async replay<TReturn>(\n    traceFunctionKey: string,\n    // biome-ignore lint/suspicious/noExplicitAny: replay deserializes inputs from historical data, typed args would be incorrect\n    fn: (...args: any[]) => TReturn | Promise<TReturn>,\n    options?: ReplayOptions,\n  ): Promise<ReplayResult<TReturn>> {\n    const wrappedKey = (fn as { _bitfabTraceFunctionKey?: string })\n      ._bitfabTraceFunctionKey\n    let replayFn = fn\n    if (wrappedKey === undefined) {\n      // Name the root span after the key (not the callable's name) so it\n      // matches the production root span: handler-instrumented roots (Claude\n      // Agent SDK, OpenAI Agents) are named after the trace function key, so\n      // naming the auto-wrap after fn.name would make the replayed root read\n      // differently from the trace it replays.\n      replayFn = this.withSpan(\n        traceFunctionKey,\n        { name: traceFunctionKey, type: \"agent\" },\n        fn,\n      )\n    } else if (wrappedKey !== traceFunctionKey) {\n      throw new BitfabError(\n        `Function is wrapped with trace function key '${wrappedKey}' but ` +\n          `replay was called with '${traceFunctionKey}'. Pass matching keys, ` +\n          \"or pass the unwrapped function to replay it under the explicit key.\",\n      )\n    }\n    const { replay: doReplay } = await import(\"./replay.js\")\n    return doReplay(\n      this.httpClient,\n      this.serviceUrl,\n      traceFunctionKey,\n      replayFn,\n      options,\n    )\n  }\n}\n\n/**\n * Represents a Bitfab function that can wrap user functions for tracing.\n *\n * This provides a fluent API for binding a traceFunctionKey once and\n * then wrapping multiple functions with that key.\n *\n * Example usage:\n * ```typescript\n * const client = new Bitfab({ apiKey: 'your-api-key' });\n *\n * const orderFunc = client.getFunction('order-processing');\n * const tracedProcessOrder = orderFunc.withSpan(processOrder);\n * const tracedValidateOrder = orderFunc.withSpan(validateOrder);\n * ```\n */\nexport class BitfabFunction {\n  constructor(\n    private readonly client: Bitfab,\n    private readonly traceFunctionKey: string,\n  ) {}\n\n  /**\n   * Wrap a function to automatically create a span for its inputs and outputs.\n   *\n   * The wrapped function behaves identically to the original, but sends\n   * span data to Bitfab in the background after each call.\n   *\n   * Example usage:\n   * ```typescript\n   * const orderFunc = client.getFunction('order-processing');\n   *\n   * // Basic usage (defaults to \"custom\" span type)\n   * const tracedProcessOrder = orderFunc.withSpan(processOrder);\n   *\n   * // With explicit span type\n   * const tracedProcessOrder = orderFunc.withSpan({ type: 'function' }, processOrder);\n   * ```\n   *\n   * @param optionsOrFn - Either SpanOptions or the function to wrap\n   * @param maybeFn - The function to wrap if options were provided\n   * @returns A wrapped function with the same signature that creates spans\n   */\n  withSpan<TArgs extends unknown[], TReturn>(\n    optionsOrFn: SpanOptions | ((...args: TArgs) => TReturn),\n    maybeFn?: (...args: TArgs) => TReturn,\n  ): (...args: TArgs) => TReturn {\n    // Handle overloaded signature\n    const options: SpanOptions =\n      typeof optionsOrFn === \"function\" ? {} : optionsOrFn\n    const fn: (...args: TArgs) => TReturn =\n      typeof optionsOrFn === \"function\" ? optionsOrFn : maybeFn!\n\n    return this.client.withSpan(this.traceFunctionKey, options, fn)\n  }\n\n  /**\n   * Get a Vercel AI SDK language-model middleware bound to this function's key.\n   *\n   * Equivalent to `client.getVercelAiMiddleware(key)` but reuses the key bound\n   * on this handle, so an outer `withSpan` root and the middleware-traced model\n   * calls share one key without repeating the string. With a matching key, the\n   * outer span is the replayable root and the model-call spans nest beneath it.\n   *\n   * Nesting is captured when the model is called, so keep the\n   * `generateText` / `streamText` call inside this handle's `withSpan`; the\n   * middleware object itself can be created anywhere.\n   *\n   * ```typescript\n   * const chatTurn = client.getFunction(\"chat-turn\");\n   * const runChatTurn = chatTurn.withSpan(\n   *   { type: \"agent\", finalize: finalizers.aiSdk },\n   *   (messages) => streamText({ model, messages }),\n   * );\n   * const model = wrapLanguageModel({\n   *   model: openai(\"gpt-4o\"),\n   *   middleware: chatTurn.getVercelAiMiddleware(),\n   * });\n   * ```\n   *\n   * @returns A Vercel AI SDK middleware configured for this client and key\n   */\n  getVercelAiMiddleware() {\n    return this.client.getVercelAiMiddleware(this.traceFunctionKey)\n  }\n\n  /**\n   * Get a Claude Agent SDK handler bound to this function's key.\n   *\n   * Equivalent to `client.getClaudeAgentHandler(key)` but reuses the key bound\n   * on this handle, so an outer `withSpan` root and the handler share one key\n   * without repeating the string. With a matching key, the outer span is the\n   * replayable root and every handler span nests beneath it.\n   *\n   * Use the handler inside this handle's `withSpan` body so its spans capture\n   * the enclosing root; framework calls made with no active span record their\n   * own root instead.\n   *\n   * ```typescript\n   * const pipeline = client.getFunction(\"my-agent\");\n   * const tracedRun = pipeline.withSpan({ type: \"agent\" }, async (prompt) => {\n   *   const handler = pipeline.getClaudeAgentHandler();\n   *   const options = handler.instrumentOptions({ model: \"claude-sonnet-4-6\" });\n   *   for await (const msg of handler.wrapQuery(query({ prompt, options }))) { ... }\n   * });\n   * ```\n   *\n   * @returns A Claude Agent SDK handler configured for this client and key\n   */\n  getClaudeAgentHandler() {\n    return this.client.getClaudeAgentHandler(this.traceFunctionKey)\n  }\n\n  /**\n   * Get a LangGraph/LangChain callback handler bound to this function's key.\n   *\n   * Equivalent to `client.getLangGraphCallbackHandler(key)` but reuses the key\n   * bound on this handle, so an outer `withSpan` root and the handler share one\n   * key without repeating the string. With a matching key, the outer span is\n   * the replayable root and the LangGraph spans nest beneath it.\n   *\n   * Use the handler inside this handle's `withSpan` body so its spans capture\n   * the enclosing root; framework calls made with no active span record their\n   * own root instead.\n   *\n   * ```typescript\n   * const pipeline = client.getFunction(\"my-pipeline\");\n   * const tracedRun = pipeline.withSpan({ type: \"agent\" }, async (query) => {\n   *   const handler = pipeline.getLangGraphCallbackHandler();\n   *   return agent.invoke({ messages: [...] }, { callbacks: [handler] });\n   * });\n   * ```\n   *\n   * @returns A LangGraph/LangChain callback handler for this client and key\n   */\n  getLangGraphCallbackHandler() {\n    return this.client.getLangGraphCallbackHandler(this.traceFunctionKey)\n  }\n\n  /**\n   * Alias of {@link getLangGraphCallbackHandler} - LangChain and LangGraph\n   * share one callback system, so the same bound handler serves both.\n   *\n   * @returns A LangChain callback handler for this client and key\n   */\n  getLangChainCallbackHandler() {\n    return this.client.getLangChainCallbackHandler(this.traceFunctionKey)\n  }\n\n  /**\n   * Wrap a BAML client method to automatically capture prompt and LLM metadata.\n   * Delegates to the parent client's wrapBAML method.\n   *\n   * Unlike the other methods on this handle, `wrapBAML` does NOT use the bound\n   * key: it opens no span of its own. It enriches the *current* span (via\n   * `getCurrentSpan().setPrompt()` / `addContext()`), so call it inside a\n   * function wrapped by this handle's `withSpan` - the bound key keys that\n   * wrapper, and the BAML prompt/metadata attach to it.\n   *\n   * @param methodOrClient - Either a BAML method (uses constructor bamlClient) or the BAML client instance\n   * @param maybeMethodOrOptions - The BAML method when the first argument is a client, or WrapBAMLOptions when the first argument is the method\n   * @param maybeOptions - WrapBAMLOptions when using the two-argument (client, method) form\n   * @returns An async function with the same signature that instruments the BAML call\n   */\n  wrapBAML<TArgs extends unknown[], TReturn>(\n    methodOrClient: unknown,\n    maybeMethodOrOptions?:\n      | ((...args: TArgs) => Promise<TReturn>)\n      | WrapBAMLOptions,\n    maybeOptions?: WrapBAMLOptions,\n  ): WrappedBamlFn<TArgs, TReturn> {\n    return this.client.wrapBAML(\n      methodOrClient,\n      maybeMethodOrOptions,\n      maybeOptions,\n    )\n  }\n}\n","/**\n * Import an OPTIONAL peer dependency without breaking a consumer's bundler.\n *\n * Optional peers (declared in this package's `peerDependenciesMeta` with\n * `optional: true` - e.g. `@openai/agents`, `@boundaryml/baml`) are absent by\n * design for most consumers: someone who only uses the Vercel AI integration\n * never installs `@openai/agents`, and someone who never calls `Bitfab.call()`\n * never installs `@boundaryml/baml`.\n *\n * A plain `import(\"@openai/agents\")` leaves a static, literal specifier in the\n * built SDK. A consumer's bundler (webpack, Turbopack, Vite, Rollup, esbuild)\n * statically analyses that specifier and tries to resolve it at *build* time,\n * failing the whole build with \"Module not found: Can't resolve\n * '@openai/agents'\" even though that code path never runs for that consumer.\n * Wrapping the import in try/catch is not enough: only webpack >= 5.90.2 treats\n * that as optional, and Turbopack/Vite/older webpack do not.\n *\n * The robust, bundler-agnostic fix is to keep the specifier out of static\n * analysis entirely. The caller passes the specifier as parts that are joined\n * at runtime, so no bundler can see a literal module name to resolve. The\n * `webpackIgnore` / `@vite-ignore` magic comments are belt-and-suspenders for\n * bundlers that still inspect the (now non-literal) request. This mirrors the\n * technique already used for `node:async_hooks` in `asyncStorage.ts`.\n *\n * The import stays a native runtime `import()`: it resolves from `node_modules`\n * when the peer IS installed, and throws an ordinary module-not-found error\n * only when the feature is actually used without its peer installed - which is\n * the correct behaviour (the caller opted into an integration whose peer they\n * chose not to install).\n *\n * @param specifierParts - The package specifier split so it is reconstructed at\n *   runtime, never appearing as a literal (e.g. `[\"@openai\", \"agents\"]` ->\n *   `\"@openai/agents\"`).\n */\nexport function importOptionalPeer<T = unknown>(\n  specifierParts: readonly string[],\n): Promise<T> {\n  // Reconstructed at runtime so no bundler sees a literal specifier to resolve.\n  const specifier = specifierParts.join(\"/\")\n  return import(\n    /* webpackIgnore: true */ /* @vite-ignore */ specifier\n  ) as Promise<T>\n}\n","/**\n * BAML execution utilities for the Bitfab TypeScript SDK.\n * This module provides functions to execute BAML prompts dynamically on the client side.\n */\n\nimport { importOptionalPeer } from \"./optionalPeer.js\"\n\ntype BamlModule = typeof import(\"@boundaryml/baml\")\n\nlet cachedBaml: BamlModule | null = null\n\nasync function loadBaml(): Promise<BamlModule> {\n  if (cachedBaml) {\n    return cachedBaml\n  }\n  try {\n    // Reconstructed specifier (see importOptionalPeer): keeps a consumer's\n    // bundler from trying to resolve `@boundaryml/baml` at build time when it\n    // is not installed (it is an optional peer, only needed for Bitfab.call()).\n    cachedBaml = await importOptionalPeer<BamlModule>([\"@boundaryml\", \"baml\"])\n    return cachedBaml\n  } catch {\n    throw new Error(\n      \"@boundaryml/baml is required for Bitfab.call(). Install it with: npm install @boundaryml/baml\",\n    )\n  }\n}\n\n/**\n * Provider definition from the server.\n */\nexport interface ProviderDefinition {\n  provider: string\n  apiKeyEnv: string\n  models: Array<{\n    model: string\n    description: string\n  }>\n}\n\n/**\n * Result of a BAML function execution with raw collector data.\n */\nexport interface BamlExecutionResult {\n  /** The parsed result of the function */\n  result: unknown\n  /** Raw collector data for the server to parse */\n  rawCollector: Record<string, unknown> | null\n}\n\n/**\n * Capitalize first letter of a string.\n */\nfunction capitalize(str: string): string {\n  return str.charAt(0).toUpperCase() + str.slice(1)\n}\n\n/**\n * Convert provider name to PascalCase.\n * e.g., \"openai\" -> \"OpenAI\", \"anthropic\" -> \"Anthropic\"\n */\nfunction formatProvider(provider: string): string {\n  const providerMap: Record<string, string> = {\n    openai: \"OpenAI\",\n    anthropic: \"Anthropic\",\n    google: \"Google\",\n  }\n  return providerMap[provider] ?? capitalize(provider)\n}\n\n/**\n * Convert a model name to a valid BAML identifier part.\n * e.g., \"gpt-5-mini\" -> \"GPT5_mini\", \"gpt-4.1\" -> \"GPT4_1\"\n */\nfunction formatModel(model: string): string {\n  return model\n    .replace(/^gpt-/, \"GPT\") // gpt- prefix -> GPT\n    .replace(/\\./g, \"_\") // dots -> underscore\n    .replace(/-/g, \"_\") // hyphens -> underscore\n}\n\n/**\n * Generate the BAML client name from provider and model.\n * e.g., \"openai\" + \"gpt-4.1-mini\" -> \"OpenAI_GPT4_1_mini\"\n */\nexport function getClientName(provider: string, model: string): string {\n  return `${formatProvider(provider)}_${formatModel(model)}`\n}\n\n/**\n * Generates BAML client definition strings.\n * BamlRuntime.fromFiles requires clients to be defined in source for parsing.\n */\nfunction generateClientDefinitions(providers: ProviderDefinition[]): string {\n  const definitions: string[] = []\n\n  for (const providerDef of providers) {\n    for (const model of providerDef.models) {\n      const clientName = getClientName(providerDef.provider, model.model)\n      const temperatureOption = supportsTemperatureZero(\n        providerDef.provider,\n        model.model,\n      )\n        ? \"\\n    temperature 0\"\n        : \"\"\n      definitions.push(`client<llm> ${clientName} {\n  provider ${providerDef.provider}\n  options {\n    model \"${model.model}\"\n    api_key env.${providerDef.apiKeyEnv}${temperatureOption}\n  }\n}`)\n    }\n  }\n\n  return definitions.join(\"\\n\\n\")\n}\n\nfunction supportsTemperatureZero(provider: string, model: string): boolean {\n  return (\n    provider === \"openai\" &&\n    (model.startsWith(\"gpt-4.1\") || model.startsWith(\"gpt-4o\"))\n  )\n}\n\n/**\n * Prepends the default client definitions to a BAML source if it doesn't already define them.\n */\nfunction withDefaultClients(\n  bamlSource: string,\n  providers: ProviderDefinition[],\n): string {\n  const hasDefaultClient = bamlSource.includes(\"client<llm> OpenAI_\")\n  if (hasDefaultClient) {\n    return bamlSource\n  }\n  const defaultClients = generateClientDefinitions(providers)\n  return `${defaultClients}\\n\\n${bamlSource}`\n}\n\n/**\n * Extracts the first function name from BAML source code.\n */\nfunction extractFunctionName(bamlSource: string): string | null {\n  const match = bamlSource.match(/function\\s+(\\w+)\\s*\\(/)\n  return match?.[1] ?? null\n}\n\n/**\n * Parameter type information extracted from BAML function signature.\n */\nexport interface BamlParameterType {\n  name: string\n  type: string\n  isOptional: boolean\n}\n\n/**\n * Extracts function parameter names and types from BAML source code.\n * Used to properly coerce inputs based on expected types.\n */\nexport function extractFunctionParameters(\n  bamlSource: string,\n): BamlParameterType[] {\n  const functionMatch = bamlSource.match(/function\\s+\\w+\\s*\\(([^)]*)\\)\\s*->/)\n  if (!functionMatch) {\n    return []\n  }\n\n  const paramsString = functionMatch[1].trim()\n  if (!paramsString) {\n    return []\n  }\n\n  const params: BamlParameterType[] = []\n  const paramParts = splitParameters(paramsString)\n\n  for (const part of paramParts) {\n    const trimmed = part.trim()\n    if (!trimmed) {\n      continue\n    }\n\n    const paramMatch = trimmed.match(/^(\\w+)\\s*:\\s*(.+)$/)\n    if (paramMatch) {\n      const name = paramMatch[1]\n      let type = paramMatch[2].trim()\n      const isOptional = type.endsWith(\"?\")\n      if (isOptional) {\n        type = type.slice(0, -1)\n      }\n      params.push({ name, type, isOptional })\n    }\n  }\n\n  return params\n}\n\n/**\n * Split parameter string by commas, respecting nested angle brackets.\n */\nfunction splitParameters(paramsString: string): string[] {\n  const parts: string[] = []\n  let current = \"\"\n  let depth = 0\n\n  for (const char of paramsString) {\n    if (char === \"<\") {\n      depth++\n      current += char\n    } else if (char === \">\") {\n      depth--\n      current += char\n    } else if (char === \",\" && depth === 0) {\n      parts.push(current)\n      current = \"\"\n    } else {\n      current += char\n    }\n  }\n\n  if (current.trim()) {\n    parts.push(current)\n  }\n\n  return parts\n}\n\n/**\n * Coerce a single string value to the expected BAML type.\n * Returns the coerced value, or the original string if coercion fails.\n */\nfunction coerceToType(value: string, expectedType: string): unknown {\n  // String type - keep as is\n  if (expectedType === \"string\") {\n    return value\n  }\n\n  // Integer type\n  if (expectedType === \"int\") {\n    const parsed = Number.parseInt(value, 10)\n    if (!Number.isNaN(parsed)) {\n      return parsed\n    }\n    return value\n  }\n\n  // Float type\n  if (expectedType === \"float\") {\n    const parsed = Number.parseFloat(value)\n    if (!Number.isNaN(parsed)) {\n      return parsed\n    }\n    return value\n  }\n\n  // Boolean type\n  if (expectedType === \"bool\") {\n    const lower = value.toLowerCase()\n    if (lower === \"true\") {\n      return true\n    }\n    if (lower === \"false\") {\n      return false\n    }\n    return value\n  }\n\n  // Array types (e.g., string[], int[])\n  if (expectedType.endsWith(\"[]\")) {\n    try {\n      const parsed = JSON.parse(value)\n      if (Array.isArray(parsed)) {\n        return parsed\n      }\n    } catch {\n      // Not valid JSON array\n    }\n    return value\n  }\n\n  // Complex types (objects, classes, maps) - try JSON parse\n  try {\n    return JSON.parse(value)\n  } catch {\n    return value\n  }\n}\n\n/**\n * Coerces input values from strings to their appropriate types based on expected BAML types.\n * Actively coerces to the expected type (int, float, bool, etc.) rather than just avoiding\n * unintended conversions.\n */\nfunction coerceInputs(\n  inputs: Record<string, unknown>,\n  expectedTypes: Map<string, string>,\n): Record<string, unknown> {\n  const coerced: Record<string, unknown> = {}\n\n  for (const [key, value] of Object.entries(inputs)) {\n    if (typeof value === \"string\") {\n      const expectedType = expectedTypes.get(key)\n\n      if (expectedType) {\n        coerced[key] = coerceToType(value, expectedType)\n      } else {\n        // No expected type info - keep as string\n        coerced[key] = value\n      }\n    } else {\n      coerced[key] = value\n    }\n  }\n\n  return coerced\n}\n\n/**\n * Recursively convert an object to a JSON-serializable structure.\n * Similar to Python's _obj_to_dict function.\n */\nfunction objToDict(obj: unknown, depth = 0, maxDepth = 5): unknown {\n  if (depth > maxDepth) {\n    return `<max depth reached: ${typeof obj}>`\n  }\n\n  // Handle primitives\n  if (\n    obj === null ||\n    obj === undefined ||\n    typeof obj === \"string\" ||\n    typeof obj === \"number\" ||\n    typeof obj === \"boolean\"\n  ) {\n    return obj\n  }\n\n  // Handle arrays\n  if (Array.isArray(obj)) {\n    return obj.map((item) => objToDict(item, depth + 1, maxDepth))\n  }\n\n  // Handle plain objects and class instances\n  if (typeof obj === \"object\") {\n    const result: Record<string, unknown> = {}\n\n    // Add type information for non-plain objects\n    if (obj.constructor && obj.constructor.name !== \"Object\") {\n      result.__type__ = obj.constructor.name\n    }\n\n    // Extract all enumerable properties\n    for (const key of Object.keys(obj)) {\n      if (key.startsWith(\"_\")) {\n        continue // Skip private properties\n      }\n\n      try {\n        const value = (obj as Record<string, unknown>)[key]\n\n        // Skip functions\n        if (typeof value === \"function\") {\n          continue\n        }\n\n        result[key] = objToDict(value, depth + 1, maxDepth)\n      } catch (error) {\n        result[key] =\n          `<error: ${error instanceof Error ? error.message : String(error)}>`\n      }\n    }\n\n    // Also try to get non-enumerable properties from the prototype\n    // This helps capture getters and computed properties\n    try {\n      const proto = Object.getPrototypeOf(obj)\n      if (proto && proto !== Object.prototype) {\n        const descriptors = Object.getOwnPropertyDescriptors(proto)\n        for (const [key, descriptor] of Object.entries(descriptors)) {\n          if (key.startsWith(\"_\") || key === \"constructor\" || key in result) {\n            continue\n          }\n\n          // Try to get the value if it has a getter\n          if (descriptor.get) {\n            try {\n              const value = (obj as Record<string, unknown>)[key]\n              if (typeof value !== \"function\") {\n                result[key] = objToDict(value, depth + 1, maxDepth)\n              }\n            } catch {\n              // Getter might throw or be inaccessible\n            }\n          }\n        }\n      }\n    } catch {\n      // Prototype inspection might fail\n    }\n\n    return result\n  }\n\n  // Fallback for other types\n  return String(obj)\n}\n\n/**\n * Serialize the BAML Collector to a JSON-serializable structure.\n * Recursively extracts all properties from the Collector for server-side parsing.\n */\nfunction serializeCollector(\n  collector: unknown,\n): Record<string, unknown> | null {\n  try {\n    return objToDict(collector, 0, 5) as Record<string, unknown>\n  } catch (_error) {\n    // Silently ignore serialization failures\n    return null\n  }\n}\n\n/**\n * Allowed environment variable keys for LLM providers.\n * Only these keys will be passed to the BAML runtime.\n */\nconst ALLOWED_ENV_KEYS = [\"OPENAI_API_KEY\"] as const\n\n/**\n * Type for allowed environment variables.\n * Only OPENAI_API_KEY is currently supported.\n */\nexport type AllowedEnvVars = {\n  OPENAI_API_KEY?: string\n}\n\n/**\n * Filters environment variables to only include allowed keys.\n * This prevents accidentally passing sensitive environment variables to the BAML runtime.\n */\nfunction filterEnvVars(envVars: AllowedEnvVars): Record<string, string> {\n  const filtered: Record<string, string> = {}\n  for (const key of ALLOWED_ENV_KEYS) {\n    const value = envVars[key]\n    if (value) {\n      filtered[key] = value\n    }\n  }\n  return filtered\n}\n\n/**\n * Runs the BAML function with the given inputs using the BAML runtime directly.\n * No file generation or subprocess spawning needed.\n *\n * @param bamlSource - The BAML source code containing the function\n * @param inputs - Named arguments to pass to the function\n * @param providers - Available provider definitions\n * @param envVars - Environment variables for API keys (only OPENAI_API_KEY is allowed)\n * @returns The result and execution metadata of the BAML function call\n */\nexport async function runFunctionWithBaml(\n  bamlSource: string,\n  inputs: Record<string, unknown>,\n  providers: ProviderDefinition[],\n  envVars: AllowedEnvVars,\n): Promise<BamlExecutionResult> {\n  const { BamlRuntime, Collector } = await loadBaml()\n\n  // Extract function name from the BAML source\n  const functionName = extractFunctionName(bamlSource)\n  if (!functionName) {\n    throw new Error(\"No function found in BAML source\")\n  }\n\n  // Add default client definitions (runtime needs them for parsing)\n  const fullSource = withDefaultClients(bamlSource, providers)\n\n  // Filter env vars to only allowed keys\n  const filteredEnvVars = filterEnvVars(envVars)\n\n  // Create runtime from source with env vars\n  const runtime = BamlRuntime.fromFiles(\n    \"/tmp/baml_runtime\",\n    { \"source.baml\": fullSource },\n    filteredEnvVars,\n  )\n\n  // Create context manager\n  const ctx = runtime.createContextManager()\n\n  // Create collector to capture execution metadata\n  const collector = new Collector(\"bitfab-collector\")\n\n  // Extract expected parameter types from BAML source\n  const params = extractFunctionParameters(bamlSource)\n  const expectedTypes = new Map(params.map((p) => [p.name, p.type]))\n\n  // Coerce inputs from strings to proper types based on BAML signature\n  const args = coerceInputs(inputs, expectedTypes)\n\n  // Call the function with collector\n  const functionResult = await runtime.callFunction(\n    functionName,\n    args,\n    ctx,\n    null, // TypeBuilder\n    null, // ClientRegistry\n    [collector], // Collectors - capture execution data\n    {}, // Tags\n    filteredEnvVars,\n  )\n\n  if (!functionResult.isOk()) {\n    throw new Error(\"BAML function execution failed\")\n  }\n\n  // Serialize the collector to a dict for the server to parse\n  const rawCollector = serializeCollector(collector)\n\n  return {\n    result: functionResult.parsed(false),\n    rawCollector,\n  }\n}\n","/**\n * Per-trace database snapshot ref capture.\n *\n * Every root span carries a `DbSnapshotRef` that pins the DB state at trace\n * open by wall-clock timestamp. Capturing the timestamp is free (no IO) and\n * harmless, so it happens on every trace regardless of configuration: that\n * lets any trace be replayed against a historical branch later. A `provider`\n * is attached only when the customer configured `dbSnapshot`; when absent it\n * is resolved at replay time. The Bitfab service uses the timestamp to\n * materialize an ephemeral branch from `customer-main`.\n */\n\nimport { BitfabError } from \"./errors.js\"\n\n// TODO: add more providers as resolvers are built (ardent, dolt, gfs, ...).\nexport const SUPPORTED_PROVIDERS = [\"neon\"] as const\n\nexport type DbSnapshotProvider = (typeof SUPPORTED_PROVIDERS)[number]\n\nexport interface DbSnapshotConfig {\n  /** Discriminator for the server-side resolver. */\n  provider: DbSnapshotProvider\n}\n\nexport interface DbSnapshotRef {\n  /**\n   * The wall-clock ISO timestamp the SDK observed immediately before\n   * invoking the wrapped function. The name encodes its provenance:\n   * SDK-observed, wall clock (not monotonic), captured before user code\n   * began executing. Always present.\n   */\n  sdkWallClockBeforeFn: string\n  /**\n   * The configured provider for server-side branch resolution. Only set when\n   * the customer configured `dbSnapshot`; otherwise the provider is resolved\n   * at replay time.\n   */\n  provider?: DbSnapshotProvider\n}\n\nexport function validateDbSnapshotConfig(config: DbSnapshotConfig): void {\n  if (!SUPPORTED_PROVIDERS.includes(config.provider)) {\n    throw new BitfabError(\n      `dbSnapshot.provider \"${config.provider}\" is not supported. Supported providers: ${SUPPORTED_PROVIDERS.join(\", \")}.`,\n    )\n  }\n}\n\n/**\n * Build a snapshot ref for one trace. Synchronous, no IO. Always stores the\n * wall clock the SDK observed immediately before invoking the wrapped\n * function; the resolver uses that as the Neon snapshot timestamp. The\n * `provider` is included only when `dbSnapshot` was configured (`config`\n * present); otherwise it is resolved at replay time.\n */\nexport function buildSnapshotRef(\n  config: DbSnapshotConfig | undefined,\n  sdkWallClockBeforeFn: string,\n): DbSnapshotRef {\n  return {\n    sdkWallClockBeforeFn,\n    ...(config && { provider: config.provider }),\n  }\n}\n","/**\n * LangGraph/LangChain callback handler for Bitfab tracing.\n *\n * Hooks into LangGraph's callback system to capture graph node execution,\n * LLM calls, and tool invocations as Bitfab spans, without requiring users\n * to wrap their functions with withSpan (which fails on non-serializable args).\n *\n * Duck-typed to match LangChain.js's BaseCallbackHandler interface.\n * No @langchain/core dependency required.\n */\n\nimport { DEFAULT_SERVICE_URL } from \"./constants.js\"\nimport { type ApiKeyInput, HttpClient } from \"./http.js\"\nimport {\n  finalizeSpanPayload,\n  finalizeTracePayload,\n} from \"./processorPayload.js\"\nimport { randomUuid } from \"./randomUuid.js\"\nimport { toJsonSafeReport } from \"./serialize.js\"\n\nexport interface ActiveSpanContext {\n  traceId: string\n  spanId: string\n}\n\ninterface SpanInfo {\n  spanId: string\n  traceId: string\n  rootRunId: string\n  parentId: string | null\n  startedAt: string\n  endedAt?: string\n  name: string\n  type: string\n  input?: unknown\n  output?: unknown\n  error?: string\n  contexts: Array<Record<string, unknown>>\n  model?: string\n  hidden?: boolean\n  // Type names of input/output values that could only be captured as\n  // placeholders. Carried to the send boundary so finalizeSpanPayload can mark\n  // the span non-replayable.\n  dropped?: string[]\n}\n\ninterface InvocationState {\n  traceId: string\n  activeContext: ActiveSpanContext | null\n  rootRunId: string\n}\n\nconst LANGSMITH_HIDDEN_TAG = \"langsmith:hidden\"\n\nconst CHAIN_RUN_TYPES = new Set([\"chain\", \"parser\", \"prompt\"])\n\nconst LANGGRAPH_METADATA_KEYS = [\n  \"langgraph_step\",\n  \"langgraph_node\",\n  \"langgraph_triggers\",\n  \"langgraph_path\",\n  \"langgraph_checkpoint_ns\",\n] as const\n\nfunction nowIso(): string {\n  return new Date().toISOString()\n}\n\nfunction normalizeChainStartArgs(\n  parentRunIdOrRunType?: string,\n  runTypeOrRunName?: string,\n  runNameOrParentRunId?: string,\n): { parentRunId?: string; runName?: string } {\n  if (parentRunIdOrRunType && CHAIN_RUN_TYPES.has(parentRunIdOrRunType)) {\n    return {\n      parentRunId: runNameOrParentRunId,\n      runName: runTypeOrRunName,\n    }\n  }\n\n  return {\n    parentRunId: parentRunIdOrRunType,\n    runName: runNameOrParentRunId,\n  }\n}\n\nfunction convertMessage(message: unknown): Record<string, unknown> {\n  if (typeof message !== \"object\" || message === null) {\n    return { role: \"unknown\", content: String(message) }\n  }\n\n  const msg = message as Record<string, unknown>\n\n  if (typeof msg.toDict === \"function\") {\n    return (msg as { toDict(): Record<string, unknown> }).toDict()\n  }\n\n  const typeToRole: Record<string, string> = {\n    human: \"user\",\n    ai: \"assistant\",\n    system: \"system\",\n    tool: \"tool\",\n    function: \"function\",\n  }\n\n  const result: Record<string, unknown> = {}\n\n  const msgType = msg._getType\n    ? String((msg as { _getType(): string })._getType())\n    : (msg.type as string | undefined)\n\n  result.role =\n    (msgType ? typeToRole[msgType] : undefined) ?? msg.role ?? \"unknown\"\n  result.content = msg.content ?? \"\"\n\n  if (msg.tool_calls) {\n    result.tool_calls = msg.tool_calls\n  }\n  if (msg.tool_call_id) {\n    result.tool_call_id = msg.tool_call_id\n  }\n  if (msg.name) {\n    result.name = msg.name\n  }\n\n  return result\n}\n\nfunction extractModelName(\n  serialized: Record<string, unknown> | undefined,\n  metadata: Record<string, unknown> | undefined,\n): string | undefined {\n  if (serialized) {\n    const kwargs = serialized.kwargs as Record<string, unknown> | undefined\n    if (kwargs) {\n      const model = kwargs.model_name ?? kwargs.model ?? kwargs.model_id\n      if (model) {\n        return String(model)\n      }\n    }\n  }\n  if (metadata) {\n    const lsModel = metadata.ls_model_name\n    if (lsModel) {\n      return String(lsModel)\n    }\n  }\n  return undefined\n}\n\ninterface NormalizedUsage {\n  inputTokens: number | null\n  outputTokens: number | null\n  totalTokens: number | null\n  cachedInputTokens: number | null\n}\n\nfunction asTokenCount(value: unknown): number | null {\n  return typeof value === \"number\" && Number.isFinite(value) ? value : null\n}\n\n/**\n * Normalize a provider-reported token-usage dict into Bitfab's span fields.\n *\n * Handles, in priority order:\n * - Anthropic native (`input_tokens` EXCLUDES cache reads/creation, so they\n *   are added back to get the true prompt size)\n * - OpenAI native (`prompt_tokens` / `completion_tokens`, snake or camel case)\n * - Google Gemini / Vertex native (`prompt_token_count` / `candidates_token_count`)\n * - LangChain normalized `usage_metadata` (`input_tokens` / `output_tokens` /\n *   `total_tokens` with `input_token_details.cache_read`)\n *\n * Returns null when the value carries no recognizable token counts. Never\n * estimates: only provider-reported numbers are returned.\n */\nfunction normalizeTokenUsage(raw: unknown): NormalizedUsage | null {\n  if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) {\n    return null\n  }\n  const u = raw as Record<string, unknown>\n\n  // Anthropic native: input_tokens excludes cached reads and cache writes.\n  if (\"cache_read_input_tokens\" in u || \"cache_creation_input_tokens\" in u) {\n    const cacheRead = asTokenCount(u.cache_read_input_tokens)\n    const cacheCreation = asTokenCount(u.cache_creation_input_tokens)\n    const baseInput = asTokenCount(u.input_tokens)\n    const outputTokens = asTokenCount(u.output_tokens)\n    if (\n      cacheRead === null &&\n      cacheCreation === null &&\n      baseInput === null &&\n      outputTokens === null\n    ) {\n      return null\n    }\n    const inputTokens =\n      (baseInput ?? 0) + (cacheRead ?? 0) + (cacheCreation ?? 0)\n    return {\n      inputTokens,\n      outputTokens,\n      totalTokens: inputTokens + (outputTokens ?? 0),\n      cachedInputTokens: cacheRead,\n    }\n  }\n\n  // OpenAI native (snake_case) and LangChain.js legacy llmOutput (camelCase).\n  if (\n    \"prompt_tokens\" in u ||\n    \"completion_tokens\" in u ||\n    \"promptTokens\" in u ||\n    \"completionTokens\" in u\n  ) {\n    const promptDetails = (u.prompt_tokens_details ?? {}) as Record<\n      string,\n      unknown\n    >\n    return withAnyTokenCount({\n      inputTokens:\n        asTokenCount(u.prompt_tokens) ?? asTokenCount(u.promptTokens),\n      outputTokens:\n        asTokenCount(u.completion_tokens) ?? asTokenCount(u.completionTokens),\n      totalTokens: asTokenCount(u.total_tokens) ?? asTokenCount(u.totalTokens),\n      cachedInputTokens: asTokenCount(promptDetails.cached_tokens),\n    })\n  }\n\n  // Google Gemini / Vertex native.\n  if (\"prompt_token_count\" in u || \"candidates_token_count\" in u) {\n    return withAnyTokenCount({\n      inputTokens: asTokenCount(u.prompt_token_count),\n      outputTokens: asTokenCount(u.candidates_token_count),\n      totalTokens: asTokenCount(u.total_token_count),\n      cachedInputTokens: asTokenCount(u.cached_content_token_count),\n    })\n  }\n\n  // LangChain normalized usage_metadata (also plain Anthropic without cache keys).\n  if (\"input_tokens\" in u || \"output_tokens\" in u) {\n    const inputDetails = (u.input_token_details ?? {}) as Record<\n      string,\n      unknown\n    >\n    const inputTokens = asTokenCount(u.input_tokens)\n    const outputTokens = asTokenCount(u.output_tokens)\n    let totalTokens = asTokenCount(u.total_tokens)\n    if (totalTokens === null && inputTokens !== null && outputTokens !== null) {\n      totalTokens = inputTokens + outputTokens\n    }\n    return withAnyTokenCount({\n      inputTokens,\n      outputTokens,\n      totalTokens,\n      cachedInputTokens: asTokenCount(inputDetails.cache_read),\n    })\n  }\n\n  return null\n}\n\n/**\n * A recognizable usage shape whose values are all null/non-numeric carries no\n * usage. Returning null lets extraction fall through to the next source\n * (response_metadata, then legacy llm_output) instead of blocking it.\n */\nfunction withAnyTokenCount(usage: NormalizedUsage): NormalizedUsage | null {\n  const hasCount =\n    usage.inputTokens !== null ||\n    usage.outputTokens !== null ||\n    usage.totalTokens !== null ||\n    usage.cachedInputTokens !== null\n  return hasCount ? usage : null\n}\n\nfunction addUsage(totals: NormalizedUsage, usage: NormalizedUsage): void {\n  for (const key of [\n    \"inputTokens\",\n    \"outputTokens\",\n    \"totalTokens\",\n    \"cachedInputTokens\",\n  ] as const) {\n    const value = usage[key]\n    if (value !== null) {\n      totals[key] = (totals[key] ?? 0) + value\n    }\n  }\n}\n\n/**\n * Extract usage from each generation's message: the standardized\n * `usage_metadata` (set by modern LangChain chat models, including the final\n * aggregated chunk of streaming runs), falling back to provider-native\n * `response_metadata`. Sums across generations when a result has several.\n */\nfunction usageFromGenerations(\n  generations: unknown[][] | undefined,\n): NormalizedUsage | null {\n  if (!generations?.length) {\n    return null\n  }\n  const totals: NormalizedUsage = {\n    inputTokens: null,\n    outputTokens: null,\n    totalTokens: null,\n    cachedInputTokens: null,\n  }\n  let found = false\n  for (const batch of generations) {\n    if (!Array.isArray(batch)) {\n      continue\n    }\n    for (const gen of batch) {\n      const msg = (gen as Record<string, unknown> | null)?.message as\n        | Record<string, unknown>\n        | undefined\n      if (!msg || typeof msg !== \"object\") {\n        continue\n      }\n      const responseMetadata = msg.response_metadata as\n        | Record<string, unknown>\n        | undefined\n      const usage =\n        normalizeTokenUsage(msg.usage_metadata) ??\n        normalizeTokenUsage(responseMetadata?.token_usage) ??\n        normalizeTokenUsage(responseMetadata?.usage) ??\n        normalizeTokenUsage(responseMetadata?.tokenUsage)\n      if (!usage) {\n        continue\n      }\n      found = true\n      addUsage(totals, usage)\n    }\n  }\n  return found ? totals : null\n}\n\n/**\n * Extract token usage from an LLM result.\n *\n * Resolution order: per-generation `message.usage_metadata` (normalized,\n * provider-agnostic), then `message.response_metadata` token usage, then the\n * legacy `llmOutput.tokenUsage` / `token_usage` / `usage` location. Fields\n * with no provider-reported value are omitted; nothing is ever estimated.\n */\nfunction extractUsage(\n  output: Record<string, unknown>,\n): Record<string, unknown> {\n  const generations = output.generations as unknown[][] | undefined\n  const llmOutput = (output.llmOutput ?? output.llm_output) as\n    | Record<string, unknown>\n    | undefined\n\n  const normalized =\n    usageFromGenerations(generations) ??\n    normalizeTokenUsage(llmOutput?.tokenUsage) ??\n    normalizeTokenUsage(llmOutput?.token_usage) ??\n    normalizeTokenUsage(llmOutput?.usage)\n\n  const usage: Record<string, unknown> = {}\n  if (!normalized) {\n    return usage\n  }\n  if (normalized.inputTokens !== null) {\n    usage.inputTokens = normalized.inputTokens\n  }\n  if (normalized.outputTokens !== null) {\n    usage.outputTokens = normalized.outputTokens\n  }\n  if (normalized.totalTokens !== null) {\n    usage.totalTokens = normalized.totalTokens\n  }\n  if (normalized.cachedInputTokens !== null) {\n    usage.cachedInputTokens = normalized.cachedInputTokens\n  }\n\n  return usage\n}\n\nfunction extractLangGraphMetadata(\n  metadata: Record<string, unknown> | undefined,\n): Record<string, unknown> {\n  if (!metadata) {\n    return {}\n  }\n  const result: Record<string, unknown> = {}\n  for (const key of LANGGRAPH_METADATA_KEYS) {\n    if (key in metadata) {\n      result[key] = metadata[key]\n    }\n  }\n  return result\n}\n\n/**\n * LangChain/LangGraph callback handler that sends traces to Bitfab.\n *\n * Duck-typed to match LangChain.js's BaseCallbackHandler, so no\n * `@langchain/core` dependency is required. Pass as a callback:\n *\n * ```typescript\n * const handler = bitfab.getLangGraphCallbackHandler(\"my-agent\");\n * const result = await agent.invoke(\n *   { messages: [...] },\n *   { callbacks: [handler] },\n * );\n * ```\n */\nexport class BitfabLangGraphCallbackHandler {\n  name = \"BitfabLangGraphCallbackHandler\"\n\n  ignoreRetry = true\n  // Retriever callbacks ARE captured (retriever queries -> function spans).\n  ignoreRetriever = false\n  ignoreCustomEvent = true\n\n  private readonly httpClient: HttpClient\n  private readonly traceFunctionKey: string\n  private readonly getActiveSpanContext: (() => ActiveSpanContext | null) | null\n\n  private runToSpan: Map<string, SpanInfo> = new Map()\n  private invocations: Map<string, InvocationState> = new Map()\n\n  constructor(config: {\n    apiKey?: ApiKeyInput\n    traceFunctionKey: string\n    serviceUrl?: string\n    timeout?: number\n    getActiveSpanContext?: () => ActiveSpanContext | null\n  }) {\n    this.httpClient = new HttpClient({\n      apiKey: config.apiKey,\n      serviceUrl: config.serviceUrl ?? DEFAULT_SERVICE_URL,\n      timeout: config.timeout ?? 10000,\n    })\n    this.traceFunctionKey = config.traceFunctionKey\n    this.getActiveSpanContext = config.getActiveSpanContext ?? null\n  }\n\n  // ── lifecycle helpers ──────────────────────────────────────────\n\n  private startSpan(\n    runId: string,\n    parentRunId: string | undefined,\n    name: string,\n    spanType: string,\n    inputData?: unknown,\n    metadata?: Record<string, unknown>,\n    tags?: string[],\n  ): SpanInfo {\n    // If we have a tracked parent, inherit its invocation. Otherwise this\n    // callback is the root of a fresh invocation: capture the outer Bitfab\n    // span context now so concurrent invocations don't overwrite each other.\n    const parentSpan = parentRunId ? this.runToSpan.get(parentRunId) : undefined\n    const willHide = tags?.includes(LANGSMITH_HIDDEN_TAG) === true\n\n    let invocation: InvocationState\n    let effectiveParentId: string | null\n    let isRootInvocation = false\n    if (parentSpan) {\n      const existing = this.invocations.get(parentSpan.rootRunId)\n      if (existing) {\n        invocation = existing\n      } else {\n        invocation = {\n          traceId: parentSpan.traceId,\n          activeContext: null,\n          rootRunId: parentSpan.rootRunId,\n        }\n        this.invocations.set(invocation.rootRunId, invocation)\n      }\n      // If this visible span's parent is hidden, walk up to the nearest\n      // visible ancestor so the server can drop hidden spans without leaving\n      // the visible child as an orphan.\n      if (!willHide) {\n        let resolved: SpanInfo | undefined = parentSpan\n        while (resolved?.hidden === true) {\n          resolved = resolved.parentId\n            ? this.runToSpan.get(resolved.parentId)\n            : undefined\n        }\n        effectiveParentId = resolved\n          ? resolved.spanId\n          : (invocation.activeContext?.spanId ?? null)\n      } else {\n        effectiveParentId = parentRunId ?? null\n      }\n    } else {\n      const activeContext = this.getActiveSpanContext?.() ?? null\n      invocation = {\n        traceId: activeContext ? activeContext.traceId : randomUuid(),\n        activeContext,\n        rootRunId: runId,\n      }\n      this.invocations.set(runId, invocation)\n      effectiveParentId = activeContext?.spanId ?? null\n      isRootInvocation = true\n    }\n\n    const lgMetadata = extractLangGraphMetadata(metadata)\n    const contexts: Array<Record<string, unknown>> =\n      Object.keys(lgMetadata).length > 0 ? [lgMetadata] : []\n\n    const { safe: safeInput, dropped: inputDropped } =\n      toJsonSafeReport(inputData)\n    const spanInfo: SpanInfo = {\n      spanId: runId,\n      traceId: invocation.traceId,\n      rootRunId: invocation.rootRunId,\n      parentId: effectiveParentId,\n      startedAt: nowIso(),\n      name,\n      type: spanType,\n      input: safeInput,\n      contexts,\n    }\n    if (inputDropped.length > 0) {\n      spanInfo.dropped = [...inputDropped]\n    }\n    if (willHide) {\n      spanInfo.hidden = true\n    }\n    this.runToSpan.set(runId, spanInfo)\n    if (isRootInvocation) {\n      this.sendTraceStart(spanInfo)\n    }\n    return spanInfo\n  }\n\n  private completeSpan(\n    runId: string,\n    output?: unknown,\n    error?: string,\n    extraContexts?: Record<string, unknown>,\n  ): void {\n    const spanInfo = this.runToSpan.get(runId)\n    if (!spanInfo) {\n      return\n    }\n    this.runToSpan.delete(runId)\n\n    spanInfo.endedAt = nowIso()\n    const { safe: safeOutput, dropped: outputDropped } =\n      toJsonSafeReport(output)\n    spanInfo.output = safeOutput\n    if (outputDropped.length > 0) {\n      spanInfo.dropped = [...(spanInfo.dropped ?? []), ...outputDropped]\n    }\n    if (error !== undefined) {\n      spanInfo.error = error\n    }\n\n    if (extraContexts && Object.keys(extraContexts).length > 0) {\n      spanInfo.contexts.push(extraContexts)\n    }\n\n    this.sendSpan(spanInfo)\n\n    if (runId === spanInfo.rootRunId) {\n      const invocation = this.invocations.get(runId)\n      this.sendTraceCompletion(spanInfo, invocation?.activeContext ?? null)\n      this.invocations.delete(runId)\n    }\n  }\n\n  private sendSpan(spanInfo: SpanInfo): void {\n    const spanData: Record<string, unknown> = {\n      name: spanInfo.name,\n      type: spanInfo.type,\n    }\n    if (spanInfo.input !== undefined) {\n      spanData.input = spanInfo.input\n    }\n    if (spanInfo.output !== undefined) {\n      spanData.output = spanInfo.output\n    }\n    if (spanInfo.error !== undefined) {\n      spanData.error = spanInfo.error\n    }\n    if (spanInfo.contexts.length > 0) {\n      spanData.contexts = spanInfo.contexts\n    }\n    if (spanInfo.hidden) {\n      spanData.hidden = true\n    }\n\n    const rawSpan: Record<string, unknown> = {\n      id: spanInfo.spanId,\n      trace_id: spanInfo.traceId,\n      started_at: spanInfo.startedAt,\n      ended_at: spanInfo.endedAt ?? nowIso(),\n      span_data: spanData,\n    }\n    if (spanInfo.parentId !== null) {\n      rawSpan.parent_id = spanInfo.parentId\n    }\n\n    const payload: Record<string, unknown> = {\n      type: \"sdk-function\",\n      source: \"typescript-sdk-langgraph\",\n      traceFunctionKey: this.traceFunctionKey,\n      sourceTraceId: spanInfo.traceId,\n      rawSpan,\n    }\n\n    // Sanitize the whole span and mark a lossy capture non-replayable.\n    // spanInfo.dropped carries losses from the capture-time input/output\n    // snapshot above.\n    const finalized = finalizeSpanPayload(payload, spanInfo.dropped)\n\n    try {\n      this.httpClient.sendExternalSpan(finalized)\n    } catch {\n      // Never crash the host app\n    }\n  }\n\n  private sendTraceCompletion(\n    rootSpan: SpanInfo,\n    activeContext: ActiveSpanContext | null,\n  ): void {\n    const completed = activeContext === null\n\n    const traceData: Record<string, unknown> = {\n      type: \"sdk-function\",\n      source: \"typescript-sdk-langgraph\",\n      traceFunctionKey: this.traceFunctionKey,\n      externalTrace: {\n        id: rootSpan.traceId,\n        started_at: rootSpan.startedAt,\n        ended_at: rootSpan.endedAt ?? nowIso(),\n        workflow_name: this.traceFunctionKey,\n      },\n      completed,\n    }\n\n    const finalized = finalizeTracePayload(traceData)\n\n    try {\n      this.httpClient.sendExternalTrace(finalized)\n    } catch {\n      // Never crash the host app\n    }\n  }\n\n  private sendTraceStart(rootSpan: SpanInfo): void {\n    const traceData: Record<string, unknown> = {\n      type: \"sdk-function\",\n      source: \"typescript-sdk-langgraph\",\n      traceFunctionKey: this.traceFunctionKey,\n      externalTrace: {\n        id: rootSpan.traceId,\n        started_at: rootSpan.startedAt,\n        workflow_name: this.traceFunctionKey,\n      },\n      completed: false,\n    }\n\n    const finalized = finalizeTracePayload(traceData)\n\n    try {\n      this.httpClient.sendExternalTrace(finalized)\n    } catch {\n      // Never crash the host app\n    }\n  }\n\n  // ── chain callbacks (graph nodes) ─────────────────────────────\n\n  async handleChainStart(\n    chain: Record<string, unknown> | null | undefined,\n    inputs: Record<string, unknown>,\n    runId: string,\n    parentRunIdOrRunType?: string,\n    tags?: string[],\n    metadata?: Record<string, unknown>,\n    runTypeOrRunName?: string,\n    runNameOrParentRunId?: string,\n  ): Promise<void> {\n    try {\n      const { parentRunId, runName } = normalizeChainStartArgs(\n        parentRunIdOrRunType,\n        runTypeOrRunName,\n        runNameOrParentRunId,\n      )\n      const serialized = chain ?? {}\n      const idArr = serialized.id as string[] | undefined\n      const name =\n        runName ??\n        (serialized.name as string) ??\n        idArr?.[idArr.length - 1] ??\n        \"chain\"\n      this.startSpan(\n        runId,\n        parentRunId,\n        String(name),\n        \"agent\",\n        inputs,\n        metadata,\n        tags,\n      )\n    } catch {\n      // Never crash the host app\n    }\n  }\n\n  async handleChainEnd(\n    outputs: Record<string, unknown>,\n    runId: string,\n  ): Promise<void> {\n    try {\n      this.completeSpan(runId, outputs)\n    } catch {\n      // Never crash the host app\n    }\n  }\n\n  async handleChainError(error: unknown, runId: string): Promise<void> {\n    try {\n      const errorObj = error as { constructor?: { name?: string } }\n      if (errorObj?.constructor?.name === \"GraphBubbleUp\") {\n        this.completeSpan(runId, undefined, undefined)\n        return\n      }\n      this.completeSpan(\n        runId,\n        undefined,\n        error instanceof Error ? error.message : String(error),\n      )\n    } catch {\n      // Never crash the host app\n    }\n  }\n\n  // ── LLM callbacks ─────────────────────────────────────────────\n\n  async handleChatModelStart(\n    llm: Record<string, unknown> | null | undefined,\n    messages: unknown[][],\n    runId: string,\n    parentRunId?: string,\n    _extraParams?: Record<string, unknown>,\n    tags?: string[],\n    metadata?: Record<string, unknown>,\n    runName?: string,\n  ): Promise<void> {\n    try {\n      const serialized = llm ?? {}\n      const model = extractModelName(serialized, metadata)\n      const idArr = serialized.id as string[] | undefined\n      const name = runName ?? model ?? idArr?.[idArr.length - 1] ?? \"llm\"\n      const converted = messages.map((batch) => batch.map(convertMessage))\n\n      const spanInfo = this.startSpan(\n        runId,\n        parentRunId,\n        String(name),\n        \"llm\",\n        converted,\n        metadata,\n        tags,\n      )\n      spanInfo.model = model\n    } catch {\n      // Never crash the host app\n    }\n  }\n\n  async handleLLMStart(\n    llm: Record<string, unknown> | null | undefined,\n    prompts: string[],\n    runId: string,\n    parentRunId?: string,\n    _extraParams?: Record<string, unknown>,\n    tags?: string[],\n    metadata?: Record<string, unknown>,\n    runName?: string,\n  ): Promise<void> {\n    try {\n      const serialized = llm ?? {}\n      const model = extractModelName(serialized, metadata)\n      const idArr = serialized.id as string[] | undefined\n      const name = runName ?? model ?? idArr?.[idArr.length - 1] ?? \"llm\"\n\n      const spanInfo = this.startSpan(\n        runId,\n        parentRunId,\n        String(name),\n        \"llm\",\n        prompts,\n        metadata,\n        tags,\n      )\n      spanInfo.model = model\n    } catch {\n      // Never crash the host app\n    }\n  }\n\n  async handleLLMEnd(\n    output: Record<string, unknown>,\n    runId: string,\n  ): Promise<void> {\n    try {\n      let llmOutput: unknown\n      const generations = output.generations as unknown[][] | undefined\n      if (generations?.length && generations[generations.length - 1]?.length) {\n        const gen = generations[generations.length - 1][\n          generations[generations.length - 1].length - 1\n        ] as Record<string, unknown>\n        const msg = gen.message as Record<string, unknown> | undefined\n        llmOutput = msg ? convertMessage(msg) : (gen.text ?? String(gen))\n      }\n\n      const usage = extractUsage(output)\n      const spanInfo = this.runToSpan.get(runId)\n      const model = spanInfo?.model\n\n      const llmContext: Record<string, unknown> = {}\n      if (model) {\n        llmContext.model = model\n      }\n      Object.assign(llmContext, usage)\n\n      this.completeSpan(\n        runId,\n        llmOutput,\n        undefined,\n        Object.keys(llmContext).length > 0 ? llmContext : undefined,\n      )\n    } catch {\n      // Never crash the host app\n    }\n  }\n\n  async handleLLMError(error: unknown, runId: string): Promise<void> {\n    try {\n      this.completeSpan(\n        runId,\n        undefined,\n        error instanceof Error ? error.message : String(error),\n      )\n    } catch {\n      // Never crash the host app\n    }\n  }\n\n  async handleLLMNewToken(): Promise<void> {\n    // Intentionally empty: per-token events are not traced. Usage for\n    // streaming runs is captured in handleLLMEnd from the final aggregated\n    // chunk's usage_metadata / response_metadata.\n  }\n\n  // ── tool callbacks ────────────────────────────────────────────\n\n  async handleToolStart(\n    tool: Record<string, unknown> | null | undefined,\n    input: string,\n    runId: string,\n    parentRunId?: string,\n    tags?: string[],\n    metadata?: Record<string, unknown>,\n    runName?: string,\n  ): Promise<void> {\n    try {\n      const serialized = tool ?? {}\n      const name = runName ?? (serialized.name as string) ?? \"tool\"\n      this.startSpan(\n        runId,\n        parentRunId,\n        String(name),\n        \"function\",\n        input,\n        metadata,\n        tags,\n      )\n    } catch {\n      // Never crash the host app\n    }\n  }\n\n  async handleToolEnd(output: unknown, runId: string): Promise<void> {\n    try {\n      this.completeSpan(runId, output)\n    } catch {\n      // Never crash the host app\n    }\n  }\n\n  async handleToolError(error: unknown, runId: string): Promise<void> {\n    try {\n      this.completeSpan(\n        runId,\n        undefined,\n        error instanceof Error ? error.message : String(error),\n      )\n    } catch {\n      // Never crash the host app\n    }\n  }\n\n  // ── retriever callbacks ───────────────────────────────────────\n\n  async handleRetrieverStart(\n    retriever: Record<string, unknown> | null | undefined,\n    query: string,\n    runId: string,\n    parentRunId?: string,\n    tags?: string[],\n    metadata?: Record<string, unknown>,\n    runName?: string,\n  ): Promise<void> {\n    try {\n      const serialized = retriever ?? {}\n      const name = runName ?? (serialized.name as string) ?? \"retriever\"\n      this.startSpan(\n        runId,\n        parentRunId,\n        String(name),\n        \"function\",\n        query,\n        metadata,\n        tags,\n      )\n    } catch {\n      // Never crash the host app\n    }\n  }\n\n  async handleRetrieverEnd(documents: unknown, runId: string): Promise<void> {\n    try {\n      this.completeSpan(runId, documents)\n    } catch {\n      // Never crash the host app\n    }\n  }\n\n  async handleRetrieverError(error: unknown, runId: string): Promise<void> {\n    try {\n      this.completeSpan(\n        runId,\n        undefined,\n        error instanceof Error ? error.message : String(error),\n      )\n    } catch {\n      // Never crash the host app\n    }\n  }\n}\n","/**\n * OpenAI Agents SDK handler for Bitfab tracing.\n *\n * The OpenAI Agents SDK is instrumented in two layers:\n *\n *   1. A process-wide `TracingProcessor` (see `getOpenAiTracingProcessor` /\n *      `BitfabOpenAITracingProcessor`) registered once with `addTraceProcessor`.\n *      It captures everything *inside* a run - LLM calls, tool calls, handoffs -\n *      as Bitfab spans.\n *   2. This handler's `wrapRun`, which owns the *root*. The processor never sees\n *      the caller's input (the SDK's trace events don't carry it), so a\n *      processor-only run records a root span with an empty input and is not\n *      replayable. `wrapRun` is a thin drop-in for `run()` that opens a\n *      `withSpan` root carrying the input and final output, so the run is\n *      replayable with no hand-written `withSpan`. The processor's spans nest\n *      underneath it automatically (it remaps onto the active span context).\n *\n * When `wrapRun` runs inside an enclosing Bitfab span (the replay auto-wrap, or\n * a caller's own `withSpan`), that span is already the replayable root: the\n * handler skips opening a second one and lets the processor nest the run's spans\n * under the existing root. This mirrors the Claude Agent SDK and LangGraph\n * handlers, which no-op their root span under an enclosing span, and keeps a\n * replayed run's span tree identical to the original (no doubled root agent\n * span).\n *\n * Use both together: register the processor once at startup, then call\n * `handler.wrapRun(agent, input)` instead of `run(agent, input)`.\n */\n\nimport { importOptionalPeer } from \"./optionalPeer.js\"\n\n// Local structural stand-ins for the OpenAI Agents SDK types this handler\n// touches. Declared here so neither this module nor the SDK's published `.d.ts`\n// references `@openai/agents` (an optional peer most consumers never install):\n// a top-level `import ... from \"@openai/agents\"` in the shipped types breaks a\n// consumer's `tsc` under `skipLibCheck: false` even when they never use this\n// handler. The stand-ins are deliberately loose supersets, so a consumer's real\n// `Agent` / run input is still assignable when they DO call `wrapRun`. The\n// concrete `@openai/agents` types enter only inside the function body (via\n// `importOptionalPeer<typeof import(\"@openai/agents\")>`), which the declaration\n// output erases.\n\n// biome-ignore lint/suspicious/noExplicitAny: structural stand-in for the agent SDK's `Agent<any, any>`\ntype AgentLike = any\n\n// The run input union `run()` accepts: a prompt string, a list of input items,\n// or a serialized run state. Items/state are opaque here (we only forward them).\ntype RunInput = string | unknown[] | Record<string, unknown>\n\n// The run options `run()` accepts; only `stream` is read by this handler.\ntype RunOptions = {\n  stream?: boolean\n} & Record<string, unknown>\n\n// What this handler reads off a run result: streamed runs expose `completed`,\n// both variants expose `finalOutput`.\ntype RunResultLike = {\n  finalOutput?: unknown\n  completed?: Promise<void>\n}\n\n// The exact span options this handler passes to `withSpan`. Declared locally\n// (a structural subset of the client's `SpanOptions`, so the bound `withSpan`\n// is assignable) rather than imported from client.ts - that would create an\n// import cycle, since client.ts imports this handler. Mirrors how the other\n// framework handlers stay free of any client import.\ntype RootSpanOptions = {\n  type: \"agent\"\n  finalize: (result: unknown) => unknown | Promise<unknown>\n}\n\n// The subset of the Bitfab client this handler needs: a bound `withSpan`.\ntype WithSpanFn = <TArgs extends unknown[], TReturn>(\n  traceFunctionKey: string,\n  options: RootSpanOptions,\n  fn: (...args: TArgs) => TReturn,\n) => (...args: TArgs) => TReturn\n\n// Returns the active Bitfab span context (or null) so wrapRun can detect an\n// enclosing span and skip opening its own root. Only nullness is read, so the\n// context shape is left opaque (avoids importing SpanContext from client.ts,\n// which would create an import cycle).\ntype GetActiveSpanContextFn = () => unknown | null\n\n/**\n * OpenAI Agents SDK handler that records a replayable root span around a run.\n *\n * ```typescript\n * import { Bitfab } from \"@bitfab/sdk\";\n * import { addTraceProcessor, Agent, run } from \"@openai/agents\";\n *\n * const bitfab = new Bitfab({ apiKey: \"...\" });\n * addTraceProcessor(bitfab.getOpenAiTracingProcessor()); // captures internals\n *\n * const agent = new Agent({ name: \"Researcher\", instructions: \"...\" });\n * const handler = bitfab.getOpenAiAgentHandler(\"research-topic\");\n *\n * // Swap run(agent, input) -> handler.wrapRun(agent, input)\n * const result = await handler.wrapRun(agent, \"Find X\");\n * return result.finalOutput;\n * ```\n */\nexport class BitfabOpenAIAgentHandler {\n  private readonly traceFunctionKey: string\n  private readonly withSpanFn: WithSpanFn\n  private readonly getActiveSpanContext?: GetActiveSpanContextFn\n\n  constructor(config: {\n    traceFunctionKey: string\n    withSpan: WithSpanFn\n    getActiveSpanContext?: GetActiveSpanContextFn\n  }) {\n    this.traceFunctionKey = config.traceFunctionKey\n    this.withSpanFn = config.withSpan\n    this.getActiveSpanContext = config.getActiveSpanContext\n  }\n\n  /**\n   * Drop-in replacement for the OpenAI Agents SDK's `run()` that records a\n   * replayable root `agent` span.\n   *\n   * The `input` is captured as the root span's input (as a single positional\n   * argument, so `replay(key, fn)` re-feeds it), and the run's `finalOutput`\n   * is recorded as the root output. For streaming runs (`{ stream: true }`),\n   * the result is handed back immediately and the final output is recorded\n   * once the stream completes - first-byte latency is untouched.\n   *\n   * The process-wide tracing processor (`getOpenAiTracingProcessor`) must still\n   * be registered: it captures the LLM/tool/handoff spans that nest beneath\n   * this root.\n   */\n  async wrapRun(\n    agent: AgentLike,\n    input: RunInput,\n    options?: RunOptions,\n  ): Promise<RunResultLike> {\n    // Dynamic import keeps `@openai/agents` an optional peer dependency and\n    // matches the SDK's browser-safe import rules (no static Node/agent SDK\n    // imports). Callers of this handler necessarily have the package installed.\n    // Routed through `importOptionalPeer` so the specifier never appears as a\n    // literal - otherwise a consumer's bundler tries to resolve `@openai/agents`\n    // at build time and fails even when they never use this handler.\n    const { run } = await importOptionalPeer<typeof import(\"@openai/agents\")>([\n      \"@openai\",\n      \"agents\",\n    ])\n\n    // The local stand-in types are looser than `run()`'s real parameters, so\n    // cast at the call boundary. These casts live in the function body, which\n    // the declaration output erases, so no `@openai/agents` reference leaks\n    // into the published `.d.ts`.\n    type RunInputArg = Parameters<typeof run>[1]\n    type RunOptionsArg = Parameters<typeof run>[2]\n\n    // An enclosing span is already the replayable root: run directly and let the\n    // processor nest the run's spans under it, instead of opening (and doubling)\n    // a second root agent span. Covers the replay auto-wrap and a caller's own\n    // withSpan; mirrors the Claude Agent SDK and LangGraph handlers.\n    if (this.getActiveSpanContext?.() != null) {\n      return run(\n        agent,\n        input as RunInputArg,\n        options as RunOptionsArg,\n      ) as Promise<RunResultLike>\n    }\n\n    const isStreaming = options?.stream === true\n\n    // The recorded output is the run's final answer, not the (non-serializable)\n    // result object. `finalize` records it without disturbing the caller's\n    // return value; for streaming it also waits for the stream to drain so the\n    // final output is present before the span is recorded.\n    const finalize = async (result: unknown): Promise<unknown> => {\n      const res = result as RunResultLike | null\n      if (isStreaming && res?.completed) {\n        try {\n          await res.completed\n        } catch {\n          // Stream errors surface to the caller; the span still records what\n          // final output is available rather than crashing finalize.\n        }\n      }\n      return res?.finalOutput\n    }\n\n    const options_: RootSpanOptions = { type: \"agent\", finalize }\n\n    // Wrap a function that TAKES the input as its argument and call it with the\n    // input, so withSpan records `[input]` as the root span input. run() runs\n    // inside the withSpan context, so the tracing processor's onTraceStart sees\n    // this root and nests the run's internal spans beneath it.\n    const traced = this.withSpanFn(\n      this.traceFunctionKey,\n      options_,\n      (agentInput: RunInput) =>\n        run(\n          agent,\n          agentInput as RunInputArg,\n          options as RunOptionsArg,\n        ) as Promise<RunResultLike>,\n    )\n\n    return traced(input)\n  }\n}\n","/**\n * Per-trace environment exposed to customer code during replay.\n *\n * The customer instantiates one `ReplayEnvironment` and passes it to\n * `bitfab.replay({ environment })`. Inside the replayed function they read\n * `env.databaseUrl` (and friends) to pick up the per-trace branch URL the\n * Bitfab service resolved from the source trace's snapshot reference.\n *\n * Outside replay, accessing `env.databaseUrl` throws. Customer code uses\n * the env only on the replay path; live request code keeps reading\n * `process.env.DATABASE_URL` the normal way.\n *\n * Concurrency-safe: getters resolve through the replay AsyncLocalStorage\n * context, so each in-flight replay item sees its own per-trace values\n * even when the SDK runs items in parallel.\n *\n * Internally, the resolved per-item state is a `DbBranchLease` (see\n * replayContext.ts) - that's the SDK ↔ server protocol term. We expose\n * its useful fields directly here so customer code never sees the word.\n */\n\nimport { getReplayContext } from \"./replayContext.js\"\n\nexport interface ReplayEnvironmentSnapshot {\n  databaseUrl: string\n  expiresAt: string\n  providerConsoleUrl?: string\n  readOnly?: boolean\n  traceId: string\n}\n\nexport class ReplayEnvironment {\n  /**\n   * The per-trace branch URL for the item currently being replayed.\n   * Throws if read outside a replay item.\n   */\n  get databaseUrl(): string {\n    const snapshot = this.require()\n    this.markAccessed()\n    return snapshot.databaseUrl\n  }\n\n  /** When the per-trace branch URL stops being valid. ISO-8601. */\n  get expiresAt(): string {\n    return this.require().expiresAt\n  }\n\n  /** Deep link to the branch in the provider console, if available. */\n  get providerConsoleUrl(): string | undefined {\n    return this.require().providerConsoleUrl\n  }\n\n  /**\n   * True if the branch is read-only. Customer code can use this to skip\n   * write operations during replay when the provider returned a read-only\n   * lease.\n   */\n  get readOnly(): boolean | undefined {\n    return this.require().readOnly\n  }\n\n  /** The historical trace ID that produced the input for this replay item. */\n  get traceId(): string {\n    return this.require().traceId\n  }\n\n  /** True when read inside a replay item that has a resolved branch. */\n  get active(): boolean {\n    return this.read() !== null\n  }\n\n  /** Non-throwing variant for callers that handle the inactive case. */\n  snapshot(): ReplayEnvironmentSnapshot | null {\n    const snapshot = this.read()\n    if (snapshot) {\n      this.markAccessed()\n    }\n    return snapshot\n  }\n\n  /**\n   * Record on the replay context that customer code obtained the branch\n   * URL. Only `databaseUrl` and `snapshot()` count - `active`, `readOnly`\n   * and friends inspect the lease without exposing the connection string,\n   * so they don't prove the replayed code could have connected to the\n   * branch.\n   */\n  private markAccessed(): void {\n    const ctx = getReplayContext()\n    if (ctx?.dbBranchLease) {\n      ctx.dbSnapshotAccessed = true\n    }\n  }\n\n  private read(): ReplayEnvironmentSnapshot | null {\n    const ctx = getReplayContext()\n    if (!ctx?.dbBranchLease) {\n      return null\n    }\n    // Surface the Bitfab traceId (what the customer sees in the dashboard),\n    // not the external_traces.id. Fall back to the external ID only if the\n    // Bitfab ID is somehow absent - keeps replays from external sources\n    // working until the source-system path is fully wired.\n    const traceId = ctx.sourceBitfabTraceId ?? ctx.inputSourceTraceId\n    if (!traceId) {\n      return null\n    }\n    const lease = ctx.dbBranchLease\n    return {\n      databaseUrl: lease.databaseUrl,\n      expiresAt: lease.expiresAt,\n      providerConsoleUrl: lease.providerConsoleUrl,\n      readOnly: lease.readOnly,\n      traceId,\n    }\n  }\n\n  private require(): ReplayEnvironmentSnapshot {\n    const snapshot = this.read()\n    if (!snapshot) {\n      throw new Error(\n        \"ReplayEnvironment accessed outside of a replay item. Pass it to bitfab.replay({ environment }) and only read it inside the replayed function.\",\n      )\n    }\n    return snapshot\n  }\n}\n","/**\n * Tracing utilities for external trace submission to Bitfab.\n *\n * This module provides utilities for sending external traces (e.g., from OpenAI API calls)\n * to Bitfab for monitoring and analysis.\n */\n\nimport { DEFAULT_SERVICE_URL } from \"./constants.js\"\nimport { type ApiKeyInput, HttpClient } from \"./http.js\"\nimport { finalizeSpanPayload } from \"./processorPayload.js\"\n\n// Minimal structural shapes of the OpenAI Agents SDK's `Trace` and `Span`,\n// declared locally so neither this module nor the SDK's published `.d.ts`\n// references `@openai/agents` - an optional peer many consumers never install.\n// We only touch the fields below; the real SDK objects are structural\n// supersets, so a consumer's `addTraceProcessor(processor)` still type-checks.\ninterface Trace {\n  traceId: string\n  toJSON(): unknown\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: mirrors the agent SDK's `Span<any>`\ninterface Span<_T = any> {\n  traceId?: string\n  toJSON(): unknown\n  spanData?: {\n    type?: string\n    _input?: unknown\n    _response?: unknown\n  } | null\n}\n\nexport interface TraceResponse {\n  traceId: string\n  status: \"success\"\n}\n\nexport interface ActiveSpanContext {\n  traceId: string\n  spanId: string\n}\n\n/**\n * TracingProcessor interface from OpenAI Agents SDK v0.3.7\n */\nexport interface TracingProcessor {\n  onTraceStart(trace: Trace): Promise<void>\n  onTraceEnd(trace: Trace): Promise<void>\n  // biome-ignore lint/suspicious/noExplicitAny: OpenAI Agents SDK uses any for span data\n  onSpanStart(span: Span<any>): Promise<void>\n  // biome-ignore lint/suspicious/noExplicitAny: OpenAI Agents SDK uses any for span data\n  onSpanEnd(span: Span<any>): Promise<void>\n  forceFlush(): Promise<void>\n  shutdown(timeout?: number): Promise<void>\n}\n\n/**\n * Tracing processor for OpenAI Agents SDK integration.\n *\n * Implements the TracingProcessor interface from the OpenAI Agents SDK to\n * automatically capture traces and spans and send them to Bitfab for\n * monitoring and analysis.\n *\n * Example usage:\n * ```typescript\n * import { Bitfab } from 'bitfab';\n * import { addTraceProcessor } from '@openai/agents';\n *\n * const client = new Bitfab({ apiKey: 'your-api-key' });\n * const processor = client.getOpenAiTracingProcessor();\n * addTraceProcessor(processor);\n * ```\n */\nexport class BitfabOpenAITracingProcessor implements TracingProcessor {\n  private readonly httpClient: HttpClient\n  private activeTraces: Record<string, Trace> = {}\n  private readonly getActiveSpanContext: (() => ActiveSpanContext | null) | null\n  private activeSpanMappings: Record<string, ActiveSpanContext> = {}\n\n  /**\n   * Initialize the tracing processor.\n   *\n   * @param config - Configuration options\n   */\n  constructor(config: {\n    apiKey?: ApiKeyInput\n    serviceUrl?: string\n    timeout?: number\n    getActiveSpanContext?: () => ActiveSpanContext | null\n  }) {\n    this.httpClient = new HttpClient({\n      apiKey: config.apiKey,\n      serviceUrl: config.serviceUrl ?? DEFAULT_SERVICE_URL,\n      timeout: config.timeout ?? 10000,\n    })\n    this.getActiveSpanContext = config.getActiveSpanContext ?? null\n  }\n\n  /**\n   * Called when a trace is started.\n   * If there's an active withSpan context, the trace ID is remapped to the\n   * outer trace and sent to pre-create the external_traces row on the server.\n   */\n  async onTraceStart(trace: Trace): Promise<void> {\n    this.activeTraces[trace.traceId] = trace\n\n    const activeContext = this.getActiveSpanContext?.()\n    if (activeContext) {\n      this.activeSpanMappings[trace.traceId] = activeContext\n    }\n\n    this.sendTrace(trace, activeContext ? { id: activeContext.traceId } : {})\n  }\n\n  /**\n   * Called when a trace is ended.\n   * If mapped to a withSpan trace, sends with remapped ID and completed=false\n   * since the parent withSpan handles completion.\n   */\n  async onTraceEnd(trace: Trace): Promise<void> {\n    const mapping = this.activeSpanMappings[trace.traceId]\n\n    this.sendTrace(\n      trace,\n      mapping ? { id: mapping.traceId } : { completed: true },\n    )\n\n    delete this.activeSpanMappings[trace.traceId]\n    delete this.activeTraces[trace.traceId]\n  }\n\n  /**\n   * Called when a span is started.\n   */\n  // biome-ignore lint/suspicious/noExplicitAny: OpenAI Agents SDK uses any for span data\n  async onSpanStart(span: Span<any>): Promise<void> {\n    // Send the span to Bitfab (fire-and-forget)\n    this.sendSpan(span)\n  }\n\n  /**\n   * Called when a span is ended.\n   *\n   * Send all spans to Bitfab for complete trace capture.\n   */\n  // biome-ignore lint/suspicious/noExplicitAny: OpenAI Agents SDK uses any for span data\n  async onSpanEnd(span: Span<any>): Promise<void> {\n    // Send the span to Bitfab again to capture updates (fire-and-forget)\n    this.sendSpan(span)\n  }\n\n  /**\n   * Called when a trace is being flushed.\n   */\n  async forceFlush(): Promise<void> {\n    // No buffering, so nothing to flush\n  }\n\n  /**\n   * Called when the trace processor is shutting down.\n   */\n  async shutdown(_timeout?: number): Promise<void> {\n    this.activeTraces = {}\n    this.activeSpanMappings = {}\n  }\n\n  /**\n   * Send trace to Bitfab API (fire-and-forget).\n   * When traceIdOverride is provided, the trace ID is remapped to link\n   * the OpenAI trace into an outer withSpan trace.\n   */\n  private sendTrace(\n    trace: Trace,\n    overrides: { completed?: boolean; id?: string } = {},\n  ): void {\n    try {\n      const { completed, ...traceOverrides } = overrides\n      const traceData = trace.toJSON() as Record<string, unknown>\n      Object.assign(traceData, traceOverrides)\n\n      this.httpClient.sendExternalTrace({\n        type: \"openai\",\n        source: \"typescript-sdk-openai-tracing\",\n        externalTrace: traceData,\n        completed: completed ?? false,\n      })\n    } catch {\n      // Silently ignore - never crash the host app\n    }\n  }\n\n  /**\n   * Export span to JSON object, collecting any errors.\n   */\n  private exportSpan(\n    // biome-ignore lint/suspicious/noExplicitAny: OpenAI Agents SDK uses any for span data\n    span: Span<any>,\n  ): [\n    Record<string, unknown>,\n    Array<{ source: string; step: string; error: string }>,\n  ] {\n    const errors: Array<{ source: string; step: string; error: string }> = []\n    let serializedSpan: Record<string, unknown>\n\n    try {\n      const jsonResult = span.toJSON()\n      if (typeof jsonResult !== \"object\" || jsonResult === null) {\n        errors.push({\n          source: \"sdk\",\n          step: \"span.toJSON()\",\n          error: `Returned unexpected type: ${typeof jsonResult}`,\n        })\n        serializedSpan = {}\n      } else {\n        serializedSpan = jsonResult as Record<string, unknown>\n      }\n    } catch (error) {\n      errors.push({\n        source: \"sdk\",\n        step: \"span.toJSON()\",\n        error: error instanceof Error ? error.message : String(error),\n      })\n      serializedSpan = {}\n    }\n\n    if (!serializedSpan.span_data) {\n      serializedSpan.span_data = {} as Record<string, unknown>\n    }\n\n    return [serializedSpan, errors]\n  }\n\n  /**\n   * Extract and add input/response to serialized span, updating errors list.\n   */\n  private extractSpanInputResponse(\n    // biome-ignore lint/suspicious/noExplicitAny: OpenAI Agents SDK uses any for span data\n    span: Span<any>,\n    serializedSpan: Record<string, unknown>,\n    errors: Array<{ source: string; step: string; error: string }>,\n  ): void {\n    // Only ResponseSpanData hides its content from toJSON(): the SDK's\n    // removePrivateFields strips its _input/_response, so we recover them here.\n    // Every other span type (function, generation, agent, custom, ...) already\n    // carries its data in span_data, so writing here would clobber a real input\n    // with an empty placeholder. Gate strictly to response spans, and only set a\n    // field when the value is actually present (never stamp []/null).\n    if (span.spanData?.type !== \"response\") {\n      return\n    }\n\n    const spanData = serializedSpan.span_data as Record<string, unknown>\n\n    try {\n      const input = span.spanData?._input\n      if (input !== undefined) {\n        spanData.input = input\n      }\n    } catch (error) {\n      errors.push({\n        source: \"sdk\",\n        step: \"access_input\",\n        error: error instanceof Error ? error.message : String(error),\n      })\n    }\n\n    try {\n      const response = span.spanData?._response\n      if (response !== undefined) {\n        spanData.response = response\n      }\n    } catch (error) {\n      errors.push({\n        source: \"sdk\",\n        step: \"access_response\",\n        error: error instanceof Error ? error.message : String(error),\n      })\n    }\n  }\n\n  /**\n   * If the span's trace is mapped to a withSpan trace, rewrite trace_id and parent_id.\n   */\n  private applySpanOverrides(\n    serializedSpan: Record<string, unknown>,\n    traceId: string,\n  ): void {\n    const mapping = this.activeSpanMappings[traceId]\n    if (mapping) {\n      serializedSpan.trace_id = mapping.traceId\n      if (!serializedSpan.parent_id) {\n        serializedSpan.parent_id = mapping.spanId\n      }\n    }\n  }\n\n  /**\n   * Build span payload for the external spans API.\n   */\n  private buildSpanPayload(\n    serializedSpan: Record<string, unknown>,\n    errors: Array<{ source: string; step: string; error: string }>,\n  ): Record<string, unknown> {\n    const payload: Record<string, unknown> = {\n      type: \"openai\",\n      source: \"typescript-sdk-openai-tracing\",\n      sourceTraceId: serializedSpan.trace_id ?? \"unknown\",\n      rawSpan: serializedSpan,\n    }\n\n    if (errors.length > 0) {\n      payload.errors = errors\n    }\n\n    // Sanitize the whole span (the raw OpenAI span_data is otherwise shipped\n    // unsanitized, relying only on the http-layer net) and mark a lossy capture\n    // non-replayable, merging with the SDK-level errors collected above.\n    return finalizeSpanPayload(payload)\n  }\n\n  /**\n   * Send span to Bitfab API (fire-and-forget).\n   * If the span belongs to a trace mapped to a withSpan trace, the trace_id\n   * and parent_id are rewritten to link the span into the withSpan tree.\n   */\n  private sendSpan(\n    // biome-ignore lint/suspicious/noExplicitAny: OpenAI Agents SDK uses any for span data\n    span: Span<any>,\n  ): void {\n    const errors: Array<{ source: string; step: string; error: string }> = []\n    const [serializedSpan, exportErrors] = this.exportSpan(span)\n    errors.push(...exportErrors)\n\n    this.extractSpanInputResponse(span, serializedSpan, errors)\n\n    this.applySpanOverrides(serializedSpan, span.traceId ?? \"\")\n\n    const payload = this.buildSpanPayload(serializedSpan, errors)\n\n    this.httpClient.sendExternalSpan(payload)\n  }\n}\n","/**\n * Vercel AI SDK integration for Bitfab tracing.\n *\n * The Vercel AI SDK (`ai`) routes every `generateText` / `streamText` /\n * `generateObject` / `streamObject` call through a language model. Bitfab hooks\n * that model with a *language-model middleware* (`wrapLanguageModel`), so each\n * model call is captured as a keyed `llm` span with no hand-written `withSpan`:\n *\n * ```typescript\n * import { Bitfab } from \"@bitfab/sdk\";\n * import { wrapLanguageModel, streamText } from \"ai\";\n * import { openai } from \"@ai-sdk/openai\";\n *\n * const bitfab = new Bitfab({ apiKey: \"...\" });\n *\n * const model = wrapLanguageModel({\n *   model: openai(\"gpt-4o\"),\n *   middleware: bitfab.getVercelAiMiddleware(\"chat-turn\"),\n * });\n *\n * const result = streamText({ model, messages });\n * return result.toUIMessageStreamResponse(); // live stream untouched\n * ```\n *\n * The span records the call parameters (the prompt/messages) as its input and a\n * serializable summary (`{ text, toolCalls, usage, finishReason }`) as its\n * output. Streaming is handled by passing the model's stream through a\n * transform that accumulates the assembled text/usage as the caller consumes\n * it: the live stream is handed back unchanged (first-byte latency untouched)\n * and the span is finalized once the stream completes.\n *\n * The middleware is fully duck-typed (no static or dynamic `ai` import), so it\n * adds no dependency and is browser-safe. It works with `ai` v5 and v6.\n */\n\n// The exact span options this middleware passes to `withSpan`. Declared locally\n// (a structural subset of the client's `SpanOptions`, so the bound `withSpan`\n// is assignable) rather than imported from client.ts - that would create an\n// import cycle, since client.ts imports this handler. Mirrors how the other\n// framework handlers stay free of any client import.\ntype LlmSpanOptions = {\n  type: \"llm\"\n  finalize: (result: unknown) => unknown | Promise<unknown>\n}\n\n// The subset of the Bitfab client this middleware needs: a bound `withSpan`.\ntype WithSpanFn = <TArgs extends unknown[], TReturn>(\n  traceFunctionKey: string,\n  options: LlmSpanOptions,\n  fn: (...args: TArgs) => TReturn,\n) => (...args: TArgs) => TReturn\n\n/**\n * Duck-typed subset of the Vercel AI SDK language-model call parameters. The\n * only field we read for the span input is `prompt` (the messages), but the\n * whole object is recorded so the call is reconstructable on replay.\n */\nexport interface VercelCallParams {\n  prompt?: unknown\n  [key: string]: unknown\n}\n\n/** A content part of a non-streaming `doGenerate` result. */\ninterface VercelContentPart {\n  type: string\n  text?: string\n  toolCallId?: string\n  toolName?: string\n  // v3 names tool arguments `input`; v5/v2 used `args`.\n  input?: unknown\n  args?: unknown\n}\n\n/** Duck-typed subset of a non-streaming `doGenerate` result. */\nexport interface VercelGenerateResult {\n  content?: VercelContentPart[]\n  // Some providers expose a flattened `text`; prefer it when present.\n  text?: string\n  usage?: unknown\n  finishReason?: unknown\n  [key: string]: unknown\n}\n\n/** Duck-typed subset of a single streaming part from `doStream`. */\ninterface VercelStreamPart {\n  type: string\n  // v3 text-delta carries `delta`; v2 carried `textDelta`.\n  delta?: string\n  textDelta?: string\n  toolCallId?: string\n  toolName?: string\n  input?: unknown\n  args?: unknown\n  usage?: unknown\n  finishReason?: unknown\n}\n\n/** Duck-typed subset of a streaming `doStream` result. */\nexport interface VercelStreamResult {\n  stream: ReadableStream<VercelStreamPart>\n  [key: string]: unknown\n}\n\ninterface MiddlewareCall<TResult> {\n  doGenerate: () => PromiseLike<VercelGenerateResult>\n  doStream: () => PromiseLike<VercelStreamResult>\n  params: VercelCallParams\n  model: unknown\n  __result?: TResult\n}\n\n/**\n * The structural shape of a Vercel AI SDK language-model middleware. Matches\n * `LanguageModelV3Middleware` from `@ai-sdk/provider` without importing it, so\n * the SDK stays dependency-free. `wrapLanguageModel` only reads the method\n * fields (it ignores `specificationVersion`), so this object drops straight in.\n */\nexport interface BitfabLanguageModelMiddleware {\n  specificationVersion: \"v3\"\n  // The wrap methods hand the provider's own result straight back (only the\n  // span output is derived from it), so the return is typed `any` to stay\n  // assignable to `LanguageModelV{2,3}Middleware` across AI SDK majors - the\n  // SDK's strict result types (which require `warnings`, `content`, etc.) are a\n  // superset of the duck-typed subset declared here. Implementation returns the\n  // precise `VercelGenerateResult` / `VercelStreamResult` shapes.\n  wrapGenerate: (\n    options: MiddlewareCall<VercelGenerateResult>,\n    // biome-ignore lint/suspicious/noExplicitAny: passthrough of the provider result; see note above\n  ) => Promise<any>\n  wrapStream: (\n    options: MiddlewareCall<VercelStreamResult>,\n    // biome-ignore lint/suspicious/noExplicitAny: passthrough of the provider result; see note above\n  ) => Promise<any>\n}\n\n/** The provider/model that served a call (e.g. `{ provider, modelId }`). */\ntype ModelLabel = { provider?: string; modelId?: string }\n\n/** The serializable summary recorded as a model call's span output. */\ntype CallSummary = {\n  text: string\n  toolCalls?: unknown[]\n  usage?: unknown\n  finishReason?: unknown\n  // Which provider/model actually served this call. Invaluable when a single\n  // wrapped key spans multiple providers (e.g. a Claude-primary, GPT-4o-fallback\n  // setup) so each span shows who answered.\n  model?: ModelLabel\n}\n\n/** Read `{ provider, modelId }` off an AI SDK language model, defensively. */\nfunction modelLabel(model: unknown): ModelLabel | undefined {\n  if (!model || typeof model !== \"object\") {\n    return undefined\n  }\n  const m = model as { provider?: unknown; modelId?: unknown }\n  const provider = typeof m.provider === \"string\" ? m.provider : undefined\n  const modelId = typeof m.modelId === \"string\" ? m.modelId : undefined\n  if (provider == null && modelId == null) {\n    return undefined\n  }\n  return { provider, modelId }\n}\n\n/** Collapse a non-streaming generate result into a serializable span output. */\nfunction summarizeGenerate(\n  result: VercelGenerateResult,\n  model: ModelLabel | undefined,\n): CallSummary {\n  const content = Array.isArray(result.content) ? result.content : []\n  const text =\n    typeof result.text === \"string\"\n      ? result.text\n      : content\n          .filter((p) => p.type === \"text\" && typeof p.text === \"string\")\n          .map((p) => p.text)\n          .join(\"\")\n  const toolCalls = content\n    .filter((p) => p.type === \"tool-call\")\n    .map((p) => ({\n      toolCallId: p.toolCallId,\n      toolName: p.toolName,\n      input: p.input ?? p.args,\n    }))\n  const summary: CallSummary = {\n    text,\n    toolCalls: toolCalls.length > 0 ? toolCalls : undefined,\n    usage: result.usage,\n    finishReason: result.finishReason,\n  }\n  if (model) {\n    summary.model = model\n  }\n  return summary\n}\n\n/**\n * A pass-through transform that accumulates the assembled text, tool calls, and\n * final usage from a model's stream, resolving `onComplete` with that summary\n * once the stream finishes. Parts are enqueued unchanged so the caller's stream\n * is untouched; capture errors are swallowed so tracing never breaks the stream.\n */\nfunction accumulateStream(\n  onComplete: (summary: CallSummary) => void,\n  model: ModelLabel | undefined,\n): TransformStream<VercelStreamPart, VercelStreamPart> {\n  let text = \"\"\n  const toolCalls: unknown[] = []\n  let usage: unknown\n  let finishReason: unknown\n  let completed = false\n  const complete = (): void => {\n    if (completed) {\n      return\n    }\n    completed = true\n    const summary: CallSummary = {\n      text,\n      toolCalls: toolCalls.length > 0 ? toolCalls : undefined,\n      usage,\n      finishReason,\n    }\n    if (model) {\n      summary.model = model\n    }\n    onComplete(summary)\n  }\n  return new TransformStream<VercelStreamPart, VercelStreamPart>({\n    transform(part, controller) {\n      try {\n        if (part?.type === \"text-delta\") {\n          text += part.delta ?? part.textDelta ?? \"\"\n        } else if (part?.type === \"tool-call\") {\n          toolCalls.push({\n            toolCallId: part.toolCallId,\n            toolName: part.toolName,\n            input: part.input ?? part.args,\n          })\n        } else if (part?.type === \"finish\") {\n          usage = part.usage\n          finishReason = part.finishReason\n          // The `finish` part is the stream's last meaningful event; resolve\n          // the span output as soon as it passes rather than waiting for the\n          // reader to close the stream.\n          complete()\n        }\n      } catch {\n        // Never let span capture break the caller's stream.\n      }\n      controller.enqueue(part)\n    },\n    flush() {\n      // Fallback when a provider omits an explicit `finish` part.\n      complete()\n    },\n  })\n}\n\n/**\n * Vercel AI SDK middleware that records each language-model call as a keyed\n * `llm` span. Obtain it from {@link BitfabClient.getVercelAiMiddleware} rather\n * than constructing it directly.\n */\nexport class BitfabVercelAiHandler {\n  private readonly traceFunctionKey: string\n  private readonly withSpanFn: WithSpanFn\n\n  constructor(config: { traceFunctionKey: string; withSpan: WithSpanFn }) {\n    this.traceFunctionKey = config.traceFunctionKey\n    this.withSpanFn = config.withSpan\n  }\n\n  /** The `wrapLanguageModel` middleware object for this trace function key. */\n  get middleware(): BitfabLanguageModelMiddleware {\n    const key = this.traceFunctionKey\n    const withSpan = this.withSpanFn\n    return {\n      specificationVersion: \"v3\",\n      wrapGenerate: async ({ doGenerate, params, model }) => {\n        const label = modelLabel(model)\n        // Wrap a function that TAKES the call params as its argument and call it\n        // with them, so withSpan records `[params]` (the prompt/settings) as the\n        // span input. `finalize` records the serializable summary as the output\n        // while the raw result is returned to the AI SDK unchanged.\n        const traced = withSpan<\n          [VercelCallParams],\n          Promise<VercelGenerateResult>\n        >(\n          key,\n          {\n            type: \"llm\",\n            finalize: (result) =>\n              summarizeGenerate((result ?? {}) as VercelGenerateResult, label),\n          },\n          () => doGenerate() as Promise<VercelGenerateResult>,\n        )\n        return traced(params)\n      },\n      wrapStream: async ({ doStream, params, model }) => {\n        const label = modelLabel(model)\n        let resolveSummary: (summary: CallSummary) => void = () => {}\n        const summary = new Promise<CallSummary>((resolve) => {\n          resolveSummary = resolve\n        })\n        const traced = withSpan<\n          [VercelCallParams],\n          Promise<VercelStreamResult>\n        >(\n          key,\n          // The wrapped fn returns immediately with the live stream, so the span\n          // output cannot be read from the return value. `finalize` instead\n          // awaits the summary the accumulator resolves once the stream drains.\n          { type: \"llm\", finalize: () => summary },\n          async () => {\n            const result = await doStream()\n            const stream = result.stream.pipeThrough(\n              accumulateStream(resolveSummary, label),\n            )\n            return { ...result, stream }\n          },\n        )\n        return traced(params)\n      },\n    }\n  }\n}\n","/**\n * Prebuilt `finalize` helpers for `withSpan({ finalize }, fn)`.\n *\n * A streaming function returns a live stream object that the caller consumes\n * directly (SSE, a UI message stream). `withSpan` hands that object back\n * unchanged; a `finalize` function tells it what serializable view to record\n * as the span output instead of the raw, non-serializable stream.\n */\n\n/**\n * Duck-typed subset of the Vercel AI SDK `streamText` / `streamObject`\n * result. Each field is exposed as a promise that resolves once the stream\n * finishes; reading them does not consume the live stream (the AI SDK tees\n * internally), so the caller's own consumption is unaffected. We avoid a\n * hard dependency on `ai` by matching structurally.\n */\ninterface AiSdkStreamResultLike {\n  text?: Promise<string> | string\n  usage?: Promise<unknown> | unknown\n  totalUsage?: Promise<unknown> | unknown\n  finishReason?: Promise<unknown> | unknown\n  toolCalls?: Promise<unknown> | unknown\n  toolResults?: Promise<unknown> | unknown\n  reasoningText?: Promise<string> | string\n}\n\n/** Await a value that may be a promise, swallowing rejection to `undefined`. */\nasync function settle<T>(\n  value: Promise<T> | T | undefined,\n): Promise<T | undefined> {\n  try {\n    return await value\n  } catch {\n    return undefined\n  }\n}\n\n/**\n * Drain a Vercel AI SDK streaming result into a serializable, replayable\n * span output: `{ text, usage, finishReason, toolCalls, toolResults }`.\n *\n * Pass it straight to `withSpan`:\n *\n * ```ts\n * import { finalizers } from \"@bitfab/sdk\"\n *\n * const traced = bitfab.withSpan(\n *   \"chat-turn\",\n *   { type: \"agent\", finalize: finalizers.aiSdk },\n *   () => streamText({ model, messages }),\n * )\n * const result = traced() // caller still gets the live StreamTextResult\n * return result.toUIMessageStreamResponse()\n * ```\n *\n * Never throws: any field that is absent or rejects is recorded as\n * `undefined` so finalize never drops the span.\n */\nasync function aiSdk(result: unknown): Promise<Record<string, unknown>> {\n  const r = (result ?? {}) as AiSdkStreamResultLike\n  const [text, usage, totalUsage, finishReason, toolCalls, toolResults] =\n    await Promise.all([\n      settle(r.text),\n      settle(r.usage),\n      settle(r.totalUsage),\n      settle(r.finishReason),\n      settle(r.toolCalls),\n      settle(r.toolResults),\n    ])\n  return {\n    text,\n    usage: totalUsage ?? usage,\n    finishReason,\n    toolCalls,\n    toolResults,\n  }\n}\n\n/**\n * Collect a `ReadableStream`'s chunks into an array for the span output,\n * via a `tee()` so the caller's branch is untouched. The caller MUST use\n * the returned stream, not the original, since a stream can only be read\n * once:\n *\n * ```ts\n * let live: ReadableStream\n * const traced = bitfab.withSpan(\n *   \"render\",\n *   { finalize: (r) => finalizers.readableStream(r, (s) => { live = s }) },\n *   () => makeReadableStream(),\n * )\n * traced()\n * return new Response(live!)\n * ```\n *\n * Prefer `aiSdk` for the Vercel AI SDK, whose result tees internally and\n * needs no caller rewiring.\n */\nasync function readableStream(\n  stream: ReadableStream,\n  onLive: (live: ReadableStream) => void,\n): Promise<{ chunks: unknown[] }> {\n  const [live, copy] = stream.tee()\n  onLive(live)\n  const chunks: unknown[] = []\n  const reader = copy.getReader()\n  try {\n    for (;;) {\n      const { done, value } = await reader.read()\n      if (done) {\n        break\n      }\n      chunks.push(value)\n    }\n  } catch {\n    // Never let span capture crash the host app.\n  }\n  return { chunks }\n}\n\nexport const finalizers = {\n  aiSdk,\n  readableStream,\n}\n","/**\n * Bitfab client for provider-based API calls.\n */\n\nexport type {\n  AllowedEnvVars,\n  BamlExecutionResult,\n  ProviderDefinition,\n} from \"./baml.js\"\nexport { BitfabClaudeAgentHandler } from \"./claudeAgentSdk.js\"\nexport type {\n  BitfabConfig,\n  CurrentSpan,\n  CurrentTrace,\n  DetachedTrace,\n  SpanOptions,\n  SpanType,\n  WrapBAMLOptions,\n  WrappedBamlFn,\n} from \"./client.js\"\nexport {\n  Bitfab,\n  BitfabError,\n  BitfabFunction,\n  getCurrentSpan,\n  getCurrentTrace,\n} from \"./client.js\"\nexport { __version__, DEFAULT_SERVICE_URL } from \"./constants.js\"\nexport type {\n  DbSnapshotConfig,\n  DbSnapshotProvider,\n  DbSnapshotRef,\n} from \"./dbSnapshot.js\"\nexport { SUPPORTED_PROVIDERS } from \"./dbSnapshot.js\"\nexport { finalizers } from \"./finalizers.js\"\nexport { flushTraces } from \"./http.js\"\nexport {\n  BitfabLangGraphCallbackHandler,\n  BitfabLangGraphCallbackHandler as BitfabLangChainCallbackHandler,\n} from \"./langgraph.js\"\nexport { BitfabOpenAIAgentHandler } from \"./openaiAgentSdk.js\"\nexport type {\n  AdaptContext,\n  AdaptInputsFn,\n  CodeChangeFile,\n  MockStrategy,\n  ReplayItem,\n  ReplayOptions,\n  ReplayProgress,\n  ReplayResult,\n  TokenUsage,\n} from \"./replay.js\"\nexport { BITFAB_PROGRESS_PREFIX, reportReplayProgress } from \"./replay.js\"\nexport type { ReplayEnvironmentSnapshot } from \"./replayEnvironment.js\"\nexport { ReplayEnvironment } from \"./replayEnvironment.js\"\nexport type {\n  ActiveSpanContext,\n  TraceResponse,\n  TracingProcessor,\n} from \"./tracing.js\"\nexport { BitfabOpenAITracingProcessor } from \"./tracing.js\"\nexport type {\n  BitfabLanguageModelMiddleware,\n  VercelCallParams,\n  VercelGenerateResult,\n  VercelStreamResult,\n} from \"./vercelAiSdk.js\"\nexport { BitfabVercelAiHandler } from \"./vercelAiSdk.js\"\n"],"mappings":"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","names":["superjson","nowIso","asTokenCount","extractUsage","method"]}