bitfab 0.59.0 → 0.59.1

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 (41) hide show
  1. package/dist/autoTrace.cjs.map +1 -1
  2. package/dist/autoTrace.d.cts +2 -0
  3. package/dist/autoTrace.d.ts +2 -0
  4. package/dist/autoTrace.js +1 -1
  5. package/dist/{chunk-FHEEAPG2.js → chunk-3D5EEY47.js} +54 -38
  6. package/dist/chunk-3D5EEY47.js.map +1 -0
  7. package/dist/{chunk-Y6FVWJKU.js → chunk-4F46OBRG.js} +18 -10
  8. package/dist/chunk-4F46OBRG.js.map +1 -0
  9. package/dist/{chunk-ETZUSSF6.js → chunk-5DNB7EN7.js} +1 -1
  10. package/dist/chunk-5DNB7EN7.js.map +1 -0
  11. package/dist/{chunk-R5MUOBRK.js → chunk-5MN6WIMW.js} +29 -14
  12. package/dist/chunk-5MN6WIMW.js.map +1 -0
  13. package/dist/{chunk-KFZ5OIN5.js → chunk-GJCZABUC.js} +29 -14
  14. package/dist/chunk-GJCZABUC.js.map +1 -0
  15. package/dist/{chunk-RYSCYPHQ.js → chunk-NVOQ7YMI.js} +37 -26
  16. package/dist/chunk-NVOQ7YMI.js.map +1 -0
  17. package/dist/{http-D7P4JL6C.js → http-2QEMP27E.js} +4 -2
  18. package/dist/{http-7WLON2BH.js → http-OXKVRA3E.js} +4 -2
  19. package/dist/index.cjs +109 -67
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.cts +68 -35
  22. package/dist/index.d.ts +68 -35
  23. package/dist/index.js +4 -4
  24. package/dist/node.cjs +109 -67
  25. package/dist/node.cjs.map +1 -1
  26. package/dist/node.d.cts +1 -1
  27. package/dist/node.d.ts +1 -1
  28. package/dist/node.js +4 -4
  29. package/dist/{replay-5TZNJ2DL.js → replay-WYPFFXSU.js} +3 -3
  30. package/dist/replayCli.js +2 -2
  31. package/dist/seedCli.js +2 -2
  32. package/package.json +1 -1
  33. package/dist/chunk-ETZUSSF6.js.map +0 -1
  34. package/dist/chunk-FHEEAPG2.js.map +0 -1
  35. package/dist/chunk-KFZ5OIN5.js.map +0 -1
  36. package/dist/chunk-R5MUOBRK.js.map +0 -1
  37. package/dist/chunk-RYSCYPHQ.js.map +0 -1
  38. package/dist/chunk-Y6FVWJKU.js.map +0 -1
  39. /package/dist/{http-7WLON2BH.js.map → http-2QEMP27E.js.map} +0 -0
  40. /package/dist/{http-D7P4JL6C.js.map → http-OXKVRA3E.js.map} +0 -0
  41. /package/dist/{replay-5TZNJ2DL.js.map → replay-WYPFFXSU.js.map} +0 -0
@@ -3,18 +3,20 @@ import {
3
3
  HttpClient,
4
4
  awaitOnExit,
5
5
  awaitPendingRequests,
6
+ experimentIdWireFields,
6
7
  flushTraces,
7
8
  parseRetryAfterMs,
8
9
  serializePayloadBody
9
- } from "./chunk-KFZ5OIN5.js";
10
+ } from "./chunk-GJCZABUC.js";
10
11
  import "./chunk-BAOIRE5T.js";
11
12
  export {
12
13
  BitfabError,
13
14
  HttpClient,
14
15
  awaitOnExit,
15
16
  awaitPendingRequests,
17
+ experimentIdWireFields,
16
18
  flushTraces,
17
19
  parseRetryAfterMs,
18
20
  serializePayloadBody
19
21
  };
