bitfab 0.24.0 → 0.25.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
@@ -651,6 +651,30 @@ interface ReplayOptions {
651
651
  * Omit it to spread the recorded inputs unchanged.
652
652
  */
653
653
  adaptInputs?: (inputs: unknown[], ctx: AdaptContext) => unknown[];
654
+ /**
655
+ * Called once per item as it finishes, in completion order (not input
656
+ * order), with running totals for the whole run. Use it to render replay
657
+ * progress, for example a terminal progress bar. Replay does not know
658
+ * pass/fail at this point (verdicts are assigned later), so the totals only
659
+ * distinguish items whose function ran (`succeeded`) from items that threw
660
+ * (`errored`).
661
+ *
662
+ * Invoked synchronously right after each item settles, so keep it cheap. A
663
+ * throwing callback never crashes the run: the error is swallowed so progress
664
+ * UI can't break replay.
665
+ */
666
+ onProgress?: (progress: ReplayProgress) => void;
667
+ }
668
+ /** Running totals reported to {@link ReplayOptions.onProgress} as replay proceeds. */
669
+ interface ReplayProgress {
670
+ /** Items that have finished so far, whether they succeeded or errored. */
671
+ completed: number;
672
+ /** Total number of items in this replay run. */
673
+ total: number;
674
+ /** Of the completed items, how many ran the function without throwing. */
675
+ succeeded: number;
676
+ /** Of the completed items, how many threw (their `item.error` is set). */
677
+ errored: number;
654
678
  }
655
679
  /** Per-trace context passed to {@link ReplayOptions.adaptInputs}. */
