bitfab 0.54.9 → 0.54.11

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 (35) hide show
  1. package/dist/{chunk-5EW5MV2Z.js → chunk-2C7M3Y3H.js} +3 -3
  2. package/dist/chunk-2C7M3Y3H.js.map +1 -0
  3. package/dist/{chunk-7HXFT6JR.js → chunk-FMUJONTQ.js} +6 -4
  4. package/dist/chunk-FMUJONTQ.js.map +1 -0
  5. package/dist/{chunk-VT5IUVBY.js → chunk-G4LWALQ7.js} +85 -40
  6. package/dist/chunk-G4LWALQ7.js.map +1 -0
  7. package/dist/{chunk-UKKR2PF4.js → chunk-MEJOPEKV.js} +710 -16
  8. package/dist/chunk-MEJOPEKV.js.map +1 -0
  9. package/dist/{chunk-TOCJX6OP.js → chunk-RUBVHBIK.js} +4 -3
  10. package/dist/chunk-RUBVHBIK.js.map +1 -0
  11. package/dist/{http-WQ6YWRTW.js → http-AXPT27DO.js} +2 -2
  12. package/dist/{http-HYJYQTX2.js → http-JQN2LHHF.js} +2 -2
  13. package/dist/index.cjs +801 -47
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.d.cts +130 -2
  16. package/dist/index.d.ts +130 -2
  17. package/dist/index.js +5 -3
  18. package/dist/node.cjs +801 -47
  19. package/dist/node.cjs.map +1 -1
  20. package/dist/node.d.cts +1 -1
  21. package/dist/node.d.ts +1 -1
  22. package/dist/node.js +5 -3
  23. package/dist/node.js.map +1 -1
  24. package/dist/{replay-MISWCCCG.js → replay-DOG4KV7I.js} +3 -3
  25. package/dist/replayCli.js +2 -2
  26. package/dist/seedCli.js +2 -2
  27. package/package.json +1 -1
  28. package/dist/chunk-5EW5MV2Z.js.map +0 -1
  29. package/dist/chunk-7HXFT6JR.js.map +0 -1
  30. package/dist/chunk-TOCJX6OP.js.map +0 -1
  31. package/dist/chunk-UKKR2PF4.js.map +0 -1
  32. package/dist/chunk-VT5IUVBY.js.map +0 -1
  33. /package/dist/{http-HYJYQTX2.js.map → http-AXPT27DO.js.map} +0 -0
  34. /package/dist/{http-WQ6YWRTW.js.map → http-JQN2LHHF.js.map} +0 -0
  35. /package/dist/{replay-MISWCCCG.js.map → replay-DOG4KV7I.js.map} +0 -0
@@ -11,6 +11,7 @@ import {
11
11
  } from "./chunk-EGWJYCNT.js";
12
12
  import {
13
13
  NO_MOCK_OVERRIDE,
14
+ createIntegrationFixtureContext,
14
15
  deserializeInputs,
15
16
  deserializeValue,
16
17
  randomUuid,
@@ -18,7 +19,7 @@ import {
18
19
  serializeValue,
19
20
  toJsonSafe,
20
21
  toJsonSafeReport
21
- } from "./chunk-VT5IUVBY.js";
22
+ } from "./chunk-G4LWALQ7.js";
22
23
  import {
23
24
  BitfabError,
24
25
  DEFAULT_SERVICE_URL,
@@ -35,7 +36,7 @@ import {
35
36
  recordCallerTraceMetadata,
36
37
  retireTraceMetadata,
37
38
  warnOnce
38
- } from "./chunk-7HXFT6JR.js";
39
+ } from "./chunk-FMUJONTQ.js";
39
40
  import {
40
41
  __privateAdd,
41
42
  __privateGet,
@@ -2440,6 +2441,83 @@ var BitfabOpenAIAgentHandler = class {
2440
2441
  }
2441
2442
  };
2442
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
+
2443
2521
  // src/replayBranch.ts
2444
2522
  var _url, _context;
