bitfab 0.61.2 → 0.61.3

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 +1 -0
  3. package/dist/autoTrace.d.ts +1 -0
  4. package/dist/autoTrace.js +1 -1
  5. package/dist/{chunk-INA6W7OB.js → chunk-6IMUONDN.js} +7 -3
  6. package/dist/chunk-6IMUONDN.js.map +1 -0
  7. package/dist/{chunk-ONZFMRRF.js → chunk-HVEZHLVQ.js} +6 -3
  8. package/dist/chunk-HVEZHLVQ.js.map +1 -0
  9. package/dist/{chunk-A4UVO6BQ.js → chunk-IZUZ5NBB.js} +306 -7
  10. package/dist/chunk-IZUZ5NBB.js.map +1 -0
  11. package/dist/{chunk-BMJNDIVA.js → chunk-K4XCWQBC.js} +1 -1
  12. package/dist/chunk-K4XCWQBC.js.map +1 -0
  13. package/dist/{chunk-LUOCT4HG.js → chunk-PAUXHTNF.js} +38 -7
  14. package/dist/chunk-PAUXHTNF.js.map +1 -0
  15. package/dist/{chunk-MTK6PZHA.js → chunk-WOHIAKZF.js} +3 -3
  16. package/dist/chunk-WOHIAKZF.js.map +1 -0
  17. package/dist/{http-KM6QWKAP.js → http-3IYU5Z54.js} +2 -2
  18. package/dist/{http-2R6MSRVA.js → http-BYICBOWP.js} +2 -2
  19. package/dist/index.cjs +355 -7
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.cts +120 -3
  22. package/dist/index.d.ts +120 -3
  23. package/dist/index.js +4 -4
  24. package/dist/node.cjs +355 -7
  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-6UUBJBLK.js → replay-SXHX5BBU.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-A4UVO6BQ.js.map +0 -1
  34. package/dist/chunk-BMJNDIVA.js.map +0 -1
  35. package/dist/chunk-INA6W7OB.js.map +0 -1
  36. package/dist/chunk-LUOCT4HG.js.map +0 -1
  37. package/dist/chunk-MTK6PZHA.js.map +0 -1
  38. package/dist/chunk-ONZFMRRF.js.map +0 -1
  39. /package/dist/{http-2R6MSRVA.js.map → http-3IYU5Z54.js.map} +0 -0
  40. /package/dist/{http-KM6QWKAP.js.map → http-BYICBOWP.js.map} +0 -0
  41. /package/dist/{replay-6UUBJBLK.js.map → replay-SXHX5BBU.js.map} +0 -0
@@ -5,7 +5,7 @@ import {
5
5
  gitRunner,
6
6
  replayContextReady,
7
7
  runWithReplayContext
8
- } from "./chunk-INA6W7OB.js";
8
+ } from "./chunk-6IMUONDN.js";
9
9
  import {
10
10
  runWithCaptureSuppressed,
11
11
  warnOnce
@@ -437,6 +437,278 @@ function fallbackUuidV4() {
437
437
  });
438
438
  }
439
439
 