20
- //# sourceMappingURL=http-D7P4JL6C.js.map
22
+ //# sourceMappingURL=http-2QEMP27E.js.map
@@ -3,17 +3,19 @@ import {
3
3
  HttpClient,
4
4
  awaitOnExit,
5
5
  awaitPendingRequests,
6
+ experimentIdWireFields,
6
7
  flushTraces,
7
8
  parseRetryAfterMs,
8
9
  serializePayloadBody
9
- } from "./chunk-R5MUOBRK.js";
10
+ } from "./chunk-5MN6WIMW.js";
10
11
  export {
11
12
  BitfabError,
12
13
  HttpClient,
13
14
  awaitOnExit,
14
15
  awaitPendingRequests,
16
+ experimentIdWireFields,
15
17
  flushTraces,
16
18
  parseRetryAfterMs,
17
19
  serializePayloadBody
18
20
  };
19
- //# sourceMappingURL=http-7WLON2BH.js.map
21
+ //# sourceMappingURL=http-OXKVRA3E.js.map
package/dist/index.cjs CHANGED
@@ -51,7 +51,7 @@ var __version__, __packageName__;
51
51
  var init_version_generated = __esm({
52
52
  "src/version.generated.ts"() {
53
53
  "use strict";
54
- __version__ = "0.59.0";
54
+ __version__ = "0.59.1";
55
55
  __packageName__ = "bitfab";
56
56
  }
57
57
  });
