braintrust 3.32.0 → 3.33.0
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/README.md +0 -43
- package/dev/dist/index.d.mts +31 -0
- package/dev/dist/index.d.ts +31 -0
- package/dev/dist/index.js +2275 -920
- package/dev/dist/index.mjs +1610 -255
- package/dist/apply-auto-instrumentation.js +263 -224
- package/dist/apply-auto-instrumentation.mjs +45 -6
- package/dist/auto-instrumentations/bundler/esbuild.cjs +78 -5
- package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
- package/dist/auto-instrumentations/bundler/next.cjs +78 -5
- package/dist/auto-instrumentations/bundler/next.mjs +3 -3
- package/dist/auto-instrumentations/bundler/rollup.cjs +78 -5
- package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
- package/dist/auto-instrumentations/bundler/vite.cjs +78 -5
- package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
- package/dist/auto-instrumentations/bundler/webpack-loader.cjs +78 -5
- package/dist/auto-instrumentations/bundler/webpack.cjs +78 -5
- package/dist/auto-instrumentations/bundler/webpack.mjs +3 -3
- package/dist/auto-instrumentations/{chunk-AFND2U7E.mjs → chunk-T2DMPWFI.mjs} +75 -5
- package/dist/auto-instrumentations/{chunk-RI4Y55ZF.mjs → chunk-UHJ2DNYJ.mjs} +6 -1
- package/dist/auto-instrumentations/{chunk-QEEPRBIS.mjs → chunk-W5QNG3PV.mjs} +1 -1
- package/dist/auto-instrumentations/hook.mjs +86 -7
- package/dist/auto-instrumentations/index.cjs +76 -5
- package/dist/auto-instrumentations/index.d.mts +3 -1
- package/dist/auto-instrumentations/index.d.ts +3 -1
- package/dist/auto-instrumentations/index.mjs +3 -1
- package/dist/browser.d.mts +202 -342
- package/dist/browser.d.ts +202 -342
- package/dist/browser.js +2586 -623
- package/dist/browser.mjs +2586 -623
- package/dist/chunk-7P6ASYW6.mjs +9 -0
- package/dist/{chunk-BTRLPQG5.js → chunk-AXJTOUOC.js} +2250 -1172
- package/dist/{chunk-AW4QECG5.js → chunk-G3VHOHRC.js} +40 -9
- package/dist/chunk-MLKGABMK.js +9 -0
- package/dist/{chunk-4QSAHP7D.mjs → chunk-MZLBAFVJ.mjs} +1236 -158
- package/dist/{chunk-WV6QZI2W.mjs → chunk-TZVZN2JJ.mjs} +39 -8
- package/dist/cli.js +1695 -293
- package/dist/custom-views.d.mts +112 -0
- package/dist/custom-views.d.ts +112 -0
- package/dist/custom-views.js +13 -0
- package/dist/custom-views.mjs +13 -0
- package/dist/edge-light.d.mts +1 -1
- package/dist/edge-light.d.ts +1 -1
- package/dist/edge-light.js +2586 -623
- package/dist/edge-light.mjs +2586 -623
- package/dist/index.d.mts +202 -342
- package/dist/index.d.ts +202 -342
- package/dist/index.js +1842 -986
- package/dist/index.mjs +1310 -454
- package/dist/instrumentation/index.d.mts +5 -245
- package/dist/instrumentation/index.d.ts +5 -245
- package/dist/instrumentation/index.js +1694 -254
- package/dist/instrumentation/index.mjs +1694 -254
- package/dist/vitest-evals-reporter.js +17 -16
- package/dist/vitest-evals-reporter.mjs +3 -2
- package/dist/workerd.d.mts +1 -1
- package/dist/workerd.d.ts +1 -1
- package/dist/workerd.js +2586 -623
- package/dist/workerd.mjs +2586 -623
- package/package.json +10 -2
package/dist/browser.js
CHANGED
|
@@ -38,8 +38,6 @@ __export(browser_exports, {
|
|
|
38
38
|
BRAINTRUST_PARENT_KEY: () => BRAINTRUST_PARENT_KEY,
|
|
39
39
|
BaseAttachment: () => BaseAttachment,
|
|
40
40
|
BaseExperiment: () => BaseExperiment,
|
|
41
|
-
BatchScorer: () => BatchScorer,
|
|
42
|
-
BatchTask: () => BatchTask,
|
|
43
41
|
BraintrustLangChainCallbackHandler: () => BraintrustLangChainCallbackHandler,
|
|
44
42
|
BraintrustMiddleware: () => BraintrustMiddleware,
|
|
45
43
|
BraintrustObservabilityExporter: () => BraintrustObservabilityExporter,
|
|
@@ -53,8 +51,6 @@ __export(browser_exports, {
|
|
|
53
51
|
DEFAULT_MAX_REQUEST_SIZE: () => DEFAULT_MAX_REQUEST_SIZE,
|
|
54
52
|
Dataset: () => Dataset2,
|
|
55
53
|
DatasetPipeline: () => DatasetPipeline,
|
|
56
|
-
DurableEvalMemoryStore: () => DurableEvalMemoryStore,
|
|
57
|
-
DurableEvalRedisStore: () => DurableEvalRedisStore,
|
|
58
54
|
ERR_PERMALINK: () => ERR_PERMALINK,
|
|
59
55
|
Eval: () => Eval,
|
|
60
56
|
EvalResultWithSummary: () => EvalResultWithSummary,
|
|
@@ -89,6 +85,10 @@ __export(browser_exports, {
|
|
|
89
85
|
TestBackgroundLogger: () => TestBackgroundLogger,
|
|
90
86
|
ToolBuilder: () => ToolBuilder,
|
|
91
87
|
UUIDGenerator: () => UUIDGenerator,
|
|
88
|
+
WorkflowEvalMemoryStore: () => WorkflowEvalMemoryStore,
|
|
89
|
+
WorkflowEvalRedisStore: () => WorkflowEvalRedisStore,
|
|
90
|
+
WorkflowScorer: () => WorkflowScorer,
|
|
91
|
+
WorkflowTask: () => WorkflowTask,
|
|
92
92
|
X_CACHED_HEADER: () => X_CACHED_HEADER,
|
|
93
93
|
_exportsForTestingOnly: () => _exportsForTestingOnly,
|
|
94
94
|
_internalGetGlobalState: () => _internalGetGlobalState,
|
|
@@ -114,12 +114,13 @@ __export(browser_exports, {
|
|
|
114
114
|
deepCopyEvent: () => deepCopyEvent,
|
|
115
115
|
default: () => exports_exports,
|
|
116
116
|
defaultErrorScoreHandler: () => defaultErrorScoreHandler,
|
|
117
|
-
|
|
117
|
+
defineWorkflowEval: () => defineWorkflowEval,
|
|
118
118
|
deserializePlainStringAsJSON: () => deserializePlainStringAsJSON,
|
|
119
119
|
devNullWritableStream: () => devNullWritableStream,
|
|
120
120
|
evaluatorDefinitionSchema: () => evaluatorDefinitionSchema,
|
|
121
121
|
evaluatorDefinitionsSchema: () => evaluatorDefinitionsSchema,
|
|
122
122
|
extractTraceContextFromHeaders: () => extractTraceContextFromHeaders,
|
|
123
|
+
failOpenAIAgentsTrace: () => failOpenAIAgentsTrace,
|
|
123
124
|
flush: () => flush,
|
|
124
125
|
getContextManager: () => getContextManager,
|
|
125
126
|
getIdGenerator: () => getIdGenerator,
|
|
@@ -166,12 +167,14 @@ __export(browser_exports, {
|
|
|
166
167
|
setFetch: () => setFetch,
|
|
167
168
|
setMaskingFunction: () => setMaskingFunction,
|
|
168
169
|
spanComponentsToObjectId: () => spanComponentsToObjectId,
|
|
170
|
+
startOpenAIAgentsTrace: () => startOpenAIAgentsTrace,
|
|
169
171
|
startSpan: () => startSpan,
|
|
170
172
|
summarize: () => summarize,
|
|
171
173
|
templateRegistry: () => templateRegistry,
|
|
172
174
|
toolFunctionDefinitionSchema: () => ToolFunctionDefinition,
|
|
173
175
|
traceable: () => traceable,
|
|
174
176
|
traced: () => traced,
|
|
177
|
+
updateOpenAIAgentsTrace: () => updateOpenAIAgentsTrace,
|
|
175
178
|
updateSpan: () => updateSpan,
|
|
176
179
|
uploadLogs3OverflowPayload: () => uploadLogs3OverflowPayload,
|
|
177
180
|
utf8ByteLength: () => utf8ByteLength2,
|
|
@@ -200,6 +203,7 @@ __export(browser_exports, {
|
|
|
200
203
|
wrapGroq: () => wrapGroq,
|
|
201
204
|
wrapHuggingFace: () => wrapHuggingFace,
|
|
202
205
|
wrapHuggingFaceTransformers: () => wrapHuggingFaceTransformers,
|
|
206
|
+
wrapLangGraphSDK: () => wrapLangGraphSDK,
|
|
203
207
|
wrapLangSmithClient: () => wrapLangSmithClient,
|
|
204
208
|
wrapLangSmithRunTrees: () => wrapLangSmithRunTrees,
|
|
205
209
|
wrapLangSmithTraceable: () => wrapLangSmithTraceable,
|
|
@@ -5884,6 +5888,7 @@ var INSTRUMENTATION_NAMES = {
|
|
|
5884
5888
|
LANGSMITH: "langsmith",
|
|
5885
5889
|
MASTRA: "mastra",
|
|
5886
5890
|
MISTRAL: "mistral",
|
|
5891
|
+
LANGGRAPH_SDK: "langgraph-sdk",
|
|
5887
5892
|
OLLAMA: "ollama",
|
|
5888
5893
|
OPENAI: "openai",
|
|
5889
5894
|
OPENAI_AGENTS: "openai-agents",
|
|
@@ -5898,7 +5903,7 @@ var INSTRUMENTATION_NAMES = {
|
|
|
5898
5903
|
var INTERNAL_SPAN_INSTRUMENTATION_NAME = /* @__PURE__ */ Symbol.for(
|
|
5899
5904
|
"braintrust.spanInstrumentationName"
|
|
5900
5905
|
);
|
|
5901
|
-
var SDK_VERSION = true ? "3.
|
|
5906
|
+
var SDK_VERSION = true ? "3.33.0" : "0.0.0";
|
|
5902
5907
|
function withSpanInstrumentationName(args, instrumentationName) {
|
|
5903
5908
|
return {
|
|
5904
5909
|
...args,
|
|
@@ -9689,6 +9694,38 @@ function getSpanParentObjectAndPropagatedState(options) {
|
|
|
9689
9694
|
function getSpanParentObject(options) {
|
|
9690
9695
|
return getSpanParentObjectAndPropagatedState(options).parentObject;
|
|
9691
9696
|
}
|
|
9697
|
+
function _internalExportParentSynchronously(parent) {
|
|
9698
|
+
if ("toStr" in parent) {
|
|
9699
|
+
return parent.toStr();
|
|
9700
|
+
}
|
|
9701
|
+
if ("getParentInfo" in parent) {
|
|
9702
|
+
const parentInfo = parent.getParentInfo();
|
|
9703
|
+
if (!parentInfo) {
|
|
9704
|
+
return void 0;
|
|
9705
|
+
}
|
|
9706
|
+
const objectId = parentInfo.objectId.getSync().value;
|
|
9707
|
+
if (!objectId && !parentInfo.computeObjectMetadataArgs) {
|
|
9708
|
+
return void 0;
|
|
9709
|
+
}
|
|
9710
|
+
return new SpanComponentsV4({
|
|
9711
|
+
object_type: parentInfo.objectType,
|
|
9712
|
+
...objectId ? { object_id: objectId } : {
|
|
9713
|
+
compute_object_metadata_args: parentInfo.computeObjectMetadataArgs ?? {}
|
|
9714
|
+
},
|
|
9715
|
+
row_id: parent.id,
|
|
9716
|
+
root_span_id: parent.rootSpanId,
|
|
9717
|
+
span_id: parent.spanId
|
|
9718
|
+
}).toStr();
|
|
9719
|
+
}
|
|
9720
|
+
const components = braintrustParentToComponents(parent._getOtelParent());
|
|
9721
|
+
if (!components) {
|
|
9722
|
+
return void 0;
|
|
9723
|
+
}
|
|
9724
|
+
return new SpanComponentsV4({
|
|
9725
|
+
object_type: components.objectType,
|
|
9726
|
+
...components.objectId ? { object_id: components.objectId } : { compute_object_metadata_args: components.computeArgs ?? {} }
|
|
9727
|
+
}).toStr();
|
|
9728
|
+
}
|
|
9692
9729
|
function currentBraintrustParent(state) {
|
|
9693
9730
|
const resolvedState = state ?? _globalState;
|
|
9694
9731
|
const experiment = currentExperiment({ state: resolvedState });
|
|
@@ -11300,10 +11337,16 @@ var SpanImpl = class _SpanImpl {
|
|
|
11300
11337
|
inject(carrier) {
|
|
11301
11338
|
const resolvedCarrier = carrier ?? {};
|
|
11302
11339
|
try {
|
|
11340
|
+
const braintrustParent = this._getOtelParent() ?? this._propagatedState?.braintrustParent;
|
|
11341
|
+
if (!braintrustParent) {
|
|
11342
|
+
debugLogger.forState(this._state).warn(
|
|
11343
|
+
"Injecting trace context without braintrust.parent because the span's destination is not available yet. The receiver will start a new local trace instead of continuing this one."
|
|
11344
|
+
);
|
|
11345
|
+
}
|
|
11303
11346
|
_injectIntoCarrier(resolvedCarrier, {
|
|
11304
11347
|
traceId: this._rootSpanId,
|
|
11305
11348
|
spanId: this._spanId,
|
|
11306
|
-
braintrustParent
|
|
11349
|
+
braintrustParent,
|
|
11307
11350
|
propagatedState: this._propagatedState
|
|
11308
11351
|
});
|
|
11309
11352
|
} catch (e) {
|
|
@@ -13708,6 +13751,18 @@ function defineChannels(pkg, channels, options) {
|
|
|
13708
13751
|
var openAIChannels = defineChannels(
|
|
13709
13752
|
"openai",
|
|
13710
13753
|
{
|
|
13754
|
+
agentsTraceStart: channel({
|
|
13755
|
+
channelName: "agents.trace.start",
|
|
13756
|
+
kind: "async"
|
|
13757
|
+
}),
|
|
13758
|
+
agentsTraceCapture: channel({
|
|
13759
|
+
channelName: "agents.trace.capture",
|
|
13760
|
+
kind: "async"
|
|
13761
|
+
}),
|
|
13762
|
+
agentsTraceFail: channel({
|
|
13763
|
+
channelName: "agents.trace.fail",
|
|
13764
|
+
kind: "async"
|
|
13765
|
+
}),
|
|
13711
13766
|
filesCreateTraced: channel({
|
|
13712
13767
|
channelName: "files.create-traced",
|
|
13713
13768
|
kind: "async"
|
|
@@ -14076,6 +14131,23 @@ function getCachedMetricFromHeaders(headers) {
|
|
|
14076
14131
|
return parseCachedHeader(headers.get(LEGACY_CACHED_HEADER));
|
|
14077
14132
|
}
|
|
14078
14133
|
|
|
14134
|
+
// src/instrumentation/plugins/openai-manual-instrumentation-utils.ts
|
|
14135
|
+
async function deterministicDigest(namespace, ...parts) {
|
|
14136
|
+
const encoded = new TextEncoder().encode(
|
|
14137
|
+
[namespace, ...parts].map((part) => `${part.length}:${part}`).join("\0")
|
|
14138
|
+
);
|
|
14139
|
+
return new Uint8Array(
|
|
14140
|
+
await globalThis.crypto.subtle.digest("SHA-256", encoded)
|
|
14141
|
+
);
|
|
14142
|
+
}
|
|
14143
|
+
function digestHex(bytes, length) {
|
|
14144
|
+
return Array.from(bytes.slice(0, length)).map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
14145
|
+
}
|
|
14146
|
+
function digestUuid(bytes) {
|
|
14147
|
+
const hex = digestHex(bytes, 16);
|
|
14148
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
14149
|
+
}
|
|
14150
|
+
|
|
14079
14151
|
// src/instrumentation/plugins/openai-batch-instrumentation.ts
|
|
14080
14152
|
var SUPPORTED_ENDPOINTS = /* @__PURE__ */ new Set(["/v1/chat/completions", "/v1/responses"]);
|
|
14081
14153
|
var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
@@ -14116,21 +14188,6 @@ async function exportParent(parent) {
|
|
|
14116
14188
|
}
|
|
14117
14189
|
return void 0;
|
|
14118
14190
|
}
|
|
14119
|
-
async function deterministicDigest(namespace, ...parts) {
|
|
14120
|
-
const encoded = new TextEncoder().encode(
|
|
14121
|
-
[namespace, ...parts].map((part) => `${part.length}:${part}`).join("\0")
|
|
14122
|
-
);
|
|
14123
|
-
return new Uint8Array(
|
|
14124
|
-
await globalThis.crypto.subtle.digest("SHA-256", encoded)
|
|
14125
|
-
);
|
|
14126
|
-
}
|
|
14127
|
-
function digestHex(bytes, length) {
|
|
14128
|
-
return Array.from(bytes.slice(0, length)).map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
14129
|
-
}
|
|
14130
|
-
function digestUuid(bytes) {
|
|
14131
|
-
const hex = digestHex(bytes, 16);
|
|
14132
|
-
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
14133
|
-
}
|
|
14134
14191
|
async function batchSpanIds(inputFileId) {
|
|
14135
14192
|
const [row, span, root] = await Promise.all([
|
|
14136
14193
|
deterministicDigest("openai:batch:row", inputFileId),
|
|
@@ -14621,6 +14678,628 @@ var interceptOpenAIBatchTraceComplete = (target, thisArg, args) => Promise.resol
|
|
|
14621
14678
|
return result;
|
|
14622
14679
|
});
|
|
14623
14680
|
|
|
14681
|
+
// src/instrumentation/plugins/openai-agents-api-instrumentation.ts
|
|
14682
|
+
var TERMINAL_TURN_EVENTS = /* @__PURE__ */ new Set([
|
|
14683
|
+
"agent.session.turn.completed",
|
|
14684
|
+
"agent.session.turn.failed",
|
|
14685
|
+
"agent.session.turn.cancelled"
|
|
14686
|
+
]);
|
|
14687
|
+
var TURN_LIFECYCLE_EVENTS = /* @__PURE__ */ new Set([
|
|
14688
|
+
"agent.session.turn.created",
|
|
14689
|
+
"agent.session.turn.in_progress",
|
|
14690
|
+
...TERMINAL_TURN_EVENTS
|
|
14691
|
+
]);
|
|
14692
|
+
var SESSION_EVENTS = /* @__PURE__ */ new Set([
|
|
14693
|
+
"agent.session.created",
|
|
14694
|
+
"agent.session.failed",
|
|
14695
|
+
"agent.session.idle",
|
|
14696
|
+
"agent.session.in_progress",
|
|
14697
|
+
"agent.session.requires_action"
|
|
14698
|
+
]);
|
|
14699
|
+
var SUBAGENT_EVENTS = /* @__PURE__ */ new Set([
|
|
14700
|
+
"agent.session.subagent.active",
|
|
14701
|
+
"agent.session.subagent.closed",
|
|
14702
|
+
"agent.session.subagent.created"
|
|
14703
|
+
]);
|
|
14704
|
+
function read2(value, key) {
|
|
14705
|
+
if (!isObject(value)) {
|
|
14706
|
+
return void 0;
|
|
14707
|
+
}
|
|
14708
|
+
try {
|
|
14709
|
+
return Reflect.get(value, key);
|
|
14710
|
+
} catch {
|
|
14711
|
+
return void 0;
|
|
14712
|
+
}
|
|
14713
|
+
}
|
|
14714
|
+
function stringValue(value) {
|
|
14715
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
14716
|
+
}
|
|
14717
|
+
function recordValue(record, key) {
|
|
14718
|
+
return Object.hasOwn(record, key) ? record[key] : void 0;
|
|
14719
|
+
}
|
|
14720
|
+
function setRecordValue(record, key, value) {
|
|
14721
|
+
Object.defineProperty(record, key, {
|
|
14722
|
+
configurable: true,
|
|
14723
|
+
enumerable: true,
|
|
14724
|
+
value,
|
|
14725
|
+
writable: true
|
|
14726
|
+
});
|
|
14727
|
+
}
|
|
14728
|
+
function loggedError(value, fallback2) {
|
|
14729
|
+
if (value instanceof Error) {
|
|
14730
|
+
return value;
|
|
14731
|
+
}
|
|
14732
|
+
const message = stringValue(read2(value, "message"));
|
|
14733
|
+
return new Error(message ?? (typeof value === "string" ? value : fallback2));
|
|
14734
|
+
}
|
|
14735
|
+
function logInstrumentationError(context, error) {
|
|
14736
|
+
debugLogger.debug(`OpenAI Agents API instrumentation ${context}:`, error);
|
|
14737
|
+
}
|
|
14738
|
+
async function childSpanIds2(rootKey, kind, providerId) {
|
|
14739
|
+
const [row, span] = await Promise.all([
|
|
14740
|
+
deterministicDigest("openai:agents:row", rootKey, kind, providerId),
|
|
14741
|
+
deterministicDigest("openai:agents:span", rootKey, kind, providerId)
|
|
14742
|
+
]);
|
|
14743
|
+
return { rowId: digestUuid(row), spanId: digestHex(span, 8) };
|
|
14744
|
+
}
|
|
14745
|
+
function traceMetadata(args) {
|
|
14746
|
+
const metadata = {};
|
|
14747
|
+
const suppliedMetadata = read2(args, "metadata");
|
|
14748
|
+
if (isObject(suppliedMetadata)) {
|
|
14749
|
+
try {
|
|
14750
|
+
for (const key of Object.keys(suppliedMetadata)) {
|
|
14751
|
+
metadata[key] = read2(suppliedMetadata, key);
|
|
14752
|
+
}
|
|
14753
|
+
} catch (error) {
|
|
14754
|
+
logInstrumentationError("could not read supplied metadata", error);
|
|
14755
|
+
}
|
|
14756
|
+
}
|
|
14757
|
+
const agent = read2(args, "agent");
|
|
14758
|
+
const agentId = stringValue(read2(agent, "id")) ?? stringValue(read2(args, "agent_id"));
|
|
14759
|
+
const agentName = stringValue(read2(agent, "name"));
|
|
14760
|
+
const model = stringValue(read2(agent, "model"));
|
|
14761
|
+
return {
|
|
14762
|
+
...metadata,
|
|
14763
|
+
api: "agents",
|
|
14764
|
+
...agentId ? { agent_id: agentId } : {},
|
|
14765
|
+
...agentName ? { agent_name: agentName } : {},
|
|
14766
|
+
...model ? { model } : {},
|
|
14767
|
+
provider: "openai"
|
|
14768
|
+
};
|
|
14769
|
+
}
|
|
14770
|
+
function copyState(state) {
|
|
14771
|
+
return {
|
|
14772
|
+
...state,
|
|
14773
|
+
callItems: { ...state.callItems },
|
|
14774
|
+
eventIds: [...state.eventIds],
|
|
14775
|
+
openTools: { ...state.openTools },
|
|
14776
|
+
subagents: { ...state.subagents },
|
|
14777
|
+
turnSubagents: { ...state.turnSubagents }
|
|
14778
|
+
};
|
|
14779
|
+
}
|
|
14780
|
+
function startRootSpan(state) {
|
|
14781
|
+
const root = SpanComponentsV4.fromStr(state.root);
|
|
14782
|
+
const parent = SpanComponentsV4.fromStr(state.rootParent);
|
|
14783
|
+
const rowId = stringValue(root.data.row_id);
|
|
14784
|
+
const rootSpanId = stringValue(root.data.root_span_id);
|
|
14785
|
+
const spanId = stringValue(root.data.span_id);
|
|
14786
|
+
if (!rowId || !rootSpanId || !spanId) {
|
|
14787
|
+
throw new Error("OpenAI Agents trace root is invalid");
|
|
14788
|
+
}
|
|
14789
|
+
const hasParentSpan = Boolean(
|
|
14790
|
+
parent.data.row_id && parent.data.span_id && parent.data.root_span_id
|
|
14791
|
+
);
|
|
14792
|
+
return withCurrent(
|
|
14793
|
+
NOOP_SPAN,
|
|
14794
|
+
() => _internalStartSpanWithInitialMergeAndParentSpanIds(
|
|
14795
|
+
withSpanInstrumentationName(
|
|
14796
|
+
{
|
|
14797
|
+
name: "openai.agents.turn",
|
|
14798
|
+
type: "task" /* TASK */,
|
|
14799
|
+
parent: state.rootParent,
|
|
14800
|
+
...!hasParentSpan ? {
|
|
14801
|
+
parentSpanIds: {
|
|
14802
|
+
parentSpanIds: [],
|
|
14803
|
+
rootSpanId
|
|
14804
|
+
}
|
|
14805
|
+
} : {},
|
|
14806
|
+
spanId,
|
|
14807
|
+
startTime: state.startTime,
|
|
14808
|
+
event: { id: rowId }
|
|
14809
|
+
},
|
|
14810
|
+
INSTRUMENTATION_NAMES.OPENAI
|
|
14811
|
+
)
|
|
14812
|
+
)
|
|
14813
|
+
);
|
|
14814
|
+
}
|
|
14815
|
+
async function startSubagentSpan(state, subagentId, input, metadata, visiting = /* @__PURE__ */ new Set()) {
|
|
14816
|
+
const subagent = recordValue(state.subagents, subagentId);
|
|
14817
|
+
let parent = state.root;
|
|
14818
|
+
if (subagent?.parentAgentId && subagent.parentAgentId !== subagentId && recordValue(state.subagents, subagent.parentAgentId) && !visiting.has(subagent.parentAgentId)) {
|
|
14819
|
+
visiting.add(subagentId);
|
|
14820
|
+
parent = await (await startSubagentSpan(
|
|
14821
|
+
state,
|
|
14822
|
+
subagent.parentAgentId,
|
|
14823
|
+
void 0,
|
|
14824
|
+
void 0,
|
|
14825
|
+
visiting
|
|
14826
|
+
)).export();
|
|
14827
|
+
}
|
|
14828
|
+
const ids = await childSpanIds2(state.rootKey, "subagent", subagentId);
|
|
14829
|
+
return withCurrent(
|
|
14830
|
+
NOOP_SPAN,
|
|
14831
|
+
() => _internalStartSpanWithInitialMerge(
|
|
14832
|
+
withSpanInstrumentationName(
|
|
14833
|
+
{
|
|
14834
|
+
name: "openai.agents.subagent",
|
|
14835
|
+
type: "task" /* TASK */,
|
|
14836
|
+
parent,
|
|
14837
|
+
spanId: ids.spanId,
|
|
14838
|
+
startTime: subagent?.openedAt,
|
|
14839
|
+
event: {
|
|
14840
|
+
id: ids.rowId,
|
|
14841
|
+
...input !== void 0 ? { input } : {},
|
|
14842
|
+
metadata: {
|
|
14843
|
+
...metadata,
|
|
14844
|
+
agent_id: subagentId,
|
|
14845
|
+
...subagent?.parentAgentId ? { parent_agent_id: subagent.parentAgentId } : {},
|
|
14846
|
+
provider: "openai"
|
|
14847
|
+
}
|
|
14848
|
+
}
|
|
14849
|
+
},
|
|
14850
|
+
INSTRUMENTATION_NAMES.OPENAI
|
|
14851
|
+
)
|
|
14852
|
+
)
|
|
14853
|
+
);
|
|
14854
|
+
}
|
|
14855
|
+
async function parentForTurn(state, turnId) {
|
|
14856
|
+
const subagentId = turnId ? recordValue(state.turnSubagents, turnId) : void 0;
|
|
14857
|
+
if (!subagentId) {
|
|
14858
|
+
return state.root;
|
|
14859
|
+
}
|
|
14860
|
+
return await (await startSubagentSpan(state, subagentId)).export();
|
|
14861
|
+
}
|
|
14862
|
+
async function startToolSpan(state, tool, input) {
|
|
14863
|
+
const ids = await childSpanIds2(state.rootKey, "tool", tool.itemId);
|
|
14864
|
+
return withCurrent(
|
|
14865
|
+
NOOP_SPAN,
|
|
14866
|
+
async () => _internalStartSpanWithInitialMerge(
|
|
14867
|
+
withSpanInstrumentationName(
|
|
14868
|
+
{
|
|
14869
|
+
name: tool.name,
|
|
14870
|
+
type: "tool" /* TOOL */,
|
|
14871
|
+
parent: await parentForTurn(state, tool.turnId),
|
|
14872
|
+
spanId: ids.spanId,
|
|
14873
|
+
startTime: tool.startTime,
|
|
14874
|
+
event: {
|
|
14875
|
+
id: ids.rowId,
|
|
14876
|
+
...input !== void 0 ? { input } : {},
|
|
14877
|
+
metadata: {
|
|
14878
|
+
item_id: tool.itemId,
|
|
14879
|
+
provider: "openai",
|
|
14880
|
+
tool_type: tool.toolType,
|
|
14881
|
+
...tool.turnId ? { turn_id: tool.turnId } : {}
|
|
14882
|
+
}
|
|
14883
|
+
}
|
|
14884
|
+
},
|
|
14885
|
+
INSTRUMENTATION_NAMES.OPENAI
|
|
14886
|
+
)
|
|
14887
|
+
)
|
|
14888
|
+
);
|
|
14889
|
+
}
|
|
14890
|
+
function toolFromItem(item, observedAt) {
|
|
14891
|
+
const itemId = stringValue(read2(item, "id"));
|
|
14892
|
+
const toolType = stringValue(read2(item, "type"));
|
|
14893
|
+
if (!itemId || !toolType) {
|
|
14894
|
+
return void 0;
|
|
14895
|
+
}
|
|
14896
|
+
const turnId = stringValue(read2(item, "turn_id"));
|
|
14897
|
+
switch (toolType) {
|
|
14898
|
+
case "function_call":
|
|
14899
|
+
return {
|
|
14900
|
+
input: read2(item, "arguments"),
|
|
14901
|
+
tool: {
|
|
14902
|
+
itemId,
|
|
14903
|
+
name: stringValue(read2(item, "name")) ?? "Function call",
|
|
14904
|
+
startTime: observedAt,
|
|
14905
|
+
toolType,
|
|
14906
|
+
...turnId ? { turnId } : {}
|
|
14907
|
+
}
|
|
14908
|
+
};
|
|
14909
|
+
case "mcp_call": {
|
|
14910
|
+
const name = stringValue(read2(item, "name")) ?? "MCP call";
|
|
14911
|
+
const server = stringValue(read2(item, "server_label"));
|
|
14912
|
+
return {
|
|
14913
|
+
input: read2(item, "arguments"),
|
|
14914
|
+
tool: {
|
|
14915
|
+
itemId,
|
|
14916
|
+
name: server ? `${server}.${name}` : name,
|
|
14917
|
+
startTime: observedAt,
|
|
14918
|
+
toolType,
|
|
14919
|
+
...turnId ? { turnId } : {}
|
|
14920
|
+
}
|
|
14921
|
+
};
|
|
14922
|
+
}
|
|
14923
|
+
case "web_search_call":
|
|
14924
|
+
return {
|
|
14925
|
+
input: read2(item, "action"),
|
|
14926
|
+
tool: {
|
|
14927
|
+
itemId,
|
|
14928
|
+
name: "Web search",
|
|
14929
|
+
startTime: observedAt,
|
|
14930
|
+
toolType,
|
|
14931
|
+
...turnId ? { turnId } : {}
|
|
14932
|
+
}
|
|
14933
|
+
};
|
|
14934
|
+
case "command_execution":
|
|
14935
|
+
return {
|
|
14936
|
+
input: {
|
|
14937
|
+
command: read2(item, "command"),
|
|
14938
|
+
cwd: read2(item, "cwd")
|
|
14939
|
+
},
|
|
14940
|
+
tool: {
|
|
14941
|
+
itemId,
|
|
14942
|
+
name: "Command execution",
|
|
14943
|
+
startTime: observedAt,
|
|
14944
|
+
toolType,
|
|
14945
|
+
...turnId ? { turnId } : {}
|
|
14946
|
+
}
|
|
14947
|
+
};
|
|
14948
|
+
default:
|
|
14949
|
+
return void 0;
|
|
14950
|
+
}
|
|
14951
|
+
}
|
|
14952
|
+
function textFromContent(content) {
|
|
14953
|
+
if (!Array.isArray(content)) {
|
|
14954
|
+
return void 0;
|
|
14955
|
+
}
|
|
14956
|
+
const text = [];
|
|
14957
|
+
for (const part of content) {
|
|
14958
|
+
const partText = read2(part, "text");
|
|
14959
|
+
if (read2(part, "type") === "output_text" && typeof partText === "string") {
|
|
14960
|
+
text.push(partText);
|
|
14961
|
+
}
|
|
14962
|
+
}
|
|
14963
|
+
return text.length > 0 ? text.join("") : void 0;
|
|
14964
|
+
}
|
|
14965
|
+
function toolOutput(item, toolType) {
|
|
14966
|
+
switch (toolType) {
|
|
14967
|
+
case "function_call":
|
|
14968
|
+
return read2(item, "output");
|
|
14969
|
+
case "mcp_call":
|
|
14970
|
+
return read2(item, "output");
|
|
14971
|
+
case "web_search_call":
|
|
14972
|
+
return read2(item, "action");
|
|
14973
|
+
case "command_execution":
|
|
14974
|
+
return read2(item, "output");
|
|
14975
|
+
default:
|
|
14976
|
+
return void 0;
|
|
14977
|
+
}
|
|
14978
|
+
}
|
|
14979
|
+
function toolFailed(item, toolType) {
|
|
14980
|
+
const status = read2(item, "status");
|
|
14981
|
+
const explicitError = read2(item, "error");
|
|
14982
|
+
if (explicitError !== void 0 && explicitError !== null) {
|
|
14983
|
+
return loggedError(explicitError, `OpenAI ${toolType} failed`);
|
|
14984
|
+
}
|
|
14985
|
+
if (status === "failed" || status === "incomplete") {
|
|
14986
|
+
return new Error(`OpenAI ${toolType} ${status}`);
|
|
14987
|
+
}
|
|
14988
|
+
if (toolType === "command_execution" && typeof read2(item, "exit_code") === "number" && read2(item, "exit_code") !== 0) {
|
|
14989
|
+
return new Error(
|
|
14990
|
+
`OpenAI command exited with code ${read2(item, "exit_code")}`
|
|
14991
|
+
);
|
|
14992
|
+
}
|
|
14993
|
+
return void 0;
|
|
14994
|
+
}
|
|
14995
|
+
async function completeTool(state, tool, item, endTime) {
|
|
14996
|
+
const span = await startToolSpan(state, tool);
|
|
14997
|
+
const output = toolOutput(item, tool.toolType);
|
|
14998
|
+
const error = toolFailed(item, tool.toolType);
|
|
14999
|
+
span.log({
|
|
15000
|
+
...output !== void 0 ? { output } : {},
|
|
15001
|
+
...error ? { error } : {},
|
|
15002
|
+
metadata: {
|
|
15003
|
+
status: read2(item, "status"),
|
|
15004
|
+
...tool.toolType === "command_execution" ? { exit_code: read2(item, "exit_code") } : {}
|
|
15005
|
+
}
|
|
15006
|
+
});
|
|
15007
|
+
span.end({ endTime });
|
|
15008
|
+
Reflect.deleteProperty(state.openTools, tool.itemId);
|
|
15009
|
+
}
|
|
15010
|
+
async function captureMessage(state, item) {
|
|
15011
|
+
if (read2(item, "type") !== "message" || read2(item, "role") !== "assistant" || read2(item, "phase") !== "final_answer") {
|
|
15012
|
+
return;
|
|
15013
|
+
}
|
|
15014
|
+
const output = textFromContent(read2(item, "content"));
|
|
15015
|
+
if (output === void 0) {
|
|
15016
|
+
return;
|
|
15017
|
+
}
|
|
15018
|
+
const turnId = stringValue(read2(item, "turn_id"));
|
|
15019
|
+
const subagentId = turnId ? recordValue(state.turnSubagents, turnId) : void 0;
|
|
15020
|
+
if (subagentId) {
|
|
15021
|
+
(await startSubagentSpan(state, subagentId)).log({ output });
|
|
15022
|
+
} else {
|
|
15023
|
+
startRootSpan(state).log({ output });
|
|
15024
|
+
}
|
|
15025
|
+
}
|
|
15026
|
+
async function captureItem(state, item, isDone, observedAt) {
|
|
15027
|
+
await captureMessage(state, item);
|
|
15028
|
+
const itemType = stringValue(read2(item, "type"));
|
|
15029
|
+
if (itemType === "function_call_output") {
|
|
15030
|
+
const callId = stringValue(read2(item, "call_id"));
|
|
15031
|
+
const itemId = callId ? recordValue(state.callItems, callId) : void 0;
|
|
15032
|
+
const tool2 = itemId ? recordValue(state.openTools, itemId) : void 0;
|
|
15033
|
+
if (tool2) {
|
|
15034
|
+
await completeTool(state, tool2, item, observedAt);
|
|
15035
|
+
}
|
|
15036
|
+
return;
|
|
15037
|
+
}
|
|
15038
|
+
const descriptor = toolFromItem(item, observedAt);
|
|
15039
|
+
if (!descriptor) {
|
|
15040
|
+
return;
|
|
15041
|
+
}
|
|
15042
|
+
const existing = recordValue(state.openTools, descriptor.tool.itemId);
|
|
15043
|
+
const tool = existing ?? descriptor.tool;
|
|
15044
|
+
setRecordValue(state.openTools, tool.itemId, tool);
|
|
15045
|
+
if (itemType === "function_call") {
|
|
15046
|
+
const callId = stringValue(read2(item, "call_id"));
|
|
15047
|
+
if (callId) {
|
|
15048
|
+
setRecordValue(state.callItems, callId, tool.itemId);
|
|
15049
|
+
}
|
|
15050
|
+
}
|
|
15051
|
+
await startToolSpan(state, tool, descriptor.input);
|
|
15052
|
+
const status = read2(item, "status");
|
|
15053
|
+
const terminalFunctionCall = itemType === "function_call" && (status === "failed" || status === "incomplete");
|
|
15054
|
+
if (itemType !== "function_call" && (isDone || status !== "in_progress") || terminalFunctionCall) {
|
|
15055
|
+
await completeTool(state, tool, item, observedAt);
|
|
15056
|
+
}
|
|
15057
|
+
}
|
|
15058
|
+
function updateSessionMetadata(state, session) {
|
|
15059
|
+
const sessionId = stringValue(read2(session, "id"));
|
|
15060
|
+
const agent = read2(session, "agent");
|
|
15061
|
+
startRootSpan(state).log({
|
|
15062
|
+
metadata: {
|
|
15063
|
+
...sessionId ? { session_id: sessionId } : {},
|
|
15064
|
+
...stringValue(read2(agent, "id")) ? { agent_id: read2(agent, "id") } : {},
|
|
15065
|
+
...stringValue(read2(agent, "name")) ? { agent_name: read2(agent, "name") } : {},
|
|
15066
|
+
...stringValue(read2(agent, "model")) ? { model: read2(agent, "model") } : {}
|
|
15067
|
+
}
|
|
15068
|
+
});
|
|
15069
|
+
}
|
|
15070
|
+
async function captureSubagent(state, eventType, subagent, observedAt) {
|
|
15071
|
+
const subagentId = stringValue(read2(subagent, "id"));
|
|
15072
|
+
if (!subagentId) {
|
|
15073
|
+
return;
|
|
15074
|
+
}
|
|
15075
|
+
const existing = recordValue(state.subagents, subagentId);
|
|
15076
|
+
const observedOpenedAt = read2(subagent, "opened_at");
|
|
15077
|
+
const openedAt = typeof observedOpenedAt === "number" && Number.isFinite(observedOpenedAt) && observedOpenedAt >= 0 ? observedOpenedAt : existing?.openedAt ?? observedAt;
|
|
15078
|
+
const observedClosedAt = read2(subagent, "closed_at");
|
|
15079
|
+
const closedAt = typeof observedClosedAt === "number" && Number.isFinite(observedClosedAt) && observedClosedAt >= 0 ? observedClosedAt : existing?.closedAt;
|
|
15080
|
+
const parentAgentId = stringValue(read2(subagent, "parent_agent_id")) ?? existing?.parentAgentId;
|
|
15081
|
+
setRecordValue(state.subagents, subagentId, {
|
|
15082
|
+
...closedAt !== void 0 ? { closedAt } : {},
|
|
15083
|
+
openedAt,
|
|
15084
|
+
...parentAgentId ? { parentAgentId } : {}
|
|
15085
|
+
});
|
|
15086
|
+
const span = await startSubagentSpan(
|
|
15087
|
+
state,
|
|
15088
|
+
subagentId,
|
|
15089
|
+
read2(subagent, "instructions"),
|
|
15090
|
+
{
|
|
15091
|
+
...stringValue(read2(subagent, "name")) ? { agent_name: read2(subagent, "name") } : {},
|
|
15092
|
+
status: read2(subagent, "status")
|
|
15093
|
+
}
|
|
15094
|
+
);
|
|
15095
|
+
if (eventType === "agent.session.subagent.closed") {
|
|
15096
|
+
span.end({ endTime: closedAt ?? observedAt });
|
|
15097
|
+
}
|
|
15098
|
+
}
|
|
15099
|
+
async function closeTrace(state, endTime, error, usage) {
|
|
15100
|
+
if (state.ended) {
|
|
15101
|
+
return;
|
|
15102
|
+
}
|
|
15103
|
+
for (const tool of Object.values(state.openTools)) {
|
|
15104
|
+
const span = await startToolSpan(state, tool);
|
|
15105
|
+
span.log({
|
|
15106
|
+
error: error ?? new Error("OpenAI Agents turn ended before tool completion")
|
|
15107
|
+
});
|
|
15108
|
+
span.end({ endTime });
|
|
15109
|
+
}
|
|
15110
|
+
state.openTools = {};
|
|
15111
|
+
for (const subagentId of Object.keys(state.subagents)) {
|
|
15112
|
+
const subagent = state.subagents[subagentId];
|
|
15113
|
+
const span = await startSubagentSpan(state, subagentId);
|
|
15114
|
+
span.end({ endTime: subagent.closedAt ?? endTime });
|
|
15115
|
+
}
|
|
15116
|
+
const root = startRootSpan(state);
|
|
15117
|
+
root.log({
|
|
15118
|
+
...error ? { error } : {},
|
|
15119
|
+
metrics: parseMetricsFromUsage(usage)
|
|
15120
|
+
});
|
|
15121
|
+
root.end({ endTime });
|
|
15122
|
+
state.ended = true;
|
|
15123
|
+
}
|
|
15124
|
+
async function captureTurnLifecycle(state, event, eventType, observedAt) {
|
|
15125
|
+
const turn = read2(event, "turn");
|
|
15126
|
+
const turnId = stringValue(read2(event, "turn_id")) ?? stringValue(read2(turn, "id"));
|
|
15127
|
+
const subagentId = stringValue(read2(turn, "subagent_id"));
|
|
15128
|
+
if (turnId && subagentId) {
|
|
15129
|
+
setRecordValue(state.turnSubagents, turnId, subagentId);
|
|
15130
|
+
if (!recordValue(state.subagents, subagentId)) {
|
|
15131
|
+
const createdAt = read2(turn, "created_at");
|
|
15132
|
+
setRecordValue(state.subagents, subagentId, {
|
|
15133
|
+
openedAt: typeof createdAt === "number" && Number.isFinite(createdAt) && createdAt >= 0 ? createdAt : observedAt
|
|
15134
|
+
});
|
|
15135
|
+
}
|
|
15136
|
+
await startSubagentSpan(state, subagentId);
|
|
15137
|
+
}
|
|
15138
|
+
const sessionId = stringValue(read2(event, "session_id"));
|
|
15139
|
+
if (sessionId) {
|
|
15140
|
+
startRootSpan(state).log({ metadata: { session_id: sessionId } });
|
|
15141
|
+
}
|
|
15142
|
+
if (!TERMINAL_TURN_EVENTS.has(eventType) || subagentId) {
|
|
15143
|
+
if (subagentId && eventType === "agent.session.turn.failed") {
|
|
15144
|
+
(await startSubagentSpan(state, subagentId)).log({
|
|
15145
|
+
error: loggedError(read2(turn, "error"), "OpenAI subagent turn failed")
|
|
15146
|
+
});
|
|
15147
|
+
}
|
|
15148
|
+
return;
|
|
15149
|
+
}
|
|
15150
|
+
const completedAt = read2(turn, "completed_at");
|
|
15151
|
+
const endTime = typeof completedAt === "number" && Number.isFinite(completedAt) && completedAt >= 0 ? completedAt : observedAt;
|
|
15152
|
+
const usage = read2(event, "usage") ?? read2(turn, "usage");
|
|
15153
|
+
const error = eventType === "agent.session.turn.completed" ? void 0 : loggedError(
|
|
15154
|
+
read2(turn, "error"),
|
|
15155
|
+
eventType === "agent.session.turn.cancelled" ? "OpenAI Agents turn cancelled" : "OpenAI Agents turn failed"
|
|
15156
|
+
);
|
|
15157
|
+
await closeTrace(state, endTime, error, usage);
|
|
15158
|
+
}
|
|
15159
|
+
async function captureEvent(state, event) {
|
|
15160
|
+
if (state.ended) {
|
|
15161
|
+
return state;
|
|
15162
|
+
}
|
|
15163
|
+
const eventType = stringValue(read2(event, "type"));
|
|
15164
|
+
const eventId = stringValue(read2(event, "event_id"));
|
|
15165
|
+
if (!eventType || eventId && state.eventIds.includes(eventId)) {
|
|
15166
|
+
return state;
|
|
15167
|
+
}
|
|
15168
|
+
const next = copyState(state);
|
|
15169
|
+
const observedAt = getCurrentUnixTimestamp();
|
|
15170
|
+
let handled = false;
|
|
15171
|
+
if (SESSION_EVENTS.has(eventType)) {
|
|
15172
|
+
const session = read2(event, "session");
|
|
15173
|
+
if (session) {
|
|
15174
|
+
updateSessionMetadata(next, session);
|
|
15175
|
+
}
|
|
15176
|
+
handled = true;
|
|
15177
|
+
}
|
|
15178
|
+
if (eventType === "agent.session.turn.item.added") {
|
|
15179
|
+
await captureItem(next, read2(event, "item"), false, observedAt);
|
|
15180
|
+
handled = true;
|
|
15181
|
+
} else if (eventType === "agent.session.turn.item.done") {
|
|
15182
|
+
await captureItem(next, read2(event, "item"), true, observedAt);
|
|
15183
|
+
handled = true;
|
|
15184
|
+
} else if (TURN_LIFECYCLE_EVENTS.has(eventType)) {
|
|
15185
|
+
await captureTurnLifecycle(next, event, eventType, observedAt);
|
|
15186
|
+
handled = true;
|
|
15187
|
+
} else if (SUBAGENT_EVENTS.has(eventType)) {
|
|
15188
|
+
await captureSubagent(next, eventType, read2(event, "subagent"), observedAt);
|
|
15189
|
+
handled = true;
|
|
15190
|
+
} else if (eventType === "agent.session.turn.output_text.delta" && next.firstTokenAt === void 0 && stringValue(read2(event, "delta"))) {
|
|
15191
|
+
next.firstTokenAt = observedAt;
|
|
15192
|
+
startRootSpan(next).log({
|
|
15193
|
+
metrics: { time_to_first_token: observedAt - next.startTime }
|
|
15194
|
+
});
|
|
15195
|
+
handled = true;
|
|
15196
|
+
} else if (eventType === "agent.session.failed") {
|
|
15197
|
+
const session = read2(event, "session");
|
|
15198
|
+
const lastActiveAt = read2(session, "last_active_at");
|
|
15199
|
+
const endTime = typeof lastActiveAt === "number" && Number.isFinite(lastActiveAt) && lastActiveAt >= 0 ? lastActiveAt : observedAt;
|
|
15200
|
+
await closeTrace(
|
|
15201
|
+
next,
|
|
15202
|
+
endTime,
|
|
15203
|
+
loggedError(read2(session, "error"), "OpenAI Agents session failed"),
|
|
15204
|
+
read2(session, "usage")
|
|
15205
|
+
);
|
|
15206
|
+
handled = true;
|
|
15207
|
+
} else if (eventType === "error") {
|
|
15208
|
+
await closeTrace(
|
|
15209
|
+
next,
|
|
15210
|
+
observedAt,
|
|
15211
|
+
loggedError(read2(event, "error"), "OpenAI Agents session failed")
|
|
15212
|
+
);
|
|
15213
|
+
handled = true;
|
|
15214
|
+
}
|
|
15215
|
+
if (!handled) {
|
|
15216
|
+
return state;
|
|
15217
|
+
}
|
|
15218
|
+
if (eventId) {
|
|
15219
|
+
next.eventIds.push(eventId);
|
|
15220
|
+
}
|
|
15221
|
+
return next;
|
|
15222
|
+
}
|
|
15223
|
+
var interceptOpenAIAgentsTraceStart = async (target, thisArg, args) => {
|
|
15224
|
+
const fallback2 = await Reflect.apply(target, thisArg, args);
|
|
15225
|
+
try {
|
|
15226
|
+
const state = args[0].state;
|
|
15227
|
+
const parent = state.rootParent;
|
|
15228
|
+
const traceArgs = args[0].args;
|
|
15229
|
+
const parentComponents = SpanComponentsV4.fromStr(parent);
|
|
15230
|
+
const hasParentSpan = Boolean(
|
|
15231
|
+
parentComponents.data.row_id && parentComponents.data.span_id && parentComponents.data.root_span_id
|
|
15232
|
+
);
|
|
15233
|
+
const rootComponents = SpanComponentsV4.fromStr(state.root);
|
|
15234
|
+
const rowId = stringValue(rootComponents.data.row_id);
|
|
15235
|
+
const rootSpanId = stringValue(rootComponents.data.root_span_id);
|
|
15236
|
+
const spanId = stringValue(rootComponents.data.span_id);
|
|
15237
|
+
if (!rowId || !rootSpanId || !spanId) {
|
|
15238
|
+
throw new Error("OpenAI Agents trace root is invalid");
|
|
15239
|
+
}
|
|
15240
|
+
withCurrent(
|
|
15241
|
+
NOOP_SPAN,
|
|
15242
|
+
() => _internalStartSpanWithInitialMergeAndParentSpanIds(
|
|
15243
|
+
withSpanInstrumentationName(
|
|
15244
|
+
{
|
|
15245
|
+
name: "openai.agents.turn",
|
|
15246
|
+
type: "task" /* TASK */,
|
|
15247
|
+
parent,
|
|
15248
|
+
...!hasParentSpan ? {
|
|
15249
|
+
parentSpanIds: {
|
|
15250
|
+
parentSpanIds: [],
|
|
15251
|
+
rootSpanId
|
|
15252
|
+
}
|
|
15253
|
+
} : {},
|
|
15254
|
+
spanId,
|
|
15255
|
+
startTime: state.startTime,
|
|
15256
|
+
event: {
|
|
15257
|
+
id: rowId,
|
|
15258
|
+
input: read2(traceArgs, "input"),
|
|
15259
|
+
metadata: traceMetadata(traceArgs)
|
|
15260
|
+
}
|
|
15261
|
+
},
|
|
15262
|
+
INSTRUMENTATION_NAMES.OPENAI
|
|
15263
|
+
)
|
|
15264
|
+
)
|
|
15265
|
+
);
|
|
15266
|
+
return state;
|
|
15267
|
+
} catch (error) {
|
|
15268
|
+
logInstrumentationError("could not start trace", error);
|
|
15269
|
+
return fallback2;
|
|
15270
|
+
}
|
|
15271
|
+
};
|
|
15272
|
+
var interceptOpenAIAgentsTraceCapture = async (target, thisArg, args) => {
|
|
15273
|
+
const fallback2 = await Reflect.apply(target, thisArg, args);
|
|
15274
|
+
if (!args[0].state) {
|
|
15275
|
+
return fallback2;
|
|
15276
|
+
}
|
|
15277
|
+
try {
|
|
15278
|
+
return await captureEvent(args[0].state, args[0].event);
|
|
15279
|
+
} catch (error) {
|
|
15280
|
+
logInstrumentationError("could not capture event", error);
|
|
15281
|
+
return fallback2;
|
|
15282
|
+
}
|
|
15283
|
+
};
|
|
15284
|
+
var interceptOpenAIAgentsTraceFail = async (target, thisArg, args) => {
|
|
15285
|
+
const fallback2 = await Reflect.apply(target, thisArg, args);
|
|
15286
|
+
if (!args[0].state) {
|
|
15287
|
+
return fallback2;
|
|
15288
|
+
}
|
|
15289
|
+
try {
|
|
15290
|
+
const next = copyState(args[0].state);
|
|
15291
|
+
await closeTrace(
|
|
15292
|
+
next,
|
|
15293
|
+
getCurrentUnixTimestamp(),
|
|
15294
|
+
loggedError(args[0].error, "OpenAI Agents request failed")
|
|
15295
|
+
);
|
|
15296
|
+
return next;
|
|
15297
|
+
} catch (error) {
|
|
15298
|
+
logInstrumentationError("could not fail trace", error);
|
|
15299
|
+
return fallback2;
|
|
15300
|
+
}
|
|
15301
|
+
};
|
|
15302
|
+
|
|
14624
15303
|
// src/instrumentation/plugins/openai-plugin.ts
|
|
14625
15304
|
var OpenAIPlugin = class extends BasePlugin {
|
|
14626
15305
|
constructor() {
|
|
@@ -14628,6 +15307,13 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
14628
15307
|
}
|
|
14629
15308
|
onEnable() {
|
|
14630
15309
|
this.unsubscribers.push(
|
|
15310
|
+
openAIChannels.agentsTraceStart.intercept(
|
|
15311
|
+
interceptOpenAIAgentsTraceStart
|
|
15312
|
+
),
|
|
15313
|
+
openAIChannels.agentsTraceCapture.intercept(
|
|
15314
|
+
interceptOpenAIAgentsTraceCapture
|
|
15315
|
+
),
|
|
15316
|
+
openAIChannels.agentsTraceFail.intercept(interceptOpenAIAgentsTraceFail),
|
|
14631
15317
|
openAIChannels.filesCreateTraced.intercept(
|
|
14632
15318
|
interceptOpenAIFilesCreateTraced
|
|
14633
15319
|
),
|
|
@@ -15188,7 +15874,7 @@ async function* patchCodexEventStream(events, state) {
|
|
|
15188
15874
|
try {
|
|
15189
15875
|
await handleCodexEvent(state, event);
|
|
15190
15876
|
} catch (error) {
|
|
15191
|
-
|
|
15877
|
+
logInstrumentationError2("OpenAI Codex stream event", error);
|
|
15192
15878
|
}
|
|
15193
15879
|
yield event;
|
|
15194
15880
|
}
|
|
@@ -15688,10 +16374,10 @@ function safeLog(span, event) {
|
|
|
15688
16374
|
try {
|
|
15689
16375
|
span.log(event);
|
|
15690
16376
|
} catch (error) {
|
|
15691
|
-
|
|
16377
|
+
logInstrumentationError2("OpenAI Codex span log", error);
|
|
15692
16378
|
}
|
|
15693
16379
|
}
|
|
15694
|
-
function
|
|
16380
|
+
function logInstrumentationError2(context, error) {
|
|
15695
16381
|
debugLogger.error(`Error processing ${context}:`, error);
|
|
15696
16382
|
}
|
|
15697
16383
|
|
|
@@ -17086,27 +17772,8 @@ function continuationParentFromCreateSessionParams(params) {
|
|
|
17086
17772
|
}
|
|
17087
17773
|
return context.parent;
|
|
17088
17774
|
}
|
|
17089
|
-
function exportSpanSynchronously(span) {
|
|
17090
|
-
const parentInfo = span.getParentInfo();
|
|
17091
|
-
if (!parentInfo) {
|
|
17092
|
-
return void 0;
|
|
17093
|
-
}
|
|
17094
|
-
const objectId = parentInfo.objectId.getSync().value;
|
|
17095
|
-
if (!objectId && !parentInfo.computeObjectMetadataArgs) {
|
|
17096
|
-
return void 0;
|
|
17097
|
-
}
|
|
17098
|
-
return new SpanComponentsV4({
|
|
17099
|
-
object_type: parentInfo.objectType,
|
|
17100
|
-
...objectId ? { object_id: objectId } : {
|
|
17101
|
-
compute_object_metadata_args: parentInfo.computeObjectMetadataArgs ?? {}
|
|
17102
|
-
},
|
|
17103
|
-
row_id: span.id,
|
|
17104
|
-
root_span_id: span.rootSpanId,
|
|
17105
|
-
span_id: span.spanId
|
|
17106
|
-
}).toStr();
|
|
17107
|
-
}
|
|
17108
17775
|
function exportedParent(parent) {
|
|
17109
|
-
return typeof parent === "string" ? parent :
|
|
17776
|
+
return typeof parent === "string" ? parent : _internalExportParentSynchronously(parent);
|
|
17110
17777
|
}
|
|
17111
17778
|
function addSerializedContext(args) {
|
|
17112
17779
|
if (!isObject(args.continuation) || args.sessionId === void 0) {
|
|
@@ -17863,16 +18530,16 @@ function braintrustAISDKTelemetry() {
|
|
|
17863
18530
|
if (!toolCallId || !state) {
|
|
17864
18531
|
return;
|
|
17865
18532
|
}
|
|
17866
|
-
const
|
|
18533
|
+
const toolOutput2 = event.toolOutput;
|
|
17867
18534
|
const workflowToolError = event.success === false && "error" in event ? event.error : void 0;
|
|
17868
|
-
if (
|
|
17869
|
-
const error =
|
|
18535
|
+
if (toolOutput2?.type === "tool-error" || workflowToolError !== void 0) {
|
|
18536
|
+
const error = toolOutput2?.error ?? workflowToolError;
|
|
17870
18537
|
state.span.log({
|
|
17871
18538
|
error: error instanceof Error ? error.message : String(error),
|
|
17872
18539
|
metrics: typeof event.durationMs === "number" ? { duration_ms: event.durationMs } : {}
|
|
17873
18540
|
});
|
|
17874
18541
|
} else {
|
|
17875
|
-
const output =
|
|
18542
|
+
const output = toolOutput2 && "output" in toolOutput2 ? toolOutput2.output : event.output;
|
|
17876
18543
|
state.span.log({
|
|
17877
18544
|
...shouldRecordOutputs(event) ? { output } : {},
|
|
17878
18545
|
metrics: typeof event.durationMs === "number" ? { duration_ms: event.durationMs } : {}
|
|
@@ -20331,9 +20998,9 @@ function patchAISDKStreamingResult(args) {
|
|
|
20331
20998
|
}
|
|
20332
20999
|
finalize({ metrics, output });
|
|
20333
21000
|
} catch (error) {
|
|
20334
|
-
const
|
|
21001
|
+
const loggedError2 = toLoggedError(error);
|
|
20335
21002
|
try {
|
|
20336
|
-
span.log({ error:
|
|
21003
|
+
span.log({ error: loggedError2 });
|
|
20337
21004
|
} catch (loggingError) {
|
|
20338
21005
|
debugLogger.error(
|
|
20339
21006
|
"Error logging AI SDK streaming failure:",
|
|
@@ -20341,7 +21008,7 @@ function patchAISDKStreamingResult(args) {
|
|
|
20341
21008
|
);
|
|
20342
21009
|
}
|
|
20343
21010
|
finalize({
|
|
20344
|
-
error: error instanceof Error ? error : new Error(String(
|
|
21011
|
+
error: error instanceof Error ? error : new Error(String(loggedError2))
|
|
20345
21012
|
});
|
|
20346
21013
|
}
|
|
20347
21014
|
};
|
|
@@ -20454,9 +21121,9 @@ function patchAISDKStreamingResult(args) {
|
|
|
20454
21121
|
}
|
|
20455
21122
|
controller.enqueue(value);
|
|
20456
21123
|
} catch (error) {
|
|
20457
|
-
const
|
|
21124
|
+
const loggedError2 = toLoggedError(error);
|
|
20458
21125
|
try {
|
|
20459
|
-
span.log({ error:
|
|
21126
|
+
span.log({ error: loggedError2 });
|
|
20460
21127
|
} catch (loggingError) {
|
|
20461
21128
|
debugLogger.error(
|
|
20462
21129
|
"Error logging AI SDK base stream failure:",
|
|
@@ -20464,7 +21131,7 @@ function patchAISDKStreamingResult(args) {
|
|
|
20464
21131
|
);
|
|
20465
21132
|
}
|
|
20466
21133
|
finalize({
|
|
20467
|
-
error: error instanceof Error ? error : new Error(String(
|
|
21134
|
+
error: error instanceof Error ? error : new Error(String(loggedError2))
|
|
20468
21135
|
});
|
|
20469
21136
|
controller.error(error);
|
|
20470
21137
|
}
|
|
@@ -23358,7 +24025,7 @@ function wrapSendOptionsCallbacks(options, state) {
|
|
|
23358
24025
|
try {
|
|
23359
24026
|
await handleInteractionUpdate(state, args.update);
|
|
23360
24027
|
} catch (error) {
|
|
23361
|
-
|
|
24028
|
+
logInstrumentationError3("Cursor SDK onDelta", error);
|
|
23362
24029
|
}
|
|
23363
24030
|
if (originalOnDelta) {
|
|
23364
24031
|
return originalOnDelta(args);
|
|
@@ -23368,7 +24035,7 @@ function wrapSendOptionsCallbacks(options, state) {
|
|
|
23368
24035
|
try {
|
|
23369
24036
|
handleStepUpdate(state, args.step);
|
|
23370
24037
|
} catch (error) {
|
|
23371
|
-
|
|
24038
|
+
logInstrumentationError3("Cursor SDK onStep", error);
|
|
23372
24039
|
}
|
|
23373
24040
|
if (originalOnStep) {
|
|
23374
24041
|
return originalOnStep(args);
|
|
@@ -23450,7 +24117,7 @@ async function* patchCursorStream(stream, state) {
|
|
|
23450
24117
|
try {
|
|
23451
24118
|
await handleStreamMessage2(state, message);
|
|
23452
24119
|
} catch (error) {
|
|
23453
|
-
|
|
24120
|
+
logInstrumentationError3("Cursor SDK stream", error);
|
|
23454
24121
|
}
|
|
23455
24122
|
yield message;
|
|
23456
24123
|
}
|
|
@@ -23514,7 +24181,7 @@ async function handleToolUpdate(state, update) {
|
|
|
23514
24181
|
if (!state.activeToolSpans.has(callId)) {
|
|
23515
24182
|
state.activeToolSpans.set(
|
|
23516
24183
|
callId,
|
|
23517
|
-
await
|
|
24184
|
+
await startToolSpan2(state, {
|
|
23518
24185
|
args,
|
|
23519
24186
|
callId,
|
|
23520
24187
|
name,
|
|
@@ -23525,7 +24192,7 @@ async function handleToolUpdate(state, update) {
|
|
|
23525
24192
|
}
|
|
23526
24193
|
return;
|
|
23527
24194
|
}
|
|
23528
|
-
const toolState = state.activeToolSpans.get(callId) ?? await
|
|
24195
|
+
const toolState = state.activeToolSpans.get(callId) ?? await startToolSpan2(state, {
|
|
23529
24196
|
args,
|
|
23530
24197
|
callId,
|
|
23531
24198
|
name,
|
|
@@ -23562,7 +24229,7 @@ async function handleStreamMessage2(state, message) {
|
|
|
23562
24229
|
} else if (block?.type === "tool_use" && block.id) {
|
|
23563
24230
|
state.activeToolSpans.set(
|
|
23564
24231
|
block.id,
|
|
23565
|
-
await
|
|
24232
|
+
await startToolSpan2(state, {
|
|
23566
24233
|
args: block.input,
|
|
23567
24234
|
callId: block.id,
|
|
23568
24235
|
name: block.name,
|
|
@@ -23597,7 +24264,7 @@ async function handleToolMessage(state, message) {
|
|
|
23597
24264
|
if (!state.activeToolSpans.has(callId)) {
|
|
23598
24265
|
state.activeToolSpans.set(
|
|
23599
24266
|
callId,
|
|
23600
|
-
await
|
|
24267
|
+
await startToolSpan2(state, {
|
|
23601
24268
|
args: message.args,
|
|
23602
24269
|
callId,
|
|
23603
24270
|
name: message.name,
|
|
@@ -23608,7 +24275,7 @@ async function handleToolMessage(state, message) {
|
|
|
23608
24275
|
}
|
|
23609
24276
|
return;
|
|
23610
24277
|
}
|
|
23611
|
-
const toolState = state.activeToolSpans.get(callId) ?? await
|
|
24278
|
+
const toolState = state.activeToolSpans.get(callId) ?? await startToolSpan2(state, {
|
|
23612
24279
|
args: message.args,
|
|
23613
24280
|
callId,
|
|
23614
24281
|
name: message.name,
|
|
@@ -23635,7 +24302,7 @@ async function handleConversation(state, turns) {
|
|
|
23635
24302
|
const command = turn.turn?.shellCommand?.command;
|
|
23636
24303
|
if (command) {
|
|
23637
24304
|
const callId = `shell:${state.activeToolSpans.size}:${command}`;
|
|
23638
|
-
const toolState = await
|
|
24305
|
+
const toolState = await startToolSpan2(state, {
|
|
23639
24306
|
args: turn.turn?.shellCommand,
|
|
23640
24307
|
callId,
|
|
23641
24308
|
name: "shell",
|
|
@@ -23659,7 +24326,7 @@ async function handleConversationStep(state, step) {
|
|
|
23659
24326
|
}
|
|
23660
24327
|
const toolCall = step.message;
|
|
23661
24328
|
const callId = typeof toolCall?.callId === "string" ? toolCall.callId : `conversation-tool:${state.activeToolSpans.size}`;
|
|
23662
|
-
const toolState = await
|
|
24329
|
+
const toolState = await startToolSpan2(state, {
|
|
23663
24330
|
args: extractToolArgs(toolCall),
|
|
23664
24331
|
callId,
|
|
23665
24332
|
name: extractToolName(toolCall),
|
|
@@ -23690,7 +24357,7 @@ function handleStepUpdate(state, step) {
|
|
|
23690
24357
|
state.stepText.push(step.message.text);
|
|
23691
24358
|
}
|
|
23692
24359
|
}
|
|
23693
|
-
async function
|
|
24360
|
+
async function startToolSpan2(state, args) {
|
|
23694
24361
|
const name = args.name || "unknown";
|
|
23695
24362
|
const metadata = {
|
|
23696
24363
|
"cursor_sdk.tool.status": args.status,
|
|
@@ -23977,10 +24644,10 @@ function safeLog2(span, event) {
|
|
|
23977
24644
|
try {
|
|
23978
24645
|
span.log(event);
|
|
23979
24646
|
} catch (error) {
|
|
23980
|
-
|
|
24647
|
+
logInstrumentationError3("Cursor SDK span log", error);
|
|
23981
24648
|
}
|
|
23982
24649
|
}
|
|
23983
|
-
function
|
|
24650
|
+
function logInstrumentationError3(context, error) {
|
|
23984
24651
|
debugLogger.error(`Error processing ${context}:`, error);
|
|
23985
24652
|
}
|
|
23986
24653
|
function cleanMetrics2(metrics) {
|
|
@@ -24818,6 +25485,10 @@ var googleGenAIChannels = defineChannels(
|
|
|
24818
25485
|
channelName: "models.embedContent",
|
|
24819
25486
|
kind: "async"
|
|
24820
25487
|
}),
|
|
25488
|
+
httpResponseJson: channel({
|
|
25489
|
+
channelName: "httpResponse.json",
|
|
25490
|
+
kind: "async"
|
|
25491
|
+
}),
|
|
24821
25492
|
interactionsCreate: channel({
|
|
24822
25493
|
channelName: "interactions.create",
|
|
24823
25494
|
kind: "async"
|
|
@@ -24966,13 +25637,45 @@ var GoogleGenAIPlugin = class extends BasePlugin {
|
|
|
24966
25637
|
subscribeToEmbedContentChannel() {
|
|
24967
25638
|
const tracingChannel = googleGenAIChannels.embedContent.tracingChannel();
|
|
24968
25639
|
const states = /* @__PURE__ */ new WeakMap();
|
|
25640
|
+
const embeddingSpans = /* @__PURE__ */ new WeakSet();
|
|
25641
|
+
this.unsubscribers.push(
|
|
25642
|
+
googleGenAIChannels.httpResponseJson.intercept(
|
|
25643
|
+
(target, thisArg, args) => {
|
|
25644
|
+
const span = currentSpan();
|
|
25645
|
+
const result = Reflect.apply(target, thisArg, args);
|
|
25646
|
+
if (embeddingSpans.has(span)) {
|
|
25647
|
+
void Promise.resolve(result).then(
|
|
25648
|
+
(response) => {
|
|
25649
|
+
try {
|
|
25650
|
+
const metrics = cleanMetrics3(
|
|
25651
|
+
extractEmbedContentMetrics(response)
|
|
25652
|
+
);
|
|
25653
|
+
if (embeddingSpans.has(span) && Object.keys(metrics).length > 0) {
|
|
25654
|
+
span.log({ metrics });
|
|
25655
|
+
}
|
|
25656
|
+
} catch (error) {
|
|
25657
|
+
debugLogger.error(
|
|
25658
|
+
"Error reading Google GenAI embedding usage:",
|
|
25659
|
+
error
|
|
25660
|
+
);
|
|
25661
|
+
}
|
|
25662
|
+
},
|
|
25663
|
+
() => {
|
|
25664
|
+
}
|
|
25665
|
+
// The embedding channel handles the original rejection.
|
|
25666
|
+
);
|
|
25667
|
+
}
|
|
25668
|
+
return result;
|
|
25669
|
+
}
|
|
25670
|
+
)
|
|
25671
|
+
);
|
|
24969
25672
|
const unbindCurrentSpanStore = bindCurrentSpanStoreToStart2(
|
|
24970
25673
|
tracingChannel,
|
|
24971
25674
|
states,
|
|
24972
25675
|
(event) => {
|
|
24973
25676
|
const params = event.arguments[0];
|
|
24974
25677
|
const input = serializeEmbedContentInput(params);
|
|
24975
|
-
const metadata =
|
|
25678
|
+
const metadata = { provider: "google", model: params.model };
|
|
24976
25679
|
const span = startSpan(
|
|
24977
25680
|
withSpanInstrumentationName(
|
|
24978
25681
|
{
|
|
@@ -24985,6 +25688,7 @@ var GoogleGenAIPlugin = class extends BasePlugin {
|
|
|
24985
25688
|
INSTRUMENTATION_NAMES.GOOGLE_GENAI
|
|
24986
25689
|
)
|
|
24987
25690
|
);
|
|
25691
|
+
embeddingSpans.add(span);
|
|
24988
25692
|
return {
|
|
24989
25693
|
span,
|
|
24990
25694
|
startTime: getCurrentUnixTimestamp()
|
|
@@ -24996,7 +25700,7 @@ var GoogleGenAIPlugin = class extends BasePlugin {
|
|
|
24996
25700
|
ensureSpanState(states, event, () => {
|
|
24997
25701
|
const params = event.arguments[0];
|
|
24998
25702
|
const input = serializeEmbedContentInput(params);
|
|
24999
|
-
const metadata =
|
|
25703
|
+
const metadata = { provider: "google", model: params.model };
|
|
25000
25704
|
const span = startSpan(
|
|
25001
25705
|
withSpanInstrumentationName(
|
|
25002
25706
|
{
|
|
@@ -25009,6 +25713,7 @@ var GoogleGenAIPlugin = class extends BasePlugin {
|
|
|
25009
25713
|
INSTRUMENTATION_NAMES.GOOGLE_GENAI
|
|
25010
25714
|
)
|
|
25011
25715
|
);
|
|
25716
|
+
embeddingSpans.add(span);
|
|
25012
25717
|
return {
|
|
25013
25718
|
span,
|
|
25014
25719
|
startTime: getCurrentUnixTimestamp()
|
|
@@ -25021,20 +25726,28 @@ var GoogleGenAIPlugin = class extends BasePlugin {
|
|
|
25021
25726
|
return;
|
|
25022
25727
|
}
|
|
25023
25728
|
try {
|
|
25024
|
-
const output = summarizeEmbedContentOutput(event.result);
|
|
25025
25729
|
spanState.span.log({
|
|
25026
|
-
|
|
25730
|
+
output: summarizeEmbedContentOutput(event.result),
|
|
25027
25731
|
metrics: cleanMetrics3(
|
|
25028
25732
|
extractEmbedContentMetrics(event.result, spanState.startTime)
|
|
25029
25733
|
)
|
|
25030
25734
|
});
|
|
25031
25735
|
} finally {
|
|
25736
|
+
embeddingSpans.delete(spanState.span);
|
|
25032
25737
|
spanState.span.end();
|
|
25033
25738
|
states.delete(event);
|
|
25034
25739
|
}
|
|
25035
25740
|
},
|
|
25036
25741
|
error: (event) => {
|
|
25037
|
-
|
|
25742
|
+
const spanState = states.get(event);
|
|
25743
|
+
if (!spanState) return;
|
|
25744
|
+
try {
|
|
25745
|
+
spanState.span.log({ error: event.error, output: { count: 0 } });
|
|
25746
|
+
} finally {
|
|
25747
|
+
embeddingSpans.delete(spanState.span);
|
|
25748
|
+
spanState.span.end();
|
|
25749
|
+
states.delete(event);
|
|
25750
|
+
}
|
|
25038
25751
|
}
|
|
25039
25752
|
};
|
|
25040
25753
|
tracingChannel.subscribe(handlers);
|
|
@@ -25269,15 +25982,53 @@ function serializeGenerateContentInput(params) {
|
|
|
25269
25982
|
return input;
|
|
25270
25983
|
}
|
|
25271
25984
|
function serializeEmbedContentInput(params) {
|
|
25985
|
+
let contents = Array.isArray(params.contents) ? params.contents : [params.contents];
|
|
25986
|
+
if (params.model.includes("gemini-embedding-2") && contents.length > 0 && contents.every(
|
|
25987
|
+
(content) => typeof content === "string" || !Array.isArray(content) && !("parts" in content)
|
|
25988
|
+
)) {
|
|
25989
|
+
contents = [contents];
|
|
25990
|
+
}
|
|
25272
25991
|
const input = {
|
|
25273
|
-
|
|
25274
|
-
|
|
25992
|
+
inputs: contents.map((content) => {
|
|
25993
|
+
const parts = typeof content === "string" ? [content] : Array.isArray(content) ? content : "parts" in content ? content.parts : [content];
|
|
25994
|
+
const normalized = parts.flatMap((part) => {
|
|
25995
|
+
if (typeof part === "string") return [{ type: "text", text: part }];
|
|
25996
|
+
if (part.text !== void 0) return [{ type: "text", text: part.text }];
|
|
25997
|
+
const media = part.inlineData ?? part.fileData;
|
|
25998
|
+
if (!media) return [];
|
|
25999
|
+
const data = "data" in media ? `data:${media.mimeType};base64,${typeof media.data === "string" ? media.data : uint8ArrayToBase64(media.data)}` : media.fileUri;
|
|
26000
|
+
return media.mimeType?.startsWith("image/") ? [{ type: "image_url", image_url: { url: data } }] : [
|
|
26001
|
+
{
|
|
26002
|
+
type: "file",
|
|
26003
|
+
file: {
|
|
26004
|
+
file_data: data,
|
|
26005
|
+
..."displayName" in media && media.displayName ? { filename: media.displayName } : {}
|
|
26006
|
+
}
|
|
26007
|
+
}
|
|
26008
|
+
];
|
|
26009
|
+
});
|
|
26010
|
+
return {
|
|
26011
|
+
content: normalized.length === 1 && normalized[0].type === "text" ? normalized[0].text : normalized
|
|
26012
|
+
};
|
|
26013
|
+
}),
|
|
26014
|
+
...params.config?.outputDimensionality !== void 0 ? { output_dimensions: params.config.outputDimensionality } : {}
|
|
25275
26015
|
};
|
|
25276
|
-
|
|
25277
|
-
|
|
25278
|
-
|
|
26016
|
+
try {
|
|
26017
|
+
const processed = processInputAttachments(input);
|
|
26018
|
+
const hasInlineMedia = processed.inputs.some(
|
|
26019
|
+
({ content }) => Array.isArray(content) && content.some((part) => {
|
|
26020
|
+
const data = part.type === "image_url" ? part.image_url.url : part.type === "file" ? part.file.file_data : void 0;
|
|
26021
|
+
return typeof data === "string" && data.startsWith("data:");
|
|
26022
|
+
})
|
|
26023
|
+
);
|
|
26024
|
+
return hasInlineMedia ? input : processed;
|
|
26025
|
+
} catch (error) {
|
|
26026
|
+
debugLogger.error(
|
|
26027
|
+
"Error processing Google GenAI embedding attachments:",
|
|
26028
|
+
error
|
|
26029
|
+
);
|
|
26030
|
+
return input;
|
|
25279
26031
|
}
|
|
25280
|
-
return input;
|
|
25281
26032
|
}
|
|
25282
26033
|
function serializeInteractionInput(params) {
|
|
25283
26034
|
const input = {
|
|
@@ -25465,19 +26216,6 @@ function extractGenerateContentMetadata(params) {
|
|
|
25465
26216
|
}
|
|
25466
26217
|
return metadata;
|
|
25467
26218
|
}
|
|
25468
|
-
function extractEmbedContentMetadata(params) {
|
|
25469
|
-
const metadata = {};
|
|
25470
|
-
if (params.model) {
|
|
25471
|
-
metadata.model = params.model;
|
|
25472
|
-
}
|
|
25473
|
-
const config = params.config ? tryToDict(params.config) : null;
|
|
25474
|
-
if (config) {
|
|
25475
|
-
Object.keys(config).forEach((key) => {
|
|
25476
|
-
metadata[key] = config[key];
|
|
25477
|
-
});
|
|
25478
|
-
}
|
|
25479
|
-
return metadata;
|
|
25480
|
-
}
|
|
25481
26219
|
function extractGenerateContentMetrics(response, startTime) {
|
|
25482
26220
|
const metrics = {};
|
|
25483
26221
|
if (startTime !== void 0) {
|
|
@@ -25497,15 +26235,23 @@ function extractEmbedContentMetrics(response, startTime) {
|
|
|
25497
26235
|
const end = getCurrentUnixTimestamp();
|
|
25498
26236
|
metrics.start = startTime;
|
|
25499
26237
|
metrics.end = end;
|
|
25500
|
-
metrics.duration = end - startTime;
|
|
25501
|
-
}
|
|
25502
|
-
if (response?.usageMetadata) {
|
|
25503
|
-
populateUsageMetrics(metrics, response.usageMetadata);
|
|
25504
26238
|
}
|
|
25505
26239
|
const embeddingTokenCount = extractEmbedPromptTokenCount(response);
|
|
25506
26240
|
if (embeddingTokenCount !== void 0) {
|
|
25507
26241
|
metrics.prompt_tokens = embeddingTokenCount;
|
|
25508
|
-
|
|
26242
|
+
}
|
|
26243
|
+
const totalTokens = response?.usageMetadata?.totalTokenCount ?? embeddingTokenCount;
|
|
26244
|
+
if (totalTokens !== void 0) {
|
|
26245
|
+
metrics.tokens = totalTokens;
|
|
26246
|
+
}
|
|
26247
|
+
const audioTokens = (response?.usageMetadata?.promptTokenDetails ?? response?.usageMetadata?.promptTokensDetails)?.filter(
|
|
26248
|
+
(detail) => detail.modality === "AUDIO" && detail.tokenCount !== void 0
|
|
26249
|
+
);
|
|
26250
|
+
if (audioTokens?.length) {
|
|
26251
|
+
metrics.prompt_audio_tokens = audioTokens.reduce(
|
|
26252
|
+
(sum, detail) => sum + (detail.tokenCount ?? 0),
|
|
26253
|
+
0
|
|
26254
|
+
);
|
|
25509
26255
|
}
|
|
25510
26256
|
return metrics;
|
|
25511
26257
|
}
|
|
@@ -25544,41 +26290,25 @@ function extractEmbedPromptTokenCount(response) {
|
|
|
25544
26290
|
if (typeof usagePromptTokens === "number" && Number.isFinite(usagePromptTokens)) {
|
|
25545
26291
|
return usagePromptTokens;
|
|
25546
26292
|
}
|
|
25547
|
-
const usageTotalTokens = response.usageMetadata?.totalTokenCount;
|
|
25548
|
-
if (typeof usageTotalTokens === "number" && Number.isFinite(usageTotalTokens)) {
|
|
25549
|
-
return usageTotalTokens;
|
|
25550
|
-
}
|
|
25551
26293
|
const embeddings = Array.isArray(response.embeddings) ? response.embeddings : response.embedding ? [response.embedding] : [];
|
|
25552
26294
|
if (embeddings.length === 0) {
|
|
25553
26295
|
return void 0;
|
|
25554
26296
|
}
|
|
25555
26297
|
let total = 0;
|
|
25556
|
-
let sawAny = false;
|
|
25557
26298
|
for (const embedding of embeddings) {
|
|
25558
26299
|
const embeddingStats = tryToDict(tryToDict(embedding)?.statistics);
|
|
25559
26300
|
const tokenCount2 = embeddingStats?.tokenCount;
|
|
25560
26301
|
if (typeof tokenCount2 === "number" && Number.isFinite(tokenCount2)) {
|
|
25561
26302
|
total += tokenCount2;
|
|
25562
|
-
|
|
26303
|
+
} else {
|
|
26304
|
+
return void 0;
|
|
25563
26305
|
}
|
|
25564
26306
|
}
|
|
25565
|
-
return
|
|
26307
|
+
return total;
|
|
25566
26308
|
}
|
|
25567
26309
|
function summarizeEmbedContentOutput(response) {
|
|
25568
|
-
if (!response) {
|
|
25569
|
-
return void 0;
|
|
25570
|
-
}
|
|
25571
|
-
const embeddings = Array.isArray(response.embeddings) ? response.embeddings : response.embedding ? [response.embedding] : [];
|
|
25572
|
-
if (embeddings.length === 0) {
|
|
25573
|
-
return void 0;
|
|
25574
|
-
}
|
|
25575
|
-
const firstValues = embeddings[0]?.values;
|
|
25576
|
-
if (!Array.isArray(firstValues)) {
|
|
25577
|
-
return void 0;
|
|
25578
|
-
}
|
|
25579
26310
|
return {
|
|
25580
|
-
|
|
25581
|
-
embedding_length: firstValues.length
|
|
26311
|
+
count: Array.isArray(response?.embeddings) ? response.embeddings.length : response?.embedding ? 1 : 0
|
|
25582
26312
|
};
|
|
25583
26313
|
}
|
|
25584
26314
|
function populateUsageMetrics(metrics, usage) {
|
|
@@ -29205,6 +29935,379 @@ function aggregateMistralStreamChunks(chunks) {
|
|
|
29205
29935
|
};
|
|
29206
29936
|
}
|
|
29207
29937
|
|
|
29938
|
+
// src/instrumentation/plugins/langgraph-sdk-channels.ts
|
|
29939
|
+
var langGraphSDKChannels = defineChannels(
|
|
29940
|
+
"@langchain/langgraph-sdk",
|
|
29941
|
+
{
|
|
29942
|
+
wait: channel({
|
|
29943
|
+
channelName: "runs.wait",
|
|
29944
|
+
kind: "async"
|
|
29945
|
+
}),
|
|
29946
|
+
stream: channel({
|
|
29947
|
+
channelName: "runs.stream",
|
|
29948
|
+
kind: "sync-stream"
|
|
29949
|
+
})
|
|
29950
|
+
},
|
|
29951
|
+
{ instrumentationName: INSTRUMENTATION_NAMES.LANGGRAPH_SDK }
|
|
29952
|
+
);
|
|
29953
|
+
|
|
29954
|
+
// src/instrumentation/plugins/langgraph-sdk-plugin.ts
|
|
29955
|
+
var LangGraphSDKPlugin = class extends BasePlugin {
|
|
29956
|
+
onEnable() {
|
|
29957
|
+
this.unsubscribers.push(
|
|
29958
|
+
langGraphSDKChannels.wait.intercept(
|
|
29959
|
+
(target, self, args) => instrumentRun("wait", args, () => Reflect.apply(target, self, args))
|
|
29960
|
+
),
|
|
29961
|
+
langGraphSDKChannels.stream.intercept(
|
|
29962
|
+
(target, self, args) => instrumentRun("stream", args, () => Reflect.apply(target, self, args))
|
|
29963
|
+
)
|
|
29964
|
+
);
|
|
29965
|
+
}
|
|
29966
|
+
onDisable() {
|
|
29967
|
+
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
29968
|
+
}
|
|
29969
|
+
};
|
|
29970
|
+
function normalizeMessage(value) {
|
|
29971
|
+
if (!isObject(value)) return value;
|
|
29972
|
+
const role = value.role ?? (value.type === "human" ? "user" : value.type === "ai" || value.type === "AIMessageChunk" ? "assistant" : value.type === "system" || value.type === "tool" || value.type === "function" ? value.type : void 0);
|
|
29973
|
+
if (typeof role !== "string") return value;
|
|
29974
|
+
const message = {
|
|
29975
|
+
role,
|
|
29976
|
+
content: value.content ?? ""
|
|
29977
|
+
};
|
|
29978
|
+
for (const key of ["name", "tool_call_id", "refusal"]) {
|
|
29979
|
+
if (value[key] !== void 0) message[key] = value[key];
|
|
29980
|
+
}
|
|
29981
|
+
const additional = isObject(value.additional_kwargs) ? value.additional_kwargs : {};
|
|
29982
|
+
const toolCalls2 = Array.isArray(value.tool_calls) && value.tool_calls.length ? value.tool_calls : additional.tool_calls;
|
|
29983
|
+
if (Array.isArray(toolCalls2) && toolCalls2.length > 0) {
|
|
29984
|
+
message.tool_calls = toolCalls2.map((call) => {
|
|
29985
|
+
if (!isObject(call)) return call;
|
|
29986
|
+
if (isObject(call.function)) return call;
|
|
29987
|
+
return {
|
|
29988
|
+
id: call.id,
|
|
29989
|
+
type: "function",
|
|
29990
|
+
function: {
|
|
29991
|
+
name: call.name,
|
|
29992
|
+
arguments: typeof call.args === "string" ? call.args : JSON.stringify(call.args ?? {})
|
|
29993
|
+
}
|
|
29994
|
+
};
|
|
29995
|
+
});
|
|
29996
|
+
}
|
|
29997
|
+
if (Array.isArray(value.invalid_tool_calls) && value.invalid_tool_calls.length > 0)
|
|
29998
|
+
message.invalid_tool_calls = value.invalid_tool_calls;
|
|
29999
|
+
if (message.refusal === void 0 && additional.refusal !== void 0)
|
|
30000
|
+
message.refusal = additional.refusal;
|
|
30001
|
+
return message;
|
|
30002
|
+
}
|
|
30003
|
+
function normalizeRunError(value) {
|
|
30004
|
+
let name;
|
|
30005
|
+
let message;
|
|
30006
|
+
if (value instanceof Error) {
|
|
30007
|
+
name = value.name;
|
|
30008
|
+
message = value.message;
|
|
30009
|
+
} else if (isObject(value) && typeof value.error === "string" && typeof value.message === "string") {
|
|
30010
|
+
name = value.error;
|
|
30011
|
+
message = value.message;
|
|
30012
|
+
} else {
|
|
30013
|
+
return value;
|
|
30014
|
+
}
|
|
30015
|
+
for (let depth = 0; depth < 3; depth++) {
|
|
30016
|
+
try {
|
|
30017
|
+
const nested = JSON.parse(
|
|
30018
|
+
message.startsWith(`${name}: `) ? message.slice(name.length + 2) : message
|
|
30019
|
+
);
|
|
30020
|
+
if (!isObject(nested) || typeof nested.error !== "string" || typeof nested.message !== "string")
|
|
30021
|
+
break;
|
|
30022
|
+
name = nested.error;
|
|
30023
|
+
message = nested.message;
|
|
30024
|
+
} catch {
|
|
30025
|
+
break;
|
|
30026
|
+
}
|
|
30027
|
+
}
|
|
30028
|
+
if (value instanceof Error && name === value.name && message === value.message)
|
|
30029
|
+
return value;
|
|
30030
|
+
return Object.assign(new Error(message), { name });
|
|
30031
|
+
}
|
|
30032
|
+
function normalizeState(value) {
|
|
30033
|
+
if (!isObject(value)) return value;
|
|
30034
|
+
return Object.fromEntries(
|
|
30035
|
+
Object.entries(value).map(([key, field]) => {
|
|
30036
|
+
if (key === "messages" && Array.isArray(field))
|
|
30037
|
+
return [key, field.map(normalizeMessage)];
|
|
30038
|
+
if (key === "__error__") {
|
|
30039
|
+
const error = normalizeRunError(field);
|
|
30040
|
+
if (error instanceof Error)
|
|
30041
|
+
return [key, { error: error.name, message: error.message }];
|
|
30042
|
+
}
|
|
30043
|
+
return [key, field];
|
|
30044
|
+
})
|
|
30045
|
+
);
|
|
30046
|
+
}
|
|
30047
|
+
function normalizeRunOutput(value, input) {
|
|
30048
|
+
if (!isObject(value)) return value;
|
|
30049
|
+
if (Array.isArray(value.messages)) {
|
|
30050
|
+
if (value.__interrupt__ !== void 0 || value.__error__ !== void 0)
|
|
30051
|
+
return void 0;
|
|
30052
|
+
const inputMessages = isObject(input) && Array.isArray(input.messages) ? input.messages : [];
|
|
30053
|
+
let inputPrefixLength = 0;
|
|
30054
|
+
while (inputPrefixLength < inputMessages.length) {
|
|
30055
|
+
const previous = inputMessages[inputPrefixLength];
|
|
30056
|
+
const message = value.messages[inputPrefixLength];
|
|
30057
|
+
if (isObject(previous) && isObject(message) && previous.id !== void 0 && message.id !== void 0 && previous.id !== message.id || JSON.stringify(normalizeMessage(previous)) !== JSON.stringify(normalizeMessage(message)))
|
|
30058
|
+
break;
|
|
30059
|
+
inputPrefixLength++;
|
|
30060
|
+
}
|
|
30061
|
+
for (let index = value.messages.length - 1; index >= inputPrefixLength; index--) {
|
|
30062
|
+
const message = value.messages[index];
|
|
30063
|
+
const normalized = normalizeMessage(message);
|
|
30064
|
+
if (!isObject(normalized)) continue;
|
|
30065
|
+
if (normalized.role === "user") return void 0;
|
|
30066
|
+
if (normalized.role !== "assistant") continue;
|
|
30067
|
+
if (inputMessages.some((previous) => {
|
|
30068
|
+
if (!isObject(previous) || !isObject(message)) return false;
|
|
30069
|
+
return previous.id !== void 0 && previous.id === message.id && JSON.stringify(normalizeMessage(previous)) === JSON.stringify(normalized);
|
|
30070
|
+
}))
|
|
30071
|
+
continue;
|
|
30072
|
+
return normalized;
|
|
30073
|
+
}
|
|
30074
|
+
return void 0;
|
|
30075
|
+
}
|
|
30076
|
+
const result = Object.fromEntries(
|
|
30077
|
+
Object.entries(value).filter(
|
|
30078
|
+
([key]) => key !== "__interrupt__" && key !== "__error__"
|
|
30079
|
+
)
|
|
30080
|
+
);
|
|
30081
|
+
return !Object.keys(result).length && (value.__interrupt__ !== void 0 || value.__error__ !== void 0) ? void 0 : result;
|
|
30082
|
+
}
|
|
30083
|
+
function instrumentRun(operation, [threadId, assistantId, options], invoke2) {
|
|
30084
|
+
if (isAutoInstrumentationSuppressed()) return invoke2();
|
|
30085
|
+
const start = getCurrentUnixTimestamp();
|
|
30086
|
+
let span;
|
|
30087
|
+
try {
|
|
30088
|
+
const metadata = {
|
|
30089
|
+
"langgraph.thread_id": threadId,
|
|
30090
|
+
"langgraph.assistant_id": assistantId
|
|
30091
|
+
};
|
|
30092
|
+
for (const key of [
|
|
30093
|
+
"streamMode",
|
|
30094
|
+
"streamSubgraphs",
|
|
30095
|
+
"interruptBefore",
|
|
30096
|
+
"interruptAfter",
|
|
30097
|
+
"multitaskStrategy",
|
|
30098
|
+
"durability"
|
|
30099
|
+
]) {
|
|
30100
|
+
if (options?.[key] !== void 0) metadata[key] = options[key];
|
|
30101
|
+
}
|
|
30102
|
+
span = startSpan(
|
|
30103
|
+
withSpanInstrumentationName(
|
|
30104
|
+
{
|
|
30105
|
+
name: `langgraph.runs.${operation}`,
|
|
30106
|
+
spanAttributes: { type: "task" /* TASK */ },
|
|
30107
|
+
event: {
|
|
30108
|
+
input: options?.command === void 0 ? normalizeState(options?.input) : {
|
|
30109
|
+
input: normalizeState(options.input),
|
|
30110
|
+
command: options.command
|
|
30111
|
+
},
|
|
30112
|
+
metadata
|
|
30113
|
+
}
|
|
30114
|
+
},
|
|
30115
|
+
INSTRUMENTATION_NAMES.LANGGRAPH_SDK
|
|
30116
|
+
)
|
|
30117
|
+
);
|
|
30118
|
+
} catch (error) {
|
|
30119
|
+
debugLogger.error("Error starting LangGraph SDK span:", error);
|
|
30120
|
+
return invoke2();
|
|
30121
|
+
}
|
|
30122
|
+
let ended = false;
|
|
30123
|
+
let output;
|
|
30124
|
+
let streamError;
|
|
30125
|
+
let firstToken;
|
|
30126
|
+
const updates = [];
|
|
30127
|
+
const usageByMessage = /* @__PURE__ */ new Map();
|
|
30128
|
+
const captureUsage = (id, usage) => {
|
|
30129
|
+
if (!isObject(usage)) return;
|
|
30130
|
+
const metrics = {};
|
|
30131
|
+
for (const [source, destination] of [
|
|
30132
|
+
["input_tokens", "prompt_tokens"],
|
|
30133
|
+
["output_tokens", "completion_tokens"],
|
|
30134
|
+
["total_tokens", "tokens"]
|
|
30135
|
+
]) {
|
|
30136
|
+
const value = usage[source];
|
|
30137
|
+
if (typeof value === "number" && Number.isFinite(value) && value >= 0)
|
|
30138
|
+
metrics[destination] = value;
|
|
30139
|
+
}
|
|
30140
|
+
if (metrics.tokens === void 0 && metrics.prompt_tokens !== void 0 && metrics.completion_tokens !== void 0)
|
|
30141
|
+
metrics.tokens = metrics.prompt_tokens + metrics.completion_tokens;
|
|
30142
|
+
usageByMessage.set(id, { ...usageByMessage.get(id), ...metrics });
|
|
30143
|
+
};
|
|
30144
|
+
const messages = /* @__PURE__ */ new Map();
|
|
30145
|
+
const messageSnapshots = /* @__PURE__ */ new Map();
|
|
30146
|
+
const finish = (error) => {
|
|
30147
|
+
if (ended) return;
|
|
30148
|
+
ended = true;
|
|
30149
|
+
try {
|
|
30150
|
+
const metrics = {};
|
|
30151
|
+
for (const usage of usageByMessage.values()) {
|
|
30152
|
+
for (const [key, value] of Object.entries(usage))
|
|
30153
|
+
metrics[key] = (metrics[key] ?? 0) + value;
|
|
30154
|
+
}
|
|
30155
|
+
if (firstToken !== void 0)
|
|
30156
|
+
metrics.time_to_first_token = firstToken - start;
|
|
30157
|
+
const finalMessages = [
|
|
30158
|
+
...new Map([...messages, ...messageSnapshots]).values()
|
|
30159
|
+
];
|
|
30160
|
+
let loggedOutput = normalizeRunOutput(output, options?.input);
|
|
30161
|
+
if (loggedOutput === void 0 && finalMessages.length)
|
|
30162
|
+
loggedOutput = normalizeRunOutput(
|
|
30163
|
+
{ messages: finalMessages },
|
|
30164
|
+
void 0
|
|
30165
|
+
);
|
|
30166
|
+
if (output === void 0 && !finalMessages.length && updates.length) {
|
|
30167
|
+
const results = updates.map((update) => normalizeRunOutput(update, options?.input)).filter((update) => update !== void 0);
|
|
30168
|
+
if (results.length) loggedOutput = { updates: results };
|
|
30169
|
+
}
|
|
30170
|
+
const interrupted = [output, ...updates].find(
|
|
30171
|
+
(state) => isObject(state) && state.__interrupt__ !== void 0
|
|
30172
|
+
);
|
|
30173
|
+
span.log({
|
|
30174
|
+
...loggedOutput !== void 0 ? { output: loggedOutput } : {},
|
|
30175
|
+
...isObject(interrupted) ? { metadata: { "langgraph.interrupts": interrupted.__interrupt__ } } : {},
|
|
30176
|
+
...error !== void 0 || streamError !== void 0 ? { error: normalizeRunError(error ?? streamError) } : {},
|
|
30177
|
+
metrics
|
|
30178
|
+
});
|
|
30179
|
+
} catch (error2) {
|
|
30180
|
+
debugLogger.error("Error logging LangGraph SDK span:", error2);
|
|
30181
|
+
}
|
|
30182
|
+
try {
|
|
30183
|
+
span.end();
|
|
30184
|
+
} catch (error2) {
|
|
30185
|
+
debugLogger.error("Error ending LangGraph SDK span:", error2);
|
|
30186
|
+
}
|
|
30187
|
+
};
|
|
30188
|
+
const observeMessages = (value, streaming) => {
|
|
30189
|
+
if (!isObject(value) || !Array.isArray(value.messages)) return;
|
|
30190
|
+
const inputMessages = isObject(options?.input) && Array.isArray(options.input.messages) ? options.input.messages : [];
|
|
30191
|
+
for (const message of value.messages) {
|
|
30192
|
+
if (!isObject(message) || message.type !== "ai" && message.role !== "assistant")
|
|
30193
|
+
continue;
|
|
30194
|
+
if (message.id !== void 0 && inputMessages.some(
|
|
30195
|
+
(input) => isObject(input) && input.id === message.id
|
|
30196
|
+
))
|
|
30197
|
+
continue;
|
|
30198
|
+
captureUsage(
|
|
30199
|
+
typeof message.id === "string" ? message.id : "message",
|
|
30200
|
+
message.usage_metadata
|
|
30201
|
+
);
|
|
30202
|
+
if (streaming && (typeof message.content === "string" ? message.content.length > 0 : Array.isArray(message.content) && message.content.some(
|
|
30203
|
+
(part) => isObject(part) && typeof part.text === "string" && part.text.length > 0
|
|
30204
|
+
)))
|
|
30205
|
+
firstToken ??= getCurrentUnixTimestamp();
|
|
30206
|
+
}
|
|
30207
|
+
};
|
|
30208
|
+
const onChunk = ({ event, data }) => {
|
|
30209
|
+
if (ended) return;
|
|
30210
|
+
if (event === "metadata" && isObject(data)) {
|
|
30211
|
+
if (typeof data.run_id === "string")
|
|
30212
|
+
span.log({ metadata: { "langgraph.run_id": data.run_id } });
|
|
30213
|
+
} else if (event === "error") {
|
|
30214
|
+
streamError = normalizeRunError(data);
|
|
30215
|
+
} else if (event === "values") {
|
|
30216
|
+
output = data;
|
|
30217
|
+
observeMessages(data, true);
|
|
30218
|
+
} else if (event === "updates") {
|
|
30219
|
+
if (isObject(data)) {
|
|
30220
|
+
const stateUpdates = [];
|
|
30221
|
+
for (const [node, update] of Object.entries(data)) {
|
|
30222
|
+
observeMessages(update, true);
|
|
30223
|
+
if (isObject(update) && Array.isArray(update.messages)) {
|
|
30224
|
+
for (const message of update.messages) {
|
|
30225
|
+
if (isObject(message))
|
|
30226
|
+
messageSnapshots.set(
|
|
30227
|
+
typeof message.id === "string" ? message.id : `update-${messageSnapshots.size}`,
|
|
30228
|
+
message
|
|
30229
|
+
);
|
|
30230
|
+
}
|
|
30231
|
+
const state = Object.fromEntries(
|
|
30232
|
+
Object.entries(update).filter(([key]) => key !== "messages")
|
|
30233
|
+
);
|
|
30234
|
+
if (Object.keys(state).length) stateUpdates.push([node, state]);
|
|
30235
|
+
} else {
|
|
30236
|
+
stateUpdates.push([node, update]);
|
|
30237
|
+
}
|
|
30238
|
+
}
|
|
30239
|
+
if (stateUpdates.length) updates.push(Object.fromEntries(stateUpdates));
|
|
30240
|
+
} else {
|
|
30241
|
+
updates.push(data);
|
|
30242
|
+
}
|
|
30243
|
+
} else if ((event === "messages" || event === "messages/partial" || event === "messages/complete") && Array.isArray(data)) {
|
|
30244
|
+
const parts = event === "messages" ? [data[0]] : data;
|
|
30245
|
+
for (const part of parts) {
|
|
30246
|
+
if (!isObject(part)) continue;
|
|
30247
|
+
const id = typeof part.id === "string" ? part.id : "message";
|
|
30248
|
+
captureUsage(id, part.usage_metadata);
|
|
30249
|
+
const previous = messages.get(id);
|
|
30250
|
+
messages.set(
|
|
30251
|
+
id,
|
|
30252
|
+
event === "messages" && previous && typeof part.content === "string" && typeof previous.content === "string" ? { ...part, content: previous.content + part.content } : part
|
|
30253
|
+
);
|
|
30254
|
+
if (typeof part.content === "string" && part.content.length > 0)
|
|
30255
|
+
firstToken ??= getCurrentUnixTimestamp();
|
|
30256
|
+
}
|
|
30257
|
+
}
|
|
30258
|
+
};
|
|
30259
|
+
let result;
|
|
30260
|
+
try {
|
|
30261
|
+
result = withCurrent(
|
|
30262
|
+
span,
|
|
30263
|
+
() => runWithAutoInstrumentationSuppressed(invoke2)
|
|
30264
|
+
);
|
|
30265
|
+
} catch (error) {
|
|
30266
|
+
finish(error);
|
|
30267
|
+
throw error;
|
|
30268
|
+
}
|
|
30269
|
+
if (operation === "stream") {
|
|
30270
|
+
try {
|
|
30271
|
+
patchStreamIfNeeded(result, {
|
|
30272
|
+
shouldCollect: (chunk) => {
|
|
30273
|
+
try {
|
|
30274
|
+
onChunk(chunk);
|
|
30275
|
+
} catch (error) {
|
|
30276
|
+
debugLogger.error(
|
|
30277
|
+
"Error processing LangGraph stream event:",
|
|
30278
|
+
error
|
|
30279
|
+
);
|
|
30280
|
+
}
|
|
30281
|
+
return false;
|
|
30282
|
+
},
|
|
30283
|
+
aroundNext: (next) => withCurrent(span, () => runWithAutoInstrumentationSuppressed(next)),
|
|
30284
|
+
onComplete: () => finish(),
|
|
30285
|
+
onCancel: () => finish(),
|
|
30286
|
+
onError: (error) => finish(error)
|
|
30287
|
+
});
|
|
30288
|
+
} catch (error) {
|
|
30289
|
+
debugLogger.error("Error observing LangGraph stream:", error);
|
|
30290
|
+
finish();
|
|
30291
|
+
}
|
|
30292
|
+
} else {
|
|
30293
|
+
void Promise.resolve(result).then(
|
|
30294
|
+
(value) => {
|
|
30295
|
+
try {
|
|
30296
|
+
output = value;
|
|
30297
|
+
observeMessages(value, false);
|
|
30298
|
+
if (isObject(value) && isObject(value.__error__))
|
|
30299
|
+
streamError = normalizeRunError(value.__error__);
|
|
30300
|
+
finish();
|
|
30301
|
+
} catch (error) {
|
|
30302
|
+
finish(error);
|
|
30303
|
+
}
|
|
30304
|
+
},
|
|
30305
|
+
(error) => finish(error)
|
|
30306
|
+
);
|
|
30307
|
+
}
|
|
30308
|
+
return result;
|
|
30309
|
+
}
|
|
30310
|
+
|
|
29208
30311
|
// src/instrumentation/plugins/ollama-channels.ts
|
|
29209
30312
|
var ollamaChannels = defineChannels(
|
|
29210
30313
|
"ollama",
|
|
@@ -29414,7 +30517,7 @@ function normalizeTextAndImages(content, images) {
|
|
|
29414
30517
|
...unrecognizedImages.length > 0 ? { unrecognizedImages } : {}
|
|
29415
30518
|
};
|
|
29416
30519
|
}
|
|
29417
|
-
function
|
|
30520
|
+
function normalizeMessage2(message, toolCallId, syntheticToolCallIdOffset = 0) {
|
|
29418
30521
|
if (typeof message.role !== "string") {
|
|
29419
30522
|
return void 0;
|
|
29420
30523
|
}
|
|
@@ -29460,7 +30563,7 @@ function normalizeMessages(messages) {
|
|
|
29460
30563
|
toolCallId = pendingToolCallIds.get(toolName)?.shift();
|
|
29461
30564
|
}
|
|
29462
30565
|
}
|
|
29463
|
-
const normalized =
|
|
30566
|
+
const normalized = normalizeMessage2(
|
|
29464
30567
|
ollamaMessage,
|
|
29465
30568
|
toolCallId,
|
|
29466
30569
|
syntheticToolCallIdOffset
|
|
@@ -29579,7 +30682,7 @@ function extractOllamaChatOutput(result, syntheticToolCallIdOffset = 0) {
|
|
|
29579
30682
|
if (!isObject(result) || !isObject(result.message)) {
|
|
29580
30683
|
return void 0;
|
|
29581
30684
|
}
|
|
29582
|
-
const message =
|
|
30685
|
+
const message = normalizeMessage2(
|
|
29583
30686
|
result.message,
|
|
29584
30687
|
void 0,
|
|
29585
30688
|
syntheticToolCallIdOffset
|
|
@@ -32299,14 +33402,14 @@ function extractActionSpanMetadata(args) {
|
|
|
32299
33402
|
const options = extractRunInNewSpanOptions(args);
|
|
32300
33403
|
const labels = isObject(options?.labels) ? options.labels : void 0;
|
|
32301
33404
|
const metadata = isObject(options?.metadata) ? options.metadata : void 0;
|
|
32302
|
-
const actionType =
|
|
32303
|
-
const name =
|
|
33405
|
+
const actionType = stringValue2(labels?.["genkit:metadata:subtype"]);
|
|
33406
|
+
const name = stringValue2(metadata?.name);
|
|
32304
33407
|
if (!actionType || !name) {
|
|
32305
33408
|
return void 0;
|
|
32306
33409
|
}
|
|
32307
33410
|
return {
|
|
32308
33411
|
actionType,
|
|
32309
|
-
key:
|
|
33412
|
+
key: stringValue2(labels?.["genkit:key"]),
|
|
32310
33413
|
name
|
|
32311
33414
|
};
|
|
32312
33415
|
}
|
|
@@ -32416,7 +33519,7 @@ function pickNumberMetrics(values) {
|
|
|
32416
33519
|
})
|
|
32417
33520
|
);
|
|
32418
33521
|
}
|
|
32419
|
-
function
|
|
33522
|
+
function stringValue2(value) {
|
|
32420
33523
|
return typeof value === "string" ? value : void 0;
|
|
32421
33524
|
}
|
|
32422
33525
|
|
|
@@ -33101,7 +34204,7 @@ function subscribeToFlueContext(value, state) {
|
|
|
33101
34204
|
try {
|
|
33102
34205
|
unsubscribe?.();
|
|
33103
34206
|
} catch (error) {
|
|
33104
|
-
|
|
34207
|
+
logInstrumentationError4("Flue context unsubscribe", error);
|
|
33105
34208
|
}
|
|
33106
34209
|
};
|
|
33107
34210
|
try {
|
|
@@ -33117,7 +34220,7 @@ function subscribeToFlueContext(value, state) {
|
|
|
33117
34220
|
});
|
|
33118
34221
|
state.contexts.add(value);
|
|
33119
34222
|
} catch (error) {
|
|
33120
|
-
|
|
34223
|
+
logInstrumentationError4("Flue context subscription", error);
|
|
33121
34224
|
}
|
|
33122
34225
|
}
|
|
33123
34226
|
function isAutoContextTerminalEvent(event, ctx) {
|
|
@@ -33173,7 +34276,7 @@ var FlueObserveBridge = class {
|
|
|
33173
34276
|
try {
|
|
33174
34277
|
this.handleEvent(event, flueContextFromUnknown(ctx));
|
|
33175
34278
|
} catch (error) {
|
|
33176
|
-
|
|
34279
|
+
logInstrumentationError4("Flue observe", error);
|
|
33177
34280
|
}
|
|
33178
34281
|
}
|
|
33179
34282
|
reset() {
|
|
@@ -33190,7 +34293,7 @@ var FlueObserveBridge = class {
|
|
|
33190
34293
|
try {
|
|
33191
34294
|
span = this.spanForExecutionOperation(operation, executionContext);
|
|
33192
34295
|
} catch (error) {
|
|
33193
|
-
|
|
34296
|
+
logInstrumentationError4("Flue execution interceptor", error);
|
|
33194
34297
|
}
|
|
33195
34298
|
return span ? runWithCurrentSpanStore(span, next) : next();
|
|
33196
34299
|
}
|
|
@@ -33396,7 +34499,7 @@ var FlueObserveBridge = class {
|
|
|
33396
34499
|
this.runsById.delete(event.runId);
|
|
33397
34500
|
}
|
|
33398
34501
|
void flush().catch((error) => {
|
|
33399
|
-
|
|
34502
|
+
logInstrumentationError4("Flue flush", error);
|
|
33400
34503
|
});
|
|
33401
34504
|
}
|
|
33402
34505
|
handleOperationStart(event) {
|
|
@@ -34171,17 +35274,17 @@ function safeLog3(span, event) {
|
|
|
34171
35274
|
try {
|
|
34172
35275
|
span.log(event);
|
|
34173
35276
|
} catch (error) {
|
|
34174
|
-
|
|
35277
|
+
logInstrumentationError4("Flue span log", error);
|
|
34175
35278
|
}
|
|
34176
35279
|
}
|
|
34177
35280
|
function safeEnd(span, endTime) {
|
|
34178
35281
|
try {
|
|
34179
35282
|
span.end(endTime === void 0 ? void 0 : { endTime });
|
|
34180
35283
|
} catch (error) {
|
|
34181
|
-
|
|
35284
|
+
logInstrumentationError4("Flue span end", error);
|
|
34182
35285
|
}
|
|
34183
35286
|
}
|
|
34184
|
-
function
|
|
35287
|
+
function logInstrumentationError4(label, error) {
|
|
34185
35288
|
debugLogger.debug(`Error in ${label} instrumentation:`, error);
|
|
34186
35289
|
}
|
|
34187
35290
|
|
|
@@ -34749,10 +35852,10 @@ var LangSmithPlugin = class extends BasePlugin {
|
|
|
34749
35852
|
const creates = ownValue(batch, "runCreates");
|
|
34750
35853
|
if (Array.isArray(creates)) {
|
|
34751
35854
|
const parentFirst = [...creates].sort((left, right) => {
|
|
34752
|
-
const leftId =
|
|
34753
|
-
const rightId =
|
|
34754
|
-
const leftParent =
|
|
34755
|
-
const rightParent =
|
|
35855
|
+
const leftId = stringValue3(ownValue(left, "id"));
|
|
35856
|
+
const rightId = stringValue3(ownValue(right, "id"));
|
|
35857
|
+
const leftParent = stringValue3(ownValue(left, "parent_run_id"));
|
|
35858
|
+
const rightParent = stringValue3(ownValue(right, "parent_run_id"));
|
|
34756
35859
|
if (leftParent && leftParent === rightId) {
|
|
34757
35860
|
return 1;
|
|
34758
35861
|
}
|
|
@@ -34771,13 +35874,13 @@ var LangSmithPlugin = class extends BasePlugin {
|
|
|
34771
35874
|
if (Array.isArray(updates)) {
|
|
34772
35875
|
for (const run of updates) {
|
|
34773
35876
|
this.containLifecycleFailure("batchIngestRuns update", () => {
|
|
34774
|
-
this.processUpdate(
|
|
35877
|
+
this.processUpdate(stringValue3(ownValue(run, "id")) ?? "", run);
|
|
34775
35878
|
});
|
|
34776
35879
|
}
|
|
34777
35880
|
}
|
|
34778
35881
|
}
|
|
34779
35882
|
processCreate(run) {
|
|
34780
|
-
const id =
|
|
35883
|
+
const id = stringValue3(ownValue(run, "id"));
|
|
34781
35884
|
if (!id || this.completedRuns.get(id)) {
|
|
34782
35885
|
return;
|
|
34783
35886
|
}
|
|
@@ -34810,7 +35913,7 @@ var LangSmithPlugin = class extends BasePlugin {
|
|
|
34810
35913
|
this.endIfComplete(id, activeRun, run);
|
|
34811
35914
|
}
|
|
34812
35915
|
processUpdate(explicitId, run) {
|
|
34813
|
-
const id =
|
|
35916
|
+
const id = stringValue3(explicitId) ?? stringValue3(ownValue(run, "id"));
|
|
34814
35917
|
if (!id || this.completedRuns.get(id)) {
|
|
34815
35918
|
return;
|
|
34816
35919
|
}
|
|
@@ -34833,13 +35936,13 @@ var LangSmithPlugin = class extends BasePlugin {
|
|
|
34833
35936
|
this.endIfComplete(id, active, active.run);
|
|
34834
35937
|
}
|
|
34835
35938
|
startRunSpan(id, run) {
|
|
34836
|
-
const traceId =
|
|
34837
|
-
const parentId =
|
|
35939
|
+
const traceId = stringValue3(ownValue(run, "trace_id")) ?? id;
|
|
35940
|
+
const parentId = stringValue3(ownValue(run, "parent_run_id")) ?? stringValue3(ownValue(ownValue(run, "parent_run"), "id"));
|
|
34838
35941
|
const startTime = timestampSeconds(ownValue(run, "start_time"));
|
|
34839
35942
|
return startSpan(
|
|
34840
35943
|
withSpanInstrumentationName(
|
|
34841
35944
|
{
|
|
34842
|
-
name:
|
|
35945
|
+
name: stringValue3(ownValue(run, "name")) ?? "LangSmith run",
|
|
34843
35946
|
spanId: id,
|
|
34844
35947
|
parentSpanIds: {
|
|
34845
35948
|
parentSpanIds: parentId ? [parentId] : [],
|
|
@@ -34931,7 +36034,7 @@ function mergeRuns(previous, current) {
|
|
|
34931
36034
|
function isRecord2(value) {
|
|
34932
36035
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
34933
36036
|
}
|
|
34934
|
-
function
|
|
36037
|
+
function stringValue3(value) {
|
|
34935
36038
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
34936
36039
|
}
|
|
34937
36040
|
function timestampSeconds(value) {
|
|
@@ -34949,7 +36052,7 @@ function timestampSeconds(value) {
|
|
|
34949
36052
|
return void 0;
|
|
34950
36053
|
}
|
|
34951
36054
|
function dottedOrderDepth(run) {
|
|
34952
|
-
const dottedOrder =
|
|
36055
|
+
const dottedOrder = stringValue3(ownValue(run, "dotted_order"));
|
|
34953
36056
|
return dottedOrder ? dottedOrder.split(".").length : Number.MAX_SAFE_INTEGER;
|
|
34954
36057
|
}
|
|
34955
36058
|
function mapRunType(runType) {
|
|
@@ -35154,7 +36257,7 @@ var PiCodingAgentPlugin = class extends BasePlugin {
|
|
|
35154
36257
|
}
|
|
35155
36258
|
);
|
|
35156
36259
|
} catch (error) {
|
|
35157
|
-
|
|
36260
|
+
logInstrumentationError5("Pi Coding Agent prompt start", error);
|
|
35158
36261
|
}
|
|
35159
36262
|
if (!state) {
|
|
35160
36263
|
return runWithAutoInstrumentationSuppressed(invokeTarget);
|
|
@@ -35287,12 +36390,12 @@ function installPiAgentInstrumentation(agent) {
|
|
|
35287
36390
|
() => handlePiAgentEvent(state, event)
|
|
35288
36391
|
);
|
|
35289
36392
|
} catch (error) {
|
|
35290
|
-
|
|
36393
|
+
logInstrumentationError5("Pi Coding Agent event", error);
|
|
35291
36394
|
}
|
|
35292
36395
|
});
|
|
35293
36396
|
piAgentEventSubscriptions.add(agent);
|
|
35294
36397
|
} catch (error) {
|
|
35295
|
-
|
|
36398
|
+
logInstrumentationError5("Pi Coding Agent event subscription", error);
|
|
35296
36399
|
}
|
|
35297
36400
|
}
|
|
35298
36401
|
function makeInstrumentedStreamFunction(agent, originalStreamFunction, property) {
|
|
@@ -35342,7 +36445,7 @@ function wrapPiToolExecutors(tools) {
|
|
|
35342
36445
|
});
|
|
35343
36446
|
tool.execute = wrappedExecute;
|
|
35344
36447
|
} catch (error) {
|
|
35345
|
-
|
|
36448
|
+
logInstrumentationError5("Pi Coding Agent tool wrapping", error);
|
|
35346
36449
|
}
|
|
35347
36450
|
}
|
|
35348
36451
|
}
|
|
@@ -35421,7 +36524,7 @@ function patchAssistantMessageStream(stream, promptState, llmState) {
|
|
|
35421
36524
|
try {
|
|
35422
36525
|
await iterator.return();
|
|
35423
36526
|
} catch (cleanupError) {
|
|
35424
|
-
|
|
36527
|
+
logInstrumentationError5(
|
|
35425
36528
|
"Pi Coding Agent stream cleanup",
|
|
35426
36529
|
cleanupError
|
|
35427
36530
|
);
|
|
@@ -35586,7 +36689,7 @@ function finishPiPromptRun(state, error) {
|
|
|
35586
36689
|
try {
|
|
35587
36690
|
state.span.end();
|
|
35588
36691
|
} catch (endError) {
|
|
35589
|
-
|
|
36692
|
+
logInstrumentationError5("Pi Coding Agent prompt end", endError);
|
|
35590
36693
|
}
|
|
35591
36694
|
}
|
|
35592
36695
|
}
|
|
@@ -35918,10 +37021,10 @@ function safeLog4(span, event) {
|
|
|
35918
37021
|
try {
|
|
35919
37022
|
span.log(event);
|
|
35920
37023
|
} catch (error) {
|
|
35921
|
-
|
|
37024
|
+
logInstrumentationError5("Pi Coding Agent span log", error);
|
|
35922
37025
|
}
|
|
35923
37026
|
}
|
|
35924
|
-
function
|
|
37027
|
+
function logInstrumentationError5(context, error) {
|
|
35925
37028
|
debugLogger.debug(`${context}:`, error);
|
|
35926
37029
|
}
|
|
35927
37030
|
|
|
@@ -36159,7 +37262,7 @@ function handleAgentStreamEvent(state, event) {
|
|
|
36159
37262
|
finalizeModelSpan(state, event);
|
|
36160
37263
|
break;
|
|
36161
37264
|
case "beforeToolCallEvent":
|
|
36162
|
-
|
|
37265
|
+
startToolSpan3(state, event);
|
|
36163
37266
|
break;
|
|
36164
37267
|
case "afterToolCallEvent":
|
|
36165
37268
|
finalizeToolSpan(state, event);
|
|
@@ -36184,7 +37287,7 @@ function handleAgentStreamEvent(state, event) {
|
|
|
36184
37287
|
break;
|
|
36185
37288
|
}
|
|
36186
37289
|
} catch (error) {
|
|
36187
|
-
|
|
37290
|
+
logInstrumentationError6("Strands Agent SDK event", error);
|
|
36188
37291
|
}
|
|
36189
37292
|
}
|
|
36190
37293
|
function handleMultiAgentStreamEvent(state, event, activeChildParents) {
|
|
@@ -36220,7 +37323,7 @@ function handleMultiAgentStreamEvent(state, event, activeChildParents) {
|
|
|
36220
37323
|
break;
|
|
36221
37324
|
}
|
|
36222
37325
|
} catch (error) {
|
|
36223
|
-
|
|
37326
|
+
logInstrumentationError6("Strands Agent SDK multi-agent event", error);
|
|
36224
37327
|
}
|
|
36225
37328
|
}
|
|
36226
37329
|
function buildModelSpanInput(event, attachmentCache) {
|
|
@@ -36299,7 +37402,7 @@ function finalizeModelSpan(state, event) {
|
|
|
36299
37402
|
});
|
|
36300
37403
|
modelState.span.end();
|
|
36301
37404
|
}
|
|
36302
|
-
function
|
|
37405
|
+
function startToolSpan3(state, event) {
|
|
36303
37406
|
const toolUse = event.toolUse;
|
|
36304
37407
|
const key = toolKey2(toolUse);
|
|
36305
37408
|
if (state.activeTools.has(key)) {
|
|
@@ -36579,7 +37682,7 @@ function getModelConfig(model) {
|
|
|
36579
37682
|
try {
|
|
36580
37683
|
return model.getConfig();
|
|
36581
37684
|
} catch (error) {
|
|
36582
|
-
|
|
37685
|
+
logInstrumentationError6("Strands Agent SDK model config", error);
|
|
36583
37686
|
return void 0;
|
|
36584
37687
|
}
|
|
36585
37688
|
}
|
|
@@ -36662,7 +37765,7 @@ function processStrandsInputAttachments(input, cache = createStrandsAttachmentCa
|
|
|
36662
37765
|
try {
|
|
36663
37766
|
return processStrandsInputNode(input, cache);
|
|
36664
37767
|
} catch (error) {
|
|
36665
|
-
|
|
37768
|
+
logInstrumentationError6("Strands Agent SDK input attachments", error);
|
|
36666
37769
|
return input;
|
|
36667
37770
|
}
|
|
36668
37771
|
}
|
|
@@ -36882,10 +37985,10 @@ function safeLog5(span, event) {
|
|
|
36882
37985
|
try {
|
|
36883
37986
|
span.log(event);
|
|
36884
37987
|
} catch (error) {
|
|
36885
|
-
|
|
37988
|
+
logInstrumentationError6("Strands Agent SDK span log", error);
|
|
36886
37989
|
}
|
|
36887
37990
|
}
|
|
36888
|
-
function
|
|
37991
|
+
function logInstrumentationError6(context, error) {
|
|
36889
37992
|
debugLogger.debug(`${context}:`, error);
|
|
36890
37993
|
}
|
|
36891
37994
|
|
|
@@ -37288,10 +38391,10 @@ function observeAudioStream(value, observe, complete, cancel, span) {
|
|
|
37288
38391
|
const getReader = value.getReader;
|
|
37289
38392
|
value.getReader = function(...args) {
|
|
37290
38393
|
const reader = Reflect.apply(getReader, this, args);
|
|
37291
|
-
const
|
|
38394
|
+
const read4 = reader.read;
|
|
37292
38395
|
reader.read = function(...readArgs) {
|
|
37293
38396
|
return Promise.resolve(
|
|
37294
|
-
withCurrent(span, () => Reflect.apply(
|
|
38397
|
+
withCurrent(span, () => Reflect.apply(read4, this, readArgs))
|
|
37295
38398
|
).then(
|
|
37296
38399
|
(result) => {
|
|
37297
38400
|
if (result.value) safeObserve(result.value);
|
|
@@ -37808,14 +38911,14 @@ var CloudflareAIChatPlugin = class extends BasePlugin {
|
|
|
37808
38911
|
const result = event.arguments[0];
|
|
37809
38912
|
state = agent ? this.findResponseState(
|
|
37810
38913
|
agent,
|
|
37811
|
-
|
|
38914
|
+
stringValue4(ownValue2(result, "requestId"))
|
|
37812
38915
|
) : void 0;
|
|
37813
38916
|
if (!state) {
|
|
37814
38917
|
return;
|
|
37815
38918
|
}
|
|
37816
38919
|
state.responseObserved = true;
|
|
37817
38920
|
const output = serializeMessage(ownValue2(result, "message"));
|
|
37818
|
-
const status =
|
|
38921
|
+
const status = stringValue4(ownValue2(result, "status"));
|
|
37819
38922
|
const error = ownValue2(result, "error");
|
|
37820
38923
|
const input = ownValue2(result, "continuation") === true ? state.input : serializeMessages(readProperty(agent, "messages"))?.filter(
|
|
37821
38924
|
(message) => typeof output?.id !== "string" || message.id !== output.id
|
|
@@ -37862,7 +38965,7 @@ var CloudflareAIChatPlugin = class extends BasePlugin {
|
|
|
37862
38965
|
}
|
|
37863
38966
|
try {
|
|
37864
38967
|
const agent = asObject(event.self);
|
|
37865
|
-
const requestId =
|
|
38968
|
+
const requestId = stringValue4(event.arguments[0]);
|
|
37866
38969
|
const key = requestId ?? /* @__PURE__ */ Symbol("cloudflare-ai-chat-turn");
|
|
37867
38970
|
const activeForAgent = agent ? this.getActiveTurns(agent) : void 0;
|
|
37868
38971
|
const existing = activeForAgent?.get(key);
|
|
@@ -38031,7 +39134,7 @@ function ownValue2(value, key) {
|
|
|
38031
39134
|
const descriptor = Object.getOwnPropertyDescriptor(object, key);
|
|
38032
39135
|
return descriptor && "value" in descriptor ? descriptor.value : void 0;
|
|
38033
39136
|
}
|
|
38034
|
-
function
|
|
39137
|
+
function stringValue4(value) {
|
|
38035
39138
|
return typeof value === "string" ? value : void 0;
|
|
38036
39139
|
}
|
|
38037
39140
|
function serializeMessages(value) {
|
|
@@ -38149,7 +39252,7 @@ var CloudflareAgentsPlugin = class extends BasePlugin {
|
|
|
38149
39252
|
);
|
|
38150
39253
|
spans.set(event, span);
|
|
38151
39254
|
} catch (error) {
|
|
38152
|
-
|
|
39255
|
+
logInstrumentationError7("start", error);
|
|
38153
39256
|
}
|
|
38154
39257
|
},
|
|
38155
39258
|
asyncEnd: (event) => {
|
|
@@ -38169,7 +39272,7 @@ var CloudflareAgentsPlugin = class extends BasePlugin {
|
|
|
38169
39272
|
}
|
|
38170
39273
|
}
|
|
38171
39274
|
} catch (error) {
|
|
38172
|
-
|
|
39275
|
+
logInstrumentationError7("completion", error);
|
|
38173
39276
|
} finally {
|
|
38174
39277
|
safelyEndSpan(span);
|
|
38175
39278
|
}
|
|
@@ -38183,7 +39286,7 @@ var CloudflareAgentsPlugin = class extends BasePlugin {
|
|
|
38183
39286
|
try {
|
|
38184
39287
|
span.log({ error: event.error });
|
|
38185
39288
|
} catch (error) {
|
|
38186
|
-
|
|
39289
|
+
logInstrumentationError7("rejection", error);
|
|
38187
39290
|
} finally {
|
|
38188
39291
|
safelyEndSpan(span);
|
|
38189
39292
|
}
|
|
@@ -38213,10 +39316,10 @@ function safelyEndSpan(span) {
|
|
|
38213
39316
|
try {
|
|
38214
39317
|
span.end();
|
|
38215
39318
|
} catch (error) {
|
|
38216
|
-
|
|
39319
|
+
logInstrumentationError7("span end", error);
|
|
38217
39320
|
}
|
|
38218
39321
|
}
|
|
38219
|
-
function
|
|
39322
|
+
function logInstrumentationError7(operation, error) {
|
|
38220
39323
|
debugLogger.error(
|
|
38221
39324
|
`Failed to process Cloudflare Agents ${operation} instrumentation:`,
|
|
38222
39325
|
error
|
|
@@ -38241,6 +39344,7 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
38241
39344
|
openRouterPlugin = null;
|
|
38242
39345
|
openRouterAgentPlugin = null;
|
|
38243
39346
|
mistralPlugin = null;
|
|
39347
|
+
langGraphSDKPlugin = null;
|
|
38244
39348
|
ollamaPlugin = null;
|
|
38245
39349
|
googleADKPlugin = null;
|
|
38246
39350
|
coherePlugin = null;
|
|
@@ -38321,6 +39425,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
38321
39425
|
this.mistralPlugin = new MistralPlugin();
|
|
38322
39426
|
this.mistralPlugin.enable();
|
|
38323
39427
|
}
|
|
39428
|
+
if (integrations.langgraphSDK !== false) {
|
|
39429
|
+
this.langGraphSDKPlugin = new LangGraphSDKPlugin();
|
|
39430
|
+
this.langGraphSDKPlugin.enable();
|
|
39431
|
+
}
|
|
38324
39432
|
if (integrations.ollama !== false) {
|
|
38325
39433
|
this.ollamaPlugin = new OllamaPlugin();
|
|
38326
39434
|
this.ollamaPlugin.enable();
|
|
@@ -38449,6 +39557,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
38449
39557
|
this.mistralPlugin.disable();
|
|
38450
39558
|
this.mistralPlugin = null;
|
|
38451
39559
|
}
|
|
39560
|
+
if (this.langGraphSDKPlugin) {
|
|
39561
|
+
this.langGraphSDKPlugin.disable();
|
|
39562
|
+
this.langGraphSDKPlugin = null;
|
|
39563
|
+
}
|
|
38452
39564
|
if (this.ollamaPlugin) {
|
|
38453
39565
|
this.ollamaPlugin.disable();
|
|
38454
39566
|
this.ollamaPlugin = null;
|
|
@@ -38590,6 +39702,9 @@ var envIntegrationAliases = {
|
|
|
38590
39702
|
"langchain-js": "langchain",
|
|
38591
39703
|
"@langchain": "langchain",
|
|
38592
39704
|
langgraph: "langgraph",
|
|
39705
|
+
langgraphsdk: "langgraphSDK",
|
|
39706
|
+
"langgraph-sdk": "langgraphSDK",
|
|
39707
|
+
"@langchain/langgraph-sdk": "langgraphSDK",
|
|
38593
39708
|
langsmith: "langsmith",
|
|
38594
39709
|
voyage: "voyageai",
|
|
38595
39710
|
"voyage-ai": "voyageai",
|
|
@@ -38630,6 +39745,7 @@ function getDefaultInstrumentationIntegrations() {
|
|
|
38630
39745
|
gitHubCopilot: true,
|
|
38631
39746
|
langchain: true,
|
|
38632
39747
|
langgraph: true,
|
|
39748
|
+
langgraphSDK: true,
|
|
38633
39749
|
langsmith: true,
|
|
38634
39750
|
voyageai: true,
|
|
38635
39751
|
elevenlabs: true,
|
|
@@ -38798,8 +39914,6 @@ __export(exports_exports, {
|
|
|
38798
39914
|
BRAINTRUST_PARENT_KEY: () => BRAINTRUST_PARENT_KEY,
|
|
38799
39915
|
BaseAttachment: () => BaseAttachment,
|
|
38800
39916
|
BaseExperiment: () => BaseExperiment,
|
|
38801
|
-
BatchScorer: () => BatchScorer,
|
|
38802
|
-
BatchTask: () => BatchTask,
|
|
38803
39917
|
BraintrustLangChainCallbackHandler: () => BraintrustLangChainCallbackHandler,
|
|
38804
39918
|
BraintrustMiddleware: () => BraintrustMiddleware,
|
|
38805
39919
|
BraintrustObservabilityExporter: () => BraintrustObservabilityExporter,
|
|
@@ -38813,8 +39927,6 @@ __export(exports_exports, {
|
|
|
38813
39927
|
DEFAULT_MAX_REQUEST_SIZE: () => DEFAULT_MAX_REQUEST_SIZE,
|
|
38814
39928
|
Dataset: () => Dataset2,
|
|
38815
39929
|
DatasetPipeline: () => DatasetPipeline,
|
|
38816
|
-
DurableEvalMemoryStore: () => DurableEvalMemoryStore,
|
|
38817
|
-
DurableEvalRedisStore: () => DurableEvalRedisStore,
|
|
38818
39930
|
ERR_PERMALINK: () => ERR_PERMALINK,
|
|
38819
39931
|
Eval: () => Eval,
|
|
38820
39932
|
EvalResultWithSummary: () => EvalResultWithSummary,
|
|
@@ -38849,6 +39961,10 @@ __export(exports_exports, {
|
|
|
38849
39961
|
TestBackgroundLogger: () => TestBackgroundLogger,
|
|
38850
39962
|
ToolBuilder: () => ToolBuilder,
|
|
38851
39963
|
UUIDGenerator: () => UUIDGenerator,
|
|
39964
|
+
WorkflowEvalMemoryStore: () => WorkflowEvalMemoryStore,
|
|
39965
|
+
WorkflowEvalRedisStore: () => WorkflowEvalRedisStore,
|
|
39966
|
+
WorkflowScorer: () => WorkflowScorer,
|
|
39967
|
+
WorkflowTask: () => WorkflowTask,
|
|
38852
39968
|
X_CACHED_HEADER: () => X_CACHED_HEADER,
|
|
38853
39969
|
_exportsForTestingOnly: () => _exportsForTestingOnly,
|
|
38854
39970
|
_internalGetGlobalState: () => _internalGetGlobalState,
|
|
@@ -38873,12 +39989,13 @@ __export(exports_exports, {
|
|
|
38873
39989
|
currentSpan: () => currentSpan,
|
|
38874
39990
|
deepCopyEvent: () => deepCopyEvent,
|
|
38875
39991
|
defaultErrorScoreHandler: () => defaultErrorScoreHandler,
|
|
38876
|
-
|
|
39992
|
+
defineWorkflowEval: () => defineWorkflowEval,
|
|
38877
39993
|
deserializePlainStringAsJSON: () => deserializePlainStringAsJSON,
|
|
38878
39994
|
devNullWritableStream: () => devNullWritableStream,
|
|
38879
39995
|
evaluatorDefinitionSchema: () => evaluatorDefinitionSchema,
|
|
38880
39996
|
evaluatorDefinitionsSchema: () => evaluatorDefinitionsSchema,
|
|
38881
39997
|
extractTraceContextFromHeaders: () => extractTraceContextFromHeaders,
|
|
39998
|
+
failOpenAIAgentsTrace: () => failOpenAIAgentsTrace,
|
|
38882
39999
|
flush: () => flush,
|
|
38883
40000
|
getContextManager: () => getContextManager,
|
|
38884
40001
|
getIdGenerator: () => getIdGenerator,
|
|
@@ -38925,12 +40042,14 @@ __export(exports_exports, {
|
|
|
38925
40042
|
setFetch: () => setFetch,
|
|
38926
40043
|
setMaskingFunction: () => setMaskingFunction,
|
|
38927
40044
|
spanComponentsToObjectId: () => spanComponentsToObjectId,
|
|
40045
|
+
startOpenAIAgentsTrace: () => startOpenAIAgentsTrace,
|
|
38928
40046
|
startSpan: () => startSpan,
|
|
38929
40047
|
summarize: () => summarize,
|
|
38930
40048
|
templateRegistry: () => templateRegistry,
|
|
38931
40049
|
toolFunctionDefinitionSchema: () => ToolFunctionDefinition,
|
|
38932
40050
|
traceable: () => traceable,
|
|
38933
40051
|
traced: () => traced,
|
|
40052
|
+
updateOpenAIAgentsTrace: () => updateOpenAIAgentsTrace,
|
|
38934
40053
|
updateSpan: () => updateSpan,
|
|
38935
40054
|
uploadLogs3OverflowPayload: () => uploadLogs3OverflowPayload,
|
|
38936
40055
|
utf8ByteLength: () => utf8ByteLength2,
|
|
@@ -38959,6 +40078,7 @@ __export(exports_exports, {
|
|
|
38959
40078
|
wrapGroq: () => wrapGroq,
|
|
38960
40079
|
wrapHuggingFace: () => wrapHuggingFace,
|
|
38961
40080
|
wrapHuggingFaceTransformers: () => wrapHuggingFaceTransformers,
|
|
40081
|
+
wrapLangGraphSDK: () => wrapLangGraphSDK,
|
|
38962
40082
|
wrapLangSmithClient: () => wrapLangSmithClient,
|
|
38963
40083
|
wrapLangSmithRunTrees: () => wrapLangSmithRunTrees,
|
|
38964
40084
|
wrapLangSmithTraceable: () => wrapLangSmithTraceable,
|
|
@@ -39158,7 +40278,7 @@ function createLazyAPIPromise(ensureExecuted, ensureResponse, getAPIPromise) {
|
|
|
39158
40278
|
}
|
|
39159
40279
|
|
|
39160
40280
|
// src/openai-batch.ts
|
|
39161
|
-
function
|
|
40281
|
+
function read3(value, key) {
|
|
39162
40282
|
if (value === null || typeof value !== "object" && typeof value !== "function") {
|
|
39163
40283
|
return void 0;
|
|
39164
40284
|
}
|
|
@@ -39169,7 +40289,7 @@ function read2(value, key) {
|
|
|
39169
40289
|
}
|
|
39170
40290
|
}
|
|
39171
40291
|
function isAsyncIterable5(value) {
|
|
39172
|
-
return typeof
|
|
40292
|
+
return typeof read3(value, Symbol.asyncIterator) === "function";
|
|
39173
40293
|
}
|
|
39174
40294
|
function teeAsyncIterable(source) {
|
|
39175
40295
|
const iterator = source[Symbol.asyncIterator]();
|
|
@@ -39212,7 +40332,7 @@ function teeAsyncIterable(source) {
|
|
|
39212
40332
|
}
|
|
39213
40333
|
}
|
|
39214
40334
|
};
|
|
39215
|
-
const path =
|
|
40335
|
+
const path = read3(source, "path");
|
|
39216
40336
|
if (typeof path === "string") {
|
|
39217
40337
|
Object.defineProperty(upload, "path", { value: path });
|
|
39218
40338
|
}
|
|
@@ -39233,8 +40353,8 @@ function teeUpload(upload) {
|
|
|
39233
40353
|
function openaiFilesCreateTraced(files) {
|
|
39234
40354
|
return (params, options) => {
|
|
39235
40355
|
const parent = getSpanParentObject();
|
|
39236
|
-
const purpose =
|
|
39237
|
-
const file =
|
|
40356
|
+
const purpose = read3(params, "purpose");
|
|
40357
|
+
const file = read3(params, "file");
|
|
39238
40358
|
if (purpose !== "batch") {
|
|
39239
40359
|
return files.create(params, options);
|
|
39240
40360
|
}
|
|
@@ -39325,6 +40445,143 @@ async function completeOpenAIBatchTrace(args) {
|
|
|
39325
40445
|
);
|
|
39326
40446
|
}
|
|
39327
40447
|
|
|
40448
|
+
// src/openai-agents-api.ts
|
|
40449
|
+
function isRecord3(value) {
|
|
40450
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
40451
|
+
}
|
|
40452
|
+
function validateStartArgs(value) {
|
|
40453
|
+
if (!isRecord3(value)) {
|
|
40454
|
+
throw new TypeError(
|
|
40455
|
+
"startOpenAIAgentsTrace expected an OpenAI Agents parameters object"
|
|
40456
|
+
);
|
|
40457
|
+
}
|
|
40458
|
+
const agent = value.agent;
|
|
40459
|
+
if (agent !== void 0 && agent !== null && !isRecord3(agent)) {
|
|
40460
|
+
throw new TypeError(
|
|
40461
|
+
"startOpenAIAgentsTrace expected agent to be an object or null"
|
|
40462
|
+
);
|
|
40463
|
+
}
|
|
40464
|
+
if (isRecord3(agent) && (agent.id !== void 0 && typeof agent.id !== "string" || agent.model !== void 0 && typeof agent.model !== "string" || agent.name !== void 0 && agent.name !== null && typeof agent.name !== "string")) {
|
|
40465
|
+
throw new TypeError(
|
|
40466
|
+
"startOpenAIAgentsTrace received invalid agent identity fields"
|
|
40467
|
+
);
|
|
40468
|
+
}
|
|
40469
|
+
if (value.agent_id !== void 0 && typeof value.agent_id !== "string") {
|
|
40470
|
+
throw new TypeError(
|
|
40471
|
+
"startOpenAIAgentsTrace expected agent_id to be a string"
|
|
40472
|
+
);
|
|
40473
|
+
}
|
|
40474
|
+
if (value.metadata !== void 0 && value.metadata !== null && !isRecord3(value.metadata)) {
|
|
40475
|
+
throw new TypeError(
|
|
40476
|
+
"startOpenAIAgentsTrace expected metadata to be an object or null"
|
|
40477
|
+
);
|
|
40478
|
+
}
|
|
40479
|
+
return value;
|
|
40480
|
+
}
|
|
40481
|
+
function validateEvent(event) {
|
|
40482
|
+
if (!isRecord3(event) || typeof event.type !== "string" || event.type.length === 0) {
|
|
40483
|
+
throw new TypeError(
|
|
40484
|
+
"updateOpenAIAgentsTrace expected an OpenAI Agents event object"
|
|
40485
|
+
);
|
|
40486
|
+
}
|
|
40487
|
+
return event;
|
|
40488
|
+
}
|
|
40489
|
+
function createTraceState() {
|
|
40490
|
+
const parent = _internalExportParentSynchronously(getSpanParentObject());
|
|
40491
|
+
if (!parent) {
|
|
40492
|
+
return null;
|
|
40493
|
+
}
|
|
40494
|
+
const parentComponents = SpanComponentsV4.fromStr(parent);
|
|
40495
|
+
const rowId = newId();
|
|
40496
|
+
const useLegacyIds = resolveUseLegacyUuidIds();
|
|
40497
|
+
const spanId = useLegacyIds ? newId() : newId().replaceAll("-", "").slice(0, 16);
|
|
40498
|
+
const rootSpanId = useLegacyIds ? spanId : newId().replaceAll("-", "");
|
|
40499
|
+
const root = new SpanComponentsV4({
|
|
40500
|
+
object_type: parentComponents.data.object_type,
|
|
40501
|
+
...parentComponents.data.object_id ? { object_id: parentComponents.data.object_id } : {
|
|
40502
|
+
compute_object_metadata_args: parentComponents.data.compute_object_metadata_args ?? {}
|
|
40503
|
+
},
|
|
40504
|
+
propagated_event: parentComponents.data.propagated_event,
|
|
40505
|
+
root_span_id: rootSpanId,
|
|
40506
|
+
row_id: rowId,
|
|
40507
|
+
span_id: spanId
|
|
40508
|
+
}).toStr();
|
|
40509
|
+
return {
|
|
40510
|
+
callItems: {},
|
|
40511
|
+
ended: false,
|
|
40512
|
+
eventIds: [],
|
|
40513
|
+
openTools: {},
|
|
40514
|
+
root,
|
|
40515
|
+
rootKey: spanId,
|
|
40516
|
+
rootParent: parent,
|
|
40517
|
+
startTime: getCurrentUnixTimestamp(),
|
|
40518
|
+
subagents: {},
|
|
40519
|
+
turnSubagents: {},
|
|
40520
|
+
version: 1
|
|
40521
|
+
};
|
|
40522
|
+
}
|
|
40523
|
+
function startOpenAIAgentsTrace(args) {
|
|
40524
|
+
const validatedArgs = validateStartArgs(args);
|
|
40525
|
+
const state = createTraceState();
|
|
40526
|
+
if (!state) {
|
|
40527
|
+
return null;
|
|
40528
|
+
}
|
|
40529
|
+
try {
|
|
40530
|
+
void openAIChannels.agentsTraceStart.invoke(
|
|
40531
|
+
async () => state,
|
|
40532
|
+
void 0,
|
|
40533
|
+
[{ args: validatedArgs, state }],
|
|
40534
|
+
{}
|
|
40535
|
+
).catch((error) => {
|
|
40536
|
+
debugLogger.debug(
|
|
40537
|
+
"OpenAI Agents API instrumentation could not start:",
|
|
40538
|
+
error
|
|
40539
|
+
);
|
|
40540
|
+
});
|
|
40541
|
+
} catch (error) {
|
|
40542
|
+
debugLogger.debug(
|
|
40543
|
+
"OpenAI Agents API instrumentation could not start:",
|
|
40544
|
+
error
|
|
40545
|
+
);
|
|
40546
|
+
}
|
|
40547
|
+
return state;
|
|
40548
|
+
}
|
|
40549
|
+
async function updateOpenAIAgentsTrace(token, event) {
|
|
40550
|
+
const state = token;
|
|
40551
|
+
const validatedEvent = validateEvent(event);
|
|
40552
|
+
try {
|
|
40553
|
+
return await openAIChannels.agentsTraceCapture.invoke(
|
|
40554
|
+
async () => state,
|
|
40555
|
+
void 0,
|
|
40556
|
+
[{ state, event: validatedEvent }],
|
|
40557
|
+
{}
|
|
40558
|
+
);
|
|
40559
|
+
} catch (error) {
|
|
40560
|
+
debugLogger.debug(
|
|
40561
|
+
"OpenAI Agents API instrumentation could not update:",
|
|
40562
|
+
error
|
|
40563
|
+
);
|
|
40564
|
+
return token;
|
|
40565
|
+
}
|
|
40566
|
+
}
|
|
40567
|
+
async function failOpenAIAgentsTrace(token, error) {
|
|
40568
|
+
const state = token;
|
|
40569
|
+
try {
|
|
40570
|
+
return await openAIChannels.agentsTraceFail.invoke(
|
|
40571
|
+
async () => state,
|
|
40572
|
+
void 0,
|
|
40573
|
+
[{ state, error }],
|
|
40574
|
+
{}
|
|
40575
|
+
);
|
|
40576
|
+
} catch (instrumentationError) {
|
|
40577
|
+
debugLogger.debug(
|
|
40578
|
+
"OpenAI Agents API instrumentation could not record failure:",
|
|
40579
|
+
instrumentationError
|
|
40580
|
+
);
|
|
40581
|
+
return token;
|
|
40582
|
+
}
|
|
40583
|
+
}
|
|
40584
|
+
|
|
39328
40585
|
// src/functions/invoke.ts
|
|
39329
40586
|
async function invoke(args) {
|
|
39330
40587
|
const {
|
|
@@ -40774,7 +42031,31 @@ var MAX_STORED_LLM_INPUTS = 100;
|
|
|
40774
42031
|
var MAX_STORED_REASONING_BLOCKS = 100;
|
|
40775
42032
|
var MAX_STORED_SPAN_REFERENCES = 1e4;
|
|
40776
42033
|
var MAX_STORED_STEP_STARTS = 1e4;
|
|
42034
|
+
var EVE_HANDLED_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
42035
|
+
"action.result",
|
|
42036
|
+
"actions.requested",
|
|
42037
|
+
"message.completed",
|
|
42038
|
+
"message.received",
|
|
42039
|
+
"reasoning.completed",
|
|
42040
|
+
"result.completed",
|
|
42041
|
+
"session.completed",
|
|
42042
|
+
"session.failed",
|
|
42043
|
+
"session.started",
|
|
42044
|
+
"step.completed",
|
|
42045
|
+
"step.failed",
|
|
42046
|
+
"step.started",
|
|
42047
|
+
"subagent.called",
|
|
42048
|
+
"subagent.completed",
|
|
42049
|
+
"turn.completed",
|
|
42050
|
+
"turn.failed",
|
|
42051
|
+
"turn.started"
|
|
42052
|
+
]);
|
|
40777
42053
|
function braintrustEveHook(options) {
|
|
42054
|
+
if (!options || typeof options.defineState !== "function") {
|
|
42055
|
+
throw new TypeError(
|
|
42056
|
+
"braintrustEveHook requires Eve's defineState function"
|
|
42057
|
+
);
|
|
42058
|
+
}
|
|
40778
42059
|
const state = options.defineState(EVE_TRACE_STATE_KEY, emptyEveTraceState);
|
|
40779
42060
|
const bridge = new EveBridge(state);
|
|
40780
42061
|
return {
|
|
@@ -40786,15 +42067,27 @@ function braintrustEveHook(options) {
|
|
|
40786
42067
|
};
|
|
40787
42068
|
}
|
|
40788
42069
|
function createLegacyEveInstrumentation(options) {
|
|
42070
|
+
if (!options || typeof options.defineState !== "function") {
|
|
42071
|
+
throw new TypeError(
|
|
42072
|
+
"braintrustEveInstrumentation requires Eve's defineState function"
|
|
42073
|
+
);
|
|
42074
|
+
}
|
|
40789
42075
|
const state = options.defineState(EVE_TRACE_STATE_KEY, emptyEveTraceState);
|
|
40790
42076
|
return {
|
|
40791
42077
|
events: {
|
|
40792
42078
|
"step.started": (input) => {
|
|
40793
42079
|
try {
|
|
42080
|
+
if (!isEveInstrumentationStepStartedEventInput(input)) {
|
|
42081
|
+
debugLogger.warn(
|
|
42082
|
+
"Ignoring malformed Eve instrumentation step.started event"
|
|
42083
|
+
);
|
|
42084
|
+
return void 0;
|
|
42085
|
+
}
|
|
40794
42086
|
captureEveModelInput(state, input);
|
|
40795
42087
|
} catch (error) {
|
|
40796
42088
|
debugLogger.warn("Error in Eve LLM input capture:", error);
|
|
40797
42089
|
}
|
|
42090
|
+
return void 0;
|
|
40798
42091
|
}
|
|
40799
42092
|
},
|
|
40800
42093
|
recordInputs: false,
|
|
@@ -40803,7 +42096,77 @@ function createLegacyEveInstrumentation(options) {
|
|
|
40803
42096
|
};
|
|
40804
42097
|
}
|
|
40805
42098
|
function isEveHandleMessageStreamEvent(event) {
|
|
40806
|
-
|
|
42099
|
+
if (!isObject(event) || typeof event["type"] !== "string") {
|
|
42100
|
+
return false;
|
|
42101
|
+
}
|
|
42102
|
+
const type = event["type"];
|
|
42103
|
+
if (type === "session.completed") {
|
|
42104
|
+
return true;
|
|
42105
|
+
}
|
|
42106
|
+
if (!isObject(event["data"])) {
|
|
42107
|
+
return false;
|
|
42108
|
+
}
|
|
42109
|
+
const data = event["data"];
|
|
42110
|
+
if (type === "session.started") {
|
|
42111
|
+
return true;
|
|
42112
|
+
}
|
|
42113
|
+
if (type === "session.failed") {
|
|
42114
|
+
return typeof data["sessionId"] === "string" && typeof data["code"] === "string" && typeof data["message"] === "string";
|
|
42115
|
+
}
|
|
42116
|
+
if (type === "session.waiting") {
|
|
42117
|
+
return data["wait"] === "next-user-message";
|
|
42118
|
+
}
|
|
42119
|
+
if (typeof data["turnId"] !== "string" || typeof data["sequence"] !== "number" || !Number.isFinite(data["sequence"])) {
|
|
42120
|
+
return false;
|
|
42121
|
+
}
|
|
42122
|
+
if (type === "turn.started" || type === "turn.completed" || type === "subagent.called" || type === "subagent.completed") {
|
|
42123
|
+
if (type === "subagent.called") {
|
|
42124
|
+
return typeof data["callId"] === "string" && typeof data["childSessionId"] === "string" && typeof data["name"] === "string";
|
|
42125
|
+
}
|
|
42126
|
+
if (type === "subagent.completed") {
|
|
42127
|
+
return typeof data["callId"] === "string" && typeof data["subagentName"] === "string";
|
|
42128
|
+
}
|
|
42129
|
+
return true;
|
|
42130
|
+
}
|
|
42131
|
+
if (type === "turn.failed") {
|
|
42132
|
+
return typeof data["code"] === "string" && typeof data["message"] === "string";
|
|
42133
|
+
}
|
|
42134
|
+
if (type === "message.received") {
|
|
42135
|
+
return typeof data["message"] === "string";
|
|
42136
|
+
}
|
|
42137
|
+
if (typeof data["stepIndex"] !== "number" || !Number.isFinite(data["stepIndex"]) || data["stepIndex"] < 0) {
|
|
42138
|
+
return false;
|
|
42139
|
+
}
|
|
42140
|
+
switch (type) {
|
|
42141
|
+
case "step.started":
|
|
42142
|
+
return true;
|
|
42143
|
+
case "message.completed":
|
|
42144
|
+
return typeof data["finishReason"] === "string" && (typeof data["message"] === "string" || data["message"] === null);
|
|
42145
|
+
case "reasoning.completed":
|
|
42146
|
+
return typeof data["reasoning"] === "string";
|
|
42147
|
+
case "result.completed":
|
|
42148
|
+
return true;
|
|
42149
|
+
case "step.completed":
|
|
42150
|
+
return typeof data["finishReason"] === "string";
|
|
42151
|
+
case "step.failed":
|
|
42152
|
+
return typeof data["code"] === "string" && typeof data["message"] === "string";
|
|
42153
|
+
case "actions.requested":
|
|
42154
|
+
return Array.isArray(data["actions"]);
|
|
42155
|
+
case "action.result":
|
|
42156
|
+
return isObject(data["result"]) && (data["status"] === "completed" || data["status"] === "failed" || data["status"] === "rejected");
|
|
42157
|
+
default:
|
|
42158
|
+
return false;
|
|
42159
|
+
}
|
|
42160
|
+
}
|
|
42161
|
+
function isEveInstrumentationStepStartedEventInput(input) {
|
|
42162
|
+
if (!isObject(input)) {
|
|
42163
|
+
return false;
|
|
42164
|
+
}
|
|
42165
|
+
const modelInput = input["modelInput"];
|
|
42166
|
+
const session = input["session"];
|
|
42167
|
+
const step = input["step"];
|
|
42168
|
+
const turn = input["turn"];
|
|
42169
|
+
return isObject(modelInput) && Array.isArray(modelInput["messages"]) && isObject(session) && typeof session["id"] === "string" && isObject(step) && typeof step["index"] === "number" && Number.isFinite(step["index"]) && step["index"] >= 0 && isObject(turn) && typeof turn["id"] === "string" && typeof turn["sequence"] === "number" && Number.isFinite(turn["sequence"]);
|
|
40807
42170
|
}
|
|
40808
42171
|
var ResumedEveSpan = class {
|
|
40809
42172
|
constructor(reference) {
|
|
@@ -40972,7 +42335,17 @@ var EveBridge = class {
|
|
|
40972
42335
|
});
|
|
40973
42336
|
}
|
|
40974
42337
|
async handle(event, ctx, hookMetadata) {
|
|
42338
|
+
try {
|
|
42339
|
+
await this.handleUnchecked(event, ctx, hookMetadata);
|
|
42340
|
+
} catch (error) {
|
|
42341
|
+
debugLogger.warn("Error in Eve hook instrumentation:", error);
|
|
42342
|
+
}
|
|
42343
|
+
}
|
|
42344
|
+
async handleUnchecked(event, ctx, hookMetadata) {
|
|
40975
42345
|
if (!isEveHandleMessageStreamEvent(event)) {
|
|
42346
|
+
if (isObject(event) && typeof event["type"] === "string" && EVE_HANDLED_EVENT_TYPES.has(event["type"])) {
|
|
42347
|
+
debugLogger.warn(`Ignoring malformed Eve hook ${event["type"]} event`);
|
|
42348
|
+
}
|
|
40976
42349
|
return;
|
|
40977
42350
|
}
|
|
40978
42351
|
const run = async () => {
|
|
@@ -41298,9 +42671,14 @@ var EveBridge = class {
|
|
|
41298
42671
|
}
|
|
41299
42672
|
for (const action of traceActions) {
|
|
41300
42673
|
const name = action.kind === "tool-call" ? action.toolName : action.subagentName ?? action.name ?? "agent";
|
|
42674
|
+
let args = "null";
|
|
42675
|
+
try {
|
|
42676
|
+
args = JSON.stringify(action.input) ?? "null";
|
|
42677
|
+
} catch {
|
|
42678
|
+
}
|
|
41301
42679
|
toolCallsById.set(action.callId, {
|
|
41302
42680
|
function: {
|
|
41303
|
-
arguments:
|
|
42681
|
+
arguments: args,
|
|
41304
42682
|
name
|
|
41305
42683
|
},
|
|
41306
42684
|
id: action.callId,
|
|
@@ -42169,17 +43547,33 @@ function consumeCapturedEveModelInput(state, sessionId, turnId, stepIndex) {
|
|
|
42169
43547
|
}
|
|
42170
43548
|
}
|
|
42171
43549
|
function capturedModelInput(modelInput) {
|
|
42172
|
-
const { instructions, messages } = modelInput;
|
|
42173
|
-
const value = [];
|
|
42174
|
-
if (typeof instructions === "string") {
|
|
42175
|
-
value.push({ content: instructions, role: "system" });
|
|
42176
|
-
} else if (Array.isArray(instructions)) {
|
|
42177
|
-
value.push(...instructions.map(capturedEveModelMessage));
|
|
42178
|
-
} else if (instructions) {
|
|
42179
|
-
value.push(capturedEveModelMessage(instructions));
|
|
42180
|
-
}
|
|
42181
|
-
value.push(...messages.map(capturedEveModelMessage));
|
|
42182
43550
|
try {
|
|
43551
|
+
if (!isObject(modelInput) || !Array.isArray(modelInput["messages"])) {
|
|
43552
|
+
return void 0;
|
|
43553
|
+
}
|
|
43554
|
+
const value = [];
|
|
43555
|
+
const instructions = modelInput["instructions"];
|
|
43556
|
+
if (typeof instructions === "string") {
|
|
43557
|
+
value.push({ content: instructions, role: "system" });
|
|
43558
|
+
} else if (Array.isArray(instructions)) {
|
|
43559
|
+
for (const instruction of instructions) {
|
|
43560
|
+
const captured = capturedEveModelMessage(instruction);
|
|
43561
|
+
if (captured?.role === "system") {
|
|
43562
|
+
value.push(captured);
|
|
43563
|
+
}
|
|
43564
|
+
}
|
|
43565
|
+
} else {
|
|
43566
|
+
const captured = capturedEveModelMessage(instructions);
|
|
43567
|
+
if (captured?.role === "system") {
|
|
43568
|
+
value.push(captured);
|
|
43569
|
+
}
|
|
43570
|
+
}
|
|
43571
|
+
for (const message of modelInput["messages"]) {
|
|
43572
|
+
const captured = capturedEveModelMessage(message);
|
|
43573
|
+
if (captured) {
|
|
43574
|
+
value.push(captured);
|
|
43575
|
+
}
|
|
43576
|
+
}
|
|
42183
43577
|
const cloned = JSON.parse(JSON.stringify(value));
|
|
42184
43578
|
if (!Array.isArray(cloned)) {
|
|
42185
43579
|
return void 0;
|
|
@@ -42190,116 +43584,202 @@ function capturedModelInput(modelInput) {
|
|
|
42190
43584
|
}
|
|
42191
43585
|
}
|
|
42192
43586
|
function capturedEveModelMessage(message) {
|
|
42193
|
-
|
|
43587
|
+
if (!isObject(message)) {
|
|
43588
|
+
return void 0;
|
|
43589
|
+
}
|
|
43590
|
+
const role = message["role"];
|
|
43591
|
+
if (role !== "system" && role !== "user" && role !== "assistant" && role !== "tool") {
|
|
43592
|
+
return void 0;
|
|
43593
|
+
}
|
|
43594
|
+
const content = message["content"];
|
|
42194
43595
|
if (typeof content === "string") {
|
|
42195
43596
|
return { content, role };
|
|
42196
43597
|
}
|
|
42197
|
-
|
|
43598
|
+
if (!Array.isArray(content)) {
|
|
43599
|
+
return void 0;
|
|
43600
|
+
}
|
|
43601
|
+
const capturedContent = [];
|
|
43602
|
+
for (const part of content) {
|
|
43603
|
+
const captured = capturedEveModelContentPart(part);
|
|
43604
|
+
if (captured) {
|
|
43605
|
+
capturedContent.push(captured);
|
|
43606
|
+
}
|
|
43607
|
+
}
|
|
43608
|
+
return { content: capturedContent, role };
|
|
42198
43609
|
}
|
|
42199
43610
|
function capturedEveModelContentPart(part) {
|
|
42200
|
-
|
|
43611
|
+
if (!isObject(part) || typeof part["type"] !== "string") {
|
|
43612
|
+
return void 0;
|
|
43613
|
+
}
|
|
43614
|
+
switch (part["type"]) {
|
|
42201
43615
|
case "text":
|
|
42202
|
-
case "reasoning":
|
|
42203
|
-
|
|
43616
|
+
case "reasoning": {
|
|
43617
|
+
const text = part["text"];
|
|
43618
|
+
return typeof text === "string" ? { text, type: part["type"] } : void 0;
|
|
43619
|
+
}
|
|
42204
43620
|
case "image":
|
|
43621
|
+
if (!Object.hasOwn(part, "image")) {
|
|
43622
|
+
return void 0;
|
|
43623
|
+
}
|
|
42205
43624
|
return {
|
|
42206
|
-
image: part
|
|
42207
|
-
...part
|
|
43625
|
+
image: part["image"],
|
|
43626
|
+
...typeof part["mediaType"] === "string" ? { mediaType: part["mediaType"] } : {},
|
|
42208
43627
|
type: "image"
|
|
42209
43628
|
};
|
|
42210
43629
|
case "file":
|
|
42211
|
-
case "reasoning-file":
|
|
43630
|
+
case "reasoning-file": {
|
|
43631
|
+
if (!Object.hasOwn(part, "data") || typeof part["mediaType"] !== "string") {
|
|
43632
|
+
return void 0;
|
|
43633
|
+
}
|
|
42212
43634
|
return {
|
|
42213
|
-
data: part
|
|
42214
|
-
...part
|
|
42215
|
-
mediaType: part
|
|
42216
|
-
type: part
|
|
43635
|
+
data: part["data"],
|
|
43636
|
+
...part["type"] === "file" && typeof part["filename"] === "string" ? { filename: part["filename"] } : {},
|
|
43637
|
+
mediaType: part["mediaType"],
|
|
43638
|
+
type: part["type"]
|
|
42217
43639
|
};
|
|
43640
|
+
}
|
|
42218
43641
|
case "custom":
|
|
42219
43642
|
return {
|
|
42220
|
-
..."kind"
|
|
43643
|
+
...typeof part["kind"] === "string" ? { kind: part["kind"] } : {},
|
|
42221
43644
|
type: "custom"
|
|
42222
43645
|
};
|
|
42223
|
-
case "tool-call":
|
|
43646
|
+
case "tool-call": {
|
|
43647
|
+
if (typeof part["toolCallId"] !== "string" || typeof part["toolName"] !== "string") {
|
|
43648
|
+
return void 0;
|
|
43649
|
+
}
|
|
42224
43650
|
return {
|
|
42225
|
-
input: part
|
|
42226
|
-
...part
|
|
42227
|
-
toolCallId: part
|
|
42228
|
-
toolName: part
|
|
43651
|
+
input: part["input"],
|
|
43652
|
+
...typeof part["providerExecuted"] === "boolean" ? { providerExecuted: part["providerExecuted"] } : {},
|
|
43653
|
+
toolCallId: part["toolCallId"],
|
|
43654
|
+
toolName: part["toolName"],
|
|
42229
43655
|
type: "tool-call"
|
|
42230
43656
|
};
|
|
43657
|
+
}
|
|
42231
43658
|
case "tool-result": {
|
|
42232
|
-
const output = part
|
|
43659
|
+
const output = part["output"];
|
|
43660
|
+
if (typeof part["toolCallId"] !== "string" || typeof part["toolName"] !== "string" || !isObject(output) || typeof output["type"] !== "string") {
|
|
43661
|
+
return void 0;
|
|
43662
|
+
}
|
|
42233
43663
|
let capturedOutput;
|
|
42234
|
-
switch (output
|
|
43664
|
+
switch (output["type"]) {
|
|
42235
43665
|
case "text":
|
|
42236
|
-
case "error-text":
|
|
42237
|
-
|
|
43666
|
+
case "error-text": {
|
|
43667
|
+
if (typeof output["value"] !== "string") {
|
|
43668
|
+
return void 0;
|
|
43669
|
+
}
|
|
43670
|
+
capturedOutput = {
|
|
43671
|
+
type: output["type"],
|
|
43672
|
+
value: output["value"]
|
|
43673
|
+
};
|
|
42238
43674
|
break;
|
|
43675
|
+
}
|
|
42239
43676
|
case "json":
|
|
42240
43677
|
case "error-json":
|
|
42241
|
-
capturedOutput = {
|
|
43678
|
+
capturedOutput = {
|
|
43679
|
+
type: output["type"],
|
|
43680
|
+
value: output["value"]
|
|
43681
|
+
};
|
|
42242
43682
|
break;
|
|
42243
43683
|
case "execution-denied":
|
|
42244
43684
|
capturedOutput = {
|
|
42245
|
-
...output
|
|
43685
|
+
...typeof output["reason"] === "string" ? { reason: output["reason"] } : {},
|
|
42246
43686
|
type: "execution-denied"
|
|
42247
43687
|
};
|
|
42248
43688
|
break;
|
|
42249
|
-
case "content":
|
|
43689
|
+
case "content": {
|
|
43690
|
+
if (!Array.isArray(output["value"])) {
|
|
43691
|
+
return void 0;
|
|
43692
|
+
}
|
|
43693
|
+
const value = [];
|
|
43694
|
+
for (const outputPart of output["value"]) {
|
|
43695
|
+
const captured = capturedEveModelContentPart(outputPart);
|
|
43696
|
+
if (captured) {
|
|
43697
|
+
value.push(captured);
|
|
43698
|
+
}
|
|
43699
|
+
}
|
|
42250
43700
|
capturedOutput = {
|
|
42251
43701
|
type: "content",
|
|
42252
|
-
value
|
|
43702
|
+
value
|
|
42253
43703
|
};
|
|
42254
43704
|
break;
|
|
43705
|
+
}
|
|
43706
|
+
default:
|
|
43707
|
+
return void 0;
|
|
42255
43708
|
}
|
|
42256
43709
|
return {
|
|
42257
43710
|
output: capturedOutput,
|
|
42258
|
-
toolCallId: part
|
|
42259
|
-
toolName: part
|
|
43711
|
+
toolCallId: part["toolCallId"],
|
|
43712
|
+
toolName: part["toolName"],
|
|
42260
43713
|
type: "tool-result"
|
|
42261
43714
|
};
|
|
42262
43715
|
}
|
|
42263
|
-
case "tool-approval-request":
|
|
43716
|
+
case "tool-approval-request": {
|
|
43717
|
+
if (typeof part["approvalId"] !== "string" || typeof part["toolCallId"] !== "string") {
|
|
43718
|
+
return void 0;
|
|
43719
|
+
}
|
|
42264
43720
|
return {
|
|
42265
|
-
approvalId: part
|
|
42266
|
-
...part
|
|
42267
|
-
...part
|
|
42268
|
-
toolCallId: part
|
|
43721
|
+
approvalId: part["approvalId"],
|
|
43722
|
+
...typeof part["isAutomatic"] === "boolean" ? { isAutomatic: part["isAutomatic"] } : {},
|
|
43723
|
+
...typeof part["signature"] === "string" ? { signature: part["signature"] } : {},
|
|
43724
|
+
toolCallId: part["toolCallId"],
|
|
42269
43725
|
type: "tool-approval-request"
|
|
42270
43726
|
};
|
|
42271
|
-
|
|
43727
|
+
}
|
|
43728
|
+
case "tool-approval-response": {
|
|
43729
|
+
if (typeof part["approvalId"] !== "string" || typeof part["approved"] !== "boolean") {
|
|
43730
|
+
return void 0;
|
|
43731
|
+
}
|
|
42272
43732
|
return {
|
|
42273
|
-
approvalId: part
|
|
42274
|
-
approved: part
|
|
42275
|
-
...part
|
|
42276
|
-
...part
|
|
43733
|
+
approvalId: part["approvalId"],
|
|
43734
|
+
approved: part["approved"],
|
|
43735
|
+
...typeof part["providerExecuted"] === "boolean" ? { providerExecuted: part["providerExecuted"] } : {},
|
|
43736
|
+
...typeof part["reason"] === "string" ? { reason: part["reason"] } : {},
|
|
42277
43737
|
type: "tool-approval-response"
|
|
42278
43738
|
};
|
|
43739
|
+
}
|
|
42279
43740
|
case "file-data":
|
|
42280
|
-
case "image-data":
|
|
43741
|
+
case "image-data": {
|
|
43742
|
+
if (typeof part["data"] !== "string" || typeof part["mediaType"] !== "string") {
|
|
43743
|
+
return void 0;
|
|
43744
|
+
}
|
|
42281
43745
|
return {
|
|
42282
|
-
data: part
|
|
42283
|
-
...part
|
|
42284
|
-
mediaType: part
|
|
42285
|
-
type: part
|
|
43746
|
+
data: part["data"],
|
|
43747
|
+
...part["type"] === "file-data" && typeof part["filename"] === "string" ? { filename: part["filename"] } : {},
|
|
43748
|
+
mediaType: part["mediaType"],
|
|
43749
|
+
type: part["type"]
|
|
42286
43750
|
};
|
|
43751
|
+
}
|
|
42287
43752
|
case "file-url":
|
|
42288
|
-
case "image-url":
|
|
43753
|
+
case "image-url": {
|
|
43754
|
+
if (typeof part["url"] !== "string") {
|
|
43755
|
+
return void 0;
|
|
43756
|
+
}
|
|
42289
43757
|
return {
|
|
42290
|
-
...part
|
|
42291
|
-
type: part
|
|
42292
|
-
url: part
|
|
43758
|
+
...part["type"] === "file-url" && typeof part["mediaType"] === "string" ? { mediaType: part["mediaType"] } : {},
|
|
43759
|
+
type: part["type"],
|
|
43760
|
+
url: part["url"]
|
|
42293
43761
|
};
|
|
43762
|
+
}
|
|
42294
43763
|
case "file-id":
|
|
42295
|
-
case "image-file-id":
|
|
42296
|
-
|
|
43764
|
+
case "image-file-id": {
|
|
43765
|
+
const fileId = part["fileId"];
|
|
43766
|
+
if (typeof fileId !== "string" && !isObject(fileId)) {
|
|
43767
|
+
return void 0;
|
|
43768
|
+
}
|
|
43769
|
+
return { fileId, type: part["type"] };
|
|
43770
|
+
}
|
|
42297
43771
|
case "file-reference":
|
|
42298
|
-
case "image-file-reference":
|
|
43772
|
+
case "image-file-reference": {
|
|
43773
|
+
if (!isObject(part["providerReference"])) {
|
|
43774
|
+
return void 0;
|
|
43775
|
+
}
|
|
42299
43776
|
return {
|
|
42300
|
-
providerReference: part
|
|
42301
|
-
type: part
|
|
43777
|
+
providerReference: part["providerReference"],
|
|
43778
|
+
type: part["type"]
|
|
42302
43779
|
};
|
|
43780
|
+
}
|
|
43781
|
+
default:
|
|
43782
|
+
return void 0;
|
|
42303
43783
|
}
|
|
42304
43784
|
}
|
|
42305
43785
|
function isCapturedModelInput(input) {
|
|
@@ -42435,18 +43915,54 @@ function createEveInstrumentationProvider(options = {}) {
|
|
|
42435
43915
|
recordOutputs: true
|
|
42436
43916
|
}),
|
|
42437
43917
|
events: {
|
|
42438
|
-
"action.completed": (
|
|
42439
|
-
|
|
42440
|
-
|
|
42441
|
-
|
|
42442
|
-
"
|
|
42443
|
-
|
|
42444
|
-
|
|
42445
|
-
|
|
42446
|
-
"
|
|
42447
|
-
|
|
42448
|
-
|
|
42449
|
-
|
|
43918
|
+
"action.completed": providerHandler(
|
|
43919
|
+
"action.completed",
|
|
43920
|
+
bridge.handleActionTerminal.bind(bridge)
|
|
43921
|
+
),
|
|
43922
|
+
"action.failed": providerHandler(
|
|
43923
|
+
"action.failed",
|
|
43924
|
+
bridge.handleActionTerminal.bind(bridge)
|
|
43925
|
+
),
|
|
43926
|
+
"action.started": providerHandler(
|
|
43927
|
+
"action.started",
|
|
43928
|
+
bridge.handleActionStarted.bind(bridge)
|
|
43929
|
+
),
|
|
43930
|
+
"model.call.completed": providerHandler(
|
|
43931
|
+
"model.call.completed",
|
|
43932
|
+
bridge.handleModelTerminal.bind(bridge)
|
|
43933
|
+
),
|
|
43934
|
+
"model.call.failed": providerHandler(
|
|
43935
|
+
"model.call.failed",
|
|
43936
|
+
bridge.handleModelTerminal.bind(bridge)
|
|
43937
|
+
),
|
|
43938
|
+
"model.call.started": providerHandler(
|
|
43939
|
+
"model.call.started",
|
|
43940
|
+
bridge.handleModelStarted.bind(bridge)
|
|
43941
|
+
),
|
|
43942
|
+
"step.attempt.completed": providerHandler(
|
|
43943
|
+
"step.attempt.completed",
|
|
43944
|
+
(event) => bridge.handleStepAttemptTerminal(event)
|
|
43945
|
+
),
|
|
43946
|
+
"step.attempt.failed": providerHandler(
|
|
43947
|
+
"step.attempt.failed",
|
|
43948
|
+
(event) => bridge.handleStepAttemptTerminal(event)
|
|
43949
|
+
),
|
|
43950
|
+
"turn.cancelled": providerHandler(
|
|
43951
|
+
"turn.cancelled",
|
|
43952
|
+
bridge.handleTurnTerminal.bind(bridge)
|
|
43953
|
+
),
|
|
43954
|
+
"turn.completed": providerHandler(
|
|
43955
|
+
"turn.completed",
|
|
43956
|
+
bridge.handleTurnTerminal.bind(bridge)
|
|
43957
|
+
),
|
|
43958
|
+
"turn.failed": providerHandler(
|
|
43959
|
+
"turn.failed",
|
|
43960
|
+
bridge.handleTurnTerminal.bind(bridge)
|
|
43961
|
+
),
|
|
43962
|
+
"turn.started": providerHandler(
|
|
43963
|
+
"turn.started",
|
|
43964
|
+
bridge.handleTurnStarted.bind(bridge)
|
|
43965
|
+
)
|
|
42450
43966
|
},
|
|
42451
43967
|
flush,
|
|
42452
43968
|
setup: options.setup
|
|
@@ -42802,17 +44318,20 @@ function modelOutput(event) {
|
|
|
42802
44318
|
const reasoning = [];
|
|
42803
44319
|
const toolCalls2 = [];
|
|
42804
44320
|
for (const part of content) {
|
|
42805
|
-
if (part
|
|
42806
|
-
|
|
42807
|
-
}
|
|
42808
|
-
|
|
42809
|
-
|
|
44321
|
+
if (!isObject(part)) {
|
|
44322
|
+
continue;
|
|
44323
|
+
}
|
|
44324
|
+
if (part["type"] === "text" && typeof part["text"] === "string") {
|
|
44325
|
+
text += part["text"];
|
|
44326
|
+
} else if (part["type"] === "reasoning" && typeof part["text"] === "string" && part["text"].trim().length > 0) {
|
|
44327
|
+
reasoning.push({ content: part["text"] });
|
|
44328
|
+
} else if (part["type"] === "tool-call" && typeof part["toolName"] === "string" && typeof part["callId"] === "string") {
|
|
42810
44329
|
toolCalls2.push({
|
|
42811
44330
|
function: {
|
|
42812
|
-
arguments: safeJsonStringify(part
|
|
42813
|
-
name: part
|
|
44331
|
+
arguments: safeJsonStringify(part["input"]),
|
|
44332
|
+
name: part["toolName"]
|
|
42814
44333
|
},
|
|
42815
|
-
id: part
|
|
44334
|
+
id: part["callId"],
|
|
42816
44335
|
type: "function"
|
|
42817
44336
|
});
|
|
42818
44337
|
}
|
|
@@ -42831,13 +44350,13 @@ function modelOutput(event) {
|
|
|
42831
44350
|
];
|
|
42832
44351
|
}
|
|
42833
44352
|
function usageMetrics(usage) {
|
|
42834
|
-
const promptTokens = nonNegativeNumber(usage
|
|
42835
|
-
const completionTokens = nonNegativeNumber(usage
|
|
44353
|
+
const promptTokens = nonNegativeNumber(usage?.inputTokens);
|
|
44354
|
+
const completionTokens = nonNegativeNumber(usage?.outputTokens);
|
|
42836
44355
|
const cachedTokens = nonNegativeNumber(
|
|
42837
|
-
usage
|
|
44356
|
+
usage?.inputTokenDetails?.cacheReadTokens
|
|
42838
44357
|
);
|
|
42839
44358
|
const cacheCreationTokens = nonNegativeNumber(
|
|
42840
|
-
usage
|
|
44359
|
+
usage?.inputTokenDetails?.cacheWriteTokens
|
|
42841
44360
|
);
|
|
42842
44361
|
return {
|
|
42843
44362
|
...promptTokens !== void 0 ? { prompt_tokens: promptTokens } : {},
|
|
@@ -42874,10 +44393,76 @@ function turnIdempotencyKey(sessionId, turnId) {
|
|
|
42874
44393
|
function actionIdempotencyKey(sessionId, turnId, callId) {
|
|
42875
44394
|
return `action:${sessionId}:${turnId}:${callId}`;
|
|
42876
44395
|
}
|
|
44396
|
+
function providerHandler(type, handler) {
|
|
44397
|
+
return async (event, context) => {
|
|
44398
|
+
try {
|
|
44399
|
+
if (!isEveProviderEvent(event, type) || !isEveProviderContext(context)) {
|
|
44400
|
+
debugLogger.warn(`Ignoring malformed Eve provider ${type} event`);
|
|
44401
|
+
return;
|
|
44402
|
+
}
|
|
44403
|
+
await handler(event, context);
|
|
44404
|
+
} catch (error) {
|
|
44405
|
+
debugLogger.warn(`Error in Eve provider ${type}:`, error);
|
|
44406
|
+
}
|
|
44407
|
+
};
|
|
44408
|
+
}
|
|
44409
|
+
function isEveProviderEvent(event, type) {
|
|
44410
|
+
if (!isObject(event) || event["type"] !== type || typeof event["idempotencyKey"] !== "string" || event["idempotencyKey"].length === 0) {
|
|
44411
|
+
return false;
|
|
44412
|
+
}
|
|
44413
|
+
if (type === "turn.started") {
|
|
44414
|
+
const parentLineage = event["parentLineage"];
|
|
44415
|
+
return typeof event["rootSessionId"] === "string" && typeof event["sessionId"] === "string" && typeof event["turnId"] === "string" && typeof event["sequence"] === "number" && Number.isFinite(event["sequence"]) && (parentLineage === void 0 || isEveProviderParentLineage(parentLineage));
|
|
44416
|
+
}
|
|
44417
|
+
if (type === "turn.cancelled" || type === "turn.completed" || type === "turn.failed") {
|
|
44418
|
+
return typeof event["sessionId"] === "string" && typeof event["turnId"] === "string";
|
|
44419
|
+
}
|
|
44420
|
+
if (!isEveProviderScope(event["scope"])) {
|
|
44421
|
+
return false;
|
|
44422
|
+
}
|
|
44423
|
+
if (type === "model.call.started") {
|
|
44424
|
+
const model = event["model"];
|
|
44425
|
+
return isObject(model) && typeof model["modelId"] === "string" && typeof model["provider"] === "string";
|
|
44426
|
+
}
|
|
44427
|
+
if (type === "model.call.completed") {
|
|
44428
|
+
return typeof event["finishReason"] === "string" && isObject(event["usage"]) && (event["content"] === void 0 || Array.isArray(event["content"]));
|
|
44429
|
+
}
|
|
44430
|
+
if (type === "model.call.failed") {
|
|
44431
|
+
return true;
|
|
44432
|
+
}
|
|
44433
|
+
if (type === "action.started") {
|
|
44434
|
+
return typeof event["callId"] === "string" && typeof event["name"] === "string" && (event["kind"] === "load-skill" || event["kind"] === "remote-agent-call" || event["kind"] === "subagent-call" || event["kind"] === "tool-call");
|
|
44435
|
+
}
|
|
44436
|
+
if (type === "action.completed") {
|
|
44437
|
+
const output = event["output"];
|
|
44438
|
+
return event["outcome"] === "completed" && isObject(output) && (output["type"] === "result" || output["type"] === "error");
|
|
44439
|
+
}
|
|
44440
|
+
if (type === "action.failed") {
|
|
44441
|
+
return event["outcome"] === "abandoned" || event["outcome"] === "cancelled" || event["outcome"] === "failed" || event["outcome"] === "rejected";
|
|
44442
|
+
}
|
|
44443
|
+
return type === "step.attempt.completed" || type === "step.attempt.failed";
|
|
44444
|
+
}
|
|
44445
|
+
function isEveProviderContext(value) {
|
|
44446
|
+
if (!isObject(value) || !isObject(value["state"])) {
|
|
44447
|
+
return false;
|
|
44448
|
+
}
|
|
44449
|
+
return typeof value["state"]["get"] === "function" && typeof value["state"]["set"] === "function";
|
|
44450
|
+
}
|
|
44451
|
+
function isEveProviderScope(value) {
|
|
44452
|
+
return isObject(value) && typeof value["attemptId"] === "string" && typeof value["attemptIndex"] === "number" && Number.isFinite(value["attemptIndex"]) && typeof value["sessionId"] === "string" && typeof value["stepIndex"] === "number" && Number.isFinite(value["stepIndex"]) && typeof value["turnId"] === "string" && (value["rootSessionId"] === void 0 || typeof value["rootSessionId"] === "string");
|
|
44453
|
+
}
|
|
44454
|
+
function isEveProviderParentLineage(value) {
|
|
44455
|
+
return isObject(value) && typeof value["callId"] === "string" && typeof value["sessionId"] === "string" && typeof value["turnId"] === "string";
|
|
44456
|
+
}
|
|
42877
44457
|
|
|
42878
44458
|
// src/instrumentation/plugins/eve-instrumentation.ts
|
|
42879
44459
|
var EVE_INSTRUMENTATION_PROVIDER = /* @__PURE__ */ Symbol.for("eve.instrumentation.provider");
|
|
42880
44460
|
function braintrustEveInstrumentation(options) {
|
|
44461
|
+
if (!options || typeof options !== "object") {
|
|
44462
|
+
throw new TypeError(
|
|
44463
|
+
"braintrustEveInstrumentation requires an options object"
|
|
44464
|
+
);
|
|
44465
|
+
}
|
|
42881
44466
|
const definition = "defineState" in options ? createLegacyEveInstrumentation(options) : createEveInstrumentationProvider(options);
|
|
42882
44467
|
const declaration = {
|
|
42883
44468
|
...definition,
|
|
@@ -44114,6 +45699,7 @@ function wrapClient(client) {
|
|
|
44114
45699
|
}
|
|
44115
45700
|
|
|
44116
45701
|
// src/wrappers/google-genai.ts
|
|
45702
|
+
var patchedHttpResponses = /* @__PURE__ */ new WeakSet();
|
|
44117
45703
|
function wrapGoogleGenAI(googleGenAI) {
|
|
44118
45704
|
if (!googleGenAI || typeof googleGenAI !== "object") {
|
|
44119
45705
|
console.warn("Invalid Google GenAI module. Not wrapping.");
|
|
@@ -44125,6 +45711,21 @@ function wrapGoogleGenAI(googleGenAI) {
|
|
|
44125
45711
|
);
|
|
44126
45712
|
return googleGenAI;
|
|
44127
45713
|
}
|
|
45714
|
+
const httpResponse = googleGenAI.HttpResponse;
|
|
45715
|
+
if (typeof httpResponse === "function" && isObject(httpResponse.prototype) && typeof httpResponse.prototype.json === "function" && !patchedHttpResponses.has(httpResponse.prototype)) {
|
|
45716
|
+
const prototype = httpResponse.prototype;
|
|
45717
|
+
const originalJson = prototype.json;
|
|
45718
|
+
if (Reflect.set(prototype, "json", function() {
|
|
45719
|
+
return googleGenAIChannels.httpResponseJson.invoke(
|
|
45720
|
+
originalJson,
|
|
45721
|
+
this,
|
|
45722
|
+
[],
|
|
45723
|
+
{}
|
|
45724
|
+
);
|
|
45725
|
+
})) {
|
|
45726
|
+
patchedHttpResponses.add(prototype);
|
|
45727
|
+
}
|
|
45728
|
+
}
|
|
44128
45729
|
return new Proxy(googleGenAI, {
|
|
44129
45730
|
get(target, prop, receiver) {
|
|
44130
45731
|
if (prop === "GoogleGenAI") {
|
|
@@ -44375,17 +45976,17 @@ function wrapGenkit(genkit) {
|
|
|
44375
45976
|
console.warn("Unsupported Genkit object. Not wrapping.");
|
|
44376
45977
|
return genkit;
|
|
44377
45978
|
}
|
|
44378
|
-
function
|
|
45979
|
+
function isRecord4(value) {
|
|
44379
45980
|
return typeof value === "object" && value !== null;
|
|
44380
45981
|
}
|
|
44381
45982
|
function isPropertyBag(value) {
|
|
44382
|
-
return
|
|
45983
|
+
return isRecord4(value) || typeof value === "function";
|
|
44383
45984
|
}
|
|
44384
45985
|
function hasFunction(value, methodName) {
|
|
44385
45986
|
return isPropertyBag(value) && methodName in value && typeof value[methodName] === "function";
|
|
44386
45987
|
}
|
|
44387
45988
|
function isGenkitInstance(value) {
|
|
44388
|
-
return
|
|
45989
|
+
return isRecord4(value) && (hasFunction(value, "generate") || hasFunction(value, "generateStream") || hasFunction(value, "defineFlow") || hasFunction(value, "defineTool"));
|
|
44389
45990
|
}
|
|
44390
45991
|
function isGenkitModule(value) {
|
|
44391
45992
|
return hasFunction(value, "genkit");
|
|
@@ -44439,7 +46040,7 @@ function patchGenkitRegistry(instance) {
|
|
|
44439
46040
|
patchGenkitRegistryConstructor(registry2);
|
|
44440
46041
|
}
|
|
44441
46042
|
function patchGenkitRegistryLookup(registry2) {
|
|
44442
|
-
if (!
|
|
46043
|
+
if (!isRecord4(registry2) || hasRegistryPatchedFlag(registry2) || !hasFunction(registry2, "lookupAction")) {
|
|
44443
46044
|
return;
|
|
44444
46045
|
}
|
|
44445
46046
|
const originalLookupAction = registry2.lookupAction;
|
|
@@ -44465,7 +46066,7 @@ function patchGenkitRegistryLookup(registry2) {
|
|
|
44465
46066
|
}
|
|
44466
46067
|
}
|
|
44467
46068
|
function patchGenkitRegistryConstructor(registry2) {
|
|
44468
|
-
if (!
|
|
46069
|
+
if (!isRecord4(registry2)) {
|
|
44469
46070
|
return;
|
|
44470
46071
|
}
|
|
44471
46072
|
const constructor = registry2.constructor;
|
|
@@ -44481,7 +46082,7 @@ function patchGenkitRegistryConstructor(registry2) {
|
|
|
44481
46082
|
configurable: true,
|
|
44482
46083
|
value: (...args) => {
|
|
44483
46084
|
const childRegistry = originalWithParent.apply(constructor, args);
|
|
44484
|
-
if (args.some((arg) =>
|
|
46085
|
+
if (args.some((arg) => isRecord4(arg) && hasRegistryPatchedFlag(arg))) {
|
|
44485
46086
|
patchGenkitRegistryLookup(childRegistry);
|
|
44486
46087
|
patchGenkitRegistryConstructor(childRegistry);
|
|
44487
46088
|
}
|
|
@@ -44580,7 +46181,7 @@ function hasRegistryConstructorPatchedFlag(value) {
|
|
|
44580
46181
|
);
|
|
44581
46182
|
}
|
|
44582
46183
|
function isPromiseLike2(value) {
|
|
44583
|
-
return
|
|
46184
|
+
return isRecord4(value) && "then" in value && typeof value.then === "function";
|
|
44584
46185
|
}
|
|
44585
46186
|
|
|
44586
46187
|
// src/wrappers/huggingface.ts
|
|
@@ -45057,14 +46658,14 @@ function wrapMistral(mistral) {
|
|
|
45057
46658
|
console.warn("Unsupported Mistral library. Not wrapping.");
|
|
45058
46659
|
return mistral;
|
|
45059
46660
|
}
|
|
45060
|
-
function
|
|
46661
|
+
function isRecord5(value) {
|
|
45061
46662
|
return typeof value === "object" && value !== null;
|
|
45062
46663
|
}
|
|
45063
46664
|
function hasFunction3(value, methodName) {
|
|
45064
|
-
return
|
|
46665
|
+
return isRecord5(value) && methodName in value && typeof value[methodName] === "function";
|
|
45065
46666
|
}
|
|
45066
46667
|
function isSupportedMistralClient(value) {
|
|
45067
|
-
if (!
|
|
46668
|
+
if (!isRecord5(value)) {
|
|
45068
46669
|
return false;
|
|
45069
46670
|
}
|
|
45070
46671
|
return value.chat !== void 0 && hasChat(value.chat) || value.embeddings !== void 0 && hasEmbeddings(value.embeddings) || value.fim !== void 0 && hasFim(value.fim) || value.agents !== void 0 && hasAgents(value.agents) || value.classifiers !== void 0 && hasClassifiers(value.classifiers);
|
|
@@ -45239,6 +46840,42 @@ function wrapAgentsStream(stream) {
|
|
|
45239
46840
|
});
|
|
45240
46841
|
}
|
|
45241
46842
|
|
|
46843
|
+
// src/wrappers/langgraph-sdk.ts
|
|
46844
|
+
var clients = /* @__PURE__ */ new WeakMap();
|
|
46845
|
+
function wrapLangGraphSDK(client) {
|
|
46846
|
+
const runsClient = isObject(client) ? client.runs : void 0;
|
|
46847
|
+
if (!isObject(client) || !isObject(runsClient) || !["wait", "stream"].every((key) => typeof runsClient[key] === "function")) {
|
|
46848
|
+
debugLogger.warn("Unsupported LangGraph SDK client. Not wrapping.");
|
|
46849
|
+
return client;
|
|
46850
|
+
}
|
|
46851
|
+
const sdk = client;
|
|
46852
|
+
const cached = clients.get(sdk);
|
|
46853
|
+
if (cached) return cached;
|
|
46854
|
+
const runs = new Proxy(sdk.runs, {
|
|
46855
|
+
get(target, key) {
|
|
46856
|
+
switch (key) {
|
|
46857
|
+
case "wait":
|
|
46858
|
+
return (...args) => langGraphSDKChannels.wait.invoke(target.wait, target, args, {});
|
|
46859
|
+
case "stream":
|
|
46860
|
+
return (...args) => langGraphSDKChannels.stream.invoke(target.stream, target, args, {});
|
|
46861
|
+
default:
|
|
46862
|
+
const value = Reflect.get(target, key, target);
|
|
46863
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
46864
|
+
}
|
|
46865
|
+
}
|
|
46866
|
+
});
|
|
46867
|
+
const wrapped = new Proxy(sdk, {
|
|
46868
|
+
get(target, key) {
|
|
46869
|
+
if (key === "runs") return runs;
|
|
46870
|
+
const value = Reflect.get(target, key, target);
|
|
46871
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
46872
|
+
}
|
|
46873
|
+
});
|
|
46874
|
+
clients.set(sdk, wrapped);
|
|
46875
|
+
clients.set(wrapped, wrapped);
|
|
46876
|
+
return wrapped;
|
|
46877
|
+
}
|
|
46878
|
+
|
|
45242
46879
|
// src/wrappers/ollama.ts
|
|
45243
46880
|
function wrapOllama(ollama) {
|
|
45244
46881
|
if (isSupportedOllamaClient(ollama)) {
|
|
@@ -45325,14 +46962,14 @@ function wrapCohere(cohere) {
|
|
|
45325
46962
|
return cohere;
|
|
45326
46963
|
}
|
|
45327
46964
|
var cohereProxyCache = /* @__PURE__ */ new WeakMap();
|
|
45328
|
-
function
|
|
46965
|
+
function isRecord6(value) {
|
|
45329
46966
|
return typeof value === "object" && value !== null;
|
|
45330
46967
|
}
|
|
45331
46968
|
function hasFunction4(value, methodName) {
|
|
45332
|
-
return
|
|
46969
|
+
return isRecord6(value) && methodName in value && typeof value[methodName] === "function";
|
|
45333
46970
|
}
|
|
45334
46971
|
function isSupportedCohereClient(value) {
|
|
45335
|
-
if (!
|
|
46972
|
+
if (!isRecord6(value)) {
|
|
45336
46973
|
return false;
|
|
45337
46974
|
}
|
|
45338
46975
|
return hasFunction4(value, "chat") || hasFunction4(value, "chatStream") || hasFunction4(value, "embed") || hasFunction4(value, "rerank");
|
|
@@ -45470,20 +47107,20 @@ function wrapGroq(groq) {
|
|
|
45470
47107
|
console.warn("Unsupported Groq library. Not wrapping.");
|
|
45471
47108
|
return groq;
|
|
45472
47109
|
}
|
|
45473
|
-
function
|
|
47110
|
+
function isRecord7(value) {
|
|
45474
47111
|
return typeof value === "object" && value !== null;
|
|
45475
47112
|
}
|
|
45476
47113
|
function hasFunction6(value, methodName) {
|
|
45477
|
-
return
|
|
47114
|
+
return isRecord7(value) && methodName in value && typeof value[methodName] === "function";
|
|
45478
47115
|
}
|
|
45479
47116
|
function hasChat2(value) {
|
|
45480
|
-
return
|
|
47117
|
+
return isRecord7(value) && isRecord7(value.completions) && hasFunction6(value.completions, "create");
|
|
45481
47118
|
}
|
|
45482
47119
|
function hasEmbeddings2(value) {
|
|
45483
47120
|
return hasFunction6(value, "create");
|
|
45484
47121
|
}
|
|
45485
47122
|
function isSupportedGroqClient(value) {
|
|
45486
|
-
return
|
|
47123
|
+
return isRecord7(value) && (value.chat !== void 0 && hasChat2(value.chat) || value.embeddings !== void 0 && hasEmbeddings2(value.embeddings));
|
|
45487
47124
|
}
|
|
45488
47125
|
function groqProxy(groq) {
|
|
45489
47126
|
const privateMethodWorkaroundCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -45566,11 +47203,11 @@ var BEDROCK_RUNTIME_OPERATION_METHODS = /* @__PURE__ */ new Set([
|
|
|
45566
47203
|
"invokeModelWithBidirectionalStream",
|
|
45567
47204
|
"invokeModelWithResponseStream"
|
|
45568
47205
|
]);
|
|
45569
|
-
function
|
|
47206
|
+
function isRecord8(value) {
|
|
45570
47207
|
return typeof value === "object" && value !== null;
|
|
45571
47208
|
}
|
|
45572
47209
|
function isSupportedBedrockRuntimeClient(value) {
|
|
45573
|
-
return
|
|
47210
|
+
return isRecord8(value) && typeof value.send === "function";
|
|
45574
47211
|
}
|
|
45575
47212
|
function bedrockRuntimeProxy(client) {
|
|
45576
47213
|
const cached = bedrockRuntimeProxyCache.get(client);
|
|
@@ -47896,12 +49533,272 @@ function waterfall(tasks, callback) {
|
|
|
47896
49533
|
}
|
|
47897
49534
|
var waterfall$1 = awaitify(waterfall);
|
|
47898
49535
|
|
|
49536
|
+
// src/framework.ts
|
|
49537
|
+
var import_uuid3 = require("uuid");
|
|
49538
|
+
|
|
47899
49539
|
// src/trace.ts
|
|
49540
|
+
var spanFilterFields = /* @__PURE__ */ new Set([
|
|
49541
|
+
"spanType",
|
|
49542
|
+
"name",
|
|
49543
|
+
"hasError",
|
|
49544
|
+
"metadata",
|
|
49545
|
+
"duration"
|
|
49546
|
+
]);
|
|
49547
|
+
function isRecord9(value) {
|
|
49548
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
49549
|
+
return false;
|
|
49550
|
+
}
|
|
49551
|
+
const prototype = Object.getPrototypeOf(value);
|
|
49552
|
+
return prototype === Object.prototype || prototype === null;
|
|
49553
|
+
}
|
|
49554
|
+
function validateMetadataValue(value, ancestors) {
|
|
49555
|
+
if (value === null || typeof value === "string" || typeof value === "boolean") {
|
|
49556
|
+
return;
|
|
49557
|
+
}
|
|
49558
|
+
if (typeof value === "number") {
|
|
49559
|
+
if (Number.isFinite(value)) {
|
|
49560
|
+
return;
|
|
49561
|
+
}
|
|
49562
|
+
throw new Error("filters.metadata numbers must be finite");
|
|
49563
|
+
}
|
|
49564
|
+
if (typeof value !== "object" || value === null) {
|
|
49565
|
+
throw new Error("filters.metadata values must be JSON-serializable");
|
|
49566
|
+
}
|
|
49567
|
+
if (!Array.isArray(value) && !isRecord9(value)) {
|
|
49568
|
+
throw new Error("filters.metadata values must be JSON-serializable");
|
|
49569
|
+
}
|
|
49570
|
+
if (ancestors.has(value)) {
|
|
49571
|
+
throw new Error("filters.metadata must not contain cycles");
|
|
49572
|
+
}
|
|
49573
|
+
ancestors.add(value);
|
|
49574
|
+
if (Array.isArray(value)) {
|
|
49575
|
+
for (let index = 0; index < value.length; index++) {
|
|
49576
|
+
validateMetadataValue(value[index], ancestors);
|
|
49577
|
+
}
|
|
49578
|
+
} else {
|
|
49579
|
+
if (Object.getOwnPropertySymbols(value).length > 0) {
|
|
49580
|
+
throw new Error("filters.metadata keys must be strings");
|
|
49581
|
+
}
|
|
49582
|
+
for (const nested of Object.values(value)) {
|
|
49583
|
+
validateMetadataValue(nested, ancestors);
|
|
49584
|
+
}
|
|
49585
|
+
}
|
|
49586
|
+
ancestors.delete(value);
|
|
49587
|
+
}
|
|
49588
|
+
function compileMetadataLeaves(metadata, path = [], ancestors = /* @__PURE__ */ new WeakSet()) {
|
|
49589
|
+
if (Object.getOwnPropertySymbols(metadata).length > 0) {
|
|
49590
|
+
throw new Error("filters.metadata keys must be strings");
|
|
49591
|
+
}
|
|
49592
|
+
if (ancestors.has(metadata)) {
|
|
49593
|
+
throw new Error("filters.metadata must not contain cycles");
|
|
49594
|
+
}
|
|
49595
|
+
ancestors.add(metadata);
|
|
49596
|
+
const leaves = [];
|
|
49597
|
+
for (const [key, value] of Object.entries(metadata)) {
|
|
49598
|
+
const childPath = [...path, key];
|
|
49599
|
+
if (isRecord9(value)) {
|
|
49600
|
+
leaves.push(...compileMetadataLeaves(value, childPath, ancestors));
|
|
49601
|
+
} else {
|
|
49602
|
+
validateMetadataValue(value, ancestors);
|
|
49603
|
+
leaves.push([childPath, value]);
|
|
49604
|
+
}
|
|
49605
|
+
}
|
|
49606
|
+
ancestors.delete(metadata);
|
|
49607
|
+
return leaves;
|
|
49608
|
+
}
|
|
49609
|
+
function normalizeSpanFilters(filters, spanType) {
|
|
49610
|
+
if (filters != null && !isRecord9(filters)) {
|
|
49611
|
+
throw new Error("filters must be an object");
|
|
49612
|
+
}
|
|
49613
|
+
const values = { ...filters ?? {} };
|
|
49614
|
+
if (spanType !== void 0) {
|
|
49615
|
+
if (!Array.isArray(spanType) || !spanType.every((item) => typeof item === "string")) {
|
|
49616
|
+
throw new Error("spanType must be an array of strings");
|
|
49617
|
+
}
|
|
49618
|
+
if (Object.hasOwn(values, "spanType")) {
|
|
49619
|
+
throw new Error(
|
|
49620
|
+
"spanType cannot be provided both directly and in filters"
|
|
49621
|
+
);
|
|
49622
|
+
}
|
|
49623
|
+
if (spanType.length > 0) {
|
|
49624
|
+
values.spanType = spanType;
|
|
49625
|
+
}
|
|
49626
|
+
}
|
|
49627
|
+
if (Object.keys(values).some((field) => !spanFilterFields.has(field))) {
|
|
49628
|
+
throw new Error("Unsupported span filter fields");
|
|
49629
|
+
}
|
|
49630
|
+
for (const field of ["spanType", "name"]) {
|
|
49631
|
+
if (Object.hasOwn(values, field)) {
|
|
49632
|
+
const items = values[field];
|
|
49633
|
+
if (!Array.isArray(items) || !items.every((item) => typeof item === "string")) {
|
|
49634
|
+
throw new Error(`filters.${field} must be an array of strings`);
|
|
49635
|
+
}
|
|
49636
|
+
}
|
|
49637
|
+
}
|
|
49638
|
+
if (Object.hasOwn(values, "hasError") && typeof values.hasError !== "boolean") {
|
|
49639
|
+
throw new Error("filters.hasError must be a boolean");
|
|
49640
|
+
}
|
|
49641
|
+
let compiledMetadataLeaves = [];
|
|
49642
|
+
if (Object.hasOwn(values, "metadata")) {
|
|
49643
|
+
if (!isRecord9(values.metadata)) {
|
|
49644
|
+
throw new Error("filters.metadata must be an object");
|
|
49645
|
+
}
|
|
49646
|
+
compiledMetadataLeaves = compileMetadataLeaves(values.metadata);
|
|
49647
|
+
}
|
|
49648
|
+
if (Object.hasOwn(values, "duration")) {
|
|
49649
|
+
if (!isRecord9(values.duration) || Object.keys(values.duration).some(
|
|
49650
|
+
(bound) => bound !== "min" && bound !== "max"
|
|
49651
|
+
)) {
|
|
49652
|
+
throw new Error("filters.duration must contain only min and/or max");
|
|
49653
|
+
}
|
|
49654
|
+
if (Object.values(values.duration).some(
|
|
49655
|
+
(bound) => typeof bound !== "number" || !Number.isFinite(bound)
|
|
49656
|
+
)) {
|
|
49657
|
+
throw new Error("filters.duration bounds must be finite numbers");
|
|
49658
|
+
}
|
|
49659
|
+
}
|
|
49660
|
+
const normalized = {};
|
|
49661
|
+
if (Array.isArray(values.spanType)) {
|
|
49662
|
+
normalized.spanType = values.spanType;
|
|
49663
|
+
}
|
|
49664
|
+
if (Array.isArray(values.name)) {
|
|
49665
|
+
normalized.name = values.name;
|
|
49666
|
+
}
|
|
49667
|
+
if (typeof values.hasError === "boolean") {
|
|
49668
|
+
normalized.hasError = values.hasError;
|
|
49669
|
+
}
|
|
49670
|
+
if (isRecord9(values.metadata)) {
|
|
49671
|
+
normalized.metadata = values.metadata;
|
|
49672
|
+
}
|
|
49673
|
+
if (isRecord9(values.duration)) {
|
|
49674
|
+
normalized.duration = {};
|
|
49675
|
+
if (typeof values.duration.min === "number") {
|
|
49676
|
+
normalized.duration.min = values.duration.min;
|
|
49677
|
+
}
|
|
49678
|
+
if (typeof values.duration.max === "number") {
|
|
49679
|
+
normalized.duration.max = values.duration.max;
|
|
49680
|
+
}
|
|
49681
|
+
}
|
|
49682
|
+
return { filters: normalized, metadataLeaves: compiledMetadataLeaves };
|
|
49683
|
+
}
|
|
49684
|
+
function metadataEqual(actual, expected) {
|
|
49685
|
+
if (expected === null) {
|
|
49686
|
+
return actual === null || actual === void 0;
|
|
49687
|
+
}
|
|
49688
|
+
if (Array.isArray(expected)) {
|
|
49689
|
+
return Array.isArray(actual) && actual.length === expected.length && expected.every((value, index) => metadataEqual(actual[index], value));
|
|
49690
|
+
}
|
|
49691
|
+
if (isRecord9(expected)) {
|
|
49692
|
+
if (!isRecord9(actual)) {
|
|
49693
|
+
return false;
|
|
49694
|
+
}
|
|
49695
|
+
const expectedKeys = Object.keys(expected);
|
|
49696
|
+
const actualKeys = Object.keys(actual);
|
|
49697
|
+
return actualKeys.length === expectedKeys.length && expectedKeys.every(
|
|
49698
|
+
(key) => Object.hasOwn(actual, key) && metadataEqual(actual[key], expected[key])
|
|
49699
|
+
);
|
|
49700
|
+
}
|
|
49701
|
+
return actual === expected;
|
|
49702
|
+
}
|
|
49703
|
+
function matchesSpanFilters(span, compiledFilters) {
|
|
49704
|
+
const { filters, metadataLeaves } = compiledFilters;
|
|
49705
|
+
if (filters.spanType !== void 0 && !filters.spanType.includes(span.span_attributes?.type ?? "")) {
|
|
49706
|
+
return false;
|
|
49707
|
+
}
|
|
49708
|
+
if (filters.name !== void 0 && !filters.name.includes(span.span_attributes?.name ?? "")) {
|
|
49709
|
+
return false;
|
|
49710
|
+
}
|
|
49711
|
+
if (filters.hasError !== void 0 && (span.error !== null && span.error !== void 0) !== filters.hasError) {
|
|
49712
|
+
return false;
|
|
49713
|
+
}
|
|
49714
|
+
for (const [path, expected] of metadataLeaves) {
|
|
49715
|
+
let actual = span.metadata;
|
|
49716
|
+
for (const key of path) {
|
|
49717
|
+
actual = isRecord9(actual) && Object.hasOwn(actual, key) ? actual[key] : void 0;
|
|
49718
|
+
}
|
|
49719
|
+
if (!metadataEqual(actual, expected)) {
|
|
49720
|
+
return false;
|
|
49721
|
+
}
|
|
49722
|
+
}
|
|
49723
|
+
if (filters.duration && Object.keys(filters.duration).length > 0) {
|
|
49724
|
+
const metrics = span.metrics;
|
|
49725
|
+
const start = isRecord9(metrics) ? metrics.start : void 0;
|
|
49726
|
+
const end = isRecord9(metrics) ? metrics.end : void 0;
|
|
49727
|
+
if (typeof start !== "number" || !Number.isFinite(start) || typeof end !== "number" || !Number.isFinite(end)) {
|
|
49728
|
+
return false;
|
|
49729
|
+
}
|
|
49730
|
+
const elapsed = end - start;
|
|
49731
|
+
if (filters.duration.min !== void 0 && elapsed < filters.duration.min) {
|
|
49732
|
+
return false;
|
|
49733
|
+
}
|
|
49734
|
+
if (filters.duration.max !== void 0 && elapsed > filters.duration.max) {
|
|
49735
|
+
return false;
|
|
49736
|
+
}
|
|
49737
|
+
}
|
|
49738
|
+
return true;
|
|
49739
|
+
}
|
|
49740
|
+
function btqlComparison(op, name, value) {
|
|
49741
|
+
return {
|
|
49742
|
+
op,
|
|
49743
|
+
left: { op: "ident", name },
|
|
49744
|
+
right: { op: "literal", value }
|
|
49745
|
+
};
|
|
49746
|
+
}
|
|
49747
|
+
function btqlNullCheck(op, name) {
|
|
49748
|
+
return { op, expr: { op: "ident", name } };
|
|
49749
|
+
}
|
|
49750
|
+
function spanFilterClauses(compiledFilters) {
|
|
49751
|
+
const { filters, metadataLeaves } = compiledFilters;
|
|
49752
|
+
const children = [];
|
|
49753
|
+
for (const [field, attribute] of [
|
|
49754
|
+
["spanType", "type"],
|
|
49755
|
+
["name", "name"]
|
|
49756
|
+
]) {
|
|
49757
|
+
const values = filters[field];
|
|
49758
|
+
if (values !== void 0) {
|
|
49759
|
+
children.push(
|
|
49760
|
+
values.length > 0 ? btqlComparison("in", ["span_attributes", attribute], values) : { op: "literal", value: false }
|
|
49761
|
+
);
|
|
49762
|
+
}
|
|
49763
|
+
}
|
|
49764
|
+
if (filters.hasError !== void 0) {
|
|
49765
|
+
children.push(
|
|
49766
|
+
btqlNullCheck(filters.hasError ? "isnotnull" : "isnull", ["error"])
|
|
49767
|
+
);
|
|
49768
|
+
}
|
|
49769
|
+
for (const [path, value] of metadataLeaves) {
|
|
49770
|
+
const name = ["metadata", ...path];
|
|
49771
|
+
children.push(
|
|
49772
|
+
value === null ? btqlNullCheck("isnull", name) : btqlComparison("eq", name, value)
|
|
49773
|
+
);
|
|
49774
|
+
}
|
|
49775
|
+
const elapsed = {
|
|
49776
|
+
op: "sub",
|
|
49777
|
+
left: { op: "ident", name: ["metrics", "end"] },
|
|
49778
|
+
right: { op: "ident", name: ["metrics", "start"] }
|
|
49779
|
+
};
|
|
49780
|
+
if (filters.duration?.min !== void 0) {
|
|
49781
|
+
children.push({
|
|
49782
|
+
op: "ge",
|
|
49783
|
+
left: elapsed,
|
|
49784
|
+
right: { op: "literal", value: filters.duration.min }
|
|
49785
|
+
});
|
|
49786
|
+
}
|
|
49787
|
+
if (filters.duration?.max !== void 0) {
|
|
49788
|
+
children.push({
|
|
49789
|
+
op: "le",
|
|
49790
|
+
left: elapsed,
|
|
49791
|
+
right: { op: "literal", value: filters.duration.max }
|
|
49792
|
+
});
|
|
49793
|
+
}
|
|
49794
|
+
return children;
|
|
49795
|
+
}
|
|
47900
49796
|
var SpanFetcher = class _SpanFetcher extends ObjectFetcher {
|
|
47901
|
-
constructor(objectType, _objectId, rootSpanId, _state, spanTypeFilter, includeScorers = false, brainstoreRealtime = true) {
|
|
49797
|
+
constructor(objectType, _objectId, rootSpanId, _state, spanTypeFilter, includeScorers = false, brainstoreRealtime = true, filters) {
|
|
49798
|
+
const normalizedFilters = normalizeSpanFilters(filters, spanTypeFilter);
|
|
47902
49799
|
const filterExpr = _SpanFetcher.buildFilter(
|
|
47903
49800
|
rootSpanId,
|
|
47904
|
-
|
|
49801
|
+
normalizedFilters,
|
|
47905
49802
|
includeScorers
|
|
47906
49803
|
);
|
|
47907
49804
|
super(
|
|
@@ -47922,42 +49819,22 @@ var SpanFetcher = class _SpanFetcher extends ObjectFetcher {
|
|
|
47922
49819
|
rootSpanId;
|
|
47923
49820
|
_state;
|
|
47924
49821
|
spanTypeFilter;
|
|
47925
|
-
static buildFilter(rootSpanId,
|
|
49822
|
+
static buildFilter(rootSpanId, filters, includeScorers = false) {
|
|
49823
|
+
const purpose = ["span_attributes", "purpose"];
|
|
47926
49824
|
const children = [
|
|
47927
|
-
|
|
47928
|
-
{
|
|
47929
|
-
op: "eq",
|
|
47930
|
-
left: { op: "ident", name: ["root_span_id"] },
|
|
47931
|
-
right: { op: "literal", value: rootSpanId }
|
|
47932
|
-
}
|
|
49825
|
+
btqlComparison("eq", ["root_span_id"], rootSpanId)
|
|
47933
49826
|
];
|
|
47934
49827
|
if (!includeScorers) {
|
|
47935
49828
|
children.push({
|
|
47936
49829
|
op: "or",
|
|
47937
49830
|
children: [
|
|
47938
|
-
|
|
47939
|
-
|
|
47940
|
-
expr: { op: "ident", name: ["span_attributes", "purpose"] }
|
|
47941
|
-
},
|
|
47942
|
-
{
|
|
47943
|
-
op: "ne",
|
|
47944
|
-
left: { op: "ident", name: ["span_attributes", "purpose"] },
|
|
47945
|
-
right: { op: "literal", value: "scorer" }
|
|
47946
|
-
}
|
|
49831
|
+
btqlNullCheck("isnull", purpose),
|
|
49832
|
+
btqlComparison("ne", purpose, "scorer")
|
|
47947
49833
|
]
|
|
47948
49834
|
});
|
|
47949
49835
|
}
|
|
47950
|
-
|
|
47951
|
-
|
|
47952
|
-
op: "in",
|
|
47953
|
-
left: { op: "ident", name: ["span_attributes", "type"] },
|
|
47954
|
-
right: { op: "literal", value: spanTypeFilter }
|
|
47955
|
-
});
|
|
47956
|
-
}
|
|
47957
|
-
return {
|
|
47958
|
-
op: "and",
|
|
47959
|
-
children
|
|
47960
|
-
};
|
|
49836
|
+
children.push(...spanFilterClauses(filters));
|
|
49837
|
+
return { op: "and", children };
|
|
47961
49838
|
}
|
|
47962
49839
|
get id() {
|
|
47963
49840
|
return Promise.resolve(this._objectId);
|
|
@@ -47972,67 +49849,80 @@ var CachedSpanFetcher = class {
|
|
|
47972
49849
|
fetchFn;
|
|
47973
49850
|
constructor(objectTypeOrFetchFn, objectId, rootSpanId, getState, brainstoreRealtime = true) {
|
|
47974
49851
|
if (typeof objectTypeOrFetchFn === "function") {
|
|
47975
|
-
this.fetchFn = (
|
|
49852
|
+
this.fetchFn = async (filters) => (await objectTypeOrFetchFn(filters.filters.spanType)).filter(
|
|
49853
|
+
(span) => matchesSpanFilters(span, filters)
|
|
49854
|
+
);
|
|
47976
49855
|
} else {
|
|
47977
49856
|
const objectType = objectTypeOrFetchFn;
|
|
47978
|
-
this.fetchFn = async (
|
|
49857
|
+
this.fetchFn = async (filters, includeScorers) => {
|
|
47979
49858
|
const state = await getState();
|
|
47980
49859
|
const fetcher = new SpanFetcher(
|
|
47981
49860
|
objectType,
|
|
47982
49861
|
objectId,
|
|
47983
49862
|
rootSpanId,
|
|
47984
49863
|
state,
|
|
47985
|
-
|
|
49864
|
+
void 0,
|
|
47986
49865
|
includeScorers,
|
|
47987
|
-
brainstoreRealtime
|
|
49866
|
+
brainstoreRealtime,
|
|
49867
|
+
filters.filters
|
|
47988
49868
|
);
|
|
47989
|
-
|
|
47990
|
-
|
|
47991
|
-
|
|
47992
|
-
|
|
47993
|
-
|
|
47994
|
-
|
|
47995
|
-
|
|
47996
|
-
metrics: row.metrics,
|
|
47997
|
-
metadata: row.metadata,
|
|
47998
|
-
span_id: row.span_id,
|
|
47999
|
-
span_parents: row.span_parents,
|
|
48000
|
-
is_root: row.is_root,
|
|
48001
|
-
span_attributes: row.span_attributes,
|
|
48002
|
-
id: row.id,
|
|
48003
|
-
_xact_id: row._xact_id,
|
|
48004
|
-
_pagination_key: row._pagination_key,
|
|
48005
|
-
root_span_id: row.root_span_id,
|
|
48006
|
-
created: row.created,
|
|
48007
|
-
tags: row.tags
|
|
48008
|
-
}));
|
|
49869
|
+
let spans = (await fetcher.fetchedData()).map(
|
|
49870
|
+
(row) => ({ ...row })
|
|
49871
|
+
);
|
|
49872
|
+
if (filters.filters.metadata !== void 0) {
|
|
49873
|
+
spans = spans.filter((span) => matchesSpanFilters(span, filters));
|
|
49874
|
+
}
|
|
49875
|
+
return spans;
|
|
48009
49876
|
};
|
|
48010
49877
|
}
|
|
48011
49878
|
}
|
|
48012
49879
|
async getSpans({
|
|
48013
|
-
spanType,
|
|
49880
|
+
spanType: requestedSpanType,
|
|
49881
|
+
filters,
|
|
48014
49882
|
includeScorers = false
|
|
48015
49883
|
} = {}) {
|
|
49884
|
+
const normalizedFilters = normalizeSpanFilters(filters, requestedSpanType);
|
|
49885
|
+
const spanType = normalizedFilters.filters.spanType;
|
|
49886
|
+
const hasAdvancedFilters = Object.keys(normalizedFilters.filters).some(
|
|
49887
|
+
(field) => field !== "spanType"
|
|
49888
|
+
);
|
|
49889
|
+
if (spanType?.length === 0) {
|
|
49890
|
+
return [];
|
|
49891
|
+
}
|
|
48016
49892
|
if (includeScorers) {
|
|
48017
|
-
return this.fetchFn(
|
|
49893
|
+
return this.fetchFn(normalizedFilters, true);
|
|
48018
49894
|
}
|
|
48019
49895
|
if (this.allFetched) {
|
|
48020
|
-
|
|
49896
|
+
const spans = this.getFromCache(spanType);
|
|
49897
|
+
return hasAdvancedFilters ? spans.filter((span) => matchesSpanFilters(span, normalizedFilters)) : spans;
|
|
48021
49898
|
}
|
|
48022
|
-
if (
|
|
49899
|
+
if (hasAdvancedFilters && spanType && spanType.every((type) => this.spanCache.has(type))) {
|
|
49900
|
+
return this.getFromCache(spanType).filter(
|
|
49901
|
+
(span) => matchesSpanFilters(span, normalizedFilters)
|
|
49902
|
+
);
|
|
49903
|
+
}
|
|
49904
|
+
if (hasAdvancedFilters) {
|
|
49905
|
+
return this.fetchFn(normalizedFilters, false);
|
|
49906
|
+
}
|
|
49907
|
+
if (!spanType) {
|
|
49908
|
+
this.spanCache.clear();
|
|
48023
49909
|
await this.fetchSpans(void 0);
|
|
48024
|
-
this.
|
|
49910
|
+
if (this.spanCache.size > 0) {
|
|
49911
|
+
this.allFetched = true;
|
|
49912
|
+
}
|
|
48025
49913
|
return this.getFromCache(void 0);
|
|
48026
49914
|
}
|
|
48027
|
-
const missingTypes = spanType.filter((
|
|
48028
|
-
if (missingTypes.length
|
|
48029
|
-
|
|
49915
|
+
const missingTypes = spanType.filter((type) => !this.spanCache.has(type));
|
|
49916
|
+
if (missingTypes.length > 0) {
|
|
49917
|
+
await this.fetchSpans(missingTypes);
|
|
48030
49918
|
}
|
|
48031
|
-
await this.fetchSpans(missingTypes);
|
|
48032
49919
|
return this.getFromCache(spanType);
|
|
48033
49920
|
}
|
|
48034
49921
|
async fetchSpans(spanType) {
|
|
48035
|
-
const spans = await this.fetchFn(
|
|
49922
|
+
const spans = await this.fetchFn(
|
|
49923
|
+
normalizeSpanFilters(spanType ? { spanType } : void 0),
|
|
49924
|
+
false
|
|
49925
|
+
);
|
|
48036
49926
|
for (const span of spans) {
|
|
48037
49927
|
const type = span.span_attributes?.type ?? "";
|
|
48038
49928
|
const existing = this.spanCache.get(type) ?? [];
|
|
@@ -48112,34 +50002,20 @@ var LocalTrace = class {
|
|
|
48112
50002
|
*/
|
|
48113
50003
|
async getSpans({
|
|
48114
50004
|
spanType,
|
|
50005
|
+
filters,
|
|
48115
50006
|
includeScorers = false
|
|
48116
50007
|
} = {}) {
|
|
50008
|
+
const normalizedFilters = normalizeSpanFilters(filters, spanType);
|
|
48117
50009
|
const cachedSpans = this.state.spanCache.getByRootSpanId(this.rootSpanId);
|
|
48118
50010
|
if (cachedSpans && cachedSpans.length > 0) {
|
|
48119
|
-
|
|
48120
|
-
(span) => span.span_attributes?.purpose !== "scorer"
|
|
48121
|
-
);
|
|
48122
|
-
|
|
48123
|
-
|
|
48124
|
-
|
|
48125
|
-
|
|
48126
|
-
|
|
48127
|
-
return spans.map((span) => ({
|
|
48128
|
-
input: span.input,
|
|
48129
|
-
output: span.output,
|
|
48130
|
-
expected: span.expected,
|
|
48131
|
-
error: span.error,
|
|
48132
|
-
scores: span.scores,
|
|
48133
|
-
metrics: span.metrics,
|
|
48134
|
-
metadata: span.metadata,
|
|
48135
|
-
span_id: span.span_id,
|
|
48136
|
-
span_parents: span.span_parents,
|
|
48137
|
-
is_root: span.is_root,
|
|
48138
|
-
span_attributes: span.span_attributes,
|
|
48139
|
-
tags: span.tags
|
|
48140
|
-
}));
|
|
48141
|
-
}
|
|
48142
|
-
return this.cachedFetcher.getSpans({ spanType, includeScorers });
|
|
50011
|
+
return cachedSpans.filter(
|
|
50012
|
+
(span) => (includeScorers || span.span_attributes?.purpose !== "scorer") && matchesSpanFilters({ ...span }, normalizedFilters)
|
|
50013
|
+
).map((span) => ({ ...span }));
|
|
50014
|
+
}
|
|
50015
|
+
return this.cachedFetcher.getSpans({
|
|
50016
|
+
filters: normalizedFilters.filters,
|
|
50017
|
+
includeScorers
|
|
50018
|
+
});
|
|
48143
50019
|
}
|
|
48144
50020
|
/**
|
|
48145
50021
|
* Get the thread (preprocessed messages) for this trace.
|
|
@@ -48559,7 +50435,7 @@ async function Eval(name, evaluator, reporterOrOpts) {
|
|
|
48559
50435
|
data,
|
|
48560
50436
|
{ disabled: Boolean(options.parent || options.noSendLogs) }
|
|
48561
50437
|
);
|
|
48562
|
-
if (experiment
|
|
50438
|
+
if (experiment) {
|
|
48563
50439
|
await experiment._waitForId();
|
|
48564
50440
|
}
|
|
48565
50441
|
if (experiment && options.onStart) {
|
|
@@ -48884,6 +50760,10 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
48884
50760
|
} : void 0;
|
|
48885
50761
|
const parsedDatumOrigin = ObjectReference.safeParse(datum.origin);
|
|
48886
50762
|
const origin = inlineDatasetOrigin ?? (parsedDatumOrigin?.success ? parsedDatumOrigin.data : void 0);
|
|
50763
|
+
const upsertId = datum.upsert_id && trialIndex > 0 ? (0, import_uuid3.v5)(
|
|
50764
|
+
`braintrust:eval:${datum.upsert_id}:trial:${trialIndex}`,
|
|
50765
|
+
import_uuid3.v5.URL
|
|
50766
|
+
) : datum.upsert_id;
|
|
48887
50767
|
const baseEvent = {
|
|
48888
50768
|
name: "eval",
|
|
48889
50769
|
spanAttributes: {
|
|
@@ -48894,7 +50774,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
48894
50774
|
expected: "expected" in datum ? datum.expected : void 0,
|
|
48895
50775
|
tags: datum.tags,
|
|
48896
50776
|
origin,
|
|
48897
|
-
...
|
|
50777
|
+
...upsertId ? { id: upsertId } : {}
|
|
48898
50778
|
}
|
|
48899
50779
|
};
|
|
48900
50780
|
const callback = async (rootSpan) => {
|
|
@@ -49403,14 +51283,14 @@ var defaultReporter = {
|
|
|
49403
51283
|
}
|
|
49404
51284
|
};
|
|
49405
51285
|
|
|
49406
|
-
// src/
|
|
51286
|
+
// src/workflow-eval.ts
|
|
49407
51287
|
var encoder = new TextEncoder();
|
|
49408
51288
|
var decoder = new TextDecoder();
|
|
49409
|
-
var
|
|
49410
|
-
var
|
|
49411
|
-
var
|
|
49412
|
-
var DurableEvalMemoryStore = class {
|
|
51289
|
+
var WORKFLOW_TASK_KIND = "braintrust.workflow.task";
|
|
51290
|
+
var WORKFLOW_SCORER_KIND = "braintrust.workflow.scorer";
|
|
51291
|
+
var WorkflowEvalMemoryStore = class {
|
|
49413
51292
|
values = /* @__PURE__ */ new Map();
|
|
51293
|
+
sets = /* @__PURE__ */ new Map();
|
|
49414
51294
|
async read(key) {
|
|
49415
51295
|
return this.values.get(key)?.slice();
|
|
49416
51296
|
}
|
|
@@ -49423,8 +51303,16 @@ var DurableEvalMemoryStore = class {
|
|
|
49423
51303
|
this.values.set(key, value.slice());
|
|
49424
51304
|
return { value: value.slice(), created: true };
|
|
49425
51305
|
}
|
|
51306
|
+
async addToSet(key, member) {
|
|
51307
|
+
let members = this.sets.get(key);
|
|
51308
|
+
if (!members) this.sets.set(key, members = /* @__PURE__ */ new Set());
|
|
51309
|
+
members.add(member);
|
|
51310
|
+
}
|
|
51311
|
+
async getSetSize(key) {
|
|
51312
|
+
return this.sets.get(key)?.size ?? 0;
|
|
51313
|
+
}
|
|
49426
51314
|
};
|
|
49427
|
-
var
|
|
51315
|
+
var WorkflowEvalRedisStore = class {
|
|
49428
51316
|
client;
|
|
49429
51317
|
keyPrefix;
|
|
49430
51318
|
ttlMs;
|
|
@@ -49433,14 +51321,16 @@ var DurableEvalRedisStore = class {
|
|
|
49433
51321
|
this.keyPrefix = options.keyPrefix ?? "braintrust-eval:";
|
|
49434
51322
|
this.ttlMs = options.ttlMs ?? 1e3 * 60 * 60 * 24 * 7;
|
|
49435
51323
|
if (!Number.isInteger(this.ttlMs) || this.ttlMs < 1) {
|
|
49436
|
-
throw new Error(
|
|
51324
|
+
throw new Error(
|
|
51325
|
+
"WorkflowEvalRedisStore ttlMs must be a positive integer"
|
|
51326
|
+
);
|
|
49437
51327
|
}
|
|
49438
51328
|
}
|
|
49439
51329
|
async read(key) {
|
|
49440
51330
|
const value = await this.client.get(`${this.keyPrefix}${key}`);
|
|
49441
51331
|
if (value == null) return void 0;
|
|
49442
51332
|
if (typeof value !== "string") {
|
|
49443
|
-
throw new Error("
|
|
51333
|
+
throw new Error("WorkflowEvalRedisStore expected GET to return a string");
|
|
49444
51334
|
}
|
|
49445
51335
|
return base64ToUint8Array(value);
|
|
49446
51336
|
}
|
|
@@ -49457,7 +51347,7 @@ var DurableEvalRedisStore = class {
|
|
|
49457
51347
|
await set.call(client, redisKey, encoded, { px: this.ttlMs });
|
|
49458
51348
|
} else {
|
|
49459
51349
|
throw new Error(
|
|
49460
|
-
"
|
|
51350
|
+
"WorkflowEvalRedisStore requires a node-redis, ioredis, or @upstash/redis client"
|
|
49461
51351
|
);
|
|
49462
51352
|
}
|
|
49463
51353
|
}
|
|
@@ -49475,49 +51365,73 @@ var DurableEvalRedisStore = class {
|
|
|
49475
51365
|
setOptions = [{ px: this.ttlMs, nx: true, get: true }];
|
|
49476
51366
|
} else {
|
|
49477
51367
|
throw new Error(
|
|
49478
|
-
"
|
|
51368
|
+
"WorkflowEvalRedisStore getOrSet requires a node-redis, ioredis, or @upstash/redis client"
|
|
49479
51369
|
);
|
|
49480
51370
|
}
|
|
49481
51371
|
const existing = await set.call(client, redisKey, encoded, ...setOptions);
|
|
49482
51372
|
if (existing === null) return { value: value.slice(), created: true };
|
|
49483
51373
|
if (typeof existing !== "string") {
|
|
49484
51374
|
throw new Error(
|
|
49485
|
-
"
|
|
51375
|
+
"WorkflowEvalRedisStore expected atomic SET to return a string or null"
|
|
49486
51376
|
);
|
|
49487
51377
|
}
|
|
49488
51378
|
return { value: base64ToUint8Array(existing), created: false };
|
|
49489
51379
|
}
|
|
51380
|
+
async addToSet(key, member) {
|
|
51381
|
+
await this.evalSet(
|
|
51382
|
+
"redis.call('SADD', KEYS[1], ARGV[1]); redis.call('PEXPIRE', KEYS[1], ARGV[2]); return 1",
|
|
51383
|
+
key,
|
|
51384
|
+
[member, String(this.ttlMs)]
|
|
51385
|
+
);
|
|
51386
|
+
}
|
|
51387
|
+
async getSetSize(key) {
|
|
51388
|
+
return this.evalSet("return redis.call('SCARD', KEYS[1])", key, []);
|
|
51389
|
+
}
|
|
51390
|
+
async evalSet(script, key, args) {
|
|
51391
|
+
const client = this.client;
|
|
51392
|
+
const redisKey = `${this.keyPrefix}${key}`;
|
|
51393
|
+
const result = typeof client.defineCommand === "function" ? await client.eval(script, 1, redisKey, ...args) : typeof client.sendCommand === "function" ? await client.eval(script, { keys: [redisKey], arguments: args }) : await client.eval(script, [redisKey], args);
|
|
51394
|
+
if (typeof result !== "number") {
|
|
51395
|
+
throw new Error(
|
|
51396
|
+
"WorkflowEvalRedisStore expected EVAL to return a number"
|
|
51397
|
+
);
|
|
51398
|
+
}
|
|
51399
|
+
return result;
|
|
51400
|
+
}
|
|
49490
51401
|
};
|
|
49491
|
-
var
|
|
51402
|
+
var WorkflowTask = class {
|
|
49492
51403
|
constructor(processor) {
|
|
49493
51404
|
this.processor = processor;
|
|
49494
51405
|
}
|
|
49495
51406
|
processor;
|
|
49496
|
-
kind =
|
|
51407
|
+
kind = WORKFLOW_TASK_KIND;
|
|
49497
51408
|
};
|
|
49498
|
-
var
|
|
51409
|
+
var WorkflowScorer = class {
|
|
49499
51410
|
constructor(processor) {
|
|
49500
51411
|
this.processor = processor;
|
|
49501
51412
|
this.name = processor.name;
|
|
49502
51413
|
}
|
|
49503
51414
|
processor;
|
|
49504
|
-
kind =
|
|
51415
|
+
kind = WORKFLOW_SCORER_KIND;
|
|
49505
51416
|
name;
|
|
49506
51417
|
};
|
|
49507
|
-
function
|
|
51418
|
+
function defineWorkflowEval(projectName, evaluator) {
|
|
51419
|
+
if (evaluator.maxConcurrency !== void 0 && (!Number.isInteger(evaluator.maxConcurrency) || evaluator.maxConcurrency < 1)) {
|
|
51420
|
+
throw new Error("maxConcurrency must be a positive integer");
|
|
51421
|
+
}
|
|
49508
51422
|
const definition = {
|
|
49509
51423
|
projectName,
|
|
49510
51424
|
evalName: evaluator.experimentName ?? projectName,
|
|
49511
51425
|
evaluator
|
|
49512
51426
|
};
|
|
49513
51427
|
return {
|
|
49514
|
-
start: (options = {}) =>
|
|
49515
|
-
status: (options) =>
|
|
49516
|
-
poll: (options) =>
|
|
49517
|
-
|
|
51428
|
+
start: (options = {}) => startWorkflowEval(definition, options),
|
|
51429
|
+
status: (options) => getWorkflowEvalStatus(definition, options),
|
|
51430
|
+
poll: (options) => pollWorkflowEval(definition, options),
|
|
51431
|
+
processSubmissionResult: (result) => processWorkflowSubmissionResult(definition, result)
|
|
49518
51432
|
};
|
|
49519
51433
|
}
|
|
49520
|
-
async function
|
|
51434
|
+
async function startWorkflowEval(definition, options) {
|
|
49521
51435
|
const store = definition.evaluator.store;
|
|
49522
51436
|
const runId = newId();
|
|
49523
51437
|
const key = runKey(definition.projectName, definition.evalName, runId);
|
|
@@ -49537,7 +51451,7 @@ async function startDurableEval(definition, options) {
|
|
|
49537
51451
|
update: true
|
|
49538
51452
|
}
|
|
49539
51453
|
);
|
|
49540
|
-
if (!
|
|
51454
|
+
if (!isWorkflowTask(definition.evaluator.task) && !(definition.evaluator.scores ?? []).some(isWorkflowScorer)) {
|
|
49541
51455
|
const result = await runEvaluator(
|
|
49542
51456
|
experiment,
|
|
49543
51457
|
{
|
|
@@ -49564,67 +51478,91 @@ async function startDurableEval(definition, options) {
|
|
|
49564
51478
|
parameters: assertJsonValue(parameters, "eval parameters"),
|
|
49565
51479
|
status: "completed",
|
|
49566
51480
|
summary: result.summary,
|
|
51481
|
+
caseCount: 0,
|
|
49567
51482
|
cases: [],
|
|
49568
|
-
|
|
51483
|
+
submissions: []
|
|
49569
51484
|
};
|
|
49570
51485
|
await experiment?.flush();
|
|
49571
51486
|
await writeRunRecord(store, key, state2);
|
|
49572
51487
|
return currentStatus(definition, state2);
|
|
49573
51488
|
}
|
|
51489
|
+
const cases = await materializeCases(definition, data, experiment);
|
|
49574
51490
|
const state = {
|
|
49575
51491
|
runId,
|
|
49576
51492
|
experimentName,
|
|
49577
51493
|
noSendLogs: options.noSendLogs ?? false,
|
|
49578
51494
|
parameters: assertJsonValue(parameters, "eval parameters"),
|
|
49579
51495
|
status: "running",
|
|
49580
|
-
|
|
49581
|
-
|
|
51496
|
+
caseCount: cases.length,
|
|
51497
|
+
cases,
|
|
51498
|
+
submissions: []
|
|
49582
51499
|
};
|
|
51500
|
+
await writeJson(
|
|
51501
|
+
store,
|
|
51502
|
+
`${key}/case-ids`,
|
|
51503
|
+
cases.map(({ id }) => id)
|
|
51504
|
+
);
|
|
49583
51505
|
await writeCaseBaseRecords(store, key, state.cases);
|
|
49584
51506
|
await writeRunRecord(store, key, state);
|
|
49585
|
-
return
|
|
51507
|
+
return advanceWorkflowEval(definition, state, store, key, experiment);
|
|
49586
51508
|
}
|
|
49587
|
-
async function
|
|
51509
|
+
async function getWorkflowEvalStatus(definition, options) {
|
|
49588
51510
|
const store = definition.evaluator.store;
|
|
49589
|
-
const
|
|
49590
|
-
definition,
|
|
49591
|
-
|
|
49592
|
-
|
|
51511
|
+
const key = runKey(
|
|
51512
|
+
definition.projectName,
|
|
51513
|
+
definition.evalName,
|
|
51514
|
+
options.runId
|
|
49593
51515
|
);
|
|
49594
|
-
|
|
51516
|
+
const state = await readJson(store, key);
|
|
51517
|
+
if (!state) throw new Error(`Workflow eval run ${options.runId} is missing`);
|
|
49595
51518
|
return currentStatus(definition, state);
|
|
49596
51519
|
}
|
|
49597
|
-
async function
|
|
49598
|
-
if (!result.
|
|
49599
|
-
throw new Error("
|
|
51520
|
+
async function processWorkflowSubmissionResult(definition, result) {
|
|
51521
|
+
if (!result.submissionId && !result.externalId) {
|
|
51522
|
+
throw new Error("Submission results require submissionId or externalId");
|
|
49600
51523
|
}
|
|
49601
51524
|
const store = definition.evaluator.store;
|
|
49602
51525
|
const key = runKey(definition.projectName, definition.evalName, result.runId);
|
|
49603
|
-
const
|
|
49604
|
-
if (!
|
|
49605
|
-
const
|
|
49606
|
-
|
|
49607
|
-
(
|
|
51526
|
+
const run = await readJson(store, key);
|
|
51527
|
+
if (!run) throw new Error(`Workflow eval run ${result.runId} is missing`);
|
|
51528
|
+
const externalSubmissionId = result.externalId ? await readJson(
|
|
51529
|
+
store,
|
|
51530
|
+
`${key}/external/${encodedKeyPart(result.externalId)}`
|
|
51531
|
+
) : void 0;
|
|
51532
|
+
if (result.submissionId && externalSubmissionId && result.submissionId !== externalSubmissionId) {
|
|
51533
|
+
throw new Error(
|
|
51534
|
+
"submissionId and externalId identify different submissions"
|
|
51535
|
+
);
|
|
51536
|
+
}
|
|
51537
|
+
const submissionId = result.submissionId ?? externalSubmissionId;
|
|
51538
|
+
const submission = submissionId ? await readJson(
|
|
51539
|
+
store,
|
|
51540
|
+
submissionRecordKey(key, submissionId)
|
|
49608
51541
|
) : void 0;
|
|
49609
|
-
if (
|
|
49610
|
-
|
|
49611
|
-
|
|
49612
|
-
|
|
49613
|
-
|
|
49614
|
-
|
|
49615
|
-
|
|
49616
|
-
|
|
49617
|
-
|
|
49618
|
-
|
|
49619
|
-
|
|
49620
|
-
|
|
51542
|
+
if (!submission) throw new Error("No submission matches this result");
|
|
51543
|
+
if (result.externalId && submission.externalId !== result.externalId) {
|
|
51544
|
+
throw new Error(
|
|
51545
|
+
"submissionId and externalId identify different submissions"
|
|
51546
|
+
);
|
|
51547
|
+
}
|
|
51548
|
+
if (run.status === "completed") return currentStatus(definition, run);
|
|
51549
|
+
const state = await readRunState(definition, store, key, [
|
|
51550
|
+
submission.itemId
|
|
51551
|
+
]);
|
|
51552
|
+
if (submission.status !== "complete") {
|
|
51553
|
+
const record = await collectSubmission(definition, state, submission);
|
|
51554
|
+
await writeCaseRecords(store, key, [record]);
|
|
51555
|
+
submission.status = "complete";
|
|
51556
|
+
}
|
|
51557
|
+
await writeSubmissionRecords(store, key, [submission]);
|
|
51558
|
+
return advanceWorkflowEval(
|
|
49621
51559
|
definition,
|
|
49622
|
-
await readRunState(definition, store, key),
|
|
51560
|
+
await readRunState(definition, store, key, [submission.itemId]),
|
|
49623
51561
|
store,
|
|
49624
51562
|
key
|
|
49625
51563
|
);
|
|
49626
51564
|
}
|
|
49627
|
-
async function
|
|
51565
|
+
async function pollWorkflowEval(definition, options) {
|
|
49628
51566
|
const store = definition.evaluator.store;
|
|
49629
51567
|
const key = runKey(
|
|
49630
51568
|
definition.projectName,
|
|
@@ -49632,39 +51570,53 @@ async function pollDurableEval(definition, options) {
|
|
|
49632
51570
|
options.runId
|
|
49633
51571
|
);
|
|
49634
51572
|
const state = await readRunState(definition, store, key);
|
|
49635
|
-
if (!state) throw new Error(`
|
|
49636
|
-
const
|
|
49637
|
-
if (
|
|
49638
|
-
return processorForStage(definition,
|
|
49639
|
-
});
|
|
49640
|
-
const
|
|
49641
|
-
|
|
49642
|
-
|
|
49643
|
-
|
|
49644
|
-
|
|
49645
|
-
|
|
49646
|
-
|
|
49647
|
-
|
|
49648
|
-
|
|
49649
|
-
|
|
49650
|
-
|
|
49651
|
-
for (const { batch, result } of results) {
|
|
51573
|
+
if (!state) throw new Error(`Workflow eval run ${options.runId} is missing`);
|
|
51574
|
+
const submissions = state.submissions.filter((submission) => {
|
|
51575
|
+
if (submission.status === "complete") return false;
|
|
51576
|
+
return processorForStage(definition, submission.kind, submission.scorerName).completion.mode === "poll";
|
|
51577
|
+
});
|
|
51578
|
+
const workers = queue(async (submission) => {
|
|
51579
|
+
const completion = processorForStage(
|
|
51580
|
+
definition,
|
|
51581
|
+
submission.kind,
|
|
51582
|
+
submission.scorerName
|
|
51583
|
+
).completion;
|
|
51584
|
+
if (completion.mode !== "poll") return;
|
|
51585
|
+
const result = await completion.poll(submission.submissionData, {
|
|
51586
|
+
runId: state.runId,
|
|
51587
|
+
submissionId: submission.id
|
|
51588
|
+
});
|
|
49652
51589
|
if (result.status === "failed") throw asError(result.error);
|
|
49653
|
-
if (result.status
|
|
49654
|
-
|
|
49655
|
-
|
|
49656
|
-
|
|
49657
|
-
|
|
49658
|
-
|
|
49659
|
-
}
|
|
49660
|
-
|
|
49661
|
-
|
|
49662
|
-
|
|
51590
|
+
if (result.status === "complete") {
|
|
51591
|
+
const record = await collectSubmission(definition, state, submission);
|
|
51592
|
+
await writeCaseRecords(store, key, [record]);
|
|
51593
|
+
submission.status = "complete";
|
|
51594
|
+
await writeSubmissionRecords(store, key, [submission]);
|
|
51595
|
+
}
|
|
51596
|
+
}, definition.evaluator.maxConcurrency ?? 10);
|
|
51597
|
+
const results = await Promise.allSettled(
|
|
51598
|
+
submissions.map((submission) => workers.pushAsync(submission))
|
|
51599
|
+
);
|
|
51600
|
+
let status;
|
|
51601
|
+
const errors = results.flatMap(
|
|
51602
|
+
(result) => result.status === "rejected" ? [asError(result.reason)] : []
|
|
51603
|
+
);
|
|
51604
|
+
try {
|
|
51605
|
+
status = await advanceWorkflowEval(
|
|
51606
|
+
definition,
|
|
51607
|
+
await readRunState(definition, store, key),
|
|
51608
|
+
store,
|
|
51609
|
+
key
|
|
51610
|
+
);
|
|
51611
|
+
} catch (error) {
|
|
51612
|
+
errors.push(asError(error));
|
|
49663
51613
|
}
|
|
49664
|
-
|
|
49665
|
-
|
|
51614
|
+
if (errors.length === 1) throw errors[0];
|
|
51615
|
+
if (errors.length > 1)
|
|
51616
|
+
throw new AggregateError(errors, "Workflow submission callbacks failed");
|
|
51617
|
+
return status;
|
|
49666
51618
|
}
|
|
49667
|
-
async function
|
|
51619
|
+
async function openWorkflowExperiment(definition, state) {
|
|
49668
51620
|
const data = [];
|
|
49669
51621
|
return await _internalInitEvaluatorExperiment(
|
|
49670
51622
|
definition.projectName,
|
|
@@ -49677,45 +51629,49 @@ async function openDurableExperiment(definition, state) {
|
|
|
49677
51629
|
}
|
|
49678
51630
|
);
|
|
49679
51631
|
}
|
|
49680
|
-
async function
|
|
51632
|
+
async function advanceWorkflowEval(definition, state, store, key, existingExperiment) {
|
|
49681
51633
|
if (state.status === "completed") return currentStatus(definition, state);
|
|
49682
|
-
const experiment = existingExperiment === void 0 ? await
|
|
51634
|
+
const experiment = existingExperiment === void 0 ? await openWorkflowExperiment(definition, state) : existingExperiment;
|
|
51635
|
+
const caseIds = state.cases.map(({ id }) => id);
|
|
49683
51636
|
await runTaskStage(definition, state, store, key, experiment);
|
|
49684
51637
|
await logCompletedTasks(definition, state, store, key, experiment);
|
|
49685
|
-
state = await readRunState(definition, store, key) ?? state;
|
|
49686
|
-
if (state.cases.some((record) => !record.taskComplete || !record.taskLogged)) {
|
|
49687
|
-
return currentStatus(definition, state);
|
|
49688
|
-
}
|
|
51638
|
+
state = await readRunState(definition, store, key, caseIds) ?? state;
|
|
49689
51639
|
await runScoreStages(definition, state, store, key, experiment);
|
|
49690
|
-
state = await readRunState(definition, store, key) ?? state;
|
|
51640
|
+
state = await readRunState(definition, store, key, caseIds) ?? state;
|
|
49691
51641
|
const scorerNames = resolveScorers(definition.evaluator.scores ?? []).map(
|
|
49692
51642
|
({ name }) => name
|
|
49693
51643
|
);
|
|
49694
51644
|
const classifierNames = (definition.evaluator.classifiers ?? []).map(
|
|
49695
51645
|
classifierName
|
|
49696
51646
|
);
|
|
49697
|
-
|
|
49698
|
-
(record) =>
|
|
49699
|
-
(
|
|
49700
|
-
|
|
49701
|
-
|
|
49702
|
-
|
|
49703
|
-
|
|
51647
|
+
await Promise.all(
|
|
51648
|
+
state.cases.map(async (record) => {
|
|
51649
|
+
if (record.taskComplete && record.taskLogged && scorerNames.every(
|
|
51650
|
+
(name) => Object.hasOwn(record.scores, name) && Object.hasOwn(record.loggedScores, name)
|
|
51651
|
+
) && classifierNames.every(
|
|
51652
|
+
(name) => Object.hasOwn(record.loggedClassifications, name)
|
|
51653
|
+
)) {
|
|
51654
|
+
await store.addToSet(`${key}/progress/cases`, record.id);
|
|
51655
|
+
}
|
|
51656
|
+
})
|
|
51657
|
+
);
|
|
51658
|
+
if (await store.getSetSize(`${key}/progress/cases`) !== state.caseCount) {
|
|
49704
51659
|
return currentStatus(definition, state);
|
|
49705
51660
|
}
|
|
49706
51661
|
if (!await claimAction(store, key, "finish")) {
|
|
49707
|
-
const latest = await
|
|
51662
|
+
const latest = await readJson(store, key);
|
|
49708
51663
|
return currentStatus(definition, latest ?? state);
|
|
49709
51664
|
}
|
|
51665
|
+
state = await readRunState(definition, store, key);
|
|
49710
51666
|
state.summary = await finishExperiment(definition, state, experiment);
|
|
49711
51667
|
state.status = "completed";
|
|
49712
51668
|
await writeRunRecord(store, key, state);
|
|
49713
51669
|
return currentStatus(definition, state);
|
|
49714
51670
|
}
|
|
49715
|
-
function currentStatus(definition, state) {
|
|
51671
|
+
async function currentStatus(definition, state) {
|
|
49716
51672
|
if (state.status === "completed") {
|
|
49717
51673
|
if (!state.summary) {
|
|
49718
|
-
throw new Error(`
|
|
51674
|
+
throw new Error(`Workflow eval run ${state.runId} has no saved summary`);
|
|
49719
51675
|
}
|
|
49720
51676
|
return {
|
|
49721
51677
|
status: "completed",
|
|
@@ -49724,11 +51680,20 @@ function currentStatus(definition, state) {
|
|
|
49724
51680
|
summary: state.summary
|
|
49725
51681
|
};
|
|
49726
51682
|
}
|
|
51683
|
+
const key = runKey(definition.projectName, definition.evalName, state.runId);
|
|
51684
|
+
const store = definition.evaluator.store;
|
|
49727
51685
|
const pending = { poll: 0, webhook: 0 };
|
|
49728
|
-
|
|
49729
|
-
|
|
49730
|
-
|
|
49731
|
-
|
|
51686
|
+
await Promise.all(
|
|
51687
|
+
["poll", "webhook"].map(async (mode) => {
|
|
51688
|
+
const completed = await store.getSetSize(
|
|
51689
|
+
`${key}/progress/${mode}/complete`
|
|
51690
|
+
);
|
|
51691
|
+
const submitted = await store.getSetSize(
|
|
51692
|
+
`${key}/progress/${mode}/submitted`
|
|
51693
|
+
);
|
|
51694
|
+
pending[mode] = submitted - completed;
|
|
51695
|
+
})
|
|
51696
|
+
);
|
|
49732
51697
|
return { status: "waiting", runId: state.runId, pending };
|
|
49733
51698
|
}
|
|
49734
51699
|
async function startCaseRoot(definition, state, record, experiment) {
|
|
@@ -49789,7 +51754,7 @@ async function logTaskResult(definition, state, record, experiment, task) {
|
|
|
49789
51754
|
expected: "expected" in datum ? datum.expected : void 0,
|
|
49790
51755
|
metadata: {
|
|
49791
51756
|
...record.metadata,
|
|
49792
|
-
|
|
51757
|
+
workflow_eval: {
|
|
49793
51758
|
run_id: state.runId,
|
|
49794
51759
|
case_id: record.caseId,
|
|
49795
51760
|
trial_index: record.trialIndex
|
|
@@ -49820,8 +51785,8 @@ async function logCompletedTasks(definition, state, store, key, experiment) {
|
|
|
49820
51785
|
}
|
|
49821
51786
|
}
|
|
49822
51787
|
async function runTaskStage(definition, state, store, key, experiment) {
|
|
49823
|
-
if (
|
|
49824
|
-
await
|
|
51788
|
+
if (isWorkflowTask(definition.evaluator.task)) {
|
|
51789
|
+
await ensureSubmissions(definition, state, store, key, "task");
|
|
49825
51790
|
return;
|
|
49826
51791
|
}
|
|
49827
51792
|
const task = definition.evaluator.task;
|
|
@@ -49847,8 +51812,9 @@ async function runScoreStages(definition, state, store, key, experiment) {
|
|
|
49847
51812
|
changed.clear();
|
|
49848
51813
|
};
|
|
49849
51814
|
for (const { name, scorer } of scorers) {
|
|
49850
|
-
if (
|
|
51815
|
+
if (isWorkflowScorer(scorer)) {
|
|
49851
51816
|
for (const record of state.cases) {
|
|
51817
|
+
if (!record.taskComplete || !record.taskLogged) continue;
|
|
49852
51818
|
if (Object.hasOwn(record.scores, name) && !Object.hasOwn(record.loggedScores, name)) {
|
|
49853
51819
|
if (!await claimAction(store, key, "score-log", record.id, name)) {
|
|
49854
51820
|
continue;
|
|
@@ -49864,10 +51830,11 @@ async function runScoreStages(definition, state, store, key, experiment) {
|
|
|
49864
51830
|
}
|
|
49865
51831
|
}
|
|
49866
51832
|
await persistChangedCases();
|
|
49867
|
-
await
|
|
51833
|
+
await ensureSubmissions(definition, state, store, key, "score", name);
|
|
49868
51834
|
continue;
|
|
49869
51835
|
}
|
|
49870
51836
|
for (const record of state.cases) {
|
|
51837
|
+
if (!record.taskComplete || !record.taskLogged) continue;
|
|
49871
51838
|
if (Object.hasOwn(record.loggedScores, name)) continue;
|
|
49872
51839
|
if (!await claimAction(store, key, "score", record.id, name)) continue;
|
|
49873
51840
|
await evaluateAndLogScore(
|
|
@@ -49884,6 +51851,7 @@ async function runScoreStages(definition, state, store, key, experiment) {
|
|
|
49884
51851
|
for (const [index, classifier] of (definition.evaluator.classifiers ?? []).entries()) {
|
|
49885
51852
|
const name = classifierName(classifier, index);
|
|
49886
51853
|
for (const record of state.cases) {
|
|
51854
|
+
if (!record.taskComplete || !record.taskLogged) continue;
|
|
49887
51855
|
if (Object.hasOwn(record.loggedClassifications, name)) continue;
|
|
49888
51856
|
if (!await claimAction(store, key, "classification", record.id, name)) {
|
|
49889
51857
|
continue;
|
|
@@ -49906,13 +51874,14 @@ function scorerArgs(record) {
|
|
|
49906
51874
|
return {
|
|
49907
51875
|
...datum,
|
|
49908
51876
|
metadata: record.metadata,
|
|
51877
|
+
tags: record.tags,
|
|
49909
51878
|
output: record.output
|
|
49910
51879
|
};
|
|
49911
51880
|
}
|
|
49912
51881
|
function resumeCaseRoot(definition, record, experiment) {
|
|
49913
51882
|
if (!experiment) return NOOP_SPAN;
|
|
49914
51883
|
if (!record.rootSpan) {
|
|
49915
|
-
throw new Error(`
|
|
51884
|
+
throw new Error(`Workflow eval case ${record.caseId} has no root span`);
|
|
49916
51885
|
}
|
|
49917
51886
|
return _internalResumeSpan({
|
|
49918
51887
|
exported: record.rootSpan,
|
|
@@ -50000,117 +51969,110 @@ async function evaluateAndLogClassification(definition, state, record, name, cla
|
|
|
50000
51969
|
root.end();
|
|
50001
51970
|
}
|
|
50002
51971
|
}
|
|
50003
|
-
async function
|
|
51972
|
+
async function ensureSubmissions(definition, state, store, key, kind, scorerName2) {
|
|
50004
51973
|
const processor = processorForStage(definition, kind, scorerName2);
|
|
50005
|
-
const plans =
|
|
51974
|
+
const plans = plannedSubmissions(
|
|
50006
51975
|
definition,
|
|
50007
51976
|
state.runId,
|
|
50008
51977
|
state.cases.map(({ id }) => id)
|
|
50009
51978
|
);
|
|
50010
51979
|
const casesById = new Map(state.cases.map((record) => [record.id, record]));
|
|
50011
|
-
|
|
50012
|
-
|
|
50013
|
-
if (
|
|
50014
|
-
|
|
50015
|
-
const
|
|
50016
|
-
|
|
50017
|
-
);
|
|
50018
|
-
|
|
50019
|
-
const batchId = plan.id;
|
|
51980
|
+
const existingIds = new Set(state.submissions.map(({ id }) => id));
|
|
51981
|
+
const workers = queue(async (plan) => {
|
|
51982
|
+
if (plan.kind !== kind || plan.scorerName !== scorerName2) return;
|
|
51983
|
+
if (existingIds.has(plan.id)) return;
|
|
51984
|
+
const record = casesById.get(plan.itemId);
|
|
51985
|
+
const ready = kind === "task" ? !record.taskComplete : record.taskComplete && record.taskLogged && !Object.hasOwn(record.scores, scorerName2);
|
|
51986
|
+
if (!ready) return;
|
|
51987
|
+
const submissionId = plan.id;
|
|
50020
51988
|
const claim = await store.getOrSet(
|
|
50021
|
-
claimRecordKey(key, "
|
|
50022
|
-
encoder.encode(
|
|
50023
|
-
);
|
|
50024
|
-
if (!claim.created) continue;
|
|
50025
|
-
const context = { runId: state.runId, batchId };
|
|
50026
|
-
const items = records.map(
|
|
50027
|
-
(record) => kind === "task" ? taskBatchItem(record, state.parameters) : scorerBatchItem(record)
|
|
51989
|
+
claimRecordKey(key, "submission", submissionId),
|
|
51990
|
+
encoder.encode(submissionId)
|
|
50028
51991
|
);
|
|
51992
|
+
if (!claim.created) return;
|
|
51993
|
+
const context = { runId: state.runId, submissionId };
|
|
51994
|
+
const item = kind === "task" ? taskSubmissionItem(record, state.parameters) : scorerSubmissionItem(record);
|
|
50029
51995
|
const submissionData = assertJsonValue(
|
|
50030
|
-
await processor.submit(
|
|
50031
|
-
`submission data for
|
|
51996
|
+
await processor.submit(item, context),
|
|
51997
|
+
`submission data for submission ${submissionId}`
|
|
50032
51998
|
);
|
|
50033
51999
|
const externalId = processor.completion.mode === "webhook" ? processor.completion.getExternalId(submissionData, context) : void 0;
|
|
50034
52000
|
if (externalId !== void 0 && !externalId.trim()) {
|
|
50035
|
-
throw new Error(
|
|
52001
|
+
throw new Error(
|
|
52002
|
+
`Submission ${submissionId} produced an empty externalId`
|
|
52003
|
+
);
|
|
50036
52004
|
}
|
|
50037
|
-
const
|
|
50038
|
-
id:
|
|
52005
|
+
const submission = {
|
|
52006
|
+
id: submissionId,
|
|
50039
52007
|
kind,
|
|
50040
52008
|
scorerName: scorerName2,
|
|
50041
|
-
|
|
52009
|
+
itemId: record.id,
|
|
50042
52010
|
submissionData,
|
|
50043
52011
|
externalId,
|
|
50044
|
-
status: "submitted"
|
|
50045
|
-
|
|
50046
|
-
|
|
50047
|
-
|
|
50048
|
-
|
|
52012
|
+
status: "submitted",
|
|
52013
|
+
completionMode: processor.completion.mode
|
|
52014
|
+
};
|
|
52015
|
+
state.submissions.push(submission);
|
|
52016
|
+
await writeSubmissionRecords(store, key, [submission]);
|
|
52017
|
+
}, definition.evaluator.maxConcurrency ?? 10);
|
|
52018
|
+
const results = await Promise.allSettled(
|
|
52019
|
+
plans.map((plan) => workers.pushAsync(plan))
|
|
52020
|
+
);
|
|
52021
|
+
const errors = results.flatMap(
|
|
52022
|
+
(result) => result.status === "rejected" ? [asError(result.reason)] : []
|
|
52023
|
+
);
|
|
52024
|
+
if (errors.length === 1) throw errors[0];
|
|
52025
|
+
if (errors.length > 1)
|
|
52026
|
+
throw new AggregateError(errors, "Workflow submissions failed");
|
|
50049
52027
|
}
|
|
50050
|
-
async function
|
|
50051
|
-
const processor = processorForStage(
|
|
50052
|
-
|
|
50053
|
-
|
|
50054
|
-
|
|
50055
|
-
|
|
52028
|
+
async function collectSubmission(definition, state, submission) {
|
|
52029
|
+
const processor = processorForStage(
|
|
52030
|
+
definition,
|
|
52031
|
+
submission.kind,
|
|
52032
|
+
submission.scorerName
|
|
52033
|
+
);
|
|
52034
|
+
const context = { runId: state.runId, submissionId: submission.id };
|
|
52035
|
+
const result = await processor.collect(submission.submissionData, context);
|
|
52036
|
+
if (typeof result !== "object" || result === null || Array.isArray(result)) {
|
|
52037
|
+
throw new Error(
|
|
52038
|
+
`collect for submission ${submission.id} must return a result object`
|
|
52039
|
+
);
|
|
50056
52040
|
}
|
|
50057
|
-
const
|
|
50058
|
-
|
|
50059
|
-
|
|
50060
|
-
|
|
50061
|
-
|
|
50062
|
-
|
|
50063
|
-
|
|
50064
|
-
|
|
50065
|
-
if (
|
|
50066
|
-
|
|
50067
|
-
|
|
50068
|
-
|
|
50069
|
-
const record = state.cases.find((candidate) => candidate.id === id);
|
|
50070
|
-
records.push(record);
|
|
50071
|
-
if (batch.kind === "task") {
|
|
50072
|
-
record.output = assertJsonValue(
|
|
50073
|
-
result.output,
|
|
50074
|
-
`task output for item ${id}`
|
|
50075
|
-
);
|
|
50076
|
-
if ("metadata" in result && result.metadata !== void 0) {
|
|
50077
|
-
record.metadata = assertJsonValue(
|
|
50078
|
-
{
|
|
50079
|
-
...record.metadata,
|
|
50080
|
-
...result.metadata
|
|
50081
|
-
},
|
|
50082
|
-
`metadata for ${id}`
|
|
50083
|
-
);
|
|
50084
|
-
}
|
|
50085
|
-
if ("tags" in result && result.tags !== void 0)
|
|
50086
|
-
record.tags = result.tags;
|
|
50087
|
-
record.taskComplete = true;
|
|
50088
|
-
} else {
|
|
50089
|
-
record.scores[batch.scorerName] = assertJsonValue(
|
|
50090
|
-
result.score,
|
|
50091
|
-
`score output for item ${id}`
|
|
52041
|
+
const record = state.cases.find(
|
|
52042
|
+
(candidate) => candidate.id === submission.itemId
|
|
52043
|
+
);
|
|
52044
|
+
if (submission.kind === "task") {
|
|
52045
|
+
record.output = assertJsonValue(
|
|
52046
|
+
result.output,
|
|
52047
|
+
`task output for item ${record.id}`
|
|
52048
|
+
);
|
|
52049
|
+
if (result.metadata !== void 0) {
|
|
52050
|
+
record.metadata = assertJsonValue(
|
|
52051
|
+
{ ...record.metadata, ...result.metadata },
|
|
52052
|
+
`metadata for ${record.id}`
|
|
50092
52053
|
);
|
|
50093
52054
|
}
|
|
50094
|
-
|
|
50095
|
-
|
|
50096
|
-
|
|
50097
|
-
|
|
50098
|
-
|
|
52055
|
+
if (result.tags !== void 0) record.tags = result.tags;
|
|
52056
|
+
record.taskComplete = true;
|
|
52057
|
+
} else {
|
|
52058
|
+
record.scores[submission.scorerName] = assertJsonValue(
|
|
52059
|
+
result.score,
|
|
52060
|
+
`score output for item ${record.id}`
|
|
50099
52061
|
);
|
|
50100
52062
|
}
|
|
50101
|
-
return
|
|
52063
|
+
return record;
|
|
50102
52064
|
}
|
|
50103
52065
|
function processorForStage(definition, kind, scorerName2) {
|
|
50104
52066
|
if (kind === "task") {
|
|
50105
|
-
if (!
|
|
50106
|
-
throw new Error("Definition no longer contains the
|
|
52067
|
+
if (!isWorkflowTask(definition.evaluator.task)) {
|
|
52068
|
+
throw new Error("Definition no longer contains the submission task");
|
|
50107
52069
|
}
|
|
50108
52070
|
return definition.evaluator.task.processor;
|
|
50109
52071
|
}
|
|
50110
52072
|
const scorer = resolveScorers(definition.evaluator.scores ?? []).find(
|
|
50111
52073
|
({ name }) => name === scorerName2
|
|
50112
52074
|
)?.scorer;
|
|
50113
|
-
if (!
|
|
52075
|
+
if (!isWorkflowScorer(scorer)) {
|
|
50114
52076
|
throw new Error(`Definition no longer contains scorer ${scorerName2}`);
|
|
50115
52077
|
}
|
|
50116
52078
|
return scorer.processor;
|
|
@@ -50132,15 +52094,15 @@ async function materializeCases(definition, data, experiment) {
|
|
|
50132
52094
|
const caseId = datum.id ?? datum.upsert_id ?? (evaluator.caseId ? await evaluator.caseId(datum) : void 0);
|
|
50133
52095
|
if (!caseId) {
|
|
50134
52096
|
throw new Error(
|
|
50135
|
-
"Every
|
|
52097
|
+
"Every workflow eval case requires id, upsert_id, or caseId"
|
|
50136
52098
|
);
|
|
50137
52099
|
}
|
|
50138
52100
|
if (seen.has(caseId))
|
|
50139
|
-
throw new Error(`Duplicate
|
|
52101
|
+
throw new Error(`Duplicate workflow eval case id: ${caseId}`);
|
|
50140
52102
|
seen.add(caseId);
|
|
50141
52103
|
const trialCount = datum.trialCount ?? evaluator.trialCount ?? 1;
|
|
50142
52104
|
if (!Number.isInteger(trialCount) || trialCount < 1) {
|
|
50143
|
-
throw new Error(`Invalid trialCount for
|
|
52105
|
+
throw new Error(`Invalid trialCount for workflow eval case ${caseId}`);
|
|
50144
52106
|
}
|
|
50145
52107
|
for (let trialIndex = 0; trialIndex < trialCount; trialIndex++) {
|
|
50146
52108
|
records.push({
|
|
@@ -50164,7 +52126,7 @@ async function materializeCases(definition, data, experiment) {
|
|
|
50164
52126
|
}
|
|
50165
52127
|
return records;
|
|
50166
52128
|
}
|
|
50167
|
-
function
|
|
52129
|
+
function taskSubmissionItem(record, parameters) {
|
|
50168
52130
|
const datum = record.datum;
|
|
50169
52131
|
return {
|
|
50170
52132
|
id: record.id,
|
|
@@ -50176,7 +52138,7 @@ function taskBatchItem(record, parameters) {
|
|
|
50176
52138
|
trialIndex: record.trialIndex
|
|
50177
52139
|
};
|
|
50178
52140
|
}
|
|
50179
|
-
function
|
|
52141
|
+
function scorerSubmissionItem(record) {
|
|
50180
52142
|
const datum = record.datum;
|
|
50181
52143
|
return {
|
|
50182
52144
|
id: record.id,
|
|
@@ -50247,12 +52209,12 @@ async function finishExperiment(definition, state, experiment) {
|
|
|
50247
52209
|
}
|
|
50248
52210
|
function resolveScorers(scorers) {
|
|
50249
52211
|
return scorers.map((scorer, index) => ({
|
|
50250
|
-
name:
|
|
52212
|
+
name: isWorkflowScorer(scorer) ? scorer.name : scorer.name || `scorer_${index}`,
|
|
50251
52213
|
scorer
|
|
50252
52214
|
}));
|
|
50253
52215
|
}
|
|
50254
52216
|
function runKey(projectName, evalName, runId) {
|
|
50255
|
-
return `
|
|
52217
|
+
return `workflow-eval/v1/runs/${contentVersion(encoder.encode(`${projectName}\0${evalName}\0${runId}`))}`;
|
|
50256
52218
|
}
|
|
50257
52219
|
function encodedKeyPart(value) {
|
|
50258
52220
|
return uint8ArrayToBase64(encoder.encode(value)).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/, "");
|
|
@@ -50261,8 +52223,8 @@ function caseRecordKey(key, caseId, kind, ...names) {
|
|
|
50261
52223
|
const suffix = names.map(encodedKeyPart).join("/");
|
|
50262
52224
|
return `${key}/cases/${encodedKeyPart(caseId)}/${kind}${suffix ? `/${suffix}` : ""}`;
|
|
50263
52225
|
}
|
|
50264
|
-
function
|
|
50265
|
-
return `${key}/
|
|
52226
|
+
function submissionRecordKey(key, submissionId) {
|
|
52227
|
+
return `${key}/submissions/${encodedKeyPart(submissionId)}`;
|
|
50266
52228
|
}
|
|
50267
52229
|
function claimRecordKey(key, kind, ...parts) {
|
|
50268
52230
|
const identity = stableStringify([kind, parts]);
|
|
@@ -50274,33 +52236,24 @@ async function claimAction(store, key, kind, ...parts) {
|
|
|
50274
52236
|
encoder.encode("claimed")
|
|
50275
52237
|
)).created;
|
|
50276
52238
|
}
|
|
50277
|
-
function
|
|
52239
|
+
function plannedSubmissions(definition, runId, caseIds) {
|
|
50278
52240
|
const stages = [];
|
|
50279
|
-
if (
|
|
52241
|
+
if (isWorkflowTask(definition.evaluator.task)) stages.push({ kind: "task" });
|
|
50280
52242
|
for (const { name, scorer } of resolveScorers(
|
|
50281
52243
|
definition.evaluator.scores ?? []
|
|
50282
52244
|
)) {
|
|
50283
|
-
if (
|
|
52245
|
+
if (isWorkflowScorer(scorer)) {
|
|
50284
52246
|
stages.push({ kind: "score", scorerName: name });
|
|
50285
52247
|
}
|
|
50286
52248
|
}
|
|
50287
52249
|
const plans = [];
|
|
50288
52250
|
for (const { kind, scorerName: scorerName2 } of stages) {
|
|
50289
|
-
const
|
|
50290
|
-
if (!Number.isInteger(batchSize) || batchSize < 1) {
|
|
50291
|
-
throw new Error(
|
|
50292
|
-
`Invalid batchSize for ${scorerName2 ?? "task"}: ${batchSize}`
|
|
50293
|
-
);
|
|
50294
|
-
}
|
|
50295
|
-
for (let offset = 0; offset < caseIds.length; offset += batchSize) {
|
|
50296
|
-
const itemIds = caseIds.slice(offset, offset + batchSize);
|
|
52251
|
+
for (const itemId of caseIds) {
|
|
50297
52252
|
plans.push({
|
|
50298
|
-
id: deterministicId(
|
|
50299
|
-
stableStringify([runId, kind, scorerName2, itemIds])
|
|
50300
|
-
),
|
|
52253
|
+
id: deterministicId(stableStringify([runId, kind, scorerName2, itemId])),
|
|
50301
52254
|
kind,
|
|
50302
52255
|
scorerName: scorerName2,
|
|
50303
|
-
|
|
52256
|
+
itemId
|
|
50304
52257
|
});
|
|
50305
52258
|
}
|
|
50306
52259
|
}
|
|
@@ -50360,7 +52313,7 @@ async function readCaseRecord(definition, store, key, id) {
|
|
|
50360
52313
|
}))
|
|
50361
52314
|
)
|
|
50362
52315
|
]);
|
|
50363
|
-
if (!base) throw new Error(`
|
|
52316
|
+
if (!base) throw new Error(`Workflow eval case ${id} is missing`);
|
|
50364
52317
|
const scores = /* @__PURE__ */ Object.create(null);
|
|
50365
52318
|
for (const { name, value } of scoreValues) {
|
|
50366
52319
|
if (value !== void 0) scores[name] = value;
|
|
@@ -50391,32 +52344,34 @@ async function readCaseRecord(definition, store, key, id) {
|
|
|
50391
52344
|
loggedClassifications
|
|
50392
52345
|
};
|
|
50393
52346
|
}
|
|
50394
|
-
async function readRunState(definition, store, key) {
|
|
52347
|
+
async function readRunState(definition, store, key, caseIds) {
|
|
50395
52348
|
const record = await readJson(store, key);
|
|
50396
52349
|
if (!record) return void 0;
|
|
50397
|
-
const
|
|
50398
|
-
|
|
52350
|
+
const selectedIds = caseIds ?? (record.caseCount === 0 ? [] : await readJson(store, `${key}/case-ids`));
|
|
52351
|
+
if (!selectedIds)
|
|
52352
|
+
throw new Error(`Workflow eval run ${record.runId} has no case index`);
|
|
52353
|
+
const plans = plannedSubmissions(definition, record.runId, selectedIds);
|
|
52354
|
+
const [cases, submissionRecords] = await Promise.all([
|
|
50399
52355
|
Promise.all(
|
|
50400
|
-
|
|
52356
|
+
selectedIds.map((id) => readCaseRecord(definition, store, key, id))
|
|
50401
52357
|
),
|
|
50402
52358
|
Promise.all(
|
|
50403
52359
|
plans.map(async ({ id }) => {
|
|
50404
|
-
return readJson(
|
|
52360
|
+
return readJson(
|
|
52361
|
+
store,
|
|
52362
|
+
submissionRecordKey(key, id)
|
|
52363
|
+
);
|
|
50405
52364
|
})
|
|
50406
52365
|
)
|
|
50407
52366
|
]);
|
|
50408
|
-
const
|
|
52367
|
+
const submissions = submissionRecords.filter(
|
|
50409
52368
|
(value) => value !== void 0
|
|
50410
52369
|
);
|
|
50411
|
-
|
|
50412
|
-
return { ...state, cases, batches };
|
|
52370
|
+
return { ...record, cases, submissions };
|
|
50413
52371
|
}
|
|
50414
52372
|
async function writeRunRecord(store, key, state) {
|
|
50415
|
-
const { cases,
|
|
50416
|
-
await writeJson(store, key,
|
|
50417
|
-
...record,
|
|
50418
|
-
caseIds: cases.map(({ id }) => id)
|
|
50419
|
-
});
|
|
52373
|
+
const { cases: _cases, submissions: _submissions, ...record } = state;
|
|
52374
|
+
await writeJson(store, key, record);
|
|
50420
52375
|
}
|
|
50421
52376
|
async function writeCaseBaseRecords(store, key, records) {
|
|
50422
52377
|
await Promise.all(
|
|
@@ -50488,11 +52443,25 @@ async function writeCaseRecords(store, key, records) {
|
|
|
50488
52443
|
}
|
|
50489
52444
|
await Promise.all(writes);
|
|
50490
52445
|
}
|
|
50491
|
-
async function
|
|
52446
|
+
async function writeSubmissionRecords(store, key, records) {
|
|
50492
52447
|
await Promise.all(
|
|
50493
|
-
records.map(
|
|
50494
|
-
(record
|
|
50495
|
-
|
|
52448
|
+
records.map(async (record) => {
|
|
52449
|
+
if (record.externalId !== void 0) {
|
|
52450
|
+
const locator = await store.getOrSet(
|
|
52451
|
+
`${key}/external/${encodedKeyPart(record.externalId)}`,
|
|
52452
|
+
encoder.encode(JSON.stringify(record.id))
|
|
52453
|
+
);
|
|
52454
|
+
if (JSON.parse(decoder.decode(locator.value)) !== record.id) {
|
|
52455
|
+
throw new Error(`Duplicate externalId: ${record.externalId}`);
|
|
52456
|
+
}
|
|
52457
|
+
}
|
|
52458
|
+
const progressKey = `${key}/progress/${record.completionMode}`;
|
|
52459
|
+
await store.addToSet(`${progressKey}/submitted`, record.id);
|
|
52460
|
+
if (record.status === "complete") {
|
|
52461
|
+
await store.addToSet(`${progressKey}/complete`, record.id);
|
|
52462
|
+
}
|
|
52463
|
+
await writeJson(store, submissionRecordKey(key, record.id), record);
|
|
52464
|
+
})
|
|
50496
52465
|
);
|
|
50497
52466
|
}
|
|
50498
52467
|
function deterministicId(value) {
|
|
@@ -50537,17 +52506,11 @@ function assertJsonValue(value, label) {
|
|
|
50537
52506
|
throw new Error(`${label} must be JSON serializable`, { cause: error });
|
|
50538
52507
|
}
|
|
50539
52508
|
}
|
|
50540
|
-
function
|
|
50541
|
-
|
|
50542
|
-
throw new Error("Batch results must contain a string id");
|
|
50543
|
-
}
|
|
50544
|
-
return value.id;
|
|
50545
|
-
}
|
|
50546
|
-
function isBatchTask(value) {
|
|
50547
|
-
return typeof value === "object" && value !== null && "kind" in value && value.kind === BATCH_TASK_KIND;
|
|
52509
|
+
function isWorkflowTask(value) {
|
|
52510
|
+
return typeof value === "object" && value !== null && "kind" in value && value.kind === WORKFLOW_TASK_KIND;
|
|
50548
52511
|
}
|
|
50549
|
-
function
|
|
50550
|
-
return typeof value === "object" && value !== null && "kind" in value && value.kind ===
|
|
52512
|
+
function isWorkflowScorer(value) {
|
|
52513
|
+
return typeof value === "object" && value !== null && "kind" in value && value.kind === WORKFLOW_SCORER_KIND;
|
|
50551
52514
|
}
|
|
50552
52515
|
function asError(error) {
|
|
50553
52516
|
return error instanceof Error ? error : new Error(String(error));
|
|
@@ -51475,13 +53438,13 @@ var evaluatorDefinitionsSchema = import_v313.z.record(
|
|
|
51475
53438
|
);
|
|
51476
53439
|
|
|
51477
53440
|
// src/wrappers/elevenlabs.ts
|
|
51478
|
-
var
|
|
53441
|
+
var clients2 = /* @__PURE__ */ new WeakMap();
|
|
51479
53442
|
function wrapElevenLabs(client) {
|
|
51480
53443
|
if (!isObject(client) || !isObject(client.textToSpeech) || typeof client.textToSpeech.convert !== "function") {
|
|
51481
53444
|
debugLogger.warn("Unsupported ElevenLabs client. Not wrapping.");
|
|
51482
53445
|
return client;
|
|
51483
53446
|
}
|
|
51484
|
-
const cached =
|
|
53447
|
+
const cached = clients2.get(client);
|
|
51485
53448
|
if (cached) return cached;
|
|
51486
53449
|
const sdk = client;
|
|
51487
53450
|
const speech = new Proxy(sdk.textToSpeech, {
|
|
@@ -51528,8 +53491,8 @@ function wrapElevenLabs(client) {
|
|
|
51528
53491
|
return Reflect.get(target, prop, receiver);
|
|
51529
53492
|
}
|
|
51530
53493
|
});
|
|
51531
|
-
|
|
51532
|
-
|
|
53494
|
+
clients2.set(client, proxy);
|
|
53495
|
+
clients2.set(proxy, proxy);
|
|
51533
53496
|
return proxy;
|
|
51534
53497
|
}
|
|
51535
53498
|
|