656
680
  interface AdaptContext {
@@ -684,7 +708,13 @@ interface ReplayItem<T> {
684
708
  error: string | null;
685
709
  /** Original trace duration in milliseconds, or null if timestamps are missing. */
686
710
  durationMs: number | null;
687
- /** Token usage from the original trace, or null if not captured. */
711
+ /**
712
+ * Token usage from the REPLAYED run (this item's new execution), aggregated
713
+ * server-side from the spans it produced, or null if the run captured no
714
+ * token data. This is the "new" side of a token delta: compare it against
715
+ * the original trace's recorded usage to see how the code change moved cost.
716
+ * Matches what Studio's experiments view shows.
717
+ */
688
718
  tokens: TokenUsage | null;
689
719
  /** Model name from the original trace, or null if not captured. */
690
720
  model: string | null;
@@ -1374,7 +1404,7 @@ declare class BitfabFunction {
1374
1404
  /**
1375
1405
  * SDK version from package.json (injected at build time)
1376
1406
  */
1377
- declare const __version__ = "0.24.0";
1407
+ declare const __version__ = "0.25.0";
1378
1408
 
1379
1409
  /**
1380
1410
  * Constants for the Bitfab SDK.
@@ -1442,4 +1472,4 @@ declare const finalizers: {
1442
1472
  readableStream: typeof readableStream;
1443
1473
  };
1444
1474
 
1445
- export { type ActiveSpanContext, type AdaptContext, type AdaptInputsFn, type AllowedEnvVars, type BamlExecutionResult, Bitfab, BitfabClaudeAgentHandler, type BitfabConfig, BitfabError, BitfabFunction, BitfabLangGraphCallbackHandler as BitfabLangChainCallbackHandler, BitfabLangGraphCallbackHandler, type BitfabLanguageModelMiddleware, BitfabOpenAIAgentHandler, BitfabOpenAITracingProcessor, BitfabVercelAiHandler, type CodeChangeFile, type CurrentSpan, type CurrentTrace, DEFAULT_SERVICE_URL, type DbSnapshotConfig, type DbSnapshotProvider, type DbSnapshotRef, type DetachedTrace, type MockStrategy, type ProviderDefinition, ReplayEnvironment, type ReplayEnvironmentSnapshot, type ReplayItem, type ReplayOptions, type ReplayResult, SUPPORTED_PROVIDERS, type SpanOptions, type SpanType, type TokenUsage, type TraceResponse, type TracingProcessor, type VercelCallParams, type VercelGenerateResult, type VercelStreamResult, type WrapBAMLOptions, type WrappedBamlFn, __version__, finalizers, flushTraces, getCurrentSpan, getCurrentTrace };
1475
+ export { type ActiveSpanContext, type AdaptContext, type AdaptInputsFn, type AllowedEnvVars, type BamlExecutionResult, Bitfab, BitfabClaudeAgentHandler, type BitfabConfig, BitfabError, BitfabFunction, BitfabLangGraphCallbackHandler as BitfabLangChainCallbackHandler, BitfabLangGraphCallbackHandler, type BitfabLanguageModelMiddleware, BitfabOpenAIAgentHandler, BitfabOpenAITracingProcessor, BitfabVercelAiHandler, type CodeChangeFile, type CurrentSpan, type CurrentTrace, DEFAULT_SERVICE_URL, type DbSnapshotConfig, type DbSnapshotProvider, type DbSnapshotRef, type DetachedTrace, type MockStrategy, type ProviderDefinition, ReplayEnvironment, type ReplayEnvironmentSnapshot, type ReplayItem, type ReplayOptions, type ReplayProgress, type ReplayResult, SUPPORTED_PROVIDERS, type SpanOptions, type SpanType, type TokenUsage, type TraceResponse, type TracingProcessor, type VercelCallParams, type VercelGenerateResult, type VercelStreamResult, type WrapBAMLOptions, type WrappedBamlFn, __version__, finalizers, flushTraces, getCurrentSpan, getCurrentTrace };
package/dist/index.d.ts CHANGED
@@ -651,6 +651,30 @@ interface ReplayOptions {
651
651
  * Omit it to spread the recorded inputs unchanged.
652
652
  */
653
653
  adaptInputs?: (inputs: unknown[], ctx: AdaptContext) => unknown[];
654
+ /**
655
+ * Called once per item as it finishes, in completion order (not input
656
+ * order), with running totals for the whole run. Use it to render replay
657
+ * progress, for example a terminal progress bar. Replay does not know
658
+ * pass/fail at this point (verdicts are assigned later), so the totals only
659
+ * distinguish items whose function ran (`succeeded`) from items that threw
660
+ * (`errored`).
661
+ *
662
+ * Invoked synchronously right after each item settles, so keep it cheap. A
663
+ * throwing callback never crashes the run: the error is swallowed so progress
664
+ * UI can't break replay.
665
+ */
666
+ onProgress?: (progress: ReplayProgress) => void;
667
+ }
668
+ /** Running totals reported to {@link ReplayOptions.onProgress} as replay proceeds. */
669
+ interface ReplayProgress {
670
+ /** Items that have finished so far, whether they succeeded or errored. */
671
+ completed: number;
672
+ /** Total number of items in this replay run. */
673
+ total: number;
674
+ /** Of the completed items, how many ran the function without throwing. */
675
+ succeeded: number;
676
+ /** Of the completed items, how many threw (their `item.error` is set). */
677
+ errored: number;
654
678
  }
655
679
  /** Per-trace context passed to {@link ReplayOptions.adaptInputs}. */
656
680
  interface AdaptContext {
@@ -684,7 +708,13 @@ interface ReplayItem<T> {
684
708
  error: string | null;
685
709
  /** Original trace duration in milliseconds, or null if timestamps are missing. */
686
710
  durationMs: number | null;
687
- /** Token usage from the original trace, or null if not captured. */
711
+ /**
712
+ * Token usage from the REPLAYED run (this item's new execution), aggregated
713
+ * server-side from the spans it produced, or null if the run captured no
714
+ * token data. This is the "new" side of a token delta: compare it against
715
+ * the original trace's recorded usage to see how the code change moved cost.
716
+ * Matches what Studio's experiments view shows.
717
+ */
688
718
  tokens: TokenUsage | null;
689
719
  /** Model name from the original trace, or null if not captured. */
690
720
  model: string | null;
@@ -1374,7 +1404,7 @@ declare class BitfabFunction {
1374
1404
  /**
1375
1405
  * SDK version from package.json (injected at build time)
1376
1406
  */
1377
- declare const __version__ = "0.24.0";
1407
+ declare const __version__ = "0.25.0";
1378
1408
 
1379
1409
  /**
1380
1410
  * Constants for the Bitfab SDK.
@@ -1442,4 +1472,4 @@ declare const finalizers: {
1442
1472
  readableStream: typeof readableStream;
1443
1473
  };
1444
1474
 
1445
- export { type ActiveSpanContext, type AdaptContext, type AdaptInputsFn, type AllowedEnvVars, type BamlExecutionResult, Bitfab, BitfabClaudeAgentHandler, type BitfabConfig, BitfabError, BitfabFunction, BitfabLangGraphCallbackHandler as BitfabLangChainCallbackHandler, BitfabLangGraphCallbackHandler, type BitfabLanguageModelMiddleware, BitfabOpenAIAgentHandler, BitfabOpenAITracingProcessor, BitfabVercelAiHandler, type CodeChangeFile, type CurrentSpan, type CurrentTrace, DEFAULT_SERVICE_URL, type DbSnapshotConfig, type DbSnapshotProvider, type DbSnapshotRef, type DetachedTrace, type MockStrategy, type ProviderDefinition, ReplayEnvironment, type ReplayEnvironmentSnapshot, type ReplayItem, type ReplayOptions, type ReplayResult, SUPPORTED_PROVIDERS, type SpanOptions, type SpanType, type TokenUsage, type TraceResponse, type TracingProcessor, type VercelCallParams, type VercelGenerateResult, type VercelStreamResult, type WrapBAMLOptions, type WrappedBamlFn, __version__, finalizers, flushTraces, getCurrentSpan, getCurrentTrace };
1475
+ export { type ActiveSpanContext, type AdaptContext, type AdaptInputsFn, type AllowedEnvVars, type BamlExecutionResult, Bitfab, BitfabClaudeAgentHandler, type BitfabConfig, BitfabError, BitfabFunction, BitfabLangGraphCallbackHandler as BitfabLangChainCallbackHandler, BitfabLangGraphCallbackHandler, type BitfabLanguageModelMiddleware, BitfabOpenAIAgentHandler, BitfabOpenAITracingProcessor, BitfabVercelAiHandler, type CodeChangeFile, type CurrentSpan, type CurrentTrace, DEFAULT_SERVICE_URL, type DbSnapshotConfig, type DbSnapshotProvider, type DbSnapshotRef, type DetachedTrace, type MockStrategy, type ProviderDefinition, ReplayEnvironment, type ReplayEnvironmentSnapshot, type ReplayItem, type ReplayOptions, type ReplayProgress, type ReplayResult, SUPPORTED_PROVIDERS, type SpanOptions, type SpanType, type TokenUsage, type TraceResponse, type TracingProcessor, type VercelCallParams, type VercelGenerateResult, type VercelStreamResult, type WrapBAMLOptions, type WrappedBamlFn, __version__, finalizers, flushTraces, getCurrentSpan, getCurrentTrace };
package/dist/index.js CHANGED
@@ -23,7 +23,7 @@ import {
23
23
  flushTraces,
24
24
  getCurrentSpan,
25
25
  getCurrentTrace
26
- } from "./chunk-S3PN26RH.js";
26
+ } from "./chunk-GQLNEYSU.js";
27
27
  import {
28
28
  BitfabError
29
29
  } from "./chunk-26MUT4IP.js";
package/dist/node.cjs CHANGED
@@ -421,18 +421,23 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
421
421
  originalOutput,
422
422
  error,
423
423
  durationMs: serverItem.durationMs ?? null,
424
- tokens: serverItem.tokens ?? null,
424
+ // Filled in by replay() from the complete-replay response once the
425
+ // replay traces are persisted and their spans aggregated server-side.
426
+ // Null here (and on older servers) means "replay tokens not known".
427
+ tokens: null,
425
428
  model: serverItem.model ?? null,
426
429
  dbSnapshotRef: serverItem.dbSnapshotRef ?? null
427
430
  };
428
431
  }
429
- async function mapWithConcurrency(tasks, maxConcurrency) {
432
+ async function mapWithConcurrency(tasks, maxConcurrency, onSettled) {
430
433
  const results = new Array(tasks.length);
431
434
  let nextIndex = 0;
432
435
  async function worker() {
433
436
  while (nextIndex < tasks.length) {
434
437
  const index = nextIndex++;
435
- results[index] = await tasks[index]();
438
+ const result = await tasks[index]();
439
+ results[index] = result;
440
+ onSettled?.(result, index);
436
441
  }
437
442
  }
438
443
  const workers = Array.from(
@@ -492,9 +497,29 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options) {
492
497
  options?.adaptInputs
493
498
  )
494
499
  );
495
- const resultItems = await mapWithConcurrency(tasks, maxConcurrency);
500
+ const total = tasks.length;
501
+ let completed = 0;
502
+ let succeeded = 0;
503
+ let errored = 0;
504
+ const resultItems = await mapWithConcurrency(
505
+ tasks,
506
+ maxConcurrency,
507
+ options?.onProgress ? (item) => {
508
+ completed += 1;
509
+ if (item.error === null) {
510
+ succeeded += 1;
511
+ } else {
512
+ errored += 1;
513
+ }
514
+ try {
515
+ options?.onProgress?.({ completed, total, succeeded, errored });
516
+ } catch {
517
+ }
518
+ } : void 0
519
+ );
496
520
  const completeResult = await httpClient.completeReplay(testRunId);
497
521
  const serverTraceIds = completeResult.traceIds;
522
+ const replayTokens = completeResult.tokens;
498
523
  if (serverTraceIds === void 0) {
499
524
  try {
500
525
  console.warn(
@@ -517,6 +542,9 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options) {
517
542
  missing.push(item.traceId);
518
543
  }
519
544
  }
545
+ if (mapped !== void 0) {
546
+ item.tokens = replayTokens?.[mapped] ?? null;
547
+ }
520
548
  item.traceId = mapped ?? null;
521
549
  }
522
550
  }
@@ -582,7 +610,7 @@ registerAsyncLocalStorageClass(
582
610
  );
583
611
 
584
612
  // src/version.generated.ts
585
- var __version__ = "0.24.0";
613
+ var __version__ = "0.25.0";
586
614
 
587
615
  // src/constants.ts
588
616
  var DEFAULT_SERVICE_URL = "https://bitfab.ai";