bitfab 0.13.3 → 0.13.5

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.
@@ -8,7 +8,7 @@ import {
8
8
  getReplayContext,
9
9
  isAsyncStorageInitDone,
10
10
  serializeValue
11
- } from "./chunk-LOZFAPCS.js";
11
+ } from "./chunk-BVFST7Q3.js";
12
12
 
13
13
  // src/claudeAgentSdk.ts
14
14
  function nowIso() {
@@ -772,6 +772,31 @@ async function runFunctionWithBaml(bamlSource, inputs, providers, envVars) {
772
772
  };
773
773
  }
774
774
 
775
+ // src/dbSnapshot.ts
776
+ var SUPPORTED_PROVIDERS = [
777
+ "neon",
778
+ "ardent",
779
+ "dolt",
780
+ "gfs",
781
+ "mongodb-atlas",
782
+ "dynamodb",
783
+ "snowflake",
784
+ "bigquery"
785
+ ];
786
+ function validateDbSnapshotConfig(config) {
787
+ if (!SUPPORTED_PROVIDERS.includes(config.provider)) {
788
+ throw new BitfabError(
789
+ `dbSnapshot.provider "${config.provider}" is not supported. Supported providers: ${SUPPORTED_PROVIDERS.join(", ")}.`
790
+ );
791
+ }
792
+ }
793
+ function buildSnapshotRef(config, sdkWallClockBeforeFn) {
794
+ return {
795
+ provider: config.provider,
796
+ sdkWallClockBeforeFn
797
+ };
798
+ }
799
+
775
800
  // src/langgraph.ts
776
801
  var LANGSMITH_HIDDEN_TAG = "langsmith:hidden";
777
802
  var LANGGRAPH_METADATA_KEYS = [
@@ -1246,6 +1271,81 @@ var BitfabLangGraphCallbackHandler = class {
1246
1271
  }
1247
1272
  };
1248
1273
 
1274
+ // src/replayEnvironment.ts
1275
+ var ReplayEnvironment = class {
1276
+ /**
1277
+ * The per-trace branch URL for the item currently being replayed.
1278
+ * Throws if read outside a replay item.
1279
+ */
1280
+ get databaseUrl() {
1281
+ return this.require().databaseUrl;
1282
+ }
1283
+ /** When the per-trace branch URL stops being valid. ISO-8601. */
1284
+ get expiresAt() {
1285
+ return this.require().expiresAt;
1286
+ }
1287
+ /** Deep link to the branch in the provider console, if available. */
1288
+ get providerConsoleUrl() {
1289
+ return this.require().providerConsoleUrl;
1290
+ }
1291
+ /**
1292
+ * True if the branch is read-only. Customer code can use this to skip
1293
+ * write operations during replay when the provider returned a read-only
1294
+ * lease.
1295
+ */
1296
+ get readOnly() {
1297
+ return this.require().readOnly;
1298
+ }
1299
+ /** The historical trace ID that produced the input for this replay item. */
1300
+ get traceId() {
1301
+ return this.require().traceId;
1302
+ }
1303
+ /**
1304
+ * How the resolver pinned this branch.
1305
+ * - "timestamp": snapshot at SDK wall clock; bounded by replication lag.
1306
+ * - "lsn": customer LSN mapped to a replica snapshot (future).
1307
+ */
1308
+ get precision() {
1309
+ return this.require().precision;
1310
+ }
1311
+ /** True when read inside a replay item that has a resolved branch. */
1312
+ get active() {
1313
+ return this.read() !== null;
1314
+ }
1315
+ /** Non-throwing variant for callers that handle the inactive case. */
1316
+ snapshot() {
1317
+ return this.read();
1318
+ }
1319
+ read() {
1320
+ const ctx = getReplayContext();
1321
+ if (!ctx?.dbBranchLease) {
1322
+ return null;
1323
+ }
1324
+ const traceId = ctx.sourceBitfabTraceId ?? ctx.inputSourceTraceId;
1325
+ if (!traceId) {
1326
+ return null;
1327
+ }
1328
+ const lease = ctx.dbBranchLease;
1329
+ return {
1330
+ databaseUrl: lease.databaseUrl,
1331
+ expiresAt: lease.expiresAt,
1332
+ providerConsoleUrl: lease.providerConsoleUrl,
1333
+ readOnly: lease.readOnly,
1334
+ traceId,
1335
+ precision: lease.precision
1336
+ };
1337
+ }
1338
+ require() {
1339
+ const snapshot = this.read();
1340
+ if (!snapshot) {
1341
+ throw new Error(
1342
+ "ReplayEnvironment accessed outside of a replay item. Pass it to bitfab.replay({ environment }) and only read it inside the replayed function."
1343
+ );
1344
+ }
1345
+ return snapshot;
1346
+ }
1347
+ };
1348
+
1249
1349
  // src/tracing.ts
