bitfab 0.54.9 → 0.54.10

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-UKKR2PF4.js → chunk-A3OBQOLV.js} +609 -8
  2. package/dist/chunk-A3OBQOLV.js.map +1 -0
  3. package/dist/{chunk-7HXFT6JR.js → chunk-B2O33DBH.js} +6 -4
  4. package/dist/chunk-B2O33DBH.js.map +1 -0
  5. package/dist/{chunk-5EW5MV2Z.js → chunk-OGZLJINL.js} +3 -3
  6. package/dist/chunk-OGZLJINL.js.map +1 -0
  7. package/dist/{chunk-VT5IUVBY.js → chunk-PRXW4B5X.js} +85 -40
  8. package/dist/chunk-PRXW4B5X.js.map +1 -0
  9. package/dist/{chunk-TOCJX6OP.js → chunk-XLWQOUOP.js} +4 -3
  10. package/dist/chunk-XLWQOUOP.js.map +1 -0
  11. package/dist/{http-WQ6YWRTW.js → http-AVWWAMFV.js} +2 -2
  12. package/dist/{http-HYJYQTX2.js → http-DH3O3L5X.js} +2 -2
  13. package/dist/index.cjs +669 -8
  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 +669 -8
  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-BCWIDCKH.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-AVWWAMFV.js.map} +0 -0
  34. /package/dist/{http-WQ6YWRTW.js.map → http-DH3O3L5X.js.map} +0 -0
  35. /package/dist/{replay-MISWCCCG.js.map → replay-BCWIDCKH.js.map} +0 -0
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.54.9";
54
+ __version__ = "0.54.10";
55
55
  __packageName__ = "bitfab";
56
56
  }
57
57
  });
@@ -836,8 +836,8 @@ function encodePayloadBody(payload) {
836
836
  const marker = { error: `payload_serialize_failed: ${message}` };
837
837
  return { body: JSON.stringify(marker), dropped, value: marker };
838
838
  }
