bitfab 0.54.10 → 0.54.12

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.
@@ -19,7 +19,7 @@ import {
19
19
  serializeValue,
20
20
  toJsonSafe,
21
21
  toJsonSafeReport
22
- } from "./chunk-PRXW4B5X.js";
22
+ } from "./chunk-ZR4HGK6G.js";
23
23
  import {
24
24
  BitfabError,
25
25
  DEFAULT_SERVICE_URL,
@@ -36,7 +36,7 @@ import {
36
36
  recordCallerTraceMetadata,
37
37
  retireTraceMetadata,
38
38
  warnOnce
39
- } from "./chunk-B2O33DBH.js";
39
+ } from "./chunk-WKXLCFLT.js";
40
40
  import {
41
41
  __privateAdd,
42
42
  __privateGet,
@@ -2441,6 +2441,83 @@ var BitfabOpenAIAgentHandler = class {
2441
2441
  }
2442
2442
  };
2443
2443
 
2444
+ // src/openaiAgentsSpanContext.ts
2445
+ var OPENAI_AGENTS_CONTEXT_STORAGE = /* @__PURE__ */ Symbol.for(
2446
+ "openai.agents.core.asyncLocalStorage"
2447
+ );
2448
+ var MAX_OPENAI_AGENTS_SPAN_CHAIN = 64;
2449
+ var spanGlobal = globalThis;
2450
+ var state = spanGlobal.__bitfabOpenAiAgentsSpansV1 ?? {
2451
+ bitfabTraceIds: /* @__PURE__ */ new Map(),
2452
+ endedSpanIds: /* @__PURE__ */ new Map()
2453
+ };
2454
+ spanGlobal.__bitfabOpenAiAgentsSpansV1 = state;
2455
+ function mapOpenAiAgentsTrace(agentsTraceId, bitfabTraceId) {
2456
+ state.bitfabTraceIds.set(agentsTraceId, bitfabTraceId);
2457
+ }
2458
+ function unmapOpenAiAgentsTrace(agentsTraceId) {
2459
+ state.bitfabTraceIds.delete(agentsTraceId);
2460
+ state.endedSpanIds.delete(agentsTraceId);
2461
+ }
2462
+ function endOpenAiAgentsSpan(agentsTraceId, spanId) {
2463
+ if (!state.bitfabTraceIds.has(agentsTraceId)) {
2464
+ return;
2465
+ }
2466
+ const ended = state.endedSpanIds.get(agentsTraceId) ?? /* @__PURE__ */ new Set();
2467
+ ended.add(spanId);
2468
+ state.endedSpanIds.set(agentsTraceId, ended);
2469
+ }
2470
+ function isOpenAiAgentsContextStorage(value) {
2471
+ return value !== null && typeof value === "object" && typeof value.getStore === "function";
2472
+ }
2473
+ function currentOpenAiAgentsSpan() {
2474
+ const storage2 = spanGlobal[OPENAI_AGENTS_CONTEXT_STORAGE];
2475
+ if (!isOpenAiAgentsContextStorage(storage2)) {
2476
+ return void 0;
2477
+ }
2478
+ try {
2479
+ const store = storage2.getStore();
2480
+ return store?.active === true ? store.span ?? void 0 : void 0;
2481
+ } catch {
2482
+ return void 0;
2483
+ }
2484
+ }
2485
+ function currentOpenAiAgentsSpans() {
2486
+ const spans = [];
2487
+ let span = currentOpenAiAgentsSpan();
2488
+ while (span !== void 0 && spans.length < MAX_OPENAI_AGENTS_SPAN_CHAIN) {
2489
+ spans.push(span);
2490
+ span = span.previousSpan ?? void 0;
2491
+ }
2492
+ return spans;
2493
+ }
2494
+ function openAiAgentsSpanChain() {
2495
+ if (state.bitfabTraceIds.size === 0) {
2496
+ return [];
2497
+ }
2498
+ return currentOpenAiAgentsSpans().map((span) => span.spanId).filter((spanId) => typeof spanId === "string");
2499
+ }
2500
+ function openAiAgentsParentSpanId(bitfabTraceId, enclosingSpanIds) {
2501
+ if (state.bitfabTraceIds.size === 0) {
2502
+ return void 0;
2503
+ }
2504
+ for (const span of currentOpenAiAgentsSpans()) {
2505
+ if (typeof span.spanId !== "string" || typeof span.traceId !== "string") {
2506
+ return void 0;
2507
+ }
2508
+ if (state.bitfabTraceIds.get(span.traceId) !== bitfabTraceId) {
2509
+ return void 0;
2510
+ }
2511
+ if (enclosingSpanIds?.includes(span.spanId)) {
2512
+ return void 0;
2513
+ }
2514
+ if (!state.endedSpanIds.get(span.traceId)?.has(span.spanId)) {
2515
+ return span.spanId;
2516
+ }
2517
+ }
2518
+ return void 0;
2519
+ }
2520
+
2444
2521
  // src/replayBranch.ts