1250
1350
  var BitfabOpenAITracingProcessor = class {
1251
1351
  /**
@@ -1737,6 +1837,10 @@ var Bitfab = class {
1737
1837
  this.enabled = enabled;
1738
1838
  }
1739
1839
  this.bamlClient = config.bamlClient ?? null;
1840
+ if (config.dbSnapshot) {
1841
+ validateDbSnapshotConfig(config.dbSnapshot);
1842
+ }
1843
+ this.dbSnapshot = config.dbSnapshot;
1740
1844
  this.httpClient = new HttpClient({
1741
1845
  apiKey: this.apiKey,
1742
1846
  serviceUrl: this.serviceUrl,
@@ -2033,7 +2137,8 @@ var Bitfab = class {
2033
2137
  }
2034
2138
  const currentStack = getSpanStack();
2035
2139
  const parentContext = currentStack[currentStack.length - 1];
2036
- const traceId = parentContext?.traceId ?? crypto.randomUUID();
2140
+ const replayCtxForTraceId = parentContext ? null : getReplayContext();
2141
+ const traceId = parentContext?.traceId ?? replayCtxForTraceId?.traceId ?? crypto.randomUUID();
2037
2142
  const spanId = crypto.randomUUID();
2038
2143
  const parentSpanId = parentContext?.spanId ?? null;
2039
2144
  const isRootSpan = parentSpanId === null;
@@ -2043,6 +2148,7 @@ var Bitfab = class {
2043
2148
  const startedAt = (/* @__PURE__ */ new Date()).toISOString();
2044
2149
  if (isRootSpan && !activeTraceStates.has(traceId)) {
2045
2150
  const replayCtxAtRoot = getReplayContext();
2151
+ const dbSnapshotRef = self.dbSnapshot ? buildSnapshotRef(self.dbSnapshot, startedAt) : void 0;
2046
2152
  activeTraceStates.set(traceId, {
2047
2153
  traceId,
2048
2154
  startedAt,
@@ -2052,7 +2158,8 @@ var Bitfab = class {
2052
2158
  },
2053
2159
  ...replayCtxAtRoot?.inputSourceTraceId && {
2054
2160
  inputSourceTraceId: replayCtxAtRoot.inputSourceTraceId
2055
- }
2161
+ },
2162
+ ...dbSnapshotRef && { dbSnapshotRef }
2056
2163
  });
2057
2164
  pendingSpanPromises.set(traceId, []);
2058
2165
  }
