bitfab 0.68.1 → 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.
- package/dist/{http-f8Rl8oRa.js → http-WVZO9E-Q.js} +2 -2
- package/dist/http-WVZO9E-Q.js.map +1 -0
- package/dist/{http-r1r6injY.cjs → http-bBRhl6b9.cjs} +2 -2
- package/dist/http-bBRhl6b9.cjs.map +1 -0
- package/dist/{index-BQV7zzJx.d.cts → index-D1heoBkv.d.cts} +186 -13
- package/dist/{index-BQV7zzJx.d.ts → index-D1heoBkv.d.ts} +186 -13
- package/dist/index.cjs +2 -2
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/node.cjs +2 -2
- package/dist/node.d.cts +2 -2
- package/dist/node.d.ts +2 -2
- package/dist/node.js +2 -2
- package/dist/registryCommand-Dk4Y1ZgW.js.map +1 -1
- package/dist/{src-Cps3Xs_J.js → src--sgdobPE.js} +527 -85
- package/dist/src--sgdobPE.js.map +1 -0
- package/dist/{src-BYXxPnpE.cjs → src-BRR42NiJ.cjs} +527 -85
- package/dist/src-BRR42NiJ.cjs.map +1 -0
- package/package.json +12 -2
- package/dist/http-f8Rl8oRa.js.map +0 -1
- package/dist/http-r1r6injY.cjs.map +0 -1
- package/dist/src-BYXxPnpE.cjs.map +0 -1
- package/dist/src-Cps3Xs_J.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
|
-
import { C as readEnv$1, S as MixedTracingError, _ as getReplayContext, b as gitRunner, c as recordCallerTraceMetadata, f as ROOT_TRACE_FUNCTION_KEY_FIELD, g as MAX_COMPRESSIBLE_SPAN_CARRIER_BYTES, h as makeSpanOrigin, i as flushTraces, l as retireTraceMetadata, m as isFrameworkInstrumentation, n as SPAN_TYPES, o as unrefTimer, p as SimulationPlan, r as experimentIdWireFields, s as callerTraceMetadata, t as HttpClient, v as replayContextReady, w as __version__, x as BitfabError, y as runWithReplayContext } from "./http-
|
|
2
|
+
import { C as readEnv$1, S as MixedTracingError, _ as getReplayContext, b as gitRunner, c as recordCallerTraceMetadata, f as ROOT_TRACE_FUNCTION_KEY_FIELD, g as MAX_COMPRESSIBLE_SPAN_CARRIER_BYTES, h as makeSpanOrigin, i as flushTraces, l as retireTraceMetadata, m as isFrameworkInstrumentation, n as SPAN_TYPES, o as unrefTimer, p as SimulationPlan, r as experimentIdWireFields, s as callerTraceMetadata, t as HttpClient, v as replayContextReady, w as __version__, x as BitfabError, y as runWithReplayContext } from "./http-WVZO9E-Q.js";
|
|
3
3
|
import { E as isAsyncStorageInitDone, S as runWithCaptureSuppressed, T as createAsyncLocalStorage, _ as watchOpenRouterUsage, b as writeOnce, c as currentAutoTraceEntries, d as runAsAutoTraceRootFunction, f as runWithAutoTraceEntry, g as recordWatchedOpenRouterCompletion, h as recordAutoTracedOpenRouter, i as __bitfabAutoTraceActive, m as runWithAutoTraceRootContext, p as runWithAutoTraceNodeConfiguration, s as clearAutoTraceNodeConfiguration, u as invokeThroughAutoTraceEntries, w as asyncStorageReady, x as isCaptureSuppressed, y as warnOnce } from "./autoTrace-ghnojSj9.js";
|
|
4
4
|
import { r as importOptionalPeer, t as loadBamlModule } from "./bamlPeer-CIVwS68E.js";
|
|
5
5
|
import superjson from "superjson";
|
|
@@ -1411,11 +1411,11 @@ var GradersClient = class {
|
|
|
1411
1411
|
const JEV_PROVIDER = "typesafe";
|
|
1412
1412
|
const JEV_WATCH_STORAGE_SYMBOL = Symbol.for("bitfab.jevWatchStorage");
|
|
1413
1413
|
const repliesRecordedByAutoTrace = /* @__PURE__ */ new WeakSet();
|
|
1414
|
-
function isRecord$
|
|
1414
|
+
function isRecord$4(value) {
|
|
1415
1415
|
return typeof value === "object" && value !== null;
|
|
1416
1416
|
}
|
|
1417
1417
|
function isJevReply(value) {
|
|
1418
|
-
return isRecord$
|
|
1418
|
+
return isRecord$4(value) && typeof value.model === "string" && isRecord$4(value.usage);
|
|
1419
1419
|
}
|
|
1420
1420
|
function tokenCount(usage, key) {
|
|
1421
1421
|
const count = usage[key];
|
|
@@ -1474,7 +1474,7 @@ function recordWatchedJevReply(span, watch, reply, durationMs) {
|
|
|
1474
1474
|
markEnclosingWatches(watch);
|
|
1475
1475
|
}
|
|
1476
1476
|
function isRecordedByAutoTrace(reply) {
|
|
1477
|
-
return isRecord$
|
|
1477
|
+
return isRecord$4(reply) && repliesRecordedByAutoTrace.has(reply);
|
|
1478
1478
|
}
|
|
1479
1479
|
function recordAutoTracedJev(invokeFn, span) {
|
|
1480
1480
|
const startedAt = Date.now();
|
|
@@ -1492,6 +1492,22 @@ function recordAutoTracedJev(invokeFn, span) {
|
|
|
1492
1492
|
//#endregion
|
|
1493
1493
|
//#region src/langgraph.ts
|
|
1494
1494
|
const LANGSMITH_HIDDEN_TAG = "langsmith:hidden";
|
|
1495
|
+
function toolCallClaim(traceId, toolCallId) {
|
|
1496
|
+
return `${traceId}\u0000${toolCallId}`;
|
|
1497
|
+
}
|
|
1498
|
+
var OutermostRunOutput = class {
|
|
1499
|
+
constructor() {
|
|
1500
|
+
this.name = "BitfabOutermostRunOutput";
|
|
1501
|
+
this.awaitHandlers = true;
|
|
1502
|
+
this.output = void 0;
|
|
1503
|
+
}
|
|
1504
|
+
handleChainStart(_chain, _inputs, runId) {
|
|
1505
|
+
this.runId ?? (this.runId = runId);
|
|
1506
|
+
}
|
|
1507
|
+
handleChainEnd(outputs, runId) {
|
|
1508
|
+
if (runId === this.runId) this.output = outputs;
|
|
1509
|
+
}
|
|
1510
|
+
};
|
|
1495
1511
|
const CHAIN_RUN_TYPES = /* @__PURE__ */ new Set([
|
|
1496
1512
|
"chain",
|
|
1497
1513
|
"parser",
|
|
@@ -1661,11 +1677,15 @@ function extractLangGraphMetadata(metadata) {
|
|
|
1661
1677
|
var BitfabLangGraphCallbackHandler = class {
|
|
1662
1678
|
constructor(config) {
|
|
1663
1679
|
this.name = "BitfabLangGraphCallbackHandler";
|
|
1680
|
+
this.awaitHandlers = true;
|
|
1664
1681
|
this.ignoreRetry = true;
|
|
1665
1682
|
this.ignoreRetriever = false;
|
|
1666
1683
|
this.ignoreCustomEvent = true;
|
|
1667
1684
|
this.runToSpan = /* @__PURE__ */ new Map();
|
|
1668
1685
|
this.invocations = /* @__PURE__ */ new Map();
|
|
1686
|
+
this.claimedToolCalls = /* @__PURE__ */ new Set();
|
|
1687
|
+
this.stepRunIdByNamespace = /* @__PURE__ */ new Map();
|
|
1688
|
+
this.namespaceByStepRunId = /* @__PURE__ */ new Map();
|
|
1669
1689
|
this.ownsHttpClient = config._httpClient === void 0;
|
|
1670
1690
|
this.httpClient = config._httpClient ?? new HttpClient({
|
|
1671
1691
|
apiKey: config.apiKey,
|
|
@@ -1680,6 +1700,37 @@ var BitfabLangGraphCallbackHandler = class {
|
|
|
1680
1700
|
async close(timeoutMs) {
|
|
1681
1701
|
return this.ownsHttpClient ? this.httpClient.close(timeoutMs) : true;
|
|
1682
1702
|
}
|
|
1703
|
+
claimToolCall(traceId, toolCallId) {
|
|
1704
|
+
const claim = toolCallClaim(traceId, toolCallId);
|
|
1705
|
+
this.claimedToolCalls.add(claim);
|
|
1706
|
+
return () => {
|
|
1707
|
+
this.claimedToolCalls.delete(claim);
|
|
1708
|
+
};
|
|
1709
|
+
}
|
|
1710
|
+
visibleStepSpanId(checkpointNamespace, traceId) {
|
|
1711
|
+
const runId = this.stepRunIdByNamespace.get(checkpointNamespace);
|
|
1712
|
+
let span = runId === void 0 ? void 0 : this.runToSpan.get(runId);
|
|
1713
|
+
while (span?.hidden === true) span = span.parentId ? this.runToSpan.get(span.parentId) : void 0;
|
|
1714
|
+
return span !== void 0 && span.traceId === traceId ? span.spanId : null;
|
|
1715
|
+
}
|
|
1716
|
+
isClaimedToolCall(parentRunId, toolCallId) {
|
|
1717
|
+
if (toolCallId === void 0) return false;
|
|
1718
|
+
const traceId = (parentRunId ? this.runToSpan.get(parentRunId)?.traceId : void 0) ?? this.getActiveSpanContext?.()?.traceId;
|
|
1719
|
+
return traceId !== void 0 && this.claimedToolCalls.has(toolCallClaim(traceId, toolCallId));
|
|
1720
|
+
}
|
|
1721
|
+
rememberStep(runId, metadata) {
|
|
1722
|
+
const namespace = metadata?.langgraph_checkpoint_ns;
|
|
1723
|
+
if (typeof namespace === "string") {
|
|
1724
|
+
this.stepRunIdByNamespace.set(namespace, runId);
|
|
1725
|
+
this.namespaceByStepRunId.set(runId, namespace);
|
|
1726
|
+
}
|
|
1727
|
+
}
|
|
1728
|
+
forgetStep(runId) {
|
|
1729
|
+
const namespace = this.namespaceByStepRunId.get(runId);
|
|
1730
|
+
if (namespace === void 0) return;
|
|
1731
|
+
this.namespaceByStepRunId.delete(runId);
|
|
1732
|
+
if (this.stepRunIdByNamespace.get(namespace) === runId) this.stepRunIdByNamespace.delete(namespace);
|
|
1733
|
+
}
|
|
1683
1734
|
startSpan(runId, parentRunId, name, spanType, inputData, metadata, tags) {
|
|
1684
1735
|
const parentSpan = parentRunId ? this.runToSpan.get(parentRunId) : void 0;
|
|
1685
1736
|
const willHide = tags?.includes(LANGSMITH_HIDDEN_TAG) === true;
|
|
@@ -1828,15 +1879,18 @@ var BitfabLangGraphCallbackHandler = class {
|
|
|
1828
1879
|
const idArr = serialized.id;
|
|
1829
1880
|
const name = runName ?? serialized.name ?? idArr?.[idArr.length - 1] ?? "chain";
|
|
1830
1881
|
this.startSpan(runId, parentRunId, String(name), "agent", inputs, metadata, tags);
|
|
1882
|
+
this.rememberStep(runId, metadata);
|
|
1831
1883
|
} catch {}
|
|
1832
1884
|
}
|
|
1833
1885
|
async handleChainEnd(outputs, runId) {
|
|
1834
1886
|
try {
|
|
1887
|
+
this.forgetStep(runId);
|
|
1835
1888
|
this.completeSpan(runId, outputs);
|
|
1836
1889
|
} catch {}
|
|
1837
1890
|
}
|
|
1838
1891
|
async handleChainError(error, runId) {
|
|
1839
1892
|
try {
|
|
1893
|
+
this.forgetStep(runId);
|
|
1840
1894
|
if (error?.constructor?.name === "GraphBubbleUp") {
|
|
1841
1895
|
this.completeSpan(runId, void 0, void 0);
|
|
1842
1896
|
return;
|
|
@@ -1888,8 +1942,8 @@ var BitfabLangGraphCallbackHandler = class {
|
|
|
1888
1942
|
} catch {}
|
|
1889
1943
|
}
|
|
1890
1944
|
async handleLLMNewToken() {}
|
|
1891
|
-
async handleToolStart(tool, input, runId, parentRunId, tags, metadata, runName) {
|
|
1892
|
-
if (!this.captureTools) return;
|
|
1945
|
+
async handleToolStart(tool, input, runId, parentRunId, tags, metadata, runName, toolCallId) {
|
|
1946
|
+
if (!this.captureTools || this.isClaimedToolCall(parentRunId, toolCallId)) return;
|
|
1893
1947
|
try {
|
|
1894
1948
|
const name = runName ?? (tool ?? {}).name ?? "tool";
|
|
1895
1949
|
this.startSpan(runId, parentRunId, String(name), "function", input, metadata, tags);
|
|
@@ -1925,21 +1979,282 @@ var BitfabLangGraphCallbackHandler = class {
|
|
|
1925
1979
|
}
|
|
1926
1980
|
};
|
|
1927
1981
|
//#endregion
|
|
1982
|
+
//#region src/integrationFixture.ts
|
|
1983
|
+
const INTEGRATION_FIXTURE_CONTEXT_KEY = "__bitfabIntegrationFixture";
|
|
1984
|
+
const INTEGRATION_FIXTURE_VERSION = 1;
|
|
1985
|
+
function isRecord$3(value) {
|
|
1986
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1987
|
+
}
|
|
1988
|
+
function createIntegrationFixtureContext(name, value) {
|
|
1989
|
+
const serialized = serializeValue(value);
|
|
1990
|
+
return { [INTEGRATION_FIXTURE_CONTEXT_KEY]: {
|
|
1991
|
+
version: INTEGRATION_FIXTURE_VERSION,
|
|
1992
|
+
name,
|
|
1993
|
+
value: serialized.json,
|
|
1994
|
+
...serialized.meta !== void 0 && { valueMeta: serialized.meta }
|
|
1995
|
+
} };
|
|
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
|
+
}
|
|
2003
|
+
function extractIntegrationFixtures(spanData) {
|
|
2004
|
+
const contexts = spanData.contexts;
|
|
2005
|
+
if (!Array.isArray(contexts)) return;
|
|
2006
|
+
const fixtures = /* @__PURE__ */ new Map();
|
|
2007
|
+
for (const context of contexts) {
|
|
2008
|
+
if (!isRecord$3(context)) continue;
|
|
2009
|
+
const fixture = context[INTEGRATION_FIXTURE_CONTEXT_KEY];
|
|
2010
|
+
if (!isRecord$3(fixture) || fixture.version !== INTEGRATION_FIXTURE_VERSION || typeof fixture.name !== "string" || fixtures.has(fixture.name)) continue;
|
|
2011
|
+
fixtures.set(fixture.name, deserializeValue({
|
|
2012
|
+
json: fixture.value,
|
|
2013
|
+
...fixture.valueMeta !== void 0 && { meta: fixture.valueMeta }
|
|
2014
|
+
}));
|
|
2015
|
+
}
|
|
2016
|
+
return fixtures.size > 0 ? fixtures : void 0;
|
|
2017
|
+
}
|
|
2018
|
+
//#endregion
|
|
2019
|
+
//#region src/langgraphRuns.ts
|
|
2020
|
+
function threadFixtureName(traceFunctionKey) {
|
|
2021
|
+
return `langgraph-thread:${traceFunctionKey}`;
|
|
2022
|
+
}
|
|
2023
|
+
const CHECKPOINTER_CONFIG_KEY = "__pregel_checkpointer";
|
|
2024
|
+
const THREAD_CONFIG_KEYS = [
|
|
2025
|
+
"thread_id",
|
|
2026
|
+
"checkpoint_ns",
|
|
2027
|
+
"checkpoint_id"
|
|
2028
|
+
];
|
|
2029
|
+
function isRecord$2(value) {
|
|
2030
|
+
return typeof value === "object" && value !== null;
|
|
2031
|
+
}
|
|
2032
|
+
function toBase64(bytes) {
|
|
2033
|
+
const buffer = globalThis.Buffer;
|
|
2034
|
+
if (buffer !== void 0) return buffer.from(bytes).toString("base64");
|
|
2035
|
+
let binary = "";
|
|
2036
|
+
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
2037
|
+
return btoa(binary);
|
|
2038
|
+
}
|
|
2039
|
+
function fromBase64(text) {
|
|
2040
|
+
const buffer = globalThis.Buffer;
|
|
2041
|
+
if (buffer !== void 0) return new Uint8Array(buffer.from(text, "base64"));
|
|
2042
|
+
return Uint8Array.from(atob(text), (char) => char.charCodeAt(0));
|
|
2043
|
+
}
|
|
2044
|
+
async function loadLangGraphPeer() {
|
|
2045
|
+
try {
|
|
2046
|
+
return await importOptionalPeer(["@langchain", "langgraph"]);
|
|
2047
|
+
} catch {
|
|
2048
|
+
throw new BitfabError("Restoring a LangGraph thread during replay requires @langchain/langgraph.", "https://docs.bitfab.ai/frameworks/langgraph");
|
|
2049
|
+
}
|
|
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
|
+
}
|
|
2080
|
+
function savingCheckpointer(graph) {
|
|
2081
|
+
const own = isRecord$2(graph) ? graph.checkpointer : void 0;
|
|
2082
|
+
const inner = isRecord$2(graph) && isRecord$2(graph.graph) ? graph.graph.checkpointer : void 0;
|
|
2083
|
+
const checkpointer = own ?? inner;
|
|
2084
|
+
return isRecord$2(checkpointer) && typeof checkpointer.getTuple === "function" ? checkpointer : null;
|
|
2085
|
+
}
|
|
2086
|
+
function threadConfig(config) {
|
|
2087
|
+
const configurable = isRecord$2(config?.configurable) ? config.configurable : {};
|
|
2088
|
+
return Object.fromEntries(THREAD_CONFIG_KEYS.filter((key) => key in configurable).map((key) => [key, configurable[key]]));
|
|
2089
|
+
}
|
|
2090
|
+
function withConfigurable(config, values) {
|
|
2091
|
+
return {
|
|
2092
|
+
...config ?? {},
|
|
2093
|
+
configurable: {
|
|
2094
|
+
...isRecord$2(config?.configurable) ? config.configurable : {},
|
|
2095
|
+
...values
|
|
2096
|
+
}
|
|
2097
|
+
};
|
|
2098
|
+
}
|
|
2099
|
+
async function encodeTyped(saver, value) {
|
|
2100
|
+
const [type, data] = await saver.serde.dumpsTyped(value);
|
|
2101
|
+
return [type, toBase64(data)];
|
|
2102
|
+
}
|
|
2103
|
+
async function decodeTyped(saver, [type, data]) {
|
|
2104
|
+
return saver.serde.loadsTyped(type, fromBase64(data));
|
|
2105
|
+
}
|
|
2106
|
+
async function encodeCheckpoint(tuple) {
|
|
2107
|
+
if (tuple === void 0) return null;
|
|
2108
|
+
const saver = await newMemorySaver();
|
|
2109
|
+
return {
|
|
2110
|
+
config: threadConfig(tuple.config),
|
|
2111
|
+
checkpoint: await encodeTyped(saver, tuple.checkpoint),
|
|
2112
|
+
metadata: await encodeTyped(saver, tuple.metadata ?? {}),
|
|
2113
|
+
pendingWrites: await Promise.all((tuple.pendingWrites ?? []).map(async ([taskId, channel, value]) => [
|
|
2114
|
+
taskId,
|
|
2115
|
+
channel,
|
|
2116
|
+
await encodeTyped(saver, value)
|
|
2117
|
+
]))
|
|
2118
|
+
};
|
|
2119
|
+
}
|
|
2120
|
+
async function restoredCheckpointer(recorded) {
|
|
2121
|
+
const saver = await newMemorySaver();
|
|
2122
|
+
if (recorded === null) return {
|
|
2123
|
+
saver,
|
|
2124
|
+
thread: {}
|
|
2125
|
+
};
|
|
2126
|
+
const checkpoint = await decodeTyped(saver, recorded.checkpoint);
|
|
2127
|
+
const saved = await saver.put({ configurable: {
|
|
2128
|
+
thread_id: recorded.config.thread_id,
|
|
2129
|
+
checkpoint_ns: recorded.config.checkpoint_ns ?? ""
|
|
2130
|
+
} }, checkpoint, await decodeTyped(saver, recorded.metadata), checkpoint.channel_versions ?? {});
|
|
2131
|
+
const writesByTask = /* @__PURE__ */ new Map();
|
|
2132
|
+
for (const [taskId, channel, value] of recorded.pendingWrites) writesByTask.set(taskId, [...writesByTask.get(taskId) ?? [], [channel, await decodeTyped(saver, value)]]);
|
|
2133
|
+
for (const [taskId, writes] of writesByTask) await saver.putWrites(saved, writes, taskId);
|
|
2134
|
+
return {
|
|
2135
|
+
saver,
|
|
2136
|
+
thread: recorded.config
|
|
2137
|
+
};
|
|
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
|
+
}
|
|
2147
|
+
var GraphRun = class {
|
|
2148
|
+
constructor(host, graph, config) {
|
|
2149
|
+
this.host = host;
|
|
2150
|
+
this.graph = graph;
|
|
2151
|
+
this.config = config;
|
|
2152
|
+
this.finalState = new OutermostRunOutput();
|
|
2153
|
+
this.traced = graph.withConfig({ callbacks: [host.callbackHandler, this.finalState] });
|
|
2154
|
+
const active = host.activeSpan();
|
|
2155
|
+
this.opensRoot = active?.rootTraceFunctionKey !== host.traceFunctionKey;
|
|
2156
|
+
this.replay = getReplayContext();
|
|
2157
|
+
this.reportsStreamResult = this.replay !== null && !this.opensRoot && active?.isRoot === true;
|
|
2158
|
+
}
|
|
2159
|
+
get fixtureName() {
|
|
2160
|
+
return threadFixtureName(this.host.traceFunctionKey);
|
|
2161
|
+
}
|
|
2162
|
+
invoke(input) {
|
|
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();
|
|
2168
|
+
return result;
|
|
2169
|
+
};
|
|
2170
|
+
return this.opensRoot ? this.host.rootSpan(run)(this.host.encodeRootInput(input)) : run(input);
|
|
2171
|
+
}
|
|
2172
|
+
stream(input) {
|
|
2173
|
+
return this.chunks(input, async (rootInput, config) => this.traced.stream(rootInput, config));
|
|
2174
|
+
}
|
|
2175
|
+
streamEvents(input, streamOptions) {
|
|
2176
|
+
return this.chunks(input, async (rootInput, config) => this.traced.streamEvents(rootInput, config, streamOptions));
|
|
2177
|
+
}
|
|
2178
|
+
chunks(input, open) {
|
|
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 = getReplayContext();
|
|
2188
|
+
if (reportsStreamResult && replay !== null) replay.streamResult = finalState.output;
|
|
2189
|
+
}
|
|
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 {
|
|
2202
|
+
config: this.config,
|
|
2203
|
+
checkpointer: own,
|
|
2204
|
+
confirm: async () => {}
|
|
2205
|
+
};
|
|
2206
|
+
const { saver, thread } = await this.replayThread(this.replay);
|
|
2207
|
+
const restoredId = (await saver.getTuple({ configurable: thread }))?.checkpoint.id;
|
|
2208
|
+
const confirm = async () => {
|
|
2209
|
+
const latest = await saver.getTuple({ configurable: thread });
|
|
2210
|
+
if (latest === void 0 || latest.checkpoint.id === restoredId) 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.");
|
|
2211
|
+
};
|
|
2212
|
+
return {
|
|
2213
|
+
config: withConfigurable(this.config, {
|
|
2214
|
+
...thread,
|
|
2215
|
+
[CHECKPOINTER_CONFIG_KEY]: saver
|
|
2216
|
+
}),
|
|
2217
|
+
checkpointer: saver,
|
|
2218
|
+
confirm
|
|
2219
|
+
};
|
|
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
|
+
}
|
|
2240
|
+
};
|
|
2241
|
+
//#endregion
|
|
1928
2242
|
//#region src/langgraphIntegration.ts
|
|
1929
2243
|
const TOOL_RESULT_TAG = "__bitfabLangGraphToolResult";
|
|
1930
|
-
|
|
2244
|
+
const AGENT_MIDDLEWARE_BRAND = Symbol.for("AgentMiddleware");
|
|
2245
|
+
function isRecord$1(value) {
|
|
1931
2246
|
return typeof value === "object" && value !== null;
|
|
1932
2247
|
}
|
|
1933
2248
|
function isToolMessage(value) {
|
|
1934
|
-
return isRecord$
|
|
2249
|
+
return isRecord$1(value) && value.lc_direct_tool_output === true && value.type === "tool" && (typeof value.content === "string" || Array.isArray(value.content));
|
|
1935
2250
|
}
|
|
1936
2251
|
function isCommand(value) {
|
|
1937
|
-
return isRecord$
|
|
2252
|
+
return isRecord$1(value) && value.lg_name === "Command";
|
|
1938
2253
|
}
|
|
1939
2254
|
function encodeNested(value) {
|
|
1940
2255
|
if (isToolMessage(value) || isCommand(value)) return encodeNativeToolResult(value);
|
|
1941
2256
|
if (Array.isArray(value)) return value.map(encodeNested);
|
|
1942
|
-
if (isRecord$
|
|
2257
|
+
if (isRecord$1(value)) return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, encodeNested(entry)]));
|
|
1943
2258
|
return value;
|
|
1944
2259
|
}
|
|
1945
2260
|
function encodeNativeToolResult(value) {
|
|
@@ -1956,17 +2271,24 @@ function encodeNativeToolResult(value) {
|
|
|
1956
2271
|
};
|
|
1957
2272
|
return {
|
|
1958
2273
|
[TOOL_RESULT_TAG]: "command",
|
|
1959
|
-
graph: isRecord$
|
|
1960
|
-
update: isRecord$
|
|
1961
|
-
resume: isRecord$
|
|
1962
|
-
goto: isRecord$
|
|
2274
|
+
graph: isRecord$1(value) && typeof value.graph === "string" ? value.graph : void 0,
|
|
2275
|
+
update: isRecord$1(value) ? encodeNested(value.update) : void 0,
|
|
2276
|
+
resume: isRecord$1(value) ? encodeNested(value.resume) : void 0,
|
|
2277
|
+
goto: isRecord$1(value) ? encodeNested(value.goto) : void 0
|
|
1963
2278
|
};
|
|
1964
2279
|
}
|
|
1965
2280
|
function finalizeToolResult(value) {
|
|
1966
2281
|
return isToolMessage(value) || isCommand(value) ? encodeNativeToolResult(value) : value;
|
|
1967
2282
|
}
|
|
1968
2283
|
function isEncodedToolResult(value) {
|
|
1969
|
-
return isRecord$
|
|
2284
|
+
return isRecord$1(value) && typeof value[TOOL_RESULT_TAG] === "string";
|
|
2285
|
+
}
|
|
2286
|
+
async function loadPeer(specifierParts, packageName, docsPath) {
|
|
2287
|
+
try {
|
|
2288
|
+
return await importOptionalPeer(specifierParts);
|
|
2289
|
+
} catch {
|
|
2290
|
+
throw new BitfabError(`This LangGraph integration method requires ${packageName}. Install it to use it.`, `https://docs.bitfab.ai${docsPath}`);
|
|
2291
|
+
}
|
|
1970
2292
|
}
|
|
1971
2293
|
async function loadLangChainCore() {
|
|
1972
2294
|
try {
|
|
@@ -1989,7 +2311,7 @@ async function loadLangGraph() {
|
|
|
1989
2311
|
async function reviveNested(value, toolCallId) {
|
|
1990
2312
|
if (isEncodedToolResult(value)) return reviveToolResult(value, toolCallId);
|
|
1991
2313
|
if (Array.isArray(value)) return Promise.all(value.map((entry) => reviveNested(entry, toolCallId)));
|
|
1992
|
-
if (isRecord$
|
|
2314
|
+
if (isRecord$1(value)) {
|
|
1993
2315
|
const entries = await Promise.all(Object.entries(value).map(async ([key, entry]) => [key, await reviveNested(entry, toolCallId)]));
|
|
1994
2316
|
return Object.fromEntries(entries);
|
|
1995
2317
|
}
|
|
@@ -2005,9 +2327,9 @@ async function reviveToolResult(value, toolCallId) {
|
|
|
2005
2327
|
...typeof value.id === "string" && { id: value.id },
|
|
2006
2328
|
...(value.status === "success" || value.status === "error") && { status: value.status },
|
|
2007
2329
|
...value.artifact !== void 0 && { artifact: await reviveNested(value.artifact, toolCallId) },
|
|
2008
|
-
...isRecord$
|
|
2009
|
-
...isRecord$
|
|
2010
|
-
...isRecord$
|
|
2330
|
+
...isRecord$1(value.metadata) && { metadata: await reviveNested(value.metadata, toolCallId) },
|
|
2331
|
+
...isRecord$1(value.additionalKwargs) && { additional_kwargs: await reviveNested(value.additionalKwargs, toolCallId) },
|
|
2332
|
+
...isRecord$1(value.responseMetadata) && { response_metadata: await reviveNested(value.responseMetadata, toolCallId) }
|
|
2011
2333
|
});
|
|
2012
2334
|
}
|
|
2013
2335
|
const { Command } = await loadLangGraph();
|
|
@@ -2024,37 +2346,148 @@ var BitfabLangGraphIntegration = class {
|
|
|
2024
2346
|
this.traceFunctionKey = config.traceFunctionKey;
|
|
2025
2347
|
this.callbackHandler = config.callbackHandler;
|
|
2026
2348
|
this.mockToolsOnReplay = config.options?.mockToolsOnReplay ?? true;
|
|
2349
|
+
this.getActiveSpan = config.getActiveSpan ?? (() => null);
|
|
2350
|
+
this.getTraceRootContexts = config.getTraceRootContexts ?? (() => null);
|
|
2351
|
+
}
|
|
2352
|
+
get middleware() {
|
|
2353
|
+
this.agentMiddleware ?? (this.agentMiddleware = {
|
|
2354
|
+
[AGENT_MIDDLEWARE_BRAND]: true,
|
|
2355
|
+
name: "BitfabAgentMiddleware",
|
|
2356
|
+
wrapToolCall: (request, handler) => this.interceptToolCall(request, handler)
|
|
2357
|
+
});
|
|
2358
|
+
return this.agentMiddleware;
|
|
2359
|
+
}
|
|
2360
|
+
instrument(graph) {
|
|
2361
|
+
const run = (config) => new GraphRun(this.graphRunHost, graph, config);
|
|
2362
|
+
return new Proxy(graph, { get: (target, property) => {
|
|
2363
|
+
if (property === "invoke") return (input, config) => run(config).invoke(input);
|
|
2364
|
+
if (property === "stream") return async (input, config) => run(config).stream(input);
|
|
2365
|
+
if (property === "streamEvents") return (input, config, streamOptions) => run(config).streamEvents(input, streamOptions);
|
|
2366
|
+
if (property === "batch") return (inputs, config) => Promise.all(inputs.map((input, index) => run(Array.isArray(config) ? config[index] : config).invoke(input)));
|
|
2367
|
+
if (property === "withConfig") return (config) => this.instrument(target.withConfig(config));
|
|
2368
|
+
const value = Reflect.get(target, property, target);
|
|
2369
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
2370
|
+
} });
|
|
2371
|
+
}
|
|
2372
|
+
get graphRunHost() {
|
|
2373
|
+
this.runHost ?? (this.runHost = {
|
|
2374
|
+
traceFunctionKey: this.traceFunctionKey,
|
|
2375
|
+
callbackHandler: this.callbackHandler,
|
|
2376
|
+
activeSpan: () => this.getActiveSpan(),
|
|
2377
|
+
rootSpan: (fn, finalize) => this.client.withSpan(this.traceFunctionKey, {
|
|
2378
|
+
name: this.traceFunctionKey,
|
|
2379
|
+
type: "agent",
|
|
2380
|
+
surface: "inherit",
|
|
2381
|
+
instrumentation: "langgraph",
|
|
2382
|
+
...finalize !== void 0 && { finalize }
|
|
2383
|
+
}, fn),
|
|
2384
|
+
traceRootContexts: () => this.getTraceRootContexts(),
|
|
2385
|
+
encodeRootInput: (input) => isCommand(input) ? encodeNativeToolResult(input) : input,
|
|
2386
|
+
reviveRootInput: async (input) => isEncodedToolResult(input) ? await reviveToolResult(input, "") : input
|
|
2387
|
+
});
|
|
2388
|
+
return this.runHost;
|
|
2389
|
+
}
|
|
2390
|
+
async createDeepAgent(params = {}) {
|
|
2391
|
+
const { createDeepAgent } = await loadPeer(["deepagents"], "deepagents", "/frameworks/deep-agents");
|
|
2392
|
+
return this.instrument(createDeepAgent({
|
|
2393
|
+
...params,
|
|
2394
|
+
middleware: this.withMiddleware(params.middleware),
|
|
2395
|
+
...params.subagents !== void 0 && { subagents: params.subagents.map((spec) => this.withSubagentMiddleware(spec)) }
|
|
2396
|
+
}));
|
|
2397
|
+
}
|
|
2398
|
+
async createAgent(params) {
|
|
2399
|
+
const { createAgent } = await loadPeer(["langchain"], "langchain", "/frameworks/langgraph");
|
|
2400
|
+
return this.instrument(createAgent({
|
|
2401
|
+
...params,
|
|
2402
|
+
middleware: this.withMiddleware(params.middleware)
|
|
2403
|
+
}));
|
|
2404
|
+
}
|
|
2405
|
+
withMiddleware(middleware = []) {
|
|
2406
|
+
return middleware.includes(this.middleware) ? [...middleware] : [...middleware, this.middleware];
|
|
2407
|
+
}
|
|
2408
|
+
withSubagentMiddleware(spec) {
|
|
2409
|
+
if (!isRecord$1(spec) || "runnable" in spec || "graphId" in spec) return spec;
|
|
2410
|
+
return {
|
|
2411
|
+
...spec,
|
|
2412
|
+
middleware: this.withMiddleware(Array.isArray(spec.middleware) ? spec.middleware : [])
|
|
2413
|
+
};
|
|
2414
|
+
}
|
|
2415
|
+
async interceptToolCall(request, handler) {
|
|
2416
|
+
const toolName = request.toolCall.name;
|
|
2417
|
+
const toolCallId = request.toolCall.id;
|
|
2418
|
+
const shouldMock = this.shouldMock(toolName);
|
|
2419
|
+
this.assertReplayToolResultExists(toolName, shouldMock);
|
|
2420
|
+
const traceId = this.recordingTraceId(toolName);
|
|
2421
|
+
if (traceId === null || !toolCallId) return await handler(request);
|
|
2422
|
+
const stepSpanId = this.stepSpanIdFor(request.runtime, traceId);
|
|
2423
|
+
return await this.runClaimedToolCall(traceId, toolCallId, toolName, shouldMock, request.toolCall.args, async () => await handler(request), stepSpanId);
|
|
2424
|
+
}
|
|
2425
|
+
stepSpanIdFor(config, traceId) {
|
|
2426
|
+
const namespace = isRecord$1(config) && isRecord$1(config.configurable) ? config.configurable.checkpoint_ns : void 0;
|
|
2427
|
+
return typeof namespace === "string" ? this.callbackHandler.visibleStepSpanId(namespace, traceId) : null;
|
|
2428
|
+
}
|
|
2429
|
+
recordingTraceId(toolName) {
|
|
2430
|
+
const activeSpan = this.getActiveSpan();
|
|
2431
|
+
if (activeSpan === null) {
|
|
2432
|
+
warnOnce(`langgraph-tool-call-outside-root:${this.traceFunctionKey}`, `tool call "${toolName}" ran outside a Bitfab trace for "${this.traceFunctionKey}", so it was not recorded as a replayable span. Run the agent through instrument(agent), createAgent(), or createDeepAgent().`);
|
|
2433
|
+
return null;
|
|
2434
|
+
}
|
|
2435
|
+
return activeSpan.traceId;
|
|
2436
|
+
}
|
|
2437
|
+
async runClaimedToolCall(traceId, toolCallId, toolName, shouldMock, args, run, stepSpanId) {
|
|
2438
|
+
const release = this.callbackHandler.claimToolCall(traceId, toolCallId);
|
|
2439
|
+
try {
|
|
2440
|
+
const result = await this.client.withSpan(this.traceFunctionKey, {
|
|
2441
|
+
name: toolName,
|
|
2442
|
+
type: "function",
|
|
2443
|
+
captureWhen: "nested",
|
|
2444
|
+
mockOnReplay: shouldMock,
|
|
2445
|
+
finalize: finalizeToolResult,
|
|
2446
|
+
surface: "inherit",
|
|
2447
|
+
instrumentation: "langgraph",
|
|
2448
|
+
...stepSpanId !== null && { frameworkParentSpanId: stepSpanId }
|
|
2449
|
+
}, async (_args) => await run())(args);
|
|
2450
|
+
return isEncodedToolResult(result) ? await reviveToolResult(result, toolCallId) : result;
|
|
2451
|
+
} finally {
|
|
2452
|
+
release();
|
|
2453
|
+
}
|
|
2454
|
+
}
|
|
2455
|
+
shouldMock(toolName) {
|
|
2456
|
+
return typeof this.mockToolsOnReplay === "boolean" ? this.mockToolsOnReplay : this.mockToolsOnReplay.includes(toolName);
|
|
2027
2457
|
}
|
|
2028
2458
|
wrapTools(tools) {
|
|
2029
2459
|
return tools.map((tool) => this.wrapTool(tool));
|
|
2030
2460
|
}
|
|
2031
2461
|
createInvoker(graph) {
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
};
|
|
2462
|
+
warnOnce("deprecated-create-invoker", "createInvoker(graph) is deprecated; use instrument(graph).invoke instead.");
|
|
2463
|
+
const traced = this.instrument(graph);
|
|
2464
|
+
return (input, config) => traced.invoke(input, config);
|
|
2036
2465
|
}
|
|
2037
2466
|
wrapTool(tool) {
|
|
2038
2467
|
const toolName = tool.name;
|
|
2039
2468
|
if (typeof toolName !== "string" || toolName.length === 0) throw new BitfabError("LangGraph replayable tools must have a name.", "https://docs.bitfab.ai/frameworks/langgraph");
|
|
2040
|
-
const
|
|
2041
|
-
const shouldMock = typeof mockToolsOnReplay === "boolean" ? mockToolsOnReplay : mockToolsOnReplay.includes(toolName);
|
|
2469
|
+
const shouldMock = this.shouldMock(toolName);
|
|
2042
2470
|
const originalInvoke = tool.invoke.bind(tool);
|
|
2043
2471
|
return new Proxy(tool, { get: (target, property) => {
|
|
2044
2472
|
if (property === "invoke") return async (input, ...rest) => {
|
|
2045
|
-
const toolCallId = isRecord$
|
|
2046
|
-
const args = isRecord$
|
|
2473
|
+
const toolCallId = isRecord$1(input) && typeof input.id === "string" ? input.id : "";
|
|
2474
|
+
const args = isRecord$1(input) && "args" in input ? input.args : input;
|
|
2047
2475
|
this.assertReplayToolResultExists(toolName, shouldMock);
|
|
2048
|
-
const
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2476
|
+
const traceId = this.getActiveSpan()?.traceId ?? null;
|
|
2477
|
+
const run = async () => await originalInvoke(input, ...rest);
|
|
2478
|
+
if (traceId === null || toolCallId === "") {
|
|
2479
|
+
const result = await this.client.withSpan(this.traceFunctionKey, {
|
|
2480
|
+
name: toolName,
|
|
2481
|
+
type: "function",
|
|
2482
|
+
captureWhen: "nested",
|
|
2483
|
+
mockOnReplay: shouldMock,
|
|
2484
|
+
finalize: finalizeToolResult,
|
|
2485
|
+
surface: "inherit",
|
|
2486
|
+
instrumentation: "langgraph"
|
|
2487
|
+
}, async (_args) => await run())(args);
|
|
2488
|
+
return isEncodedToolResult(result) ? await reviveToolResult(result, toolCallId) : result;
|
|
2489
|
+
}
|
|
2490
|
+
return await this.runClaimedToolCall(traceId, toolCallId, toolName, shouldMock, args, run, this.stepSpanIdFor(rest[0], traceId));
|
|
2058
2491
|
};
|
|
2059
2492
|
const value = Reflect.get(target, property, target);
|
|
2060
2493
|
return typeof value === "function" ? value.bind(target) : value;
|
|
@@ -2505,37 +2938,6 @@ function looksBinary(s) {
|
|
|
2505
2938
|
return s.slice(0, 8e3).includes(NUL);
|
|
2506
2939
|
}
|
|
2507
2940
|
//#endregion
|
|
2508
|
-
//#region src/integrationFixture.ts
|
|
2509
|
-
const INTEGRATION_FIXTURE_CONTEXT_KEY = "__bitfabIntegrationFixture";
|
|
2510
|
-
const INTEGRATION_FIXTURE_VERSION = 1;
|
|
2511
|
-
function isRecord$1(value) {
|
|
2512
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2513
|
-
}
|
|
2514
|
-
function createIntegrationFixtureContext(name, value) {
|
|
2515
|
-
const serialized = serializeValue(value);
|
|
2516
|
-
return { [INTEGRATION_FIXTURE_CONTEXT_KEY]: {
|
|
2517
|
-
version: INTEGRATION_FIXTURE_VERSION,
|
|
2518
|
-
name,
|
|
2519
|
-
value: serialized.json,
|
|
2520
|
-
...serialized.meta !== void 0 && { valueMeta: serialized.meta }
|
|
2521
|
-
} };
|
|
2522
|
-
}
|
|
2523
|
-
function extractIntegrationFixtures(spanData) {
|
|
2524
|
-
const contexts = spanData.contexts;
|
|
2525
|
-
if (!Array.isArray(contexts)) return;
|
|
2526
|
-
const fixtures = /* @__PURE__ */ new Map();
|
|
2527
|
-
for (const context of contexts) {
|
|
2528
|
-
if (!isRecord$1(context)) continue;
|
|
2529
|
-
const fixture = context[INTEGRATION_FIXTURE_CONTEXT_KEY];
|
|
2530
|
-
if (!isRecord$1(fixture) || fixture.version !== INTEGRATION_FIXTURE_VERSION || typeof fixture.name !== "string") continue;
|
|
2531
|
-
fixtures.set(fixture.name, deserializeValue({
|
|
2532
|
-
json: fixture.value,
|
|
2533
|
-
...fixture.valueMeta !== void 0 && { meta: fixture.valueMeta }
|
|
2534
|
-
}));
|
|
2535
|
-
}
|
|
2536
|
-
return fixtures.size > 0 ? fixtures : void 0;
|
|
2537
|
-
}
|
|
2538
|
-
//#endregion
|
|
2539
2941
|
//#region src/replayHeartbeat.ts
|
|
2540
2942
|
const REPLAY_HEARTBEAT_INTERVAL_MS = 6e4;
|
|
2541
2943
|
function startReplayHeartbeat(send) {
|
|
@@ -4686,25 +5088,45 @@ function runWithSpanStack(stack, fn) {
|
|
|
4686
5088
|
throw error;
|
|
4687
5089
|
}
|
|
4688
5090
|
}
|
|
5091
|
+
function isAsyncIterable(value) {
|
|
5092
|
+
return value !== null && typeof value === "object" && typeof value[Symbol.asyncIterator] === "function";
|
|
5093
|
+
}
|
|
5094
|
+
function drainingStreams(fn) {
|
|
5095
|
+
return async (...args) => {
|
|
5096
|
+
const result = await fn(...args);
|
|
5097
|
+
if (!isAsyncIterable(result)) return result;
|
|
5098
|
+
const chunks = [];
|
|
5099
|
+
for await (const chunk of result) chunks.push(chunk);
|
|
5100
|
+
const replay = getReplayContext();
|
|
5101
|
+
return replay !== null && "streamResult" in replay ? replay.streamResult : chunks;
|
|
5102
|
+
};
|
|
5103
|
+
}
|
|
4689
5104
|
function isAsyncGenerator(value) {
|
|
4690
5105
|
if (value === null || typeof value !== "object") return false;
|
|
4691
5106
|
const candidate = value;
|
|
4692
5107
|
return typeof candidate.next === "function" && typeof candidate.return === "function" && typeof candidate.throw === "function" && typeof candidate[Symbol.asyncIterator] === "function";
|
|
4693
5108
|
}
|
|
4694
|
-
function wrapAsyncGenerator(source, spanStack, sendSpan) {
|
|
5109
|
+
function wrapAsyncGenerator(source, spanStack, sendSpan, recordYielded) {
|
|
4695
5110
|
const yielded = [];
|
|
4696
5111
|
let returnValue;
|
|
4697
5112
|
let finalized = false;
|
|
4698
5113
|
const finalize = (errorMsg) => {
|
|
4699
5114
|
if (finalized) return;
|
|
4700
5115
|
finalized = true;
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
|
|
5116
|
+
if (recordYielded === void 0 || errorMsg) {
|
|
5117
|
+
sendSpan({
|
|
5118
|
+
result: {
|
|
5119
|
+
yielded,
|
|
5120
|
+
return: returnValue
|
|
5121
|
+
},
|
|
5122
|
+
...errorMsg && { error: errorMsg }
|
|
5123
|
+
});
|
|
5124
|
+
return;
|
|
5125
|
+
}
|
|
5126
|
+
Promise.resolve().then(() => recordYielded(yielded)).then((output) => sendSpan({ result: output }), (error) => sendSpan({
|
|
5127
|
+
result: void 0,
|
|
5128
|
+
error: `finalize failed: ${error instanceof Error ? error.message : String(error)}`
|
|
5129
|
+
}));
|
|
4708
5130
|
};
|
|
4709
5131
|
const step = (method, arg) => runWithSpanStack(spanStack, () => {
|
|
4710
5132
|
return source[method].call(source, arg);
|
|
@@ -4868,6 +5290,14 @@ const noOpTrace = {
|
|
|
4868
5290
|
addContext() {},
|
|
4869
5291
|
drop() {}
|
|
4870
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
|
+
}
|
|
4871
5301
|
function getCurrentSpan() {
|
|
4872
5302
|
const stack = getSpanStack();
|
|
4873
5303
|
const current = stack[stack.length - 1];
|
|
@@ -5378,16 +5808,23 @@ var Bitfab = class {
|
|
|
5378
5808
|
const stack = getSpanStack();
|
|
5379
5809
|
return stack[stack.length - 1] ?? null;
|
|
5380
5810
|
},
|
|
5381
|
-
captureTools: false,
|
|
5382
5811
|
_httpClient: this.httpClient
|
|
5383
5812
|
});
|
|
5384
5813
|
return new BitfabLangGraphIntegration({
|
|
5385
5814
|
client: this,
|
|
5386
5815
|
traceFunctionKey,
|
|
5387
5816
|
callbackHandler,
|
|
5388
|
-
options
|
|
5817
|
+
options,
|
|
5818
|
+
getActiveSpan: () => {
|
|
5819
|
+
const stack = getSpanStack();
|
|
5820
|
+
return stack[stack.length - 1] ?? null;
|
|
5821
|
+
},
|
|
5822
|
+
getTraceRootContexts: () => currentTraceRootSpan()?.details.contexts ?? null
|
|
5389
5823
|
});
|
|
5390
5824
|
}
|
|
5825
|
+
getDeepAgentsIntegration(traceFunctionKey, options) {
|
|
5826
|
+
return this.getLangGraphIntegration(traceFunctionKey, options);
|
|
5827
|
+
}
|
|
5391
5828
|
getRivetIntegration(traceFunctionKey, options) {
|
|
5392
5829
|
return new BitfabRivetIntegration(traceFunctionKey, {
|
|
5393
5830
|
wrapEffect: (effect, mockOnReplay, fn, replayOutput) => {
|
|
@@ -5403,7 +5840,7 @@ var Bitfab = class {
|
|
|
5403
5840
|
return this.withSpan(traceFunctionKey, spanOptions, fn);
|
|
5404
5841
|
},
|
|
5405
5842
|
recordRootFixture: (context, recordedRoots) => {
|
|
5406
|
-
const root =
|
|
5843
|
+
const root = currentTraceRootSpan();
|
|
5407
5844
|
if (!root) return;
|
|
5408
5845
|
const rootId = `${root.traceId}:${root.spanId}`;
|
|
5409
5846
|
if (recordedRoots.has(rootId)) return;
|
|
@@ -5574,7 +6011,9 @@ var Bitfab = class {
|
|
|
5574
6011
|
const seedCtxForTraceId = parentContext ? null : getSeedContext();
|
|
5575
6012
|
const traceId = parentContext?.traceId ?? replayCtxForTraceId?.traceId ?? seedCtxForTraceId?.traceId ?? randomUuid();
|
|
5576
6013
|
const spanId = randomUuid();
|
|
5577
|
-
const
|
|
6014
|
+
const openAiAgentsParent = parentContext !== void 0 && options.instrumentation === "trace" ? openAiAgentsParentSpanId(parentContext.traceId, parentContext.openAiAgentsSpanIds) : void 0;
|
|
6015
|
+
const frameworkParent = parentContext !== void 0 ? options.frameworkParentSpanId : void 0;
|
|
6016
|
+
const parentSpanId = openAiAgentsParent ?? frameworkParent ?? parentContext?.spanId ?? null;
|
|
5578
6017
|
const isRootSpan = parentSpanId === null;
|
|
5579
6018
|
if (options.enclosingTrace !== void 0) {
|
|
5580
6019
|
options.enclosingTrace.link.traceId = traceId;
|
|
@@ -5729,7 +6168,7 @@ var Bitfab = class {
|
|
|
5729
6168
|
});
|
|
5730
6169
|
throw error;
|
|
5731
6170
|
});
|
|
5732
|
-
if (isAsyncGenerator(result)) return wrapAsyncGenerator(result, newStack, sendSpan);
|
|
6171
|
+
if (isAsyncGenerator(result)) return wrapAsyncGenerator(result, newStack, sendSpan, options.finalize);
|
|
5733
6172
|
recordSpan(result);
|
|
5734
6173
|
return result;
|
|
5735
6174
|
};
|
|
@@ -6159,7 +6598,7 @@ var Bitfab = class {
|
|
|
6159
6598
|
await runWithSeedContext({ traceId }, async () => target(...args));
|
|
6160
6599
|
} finally {
|
|
6161
6600
|
try {
|
|
6162
|
-
const { flushTraces } = await import("./http-
|
|
6601
|
+
const { flushTraces } = await import("./http-WVZO9E-Q.js").then((n) => n.a);
|
|
6163
6602
|
await flushTraces(3e4);
|
|
6164
6603
|
} finally {
|
|
6165
6604
|
unrecorded = activeTraceStates.delete(traceId);
|
|
@@ -6197,7 +6636,7 @@ var Bitfab = class {
|
|
|
6197
6636
|
type: "agent",
|
|
6198
6637
|
surface: "neutral"
|
|
6199
6638
|
};
|
|
6200
|
-
replayFn = this.withSpan(traceFunctionKey, replayRootOptions, fn);
|
|
6639
|
+
replayFn = this.withSpan(traceFunctionKey, replayRootOptions, drainingStreams(fn));
|
|
6201
6640
|
} else if (wrappedKey !== traceFunctionKey) throw new BitfabError(`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.`);
|
|
6202
6641
|
const { replay: doReplay } = await Promise.resolve().then(() => replay_exports);
|
|
6203
6642
|
return doReplay(this.httpClient, this.serviceUrl, traceFunctionKey, replayFn, options, this.mockOverrides);
|
|
@@ -6239,6 +6678,9 @@ var BitfabFunction = class {
|
|
|
6239
6678
|
getLangGraphIntegration(options) {
|
|
6240
6679
|
return this.client.getLangGraphIntegration(this.traceFunctionKey, options);
|
|
6241
6680
|
}
|
|
6681
|
+
getDeepAgentsIntegration(options) {
|
|
6682
|
+
return this.client.getDeepAgentsIntegration(this.traceFunctionKey, options);
|
|
6683
|
+
}
|
|
6242
6684
|
getRivetIntegration(options) {
|
|
6243
6685
|
return this.client.getRivetIntegration(this.traceFunctionKey, options);
|
|
6244
6686
|
}
|
|
@@ -6353,7 +6795,7 @@ async function seedFromRegistry(registry, pipeline, cases, options = {}) {
|
|
|
6353
6795
|
metadata: seedCase.metadata,
|
|
6354
6796
|
sessionId: seedCase.sessionId
|
|
6355
6797
|
}));
|
|
6356
|
-
const { flushTraces } = await import("./http-
|
|
6798
|
+
const { flushTraces } = await import("./http-WVZO9E-Q.js").then((n) => n.a);
|
|
6357
6799
|
await flushTraces(3e4);
|
|
6358
6800
|
return {
|
|
6359
6801
|
pipeline,
|
|
@@ -6370,4 +6812,4 @@ function resolveTraceFunctionKey(registration) {
|
|
|
6370
6812
|
//#endregion
|
|
6371
6813
|
export { ExperimentsClient as A, BitfabOpenAIAgentHandler as C, GradersClient as D, BitfabLangGraphCallbackHandler as E, BitfabClaudeAgentHandler as F, DEFAULT_SERVICE_URL as I, AssertionCategoriesClient as L, DatasetsClient as M, GraderRerunError as N, LabelsClient as O, GraderRerunTimeoutError as P, CategoriesClient as R, OrganizationMembersClient as S, BitfabLangGraphIntegration as T, BITFAB_PROGRESS_PREFIX as _, Bitfab as a, reportReplayProgress as b, getCurrentSpan as c, BitfabOpenAITracingProcessor as d, AssertionGenerationError as f, BitfabRivetIntegration as g, SpansClient as h, finalizers as i, SUPPORTED_PROVIDERS as j, VerdictsClient as k, getCurrentTrace as l, TracesClient as m, reseedFromRegistry as n, BitfabFunction as o, AssertionGenerationTimeoutError as p, seedFromRegistry as r, getCurrentReplayBranch as s, defineReplayRegistry as t, BitfabVercelAiHandler as u, DbBranchReplayError as v, NO_MOCK_OVERRIDE as w, serializeReplayResult as x, ReplayError as y };
|
|
6372
6814
|
|
|
6373
|
-
//# sourceMappingURL=src
|
|
6815
|
+
//# sourceMappingURL=src--sgdobPE.js.map
|