@bitfab/sdk 0.65.4 → 0.65.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/dist/autoTrace-CQw0qMBt.cjs +396 -0
  2. package/dist/autoTrace-CQw0qMBt.cjs.map +1 -0
  3. package/dist/autoTrace-O40k8f5M.js +271 -0
  4. package/dist/autoTrace-O40k8f5M.js.map +1 -0
  5. package/dist/autoTrace.cjs +15 -353
  6. package/dist/autoTrace.d.cts +48 -44
  7. package/dist/autoTrace.d.ts +48 -44
  8. package/dist/autoTrace.js +1 -28
  9. package/dist/babelPlugin-C70OxrqA.js +209 -0
  10. package/dist/babelPlugin-C70OxrqA.js.map +1 -0
  11. package/dist/babelPlugin-Nta4-VcL.cjs +232 -0
  12. package/dist/babelPlugin-Nta4-VcL.cjs.map +1 -0
  13. package/dist/http-lnqCEnB1.js +2154 -0
  14. package/dist/http-lnqCEnB1.js.map +1 -0
  15. package/dist/index-CFOLQ1IF.d.cts +4410 -0
  16. package/dist/index-CFOLQ1IF.d.ts +4410 -0
  17. package/dist/index.cjs +48 -12504
  18. package/dist/index.d.cts +2 -4443
  19. package/dist/index.d.ts +2 -4443
  20. package/dist/index.js +3 -96
  21. package/dist/loaderRuntime-0huddOOP.d.ts +12 -0
  22. package/dist/loaderRuntime-CslfDFO7.d.cts +12 -0
  23. package/dist/node.cjs +56 -12520
  24. package/dist/node.cjs.map +1 -1
  25. package/dist/node.d.cts +2 -1
  26. package/dist/node.d.ts +2 -1
  27. package/dist/node.js +10 -105
  28. package/dist/node.js.map +1 -1
  29. package/dist/registryCommand-Di8x0YoJ.js +1111 -0
  30. package/dist/registryCommand-Di8x0YoJ.js.map +1 -0
  31. package/dist/replayCli.js +49 -87
  32. package/dist/replayCli.js.map +1 -1
  33. package/dist/rolldown-runtime-D7D4PA-g.js +13 -0
  34. package/dist/seedCli.js +10 -24
  35. package/dist/seedCli.js.map +1 -1
  36. package/dist/src-BungStQw.js +6015 -0
  37. package/dist/src-BungStQw.js.map +1 -0
  38. package/dist/src-FFSCRXpz.cjs +8438 -0
  39. package/dist/src-FFSCRXpz.cjs.map +1 -0
  40. package/dist/transform/babel.cjs +5 -422
  41. package/dist/transform/babel.d.cts +16 -16
  42. package/dist/transform/babel.d.ts +16 -16
  43. package/dist/transform/babel.js +1 -7
  44. package/dist/transform/bun.cjs +9 -478
  45. package/dist/transform/bun.cjs.map +1 -1
  46. package/dist/transform/bun.d.cts +5 -7
  47. package/dist/transform/bun.d.ts +5 -7
  48. package/dist/transform/bun.js +6 -11
  49. package/dist/transform/bun.js.map +1 -1
  50. package/dist/transform/esbuild.cjs +9 -478
  51. package/dist/transform/esbuild.cjs.map +1 -1
  52. package/dist/transform/esbuild.d.cts +5 -7
  53. package/dist/transform/esbuild.d.ts +5 -7
  54. package/dist/transform/esbuild.js +6 -11
  55. package/dist/transform/esbuild.js.map +1 -1
  56. package/dist/transform/loaderRuntime.cjs +85 -532
  57. package/dist/transform/loaderRuntime.cjs.map +1 -1
  58. package/dist/transform/loaderRuntime.d.cts +2 -12
  59. package/dist/transform/loaderRuntime.d.ts +2 -12
  60. package/dist/transform/loaderRuntime.js +56 -98
  61. package/dist/transform/loaderRuntime.js.map +1 -1
  62. package/dist/transform/nest.cjs +12 -481
  63. package/dist/transform/nest.cjs.map +1 -1
  64. package/dist/transform/nest.d.cts +8 -9
  65. package/dist/transform/nest.d.ts +8 -9
  66. package/dist/transform/nest.js +9 -14
  67. package/dist/transform/nest.js.map +1 -1
  68. package/dist/transform/next.cjs +56 -528
  69. package/dist/transform/next.cjs.map +1 -1
  70. package/dist/transform/next.d.cts +25 -25
  71. package/dist/transform/next.d.ts +24 -24
  72. package/dist/transform/next.js +52 -60
  73. package/dist/transform/next.js.map +1 -1
  74. package/dist/transform/nodeLoader.js +260 -506
  75. package/dist/transform/nodeLoader.js.map +1 -1
  76. package/dist/transform/register.js +4 -1
  77. package/dist/transform/register.js.map +1 -1
  78. package/dist/transform/rolldown.cjs +9 -478
  79. package/dist/transform/rolldown.cjs.map +1 -1
  80. package/dist/transform/rolldown.d.cts +5 -7
  81. package/dist/transform/rolldown.d.ts +5 -7
  82. package/dist/transform/rolldown.js +6 -11
  83. package/dist/transform/rolldown.js.map +1 -1
  84. package/dist/transform/rollup.cjs +9 -478
  85. package/dist/transform/rollup.cjs.map +1 -1
  86. package/dist/transform/rollup.d.cts +5 -7
  87. package/dist/transform/rollup.d.ts +5 -7
  88. package/dist/transform/rollup.js +6 -11
  89. package/dist/transform/rollup.js.map +1 -1
  90. package/dist/transform/rsbuild.cjs +9 -478
  91. package/dist/transform/rsbuild.cjs.map +1 -1
  92. package/dist/transform/rsbuild.d.cts +5 -7
  93. package/dist/transform/rsbuild.d.ts +5 -7
  94. package/dist/transform/rsbuild.js +6 -11
  95. package/dist/transform/rsbuild.js.map +1 -1
  96. package/dist/transform/rspack.cjs +9 -478
  97. package/dist/transform/rspack.cjs.map +1 -1
  98. package/dist/transform/rspack.d.cts +5 -7
  99. package/dist/transform/rspack.d.ts +5 -7
  100. package/dist/transform/rspack.js +6 -11
  101. package/dist/transform/rspack.js.map +1 -1
  102. package/dist/transform/swc.cjs +18 -486
  103. package/dist/transform/swc.cjs.map +1 -1
  104. package/dist/transform/swc.d.cts +15 -14
  105. package/dist/transform/swc.d.ts +15 -14
  106. package/dist/transform/swc.js +14 -32
  107. package/dist/transform/swc.js.map +1 -1
  108. package/dist/transform/unplugin.cjs +20 -476
  109. package/dist/transform/unplugin.cjs.map +1 -1
  110. package/dist/transform/unplugin.d.cts +4 -6
  111. package/dist/transform/unplugin.d.ts +4 -6
  112. package/dist/transform/unplugin.js +19 -8
  113. package/dist/transform/unplugin.js.map +1 -1
  114. package/dist/transform/vite.cjs +9 -478
  115. package/dist/transform/vite.cjs.map +1 -1
  116. package/dist/transform/vite.d.cts +5 -7
  117. package/dist/transform/vite.d.ts +5 -7
  118. package/dist/transform/vite.js +6 -11
  119. package/dist/transform/vite.js.map +1 -1
  120. package/dist/transform/webpack.cjs +9 -478
  121. package/dist/transform/webpack.cjs.map +1 -1
  122. package/dist/transform/webpack.d.cts +5 -7
  123. package/dist/transform/webpack.d.ts +5 -7
  124. package/dist/transform/webpack.js +6 -11
  125. package/dist/transform/webpack.js.map +1 -1
  126. package/dist/transform-BcyUocwm.js +36 -0
  127. package/dist/transform-BcyUocwm.js.map +1 -0
  128. package/dist/transform-BjxHGGKc.cjs +47 -0
  129. package/dist/transform-BjxHGGKc.cjs.map +1 -0
  130. package/dist/transformOptions-BsjCELkh.d.cts +11 -0
  131. package/dist/transformOptions-BsjCELkh.d.ts +11 -0
  132. package/package.json +5 -5
  133. package/dist/autoTrace.cjs.map +0 -1
  134. package/dist/autoTrace.js.map +0 -1
  135. package/dist/chunk-27B3UBSS.js +0 -2547
  136. package/dist/chunk-27B3UBSS.js.map +0 -1
  137. package/dist/chunk-B2M4KELA.js +0 -1912
  138. package/dist/chunk-B2M4KELA.js.map +0 -1
  139. package/dist/chunk-I233ERUH.js +0 -2979
  140. package/dist/chunk-I233ERUH.js.map +0 -1
  141. package/dist/chunk-ISU6FQKY.js +0 -6877
  142. package/dist/chunk-ISU6FQKY.js.map +0 -1
  143. package/dist/chunk-MT36GJMW.js +0 -106
  144. package/dist/chunk-MT36GJMW.js.map +0 -1
  145. package/dist/chunk-PTCLRG4E.js +0 -28
  146. package/dist/chunk-PTCLRG4E.js.map +0 -1
  147. package/dist/chunk-QRNHRY7F.js +0 -270
  148. package/dist/chunk-QRNHRY7F.js.map +0 -1
  149. package/dist/chunk-R6M54SPO.js +0 -1176
  150. package/dist/chunk-R6M54SPO.js.map +0 -1
  151. package/dist/chunk-SOP5AFMH.js +0 -2060
  152. package/dist/chunk-SOP5AFMH.js.map +0 -1
  153. package/dist/chunk-YVJAOGHE.js +0 -45
  154. package/dist/chunk-YVJAOGHE.js.map +0 -1
  155. package/dist/chunk-ZG6SHKEF.js +0 -404
  156. package/dist/chunk-ZG6SHKEF.js.map +0 -1
  157. package/dist/http-LL3JD2JE.js +0 -24
  158. package/dist/http-LL3JD2JE.js.map +0 -1
  159. package/dist/http-QZDTQC3C.js +0 -23
  160. package/dist/http-QZDTQC3C.js.map +0 -1
  161. package/dist/index.cjs.map +0 -1
  162. package/dist/index.js.map +0 -1
  163. package/dist/replay-636XZIS2.js +0 -29
  164. package/dist/replay-636XZIS2.js.map +0 -1
  165. package/dist/replay-S4DNF4VR.js +0 -28
  166. package/dist/replay-S4DNF4VR.js.map +0 -1
  167. package/dist/transform/babel.cjs.map +0 -1
  168. package/dist/transform/babel.js.map +0 -1
  169. package/dist/transformOptions-Df2_Chtc.d.cts +0 -10
  170. package/dist/transformOptions-Df2_Chtc.d.ts +0 -10