@@ -2072,6 +2179,7 @@ var Bitfab = class {
2072
2179
  try {
2073
2180
  const endedAt = (/* @__PURE__ */ new Date()).toISOString();
2074
2181
  const replayCtx = getReplayContext();
2182
+ const dbSnapshotRefForSpan = isRootSpan ? activeTraceStates.get(traceId)?.dbSnapshotRef : void 0;
2075
2183
  const spanPromise = self.sendWrapperSpan({
2076
2184
  ...baseSpanParams,
2077
2185
  ...params,
@@ -2081,6 +2189,9 @@ var Bitfab = class {
2081
2189
  ...replayCtx?.testRunId && { testRunId: replayCtx.testRunId },
2082
2190
  ...replayCtx?.inputSourceSpanId && {
2083
2191
  inputSourceSpanId: replayCtx.inputSourceSpanId
2192
+ },
2193
+ ...dbSnapshotRefForSpan && {
2194
+ dbSnapshotRef: dbSnapshotRefForSpan
2084
2195
  }
2085
2196
  });
2086
2197
  if (isRootSpan) {
@@ -2101,7 +2212,8 @@ var Bitfab = class {
2101
2212
  metadata: traceState?.metadata,
2102
2213
  contexts: traceState?.contexts ?? [],
2103
2214
  testRunId: traceState?.testRunId,
2104
- inputSourceTraceId: traceState?.inputSourceTraceId
2215
+ inputSourceTraceId: traceState?.inputSourceTraceId,
2216
+ dbSnapshotRef: traceState?.dbSnapshotRef
2105
2217
  });
2106
2218
  activeTraceStates.delete(traceId);
2107
2219
  } else {
@@ -2262,6 +2374,9 @@ var Bitfab = class {
2262
2374
  if (params.inputSourceTraceId) {
2263
2375
  rawTrace.input_source_trace_id = params.inputSourceTraceId;
2264
2376
  }
2377
+ if (params.dbSnapshotRef) {
2378
+ rawTrace.db_snapshot_ref = params.dbSnapshotRef;
2379
+ }
2265
2380
  this.httpClient.sendExternalTrace({
2266
2381
  type: "sdk-function",
2267
2382
  source: "typescript-sdk-function",
@@ -2304,7 +2419,10 @@ var Bitfab = class {
2304
2419
  ...params.contexts && params.contexts.length > 0 && {
2305
2420
  contexts: params.contexts
2306
2421
  },
2307
- ...params.prompt !== void 0 && { prompt: params.prompt }
2422
+ ...params.prompt !== void 0 && { prompt: params.prompt },
2423
+ ...params.dbSnapshotRef && {
2424
+ db_snapshot_ref: params.dbSnapshotRef
2425
+ }
2308
2426
  }
2309
2427
  };
2310
2428
  if (params.parentSpanId) {
@@ -2337,7 +2455,7 @@ var Bitfab = class {
2337
2455
  * @returns ReplayResult with items, testRunId, and testRunUrl
2338
2456
  */
2339
2457
  async replay(traceFunctionKey, fn, options) {
2340
- const { replay: doReplay } = await import("./replay-JX33WJUT.js");
2458
+ const { replay: doReplay } = await import("./replay-CLQKO7U7.js");
2341
2459
  return doReplay(
2342
2460
  this.httpClient,
2343
2461
  this.serviceUrl,
@@ -2347,6 +2465,12 @@ var Bitfab = class {
2347
2465
  );
2348
2466
  }
2349
2467
  };
2468
+ /**
2469
+ * Per-trace environment for `replay({ environment })`. Construct one,
2470
+ * pass it to replay, and read `env.databaseUrl` inside the replayed
2471
+ * function to pick up the per-trace branch URL.
2472
+ */
2473
+ Bitfab.ReplayEnvironment = ReplayEnvironment;
2350
2474
  var BitfabFunction = class {
2351
2475
  constructor(client, traceFunctionKey) {
2352
2476
  this.client = client;
@@ -2398,11 +2522,13 @@ var BitfabFunction = class {
2398
2522
 
2399
2523
  export {
2400
2524
  BitfabClaudeAgentHandler,
2525
+ SUPPORTED_PROVIDERS,
2401
2526
  BitfabLangGraphCallbackHandler,
2527
+ ReplayEnvironment,
2402
2528
  BitfabOpenAITracingProcessor,
2403
2529
  getCurrentSpan,
2404
2530
  getCurrentTrace,
2405
2531
  Bitfab,
2406
2532
  BitfabFunction
2407
2533
  };
2408
- //# sourceMappingURL=chunk-NHYPYRQB.js.map
2534
+ //# sourceMappingURL=chunk-4IHJJRMU.js.map