839
- const isRecord4 = typeof sanitized === "object" && sanitized !== null && !Array.isArray(sanitized);
840
- if (dropped.length > 0 && isRecord4) {
839
+ const isRecord6 = typeof sanitized === "object" && sanitized !== null && !Array.isArray(sanitized);
840
+ if (dropped.length > 0 && isRecord6) {
841
841
  const obj = sanitized;
842
842
  const existing = Array.isArray(obj.errors) ? obj.errors : [];
843
843
  obj.errors = [
@@ -854,7 +854,7 @@ function encodePayloadBody(payload) {
854
854
  return {
855
855
  body: JSON.stringify(sanitized),
856
856
  dropped,
857
- value: isRecord4 ? sanitized : void 0
857
+ value: isRecord6 ? sanitized : void 0
858
858
  };
859
859
  }
860
860
  }
@@ -956,13 +956,15 @@ var init_spanOrigin = __esm({
956
956
  "openai-agents",
957
957
  "langgraph",
958
958
  "claude-agent-sdk",
959
- "vercel-ai"
959
+ "vercel-ai",
960
+ "rivet"
960
961
  ];
961
962
  FRAMEWORK_INSTRUMENTATIONS = [
962
963
  "openai-agents",
963
964
  "langgraph",
964
965
  "claude-agent-sdk",
965
- "vercel-ai"
966
+ "vercel-ai",
967
+ "rivet"
966
968
  ];
967
969
  FRAMEWORK_INSTRUMENTATION_SET = new Set(
968
970
  FRAMEWORK_INSTRUMENTATIONS
@@ -3466,6 +3468,55 @@ var init_codeChange = __esm({
3466
3468
  }
3467
3469
  });
3468
3470
 
3471
+ // src/integrationFixture.ts
3472
+ function isRecord4(value) {
3473
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3474
+ }
3475
+ function createIntegrationFixtureContext(name, value) {
3476
+ const serialized = serializeValue(value);
3477
+ return {
3478
+ [INTEGRATION_FIXTURE_CONTEXT_KEY]: {
3479
+ version: INTEGRATION_FIXTURE_VERSION,
3480
+ name,
3481
+ value: serialized.json,
3482
+ ...serialized.meta !== void 0 && { valueMeta: serialized.meta }
3483
+ }
3484
+ };
3485
+ }
3486
+ function extractIntegrationFixtures(spanData) {
3487
+ const contexts = spanData.contexts;
3488
+ if (!Array.isArray(contexts)) {
3489
+ return void 0;
3490
+ }
3491
+ const fixtures = /* @__PURE__ */ new Map();
3492
+ for (const context of contexts) {
3493
+ if (!isRecord4(context)) {
3494
+ continue;
3495
+ }
3496
+ const fixture = context[INTEGRATION_FIXTURE_CONTEXT_KEY];
3497
+ if (!isRecord4(fixture) || fixture.version !== INTEGRATION_FIXTURE_VERSION || typeof fixture.name !== "string") {
3498
+ continue;
3499
+ }
3500
+ fixtures.set(
3501
+ fixture.name,
3502
+ deserializeValue({
3503
+ json: fixture.value,
3504
+ ...fixture.valueMeta !== void 0 && { meta: fixture.valueMeta }
3505
+ })
3506
+ );
3507
+ }
3508
+ return fixtures.size > 0 ? fixtures : void 0;
3509
+ }
3510
+ var INTEGRATION_FIXTURE_CONTEXT_KEY, INTEGRATION_FIXTURE_VERSION;
3511
+ var init_integrationFixture = __esm({
3512
+ "src/integrationFixture.ts"() {
3513
+ "use strict";
3514
+ init_serialize();
3515
+ INTEGRATION_FIXTURE_CONTEXT_KEY = "__bitfabIntegrationFixture";
3516
+ INTEGRATION_FIXTURE_VERSION = 1;
3517
+ }
3518
+ });
3519
+
3469
3520
  // src/replay.ts
3470
3521
  var replay_exports = {};
3471
3522
  __export(replay_exports, {
@@ -3690,6 +3741,7 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
3690
3741
  const spanData = span.rawData?.span_data ?? {};
3691
3742
  inputs = deserializeInputs(spanData);
3692
3743
  originalOutput = deserializeOutput(spanData);
3744
+ const integrationFixtures = extractIntegrationFixtures(spanData);
3693
3745
  if (adaptInputs) {
3694
3746
  const originalMetadata = serverItem.originalMetadata;
3695
3747
  inputs = adaptInputs(inputs, {
@@ -3781,6 +3833,7 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
3781
3833
  mockStrategy,
3782
3834
  mockOverrides: hasOverrides ? resolvedOverrides : void 0,
3783
3835
  fetchSpanOutput,
3836
+ integrationFixtures,
3784
3837
  dbBranchLease: lease,
3785
3838
  dbBranchTimings
3786
3839
  },
@@ -4261,6 +4314,7 @@ var init_replay = __esm({
4261
4314
  init_codeChange();
4262
4315
  init_errors();
4263
4316
  init_http();
4317
+ init_integrationFixture();
4264
4318
  init_mockOverride();
4265
4319
  init_randomUuid();
4266
4320
  init_replayContext();
@@ -4304,6 +4358,7 @@ __export(index_exports, {
4304
4358
  BitfabLangGraphIntegration: () => BitfabLangGraphIntegration,
4305
4359
  BitfabOpenAIAgentHandler: () => BitfabOpenAIAgentHandler,
4306
4360
  BitfabOpenAITracingProcessor: () => BitfabOpenAITracingProcessor,
4361
+ BitfabRivetIntegration: () => BitfabRivetIntegration,
4307
4362
  BitfabVercelAiHandler: () => BitfabVercelAiHandler,
4308
4363
  DEFAULT_SERVICE_URL: () => DEFAULT_SERVICE_URL,
4309
4364
  DatasetsClient: () => DatasetsClient,
@@ -6978,6 +7033,533 @@ _context = new WeakMap();
6978
7033
  // src/client.ts
6979
7034
  init_replayContext();
6980
7035
 
7036
+ // src/rivetIntegration.ts
7037
+ init_errors();
7038
+ init_integrationFixture();
7039
+ init_replayContext();
7040
+
7041
+ // src/rivetContext.ts
7042
+ init_asyncStorage();
7043
+ var storage = null;
7044
+ var browserBinding = null;
7045
+ var STORAGE_SYMBOL = /* @__PURE__ */ Symbol.for("bitfab.rivetContextStorage");
7046
+ function initializeStorage() {
7047
+ if (storage) {
7048
+ return;
7049
+ }
7050
+ const shared = globalThis;
7051
+ const existing = shared[STORAGE_SYMBOL];
7052
+ if (existing) {
7053
+ storage = existing;
7054
+ return;
7055
+ }
7056
+ const created = createAsyncLocalStorage();
7057
+ if (created) {
7058
+ shared[STORAGE_SYMBOL] = created;
7059
+ storage = created;
7060
+ }
7061
+ }
7062
+ var rivetContextReady = asyncStorageReady.then(() => {
7063
+ initializeStorage();
7064
+ });
7065
+ function getRivetContextBinding() {
7066
+ initializeStorage();
7067
+ return storage?.getStore() ?? browserBinding ?? void 0;
7068
+ }
7069
+ function runWithBrowserBinding(binding, fn) {
7070
+ const previous = browserBinding;
7071
+ browserBinding = binding;
7072
+ try {
7073
+ const result = fn();
7074
+ if (result instanceof Promise) {
7075
+ return result.finally(() => {
7076
+ browserBinding = previous;
7077
+ });
7078
+ }
7079
+ browserBinding = previous;
7080
+ return result;
7081
+ } catch (error) {
7082
+ browserBinding = previous;
7083
+ throw error;
7084
+ }
7085
+ }
7086
+ function runWithRivetContext(binding, fn) {
7087
+ initializeStorage();
7088
+ if (!storage && !isAsyncStorageInitDone()) {
7089
+ return rivetContextReady.then(() => runWithRivetContext(binding, fn));
7090
+ }
7091
+ if (storage) {
7092
+ return storage.run(binding, fn);
7093
+ }
7094
+ return runWithBrowserBinding(binding, fn);
7095
+ }
7096
+
7097
+ // src/rivetIntegration.ts
7098
+ var RIVET_DOCS_URL = "https://docs.bitfab.ai/frameworks/rivet";
7099
+ var RIVET_GROUP_EFFECT_METHODS = {
7100
+ db: ["execute", "nativeMetrics", "close"],
7101
+ kv: [
7102
+ "get",
7103
+ "put",
7104
+ "delete",
7105
+ "batchPut",
7106
+ "batchGet",
7107
+ "batchDelete",
7108
+ "deleteRange",
7109
+ "listPrefix",
7110
+ "listRange",
7111
+ "list"
7112
+ ],
7113
+ schedule: ["after", "at", "cancel", "get", "list"],
7114
+ cron: ["set", "every", "get", "list", "delete", "history"],
7115
+ queue: [
7116
+ "send",
7117
+ "next",
7118
+ "nextBatch",
7119
+ "waitForNames",
7120
+ "waitForAvailable",
7121
+ "complete",
7122
+ "enqueueAndWait",
7123
+ "tryNext",
7124
+ "tryNextBatch"
7125
+ ],
7126
+ run: ["setWakeAt"]
7127
+ };
7128
+ var RIVET_TOP_LEVEL_EFFECTS = [
7129
+ "broadcast",
7130
+ "saveState",
7131
+ "sleep",
7132
+ "destroy"
7133
+ ];
7134
+ var TOP_LEVEL_UNAVAILABLE_CAPABILITIES = /* @__PURE__ */ new Set([
7135
+ "conn",
7136
+ "conns",
7137
+ "log",
7138
+ "request",
7139
+ "actorRuntimeSocket",
7140
+ "keepAwake",
7141
+ "waitUntil",
7142
+ "client"
7143
+ ]);
7144
+ var SYNC_VOID_EFFECTS = /* @__PURE__ */ new Set([
7145
+ "broadcast",
7146
+ "sleep",
7147
+ "destroy"
7148
+ ]);
7149
+ var QUEUE_MESSAGE_EFFECTS = /* @__PURE__ */ new Set([
7150
+ "queue.next",
7151
+ "queue.nextBatch",
7152
+ "queue.waitForNames",
7153
+ "queue.tryNext",
7154
+ "queue.tryNextBatch"
7155
+ ]);
7156
+ function isRecord5(value) {
7157
+ return typeof value === "object" && value !== null;
7158
+ }
7159
+ function readProperty(value, property) {
7160
+ try {
7161
+ return Reflect.get(value, property, value);
7162
+ } catch {
7163
+ return void 0;
7164
+ }
7165
+ }
7166
+ function snapshotContext(context) {
7167
+ const source = context;
7168
+ const snapshot = {};
7169
+ for (const property of [
7170
+ "state",
7171
+ "vars",
7172
+ "actorId",
7173
+ "name",
7174
+ "key",
7175
+ "region",
7176
+ "aborted"
7177
+ ]) {
7178
+ const value = readProperty(source, property);
7179
+ if (value !== void 0) {
7180
+ snapshot[property] = value;
7181
+ }
7182
+ }
7183
+ return snapshot;
7184
+ }
7185
+ function unavailableCapability(path) {
7186
+ return new BitfabError(
7187
+ `Rivet context capability "${path}" is unavailable during replay. Add first-class support for that public context path before replaying code that uses it.`,
7188
+ RIVET_DOCS_URL
7189
+ );
7190
+ }
7191
+ function effectNode(traceFunctionKey, effect, mockSpanId) {
7192
+ return {
7193
+ traceFunctionKey,
7194
+ spanName: effect,
7195
+ type: "function",
7196
+ originalSpanId: mockSpanId
7197
+ };
7198
+ }
7199
+ function replayEffectStatus(replay2, traceFunctionKey, effect, marked) {
7200
+ const counterKey = `${traceFunctionKey}:${effect}`;
7201
+ const callIndex = replay2.callCounters?.get(counterKey) ?? 0;
7202
+ const mockSpan = replay2.mockTree?.spans.get(`${counterKey}:${callIndex}`);
7203
+ const hasOverride = replay2.mockOverrides?.some(
7204
+ (override) => override.match(
7205
+ effectNode(traceFunctionKey, effect, mockSpan?.sourceSpanId)
7206
+ )
7207
+ ) ?? false;
7208
+ return {
7209
+ willMock: hasOverride || replay2.mockStrategy === "all" || replay2.mockStrategy === "marked" && marked,
7210
+ hasRecordedSpan: mockSpan !== void 0,
7211
+ hasOverride,
7212
+ callIndex
7213
+ };
7214
+ }
7215
+ function assertReplayEffectAvailable(replay2, traceFunctionKey, effect, marked) {
7216
+ if (!replay2) {
7217
+ return;
7218
+ }
7219
+ const status = replayEffectStatus(replay2, traceFunctionKey, effect, marked);
7220
+ if (!status.willMock) {
7221
+ throw new BitfabError(
7222
+ `Rivet effect "${effect}" has no live actor context during replay. Add "${effect}" to mockOnReplay or provide a replay override.`,
7223
+ RIVET_DOCS_URL
7224
+ );
7225
+ }
7226
+ if (!status.hasRecordedSpan && !status.hasOverride) {
7227
+ throw new BitfabError(
7228
+ `No recorded Rivet effect "${effect}" exists at call ${status.callIndex + 1}; the live effect was not executed.`,
7229
+ RIVET_DOCS_URL
7230
+ );
7231
+ }
7232
+ }
7233
+ function fixtureName(traceFunctionKey) {
7234
+ return `rivet:${traceFunctionKey}`;
7235
+ }
7236
+ function snapshotFromReplay(traceFunctionKey, replay2) {
7237
+ const fixture = replay2.integrationFixtures?.get(fixtureName(traceFunctionKey));
7238
+ if (!isRecord5(fixture)) {
7239
+ throw new BitfabError(
7240
+ `Trace "${traceFunctionKey}" has no Rivet context fixture. Capture a fresh trace with the Rivet integration before replaying it.`,
7241
+ RIVET_DOCS_URL
7242
+ );
7243
+ }
7244
+ return fixture;
7245
+ }
7246
+ var BitfabRivetIntegration = class {
7247
+ /** @internal Constructed by `Bitfab.getRivetIntegration()`. */
7248
+ constructor(traceFunctionKey, runtime, options = {}) {
7249
+ this.traceFunctionKey = traceFunctionKey;
7250
+ this.runtime = runtime;
7251
+ this.replayProxies = /* @__PURE__ */ new WeakMap();
7252
+ this.markedEffects = new Set(options.mockOnReplay ?? []);
7253
+ }
7254
+ /**
7255
+ * Run a callback with a live Rivet context bound to the current async chain.
7256
+ * This binds context only; it creates no trace or span.
7257
+ */
7258
+ withContext(context, fn) {
7259
+ if (!isRecord5(context)) {
7260
+ throw new BitfabError("Rivet withContext requires a context object");
7261
+ }
7262
+ const binding = {
7263
+ context,
7264
+ fixtureContext: createIntegrationFixtureContext(
7265
+ fixtureName(this.traceFunctionKey),
7266
+ snapshotContext(context)
7267
+ ),
7268
+ recordedRoots: /* @__PURE__ */ new Set()
7269
+ };
7270
+ return runWithRivetContext(binding, fn);
7271
+ }
7272
+ /**
7273
+ * Adapt a traced function into a Rivet handler whose first argument is the
7274
+ * live actor context. The context is not added to the traced root's inputs.
7275
+ */
7276
+ bind(fn) {
7277
+ const integration = this;
7278
+ return function(context, ...args) {
7279
+ return integration.withContext(context, () => fn.apply(this, args));
7280
+ };
7281
+ }
7282
+ /**
7283
+ * Return the current Rivet context proxy. In production it delegates to the
7284
+ * bound live context. During replay it hydrates recorded actor state and
7285
+ * intercepts supported effects without requiring a live Rivet actor.
7286
+ */
7287
+ getContext() {
7288
+ const replay2 = getReplayContext();
7289
+ if (replay2) {
7290
+ const existing = this.replayProxies.get(replay2);
7291
+ if (existing) {
7292
+ return existing;
7293
+ }
7294
+ const proxy = this.createContextProxy(
7295
+ snapshotFromReplay(this.traceFunctionKey, replay2),
7296
+ void 0
7297
+ );
7298
+ this.replayProxies.set(replay2, proxy);
7299
+ return proxy;
7300
+ }
7301
+ const binding = getRivetContextBinding();
7302
+ if (!binding) {
7303
+ throw new BitfabError(
7304
+ "No Rivet context is bound. Call rivet.bind(handler) or rivet.withContext(context, callback) at the Rivet boundary.",
7305
+ RIVET_DOCS_URL
7306
+ );
7307
+ }
7308
+ this.runtime.recordRootFixture(
7309
+ binding.fixtureContext,
7310
+ binding.recordedRoots
7311
+ );
7312
+ if (!binding.proxy) {
7313
+ binding.proxy = this.createContextProxy(
7314
+ binding.context,
7315
+ binding
7316
+ );
7317
+ }
7318
+ return binding.proxy;
7319
+ }
7320
+ createContextProxy(target, binding) {
7321
+ const replay2 = getReplayContext();
7322
+ const dbProxy = this.createDbProxy(binding, replay2);
7323
+ const groupProxies = /* @__PURE__ */ new Map();
7324
+ for (const group of Object.keys(
7325
+ RIVET_GROUP_EFFECT_METHODS
7326
+ )) {
7327
+ if (group !== "db") {
7328
+ groupProxies.set(group, this.createGroupProxy(group, binding, replay2));
7329
+ }
7330
+ }
7331
+ const topLevelEffects = /* @__PURE__ */ new Map();
7332
+ for (const effect of RIVET_TOP_LEVEL_EFFECTS) {
7333
+ topLevelEffects.set(
7334
+ effect,
7335
+ this.createEffect(
7336
+ effect,
7337
+ () => binding?.context,
7338
+ effect,
7339
+ replay2
7340
+ )
7341
+ );
7342
+ }
7343
+ const replayTarget = replay2 ? { ...target } : target;
7344
+ if (replay2) {
7345
+ const controller = new AbortController();
7346
+ if (target.aborted === true) {
7347
+ controller.abort();
7348
+ }
7349
+ replayTarget.abortSignal = controller.signal;
7350
+ }
7351
+ return new Proxy(replayTarget, {
7352
+ get: (source, property) => {
7353
+ if (property === "db") {
7354
+ return dbProxy;
7355
+ }
7356
+ if (typeof property === "string") {
7357
+ const group = groupProxies.get(property);
7358
+ if (group) {
7359
+ return group;
7360
+ }
7361
+ const effect = topLevelEffects.get(property);
7362
+ if (effect) {
7363
+ return effect;
7364
+ }
7365
+ }
7366
+ if (property === "setPreventSleep" && replay2) {
7367
+ return (_preventSleep) => void 0;
7368
+ }
7369
+ if (replay2 && typeof property === "string" && TOP_LEVEL_UNAVAILABLE_CAPABILITIES.has(property)) {
7370
+ throw unavailableCapability(property);
7371
+ }
7372
+ const value = Reflect.get(source, property, source);
7373
+ return typeof value === "function" ? value.bind(source) : value;
7374
+ }
7375
+ });
7376
+ }
7377
+ createDbProxy(binding, replay2) {
7378
+ const proxy = this.createGroupProxy("db", binding, replay2);
7379
+ return new Proxy(proxy, {
7380
+ get: (source, property) => property === "transaction" ? this.createTransaction(binding, replay2) : Reflect.get(source, property, source)
7381
+ });
7382
+ }
7383
+ createGroupProxy(group, binding, replay2) {
7384
+ const targetProvider = () => {
7385
+ if (!binding) {
7386
+ return void 0;
7387
+ }
7388
+ const context = binding.context;
7389
+ const target = readProperty(context, group);
7390
+ return isRecord5(target) ? target : void 0;
7391
+ };
7392
+ const proxy = this.createMethodProxy(
7393
+ targetProvider,
7394
+ group,
7395
+ RIVET_GROUP_EFFECT_METHODS[group],
7396
+ replay2
7397
+ );
7398
+ if (group !== "queue") {
7399
+ return proxy;
7400
+ }
7401
+ return new Proxy(proxy, {
7402
+ get: (source, property) => property === "iter" ? (options) => this.createQueueIterator(source, options) : Reflect.get(source, property, source)
7403
+ });
7404
+ }
7405
+ createMethodProxy(targetProvider, prefix, methods, replay2) {
7406
+ const effects = /* @__PURE__ */ new Map();
7407
+ for (const method of methods) {
7408
+ const effect = `${prefix}.${method}`;
7409
+ effects.set(
7410
+ method,
7411
+ this.createEffect(effect, targetProvider, method, replay2)
7412
+ );
7413
+ }
7414
+ return new Proxy(
7415
+ {},
7416
+ {
7417
+ get: (_source, property) => {
7418
+ if (typeof property === "string") {
7419
+ const effect = effects.get(property);
7420
+ if (effect) {
7421
+ return effect;
7422
+ }
7423
+ if (replay2) {
7424
+ throw unavailableCapability(`${prefix}.${property}`);
7425
+ }
7426
+ }
7427
+ const target = targetProvider();
7428
+ if (!target) {
7429
+ return void 0;
7430
+ }
7431
+ const value = Reflect.get(target, property, target);
7432
+ return typeof value === "function" ? value.bind(target) : value;
7433
+ }
7434
+ }
7435
+ );
7436
+ }
7437
+ createEffect(effect, targetProvider, methodName, replay2) {
7438
+ const marked = this.markedEffects.has(effect);
7439
+ const invoke = (...args) => {
7440
+ assertReplayEffectAvailable(
7441
+ getReplayContext(),
7442
+ this.traceFunctionKey,
7443
+ effect,
7444
+ marked
7445
+ );
7446
+ const target = targetProvider();
7447
+ const method = target ? readProperty(target, methodName) : void 0;
7448
+ if (typeof method !== "function") {
7449
+ throw unavailableCapability(effect);
7450
+ }
7451
+ return method.apply(target, args);
7452
+ };
7453
+ const wrapped = SYNC_VOID_EFFECTS.has(effect) ? this.runtime.wrapEffect(
7454
+ effect,
7455
+ marked,
7456
+ invoke,
7457
+ replay2 ? () => void 0 : void 0
7458
+ ) : this.runtime.wrapEffect(effect, marked, async (...args) => {
7459
+ return await invoke(...args);
7460
+ });
7461
+ return (...args) => {
7462
+ if (replay2) {
7463
+ assertReplayEffectAvailable(
7464
+ replay2,
7465
+ this.traceFunctionKey,
7466
+ effect,
7467
+ marked
7468
+ );
7469
+ }
7470
+ const result = wrapped(...args);
7471
+ if (!QUEUE_MESSAGE_EFFECTS.has(effect) || !(result instanceof Promise)) {
7472
+ return result;
7473
+ }
7474
+ return result.then(
7475
+ (value) => this.decorateQueueMessages(value, effect, args, replay2)
7476
+ );
7477
+ };
7478
+ }
7479
+ createTransaction(binding, replay2) {
7480
+ return async (callback, options) => {
7481
+ if (typeof callback !== "function") {
7482
+ throw new BitfabError("Rivet db.transaction requires a callback");
7483
+ }
7484
+ if (replay2) {
7485
+ return await callback(
7486
+ this.createMethodProxy(
7487
+ () => void 0,
7488
+ "db.transaction",
7489
+ ["execute"],
7490
+ replay2
7491
+ )
7492
+ );
7493
+ }
7494
+ const context = binding?.context;
7495
+ const db = context ? readProperty(context, "db") : void 0;
7496
+ const transaction = isRecord5(db) ? readProperty(db, "transaction") : void 0;
7497
+ if (!isRecord5(db) || typeof transaction !== "function") {
7498
+ throw unavailableCapability("db.transaction");
7499
+ }
7500
+ return await transaction.call(
7501
+ db,
7502
+ async (transactionDb) => {
7503
+ if (!isRecord5(transactionDb)) {
7504
+ throw unavailableCapability("db.transaction.execute");
7505
+ }
7506
+ return await callback(
7507
+ this.createMethodProxy(
7508
+ () => transactionDb,
7509
+ "db.transaction",
7510
+ ["execute"],
7511
+ replay2
7512
+ )
7513
+ );
7514
+ },
7515
+ options
7516
+ );
7517
+ };
7518
+ }
7519
+ decorateQueueMessages(value, effect, args, replay2) {
7520
+ if (!this.queueCallIsCompletable(effect, args)) {
7521
+ return value;
7522
+ }
7523
+ if (Array.isArray(value)) {
7524
+ return value.map((message) => this.decorateQueueMessage(message, replay2));
7525
+ }
7526
+ return this.decorateQueueMessage(value, replay2);
7527
+ }
7528
+ decorateQueueMessage(value, replay2) {
7529
+ if (!isRecord5(value)) {
7530
+ return value;
7531
+ }
7532
+ const originalComplete = readProperty(value, "complete");
7533
+ const complete = this.createEffect(
7534
+ "queue.message.complete",
7535
+ () => typeof originalComplete === "function" ? { complete: originalComplete.bind(value) } : void 0,
7536
+ "complete",
7537
+ replay2
7538
+ );
7539
+ return { ...value, complete };
7540
+ }
7541
+ queueCallIsCompletable(effect, args) {
7542
+ const options = effect === "queue.waitForNames" ? args[1] : args[0];
7543
+ return isRecord5(options) && options.completable === true;
7544
+ }
7545
+ createQueueIterator(queue, options) {
7546
+ return {
7547
+ async *[Symbol.asyncIterator]() {
7548
+ for (; ; ) {
7549
+ const next = Reflect.get(queue, "next", queue);
7550
+ if (typeof next !== "function") {
7551
+ throw unavailableCapability("queue.next");
7552
+ }
7553
+ const message = await next.call(queue, options);
7554
+ if (message !== void 0 && message !== null) {
7555
+ yield message;
7556
+ }
7557
+ }
7558
+ }
7559
+ };
7560
+ }
7561
+ };
7562
+
6981
7563
  // src/seedContext.ts
6982
7564
  init_asyncStorage();
6983
7565
  var seedContextStorage = null;
@@ -8687,6 +9269,47 @@ var Bitfab = class {
8687
9269
  options
8688
9270
  });
8689
9271
  }
9272
+ /**
9273
+ * Get the first-class Rivet actor-context integration for an existing trace
9274
+ * root. The integration binds context and records effect spans; it never
9275
+ * creates another root.
9276
+ *
9277
+ * @param traceFunctionKey - Key used by the enclosing `withTrace()` root
9278
+ * @param options - Explicit per-context-path replay mocking policy
9279
+ * @experimental This API may change before it is stable.
9280
+ */
9281
+ getRivetIntegration(traceFunctionKey, options) {
9282
+ return new BitfabRivetIntegration(
9283
+ traceFunctionKey,
9284
+ {
9285
+ wrapEffect: (effect, mockOnReplay, fn, replayOutput) => {
9286
+ const spanOptions = {
9287
+ name: effect,
9288
+ type: "function",
9289
+ captureWhen: "nested",
9290
+ mockOnReplay,
9291
+ surface: "inherit",
9292
+ instrumentation: "rivet",
9293
+ ...replayOutput !== void 0 && { replayOutput }
9294
+ };
9295
+ return this.withSpan(traceFunctionKey, spanOptions, fn);
9296
+ },
9297
+ recordRootFixture: (context, recordedRoots) => {
9298
+ const root = getSpanStack()[0];
9299
+ if (!root) {
9300
+ return;
9301
+ }
9302
+ const rootId = `${root.traceId}:${root.spanId}`;
9303
+ if (recordedRoots.has(rootId)) {
9304
+ return;
9305
+ }
9306
+ root.contexts.push(context);
9307
+ recordedRoots.add(rootId);
9308
+ }
9309
+ },
9310
+ options
9311
+ );
9312
+ }
8690
9313
  /**
8691
9314
  * Get a Claude Agent SDK handler for tracing.
8692
9315
  *
@@ -9185,6 +9808,7 @@ var Bitfab = class {
9185
9808
  }
9186
9809
  return output;
9187
9810
  };
9811
+ const resolveBaseOutput = () => options.replayOutput !== void 0 ? options.replayOutput() : resolveRecordedOutput();
9188
9812
  const shouldMockWithBaseStrategy = replayCtxForMock.mockStrategy === "all" || replayCtxForMock.mockStrategy === "marked" && options.mockOnReplay === true;
9189
9813
  if (replayCtxForMock.mockOverrides?.length) {
9190
9814
  const nodeMeta = {
@@ -9241,7 +9865,7 @@ var Bitfab = class {
9241
9865
  }
9242
9866
  if (shouldMockWithBaseStrategy) {
9243
9867
  const output = await resolveMockOrAbort(
9244
- () => resolveRecordedOutput()
9868
+ () => resolveBaseOutput()
9245
9869
  );
9246
9870
  void sendSpan({
9247
9871
  result: output,
@@ -9264,7 +9888,7 @@ var Bitfab = class {
9264
9888
  );
9265
9889
  }
9266
9890
  if (shouldMockWithBaseStrategy) {
9267
- const recorded = resolveRecordedOutput();
9891
+ const recorded = resolveBaseOutput();
9268
9892
  if (recorded instanceof Promise) {
9269
9893
  return emitMockAsync(recorded, "recorded");
9270
9894
  }
@@ -9866,6 +10490,28 @@ var BitfabFunction = class {
9866
10490
  span(options = {}) {
9867
10491
  return this.client.span(this.traceFunctionKey, options);
9868
10492
  }
10493
+ withTrace(optionsOrFn, maybeFn) {
10494
+ if (typeof optionsOrFn === "function") {
10495
+ return this.client.withTrace(this.traceFunctionKey, optionsOrFn);
10496
+ }
10497
+ if (!maybeFn) {
10498
+ throw new BitfabError("BitfabFunction.withTrace requires a function");
10499
+ }
10500
+ return this.client.withTrace(this.traceFunctionKey, optionsOrFn, maybeFn);
10501
+ }
10502
+ /**
10503
+ * Create a trace method decorator bound to this function's key.
10504
+ *
10505
+ * Equivalent to `client.trace(key, options)` but reuses the key bound on
10506
+ * this handle.
10507
+ *
10508
+ * @param options - Trace configuration applied to the decorated method
10509
+ * @returns A method decorator configured for this key
10510
+ * @experimental Automatic child-call instrumentation is experimental.
10511
+ */
10512
+ trace(options = {}) {
10513
+ return this.client.trace(this.traceFunctionKey, options);
10514
+ }
9869
10515
  /**
9870
10516
  * Get a Vercel AI SDK language-model middleware bound to this function's key.
9871
10517
  *
@@ -9963,6 +10609,20 @@ var BitfabFunction = class {
9963
10609
  getLangGraphIntegration(options) {
9964
10610
  return this.client.getLangGraphIntegration(this.traceFunctionKey, options);
9965
10611
  }
10612
+ /**
10613
+ * Get the first-class Rivet actor-context integration bound to this key.
10614
+ * Use its `bind()` or `withContext()` outside this handle's `withTrace()`
10615
+ * root, then call `getContext()` inside the root.
10616
+ *
10617
+ * @param options - Explicit per-context-path replay mocking policy
10618
+ * @experimental This API may change before it is stable.
10619
+ */
10620
+ getRivetIntegration(options) {
10621
+ return this.client.getRivetIntegration(
10622
+ this.traceFunctionKey,
10623
+ options
10624
+ );
10625
+ }
9966
10626
  /**
9967
10627
  * Wrap a BAML client method to automatically capture prompt and LLM metadata.
9968
10628
  * Delegates to the parent client's wrapBAML method.
@@ -10124,6 +10784,7 @@ function resolveTraceFunctionKey(registration) {
10124
10784
  BitfabLangGraphIntegration,
10125
10785
  BitfabOpenAIAgentHandler,
10126
10786
  BitfabOpenAITracingProcessor,
10787
+ BitfabRivetIntegration,
10127
10788
  BitfabVercelAiHandler,
10128
10789
  DEFAULT_SERVICE_URL,
10129
10790
  DatasetsClient,