@bitfab/sdk 0.38.9 → 0.39.0

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.
package/dist/index.d.cts CHANGED
@@ -1288,6 +1288,13 @@ declare class BitfabOpenAIAgentHandler {
1288
1288
  */
1289
1289
 
1290
1290
  type MockStrategy = "none" | "all" | "marked";
1291
+ /**
1292
+ * How a source trace came to exist. A `seeded` trace was written from a case
1293
+ * with {@link Bitfab.seedTrace} rather than executed, so it has no recorded
1294
+ * child spans to mock from and no database state to restore, and its recorded
1295
+ * output is the value the case expected rather than a previous run's result.
1296
+ */
1297
+ type TraceIngestionType = "captured" | "seeded";
1291
1298
  /**
1292
1299
  * How the DB-snapshot branch each replay item runs against is sized and warmed.
1293
1300
  *
@@ -1418,6 +1425,15 @@ interface ReplayOptions {
1418
1425
  * Omit it to spread the recorded inputs unchanged.
1419
1426
  */
1420
1427
  adaptInputs?: (inputs: unknown[], ctx: AdaptContext) => unknown[];
1428
+ /**
1429
+ * Resolve every item's inputs and stop, without calling the function.
1430
+ *
1431
+ * Selection, span fetch, deserialization, and `adaptInputs` all run, so each
1432
+ * item reports the exact arguments the function would have received. Nothing
1433
+ * executes and no replay traces are produced, which is the cheap way to check
1434
+ * that recorded inputs still fit the current signature.
1435
+ */
1436
+ dryRun?: boolean;
1421
1437
  /**
1422
1438
  * Called once per item as it finishes, in completion order (not input
1423
1439
  * order), with running totals for the whole run. Use it to render replay
@@ -1620,8 +1636,17 @@ interface ReplayItem<T> {
1620
1636
  input: unknown[];
1621
1637
  /** The result returned by the function during replay, or undefined on error. */
1622
1638
  result: T | undefined;
1623
- /** The original output from the historical trace. */
1639
+ /**
1640
+ * The original output from the historical trace. For a `seeded` source this
1641
+ * is the value the case expected, not a previous run's result, so a
1642
+ * difference means the code missed the expectation rather than drifted.
1643
+ */
1624
1644
  originalOutput: unknown;
1645
+ /**
1646
+ * How the source trace came to exist. Absent on servers that predate the
1647
+ * field, which only ever served captured traces.
1648
+ */
1649
+ ingestionType?: TraceIngestionType;
1625
1650
  /**
1626
1651
  * Backward-compatible message for either error kind. Prefer `traceError` and
1627
1652
  * `replayError` when callers need the original exception and its source.
@@ -2209,6 +2234,12 @@ interface TraceOptions {
2209
2234
  name?: string;
2210
2235
  /** Root span type. Descendants are always `function` spans. */
2211
2236
  type?: SpanType;
2237
+ /**
2238
+ * Default replay-mocking policy for automatically captured descendants.
2239
+ * When true, those descendants are mocked by the default "marked" strategy
2240
+ * unless a node explicitly sets `mockOnReplay: false`. Defaults to false.
2241
+ */
2242
+ mockOnReplayDefault?: boolean;
2212
2243
  /** Maximum number of recorded descendant levels. Defaults to 30. */
2213
2244
  maxDepth?: number;
2214
2245
  /** Maximum descendant spans recorded per root invocation. Defaults to 500. */
@@ -2710,6 +2741,45 @@ declare class Bitfab {
2710
2741
  registerMockOverride(traceFunctionKey: string, override: MockOverride | MockOverrideResolver): void;
2711
2742
  /** Remove all overrides registered via {@link registerMockOverride}. */
2712
2743
  clearMockOverrides(): void;
2744
+ /**
2745
+ * Write a replayable trace from a case, without running anything.
2746
+ *
2747
+ * Use this to turn a corpus you already hold (a Braintrust dataset, a
2748
+ * spreadsheet, hand-written cases) into traces that {@link replay} can
2749
+ * select. The recorded root span carries `input` as its input and `expected`
2750
+ * as its output, so replay reports each item against the value you expected
2751
+ * rather than against a previous run.
2752
+ *
2753
+ * A seeded trace has no child spans and no database pin, so replay mocking
2754
+ * has nothing recorded to substitute and `dbBranch` refuses it. Pass
2755
+ * `mockOverride` at replay time for calls that must not run.
2756
+ *
2757
+ * @returns The trace ID, usable with `replay({ traceIds: [...] })`.
2758
+ */
2759
+ seedTrace(traceFunctionKey: string, options: {
2760
+ /** Arguments spread into the function at replay, as `fn(...input)`. */
2761
+ input: unknown[];
2762
+ /**
2763
+ * The output this case should produce. Optional, but without it the
2764
+ * replay has nothing to be judged against.
2765
+ */
2766
+ expected?: unknown;
2767
+ /**
2768
+ * The function these inputs will replay through. When given, the call is
2769
+ * checked against its arity here, so a case that cannot supply the
2770
+ * function's required arguments fails now instead of at replay. Omit it
2771
+ * when the seeding script cannot import the function.
2772
+ */
2773
+ fn?: (...args: any[]) => unknown;
2774
+ /**
2775
+ * Recorded on the trace. Put the source row's id here so a seeded trace
2776
+ * can be traced back to the case it came from.
2777
+ */
2778
+ metadata?: Record<string, unknown>;
2779
+ sessionId?: string;
2780
+ spanName?: string;
2781
+ spanType?: SpanType;
2782
+ }): string;
2713
2783
  replay<TReturn>(traceFunctionKey: string, fn: (...args: any[]) => TReturn | Promise<TReturn>, options?: ReplayOptions): Promise<ReplayResult<TReturn>>;
2714
2784
  }
2715
2785
  /**
@@ -2885,7 +2955,7 @@ declare class BitfabFunction {
2885
2955
  /**
2886
2956
  * SDK version from package.json (injected at build time)
2887
2957
  */
2888
- declare const __version__ = "0.38.9";
2958
+ declare const __version__ = "0.39.0";
2889
2959
 
2890
2960
  /**
2891
2961
  * Constants for the Bitfab SDK.
@@ -2987,5 +3057,30 @@ type ReplayRegistry = Record<string, ReplayRegistration>;
2987
3057
  * SDK upgrade can add replay features without regenerating the project file.
2988
3058
  */
2989
3059
  declare function defineReplayRegistry<TRegistry extends ReplayRegistry>(registry: TRegistry): TRegistry;
3060
+ /** One case to seed, in the shape `--seed` reads from JSON or JSONL. */
3061
+ interface SeedCase {
3062
+ /** Arguments spread into the registered function at replay. */
3063
+ input: unknown[];
3064
+ /** The output this case should produce. */
3065
+ expected?: unknown;
3066
+ /** Recorded on the trace, for tracing a seeded case back to its source row. */
3067
+ metadata?: Record<string, unknown>;
3068
+ sessionId?: string;
3069
+ }
3070
+ interface SeedResult {
3071
+ pipeline: string;
3072
+ traceFunctionKey: string;
3073
+ traceIds: string[];
3074
+ }
3075
+ /**
3076
+ * Seed cases through an already-registered pipeline.
3077
+ *
3078
+ * The registration is the whole point: it already holds the client, the exact
3079
+ * function production calls, and the trace function key replay selects by, so
3080
+ * a seeded case is guaranteed to line up with the replay that will read it.
3081
+ * Passing the registered function to `seedTrace` also means a case that cannot
3082
+ * supply its required arguments is rejected here rather than at replay.
3083
+ */
3084
+ declare function seedFromRegistry(registry: ReplayRegistry, pipeline: string, cases: readonly SeedCase[]): Promise<SeedResult>;
2990
3085
 
2991
- export { type ActiveSpanContext, type AdaptContext, type AdaptInputsFn, type AllowedEnvVars, BITFAB_PROGRESS_PREFIX, type BamlExecutionResult, Bitfab, BitfabClaudeAgentHandler, type BitfabConfig, BitfabError, BitfabFunction, BitfabLangGraphCallbackHandler as BitfabLangChainCallbackHandler, BitfabLangGraphCallbackHandler, BitfabLangGraphIntegration, type BitfabLanguageModelMiddleware, BitfabOpenAIAgentHandler, BitfabOpenAITracingProcessor, BitfabVercelAiHandler, type CaptureWhen, type CapturedSpan, type CodeChangeFile, type CurrentSpan, type CurrentTrace, DEFAULT_SERVICE_URL, type DbBranchOptions, DbBranchReplayError, type DbBranchTimings, type DbSnapshotConfig, type DbSnapshotProvider, type DbSnapshotRef, type DetachedTrace, HttpClient, type LangGraphIntegrationOptions, type MockOverride, type MockOverrideCtx, type MockOverrideInput, type MockOverrideResolver, type MockStrategy, type MockValue, NO_MOCK_OVERRIDE, type NodeMatcher, type NodeMethodDecorator, type NodeOptions, type ProviderDefinition, ReplayBranch, ReplayError, type ReplayItem, type ReplayItemFinishProgress, type ReplayItemStartProgress, type ReplayOptions, type ReplayOptionsFactory, type ReplayProgress, type ReplayProgressItem, type ReplayRegistration, type ReplayRegistry, type ReplayRegistryContext, type ReplayRegistryOptions, type ReplayResult, SUPPORTED_PROVIDERS, type SpanLookup, type SpanMethodDecorator, type SpanMethodDecoratorContext, type SpanNodeMeta, type SpanOccurrence, type SpanOptions, type SpanType, type TokenUsage, type TraceResponse, type TracingProcessor, type VercelCallParams, type VercelGenerateResult, type VercelStreamResult, type WrapBAMLOptions, type WrappedBamlFn, __version__, defineReplayRegistry, finalizers, flushTraces, getCurrentReplayBranch, getCurrentSpan, getCurrentTrace, reportReplayProgress, serializeReplayResult };
3086
+ export { type ActiveSpanContext, type AdaptContext, type AdaptInputsFn, type AllowedEnvVars, BITFAB_PROGRESS_PREFIX, type BamlExecutionResult, Bitfab, BitfabClaudeAgentHandler, type BitfabConfig, BitfabError, BitfabFunction, BitfabLangGraphCallbackHandler as BitfabLangChainCallbackHandler, BitfabLangGraphCallbackHandler, BitfabLangGraphIntegration, type BitfabLanguageModelMiddleware, BitfabOpenAIAgentHandler, BitfabOpenAITracingProcessor, BitfabVercelAiHandler, type CaptureWhen, type CapturedSpan, type CodeChangeFile, type CurrentSpan, type CurrentTrace, DEFAULT_SERVICE_URL, type DbBranchOptions, DbBranchReplayError, type DbBranchTimings, type DbSnapshotConfig, type DbSnapshotProvider, type DbSnapshotRef, type DetachedTrace, HttpClient, type LangGraphIntegrationOptions, type MockOverride, type MockOverrideCtx, type MockOverrideInput, type MockOverrideResolver, type MockStrategy, type MockValue, NO_MOCK_OVERRIDE, type NodeMatcher, type NodeMethodDecorator, type NodeOptions, type ProviderDefinition, ReplayBranch, ReplayError, type ReplayItem, type ReplayItemFinishProgress, type ReplayItemStartProgress, type ReplayOptions, type ReplayOptionsFactory, type ReplayProgress, type ReplayProgressItem, type ReplayRegistration, type ReplayRegistry, type ReplayRegistryContext, type ReplayRegistryOptions, type ReplayResult, SUPPORTED_PROVIDERS, type SeedCase, type SeedResult, type SpanLookup, type SpanMethodDecorator, type SpanMethodDecoratorContext, type SpanNodeMeta, type SpanOccurrence, type SpanOptions, type SpanType, type TokenUsage, type TraceIngestionType, type TraceResponse, type TracingProcessor, type VercelCallParams, type VercelGenerateResult, type VercelStreamResult, type WrapBAMLOptions, type WrappedBamlFn, __version__, defineReplayRegistry, finalizers, flushTraces, getCurrentReplayBranch, getCurrentSpan, getCurrentTrace, reportReplayProgress, seedFromRegistry, serializeReplayResult };
package/dist/index.d.ts CHANGED
@@ -1288,6 +1288,13 @@ declare class BitfabOpenAIAgentHandler {
1288
1288
  */
1289
1289
 
1290
1290
  type MockStrategy = "none" | "all" | "marked";
1291
+ /**
1292
+ * How a source trace came to exist. A `seeded` trace was written from a case
1293
+ * with {@link Bitfab.seedTrace} rather than executed, so it has no recorded
1294
+ * child spans to mock from and no database state to restore, and its recorded
1295
+ * output is the value the case expected rather than a previous run's result.
1296
+ */
1297
+ type TraceIngestionType = "captured" | "seeded";
1291
1298
  /**
1292
1299
  * How the DB-snapshot branch each replay item runs against is sized and warmed.
1293
1300
  *
@@ -1418,6 +1425,15 @@ interface ReplayOptions {
1418
1425
  * Omit it to spread the recorded inputs unchanged.
1419
1426
  */
1420
1427
  adaptInputs?: (inputs: unknown[], ctx: AdaptContext) => unknown[];
1428
+ /**
1429
+ * Resolve every item's inputs and stop, without calling the function.
1430
+ *
1431
+ * Selection, span fetch, deserialization, and `adaptInputs` all run, so each
1432
+ * item reports the exact arguments the function would have received. Nothing
1433
+ * executes and no replay traces are produced, which is the cheap way to check
1434
+ * that recorded inputs still fit the current signature.
1435
+ */
1436
+ dryRun?: boolean;
1421
1437
  /**
1422
1438
  * Called once per item as it finishes, in completion order (not input
1423
1439
  * order), with running totals for the whole run. Use it to render replay
@@ -1620,8 +1636,17 @@ interface ReplayItem<T> {
1620
1636
  input: unknown[];
1621
1637
  /** The result returned by the function during replay, or undefined on error. */
1622
1638
  result: T | undefined;
1623
- /** The original output from the historical trace. */
1639
+ /**
1640
+ * The original output from the historical trace. For a `seeded` source this
1641
+ * is the value the case expected, not a previous run's result, so a
1642
+ * difference means the code missed the expectation rather than drifted.
1643
+ */
1624
1644
  originalOutput: unknown;
1645
+ /**
1646
+ * How the source trace came to exist. Absent on servers that predate the
1647
+ * field, which only ever served captured traces.
1648
+ */
1649
+ ingestionType?: TraceIngestionType;
1625
1650
  /**
1626
1651
  * Backward-compatible message for either error kind. Prefer `traceError` and
1627
1652
  * `replayError` when callers need the original exception and its source.
@@ -2209,6 +2234,12 @@ interface TraceOptions {
2209
2234
  name?: string;
2210
2235
  /** Root span type. Descendants are always `function` spans. */
2211
2236
  type?: SpanType;
2237
+ /**
2238
+ * Default replay-mocking policy for automatically captured descendants.
2239
+ * When true, those descendants are mocked by the default "marked" strategy
2240
+ * unless a node explicitly sets `mockOnReplay: false`. Defaults to false.
2241
+ */
2242
+ mockOnReplayDefault?: boolean;
2212
2243
  /** Maximum number of recorded descendant levels. Defaults to 30. */
2213
2244
  maxDepth?: number;
2214
2245
  /** Maximum descendant spans recorded per root invocation. Defaults to 500. */
@@ -2710,6 +2741,45 @@ declare class Bitfab {
2710
2741
  registerMockOverride(traceFunctionKey: string, override: MockOverride | MockOverrideResolver): void;
2711
2742
  /** Remove all overrides registered via {@link registerMockOverride}. */
2712
2743
  clearMockOverrides(): void;
2744
+ /**
2745
+ * Write a replayable trace from a case, without running anything.
2746
+ *
2747
+ * Use this to turn a corpus you already hold (a Braintrust dataset, a
2748
+ * spreadsheet, hand-written cases) into traces that {@link replay} can
2749
+ * select. The recorded root span carries `input` as its input and `expected`
2750
+ * as its output, so replay reports each item against the value you expected
2751
+ * rather than against a previous run.
2752
+ *
2753
+ * A seeded trace has no child spans and no database pin, so replay mocking
2754
+ * has nothing recorded to substitute and `dbBranch` refuses it. Pass
2755
+ * `mockOverride` at replay time for calls that must not run.
2756
+ *
2757
+ * @returns The trace ID, usable with `replay({ traceIds: [...] })`.
2758
+ */
2759
+ seedTrace(traceFunctionKey: string, options: {
2760
+ /** Arguments spread into the function at replay, as `fn(...input)`. */
2761
+ input: unknown[];
2762
+ /**
2763
+ * The output this case should produce. Optional, but without it the
2764
+ * replay has nothing to be judged against.
2765
+ */
2766
+ expected?: unknown;
2767
+ /**
2768
+ * The function these inputs will replay through. When given, the call is
2769
+ * checked against its arity here, so a case that cannot supply the
2770
+ * function's required arguments fails now instead of at replay. Omit it
2771
+ * when the seeding script cannot import the function.
2772
+ */
2773
+ fn?: (...args: any[]) => unknown;
2774
+ /**
2775
+ * Recorded on the trace. Put the source row's id here so a seeded trace
2776
+ * can be traced back to the case it came from.
2777
+ */
2778
+ metadata?: Record<string, unknown>;
2779
+ sessionId?: string;
2780
+ spanName?: string;
2781
+ spanType?: SpanType;
2782
+ }): string;
2713
2783
  replay<TReturn>(traceFunctionKey: string, fn: (...args: any[]) => TReturn | Promise<TReturn>, options?: ReplayOptions): Promise<ReplayResult<TReturn>>;
2714
2784
  }
2715
2785
  /**
@@ -2885,7 +2955,7 @@ declare class BitfabFunction {
2885
2955
  /**
2886
2956
  * SDK version from package.json (injected at build time)
2887
2957
  */
2888
- declare const __version__ = "0.38.9";
2958
+ declare const __version__ = "0.39.0";
2889
2959
 
2890
2960
  /**
2891
2961
  * Constants for the Bitfab SDK.
@@ -2987,5 +3057,30 @@ type ReplayRegistry = Record<string, ReplayRegistration>;
2987
3057
  * SDK upgrade can add replay features without regenerating the project file.
2988
3058
  */
2989
3059
  declare function defineReplayRegistry<TRegistry extends ReplayRegistry>(registry: TRegistry): TRegistry;
3060
+ /** One case to seed, in the shape `--seed` reads from JSON or JSONL. */
3061
+ interface SeedCase {
3062
+ /** Arguments spread into the registered function at replay. */
3063
+ input: unknown[];
3064
+ /** The output this case should produce. */
3065
+ expected?: unknown;
3066
+ /** Recorded on the trace, for tracing a seeded case back to its source row. */
3067
+ metadata?: Record<string, unknown>;
3068
+ sessionId?: string;
3069
+ }
3070
+ interface SeedResult {
3071
+ pipeline: string;
3072
+ traceFunctionKey: string;
3073
+ traceIds: string[];
3074
+ }
3075
+ /**
3076
+ * Seed cases through an already-registered pipeline.
3077
+ *
3078
+ * The registration is the whole point: it already holds the client, the exact
3079
+ * function production calls, and the trace function key replay selects by, so
3080
+ * a seeded case is guaranteed to line up with the replay that will read it.
3081
+ * Passing the registered function to `seedTrace` also means a case that cannot
3082
+ * supply its required arguments is rejected here rather than at replay.
3083
+ */
3084
+ declare function seedFromRegistry(registry: ReplayRegistry, pipeline: string, cases: readonly SeedCase[]): Promise<SeedResult>;
2990
3085
 
2991
- export { type ActiveSpanContext, type AdaptContext, type AdaptInputsFn, type AllowedEnvVars, BITFAB_PROGRESS_PREFIX, type BamlExecutionResult, Bitfab, BitfabClaudeAgentHandler, type BitfabConfig, BitfabError, BitfabFunction, BitfabLangGraphCallbackHandler as BitfabLangChainCallbackHandler, BitfabLangGraphCallbackHandler, BitfabLangGraphIntegration, type BitfabLanguageModelMiddleware, BitfabOpenAIAgentHandler, BitfabOpenAITracingProcessor, BitfabVercelAiHandler, type CaptureWhen, type CapturedSpan, type CodeChangeFile, type CurrentSpan, type CurrentTrace, DEFAULT_SERVICE_URL, type DbBranchOptions, DbBranchReplayError, type DbBranchTimings, type DbSnapshotConfig, type DbSnapshotProvider, type DbSnapshotRef, type DetachedTrace, HttpClient, type LangGraphIntegrationOptions, type MockOverride, type MockOverrideCtx, type MockOverrideInput, type MockOverrideResolver, type MockStrategy, type MockValue, NO_MOCK_OVERRIDE, type NodeMatcher, type NodeMethodDecorator, type NodeOptions, type ProviderDefinition, ReplayBranch, ReplayError, type ReplayItem, type ReplayItemFinishProgress, type ReplayItemStartProgress, type ReplayOptions, type ReplayOptionsFactory, type ReplayProgress, type ReplayProgressItem, type ReplayRegistration, type ReplayRegistry, type ReplayRegistryContext, type ReplayRegistryOptions, type ReplayResult, SUPPORTED_PROVIDERS, type SpanLookup, type SpanMethodDecorator, type SpanMethodDecoratorContext, type SpanNodeMeta, type SpanOccurrence, type SpanOptions, type SpanType, type TokenUsage, type TraceResponse, type TracingProcessor, type VercelCallParams, type VercelGenerateResult, type VercelStreamResult, type WrapBAMLOptions, type WrappedBamlFn, __version__, defineReplayRegistry, finalizers, flushTraces, getCurrentReplayBranch, getCurrentSpan, getCurrentTrace, reportReplayProgress, serializeReplayResult };
3086
+ export { type ActiveSpanContext, type AdaptContext, type AdaptInputsFn, type AllowedEnvVars, BITFAB_PROGRESS_PREFIX, type BamlExecutionResult, Bitfab, BitfabClaudeAgentHandler, type BitfabConfig, BitfabError, BitfabFunction, BitfabLangGraphCallbackHandler as BitfabLangChainCallbackHandler, BitfabLangGraphCallbackHandler, BitfabLangGraphIntegration, type BitfabLanguageModelMiddleware, BitfabOpenAIAgentHandler, BitfabOpenAITracingProcessor, BitfabVercelAiHandler, type CaptureWhen, type CapturedSpan, type CodeChangeFile, type CurrentSpan, type CurrentTrace, DEFAULT_SERVICE_URL, type DbBranchOptions, DbBranchReplayError, type DbBranchTimings, type DbSnapshotConfig, type DbSnapshotProvider, type DbSnapshotRef, type DetachedTrace, HttpClient, type LangGraphIntegrationOptions, type MockOverride, type MockOverrideCtx, type MockOverrideInput, type MockOverrideResolver, type MockStrategy, type MockValue, NO_MOCK_OVERRIDE, type NodeMatcher, type NodeMethodDecorator, type NodeOptions, type ProviderDefinition, ReplayBranch, ReplayError, type ReplayItem, type ReplayItemFinishProgress, type ReplayItemStartProgress, type ReplayOptions, type ReplayOptionsFactory, type ReplayProgress, type ReplayProgressItem, type ReplayRegistration, type ReplayRegistry, type ReplayRegistryContext, type ReplayRegistryOptions, type ReplayResult, SUPPORTED_PROVIDERS, type SeedCase, type SeedResult, type SpanLookup, type SpanMethodDecorator, type SpanMethodDecoratorContext, type SpanNodeMeta, type SpanOccurrence, type SpanOptions, type SpanType, type TokenUsage, type TraceIngestionType, type TraceResponse, type TracingProcessor, type VercelCallParams, type VercelGenerateResult, type VercelStreamResult, type WrapBAMLOptions, type WrappedBamlFn, __version__, defineReplayRegistry, finalizers, flushTraces, getCurrentReplayBranch, getCurrentSpan, getCurrentTrace, reportReplayProgress, seedFromRegistry, serializeReplayResult };
package/dist/index.js CHANGED
@@ -12,22 +12,25 @@ import {
12
12
  finalizers,
13
13
  getCurrentReplayBranch,
14
14
  getCurrentSpan,
15
- getCurrentTrace
16
- } from "./chunk-B4XXAK74.js";
15
+ getCurrentTrace,
16
+ seedFromRegistry
17
+ } from "./chunk-SHJ3ABUG.js";
17
18
  import "./chunk-ZUD7OFYB.js";
18
19
  import {
19
20
  BITFAB_PROGRESS_PREFIX,
20
- BitfabError,
21
- DEFAULT_SERVICE_URL,
22
21
  DbBranchReplayError,
23
- HttpClient,
24
22
  NO_MOCK_OVERRIDE,
25
23
  ReplayError,
26
- __version__,
27
- flushTraces,
28
24
  reportReplayProgress,
29
25
  serializeReplayResult
30
- } from "./chunk-2I5TFNGK.js";
26
+ } from "./chunk-FW7PZ3EP.js";
27
+ import {
28
+ BitfabError,
29
+ DEFAULT_SERVICE_URL,
30
+ HttpClient,
31
+ __version__,
32
+ flushTraces
33
+ } from "./chunk-2JQSYJJR.js";
31
34
  import "./chunk-H6LZRFMN.js";