440
+ // src/selectiveReplay.ts
441
+ function replayNodeKey(node) {
442
+ return JSON.stringify([node.traceFunctionKey, node.spanName]);
443
+ }
444
+ function jsonFingerprint(value) {
445
+ const seen = /* @__PURE__ */ new Set();
446
+ function encode(input) {
447
+ if (input === null || typeof input === "boolean") {
448
+ return JSON.stringify(input);
449
+ }
450
+ if (typeof input === "string" && !input.startsWith("<unserializable")) {
451
+ return JSON.stringify(input);
452
+ }
453
+ if (typeof input === "number" && Number.isFinite(input) && !Object.is(input, -0)) {
454
+ return JSON.stringify(input);
455
+ }
456
+ if (typeof input !== "object" || input === null || seen.has(input)) {
457
+ throw new Error("Not a lossless JSON value");
458
+ }
459
+ seen.add(input);
460
+ const prototype = Object.getPrototypeOf(input);
461
+ if (prototype !== (Array.isArray(input) ? Array.prototype : Object.prototype)) {
462
+ throw new Error("Not a plain JSON object");
463
+ }
464
+ if (Object.getOwnPropertySymbols(input).length > 0) {
465
+ throw new Error("Symbol properties are not recorded");
466
+ }
467
+ const keys = Object.keys(input);
468
+ if (Object.getOwnPropertyNames(input).length !== keys.length + (Array.isArray(input) ? 1 : 0)) {
469
+ throw new Error("Non-enumerable properties are not recorded");
470
+ }
471
+ if (Array.isArray(input) && (keys.length !== input.length || keys.some((key, index) => key !== String(index)))) {
472
+ throw new Error("Not a dense JSON array");
473
+ }
474
+ const properties = keys.map((key) => {
475
+ const descriptor = Object.getOwnPropertyDescriptor(input, key);
476
+ if (!descriptor || !("value" in descriptor)) {
477
+ throw new Error("Accessor properties are not replay inputs");
478
+ }
479
+ return `${Array.isArray(input) ? "" : `${JSON.stringify(key)}:`}${encode(descriptor.value)}`;
480
+ });
481
+ return Array.isArray(input) ? `[${properties.join(",")}]` : `{${properties.join(",")}}`;
482
+ }
483
+ try {
484
+ return encode(value);
485
+ } catch {
486
+ return void 0;
487
+ }
488
+ }
489
+
490
+ // src/selectiveReplayRuntime.ts
491
+ function validateSelectiveReplayOptions(options) {
492
+ const validNodes = (nodes) => Array.isArray(nodes) && nodes.length <= 100 && nodes.every(
493
+ (node) => typeof node?.traceFunctionKey === "string" && node.traceFunctionKey.length > 0 && node.traceFunctionKey.length <= 500 && typeof node.spanName === "string" && node.spanName.length > 0 && node.spanName.length <= 500
494
+ );
495
+ if (!options || !validNodes(options.mustRun) || options.mustRun.length === 0 || Object.keys(options).some((key) => key !== "mustRun")) {
496
+ throw new BitfabError(
497
+ "experimentalSelectiveReplay accepts only 1\u2013100 mustRun with traceFunctionKey and spanName. Declare replayReusable on eligible spans, not reusableNodes in the replay request."
498
+ );
499
+ }
500
+ }
501
+ function policyKey(options) {
502
+ return JSON.stringify(options.mustRun.map(replayNodeKey).sort());
503
+ }
504
+ var SelectiveReplayRuntime = class {
505
+ constructor(plan, options) {
506
+ this.plan = plan;
507
+ this.options = options;
508
+ this.nodes = /* @__PURE__ */ new Map();
509
+ this.children = /* @__PURE__ */ new Map();
510
+ this.runtimeParents = /* @__PURE__ */ new Map();
511
+ this.consumed = /* @__PURE__ */ new Map();
512
+ this.requiredScopes = /* @__PURE__ */ new Set();
513
+ this.recordings = /* @__PURE__ */ new Map();
514
+ this.reached = /* @__PURE__ */ new Set();
515
+ this.decisions = [];
516
+ this.assertionNames = /* @__PURE__ */ new Set();
517
+ this.assertionScopes = /* @__PURE__ */ new Set();
518
+ this.observedNames = /* @__PURE__ */ new Map();
519
+ this.unresolvedAssertions = [];
520
+ validateSelectiveReplayOptions(options);
521
+ if (plan?.version !== 4 || !Array.isArray(plan.nodes) || plan.nodes.length === 0 || plan.nodes.length > 500 || !Array.isArray(plan.unresolvedMustRun) || !Array.isArray(plan.assertions) || !plan.options) {
522
+ throw new BitfabError(
523
+ "Server did not return a compatible selective replay plan. Update the server or disable experimentalSelectiveReplay."
524
+ );
525
+ }
526
+ validateSelectiveReplayOptions(plan.options);
527
+ if (policyKey(plan.options) !== policyKey(options)) {
528
+ throw new BitfabError(
529
+ "Selective replay plan does not match the requested mustRun nodes."
530
+ );
531
+ }
532
+ this.required = new Set(options.mustRun.map(replayNodeKey));
533
+ for (const node of plan.nodes) {
534
+ if (typeof node.id !== "string" || this.nodes.has(node.id) || typeof node.traceFunctionKey !== "string" || typeof node.spanName !== "string" || typeof node.mustRun !== "boolean" || typeof node.reusable !== "boolean") {
535
+ throw new BitfabError("Invalid selective replay node.");
536
+ }
537
+ this.nodes.set(node.id, node);
538
+ if (node.recording !== void 0) {
539
+ this.recordings.set(node.id, {
540
+ input: node.recording.kwargs === void 0 ? jsonFingerprint(node.recording.input) : void 0,
541
+ output: jsonFingerprint(node.recording.output)
542
+ });
543
+ }
544
+ if (node.parentId !== null) {
545
+ const siblings = this.children.get(node.parentId) ?? [];
546
+ siblings.push(node);
547
+ this.children.set(node.parentId, siblings);
548
+ }
549
+ }
550
+ const root = this.nodes.get(plan.rootId);
551
+ if (!root || root.parentId !== null || !root.mustRun) {
552
+ throw new BitfabError("Selective replay requires a live recorded root.");
553
+ }
554
+ const assertionIds = /* @__PURE__ */ new Set();
555
+ let wholeTrace = false;
556
+ for (const assertion of plan.assertions) {
557
+ const target = assertion?.target;
558
+ if (typeof assertion?.id !== "string" || assertion.id.length === 0 || assertionIds.has(assertion.id) || target !== null && (typeof target !== "object" || target.kind !== "output" && target.kind !== "span")) {
559
+ throw new BitfabError(
560
+ "Invalid selective replay assertion requirements."
561
+ );
562
+ }
563
+ assertionIds.add(assertion.id);
564
+ if (target === null) {
565
+ wholeTrace = true;
566
+ } else if (target.kind === "span") {
567
+ if (typeof target.name !== "string" || target.name.length === 0 || target.occurrence !== void 0 && target.occurrence !== "first" && target.occurrence !== "last" && !(Number.isInteger(target.occurrence) && typeof target.occurrence === "number" && target.occurrence >= 0)) {
568
+ throw new BitfabError("Invalid selective replay assertion target.");
569
+ }
570
+ this.assertionNames.add(target.name);
571
+ const count = plan.nodes.filter(
572
+ (node) => node.spanName === target.name
573
+ ).length;
574
+ if (count <= (typeof target.occurrence === "number" ? target.occurrence : 0)) {
575
+ this.unresolvedAssertions.push(assertion.id);
576
+ }
577
+ }
578
+ }
579
+ this.fullTraceForAssertions = wholeTrace || this.unresolvedAssertions.length > 0;
580
+ const recordedKeys = new Set(plan.nodes.map(replayNodeKey));
581
+ const unresolved = options.mustRun.filter(
582
+ (node) => !recordedKeys.has(replayNodeKey(node))
583
+ );
584
+ if (JSON.stringify(unresolved.map(replayNodeKey).sort()) !== JSON.stringify(plan.unresolvedMustRun.map(replayNodeKey).sort())) {
585
+ throw new BitfabError(
586
+ "Selective replay plan has incomplete mustRun coverage."
587
+ );
588
+ }
589
+ for (const node of plan.nodes) {
590
+ const ancestors = /* @__PURE__ */ new Set([node.id]);
591
+ let requiredByManifest = this.required.has(replayNodeKey(node));
592
+ let requiredForAssertion = this.fullTraceForAssertions || this.assertionNames.has(node.spanName);
593
+ let parentId = node.parentId;
594
+ while (parentId !== null) {
595
+ const parent = this.nodes.get(parentId);
596
+ if (!parent || ancestors.has(parentId) || node.mustRun && !parent.mustRun) {
597
+ throw new BitfabError("Invalid selective replay ancestry.");
598
+ }
599
+ ancestors.add(parentId);
600
+ requiredByManifest || (requiredByManifest = this.required.has(replayNodeKey(parent)));
601
+ requiredForAssertion || (requiredForAssertion = this.assertionNames.has(parent.spanName));
602
+ parentId = parent.parentId;
603
+ }
604
+ if (!ancestors.has(plan.rootId) || (requiredByManifest || unresolved.length > 0) && !node.mustRun) {
605
+ throw new BitfabError("Selective replay plan could hide required code.");
606
+ }
607
+ if (requiredForAssertion && !node.mustRun) {
608
+ throw new BitfabError(
609
+ "Selective replay plan could hide assertion evidence."
610
+ );
611
+ }
612
+ }
613
+ }
614
+ enter(params) {
615
+ const identity = {
616
+ traceFunctionKey: params.traceFunctionKey,
617
+ spanName: params.spanName
618
+ };
619
+ const key = replayNodeKey(identity);
620
+ const fingerprint = jsonFingerprint(params.inputs);
621
+ let node;
622
+ let matchReason = "unmatched-call";
623
+ if (params.parentSpanId === null) {
624
+ node = this.nodes.get(this.plan.rootId);
625
+ } else {
626
+ const recordedParent = this.runtimeParents.get(params.parentSpanId);
627
+ const consumed = this.consumed.get(params.parentSpanId) ?? /* @__PURE__ */ new Set();
628
+ this.consumed.set(params.parentSpanId, consumed);
629
+ const candidates = recordedParent ? (this.children.get(recordedParent) ?? []).filter(
630
+ (candidate) => replayNodeKey(candidate) === key && !consumed.has(candidate.id)
631
+ ) : [];
632
+ const exact = fingerprint === void 0 ? [] : candidates.filter(
633
+ (candidate) => this.recordings.get(candidate.id)?.input === fingerprint
634
+ );
635
+ node = exact.length === 1 ? exact[0] : exact.length === 0 && candidates.length === 1 ? candidates[0] : void 0;
636
+ if (node) {
637
+ consumed.add(node.id);
638
+ } else if (candidates.length > 0) {
639
+ matchReason = "ambiguous-call";
640
+ for (const candidate of candidates) {
641
+ consumed.add(candidate.id);
642
+ }
643
+ }
644
+ }
645
+ this.runtimeParents.set(params.spanId, node?.id ?? null);
646
+ const requiredByManifest = this.required.has(key) || params.parentSpanId !== null && this.requiredScopes.has(params.parentSpanId);
647
+ if (requiredByManifest) {
648
+ this.requiredScopes.add(params.spanId);
649
+ }
650
+ const requiredForAssertion = this.fullTraceForAssertions || this.assertionNames.has(params.spanName) || params.parentSpanId !== null && this.assertionScopes.has(params.parentSpanId);
651
+ if (requiredForAssertion) {
652
+ this.assertionScopes.add(params.spanId);
653
+ }
654
+ const mustRun = params.parentSpanId === null || requiredByManifest || node?.mustRun === true || requiredForAssertion || this.plan.unresolvedMustRun.length > 0;
655
+ const recording = node === void 0 ? void 0 : this.recordings.get(node.id);
656
+ const equalInputs = fingerprint !== void 0 && recording?.input === fingerprint;
657
+ const reusable = recording?.output !== void 0 && equalInputs && params.canReuseOutput;
658
+ const reason = mustRun ? requiredByManifest ? "must-run" : requiredForAssertion ? "assertion" : node?.reason ?? "unresolved-must-run" : !node ? matchReason : !equalInputs ? "input-drift-or-missing-recording" : !params.canReuseOutput ? "unsupported-output-boundary" : !params.safetyMock && !params.reuseAllowed ? "reuse-not-declared" : node.reason;
659
+ const decision = (action, why) => {
660
+ this.decisions.push({
661
+ ...identity,
662
+ originalSpanId: node?.id ?? null,
663
+ action,
664
+ reason: why
665
+ });
666
+ };
667
+ if (params.safetyMock && (mustRun || !reusable)) {
668
+ decision("blocked", `safety-conflict:${reason}`);
669
+ this.failure = new BitfabError(
670
+ `Selective replay cannot execute or safely reuse safety-mocked node ${params.spanName} (${reason}).`
671
+ );
672
+ throw this.failure;
673
+ }
674
+ if (!mustRun && reusable && (params.safetyMock || node?.reusable === true && params.reuseAllowed)) {
675
+ decision("mock", params.safetyMock ? "safety-mock" : "unchanged-inputs");
676
+ return {
677
+ mock: true,
678
+ output: JSON.parse(recording.output)
679
+ };
680
+ }
681
+ decision("run", reason);
682
+ this.observedNames.set(
683
+ params.spanName,
684
+ (this.observedNames.get(params.spanName) ?? 0) + 1
685
+ );
686
+ if (this.required.has(key)) {
687
+ this.reached.add(key);
688
+ }
689
+ return { mock: false };
690
+ }
691
+ assertNoSafetyConflict() {
692
+ if (this.failure) {
693
+ throw this.failure;
694
+ }
695
+ }
696
+ report() {
697
+ return {
698
+ decisions: this.decisions,
699
+ mustRunNotReached: this.options.mustRun.filter(
700
+ (node) => !this.reached.has(replayNodeKey(node))
701
+ ),
702
+ unresolvedMustRun: this.plan.unresolvedMustRun,
703
+ assertionIds: this.plan.assertions.map((assertion) => assertion.id),
704
+ unresolvedAssertions: this.unresolvedAssertions,
705
+ assertionTargetsNotReached: this.plan.assertions.flatMap(
706
+ ({ id, target }) => target?.kind === "span" && (this.observedNames.get(target.name) ?? 0) <= (typeof target.occurrence === "number" ? target.occurrence : 0) ? [id] : []
707
+ )
708
+ };
709
+ }
710
+ };
711
+
440
712
  // src/replay.ts