2445
2522
  var _url, _context;
2446
2523
  var ReplayBranch = class {
@@ -2576,18 +2653,42 @@ var RIVET_TOP_LEVEL_EFFECTS = [
2576
2653
  "broadcast",
2577
2654
  "saveState",
2578
2655
  "sleep",
2579
- "destroy"
2656
+ "destroy",
2657
+ "step",
2658
+ "tryStep",
2659
+ "try",
2660
+ "loop",
2661
+ "sleepUntil",
2662
+ "rollbackCheckpoint",
2663
+ "join",
2664
+ "race",
2665
+ "removed",
2666
+ "getVersion"
2580
2667
  ];
2581
2668
  var TOP_LEVEL_UNAVAILABLE_CAPABILITIES = /* @__PURE__ */ new Set([
2582
2669
  "conn",
2583
2670
  "conns",
2584
- "log",
2585
2671
  "request",
2586
2672
  "actorRuntimeSocket",
2587
2673
  "keepAwake",
2588
2674
  "waitUntil",
2589
2675
  "client"
2590
2676
  ]);
2677
+ var replayLog = () => void 0;
2678
+ var replayLogger = {
2679
+ level: "silent",
2680
+ msgPrefix: void 0,
2681
+ fatal: replayLog,
2682
+ trace: replayLog,
2683
+ silent: replayLog,
2684
+ debug: replayLog,
2685
+ info: replayLog,
2686
+ warn: replayLog,
2687
+ error: replayLog,
2688
+ child: () => replayLogger,
2689
+ bindings: () => ({}),
2690
+ isLevelEnabled: () => false
2691
+ };
2591
2692
  var SYNC_VOID_EFFECTS = /* @__PURE__ */ new Set([
2592
2693
  "broadcast",
2593
2694
  "sleep",
@@ -2617,16 +2718,28 @@ function snapshotContext(context) {
2617
2718
  "state",
2618
2719
  "vars",
2619
2720
  "actorId",
2721
+ "workflowId",
2620
2722
  "name",
2621
2723
  "key",
2622
- "region",
2623
- "aborted"
2724
+ "region"
2624
2725
  ]) {
2625
2726
  const value = readProperty(source, property);
2626
2727
  if (value !== void 0) {
2627
2728
  snapshot[property] = value;
2628
2729
  }
2629
2730
  }
2731
+ const aborted = readProperty(source, "aborted");
2732
+ if (typeof aborted === "boolean") {
2733
+ snapshot.aborted = aborted;
2734
+ } else {
2735
+ const abortSignal = readProperty(source, "abortSignal");
2736
+ if (isRecord2(abortSignal)) {
2737
+ const signalAborted = readProperty(abortSignal, "aborted");
2738
+ if (typeof signalAborted === "boolean") {
2739
+ snapshot.aborted = signalAborted;
2740
+ }
2741
+ }
2742
+ }
2630
2743
  return snapshot;
2631
2744
  }
2632
2745
  function unavailableCapability(path) {
@@ -2718,7 +2831,8 @@ var BitfabRivetIntegration = class {
2718
2831
  }
2719
2832
  /**
2720
2833
  * Adapt a traced function into a Rivet handler whose first argument is the
2721
- * live actor context. The context is not added to the traced root's inputs.
2834
+ * live actor or workflow context. The context is not added to the traced
2835
+ * root's inputs.
2722
2836
  */
2723
2837
  bind(fn) {
2724
2838
  const integration = this;
@@ -2729,7 +2843,8 @@ var BitfabRivetIntegration = class {
2729
2843
  /**
2730
2844
  * Return the current Rivet context proxy. In production it delegates to the
2731
2845
  * bound live context. During replay it hydrates recorded actor state and
2732
- * intercepts supported effects without requiring a live Rivet actor.
2846
+ * intercepts supported effects without requiring a live Rivet actor or
2847
+ * workflow.
2733
2848
  */
2734
2849
  getContext() {
2735
2850
  const replay = getReplayContext();
@@ -2813,6 +2928,12 @@ var BitfabRivetIntegration = class {
2813
2928
  if (property === "setPreventSleep" && replay) {
2814
2929
  return (_preventSleep) => void 0;
2815
2930
  }
2931
+ if (property === "isEvicted" && replay) {
2932
+ return () => replayTarget.abortSignal?.aborted === true;
2933
+ }
2934
+ if (property === "log" && replay) {
2935
+ return replayLogger;
2936
+ }
2816
2937
  if (replay && typeof property === "string" && TOP_LEVEL_UNAVAILABLE_CAPABILITIES.has(property)) {
2817
2938
  throw unavailableCapability(property);
2818
2939
  }
@@ -2986,7 +3107,7 @@ var BitfabRivetIntegration = class {
2986
3107
  return { ...value, complete };
2987
3108
  }
2988
3109
  queueCallIsCompletable(effect, args) {
2989
- const options = effect === "queue.waitForNames" ? args[1] : args[0];
3110
+ const options = effect === "queue.waitForNames" || (effect === "queue.next" || effect === "queue.nextBatch") && typeof args[0] === "string" ? args[1] : args[0];
2990
3111
  return isRecord2(options) && options.completable === true;
2991
3112
  }
2992
3113
  createQueueIterator(queue, options) {
@@ -3137,6 +3258,9 @@ var BitfabOpenAITracingProcessor = class {
3137
3258
  const activeContext = this.getActiveSpanContext?.();
3138
3259
  if (activeContext) {
3139
3260
  this.activeSpanMappings[trace.traceId] = activeContext;
3261
+ if (this.shouldRecord()) {
3262
+ mapOpenAiAgentsTrace(trace.traceId, activeContext.traceId);
3263
+ }
3140
3264
  }
3141
3265
  const canonicalTraceId = activeContext?.traceId ?? this.getCanonicalTraceId(trace.traceId);
3142
3266
  this.canonicalTraceIds[trace.traceId] = canonicalTraceId;
@@ -3174,6 +3298,7 @@ var BitfabOpenAITracingProcessor = class {
3174
3298
  }
3175
3299
  this.endedTraces.delete(traceId);
3176
3300
  delete this.activeSpanMappings[traceId];
3301
+ unmapOpenAiAgentsTrace(traceId);
3177
3302
  delete this.canonicalTraceIds[traceId];
3178
3303
  delete this.activeTraces[traceId];
3179
3304
  }
@@ -3198,6 +3323,9 @@ var BitfabOpenAITracingProcessor = class {
3198
3323
  async onSpanEnd(span) {
3199
3324
  const originalTraceId = span.traceId ?? "";
3200
3325
  const traceId = this.activeSpanMappings[originalTraceId]?.traceId ?? originalTraceId;
3326
+ if (span.spanId !== void 0) {
3327
+ endOpenAiAgentsSpan(originalTraceId, span.spanId);
3328
+ }
3201
3329
  try {
3202
3330
  this.sendSpan(span);
3203
3331
  } finally {
@@ -3218,6 +3346,9 @@ var BitfabOpenAITracingProcessor = class {
3218
3346
  * Called when the trace processor is shutting down.
3219
3347
  */
3220
3348
  async shutdown(timeout) {
3349
+ for (const traceId of Object.keys(this.activeSpanMappings)) {
3350
+ unmapOpenAiAgentsTrace(traceId);
3351
+ }
3221
3352
  this.activeTraces = {};
3222
3353
  this.activeSpanMappings = {};
3223
3354
  this.canonicalTraceIds = {};
@@ -4374,16 +4505,16 @@ var Bitfab = class {
4374
4505
  this.simulationPlan.send(payload, rootTraceFunctionKeyOf(payload), submit);
4375
4506
  }
4376
4507
  refreshAutoTraceCapturePolicy(traceFunctionKey) {
4377
- const state = this.autoTracePolicyRefreshes.get(traceFunctionKey) ?? new PolicyRefresh();
4378
- this.autoTracePolicyRefreshes.set(traceFunctionKey, state);
4379
- state.run(
4508
+ const state2 = this.autoTracePolicyRefreshes.get(traceFunctionKey) ?? new PolicyRefresh();
4509
+ this.autoTracePolicyRefreshes.set(traceFunctionKey, state2);
4510
+ state2.run(
4380
4511
  () => this.httpClient.getAutoTracePolicy(
4381
4512
  traceFunctionKey,
4382
4513
  AUTO_TRACE_PROTOCOL
4383
4514
  ),
4384
4515
  (policy) => {
4385
4516
  if (policy.protocol !== AUTO_TRACE_PROTOCOL) {
4386
- state.hold(AUTO_TRACE_POLICY_RETRY_MS);
4517
+ state2.hold(AUTO_TRACE_POLICY_RETRY_MS);
4387
4518
  return;
4388
4519
  }
4389
4520
  const functionIds = Array.isArray(policy.functionIds) ? policy.functionIds.filter(
@@ -4394,10 +4525,10 @@ var Bitfab = class {
4394
4525
  traceFunctionKey,
4395
4526
  policy.revision === null ? void 0 : functionIds
4396
4527
  );
4397
- state.hold(AUTO_TRACE_POLICY_REFRESH_MS);
4528
+ state2.hold(AUTO_TRACE_POLICY_REFRESH_MS);
4398
4529
  },
4399
4530
  () => {
4400
- state.hold(AUTO_TRACE_POLICY_RETRY_MS);
4531
+ state2.hold(AUTO_TRACE_POLICY_RETRY_MS);
4401
4532
  }
4402
4533
  );
4403
4534
  }
@@ -4703,9 +4834,9 @@ var Bitfab = class {
4703
4834
  });
4704
4835
  }
4705
4836
  /**
4706
- * Get the first-class Rivet actor-context integration for an existing trace
4707
- * root. The integration binds context and records effect spans; it never
4708
- * creates another root.
4837
+ * Get the first-class Rivet actor/workflow-context integration for an
4838
+ * existing trace root. The integration binds context and records effect
4839
+ * spans; it never creates another root.
4709
4840
  *
4710
4841
  * @param traceFunctionKey - Key used by the enclosing `withTrace()` root
4711
4842
  * @param options - Explicit per-context-path replay mocking policy
@@ -5008,7 +5139,11 @@ var Bitfab = class {
5008
5139
  const seedCtxForTraceId = parentContext ? null : getSeedContext();
5009
5140
  const traceId = parentContext?.traceId ?? replayCtxForTraceId?.traceId ?? seedCtxForTraceId?.traceId ?? randomUuid();
5010
5141
  const spanId = randomUuid();
5011
- const parentSpanId = parentContext?.spanId ?? null;
5142
+ const openAiAgentsParent = parentContext !== void 0 && options.instrumentation === "trace" ? openAiAgentsParentSpanId(
5143
+ parentContext.traceId,
5144
+ parentContext.openAiAgentsSpanIds
5145
+ ) : void 0;
5146
+ const parentSpanId = openAiAgentsParent ?? parentContext?.spanId ?? null;
5012
5147
  const isRootSpan = parentSpanId === null;
5013
5148
  if (options.enclosingTrace !== void 0) {
5014
5149
  options.enclosingTrace.link.traceId = traceId;
@@ -5022,11 +5157,13 @@ var Bitfab = class {
5022
5157
  parentContext?.surface,
5023
5158
  traceFunctionKey
5024
5159
  );
5160
+ const openAiAgentsSpanIds = openAiAgentsSpanChain();
5025
5161
  const newContext = {
5026
5162
  traceId,
5027
5163
  spanId,
5028
5164
  contexts: [],
5029
- ...surface !== void 0 && { surface }
5165
+ ...surface !== void 0 && { surface },
5166
+ ...openAiAgentsSpanIds.length > 0 && { openAiAgentsSpanIds }
5030
5167
  };
5031
5168
  newStack = [...currentStack, newContext];
5032
5169
  const inputs = args;
@@ -5801,7 +5938,7 @@ var Bitfab = class {
5801
5938
  await runWithSeedContext({ traceId }, async () => target(...args));
5802
5939
  } finally {
5803
5940
  try {
5804
- const { flushTraces: flushTraces2 } = await import("./http-AVWWAMFV.js");
5941
+ const { flushTraces: flushTraces2 } = await import("./http-NWSSB5FA.js");
5805
5942
  await flushTraces2(3e4);
5806
5943
  } finally {
5807
5944
  unrecorded = activeTraceStates.delete(traceId);
@@ -5860,7 +5997,7 @@ var Bitfab = class {
5860
5997
  `Function is wrapped with trace function key '${wrappedKey}' but replay was called with '${traceFunctionKey}'. Pass matching keys, or pass the unwrapped function to replay it under the explicit key.`
5861
5998
  );
5862
5999
  }
5863
- const { replay: doReplay } = await import("./replay-BCWIDCKH.js");
6000
+ const { replay: doReplay } = await import("./replay-WB5NQNQS.js");
5864
6001
  return doReplay(
5865
6002
  this.httpClient,
5866
6003
  this.serviceUrl,
@@ -6180,7 +6317,7 @@ async function seedFromRegistry(registry, pipeline, cases, options = {}) {
6180
6317
  sessionId: seedCase.sessionId
6181
6318
  })
6182
6319
  );
6183
- const { flushTraces: flushTraces2 } = await import("./http-AVWWAMFV.js");
6320
+ const { flushTraces: flushTraces2 } = await import("./http-NWSSB5FA.js");
6184
6321
  await flushTraces2(3e4);
6185
6322
  return { pipeline, traceFunctionKey, traceIds };
6186
6323
  }
@@ -6219,4 +6356,4 @@ export {
6219
6356
  reseedFromRegistry,
6220
6357
  seedFromRegistry
6221
6358
  };
6222
- //# sourceMappingURL=chunk-A3OBQOLV.js.map
6359
+ //# sourceMappingURL=chunk-YY5BB2YS.js.map