32
35
  export {
33
36
  BITFAB_PROGRESS_PREFIX,
@@ -55,6 +58,7 @@ export {
55
58
  getCurrentSpan,
56
59
  getCurrentTrace,
57
60
  reportReplayProgress,
61
+ seedFromRegistry,
58
62
  serializeReplayResult
59
63
  };
60
64
  //# sourceMappingURL=index.js.map
package/dist/node.cjs CHANGED
@@ -88,7 +88,7 @@ var __version__, __packageName__;
88
88
  var init_version_generated = __esm({
89
89
  "src/version.generated.ts"() {
90
90
  "use strict";
91
- __version__ = "0.38.9";
91
+ __version__ = "0.39.0";
92
92
  __packageName__ = "@bitfab/sdk";
93
93
  }
94
94
  });
@@ -1205,6 +1205,16 @@ var init_transport = __esm({
1205
1205
  });
1206
1206
 
1207
1207
  // src/http.ts
1208
+ var http_exports = {};
1209
+ __export(http_exports, {
1210
+ BitfabError: () => BitfabError,
1211
+ HttpClient: () => HttpClient,
1212
+ awaitOnExit: () => awaitOnExit,
1213
+ awaitPendingRequests: () => awaitPendingRequests,
1214
+ flushTraces: () => flushTraces,
1215
+ parseRetryAfterMs: () => parseRetryAfterMs,
1216
+ serializePayloadBody: () => serializePayloadBody
1217
+ });
1208
1218
  function awaitOnExit(promise) {
1209
1219
  pendingTracePromises.add(promise);
1210
1220
  void promise.finally(() => {
@@ -2549,7 +2559,7 @@ function buildMockTree(rootNode) {
2549
2559
  }
2550
2560
  return { spans };
2551
2561
  }
2552
- async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy, resolvedOverrides, replayedTraceId, includeDbBranchLease, dbBranchSettings, adaptInputs) {
2562
+ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy, resolvedOverrides, replayedTraceId, includeDbBranchLease, dbBranchSettings, adaptInputs, dryRun) {
2553
2563
  let lease = includeDbBranchLease ? serverItem.dbBranchLease : void 0;
2554
2564
  let leaseError = includeDbBranchLease ? serverItem.dbBranchLeaseError : void 0;
2555
2565
  let dbSnapshotRef = serverItem.dbSnapshotRef;
@@ -2644,6 +2654,32 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
2644
2654
  }
2645
2655
  return pending;
2646
2656
  } : void 0;
2657
+ if (dryRun) {
2658
+ return {
2659
+ traceId: null,
2660
+ originalTraceId,
2661
+ originalSpanId,
2662
+ sourceTraceId: originalTraceId,
2663
+ sourceSpanId: originalSpanId,
2664
+ input: inputs,
2665
+ result: void 0,
2666
+ originalOutput,
2667
+ ...serverItem.ingestionType && {
2668
+ ingestionType: serverItem.ingestionType
2669
+ },
2670
+ error: null,
2671
+ traceError: null,
2672
+ replayError: null,
2673
+ durationMs: null,
2674
+ originalDurationMs: serverItem.originalDurationMs ?? serverItem.durationMs ?? null,
2675
+ originalTokens: serverItem.originalTokens ?? serverItem.tokens ?? null,
2676
+ originalModel: serverItem.originalModel ?? serverItem.model ?? null,
2677
+ tokens: null,
2678
+ model: serverItem.originalModel ?? serverItem.model ?? null,
2679
+ dbSnapshotRef: dbSnapshotRef ?? null,
2680
+ dbBranchTimings: dbBranchTimings ?? null
2681
+ };
2682
+ }
2647
2683
  try {
2648
2684
  replayStarted = performance.now();
2649
2685
  const maybePromise = runWithReplayContext(
@@ -2707,6 +2743,9 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
2707
2743
  input: inputs,
2708
2744
  result,
2709
2745
  originalOutput,
2746
+ ...serverItem.ingestionType && {
2747
+ ingestionType: serverItem.ingestionType
2748
+ },
2710
2749
  error,
2711
2750
  traceError,
2712
2751
  replayError,
@@ -2854,13 +2893,23 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
2854
2893
  options?.name,
2855
2894
  codeChangeDescription,
2856
2895
  codeChangeFiles,
2857
- dbBranchEnabled(options?.dbBranch),
2858
- // includeDbBranchLease
2896
+ // A dry run executes nothing, so a branch would be provisioned (and billed)
2897
+ // for code that never runs, and a seeded source's refusal would fail the item
2898
+ // before it could report its resolved inputs.
2899
+ dbBranchEnabled(options?.dbBranch) && options?.dryRun !== true,
2859
2900
  options?.experimentGroupId,
2860
2901
  options?.datasetId,
2861
2902
  options?.graderIds,
2862
2903
  resolveDbBranchSettings(options?.dbBranch)
2863
2904
  );
2905
+ if (serverItems.length === 0) {
2906
+ try {
2907
+ console.warn(
2908
+ `Bitfab: no traces matched "${traceFunctionKey}", so this replay ran nothing. Capture a trace, or seed one with seedTrace, before replaying.`
2909
+ );
2910
+ } catch {
2911
+ }
2912
+ }
2864
2913
  const mockStrategy = options?.mock ?? "marked";
2865
2914
  const maxConcurrency = options?.maxConcurrency ?? 10;
2866
2915
  const fullTestRunUrl = `${serviceUrl}${testRunUrl}`;
@@ -2879,9 +2928,10 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
2879
2928
  mockStrategy,
2880
2929
  resolvedOverrides,
2881
2930
  replayedTraceIds[index],
2882
- dbBranchEnabled(options?.dbBranch),
2931
+ dbBranchEnabled(options?.dbBranch) && options?.dryRun !== true,
2883
2932
  resolveDbBranchSettings(options?.dbBranch),
2884
- options?.adaptInputs
2933
+ options?.adaptInputs,
2934
+ options?.dryRun === true
2885
2935
  )
2886
2936
  );