441
713
  var REPLAY_PERSISTENCE_TIMEOUT_MS = 3e4;
442
714
  var MAX_REPLAY_ATTEMPTS = 100;
@@ -454,7 +726,8 @@ var RESUME_CONFLICTING_OPTIONS = [
454
726
  "attempts",
455
727
  "graderIds",
456
728
  "onlyWithAssertions",
457
- "dryRun"
729
+ "dryRun",
730
+ "experimentalSelectiveReplay"
458
731
  ];
459
732
  var CARRIED_OVER_ERROR = "This item errored in an earlier run of this experiment, before it was resumed.";
460
733
  function validateResume(resume, options) {
@@ -715,7 +988,7 @@ function buildMockTree(rootNode) {
715
988
  }
716
989
  return { spans };
717
990
  }
718
- async function processItem(httpClient, serverItem, fn, experimentId, mockStrategy, resolvedOverrides, replayedTraceId, attempt, includeDbBranchLease, dbBranchSettings, adaptInputs, dryRun) {
991
+ async function processItem(httpClient, serverItem, fn, experimentId, mockStrategy, resolvedOverrides, replayedTraceId, attempt, includeDbBranchLease, dbBranchSettings, adaptInputs, dryRun, selectiveOptions) {
719
992
  let lease = includeDbBranchLease ? serverItem.dbBranchLease : void 0;
720
993
  let leaseError = includeDbBranchLease ? serverItem.dbBranchLeaseError : void 0;
721
994
  let dbSnapshotRef = serverItem.dbSnapshotRef;
@@ -728,6 +1001,7 @@ async function processItem(httpClient, serverItem, fn, experimentId, mockStrateg
728
1001
  let replayError = null;
729
1002
  let replayDurationMs = null;
730
1003
  let replayStarted = null;
1004
+ let selectiveReplay;
731
1005
  const originalTraceId = serverItem.originalTraceId ?? serverItem.sourceTraceId;
732
1006
  const originalSpanId = serverItem.originalSpanId ?? serverItem.sourceSpanId;
733
1007
  try {
@@ -760,6 +1034,17 @@ async function processItem(httpClient, serverItem, fn, experimentId, mockStrateg
760
1034
  originalTraceId
761
1035
  );
762
1036
  }
1037
+ if (selectiveOptions !== void 0) {
1038
+ if (serverItem.selectiveReplayPlan === void 0) {
1039
+ throw new BitfabError(
1040
+ "Server did not return a selective replay plan. Update the server or disable experimentalSelectiveReplay."
1041
+ );
1042
+ }
1043
+ selectiveReplay = new SelectiveReplayRuntime(
1044
+ serverItem.selectiveReplayPlan,
1045
+ selectiveOptions
1046
+ );
1047
+ }
763
1048
  const span = await httpClient.getExternalSpan(originalSpanId, {
764
1049
  view: "replay"
765
1050
  });
@@ -779,7 +1064,7 @@ async function processItem(httpClient, serverItem, fn, experimentId, mockStrateg
779
1064
  });
780
1065
  }
781
1066
  const hasOverrides = resolvedOverrides.length > 0;
782
- const needTree = mockStrategy === "all" || mockStrategy === "marked" || hasOverrides;
1067
+ const needTree = selectiveReplay === void 0 && (mockStrategy === "all" || mockStrategy === "marked" || hasOverrides);
783
1068
  const includeOutputs = mockStrategy === "all";
784
1069
  let mockTree;
785
1070
  if (needTree) {
@@ -854,6 +1139,7 @@ async function processItem(httpClient, serverItem, fn, experimentId, mockStrateg
854
1139
  sourceBitfabTraceId: originalTraceId,
855
1140
  replayAttempt: attempt,
856
1141
  mockTree,
1142
+ selectiveReplay,
857
1143
  callCounters: mockTree ? /* @__PURE__ */ new Map() : void 0,
858
1144
  mockStrategy,
859
1145
  mockOverrides: hasOverrides ? resolvedOverrides : void 0,
@@ -865,6 +1151,7 @@ async function processItem(httpClient, serverItem, fn, experimentId, mockStrateg
865
1151
  () => fn(...inputs)
866
1152
  );
867
1153
  result = maybePromise instanceof Promise ? await maybePromise : maybePromise;
1154
+ selectiveReplay?.assertNoSafetyConflict();
868
1155
  replayDurationMs = Math.round(performance.now() - replayStarted);
869
1156
  } catch (e) {
870
1157
  if (replayStarted !== null) {
@@ -916,6 +1203,7 @@ async function processItem(httpClient, serverItem, fn, experimentId, mockStrateg
916
1203
  traceError,
917
1204
  replayError,
918
1205
  durationMs: replayDurationMs,
1206
+ ...selectiveReplay === void 0 ? {} : { selectiveReplay: selectiveReplay.report() },
919
1207
  originalDurationMs,
920
1208
  originalTokens: serverItem.originalTokens ?? serverItem.tokens ?? null,
921
1209
  originalModel,
@@ -1020,6 +1308,14 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
1020
1308
  "force only applies when resuming an experiment. Pass it together with resume."
1021
1309
  );
1022
1310
  }
1311
+ if (options?.experimentalSelectiveReplay !== void 0) {
1312
+ validateSelectiveReplayOptions(options.experimentalSelectiveReplay);
1313
+ if ((options.mock ?? "marked") !== "marked" || normalizeMockOverrides(options.mockOverride).length > 0 || registeredOverrides.length > 0) {
1314
+ throw new BitfabError(
1315
+ "experimentalSelectiveReplay requires mock: 'marked' and cannot be combined with mock overrides."
1316
+ );
1317
+ }
1318
+ }
1023
1319
  if (options?.traceIds !== void 0) {
1024
1320
  if (options.traceIds.length === 0) {
1025
1321
  throw new BitfabError("traceIds must contain at least one trace ID.");
@@ -1081,7 +1377,8 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
1081
1377
  requestedAttempts,
1082
1378
  options?.adaptInputs !== void 0,
1083
1379
  options?.onlyWithAssertions,
1084
- options?.judgeAssertions
1380
+ options?.judgeAssertions,
1381
+ options?.experimentalSelectiveReplay
1085
1382
  );
1086
1383
  if (started2.items.length === 0) {
1087
1384
  try {
@@ -1143,7 +1440,8 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
1143
1440
  session.includeDbBranchLease,
1144
1441
  session.dbBranchSettings,
1145
1442
  options?.adaptInputs,
1146
- options?.dryRun === true
1443
+ options?.dryRun === true,
1444
+ options?.experimentalSelectiveReplay
1147
1445
  )
1148
1446
  );
1149
1447
  const total = tasks.length + carriedOverItems.length;
@@ -1216,6 +1514,7 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
1216
1514
  traceError: item.traceError,
1217
1515
  replayError: item.replayError,
1218
1516
  durationMs: item.durationMs,
1517
+ ...item.selectiveReplay === void 0 ? {} : { selectiveReplay: item.selectiveReplay },
1219
1518
  originalDurationMs: item.originalDurationMs,
1220
1519
  originalTokens: item.originalTokens,
1221
1520
  originalModel: item.originalModel,
@@ -1403,4 +1702,4 @@ export {
1403
1702
  sleepForReplayPersistence,
1404
1703
  replay
1405
1704
  };
1406
- //# sourceMappingURL=chunk-A4UVO6BQ.js.map
1705
+ //# sourceMappingURL=chunk-IZUZ5NBB.js.map