@@ -2113,6 +2113,7 @@ __export(http_exports, {
2113
2113
  HttpClient: () => HttpClient,
2114
2114
  awaitOnExit: () => awaitOnExit,
2115
2115
  awaitPendingRequests: () => awaitPendingRequests,
2116
+ experimentIdWireFields: () => experimentIdWireFields,
2116
2117
  flushTraces: () => flushTraces,
2117
2118
  parseRetryAfterMs: () => parseRetryAfterMs,
2118
2119
  serializePayloadBody: () => serializePayloadBody
@@ -2281,6 +2282,9 @@ function warnDroppedExternalTrace(error) {
2281
2282
  `a trace was dropped because the send step failed: ${describeError(error)}`
2282
2283
  );
2283
2284
  }
2285
+ function experimentIdWireFields(experimentId) {
2286
+ return { experimentId, testRunId: experimentId };
2287
+ }
2284
2288
  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, liveHttpClients, carrierSeq, HttpClient;
2285
2289
  var init_http = __esm({
2286
2290
  "src/http.ts"() {
@@ -2885,7 +2889,7 @@ var init_http = __esm({
2885
2889
  }
2886
2890
  /**
2887
2891
  * Start a replay session by fetching historical traces.
2888
- * Blocking call - creates a test run and returns lightweight item references.
2892
+ * Blocking call - creates an experiment and returns lightweight item references.
2889
2893
  */
2890
2894
  async startReplay(traceFunctionKey, limit, traceIds, name, codeChangeDescription, codeChangeFiles, includeDbBranchLease, experimentGroupId, datasetIds, graderIds, dbBranchSettings, attempts, includeOriginalMetadata, onlyWithAssertions, judgeAssertions) {
2891
2895
  const payload = { traceFunctionKey };
@@ -2941,9 +2945,20 @@ var init_http = __esm({
2941
2945
  payload.git = git;
2942
2946
  }
2943
2947
  const timeout = includeDbBranchLease ? REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS : 3e4;
2944
- return this.request("/api/sdk/replay/start", payload, {
2945
- timeout
2946
- });
2948
+ const response = await this.request(
2949
+ "/api/sdk/replay/start",
2950
+ payload,
2951
+ { timeout }
2952
+ );
2953
+ const { testRunId, testRunUrl, ...rest } = response;
2954
+ const experimentId = response.experimentId ?? testRunId;
2955
+ const experimentUrl = response.experimentUrl ?? testRunUrl;
2956
+ if (experimentId === void 0 || experimentUrl === void 0) {
2957
+ throw new BitfabError(
2958
+ "Replay start response is missing the experiment ID or URL."
2959
+ );
2960
+ }
2961
+ return { ...rest, experimentId, experimentUrl };
2947
2962
  }
2948
2963
  /**
2949
2964
  * Fetch an external span by ID.
@@ -3040,21 +3055,21 @@ var init_http = __esm({
3040
3055
  * has a final status AND at least that many persisted spans, which is what
3041
3056
  * makes this a real barrier rather than a "the row exists" check.
3042
3057
  */
3043
- async getReplayStatus(testRunId, expectedSpanCounts) {
3058
+ async getReplayStatus(experimentId, expectedSpanCounts) {
3044
3059
  return this.request(
3045
3060
  "/api/sdk/replay/status",
3046
- { testRunId, expectedSpanCounts },
3061
+ { ...experimentIdWireFields(experimentId), expectedSpanCounts },
3047
3062
  { timeout: 3e4 }
3048
3063
  );
3049
3064
  }
3050
3065
  /**
3051
- * Mark a replay test run as completed.
3066
+ * Mark a replay experiment as completed.
3052
3067
  * Blocking call.
3053
3068
  */
3054
- async completeReplay(testRunId) {
3069
+ async completeReplay(experimentId) {
3055
3070
  return this.request(
3056
3071
  "/api/sdk/replay/complete",
3057
- { testRunId },
3072
+ experimentIdWireFields(experimentId),
3058
3073
  { timeout: REPLAY_COMPLETE_REQUEST_TIMEOUT_MS }
3059
3074
  );
3060
3075
  }
@@ -3076,11 +3091,11 @@ var init_http = __esm({
3076
3091
  * snapshot + preview branch and polls operations to readiness, which
3077
3092
  * can take seconds.
3078
3093
  */
3079
- async resolveDbBranchLease(testRunId, traceId, dbBranchSettings, attempt) {
3094
+ async resolveDbBranchLease(experimentId, traceId, dbBranchSettings, attempt) {
3080
3095
  return this.request(
3081
3096
  "/api/sdk/replay/resolveDbBranchLease",
3082
3097
  {
3083
- testRunId,
3098
+ ...experimentIdWireFields(experimentId),
3084
3099
  traceId,
3085
3100
  dbBranchSettings,
3086
3101
  ...attempt !== void 0 && attempt > 0 ? { attempt } : {}
@@ -3669,7 +3684,7 @@ function replayJsonReplacer(_key, value) {
3669
3684
  function serializeReplayResult(result) {
3670
3685
  return JSON.stringify(result, replayJsonReplacer, 2);
3671
3686
  }
3672
- async function preserveReplayFailure(operation, items, testRunId, testRunUrl) {
3687
+ async function preserveReplayFailure(operation, items, experimentId, experimentUrl) {
3673
3688
  try {
3674
3689
  return await operation();
3675
3690
  } catch (cause) {
@@ -3679,8 +3694,8 @@ async function preserveReplayFailure(operation, items, testRunId, testRunUrl) {
3679
3694
  throw new ReplayError(
3680
3695
  errorMessage(cause),
3681
3696
  items,
3682
- testRunId,
3683
- testRunUrl,
3697
+ experimentId,
3698
+ experimentUrl,
3684
3699
  cause
3685
3700
  );
3686
3701
  }
@@ -3734,7 +3749,7 @@ function buildMockTree(rootNode) {
3734
3749
  }
3735
3750
  return { spans };
3736
3751
  }
3737
- async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy, resolvedOverrides, replayedTraceId, attempt, includeDbBranchLease, dbBranchSettings, adaptInputs, dryRun) {
3752
+ async function processItem(httpClient, serverItem, fn, experimentId, mockStrategy, resolvedOverrides, replayedTraceId, attempt, includeDbBranchLease, dbBranchSettings, adaptInputs, dryRun) {
3738
3753
  let lease = includeDbBranchLease ? serverItem.dbBranchLease : void 0;
3739
3754
  let leaseError = includeDbBranchLease ? serverItem.dbBranchLeaseError : void 0;
3740
3755
  let dbSnapshotRef = serverItem.dbSnapshotRef;
@@ -3754,7 +3769,7 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
3754
3769
  let resolved2;
3755
3770
  try {
3756
3771
  resolved2 = await httpClient.resolveDbBranchLease(
3757
- testRunId,
3772
+ experimentId,
3758
3773
  originalTraceId,
3759
3774
  dbBranchSettings,
3760
3775
  attempt
@@ -3866,7 +3881,7 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
3866
3881
  replayStarted = performance.now();
3867
3882
  const maybePromise = runWithReplayContext(
3868
3883
  {
3869
- testRunId,
3884
+ experimentId,
3870
3885
  traceId: replayedTraceId,
3871
3886
  inputSourceSpanId: span.id,
3872
3887
  inputSourceTraceId: span.externalTraceId,
@@ -3949,14 +3964,14 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
3949
3964
  originalTraceOutline: null
3950
3965
  };
3951
3966
  }
3952
- async function waitForReplayPersistence(httpClient, testRunId, replayedTraceIds) {
3967
+ async function waitForReplayPersistence(httpClient, experimentId, replayedTraceIds) {
3953
3968
  const deferredSettled = await httpClient.settleDeferredWork(
3954
3969
  REPLAY_PERSISTENCE_TIMEOUT_MS
3955
3970
  );
3956
3971
  if (!deferredSettled) {
3957
3972
  httpClient.takeTraceDeliveries(replayedTraceIds);
3958
3973
  throw new BitfabError(
3959
- `Replay could not settle deferred span work before the deadline, so the expected span counts are incomplete (testRunId ${testRunId}).`
3974
+ `Replay could not settle deferred span work before the deadline, so the expected span counts are incomplete (experiment ${experimentId}).`
3960
3975
  );
3961
3976
  }
3962
3977
  if (!httpClient.hasClosedDeliveries(replayedTraceIds)) {
@@ -3985,7 +4000,7 @@ async function waitForReplayPersistence(httpClient, testRunId, replayedTraceIds)
3985
4000
  let missing = Object.keys(expectedSpanCounts).length;
3986
4001
  while (true) {
3987
4002
  const status = await httpClient.getReplayStatus(
3988
- testRunId,
4003
+ experimentId,
3989
4004
  expectedSpanCounts
3990
4005
  );
3991
4006
  const ready = status.traceIds ?? {};
@@ -4004,7 +4019,7 @@ async function waitForReplayPersistence(httpClient, testRunId, replayedTraceIds)
4004
4019
  }
4005
4020
  const cause = flushed ? "" : " Delivery was also not confirmed before the flush deadline, so the spans likely never reached the server.";
4006
4021
  throw new BitfabError(
4007
- `Replay traces were not fully persisted before the delivery deadline (testRunId ${testRunId}, missing ${missing} of ${Object.keys(expectedSpanCounts).length} trace(s)).${cause}`
4022
+ `Replay traces were not fully persisted before the delivery deadline (experiment ${experimentId}, missing ${missing} of ${Object.keys(expectedSpanCounts).length} trace(s)).${cause}`
4008
4023
  );
4009
4024
  }
4010
4025
  function sleepForReplayPersistence(ms) {
@@ -4071,8 +4086,8 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
4071
4086
  }
4072
4087
  }
4073
4088
  const {
4074
- testRunId,
4075
- testRunUrl,
4089
+ experimentId,
4090
+ experimentUrl,
4076
4091
  items: serverItems
4077
4092
  } = await httpClient.startReplay(
4078
4093
  traceFunctionKey,
@@ -4105,7 +4120,14 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
4105
4120
  }
4106
4121
  }
4107
4122
  const mockStrategy = options?.mock ?? "marked";
4108
- const fullTestRunUrl = `${serviceUrl}${testRunUrl}`;
4123
+ const fullExperimentUrl = `${serviceUrl}${experimentUrl}`;
4124
+ try {
4125
+ options?.onExperimentStart?.({
4126
+ experimentId,
4127
+ experimentUrl: fullExperimentUrl
4128
+ });
4129
+ } catch {
4130
+ }
4109
4131
  const resolvedOverrides = [
4110
4132
  ...normalizeMockOverrides(options?.mockOverride),
4111
4133
  ...registeredOverrides
@@ -4118,7 +4140,7 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
4118
4140
  httpClient,
4119
4141
  serverItem,
4120
4142
  fn,
4121
- testRunId,
4143
+ experimentId,
4122
4144
  mockStrategy,
4123
4145
  resolvedOverrides,
4124
4146
  replayedTraceIds[index],
@@ -4173,7 +4195,8 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
4173
4195
  }
4174
4196
  try {
4175
4197
  onItemFinish?.({
4176
- testRunId,
4198
+ experimentId,
4199
+ testRunId: experimentId,
4177
4200
  completed,
4178
4201
  total,
4179
4202
  succeeded,
@@ -4221,7 +4244,8 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
4221
4244
  try {
4222
4245
  options.onItemStart?.({
4223
4246
  type: "started",
4224
- testRunId,
4247
+ experimentId,
4248
+ testRunId: experimentId,
4225
4249
  started,
4226
4250
  completed,
4227
4251
  total,
@@ -4240,21 +4264,23 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
4240
4264
  } : void 0
4241
4265
  );
4242
4266
  if (options?.dryRun === true) {
4243
- await httpClient.completeReplay(testRunId).catch(() => void 0);
4267
+ await httpClient.completeReplay(experimentId).catch(() => void 0);
4244
4268
  const dryResult = {
4245
4269
  items: resultItems,
4246
- testRunId,
4247
- testRunUrl: fullTestRunUrl,
4270
+ experimentId,
4271
+ experimentUrl: fullExperimentUrl,
4272
+ testRunId: experimentId,
4273
+ testRunUrl: fullExperimentUrl,
4248
4274
  attempts
4249
4275
  };
4250
4276
  await writeReplayResultFile(dryResult);
4251
4277
  return dryResult;
4252
4278
  }
4253
4279
  const deliveredTraceIds = await preserveReplayFailure(
4254
- () => waitForReplayPersistence(httpClient, testRunId, replayedTraceIds),
4280
+ () => waitForReplayPersistence(httpClient, experimentId, replayedTraceIds),
4255
4281
  resultItems,
4256
- testRunId,
4257
- fullTestRunUrl
4282
+ experimentId,
4283
+ fullExperimentUrl
4258
4284
  );
4259
4285
  for (let index = 0; index < resultItems.length; index += 1) {
4260
4286
  const localId = replayedTraceIds[index];
@@ -4264,10 +4290,10 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
4264
4290
  }
4265
4291
  }
4266
4292
  const completeResult = await preserveReplayFailure(
4267
- () => httpClient.completeReplay(testRunId),
4293
+ () => httpClient.completeReplay(experimentId),
4268
4294
  resultItems,
4269
- testRunId,
4270
- fullTestRunUrl
4295
+ experimentId,
4296
+ fullExperimentUrl
4271
4297
  );
4272
4298
  const serverTraceIds = completeResult.traceIds;
4273
4299
  const replayTokens = completeResult.tokens;
@@ -4294,20 +4320,20 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
4294
4320
  if (completedCount > 0 && missing.length === completedCount) {
4295
4321
  const serverCount = completeResult.traceCount !== void 0 ? ` The server persisted ${completeResult.traceCount} trace(s) for this run.` : "";
4296
4322
  const cause = new BitfabError(
4297
- `Replay completed but the server has no persisted trace for any of the ${completedCount} completed item(s) (testRunId ${testRunId}).${serverCount} Trace uploads were awaited, so either the uploads failed (check for "Bitfab: Failed to create" errors above) or the replayed function is not wrapped with withSpan.`
4323
+ `Replay completed but the server has no persisted trace for any of the ${completedCount} completed item(s) (experiment ${experimentId}).${serverCount} Trace uploads were awaited, so either the uploads failed (check for "Bitfab: Failed to create" errors above) or the replayed function is not wrapped with withSpan.`
4298
4324
  );
4299
4325
  throw new ReplayError(
4300
4326
  cause.message,
4301
4327
  resultItems,
4302
- testRunId,
4303
- fullTestRunUrl,
4328
+ experimentId,
4329
+ fullExperimentUrl,
4304
4330
  cause
4305
4331
  );
4306
4332
  }
4307
4333
  if (missing.length > 0) {
4308
4334
  try {
4309
4335
  console.error(
4310
- `Bitfab: server has no persisted trace for ${missing.length} of ${completedCount} completed replay item(s) (testRunId ${testRunId}). Their replay token usage is unavailable and they cannot be labeled.`
4336
+ `Bitfab: server has no persisted trace for ${missing.length} of ${completedCount} completed replay item(s) (experiment ${experimentId}). Their replay token usage is unavailable and they cannot be labeled.`
4311
4337
  );
4312
4338
  } catch {
4313
4339
  }
@@ -4315,8 +4341,10 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
4315
4341
  }
4316
4342
  const result = {
4317
4343
  items: resultItems,
4318
- testRunId,
4319
- testRunUrl: fullTestRunUrl,
4344
+ experimentId,
4345
+ experimentUrl: fullExperimentUrl,
4346
+ testRunId: experimentId,
4347
+ testRunUrl: fullExperimentUrl,
4320
4348
  attempts
4321
4349
  };
4322
4350
  await writeReplayResultFile(result);
@@ -4324,7 +4352,8 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
4324
4352
  try {
4325
4353
  options?.onProgress?.({
4326
4354
  type: "complete",
4327
- testRunId,
4355
+ experimentId,
4356
+ testRunId: experimentId,
4328
4357
  completed: total,
4329
4358
  total,
4330
4359
  succeeded,
@@ -4374,13 +4403,15 @@ var init_replay = __esm({
4374
4403
  MAX_REPLAY_ATTEMPTS = 100;
4375
4404
  BITFAB_PROGRESS_PREFIX = "@@bitfab:progress ";
4376
4405
  ReplayError = class extends BitfabError {
4377
- constructor(message, items, testRunId, testRunUrl, cause) {
4378
- super(message, testRunUrl);
4406
+ constructor(message, items, experimentId, experimentUrl, cause) {
4407
+ super(message, experimentUrl);
4379
4408
  this.items = items;
4380
- this.testRunId = testRunId;
4381
- this.testRunUrl = testRunUrl;
4409
+ this.experimentId = experimentId;
4410
+ this.experimentUrl = experimentUrl;
4382
4411
  this.cause = cause;
4383
4412
  this.name = "ReplayError";
4413
+ this.testRunId = experimentId;
4414
+ this.testRunUrl = experimentUrl;
4384
4415
  }
4385
4416
  };
4386
4417
  DbBranchReplayError = class extends BitfabError {
@@ -6066,6 +6097,7 @@ var GradersClient = class {
6066
6097
  init_http();
6067
6098
 
6068
6099
  // src/labels.ts
6100
+ init_http();
6069
6101
  var LABELS_PATH = "/api/sdk/traces/labels";
6070
6102
  var HUMAN_LABELS_PATH = "/api/sdk/traces/labels/human";
6071
6103
  function labelEvidencePath(traceId, assertionId) {
@@ -6075,27 +6107,27 @@ var LabelsClient = class {
6075
6107
  constructor(httpClient) {
6076
6108
  this.httpClient = httpClient;
6077
6109
  }
6078
- async save(update, testRunId) {
6079
- const [outcome] = await this.saveAll([update], testRunId);
6110
+ async save(update, experimentId) {
6111
+ const [outcome] = await this.saveAll([update], experimentId);
6080
6112
  return outcome;
6081
6113
  }
6082
- async saveAll(updates, testRunId) {
6114
+ async saveAll(updates, experimentId) {
6083
6115
  const response = await this.httpClient.request(
6084
6116
  LABELS_PATH,
6085
6117
  {
6086
6118
  labels: updates,
6087
- ...testRunId === void 0 ? {} : { testRunId }
6119
+ ...experimentId === void 0 ? {} : experimentIdWireFields(experimentId)
6088
6120
  }
6089
6121
  );
6090
6122
  return response.labels;
6091
6123
  }
6092
6124
  /** Withhold a verdict for a trace or replay attempt whose check did not run. */
6093
- async skip(target, testRunId) {
6094
- return this.save({ ...target, skip: true }, testRunId);
6125
+ async skip(target, experimentId) {
6126
+ return this.save({ ...target, skip: true }, experimentId);
6095
6127
  }
6096
6128
  /** Clear a previous verdict for a trace, replay attempt, or assertion. */
6097
- async archive(target, testRunId) {
6098
- return this.save({ ...target, archive: true }, testRunId);
6129
+ async archive(target, experimentId) {
6130
+ return this.save({ ...target, archive: true }, experimentId);
6099
6131
  }
6100
6132
  async saveHuman(update) {
6101
6133
  const [outcome] = await this.saveHumanAll([update]);
@@ -8453,6 +8485,15 @@ var BitfabVercelAiHandler = class {
8453
8485
 
8454
8486
  // src/client.ts
8455
8487
  init_warnOnce();
8488
+ function resolveSpanExperimentId(options) {
8489
+ const { experimentId, testRunId } = options;
8490
+ if (experimentId !== void 0 && testRunId !== void 0 && experimentId !== testRunId) {
8491
+ throw new BitfabError(
8492
+ `experimentId ("${experimentId}") and its deprecated alias testRunId ("${testRunId}") were both passed with different values. Pass only experimentId.`
8493
+ );
8494
+ }
8495
+ return experimentId ?? testRunId;
8496
+ }
8456
8497
  var TRUNCATION_LIMIT_ORDER = [
8457
8498
  "max_depth",
8458
8499
  "max_captured_subtree_spans"
@@ -9042,13 +9083,12 @@ var Bitfab = class {
9042
9083
  "bitfab.node({ capture: false }) cannot use mockOnReplay: true because an uncaptured node has no recorded output."
9043
9084
  );
9044
9085
  }
9086
+ const experimentId = resolveSpanExperimentId(options);
9045
9087
  return {
9046
9088
  capture,
9047
9089
  type: options.type ?? "custom",
9048
9090
  ...options.name !== void 0 && { name: options.name },
9049
- ...options.testRunId !== void 0 && {
9050
- testRunId: options.testRunId
9051
- },
9091
+ ...experimentId !== void 0 && { experimentId },
9052
9092
  ...options.mockOnReplay !== void 0 && {
9053
9093
  mockOnReplay: options.mockOnReplay
9054
9094
  },
@@ -9183,6 +9223,7 @@ var Bitfab = class {
9183
9223
  return invokeWithoutNode();
9184
9224
  }
9185
9225
  const mockOnReplay = nodeConfiguration?.mockOnReplay ?? options.mockOnReplayDefault;
9226
+ const nodeExperimentId = nodeConfiguration === void 0 ? void 0 : resolveSpanExperimentId(nodeConfiguration);
9186
9227
  const childOptions = {
9187
9228
  name: spanName,
9188
9229
  type: nodeConfiguration?.type ?? "function",
@@ -9193,8 +9234,8 @@ var Bitfab = class {
9193
9234
  captureContent: true,
9194
9235
  autoTraceDefinition: definition,
9195
9236
  ...declaredNode && { declaredNode },
9196
- ...nodeConfiguration?.testRunId !== void 0 && {
9197
- testRunId: nodeConfiguration.testRunId
9237
+ ...nodeExperimentId !== void 0 && {
9238
+ experimentId: nodeExperimentId
9198
9239
  },
9199
9240
  ...mockOnReplay !== void 0 && {
9200
9241
  mockOnReplay
@@ -9855,6 +9896,7 @@ var Bitfab = class {
9855
9896
  const options = typeof optionsOrFn === "function" ? {} : optionsOrFn;
9856
9897
  const fn = typeof optionsOrFn === "function" ? optionsOrFn : maybeFn;
9857
9898
  const self = this;
9899
+ const optionExperimentId = resolveSpanExperimentId(options);
9858
9900
  const fnIsAsyncFunction = fn.constructor.name === "AsyncFunction";
9859
9901
  const fnReturnsPromise = fnIsAsyncFunction || (() => {
9860
9902
  try {
@@ -9957,7 +9999,7 @@ var Bitfab = class {
9957
9999
  const inputs = args;
9958
10000
  const startedAt = nowIsoTimestamp();
9959
10001
  const replayCtxAtStart = getReplayContext();
9960
- const testRunId = replayCtxAtStart?.testRunId ?? options.testRunId;
10002
+ const experimentId = replayCtxAtStart?.experimentId ?? optionExperimentId;
9961
10003
  if (isRootSpan && !activeTraceStates.has(traceId)) {
9962
10004
  const dbSnapshotRef = buildSnapshotRef(self.dbSnapshot, startedAt);
9963
10005
  self.simulationPlan.refresh();
@@ -9966,7 +10008,7 @@ var Bitfab = class {
9966
10008
  traceFunctionKey,
9967
10009
  startedAt,
9968
10010
  contexts: [],
9969
- ...testRunId !== void 0 && { testRunId },
10011
+ ...experimentId !== void 0 && { experimentId },
9970
10012
  ...replayCtxAtStart?.inputSourceTraceId && {
9971
10013
  inputSourceTraceId: replayCtxAtStart.inputSourceTraceId
9972
10014
  },
@@ -10012,7 +10054,7 @@ var Bitfab = class {
10012
10054
  contexts: newContext.contexts,
10013
10055
  prompt: newContext.prompt,
10014
10056
  endedAt,
10015
- ...testRunId !== void 0 && { testRunId },
10057
+ ...experimentId !== void 0 && { experimentId },
10016
10058
  ...replayCtx?.inputSourceSpanId && {
10017
10059
  inputSourceSpanId: replayCtx.inputSourceSpanId
10018
10060
  }
@@ -10033,7 +10075,7 @@ var Bitfab = class {
10033
10075
  name: traceState?.name,
10034
10076
  metadata: callerTraceMetadata(traceId),
10035
10077
  contexts: traceState?.contexts ?? [],
10036
- testRunId: traceState?.testRunId,
10078
+ experimentId: traceState?.experimentId,
10037
10079
  inputSourceTraceId: traceState?.inputSourceTraceId,
10038
10080
  replayAttempt: traceState?.replayAttempt,
10039
10081
  dbSnapshotRef: traceState?.dbSnapshotRef,
@@ -10504,7 +10546,7 @@ var Bitfab = class {
10504
10546
  completed: true,
10505
10547
  ...params.dropped && { dropped: true },
10506
10548
  ...params.sessionId && { sessionId: params.sessionId },
10507
- ...params.testRunId && { testRunId: params.testRunId }
10549
+ ...params.experimentId !== void 0 && experimentIdWireFields(params.experimentId)
10508
10550
  });
10509
10551
  }
10510
10552
  sendsSpanOnCompletion(context) {
@@ -10616,7 +10658,7 @@ var Bitfab = class {
10616
10658
  },
10617
10659
  ...params.declaredNode === true && { [DECLARED_NODE_FIELD]: true },
10618
10660
  rawSpan: externalSpan,
10619
- ...params.testRunId && { testRunId: params.testRunId },
10661
+ ...params.experimentId !== void 0 && experimentIdWireFields(params.experimentId),
10620
10662
  ...params.mocked && { mocked: true },
10621
10663
  ...params.mockTarget && { mockTarget: params.mockTarget },
10622
10664
  ...params.mockSource && { mockSource: params.mockSource }