2887
2937
  const total = tasks.length;
@@ -2989,6 +3039,16 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
2989
3039
  }
2990
3040
  } : void 0
2991
3041
  );
3042
+ if (options?.dryRun === true) {
3043
+ await httpClient.completeReplay(testRunId).catch(() => void 0);
3044
+ const dryResult = {
3045
+ items: resultItems,
3046
+ testRunId,
3047
+ testRunUrl: fullTestRunUrl
3048
+ };
3049
+ await writeReplayResultFile(dryResult);
3050
+ return dryResult;
3051
+ }
2992
3052
  const deliveredTraceIds = await preserveReplayFailure(
2993
3053
  () => waitForReplayPersistence(httpClient, testRunId, replayedTraceIds),
2994
3054
  resultItems,
@@ -3157,6 +3217,7 @@ __export(node_exports, {
3157
3217
  getCurrentSpan: () => getCurrentSpan,
3158
3218
  getCurrentTrace: () => getCurrentTrace,
3159
3219
  reportReplayProgress: () => reportReplayProgress,
3220
+ seedFromRegistry: () => seedFromRegistry,
3160
3221
  serializeReplayResult: () => serializeReplayResult
3161
3222
  });
3162
3223
  module.exports = __toCommonJS(node_exports);
@@ -6176,6 +6237,7 @@ var Bitfab = class {
6176
6237
  return invokeWithoutNode();
6177
6238
  }
6178
6239
  spansUsed += 1;
6240
+ const mockOnReplay = nodeConfiguration?.mockOnReplay ?? options.mockOnReplayDefault;
6179
6241
  const childOptions = {
6180
6242
  name: nodeConfiguration?.name ?? definition.name,
6181
6243
  type: nodeConfiguration?.type ?? "function",
@@ -6186,8 +6248,8 @@ var Bitfab = class {
6186
6248
  ...nodeConfiguration?.testRunId !== void 0 && {
6187
6249
  testRunId: nodeConfiguration.testRunId
6188
6250
  },
6189
- ...nodeConfiguration?.mockOnReplay !== void 0 && {
6190
- mockOnReplay: nodeConfiguration.mockOnReplay
6251
+ ...mockOnReplay !== void 0 && {
6252
+ mockOnReplay
6191
6253
  },
6192
6254
  ...nodeConfiguration?.finalize !== void 0 && {
6193
6255
  finalize: nodeConfiguration.finalize
@@ -6873,6 +6935,7 @@ var Bitfab = class {
6873
6935
  inputSourceTraceId: traceState?.inputSourceTraceId,
6874
6936
  dbSnapshotRef: traceState?.dbSnapshotRef,
6875
6937
  dropped: traceState?.dropped,
6938
+ ingestionType: traceState?.ingestionType,
6876
6939
  // Built AFTER the wrapped fn finished, so `accessed` reflects
6877
6940
  // whether customer code obtained the branch URL during this
6878
6941
  // item. Omitted entirely when no lease was attached, so the
@@ -7096,6 +7159,7 @@ var Bitfab = class {
7096
7159
  Object.defineProperty(wrappedFn, "_bitfabTraceFunctionKey", {
7097
7160
  value: traceFunctionKey
7098
7161
  });
7162
+ Object.defineProperty(wrappedFn, "_bitfabWrappedFn", { value: fn });
7099
7163
  return wrappedFn;
7100
7164
  }
7101
7165
  /**
@@ -7258,6 +7322,9 @@ var Bitfab = class {
7258
7322
  if (params.dbSnapshotRef) {
7259
7323
  rawTrace.db_snapshot_ref = params.dbSnapshotRef;
7260
7324
  }
7325
+ if (params.ingestionType) {
7326
+ rawTrace.ingestion_type = params.ingestionType;
7327
+ }
7261
7328
  if (params.dbSnapshotUsage) {
7262
7329
  rawTrace.db_snapshot_usage = {
7263
7330
  neon_branch_id: params.dbSnapshotUsage.neonBranchId,
@@ -7404,6 +7471,68 @@ var Bitfab = class {
7404
7471
  clearMockOverrides() {
7405
7472
  this.mockOverrides.length = 0;
7406
7473
  }
7474
+ /**
7475
+ * Write a replayable trace from a case, without running anything.
7476
+ *
7477
+ * Use this to turn a corpus you already hold (a Braintrust dataset, a
7478
+ * spreadsheet, hand-written cases) into traces that {@link replay} can
7479
+ * select. The recorded root span carries `input` as its input and `expected`
7480
+ * as its output, so replay reports each item against the value you expected
7481
+ * rather than against a previous run.
7482
+ *
7483
+ * A seeded trace has no child spans and no database pin, so replay mocking
7484
+ * has nothing recorded to substitute and `dbBranch` refuses it. Pass
7485
+ * `mockOverride` at replay time for calls that must not run.
7486
+ *
7487
+ * @returns The trace ID, usable with `replay({ traceIds: [...] })`.
7488
+ */
7489
+ seedTrace(traceFunctionKey, options) {
7490
+ const { input } = options;
7491
+ const fn = options.fn?._bitfabWrappedFn ?? options.fn;
7492
+ if (fn && input.length < fn.length) {
7493
+ throw new BitfabError(
7494
+ `Seeded case supplies ${input.length} argument(s) but ${fn.name === "" ? "the function" : fn.name} requires ${fn.length}. Fix the case, or omit fn to seed it anyway.`
7495
+ );
7496
+ }
7497
+ const traceId = randomUuid();
7498
+ const startedAt = nowIsoTimestamp();
7499
+ activeTraceStates.set(traceId, {
7500
+ traceId,
7501
+ startedAt,
7502
+ contexts: [],
7503
+ ingestionType: "seeded",
7504
+ ...options.sessionId !== void 0 && { sessionId: options.sessionId },
7505
+ ...options.metadata !== void 0 && { metadata: options.metadata }
7506
+ });
7507
+ try {
7508
+ this.sendWrapperSpan({
7509
+ traceFunctionKey,
7510
+ spanName: options.spanName ?? traceFunctionKey,
7511
+ traceId,
7512
+ spanId: randomUuid(),
7513
+ parentSpanId: null,
7514
+ inputs: input,
7515
+ result: options.expected,
7516
+ startedAt,
7517
+ endedAt: startedAt,
7518
+ spanType: options.spanType ?? "agent",
7519
+ captureContent: true
7520
+ });
7521
+ this.sendTraceCompletion({
7522
+ traceFunctionKey,
7523
+ traceId,
7524
+ startedAt,
7525
+ endedAt: startedAt,
7526
+ sessionId: options.sessionId,
7527
+ metadata: options.metadata,
7528
+ contexts: [],
7529
+ ingestionType: "seeded"
7530
+ });
7531
+ } finally {
7532
+ activeTraceStates.delete(traceId);
7533
+ }
7534
+ return traceId;
7535
+ }
7407
7536
  async replay(traceFunctionKey, fn, options) {
7408
7537
  const wrappedKey = fn._bitfabTraceFunctionKey;
7409
7538
  let replayFn = fn;
@@ -7664,6 +7793,37 @@ init_replay();
7664
7793
  function defineReplayRegistry(registry) {
7665
7794
  return registry;
7666
7795
  }
7796
+ async function seedFromRegistry(registry, pipeline, cases) {
7797
+ const registration = registry[pipeline];
7798
+ if (registration === void 0) {
7799
+ throw new BitfabError(
7800
+ `Unknown pipeline '${pipeline}'. Registered: ${Object.keys(registry).join(", ")}`
7801
+ );
7802
+ }
7803
+ const traceFunctionKey = resolveTraceFunctionKey(registration);
7804
+ const traceIds = cases.map(
7805
+ (seedCase) => registration.client.seedTrace(traceFunctionKey, {
7806
+ input: seedCase.input,
7807
+ expected: seedCase.expected,
7808
+ fn: registration.fn,
7809
+ metadata: seedCase.metadata,
7810
+ sessionId: seedCase.sessionId
7811
+ })
7812
+ );
7813
+ const { flushTraces: flushTraces2 } = await Promise.resolve().then(() => (init_http(), http_exports));
7814
+ await flushTraces2(3e4);
7815
+ return { pipeline, traceFunctionKey, traceIds };
7816
+ }
7817
+ function resolveTraceFunctionKey(registration) {
7818
+ const wrappedKey = registration.fn._bitfabTraceFunctionKey;
7819
+ const key = registration.traceFunctionKey ?? wrappedKey;
7820
+ if (key === void 0) {
7821
+ throw new BitfabError(
7822
+ "Replay registry entry uses a plain function. Set traceFunctionKey to the key its production handler records."
7823
+ );
7824
+ }
7825
+ return key;
7826
+ }
7667
7827
 
7668
7828
  // src/node.ts
7669
7829
  init_asyncStorage();
@@ -7695,6 +7855,7 @@ assertAsyncStorageRegistered();
7695
7855
  getCurrentSpan,
7696
7856
  getCurrentTrace,
7697
7857
  reportReplayProgress,
7858
+ seedFromRegistry,
7698
7859
  serializeReplayResult
7699
7860
  });
7700
7861
  //# sourceMappingURL=node.cjs.map