@bitfab/sdk 0.40.0 → 0.42.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
@@ -306,6 +306,7 @@ interface ReplayContext {
306
306
  * customer sees in the Bitfab dashboard.
307
307
  */
308
308
  sourceBitfabTraceId?: string;
309
+ replayAttempt?: number;
309
310
  mockTree?: MockTree;
310
311
  callCounters?: Map<string, number>;
311
312
  mockStrategy?: "none" | "all" | "marked";
@@ -578,12 +579,13 @@ declare class HttpClient {
578
579
  appendContexts?: Record<string, unknown>[];
579
580
  mergeMetadata?: Record<string, unknown>;
580
581
  setSessionId?: string;
582
+ setName?: string;
581
583
  }): Promise<void>;
582
584
  /**
583
585
  * Start a replay session by fetching historical traces.
584
586
  * Blocking call - creates a test run and returns lightweight item references.
585
587
  */
586
- startReplay(traceFunctionKey: string, limit: number | undefined, traceIds?: string[], name?: string, codeChangeDescription?: string | null, codeChangeFiles?: CodeChangeFile[] | null, includeDbBranchLease?: boolean, experimentGroupId?: string, datasetId?: string, graderIds?: string[], dbBranchSettings?: DbBranchSettings): Promise<StartReplayResponse>;
588
+ startReplay(traceFunctionKey: string, limit: number | undefined, traceIds?: string[], name?: string, codeChangeDescription?: string | null, codeChangeFiles?: CodeChangeFile[] | null, includeDbBranchLease?: boolean, experimentGroupId?: string, datasetId?: string, graderIds?: string[], dbBranchSettings?: DbBranchSettings, attempts?: number): Promise<StartReplayResponse>;
587
589
  /**
588
590
  * Fetch an external span by ID.
589
591
  * Blocking GET request.
@@ -624,7 +626,7 @@ declare class HttpClient {
624
626
  * snapshot + preview branch and polls operations to readiness, which
625
627
  * can take seconds.
626
628
  */