2445
2523
  var ReplayBranch = class {
@@ -2485,6 +2563,527 @@ var ReplayBranch = class {
2485
2563
  _url = new WeakMap();
2486
2564
  _context = new WeakMap();
2487
2565
 
2566
+ // src/rivetContext.ts
2567
+ var storage = null;
2568
+ var browserBinding = null;
2569
+ var STORAGE_SYMBOL = /* @__PURE__ */ Symbol.for("bitfab.rivetContextStorage");
2570
+ function initializeStorage() {
2571
+ if (storage) {
2572
+ return;
2573
+ }
2574
+ const shared = globalThis;
2575
+ const existing = shared[STORAGE_SYMBOL];
2576
+ if (existing) {
2577
+ storage = existing;
2578
+ return;
2579
+ }
2580
+ const created = createAsyncLocalStorage();
2581
+ if (created) {
2582
+ shared[STORAGE_SYMBOL] = created;
2583
+ storage = created;
2584
+ }
2585
+ }
2586
+ var rivetContextReady = asyncStorageReady.then(() => {
2587
+ initializeStorage();
2588
+ });
2589
+ function getRivetContextBinding() {
2590
+ initializeStorage();
2591
+ return storage?.getStore() ?? browserBinding ?? void 0;
2592
+ }
2593
+ function runWithBrowserBinding(binding, fn) {
2594
+ const previous = browserBinding;
2595
+ browserBinding = binding;
2596
+ try {
2597
+ const result = fn();
2598
+ if (result instanceof Promise) {
2599
+ return result.finally(() => {
2600
+ browserBinding = previous;
2601
+ });
2602
+ }
2603
+ browserBinding = previous;
2604
+ return result;
2605
+ } catch (error) {
2606
+ browserBinding = previous;
2607
+ throw error;
2608
+ }
2609
+ }
2610
+ function runWithRivetContext(binding, fn) {
2611
+ initializeStorage();
2612
+ if (!storage && !isAsyncStorageInitDone()) {
2613
+ return rivetContextReady.then(() => runWithRivetContext(binding, fn));
2614
+ }
2615
+ if (storage) {
2616
+ return storage.run(binding, fn);
2617
+ }
2618
+ return runWithBrowserBinding(binding, fn);
2619
+ }
2620
+
2621
+ // src/rivetIntegration.ts
2622
+ var RIVET_DOCS_URL = "https://docs.bitfab.ai/frameworks/rivet";
2623
+ var RIVET_GROUP_EFFECT_METHODS = {
2624
+ db: ["execute", "nativeMetrics", "close"],
2625
+ kv: [
2626
+ "get",
2627
+ "put",
2628
+ "delete",
2629
+ "batchPut",
2630
+ "batchGet",
2631
+ "batchDelete",
2632
+ "deleteRange",
2633
+ "listPrefix",
2634
+ "listRange",
2635
+ "list"
2636
+ ],
2637
+ schedule: ["after", "at", "cancel", "get", "list"],
2638
+ cron: ["set", "every", "get", "list", "delete", "history"],
2639
+ queue: [
2640
+ "send",
2641
+ "next",
2642
+ "nextBatch",
2643
+ "waitForNames",
2644
+ "waitForAvailable",
2645
+ "complete",
2646
+ "enqueueAndWait",
2647
+ "tryNext",
2648
+ "tryNextBatch"
2649
+ ],
2650
+ run: ["setWakeAt"]
2651
+ };
2652
+ var RIVET_TOP_LEVEL_EFFECTS = [
2653
+ "broadcast",
2654
+ "saveState",
2655
+ "sleep",
2656
+ "destroy"
2657
+ ];
2658
+ var TOP_LEVEL_UNAVAILABLE_CAPABILITIES = /* @__PURE__ */ new Set([
2659
+ "conn",
2660
+ "conns",
2661
+ "log",
2662
+ "request",
2663
+ "actorRuntimeSocket",
2664
+ "keepAwake",
2665
+ "waitUntil",
2666
+ "client"
2667
+ ]);
2668
+ var SYNC_VOID_EFFECTS = /* @__PURE__ */ new Set([
2669
+ "broadcast",
2670
+ "sleep",
2671
+ "destroy"
2672
+ ]);
2673
+ var QUEUE_MESSAGE_EFFECTS = /* @__PURE__ */ new Set([
2674
+ "queue.next",
2675
+ "queue.nextBatch",
2676
+ "queue.waitForNames",
2677
+ "queue.tryNext",
2678
+ "queue.tryNextBatch"
2679
+ ]);
2680
+ function isRecord2(value) {
2681
+ return typeof value === "object" && value !== null;
2682
+ }
2683
+ function readProperty(value, property) {
2684
+ try {
2685
+ return Reflect.get(value, property, value);
2686
+ } catch {
2687
+ return void 0;
2688
+ }
2689
+ }
2690
+ function snapshotContext(context) {
2691
+ const source = context;
2692
+ const snapshot = {};
2693
+ for (const property of [
2694
+ "state",
2695
+ "vars",
2696
+ "actorId",
2697
+ "name",
2698
+ "key",
2699
+ "region",
2700
+ "aborted"
2701
+ ]) {
2702
+ const value = readProperty(source, property);
2703
+ if (value !== void 0) {
2704
+ snapshot[property] = value;
2705
+ }
2706
+ }
2707
+ return snapshot;
2708
+ }
2709
+ function unavailableCapability(path) {
2710
+ return new BitfabError(
2711
+ `Rivet context capability "${path}" is unavailable during replay. Add first-class support for that public context path before replaying code that uses it.`,
2712
+ RIVET_DOCS_URL
2713
+ );
2714
+ }
2715
+ function effectNode(traceFunctionKey, effect, mockSpanId) {
2716
+ return {
2717
+ traceFunctionKey,
2718
+ spanName: effect,
2719
+ type: "function",
2720
+ originalSpanId: mockSpanId
2721
+ };
2722
+ }
2723
+ function replayEffectStatus(replay, traceFunctionKey, effect, marked) {
2724
+ const counterKey = `${traceFunctionKey}:${effect}`;
2725
+ const callIndex = replay.callCounters?.get(counterKey) ?? 0;
2726
+ const mockSpan = replay.mockTree?.spans.get(`${counterKey}:${callIndex}`);
2727
+ const hasOverride = replay.mockOverrides?.some(
2728
+ (override) => override.match(
2729
+ effectNode(traceFunctionKey, effect, mockSpan?.sourceSpanId)
2730
+ )
2731
+ ) ?? false;
2732
+ return {
2733
+ willMock: hasOverride || replay.mockStrategy === "all" || replay.mockStrategy === "marked" && marked,
2734
+ hasRecordedSpan: mockSpan !== void 0,
2735
+ hasOverride,
2736
+ callIndex
2737
+ };
2738
+ }
2739
+ function assertReplayEffectAvailable(replay, traceFunctionKey, effect, marked) {
2740
+ if (!replay) {
2741
+ return;
2742
+ }
2743
+ const status = replayEffectStatus(replay, traceFunctionKey, effect, marked);
2744
+ if (!status.willMock) {
2745
+ throw new BitfabError(
2746
+ `Rivet effect "${effect}" has no live actor context during replay. Add "${effect}" to mockOnReplay or provide a replay override.`,
2747
+ RIVET_DOCS_URL
2748
+ );
2749
+ }
2750
+ if (!status.hasRecordedSpan && !status.hasOverride) {
2751
+ throw new BitfabError(
2752
+ `No recorded Rivet effect "${effect}" exists at call ${status.callIndex + 1}; the live effect was not executed.`,
2753
+ RIVET_DOCS_URL
2754
+ );
2755
+ }
2756
+ }
2757
+ function fixtureName(traceFunctionKey) {
2758
+ return `rivet:${traceFunctionKey}`;
2759
+ }
2760
+ function snapshotFromReplay(traceFunctionKey, replay) {
2761
+ const fixture = replay.integrationFixtures?.get(fixtureName(traceFunctionKey));
2762
+ if (!isRecord2(fixture)) {
2763
+ throw new BitfabError(
2764
+ `Trace "${traceFunctionKey}" has no Rivet context fixture. Capture a fresh trace with the Rivet integration before replaying it.`,
2765
+ RIVET_DOCS_URL
2766
+ );
2767
+ }
2768
+ return fixture;
2769
+ }
2770
+ var BitfabRivetIntegration = class {
2771
+ /** @internal Constructed by `Bitfab.getRivetIntegration()`. */
2772
+ constructor(traceFunctionKey, runtime, options = {}) {
2773
+ this.traceFunctionKey = traceFunctionKey;
2774
+ this.runtime = runtime;
2775
+ this.replayProxies = /* @__PURE__ */ new WeakMap();
2776
+ this.markedEffects = new Set(options.mockOnReplay ?? []);
2777
+ }
2778
+ /**
2779
+ * Run a callback with a live Rivet context bound to the current async chain.
2780
+ * This binds context only; it creates no trace or span.
2781
+ */
2782
+ withContext(context, fn) {
2783
+ if (!isRecord2(context)) {
2784
+ throw new BitfabError("Rivet withContext requires a context object");
2785
+ }
2786
+ const binding = {
2787
+ context,
2788
+ fixtureContext: createIntegrationFixtureContext(
2789
+ fixtureName(this.traceFunctionKey),
2790
+ snapshotContext(context)
2791
+ ),
2792
+ recordedRoots: /* @__PURE__ */ new Set()
2793
+ };
2794
+ return runWithRivetContext(binding, fn);
2795
+ }
2796
+ /**
2797
+ * Adapt a traced function into a Rivet handler whose first argument is the
2798
+ * live actor context. The context is not added to the traced root's inputs.
2799
+ */
2800
+ bind(fn) {
2801
+ const integration = this;
2802
+ return function(context, ...args) {
2803
+ return integration.withContext(context, () => fn.apply(this, args));
2804
+ };
2805
+ }
2806
+ /**
2807
+ * Return the current Rivet context proxy. In production it delegates to the
2808
+ * bound live context. During replay it hydrates recorded actor state and
2809
+ * intercepts supported effects without requiring a live Rivet actor.
2810
+ */
2811
+ getContext() {
2812
+ const replay = getReplayContext();
2813
+ if (replay) {
2814
+ const existing = this.replayProxies.get(replay);
2815
+ if (existing) {
2816
+ return existing;
2817
+ }
2818
+ const proxy = this.createContextProxy(
2819
+ snapshotFromReplay(this.traceFunctionKey, replay),
2820
+ void 0
2821
+ );
2822
+ this.replayProxies.set(replay, proxy);
2823
+ return proxy;
2824
+ }
2825
+ const binding = getRivetContextBinding();
2826
+ if (!binding) {
2827
+ throw new BitfabError(
2828
+ "No Rivet context is bound. Call rivet.bind(handler) or rivet.withContext(context, callback) at the Rivet boundary.",
2829
+ RIVET_DOCS_URL
2830
+ );
2831
+ }
2832
+ this.runtime.recordRootFixture(
2833
+ binding.fixtureContext,
2834
+ binding.recordedRoots
2835
+ );
2836
+ if (!binding.proxy) {
2837
+ binding.proxy = this.createContextProxy(
2838
+ binding.context,
2839
+ binding
2840
+ );
2841
+ }
2842
+ return binding.proxy;
2843
+ }
2844
+ createContextProxy(target, binding) {
2845
+ const replay = getReplayContext();
2846
+ const dbProxy = this.createDbProxy(binding, replay);
2847
+ const groupProxies = /* @__PURE__ */ new Map();
2848
+ for (const group of Object.keys(
2849
+ RIVET_GROUP_EFFECT_METHODS
2850
+ )) {
2851
+ if (group !== "db") {
2852
+ groupProxies.set(group, this.createGroupProxy(group, binding, replay));
2853
+ }
2854
+ }
2855
+ const topLevelEffects = /* @__PURE__ */ new Map();
2856
+ for (const effect of RIVET_TOP_LEVEL_EFFECTS) {
2857
+ topLevelEffects.set(
2858
+ effect,
2859
+ this.createEffect(
2860
+ effect,
2861
+ () => binding?.context,
2862
+ effect,
2863
+ replay
2864
+ )
2865
+ );
2866
+ }
2867
+ const replayTarget = replay ? { ...target } : target;
2868
+ if (replay) {
2869
+ const controller = new AbortController();
2870
+ if (target.aborted === true) {
2871
+ controller.abort();
2872
+ }
2873
+ replayTarget.abortSignal = controller.signal;
2874
+ }
2875
+ return new Proxy(replayTarget, {
2876
+ get: (source, property) => {
2877
+ if (property === "db") {
2878
+ return dbProxy;
2879
+ }
2880
+ if (typeof property === "string") {
2881
+ const group = groupProxies.get(property);
2882
+ if (group) {
2883
+ return group;
2884
+ }
2885
+ const effect = topLevelEffects.get(property);
2886
+ if (effect) {
2887
+ return effect;
2888
+ }
2889
+ }
2890
+ if (property === "setPreventSleep" && replay) {
2891
+ return (_preventSleep) => void 0;
2892
+ }
2893
+ if (replay && typeof property === "string" && TOP_LEVEL_UNAVAILABLE_CAPABILITIES.has(property)) {
2894
+ throw unavailableCapability(property);
2895
+ }
2896
+ const value = Reflect.get(source, property, source);
2897
+ return typeof value === "function" ? value.bind(source) : value;
2898
+ }
2899
+ });
2900
+ }
2901
+ createDbProxy(binding, replay) {
2902
+ const proxy = this.createGroupProxy("db", binding, replay);
2903
+ return new Proxy(proxy, {
2904
+ get: (source, property) => property === "transaction" ? this.createTransaction(binding, replay) : Reflect.get(source, property, source)
2905
+ });
2906
+ }
2907
+ createGroupProxy(group, binding, replay) {
2908
+ const targetProvider = () => {
2909
+ if (!binding) {
2910
+ return void 0;
2911
+ }
2912
+ const context = binding.context;
2913
+ const target = readProperty(context, group);
2914
+ return isRecord2(target) ? target : void 0;
2915
+ };
2916
+ const proxy = this.createMethodProxy(
2917
+ targetProvider,
2918
+ group,
2919
+ RIVET_GROUP_EFFECT_METHODS[group],
2920
+ replay
2921
+ );
2922
+ if (group !== "queue") {
2923
+ return proxy;
2924
+ }
2925
+ return new Proxy(proxy, {
2926
+ get: (source, property) => property === "iter" ? (options) => this.createQueueIterator(source, options) : Reflect.get(source, property, source)
2927
+ });
2928
+ }
2929
+ createMethodProxy(targetProvider, prefix, methods, replay) {
2930
+ const effects = /* @__PURE__ */ new Map();
2931
+ for (const method of methods) {
2932
+ const effect = `${prefix}.${method}`;
2933
+ effects.set(
2934
+ method,
2935
+ this.createEffect(effect, targetProvider, method, replay)
2936
+ );
2937
+ }
2938
+ return new Proxy(
2939
+ {},
2940
+ {
2941
+ get: (_source, property) => {
2942
+ if (typeof property === "string") {
2943
+ const effect = effects.get(property);
2944
+ if (effect) {
2945
+ return effect;
2946
+ }
2947
+ if (replay) {
2948
+ throw unavailableCapability(`${prefix}.${property}`);
2949
+ }
2950
+ }
2951
+ const target = targetProvider();
2952
+ if (!target) {
2953
+ return void 0;
2954
+ }
2955
+ const value = Reflect.get(target, property, target);
2956
+ return typeof value === "function" ? value.bind(target) : value;
2957
+ }
2958
+ }
2959
+ );
2960
+ }
2961
+ createEffect(effect, targetProvider, methodName, replay) {
2962
+ const marked = this.markedEffects.has(effect);
2963
+ const invoke = (...args) => {
2964
+ assertReplayEffectAvailable(
2965
+ getReplayContext(),
2966
+ this.traceFunctionKey,
2967
+ effect,
2968
+ marked
2969
+ );
2970
+ const target = targetProvider();
2971
+ const method = target ? readProperty(target, methodName) : void 0;
2972
+ if (typeof method !== "function") {
2973
+ throw unavailableCapability(effect);
2974
+ }
2975
+ return method.apply(target, args);
2976
+ };
2977
+ const wrapped = SYNC_VOID_EFFECTS.has(effect) ? this.runtime.wrapEffect(
2978
+ effect,
2979
+ marked,
2980
+ invoke,
2981
+ replay ? () => void 0 : void 0
2982
+ ) : this.runtime.wrapEffect(effect, marked, async (...args) => {
2983
+ return await invoke(...args);
2984
+ });
2985
+ return (...args) => {
2986
+ if (replay) {
2987
+ assertReplayEffectAvailable(
2988
+ replay,
2989
+ this.traceFunctionKey,
2990
+ effect,
2991
+ marked
2992
+ );
2993
+ }
2994
+ const result = wrapped(...args);
2995
+ if (!QUEUE_MESSAGE_EFFECTS.has(effect) || !(result instanceof Promise)) {
2996
+ return result;
2997
+ }
2998
+ return result.then(
2999
+ (value) => this.decorateQueueMessages(value, effect, args, replay)
3000
+ );
3001
+ };
3002
+ }
3003
+ createTransaction(binding, replay) {
3004
+ return async (callback, options) => {
3005
+ if (typeof callback !== "function") {
3006
+ throw new BitfabError("Rivet db.transaction requires a callback");
3007
+ }
3008
+ if (replay) {
3009
+ return await callback(
3010
+ this.createMethodProxy(
3011
+ () => void 0,
3012
+ "db.transaction",
3013
+ ["execute"],
3014
+ replay
3015
+ )
3016
+ );
3017
+ }
3018
+ const context = binding?.context;
3019
+ const db = context ? readProperty(context, "db") : void 0;
3020
+ const transaction = isRecord2(db) ? readProperty(db, "transaction") : void 0;
3021
+ if (!isRecord2(db) || typeof transaction !== "function") {
3022
+ throw unavailableCapability("db.transaction");
3023
+ }
3024
+ return await transaction.call(
3025
+ db,
3026
+ async (transactionDb) => {
3027
+ if (!isRecord2(transactionDb)) {
3028
+ throw unavailableCapability("db.transaction.execute");
3029
+ }
3030
+ return await callback(
3031
+ this.createMethodProxy(
3032
+ () => transactionDb,
3033
+ "db.transaction",
3034
+ ["execute"],
3035
+ replay
3036
+ )
3037
+ );
3038
+ },
3039
+ options
3040
+ );
3041
+ };
3042
+ }
3043
+ decorateQueueMessages(value, effect, args, replay) {
3044
+ if (!this.queueCallIsCompletable(effect, args)) {
3045
+ return value;
3046
+ }
3047
+ if (Array.isArray(value)) {
3048
+ return value.map((message) => this.decorateQueueMessage(message, replay));
3049
+ }
3050
+ return this.decorateQueueMessage(value, replay);
3051
+ }
3052
+ decorateQueueMessage(value, replay) {
3053
+ if (!isRecord2(value)) {
3054
+ return value;
3055
+ }
3056
+ const originalComplete = readProperty(value, "complete");
3057
+ const complete = this.createEffect(
3058
+ "queue.message.complete",
3059
+ () => typeof originalComplete === "function" ? { complete: originalComplete.bind(value) } : void 0,
3060
+ "complete",
3061
+ replay
3062
+ );
3063
+ return { ...value, complete };
3064
+ }
3065
+ queueCallIsCompletable(effect, args) {
3066
+ const options = effect === "queue.waitForNames" ? args[1] : args[0];
3067
+ return isRecord2(options) && options.completable === true;
3068
+ }
3069
+ createQueueIterator(queue, options) {
3070
+ return {
3071
+ async *[Symbol.asyncIterator]() {
3072
+ for (; ; ) {
3073
+ const next = Reflect.get(queue, "next", queue);
3074
+ if (typeof next !== "function") {
3075
+ throw unavailableCapability("queue.next");
3076
+ }
3077
+ const message = await next.call(queue, options);
3078
+ if (message !== void 0 && message !== null) {
3079
+ yield message;
3080
+ }
3081
+ }
3082
+ }
3083
+ };
3084
+ }
3085
+ };
3086
+
2488
3087
  // src/seedContext.ts
2489
3088
  var seedContextStorage = null;
2490
3089
  var SEED_CONTEXT_STORAGE_SYMBOL = /* @__PURE__ */ Symbol.for("bitfab.seedContextStorage");
@@ -2615,6 +3214,9 @@ var BitfabOpenAITracingProcessor = class {
2615
3214
  const activeContext = this.getActiveSpanContext?.();
2616
3215
  if (activeContext) {
2617
3216
  this.activeSpanMappings[trace.traceId] = activeContext;
3217
+ if (this.shouldRecord()) {
3218
+ mapOpenAiAgentsTrace(trace.traceId, activeContext.traceId);
3219
+ }
2618
3220
  }
2619
3221
  const canonicalTraceId = activeContext?.traceId ?? this.getCanonicalTraceId(trace.traceId);
2620
3222
  this.canonicalTraceIds[trace.traceId] = canonicalTraceId;
@@ -2652,6 +3254,7 @@ var BitfabOpenAITracingProcessor = class {
2652
3254
  }
2653
3255
  this.endedTraces.delete(traceId);
2654
3256
  delete this.activeSpanMappings[traceId];
3257
+ unmapOpenAiAgentsTrace(traceId);
2655
3258
  delete this.canonicalTraceIds[traceId];
2656
3259
  delete this.activeTraces[traceId];
2657
3260
  }
@@ -2676,6 +3279,9 @@ var BitfabOpenAITracingProcessor = class {
2676
3279
  async onSpanEnd(span) {
2677
3280
  const originalTraceId = span.traceId ?? "";
2678
3281
  const traceId = this.activeSpanMappings[originalTraceId]?.traceId ?? originalTraceId;
3282
+ if (span.spanId !== void 0) {
3283
+ endOpenAiAgentsSpan(originalTraceId, span.spanId);
3284
+ }
2679
3285
  try {
2680
3286
  this.sendSpan(span);
2681
3287
  } finally {
@@ -2696,6 +3302,9 @@ var BitfabOpenAITracingProcessor = class {
2696
3302
  * Called when the trace processor is shutting down.
2697
3303
  */
2698
3304
  async shutdown(timeout) {
3305
+ for (const traceId of Object.keys(this.activeSpanMappings)) {
3306
+ unmapOpenAiAgentsTrace(traceId);
3307
+ }
2699
3308
  this.activeTraces = {};
2700
3309
  this.activeSpanMappings = {};
2701
3310
  this.canonicalTraceIds = {};
@@ -3852,16 +4461,16 @@ var Bitfab = class {
3852
4461
  this.simulationPlan.send(payload, rootTraceFunctionKeyOf(payload), submit);
3853
4462
  }
3854
4463
  refreshAutoTraceCapturePolicy(traceFunctionKey) {
3855
- const state = this.autoTracePolicyRefreshes.get(traceFunctionKey) ?? new PolicyRefresh();
3856
- this.autoTracePolicyRefreshes.set(traceFunctionKey, state);
3857
- state.run(
4464
+ const state2 = this.autoTracePolicyRefreshes.get(traceFunctionKey) ?? new PolicyRefresh();
4465
+ this.autoTracePolicyRefreshes.set(traceFunctionKey, state2);
4466
+ state2.run(
3858
4467
  () => this.httpClient.getAutoTracePolicy(
3859
4468
  traceFunctionKey,
3860
4469
  AUTO_TRACE_PROTOCOL
3861
4470
  ),
3862
4471
  (policy) => {
3863
4472
  if (policy.protocol !== AUTO_TRACE_PROTOCOL) {
3864
- state.hold(AUTO_TRACE_POLICY_RETRY_MS);
4473
+ state2.hold(AUTO_TRACE_POLICY_RETRY_MS);
3865
4474
  return;
3866
4475
  }
3867
4476
  const functionIds = Array.isArray(policy.functionIds) ? policy.functionIds.filter(
@@ -3872,10 +4481,10 @@ var Bitfab = class {
3872
4481
  traceFunctionKey,
3873
4482
  policy.revision === null ? void 0 : functionIds
3874
4483
  );
3875
- state.hold(AUTO_TRACE_POLICY_REFRESH_MS);
4484
+ state2.hold(AUTO_TRACE_POLICY_REFRESH_MS);
3876
4485
  },
3877
4486
  () => {
3878
- state.hold(AUTO_TRACE_POLICY_RETRY_MS);
4487
+ state2.hold(AUTO_TRACE_POLICY_RETRY_MS);
3879
4488
  }
3880
4489
  );
3881
4490
  }
@@ -4180,6 +4789,47 @@ var Bitfab = class {
4180
4789
  options
4181
4790
  });
4182
4791
  }
4792
+ /**
4793
+ * Get the first-class Rivet actor-context integration for an existing trace
4794
+ * root. The integration binds context and records effect spans; it never
4795
+ * creates another root.
4796
+ *
4797
+ * @param traceFunctionKey - Key used by the enclosing `withTrace()` root
4798
+ * @param options - Explicit per-context-path replay mocking policy
4799
+ * @experimental This API may change before it is stable.
4800
+ */
4801
+ getRivetIntegration(traceFunctionKey, options) {
4802
+ return new BitfabRivetIntegration(
4803
+ traceFunctionKey,
4804
+ {
4805
+ wrapEffect: (effect, mockOnReplay, fn, replayOutput) => {
4806
+ const spanOptions = {
4807
+ name: effect,
4808
+ type: "function",
4809
+ captureWhen: "nested",
4810
+ mockOnReplay,
4811
+ surface: "inherit",
4812
+ instrumentation: "rivet",
4813
+ ...replayOutput !== void 0 && { replayOutput }
4814
+ };
4815
+ return this.withSpan(traceFunctionKey, spanOptions, fn);
4816
+ },
4817
+ recordRootFixture: (context, recordedRoots) => {
4818
+ const root = getSpanStack()[0];
4819
+ if (!root) {
4820
+ return;
4821
+ }
4822
+ const rootId = `${root.traceId}:${root.spanId}`;
4823
+ if (recordedRoots.has(rootId)) {
4824
+ return;
4825
+ }
4826
+ root.contexts.push(context);
4827
+ recordedRoots.add(rootId);
4828
+ }
4829
+ },
4830
+ options
4831
+ );
4832
+ }
4183
4833
  /**
4184
4834
  * Get a Claude Agent SDK handler for tracing.
4185
4835
  *
@@ -4445,7 +5095,11 @@ var Bitfab = class {
4445
5095
  const seedCtxForTraceId = parentContext ? null : getSeedContext();
4446
5096
  const traceId = parentContext?.traceId ?? replayCtxForTraceId?.traceId ?? seedCtxForTraceId?.traceId ?? randomUuid();
4447
5097
  const spanId = randomUuid();
4448
- const parentSpanId = parentContext?.spanId ?? null;
5098
+ const openAiAgentsParent = parentContext !== void 0 && options.instrumentation === "trace" ? openAiAgentsParentSpanId(
5099
+ parentContext.traceId,
5100
+ parentContext.openAiAgentsSpanIds
5101
+ ) : void 0;
5102
+ const parentSpanId = openAiAgentsParent ?? parentContext?.spanId ?? null;
4449
5103
  const isRootSpan = parentSpanId === null;
4450
5104
  if (options.enclosingTrace !== void 0) {
4451
5105
  options.enclosingTrace.link.traceId = traceId;
@@ -4459,11 +5113,13 @@ var Bitfab = class {
4459
5113
  parentContext?.surface,
4460
5114
  traceFunctionKey
4461
5115
  );
5116
+ const openAiAgentsSpanIds = openAiAgentsSpanChain();
4462
5117
  const newContext = {
4463
5118
  traceId,
4464
5119
  spanId,
4465
5120
  contexts: [],
4466
- ...surface !== void 0 && { surface }
5121
+ ...surface !== void 0 && { surface },
5122
+ ...openAiAgentsSpanIds.length > 0 && { openAiAgentsSpanIds }
4467
5123
  };
4468
5124
  newStack = [...currentStack, newContext];
4469
5125
  const inputs = args;
@@ -4678,6 +5334,7 @@ var Bitfab = class {
4678
5334
  }
4679
5335
  return output;
4680
5336
  };
5337
+ const resolveBaseOutput = () => options.replayOutput !== void 0 ? options.replayOutput() : resolveRecordedOutput();
4681
5338
  const shouldMockWithBaseStrategy = replayCtxForMock.mockStrategy === "all" || replayCtxForMock.mockStrategy === "marked" && options.mockOnReplay === true;
4682
5339
  if (replayCtxForMock.mockOverrides?.length) {
4683
5340
  const nodeMeta = {
@@ -4734,7 +5391,7 @@ var Bitfab = class {
4734
5391
  }
4735
5392
  if (shouldMockWithBaseStrategy) {
4736
5393
  const output = await resolveMockOrAbort(
4737
- () => resolveRecordedOutput()
5394
+ () => resolveBaseOutput()
4738
5395
  );
4739
5396
  void sendSpan({
4740
5397
  result: output,
@@ -4757,7 +5414,7 @@ var Bitfab = class {
4757
5414
  );
4758
5415
  }
4759
5416
  if (shouldMockWithBaseStrategy) {
4760
- const recorded = resolveRecordedOutput();
5417
+ const recorded = resolveBaseOutput();
4761
5418
  if (recorded instanceof Promise) {
4762
5419
  return emitMockAsync(recorded, "recorded");
4763
5420
  }
@@ -5237,7 +5894,7 @@ var Bitfab = class {
5237
5894
  await runWithSeedContext({ traceId }, async () => target(...args));
5238
5895
  } finally {
5239
5896
  try {
5240
- const { flushTraces: flushTraces2 } = await import("./http-WQ6YWRTW.js");
5897
+ const { flushTraces: flushTraces2 } = await import("./http-AXPT27DO.js");
5241
5898
  await flushTraces2(3e4);
5242
5899
  } finally {
5243
5900
  unrecorded = activeTraceStates.delete(traceId);
@@ -5296,7 +5953,7 @@ var Bitfab = class {
5296
5953
  `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.`
5297
5954
  );
5298
5955
  }
5299
- const { replay: doReplay } = await import("./replay-MISWCCCG.js");
5956
+ const { replay: doReplay } = await import("./replay-DOG4KV7I.js");
5300
5957
  return doReplay(
5301
5958
  this.httpClient,
5302
5959
  this.serviceUrl,
@@ -5359,6 +6016,28 @@ var BitfabFunction = class {
5359
6016
  span(options = {}) {
5360
6017
  return this.client.span(this.traceFunctionKey, options);
5361
6018
  }
6019
+ withTrace(optionsOrFn, maybeFn) {
6020
+ if (typeof optionsOrFn === "function") {
6021
+ return this.client.withTrace(this.traceFunctionKey, optionsOrFn);
6022
+ }
6023
+ if (!maybeFn) {
6024
+ throw new BitfabError("BitfabFunction.withTrace requires a function");
6025
+ }
6026
+ return this.client.withTrace(this.traceFunctionKey, optionsOrFn, maybeFn);
6027
+ }
6028
+ /**
6029
+ * Create a trace method decorator bound to this function's key.
6030
+ *
6031
+ * Equivalent to `client.trace(key, options)` but reuses the key bound on
6032
+ * this handle.
6033
+ *
6034
+ * @param options - Trace configuration applied to the decorated method
6035
+ * @returns A method decorator configured for this key
6036
+ * @experimental Automatic child-call instrumentation is experimental.
6037
+ */
6038
+ trace(options = {}) {
6039
+ return this.client.trace(this.traceFunctionKey, options);
6040
+ }
5362
6041
  /**
5363
6042
  * Get a Vercel AI SDK language-model middleware bound to this function's key.
5364
6043
  *
@@ -5456,6 +6135,20 @@ var BitfabFunction = class {
5456
6135
  getLangGraphIntegration(options) {
5457
6136
  return this.client.getLangGraphIntegration(this.traceFunctionKey, options);
5458
6137
  }
6138
+ /**
6139
+ * Get the first-class Rivet actor-context integration bound to this key.
6140
+ * Use its `bind()` or `withContext()` outside this handle's `withTrace()`
6141
+ * root, then call `getContext()` inside the root.
6142
+ *
6143
+ * @param options - Explicit per-context-path replay mocking policy
6144
+ * @experimental This API may change before it is stable.
6145
+ */
6146
+ getRivetIntegration(options) {
6147
+ return this.client.getRivetIntegration(
6148
+ this.traceFunctionKey,
6149
+ options
6150
+ );
6151
+ }
5459
6152
  /**
5460
6153
  * Wrap a BAML client method to automatically capture prompt and LLM metadata.
5461
6154
  * Delegates to the parent client's wrapBAML method.
@@ -5580,7 +6273,7 @@ async function seedFromRegistry(registry, pipeline, cases, options = {}) {
5580
6273
  sessionId: seedCase.sessionId
5581
6274
  })
5582
6275
  );
5583
- const { flushTraces: flushTraces2 } = await import("./http-WQ6YWRTW.js");
6276
+ const { flushTraces: flushTraces2 } = await import("./http-AXPT27DO.js");
5584
6277
  await flushTraces2(3e4);
5585
6278
  return { pipeline, traceFunctionKey, traceIds };
5586
6279
  }
@@ -5605,6 +6298,7 @@ export {
5605
6298
  BitfabLangGraphCallbackHandler,
5606
6299
  BitfabLangGraphIntegration,
5607
6300
  BitfabOpenAIAgentHandler,
6301
+ BitfabRivetIntegration,
5608
6302
  TracesClient,
5609
6303
  BitfabOpenAITracingProcessor,
5610
6304
  BitfabVercelAiHandler,
@@ -5618,4 +6312,4 @@ export {
5618
6312
  reseedFromRegistry,
5619
6313
  seedFromRegistry
5620
6314
  };
5621
- //# sourceMappingURL=chunk-UKKR2PF4.js.map
6315
+ //# sourceMappingURL=chunk-MEJOPEKV.js.map