@@ -0,0 +1,4410 @@
1
+ //#region src/approval.d.ts
2
+ /** One span the justification rests on, with what that span shows. */
3
+ type JustificationSpan = {
4
+ spanId: string;
5
+ text: string;
6
+ };
7
+ /** Evidence for an assertion decision: one entry per span relied on. */
8
+ type Justification = JustificationSpan[];
9
+ /** Whether a person has reviewed an assertion decision. */
10
+ type ApprovalState = "pending" | "approved" | "rejected";
11
+ type Approver = {
12
+ id: string;
13
+ fullName: string | null;
14
+ email: string | null;
15
+ imageUrl: string | null;
16
+ };
17
+ /** The organization member on the hook for reviewing an assertion. */
18
+ type Assignee = Approver;
19
+ /** Read-only on this client: only a person in Bitfab sets these. */
20
+ type ApprovalFields = {
21
+ approvalState: ApprovalState;
22
+ approvedBy: Approver | null;
23
+ approvedAt: string | null;
24
+ };
25
+ //#endregion
26
+ //#region src/baml.d.ts
27
+ /**
28
+ * BAML execution utilities for the Bitfab TypeScript SDK.
29
+ * This module provides functions to execute BAML prompts dynamically on the client side.
30
+ */
31
+ /**
32
+ * Provider definition from the server.
33
+ */
34
+ interface ProviderDefinition {
35
+ provider: string;
36
+ apiKeyEnv: string;
37
+ models: Array<{
38
+ model: string;
39
+ description: string;
40
+ }>;
41
+ }
42
+ /**
43
+ * Result of a BAML function execution with raw collector data.
44
+ */
45
+ interface BamlExecutionResult {
46
+ /** The parsed result of the function */
47
+ result: unknown;
48
+ /** Raw collector data for the server to parse */
49
+ rawCollector: Record<string, unknown> | null;
50
+ }
51
+ /**
52
+ * Type for allowed environment variables.
53
+ * Only OPENAI_API_KEY is currently supported.
54
+ */
55
+ type AllowedEnvVars = {
56
+ OPENAI_API_KEY?: string;
57
+ };
58
+ //#endregion
59
+ //#region src/selectiveReplay.d.ts
60
+ /** A node is identified by its workflow key and span name, never its display label. */
61
+ interface ReplayNodeIdentity {
62
+ traceFunctionKey: string;
63
+ spanName: string;
64
+ }
65
+ /** Experimental, explicit policy for the TypeScript selective replay prototype. */
66
+ interface SelectiveReplayOptions {
67
+ /** Subtrees that must execute: changed code and unchanged code with required effects. */
68
+ mustRun: ReplayNodeIdentity[];
69
+ }
70
+ interface SelectiveReplayNode extends ReplayNodeIdentity {
71
+ id: string;
72
+ parentId: string | null;
73
+ mustRun: boolean;
74
+ reusable: boolean;
75
+ reason: "root" | "must-run" | "ancestor" | "assertion" | "unresolved-must-run" | "eligible" | "not-reusable" | "missing-recording";
76
+ recording?: {
77
+ input: unknown[];
78
+ kwargs?: Record<string, unknown>;
79
+ output: unknown;
80
+ };
81
+ }
82
+ interface SelectiveReplayAssertion {
83
+ id: string;
84
+ target: null | {
85
+ kind: "output";
86
+ } | {
87
+ kind: "span";
88
+ name: string;
89
+ occurrence?: "first" | "last" | number;
90
+ };
91
+ }
92
+ interface SelectiveReplayPlan {
93
+ version: 4;
94
+ rootId: string;
95
+ options: SelectiveReplayOptions;
96
+ unresolvedMustRun: ReplayNodeIdentity[];
97
+ nodes: SelectiveReplayNode[];
98
+ assertions: SelectiveReplayAssertion[];
99
+ }
100
+ interface SelectiveReplayDecision extends ReplayNodeIdentity {
101
+ originalSpanId: string | null;
102
+ action: "run" | "mock" | "blocked";
103
+ reason: string;
104
+ }
105
+ /** Per-item execution evidence. A node not reached is not claimed as tested. */
106
+ interface SelectiveReplayReport {
107
+ decisions: SelectiveReplayDecision[];
108
+ mustRunNotReached: ReplayNodeIdentity[];
109
+ unresolvedMustRun: ReplayNodeIdentity[];
110
+ /** Assertion IDs loaded for planning; these are not verdicts. */
111
+ assertionIds: string[];
112
+ /** Assertion IDs whose span target was absent/out of range in the recording. */
113
+ unresolvedAssertions: string[];
114
+ /** Assertion IDs whose requested span occurrence was not reached in this replay. */
115
+ assertionTargetsNotReached: string[];
116
+ }
117
+ //#endregion
118
+ //#region src/traceCompletion.d.ts
119
+ declare class TraceCompletion {
120
+ private readonly traces;
121
+ private readonly closed;
122
+ private state;
123
+ start(traceId: string, spanId: string): void;
124
+ open(traceId: string): void;
125
+ hold(traceId: string, key: string): void;
126
+ record(traceId: string, spanId: string): void;
127
+ end(traceId: string, spanId: string): void;
128
+ abort(traceId: string, spanId: string): void;
129
+ close(traceId: string, complete: (count: number) => void, dropped?: boolean): void;
130
+ private drain;
131
+ }
132
+ //#endregion
133
+ //#region src/dbSnapshot.d.ts
134
+ /**
135
+ * Per-trace database snapshot ref capture.
136
+ *
137
+ * Every root span carries a `DbSnapshotRef` that pins the DB state at trace
138
+ * open by wall-clock timestamp. Capturing the timestamp is free (no IO) and
139
+ * harmless, so it happens on every trace regardless of configuration: that
140
+ * lets any trace be replayed against a historical branch later. A `provider`
141
+ * is attached only when the customer configured `dbSnapshot`; when absent it
142
+ * is resolved at replay time. The Bitfab service uses the timestamp to
143
+ * materialize an ephemeral branch from `customer-main`.
144
+ */
145
+ declare const SUPPORTED_PROVIDERS: readonly ["neon"];
146
+ type DbSnapshotProvider = (typeof SUPPORTED_PROVIDERS)[number];
147
+ interface DbSnapshotConfig {
148
+ /** Discriminator for the server-side resolver. */
149
+ provider: DbSnapshotProvider;
150
+ }
151
+ interface DbSnapshotRef {
152
+ /**
153
+ * The wall-clock ISO timestamp the SDK observed immediately before
154
+ * invoking the wrapped function. The name encodes its provenance:
155
+ * SDK-observed, wall clock (not monotonic), captured before user code
156
+ * began executing. Always present.
157
+ */
158
+ sdkWallClockBeforeFn: string;
159
+ /**
160
+ * The configured provider for server-side branch resolution. Only set when
161
+ * the customer configured `dbSnapshot`; otherwise the provider is resolved
162
+ * at replay time.
163
+ */
164
+ provider?: DbSnapshotProvider;
165
+ }
166
+ //#endregion
167
+ //#region src/errors.d.ts
168
+ /**
169
+ * Shared error type for Bitfab SDK runtime errors. Lives in its own
170
+ * module to avoid import cycles between `http.ts` and modules that need
171
+ * to throw structured errors (e.g. `dbSnapshot.ts` validation).
172
+ */
173
+ declare class BitfabError extends Error {
174
+ readonly url?: string | undefined;
175
+ /**
176
+ * HTTP status the request failed with, when it failed with one. The
177
+ * transport's retry policy needs the code itself (retry 408/425/429/5xx,
178
+ * never a 4xx the server will reject again), which a formatted message
179
+ * cannot supply. Absent for network failures and non-HTTP errors.
180
+ */
181
+ readonly status?: number | undefined;
182
+ /**
183
+ * `Retry-After` in milliseconds, when the server sent one. A 429 or 503
184
+ * carries the server's own instruction about when to come back; retrying
185
+ * on our own schedule ignores it and keeps the pressure on.
186
+ */
187
+ readonly retryAfterMs?: number | undefined;
188
+ constructor(message: string, url?: string | undefined,
189
+ /**
190
+ * HTTP status the request failed with, when it failed with one. The
191
+ * transport's retry policy needs the code itself (retry 408/425/429/5xx,
192
+ * never a 4xx the server will reject again), which a formatted message
193
+ * cannot supply. Absent for network failures and non-HTTP errors.
194
+ */
195
+ status?: number | undefined,
196
+ /**
197
+ * `Retry-After` in milliseconds, when the server sent one. A 429 or 503
198
+ * carries the server's own instruction about when to come back; retrying
199
+ * on our own schedule ignores it and keeps the pressure on.
200
+ */
201
+ retryAfterMs?: number | undefined);
202
+ }
203
+ declare class MixedTracingError extends Error {
204
+ constructor(message: string);
205
+ }
206
+ //#endregion
207
+ //#region src/mockOverride.d.ts
208
+ /**
209
+ * Selective mock overrides for replay.
210
+ *
211
+ * A mock override injects a custom value into a specific span (node) during
212
+ * replay: the matched span short-circuits its real execution and returns the
213
+ * value you supply, so downstream real code runs against the substituted
214
+ * output. This is a third mock mode alongside "run real code" and "replay
215
+ * recorded output" (see {@link MockStrategy}).
216
+ *
217
+ * The matcher and value are deliberately separate so matching stays cheap
218
+ * (structural metadata only, no output fetch) and the recorded output is
219
+ * fetched lazily - and only if the value function actually asks for it via
220
+ * {@link MockOverrideCtx.getOriginalOutput}.
221
+ */
222
+ /**
223
+ * Structural identity of a span during replay, passed to a {@link NodeMatcher}.
224
+ * Carries no output payload - matching must not depend on the recorded output,
225
+ * so the output fetch stays lazy and gated.
226
+ */
227
+ interface SpanNodeMeta {
228
+ /** The `withSpan` key of the executing span (its code-side identity). */
229
+ traceFunctionKey: string;
230
+ /** Resolved span name: `options.name ?? fn.name ?? traceFunctionKey`. */
231
+ spanName: string;
232
+ /** Span type, e.g. "llm", "agent", "tool", "custom". */
233
+ type: string;
234
+ /**
235
+ * The id of this span in the original (replayed) trace, when it exists in
236
+ * that trace's tree. Undefined when the live span has no recorded
237
+ * counterpart (e.g. a span the changed code newly introduced).
238
+ */
239
+ originalSpanId?: string;
240
+ }
241
+ /** Context passed to a {@link MockValue} function for a matched span. */
242
+ interface MockOverrideCtx {
243
+ /** The matched span's structural metadata. */
244
+ node: SpanNodeMeta;
245
+ /** The live replay args passed to the wrapped function this run. */
246
+ inputs: unknown[];
247
+ /**
248
+ * Lazily fetch this span's ORIGINAL recorded output (deserialized). The fetch
249
+ * happens only when called and is memoized per replay item, so a purely flat
250
+ * override that never calls it triggers zero output round trips. Rejects if
251
+ * the span has no recorded counterpart. Being async, it is only usable for
252
+ * spans wrapping async functions.
253
+ */
254
+ getOriginalOutput: () => Promise<unknown>;
255
+ }
256
+ /**
257
+ * Return this from a mock override resolver to decline the override for the
258
+ * current span. Resolution continues with the next override, then the replay's
259
+ * base mock strategy.
260
+ */
261
+ declare const NO_MOCK_OVERRIDE: unique symbol;
262
+ /** Selects which spans an override applies to. Runs on structural metadata. */
263
+ type NodeMatcher = (node: SpanNodeMeta) => boolean;
264
+ /** The function form of {@link MockValue}, receiving the override context. */
265
+ type MockValueFn = (ctx: MockOverrideCtx) => unknown | Promise<unknown>;
266
+ /**
267
+ * A client-wide, keyed, or per-replay resolver. A global resolver can route on
268
+ * `ctx.node.traceFunctionKey`; a keyed resolver is only invoked for spans with
269
+ * its registered key. Return {@link NO_MOCK_OVERRIDE} for spans the resolver
270
+ * does not want to override.
271
+ */
272
+ type MockOverrideResolver = (ctx: MockOverrideCtx) => unknown | Promise<unknown>;
273
+ /**
274
+ * The value injected for a matched span: either a flat value used as-is, or a
275
+ * function of the {@link MockOverrideCtx} that returns one (or a Promise of
276
+ * one). Full replacement - the value IS the span's output, no merge with the
277
+ * recorded output.
278
+ *
279
+ * The flat side is spelled out (rather than `unknown`) so an inline function
280
+ * still gets a typed `ctx`: `unknown | Fn` would collapse to `unknown` and drop
281
+ * the contextual type. To inject a value that is itself a function, wrap it:
282
+ * `value: () => theFunction`.
283
+ */
284
+ type MockValue = MockValueFn | string | number | boolean | bigint | symbol | object | null | undefined;
285
+ /** One (match, value) pair. */
286
+ interface MockOverride {
287
+ match: NodeMatcher;
288
+ value: MockValue;
289
+ }
290
+ /** Accepted shape for one mock override declaration. */
291
+ type MockOverrideInput = MockOverride | MockOverrideResolver;
292
+ //#endregion
293
+ //#region src/selectiveReplayRuntime.d.ts
294
+ declare class SelectiveReplayRuntime {
295
+ private readonly plan;
296
+ private readonly options;
297
+ private readonly nodes;
298
+ private readonly children;
299
+ private readonly runtimeParents;
300
+ private readonly consumed;
301
+ private readonly required;
302
+ private readonly requiredScopes;
303
+ private readonly recordings;
304
+ private readonly reached;
305
+ private readonly decisions;
306
+ private readonly assertionNames;
307
+ private readonly assertionScopes;
308
+ private readonly observedNames;
309
+ private readonly unresolvedAssertions;
310
+ private readonly fullTraceForAssertions;
311
+ private failure?;
312
+ constructor(plan: SelectiveReplayPlan, options: SelectiveReplayOptions);
313
+ enter(params: ReplayNodeIdentity & {
314
+ spanId: string;
315
+ parentSpanId: string | null;
316
+ inputs: unknown[];
317
+ safetyMock: boolean;
318
+ canReuseOutput: boolean;
319
+ reuseAllowed: boolean;
320
+ }): {
321
+ mock: false;
322
+ } | {
323
+ mock: true;
324
+ output: unknown;
325
+ };
326
+ assertNoSafetyConflict(): void;
327
+ report(): SelectiveReplayReport;
328
+ }
329
+ //#endregion
330
+ //#region src/replayContext.d.ts
331
+ /**
332
+ * A single span entry in the mock tree.
333
+ *
334
+ * Under the eager path (`mock: "all"`) `output`/`outputMeta` are populated
335
+ * inline, even when overrides are present. Under a non-`all` path that needs a
336
+ * tree (`marked`, or `none` with overrides), they are absent and the recorded
337
+ * output is fetched on demand via `externalSpanId` - see
338
+ * {@link ReplayContext.fetchSpanOutput}.
339
+ */
340
+ interface MockSpan {
341
+ sourceSpanId: string;
342
+ /** Row id accepted by `getExternalSpan`, for the lazy per-span output fetch. */
343
+ externalSpanId?: string;
344
+ output?: unknown;
345
+ outputMeta?: unknown;
346
+ }
347
+ /**
348
+ * Per-item DB branch resolved by the Bitfab service from the source
349
+ * trace's `dbSnapshotRef`. Carried on the replay context so that
350
+ * customer code reads `databaseUrl` through `getCurrentReplayBranch()`, and so
351
+ * the process-isolated replay runner can materialize it into a `.env`
352
+ * overlay file before customer code initializes its DB client.
353
+ *
354
+ * `neonBranchId` is the literal Neon branch id; passing it to
355
+ * `releaseDbBranchLease` deletes that branch.
356
+ */
357
+ interface DbBranchLease {
358
+ neonBranchId: string;
359
+ /** Env var name the customer's app reads, e.g. "DATABASE_URL". */
360
+ envKey: string;
361
+ databaseUrl: string;
362
+ expiresAt: string;
363
+ /**
364
+ * The instant the branch was pinned to (the source trace's wall clock).
365
+ * Echoed back in `db_snapshot_usage` on the replayed trace's completion.
366
+ */
367
+ snapshotTimestamp?: string;
368
+ providerConsoleUrl?: string;
369
+ readOnly?: boolean;
370
+ /**
371
+ * The branch's region, e.g. `aws-us-east-1`. A compute runs in its project's
372
+ * region, so a runner elsewhere pays that round trip on every query.
373
+ */
374
+ region?: string;
375
+ }
376
+ /**
377
+ * How long each phase of provisioning one replay branch took, measured
378
+ * server-side. A runner in another region sees these plus its own round trip.
379
+ *
380
+ * Durations, not instants: an instant is approximately `startedAt` plus the
381
+ * running sum, and per-phase wall-clock stamps would make clock skew between
382
+ * the server and your runner look like latency. Approximately, because
383
+ * `totalMs` is the resolve's true wall time and covers a little work no phase
384
+ * owns, so the phases account for it without summing to it exactly.
385
+ *
386
+ * `startedAt` and `totalMs` are always present. The phases are optional
387
+ * because a failed resolve reports only the ones it reached, and `totalMs` is
388
+ * then time-to-failure. On success every phase is present except `warmupMs`,
389
+ * which is absent when no warm-up SQL was supplied.
390
+ */
391
+ interface DbBranchTimings {
392
+ /** When the resolve began, ISO. */
393
+ startedAt: string;
394
+ /** Resolving the project, plus its retention and region reads. */
395
+ projectResolveMs?: number;
396
+ /** Creating the branch, through its provider operations reaching terminal. */
397
+ branchCreateMs?: number;
398
+ /** Resolving the connection URI. 0 when the provider returns one inline. */
399
+ connectionUriMs?: number;
400
+ /** The compute accepting a connection. */
401
+ computeConnectMs?: number;
402
+ /** The branch answering a readiness query. */
403
+ baseProbeMs?: number;
404
+ /** Your warm-up SQL. Absent when you supplied none. */
405
+ warmupMs?: number;
406
+ /** The whole resolve, or time-to-failure when it threw. */
407
+ totalMs: number;
408
+ }
409
+ /**
410
+ * Wire shape of the caller's `ReplayOptions.dbBranch`, sent to
411
+ * `/api/sdk/replay/start` and applied per lease.
412
+ */
413
+ interface DbBranchSettings {
414
+ minCu?: number;
415
+ maxCu?: number;
416
+ warmupSql?: string;
417
+ }
418
+ /**
419
+ * Pre-built lookup table of historical span outputs.
420
+ * Keys are `${traceFunctionKey}:${spanName}:${callIndex}` so that repeated
421
+ * calls with the same (key, name) are matched by call order, but spans
422
+ * sharing only the traceFunctionKey (different name) do not collide.
423
+ */
424
+ interface MockTree {
425
+ spans: Map<string, MockSpan>;
426
+ }
427
+ interface ReplayContext {
428
+ experimentId: string;
429
+ selectiveReplay?: SelectiveReplayRuntime;
430
+ traceId?: string;
431
+ inputSourceSpanId?: string;
432
+ /**
433
+ * External trace ID from `external_traces.id`. Used for span-chain
434
+ * lookup against the source platform's trace tree (Braintrust, etc.).
435
+ * NOT the same as the Bitfab `traceId` - see `sourceBitfabTraceId`.
436
+ */
437
+ inputSourceTraceId?: string;
438
+ /**
439
+ * The Bitfab `traces.id` of the historical trace that produced this
440
+ * replay item's input. This is what customer-facing surfaces (e.g.
441
+ * `ReplayBranch.traceId`) should expose, since it's the ID the
442
+ * customer sees in the Bitfab dashboard.
443
+ */
444
+ sourceBitfabTraceId?: string;
445
+ replayAttempt?: number;
446
+ mockTree?: MockTree;
447
+ callCounters?: Map<string, number>;
448
+ mockStrategy?: "none" | "all" | "marked";
449
+ /**
450
+ * Resolved override chain for this replay, per-call overrides first then
451
+ * registered ones (first matcher wins). Empty/absent when no overrides apply.
452
+ */
453
+ mockOverrides?: MockOverride[];
454
+ /**
455
+ * Memoized lazy fetch of a span's recorded output (deserialized), keyed by
456
+ * `externalSpanId`. Present ONLY on a non-`all` path that needs a tree
457
+ * (`marked`, or `none` with overrides); absent under `mock: "all"`, where
458
+ * outputs are inline even when overrides are present. Its presence is the
459
+ * signal that outputs must be fetched rather than read inline.
460
+ */
461
+ fetchSpanOutput?: (externalSpanId: string) => Promise<unknown>;
462
+ /** Internal framework state captured on the historical root span. */
463
+ integrationFixtures?: Map<string, unknown>;
464
+ dbBranchLease?: DbBranchLease;
465
+ /**
466
+ * Server-measured provisioning timings for this item's branch, echoed back
467
+ * on the trace completion so the trace records what it cost to set up. Kept
468
+ * off `ReplayBranch`: customer code reads that mid-replay to reach the
469
+ * branch, and provisioning latency is a property of the run, not of the
470
+ * connection.
471
+ */
472
+ dbBranchTimings?: DbBranchTimings;
473
+ /**
474
+ * Set to true by `ReplayBranch` the first time customer code actually
475
+ * obtains `databaseUrl` for this item. Reported on the trace completion inside
476
+ * `db_snapshot_usage` so the server can distinguish "branch was
477
+ * provisioned and exposed" from "branch URL was actually consumed".
478
+ * Only an explicit `databaseUrl` read may set it. A path that hands the URL
479
+ * over by other means (e.g. a process-isolated runner writing an env
480
+ * overlay) must leave it alone: setting it there would make every such
481
+ * replay report `accessed` for free, and the flag would stop separating
482
+ * "branch was used" from "branch was offered".
483
+ */
484
+ dbSnapshotAccessed?: boolean;
485
+ }
486
+ //#endregion
487
+ //#region src/replayInvocation.d.ts
488
+ type FlagScalar = string | number | boolean | null;
489
+ type FlagValue = FlagScalar | FlagScalar[];
490
+ type ReplayEnvironment = "local" | "ci" | "cloud_replay";
491
+ interface ReplayInvocation {
492
+ flags: Record<string, FlagValue>;
493
+ sdk: {
494
+ language: "typescript";
495
+ version: string;
496
+ };
497
+ environment: ReplayEnvironment;
498
+ }
499
+ //#endregion
500
+ //#region src/simulationPlan.d.ts
501
+ interface SimulationPlanNode {
502
+ traceFunctionKey: string;
503
+ name: string;
504
+ captureContent: boolean;
505
+ }
506
+ interface SimulationPlanResponse {
507
+ nodes: SimulationPlanNode[];
508
+ }
509
+ type SimulationPlanSubmit = (payload: Record<string, unknown>) => void;
510
+ //#endregion
511
+ //#region src/http.d.ts
512
+ /**
513
+ * Wait for pending fire-and-forget requests AND every live span transport to
514
+ * deliver, within one total deadline. Useful in tests and scripts to ensure all
515
+ * data has been sent before asserting or exiting.
516
+ *
517
+ * Returns `false` when delivery failed or the deadline expired, so a caller
518
+ * that depends on persistence (replay does) can react instead of assuming a
519
+ * drained queue means the server has the data.
520
+ *
521
+ * @param timeoutMs - Maximum total time to wait in milliseconds (default: 5000)
522
+ */
523
+ declare function flushTraces(timeoutMs?: number): Promise<boolean>;
524
+ /**
525
+ * How the API key is supplied internally: either a literal string or a
526
+ * function resolved each time the key is needed (at request/send time). The
527
+ * function form is what defers key resolution past module-load construction
528
+ * so an env var loaded after the client is built (the ESM dotenv-hoisting
529
+ * case) is still picked up.
530
+ */
531
+ type ApiKeyInput = string | (() => string | undefined);
532
+ interface HttpClientConfig {
533
+ apiKey?: ApiKeyInput;
534
+ serviceUrl: string;
535
+ timeout?: number;
536
+ }
537
+ type SpanOccurrence = "first" | "last" | number;
538
+ declare const SPAN_TYPES: readonly ["llm", "agent", "function", "guardrail", "handoff", "custom"];
539
+ /**
540
+ * Span types matching the backend enum.
541
+ * - llm: LLM API calls
542
+ * - agent: Autonomous orchestrators
543
+ * - function: Tool implementations
544
+ * - guardrail: Safety/validation checks
545
+ * - handoff: Agent-to-agent transfers
546
+ * - custom: Application-specific tracing (default)
547
+ */
548
+ type SpanType = (typeof SPAN_TYPES)[number];
549
+ /**
550
+ * Which span `getTraceSpan` returns: `id` alone, or `name` and/or `type`
551
+ * with an optional `occurrence` (`"first"`, `"last"` by default, or a
552
+ * zero-based index into the matches in the order they ran).
553
+ */
554
+ type SpanLookup = {
555
+ id: string;
556
+ name?: never;
557
+ type?: never;
558
+ occurrence?: never;
559
+ } | {
560
+ name: string;
561
+ type?: SpanType;
562
+ id?: never;
563
+ occurrence?: SpanOccurrence;
564
+ } | {
565
+ type: SpanType;
566
+ name?: string;
567
+ id?: never;
568
+ occurrence?: SpanOccurrence;
569
+ };
570
+ interface CapturedSpan {
571
+ id: string;
572
+ traceId: string;
573
+ parentSpanId: string | null;
574
+ name: string | null;
575
+ type: string;
576
+ input: unknown;
577
+ output: unknown;
578
+ contexts: Record<string, unknown>[];
579
+ prompt: string | null;
580
+ metadata: Record<string, unknown>;
581
+ metrics: Record<string, unknown> | null;
582
+ errors: unknown;
583
+ startedAt: string | null;
584
+ endedAt: string | null;
585
+ }
586
+ /** What a caller learns about one tracked trace once it takes it back. */
587
+ interface DeliveryReport {
588
+ spanCount: number;
589
+ /** A closing carrier was submitted, so the expected set is final. */
590
+ closed: boolean;
591
+ /** Every carrier submitted under this trace came back accepted. */
592
+ delivered: boolean;
593
+ /**
594
+ * The server's assigned `traces.id`, read back from the OTLP ingest response.
595
+ * Absent when talking to a server that predates this field, or before any
596
+ * carrier for the trace has been acked.
597
+ */
598
+ serverTraceId?: string;
599
+ }
600
+ declare class HttpClient {
601
+ private readonly apiKey;
602
+ private readonly serviceUrl;
603
+ private readonly timeout;
604
+ private traceTransport;
605
+ private readonly traceDeliveries;
606
+ private readonly deferredWork;
607
+ readonly traceCompletion: TraceCompletion;
608
+ private closed;
609
+ private closing;
610
+ externalSpanTransform: ((payload: Record<string, unknown>, submit: SimulationPlanSubmit, drop: () => void) => void) | undefined;
611
+ externalTraceTransform: ((payload: Record<string, unknown>, submit: SimulationPlanSubmit) => void) | undefined;
612
+ releaseHeldExternalSpans: ((timeoutMs: number) => Promise<boolean> | Promise<void>) | undefined;
613
+ stopSimulationPlan: (() => void) | undefined;
614
+ constructor(config: HttpClientConfig);
615
+ /**
616
+ * Resolve the API key at the moment it is needed (request time), invoking
617
+ * the function form if one was supplied. Never read at construction.
618
+ */
619
+ private resolveApiKey;
620
+ /** @internal Whether this client currently has credentials for trace delivery. */
621
+ hasApiKey(): boolean;
622
+ /**
623
+ * This client's span transport, built on first use.
624
+ *
625
+ * Lazy on purpose: a client that never sends a span must never start a batch
626
+ * worker. Every framework integration created from a `Bitfab` client shares
627
+ * the owning client's `HttpClient`, so handlers reuse this one worker instead
628
+ * of each spinning up their own.
629
+ */
630
+ private getTraceTransport;
631
+ /**
632
+ * Post one encoded batch and decide what the server's answer means, so the
633
+ * transport never reads a response. Rejections and permanent statuses come
634
+ * back as a non-retryable {@link DeliveryError}; anything the server might
635
+ * still accept on a second try comes back retryable.
636
+ */
637
+ private deliverCarriers;
638
+ /**
639
+ * Start tracking delivery for `traceIds`. Nothing is recorded for a trace
640
+ * that was never tracked, so ordinary tracing costs no bookkeeping at all.
641
+ */
642
+ trackTraceDeliveries(traceIds: string[]): void;
643
+ /**
644
+ * The server's assigned `traces.id` for a tracked trace if it has already
645
+ * been read back off an ingest response, without stopping tracking. Lets a
646
+ * replay surface the id mid-run for items whose spans already landed.
647
+ */
648
+ peekServerTraceId(traceId: string): string | undefined;
649
+ /** Whether any tracked trace has had its closing carrier submitted. */
650
+ hasClosedDeliveries(traceIds: string[]): boolean;
651
+ /**
652
+ * Report what each tracked trace submitted and whether the server confirmed
653
+ * it, and stop tracking them. Every id passed is freed, so a caller cannot
654
+ * leak a record for a trace that never closed.
655
+ *
656
+ * `delivered` is only meaningful once a flush has settled: acks land before
657
+ * an export resolves, so a flush that reported success has already collected
658
+ * every ack it is going to collect.
659
+ */
660
+ takeTraceDeliveries(traceIds: string[]): Record<string, DeliveryReport>;
661
+ /** Build a carrier's meta and record what it adds to its trace's expected set. */
662
+ private recordedMeta;
663
+ private recordSubmittedCarrier;
664
+ /**
665
+ * Ingestion commits every carrier in a request before it answers, so a
666
+ * delivered ref is proof its row exists: the same fact the replay status
667
+ * endpoint would report, already in hand.
668
+ */
669
+ /**
670
+ * Record the server's assigned `traces.id` for each tracked source trace,
671
+ * read back from the OTLP ingest response. Keyed by source trace id, the same
672
+ * key the delivery ledger uses. Untracked ids are ignored.
673
+ */
674
+ private recordServerTraceIds;
675
+ private recordDeliveredCarriers;
676
+ /**
677
+ * Track deferred span work so this client's own lifecycle waits for it, and
678
+ * so the process-wide flush and exit hook do too.
679
+ */
680
+ trackDeferred<T>(promise: Promise<T>): Promise<T>;
681
+ /**
682
+ * Settle only THIS client's deferred span work. Scoped deliberately: the
683
+ * global set can contain another client's long-running finalize, and
684
+ * attributing its timeout here would fail a client whose own work succeeded.
685
+ */
686
+ settleDeferredWork(timeoutMs?: number): Promise<boolean>;
687
+ /**
688
+ * Wait for spans queued by this client to be delivered, within one deadline.
689
+ * Returns false on delivery failure or timeout.
690
+ */
691
+ waitForPendingRequests(timeoutMs?: number): Promise<boolean>;
692
+ /**
693
+ * Flush and permanently close this client's tracing transport. Idempotent:
694
+ * a second call joins the first rather than tearing down a pipeline the
695
+ * first call already owns.
696
+ */
697
+ close(timeoutMs?: number): Promise<boolean>;
698
+ /**
699
+ * Make an HTTP request to the Bitfab API. Defaults to POST; pass
700
+ * `options.method` to use a different verb (e.g. "PATCH").
701
+ *
702
+ * @param endpoint - The API endpoint (without base URL)
703
+ * @param payload - The request body
704
+ * @param options - Optional request options
705
+ * @returns The parsed JSON response
706
+ * @throws {BitfabError} If the request fails
707
+ */
708
+ request<T>(endpoint: string, payload: Record<string, unknown>, options?: {
709
+ timeout?: number;
710
+ method?: "POST" | "PATCH" | "PUT" | "DELETE";
711
+ }): Promise<T>;
712
+ /**
713
+ * POST an already-encoded body. The span transport encodes its own batches,
714
+ * so routing them back through {@link HttpClient.request} would encode the
715
+ * same data twice.
716
+ */
717
+ sendEncoded<T>(endpoint: string, body: string, options?: {
718
+ timeout?: number;
719
+ method?: "POST" | "PATCH" | "PUT" | "DELETE";
720
+ }): Promise<T>;
721
+ private sendPrepared;
722
+ /**
723
+ * Look up a function by name.
724
+ * Blocks until complete - needed for function execution.
725
+ */
726
+ lookupFunction<T>(name: string): Promise<T>;
727
+ getSimulationPlan(): Promise<SimulationPlanResponse>;
728
+ getTraceSpan(traceId: string, lookup: SpanLookup): Promise<CapturedSpan | null>;
729
+ getSpan(spanId: string): Promise<CapturedSpan | null>;
730
+ /**
731
+ * GET a JSON endpoint on the service with the client's API key. Throws a
732
+ * `BitfabError` carrying the status text for any non-2xx response.
733
+ */
734
+ get<T>(endpoint: string, timeoutMs?: number, extraHeaders?: Record<string, string>): Promise<T>;
735
+ /**
736
+ * Queue an internal trace (from local BAML execution via `call()`) onto this
737
+ * client's batching transport. `functionId` moves into the payload because
738
+ * the OTLP carrier has no path to carry it.
739
+ */
740
+ sendInternalTrace(functionId: string, payload: Record<string, unknown>): void;
741
+ sendExternalSpan(payload: Record<string, unknown>): void;
742
+ submitExternalSpan(payload: Record<string, unknown>): void;
743
+ /**
744
+ * Queue an external trace completion (from OpenAI tracing) onto this
745
+ * client's batching transport. Fire-and-forget for the same reason as
746
+ * {@link HttpClient.sendExternalSpan}; replay confirms persistence with the
747
+ * server-authoritative barrier in `replay.ts`, not by awaiting this call.
748
+ */
749
+ sendExternalTrace(rawPayload: Record<string, unknown>): void;
750
+ private sendCountedExternalTrace;
751
+ submitExternalTrace(payload: Record<string, unknown>): void;
752
+ /**
753
+ * Partial update of an existing trace identified by its Bitfab trace ID.
754
+ * Used by the detached `client.getTrace(id)` handle.
755
+ *
756
+ * Blocking, like the other trace-API calls: it resolves once the server has
757
+ * applied the change and rejects if the server refused it. A patch targets a
758
+ * trace that is already closed, so there is no batch for it to ride along
759
+ * with and no later signal that would reveal a silent failure.
760
+ */
761
+ patchTrace(traceId: string, payload: {
762
+ appendContexts?: Record<string, unknown>[];
763
+ mergeMetadata?: Record<string, unknown>;
764
+ setSessionId?: string;
765
+ setName?: string;
766
+ }): Promise<void>;
767
+ /**
768
+ * Start a replay session by fetching historical traces.
769
+ * Blocking call - creates an experiment and returns lightweight item references.
770
+ */
771
+ startReplay(traceFunctionKey: string, limit: number | undefined, traceIds?: string[], name?: string, codeChangeDescription?: string | null, codeChangeFiles?: CodeChangeFile[] | null, includeDbBranchLease?: boolean, experimentGroupId?: string, datasetIds?: string[], graderIds?: string[], dbBranchSettings?: DbBranchSettings, attempts?: number, includeOriginalMetadata?: boolean, onlyWithAssertions?: boolean, skipAssertionJudging?: boolean, experimentalSelectiveReplay?: SelectiveReplayOptions, notes?: string, metadata?: Record<string, string>, dryRun?: boolean, experimentGroupName?: string, invocation?: ReplayInvocation): Promise<StartReplayResponse>;
772
+ resumeReplay(experimentId: string, traceFunctionKey: string, codeChangeFiles?: CodeChangeFile[] | null, force?: boolean): Promise<ResumeReplayResponse>;
773
+ /**
774
+ * Fetch an external span by ID.
775
+ * Blocking GET request.
776
+ * The replay view limits rawData to input/output serialization fields.
777
+ */
778
+ getExternalSpan(spanId: string, options?: {
779
+ view?: "full" | "replay";
780
+ }): Promise<ExternalSpanResponse>;
781
+ /**
782
+ * Fetch the span tree for a root span.
783
+ * Blocking GET request.
784
+ *
785
+ * Pass `includeOutputs: false` for a payload-free tree (structure +
786
+ * `externalSpanId` only), so recorded outputs are fetched lazily per mocked
787
+ * span instead of all up front. Omit it (default eager) for `mock: "all"`.
788
+ * Pass `includeRootOutput: false` when the root was already fetched.
789
+ */
790
+ getSpanTree(externalSpanId: string, options?: {
791
+ includeOutputs?: boolean;
792
+ includeRootOutput?: boolean;
793
+ }): Promise<SpanTreeResponse>;
794
+ /**
795
+ * Read which of a replay run's traces the server has fully persisted.
796
+ *
797
+ * With `expectedSpanCounts`, a trace appears in the response only once it
798
+ * has a final status AND at least that many persisted spans, which is what
799
+ * makes this a real barrier rather than a "the row exists" check.
800
+ */
801
+ getReplayStatus(experimentId: string, expectedSpanCounts: Record<string, number>): Promise<ReplayStatusResponse>;
802
+ /**
803
+ * Mark a replay experiment as completed.
804
+ * Blocking call.
805
+ */
806
+ completeReplay(experimentId: string): Promise<CompleteReplayResponse>;
807
+ interruptReplay(experimentId: string): Promise<boolean>;
808
+ heartbeatReplay(experimentId: string): Promise<void>;
809
+ getReseedSource(traceId: string): Promise<ReseedSourceResponse>;
810
+ reseedTrace(traceId: string, runTraceId: string): Promise<ReseedTraceResponse>;
811
+ /**
812
+ * Ask the server to materialize a per-trace DB branch lease from a
813
+ * captured `dbSnapshotRef`. Blocking - the resolver creates a Neon
814
+ * snapshot + preview branch and polls operations to readiness, which
815
+ * can take seconds.
816
+ */
817
+ resolveDbBranchLease(experimentId: string, traceId: string, dbBranchSettings?: DbBranchSettings, attempt?: number): Promise<{
818
+ dbSnapshotRef: DbSnapshotRef | null;
819
+ lease: DbBranchLease | null;
820
+ leaseError: {
821
+ code: string;
822
+ message: string;
823
+ } | null;
824
+ timings: DbBranchTimings | null;
825
+ }>;
826
+ /** Release a previously-resolved DB branch by deleting its Neon branch. Idempotent server-side. */
827
+ releaseDbBranchLease(neonBranchId: string): Promise<void>;
828
+ }
829
+ interface TokenUsage {
830
+ input: number | null;
831
+ output: number | null;
832
+ cached: number | null;
833
+ total: number | null;
834
+ }
835
+ /**
836
+ * Describes a single file edited as part of a code change.
837
+ *
838
+ * - `path`: file path (relative to the repo root, or any consistent root)
839
+ * - `before`: file contents before the change ("" for newly created files)
840
+ * - `after`: file contents after the change ("" for deleted files)
841
+ */
842
+ interface CodeChangeFile {
843
+ path: string;
844
+ before: string;
845
+ after: string;
846
+ }
847
+ interface StartReplayResponse {
848
+ /** Null for a dry run, which the server records no experiment for. */
849
+ experimentId: string | null;
850
+ experimentUrl: string | null;
851
+ attempts?: number;
852
+ items: Array<{
853
+ selectiveReplayPlan?: SelectiveReplayPlan;
854
+ /** Bitfab trace ID of the original (historical) trace being replayed. */
855
+ originalTraceId?: string;
856
+ /** External span ID the recorded inputs were read from (the original root span). */
857
+ originalSpanId?: string;
858
+ /** @deprecated alias for `originalTraceId`; the only key emitted by servers that predate the rename. */
859
+ sourceTraceId: string;
860
+ /** @deprecated alias for `originalSpanId`; the only key emitted by servers that predate the rename. */
861
+ sourceSpanId: string;
862
+ durationMs: number | null;
863
+ tokens: TokenUsage | null;
864
+ model: string | null;
865
+ /**
866
+ * The DB snapshot ref captured by the SDK at trace open. Surfaced so
867
+ * the SDK can pass it to the lease-resolver step (or report when no
868
+ * snapshot was captured for this trace).
869
+ */
870
+ dbSnapshotRef?: DbSnapshotRef;
871
+ /**
872
+ * Populated once the server-side resolver has materialized a per-item
873
+ * branch from `dbSnapshotRef`. The SDK exposes this to customer code
874
+ * via `getCurrentReplayBranch()`. Absent until the resolver lands.
875
+ */
876
+ dbBranchLease?: DbBranchLease;
877
+ /**
878
+ * Why the branch could not be resolved, when one was requested and the
879
+ * attempt failed. Distinct from both fields being absent, which means the
880
+ * trace carried no snapshot ref so nothing was attempted.
881
+ */
882
+ dbBranchLeaseError?: {
883
+ code: string;
884
+ message: string;
885
+ };
886
+ /**
887
+ * How long provisioning took, per phase. Sits beside the two fields above
888
+ * rather than inside either: it is reported on both outcomes, complete on
889
+ * success and partial up to the failing phase on error. Absent from
890
+ * servers that predate it.
891
+ */
892
+ dbBranchTimings?: DbBranchTimings;
893
+ originalMetadata?: Record<string, unknown>;
894
+ }>;
895
+ }
896
+ type StartReplayItem = StartReplayResponse["items"][number];
897
+ interface ResumeReplayWorkPair {
898
+ itemIndex: number;
899
+ attempt: number;
900
+ }
901
+ interface ResumeReplayFinishedItem {
902
+ originalTraceId: string;
903
+ attempt: number;
904
+ traceId: string;
905
+ hasError: boolean;
906
+ }
907
+ interface ResumeReplayResponse {
908
+ experimentId: string;
909
+ experimentUrl: string;
910
+ attempts: number;
911
+ items: StartReplayItem[];
912
+ work: ResumeReplayWorkPair[];
913
+ finished: ResumeReplayFinishedItem[];
914
+ skippedOriginalTraceIds: string[];
915
+ includeDbBranchLease: boolean;
916
+ dbBranchSettings: DbBranchSettings | null;
917
+ }
918
+ interface ExternalSpanResponse {
919
+ id: string;
920
+ externalTraceId: string;
921
+ rawData: {
922
+ span_data: {
923
+ input: unknown;
924
+ output: unknown;
925
+ input_meta?: unknown;
926
+ output_meta?: unknown;
927
+ input_serialized?: {
928
+ json: unknown;
929
+ meta: unknown;
930
+ };
931
+ output_serialized?: {
932
+ json: unknown;
933
+ meta: unknown;
934
+ };
935
+ };
936
+ };
937
+ }
938
+ interface ReplayStatusResponse {
939
+ /**
940
+ * Local replay trace id -> server trace row id, for the traces the server
941
+ * considers fully persisted. Traces still short of their expected span count
942
+ * are simply absent.
943
+ */
944
+ traceIds?: Record<string, string>;
945
+ }
946
+ interface CompleteReplayResponse {
947
+ id: string;
948
+ status: string;
949
+ traceIds?: Record<string, string>;
950
+ /**
951
+ * Per-replay-trace token usage, keyed by the server trace id (the values of
952
+ * `traceIds`). Aggregated server-side from the freshly-uploaded replay spans,
953
+ * so it's the REPLAYED run's tokens (the same source the dashboard reads), not the
954
+ * original trace's. The SDK maps each item onto this to set
955
+ * `ReplayItem.tokens`. Absent on servers that predate this field.
956
+ */
957
+ tokens?: Record<string, TokenUsage | null>;
958
+ /**
959
+ * Number of traces the server has persisted for this experiment at
960
+ * completion time. Lets the SDK distinguish "uploads failed" from
961
+ * "server never saw them" when the trace-ID mapping is incomplete.
962
+ */
963
+ traceCount?: number;
964
+ }
965
+ interface ReseedSourceResponse {
966
+ traceId: string;
967
+ traceFunctionKey: string;
968
+ ingestionType: string;
969
+ name: string | null;
970
+ sessionId: string | null;
971
+ metadata: Record<string, unknown>;
972
+ input: unknown;
973
+ inputMeta: unknown;
974
+ inputSerialized: unknown;
975
+ }
976
+ interface ReseedTraceResponse {
977
+ traceId: string;
978
+ previousRunTraceId: string;
979
+ }
980
+ interface SpanTreeNode {
981
+ /** Upstream platform span id. Stable structural identity; NOT the row id. */
982
+ sourceSpanId: string;
983
+ /**
984
+ * The `externalSpans` row id, accepted by {@link HttpClient.getExternalSpan}.
985
+ * Distinct from `sourceSpanId`; used to lazily fetch this node's output when
986
+ * the tree was fetched with `includeOutputs: false`. Optional so trees from
987
+ * older servers (which omit it) still deserialize.
988
+ */
989
+ externalSpanId?: string;
990
+ traceFunctionKey: string;
991
+ spanName: string;
992
+ type: string;
993
+ /** Omitted when the tree was fetched payload-free (`includeOutputs: false`). */
994
+ output?: unknown;
995
+ outputMeta?: unknown;
996
+ children: SpanTreeNode[];
997
+ }
998
+ interface SpanTreeResponse {
999
+ root: SpanTreeNode;
1000
+ }
1001
+ //#endregion
1002
+ //#region src/categories.d.ts
1003
+ type CategorySummary = {
1004
+ id: string;
1005
+ title: string;
1006
+ description: string;
1007
+ };
1008
+ type Category = CategorySummary & {
1009
+ organizationId: string;
1010
+ createdAt: string;
1011
+ updatedAt: string;
1012
+ };
1013
+ type SaveCategoryParams = {
1014
+ id?: string;
1015
+ title: string;
1016
+ description?: string;
1017
+ };
1018
+ /** @deprecated Use {@link CategorySummary}. Same shape. */
1019
+ type AssertionCategorySummary = CategorySummary;
1020
+ /** @deprecated Use {@link Category}. Same shape. */
1021
+ type AssertionCategory = Category;
1022
+ /** @deprecated Use {@link SaveCategoryParams}. Same shape. */
1023
+ type SaveAssertionCategoryParams = SaveCategoryParams;
1024
+ /** Organization-scoped groupings for assertions and scenarios. */
1025
+ declare class CategoriesClient {
1026
+ private readonly httpClient;
1027
+ constructor(httpClient: HttpClient);
1028
+ /** Create a category, or update it by ID. Omitted descriptions are preserved. */
1029
+ save(params: SaveCategoryParams): Promise<Category>;
1030
+ /** Read one category in the API key's organization. */
1031
+ get(id: string): Promise<Category>;
1032
+ /** List the organization's categories ordered by title. */
1033
+ list(): Promise<Category[]>;
1034
+ /** Delete a category and clear its assignments, preserving assertions and verdicts. */
1035
+ delete(id: string): Promise<Category>;
1036
+ }
1037
+ /**
1038
+ * @deprecated Use {@link CategoriesClient}. Same class.
1039
+ * @alias
1040
+ */
1041
+ declare const AssertionCategoriesClient: typeof CategoriesClient;
1042
+ /**
1043
+ * @deprecated Use {@link CategoriesClient}. Same class.
1044
+ * @alias
1045
+ */
1046
+ type AssertionCategoriesClient = CategoriesClient;
1047
+ //#endregion
1048
+ //#region src/claudeAgentSdk.d.ts
1049
+ interface ActiveSpanContext$2 {
1050
+ traceId: string;
1051
+ spanId: string;
1052
+ }
1053
+ /**
1054
+ * Claude Agent SDK handler that sends traces to Bitfab.
1055
+ *
1056
+ * Captures LLM turns, tool invocations, and subagent execution as
1057
+ * Bitfab spans with proper parent-child hierarchy.
1058
+ *
1059
+ * The TypeScript Claude Agent SDK exposes a single `query()` entry point (there
1060
+ * is no `ClaudeSDKClient` class - that exists only in the Python SDK). Wrap the
1061
+ * `query()` async iterator with `wrapQuery`; tool and subagent spans come from
1062
+ * the hooks injected by `instrumentOptions`.
1063
+ *
1064
+ * ```typescript
1065
+ * import { Bitfab } from "@bitfab/sdk";
1066
+ * import { query } from "@anthropic-ai/claude-agent-sdk";
1067
+ *
1068
+ * const bitfab = new Bitfab({ apiKey: "..." });
1069
+ * const handler = bitfab.getClaudeAgentHandler("my-agent");
1070
+ *
1071
+ * const options = handler.instrumentOptions({
1072
+ * model: "claude-sonnet-4-5-...",
1073
+ * });
1074
+ *
1075
+ * for await (const message of handler.wrapQuery(
1076
+ * query({ prompt: "Do something", options })
1077
+ * )) {
1078
+ * // process messages normally
1079
+ * }
1080
+ * ```
1081
+ */
1082
+ declare class BitfabClaudeAgentHandler {
1083
+ private readonly httpClient;
1084
+ private readonly ownsHttpClient;
1085
+ private readonly traceFunctionKey;
1086
+ private readonly getActiveSpanContext;
1087
+ private readonly shouldRecord;
1088
+ private runToSpan;
1089
+ private traceId;
1090
+ private rootSpanId;
1091
+ private activeContext;
1092
+ private traceStartedAt;
1093
+ private conversationHistory;
1094
+ private pendingMessages;
1095
+ private currentLlmSpanId;
1096
+ private currentLlmMessageId;
1097
+ private currentLlmContent;
1098
+ private currentLlmModel;
1099
+ private currentLlmUsage;
1100
+ private currentLlmStartedAt;
1101
+ private currentLlmHistorySnapshot;
1102
+ private activeSubagentSpans;
1103
+ private hasRootInput;
1104
+ private rootInput;
1105
+ private rootOutput;
1106
+ constructor(config: {
1107
+ apiKey?: ApiKeyInput;
1108
+ traceFunctionKey: string;
1109
+ serviceUrl?: string;
1110
+ timeout?: number;
1111
+ getActiveSpanContext?: () => ActiveSpanContext$2 | null;
1112
+ shouldRecord?: () => boolean;
1113
+ /**
1114
+ * The owning `Bitfab` client's HTTP client. Supplied by
1115
+ * `getClaudeAgentHandler()` so this handler shares that client's single
1116
+ * span-transport worker instead of starting a second one.
1117
+ * @internal
1118
+ */
1119
+ _httpClient?: HttpClient;
1120
+ });
1121
+ /**
1122
+ * Flush and release the span transport this handler started. A no-op when
1123
+ * the handler borrowed a `Bitfab` client's HTTP client: that client's
1124
+ * `close()` owns the worker's lifetime.
1125
+ */
1126
+ close(timeoutMs?: number): Promise<boolean>;
1127
+ private ensureTrace;
1128
+ private getParentId;
1129
+ private maybeStartRootSpan;
1130
+ private completeRootSpan;
1131
+ private startSpan;
1132
+ private completeSpan;
1133
+ private sendSpan;
1134
+ private sendTraceCompletion;
1135
+ private preToolUseHook;
1136
+ private postToolUseHook;
1137
+ private postToolUseFailureHook;
1138
+ private subagentStartHook;
1139
+ private subagentStopHook;
1140
+ /**
1141
+ * Inject Bitfab tracing hooks into Claude Agent SDK options.
1142
+ *
1143
+ * Modifies the options object and returns it for convenience.
1144
+ * The SDK's `HookMatcher` is constructed as a plain object
1145
+ * (`{ matcher: null, hooks: [callback] }`) to avoid requiring
1146
+ * `@anthropic-ai/claude-agent-sdk` as a dependency.
1147
+ *
1148
+ * @param options - Options object with a `hooks` property
1149
+ * @returns The modified options object with Bitfab hooks injected
1150
+ */
1151
+ instrumentOptions<T extends Record<string, unknown>>(options: T): T;
1152
+ /**
1153
+ * Wrap any Claude Agent SDK message stream to capture LLM turns.
1154
+ *
1155
+ * Yields every message unchanged while capturing assistant message
1156
+ * content as LLM turn spans. Kept for naming symmetry with the Python
1157
+ * SDK's `wrapResponse` (which wraps `ClaudeSDKClient.receiveResponse()`);
1158
+ * in TypeScript, prefer `wrapQuery` around `query()`.
1159
+ *
1160
+ * Pass `{ input }` (the prompt) to record a replayable root span - see
1161
+ * `wrapQuery`.
1162
+ */
1163
+ wrapResponse(stream: AsyncIterable<unknown>, opts?: {
1164
+ input?: unknown;
1165
+ }): AsyncIterable<unknown>;
1166
+ /**
1167
+ * Wrap a `query()` async iterator to capture LLM turns.
1168
+ *
1169
+ * Tool and subagent spans are captured separately via the hooks injected
1170
+ * by `instrumentOptions` into the `options` passed to `query()`.
1171
+ *
1172
+ * Pass `{ input }` - the prompt (or the serializable args that produced it)
1173
+ * - to make a handler-only run replayable: the handler records a root `agent`
1174
+ * span with that input, so `replay(key, fn)` can re-feed it. Omit it only
1175
+ * when an enclosing `withSpan` already supplies the replayable root.
1176
+ *
1177
+ * ```typescript
1178
+ * handler.wrapQuery(query({ prompt, options }), { input: prompt })
1179
+ * ```
1180
+ */
1181
+ wrapQuery(stream: AsyncIterable<unknown>, opts?: {
1182
+ input?: unknown;
1183
+ }): AsyncIterable<unknown>;
1184
+ private setRootInput;
1185
+ private processStream;
1186
+ private processMessage;
1187
+ private handleAssistantMessage;
1188
+ private handleUserMessage;
1189
+ private handleResultMessage;
1190
+ private flushLlmTurn;
1191
+ private resetState;
1192
+ }
1193
+ //#endregion
1194
+ //#region src/vercelAiSdk.d.ts
1195
+ /**
1196
+ * Vercel AI SDK integration for Bitfab tracing.
1197
+ *
1198
+ * The Vercel AI SDK (`ai`) routes every `generateText` / `streamText` /
1199
+ * `generateObject` / `streamObject` call through a language model. Bitfab hooks
1200
+ * that model with a *language-model middleware* (`wrapLanguageModel`), so each
1201
+ * model call is captured as a keyed `llm` span with no hand-written `withSpan`:
1202
+ *
1203
+ * ```typescript
1204
+ * import { Bitfab } from "@bitfab/sdk";
1205
+ * import { wrapLanguageModel, streamText } from "ai";
1206
+ * import { openai } from "@ai-sdk/openai";
1207
+ *
1208
+ * const bitfab = new Bitfab({ apiKey: "..." });
1209
+ *
1210
+ * const model = wrapLanguageModel({
1211
+ * model: openai("gpt-4o"),
1212
+ * middleware: bitfab.getVercelAiMiddleware("chat-turn"),
1213
+ * });
1214
+ *
1215
+ * const result = streamText({ model, messages });
1216
+ * return result.toUIMessageStreamResponse(); // live stream untouched
1217
+ * ```
1218
+ *
1219
+ * The span records the call parameters (the prompt/messages) as its input and a
1220
+ * serializable summary (`{ text, toolCalls, usage, finishReason }`) as its
1221
+ * output. Streaming is handled by passing the model's stream through a
1222
+ * reader that accumulates text and usage as the caller consumes it. Parts,
1223
+ * upstream errors, and cancellation propagate to the caller unchanged; the
1224
+ * span finalizes on completion, error, or cancellation with partial output.
1225
+ *
1226
+ * The middleware is fully duck-typed (no static or dynamic `ai` import), so it
1227
+ * adds no dependency and is browser-safe. It works with `ai` v5 and v6.
1228
+ */
1229
+ type LlmSpanOptions = {
1230
+ type: "llm";
1231
+ finalize: (result: unknown) => unknown | Promise<unknown>;
1232
+ surface: "inherit";
1233
+ instrumentation: "vercel-ai";
1234
+ };
1235
+ type WithSpanFn$1 = <TArgs extends unknown[], TReturn>(traceFunctionKey: string, options: LlmSpanOptions, fn: (...args: TArgs) => TReturn) => (...args: TArgs) => TReturn;
1236
+ /**
1237
+ * Duck-typed subset of the Vercel AI SDK language-model call parameters. The
1238
+ * only field we read for the span input is `prompt` (the messages), but the
1239
+ * whole object is recorded so the call is reconstructable on replay.
1240
+ */
1241
+ interface VercelCallParams {
1242
+ prompt?: unknown;
1243
+ [key: string]: unknown;
1244
+ }
1245
+ /** A content part of a non-streaming `doGenerate` result. */
1246
+ interface VercelContentPart {
1247
+ type: string;
1248
+ text?: string;
1249
+ toolCallId?: string;
1250
+ toolName?: string;
1251
+ input?: unknown;
1252
+ args?: unknown;
1253
+ }
1254
+ /** Duck-typed subset of a non-streaming `doGenerate` result. */
1255
+ interface VercelGenerateResult {
1256
+ content?: VercelContentPart[];
1257
+ text?: string;
1258
+ usage?: unknown;
1259
+ finishReason?: unknown;
1260
+ [key: string]: unknown;
1261
+ }
1262
+ /** Duck-typed subset of a single streaming part from `doStream`. */
1263
+ interface VercelStreamPart {
1264
+ type: string;
1265
+ error?: unknown;
1266
+ delta?: string;
1267
+ textDelta?: string;
1268
+ toolCallId?: string;
1269
+ toolName?: string;
1270
+ input?: unknown;
1271
+ args?: unknown;
1272
+ usage?: unknown;
1273
+ finishReason?: unknown;
1274
+ }
1275
+ /** Duck-typed subset of a streaming `doStream` result. */
1276
+ interface VercelStreamResult {
1277
+ stream: ReadableStream<VercelStreamPart>;
1278
+ [key: string]: unknown;
1279
+ }
1280
+ interface MiddlewareCall<TResult> {
1281
+ doGenerate: () => PromiseLike<VercelGenerateResult>;
1282
+ doStream: () => PromiseLike<VercelStreamResult>;
1283
+ params: VercelCallParams;
1284
+ model: unknown;
1285
+ __result?: TResult;
1286
+ }
1287
+ /**
1288
+ * The structural shape of a Vercel AI SDK language-model middleware. Matches
1289
+ * `LanguageModelV3Middleware` from `@ai-sdk/provider` without importing it, so
1290
+ * the SDK stays dependency-free. `wrapLanguageModel` only reads the method
1291
+ * fields (it ignores `specificationVersion`), so this object drops straight in.
1292
+ */
1293
+ interface BitfabLanguageModelMiddleware {
1294
+ specificationVersion: "v3";
1295
+ wrapGenerate: (options: MiddlewareCall<VercelGenerateResult>) => Promise<any>;
1296
+ wrapStream: (options: MiddlewareCall<VercelStreamResult>) => Promise<any>;
1297
+ }
1298
+ /**
1299
+ * Vercel AI SDK middleware that records each language-model call as a keyed
1300
+ * `llm` span. Obtain it from {@link BitfabClient.getVercelAiMiddleware} rather
1301
+ * than constructing it directly.
1302
+ */
1303
+ declare class BitfabVercelAiHandler {
1304
+ private readonly traceFunctionKey;
1305
+ private readonly withSpanFn;
1306
+ constructor(config: {
1307
+ traceFunctionKey: string;
1308
+ withSpan: WithSpanFn$1;
1309
+ });
1310
+ /** The `wrapLanguageModel` middleware object for this trace function key. */
1311
+ get middleware(): BitfabLanguageModelMiddleware;
1312
+ }
1313
+ //#endregion
1314
+ //#region src/datasets.d.ts
1315
+ interface DatasetGraderRef {
1316
+ id: string;
1317
+ name: string | null;
1318
+ }
1319
+ interface Dataset {
1320
+ id: string;
1321
+ traceFunctionKey: string;
1322
+ name: string;
1323
+ description: string | null;
1324
+ traceCount: number;
1325
+ graders: DatasetGraderRef[];
1326
+ /**
1327
+ * Whether the dataset is marked golden for the whole organization, as a
1328
+ * trusted reference set. Golden datasets are listed first in the Bitfab app.
1329
+ * Reported as `false` by servers that predate golden datasets.
1330
+ */
1331
+ golden: boolean;
1332
+ createdAt: string;
1333
+ updatedAt: string;
1334
+ }
1335
+ interface SaveDatasetParams {
1336
+ traceFunctionKey: string;
1337
+ name: string;
1338
+ description?: string;
1339
+ /**
1340
+ * `true` marks the dataset as golden for the whole organization, `false`
1341
+ * unmarks it, and omitting it leaves it as it is (a new dataset starts not
1342
+ * golden).
1343
+ */
1344
+ golden?: boolean;
1345
+ }
1346
+ interface UpdateDatasetParams {
1347
+ name?: string;
1348
+ description?: string;
1349
+ /**
1350
+ * `true` marks the dataset as golden for the whole organization, `false`
1351
+ * unmarks it, and omitting it leaves it as it is.
1352
+ */
1353
+ golden?: boolean;
1354
+ }
1355
+ interface SaveDatasetResult {
1356
+ dataset: Dataset;
1357
+ created: boolean;
1358
+ }
1359
+ interface ListDatasetsParams {
1360
+ traceFunctionKey?: string;
1361
+ }
1362
+ interface DatasetTraceIds {
1363
+ datasetId: string;
1364
+ traceIds: string[];
1365
+ }
1366
+ interface AddDatasetTracesResult {
1367
+ dataset: Dataset;
1368
+ addedTraceIds: string[];
1369
+ alreadyPresentTraceIds: string[];
1370
+ skippedTraceIds: string[];
1371
+ }
1372
+ interface RemoveDatasetTracesResult {
1373
+ dataset: Dataset;
1374
+ removedTraceIds: string[];
1375
+ notPresentTraceIds: string[];
1376
+ }
1377
+ interface AddDatasetGradersResult {
1378
+ dataset: Dataset;
1379
+ addedGraderIds: string[];
1380
+ alreadyAssignedGraderIds: string[];
1381
+ skippedGraderIds: string[];
1382
+ }
1383
+ interface RemoveDatasetGradersResult {
1384
+ dataset: Dataset;
1385
+ removedGraderIds: string[];
1386
+ notAssignedGraderIds: string[];
1387
+ }
1388
+ type GraderRerunStatus = "pending" | "running" | "completed" | "errored";
1389
+ interface GraderRerunProgress {
1390
+ completedTraces: number;
1391
+ totalTraces: number;
1392
+ graderCount: number;
1393
+ }
1394
+ interface GraderRerunResult {
1395
+ tracesGraded: number;
1396
+ gradersRun: number;
1397
+ }
1398
+ interface GraderRerun {
1399
+ id: string;
1400
+ status: GraderRerunStatus;
1401
+ graderIds: string[];
1402
+ progress: GraderRerunProgress | null;
1403
+ result: GraderRerunResult | null;
1404
+ error: string | null;
1405
+ createdAt: string;
1406
+ updatedAt: string;
1407
+ }
1408
+ interface RerunGradersOptions {
1409
+ graderIds?: string[];
1410
+ timeoutMs?: number;
1411
+ }
1412
+ interface RerunGradersResult {
1413
+ run: GraderRerun;
1414
+ joinedExisting: boolean;
1415
+ }
1416
+ declare class GraderRerunError extends Error {
1417
+ readonly run: GraderRerun;
1418
+ constructor(message: string, run: GraderRerun);
1419
+ }
1420
+ declare class GraderRerunTimeoutError extends GraderRerunError {
1421
+ constructor(datasetId: string, run: GraderRerun, timeoutMs: number);
1422
+ }
1423
+ /**
1424
+ * Dataset operations for the authenticated organization, reached as
1425
+ * `client.datasets`. A dataset is a named bucket of traces scoped to one trace
1426
+ * function. Experiments replay against it and its graders score its members.
1427
+ */
1428
+ declare class DatasetsClient {
1429
+ private readonly httpClient;
1430
+ constructor(httpClient: HttpClient);
1431
+ /**
1432
+ * Create a dataset, or update the one already named this way under the same
1433
+ * trace function. `created` reports which happened. An omitted description
1434
+ * leaves an existing one untouched.
1435
+ */
1436
+ save(params: SaveDatasetParams): Promise<SaveDatasetResult>;
1437
+ /**
1438
+ * Rename a dataset or change its description in place. The dataset keeps its
1439
+ * id, traces, and graders. An empty `description` clears it. Rejects with a
1440
+ * 400 `BitfabError` when the new name is already used by another dataset on
1441
+ * the same trace function, and a 404 when the dataset is not in this
1442
+ * organization.
1443
+ */
1444
+ update(datasetId: string, params: UpdateDatasetParams): Promise<Dataset>;
1445
+ /**
1446
+ * List datasets, scoped to one trace function when `traceFunctionKey` is
1447
+ * given and organization-wide otherwise. Fetches all pages automatically.
1448
+ */
1449
+ list(params?: ListDatasetsParams): Promise<Dataset[]>;
1450
+ /** Fetch one dataset by id. Rejects with a 404 `BitfabError` when it is not in this organization. */
1451
+ get(datasetId: string): Promise<Dataset>;
1452
+ /** Fetches all trace-ID pages, the same membership a replay with `datasetId` selects. */
1453
+ listTraces(datasetId: string): Promise<DatasetTraceIds>;
1454
+ /**
1455
+ * Add traces to the dataset (1 to 100 ids per call). Traces outside the
1456
+ * organization or under another trace function are reported in
1457
+ * `skippedTraceIds` rather than failing the call.
1458
+ */
1459
+ addTraces(datasetId: string, traceIds: string[]): Promise<AddDatasetTracesResult>;
1460
+ /** Remove traces from the dataset. The traces themselves are never deleted. */
1461
+ removeTraces(datasetId: string, traceIds: string[]): Promise<RemoveDatasetTracesResult>;
1462
+ /**
1463
+ * Assign graders to the dataset (1 to 100 ids per call). Graders outside the
1464
+ * organization or under another trace function are reported in
1465
+ * `skippedGraderIds` rather than failing the call.
1466
+ */
1467
+ addGraders(datasetId: string, graderIds: string[]): Promise<AddDatasetGradersResult>;
1468
+ /** Unassign graders from the dataset. */
1469
+ removeGraders(datasetId: string, graderIds: string[]): Promise<RemoveDatasetGradersResult>;
1470
+ rerunGraders(datasetId: string, options?: RerunGradersOptions): Promise<RerunGradersResult>;
1471
+ /**
1472
+ * The dataset's active grader re-run, or the run named by `runId`. Returns
1473
+ * `null` when nothing is active or the run does not belong to this dataset.
1474
+ */
1475
+ getGraderRerun(datasetId: string, runId?: string): Promise<GraderRerun | null>;
1476
+ }
1477
+ //#endregion
1478
+ //#region src/experiments.d.ts
1479
+ type ExperimentStatus = "pending" | "completed" | "failed" | "interrupted";
1480
+ type ExperimentRunBy = {
1481
+ id: string;
1482
+ fullName: string | null;
1483
+ email: string | null;
1484
+ imageUrl: string | null;
1485
+ };
1486
+ type ExperimentCodeChangeTotals = {
1487
+ files: number;
1488
+ added: number;
1489
+ removed: number;
1490
+ };
1491
+ type Experiment = {
1492
+ id: string;
1493
+ name: string | null;
1494
+ notes: string | null;
1495
+ status: ExperimentStatus;
1496
+ traceFunctionKey: string | null;
1497
+ createdAt: string;
1498
+ completedAt: string | null;
1499
+ codeChangeDescription: string | null;
1500
+ codeChangeTotals: ExperimentCodeChangeTotals | null;
1501
+ experimentGroupId: string | null;
1502
+ experimentGroupName: string | null;
1503
+ datasetId: string | null;
1504
+ datasetName: string | null;
1505
+ datasetIds: string[];
1506
+ datasetNames: string[];
1507
+ attempts: number;
1508
+ plannedTraceCount: number | null;
1509
+ runBy: ExperimentRunBy | null;
1510
+ githubEmail: string | null;
1511
+ gitBranch: string | null;
1512
+ commitSha: string | null;
1513
+ baseSha: string | null;
1514
+ experimentSha: string | null;
1515
+ metadata: Record<string, string>;
1516
+ };
1517
+ type ExperimentPage = {
1518
+ experiments: Experiment[];
1519
+ nextCursor: string | null;
1520
+ hasMore: boolean;
1521
+ };
1522
+ type ListExperimentsParams = {
1523
+ datasetId?: string;
1524
+ traceFunctionKey?: string;
1525
+ gitBranch?: string;
1526
+ experimentGroupId?: string;
1527
+ status?: ExperimentStatus;
1528
+ metadata?: Record<string, string>;
1529
+ createdAfter?: Date | string;
1530
+ createdBefore?: Date | string;
1531
+ cursor?: string;
1532
+ limit?: number;
1533
+ };
1534
+ type ExperimentTally = {
1535
+ fixed: number;
1536
+ stillPassing: number;
1537
+ regressed: number;
1538
+ stillFailing: number;
1539
+ originalUnlabeled: number;
1540
+ unpaired: number;
1541
+ classified: number;
1542
+ passing: number;
1543
+ failing: number;
1544
+ /** Failing verdicts where the judge abstained on every attempt because it could not find the evidence. */
1545
+ abstained: number;
1546
+ };
1547
+ type ExperimentTotals = {
1548
+ total: number;
1549
+ traces: number;
1550
+ succeeded: number;
1551
+ failed: number;
1552
+ pending: number;
1553
+ awaitingLabels: number;
1554
+ errored: number;
1555
+ withErrors: number;
1556
+ ungradable: number;
1557
+ judging: number;
1558
+ skipped: number;
1559
+ };
1560
+ type ExperimentCategoryTally = {
1561
+ category: CategorySummary;
1562
+ labels: ExperimentTally;
1563
+ };
1564
+ type ExperimentJitter = {
1565
+ disagreeing: number;
1566
+ attempts: number;
1567
+ traces: number;
1568
+ };
1569
+ type ExperimentRollup = {
1570
+ traces: ExperimentTally;
1571
+ skippedTraces: number;
1572
+ labels: ExperimentTally;
1573
+ checks: ExperimentTally;
1574
+ categories: ExperimentCategoryTally[];
1575
+ jitter: ExperimentJitter;
1576
+ };
1577
+ type ExperimentRollupResult = {
1578
+ experimentId: string;
1579
+ totals: ExperimentTotals;
1580
+ rollup: ExperimentRollup;
1581
+ };
1582
+ declare class ExperimentsClient {
1583
+ private readonly httpClient;
1584
+ constructor(httpClient: HttpClient);
1585
+ list(params?: ListExperimentsParams): Promise<ExperimentPage>;
1586
+ get(id: string): Promise<Experiment>;
1587
+ getRollup(id: string): Promise<ExperimentRollupResult>;
1588
+ getRollupAll(ids: string[]): Promise<ExperimentRollupResult[]>;
1589
+ }
1590
+ //#endregion
1591
+ //#region src/traces.d.ts
1592
+ type TraceTargetOccurrence = "first" | "last" | number;
1593
+ type TraceTarget = {
1594
+ kind: "output";
1595
+ } | {
1596
+ kind: "span";
1597
+ name: string;
1598
+ occurrence?: TraceTargetOccurrence;
1599
+ };
1600
+ type TraceAssertionSource = "human" | "agent";
1601
+ type TraceSearchFilters = {
1602
+ callerMetadata?: Record<string, string>;
1603
+ name?: string;
1604
+ nameContains?: string;
1605
+ /** Only the replay traces this experiment produced. */
1606
+ experimentId?: string;
1607
+ };
1608
+ type TraceSearchParams = TraceSearchFilters & ({
1609
+ callerMetadata: Record<string, string>;
1610
+ } | {
1611
+ name: string;
1612
+ } | {
1613
+ nameContains: string;
1614
+ } | {
1615
+ experimentId: string;
1616
+ }) & {
1617
+ traceFunctionKey?: string;
1618
+ cursor?: string | null;
1619
+ limit?: number;
1620
+ };
1621
+ type TraceSearchResult = {
1622
+ traces: Array<{
1623
+ id: string;
1624
+ traceFunctionKey: string | null;
1625
+ name: string | null;
1626
+ status: "pending" | "completed" | "failed" | "dropped";
1627
+ createdAt: string;
1628
+ callerMetadata: Record<string, string>;
1629
+ /** The experiment that produced this trace, or null for a captured trace. */
1630
+ experimentId: string | null;
1631
+ /** Wall-clock time of the whole trace, or null when it has no end time. */
1632
+ durationMs: number | null;
1633
+ /** Token usage summed across the trace, or null when none was recorded. */
1634
+ tokens: TokenUsage | null;
1635
+ }>;
1636
+ nextCursor: string | null;
1637
+ hasMore: boolean;
1638
+ };
1639
+ type TraceAssertion = {
1640
+ id: string;
1641
+ traceId: string;
1642
+ assertion: string;
1643
+ humanNote: string | null;
1644
+ category_id: string | null;
1645
+ /** @deprecated Use {@link category_id}. Same value. */
1646
+ category_assertion_id: string | null;
1647
+ category: CategorySummary | null;
1648
+ passCriteria: string | null;
1649
+ failCriteria: string | null;
1650
+ targetOnEvaluatedTrace: TraceTarget | null;
1651
+ source: TraceAssertionSource;
1652
+ /** Why this assertion is right for its trace, span by span. */
1653
+ justification: Justification | null;
1654
+ /** Why its assigned category is the right one, span by span. */
1655
+ categoryJustification: Justification | null;
1656
+ /** Who is on the hook for reviewing this assertion, or null for nobody. */
1657
+ assignee: Assignee | null;
1658
+ createdAt: string;
1659
+ updatedAt: string;
1660
+ } & ApprovalFields;
1661
+ type AssertionEvidenceParameter = {
1662
+ name: string;
1663
+ type: "string" | "number" | "boolean" | "object" | "array" | "null" | "unknown";
1664
+ };
1665
+ type AssertionLabelEvidence = {
1666
+ spanId: string;
1667
+ text: string;
1668
+ sourceField: string;
1669
+ spanName: string | null;
1670
+ parameters: AssertionEvidenceParameter[];
1671
+ spanType: "llm" | "agent" | "function" | "guardrail" | "handoff" | "custom";
1672
+ isMocked: boolean;
1673
+ };
1674
+ type SaveAssertion = {
1675
+ /** Omit to preserve the category, or pass null to clear it. */
1676
+ category_id?: string | null;
1677
+ /** @deprecated Use {@link category_id}. Ignored when `category_id` is also set. */
1678
+ category_assertion_id?: string | null;
1679
+ id?: string;
1680
+ assertion: string;
1681
+ humanNote?: string | null;
1682
+ passCriteria?: string | null;
1683
+ failCriteria?: string | null;
1684
+ targetOnEvaluatedTrace?: TraceTarget | null;
1685
+ /**
1686
+ * Why this assertion is right for this trace, one entry per span it rests on.
1687
+ * Cite spans on this trace only. Omit on an edit to preserve it.
1688
+ */
1689
+ justification?: Justification | null;
1690
+ /**
1691
+ * Why `category_id` is the right category. Changing the category
1692
+ * clears it. Omit on an edit to preserve it.
1693
+ */
1694
+ categoryJustification?: Justification | null;
1695
+ /**
1696
+ * Email of the organization member who should review this assertion. Routing
1697
+ * only, so it leaves the approval state alone. Omit on an edit to preserve
1698
+ * the current assignee, or pass null to leave it to nobody.
1699
+ */
1700
+ assigneeEmail?: string | null;
1701
+ };
1702
+ type ScenarioSource = {
1703
+ spanId: string;
1704
+ sourceField: "input" | "output";
1705
+ text: string;
1706
+ };
1707
+ type ScenarioTrigger = {
1708
+ inputId: number | null;
1709
+ inputType: string;
1710
+ channel: string;
1711
+ from: string;
1712
+ to: string | null;
1713
+ cc: string | null;
1714
+ subject: string | null;
1715
+ type: string;
1716
+ eventTime: string;
1717
+ eventTimeSource: "message date" | "run start";
1718
+ source: "request" | "run instructions";
1719
+ content: string;
1720
+ contentPassages: string[];
1721
+ contentIsWholeMessage: boolean;
1722
+ sources: ScenarioSource[];
1723
+ };
1724
+ type ScenarioDataOrigin = {
1725
+ section: string;
1726
+ channel: string | null;
1727
+ from: string | null;
1728
+ to: string | null;
1729
+ cc: string | null;
1730
+ subject: string | null;
1731
+ sentAtText: string | null;
1732
+ };
1733
+ type ScenarioHistoryEntry = {
1734
+ role: "thread start" | "fact";
1735
+ kind: string;
1736
+ quote: string;
1737
+ summary: string | null;
1738
+ origin: ScenarioDataOrigin | null;
1739
+ sentAt: string | null;
1740
+ weekday: string | null;
1741
+ sincePrevious: string | null;
1742
+ source: ScenarioSource | null;
1743
+ };
1744
+ type ScenarioData = {
1745
+ hasHistory: boolean;
1746
+ topic: string;
1747
+ history: ScenarioHistoryEntry[];
1748
+ missing: string[];
1749
+ };
1750
+ /** One thing the run did, such as sending a message or calling a tool. */
1751
+ type ScenarioAction = {
1752
+ /** The action, for example `"send_sms_message"`. */
1753
+ name: string;
1754
+ /** The arguments the action was called with. */
1755
+ details: Record<string, unknown>;
1756
+ /** What came back from the action, or null when nothing did. */
1757
+ result: string | null;
1758
+ /** True when the action did not go through. */
1759
+ failed: boolean;
1760
+ /** When the action happened, as an ISO 8601 time, or null when unknown. */
1761
+ at: string | null;
1762
+ };
1763
+ /**
1764
+ * What the run actually did in this scenario, one example of a response. It
1765
+ * never says what the run should have done. Bitfab never fills it in. The
1766
+ * caller saves it with `saveScenario`.
1767
+ */
1768
+ type ScenarioActualOutcome = {
1769
+ /** What the run did, in a few sentences. */
1770
+ summary: string;
1771
+ /** The actions the run took, in order. */
1772
+ actions: ScenarioAction[];
1773
+ /**
1774
+ * The span the outcome was read from, on a trace linked to this scenario,
1775
+ * or null when it was not read from one.
1776
+ */
1777
+ source: ScenarioSource | null;
1778
+ };
1779
+ type Scenario = {
1780
+ id: string;
1781
+ createdAt: string;
1782
+ updatedAt: string;
1783
+ organizationId: string;
1784
+ traceFunctionId: string;
1785
+ sourceTraceId: string;
1786
+ extractor: "noah";
1787
+ name: string;
1788
+ description: string;
1789
+ trigger: ScenarioTrigger;
1790
+ data: ScenarioData;
1791
+ triggerSummary: string;
1792
+ dataSummary: string;
1793
+ /** What the run actually did, or null when none has been saved. */
1794
+ actualOutcome: ScenarioActualOutcome | null;
1795
+ /** Every category the scenario is filed under, sorted by title. */
1796
+ categories: CategorySummary[];
1797
+ };
1798
+ type SaveScenarioHistoryEntry = Omit<ScenarioHistoryEntry, "source"> & {
1799
+ source?: ScenarioSource | null;
1800
+ };
1801
+ type SaveScenarioData = Omit<ScenarioData, "history"> & {
1802
+ history: SaveScenarioHistoryEntry[];
1803
+ };
1804
+ /**
1805
+ * What the run actually did, as sent to `saveScenario`. `source` may be left
1806
+ * out, which saves it as null.
1807
+ */
1808
+ type SaveScenarioActualOutcome = Omit<ScenarioActualOutcome, "source"> & {
1809
+ source?: ScenarioSource | null;
1810
+ };
1811
+ type ScenarioDataAppend = {
1812
+ history?: SaveScenarioHistoryEntry[];
1813
+ missing?: string[];
1814
+ };
1815
+ type SaveScenarioParams = {
1816
+ traceId: string;
1817
+ name?: string;
1818
+ description?: string;
1819
+ trigger?: ScenarioTrigger;
1820
+ /**
1821
+ * What the run actually did, never what it should have done. Replaces the
1822
+ * saved value whole. Pass null to clear it, or leave it out to keep it.
1823
+ * Sending only this field, null included, is a valid save.
1824
+ */
1825
+ actualOutcome?: SaveScenarioActualOutcome | null;
1826
+ /**
1827
+ * Categories to file the scenario under. Replaces the whole set. Leave it
1828
+ * out to keep the current set, or pass an empty array to clear it. An id
1829
+ * outside the organization fails the save.
1830
+ */
1831
+ categoryIds?: string[];
1832
+ } & ({
1833
+ data?: SaveScenarioData;
1834
+ appendData?: never;
1835
+ } | {
1836
+ appendData: ScenarioDataAppend;
1837
+ data?: never;
1838
+ }) & ({
1839
+ name: string;
1840
+ } | {
1841
+ description: string;
1842
+ } | {
1843
+ trigger: ScenarioTrigger;
1844
+ } | {
1845
+ data: SaveScenarioData;
1846
+ } | {
1847
+ appendData: ScenarioDataAppend;
1848
+ } | {
1849
+ actualOutcome: SaveScenarioActualOutcome | null;
1850
+ } | {
1851
+ categoryIds: string[];
1852
+ });
1853
+ type AssertionGenerationStatus = "running" | "completed" | "failed";
1854
+ type AssertionGeneration = {
1855
+ status: AssertionGenerationStatus;
1856
+ error: string | null;
1857
+ assertionIds: string[];
1858
+ startedAt: string;
1859
+ finishedAt: string | null;
1860
+ };
1861
+ type TraceAssertionsResult = {
1862
+ assertions: TraceAssertion[];
1863
+ inheritedFrom: string | null;
1864
+ generation: AssertionGeneration | null;
1865
+ };
1866
+ type TraceAssertionsUpdate = {
1867
+ traceId: string;
1868
+ assertions: SaveAssertion[];
1869
+ };
1870
+ type SaveAssertionsParams = {
1871
+ traceId: string;
1872
+ assertions: SaveAssertion[];
1873
+ source?: TraceAssertionSource;
1874
+ };
1875
+ type SaveAssertionsAllParams = {
1876
+ updates: TraceAssertionsUpdate[];
1877
+ source?: TraceAssertionSource;
1878
+ };
1879
+ type ArchiveAssertionsParams = {
1880
+ traceId: string;
1881
+ assertionIds: string[];
1882
+ };
1883
+ type GenerateAssertionsOptions = {
1884
+ guidance?: string;
1885
+ categoryIds?: string[];
1886
+ regenerate?: boolean;
1887
+ timeoutMs?: number;
1888
+ };
1889
+ declare class AssertionGenerationError extends Error {
1890
+ readonly traceId: string;
1891
+ constructor(message: string, traceId: string);
1892
+ }
1893
+ declare class AssertionGenerationTimeoutError extends AssertionGenerationError {
1894
+ constructor(traceId: string, timeoutMs: number);
1895
+ }
1896
+ declare class TracesClient {
1897
+ private readonly httpClient;
1898
+ constructor(httpClient: HttpClient);
1899
+ search(params: TraceSearchParams): Promise<TraceSearchResult>;
1900
+ getAssertions(traceId: string): Promise<TraceAssertionsResult>;
1901
+ saveAssertions(params: SaveAssertionsParams): Promise<TraceAssertion[]>;
1902
+ saveAssertionsAll(params: SaveAssertionsAllParams): Promise<TraceAssertion[]>;
1903
+ generateAssertions(traceId: string, options?: GenerateAssertionsOptions): Promise<TraceAssertion[]>;
1904
+ archiveAssertions(params: ArchiveAssertionsParams): Promise<string[]>;
1905
+ getScenario(traceId: string): Promise<Scenario>;
1906
+ saveScenario({ traceId, ...edit }: SaveScenarioParams): Promise<Scenario>;
1907
+ }
1908
+ //#endregion
1909
+ //#region src/labels.d.ts
1910
+ type LabelConfidence = "VeryLow" | "Low" | "Medium" | "High" | "VeryHigh";
1911
+ type LabelAction = "set" | "archived" | "no-active-label" | "skipped" | "abstained";
1912
+ type LabelStatus = "labeled" | "skipped" | "unlabeled";
1913
+ type LabelSource = "human" | "agent";
1914
+ /** An assertion verdict. `abstained` means the judge could not find the evidence the assertion needs; it counts as a fail. */
1915
+ type Verdict = "pass" | "fail" | "abstained";
1916
+ type LabelAddress = {
1917
+ traceId: string;
1918
+ originalTraceId?: never;
1919
+ attempt?: never;
1920
+ } | {
1921
+ originalTraceId: string;
1922
+ attempt?: number;
1923
+ traceId?: never;
1924
+ };
1925
+ type LabelTarget = LabelAddress & {
1926
+ assertionId: string;
1927
+ };
1928
+ type ArchiveLabelTarget = LabelAddress & {
1929
+ assertionId?: string;
1930
+ };
1931
+ type LabelVerdict = {
1932
+ label: boolean;
1933
+ annotation: string;
1934
+ confidence?: LabelConfidence;
1935
+ evidence?: Justification | null;
1936
+ } | {
1937
+ skip: true;
1938
+ annotation?: string;
1939
+ } | {
1940
+ abstain: true;
1941
+ annotation?: string;
1942
+ };
1943
+ type LabelUpdate = (LabelTarget & LabelVerdict) | (ArchiveLabelTarget & {
1944
+ archive: true;
1945
+ });
1946
+ type LabelOutcome = {
1947
+ key: string;
1948
+ traceId: string;
1949
+ action: LabelAction;
1950
+ };
1951
+ type HumanLabelUpdate = {
1952
+ traceId: string;
1953
+ assertionId: string;
1954
+ label: boolean;
1955
+ annotation: string;
1956
+ confidence?: LabelConfidence;
1957
+ evidence?: Justification | null;
1958
+ };
1959
+ type HumanLabelOutcome = {
1960
+ traceId: string;
1961
+ assertionId: string | null;
1962
+ label: boolean;
1963
+ action: "set";
1964
+ };
1965
+ type AssertionVerdict = {
1966
+ assertionId: string;
1967
+ assertion: string | null;
1968
+ labelStatus: LabelStatus;
1969
+ label: boolean | null;
1970
+ /** The verdict, or null when there is none. `label` carries the same verdict as a boolean, false for both fail and abstained. */
1971
+ verdict: Verdict | null;
1972
+ annotation: string | null;
1973
+ evidence: Justification | null;
1974
+ confidence: LabelConfidence | null;
1975
+ labelSource: LabelSource;
1976
+ approved: boolean;
1977
+ };
1978
+ type TraceLabels = {
1979
+ traceId: string;
1980
+ labelStatus: LabelStatus;
1981
+ label: boolean | null;
1982
+ annotation: string | null;
1983
+ evidence: Justification | null;
1984
+ approved: boolean;
1985
+ passed: number;
1986
+ failed: number;
1987
+ /** How many of the failed assertion verdicts are abstentions, where the judge could not find the evidence. */
1988
+ abstained: number;
1989
+ assertions: AssertionVerdict[];
1990
+ };
1991
+ declare class LabelsClient {
1992
+ private readonly httpClient;
1993
+ constructor(httpClient: HttpClient);
1994
+ save(update: LabelUpdate, experimentId?: string): Promise<LabelOutcome>;
1995
+ saveAll(updates: LabelUpdate[], experimentId?: string): Promise<LabelOutcome[]>;
1996
+ skip(target: LabelTarget & {
1997
+ annotation?: string;
1998
+ }, experimentId?: string): Promise<LabelOutcome>;
1999
+ /**
2000
+ * Record that the evidence does not show the part of the run this assertion
2001
+ * checks, so there was nothing to judge. Counted as a fail in every pass
2002
+ * rate, but stored and read back as an abstention, apart from a fail. Pass
2003
+ * `annotation` to say what the evidence would have had to show.
2004
+ */
2005
+ abstain(target: LabelTarget & {
2006
+ annotation?: string;
2007
+ }, experimentId?: string): Promise<LabelOutcome>;
2008
+ archive(target: ArchiveLabelTarget, experimentId?: string): Promise<LabelOutcome>;
2009
+ saveHuman(update: HumanLabelUpdate): Promise<HumanLabelOutcome>;
2010
+ saveHumanAll(updates: HumanLabelUpdate[]): Promise<HumanLabelOutcome[]>;
2011
+ get(traceId: string): Promise<TraceLabels | null>;
2012
+ getAll(traceIds: string[]): Promise<TraceLabels[]>;
2013
+ /** Generate suggested evidence for an assertion on an original or replay trace. */
2014
+ generateLabelEvidence(traceId: string, assertionId: string): Promise<AssertionLabelEvidence[]>;
2015
+ }
2016
+ //#endregion
2017
+ //#region src/graders.d.ts
2018
+ type GraderLabelSource = "human" | "live_grader";
2019
+ type GraderLabel = {
2020
+ traceId: string;
2021
+ graderId: string;
2022
+ graderName: string | null;
2023
+ graderStatus: string;
2024
+ graderType: string;
2025
+ label: boolean | null;
2026
+ labelReason: string | null;
2027
+ failureDiagnostic: string | null;
2028
+ labelConfidence: LabelConfidence | null;
2029
+ source: GraderLabelSource;
2030
+ evaluatedAt: string | null;
2031
+ };
2032
+ type GetGraderLabelsParams = {
2033
+ traceIds?: string[];
2034
+ graderId?: string;
2035
+ limit?: number;
2036
+ };
2037
+ type GraderLabelUpdate = {
2038
+ graderId: string;
2039
+ traceId: string;
2040
+ label: boolean;
2041
+ reason?: string;
2042
+ failureDiagnostic?: string;
2043
+ confidence?: LabelConfidence;
2044
+ };
2045
+ type GraderLabelOutcome = {
2046
+ graderId: string;
2047
+ traceId: string;
2048
+ label: boolean;
2049
+ action: "set";
2050
+ };
2051
+ declare class GradersClient {
2052
+ private readonly httpClient;
2053
+ constructor(httpClient: HttpClient);
2054
+ getLabels(params: GetGraderLabelsParams): Promise<GraderLabel[]>;
2055
+ saveLabel(update: GraderLabelUpdate): Promise<GraderLabelOutcome>;
2056
+ saveLabelAll(updates: GraderLabelUpdate[]): Promise<GraderLabelOutcome[]>;
2057
+ }
2058
+ //#endregion
2059
+ //#region src/langgraph.d.ts
2060
+ interface ActiveSpanContext$1 {
2061
+ traceId: string;
2062
+ spanId: string;
2063
+ }
2064
+ /**
2065
+ * LangChain/LangGraph callback handler that sends traces to Bitfab.
2066
+ *
2067
+ * Duck-typed to match LangChain.js's BaseCallbackHandler, so no
2068
+ * `@langchain/core` dependency is required. Pass as a callback:
2069
+ *
2070
+ * ```typescript
2071
+ * const handler = bitfab.getLangGraphCallbackHandler("my-agent");
2072
+ * const result = await agent.invoke(
2073
+ * { messages: [...] },
2074
+ * { callbacks: [handler] },
2075
+ * );
2076
+ * ```
2077
+ */
2078
+ declare class BitfabLangGraphCallbackHandler {
2079
+ name: string;
2080
+ ignoreRetry: boolean;
2081
+ ignoreRetriever: boolean;
2082
+ ignoreCustomEvent: boolean;
2083
+ private readonly httpClient;
2084
+ private readonly ownsHttpClient;
2085
+ private readonly traceFunctionKey;
2086
+ private readonly getActiveSpanContext;
2087
+ private readonly shouldRecord;
2088
+ private readonly captureTools;
2089
+ private runToSpan;
2090
+ private invocations;
2091
+ constructor(config: {
2092
+ apiKey?: ApiKeyInput;
2093
+ traceFunctionKey: string;
2094
+ serviceUrl?: string;
2095
+ timeout?: number;
2096
+ getActiveSpanContext?: () => ActiveSpanContext$1 | null;
2097
+ shouldRecord?: () => boolean;
2098
+ /** Whether callback tool events should emit spans. Defaults to true. */
2099
+ captureTools?: boolean;
2100
+ /**
2101
+ * The owning `Bitfab` client's HTTP client. Supplied by
2102
+ * `getLangGraphCallbackHandler()` so this handler shares that client's
2103
+ * single span-transport worker instead of starting a second one.
2104
+ * @internal
2105
+ */
2106
+ _httpClient?: HttpClient;
2107
+ });
2108
+ /**
2109
+ * Flush and release the span transport this handler started. A no-op when
2110
+ * the handler borrowed a `Bitfab` client's HTTP client: that client's
2111
+ * `close()` owns the worker's lifetime.
2112
+ */
2113
+ close(timeoutMs?: number): Promise<boolean>;
2114
+ private startSpan;
2115
+ private completeSpan;
2116
+ private sendSpan;
2117
+ private sendTraceCompletion;
2118
+ private sendTraceStart;
2119
+ handleChainStart(chain: Record<string, unknown> | null | undefined, inputs: Record<string, unknown>, runId: string, parentRunIdOrRunType?: string, tags?: string[], metadata?: Record<string, unknown>, runTypeOrRunName?: string, runNameOrParentRunId?: string): Promise<void>;
2120
+ handleChainEnd(outputs: Record<string, unknown>, runId: string): Promise<void>;
2121
+ handleChainError(error: unknown, runId: string): Promise<void>;
2122
+ handleChatModelStart(llm: Record<string, unknown> | null | undefined, messages: unknown[][], runId: string, parentRunId?: string, _extraParams?: Record<string, unknown>, tags?: string[], metadata?: Record<string, unknown>, runName?: string): Promise<void>;
2123
+ handleLLMStart(llm: Record<string, unknown> | null | undefined, prompts: string[], runId: string, parentRunId?: string, _extraParams?: Record<string, unknown>, tags?: string[], metadata?: Record<string, unknown>, runName?: string): Promise<void>;
2124
+ handleLLMEnd(output: Record<string, unknown>, runId: string): Promise<void>;
2125
+ handleLLMError(error: unknown, runId: string): Promise<void>;
2126
+ handleLLMNewToken(): Promise<void>;
2127
+ handleToolStart(tool: Record<string, unknown> | null | undefined, input: string, runId: string, parentRunId?: string, tags?: string[], metadata?: Record<string, unknown>, runName?: string): Promise<void>;
2128
+ handleToolEnd(output: unknown, runId: string): Promise<void>;
2129
+ handleToolError(error: unknown, runId: string): Promise<void>;
2130
+ handleRetrieverStart(retriever: Record<string, unknown> | null | undefined, query: string, runId: string, parentRunId?: string, tags?: string[], metadata?: Record<string, unknown>, runName?: string): Promise<void>;
2131
+ handleRetrieverEnd(documents: unknown, runId: string): Promise<void>;
2132
+ handleRetrieverError(error: unknown, runId: string): Promise<void>;
2133
+ }
2134
+ //#endregion
2135
+ //#region src/langgraphIntegration.d.ts
2136
+ interface SpanClient {
2137
+ withSpan<TArgs extends unknown[], TReturn>(traceFunctionKey: string, options: {
2138
+ name?: string;
2139
+ type?: "agent" | "function";
2140
+ captureWhen?: "always" | "nested";
2141
+ mockOnReplay?: boolean;
2142
+ finalize?: (result: unknown) => unknown | Promise<unknown>;
2143
+ surface?: "inherit";
2144
+ instrumentation?: "langgraph";
2145
+ }, fn: (...args: TArgs) => TReturn): (...args: TArgs) => TReturn;
2146
+ }
2147
+ interface LangGraphTool {
2148
+ readonly name?: string;
2149
+ invoke(input: unknown, ...rest: unknown[]): unknown;
2150
+ }
2151
+ interface ConfiguredLangGraphRunnable<TInput, TConfig, TReturn> {
2152
+ invoke(input: TInput, config?: TConfig): TReturn;
2153
+ }
2154
+ interface LangGraphRunnable<TInput, TConfig, TReturn> {
2155
+ withConfig(config: {
2156
+ callbacks: unknown[];
2157
+ }): ConfiguredLangGraphRunnable<TInput, TConfig, TReturn>;
2158
+ }
2159
+ /**
2160
+ * Options for first-class LangGraph ToolNode replay interception.
2161
+ *
2162
+ * @experimental This API may change before it is stable.
2163
+ */
2164
+ interface LangGraphIntegrationOptions {
2165
+ /**
2166
+ * Tools marked for recorded-output mocking under replay's default
2167
+ * `mock: "marked"` strategy. Defaults to every wrapped tool. Pass a list to
2168
+ * mark only those tool names, or `false` to require `mock: "all"` or an
2169
+ * override.
2170
+ */
2171
+ mockToolsOnReplay?: boolean | readonly string[];
2172
+ }
2173
+ /**
2174
+ * First-class LangGraph integration for callback tracing and replayable
2175
+ * `ToolNode` tools.
2176
+ *
2177
+ * @experimental This API may change before it is stable.
2178
+ */
2179
+ declare class BitfabLangGraphIntegration {
2180
+ /** Callback handler for the compiled graph's invocation config. */
2181
+ readonly callbackHandler: any;
2182
+ private readonly client;
2183
+ private readonly traceFunctionKey;
2184
+ private readonly mockToolsOnReplay;
2185
+ constructor(config: {
2186
+ client: SpanClient;
2187
+ traceFunctionKey: string;
2188
+ callbackHandler: BitfabLangGraphCallbackHandler;
2189
+ options?: LangGraphIntegrationOptions;
2190
+ });
2191
+ /**
2192
+ * Wrap tools before passing the same returned array to both
2193
+ * `model.bindTools()` and `new ToolNode()`. Each invocation becomes an
2194
+ * independently mockable child span.
2195
+ */
2196
+ wrapTools<T extends readonly LangGraphTool[]>(tools: T): T;
2197
+ /**
2198
+ * Create the normal graph entry point. The returned function adds Bitfab's
2199
+ * callback handler, preserves invocation config, and records only the graph
2200
+ * input as the replayable root input.
2201
+ *
2202
+ * @experimental This API may change before it is stable.
2203
+ */
2204
+ createInvoker<TInput, TConfig, TReturn>(graph: LangGraphRunnable<TInput, TConfig, TReturn>): (input: TInput, config?: TConfig) => TReturn;
2205
+ private wrapTool;
2206
+ private assertReplayToolResultExists;
2207
+ /** Wrap the function that invokes the compiled graph as the replay root. */
2208
+ wrapInvoke<TArgs extends unknown[], TReturn>(fn: (...args: TArgs) => TReturn): (...args: TArgs) => TReturn;
2209
+ }
2210
+ //#endregion
2211
+ //#region src/openaiAgentSdk.d.ts
2212
+ /**
2213
+ * OpenAI Agents SDK handler for Bitfab tracing.
2214
+ *
2215
+ * The OpenAI Agents SDK is instrumented in two layers:
2216
+ *
2217
+ * 1. A process-wide `TracingProcessor` (see `getOpenAiTracingProcessor` /
2218
+ * `BitfabOpenAITracingProcessor`) registered once with `addTraceProcessor`.
2219
+ * It captures everything *inside* a run - LLM calls, tool calls, handoffs -
2220
+ * as Bitfab spans.
2221
+ * 2. This handler's `wrapRun`, which owns the *root*. The processor never sees
2222
+ * the caller's input (the SDK's trace events don't carry it), so a
2223
+ * processor-only run records a root span with an empty input and is not
2224
+ * replayable. `wrapRun` is a thin drop-in for `run()` that opens a
2225
+ * `withSpan` root carrying the input and final output, so the run is
2226
+ * replayable with no hand-written `withSpan`. The processor's spans nest
2227
+ * underneath it automatically (it remaps onto the active span context).
2228
+ *
2229
+ * When `wrapRun` runs inside an enclosing Bitfab span (the replay auto-wrap, or
2230
+ * a caller's own `withSpan`), that span is already the replayable root: the
2231
+ * handler skips opening a second one and lets the processor nest the run's spans
2232
+ * under the existing root. This mirrors the Claude Agent SDK and LangGraph
2233
+ * handlers, which no-op their root span under an enclosing span, and keeps a
2234
+ * replayed run's span tree identical to the original (no doubled root agent
2235
+ * span).
2236
+ *
2237
+ * Use both together: register the processor once at startup, then call
2238
+ * `handler.wrapRun(agent, input)` instead of `run(agent, input)`.
2239
+ */
2240
+ type AgentLike = any;
2241
+ type RunInput = string | unknown[] | Record<string, unknown>;
2242
+ type RunOptions = {
2243
+ stream?: boolean;
2244
+ } & Record<string, unknown>;
2245
+ type RunResultLike = {
2246
+ finalOutput?: unknown;
2247
+ completed?: Promise<void>;
2248
+ };
2249
+ type RootSpanOptions = {
2250
+ type: "agent";
2251
+ finalize: (result: unknown) => unknown | Promise<unknown>;
2252
+ surface: "inherit";
2253
+ instrumentation: "openai-agents";
2254
+ };
2255
+ type WithSpanFn = <TArgs extends unknown[], TReturn>(traceFunctionKey: string, options: RootSpanOptions, fn: (...args: TArgs) => TReturn) => (...args: TArgs) => TReturn;
2256
+ type GetActiveSpanContextFn = () => unknown | null;
2257
+ /**
2258
+ * OpenAI Agents SDK handler that records a replayable root span around a run.
2259
+ *
2260
+ * ```typescript
2261
+ * import { Bitfab } from "@bitfab/sdk";
2262
+ * import { addTraceProcessor, Agent, run } from "@openai/agents";
2263
+ *
2264
+ * const bitfab = new Bitfab({ apiKey: "..." });
2265
+ * addTraceProcessor(bitfab.getOpenAiTracingProcessor()); // captures internals
2266
+ *
2267
+ * const agent = new Agent({ name: "Researcher", instructions: "..." });
2268
+ * const handler = bitfab.getOpenAiAgentHandler("research-topic");
2269
+ *
2270
+ * // Swap run(agent, input) -> handler.wrapRun(agent, input)
2271
+ * const result = await handler.wrapRun(agent, "Find X");
2272
+ * return result.finalOutput;
2273
+ * ```
2274
+ */
2275
+ declare class BitfabOpenAIAgentHandler {
2276
+ private readonly traceFunctionKey;
2277
+ private readonly withSpanFn;
2278
+ private readonly getActiveSpanContext?;
2279
+ constructor(config: {
2280
+ traceFunctionKey: string;
2281
+ withSpan: WithSpanFn;
2282
+ getActiveSpanContext?: GetActiveSpanContextFn;
2283
+ });
2284
+ /**
2285
+ * Drop-in replacement for the OpenAI Agents SDK's `run()` that records a
2286
+ * replayable root `agent` span.
2287
+ *
2288
+ * The `input` is captured as the root span's input (as a single positional
2289
+ * argument, so `replay(key, fn)` re-feeds it), and the run's `finalOutput`
2290
+ * is recorded as the root output. For streaming runs (`{ stream: true }`),
2291
+ * the result is handed back immediately and the final output is recorded
2292
+ * once the stream completes - first-byte latency is untouched.
2293
+ *
2294
+ * The process-wide tracing processor (`getOpenAiTracingProcessor`) must still
2295
+ * be registered: it captures the LLM/tool/handoff spans that nest beneath
2296
+ * this root.
2297
+ */
2298
+ wrapRun(agent: AgentLike, input: RunInput, options?: RunOptions): Promise<RunResultLike>;
2299
+ }
2300
+ //#endregion
2301
+ //#region src/organizationMembers.d.ts
2302
+ type OrganizationMember = {
2303
+ id: string;
2304
+ fullName: string | null;
2305
+ email: string | null;
2306
+ imageUrl: string | null;
2307
+ };
2308
+ /** The people in the API key's organization. */
2309
+ declare class OrganizationMembersClient {
2310
+ private readonly httpClient;
2311
+ constructor(httpClient: HttpClient);
2312
+ /**
2313
+ * List the organization's members, ordered by name. Read it to find the
2314
+ * address to pass as an assertion's `assigneeEmail`.
2315
+ */
2316
+ list(): Promise<OrganizationMember[]>;
2317
+ }
2318
+ //#endregion
2319
+ //#region src/replayInterrupt.d.ts
2320
+ type ReplayInterruptSignal = "SIGINT" | "SIGTERM";
2321
+ interface ReplayInterrupt {
2322
+ experimentId: string;
2323
+ experimentUrl: string;
2324
+ signal: ReplayInterruptSignal;
2325
+ markedInterrupted: boolean;
2326
+ }
2327
+ //#endregion
2328
+ //#region src/replay.d.ts
2329
+ type MockStrategy = "none" | "all" | "marked";
2330
+ type TraceIngestionType = "captured" | "seeded";
2331
+ /**
2332
+ * How the DB-snapshot branch each replay item runs against is sized and warmed.
2333
+ *
2334
+ * Every field is optional, so this object is only worth passing when you want
2335
+ * to override the mirror project's own sizing. To branch with those defaults,
2336
+ * pass `dbBranch: true` instead of an empty object.
2337
+ */
2338
+ interface DbBranchOptions {
2339
+ /**
2340
+ * Autoscaling floor for the branch's compute, in Neon Compute Units (0.25 to
2341
+ * 56). Omit to keep the mirror project's own default. Raise it when the
2342
+ * mirror is provisioned smaller than the database it stands in for, so
2343
+ * replay latency reflects your code rather than a cold, undersized branch.
2344
+ */
2345
+ minCu?: number;
2346
+ /**
2347
+ * Autoscaling ceiling for the branch's compute, in Neon Compute Units.
2348
+ * Setting it equal to `minCu` pins the size, which keeps items comparable:
2349
+ * otherwise a later item can run against an endpoint that has already
2350
+ * scaled up and post a better number for the same code.
2351
+ */
2352
+ maxCu?: number;
2353
+ /**
2354
+ * SQL that warms the branch's cache. The server appends it to the branch's
2355
+ * readiness check, so it runs BEFORE your function sees the branch and its
2356
+ * time is not charged to the replayed call. Invalid SQL fails the branch
2357
+ * rather than silently leaving it cold.
2358
+ */
2359
+ warmupSql?: string;
2360
+ }
2361
+ interface ReplayOptions {
2362
+ /**
2363
+ * Experimental selective replay. Explicit required nodes
2364
+ * always execute; eligible output-only nodes reuse JSON recordings only
2365
+ * when runtime inputs match. Requires a compatible server, mock: "marked",
2366
+ * and no mock overrides or resume. Does not infer changes from codeChangeFiles.
2367
+ * The server reads active/inherited assertions and protects their scoped
2368
+ * execution evidence. Coverage in item.selectiveReplay is not a verdict.
2369
+ */
2370
+ experimentalSelectiveReplay?: SelectiveReplayOptions;
2371
+ /**
2372
+ * Maximum number of traces to replay (1-5,000, default 5). Ignored when
2373
+ * `traceIds` is passed (with a warning), or when `datasetId` / `datasetIds`
2374
+ * is passed, because either source already determines how many traces replay.
2375
+ * To replay part of a dataset selection, name the members to run in
2376
+ * `traceIds` rather than bounding it here.
2377
+ */
2378
+ limit?: number;
2379
+ attempts?: number;
2380
+ /**
2381
+ * Optional list of specific trace IDs to replay (max 100). Passed alongside
2382
+ * `datasetId` or `datasetIds` it pins which members of that selection replay,
2383
+ * and the server rejects any ID none of those datasets contains. On its own
2384
+ * it selects by ID with no dataset attribution.
2385
+ */
2386
+ traceIds?: string[];
2387
+ /**
2388
+ * What this run is testing, in a few words, such as 'baseline' or 'shorter
2389
+ * system prompt'. Bitfab records the commit, branch, tree state, datasets,
2390
+ * and who ran it with every experiment, so do not repeat them here.
2391
+ */
2392
+ name?: string;
2393
+ /**
2394
+ * Run conditions Bitfab cannot see on its own, such as an environment
2395
+ * override or a forced feature flag. Kept on the experiment next to its name.
2396
+ */
2397
+ notes?: string;
2398
+ metadata?: Record<string, string>;
2399
+ /** Positive integer limiting parallel items. Set to 1 for sequential. Default 10. */
2400
+ maxConcurrency?: number;
2401
+ /**
2402
+ * Description of the code change being tested in this replay. Stored on
2403
+ * the resulting experiment so the change can be reviewed alongside results.
2404
+ * Supplying a description without `codeChangeFiles` preserves this text
2405
+ * while the SDK automatically captures the files.
2406
+ * Pass `null` when the replay should have no description; use
2407
+ * `codeChangeFiles: null` to suppress automatic file capture.
2408
+ */
2409
+ codeChangeDescription?: string | null;
2410
+ /**
2411
+ * Files edited as part of this code change. Each entry holds the file path
2412
+ * and the full `before`/`after` contents. The agent reads each file before
2413
+ * and after editing and passes the two strings. Use `""` for newly created
2414
+ * files (`before`) or deleted files (`after`). Omit this field to capture
2415
+ * automatically, or pass `null` to suppress file capture for this replay.
2416
+ */
2417
+ codeChangeFiles?: CodeChangeFile[] | null;
2418
+ /**
2419
+ * Mock strategy for child spans during replay.
2420
+ * - "marked": only spans tagged with { mockOnReplay: true } in SpanOptions are mocked (default)
2421
+ * - "none": everything runs real code
2422
+ * - "all": every matched recorded child withSpan returns historical output;
2423
+ * a missing occurrence fails the replay item closed
2424
+ */
2425
+ mock?: MockStrategy;
2426
+ /**
2427
+ * Selective mock overrides: inject custom values into specific spans during
2428
+ * replay, so downstream real code runs against the substituted output. Each
2429
+ * Pass `{ match, value }` pairs, or one resolver invoked for every child span.
2430
+ * A resolver can route on `ctx.node.traceFunctionKey` and return
2431
+ * `NO_MOCK_OVERRIDE` to continue to the next override and base strategy.
2432
+ * Per-call overrides take precedence over registrations on the client.
2433
+ */
2434
+ mockOverride?: MockOverrideInput | MockOverrideInput[];
2435
+ /**
2436
+ * Run each item against a database branch restored to the state its source
2437
+ * trace saw. Pass `true` to branch with the mirror project's own sizing, or a
2438
+ * {@link DbBranchOptions} object to tune how each branch is sized and warmed.
2439
+ * `false` and omission leave branching off. Inside `fn`, read the resolved
2440
+ * branch with `getCurrentReplayBranch()`.
2441
+ *
2442
+ * Items whose source trace carried no DB snapshot reference get no branch and
2443
+ * use the app's normal database path. Unsafe calls on that path still require
2444
+ * replay mocking. An item whose branch was requested but could not be resolved
2445
+ * fails instead of running, so replay never silently reports a result that did
2446
+ * not use the historical data you asked for.
2447
+ */
2448
+ dbBranch?: DbBranchOptions | boolean;
2449
+ /**
2450
+ * Experiment group this replay joins, shown together on the experiments
2451
+ * page. An ID with no group yet creates the group.
2452
+ */
2453
+ experimentGroupId?: string;
2454
+ /**
2455
+ * Name for the experiment group in `experimentGroupId`. Applied when this
2456
+ * replay creates the group, or when the group exists without a name. A group
2457
+ * that already has a name keeps it. Requires `experimentGroupId`.
2458
+ */
2459
+ experimentGroupName?: string;
2460
+ /**
2461
+ * Dataset this replay runs against. Mutually exclusive with `datasetIds`.
2462
+ * Alone it replays the dataset's full membership, and with `traceIds` it
2463
+ * replays only those members. When set, the resulting experiment is
2464
+ * durably attributed to the dataset (stored on the experiment), so it appears
2465
+ * under the dataset's experiments even if the trace lineage can't be
2466
+ * reconstructed. Validated server-side against the org.
2467
+ */
2468
+ datasetId?: string;
2469
+ datasetIds?: string[];
2470
+ /**
2471
+ * Graders to attach directly to this experiment, independent of any
2472
+ * graders already on the dataset. The resulting experiment is graded by the
2473
+ * union of these and the dataset's runnable graders at completion, so use this
2474
+ * to grade a single run with a check you don't want to add to the dataset
2475
+ * permanently. Each id must be an active/live grader belonging to the same
2476
+ * organization and trace function, otherwise the server rejects the replay.
2477
+ */
2478
+ graderIds?: string[];
2479
+ /**
2480
+ * Replay only the selected traces that carry at least one approved assertion.
2481
+ *
2482
+ * Narrows whatever `limit`, `traceIds` or `datasetIds` selected, so a run that
2483
+ * measures assertion outcomes does not pay to re-execute traces nothing can
2484
+ * grade. The server applies it as part of selection, which is what makes it
2485
+ * compose with `limit`: `{ limit: 10, onlyWithAssertions: true }` is the ten
2486
+ * most recent traces that HAVE approved assertions, not the ten most recent
2487
+ * filtered down to however few do. An archived assertion does not count, and
2488
+ * neither does one still awaiting review: a replay is only ever judged
2489
+ * against assertions a person has approved, so a trace carrying nothing but
2490
+ * drafts has nothing here to measure. A selection that narrows to nothing
2491
+ * replays nothing.
2492
+ */
2493
+ onlyWithAssertions?: boolean;
2494
+ skipAssertionJudging?: boolean;
2495
+ judgeAssertions?: boolean;
2496
+ /**
2497
+ * Reshape recorded inputs before they are spread into `fn`.
2498
+ *
2499
+ * Replay pulls each trace's inputs exactly as they were captured against the
2500
+ * function's signature AT TRACE TIME. When the function's shape has since
2501
+ * changed (params renamed, reordered, collapsed into an options object, etc.),
2502
+ * the recorded inputs no longer line up and `fn(...inputs)` throws. This hook
2503
+ * lets a caller map the recorded inputs onto the current signature so replay
2504
+ * can still run.
2505
+ *
2506
+ * Receives the deserialized recorded inputs and a per-trace {@link AdaptContext}
2507
+ * (so a table-driven adapter can look up the adapted inputs by `traceId`), and
2508
+ * returns the array actually spread into `fn`. The returned array is also what
2509
+ * `ReplayItem.input` reports, so the experiment shows what was really run.
2510
+ *
2511
+ * Runs per item, inside the same try/catch as `fn`: if the adapter throws, the
2512
+ * failure is surfaced on that item's `error` rather than crashing the run.
2513
+ * Omit it to spread the recorded inputs unchanged.
2514
+ */
2515
+ adaptInputs?: (inputs: unknown[], ctx: AdaptContext) => unknown[];
2516
+ /**
2517
+ * Resolve every item's inputs and stop, without calling the function.
2518
+ *
2519
+ * Selection, span fetch, deserialization, and `adaptInputs` all run, so each
2520
+ * item reports the exact arguments the function would have received. Nothing
2521
+ * executes and no replay traces are produced, which is the cheap way to check
2522
+ * that recorded inputs still fit the current signature. No experiment is
2523
+ * created either, so the result's `experimentId` and `experimentUrl` are null
2524
+ * and `onExperimentStart` is not called.
2525
+ */
2526
+ dryRun?: boolean;
2527
+ /**
2528
+ * Called once per item as it finishes, in completion order (not input
2529
+ * order), with running totals for the whole run. Use it to render replay
2530
+ * progress, for example a terminal progress bar. Replay does not know
2531
+ * pass/fail at this point (verdicts are assigned later), so the totals only
2532
+ * distinguish items whose function ran (`succeeded`) from items that threw
2533
+ * (`errored`).
2534
+ *
2535
+ * Invoked synchronously right after each item finishes, so keep it cheap. A
2536
+ * throwing callback never crashes the run: the error is swallowed so progress
2537
+ * UI can't break replay.
2538
+ */
2539
+ onItemFinish?: (progress: ReplayItemFinishProgress) => void;
2540
+ /**
2541
+ * @deprecated Use {@link onItemFinish}. This compatibility callback receives
2542
+ * the same per-item finish events plus the legacy whole-run `"complete"`
2543
+ * event. It is ignored when `onItemFinish` is also provided.
2544
+ */
2545
+ onProgress?: (progress: ReplayProgress) => void;
2546
+ /**
2547
+ * Called once when each replay item begins processing, before input loading,
2548
+ * mock preparation, database branching, or the customer function runs. Use
2549
+ * it with {@link onItemFinish} to distinguish queued items from items that
2550
+ * are still in flight. A throwing callback never crashes the run.
2551
+ */
2552
+ onItemStart?: (progress: ReplayItemStartProgress) => void;
2553
+ /**
2554
+ * Called once, right after the server creates the experiment and before any
2555
+ * item runs, with the experiment ID and its dashboard URL. Use it to show
2556
+ * where results will appear while the replay is still running. A throwing
2557
+ * callback never crashes the run.
2558
+ */
2559
+ onExperimentStart?: (experiment: ReplayExperiment) => void;
2560
+ onInterrupt?: (interrupt: ReplayInterrupt) => void;
2561
+ resume?: string;
2562
+ force?: boolean;
2563
+ }
2564
+ /** The experiment a replay records into, passed to {@link ReplayOptions.onExperimentStart}. */
2565
+ interface ReplayExperiment {
2566
+ /** Experiment ID created for this replay. */
2567
+ experimentId: string;
2568
+ /** Full URL to view the experiment in the dashboard. */
2569
+ experimentUrl: string;
2570
+ }
2571
+ /** Emitted through {@link ReplayOptions.onItemStart} when a worker starts an item. */
2572
+ interface ReplayItemStartProgress {
2573
+ type: "started";
2574
+ /** Experiment ID created for this replay. Null for a dry run, which creates none. */
2575
+ experimentId: string | null;
2576
+ /** @deprecated Use {@link experimentId}. Same value. */
2577
+ testRunId: string | null;
2578
+ /** Items whose processing has started so far. */
2579
+ started: number;
2580
+ /** Items that have finished so far, whether they succeeded or errored. */
2581
+ completed: number;
2582
+ /** Total number of items in this replay run. */
2583
+ total: number;
2584
+ /** Of the completed items, how many finished without a code or replay error. */
2585
+ succeeded: number;
2586
+ /** Of the completed items, how many finished with an error. */
2587
+ errored: number;
2588
+ /** The historical trace and span whose replay processing just started. */
2589
+ item: {
2590
+ originalTraceId: string;
2591
+ originalSpanId: string;
2592
+ /** @deprecated alias for `originalTraceId`. */
2593
+ sourceTraceId: string;
2594
+ /** @deprecated alias for `originalSpanId`. */
2595
+ sourceSpanId: string;
2596
+ attempt: number;
2597
+ };
2598
+ }
2599
+ /** Running totals reported to {@link ReplayOptions.onItemFinish} as replay proceeds. */
2600
+ interface ReplayItemFinishProgress {
2601
+ /** Event kind, omitted for backward-compatible per-item events. */
2602
+ type?: "item";
2603
+ /** Experiment ID created for this replay. Null for a dry run, which creates none. */
2604
+ experimentId: string | null;
2605
+ /** @deprecated Use {@link experimentId}. Same value. */
2606
+ testRunId: string | null;
2607
+ /** Items that have finished so far, whether they succeeded or errored. */
2608
+ completed: number;
2609
+ /** Total number of items in this replay run. */
2610
+ total: number;
2611
+ /** Of the completed items, how many finished without a code or replay error. */
2612
+ succeeded: number;
2613
+ /** Of the completed items, how many have `item.error` set. */
2614
+ errored: number;
2615
+ /**
2616
+ * The single item that just finished to produce this event. Field-for-field
2617
+ * the same shape and meaning as {@link ReplayItem}, so a progress UI and a
2618
+ * final-result UI read one contract. `traceId` is null at this stage (the
2619
+ * server replay id arrives at completion), and `tokens` is null for the same
2620
+ * reason: the replayed run's usage is aggregated server-side by
2621
+ * completeReplay. `durationMs` is how long this item took to replay; the
2622
+ * `original*` fields describe the trace it replayed.
2623
+ */
2624
+ item: ReplayProgressItem;
2625
+ }
2626
+ /** See {@link ReplayItemFinishProgress.item}. Mirrors {@link ReplayItem}. */
2627
+ interface ReplayProgressItem {
2628
+ selectiveReplay?: SelectiveReplayReport;
2629
+ /** Trace ID of the new replay trace (null during the run; the server id arrives at completion). */
2630
+ traceId?: string | null;
2631
+ /** Bitfab trace ID of the original (historical) trace being replayed. */
2632
+ originalTraceId: string | null;
2633
+ /** External span ID the recorded inputs were read from (the original root span). */
2634
+ originalSpanId?: string | null;
2635
+ /** @deprecated alias for `originalTraceId`. */
2636
+ sourceTraceId: string | null;
2637
+ /** @deprecated alias for `originalSpanId`. */
2638
+ sourceSpanId?: string | null;
2639
+ attempt: number;
2640
+ /** Deserialized inputs from the original trace. */
2641
+ input?: unknown[];
2642
+ /** The result returned by the replayed function, or undefined on error. */
2643
+ result?: unknown;
2644
+ /** The original output from the historical trace. */
2645
+ originalOutput?: unknown;
2646
+ /** Backward-compatible message for either error kind. */
2647
+ error: string | null;
2648
+ /** The actual value thrown by the replayed customer function. */
2649
+ traceError?: unknown | null;
2650
+ /** The actual value thrown while Bitfab prepared this replay item. */
2651
+ replayError?: unknown | null;
2652
+ /** How long the replayed function took on this run. */
2653
+ durationMs?: number | null;
2654
+ /** The original trace's duration, tokens, and model. */
2655
+ originalDurationMs?: number | null;
2656
+ originalTokens?: TokenUsage | null;
2657
+ originalModel?: string | null;
2658
+ ingestionType?: TraceIngestionType;
2659
+ /** Always null here: the replayed run's usage is only known at completion. */
2660
+ tokens?: TokenUsage | null;
2661
+ /** @deprecated renamed to `originalModel`. */
2662
+ model?: string | null;
2663
+ dbSnapshotRef?: DbSnapshotRef | null;
2664
+ dbBranchTimings?: DbBranchTimings | null;
2665
+ }
2666
+ /**
2667
+ * @deprecated Use {@link ReplayItemFinishProgress}. This legacy shape also
2668
+ * represents the item-less terminal `"complete"` event emitted by
2669
+ * {@link ReplayOptions.onProgress}.
2670
+ */
2671
+ interface ReplayProgress {
2672
+ type?: "item" | "complete";
2673
+ result?: ReplayResult<unknown>;
2674
+ /** Null for a dry run, which creates no experiment. */
2675
+ experimentId?: string | null;
2676
+ /** @deprecated Use {@link experimentId}. Same value. */
2677
+ testRunId?: string | null;
2678
+ completed: number;
2679
+ total: number;
2680
+ succeeded: number;
2681
+ errored: number;
2682
+ item?: ReplayItemFinishProgress["item"];
2683
+ }
2684
+ /**
2685
+ * Wire prefix the Bitfab plugin scans for. Each line {@link reportReplayProgress}
2686
+ * writes is this prefix followed by the JSON of the running totals (plus the
2687
+ * finished `item`). The plugin polls these lines to report live progress while a
2688
+ * replay runs in the background; keep the SDK emitter and the plugin parser in
2689
+ * sync.
2690
+ */
2691
+ declare const BITFAB_PROGRESS_PREFIX = "@@bitfab:progress ";
2692
+ /**
2693
+ * A ready-made replay lifecycle callback for replay scripts.
2694
+ * Pass it straight in:
2695
+ *
2696
+ * ```ts
2697
+ * await bitfab.replay("my-fn", fn, {
2698
+ * limit,
2699
+ * onItemStart: reportReplayProgress,
2700
+ * onItemFinish: reportReplayProgress,
2701
+ * })
2702
+ * ```
2703
+ *
2704
+ * It writes `@@bitfab:progress` lines to stderr, which the Bitfab plugin polls
2705
+ * to report in-flight and finished items while replay runs in the background,
2706
+ * so scripts never hand-format the wire protocol.
2707
+ * stdout is left untouched for direct-run ReplayResult JSON. Outside Node (no
2708
+ * `process.stderr`, e.g. a browser) it is a no-op, and a write failure is
2709
+ * swallowed so progress can never crash a run.
2710
+ */
2711
+ declare function reportReplayProgress(progress: ReplayItemFinishProgress | ReplayItemStartProgress | ReplayProgress): void;
2712
+ /** Per-trace context passed to {@link ReplayOptions.adaptInputs}. */
2713
+ interface AdaptContext {
2714
+ /** Bitfab trace ID of the original (historical) trace being replayed. */
2715
+ originalTraceId: string;
2716
+ /** External span ID the recorded inputs were read from. */
2717
+ originalSpanId: string;
2718
+ /** @deprecated alias for {@link AdaptContext.originalTraceId}. */
2719
+ sourceTraceId: string;
2720
+ /** @deprecated alias for {@link AdaptContext.originalSpanId}. */
2721
+ sourceSpanId: string;
2722
+ metadata: Record<string, unknown>;
2723
+ }
2724
+ /**
2725
+ * The shape an adapter module must export as `adaptInputs`.
2726
+ *
2727
+ * Author an adapter in its own file (e.g. `scripts/replay-adapters/<name>.ts`),
2728
+ * import it in your replay script, and pass it to `replay({ adaptInputs })`:
2729
+ *
2730
+ * ```ts
2731
+ * import type { AdaptInputsFn } from "@bitfab/sdk"
2732
+ * export const adaptInputs: AdaptInputsFn = (inputs, ctx) => [reshape(inputs)]
2733
+ * ```
2734
+ */
2735
+ type AdaptInputsFn = (inputs: unknown[], ctx: AdaptContext) => unknown[];
2736
+ interface ReplayItem<T> {
2737
+ /** Decisions and changed-code coverage for experimental selective replay. */
2738
+ selectiveReplay?: SelectiveReplayReport;
2739
+ /**
2740
+ * Server trace ID of the new replay trace this item produced. Written in by
2741
+ * `replay()` from the complete-replay response once the server has minted the
2742
+ * trace row; the client-side id used to correlate spans during the run is
2743
+ * never surfaced here. Null until completion, on older servers that omit the
2744
+ * mapping, or if the item produced no trace. Not the verdict-persistence key:
2745
+ * that is the original-trace lineage (`originalTraceId` + `experimentId`).
2746
+ */
2747
+ traceId: string | null;
2748
+ /** Bitfab trace ID of the original (historical) trace being replayed. */
2749
+ originalTraceId: string;
2750
+ /** External span ID the recorded inputs were read from (the original root span). */
2751
+ originalSpanId: string;
2752
+ /** @deprecated alias for {@link ReplayItem.originalTraceId}. */
2753
+ sourceTraceId: string;
2754
+ /** @deprecated alias for {@link ReplayItem.originalSpanId}. */
2755
+ sourceSpanId: string;
2756
+ attempt: number;
2757
+ /** Deserialized inputs from the original trace. */
2758
+ input: unknown[];
2759
+ /** The result returned by the function during replay, or undefined on error. */
2760
+ result: T | undefined;
2761
+ originalOutput: unknown;
2762
+ /**
2763
+ * How the source trace came to exist. Absent on servers that predate the
2764
+ * field, which only ever served captured traces.
2765
+ */
2766
+ ingestionType?: TraceIngestionType;
2767
+ /**
2768
+ * Backward-compatible message for either error kind. Prefer `traceError` and
2769
+ * `replayError` when callers need the original exception and its source.
2770
+ */
2771
+ error: string | null;
2772
+ /** The actual value thrown by the replayed customer function. */
2773
+ traceError: unknown | null;
2774
+ /**
2775
+ * The actual value thrown by replay setup before the customer function ran,
2776
+ * such as database warmup, input hydration, or mock preparation.
2777
+ */
2778
+ replayError: unknown | null;
2779
+ /**
2780
+ * How long the replayed function took on this run, in ms. Null if the item
2781
+ * failed before it ran. Compare against
2782
+ * {@link ReplayItem.originalDurationMs} for the before/after.
2783
+ */
2784
+ durationMs: number | null;
2785
+ /** The original trace's duration in ms, or null if its timestamps are missing. */
2786
+ originalDurationMs: number | null;
2787
+ /**
2788
+ * Token usage recorded on the original trace, or null if it captured none.
2789
+ * The "old" side of a token delta; {@link ReplayItem.tokens} is the new one.
2790
+ */
2791
+ originalTokens: TokenUsage | null;
2792
+ /** Model name from the original trace, or null if not captured. */
2793
+ originalModel: string | null;
2794
+ /**
2795
+ * Token usage from the REPLAYED run (this item's new execution), aggregated
2796
+ * server-side from the spans it produced, or null if the run captured no
2797
+ * token data. Compare against {@link ReplayItem.originalTokens} to see how
2798
+ * the code change moved cost. Matches what the experiments page shows.
2799
+ *
2800
+ * Unprefixed because the replay is this item's subject: anything describing
2801
+ * the trace being replayed carries `original`.
2802
+ */
2803
+ tokens: TokenUsage | null;
2804
+ /** @deprecated renamed to {@link ReplayItem.originalModel}. */
2805
+ model: string | null;
2806
+ /**
2807
+ * The DB snapshot ref the SDK captured at trace open. Useful for debugging
2808
+ * ("what state was this trace pinned to?") and for customers building
2809
+ * their own resolvers. Undefined when the source trace was captured
2810
+ * without `dbSnapshot` configured.
2811
+ */
2812
+ dbSnapshotRef: DbSnapshotRef | null;
2813
+ /**
2814
+ * How long this item's DB branch took to provision, per phase, measured
2815
+ * server-side. Present whenever a branch was attempted, on both outcomes:
2816
+ * complete on success, partial up to the failing phase when the resolve
2817
+ * failed. Null when no branch was asked for, when the source trace carried
2818
+ * no snapshot ref, or against a server that predates timings.
2819
+ */
2820
+ dbBranchTimings: DbBranchTimings | null;
2821
+ carriedOver?: boolean;
2822
+ }
2823
+ interface ReplayResult<T> {
2824
+ /** Individual replay items with inputs, results, and comparison data. */
2825
+ items: ReplayItem<T>[];
2826
+ /**
2827
+ * The experiment ID created on the server. Null for a dry run, which
2828
+ * executes nothing and so creates no experiment.
2829
+ */
2830
+ experimentId: string | null;
2831
+ /** Full URL to view the experiment in the dashboard. Null for a dry run. */
2832
+ experimentUrl: string | null;
2833
+ /** @deprecated Use {@link experimentId}. Same value. */
2834
+ testRunId: string | null;
2835
+ /** @deprecated Use {@link experimentUrl}. Same value. */
2836
+ testRunUrl: string | null;
2837
+ attempts: number;
2838
+ }
2839
+ /**
2840
+ * Whole-run replay failure that preserves every item collected before the run
2841
+ * failed. The original whole-run exception is available as `cause`.
2842
+ */
2843
+ declare class ReplayError<T = unknown> extends BitfabError {
2844
+ readonly items: ReplayItem<T>[];
2845
+ readonly experimentId: string;
2846
+ readonly experimentUrl: string;
2847
+ readonly cause: unknown;
2848
+ /** @deprecated Use {@link experimentId}. Same value. */
2849
+ readonly testRunId: string;
2850
+ /** @deprecated Use {@link experimentUrl}. Same value. */
2851
+ readonly testRunUrl: string;
2852
+ constructor(message: string, items: ReplayItem<T>[], experimentId: string, experimentUrl: string, cause: unknown);
2853
+ }
2854
+ /**
2855
+ * A database branch requested for one replay item could not be resolved.
2856
+ *
2857
+ * The server's resolver code and message are retained as structured fields so
2858
+ * callers can handle failures such as `branch_create_failed` and
2859
+ * `snapshot_from_replaced_origin` without parsing the compatible `item.error`
2860
+ * string.
2861
+ */
2862
+ declare class DbBranchReplayError extends BitfabError {
2863
+ readonly code: string;
2864
+ readonly originalTraceId: string;
2865
+ readonly cause?: unknown;
2866
+ constructor(code: string, message: string, originalTraceId: string, cause?: unknown);
2867
+ }
2868
+ /**
2869
+ * Serialize a replay result as JSON while retaining structured trace and replay
2870
+ * errors. Use this for direct-run stdout instead of raw `JSON.stringify`, which
2871
+ * drops the useful fields on JavaScript `Error` objects.
2872
+ */
2873
+ declare function serializeReplayResult<T>(result: ReplayResult<T>): string;
2874
+ //#endregion
2875
+ //#region src/replayBranch.d.ts
2876
+ declare class ReplayBranch implements Omit<DbBranchLease, "databaseUrl"> {
2877
+ #private;
2878
+ /** The provider's own id for this branch, e.g. for correlating with its console. */
2879
+ readonly neonBranchId: string;
2880
+ /** Env var name the customer's app reads, e.g. `DATABASE_URL`. */
2881
+ readonly envKey: string;
2882
+ /** When this branch's URL stops being valid. ISO-8601. */
2883
+ readonly expiresAt: string;
2884
+ /**
2885
+ * The instant this branch is pinned to: the source trace's wall clock, read
2886
+ * just before the traced function ran. Compare it against the trace you meant
2887
+ * to replay to confirm the branch is the right point in history.
2888
+ */
2889
+ readonly snapshotTimestamp?: string;
2890
+ /** Deep link to the branch in the provider console, if available. */
2891
+ readonly providerConsoleUrl?: string;
2892
+ /**
2893
+ * True if the branch is read-only. Use it to skip write operations during
2894
+ * replay when the provider returned a read-only lease.
2895
+ */
2896
+ readonly readOnly?: boolean;
2897
+ /**
2898
+ * The branch's region, e.g. `aws-us-east-1`. A compute runs in its project's
2899
+ * region, so a replay runner elsewhere pays that round trip on every query.
2900
+ */
2901
+ readonly region?: string;
2902
+ /** The historical trace ID that produced the input for this replay item. */
2903
+ readonly traceId: string;
2904
+ /** @internal Built by `getCurrentReplayBranch()`; never constructed by callers. */
2905
+ constructor(lease: DbBranchLease, traceId: string, context: ReplayContext);
2906
+ /**
2907
+ * Connection string for this item's branch. Point your database client at it
2908
+ * instead of the live database for the duration of the replayed call.
2909
+ *
2910
+ * Reading it records on the trace that the replayed code obtained the branch
2911
+ * URL, which is what separates "a branch was provisioned" from "the branch
2912
+ * was actually used". The other fields inspect the lease without exposing the
2913
+ * connection string, so they deliberately do not record anything. That is
2914
+ * also why this is a getter and not a plain field: the URL is absent from
2915
+ * `JSON.stringify(branch)` and from logging the object.
2916
+ */
2917
+ get databaseUrl(): string;
2918
+ }
2919
+ //#endregion
2920
+ //#region src/rivetIntegration.d.ts
2921
+ declare const RIVET_GROUP_EFFECT_METHODS: {
2922
+ readonly db: readonly ["execute", "nativeMetrics", "close"];
2923
+ readonly kv: readonly ["get", "put", "delete", "batchPut", "batchGet", "batchDelete", "deleteRange", "listPrefix", "listRange", "list"];
2924
+ readonly schedule: readonly ["after", "at", "cancel", "get", "list"];
2925
+ readonly cron: readonly ["set", "every", "get", "list", "delete", "history"];
2926
+ readonly queue: readonly ["send", "next", "nextBatch", "waitForNames", "waitForAvailable", "complete", "enqueueAndWait", "tryNext", "tryNextBatch"];
2927
+ readonly run: readonly ["setWakeAt"];
2928
+ };
2929
+ declare const RIVET_TOP_LEVEL_EFFECTS: readonly ["broadcast", "saveState", "sleep", "destroy", "step", "tryStep", "try", "loop", "sleepUntil", "rollbackCheckpoint", "join", "race", "removed", "getVersion"];
2930
+ type RivetGroup = keyof typeof RIVET_GROUP_EFFECT_METHODS;
2931
+ type RivetGroupEffectType = { [TGroup in RivetGroup]: `${TGroup}.${(typeof RIVET_GROUP_EFFECT_METHODS)[TGroup][number]}`; }[RivetGroup];
2932
+ /** Rivet context operations supported as replay effects. */
2933
+ type RivetEffectType = RivetGroupEffectType | (typeof RIVET_TOP_LEVEL_EFFECTS)[number] | "db.transaction.execute" | "queue.message.complete";
2934
+ /** Configuration for {@link BitfabRivetIntegration}. */
2935
+ interface RivetIntegrationOptions {
2936
+ /**
2937
+ * Context operations whose recorded outputs replay should serve instead of
2938
+ * executing against a live actor or workflow. Nothing is marked by default.
2939
+ */
2940
+ mockOnReplay?: readonly RivetEffectType[];
2941
+ }
2942
+ /** Minimal structural context type used when callers do not supply Rivet's type. */
2943
+ interface RivetContextLike {
2944
+ state: unknown;
2945
+ readonly db: {
2946
+ execute(...args: unknown[]): Promise<unknown>;
2947
+ };
2948
+ broadcast(name: string, ...args: unknown[]): void;
2949
+ readonly actorId?: string;
2950
+ readonly name?: string;
2951
+ readonly key?: readonly string[];
2952
+ readonly region?: string;
2953
+ }
2954
+ interface RivetIntegrationRuntime {
2955
+ wrapEffect<TArgs extends unknown[], TReturn>(effect: RivetEffectType, mockOnReplay: boolean, fn: (...args: TArgs) => TReturn, replayOutput?: () => unknown): (...args: TArgs) => TReturn;
2956
+ recordRootFixture(context: Record<string, unknown>, recordedRoots: Set<string>): void;
2957
+ }
2958
+ /**
2959
+ * Binds a live Rivet actor or workflow context to an existing traced function
2960
+ * and exposes replay-aware proxies for supported context operations.
2961
+ *
2962
+ * The integration never creates a trace root. Use it with the same
2963
+ * `BitfabFunction` handle whose `withTrace()` wrapper is the production and
2964
+ * replay root.
2965
+ */
2966
+ declare class BitfabRivetIntegration<TContext extends object = RivetContextLike> {
2967
+ private readonly traceFunctionKey;
2968
+ private readonly runtime;
2969
+ private readonly markedEffects;
2970
+ private readonly replayProxies;
2971
+ /** @internal Constructed by `Bitfab.getRivetIntegration()`. */
2972
+ constructor(traceFunctionKey: string, runtime: RivetIntegrationRuntime, options?: RivetIntegrationOptions);
2973
+ /**
2974
+ * Run a callback with a live Rivet context bound to the current async chain.
2975
+ * This binds context only; it creates no trace or span.
2976
+ */
2977
+ withContext<TReturn>(context: TContext, fn: () => TReturn): TReturn;
2978
+ /**
2979
+ * Adapt a traced function into a Rivet handler whose first argument is the
2980
+ * live actor or workflow context. The context is not added to the traced
2981
+ * root's inputs.
2982
+ */
2983
+ bind<This, TArgs extends unknown[], TReturn>(fn: (this: This, ...args: TArgs) => TReturn): (this: This, context: TContext, ...args: TArgs) => TReturn;
2984
+ /**
2985
+ * Return the current Rivet context proxy. In production it delegates to the
2986
+ * bound live context. During replay it hydrates recorded actor state and
2987
+ * intercepts supported effects without requiring a live Rivet actor or
2988
+ * workflow.
2989
+ */
2990
+ getContext(): TContext;
2991
+ private createContextProxy;
2992
+ private createDbProxy;
2993
+ private createGroupProxy;
2994
+ private createMethodProxy;
2995
+ private createEffect;
2996
+ private createTransaction;
2997
+ private decorateQueueMessages;
2998
+ private decorateQueueMessage;
2999
+ private queueCallIsCompletable;
3000
+ private createQueueIterator;
3001
+ }
3002
+ //#endregion
3003
+ //#region src/spans.d.ts
3004
+ type SpanListField = "input" | "output" | "reasoning" | "content" | "errors" | "contexts";
3005
+ type SpanListParams = {
3006
+ spanType?: SpanType;
3007
+ spanName?: string;
3008
+ fields?: SpanListField[];
3009
+ cursor?: string | null;
3010
+ /** Spans per page, 1 to 200, or at most 50 when `fields` is set. The server defaults to 50. */
3011
+ limit?: number;
3012
+ };
3013
+ type ListedSpan = {
3014
+ id: string;
3015
+ traceId: string;
3016
+ parentSpanId: string | null;
3017
+ name: string | null;
3018
+ type: string | null;
3019
+ startedAt: string | null;
3020
+ endedAt: string | null;
3021
+ input?: unknown;
3022
+ output?: unknown;
3023
+ reasoning?: unknown;
3024
+ content?: unknown;
3025
+ errors?: unknown;
3026
+ contexts?: unknown;
3027
+ };
3028
+ type SpanListResult = {
3029
+ spans: ListedSpan[];
3030
+ nextCursor: string | null;
3031
+ hasMore: boolean;
3032
+ };
3033
+ declare class SpansClient {
3034
+ private readonly httpClient;
3035
+ constructor(httpClient: HttpClient);
3036
+ /**
3037
+ * List one trace's spans in the order they ran, one page at a time. No
3038
+ * filter is required: omit `spanType` and `spanName` to page through every
3039
+ * span. Each span carries one extra key per requested `fields` entry. Pass
3040
+ * the returned `nextCursor` back as `cursor` for the next page. Throws a
3041
+ * `BitfabError` with status 404 when the trace is not in your organization.
3042
+ */
3043
+ list(traceId: string, params?: SpanListParams): Promise<SpanListResult>;
3044
+ }
3045
+ //#endregion
3046
+ //#region src/tracing.d.ts
3047
+ interface Trace {
3048
+ traceId: string;
3049
+ toJSON(): unknown;
3050
+ }
3051
+ interface Span<_T = any> {
3052
+ spanId?: string;
3053
+ traceId?: string;
3054
+ parentId?: string | null;
3055
+ toJSON(): unknown;
3056
+ spanData?: {
3057
+ type?: string;
3058
+ _input?: unknown;
3059
+ _response?: unknown;
3060
+ } | null;
3061
+ }
3062
+ interface TraceResponse {
3063
+ traceId: string;
3064
+ status: "success";
3065
+ }
3066
+ interface ActiveSpanContext {
3067
+ traceId: string;
3068
+ spanId: string;
3069
+ }
3070
+ /**
3071
+ * TracingProcessor interface from OpenAI Agents SDK v0.3.7
3072
+ */
3073
+ interface TracingProcessor {
3074
+ onTraceStart(trace: Trace): Promise<void>;
3075
+ onTraceEnd(trace: Trace): Promise<void>;
3076
+ onSpanStart(span: Span<any>): Promise<void>;
3077
+ onSpanEnd(span: Span<any>): Promise<void>;
3078
+ forceFlush(): Promise<void>;
3079
+ shutdown(timeout?: number): Promise<void>;
3080
+ }
3081
+ /**
3082
+ * Tracing processor for OpenAI Agents SDK integration.
3083
+ *
3084
+ * Implements the TracingProcessor interface from the OpenAI Agents SDK to
3085
+ * automatically capture traces and spans and send them to Bitfab for
3086
+ * monitoring and analysis.
3087
+ *
3088
+ * Example usage:
3089
+ * ```typescript
3090
+ * import { Bitfab } from 'bitfab';
3091
+ * import { addTraceProcessor } from '@openai/agents';
3092
+ *
3093
+ * const client = new Bitfab({ apiKey: 'your-api-key' });
3094
+ * const processor = client.getOpenAiTracingProcessor();
3095
+ * addTraceProcessor(processor);
3096
+ * ```
3097
+ */
3098
+ declare class BitfabOpenAITracingProcessor implements TracingProcessor {
3099
+ private readonly httpClient;
3100
+ private readonly ownsHttpClient;
3101
+ private activeTraces;
3102
+ private readonly getActiveSpanContext;
3103
+ private readonly shouldRecord;
3104
+ private activeSpanMappings;
3105
+ private canonicalTraceIds;
3106
+ private getCanonicalTraceId;
3107
+ /**
3108
+ * Initialize the tracing processor.
3109
+ *
3110
+ * @param config - Configuration options
3111
+ */
3112
+ constructor(config: {
3113
+ apiKey?: ApiKeyInput;
3114
+ serviceUrl?: string;
3115
+ timeout?: number;
3116
+ getActiveSpanContext?: () => ActiveSpanContext | null;
3117
+ shouldRecord?: () => boolean;
3118
+ /**
3119
+ * The owning `Bitfab` client's HTTP client. Supplied by
3120
+ * `getOpenAiTracingProcessor()` so this processor shares that client's
3121
+ * single span-transport worker instead of starting a second one.
3122
+ * @internal
3123
+ */
3124
+ _httpClient?: HttpClient;
3125
+ });
3126
+ /**
3127
+ * Flush and release the span transport this processor started. A no-op when
3128
+ * the processor borrowed a `Bitfab` client's HTTP client: that client's
3129
+ * `close()` owns the worker's lifetime.
3130
+ */
3131
+ close(timeoutMs?: number): Promise<boolean>;
3132
+ /**
3133
+ * Called when a trace is started.
3134
+ * If there's an active withSpan context, the trace ID is remapped to the
3135
+ * outer trace and sent to pre-create the external_traces row on the server.
3136
+ */
3137
+ onTraceStart(trace: Trace): Promise<void>;
3138
+ /**
3139
+ * Called when a trace is ended.
3140
+ * If mapped to a withSpan trace, sends with remapped ID and completed=false
3141
+ * since the parent withSpan handles completion.
3142
+ */
3143
+ onTraceEnd(trace: Trace): Promise<void>;
3144
+ private readonly startedSpans;
3145
+ private readonly endedTraces;
3146
+ private cleanupTrace;
3147
+ /**
3148
+ * Called when a span is started. Span payloads are authoritative completed
3149
+ * snapshots, so start notifications do not cross the transport boundary.
3150
+ */
3151
+ onSpanStart(span: Span<any>): Promise<void>;
3152
+ /**
3153
+ * Called when a span is ended.
3154
+ *
3155
+ * Send the finalized span snapshot to Bitfab for complete trace capture.
3156
+ */
3157
+ onSpanEnd(span: Span<any>): Promise<void>;
3158
+ /**
3159
+ * Called when a trace is being flushed.
3160
+ */
3161
+ forceFlush(): Promise<void>;
3162
+ /**
3163
+ * Called when the trace processor is shutting down.
3164
+ */
3165
+ shutdown(timeout?: number): Promise<void>;
3166
+ /**
3167
+ * Send trace to Bitfab API (fire-and-forget).
3168
+ * When traceIdOverride is provided, the trace ID is remapped to link
3169
+ * the OpenAI trace into an outer withSpan trace.
3170
+ */
3171
+ private sendTrace;
3172
+ /**
3173
+ * Export span to JSON object, collecting any errors.
3174
+ */
3175
+ private exportSpan;
3176
+ /**
3177
+ * Extract and add input/response to serialized span, updating errors list.
3178
+ */
3179
+ private extractSpanInputResponse;
3180
+ /**
3181
+ * If the span's trace is mapped to a withSpan trace, rewrite trace_id and parent_id.
3182
+ */
3183
+ private applySpanOverrides;
3184
+ /**
3185
+ * Build span payload for the external spans API.
3186
+ */
3187
+ private buildSpanPayload;
3188
+ /**
3189
+ * Send span to Bitfab API (fire-and-forget).
3190
+ * If the span belongs to a trace mapped to a withSpan trace, the trace_id
3191
+ * and parent_id are rewritten to link the span into the withSpan tree.
3192
+ */
3193
+ private sendSpan;
3194
+ }
3195
+ //#endregion
3196
+ //#region src/captureSurface.d.ts
3197
+ type CaptureSurface = "opt-in" | "opt-out";
3198
+ //#endregion
3199
+ //#region src/client.d.ts
3200
+ /**
3201
+ * Options for wrapBAML.
3202
+ */
3203
+ interface WrapBAMLOptions {
3204
+ /** Called after each BAML invocation with the Collector instance. */
3205
+ onCollector?: (collector: unknown) => void;
3206
+ }
3207
+ /**
3208
+ * A function returned by wrapBAML that exposes the BAML collector from the last call.
3209
+ */
3210
+ interface WrappedBamlFn<TArgs extends unknown[], TReturn> {
3211
+ (...args: TArgs): Promise<TReturn>;
3212
+ /** The BAML Collector instance from the most recent call. `null` before the first call or if @boundaryml/baml is unavailable. */
3213
+ collector: unknown | null;
3214
+ }
3215
+ /**
3216
+ * A handle to the current active span, allowing context to be added.
3217
+ */
3218
+ interface CurrentSpan {
3219
+ /** The Bitfab ID for the current span. */
3220
+ readonly id: string;
3221
+ /** The trace ID for the current span. */
3222
+ readonly traceId: string;
3223
+ /**
3224
+ * Add a context entry to this span. Each call appends to the contexts array.
3225
+ * Context entries are stored in span_data.contexts as [{key, value}, ...].
3226
+ */
3227
+ addContext(context: Record<string, unknown>): void;
3228
+ /**
3229
+ * Set the prompt for this span. Stored in span_data.prompt.
3230
+ * Calling multiple times overwrites the previous value.
3231
+ */
3232
+ setPrompt(prompt: string): void;
3233
+ }
3234
+ /**
3235
+ * A detached handle to a previously-created trace, looked up by its
3236
+ * canonical Bitfab trace ID.
3237
+ *
3238
+ * Unlike `getCurrentTrace()`, this handle is not tied to AsyncLocalStorage -
3239
+ * each method sends to the server immediately. Useful for adding context
3240
+ * to a trace from a different process, request, or thread (e.g. a forked
3241
+ * agent that wants to annotate the original conversation's trace). Its methods
3242
+ * write whether or not capture is on.
3243
+ */
3244
+ interface DetachedTrace {
3245
+ /** The canonical Bitfab trace ID this handle resolves. */
3246
+ readonly traceId: string;
3247
+ /**
3248
+ * Append a context entry to this trace. Each call adds one entry to the
3249
+ * server-side contexts array; existing entries are preserved.
3250
+ *
3251
+ * Resolves once the server has applied the change and REJECTS if the server
3252
+ * refused it. A detached patch targets an already-closed trace, so it rides
3253
+ * no batch and no later signal would reveal a silent failure - the caller is
3254
+ * the only one who can react.
3255
+ */
3256
+ addContext(context: Record<string, unknown>): Promise<void>;
3257
+ /**
3258
+ * Merge metadata into this trace. Server-side shallow-merges the new keys
3259
+ * into the existing metadata object; existing keys are preserved unless
3260
+ * overwritten by the new values. Rejects if the server refused the update.
3261
+ */
3262
+ setMetadata(metadata: Record<string, unknown>): Promise<void>;
3263
+ /**
3264
+ * Set the sessionId for this trace. Replaces any existing sessionId.
3265
+ * Rejects if the server refused the update.
3266
+ */
3267
+ setSessionId(sessionId: string): Promise<void>;
3268
+ setName(name: string): Promise<void>;
3269
+ }
3270
+ /**
3271
+ * A handle to the current active trace, allowing trace-level context to be set.
3272
+ */
3273
+ interface CurrentTrace {
3274
+ /**
3275
+ * Set the session ID for this trace. Stored in the database session_id column.
3276
+ */
3277
+ setSessionId(sessionId: string): void;
3278
+ setName(name: string): void;
3279
+ /**
3280
+ * Set metadata for this trace. Stored in rawData.metadata.
3281
+ * Subsequent calls merge with existing metadata, with later values taking precedence.
3282
+ */
3283
+ setMetadata(metadata: Record<string, unknown>): void;
3284
+ /**
3285
+ * Add a context entry to this trace. Each call appends to the contexts array.
3286
+ * Context entries are stored in rawData.contexts as [{key, value}, ...].
3287
+ */
3288
+ addContext(context: Record<string, unknown>): void;
3289
+ /**
3290
+ * Flag this trace to be dropped. Once flagged, spans that complete afterward
3291
+ * are not uploaded at all, and when the trace completes the server scrubs any
3292
+ * payloads that already raced out (trace, external trace, and sibling spans),
3293
+ * marking it `dropped` instead of `completed` and retaining only a skeleton
3294
+ * audit record. Use this to discard runs you never want stored (e.g. health
3295
+ * checks, or a run you know contains sensitive data). Takes effect
3296
+ * immediately for later spans; the server-side scrub takes effect at trace
3297
+ * completion, so a trace that is flagged but never completes is not scrubbed.
3298
+ */
3299
+ drop(): void;
3300
+ }
3301
+ /**
3302
+ * Get a handle to the current active span.
3303
+ *
3304
+ * Call this from inside a traced function (wrapped with `withSpan`) to get
3305
+ * a span handle that allows adding context at runtime.
3306
+ *
3307
+ * Returns a no-op object if called outside of a span context (methods do nothing).
3308
+ */
3309
+ declare function getCurrentSpan(): CurrentSpan;
3310
+ /**
3311
+ * Get the database branch the current replay item is running against.
3312
+ *
3313
+ * Call this from inside a function being replayed with `replay({ dbBranch })`
3314
+ * and point your database client at `branch.databaseUrl` so the replay reads
3315
+ * the data as it was at trace time:
3316
+ *
3317
+ * ```ts
3318
+ * const branch = getCurrentReplayBranch()
3319
+ * const url = branch?.databaseUrl ?? process.env.DATABASE_URL
3320
+ * ```
3321
+ *
3322
+ * Returns null outside a replay item, and for an item whose source trace
3323
+ * carried no DB snapshot reference, so live request code takes the same path
3324
+ * it always did.
3325
+ */
3326
+ declare function getCurrentReplayBranch(): ReplayBranch | null;
3327
+ /**
3328
+ * Get a handle to the current active trace.
3329
+ *
3330
+ * Call this from inside a traced function (wrapped with `withSpan`) to get
3331
+ * a trace handle that allows setting trace-level context at runtime.
3332
+ *
3333
+ * Returns a no-op object if called outside of a span context (methods do nothing).
3334
+ */
3335
+ declare function getCurrentTrace(): CurrentTrace;
3336
+ interface SeedCaseOptions {
3337
+ input: unknown[];
3338
+ expected?: unknown;
3339
+ fn?: (...args: any[]) => unknown;
3340
+ metadata?: Record<string, unknown>;
3341
+ sessionId?: string;
3342
+ name?: string;
3343
+ spanName?: string;
3344
+ spanType?: SpanType;
3345
+ }
3346
+ interface SeedRunOptions<TArgs extends unknown[]> {
3347
+ args?: TArgs;
3348
+ metadata?: Record<string, unknown>;
3349
+ sessionId?: string;
3350
+ name?: string;
3351
+ }
3352
+ interface ReseedOptions {
3353
+ traceId: string;
3354
+ }
3355
+ interface ReseedResult {
3356
+ traceId: string;
3357
+ previousRunTraceId: string;
3358
+ }
3359
+ interface BitfabConfig {
3360
+ /**
3361
+ * The API key for Bitfab API authentication. Resolved lazily, the first
3362
+ * time a span actually needs it, not at construction. When it resolves
3363
+ * empty, tracing is disabled (a no-op, unless `strict` is set).
3364
+ *
3365
+ * Accepts either a string or a function returning the key. The function
3366
+ * form is resolved at first use, so it survives the ESM trap where a shim
3367
+ * built at module load runs before the script body's `dotenv.config()`:
3368
+ * `apiKey: () => process.env.BITFAB_API_KEY`. When omitted (or it resolves
3369
+ * empty), the SDK also falls back to reading `BITFAB_API_KEY` from the
3370
+ * environment itself, again at first use.
3371
+ */
3372
+ apiKey?: string | (() => string | null | undefined);
3373
+ /** The base URL for the Bitfab API (default: https://bitfab.ai) */
3374
+ serviceUrl?: string;
3375
+ /** Request timeout in milliseconds (default: 120000) */
3376
+ timeout?: number;
3377
+ /** Environment variables for LLM provider API keys (only OPENAI_API_KEY is supported) */
3378
+ envVars?: AllowedEnvVars;
3379
+ captureEnabled?: boolean;
3380
+ enabled?: boolean;
3381
+ /**
3382
+ * Fail loud instead of degrading quietly. When true, the first traced call
3383
+ * with no resolvable API key throws a `BitfabError` rather than silently
3384
+ * disabling tracing. Off by default so a missing telemetry key never takes
3385
+ * down the host app; turn it on in standalone scripts where a run that
3386
+ * emits no traces is a failure you want surfaced immediately.
3387
+ */
3388
+ strict?: boolean;
3389
+ /** The generated BAML client instance (e.g., `b` from your baml_client). Used by wrapBAML() when no explicit client is passed. */
3390
+ bamlClient?: unknown;
3391
+ /**
3392
+ * Per-trace database snapshot config. When set, every root span captures
3393
+ * a wall-clock timestamp (and, if `captureRef` is provided, a provider-
3394
+ * specific point-in-time ref) so the trace can later be replayed against
3395
+ * a branch materialized from that point.
3396
+ */
3397
+ dbSnapshot?: DbSnapshotConfig;
3398
+ simulationPlan?: boolean;
3399
+ }
3400
+ /**
3401
+ * Controls when a span is captured.
3402
+ * - always: Capture the span even when it becomes the root of a new trace.
3403
+ * - nested: Capture the span only when another Bitfab span is already active.
3404
+ */
3405
+ type CaptureWhen = "always" | "nested";
3406
+ /**
3407
+ * Options for configuring span behavior.
3408
+ */
3409
+ interface SpanOptions {
3410
+ /**
3411
+ * The name of the span. Defaults to the function name if available,
3412
+ * otherwise falls back to the trace function key.
3413
+ */
3414
+ name?: string;
3415
+ /**
3416
+ * The type of span. Defaults to "custom" if not specified.
3417
+ */
3418
+ type?: SpanType;
3419
+ /**
3420
+ * Controls whether this span may start a new trace. Defaults to "always".
3421
+ *
3422
+ * Use "nested" for reusable helpers that should appear inside an existing
3423
+ * trace but should run untraced when called on their own.
3424
+ * Unknown values warn once and default to "always".
3425
+ */
3426
+ captureWhen?: CaptureWhen;
3427
+ /**
3428
+ * When true, replay will reuse this span's historical output instead of
3429
+ * executing the wrapped function. Read by the "marked" replay strategy;
3430
+ * ignored outside replay and under the "all"/"none" strategies.
3431
+ *
3432
+ * Use this for child spans that are expensive (paid LLM/API calls),
3433
+ * slow, or non-deterministic - the root function still runs real code,
3434
+ * only the marked descendants return their recorded output. If a selected
3435
+ * occurrence is unavailable, replay fails the item without executing the
3436
+ * real child.
3437
+ */
3438
+ mockOnReplay?: boolean;
3439
+ /**
3440
+ * Experimental selective-replay eligibility, recorded with this span.
3441
+ * Attests that the whole subtree is output-only with JSON value semantics:
3442
+ * no hidden mutable reads, required effects, input mutations, or reliance
3443
+ * on object identity. Include implementation/dependency changes in replay's
3444
+ * mustRun. Both capture-time and current declarations must allow reuse.
3445
+ * Does not affect ordinary replay or replace mockOnReplay safety protection.
3446
+ */
3447
+ replayReusable?: boolean;
3448
+ /** Optional experiment ID included on the span and on the trace it starts. */
3449
+ experimentId?: string;
3450
+ /**
3451
+ * @deprecated Use {@link experimentId}. Same meaning. Passing both with
3452
+ * different values throws.
3453
+ */
3454
+ testRunId?: string;
3455
+ /**
3456
+ * Record a serializable view of a non-serializable result (e.g. a live
3457
+ * stream object) as the span output.
3458
+ *
3459
+ * When set, the wrapped function's raw return value is handed back to the
3460
+ * caller unchanged (so streaming and first-byte latency are untouched),
3461
+ * but instead of serializing that raw value, the span records
3462
+ * `await finalize(result)`. Use this to trace functions that return a live
3463
+ * stream consumed by the caller (Vercel AI SDK `streamText`, a
3464
+ * `ReadableStream`, an SSE response) while still capturing a serializable,
3465
+ * replayable output such as `{ text, usage, toolCalls }`.
3466
+ *
3467
+ * Reading from a multi-consumer stream result (like the AI SDK's, which
3468
+ * tees internally) does not disturb the caller's own consumption. For the
3469
+ * Vercel AI SDK shape, pass the prebuilt `finalizers.aiSdk` helper.
3470
+ *
3471
+ * Ignored for async-generator results, which are captured automatically.
3472
+ */
3473
+ finalize?: (result: any) => unknown | Promise<unknown>;
3474
+ }
3475
+ /**
3476
+ * The standard method context passed to a decorator.
3477
+ *
3478
+ * Defined structurally instead of referencing TypeScript's built-in
3479
+ * `ClassMethodDecoratorContext`, which was added in TypeScript 5.0. This keeps
3480
+ * the SDK's non-decorator APIs consumable by projects on older compilers.
3481
+ */
3482
+ interface SpanMethodDecoratorContext<TThis, TValue> {
3483
+ readonly kind: "method";
3484
+ readonly name: string | symbol;
3485
+ readonly static: boolean;
3486
+ readonly private: boolean;
3487
+ readonly access: {
3488
+ has(object: TThis): boolean;
3489
+ get(object: TThis): TValue;
3490
+ };
3491
+ addInitializer(initializer: (this: TThis) => void): void;
3492
+ readonly metadata?: Record<PropertyKey, unknown>;
3493
+ }
3494
+ /** A standard ECMAScript method decorator produced by {@link Bitfab.span}. */
3495
+ type SpanMethodDecorator = <TThis, TArgs extends unknown[], TReturn>(originalMethod: (this: TThis, ...args: TArgs) => TReturn, context: SpanMethodDecoratorContext<TThis, (this: TThis, ...args: TArgs) => TReturn>) => (this: TThis, ...args: TArgs) => TReturn;
3496
+ /** Trace-owned configuration for a function discovered beneath `trace()`. */
3497
+ interface NodeOptions extends Omit<SpanOptions, "captureWhen"> {
3498
+ /** Whether the enclosing trace captures this call. Defaults to true. */
3499
+ capture?: boolean;
3500
+ }
3501
+ type StandardNodeMethodDecorator = SpanMethodDecorator;
3502
+ type LegacyNodeMethodDecorator = <TThis, TArgs extends unknown[], TReturn>(target: object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<(this: TThis, ...args: TArgs) => TReturn>) => void;
3503
+ /** A method decorator produced by {@link Bitfab.node}. */
3504
+ type NodeMethodDecorator = StandardNodeMethodDecorator & LegacyNodeMethodDecorator;
3505
+ /** Options for experimental automatic subtree tracing. */
3506
+ interface TraceOptions {
3507
+ /** Root span name. Defaults to the decorated or wrapped function name. */
3508
+ name?: string;
3509
+ /** Root span type. Descendants are always `function` spans. */
3510
+ type?: SpanType;
3511
+ /**
3512
+ * Default replay-mocking policy for automatically captured descendants.
3513
+ * When true, those descendants are mocked by the default "marked" strategy
3514
+ * unless a node explicitly sets `mockOnReplay: false`. Defaults to false.
3515
+ */
3516
+ mockOnReplayDefault?: boolean;
3517
+ /** Maximum number of recorded descendant levels. Defaults to 30. */
3518
+ maxDepth?: number;
3519
+ maxCapturedSubtreeSpans?: number;
3520
+ /** Qualified or simple function names to leave out of the subtree. */
3521
+ exclude?: readonly string[] | ReadonlySet<string>;
3522
+ /** Record rest-argument wrapper functions. Defaults to false. */
3523
+ includeWrappers?: boolean;
3524
+ }
3525
+ type StandardTraceMethodDecorator = <This, TArgs extends unknown[], TReturn>(method: (this: This, ...args: TArgs) => TReturn, context: {
3526
+ kind: "method";
3527
+ name: string | symbol;
3528
+ }) => (this: This, ...args: TArgs) => TReturn;
3529
+ type LegacyTraceMethodDecorator = <This, TArgs extends unknown[], TReturn>(target: object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<(this: This, ...args: TArgs) => TReturn>) => void;
3530
+ type TraceMethodDecorator = StandardTraceMethodDecorator & LegacyTraceMethodDecorator;
3531
+ /**
3532
+ * Client for making provider-based API calls via BAML.
3533
+ */
3534
+ declare class Bitfab {
3535
+ private readonly apiKeyConfig;
3536
+ /** Cached only once a non-empty key is found, so an early resolve (before env loaded) can't poison a later one. */
3537
+ private resolvedApiKey;
3538
+ /** Gate the empty-key warning to fire at most once. */
3539
+ private apiKeyWarned;
3540
+ private readonly serviceUrl;
3541
+ private readonly timeout;
3542
+ private readonly envVars;
3543
+ private readonly captureConfiguredInCode;
3544
+ private captureConfiguredFromEnv;
3545
+ private readonly strict;
3546
+ private readonly httpClient;
3547
+ /** Dataset operations for the authenticated organization. */
3548
+ readonly datasets: DatasetsClient;
3549
+ /** Organization-scoped groupings for assertions and scenarios. */
3550
+ readonly categories: CategoriesClient;
3551
+ /** @deprecated Use {@link categories}. Same client. */
3552
+ readonly assertionCategories: CategoriesClient;
3553
+ readonly organizationMembers: OrganizationMembersClient;
3554
+ readonly traces: TracesClient;
3555
+ readonly spans: SpansClient;
3556
+ readonly labels: LabelsClient;
3557
+ readonly graders: GradersClient;
3558
+ readonly experiments: ExperimentsClient;
3559
+ private readonly bamlClient;
3560
+ private readonly dbSnapshot;
3561
+ private readonly simulationPlan;
3562
+ /**
3563
+ * Mock overrides registered via {@link Bitfab.registerMockOverride}, applied
3564
+ * to every `replay` on this client (after any per-call `mockOverride`). In
3565
+ * registration order; first matcher wins within this list.
3566
+ */
3567
+ private readonly mockOverrides;
3568
+ /**
3569
+ * Initialize the Bitfab client.
3570
+ *
3571
+ * @param config - Configuration options for the client
3572
+ */
3573
+ constructor(config: BitfabConfig);
3574
+ /**
3575
+ * Decorate a class method as an automatically expanded trace root.
3576
+ *
3577
+ * Build instrumentation turns repository functions called beneath this
3578
+ * method into nested spans that capture inputs, outputs, and errors by
3579
+ * default. Source exclusions and sim-plan capture-off decisions are explicit
3580
+ * opt-outs from that default.
3581
+ * Without a compatible build transform, this still records the decorated
3582
+ * method as a normal rich root span but cannot discover child calls.
3583
+ *
3584
+ * @param traceFunctionKey - Groups traces and their capture controls.
3585
+ * @param options - Root presentation, subtree bounds, and exclusions.
3586
+ * @experimental Automatic child-call instrumentation is experimental.
3587
+ */
3588
+ trace(traceFunctionKey: string, options?: TraceOptions): TraceMethodDecorator;
3589
+ /**
3590
+ * Wrap a function as an automatically expanded trace root.
3591
+ *
3592
+ * This is the function-oriented equivalent of {@link Bitfab.trace}. Build
3593
+ * instrumentation turns repository functions called beneath the wrapped
3594
+ * function into nested spans that capture inputs, outputs, and errors by
3595
+ * default. Source exclusions and sim-plan capture-off decisions are explicit
3596
+ * opt-outs from that default. Without a compatible transform, this still
3597
+ * records one normal rich root span and runs the function unchanged.
3598
+ *
3599
+ * @param traceFunctionKey - Groups traces and their capture controls.
3600
+ * @param optionsOrFn - Options or the workflow entrypoint to wrap.
3601
+ * @param maybeFn - Workflow entrypoint when options are provided.
3602
+ * @experimental Automatic child-call instrumentation is experimental.
3603
+ */
3604
+ withTrace<This, TArgs extends unknown[], TReturn>(traceFunctionKey: string, fn: (this: This, ...args: TArgs) => TReturn): (this: This, ...args: TArgs) => TReturn;
3605
+ withTrace<This, TArgs extends unknown[], TReturn>(traceFunctionKey: string, options: TraceOptions, fn: (this: This, ...args: TArgs) => TReturn): (this: This, ...args: TArgs) => TReturn;
3606
+ /**
3607
+ * Configure a transformed class method when it is discovered beneath a
3608
+ * {@link Bitfab.trace} root.
3609
+ *
3610
+ * The decorator creates no span or trace by itself. Beneath an active trace,
3611
+ * it can rename or retype the discovered call, capture its contents, mark it
3612
+ * for recorded-output replay, finalize its output, or omit it while leaving
3613
+ * captured descendants attached to the nearest captured parent.
3614
+ *
3615
+ * @param options - Trace-owned call configuration.
3616
+ * @experimental Automatic child-call instrumentation is experimental.
3617
+ */
3618
+ node(options?: NodeOptions): NodeMethodDecorator;
3619
+ /**
3620
+ * Configure a transformed standalone function when it is discovered beneath
3621
+ * a {@link Bitfab.trace} or {@link Bitfab.withTrace} root.
3622
+ *
3623
+ * This is the function-oriented equivalent of {@link Bitfab.node}. Without
3624
+ * an active automatic trace, the returned function runs normally and never
3625
+ * creates a span or trace. The function must be named so configuration can
3626
+ * be bound to its transformed definition without leaking to a descendant.
3627
+ *
3628
+ * @param optionsOrFn - Node options or the function to configure.
3629
+ * @param maybeFn - Function to configure when options are provided.
3630
+ * @experimental Automatic child-call instrumentation is experimental.
3631
+ */
3632
+ withNode<This, TArgs extends unknown[], TReturn>(fn: (this: This, ...args: TArgs) => TReturn): (this: This, ...args: TArgs) => TReturn;
3633
+ withNode<This, TArgs extends unknown[], TReturn>(options: NodeOptions, fn: (this: This, ...args: TArgs) => TReturn): (this: This, ...args: TArgs) => TReturn;
3634
+ private resolveNodeConfiguration;
3635
+ private createAutoTraceNode;
3636
+ private createAutoTraceRoot;
3637
+ private applySimulationPlan;
3638
+ /**
3639
+ * Flush and permanently close this client's tracing resources: its pending
3640
+ * requests and the single span-transport worker shared by its decorators and
3641
+ * framework handlers.
3642
+ *
3643
+ * Resolves `false` when delivery failed or the deadline expired. Long-lived
3644
+ * processes never need this (the transport batches in the background and the
3645
+ * exit hook drains it); scripts and tests that want a hard guarantee should
3646
+ * await it.
3647
+ *
3648
+ * Deliberately not a `Symbol.asyncDispose` method: the SDK targets runtimes
3649
+ * where that symbol may be absent, and a computed key on a missing symbol
3650
+ * throws at class-definition time, taking the whole SDK down on load.
3651
+ */
3652
+ close(timeoutMs?: number): Promise<boolean>;
3653
+ /**
3654
+ * Resolve the API key lazily, the first time a span actually needs it.
3655
+ *
3656
+ * The key is intentionally NOT read at construction. In ESM, a shim that
3657
+ * does `new Bitfab({ apiKey: process.env.BITFAB_API_KEY })` is hoisted and
3658
+ * evaluated before the importing script's body runs `dotenv.config()`, so
3659
+ * the key would be empty at construction even though it is set moments
3660
+ * later. Resolving here (at first `withSpan` call / first request) reads
3661
+ * the key after env loading has run.
3662
+ *
3663
+ * Resolution order: the configured value (string, or function called each
3664
+ * time it is still unresolved), then a fallback read of `BITFAB_API_KEY`
3665
+ * from the environment. Once a non-empty key is found it is cached, so an
3666
+ * early resolve that found nothing never poisons a later one.
3667
+ */
3668
+ private findApiKey;
3669
+ private resolveApiKey;
3670
+ private isCaptureConfigured;
3671
+ private isCaptureEnabled;
3672
+ private shouldRecord;
3673
+ private prepareFrameworkIntegration;
3674
+ get captureEnabled(): boolean;
3675
+ /**
3676
+ * Fetch the function with its current version and BAML prompt from the server.
3677
+ *
3678
+ * @param methodName - The name of the method to fetch
3679
+ * @returns The function with current version, BAML prompt, and provider definitions
3680
+ * @throws {BitfabError} If the function is not found or an error occurs
3681
+ */
3682
+ private fetchFunctionVersion;
3683
+ /**
3684
+ * Call a method with the given named arguments via BAML execution.
3685
+ *
3686
+ * @param methodName - The name of the method to call
3687
+ * @param inputs - Named arguments to pass to the method
3688
+ * @returns The result of the BAML function execution
3689
+ * @throws {BitfabError} If service_url is not set, or if an error occurs
3690
+ */
3691
+ call<T = unknown>(methodName: string, inputs?: Record<string, unknown>): Promise<T>;
3692
+ /**
3693
+ * Get a tracing processor for OpenAI Agents SDK integration.
3694
+ *
3695
+ * This processor automatically captures traces and spans from the OpenAI Agents SDK
3696
+ * and sends them to Bitfab for monitoring and analysis.
3697
+ *
3698
+ * Example usage:
3699
+ * ```typescript
3700
+ * import { addTraceProcessor } from '@openai/agents';
3701
+ *
3702
+ * const client = new Bitfab({ apiKey: 'your-api-key' });
3703
+ * const processor = client.getOpenAiTracingProcessor();
3704
+ * addTraceProcessor(processor);
3705
+ * ```
3706
+ *
3707
+ * @returns A BitfabOpenAITracingProcessor instance configured for this client
3708
+ */
3709
+ getOpenAiTracingProcessor(): BitfabOpenAITracingProcessor;
3710
+ /**
3711
+ * Get an OpenAI Agents SDK handler that records a replayable root span.
3712
+ *
3713
+ * The processor from {@link getOpenAiTracingProcessor} captures everything
3714
+ * inside a run (LLM calls, tools, handoffs) but never sees the caller's
3715
+ * input, so a processor-only run records an empty-input root and is not
3716
+ * replayable. This handler's `wrapRun` is a drop-in for `run()` that opens a
3717
+ * `withSpan` root carrying the input and final output; the processor's spans
3718
+ * nest beneath it. Register the processor once at startup, then call
3719
+ * `handler.wrapRun(agent, input)` in place of `run(agent, input)`.
3720
+ *
3721
+ * ```typescript
3722
+ * import { addTraceProcessor, Agent, run } from "@openai/agents";
3723
+ *
3724
+ * addTraceProcessor(client.getOpenAiTracingProcessor());
3725
+ * const handler = client.getOpenAiAgentHandler("research-topic");
3726
+ * const result = await handler.wrapRun(agent, "Find X");
3727
+ * ```
3728
+ *
3729
+ * @param traceFunctionKey - Groups traces under this key in Bitfab
3730
+ * @returns A BitfabOpenAIAgentHandler configured for this client
3731
+ */
3732
+ getOpenAiAgentHandler(traceFunctionKey: string): BitfabOpenAIAgentHandler;
3733
+ /**
3734
+ * Get a LangGraph/LangChain callback handler for tracing.
3735
+ *
3736
+ * The handler captures graph node execution, LLM calls, and tool
3737
+ * invocations as Bitfab spans with proper parent-child hierarchy.
3738
+ *
3739
+ * ```typescript
3740
+ * const handler = client.getLangGraphCallbackHandler("my-agent");
3741
+ * const result = await agent.invoke(
3742
+ * { messages: [...] },
3743
+ * { callbacks: [handler] },
3744
+ * );
3745
+ * ```
3746
+ *
3747
+ * @param traceFunctionKey - Groups traces under this key in Bitfab
3748
+ * @returns A BitfabLangGraphCallbackHandler configured for this client
3749
+ */
3750
+ getLangGraphCallbackHandler(traceFunctionKey: string): BitfabLangGraphCallbackHandler;
3751
+ /**
3752
+ * Get a LangChain callback handler for tracing.
3753
+ *
3754
+ * Alias of {@link getLangGraphCallbackHandler}: LangChain chains and
3755
+ * LangGraph graphs share the same callback system, so one handler serves
3756
+ * both.
3757
+ *
3758
+ * ```typescript
3759
+ * const handler = client.getLangChainCallbackHandler("my-chain");
3760
+ * const result = await chain.invoke(input, { callbacks: [handler] });
3761
+ * ```
3762
+ *
3763
+ * @param traceFunctionKey - Groups traces under this key in Bitfab
3764
+ * @returns A BitfabLangGraphCallbackHandler configured for this client
3765
+ */
3766
+ getLangChainCallbackHandler(traceFunctionKey: string): BitfabLangGraphCallbackHandler;
3767
+ /**
3768
+ * Get the first-class LangGraph integration for tracing and replaying tools
3769
+ * executed by `ToolNode`.
3770
+ *
3771
+ * The integration combines `wrapTools()` for per-tool replay interception
3772
+ * with `createInvoker()` for a callback-configured replayable graph entry
3773
+ * point. Lower-level callback and root wrappers remain available.
3774
+ *
3775
+ * @param traceFunctionKey - Groups traces under this key in Bitfab
3776
+ * @param options - Controls which tools are marked for replay mocking
3777
+ * @experimental This API may change before it is stable.
3778
+ */
3779
+ getLangGraphIntegration(traceFunctionKey: string, options?: LangGraphIntegrationOptions): BitfabLangGraphIntegration;
3780
+ /**
3781
+ * Get the first-class Rivet actor/workflow-context integration for an
3782
+ * existing trace root. The integration binds context and records effect
3783
+ * spans; it never creates another root.
3784
+ *
3785
+ * @param traceFunctionKey - Key used by the enclosing `withTrace()` root
3786
+ * @param options - Explicit per-context-path replay mocking policy
3787
+ * @experimental This API may change before it is stable.
3788
+ */
3789
+ getRivetIntegration<TContext extends object = RivetContextLike>(traceFunctionKey: string, options?: RivetIntegrationOptions): BitfabRivetIntegration<TContext>;
3790
+ /**
3791
+ * Get a Claude Agent SDK handler for tracing.
3792
+ *
3793
+ * The handler captures LLM turns, tool invocations, and subagent
3794
+ * execution as Bitfab spans with proper parent-child hierarchy.
3795
+ *
3796
+ * ```typescript
3797
+ * import { query } from "@anthropic-ai/claude-agent-sdk";
3798
+ *
3799
+ * const handler = client.getClaudeAgentHandler("my-agent");
3800
+ * const options = handler.instrumentOptions({
3801
+ * model: "claude-sonnet-4-5-...",
3802
+ * });
3803
+ * for await (const msg of handler.wrapQuery(
3804
+ * query({ prompt: "Do something", options })
3805
+ * )) {
3806
+ * // process messages
3807
+ * }
3808
+ * ```
3809
+ *
3810
+ * @param traceFunctionKey - Groups traces under this key in Bitfab
3811
+ * @returns A BitfabClaudeAgentHandler configured for this client
3812
+ */
3813
+ getClaudeAgentHandler(traceFunctionKey: string): BitfabClaudeAgentHandler;
3814
+ /**
3815
+ * Get a Vercel AI SDK language-model middleware for tracing.
3816
+ *
3817
+ * Pass it to the AI SDK's `wrapLanguageModel` and use the wrapped model with
3818
+ * `generateText` / `streamText` / `generateObject` / `streamObject`. Every
3819
+ * call through that model is captured as a keyed `llm` span carrying the call
3820
+ * parameters (the prompt) as input and a serializable summary
3821
+ * (`{ text, toolCalls, usage, finishReason }`) as output. Streaming is
3822
+ * captured without disturbing the caller's live stream.
3823
+ *
3824
+ * ```typescript
3825
+ * import { wrapLanguageModel, streamText } from "ai";
3826
+ * import { openai } from "@ai-sdk/openai";
3827
+ *
3828
+ * const model = wrapLanguageModel({
3829
+ * model: openai("gpt-4o"),
3830
+ * middleware: client.getVercelAiMiddleware("chat-turn"),
3831
+ * });
3832
+ * const result = streamText({ model, messages });
3833
+ * ```
3834
+ *
3835
+ * @param traceFunctionKey - Groups traces under this key in Bitfab
3836
+ * @returns A Vercel AI SDK middleware configured for this client
3837
+ */
3838
+ getVercelAiMiddleware(traceFunctionKey: string): BitfabLanguageModelMiddleware;
3839
+ /**
3840
+ * Wrap a BAML client method to automatically capture prompt and LLM metadata.
3841
+ *
3842
+ * Creates a BAML Collector, calls the method through a tracked client,
3843
+ * then extracts rendered messages and token usage - calling setPrompt()
3844
+ * and addContext() on the current span automatically.
3845
+ *
3846
+ * The BAML client can be provided in the constructor or passed explicitly:
3847
+ *
3848
+ * ```typescript
3849
+ * // Option 1: bamlClient in constructor (use wrapBAML with just the method)
3850
+ * const client = new Bitfab({ apiKey: 'your-api-key', bamlClient: b });
3851
+ * const traced = client.withSpan('classify', { type: 'llm' },
3852
+ * client.wrapBAML(b.ClassifyText)
3853
+ * );
3854
+ *
3855
+ * // Option 2: pass bamlClient at call site
3856
+ * const client = new Bitfab({ apiKey: 'your-api-key' });
3857
+ * const traced = client.withSpan('classify', { type: 'llm' },
3858
+ * client.wrapBAML(b, b.ClassifyText)
3859
+ * );
3860
+ * ```
3861
+ *
3862
+ * @param methodOrClient - Either a BAML method (uses constructor bamlClient) or the BAML client instance
3863
+ * @param maybeMethodOrOptions - The BAML method when the first argument is a client, or WrapBAMLOptions when the first argument is the method
3864
+ * @param maybeOptions - WrapBAMLOptions when using the two-argument (client, method) form
3865
+ * @returns An async function with the same signature that instruments the BAML call
3866
+ */
3867
+ wrapBAML<TArgs extends unknown[], TReturn>(methodOrClient: unknown, maybeMethodOrOptions?: ((...args: TArgs) => Promise<TReturn>) | WrapBAMLOptions, maybeOptions?: WrapBAMLOptions): WrappedBamlFn<TArgs, TReturn>;
3868
+ /**
3869
+ * Wrap a function to automatically create a span for its inputs and outputs.
3870
+ *
3871
+ * The wrapped function behaves identically to the original, but sends
3872
+ * span data to Bitfab in the background after each call.
3873
+ *
3874
+ * Example usage:
3875
+ * ```typescript
3876
+ * const client = new Bitfab({ apiKey: 'your-api-key' });
3877
+ *
3878
+ * async function processOrder(orderId: string, items: string[]): Promise<{ total: number }> {
3879
+ * // ... process order
3880
+ * return { total: 100 };
3881
+ * }
3882
+ *
3883
+ * // Basic usage (defaults to "custom" span type)
3884
+ * const tracedProcessOrder = client.withSpan('order-processing', processOrder);
3885
+ *
3886
+ * // With explicit span type
3887
+ * const tracedProcessOrder = client.withSpan('order-processing', { type: 'function' }, processOrder);
3888
+ *
3889
+ * // Call the wrapped function normally
3890
+ * const result = await tracedProcessOrder('order-123', ['item-1', 'item-2']);
3891
+ * // Span is automatically sent to Bitfab
3892
+ * ```
3893
+ *
3894
+ * @param traceFunctionKey - A string identifier for grouping spans (e.g., 'order-processing', 'user-auth')
3895
+ * @param optionsOrFn - Either SpanOptions or the function to wrap
3896
+ * @param maybeFn - The function to wrap if options were provided
3897
+ * @returns A wrapped function with the same signature that creates spans for inputs and outputs
3898
+ */
3899
+ withSpan<TArgs extends unknown[], TReturn>(traceFunctionKey: string, optionsOrFn: SpanOptions | ((...args: TArgs) => TReturn), maybeFn?: (...args: TArgs) => TReturn): (...args: TArgs) => TReturn;
3900
+ /**
3901
+ * Create a standard ECMAScript method decorator that records each invocation
3902
+ * as a span.
3903
+ *
3904
+ * It supports instance, static, and private methods; use
3905
+ * {@link Bitfab.withSpan} for standalone functions, class fields, and
3906
+ * accessors.
3907
+ *
3908
+ * @example
3909
+ * ```typescript
3910
+ * const bitfab = new Bitfab({ apiKey: process.env.BITFAB_API_KEY });
3911
+ *
3912
+ * class OrderService {
3913
+ * @bitfab.span("order-processing", { type: "agent" })
3914
+ * async process(orderId: string) {
3915
+ * return { orderId };
3916
+ * }
3917
+ * }
3918
+ * ```
3919
+ *
3920
+ * @param traceFunctionKey - A string identifier for grouping spans
3921
+ * @param options - Span configuration applied to the decorated method
3922
+ * @returns A standard ECMAScript method decorator
3923
+ */
3924
+ span(traceFunctionKey: string, options?: SpanOptions): SpanMethodDecorator;
3925
+ /**
3926
+ * Get a detached handle to a previously-created trace, looked up by the
3927
+ * canonical Bitfab trace ID.
3928
+ *
3929
+ * The returned handle is not tied to AsyncLocalStorage - each method sends
3930
+ * to the server immediately. Useful for adding context to a trace from a
3931
+ * different process or thread than the one that created it.
3932
+ *
3933
+ * Throws synchronously if `traceId` is not a valid Bitfab trace ID. The
3934
+ * server returns 404 if no trace exists with that ID in the org; the failure surfaces as a
3935
+ * logged warning (fire-and-forget) or via the awaited promise.
3936
+ *
3937
+ * Example:
3938
+ * ```typescript
3939
+ * const trace = client.getTrace(traceId);
3940
+ * await trace.addContext({ refund_status: "approved" });
3941
+ * await trace.setMetadata({ region: "us-west" });
3942
+ * ```
3943
+ */
3944
+ getTrace(traceId: string): DetachedTrace;
3945
+ /**
3946
+ * Fetch one persisted span from a trace without loading the full trace.
3947
+ * Look up by `id` alone, or by `name` and/or `type` (both must match when
3948
+ * both are given). Name and type lookups return the last matching span by
3949
+ * default. Pass `occurrence` as `"first"` or a zero-based index to select a
3950
+ * different match. Returns `null` when no span matches.
3951
+ */
3952
+ getTraceSpan(traceId: string, lookup: SpanLookup): Promise<CapturedSpan | null>;
3953
+ getSpan(spanId: string): Promise<CapturedSpan | null>;
3954
+ /**
3955
+ * Get a function wrapper for a specific trace function key.
3956
+ *
3957
+ * This provides a fluent API alternative to calling withSpan directly,
3958
+ * allowing you to bind the traceFunctionKey once and wrap multiple functions.
3959
+ *
3960
+ * Example usage:
3961
+ * ```typescript
3962
+ * const client = new Bitfab({ apiKey: 'your-api-key' });
3963
+ *
3964
+ * const orderFunc = client.getFunction('order-processing');
3965
+ * const tracedProcessOrder = orderFunc.withSpan(processOrder);
3966
+ * const tracedValidateOrder = orderFunc.withSpan(validateOrder);
3967
+ * ```
3968
+ *
3969
+ * @param traceFunctionKey - A string identifier for grouping spans
3970
+ * @returns A BitfabFunction instance for wrapping functions
3971
+ */
3972
+ getFunction(traceFunctionKey: string): BitfabFunction;
3973
+ /**
3974
+ * Send trace completion when a root span ends.
3975
+ * Internal method to record trace completion with end time.
3976
+ * Queued on the client's span transport; delivery is the transport's job.
3977
+ */
3978
+ private sendTraceCompletion;
3979
+ private sendsSpanOnCompletion;
3980
+ private nearestCapturedAncestorSpanIdOf;
3981
+ private contentOffBySimulationPlan;
3982
+ /**
3983
+ * Send a wrapper span from function execution.
3984
+ * Internal method to record spans when using withSpan.
3985
+ * Queued on the client's span transport; delivery is the transport's job.
3986
+ */
3987
+ private sendWrapperSpan;
3988
+ /**
3989
+ * Replay historical traces through a function and create an experiment.
3990
+ *
3991
+ * Fetches the last N traces for the given trace function key, re-runs each
3992
+ * through the provided function, and returns comparison data.
3993
+ *
3994
+ * Accepts either a `withSpan`-wrapped function (under the same key) or any
3995
+ * plain callable: plain callables are wrapped internally so each replayed
3996
+ * invocation records a trace tied to the experiment. The plain-callable form
3997
+ * is how handler-instrumented workflows (LangGraph/LangChain, Claude Agent
3998
+ * SDK) replay - those record traces under a key with no `withSpan`-wrapped
3999
+ * root in the app.
4000
+ *
4001
+ * @param traceFunctionKey - The trace function key to replay
4002
+ * @param fn - The function to run recorded inputs through
4003
+ * @param options - Optional replay options. When `traceIds` is passed,
4004
+ * `limit` is ignored (with a warning): an explicit ID list already
4005
+ * determines how many traces replay.
4006
+ * @returns ReplayResult with items, experimentId, and experimentUrl
4007
+ */
4008
+ /**
4009
+ * Register a mock override applied to every subsequent `replay` on this
4010
+ * client, so downstream real code runs against a value you supply for the
4011
+ * matched span. Instance-scoped (no global state); call {@link clearMockOverrides}
4012
+ * to reset. Per-call `replay({ mockOverride })` overrides take precedence, and
4013
+ * both take precedence over the base `mock` strategy.
4014
+ *
4015
+ * ```ts
4016
+ * // Object form (value is a flat value here)
4017
+ * bitfab.registerMockOverride({
4018
+ * match: (node) => node.traceFunctionKey === "classify-intent",
4019
+ * value: { label: "refund" },
4020
+ * })
4021
+ * // Ordered form (equivalent); value may also be a function of the context
4022
+ * bitfab.registerMockOverride(
4023
+ * (node) => node.traceFunctionKey === "classify-intent",
4024
+ * ({ inputs }) => ({ label: "refund" }),
4025
+ * )
4026
+ * // Keyed form: the resolver only sees spans for this trace function key.
4027
+ * bitfab.registerMockOverride("classify-intent", ({ inputs }) => ({
4028
+ * label: String(inputs[0]),
4029
+ * }))
4030
+ * // Or one resolver for every child span:
4031
+ * bitfab.registerMockOverride(({ node }) =>
4032
+ * node.traceFunctionKey === "classify-intent"
4033
+ * ? { label: "refund" }
4034
+ * : NO_MOCK_OVERRIDE,
4035
+ * )
4036
+ * ```
4037
+ */
4038
+ registerMockOverride(override: MockOverride): void;
4039
+ registerMockOverride(resolver: MockOverrideResolver): void;
4040
+ registerMockOverride(match: NodeMatcher, value: MockValue): void;
4041
+ registerMockOverride(traceFunctionKey: string, override: MockOverride | MockOverrideResolver): void;
4042
+ /** Remove all overrides registered via {@link registerMockOverride}. */
4043
+ clearMockOverrides(): void;
4044
+ seedTrace(traceFunctionKey: string, options: SeedCaseOptions): string;
4045
+ seedTrace<TArgs extends unknown[], TReturn>(traceFunctionKey: string, fn: (...args: TArgs) => TReturn, options?: SeedRunOptions<TArgs>): Promise<string>;
4046
+ private seedTraceFromCase;
4047
+ private seedTraceByRunning;
4048
+ reseedTrace(traceFunctionKey: string, fn: (...args: any[]) => unknown, options: ReseedOptions): Promise<ReseedResult>;
4049
+ replay<TReturn>(traceFunctionKey: string, fn: (...args: any[]) => TReturn | Promise<TReturn>, options?: ReplayOptions): Promise<ReplayResult<TReturn>>;
4050
+ }
4051
+ /**
4052
+ * Represents a Bitfab function that can wrap user functions for tracing.
4053
+ *
4054
+ * This provides a fluent API for binding a traceFunctionKey once and
4055
+ * then wrapping multiple functions with that key.
4056
+ *
4057
+ * Example usage:
4058
+ * ```typescript
4059
+ * const client = new Bitfab({ apiKey: 'your-api-key' });
4060
+ *
4061
+ * const orderFunc = client.getFunction('order-processing');
4062
+ * const tracedProcessOrder = orderFunc.withSpan(processOrder);
4063
+ * const tracedValidateOrder = orderFunc.withSpan(validateOrder);
4064
+ * ```
4065
+ */
4066
+ declare class BitfabFunction {
4067
+ private readonly client;
4068
+ private readonly traceFunctionKey;
4069
+ constructor(client: Bitfab, traceFunctionKey: string);
4070
+ /**
4071
+ * Wrap a function to automatically create a span for its inputs and outputs.
4072
+ *
4073
+ * The wrapped function behaves identically to the original, but sends
4074
+ * span data to Bitfab in the background after each call.
4075
+ *
4076
+ * Example usage:
4077
+ * ```typescript
4078
+ * const orderFunc = client.getFunction('order-processing');
4079
+ *
4080
+ * // Basic usage (defaults to "custom" span type)
4081
+ * const tracedProcessOrder = orderFunc.withSpan(processOrder);
4082
+ *
4083
+ * // With explicit span type
4084
+ * const tracedProcessOrder = orderFunc.withSpan({ type: 'function' }, processOrder);
4085
+ * ```
4086
+ *
4087
+ * @param optionsOrFn - Either SpanOptions or the function to wrap
4088
+ * @param maybeFn - The function to wrap if options were provided
4089
+ * @returns A wrapped function with the same signature that creates spans
4090
+ */
4091
+ withSpan<TArgs extends unknown[], TReturn>(optionsOrFn: SpanOptions | ((...args: TArgs) => TReturn), maybeFn?: (...args: TArgs) => TReturn): (...args: TArgs) => TReturn;
4092
+ /**
4093
+ * Create a standard ECMAScript method decorator bound to this function key.
4094
+ *
4095
+ * @example
4096
+ * ```typescript
4097
+ * const orders = client.getFunction("order-processing");
4098
+ *
4099
+ * class OrderService {
4100
+ * @orders.span({ type: "agent" })
4101
+ * async process(orderId: string) {
4102
+ * return { orderId };
4103
+ * }
4104
+ * }
4105
+ * ```
4106
+ *
4107
+ * @param options - Span configuration applied to the decorated method
4108
+ * @returns A standard ECMAScript method decorator
4109
+ */
4110
+ span(options?: SpanOptions): SpanMethodDecorator;
4111
+ /**
4112
+ * Wrap a function as an automatically expanded trace root bound to this
4113
+ * function's key.
4114
+ *
4115
+ * Equivalent to `client.withTrace(key, options, fn)` but reuses the key
4116
+ * bound on this handle.
4117
+ *
4118
+ * @param optionsOrFn - Trace options or the workflow entrypoint to wrap
4119
+ * @param maybeFn - Workflow entrypoint when options are provided
4120
+ * @returns A wrapped function with the same signature
4121
+ * @experimental Automatic child-call instrumentation is experimental.
4122
+ */
4123
+ withTrace<This, TArgs extends unknown[], TReturn>(fn: (this: This, ...args: TArgs) => TReturn): (this: This, ...args: TArgs) => TReturn;
4124
+ withTrace<This, TArgs extends unknown[], TReturn>(options: TraceOptions, fn: (this: This, ...args: TArgs) => TReturn): (this: This, ...args: TArgs) => TReturn;
4125
+ /**
4126
+ * Create a trace method decorator bound to this function's key.
4127
+ *
4128
+ * Equivalent to `client.trace(key, options)` but reuses the key bound on
4129
+ * this handle.
4130
+ *
4131
+ * @param options - Trace configuration applied to the decorated method
4132
+ * @returns A method decorator configured for this key
4133
+ * @experimental Automatic child-call instrumentation is experimental.
4134
+ */
4135
+ trace(options?: TraceOptions): TraceMethodDecorator;
4136
+ /**
4137
+ * Get a Vercel AI SDK language-model middleware bound to this function's key.
4138
+ *
4139
+ * Equivalent to `client.getVercelAiMiddleware(key)` but reuses the key bound
4140
+ * on this handle, so an outer `withSpan` root and the middleware-traced model
4141
+ * calls share one key without repeating the string. With a matching key, the
4142
+ * outer span is the replayable root and the model-call spans nest beneath it.
4143
+ *
4144
+ * Nesting is captured when the model is called, so keep the
4145
+ * `generateText` / `streamText` call inside this handle's `withSpan`; the
4146
+ * middleware object itself can be created anywhere.
4147
+ *
4148
+ * ```typescript
4149
+ * const chatTurn = client.getFunction("chat-turn");
4150
+ * const runChatTurn = chatTurn.withSpan(
4151
+ * { type: "agent", finalize: finalizers.aiSdk },
4152
+ * (messages) => streamText({ model, messages }),
4153
+ * );
4154
+ * const model = wrapLanguageModel({
4155
+ * model: openai("gpt-4o"),
4156
+ * middleware: chatTurn.getVercelAiMiddleware(),
4157
+ * });
4158
+ * ```
4159
+ *
4160
+ * @returns A Vercel AI SDK middleware configured for this client and key
4161
+ */
4162
+ getVercelAiMiddleware(): BitfabLanguageModelMiddleware;
4163
+ /**
4164
+ * Get a Claude Agent SDK handler bound to this function's key.
4165
+ *
4166
+ * Equivalent to `client.getClaudeAgentHandler(key)` but reuses the key bound
4167
+ * on this handle, so an outer `withSpan` root and the handler share one key
4168
+ * without repeating the string. With a matching key, the outer span is the
4169
+ * replayable root and every handler span nests beneath it.
4170
+ *
4171
+ * Use the handler inside this handle's `withSpan` body so its spans capture
4172
+ * the enclosing root; framework calls made with no active span record their
4173
+ * own root instead.
4174
+ *
4175
+ * ```typescript
4176
+ * const pipeline = client.getFunction("my-agent");
4177
+ * const tracedRun = pipeline.withSpan({ type: "agent" }, async (prompt) => {
4178
+ * const handler = pipeline.getClaudeAgentHandler();
4179
+ * const options = handler.instrumentOptions({ model: "claude-sonnet-4-6" });
4180
+ * for await (const msg of handler.wrapQuery(query({ prompt, options }))) { ... }
4181
+ * });
4182
+ * ```
4183
+ *
4184
+ * @returns A Claude Agent SDK handler configured for this client and key
4185
+ */
4186
+ getClaudeAgentHandler(): BitfabClaudeAgentHandler;
4187
+ /**
4188
+ * Get a LangGraph/LangChain callback handler bound to this function's key.
4189
+ *
4190
+ * Equivalent to `client.getLangGraphCallbackHandler(key)` but reuses the key
4191
+ * bound on this handle, so an outer `withSpan` root and the handler share one
4192
+ * key without repeating the string. With a matching key, the outer span is
4193
+ * the replayable root and the LangGraph spans nest beneath it.
4194
+ *
4195
+ * Use the handler inside this handle's `withSpan` body so its spans capture
4196
+ * the enclosing root; framework calls made with no active span record their
4197
+ * own root instead.
4198
+ *
4199
+ * ```typescript
4200
+ * const pipeline = client.getFunction("my-pipeline");
4201
+ * const tracedRun = pipeline.withSpan({ type: "agent" }, async (query) => {
4202
+ * const handler = pipeline.getLangGraphCallbackHandler();
4203
+ * return agent.invoke({ messages: [...] }, { callbacks: [handler] });
4204
+ * });
4205
+ * ```
4206
+ *
4207
+ * @returns A LangGraph/LangChain callback handler for this client and key
4208
+ */
4209
+ getLangGraphCallbackHandler(): BitfabLangGraphCallbackHandler;
4210
+ /**
4211
+ * Alias of {@link getLangGraphCallbackHandler} - LangChain and LangGraph
4212
+ * share one callback system, so the same bound handler serves both.
4213
+ *
4214
+ * @returns A LangChain callback handler for this client and key
4215
+ */
4216
+ getLangChainCallbackHandler(): BitfabLangGraphCallbackHandler;
4217
+ /**
4218
+ * Get the first-class LangGraph tool replay integration bound to this key.
4219
+ *
4220
+ * @experimental This API may change before it is stable.
4221
+ */
4222
+ getLangGraphIntegration(options?: LangGraphIntegrationOptions): BitfabLangGraphIntegration;
4223
+ /**
4224
+ * Get the first-class Rivet actor-context integration bound to this key.
4225
+ * Use its `bind()` or `withContext()` outside this handle's `withTrace()`
4226
+ * root, then call `getContext()` inside the root.
4227
+ *
4228
+ * @param options - Explicit per-context-path replay mocking policy
4229
+ * @experimental This API may change before it is stable.
4230
+ */
4231
+ getRivetIntegration<TContext extends object = RivetContextLike>(options?: RivetIntegrationOptions): BitfabRivetIntegration<TContext>;
4232
+ /**
4233
+ * Wrap a BAML client method to automatically capture prompt and LLM metadata.
4234
+ * Delegates to the parent client's wrapBAML method.
4235
+ *
4236
+ * Unlike the other methods on this handle, `wrapBAML` does NOT use the bound
4237
+ * key: it opens no span of its own. It enriches the *current* span (via
4238
+ * `getCurrentSpan().setPrompt()` / `addContext()`), so call it inside a
4239
+ * function wrapped by this handle's `withSpan` - the bound key keys that
4240
+ * wrapper, and the BAML prompt/metadata attach to it.
4241
+ *
4242
+ * @param methodOrClient - Either a BAML method (uses constructor bamlClient) or the BAML client instance
4243
+ * @param maybeMethodOrOptions - The BAML method when the first argument is a client, or WrapBAMLOptions when the first argument is the method
4244
+ * @param maybeOptions - WrapBAMLOptions when using the two-argument (client, method) form
4245
+ * @returns An async function with the same signature that instruments the BAML call
4246
+ */
4247
+ wrapBAML<TArgs extends unknown[], TReturn>(methodOrClient: unknown, maybeMethodOrOptions?: ((...args: TArgs) => Promise<TReturn>) | WrapBAMLOptions, maybeOptions?: WrapBAMLOptions): WrappedBamlFn<TArgs, TReturn>;
4248
+ }
4249
+ //#endregion
4250
+ //#region src/commitRef.d.ts
4251
+ interface CommitRef {
4252
+ sha: string;
4253
+ branch: string | null;
4254
+ dirty: boolean | null;
4255
+ remote: string | null;
4256
+ rootSha: string | null;
4257
+ }
4258
+ //#endregion
4259
+ //#region src/version.generated.d.ts
4260
+ /**
4261
+ * Auto-generated package metadata.
4262
+ * This file is generated by scripts/generate-version.ts during build.
4263
+ * DO NOT EDIT MANUALLY.
4264
+ */
4265
+ /**
4266
+ * SDK version from package.json (injected at build time)
4267
+ */
4268
+ declare const __version__ = "0.65.6";
4269
+ //#endregion
4270
+ //#region src/constants.d.ts
4271
+ /**
4272
+ * Constants for the Bitfab SDK.
4273
+ */
4274
+ /**
4275
+ * Default service URL for Bitfab API.
4276
+ */
4277
+ declare const DEFAULT_SERVICE_URL = "https://bitfab.ai";
4278
+ //#endregion
4279
+ //#region src/finalizers.d.ts
4280
+ /**
4281
+ * Prebuilt `finalize` helpers for `withSpan({ finalize }, fn)`.
4282
+ *
4283
+ * A streaming function returns a live stream object that the caller consumes
4284
+ * directly (SSE, a UI message stream). `withSpan` hands that object back
4285
+ * unchanged; a `finalize` function tells it what serializable view to record
4286
+ * as the span output instead of the raw, non-serializable stream.
4287
+ */
4288
+ /**
4289
+ * Drain a Vercel AI SDK streaming result into a serializable, replayable
4290
+ * span output: `{ text, usage, finishReason, toolCalls, toolResults }`.
4291
+ *
4292
+ * Pass it straight to `withSpan`:
4293
+ *
4294
+ * ```ts
4295
+ * import { finalizers } from "@bitfab/sdk"
4296
+ *
4297
+ * const traced = bitfab.withSpan(
4298
+ * "chat-turn",
4299
+ * { type: "agent", finalize: finalizers.aiSdk },
4300
+ * () => streamText({ model, messages }),
4301
+ * )
4302
+ * const result = traced() // caller still gets the live StreamTextResult
4303
+ * return result.toUIMessageStreamResponse()
4304
+ * ```
4305
+ *
4306
+ * Never throws: any field that is absent or rejects is recorded as
4307
+ * `undefined` so finalize never drops the span.
4308
+ */
4309
+ declare function aiSdk(result: unknown): Promise<Record<string, unknown>>;
4310
+ /**
4311
+ * Collect a `ReadableStream`'s chunks into an array for the span output,
4312
+ * via a `tee()` so the caller's branch is untouched. The caller MUST use
4313
+ * the returned stream, not the original, since a stream can only be read
4314
+ * once:
4315
+ *
4316
+ * ```ts
4317
+ * let live: ReadableStream
4318
+ * const traced = bitfab.withSpan(
4319
+ * "render",
4320
+ * { finalize: (r) => finalizers.readableStream(r, (s) => { live = s }) },
4321
+ * () => makeReadableStream(),
4322
+ * )
4323
+ * traced()
4324
+ * return new Response(live!)
4325
+ * ```
4326
+ *
4327
+ * Prefer `aiSdk` for the Vercel AI SDK, whose result tees internally and
4328
+ * needs no caller rewiring.
4329
+ */
4330
+ declare function readableStream(stream: ReadableStream, onLive: (live: ReadableStream) => void): Promise<{
4331
+ chunks: unknown[];
4332
+ }>;
4333
+ declare const finalizers: {
4334
+ aiSdk: typeof aiSdk;
4335
+ readableStream: typeof readableStream;
4336
+ };
4337
+ //#endregion
4338
+ //#region src/replayRegistry.d.ts
4339
+ type ReplayFunction = (...args: any[]) => unknown | Promise<unknown>;
4340
+ type ReplayRegistryOptions = Omit<ReplayOptions, "onItemStart" | "onItemFinish" | "onProgress" | "onExperimentStart">;
4341
+ interface ReplayRegistryContext {
4342
+ /** Values supplied through `--params` and repeated `--param name=value`. */
4343
+ params: Readonly<Record<string, unknown>>;
4344
+ }
4345
+ type ReplayOptionsFactory = (context: ReplayRegistryContext) => ReplayRegistryOptions | Promise<ReplayRegistryOptions>;
4346
+ interface ReplayRegistration {
4347
+ /** Client instance used by the production traced function. */
4348
+ client: Bitfab;
4349
+ /** The exact traced function production calls. */
4350
+ fn: ReplayFunction;
4351
+ /**
4352
+ * Required for handler-instrumented or otherwise plain callables. Omit for a
4353
+ * `withSpan`-wrapped function and the registry reads the wrapper's key.
4354
+ */
4355
+ traceFunctionKey?: string;
4356
+ /**
4357
+ * Per-function replay behavior and defaults. Put executable configuration
4358
+ * such as `mockOverride` and `adaptInputs` here; command-line values override
4359
+ * overlapping scalar defaults such as `mock` and `maxConcurrency`.
4360
+ */
4361
+ options?: ReplayRegistryOptions;
4362
+ /** Build executable replay behavior from caller-supplied CLI parameters. */
4363
+ optionsFactory?: ReplayOptionsFactory;
4364
+ }
4365
+ type ReplayRegistry = Record<string, ReplayRegistration>;
4366
+ /**
4367
+ * Define the project-owned list of replayable functions.
4368
+ *
4369
+ * The registry is deliberately data-only: the SDK owns the replay CLI, so an
4370
+ * SDK upgrade can add replay features without regenerating the project file.
4371
+ */
4372
+ declare function defineReplayRegistry<TRegistry extends ReplayRegistry>(registry: TRegistry): TRegistry;
4373
+ /** One case to seed, in the shape `--seed` reads from JSON or JSONL. */
4374
+ interface SeedCase {
4375
+ /** Arguments spread into the registered function at replay. */
4376
+ input: unknown[];
4377
+ /** The output this case should produce. */
4378
+ expected?: unknown;
4379
+ /** Recorded on the trace, for tracing a seeded case back to its source row. */
4380
+ metadata?: Record<string, unknown>;
4381
+ sessionId?: string;
4382
+ }
4383
+ interface SeedResult {
4384
+ pipeline: string;
4385
+ traceFunctionKey: string;
4386
+ traceIds: string[];
4387
+ }
4388
+ interface ReseedRegistryResult {
4389
+ pipeline: string;
4390
+ traceFunctionKey: string;
4391
+ reseeded: {
4392
+ traceId: string;
4393
+ previousRunTraceId: string;
4394
+ }[];
4395
+ }
4396
+ declare function reseedFromRegistry(registry: ReplayRegistry, pipeline: string, traceIds: readonly string[]): Promise<ReseedRegistryResult>;
4397
+ /**
4398
+ * Seed cases through an already-registered pipeline.
4399
+ *
4400
+ * The registration is the whole point: it already holds the client, the exact
4401
+ * function production calls, and the trace function key replay selects by, so
4402
+ * a seeded case is guaranteed to line up with the replay that will read it.
4403
+ * Passing the registered function to `seedTrace` also means a case that cannot
4404
+ * supply its required arguments is rejected here rather than at replay.
4405
+ */
4406
+ declare function seedFromRegistry(registry: ReplayRegistry, pipeline: string, cases: readonly SeedCase[], options?: {
4407
+ run?: boolean;
4408
+ }): Promise<SeedResult>;
4409
+ //#endregion
4410
+ export { AdaptInputsFn as $, RerunGradersResult as $n, SaveAssertionsAllParams as $t, SpanMethodDecoratorContext as A, ExperimentRollupResult as An, MockValue as Ar, ArchiveLabelTarget as At, TraceResponse as B, DatasetGraderRef as Bn, ReplayNodeIdentity as Br, LabelUpdate as Bt, NodeMethodDecorator as C, TracesClient as Cn, TokenUsage as Cr, BitfabLangGraphCallbackHandler as Ct, SeedCaseOptions as D, ExperimentJitter as Dn, MockOverrideCtx as Dr, GraderLabelSource as Dt, ReseedResult as E, ExperimentCodeChangeTotals as En, MockOverride as Er, GraderLabelOutcome as Et, getCurrentSpan as F, ExperimentsClient as Fn, MixedTracingError as Fr, LabelConfidence as Ft, SpanListResult as G, GraderRerunProgress as Gn, BamlExecutionResult as Gr, AssertionEvidenceParameter as Gt, ListedSpan as H, DatasetsClient as Hn, SelectiveReplayOptions as Hr, TraceLabels as Ht, getCurrentTrace as I, ListExperimentsParams as In, DbSnapshotConfig as Ir, LabelOutcome as It, RivetContextLike as J, GraderRerunTimeoutError as Jn, ApprovalState as Jr, AssertionGenerationStatus as Jt, SpansClient as K, GraderRerunResult as Kn, ProviderDefinition as Kr, AssertionGeneration as Kt, CaptureSurface as L, AddDatasetGradersResult as Ln, DbSnapshotProvider as Lr, LabelSource as Lt, WrapBAMLOptions as M, ExperimentStatus as Mn, NodeMatcher as Mr, HumanLabelOutcome as Mt, WrappedBamlFn as N, ExperimentTally as Nn, SpanNodeMeta as Nr, HumanLabelUpdate as Nt, SeedRunOptions as O, ExperimentPage as On, MockOverrideInput as Or, GraderLabelUpdate as Ot, getCurrentReplayBranch as P, ExperimentTotals as Pn, BitfabError as Pr, LabelAction as Pt, AdaptContext as Q, RerunGradersOptions as Qn, JustificationSpan as Qr, SaveAssertion as Qt, ActiveSpanContext as R, AddDatasetTracesResult as Rn, DbSnapshotRef as Rr, LabelStatus as Rt, DetachedTrace as S, TraceTargetOccurrence as Sn, SpanType as Sr, LangGraphIntegrationOptions as St, ReseedOptions as T, ExperimentCategoryTally as Tn, DbBranchTimings as Tr, GraderLabel as Tt, SpanListField as U, GraderRerun as Un, SelectiveReplayReport as Ur, Verdict as Ut, TracingProcessor as V, DatasetTraceIds as Vn, SelectiveReplayDecision as Vr, LabelsClient as Vt, SpanListParams as W, GraderRerunError as Wn, AllowedEnvVars as Wr, ArchiveAssertionsParams as Wt, RivetIntegrationOptions as X, RemoveDatasetGradersResult as Xn, Assignee as Xr, AssertionLabelEvidence as Xt, RivetEffectType as Y, ListDatasetsParams as Yn, Approver as Yr, AssertionGenerationTimeoutError as Yt, ReplayBranch as Z, RemoveDatasetTracesResult as Zn, Justification as Zr, GenerateAssertionsOptions as Zt, BitfabConfig as _, TraceAssertionsUpdate as _n, CapturedSpan as _r, ReplayInterruptSignal as _t, ReplayRegistryOptions as a, Scenario as an, VercelCallParams as ar, ReplayExperiment as at, CurrentSpan as b, TraceSearchResult as bn, SpanLookup as br, BitfabOpenAIAgentHandler as bt, SeedResult as c, ScenarioData as cn, BitfabClaudeAgentHandler as cr, ReplayItemStartProgress as ct, seedFromRegistry as d, ScenarioHistoryEntry as dn, AssertionCategorySummary as dr, ReplayProgressItem as dt, SaveAssertionsParams as en, SaveDatasetParams as er, BITFAB_PROGRESS_PREFIX as et, finalizers as f, ScenarioSource as fn, CategoriesClient as fr, ReplayResult as ft, Bitfab as g, TraceAssertionsResult as gn, SaveCategoryParams as gr, ReplayInterrupt as gt, CommitRef as h, TraceAssertionSource as hn, SaveAssertionCategoryParams as hr, serializeReplayResult as ht, ReplayRegistryContext as i, SaveScenarioParams as in, BitfabVercelAiHandler as ir, ReplayError as it, SpanOptions as j, ExperimentRunBy as jn, NO_MOCK_OVERRIDE as jr, AssertionVerdict as jt, SpanMethodDecorator as k, ExperimentRollup as kn, MockOverrideResolver as kr, GradersClient as kt, defineReplayRegistry as l, ScenarioDataAppend as ln, AssertionCategoriesClient as lr, ReplayOptions as lt, __version__ as m, TraceAssertion as mn, CategorySummary as mr, reportReplayProgress as mt, ReplayRegistration as n, SaveScenarioData as nn, UpdateDatasetParams as nr, DbBranchReplayError as nt, ReseedRegistryResult as o, ScenarioAction as on, VercelGenerateResult as or, ReplayItem as ot, DEFAULT_SERVICE_URL as p, ScenarioTrigger as pn, Category as pr, TraceIngestionType as pt, BitfabRivetIntegration as q, GraderRerunStatus as qn, ApprovalFields as qr, AssertionGenerationError as qt, ReplayRegistry as r, SaveScenarioHistoryEntry as rn, BitfabLanguageModelMiddleware as rr, MockStrategy as rt, SeedCase as s, ScenarioActualOutcome as sn, VercelStreamResult as sr, ReplayItemFinishProgress as st, ReplayOptionsFactory as t, SaveScenarioActualOutcome as tn, SaveDatasetResult as tr, DbBranchOptions as tt, reseedFromRegistry as u, ScenarioDataOrigin as un, AssertionCategory as ur, ReplayProgress as ut, BitfabFunction as v, TraceSearchFilters as vn, CodeChangeFile as vr, OrganizationMember as vt, NodeOptions as w, Experiment as wn, flushTraces as wr, GetGraderLabelsParams as wt, CurrentTrace as x, TraceTarget as xn, SpanOccurrence as xr, BitfabLangGraphIntegration as xt, CaptureWhen as y, TraceSearchParams as yn, HttpClient as yr, OrganizationMembersClient as yt, BitfabOpenAITracingProcessor as z, Dataset as zn, SUPPORTED_PROVIDERS as zr, LabelTarget as zt };