627
- resolveDbBranchLease(testRunId: string, traceId: string, dbBranchSettings?: DbBranchSettings): Promise<{
629
+ resolveDbBranchLease(testRunId: string, traceId: string, dbBranchSettings?: DbBranchSettings, attempt?: number): Promise<{
628
630
  dbSnapshotRef: DbSnapshotRef | null;
629
631
  lease: DbBranchLease | null;
630
632
  leaseError: {
@@ -657,6 +659,7 @@ interface CodeChangeFile {
657
659
  interface StartReplayResponse {
658
660
  testRunId: string;
659
661
  testRunUrl: string;
662
+ attempts?: number;
660
663
  items: Array<{
661
664
  /** Bitfab trace ID of the original (historical) trace being replayed. */
662
665
  originalTraceId?: string;
@@ -1471,6 +1474,7 @@ interface ReplayOptions {
1471
1474
  * because either source already determines how many traces replay.
1472
1475
  */
1473
1476
  limit?: number;
1477
+ attempts?: number;
1474
1478
  /** Optional list of specific trace IDs to replay (max 100). Mutually exclusive with `datasetId`. */
1475
1479
  traceIds?: string[];
1476
1480
  /** Optional display name for the resulting experiment/test run. */
@@ -1623,6 +1627,7 @@ interface ReplayItemStartProgress {
1623
1627
  sourceTraceId: string;
1624
1628
  /** @deprecated alias for `originalSpanId`. */
1625
1629
  sourceSpanId: string;
1630
+ attempt: number;
1626
1631
  };
1627
1632
  }
1628
1633
  /** Running totals reported to {@link ReplayOptions.onItemFinish} as replay proceeds. */
@@ -1662,6 +1667,7 @@ interface ReplayProgressItem {
1662
1667
  sourceTraceId: string | null;
1663
1668
  /** @deprecated alias for `originalSpanId`. */
1664
1669
  sourceSpanId?: string | null;
1670
+ attempt: number;
1665
1671
  /** Deserialized inputs from the original trace. */
1666
1672
  input?: unknown[];
1667
1673
  /** The result returned by the replayed function, or undefined on error. */
@@ -1771,6 +1777,7 @@ interface ReplayItem<T> {
1771
1777
  sourceTraceId: string;
1772
1778
  /** @deprecated alias for {@link ReplayItem.originalSpanId}. */
1773
1779
  sourceSpanId: string;
1780
+ attempt: number;
1774
1781
  /** Deserialized inputs from the original trace. */
1775
1782
  input: unknown[];
1776
1783
  /** The result returned by the function during replay, or undefined on error. */
@@ -1849,6 +1856,7 @@ interface ReplayResult<T> {
1849
1856
  testRunId: string;
1850
1857
  /** Full URL to view the test run in the dashboard. */
1851
1858
  testRunUrl: string;
1859
+ attempts: number;
1852
1860
  }
1853
1861
  /**
1854
1862
  * Whole-run replay failure that preserves every item collected before the run
@@ -2160,6 +2168,7 @@ interface DetachedTrace {
2160
2168
  * Rejects if the server refused the update.
2161
2169
  */
2162
2170
  setSessionId(sessionId: string): Promise<void>;
2171
+ setName(name: string): Promise<void>;
2163
2172
  }
2164
2173
  /**
2165
2174
  * A handle to the current active trace, allowing trace-level context to be set.
@@ -2169,6 +2178,7 @@ interface CurrentTrace {
2169
2178
  * Set the session ID for this trace. Stored in the database session_id column.
2170
2179
  */
2171
2180
  setSessionId(sessionId: string): void;
2181
+ setName(name: string): void;
2172
2182
  /**
2173
2183
  * Set metadata for this trace. Stored in rawData.metadata.
2174
2184
  * Subsequent calls merge with existing metadata, with later values taking precedence.
@@ -2918,6 +2928,7 @@ declare class Bitfab {
2918
2928
  */
2919
2929
  metadata?: Record<string, unknown>;
2920
2930
  sessionId?: string;
2931
+ name?: string;
2921
2932
  spanName?: string;
2922
2933
  spanType?: SpanType;
2923
2934
  }): string;
@@ -3096,7 +3107,7 @@ declare class BitfabFunction {
3096
3107
  /**
3097
3108
  * SDK version from package.json (injected at build time)
3098
3109
  */
3099
- declare const __version__ = "0.40.0";
3110
+ declare const __version__ = "0.42.0";
3100
3111
 
3101
3112
  /**
3102
3113
  * Constants for the Bitfab SDK.
package/dist/index.d.ts CHANGED
@@ -306,6 +306,7 @@ interface ReplayContext {
306
306
  * customer sees in the Bitfab dashboard.
307
307
  */
308
308
  sourceBitfabTraceId?: string;
309
+ replayAttempt?: number;
309
310
  mockTree?: MockTree;
310
311
  callCounters?: Map<string, number>;
311
312
  mockStrategy?: "none" | "all" | "marked";
@@ -578,12 +579,13 @@ declare class HttpClient {
578
579
  appendContexts?: Record<string, unknown>[];
579
580
  mergeMetadata?: Record<string, unknown>;
580
581
  setSessionId?: string;
582
+ setName?: string;
581
583
  }): Promise<void>;
582
584
  /**
583
585
  * Start a replay session by fetching historical traces.
584
586
  * Blocking call - creates a test run and returns lightweight item references.
585
587
  */
586
- startReplay(traceFunctionKey: string, limit: number | undefined, traceIds?: string[], name?: string, codeChangeDescription?: string | null, codeChangeFiles?: CodeChangeFile[] | null, includeDbBranchLease?: boolean, experimentGroupId?: string, datasetId?: string, graderIds?: string[], dbBranchSettings?: DbBranchSettings): Promise<StartReplayResponse>;
588
+ startReplay(traceFunctionKey: string, limit: number | undefined, traceIds?: string[], name?: string, codeChangeDescription?: string | null, codeChangeFiles?: CodeChangeFile[] | null, includeDbBranchLease?: boolean, experimentGroupId?: string, datasetId?: string, graderIds?: string[], dbBranchSettings?: DbBranchSettings, attempts?: number): Promise<StartReplayResponse>;
587
589
  /**
588
590
  * Fetch an external span by ID.
589
591
  * Blocking GET request.
@@ -624,7 +626,7 @@ declare class HttpClient {
624
626
  * snapshot + preview branch and polls operations to readiness, which
625
627
  * can take seconds.
626
628
  */
627
- resolveDbBranchLease(testRunId: string, traceId: string, dbBranchSettings?: DbBranchSettings): Promise<{
629
+ resolveDbBranchLease(testRunId: string, traceId: string, dbBranchSettings?: DbBranchSettings, attempt?: number): Promise<{
628
630
  dbSnapshotRef: DbSnapshotRef | null;
629
631
  lease: DbBranchLease | null;
630
632
  leaseError: {
@@ -657,6 +659,7 @@ interface CodeChangeFile {
657
659
  interface StartReplayResponse {
658
660
  testRunId: string;
659
661
  testRunUrl: string;
662
+ attempts?: number;
660
663
  items: Array<{
661
664
  /** Bitfab trace ID of the original (historical) trace being replayed. */
662
665
  originalTraceId?: string;
@@ -1471,6 +1474,7 @@ interface ReplayOptions {
1471
1474
  * because either source already determines how many traces replay.
1472
1475
  */
1473
1476
  limit?: number;
1477
+ attempts?: number;
1474
1478
  /** Optional list of specific trace IDs to replay (max 100). Mutually exclusive with `datasetId`. */
1475
1479
  traceIds?: string[];
1476
1480
  /** Optional display name for the resulting experiment/test run. */
@@ -1623,6 +1627,7 @@ interface ReplayItemStartProgress {
1623
1627
  sourceTraceId: string;
1624
1628
  /** @deprecated alias for `originalSpanId`. */
1625
1629
  sourceSpanId: string;
1630
+ attempt: number;
1626
1631
  };
1627
1632
  }
1628
1633
  /** Running totals reported to {@link ReplayOptions.onItemFinish} as replay proceeds. */
@@ -1662,6 +1667,7 @@ interface ReplayProgressItem {
1662
1667
  sourceTraceId: string | null;
1663
1668
  /** @deprecated alias for `originalSpanId`. */
1664
1669
  sourceSpanId?: string | null;
1670
+ attempt: number;
1665
1671
  /** Deserialized inputs from the original trace. */
1666
1672
  input?: unknown[];
1667
1673
  /** The result returned by the replayed function, or undefined on error. */
@@ -1771,6 +1777,7 @@ interface ReplayItem<T> {
1771
1777
  sourceTraceId: string;
1772
1778
  /** @deprecated alias for {@link ReplayItem.originalSpanId}. */
1773
1779
  sourceSpanId: string;
1780
+ attempt: number;
1774
1781
  /** Deserialized inputs from the original trace. */
1775
1782
  input: unknown[];
1776
1783
  /** The result returned by the function during replay, or undefined on error. */
@@ -1849,6 +1856,7 @@ interface ReplayResult<T> {
1849
1856
  testRunId: string;
1850
1857
  /** Full URL to view the test run in the dashboard. */
1851
1858
  testRunUrl: string;
1859
+ attempts: number;
1852
1860
  }
1853
1861
  /**
1854
1862
  * Whole-run replay failure that preserves every item collected before the run
@@ -2160,6 +2168,7 @@ interface DetachedTrace {
2160
2168
  * Rejects if the server refused the update.
2161
2169
  */
2162
2170
  setSessionId(sessionId: string): Promise<void>;
2171
+ setName(name: string): Promise<void>;
2163
2172
  }
2164
2173
  /**
2165
2174
  * A handle to the current active trace, allowing trace-level context to be set.
@@ -2169,6 +2178,7 @@ interface CurrentTrace {
2169
2178
  * Set the session ID for this trace. Stored in the database session_id column.
2170
2179
  */
2171
2180
  setSessionId(sessionId: string): void;
2181
+ setName(name: string): void;
2172
2182
  /**
2173
2183
  * Set metadata for this trace. Stored in rawData.metadata.
2174
2184
  * Subsequent calls merge with existing metadata, with later values taking precedence.
@@ -2918,6 +2928,7 @@ declare class Bitfab {
2918
2928
  */
2919
2929
  metadata?: Record<string, unknown>;
2920
2930
  sessionId?: string;
2931
+ name?: string;
2921
2932
  spanName?: string;
2922
2933
  spanType?: SpanType;
2923
2934
  }): string;
@@ -3096,7 +3107,7 @@ declare class BitfabFunction {
3096
3107
  /**
3097
3108
  * SDK version from package.json (injected at build time)
3098
3109
  */
3099
- declare const __version__ = "0.40.0";
3110
+ declare const __version__ = "0.42.0";
3100
3111
 
3101
3112
  /**
3102
3113
  * Constants for the Bitfab SDK.
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ import {
15
15
  getCurrentSpan,
16
16
  getCurrentTrace,
17
17
  seedFromRegistry
18
- } from "./chunk-5NT4YDCQ.js";
18
+ } from "./chunk-BC5OYWAM.js";
19
19
  import "./chunk-ZUD7OFYB.js";
20
20
  import {
21
21
  BITFAB_PROGRESS_PREFIX,
@@ -24,14 +24,14 @@ import {
24
24
  ReplayError,
25
25
  reportReplayProgress,
26
26
  serializeReplayResult
27
- } from "./chunk-EXT5FK54.js";
27
+ } from "./chunk-BG3A5HNC.js";
28
28
  import {
29
29
  BitfabError,
30
30
  DEFAULT_SERVICE_URL,
31
31
  HttpClient,
32
32
  __version__,
33
33
  flushTraces
34
- } from "./chunk-A22EYRSY.js";
34
+ } from "./chunk-UGFTBSGS.js";
35
35
  import "./chunk-H6LZRFMN.js";
36
36
  export {
37
37
  BITFAB_PROGRESS_PREFIX,
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.40.0";
91
+ __version__ = "0.42.0";
92
92
  __packageName__ = "@bitfab/sdk";
93
93
  }
94
94
  });
@@ -1344,7 +1344,7 @@ function sourceTraceIdOf(payload) {
1344
1344
  const id = rawTrace?.id;
1345
1345
  return typeof id === "string" ? id : void 0;
1346
1346
  }
1347
- var REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS, OTLP_TRACES_ENDPOINT, RETRYABLE_STATUSES, EXIT_FLUSH_TIMEOUT_MS, DEFAULT_LIFECYCLE_TIMEOUT_MS2, pendingTracePromises, carrierSeq, HttpClient;
1347
+ var REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS, REPLAY_COMPLETE_REQUEST_TIMEOUT_MS, OTLP_TRACES_ENDPOINT, RETRYABLE_STATUSES, EXIT_FLUSH_TIMEOUT_MS, DEFAULT_LIFECYCLE_TIMEOUT_MS2, pendingTracePromises, carrierSeq, HttpClient;
1348
1348
  var init_http = __esm({
1349
1349
  "src/http.ts"() {
1350
1350
  "use strict";
@@ -1358,6 +1358,7 @@ var init_http = __esm({
1358
1358
  init_unrefTimer();
1359
1359
  init_warnOnce();
1360
1360
  REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS = 3e5;
1361
+ REPLAY_COMPLETE_REQUEST_TIMEOUT_MS = 12e4;
1361
1362
  OTLP_TRACES_ENDPOINT = "/api/sdk/otel/v1/traces";
1362
1363
  RETRYABLE_STATUSES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
1363
1364
  EXIT_FLUSH_TIMEOUT_MS = 5e3;
@@ -1847,7 +1848,7 @@ var init_http = __esm({
1847
1848
  * Start a replay session by fetching historical traces.
1848
1849
  * Blocking call - creates a test run and returns lightweight item references.
1849
1850
  */
1850
- async startReplay(traceFunctionKey, limit, traceIds, name, codeChangeDescription, codeChangeFiles, includeDbBranchLease, experimentGroupId, datasetId, graderIds, dbBranchSettings) {
1851
+ async startReplay(traceFunctionKey, limit, traceIds, name, codeChangeDescription, codeChangeFiles, includeDbBranchLease, experimentGroupId, datasetId, graderIds, dbBranchSettings, attempts) {
1851
1852
  const payload = { traceFunctionKey };
1852
1853
  if (limit !== void 0) {
1853
1854
  payload.limit = limit;
@@ -1880,6 +1881,9 @@ var init_http = __esm({
1880
1881
  if (dbBranchSettings !== void 0) {
1881
1882
  payload.dbBranchSettings = dbBranchSettings;
1882
1883
  }
1884
+ if (attempts !== void 0 && attempts > 1) {
1885
+ payload.attempts = attempts;
1886
+ }
1883
1887
  const timeout = includeDbBranchLease ? REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS : 3e4;
1884
1888
  return this.request("/api/sdk/replay/start", payload, {
1885
1889
  timeout
@@ -1995,7 +1999,7 @@ var init_http = __esm({
1995
1999
  return this.request(
1996
2000
  "/api/sdk/replay/complete",
1997
2001
  { testRunId },
1998
- { timeout: 3e4 }
2002
+ { timeout: REPLAY_COMPLETE_REQUEST_TIMEOUT_MS }
1999
2003
  );
2000
2004
  }
2001
2005
  /**
@@ -2004,10 +2008,15 @@ var init_http = __esm({
2004
2008
  * snapshot + preview branch and polls operations to readiness, which
2005
2009
  * can take seconds.
2006
2010
  */
2007
- async resolveDbBranchLease(testRunId, traceId, dbBranchSettings) {
2011
+ async resolveDbBranchLease(testRunId, traceId, dbBranchSettings, attempt) {
2008
2012
  return this.request(
2009
2013
  "/api/sdk/replay/resolveDbBranchLease",
2010
- { testRunId, traceId, dbBranchSettings },
2014
+ {
2015
+ testRunId,
2016
+ traceId,
2017
+ dbBranchSettings,
2018
+ ...attempt !== void 0 && attempt > 0 ? { attempt } : {}
2019
+ },
2011
2020
  { timeout: REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS }
2012
2021
  );
2013
2022
  }
@@ -2443,6 +2452,23 @@ __export(replay_exports, {
2443
2452
  sleepForReplayPersistence: () => sleepForReplayPersistence,
2444
2453
  waitForReplayPersistence: () => waitForReplayPersistence
2445
2454
  });
2455
+ function expandReplayWork(serverItems, attempts) {
2456
+ return Array.from(
2457
+ { length: attempts },
2458
+ (_, attempt) => serverItems.map((serverItem) => ({ serverItem, attempt }))
2459
+ ).flat();
2460
+ }
2461
+ function resolveAttempts(attempts) {
2462
+ if (attempts === void 0) {
2463
+ return 1;
2464
+ }
2465
+ if (!Number.isInteger(attempts) || attempts < 1 || attempts > MAX_REPLAY_ATTEMPTS) {
2466
+ throw new BitfabError(
2467
+ `attempts must be an integer from 1 to ${MAX_REPLAY_ATTEMPTS} (got ${attempts}).`
2468
+ );
2469
+ }
2470
+ return attempts;
2471
+ }
2446
2472
  function dbBranchEnabled(dbBranch) {
2447
2473
  return dbBranch !== void 0 && dbBranch !== false;
2448
2474
  }
@@ -2566,7 +2592,7 @@ function buildMockTree(rootNode) {
2566
2592
  }
2567
2593
  return { spans };
2568
2594
  }
2569
- async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy, resolvedOverrides, replayedTraceId, includeDbBranchLease, dbBranchSettings, adaptInputs, dryRun) {
2595
+ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy, resolvedOverrides, replayedTraceId, attempt, includeDbBranchLease, dbBranchSettings, adaptInputs, dryRun) {
2570
2596
  let lease = includeDbBranchLease ? serverItem.dbBranchLease : void 0;
2571
2597
  let leaseError = includeDbBranchLease ? serverItem.dbBranchLeaseError : void 0;
2572
2598
  let dbSnapshotRef = serverItem.dbSnapshotRef;
@@ -2588,7 +2614,8 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
2588
2614
  resolved = await httpClient.resolveDbBranchLease(
2589
2615
  testRunId,
2590
2616
  originalTraceId,
2591
- dbBranchSettings
2617
+ dbBranchSettings,
2618
+ attempt
2592
2619
  );
2593
2620
  } catch (cause) {
2594
2621
  throw new DbBranchReplayError(
@@ -2668,6 +2695,7 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
2668
2695
  originalSpanId,
2669
2696
  sourceTraceId: originalTraceId,
2670
2697
  sourceSpanId: originalSpanId,
2698
+ attempt,
2671
2699
  input: inputs,
2672
2700
  result: void 0,
2673
2701
  originalOutput,
@@ -2696,6 +2724,7 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
2696
2724
  inputSourceSpanId: span.id,
2697
2725
  inputSourceTraceId: span.externalTraceId,
2698
2726
  sourceBitfabTraceId: originalTraceId,
2727
+ replayAttempt: attempt,
2699
2728
  mockTree,
2700
2729
  callCounters: mockTree ? /* @__PURE__ */ new Map() : void 0,
2701
2730
  mockStrategy,
@@ -2747,6 +2776,7 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
2747
2776
  // Deprecated aliases for originalTraceId/originalSpanId.
2748
2777
  sourceTraceId: originalTraceId,
2749
2778
  sourceSpanId: originalSpanId,
2779
+ attempt,
2750
2780
  input: inputs,
2751
2781
  result,
2752
2782
  originalOutput,
@@ -2875,6 +2905,7 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
2875
2905
  } catch {
2876
2906
  }
2877
2907
  }
2908
+ const attempts = resolveAttempts(options?.attempts);
2878
2909
  await replayContextReady;
2879
2910
  let codeChangeDescription = options?.codeChangeDescription;
2880
2911
  let codeChangeFiles = options?.codeChangeFiles;
@@ -2907,7 +2938,8 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
2907
2938
  options?.experimentGroupId,
2908
2939
  options?.datasetId,
2909
2940
  options?.graderIds,
2910
- resolveDbBranchSettings(options?.dbBranch)
2941
+ resolveDbBranchSettings(options?.dbBranch),
2942
+ attempts
2911
2943
  );
2912
2944
  if (serverItems.length === 0) {
2913
2945
  try {
@@ -2924,10 +2956,11 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
2924
2956
  ...normalizeMockOverrides(options?.mockOverride),
2925
2957
  ...registeredOverrides
2926
2958
  ];
2927
- const replayedTraceIds = serverItems.map(() => randomUuid());
2959
+ const workItems = expandReplayWork(serverItems, attempts);
2960
+ const replayedTraceIds = workItems.map(() => randomUuid());
2928
2961
  httpClient.trackTraceDeliveries(replayedTraceIds);
2929
- const tasks = serverItems.map(
2930
- (serverItem, index) => () => processItem(
2962
+ const tasks = workItems.map(
2963
+ ({ serverItem, attempt }, index) => () => processItem(
2931
2964
  httpClient,
2932
2965
  serverItem,
2933
2966
  fn,
@@ -2935,6 +2968,7 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
2935
2968
  mockStrategy,
2936
2969
  resolvedOverrides,
2937
2970
  replayedTraceIds[index],
2971
+ attempt,
2938
2972
  dbBranchEnabled(options?.dbBranch) && options?.dryRun !== true,
2939
2973
  resolveDbBranchSettings(options?.dbBranch),
2940
2974
  options?.adaptInputs,
@@ -3002,6 +3036,7 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
3002
3036
  // Deprecated aliases for originalTraceId/originalSpanId.
3003
3037
  sourceTraceId: item.originalTraceId ?? null,
3004
3038
  sourceSpanId: item.originalSpanId ?? null,
3039
+ attempt: item.attempt,
3005
3040
  input: item.input,
3006
3041
  result: item.result,
3007
3042
  originalOutput: item.originalOutput,
@@ -3023,7 +3058,7 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
3023
3058
  },
3024
3059
  options?.onItemStart ? (index) => {
3025
3060
  started += 1;
3026
- const serverItem = serverItems[index];
3061
+ const { serverItem, attempt } = workItems[index];
3027
3062
  const originalTraceId = serverItem.originalTraceId ?? serverItem.sourceTraceId;
3028
3063
  const originalSpanId = serverItem.originalSpanId ?? serverItem.sourceSpanId;
3029
3064
  try {
@@ -3039,7 +3074,8 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
3039
3074
  originalTraceId,
3040
3075
  originalSpanId,
3041
3076
  sourceTraceId: originalTraceId,
3042
- sourceSpanId: originalSpanId
3077
+ sourceSpanId: originalSpanId,
3078
+ attempt
3043
3079
  }
3044
3080
  });
3045
3081
  } catch {
@@ -3051,7 +3087,8 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
3051
3087
  const dryResult = {
3052
3088
  items: resultItems,
3053
3089
  testRunId,
3054
- testRunUrl: fullTestRunUrl
3090
+ testRunUrl: fullTestRunUrl,
3091
+ attempts
3055
3092
  };
3056
3093
  await writeReplayResultFile(dryResult);
3057
3094
  return dryResult;
@@ -3120,7 +3157,8 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
3120
3157
  const result = {
3121
3158
  items: resultItems,
3122
3159
  testRunId,
3123
- testRunUrl: fullTestRunUrl
3160
+ testRunUrl: fullTestRunUrl,
3161
+ attempts
3124
3162
  };
3125
3163
  await writeReplayResultFile(result);
3126
3164
  if (!options?.onItemFinish) {
@@ -3161,7 +3199,7 @@ async function writeReplayResultFile(result) {
3161
3199
  }
3162
3200
  }
3163
3201
  }
3164
- var REPLAY_PERSISTENCE_TIMEOUT_MS, BITFAB_PROGRESS_PREFIX, ReplayError, DbBranchReplayError;
3202
+ var REPLAY_PERSISTENCE_TIMEOUT_MS, MAX_REPLAY_ATTEMPTS, BITFAB_PROGRESS_PREFIX, ReplayError, DbBranchReplayError;
3165
3203
  var init_replay = __esm({
3166
3204
  "src/replay.ts"() {
3167
3205
  "use strict";
@@ -3173,6 +3211,7 @@ var init_replay = __esm({
3173
3211
  init_replayContext();
3174
3212
  init_serialize();
3175
3213
  REPLAY_PERSISTENCE_TIMEOUT_MS = 3e4;
3214
+ MAX_REPLAY_ATTEMPTS = 100;
3176
3215
  BITFAB_PROGRESS_PREFIX = "@@bitfab:progress ";
3177
3216
  ReplayError = class extends BitfabError {
3178
3217
  constructor(message, items, testRunId, testRunUrl, cause) {
@@ -3537,8 +3576,7 @@ var BitfabClaudeAgentHandler = class {
3537
3576
  const externalTrace = {
3538
3577
  id: traceId,
3539
3578
  started_at: this.traceStartedAt ?? nowIso(),
3540
- ended_at: endedAt ?? nowIso(),
3541
- workflow_name: this.traceFunctionKey
3579
+ ended_at: endedAt ?? nowIso()
3542
3580
  };
3543
3581
  if (metadata) {
3544
3582
  externalTrace.metadata = metadata;
@@ -4832,8 +4870,7 @@ var BitfabLangGraphCallbackHandler = class {
4832
4870
  externalTrace: {
4833
4871
  id: rootSpan.traceId,
4834
4872
  started_at: rootSpan.startedAt,
4835
- ended_at: rootSpan.endedAt ?? nowIso2(),
4836
- workflow_name: this.traceFunctionKey
4873
+ ended_at: rootSpan.endedAt ?? nowIso2()
4837
4874
  },
4838
4875
  completed
4839
4876
  };
@@ -4851,8 +4888,7 @@ var BitfabLangGraphCallbackHandler = class {
4851
4888
  traceFunctionKey: this.traceFunctionKey,
4852
4889
  externalTrace: {
4853
4890
  id: rootSpan.traceId,
4854
- started_at: rootSpan.startedAt,
4855
- workflow_name: this.traceFunctionKey
4891
+ started_at: rootSpan.startedAt
4856
4892
  },
4857
4893
  completed: false
4858
4894
  };
@@ -6010,6 +6046,8 @@ var noOpSpan = {
6010
6046
  var noOpTrace = {
6011
6047
  setSessionId() {
6012
6048
  },
6049
+ setName() {
6050
+ },
6013
6051
  setMetadata() {
6014
6052
  },
6015
6053
  addContext() {
@@ -6084,6 +6122,15 @@ function getCurrentTrace() {
6084
6122
  } catch {
6085
6123
  }
6086
6124
  },
6125
+ setName(name) {
6126
+ if (typeof name !== "string" || name.length === 0) {
6127
+ return;
6128
+ }
6129
+ try {
6130
+ getOrCreateTraceState().name = name;
6131
+ } catch {
6132
+ }
6133
+ },
6087
6134
  setMetadata(metadata) {
6088
6135
  try {
6089
6136
  if (typeof metadata !== "object" || metadata === null) {
@@ -7018,6 +7065,9 @@ var Bitfab = class {
7018
7065
  ...replayCtxAtStart?.inputSourceTraceId && {
7019
7066
  inputSourceTraceId: replayCtxAtStart.inputSourceTraceId
7020
7067
  },
7068
+ ...replayCtxAtStart?.replayAttempt !== void 0 && {
7069
+ replayAttempt: replayCtxAtStart.replayAttempt
7070
+ },
7021
7071
  dbSnapshotRef
7022
7072
  });
7023
7073
  registeredTraceId = traceId;
@@ -7063,10 +7113,12 @@ var Bitfab = class {
7063
7113
  startedAt: traceState?.startedAt ?? startedAt,
7064
7114
  endedAt,
7065
7115
  sessionId: traceState?.sessionId,
7116
+ name: traceState?.name,
7066
7117
  metadata: traceState?.metadata,
7067
7118
  contexts: traceState?.contexts ?? [],
7068
7119
  testRunId: traceState?.testRunId,
7069
7120
  inputSourceTraceId: traceState?.inputSourceTraceId,
7121
+ replayAttempt: traceState?.replayAttempt,
7070
7122
  dbSnapshotRef: traceState?.dbSnapshotRef,
7071
7123
  dropped: traceState?.dropped,
7072
7124
  ingestionType: traceState?.ingestionType,
@@ -7381,6 +7433,15 @@ var Bitfab = class {
7381
7433
  return Promise.resolve();
7382
7434
  }
7383
7435
  return this.httpClient.patchTrace(traceId, { setSessionId: sessionId });
7436
+ },
7437
+ setName: (name) => {
7438
+ if (!this.isTracingEnabled()) {
7439
+ return Promise.resolve();
7440
+ }
7441
+ if (typeof name !== "string" || name.length === 0) {
7442
+ return Promise.resolve();
7443
+ }
7444
+ return this.httpClient.patchTrace(traceId, { setName: name });
7384
7445
  }
7385
7446
  };
7386
7447
  }
@@ -7441,9 +7502,11 @@ var Bitfab = class {
7441
7502
  const rawTrace = {
7442
7503
  id: params.traceId,
7443
7504
  started_at: params.startedAt,
7444
- ended_at: params.endedAt,
7445
- workflow_name: params.traceFunctionKey
7505
+ ended_at: params.endedAt
7446
7506
  };
7507
+ if (params.name) {
7508
+ rawTrace.name = params.name;
7509
+ }
7447
7510
  if (params.metadata && Object.keys(params.metadata).length > 0) {
7448
7511
  rawTrace.metadata = params.metadata;
7449
7512
  }
@@ -7453,6 +7516,9 @@ var Bitfab = class {
7453
7516
  if (params.inputSourceTraceId) {
7454
7517
  rawTrace.input_source_trace_id = params.inputSourceTraceId;
7455
7518
  }
7519
+ if (params.replayAttempt !== void 0) {
7520
+ rawTrace.replay_attempt = params.replayAttempt;
7521
+ }
7456
7522
  if (params.dbSnapshotRef) {
7457
7523
  rawTrace.db_snapshot_ref = params.dbSnapshotRef;
7458
7524
  }
@@ -7636,6 +7702,7 @@ var Bitfab = class {
7636
7702
  contexts: [],
7637
7703
  ingestionType: "seeded",
7638
7704
  ...options.sessionId !== void 0 && { sessionId: options.sessionId },
7705
+ ...options.name !== void 0 && { name: options.name },
7639
7706
  ...options.metadata !== void 0 && { metadata: options.metadata }
7640
7707
  });
7641
7708
  try {
@@ -7658,6 +7725,7 @@ var Bitfab = class {
7658
7725
  startedAt,
7659
7726
  endedAt: startedAt,
7660
7727
  sessionId: options.sessionId,
7728
+ name: options.name,
7661
7729
  metadata: options.metadata,
7662
7730
  contexts: [],
7663
7731
  ingestionType: "seeded"