bitfab 0.68.2 → 0.68.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.
@@ -1,5 +1,5 @@
1
1
  const require_bamlPeer = require("./bamlPeer-BUoZgNxZ.cjs");
2
- const require_http = require("./http-Dqc-f3sp.cjs");
2
+ const require_http = require("./http-bBRhl6b9.cjs");
3
3
  const require_autoTrace = require("./autoTrace-D3-OZcmR.cjs");
4
4
  let superjson = require("superjson");
5
5
  superjson = require_bamlPeer.__toESM(superjson, 1);
@@ -1994,6 +1994,12 @@ function createIntegrationFixtureContext(name, value) {
1994
1994
  ...serialized.meta !== void 0 && { valueMeta: serialized.meta }
1995
1995
  } };
1996
1996
  }
1997
+ function hasIntegrationFixture(contexts, name) {
1998
+ return contexts.some((context) => {
1999
+ const fixture = isRecord$3(context) ? context[INTEGRATION_FIXTURE_CONTEXT_KEY] : void 0;
2000
+ return isRecord$3(fixture) && fixture.version === INTEGRATION_FIXTURE_VERSION && fixture.name === name;
2001
+ });
2002
+ }
1997
2003
  function extractIntegrationFixtures(spanData) {
1998
2004
  const contexts = spanData.contexts;
1999
2005
  if (!Array.isArray(contexts)) return;
@@ -2001,7 +2007,7 @@ function extractIntegrationFixtures(spanData) {
2001
2007
  for (const context of contexts) {
2002
2008
  if (!isRecord$3(context)) continue;
2003
2009
  const fixture = context[INTEGRATION_FIXTURE_CONTEXT_KEY];
2004
- if (!isRecord$3(fixture) || fixture.version !== INTEGRATION_FIXTURE_VERSION || typeof fixture.name !== "string") continue;
2010
+ if (!isRecord$3(fixture) || fixture.version !== INTEGRATION_FIXTURE_VERSION || typeof fixture.name !== "string" || fixtures.has(fixture.name)) continue;
2005
2011
  fixtures.set(fixture.name, deserializeValue({
2006
2012
  json: fixture.value,
2007
2013
  ...fixture.valueMeta !== void 0 && { meta: fixture.valueMeta }
@@ -2035,14 +2041,42 @@ function fromBase64(text) {
2035
2041
  if (buffer !== void 0) return new Uint8Array(buffer.from(text, "base64"));
2036
2042
  return Uint8Array.from(atob(text), (char) => char.charCodeAt(0));
2037
2043
  }
2038
- async function newMemorySaver() {
2044
+ async function loadLangGraphPeer() {
2039
2045
  try {
2040
- const { MemorySaver } = await require_bamlPeer.importOptionalPeer(["@langchain", "langgraph"]);
2041
- return new MemorySaver();
2046
+ return await require_bamlPeer.importOptionalPeer(["@langchain", "langgraph"]);
2042
2047
  } catch {
2043
2048
  throw new require_http.BitfabError("Restoring a LangGraph thread during replay requires @langchain/langgraph.", "https://docs.bitfab.ai/frameworks/langgraph");
2044
2049
  }
2045
2050
  }
2051
+ async function newMemorySaver() {
2052
+ const { MemorySaver } = await loadLangGraphPeer();
2053
+ return new MemorySaver();
2054
+ }
2055
+ async function unstoredDeltaChannels(graph, tuple) {
2056
+ const channels = isRecord$2(graph) ? graph.channels : void 0;
2057
+ if (!isRecord$2(channels)) return [];
2058
+ const { DeltaChannel } = await loadLangGraphPeer();
2059
+ if (DeltaChannel === void 0) return [];
2060
+ const versions = isRecord$2(tuple.checkpoint.channel_versions) ? tuple.checkpoint.channel_versions : {};
2061
+ const values = isRecord$2(tuple.checkpoint.channel_values) ? tuple.checkpoint.channel_values : {};
2062
+ return Object.entries(channels).filter(([name, spec]) => spec instanceof DeltaChannel && name in versions && !(name in values)).map(([name]) => name);
2063
+ }
2064
+ async function selfContained(graph, checkpointer, tuple) {
2065
+ if (tuple === void 0) return;
2066
+ const names = await unstoredDeltaChannels(graph, tuple);
2067
+ if (names.length === 0) return tuple;
2068
+ const { values } = await graph.getState(withConfigurable(tuple.config, { [CHECKPOINTER_CONFIG_KEY]: checkpointer }));
2069
+ return {
2070
+ ...tuple,
2071
+ checkpoint: {
2072
+ ...tuple.checkpoint,
2073
+ channel_values: {
2074
+ ...isRecord$2(tuple.checkpoint.channel_values) ? tuple.checkpoint.channel_values : {},
2075
+ ...Object.fromEntries(names.filter((name) => name in values).map((name) => [name, values[name]]))
2076
+ }
2077
+ }
2078
+ };
2079
+ }
2046
2080
  function savingCheckpointer(graph) {
2047
2081
  const own = isRecord$2(graph) ? graph.checkpointer : void 0;
2048
2082
  const inner = isRecord$2(graph) && isRecord$2(graph.graph) ? graph.graph.checkpointer : void 0;
@@ -2102,6 +2136,14 @@ async function restoredCheckpointer(recorded) {
2102
2136
  thread: recorded.config
2103
2137
  };
2104
2138
  }
2139
+ const REPLAY_THREADS = /* @__PURE__ */ new WeakMap();
2140
+ function replayThreadsOf(replay) {
2141
+ const existing = REPLAY_THREADS.get(replay);
2142
+ if (existing !== void 0) return existing;
2143
+ const threads = /* @__PURE__ */ new Map();
2144
+ REPLAY_THREADS.set(replay, threads);
2145
+ return threads;
2146
+ }
2105
2147
  var GraphRun = class {
2106
2148
  constructor(host, graph, config) {
2107
2149
  this.host = host;
@@ -2111,19 +2153,21 @@ var GraphRun = class {
2111
2153
  this.traced = graph.withConfig({ callbacks: [host.callbackHandler, this.finalState] });
2112
2154
  const active = host.activeSpan();
2113
2155
  this.opensRoot = active?.rootTraceFunctionKey !== host.traceFunctionKey;
2114
- this.replaysFromRoot = !this.opensRoot && active?.isRoot === true && require_http.getReplayContext() !== null;
2156
+ this.replay = require_http.getReplayContext();
2157
+ this.reportsStreamResult = this.replay !== null && !this.opensRoot && active?.isRoot === true;
2158
+ }
2159
+ get fixtureName() {
2160
+ return threadFixtureName(this.host.traceFunctionKey);
2115
2161
  }
2116
2162
  invoke(input) {
2117
- if (this.replaysFromRoot) return this.replayConfig().then(async ({ config, confirm }) => {
2118
- const result = await this.traced.invoke(await this.host.reviveRootInput(input), config);
2119
- await confirm();
2163
+ const run = async (rootInput) => {
2164
+ const target = await this.runTarget();
2165
+ await this.recordCheckpoint(target);
2166
+ const result = await this.traced.invoke(await this.host.reviveRootInput(rootInput), target.config);
2167
+ await target.confirm();
2120
2168
  return result;
2121
- });
2122
- if (!this.opensRoot) return this.host.reviveRootInput(input).then((rootInput) => this.traced.invoke(rootInput, this.config));
2123
- return this.host.rootSpan(async (rootInput) => {
2124
- await this.recordCheckpoint();
2125
- return this.traced.invoke(await this.host.reviveRootInput(rootInput), this.config);
2126
- })(this.host.encodeRootInput(input));
2169
+ };
2170
+ return this.opensRoot ? this.host.rootSpan(run)(this.host.encodeRootInput(input)) : run(input);
2127
2171
  }
2128
2172
  stream(input) {
2129
2173
  return this.chunks(input, async (rootInput, config) => this.traced.stream(rootInput, config));
@@ -2132,61 +2176,67 @@ var GraphRun = class {
2132
2176
  return this.chunks(input, async (rootInput, config) => this.traced.streamEvents(rootInput, config, streamOptions));
2133
2177
  }
2134
2178
  chunks(input, open) {
2135
- const { host, finalState } = this;
2136
- if (this.replaysFromRoot) {
2137
- const replayConfig = () => this.replayConfig();
2138
- return (async function* replayChunks() {
2139
- const { config, confirm } = await replayConfig();
2140
- yield* await open(await host.reviveRootInput(input), config);
2141
- await confirm();
2142
- const replay = require_http.getReplayContext();
2143
- if (replay !== null) replay.streamResult = finalState.output;
2144
- })();
2145
- }
2146
- if (!this.opensRoot) {
2147
- const config = this.config;
2148
- return (async function* nestedChunks() {
2149
- yield* await open(await host.reviveRootInput(input), config);
2150
- })();
2179
+ const { host, finalState, reportsStreamResult } = this;
2180
+ const runTarget = () => this.runTarget();
2181
+ const recordCheckpoint = (target) => this.recordCheckpoint(target);
2182
+ async function* run(rootInput) {
2183
+ const target = await runTarget();
2184
+ await recordCheckpoint(target);
2185
+ yield* await open(await host.reviveRootInput(rootInput), target.config);
2186
+ await target.confirm();
2187
+ const replay = require_http.getReplayContext();
2188
+ if (reportsStreamResult && replay !== null) replay.streamResult = finalState.output;
2151
2189
  }
2152
- const config = this.config;
2153
- const recordCheckpoint = () => this.recordCheckpoint();
2154
- return host.rootSpan(async function* rootChunks(rootInput) {
2155
- await recordCheckpoint();
2156
- yield* await open(await host.reviveRootInput(rootInput), config);
2157
- }, () => finalState.output)(host.encodeRootInput(input));
2158
- }
2159
- async recordCheckpoint() {
2160
- const checkpointer = savingCheckpointer(this.graph);
2161
- const thread = threadConfig(this.config);
2162
- if (checkpointer === null || thread.thread_id === void 0) return;
2163
- const encoded = await encodeCheckpoint(await checkpointer.getTuple({ configurable: thread }));
2164
- if (encoded !== null) this.host.addRootContext(createIntegrationFixtureContext(threadFixtureName(this.host.traceFunctionKey), encoded));
2165
- }
2166
- async replayConfig() {
2167
- if (savingCheckpointer(this.graph) === null) return {
2190
+ return this.opensRoot ? host.rootSpan(run, () => finalState.output)(host.encodeRootInput(input)) : run(input);
2191
+ }
2192
+ async recordCheckpoint({ config, checkpointer }) {
2193
+ const thread = threadConfig(config);
2194
+ const contexts = this.host.traceRootContexts();
2195
+ if (checkpointer === null || thread.thread_id === void 0 || contexts === null || hasIntegrationFixture(contexts, this.fixtureName)) return;
2196
+ const encoded = await encodeCheckpoint(await selfContained(this.graph, checkpointer, await checkpointer.getTuple({ configurable: thread })));
2197
+ if (!hasIntegrationFixture(contexts, this.fixtureName)) contexts.push(createIntegrationFixtureContext(this.fixtureName, encoded));
2198
+ }
2199
+ async runTarget() {
2200
+ const own = savingCheckpointer(this.graph);
2201
+ if (this.replay === null || own === null) return {
2168
2202
  config: this.config,
2203
+ checkpointer: own,
2169
2204
  confirm: async () => {}
2170
2205
  };
2171
- const { saver, thread } = await restoredCheckpointer(require_http.getReplayContext()?.integrationFixtures?.get(threadFixtureName(this.host.traceFunctionKey)) ?? null);
2172
- const configurable = isRecord$2(this.config?.configurable) ? this.config.configurable : {};
2173
- const replayThread = {
2174
- thread_id: thread.thread_id ?? configurable.thread_id ?? `bitfab-replay-${randomUuid()}`,
2175
- ...thread.checkpoint_ns !== void 0 && { checkpoint_ns: thread.checkpoint_ns }
2176
- };
2177
- const restoredId = (await saver.getTuple({ configurable: replayThread }))?.checkpoint.id;
2206
+ const { saver, thread } = await this.replayThread(this.replay);
2207
+ const restoredId = (await saver.getTuple({ configurable: thread }))?.checkpoint.id;
2178
2208
  const confirm = async () => {
2179
- const latest = await saver.getTuple({ configurable: replayThread });
2209
+ const latest = await saver.getTuple({ configurable: thread });
2180
2210
  if (latest === void 0 || latest.checkpoint.id === restoredId) require_autoTrace.warnOnce("langgraph-replay-checkpointer-not-lent", "LangGraph did not use the in-memory checkpointer Bitfab lent to a replayed run, so the run may have read and written the graph's own checkpointer. Check that your @langchain/langgraph version still lends a checkpointer through the run config.");
2181
2211
  };
2182
2212
  return {
2183
2213
  config: withConfigurable(this.config, {
2184
- ...replayThread,
2214
+ ...thread,
2185
2215
  [CHECKPOINTER_CONFIG_KEY]: saver
2186
2216
  }),
2217
+ checkpointer: saver,
2187
2218
  confirm
2188
2219
  };
2189
2220
  }
2221
+ replayThread(replay) {
2222
+ const threads = replayThreadsOf(replay);
2223
+ const existing = threads.get(this.fixtureName);
2224
+ if (existing !== void 0) return existing;
2225
+ const restored = this.restoreThread(replay);
2226
+ threads.set(this.fixtureName, restored);
2227
+ return restored;
2228
+ }
2229
+ async restoreThread(replay) {
2230
+ const { saver, thread } = await restoredCheckpointer(replay.integrationFixtures?.get(this.fixtureName) ?? null);
2231
+ const configurable = isRecord$2(this.config?.configurable) ? this.config.configurable : {};
2232
+ return {
2233
+ saver,
2234
+ thread: {
2235
+ thread_id: thread.thread_id ?? configurable.thread_id ?? `bitfab-replay-${randomUuid()}`,
2236
+ ...thread.checkpoint_ns !== void 0 && { checkpoint_ns: thread.checkpoint_ns }
2237
+ }
2238
+ };
2239
+ }
2190
2240
  };
2191
2241
  //#endregion
2192
2242
  //#region src/langgraphIntegration.ts
@@ -2297,7 +2347,7 @@ var BitfabLangGraphIntegration = class {
2297
2347
  this.callbackHandler = config.callbackHandler;
2298
2348
  this.mockToolsOnReplay = config.options?.mockToolsOnReplay ?? true;
2299
2349
  this.getActiveSpan = config.getActiveSpan ?? (() => null);
2300
- this.addRootContext = config.addContext ?? (() => {});
2350
+ this.getTraceRootContexts = config.getTraceRootContexts ?? (() => null);
2301
2351
  }
2302
2352
  get middleware() {
2303
2353
  this.agentMiddleware ?? (this.agentMiddleware = {
@@ -2331,7 +2381,7 @@ var BitfabLangGraphIntegration = class {
2331
2381
  instrumentation: "langgraph",
2332
2382
  ...finalize !== void 0 && { finalize }
2333
2383
  }, fn),
2334
- addRootContext: (context) => this.addRootContext(context),
2384
+ traceRootContexts: () => this.getTraceRootContexts(),
2335
2385
  encodeRootInput: (input) => isCommand(input) ? encodeNativeToolResult(input) : input,
2336
2386
  reviveRootInput: async (input) => isEncodedToolResult(input) ? await reviveToolResult(input, "") : input
2337
2387
  });
@@ -5240,6 +5290,14 @@ const noOpTrace = {
5240
5290
  addContext() {},
5241
5291
  drop() {}
5242
5292
  };
5293
+ function currentTraceRootSpan() {
5294
+ const stack = getSpanStack();
5295
+ const traceId = stack[stack.length - 1]?.traceId;
5296
+ for (let index = stack.length - 1; index >= 0; index--) {
5297
+ const context = stack[index];
5298
+ if (context?.isRoot && context.traceId === traceId) return context;
5299
+ }
5300
+ }
5243
5301
  function getCurrentSpan() {
5244
5302
  const stack = getSpanStack();
5245
5303
  const current = stack[stack.length - 1];
@@ -5761,7 +5819,7 @@ var Bitfab = class {
5761
5819
  const stack = getSpanStack();
5762
5820
  return stack[stack.length - 1] ?? null;
5763
5821
  },
5764
- addContext: (context) => getCurrentSpan().addContext(context)
5822
+ getTraceRootContexts: () => currentTraceRootSpan()?.details.contexts ?? null
5765
5823
  });
5766
5824
  }
5767
5825
  getDeepAgentsIntegration(traceFunctionKey, options) {
@@ -5782,7 +5840,7 @@ var Bitfab = class {
5782
5840
  return this.withSpan(traceFunctionKey, spanOptions, fn);
5783
5841
  },
5784
5842
  recordRootFixture: (context, recordedRoots) => {
5785
- const root = getSpanStack()[0];
5843
+ const root = currentTraceRootSpan();
5786
5844
  if (!root) return;
5787
5845
  const rootId = `${root.traceId}:${root.spanId}`;
5788
5846
  if (recordedRoots.has(rootId)) return;
@@ -6540,7 +6598,7 @@ var Bitfab = class {
6540
6598
  await runWithSeedContext({ traceId }, async () => target(...args));
6541
6599
  } finally {
6542
6600
  try {
6543
- const { flushTraces } = await Promise.resolve().then(() => require("./http-Dqc-f3sp.cjs")).then((n) => n.http_exports);
6601
+ const { flushTraces } = await Promise.resolve().then(() => require("./http-bBRhl6b9.cjs")).then((n) => n.http_exports);
6544
6602
  await flushTraces(3e4);
6545
6603
  } finally {
6546
6604
  unrecorded = activeTraceStates.delete(traceId);
@@ -6737,7 +6795,7 @@ async function seedFromRegistry(registry, pipeline, cases, options = {}) {
6737
6795
  metadata: seedCase.metadata,
6738
6796
  sessionId: seedCase.sessionId
6739
6797
  }));
6740
- const { flushTraces } = await Promise.resolve().then(() => require("./http-Dqc-f3sp.cjs")).then((n) => n.http_exports);
6798
+ const { flushTraces } = await Promise.resolve().then(() => require("./http-bBRhl6b9.cjs")).then((n) => n.http_exports);
6741
6799
  await flushTraces(3e4);
6742
6800
  return {
6743
6801
  pipeline,
@@ -6981,4 +7039,4 @@ Object.defineProperty(exports, "serializeReplayResult", {
6981
7039
  }
6982
7040
  });
6983
7041
 
6984
- //# sourceMappingURL=src-CdQRfsrA.cjs.map
7042
+ //# sourceMappingURL=src-BRR42NiJ.cjs.map