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.
Files changed (60) hide show
  1. package/README.md +0 -43
  2. package/dev/dist/index.d.mts +31 -0
  3. package/dev/dist/index.d.ts +31 -0
  4. package/dev/dist/index.js +2275 -920
  5. package/dev/dist/index.mjs +1610 -255
  6. package/dist/apply-auto-instrumentation.js +263 -224
  7. package/dist/apply-auto-instrumentation.mjs +45 -6
  8. package/dist/auto-instrumentations/bundler/esbuild.cjs +78 -5
  9. package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
  10. package/dist/auto-instrumentations/bundler/next.cjs +78 -5
  11. package/dist/auto-instrumentations/bundler/next.mjs +3 -3
  12. package/dist/auto-instrumentations/bundler/rollup.cjs +78 -5
  13. package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
  14. package/dist/auto-instrumentations/bundler/vite.cjs +78 -5
  15. package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
  16. package/dist/auto-instrumentations/bundler/webpack-loader.cjs +78 -5
  17. package/dist/auto-instrumentations/bundler/webpack.cjs +78 -5
  18. package/dist/auto-instrumentations/bundler/webpack.mjs +3 -3
  19. package/dist/auto-instrumentations/{chunk-AFND2U7E.mjs → chunk-T2DMPWFI.mjs} +75 -5
  20. package/dist/auto-instrumentations/{chunk-RI4Y55ZF.mjs → chunk-UHJ2DNYJ.mjs} +6 -1
  21. package/dist/auto-instrumentations/{chunk-QEEPRBIS.mjs → chunk-W5QNG3PV.mjs} +1 -1
  22. package/dist/auto-instrumentations/hook.mjs +86 -7
  23. package/dist/auto-instrumentations/index.cjs +76 -5
  24. package/dist/auto-instrumentations/index.d.mts +3 -1
  25. package/dist/auto-instrumentations/index.d.ts +3 -1
  26. package/dist/auto-instrumentations/index.mjs +3 -1
  27. package/dist/browser.d.mts +202 -342
  28. package/dist/browser.d.ts +202 -342
  29. package/dist/browser.js +2586 -623
  30. package/dist/browser.mjs +2586 -623
  31. package/dist/chunk-7P6ASYW6.mjs +9 -0
  32. package/dist/{chunk-BTRLPQG5.js → chunk-AXJTOUOC.js} +2250 -1172
  33. package/dist/{chunk-AW4QECG5.js → chunk-G3VHOHRC.js} +40 -9
  34. package/dist/chunk-MLKGABMK.js +9 -0
  35. package/dist/{chunk-4QSAHP7D.mjs → chunk-MZLBAFVJ.mjs} +1236 -158
  36. package/dist/{chunk-WV6QZI2W.mjs → chunk-TZVZN2JJ.mjs} +39 -8
  37. package/dist/cli.js +1695 -293
  38. package/dist/custom-views.d.mts +112 -0
  39. package/dist/custom-views.d.ts +112 -0
  40. package/dist/custom-views.js +13 -0
  41. package/dist/custom-views.mjs +13 -0
  42. package/dist/edge-light.d.mts +1 -1
  43. package/dist/edge-light.d.ts +1 -1
  44. package/dist/edge-light.js +2586 -623
  45. package/dist/edge-light.mjs +2586 -623
  46. package/dist/index.d.mts +202 -342
  47. package/dist/index.d.ts +202 -342
  48. package/dist/index.js +1842 -986
  49. package/dist/index.mjs +1310 -454
  50. package/dist/instrumentation/index.d.mts +5 -245
  51. package/dist/instrumentation/index.d.ts +5 -245
  52. package/dist/instrumentation/index.js +1694 -254
  53. package/dist/instrumentation/index.mjs +1694 -254
  54. package/dist/vitest-evals-reporter.js +17 -16
  55. package/dist/vitest-evals-reporter.mjs +3 -2
  56. package/dist/workerd.d.mts +1 -1
  57. package/dist/workerd.d.ts +1 -1
  58. package/dist/workerd.js +2586 -623
  59. package/dist/workerd.mjs +2586 -623
  60. package/package.json +10 -2
@@ -5814,6 +5814,7 @@ var INSTRUMENTATION_NAMES = {
5814
5814
  LANGSMITH: "langsmith",
5815
5815
  MASTRA: "mastra",
5816
5816
  MISTRAL: "mistral",
5817
+ LANGGRAPH_SDK: "langgraph-sdk",
5817
5818
  OLLAMA: "ollama",
5818
5819
  OPENAI: "openai",
5819
5820
  OPENAI_AGENTS: "openai-agents",
@@ -5828,7 +5829,7 @@ var INSTRUMENTATION_NAMES = {
5828
5829
  var INTERNAL_SPAN_INSTRUMENTATION_NAME = /* @__PURE__ */ Symbol.for(
5829
5830
  "braintrust.spanInstrumentationName"
5830
5831
  );
5831
- var SDK_VERSION = true ? "3.32.0" : "0.0.0";
5832
+ var SDK_VERSION = true ? "3.33.0" : "0.0.0";
5832
5833
  function withSpanInstrumentationName(args, instrumentationName) {
5833
5834
  return {
5834
5835
  ...args,
@@ -8547,6 +8548,38 @@ function getSpanParentObjectAndPropagatedState(options) {
8547
8548
  function getSpanParentObject(options) {
8548
8549
  return getSpanParentObjectAndPropagatedState(options).parentObject;
8549
8550
  }
8551
+ function _internalExportParentSynchronously(parent) {
8552
+ if ("toStr" in parent) {
8553
+ return parent.toStr();
8554
+ }
8555
+ if ("getParentInfo" in parent) {
8556
+ const parentInfo = parent.getParentInfo();
8557
+ if (!parentInfo) {
8558
+ return void 0;
8559
+ }
8560
+ const objectId = parentInfo.objectId.getSync().value;
8561
+ if (!objectId && !parentInfo.computeObjectMetadataArgs) {
8562
+ return void 0;
8563
+ }
8564
+ return new SpanComponentsV4({
8565
+ object_type: parentInfo.objectType,
8566
+ ...objectId ? { object_id: objectId } : {
8567
+ compute_object_metadata_args: parentInfo.computeObjectMetadataArgs ?? {}
8568
+ },
8569
+ row_id: parent.id,
8570
+ root_span_id: parent.rootSpanId,
8571
+ span_id: parent.spanId
8572
+ }).toStr();
8573
+ }
8574
+ const components = braintrustParentToComponents(parent._getOtelParent());
8575
+ if (!components) {
8576
+ return void 0;
8577
+ }
8578
+ return new SpanComponentsV4({
8579
+ object_type: components.objectType,
8580
+ ...components.objectId ? { object_id: components.objectId } : { compute_object_metadata_args: components.computeArgs ?? {} }
8581
+ }).toStr();
8582
+ }
8550
8583
  function currentBraintrustParent(state) {
8551
8584
  const resolvedState = state ?? _globalState;
8552
8585
  const experiment = currentExperiment({ state: resolvedState });
@@ -9853,10 +9886,16 @@ var SpanImpl = class _SpanImpl {
9853
9886
  inject(carrier) {
9854
9887
  const resolvedCarrier = carrier ?? {};
9855
9888
  try {
9889
+ const braintrustParent = this._getOtelParent() ?? this._propagatedState?.braintrustParent;
9890
+ if (!braintrustParent) {
9891
+ debugLogger.forState(this._state).warn(
9892
+ "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."
9893
+ );
9894
+ }
9856
9895
  _injectIntoCarrier(resolvedCarrier, {
9857
9896
  traceId: this._rootSpanId,
9858
9897
  spanId: this._spanId,
9859
- braintrustParent: this._getOtelParent() ?? this._propagatedState?.braintrustParent,
9898
+ braintrustParent,
9860
9899
  propagatedState: this._propagatedState
9861
9900
  });
9862
9901
  } catch (e) {
@@ -11939,6 +11978,18 @@ function defineChannels(pkg, channels, options) {
11939
11978
  var openAIChannels = defineChannels(
11940
11979
  "openai",
11941
11980
  {
11981
+ agentsTraceStart: channel({
11982
+ channelName: "agents.trace.start",
11983
+ kind: "async"
11984
+ }),
11985
+ agentsTraceCapture: channel({
11986
+ channelName: "agents.trace.capture",
11987
+ kind: "async"
11988
+ }),
11989
+ agentsTraceFail: channel({
11990
+ channelName: "agents.trace.fail",
11991
+ kind: "async"
11992
+ }),
11942
11993
  filesCreateTraced: channel({
11943
11994
  channelName: "files.create-traced",
11944
11995
  kind: "async"
@@ -12307,6 +12358,23 @@ function getCachedMetricFromHeaders(headers) {
12307
12358
  return parseCachedHeader(headers.get(LEGACY_CACHED_HEADER));
12308
12359
  }
12309
12360
 
12361
+ // src/instrumentation/plugins/openai-manual-instrumentation-utils.ts
12362
+ async function deterministicDigest(namespace, ...parts) {
12363
+ const encoded = new TextEncoder().encode(
12364
+ [namespace, ...parts].map((part) => `${part.length}:${part}`).join("\0")
12365
+ );
12366
+ return new Uint8Array(
12367
+ await globalThis.crypto.subtle.digest("SHA-256", encoded)
12368
+ );
12369
+ }
12370
+ function digestHex(bytes, length) {
12371
+ return Array.from(bytes.slice(0, length)).map((byte) => byte.toString(16).padStart(2, "0")).join("");
12372
+ }
12373
+ function digestUuid(bytes) {
12374
+ const hex = digestHex(bytes, 16);
12375
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
12376
+ }
12377
+
12310
12378
  // src/instrumentation/plugins/openai-batch-instrumentation.ts
12311
12379
  var SUPPORTED_ENDPOINTS = /* @__PURE__ */ new Set(["/v1/chat/completions", "/v1/responses"]);
12312
12380
  var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
@@ -12347,21 +12415,6 @@ async function exportParent(parent) {
12347
12415
  }
12348
12416
  return void 0;
12349
12417
  }
12350
- async function deterministicDigest(namespace, ...parts) {
12351
- const encoded = new TextEncoder().encode(
12352
- [namespace, ...parts].map((part) => `${part.length}:${part}`).join("\0")
12353
- );
12354
- return new Uint8Array(
12355
- await globalThis.crypto.subtle.digest("SHA-256", encoded)
12356
- );
12357
- }
12358
- function digestHex(bytes, length) {
12359
- return Array.from(bytes.slice(0, length)).map((byte) => byte.toString(16).padStart(2, "0")).join("");
12360
- }
12361
- function digestUuid(bytes) {
12362
- const hex = digestHex(bytes, 16);
12363
- return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
12364
- }
12365
12418
  async function batchSpanIds(inputFileId) {
12366
12419
  const [row, span, root] = await Promise.all([
12367
12420
  deterministicDigest("openai:batch:row", inputFileId),
@@ -12852,6 +12905,628 @@ var interceptOpenAIBatchTraceComplete = (target, thisArg, args) => Promise.resol
12852
12905
  return result;
12853
12906
  });
12854
12907
 
12908
+ // src/instrumentation/plugins/openai-agents-api-instrumentation.ts
12909
+ var TERMINAL_TURN_EVENTS = /* @__PURE__ */ new Set([
12910
+ "agent.session.turn.completed",
12911
+ "agent.session.turn.failed",
12912
+ "agent.session.turn.cancelled"
12913
+ ]);
12914
+ var TURN_LIFECYCLE_EVENTS = /* @__PURE__ */ new Set([
12915
+ "agent.session.turn.created",
12916
+ "agent.session.turn.in_progress",
12917
+ ...TERMINAL_TURN_EVENTS
12918
+ ]);
12919
+ var SESSION_EVENTS = /* @__PURE__ */ new Set([
12920
+ "agent.session.created",
12921
+ "agent.session.failed",
12922
+ "agent.session.idle",
12923
+ "agent.session.in_progress",
12924
+ "agent.session.requires_action"
12925
+ ]);
12926
+ var SUBAGENT_EVENTS = /* @__PURE__ */ new Set([
12927
+ "agent.session.subagent.active",
12928
+ "agent.session.subagent.closed",
12929
+ "agent.session.subagent.created"
12930
+ ]);
12931
+ function read2(value, key) {
12932
+ if (!isObject(value)) {
12933
+ return void 0;
12934
+ }
12935
+ try {
12936
+ return Reflect.get(value, key);
12937
+ } catch {
12938
+ return void 0;
12939
+ }
12940
+ }
12941
+ function stringValue(value) {
12942
+ return typeof value === "string" && value.length > 0 ? value : void 0;
12943
+ }
12944
+ function recordValue(record, key) {
12945
+ return Object.hasOwn(record, key) ? record[key] : void 0;
12946
+ }
12947
+ function setRecordValue(record, key, value) {
12948
+ Object.defineProperty(record, key, {
12949
+ configurable: true,
12950
+ enumerable: true,
12951
+ value,
12952
+ writable: true
12953
+ });
12954
+ }
12955
+ function loggedError(value, fallback) {
12956
+ if (value instanceof Error) {
12957
+ return value;
12958
+ }
12959
+ const message = stringValue(read2(value, "message"));
12960
+ return new Error(message ?? (typeof value === "string" ? value : fallback));
12961
+ }
12962
+ function logInstrumentationError(context, error) {
12963
+ debugLogger.debug(`OpenAI Agents API instrumentation ${context}:`, error);
12964
+ }
12965
+ async function childSpanIds2(rootKey, kind, providerId) {
12966
+ const [row, span] = await Promise.all([
12967
+ deterministicDigest("openai:agents:row", rootKey, kind, providerId),
12968
+ deterministicDigest("openai:agents:span", rootKey, kind, providerId)
12969
+ ]);
12970
+ return { rowId: digestUuid(row), spanId: digestHex(span, 8) };
12971
+ }
12972
+ function traceMetadata(args) {
12973
+ const metadata = {};
12974
+ const suppliedMetadata = read2(args, "metadata");
12975
+ if (isObject(suppliedMetadata)) {
12976
+ try {
12977
+ for (const key of Object.keys(suppliedMetadata)) {
12978
+ metadata[key] = read2(suppliedMetadata, key);
12979
+ }
12980
+ } catch (error) {
12981
+ logInstrumentationError("could not read supplied metadata", error);
12982
+ }
12983
+ }
12984
+ const agent = read2(args, "agent");
12985
+ const agentId = stringValue(read2(agent, "id")) ?? stringValue(read2(args, "agent_id"));
12986
+ const agentName = stringValue(read2(agent, "name"));
12987
+ const model = stringValue(read2(agent, "model"));
12988
+ return {
12989
+ ...metadata,
12990
+ api: "agents",
12991
+ ...agentId ? { agent_id: agentId } : {},
12992
+ ...agentName ? { agent_name: agentName } : {},
12993
+ ...model ? { model } : {},
12994
+ provider: "openai"
12995
+ };
12996
+ }
12997
+ function copyState(state) {
12998
+ return {
12999
+ ...state,
13000
+ callItems: { ...state.callItems },
13001
+ eventIds: [...state.eventIds],
13002
+ openTools: { ...state.openTools },
13003
+ subagents: { ...state.subagents },
13004
+ turnSubagents: { ...state.turnSubagents }
13005
+ };
13006
+ }
13007
+ function startRootSpan(state) {
13008
+ const root = SpanComponentsV4.fromStr(state.root);
13009
+ const parent = SpanComponentsV4.fromStr(state.rootParent);
13010
+ const rowId = stringValue(root.data.row_id);
13011
+ const rootSpanId = stringValue(root.data.root_span_id);
13012
+ const spanId = stringValue(root.data.span_id);
13013
+ if (!rowId || !rootSpanId || !spanId) {
13014
+ throw new Error("OpenAI Agents trace root is invalid");
13015
+ }
13016
+ const hasParentSpan = Boolean(
13017
+ parent.data.row_id && parent.data.span_id && parent.data.root_span_id
13018
+ );
13019
+ return withCurrent(
13020
+ NOOP_SPAN,
13021
+ () => _internalStartSpanWithInitialMergeAndParentSpanIds(
13022
+ withSpanInstrumentationName(
13023
+ {
13024
+ name: "openai.agents.turn",
13025
+ type: "task" /* TASK */,
13026
+ parent: state.rootParent,
13027
+ ...!hasParentSpan ? {
13028
+ parentSpanIds: {
13029
+ parentSpanIds: [],
13030
+ rootSpanId
13031
+ }
13032
+ } : {},
13033
+ spanId,
13034
+ startTime: state.startTime,
13035
+ event: { id: rowId }
13036
+ },
13037
+ INSTRUMENTATION_NAMES.OPENAI
13038
+ )
13039
+ )
13040
+ );
13041
+ }
13042
+ async function startSubagentSpan(state, subagentId, input, metadata, visiting = /* @__PURE__ */ new Set()) {
13043
+ const subagent = recordValue(state.subagents, subagentId);
13044
+ let parent = state.root;
13045
+ if (subagent?.parentAgentId && subagent.parentAgentId !== subagentId && recordValue(state.subagents, subagent.parentAgentId) && !visiting.has(subagent.parentAgentId)) {
13046
+ visiting.add(subagentId);
13047
+ parent = await (await startSubagentSpan(
13048
+ state,
13049
+ subagent.parentAgentId,
13050
+ void 0,
13051
+ void 0,
13052
+ visiting
13053
+ )).export();
13054
+ }
13055
+ const ids = await childSpanIds2(state.rootKey, "subagent", subagentId);
13056
+ return withCurrent(
13057
+ NOOP_SPAN,
13058
+ () => _internalStartSpanWithInitialMerge(
13059
+ withSpanInstrumentationName(
13060
+ {
13061
+ name: "openai.agents.subagent",
13062
+ type: "task" /* TASK */,
13063
+ parent,
13064
+ spanId: ids.spanId,
13065
+ startTime: subagent?.openedAt,
13066
+ event: {
13067
+ id: ids.rowId,
13068
+ ...input !== void 0 ? { input } : {},
13069
+ metadata: {
13070
+ ...metadata,
13071
+ agent_id: subagentId,
13072
+ ...subagent?.parentAgentId ? { parent_agent_id: subagent.parentAgentId } : {},
13073
+ provider: "openai"
13074
+ }
13075
+ }
13076
+ },
13077
+ INSTRUMENTATION_NAMES.OPENAI
13078
+ )
13079
+ )
13080
+ );
13081
+ }
13082
+ async function parentForTurn(state, turnId) {
13083
+ const subagentId = turnId ? recordValue(state.turnSubagents, turnId) : void 0;
13084
+ if (!subagentId) {
13085
+ return state.root;
13086
+ }
13087
+ return await (await startSubagentSpan(state, subagentId)).export();
13088
+ }
13089
+ async function startToolSpan(state, tool, input) {
13090
+ const ids = await childSpanIds2(state.rootKey, "tool", tool.itemId);
13091
+ return withCurrent(
13092
+ NOOP_SPAN,
13093
+ async () => _internalStartSpanWithInitialMerge(
13094
+ withSpanInstrumentationName(
13095
+ {
13096
+ name: tool.name,
13097
+ type: "tool" /* TOOL */,
13098
+ parent: await parentForTurn(state, tool.turnId),
13099
+ spanId: ids.spanId,
13100
+ startTime: tool.startTime,
13101
+ event: {
13102
+ id: ids.rowId,
13103
+ ...input !== void 0 ? { input } : {},
13104
+ metadata: {
13105
+ item_id: tool.itemId,
13106
+ provider: "openai",
13107
+ tool_type: tool.toolType,
13108
+ ...tool.turnId ? { turn_id: tool.turnId } : {}
13109
+ }
13110
+ }
13111
+ },
13112
+ INSTRUMENTATION_NAMES.OPENAI
13113
+ )
13114
+ )
13115
+ );
13116
+ }
13117
+ function toolFromItem(item, observedAt) {
13118
+ const itemId = stringValue(read2(item, "id"));
13119
+ const toolType = stringValue(read2(item, "type"));
13120
+ if (!itemId || !toolType) {
13121
+ return void 0;
13122
+ }
13123
+ const turnId = stringValue(read2(item, "turn_id"));
13124
+ switch (toolType) {
13125
+ case "function_call":
13126
+ return {
13127
+ input: read2(item, "arguments"),
13128
+ tool: {
13129
+ itemId,
13130
+ name: stringValue(read2(item, "name")) ?? "Function call",
13131
+ startTime: observedAt,
13132
+ toolType,
13133
+ ...turnId ? { turnId } : {}
13134
+ }
13135
+ };
13136
+ case "mcp_call": {
13137
+ const name = stringValue(read2(item, "name")) ?? "MCP call";
13138
+ const server = stringValue(read2(item, "server_label"));
13139
+ return {
13140
+ input: read2(item, "arguments"),
13141
+ tool: {
13142
+ itemId,
13143
+ name: server ? `${server}.${name}` : name,
13144
+ startTime: observedAt,
13145
+ toolType,
13146
+ ...turnId ? { turnId } : {}
13147
+ }
13148
+ };
13149
+ }
13150
+ case "web_search_call":
13151
+ return {
13152
+ input: read2(item, "action"),
13153
+ tool: {
13154
+ itemId,
13155
+ name: "Web search",
13156
+ startTime: observedAt,
13157
+ toolType,
13158
+ ...turnId ? { turnId } : {}
13159
+ }
13160
+ };
13161
+ case "command_execution":
13162
+ return {
13163
+ input: {
13164
+ command: read2(item, "command"),
13165
+ cwd: read2(item, "cwd")
13166
+ },
13167
+ tool: {
13168
+ itemId,
13169
+ name: "Command execution",
13170
+ startTime: observedAt,
13171
+ toolType,
13172
+ ...turnId ? { turnId } : {}
13173
+ }
13174
+ };
13175
+ default:
13176
+ return void 0;
13177
+ }
13178
+ }
13179
+ function textFromContent(content) {
13180
+ if (!Array.isArray(content)) {
13181
+ return void 0;
13182
+ }
13183
+ const text = [];
13184
+ for (const part of content) {
13185
+ const partText = read2(part, "text");
13186
+ if (read2(part, "type") === "output_text" && typeof partText === "string") {
13187
+ text.push(partText);
13188
+ }
13189
+ }
13190
+ return text.length > 0 ? text.join("") : void 0;
13191
+ }
13192
+ function toolOutput(item, toolType) {
13193
+ switch (toolType) {
13194
+ case "function_call":
13195
+ return read2(item, "output");
13196
+ case "mcp_call":
13197
+ return read2(item, "output");
13198
+ case "web_search_call":
13199
+ return read2(item, "action");
13200
+ case "command_execution":
13201
+ return read2(item, "output");
13202
+ default:
13203
+ return void 0;
13204
+ }
13205
+ }
13206
+ function toolFailed(item, toolType) {
13207
+ const status = read2(item, "status");
13208
+ const explicitError = read2(item, "error");
13209
+ if (explicitError !== void 0 && explicitError !== null) {
13210
+ return loggedError(explicitError, `OpenAI ${toolType} failed`);
13211
+ }
13212
+ if (status === "failed" || status === "incomplete") {
13213
+ return new Error(`OpenAI ${toolType} ${status}`);
13214
+ }
13215
+ if (toolType === "command_execution" && typeof read2(item, "exit_code") === "number" && read2(item, "exit_code") !== 0) {
13216
+ return new Error(
13217
+ `OpenAI command exited with code ${read2(item, "exit_code")}`
13218
+ );
13219
+ }
13220
+ return void 0;
13221
+ }
13222
+ async function completeTool(state, tool, item, endTime) {
13223
+ const span = await startToolSpan(state, tool);
13224
+ const output = toolOutput(item, tool.toolType);
13225
+ const error = toolFailed(item, tool.toolType);
13226
+ span.log({
13227
+ ...output !== void 0 ? { output } : {},
13228
+ ...error ? { error } : {},
13229
+ metadata: {
13230
+ status: read2(item, "status"),
13231
+ ...tool.toolType === "command_execution" ? { exit_code: read2(item, "exit_code") } : {}
13232
+ }
13233
+ });
13234
+ span.end({ endTime });
13235
+ Reflect.deleteProperty(state.openTools, tool.itemId);
13236
+ }
13237
+ async function captureMessage(state, item) {
13238
+ if (read2(item, "type") !== "message" || read2(item, "role") !== "assistant" || read2(item, "phase") !== "final_answer") {
13239
+ return;
13240
+ }
13241
+ const output = textFromContent(read2(item, "content"));
13242
+ if (output === void 0) {
13243
+ return;
13244
+ }
13245
+ const turnId = stringValue(read2(item, "turn_id"));
13246
+ const subagentId = turnId ? recordValue(state.turnSubagents, turnId) : void 0;
13247
+ if (subagentId) {
13248
+ (await startSubagentSpan(state, subagentId)).log({ output });
13249
+ } else {
13250
+ startRootSpan(state).log({ output });
13251
+ }
13252
+ }
13253
+ async function captureItem(state, item, isDone, observedAt) {
13254
+ await captureMessage(state, item);
13255
+ const itemType = stringValue(read2(item, "type"));
13256
+ if (itemType === "function_call_output") {
13257
+ const callId = stringValue(read2(item, "call_id"));
13258
+ const itemId = callId ? recordValue(state.callItems, callId) : void 0;
13259
+ const tool2 = itemId ? recordValue(state.openTools, itemId) : void 0;
13260
+ if (tool2) {
13261
+ await completeTool(state, tool2, item, observedAt);
13262
+ }
13263
+ return;
13264
+ }
13265
+ const descriptor = toolFromItem(item, observedAt);
13266
+ if (!descriptor) {
13267
+ return;
13268
+ }
13269
+ const existing = recordValue(state.openTools, descriptor.tool.itemId);
13270
+ const tool = existing ?? descriptor.tool;
13271
+ setRecordValue(state.openTools, tool.itemId, tool);
13272
+ if (itemType === "function_call") {
13273
+ const callId = stringValue(read2(item, "call_id"));
13274
+ if (callId) {
13275
+ setRecordValue(state.callItems, callId, tool.itemId);
13276
+ }
13277
+ }
13278
+ await startToolSpan(state, tool, descriptor.input);
13279
+ const status = read2(item, "status");
13280
+ const terminalFunctionCall = itemType === "function_call" && (status === "failed" || status === "incomplete");
13281
+ if (itemType !== "function_call" && (isDone || status !== "in_progress") || terminalFunctionCall) {
13282
+ await completeTool(state, tool, item, observedAt);
13283
+ }
13284
+ }
13285
+ function updateSessionMetadata(state, session) {
13286
+ const sessionId = stringValue(read2(session, "id"));
13287
+ const agent = read2(session, "agent");
13288
+ startRootSpan(state).log({
13289
+ metadata: {
13290
+ ...sessionId ? { session_id: sessionId } : {},
13291
+ ...stringValue(read2(agent, "id")) ? { agent_id: read2(agent, "id") } : {},
13292
+ ...stringValue(read2(agent, "name")) ? { agent_name: read2(agent, "name") } : {},
13293
+ ...stringValue(read2(agent, "model")) ? { model: read2(agent, "model") } : {}
13294
+ }
13295
+ });
13296
+ }
13297
+ async function captureSubagent(state, eventType, subagent, observedAt) {
13298
+ const subagentId = stringValue(read2(subagent, "id"));
13299
+ if (!subagentId) {
13300
+ return;
13301
+ }
13302
+ const existing = recordValue(state.subagents, subagentId);
13303
+ const observedOpenedAt = read2(subagent, "opened_at");
13304
+ const openedAt = typeof observedOpenedAt === "number" && Number.isFinite(observedOpenedAt) && observedOpenedAt >= 0 ? observedOpenedAt : existing?.openedAt ?? observedAt;
13305
+ const observedClosedAt = read2(subagent, "closed_at");
13306
+ const closedAt = typeof observedClosedAt === "number" && Number.isFinite(observedClosedAt) && observedClosedAt >= 0 ? observedClosedAt : existing?.closedAt;
13307
+ const parentAgentId = stringValue(read2(subagent, "parent_agent_id")) ?? existing?.parentAgentId;
13308
+ setRecordValue(state.subagents, subagentId, {
13309
+ ...closedAt !== void 0 ? { closedAt } : {},
13310
+ openedAt,
13311
+ ...parentAgentId ? { parentAgentId } : {}
13312
+ });
13313
+ const span = await startSubagentSpan(
13314
+ state,
13315
+ subagentId,
13316
+ read2(subagent, "instructions"),
13317
+ {
13318
+ ...stringValue(read2(subagent, "name")) ? { agent_name: read2(subagent, "name") } : {},
13319
+ status: read2(subagent, "status")
13320
+ }
13321
+ );
13322
+ if (eventType === "agent.session.subagent.closed") {
13323
+ span.end({ endTime: closedAt ?? observedAt });
13324
+ }
13325
+ }
13326
+ async function closeTrace(state, endTime, error, usage) {
13327
+ if (state.ended) {
13328
+ return;
13329
+ }
13330
+ for (const tool of Object.values(state.openTools)) {
13331
+ const span = await startToolSpan(state, tool);
13332
+ span.log({
13333
+ error: error ?? new Error("OpenAI Agents turn ended before tool completion")
13334
+ });
13335
+ span.end({ endTime });
13336
+ }
13337
+ state.openTools = {};
13338
+ for (const subagentId of Object.keys(state.subagents)) {
13339
+ const subagent = state.subagents[subagentId];
13340
+ const span = await startSubagentSpan(state, subagentId);
13341
+ span.end({ endTime: subagent.closedAt ?? endTime });
13342
+ }
13343
+ const root = startRootSpan(state);
13344
+ root.log({
13345
+ ...error ? { error } : {},
13346
+ metrics: parseMetricsFromUsage(usage)
13347
+ });
13348
+ root.end({ endTime });
13349
+ state.ended = true;
13350
+ }
13351
+ async function captureTurnLifecycle(state, event, eventType, observedAt) {
13352
+ const turn = read2(event, "turn");
13353
+ const turnId = stringValue(read2(event, "turn_id")) ?? stringValue(read2(turn, "id"));
13354
+ const subagentId = stringValue(read2(turn, "subagent_id"));
13355
+ if (turnId && subagentId) {
13356
+ setRecordValue(state.turnSubagents, turnId, subagentId);
13357
+ if (!recordValue(state.subagents, subagentId)) {
13358
+ const createdAt = read2(turn, "created_at");
13359
+ setRecordValue(state.subagents, subagentId, {
13360
+ openedAt: typeof createdAt === "number" && Number.isFinite(createdAt) && createdAt >= 0 ? createdAt : observedAt
13361
+ });
13362
+ }
13363
+ await startSubagentSpan(state, subagentId);
13364
+ }
13365
+ const sessionId = stringValue(read2(event, "session_id"));
13366
+ if (sessionId) {
13367
+ startRootSpan(state).log({ metadata: { session_id: sessionId } });
13368
+ }
13369
+ if (!TERMINAL_TURN_EVENTS.has(eventType) || subagentId) {
13370
+ if (subagentId && eventType === "agent.session.turn.failed") {
13371
+ (await startSubagentSpan(state, subagentId)).log({
13372
+ error: loggedError(read2(turn, "error"), "OpenAI subagent turn failed")
13373
+ });
13374
+ }
13375
+ return;
13376
+ }
13377
+ const completedAt = read2(turn, "completed_at");
13378
+ const endTime = typeof completedAt === "number" && Number.isFinite(completedAt) && completedAt >= 0 ? completedAt : observedAt;
13379
+ const usage = read2(event, "usage") ?? read2(turn, "usage");
13380
+ const error = eventType === "agent.session.turn.completed" ? void 0 : loggedError(
13381
+ read2(turn, "error"),
13382
+ eventType === "agent.session.turn.cancelled" ? "OpenAI Agents turn cancelled" : "OpenAI Agents turn failed"
13383
+ );
13384
+ await closeTrace(state, endTime, error, usage);
13385
+ }
13386
+ async function captureEvent(state, event) {
13387
+ if (state.ended) {
13388
+ return state;
13389
+ }
13390
+ const eventType = stringValue(read2(event, "type"));
13391
+ const eventId = stringValue(read2(event, "event_id"));
13392
+ if (!eventType || eventId && state.eventIds.includes(eventId)) {
13393
+ return state;
13394
+ }
13395
+ const next = copyState(state);
13396
+ const observedAt = getCurrentUnixTimestamp();
13397
+ let handled = false;
13398
+ if (SESSION_EVENTS.has(eventType)) {
13399
+ const session = read2(event, "session");
13400
+ if (session) {
13401
+ updateSessionMetadata(next, session);
13402
+ }
13403
+ handled = true;
13404
+ }
13405
+ if (eventType === "agent.session.turn.item.added") {
13406
+ await captureItem(next, read2(event, "item"), false, observedAt);
13407
+ handled = true;
13408
+ } else if (eventType === "agent.session.turn.item.done") {
13409
+ await captureItem(next, read2(event, "item"), true, observedAt);
13410
+ handled = true;
13411
+ } else if (TURN_LIFECYCLE_EVENTS.has(eventType)) {
13412
+ await captureTurnLifecycle(next, event, eventType, observedAt);
13413
+ handled = true;
13414
+ } else if (SUBAGENT_EVENTS.has(eventType)) {
13415
+ await captureSubagent(next, eventType, read2(event, "subagent"), observedAt);
13416
+ handled = true;
13417
+ } else if (eventType === "agent.session.turn.output_text.delta" && next.firstTokenAt === void 0 && stringValue(read2(event, "delta"))) {
13418
+ next.firstTokenAt = observedAt;
13419
+ startRootSpan(next).log({
13420
+ metrics: { time_to_first_token: observedAt - next.startTime }
13421
+ });
13422
+ handled = true;
13423
+ } else if (eventType === "agent.session.failed") {
13424
+ const session = read2(event, "session");
13425
+ const lastActiveAt = read2(session, "last_active_at");
13426
+ const endTime = typeof lastActiveAt === "number" && Number.isFinite(lastActiveAt) && lastActiveAt >= 0 ? lastActiveAt : observedAt;
13427
+ await closeTrace(
13428
+ next,
13429
+ endTime,
13430
+ loggedError(read2(session, "error"), "OpenAI Agents session failed"),
13431
+ read2(session, "usage")
13432
+ );
13433
+ handled = true;
13434
+ } else if (eventType === "error") {
13435
+ await closeTrace(
13436
+ next,
13437
+ observedAt,
13438
+ loggedError(read2(event, "error"), "OpenAI Agents session failed")
13439
+ );
13440
+ handled = true;
13441
+ }
13442
+ if (!handled) {
13443
+ return state;
13444
+ }
13445
+ if (eventId) {
13446
+ next.eventIds.push(eventId);
13447
+ }
13448
+ return next;
13449
+ }
13450
+ var interceptOpenAIAgentsTraceStart = async (target, thisArg, args) => {
13451
+ const fallback = await Reflect.apply(target, thisArg, args);
13452
+ try {
13453
+ const state = args[0].state;
13454
+ const parent = state.rootParent;
13455
+ const traceArgs = args[0].args;
13456
+ const parentComponents = SpanComponentsV4.fromStr(parent);
13457
+ const hasParentSpan = Boolean(
13458
+ parentComponents.data.row_id && parentComponents.data.span_id && parentComponents.data.root_span_id
13459
+ );
13460
+ const rootComponents = SpanComponentsV4.fromStr(state.root);
13461
+ const rowId = stringValue(rootComponents.data.row_id);
13462
+ const rootSpanId = stringValue(rootComponents.data.root_span_id);
13463
+ const spanId = stringValue(rootComponents.data.span_id);
13464
+ if (!rowId || !rootSpanId || !spanId) {
13465
+ throw new Error("OpenAI Agents trace root is invalid");
13466
+ }
13467
+ withCurrent(
13468
+ NOOP_SPAN,
13469
+ () => _internalStartSpanWithInitialMergeAndParentSpanIds(
13470
+ withSpanInstrumentationName(
13471
+ {
13472
+ name: "openai.agents.turn",
13473
+ type: "task" /* TASK */,
13474
+ parent,
13475
+ ...!hasParentSpan ? {
13476
+ parentSpanIds: {
13477
+ parentSpanIds: [],
13478
+ rootSpanId
13479
+ }
13480
+ } : {},
13481
+ spanId,
13482
+ startTime: state.startTime,
13483
+ event: {
13484
+ id: rowId,
13485
+ input: read2(traceArgs, "input"),
13486
+ metadata: traceMetadata(traceArgs)
13487
+ }
13488
+ },
13489
+ INSTRUMENTATION_NAMES.OPENAI
13490
+ )
13491
+ )
13492
+ );
13493
+ return state;
13494
+ } catch (error) {
13495
+ logInstrumentationError("could not start trace", error);
13496
+ return fallback;
13497
+ }
13498
+ };
13499
+ var interceptOpenAIAgentsTraceCapture = async (target, thisArg, args) => {
13500
+ const fallback = await Reflect.apply(target, thisArg, args);
13501
+ if (!args[0].state) {
13502
+ return fallback;
13503
+ }
13504
+ try {
13505
+ return await captureEvent(args[0].state, args[0].event);
13506
+ } catch (error) {
13507
+ logInstrumentationError("could not capture event", error);
13508
+ return fallback;
13509
+ }
13510
+ };
13511
+ var interceptOpenAIAgentsTraceFail = async (target, thisArg, args) => {
13512
+ const fallback = await Reflect.apply(target, thisArg, args);
13513
+ if (!args[0].state) {
13514
+ return fallback;
13515
+ }
13516
+ try {
13517
+ const next = copyState(args[0].state);
13518
+ await closeTrace(
13519
+ next,
13520
+ getCurrentUnixTimestamp(),
13521
+ loggedError(args[0].error, "OpenAI Agents request failed")
13522
+ );
13523
+ return next;
13524
+ } catch (error) {
13525
+ logInstrumentationError("could not fail trace", error);
13526
+ return fallback;
13527
+ }
13528
+ };
13529
+
12855
13530
  // src/instrumentation/plugins/openai-plugin.ts
12856
13531
  var OpenAIPlugin = class extends BasePlugin {
12857
13532
  constructor() {
@@ -12859,6 +13534,13 @@ var OpenAIPlugin = class extends BasePlugin {
12859
13534
  }
12860
13535
  onEnable() {
12861
13536
  this.unsubscribers.push(
13537
+ openAIChannels.agentsTraceStart.intercept(
13538
+ interceptOpenAIAgentsTraceStart
13539
+ ),
13540
+ openAIChannels.agentsTraceCapture.intercept(
13541
+ interceptOpenAIAgentsTraceCapture
13542
+ ),
13543
+ openAIChannels.agentsTraceFail.intercept(interceptOpenAIAgentsTraceFail),
12862
13544
  openAIChannels.filesCreateTraced.intercept(
12863
13545
  interceptOpenAIFilesCreateTraced
12864
13546
  ),
@@ -13419,7 +14101,7 @@ async function* patchCodexEventStream(events, state) {
13419
14101
  try {
13420
14102
  await handleCodexEvent(state, event);
13421
14103
  } catch (error) {
13422
- logInstrumentationError("OpenAI Codex stream event", error);
14104
+ logInstrumentationError2("OpenAI Codex stream event", error);
13423
14105
  }
13424
14106
  yield event;
13425
14107
  }
@@ -13919,10 +14601,10 @@ function safeLog(span, event) {
13919
14601
  try {
13920
14602
  span.log(event);
13921
14603
  } catch (error) {
13922
- logInstrumentationError("OpenAI Codex span log", error);
14604
+ logInstrumentationError2("OpenAI Codex span log", error);
13923
14605
  }
13924
14606
  }
13925
- function logInstrumentationError(context, error) {
14607
+ function logInstrumentationError2(context, error) {
13926
14608
  debugLogger.error(`Error processing ${context}:`, error);
13927
14609
  }
13928
14610
 
@@ -15304,27 +15986,8 @@ function continuationParentFromCreateSessionParams(params) {
15304
15986
  }
15305
15987
  return context.parent;
15306
15988
  }
15307
- function exportSpanSynchronously(span) {
15308
- const parentInfo = span.getParentInfo();
15309
- if (!parentInfo) {
15310
- return void 0;
15311
- }
15312
- const objectId = parentInfo.objectId.getSync().value;
15313
- if (!objectId && !parentInfo.computeObjectMetadataArgs) {
15314
- return void 0;
15315
- }
15316
- return new SpanComponentsV4({
15317
- object_type: parentInfo.objectType,
15318
- ...objectId ? { object_id: objectId } : {
15319
- compute_object_metadata_args: parentInfo.computeObjectMetadataArgs ?? {}
15320
- },
15321
- row_id: span.id,
15322
- root_span_id: span.rootSpanId,
15323
- span_id: span.spanId
15324
- }).toStr();
15325
- }
15326
15989
  function exportedParent(parent) {
15327
- return typeof parent === "string" ? parent : exportSpanSynchronously(parent);
15990
+ return typeof parent === "string" ? parent : _internalExportParentSynchronously(parent);
15328
15991
  }
15329
15992
  function addSerializedContext(args) {
15330
15993
  if (!isObject(args.continuation) || args.sessionId === void 0) {
@@ -16081,16 +16744,16 @@ function braintrustAISDKTelemetry() {
16081
16744
  if (!toolCallId || !state) {
16082
16745
  return;
16083
16746
  }
16084
- const toolOutput = event.toolOutput;
16747
+ const toolOutput2 = event.toolOutput;
16085
16748
  const workflowToolError = event.success === false && "error" in event ? event.error : void 0;
16086
- if (toolOutput?.type === "tool-error" || workflowToolError !== void 0) {
16087
- const error = toolOutput?.error ?? workflowToolError;
16749
+ if (toolOutput2?.type === "tool-error" || workflowToolError !== void 0) {
16750
+ const error = toolOutput2?.error ?? workflowToolError;
16088
16751
  state.span.log({
16089
16752
  error: error instanceof Error ? error.message : String(error),
16090
16753
  metrics: typeof event.durationMs === "number" ? { duration_ms: event.durationMs } : {}
16091
16754
  });
16092
16755
  } else {
16093
- const output = toolOutput && "output" in toolOutput ? toolOutput.output : event.output;
16756
+ const output = toolOutput2 && "output" in toolOutput2 ? toolOutput2.output : event.output;
16094
16757
  state.span.log({
16095
16758
  ...shouldRecordOutputs(event) ? { output } : {},
16096
16759
  metrics: typeof event.durationMs === "number" ? { duration_ms: event.durationMs } : {}
@@ -18549,9 +19212,9 @@ function patchAISDKStreamingResult(args) {
18549
19212
  }
18550
19213
  finalize({ metrics, output });
18551
19214
  } catch (error) {
18552
- const loggedError = toLoggedError(error);
19215
+ const loggedError2 = toLoggedError(error);
18553
19216
  try {
18554
- span.log({ error: loggedError });
19217
+ span.log({ error: loggedError2 });
18555
19218
  } catch (loggingError) {
18556
19219
  debugLogger.error(
18557
19220
  "Error logging AI SDK streaming failure:",
@@ -18559,7 +19222,7 @@ function patchAISDKStreamingResult(args) {
18559
19222
  );
18560
19223
  }
18561
19224
  finalize({
18562
- error: error instanceof Error ? error : new Error(String(loggedError))
19225
+ error: error instanceof Error ? error : new Error(String(loggedError2))
18563
19226
  });
18564
19227
  }
18565
19228
  };
@@ -18672,9 +19335,9 @@ function patchAISDKStreamingResult(args) {
18672
19335
  }
18673
19336
  controller.enqueue(value);
18674
19337
  } catch (error) {
18675
- const loggedError = toLoggedError(error);
19338
+ const loggedError2 = toLoggedError(error);
18676
19339
  try {
18677
- span.log({ error: loggedError });
19340
+ span.log({ error: loggedError2 });
18678
19341
  } catch (loggingError) {
18679
19342
  debugLogger.error(
18680
19343
  "Error logging AI SDK base stream failure:",
@@ -18682,7 +19345,7 @@ function patchAISDKStreamingResult(args) {
18682
19345
  );
18683
19346
  }
18684
19347
  finalize({
18685
- error: error instanceof Error ? error : new Error(String(loggedError))
19348
+ error: error instanceof Error ? error : new Error(String(loggedError2))
18686
19349
  });
18687
19350
  controller.error(error);
18688
19351
  }
@@ -21576,7 +22239,7 @@ function wrapSendOptionsCallbacks(options, state) {
21576
22239
  try {
21577
22240
  await handleInteractionUpdate(state, args.update);
21578
22241
  } catch (error) {
21579
- logInstrumentationError2("Cursor SDK onDelta", error);
22242
+ logInstrumentationError3("Cursor SDK onDelta", error);
21580
22243
  }
21581
22244
  if (originalOnDelta) {
21582
22245
  return originalOnDelta(args);
@@ -21586,7 +22249,7 @@ function wrapSendOptionsCallbacks(options, state) {
21586
22249
  try {
21587
22250
  handleStepUpdate(state, args.step);
21588
22251
  } catch (error) {
21589
- logInstrumentationError2("Cursor SDK onStep", error);
22252
+ logInstrumentationError3("Cursor SDK onStep", error);
21590
22253
  }
21591
22254
  if (originalOnStep) {
21592
22255
  return originalOnStep(args);
@@ -21668,7 +22331,7 @@ async function* patchCursorStream(stream, state) {
21668
22331
  try {
21669
22332
  await handleStreamMessage2(state, message);
21670
22333
  } catch (error) {
21671
- logInstrumentationError2("Cursor SDK stream", error);
22334
+ logInstrumentationError3("Cursor SDK stream", error);
21672
22335
  }
21673
22336
  yield message;
21674
22337
  }
@@ -21732,7 +22395,7 @@ async function handleToolUpdate(state, update) {
21732
22395
  if (!state.activeToolSpans.has(callId)) {
21733
22396
  state.activeToolSpans.set(
21734
22397
  callId,
21735
- await startToolSpan(state, {
22398
+ await startToolSpan2(state, {
21736
22399
  args,
21737
22400
  callId,
21738
22401
  name,
@@ -21743,7 +22406,7 @@ async function handleToolUpdate(state, update) {
21743
22406
  }
21744
22407
  return;
21745
22408
  }
21746
- const toolState = state.activeToolSpans.get(callId) ?? await startToolSpan(state, {
22409
+ const toolState = state.activeToolSpans.get(callId) ?? await startToolSpan2(state, {
21747
22410
  args,
21748
22411
  callId,
21749
22412
  name,
@@ -21780,7 +22443,7 @@ async function handleStreamMessage2(state, message) {
21780
22443
  } else if (block?.type === "tool_use" && block.id) {
21781
22444
  state.activeToolSpans.set(
21782
22445
  block.id,
21783
- await startToolSpan(state, {
22446
+ await startToolSpan2(state, {
21784
22447
  args: block.input,
21785
22448
  callId: block.id,
21786
22449
  name: block.name,
@@ -21815,7 +22478,7 @@ async function handleToolMessage(state, message) {
21815
22478
  if (!state.activeToolSpans.has(callId)) {
21816
22479
  state.activeToolSpans.set(
21817
22480
  callId,
21818
- await startToolSpan(state, {
22481
+ await startToolSpan2(state, {
21819
22482
  args: message.args,
21820
22483
  callId,
21821
22484
  name: message.name,
@@ -21826,7 +22489,7 @@ async function handleToolMessage(state, message) {
21826
22489
  }
21827
22490
  return;
21828
22491
  }
21829
- const toolState = state.activeToolSpans.get(callId) ?? await startToolSpan(state, {
22492
+ const toolState = state.activeToolSpans.get(callId) ?? await startToolSpan2(state, {
21830
22493
  args: message.args,
21831
22494
  callId,
21832
22495
  name: message.name,
@@ -21853,7 +22516,7 @@ async function handleConversation(state, turns) {
21853
22516
  const command = turn.turn?.shellCommand?.command;
21854
22517
  if (command) {
21855
22518
  const callId = `shell:${state.activeToolSpans.size}:${command}`;
21856
- const toolState = await startToolSpan(state, {
22519
+ const toolState = await startToolSpan2(state, {
21857
22520
  args: turn.turn?.shellCommand,
21858
22521
  callId,
21859
22522
  name: "shell",
@@ -21877,7 +22540,7 @@ async function handleConversationStep(state, step) {
21877
22540
  }
21878
22541
  const toolCall = step.message;
21879
22542
  const callId = typeof toolCall?.callId === "string" ? toolCall.callId : `conversation-tool:${state.activeToolSpans.size}`;
21880
- const toolState = await startToolSpan(state, {
22543
+ const toolState = await startToolSpan2(state, {
21881
22544
  args: extractToolArgs(toolCall),
21882
22545
  callId,
21883
22546
  name: extractToolName(toolCall),
@@ -21908,7 +22571,7 @@ function handleStepUpdate(state, step) {
21908
22571
  state.stepText.push(step.message.text);
21909
22572
  }
21910
22573
  }
21911
- async function startToolSpan(state, args) {
22574
+ async function startToolSpan2(state, args) {
21912
22575
  const name = args.name || "unknown";
21913
22576
  const metadata = {
21914
22577
  "cursor_sdk.tool.status": args.status,
@@ -22195,10 +22858,10 @@ function safeLog2(span, event) {
22195
22858
  try {
22196
22859
  span.log(event);
22197
22860
  } catch (error) {
22198
- logInstrumentationError2("Cursor SDK span log", error);
22861
+ logInstrumentationError3("Cursor SDK span log", error);
22199
22862
  }
22200
22863
  }
22201
- function logInstrumentationError2(context, error) {
22864
+ function logInstrumentationError3(context, error) {
22202
22865
  debugLogger.error(`Error processing ${context}:`, error);
22203
22866
  }
22204
22867
  function cleanMetrics2(metrics) {
@@ -23036,6 +23699,10 @@ var googleGenAIChannels = defineChannels(
23036
23699
  channelName: "models.embedContent",
23037
23700
  kind: "async"
23038
23701
  }),
23702
+ httpResponseJson: channel({
23703
+ channelName: "httpResponse.json",
23704
+ kind: "async"
23705
+ }),
23039
23706
  interactionsCreate: channel({
23040
23707
  channelName: "interactions.create",
23041
23708
  kind: "async"
@@ -23184,13 +23851,45 @@ var GoogleGenAIPlugin = class extends BasePlugin {
23184
23851
  subscribeToEmbedContentChannel() {
23185
23852
  const tracingChannel = googleGenAIChannels.embedContent.tracingChannel();
23186
23853
  const states = /* @__PURE__ */ new WeakMap();
23854
+ const embeddingSpans = /* @__PURE__ */ new WeakSet();
23855
+ this.unsubscribers.push(
23856
+ googleGenAIChannels.httpResponseJson.intercept(
23857
+ (target, thisArg, args) => {
23858
+ const span = currentSpan();
23859
+ const result = Reflect.apply(target, thisArg, args);
23860
+ if (embeddingSpans.has(span)) {
23861
+ void Promise.resolve(result).then(
23862
+ (response) => {
23863
+ try {
23864
+ const metrics = cleanMetrics3(
23865
+ extractEmbedContentMetrics(response)
23866
+ );
23867
+ if (embeddingSpans.has(span) && Object.keys(metrics).length > 0) {
23868
+ span.log({ metrics });
23869
+ }
23870
+ } catch (error) {
23871
+ debugLogger.error(
23872
+ "Error reading Google GenAI embedding usage:",
23873
+ error
23874
+ );
23875
+ }
23876
+ },
23877
+ () => {
23878
+ }
23879
+ // The embedding channel handles the original rejection.
23880
+ );
23881
+ }
23882
+ return result;
23883
+ }
23884
+ )
23885
+ );
23187
23886
  const unbindCurrentSpanStore = bindCurrentSpanStoreToStart2(
23188
23887
  tracingChannel,
23189
23888
  states,
23190
23889
  (event) => {
23191
23890
  const params = event.arguments[0];
23192
23891
  const input = serializeEmbedContentInput(params);
23193
- const metadata = extractEmbedContentMetadata(params);
23892
+ const metadata = { provider: "google", model: params.model };
23194
23893
  const span = startSpan(
23195
23894
  withSpanInstrumentationName(
23196
23895
  {
@@ -23203,6 +23902,7 @@ var GoogleGenAIPlugin = class extends BasePlugin {
23203
23902
  INSTRUMENTATION_NAMES.GOOGLE_GENAI
23204
23903
  )
23205
23904
  );
23905
+ embeddingSpans.add(span);
23206
23906
  return {
23207
23907
  span,
23208
23908
  startTime: getCurrentUnixTimestamp()
@@ -23214,7 +23914,7 @@ var GoogleGenAIPlugin = class extends BasePlugin {
23214
23914
  ensureSpanState(states, event, () => {
23215
23915
  const params = event.arguments[0];
23216
23916
  const input = serializeEmbedContentInput(params);
23217
- const metadata = extractEmbedContentMetadata(params);
23917
+ const metadata = { provider: "google", model: params.model };
23218
23918
  const span = startSpan(
23219
23919
  withSpanInstrumentationName(
23220
23920
  {
@@ -23227,6 +23927,7 @@ var GoogleGenAIPlugin = class extends BasePlugin {
23227
23927
  INSTRUMENTATION_NAMES.GOOGLE_GENAI
23228
23928
  )
23229
23929
  );
23930
+ embeddingSpans.add(span);
23230
23931
  return {
23231
23932
  span,
23232
23933
  startTime: getCurrentUnixTimestamp()
@@ -23239,20 +23940,28 @@ var GoogleGenAIPlugin = class extends BasePlugin {
23239
23940
  return;
23240
23941
  }
23241
23942
  try {
23242
- const output = summarizeEmbedContentOutput(event.result);
23243
23943
  spanState.span.log({
23244
- ...output ? { output } : {},
23944
+ output: summarizeEmbedContentOutput(event.result),
23245
23945
  metrics: cleanMetrics3(
23246
23946
  extractEmbedContentMetrics(event.result, spanState.startTime)
23247
23947
  )
23248
23948
  });
23249
23949
  } finally {
23950
+ embeddingSpans.delete(spanState.span);
23250
23951
  spanState.span.end();
23251
23952
  states.delete(event);
23252
23953
  }
23253
23954
  },
23254
23955
  error: (event) => {
23255
- logErrorAndEndSpan(states, event);
23956
+ const spanState = states.get(event);
23957
+ if (!spanState) return;
23958
+ try {
23959
+ spanState.span.log({ error: event.error, output: { count: 0 } });
23960
+ } finally {
23961
+ embeddingSpans.delete(spanState.span);
23962
+ spanState.span.end();
23963
+ states.delete(event);
23964
+ }
23256
23965
  }
23257
23966
  };
23258
23967
  tracingChannel.subscribe(handlers);
@@ -23487,15 +24196,53 @@ function serializeGenerateContentInput(params) {
23487
24196
  return input;
23488
24197
  }
23489
24198
  function serializeEmbedContentInput(params) {
24199
+ let contents = Array.isArray(params.contents) ? params.contents : [params.contents];
24200
+ if (params.model.includes("gemini-embedding-2") && contents.length > 0 && contents.every(
24201
+ (content) => typeof content === "string" || !Array.isArray(content) && !("parts" in content)
24202
+ )) {
24203
+ contents = [contents];
24204
+ }
23490
24205
  const input = {
23491
- model: params.model,
23492
- contents: serializeContentCollection(params.contents)
24206
+ inputs: contents.map((content) => {
24207
+ const parts = typeof content === "string" ? [content] : Array.isArray(content) ? content : "parts" in content ? content.parts : [content];
24208
+ const normalized = parts.flatMap((part) => {
24209
+ if (typeof part === "string") return [{ type: "text", text: part }];
24210
+ if (part.text !== void 0) return [{ type: "text", text: part.text }];
24211
+ const media = part.inlineData ?? part.fileData;
24212
+ if (!media) return [];
24213
+ const data = "data" in media ? `data:${media.mimeType};base64,${typeof media.data === "string" ? media.data : uint8ArrayToBase64(media.data)}` : media.fileUri;
24214
+ return media.mimeType?.startsWith("image/") ? [{ type: "image_url", image_url: { url: data } }] : [
24215
+ {
24216
+ type: "file",
24217
+ file: {
24218
+ file_data: data,
24219
+ ..."displayName" in media && media.displayName ? { filename: media.displayName } : {}
24220
+ }
24221
+ }
24222
+ ];
24223
+ });
24224
+ return {
24225
+ content: normalized.length === 1 && normalized[0].type === "text" ? normalized[0].text : normalized
24226
+ };
24227
+ }),
24228
+ ...params.config?.outputDimensionality !== void 0 ? { output_dimensions: params.config.outputDimensionality } : {}
23493
24229
  };
23494
- const config = params.config ? tryToDict(params.config) : null;
23495
- if (config) {
23496
- input.config = config;
24230
+ try {
24231
+ const processed = processInputAttachments(input);
24232
+ const hasInlineMedia = processed.inputs.some(
24233
+ ({ content }) => Array.isArray(content) && content.some((part) => {
24234
+ const data = part.type === "image_url" ? part.image_url.url : part.type === "file" ? part.file.file_data : void 0;
24235
+ return typeof data === "string" && data.startsWith("data:");
24236
+ })
24237
+ );
24238
+ return hasInlineMedia ? input : processed;
24239
+ } catch (error) {
24240
+ debugLogger.error(
24241
+ "Error processing Google GenAI embedding attachments:",
24242
+ error
24243
+ );
24244
+ return input;
23497
24245
  }
23498
- return input;
23499
24246
  }
23500
24247
  function serializeInteractionInput(params) {
23501
24248
  const input = {
@@ -23683,19 +24430,6 @@ function extractGenerateContentMetadata(params) {
23683
24430
  }
23684
24431
  return metadata;
23685
24432
  }
23686
- function extractEmbedContentMetadata(params) {
23687
- const metadata = {};
23688
- if (params.model) {
23689
- metadata.model = params.model;
23690
- }
23691
- const config = params.config ? tryToDict(params.config) : null;
23692
- if (config) {
23693
- Object.keys(config).forEach((key) => {
23694
- metadata[key] = config[key];
23695
- });
23696
- }
23697
- return metadata;
23698
- }
23699
24433
  function extractGenerateContentMetrics(response, startTime) {
23700
24434
  const metrics = {};
23701
24435
  if (startTime !== void 0) {
@@ -23715,15 +24449,23 @@ function extractEmbedContentMetrics(response, startTime) {
23715
24449
  const end = getCurrentUnixTimestamp();
23716
24450
  metrics.start = startTime;
23717
24451
  metrics.end = end;
23718
- metrics.duration = end - startTime;
23719
- }
23720
- if (response?.usageMetadata) {
23721
- populateUsageMetrics(metrics, response.usageMetadata);
23722
24452
  }
23723
24453
  const embeddingTokenCount = extractEmbedPromptTokenCount(response);
23724
24454
  if (embeddingTokenCount !== void 0) {
23725
24455
  metrics.prompt_tokens = embeddingTokenCount;
23726
- metrics.tokens = embeddingTokenCount;
24456
+ }
24457
+ const totalTokens = response?.usageMetadata?.totalTokenCount ?? embeddingTokenCount;
24458
+ if (totalTokens !== void 0) {
24459
+ metrics.tokens = totalTokens;
24460
+ }
24461
+ const audioTokens = (response?.usageMetadata?.promptTokenDetails ?? response?.usageMetadata?.promptTokensDetails)?.filter(
24462
+ (detail) => detail.modality === "AUDIO" && detail.tokenCount !== void 0
24463
+ );
24464
+ if (audioTokens?.length) {
24465
+ metrics.prompt_audio_tokens = audioTokens.reduce(
24466
+ (sum, detail) => sum + (detail.tokenCount ?? 0),
24467
+ 0
24468
+ );
23727
24469
  }
23728
24470
  return metrics;
23729
24471
  }
@@ -23762,41 +24504,25 @@ function extractEmbedPromptTokenCount(response) {
23762
24504
  if (typeof usagePromptTokens === "number" && Number.isFinite(usagePromptTokens)) {
23763
24505
  return usagePromptTokens;
23764
24506
  }
23765
- const usageTotalTokens = response.usageMetadata?.totalTokenCount;
23766
- if (typeof usageTotalTokens === "number" && Number.isFinite(usageTotalTokens)) {
23767
- return usageTotalTokens;
23768
- }
23769
24507
  const embeddings = Array.isArray(response.embeddings) ? response.embeddings : response.embedding ? [response.embedding] : [];
23770
24508
  if (embeddings.length === 0) {
23771
24509
  return void 0;
23772
24510
  }
23773
24511
  let total = 0;
23774
- let sawAny = false;
23775
24512
  for (const embedding of embeddings) {
23776
24513
  const embeddingStats = tryToDict(tryToDict(embedding)?.statistics);
23777
24514
  const tokenCount2 = embeddingStats?.tokenCount;
23778
24515
  if (typeof tokenCount2 === "number" && Number.isFinite(tokenCount2)) {
23779
24516
  total += tokenCount2;
23780
- sawAny = true;
24517
+ } else {
24518
+ return void 0;
23781
24519
  }
23782
24520
  }
23783
- return sawAny ? total : void 0;
24521
+ return total;
23784
24522
  }
23785
24523
  function summarizeEmbedContentOutput(response) {
23786
- if (!response) {
23787
- return void 0;
23788
- }
23789
- const embeddings = Array.isArray(response.embeddings) ? response.embeddings : response.embedding ? [response.embedding] : [];
23790
- if (embeddings.length === 0) {
23791
- return void 0;
23792
- }
23793
- const firstValues = embeddings[0]?.values;
23794
- if (!Array.isArray(firstValues)) {
23795
- return void 0;
23796
- }
23797
24524
  return {
23798
- embedding_count: embeddings.length,
23799
- embedding_length: firstValues.length
24525
+ count: Array.isArray(response?.embeddings) ? response.embeddings.length : response?.embedding ? 1 : 0
23800
24526
  };
23801
24527
  }
23802
24528
  function populateUsageMetrics(metrics, usage) {
@@ -27423,6 +28149,379 @@ function aggregateMistralStreamChunks(chunks) {
27423
28149
  };
27424
28150
  }
27425
28151
 
28152
+ // src/instrumentation/plugins/langgraph-sdk-channels.ts
28153
+ var langGraphSDKChannels = defineChannels(
28154
+ "@langchain/langgraph-sdk",
28155
+ {
28156
+ wait: channel({
28157
+ channelName: "runs.wait",
28158
+ kind: "async"
28159
+ }),
28160
+ stream: channel({
28161
+ channelName: "runs.stream",
28162
+ kind: "sync-stream"
28163
+ })
28164
+ },
28165
+ { instrumentationName: INSTRUMENTATION_NAMES.LANGGRAPH_SDK }
28166
+ );
28167
+
28168
+ // src/instrumentation/plugins/langgraph-sdk-plugin.ts
28169
+ var LangGraphSDKPlugin = class extends BasePlugin {
28170
+ onEnable() {
28171
+ this.unsubscribers.push(
28172
+ langGraphSDKChannels.wait.intercept(
28173
+ (target, self, args) => instrumentRun("wait", args, () => Reflect.apply(target, self, args))
28174
+ ),
28175
+ langGraphSDKChannels.stream.intercept(
28176
+ (target, self, args) => instrumentRun("stream", args, () => Reflect.apply(target, self, args))
28177
+ )
28178
+ );
28179
+ }
28180
+ onDisable() {
28181
+ this.unsubscribers = unsubscribeAll(this.unsubscribers);
28182
+ }
28183
+ };
28184
+ function normalizeMessage(value) {
28185
+ if (!isObject(value)) return value;
28186
+ 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);
28187
+ if (typeof role !== "string") return value;
28188
+ const message = {
28189
+ role,
28190
+ content: value.content ?? ""
28191
+ };
28192
+ for (const key of ["name", "tool_call_id", "refusal"]) {
28193
+ if (value[key] !== void 0) message[key] = value[key];
28194
+ }
28195
+ const additional = isObject(value.additional_kwargs) ? value.additional_kwargs : {};
28196
+ const toolCalls = Array.isArray(value.tool_calls) && value.tool_calls.length ? value.tool_calls : additional.tool_calls;
28197
+ if (Array.isArray(toolCalls) && toolCalls.length > 0) {
28198
+ message.tool_calls = toolCalls.map((call) => {
28199
+ if (!isObject(call)) return call;
28200
+ if (isObject(call.function)) return call;
28201
+ return {
28202
+ id: call.id,
28203
+ type: "function",
28204
+ function: {
28205
+ name: call.name,
28206
+ arguments: typeof call.args === "string" ? call.args : JSON.stringify(call.args ?? {})
28207
+ }
28208
+ };
28209
+ });
28210
+ }
28211
+ if (Array.isArray(value.invalid_tool_calls) && value.invalid_tool_calls.length > 0)
28212
+ message.invalid_tool_calls = value.invalid_tool_calls;
28213
+ if (message.refusal === void 0 && additional.refusal !== void 0)
28214
+ message.refusal = additional.refusal;
28215
+ return message;
28216
+ }
28217
+ function normalizeRunError(value) {
28218
+ let name;
28219
+ let message;
28220
+ if (value instanceof Error) {
28221
+ name = value.name;
28222
+ message = value.message;
28223
+ } else if (isObject(value) && typeof value.error === "string" && typeof value.message === "string") {
28224
+ name = value.error;
28225
+ message = value.message;
28226
+ } else {
28227
+ return value;
28228
+ }
28229
+ for (let depth = 0; depth < 3; depth++) {
28230
+ try {
28231
+ const nested = JSON.parse(
28232
+ message.startsWith(`${name}: `) ? message.slice(name.length + 2) : message
28233
+ );
28234
+ if (!isObject(nested) || typeof nested.error !== "string" || typeof nested.message !== "string")
28235
+ break;
28236
+ name = nested.error;
28237
+ message = nested.message;
28238
+ } catch {
28239
+ break;
28240
+ }
28241
+ }
28242
+ if (value instanceof Error && name === value.name && message === value.message)
28243
+ return value;
28244
+ return Object.assign(new Error(message), { name });
28245
+ }
28246
+ function normalizeState(value) {
28247
+ if (!isObject(value)) return value;
28248
+ return Object.fromEntries(
28249
+ Object.entries(value).map(([key, field]) => {
28250
+ if (key === "messages" && Array.isArray(field))
28251
+ return [key, field.map(normalizeMessage)];
28252
+ if (key === "__error__") {
28253
+ const error = normalizeRunError(field);
28254
+ if (error instanceof Error)
28255
+ return [key, { error: error.name, message: error.message }];
28256
+ }
28257
+ return [key, field];
28258
+ })
28259
+ );
28260
+ }
28261
+ function normalizeRunOutput(value, input) {
28262
+ if (!isObject(value)) return value;
28263
+ if (Array.isArray(value.messages)) {
28264
+ if (value.__interrupt__ !== void 0 || value.__error__ !== void 0)
28265
+ return void 0;
28266
+ const inputMessages = isObject(input) && Array.isArray(input.messages) ? input.messages : [];
28267
+ let inputPrefixLength = 0;
28268
+ while (inputPrefixLength < inputMessages.length) {
28269
+ const previous = inputMessages[inputPrefixLength];
28270
+ const message = value.messages[inputPrefixLength];
28271
+ 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)))
28272
+ break;
28273
+ inputPrefixLength++;
28274
+ }
28275
+ for (let index = value.messages.length - 1; index >= inputPrefixLength; index--) {
28276
+ const message = value.messages[index];
28277
+ const normalized = normalizeMessage(message);
28278
+ if (!isObject(normalized)) continue;
28279
+ if (normalized.role === "user") return void 0;
28280
+ if (normalized.role !== "assistant") continue;
28281
+ if (inputMessages.some((previous) => {
28282
+ if (!isObject(previous) || !isObject(message)) return false;
28283
+ return previous.id !== void 0 && previous.id === message.id && JSON.stringify(normalizeMessage(previous)) === JSON.stringify(normalized);
28284
+ }))
28285
+ continue;
28286
+ return normalized;
28287
+ }
28288
+ return void 0;
28289
+ }
28290
+ const result = Object.fromEntries(
28291
+ Object.entries(value).filter(
28292
+ ([key]) => key !== "__interrupt__" && key !== "__error__"
28293
+ )
28294
+ );
28295
+ return !Object.keys(result).length && (value.__interrupt__ !== void 0 || value.__error__ !== void 0) ? void 0 : result;
28296
+ }
28297
+ function instrumentRun(operation, [threadId, assistantId, options], invoke) {
28298
+ if (isAutoInstrumentationSuppressed()) return invoke();
28299
+ const start = getCurrentUnixTimestamp();
28300
+ let span;
28301
+ try {
28302
+ const metadata = {
28303
+ "langgraph.thread_id": threadId,
28304
+ "langgraph.assistant_id": assistantId
28305
+ };
28306
+ for (const key of [
28307
+ "streamMode",
28308
+ "streamSubgraphs",
28309
+ "interruptBefore",
28310
+ "interruptAfter",
28311
+ "multitaskStrategy",
28312
+ "durability"
28313
+ ]) {
28314
+ if (options?.[key] !== void 0) metadata[key] = options[key];
28315
+ }
28316
+ span = startSpan(
28317
+ withSpanInstrumentationName(
28318
+ {
28319
+ name: `langgraph.runs.${operation}`,
28320
+ spanAttributes: { type: "task" /* TASK */ },
28321
+ event: {
28322
+ input: options?.command === void 0 ? normalizeState(options?.input) : {
28323
+ input: normalizeState(options.input),
28324
+ command: options.command
28325
+ },
28326
+ metadata
28327
+ }
28328
+ },
28329
+ INSTRUMENTATION_NAMES.LANGGRAPH_SDK
28330
+ )
28331
+ );
28332
+ } catch (error) {
28333
+ debugLogger.error("Error starting LangGraph SDK span:", error);
28334
+ return invoke();
28335
+ }
28336
+ let ended = false;
28337
+ let output;
28338
+ let streamError;
28339
+ let firstToken;
28340
+ const updates = [];
28341
+ const usageByMessage = /* @__PURE__ */ new Map();
28342
+ const captureUsage = (id, usage) => {
28343
+ if (!isObject(usage)) return;
28344
+ const metrics = {};
28345
+ for (const [source, destination] of [
28346
+ ["input_tokens", "prompt_tokens"],
28347
+ ["output_tokens", "completion_tokens"],
28348
+ ["total_tokens", "tokens"]
28349
+ ]) {
28350
+ const value = usage[source];
28351
+ if (typeof value === "number" && Number.isFinite(value) && value >= 0)
28352
+ metrics[destination] = value;
28353
+ }
28354
+ if (metrics.tokens === void 0 && metrics.prompt_tokens !== void 0 && metrics.completion_tokens !== void 0)
28355
+ metrics.tokens = metrics.prompt_tokens + metrics.completion_tokens;
28356
+ usageByMessage.set(id, { ...usageByMessage.get(id), ...metrics });
28357
+ };
28358
+ const messages = /* @__PURE__ */ new Map();
28359
+ const messageSnapshots = /* @__PURE__ */ new Map();
28360
+ const finish = (error) => {
28361
+ if (ended) return;
28362
+ ended = true;
28363
+ try {
28364
+ const metrics = {};
28365
+ for (const usage of usageByMessage.values()) {
28366
+ for (const [key, value] of Object.entries(usage))
28367
+ metrics[key] = (metrics[key] ?? 0) + value;
28368
+ }
28369
+ if (firstToken !== void 0)
28370
+ metrics.time_to_first_token = firstToken - start;
28371
+ const finalMessages = [
28372
+ ...new Map([...messages, ...messageSnapshots]).values()
28373
+ ];
28374
+ let loggedOutput = normalizeRunOutput(output, options?.input);
28375
+ if (loggedOutput === void 0 && finalMessages.length)
28376
+ loggedOutput = normalizeRunOutput(
28377
+ { messages: finalMessages },
28378
+ void 0
28379
+ );
28380
+ if (output === void 0 && !finalMessages.length && updates.length) {
28381
+ const results = updates.map((update) => normalizeRunOutput(update, options?.input)).filter((update) => update !== void 0);
28382
+ if (results.length) loggedOutput = { updates: results };
28383
+ }
28384
+ const interrupted = [output, ...updates].find(
28385
+ (state) => isObject(state) && state.__interrupt__ !== void 0
28386
+ );
28387
+ span.log({
28388
+ ...loggedOutput !== void 0 ? { output: loggedOutput } : {},
28389
+ ...isObject(interrupted) ? { metadata: { "langgraph.interrupts": interrupted.__interrupt__ } } : {},
28390
+ ...error !== void 0 || streamError !== void 0 ? { error: normalizeRunError(error ?? streamError) } : {},
28391
+ metrics
28392
+ });
28393
+ } catch (error2) {
28394
+ debugLogger.error("Error logging LangGraph SDK span:", error2);
28395
+ }
28396
+ try {
28397
+ span.end();
28398
+ } catch (error2) {
28399
+ debugLogger.error("Error ending LangGraph SDK span:", error2);
28400
+ }
28401
+ };
28402
+ const observeMessages = (value, streaming) => {
28403
+ if (!isObject(value) || !Array.isArray(value.messages)) return;
28404
+ const inputMessages = isObject(options?.input) && Array.isArray(options.input.messages) ? options.input.messages : [];
28405
+ for (const message of value.messages) {
28406
+ if (!isObject(message) || message.type !== "ai" && message.role !== "assistant")
28407
+ continue;
28408
+ if (message.id !== void 0 && inputMessages.some(
28409
+ (input) => isObject(input) && input.id === message.id
28410
+ ))
28411
+ continue;
28412
+ captureUsage(
28413
+ typeof message.id === "string" ? message.id : "message",
28414
+ message.usage_metadata
28415
+ );
28416
+ if (streaming && (typeof message.content === "string" ? message.content.length > 0 : Array.isArray(message.content) && message.content.some(
28417
+ (part) => isObject(part) && typeof part.text === "string" && part.text.length > 0
28418
+ )))
28419
+ firstToken ??= getCurrentUnixTimestamp();
28420
+ }
28421
+ };
28422
+ const onChunk = ({ event, data }) => {
28423
+ if (ended) return;
28424
+ if (event === "metadata" && isObject(data)) {
28425
+ if (typeof data.run_id === "string")
28426
+ span.log({ metadata: { "langgraph.run_id": data.run_id } });
28427
+ } else if (event === "error") {
28428
+ streamError = normalizeRunError(data);
28429
+ } else if (event === "values") {
28430
+ output = data;
28431
+ observeMessages(data, true);
28432
+ } else if (event === "updates") {
28433
+ if (isObject(data)) {
28434
+ const stateUpdates = [];
28435
+ for (const [node, update] of Object.entries(data)) {
28436
+ observeMessages(update, true);
28437
+ if (isObject(update) && Array.isArray(update.messages)) {
28438
+ for (const message of update.messages) {
28439
+ if (isObject(message))
28440
+ messageSnapshots.set(
28441
+ typeof message.id === "string" ? message.id : `update-${messageSnapshots.size}`,
28442
+ message
28443
+ );
28444
+ }
28445
+ const state = Object.fromEntries(
28446
+ Object.entries(update).filter(([key]) => key !== "messages")
28447
+ );
28448
+ if (Object.keys(state).length) stateUpdates.push([node, state]);
28449
+ } else {
28450
+ stateUpdates.push([node, update]);
28451
+ }
28452
+ }
28453
+ if (stateUpdates.length) updates.push(Object.fromEntries(stateUpdates));
28454
+ } else {
28455
+ updates.push(data);
28456
+ }
28457
+ } else if ((event === "messages" || event === "messages/partial" || event === "messages/complete") && Array.isArray(data)) {
28458
+ const parts = event === "messages" ? [data[0]] : data;
28459
+ for (const part of parts) {
28460
+ if (!isObject(part)) continue;
28461
+ const id = typeof part.id === "string" ? part.id : "message";
28462
+ captureUsage(id, part.usage_metadata);
28463
+ const previous = messages.get(id);
28464
+ messages.set(
28465
+ id,
28466
+ event === "messages" && previous && typeof part.content === "string" && typeof previous.content === "string" ? { ...part, content: previous.content + part.content } : part
28467
+ );
28468
+ if (typeof part.content === "string" && part.content.length > 0)
28469
+ firstToken ??= getCurrentUnixTimestamp();
28470
+ }
28471
+ }
28472
+ };
28473
+ let result;
28474
+ try {
28475
+ result = withCurrent(
28476
+ span,
28477
+ () => runWithAutoInstrumentationSuppressed(invoke)
28478
+ );
28479
+ } catch (error) {
28480
+ finish(error);
28481
+ throw error;
28482
+ }
28483
+ if (operation === "stream") {
28484
+ try {
28485
+ patchStreamIfNeeded(result, {
28486
+ shouldCollect: (chunk) => {
28487
+ try {
28488
+ onChunk(chunk);
28489
+ } catch (error) {
28490
+ debugLogger.error(
28491
+ "Error processing LangGraph stream event:",
28492
+ error
28493
+ );
28494
+ }
28495
+ return false;
28496
+ },
28497
+ aroundNext: (next) => withCurrent(span, () => runWithAutoInstrumentationSuppressed(next)),
28498
+ onComplete: () => finish(),
28499
+ onCancel: () => finish(),
28500
+ onError: (error) => finish(error)
28501
+ });
28502
+ } catch (error) {
28503
+ debugLogger.error("Error observing LangGraph stream:", error);
28504
+ finish();
28505
+ }
28506
+ } else {
28507
+ void Promise.resolve(result).then(
28508
+ (value) => {
28509
+ try {
28510
+ output = value;
28511
+ observeMessages(value, false);
28512
+ if (isObject(value) && isObject(value.__error__))
28513
+ streamError = normalizeRunError(value.__error__);
28514
+ finish();
28515
+ } catch (error) {
28516
+ finish(error);
28517
+ }
28518
+ },
28519
+ (error) => finish(error)
28520
+ );
28521
+ }
28522
+ return result;
28523
+ }
28524
+
27426
28525
  // src/instrumentation/plugins/ollama-channels.ts
27427
28526
  var ollamaChannels = defineChannels(
27428
28527
  "ollama",
@@ -27632,7 +28731,7 @@ function normalizeTextAndImages(content, images) {
27632
28731
  ...unrecognizedImages.length > 0 ? { unrecognizedImages } : {}
27633
28732
  };
27634
28733
  }
27635
- function normalizeMessage(message, toolCallId, syntheticToolCallIdOffset = 0) {
28734
+ function normalizeMessage2(message, toolCallId, syntheticToolCallIdOffset = 0) {
27636
28735
  if (typeof message.role !== "string") {
27637
28736
  return void 0;
27638
28737
  }
@@ -27678,7 +28777,7 @@ function normalizeMessages(messages) {
27678
28777
  toolCallId = pendingToolCallIds.get(toolName)?.shift();
27679
28778
  }
27680
28779
  }
27681
- const normalized = normalizeMessage(
28780
+ const normalized = normalizeMessage2(
27682
28781
  ollamaMessage,
27683
28782
  toolCallId,
27684
28783
  syntheticToolCallIdOffset
@@ -27797,7 +28896,7 @@ function extractOllamaChatOutput(result, syntheticToolCallIdOffset = 0) {
27797
28896
  if (!isObject(result) || !isObject(result.message)) {
27798
28897
  return void 0;
27799
28898
  }
27800
- const message = normalizeMessage(
28899
+ const message = normalizeMessage2(
27801
28900
  result.message,
27802
28901
  void 0,
27803
28902
  syntheticToolCallIdOffset
@@ -30517,14 +31616,14 @@ function extractActionSpanMetadata(args) {
30517
31616
  const options = extractRunInNewSpanOptions(args);
30518
31617
  const labels = isObject(options?.labels) ? options.labels : void 0;
30519
31618
  const metadata = isObject(options?.metadata) ? options.metadata : void 0;
30520
- const actionType = stringValue(labels?.["genkit:metadata:subtype"]);
30521
- const name = stringValue(metadata?.name);
31619
+ const actionType = stringValue2(labels?.["genkit:metadata:subtype"]);
31620
+ const name = stringValue2(metadata?.name);
30522
31621
  if (!actionType || !name) {
30523
31622
  return void 0;
30524
31623
  }
30525
31624
  return {
30526
31625
  actionType,
30527
- key: stringValue(labels?.["genkit:key"]),
31626
+ key: stringValue2(labels?.["genkit:key"]),
30528
31627
  name
30529
31628
  };
30530
31629
  }
@@ -30634,7 +31733,7 @@ function pickNumberMetrics(values) {
30634
31733
  })
30635
31734
  );
30636
31735
  }
30637
- function stringValue(value) {
31736
+ function stringValue2(value) {
30638
31737
  return typeof value === "string" ? value : void 0;
30639
31738
  }
30640
31739
 
@@ -31319,7 +32418,7 @@ function subscribeToFlueContext(value, state) {
31319
32418
  try {
31320
32419
  unsubscribe?.();
31321
32420
  } catch (error) {
31322
- logInstrumentationError3("Flue context unsubscribe", error);
32421
+ logInstrumentationError4("Flue context unsubscribe", error);
31323
32422
  }
31324
32423
  };
31325
32424
  try {
@@ -31335,7 +32434,7 @@ function subscribeToFlueContext(value, state) {
31335
32434
  });
31336
32435
  state.contexts.add(value);
31337
32436
  } catch (error) {
31338
- logInstrumentationError3("Flue context subscription", error);
32437
+ logInstrumentationError4("Flue context subscription", error);
31339
32438
  }
31340
32439
  }
31341
32440
  function isAutoContextTerminalEvent(event, ctx) {
@@ -31391,7 +32490,7 @@ var FlueObserveBridge = class {
31391
32490
  try {
31392
32491
  this.handleEvent(event, flueContextFromUnknown(ctx));
31393
32492
  } catch (error) {
31394
- logInstrumentationError3("Flue observe", error);
32493
+ logInstrumentationError4("Flue observe", error);
31395
32494
  }
31396
32495
  }
31397
32496
  reset() {
@@ -31408,7 +32507,7 @@ var FlueObserveBridge = class {
31408
32507
  try {
31409
32508
  span = this.spanForExecutionOperation(operation, executionContext);
31410
32509
  } catch (error) {
31411
- logInstrumentationError3("Flue execution interceptor", error);
32510
+ logInstrumentationError4("Flue execution interceptor", error);
31412
32511
  }
31413
32512
  return span ? runWithCurrentSpanStore(span, next) : next();
31414
32513
  }
@@ -31614,7 +32713,7 @@ var FlueObserveBridge = class {
31614
32713
  this.runsById.delete(event.runId);
31615
32714
  }
31616
32715
  void flush().catch((error) => {
31617
- logInstrumentationError3("Flue flush", error);
32716
+ logInstrumentationError4("Flue flush", error);
31618
32717
  });
31619
32718
  }
31620
32719
  handleOperationStart(event) {
@@ -32389,17 +33488,17 @@ function safeLog3(span, event) {
32389
33488
  try {
32390
33489
  span.log(event);
32391
33490
  } catch (error) {
32392
- logInstrumentationError3("Flue span log", error);
33491
+ logInstrumentationError4("Flue span log", error);
32393
33492
  }
32394
33493
  }
32395
33494
  function safeEnd(span, endTime) {
32396
33495
  try {
32397
33496
  span.end(endTime === void 0 ? void 0 : { endTime });
32398
33497
  } catch (error) {
32399
- logInstrumentationError3("Flue span end", error);
33498
+ logInstrumentationError4("Flue span end", error);
32400
33499
  }
32401
33500
  }
32402
- function logInstrumentationError3(label, error) {
33501
+ function logInstrumentationError4(label, error) {
32403
33502
  debugLogger.debug(`Error in ${label} instrumentation:`, error);
32404
33503
  }
32405
33504
 
@@ -32967,10 +34066,10 @@ var LangSmithPlugin = class extends BasePlugin {
32967
34066
  const creates = ownValue(batch, "runCreates");
32968
34067
  if (Array.isArray(creates)) {
32969
34068
  const parentFirst = [...creates].sort((left, right) => {
32970
- const leftId = stringValue2(ownValue(left, "id"));
32971
- const rightId = stringValue2(ownValue(right, "id"));
32972
- const leftParent = stringValue2(ownValue(left, "parent_run_id"));
32973
- const rightParent = stringValue2(ownValue(right, "parent_run_id"));
34069
+ const leftId = stringValue3(ownValue(left, "id"));
34070
+ const rightId = stringValue3(ownValue(right, "id"));
34071
+ const leftParent = stringValue3(ownValue(left, "parent_run_id"));
34072
+ const rightParent = stringValue3(ownValue(right, "parent_run_id"));
32974
34073
  if (leftParent && leftParent === rightId) {
32975
34074
  return 1;
32976
34075
  }
@@ -32989,13 +34088,13 @@ var LangSmithPlugin = class extends BasePlugin {
32989
34088
  if (Array.isArray(updates)) {
32990
34089
  for (const run of updates) {
32991
34090
  this.containLifecycleFailure("batchIngestRuns update", () => {
32992
- this.processUpdate(stringValue2(ownValue(run, "id")) ?? "", run);
34091
+ this.processUpdate(stringValue3(ownValue(run, "id")) ?? "", run);
32993
34092
  });
32994
34093
  }
32995
34094
  }
32996
34095
  }
32997
34096
  processCreate(run) {
32998
- const id = stringValue2(ownValue(run, "id"));
34097
+ const id = stringValue3(ownValue(run, "id"));
32999
34098
  if (!id || this.completedRuns.get(id)) {
33000
34099
  return;
33001
34100
  }
@@ -33028,7 +34127,7 @@ var LangSmithPlugin = class extends BasePlugin {
33028
34127
  this.endIfComplete(id, activeRun, run);
33029
34128
  }
33030
34129
  processUpdate(explicitId, run) {
33031
- const id = stringValue2(explicitId) ?? stringValue2(ownValue(run, "id"));
34130
+ const id = stringValue3(explicitId) ?? stringValue3(ownValue(run, "id"));
33032
34131
  if (!id || this.completedRuns.get(id)) {
33033
34132
  return;
33034
34133
  }
@@ -33051,13 +34150,13 @@ var LangSmithPlugin = class extends BasePlugin {
33051
34150
  this.endIfComplete(id, active, active.run);
33052
34151
  }
33053
34152
  startRunSpan(id, run) {
33054
- const traceId = stringValue2(ownValue(run, "trace_id")) ?? id;
33055
- const parentId = stringValue2(ownValue(run, "parent_run_id")) ?? stringValue2(ownValue(ownValue(run, "parent_run"), "id"));
34153
+ const traceId = stringValue3(ownValue(run, "trace_id")) ?? id;
34154
+ const parentId = stringValue3(ownValue(run, "parent_run_id")) ?? stringValue3(ownValue(ownValue(run, "parent_run"), "id"));
33056
34155
  const startTime = timestampSeconds(ownValue(run, "start_time"));
33057
34156
  return startSpan(
33058
34157
  withSpanInstrumentationName(
33059
34158
  {
33060
- name: stringValue2(ownValue(run, "name")) ?? "LangSmith run",
34159
+ name: stringValue3(ownValue(run, "name")) ?? "LangSmith run",
33061
34160
  spanId: id,
33062
34161
  parentSpanIds: {
33063
34162
  parentSpanIds: parentId ? [parentId] : [],
@@ -33149,7 +34248,7 @@ function mergeRuns(previous, current) {
33149
34248
  function isRecord2(value) {
33150
34249
  return typeof value === "object" && value !== null && !Array.isArray(value);
33151
34250
  }
33152
- function stringValue2(value) {
34251
+ function stringValue3(value) {
33153
34252
  return typeof value === "string" && value.length > 0 ? value : void 0;
33154
34253
  }
33155
34254
  function timestampSeconds(value) {
@@ -33167,7 +34266,7 @@ function timestampSeconds(value) {
33167
34266
  return void 0;
33168
34267
  }
33169
34268
  function dottedOrderDepth(run) {
33170
- const dottedOrder = stringValue2(ownValue(run, "dotted_order"));
34269
+ const dottedOrder = stringValue3(ownValue(run, "dotted_order"));
33171
34270
  return dottedOrder ? dottedOrder.split(".").length : Number.MAX_SAFE_INTEGER;
33172
34271
  }
33173
34272
  function mapRunType(runType) {
@@ -33372,7 +34471,7 @@ var PiCodingAgentPlugin = class extends BasePlugin {
33372
34471
  }
33373
34472
  );
33374
34473
  } catch (error) {
33375
- logInstrumentationError4("Pi Coding Agent prompt start", error);
34474
+ logInstrumentationError5("Pi Coding Agent prompt start", error);
33376
34475
  }
33377
34476
  if (!state) {
33378
34477
  return runWithAutoInstrumentationSuppressed(invokeTarget);
@@ -33505,12 +34604,12 @@ function installPiAgentInstrumentation(agent) {
33505
34604
  () => handlePiAgentEvent(state, event)
33506
34605
  );
33507
34606
  } catch (error) {
33508
- logInstrumentationError4("Pi Coding Agent event", error);
34607
+ logInstrumentationError5("Pi Coding Agent event", error);
33509
34608
  }
33510
34609
  });
33511
34610
  piAgentEventSubscriptions.add(agent);
33512
34611
  } catch (error) {
33513
- logInstrumentationError4("Pi Coding Agent event subscription", error);
34612
+ logInstrumentationError5("Pi Coding Agent event subscription", error);
33514
34613
  }
33515
34614
  }
33516
34615
  function makeInstrumentedStreamFunction(agent, originalStreamFunction, property) {
@@ -33560,7 +34659,7 @@ function wrapPiToolExecutors(tools) {
33560
34659
  });
33561
34660
  tool.execute = wrappedExecute;
33562
34661
  } catch (error) {
33563
- logInstrumentationError4("Pi Coding Agent tool wrapping", error);
34662
+ logInstrumentationError5("Pi Coding Agent tool wrapping", error);
33564
34663
  }
33565
34664
  }
33566
34665
  }
@@ -33639,7 +34738,7 @@ function patchAssistantMessageStream(stream, promptState, llmState) {
33639
34738
  try {
33640
34739
  await iterator.return();
33641
34740
  } catch (cleanupError) {
33642
- logInstrumentationError4(
34741
+ logInstrumentationError5(
33643
34742
  "Pi Coding Agent stream cleanup",
33644
34743
  cleanupError
33645
34744
  );
@@ -33804,7 +34903,7 @@ function finishPiPromptRun(state, error) {
33804
34903
  try {
33805
34904
  state.span.end();
33806
34905
  } catch (endError) {
33807
- logInstrumentationError4("Pi Coding Agent prompt end", endError);
34906
+ logInstrumentationError5("Pi Coding Agent prompt end", endError);
33808
34907
  }
33809
34908
  }
33810
34909
  }
@@ -34136,10 +35235,10 @@ function safeLog4(span, event) {
34136
35235
  try {
34137
35236
  span.log(event);
34138
35237
  } catch (error) {
34139
- logInstrumentationError4("Pi Coding Agent span log", error);
35238
+ logInstrumentationError5("Pi Coding Agent span log", error);
34140
35239
  }
34141
35240
  }
34142
- function logInstrumentationError4(context, error) {
35241
+ function logInstrumentationError5(context, error) {
34143
35242
  debugLogger.debug(`${context}:`, error);
34144
35243
  }
34145
35244
 
@@ -34377,7 +35476,7 @@ function handleAgentStreamEvent(state, event) {
34377
35476
  finalizeModelSpan(state, event);
34378
35477
  break;
34379
35478
  case "beforeToolCallEvent":
34380
- startToolSpan2(state, event);
35479
+ startToolSpan3(state, event);
34381
35480
  break;
34382
35481
  case "afterToolCallEvent":
34383
35482
  finalizeToolSpan(state, event);
@@ -34402,7 +35501,7 @@ function handleAgentStreamEvent(state, event) {
34402
35501
  break;
34403
35502
  }
34404
35503
  } catch (error) {
34405
- logInstrumentationError5("Strands Agent SDK event", error);
35504
+ logInstrumentationError6("Strands Agent SDK event", error);
34406
35505
  }
34407
35506
  }
34408
35507
  function handleMultiAgentStreamEvent(state, event, activeChildParents) {
@@ -34438,7 +35537,7 @@ function handleMultiAgentStreamEvent(state, event, activeChildParents) {
34438
35537
  break;
34439
35538
  }
34440
35539
  } catch (error) {
34441
- logInstrumentationError5("Strands Agent SDK multi-agent event", error);
35540
+ logInstrumentationError6("Strands Agent SDK multi-agent event", error);
34442
35541
  }
34443
35542
  }
34444
35543
  function buildModelSpanInput(event, attachmentCache) {
@@ -34517,7 +35616,7 @@ function finalizeModelSpan(state, event) {
34517
35616
  });
34518
35617
  modelState.span.end();
34519
35618
  }
34520
- function startToolSpan2(state, event) {
35619
+ function startToolSpan3(state, event) {
34521
35620
  const toolUse = event.toolUse;
34522
35621
  const key = toolKey2(toolUse);
34523
35622
  if (state.activeTools.has(key)) {
@@ -34797,7 +35896,7 @@ function getModelConfig(model) {
34797
35896
  try {
34798
35897
  return model.getConfig();
34799
35898
  } catch (error) {
34800
- logInstrumentationError5("Strands Agent SDK model config", error);
35899
+ logInstrumentationError6("Strands Agent SDK model config", error);
34801
35900
  return void 0;
34802
35901
  }
34803
35902
  }
@@ -34880,7 +35979,7 @@ function processStrandsInputAttachments(input, cache = createStrandsAttachmentCa
34880
35979
  try {
34881
35980
  return processStrandsInputNode(input, cache);
34882
35981
  } catch (error) {
34883
- logInstrumentationError5("Strands Agent SDK input attachments", error);
35982
+ logInstrumentationError6("Strands Agent SDK input attachments", error);
34884
35983
  return input;
34885
35984
  }
34886
35985
  }
@@ -35100,10 +36199,10 @@ function safeLog5(span, event) {
35100
36199
  try {
35101
36200
  span.log(event);
35102
36201
  } catch (error) {
35103
- logInstrumentationError5("Strands Agent SDK span log", error);
36202
+ logInstrumentationError6("Strands Agent SDK span log", error);
35104
36203
  }
35105
36204
  }
35106
- function logInstrumentationError5(context, error) {
36205
+ function logInstrumentationError6(context, error) {
35107
36206
  debugLogger.debug(`${context}:`, error);
35108
36207
  }
35109
36208
 
@@ -35506,10 +36605,10 @@ function observeAudioStream(value, observe, complete, cancel, span) {
35506
36605
  const getReader = value.getReader;
35507
36606
  value.getReader = function(...args) {
35508
36607
  const reader = Reflect.apply(getReader, this, args);
35509
- const read2 = reader.read;
36608
+ const read3 = reader.read;
35510
36609
  reader.read = function(...readArgs) {
35511
36610
  return Promise.resolve(
35512
- withCurrent(span, () => Reflect.apply(read2, this, readArgs))
36611
+ withCurrent(span, () => Reflect.apply(read3, this, readArgs))
35513
36612
  ).then(
35514
36613
  (result) => {
35515
36614
  if (result.value) safeObserve(result.value);
@@ -36003,14 +37102,14 @@ var CloudflareAIChatPlugin = class extends BasePlugin {
36003
37102
  const result = event.arguments[0];
36004
37103
  state = agent ? this.findResponseState(
36005
37104
  agent,
36006
- stringValue3(ownValue2(result, "requestId"))
37105
+ stringValue4(ownValue2(result, "requestId"))
36007
37106
  ) : void 0;
36008
37107
  if (!state) {
36009
37108
  return;
36010
37109
  }
36011
37110
  state.responseObserved = true;
36012
37111
  const output = serializeMessage(ownValue2(result, "message"));
36013
- const status = stringValue3(ownValue2(result, "status"));
37112
+ const status = stringValue4(ownValue2(result, "status"));
36014
37113
  const error = ownValue2(result, "error");
36015
37114
  const input = ownValue2(result, "continuation") === true ? state.input : serializeMessages(readProperty(agent, "messages"))?.filter(
36016
37115
  (message) => typeof output?.id !== "string" || message.id !== output.id
@@ -36057,7 +37156,7 @@ var CloudflareAIChatPlugin = class extends BasePlugin {
36057
37156
  }
36058
37157
  try {
36059
37158
  const agent = asObject(event.self);
36060
- const requestId = stringValue3(event.arguments[0]);
37159
+ const requestId = stringValue4(event.arguments[0]);
36061
37160
  const key = requestId ?? /* @__PURE__ */ Symbol("cloudflare-ai-chat-turn");
36062
37161
  const activeForAgent = agent ? this.getActiveTurns(agent) : void 0;
36063
37162
  const existing = activeForAgent?.get(key);
@@ -36226,7 +37325,7 @@ function ownValue2(value, key) {
36226
37325
  const descriptor = Object.getOwnPropertyDescriptor(object, key);
36227
37326
  return descriptor && "value" in descriptor ? descriptor.value : void 0;
36228
37327
  }
36229
- function stringValue3(value) {
37328
+ function stringValue4(value) {
36230
37329
  return typeof value === "string" ? value : void 0;
36231
37330
  }
36232
37331
  function serializeMessages(value) {
@@ -36344,7 +37443,7 @@ var CloudflareAgentsPlugin = class extends BasePlugin {
36344
37443
  );
36345
37444
  spans.set(event, span);
36346
37445
  } catch (error) {
36347
- logInstrumentationError6("start", error);
37446
+ logInstrumentationError7("start", error);
36348
37447
  }
36349
37448
  },
36350
37449
  asyncEnd: (event) => {
@@ -36364,7 +37463,7 @@ var CloudflareAgentsPlugin = class extends BasePlugin {
36364
37463
  }
36365
37464
  }
36366
37465
  } catch (error) {
36367
- logInstrumentationError6("completion", error);
37466
+ logInstrumentationError7("completion", error);
36368
37467
  } finally {
36369
37468
  safelyEndSpan(span);
36370
37469
  }
@@ -36378,7 +37477,7 @@ var CloudflareAgentsPlugin = class extends BasePlugin {
36378
37477
  try {
36379
37478
  span.log({ error: event.error });
36380
37479
  } catch (error) {
36381
- logInstrumentationError6("rejection", error);
37480
+ logInstrumentationError7("rejection", error);
36382
37481
  } finally {
36383
37482
  safelyEndSpan(span);
36384
37483
  }
@@ -36408,10 +37507,10 @@ function safelyEndSpan(span) {
36408
37507
  try {
36409
37508
  span.end();
36410
37509
  } catch (error) {
36411
- logInstrumentationError6("span end", error);
37510
+ logInstrumentationError7("span end", error);
36412
37511
  }
36413
37512
  }
36414
- function logInstrumentationError6(operation, error) {
37513
+ function logInstrumentationError7(operation, error) {
36415
37514
  debugLogger.error(
36416
37515
  `Failed to process Cloudflare Agents ${operation} instrumentation:`,
36417
37516
  error
@@ -36436,6 +37535,7 @@ var BraintrustPlugin = class extends BasePlugin {
36436
37535
  openRouterPlugin = null;
36437
37536
  openRouterAgentPlugin = null;
36438
37537
  mistralPlugin = null;
37538
+ langGraphSDKPlugin = null;
36439
37539
  ollamaPlugin = null;
36440
37540
  googleADKPlugin = null;
36441
37541
  coherePlugin = null;
@@ -36516,6 +37616,10 @@ var BraintrustPlugin = class extends BasePlugin {
36516
37616
  this.mistralPlugin = new MistralPlugin();
36517
37617
  this.mistralPlugin.enable();
36518
37618
  }
37619
+ if (integrations.langgraphSDK !== false) {
37620
+ this.langGraphSDKPlugin = new LangGraphSDKPlugin();
37621
+ this.langGraphSDKPlugin.enable();
37622
+ }
36519
37623
  if (integrations.ollama !== false) {
36520
37624
  this.ollamaPlugin = new OllamaPlugin();
36521
37625
  this.ollamaPlugin.enable();
@@ -36644,6 +37748,10 @@ var BraintrustPlugin = class extends BasePlugin {
36644
37748
  this.mistralPlugin.disable();
36645
37749
  this.mistralPlugin = null;
36646
37750
  }
37751
+ if (this.langGraphSDKPlugin) {
37752
+ this.langGraphSDKPlugin.disable();
37753
+ this.langGraphSDKPlugin = null;
37754
+ }
36647
37755
  if (this.ollamaPlugin) {
36648
37756
  this.ollamaPlugin.disable();
36649
37757
  this.ollamaPlugin = null;
@@ -36718,7 +37826,31 @@ var MAX_STORED_LLM_INPUTS = 100;
36718
37826
  var MAX_STORED_REASONING_BLOCKS = 100;
36719
37827
  var MAX_STORED_SPAN_REFERENCES = 1e4;
36720
37828
  var MAX_STORED_STEP_STARTS = 1e4;
37829
+ var EVE_HANDLED_EVENT_TYPES = /* @__PURE__ */ new Set([
37830
+ "action.result",
37831
+ "actions.requested",
37832
+ "message.completed",
37833
+ "message.received",
37834
+ "reasoning.completed",
37835
+ "result.completed",
37836
+ "session.completed",
37837
+ "session.failed",
37838
+ "session.started",
37839
+ "step.completed",
37840
+ "step.failed",
37841
+ "step.started",
37842
+ "subagent.called",
37843
+ "subagent.completed",
37844
+ "turn.completed",
37845
+ "turn.failed",
37846
+ "turn.started"
37847
+ ]);
36721
37848
  function braintrustEveHook(options) {
37849
+ if (!options || typeof options.defineState !== "function") {
37850
+ throw new TypeError(
37851
+ "braintrustEveHook requires Eve's defineState function"
37852
+ );
37853
+ }
36722
37854
  const state = options.defineState(EVE_TRACE_STATE_KEY, emptyEveTraceState);
36723
37855
  const bridge = new EveBridge(state);
36724
37856
  return {
@@ -36730,15 +37862,27 @@ function braintrustEveHook(options) {
36730
37862
  };
36731
37863
  }
36732
37864
  function createLegacyEveInstrumentation(options) {
37865
+ if (!options || typeof options.defineState !== "function") {
37866
+ throw new TypeError(
37867
+ "braintrustEveInstrumentation requires Eve's defineState function"
37868
+ );
37869
+ }
36733
37870
  const state = options.defineState(EVE_TRACE_STATE_KEY, emptyEveTraceState);
36734
37871
  return {
36735
37872
  events: {
36736
37873
  "step.started": (input) => {
36737
37874
  try {
37875
+ if (!isEveInstrumentationStepStartedEventInput(input)) {
37876
+ debugLogger.warn(
37877
+ "Ignoring malformed Eve instrumentation step.started event"
37878
+ );
37879
+ return void 0;
37880
+ }
36738
37881
  captureEveModelInput(state, input);
36739
37882
  } catch (error) {
36740
37883
  debugLogger.warn("Error in Eve LLM input capture:", error);
36741
37884
  }
37885
+ return void 0;
36742
37886
  }
36743
37887
  },
36744
37888
  recordInputs: false,
@@ -36747,7 +37891,77 @@ function createLegacyEveInstrumentation(options) {
36747
37891
  };
36748
37892
  }
36749
37893
  function isEveHandleMessageStreamEvent(event) {
36750
- return isObject(event) && typeof event["type"] === "string";
37894
+ if (!isObject(event) || typeof event["type"] !== "string") {
37895
+ return false;
37896
+ }
37897
+ const type = event["type"];
37898
+ if (type === "session.completed") {
37899
+ return true;
37900
+ }
37901
+ if (!isObject(event["data"])) {
37902
+ return false;
37903
+ }
37904
+ const data = event["data"];
37905
+ if (type === "session.started") {
37906
+ return true;
37907
+ }
37908
+ if (type === "session.failed") {
37909
+ return typeof data["sessionId"] === "string" && typeof data["code"] === "string" && typeof data["message"] === "string";
37910
+ }
37911
+ if (type === "session.waiting") {
37912
+ return data["wait"] === "next-user-message";
37913
+ }
37914
+ if (typeof data["turnId"] !== "string" || typeof data["sequence"] !== "number" || !Number.isFinite(data["sequence"])) {
37915
+ return false;
37916
+ }
37917
+ if (type === "turn.started" || type === "turn.completed" || type === "subagent.called" || type === "subagent.completed") {
37918
+ if (type === "subagent.called") {
37919
+ return typeof data["callId"] === "string" && typeof data["childSessionId"] === "string" && typeof data["name"] === "string";
37920
+ }
37921
+ if (type === "subagent.completed") {
37922
+ return typeof data["callId"] === "string" && typeof data["subagentName"] === "string";
37923
+ }
37924
+ return true;
37925
+ }
37926
+ if (type === "turn.failed") {
37927
+ return typeof data["code"] === "string" && typeof data["message"] === "string";
37928
+ }
37929
+ if (type === "message.received") {
37930
+ return typeof data["message"] === "string";
37931
+ }
37932
+ if (typeof data["stepIndex"] !== "number" || !Number.isFinite(data["stepIndex"]) || data["stepIndex"] < 0) {
37933
+ return false;
37934
+ }
37935
+ switch (type) {
37936
+ case "step.started":
37937
+ return true;
37938
+ case "message.completed":
37939
+ return typeof data["finishReason"] === "string" && (typeof data["message"] === "string" || data["message"] === null);
37940
+ case "reasoning.completed":
37941
+ return typeof data["reasoning"] === "string";
37942
+ case "result.completed":
37943
+ return true;
37944
+ case "step.completed":
37945
+ return typeof data["finishReason"] === "string";
37946
+ case "step.failed":
37947
+ return typeof data["code"] === "string" && typeof data["message"] === "string";
37948
+ case "actions.requested":
37949
+ return Array.isArray(data["actions"]);
37950
+ case "action.result":
37951
+ return isObject(data["result"]) && (data["status"] === "completed" || data["status"] === "failed" || data["status"] === "rejected");
37952
+ default:
37953
+ return false;
37954
+ }
37955
+ }
37956
+ function isEveInstrumentationStepStartedEventInput(input) {
37957
+ if (!isObject(input)) {
37958
+ return false;
37959
+ }
37960
+ const modelInput = input["modelInput"];
37961
+ const session = input["session"];
37962
+ const step = input["step"];
37963
+ const turn = input["turn"];
37964
+ 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"]);
36751
37965
  }
36752
37966
  var ResumedEveSpan = class {
36753
37967
  constructor(reference) {
@@ -36916,7 +38130,17 @@ var EveBridge = class {
36916
38130
  });
36917
38131
  }
36918
38132
  async handle(event, ctx, hookMetadata) {
38133
+ try {
38134
+ await this.handleUnchecked(event, ctx, hookMetadata);
38135
+ } catch (error) {
38136
+ debugLogger.warn("Error in Eve hook instrumentation:", error);
38137
+ }
38138
+ }
38139
+ async handleUnchecked(event, ctx, hookMetadata) {
36919
38140
  if (!isEveHandleMessageStreamEvent(event)) {
38141
+ if (isObject(event) && typeof event["type"] === "string" && EVE_HANDLED_EVENT_TYPES.has(event["type"])) {
38142
+ debugLogger.warn(`Ignoring malformed Eve hook ${event["type"]} event`);
38143
+ }
36920
38144
  return;
36921
38145
  }
36922
38146
  const run = async () => {
@@ -37242,9 +38466,14 @@ var EveBridge = class {
37242
38466
  }
37243
38467
  for (const action of traceActions) {
37244
38468
  const name = action.kind === "tool-call" ? action.toolName : action.subagentName ?? action.name ?? "agent";
38469
+ let args = "null";
38470
+ try {
38471
+ args = JSON.stringify(action.input) ?? "null";
38472
+ } catch {
38473
+ }
37245
38474
  toolCallsById.set(action.callId, {
37246
38475
  function: {
37247
- arguments: JSON.stringify(action.input),
38476
+ arguments: args,
37248
38477
  name
37249
38478
  },
37250
38479
  id: action.callId,
@@ -38113,17 +39342,33 @@ function consumeCapturedEveModelInput(state, sessionId, turnId, stepIndex) {
38113
39342
  }
38114
39343
  }
38115
39344
  function capturedModelInput(modelInput) {
38116
- const { instructions, messages } = modelInput;
38117
- const value = [];
38118
- if (typeof instructions === "string") {
38119
- value.push({ content: instructions, role: "system" });
38120
- } else if (Array.isArray(instructions)) {
38121
- value.push(...instructions.map(capturedEveModelMessage));
38122
- } else if (instructions) {
38123
- value.push(capturedEveModelMessage(instructions));
38124
- }
38125
- value.push(...messages.map(capturedEveModelMessage));
38126
39345
  try {
39346
+ if (!isObject(modelInput) || !Array.isArray(modelInput["messages"])) {
39347
+ return void 0;
39348
+ }
39349
+ const value = [];
39350
+ const instructions = modelInput["instructions"];
39351
+ if (typeof instructions === "string") {
39352
+ value.push({ content: instructions, role: "system" });
39353
+ } else if (Array.isArray(instructions)) {
39354
+ for (const instruction of instructions) {
39355
+ const captured = capturedEveModelMessage(instruction);
39356
+ if (captured?.role === "system") {
39357
+ value.push(captured);
39358
+ }
39359
+ }
39360
+ } else {
39361
+ const captured = capturedEveModelMessage(instructions);
39362
+ if (captured?.role === "system") {
39363
+ value.push(captured);
39364
+ }
39365
+ }
39366
+ for (const message of modelInput["messages"]) {
39367
+ const captured = capturedEveModelMessage(message);
39368
+ if (captured) {
39369
+ value.push(captured);
39370
+ }
39371
+ }
38127
39372
  const cloned = JSON.parse(JSON.stringify(value));
38128
39373
  if (!Array.isArray(cloned)) {
38129
39374
  return void 0;
@@ -38134,116 +39379,202 @@ function capturedModelInput(modelInput) {
38134
39379
  }
38135
39380
  }
38136
39381
  function capturedEveModelMessage(message) {
38137
- const { content, role } = message;
39382
+ if (!isObject(message)) {
39383
+ return void 0;
39384
+ }
39385
+ const role = message["role"];
39386
+ if (role !== "system" && role !== "user" && role !== "assistant" && role !== "tool") {
39387
+ return void 0;
39388
+ }
39389
+ const content = message["content"];
38138
39390
  if (typeof content === "string") {
38139
39391
  return { content, role };
38140
39392
  }
38141
- return { content: content.map(capturedEveModelContentPart), role };
39393
+ if (!Array.isArray(content)) {
39394
+ return void 0;
39395
+ }
39396
+ const capturedContent = [];
39397
+ for (const part of content) {
39398
+ const captured = capturedEveModelContentPart(part);
39399
+ if (captured) {
39400
+ capturedContent.push(captured);
39401
+ }
39402
+ }
39403
+ return { content: capturedContent, role };
38142
39404
  }
38143
39405
  function capturedEveModelContentPart(part) {
38144
- switch (part.type) {
39406
+ if (!isObject(part) || typeof part["type"] !== "string") {
39407
+ return void 0;
39408
+ }
39409
+ switch (part["type"]) {
38145
39410
  case "text":
38146
- case "reasoning":
38147
- return { text: part.text, type: part.type };
39411
+ case "reasoning": {
39412
+ const text = part["text"];
39413
+ return typeof text === "string" ? { text, type: part["type"] } : void 0;
39414
+ }
38148
39415
  case "image":
39416
+ if (!Object.hasOwn(part, "image")) {
39417
+ return void 0;
39418
+ }
38149
39419
  return {
38150
- image: part.image,
38151
- ...part.mediaType !== void 0 ? { mediaType: part.mediaType } : {},
39420
+ image: part["image"],
39421
+ ...typeof part["mediaType"] === "string" ? { mediaType: part["mediaType"] } : {},
38152
39422
  type: "image"
38153
39423
  };
38154
39424
  case "file":
38155
- case "reasoning-file":
39425
+ case "reasoning-file": {
39426
+ if (!Object.hasOwn(part, "data") || typeof part["mediaType"] !== "string") {
39427
+ return void 0;
39428
+ }
38156
39429
  return {
38157
- data: part.data,
38158
- ...part.type === "file" && part.filename !== void 0 ? { filename: part.filename } : {},
38159
- mediaType: part.mediaType,
38160
- type: part.type
39430
+ data: part["data"],
39431
+ ...part["type"] === "file" && typeof part["filename"] === "string" ? { filename: part["filename"] } : {},
39432
+ mediaType: part["mediaType"],
39433
+ type: part["type"]
38161
39434
  };
39435
+ }
38162
39436
  case "custom":
38163
39437
  return {
38164
- ..."kind" in part ? { kind: part.kind } : {},
39438
+ ...typeof part["kind"] === "string" ? { kind: part["kind"] } : {},
38165
39439
  type: "custom"
38166
39440
  };
38167
- case "tool-call":
39441
+ case "tool-call": {
39442
+ if (typeof part["toolCallId"] !== "string" || typeof part["toolName"] !== "string") {
39443
+ return void 0;
39444
+ }
38168
39445
  return {
38169
- input: part.input,
38170
- ...part.providerExecuted !== void 0 ? { providerExecuted: part.providerExecuted } : {},
38171
- toolCallId: part.toolCallId,
38172
- toolName: part.toolName,
39446
+ input: part["input"],
39447
+ ...typeof part["providerExecuted"] === "boolean" ? { providerExecuted: part["providerExecuted"] } : {},
39448
+ toolCallId: part["toolCallId"],
39449
+ toolName: part["toolName"],
38173
39450
  type: "tool-call"
38174
39451
  };
39452
+ }
38175
39453
  case "tool-result": {
38176
- const output = part.output;
39454
+ const output = part["output"];
39455
+ if (typeof part["toolCallId"] !== "string" || typeof part["toolName"] !== "string" || !isObject(output) || typeof output["type"] !== "string") {
39456
+ return void 0;
39457
+ }
38177
39458
  let capturedOutput;
38178
- switch (output.type) {
39459
+ switch (output["type"]) {
38179
39460
  case "text":
38180
- case "error-text":
38181
- capturedOutput = { type: output.type, value: output.value };
39461
+ case "error-text": {
39462
+ if (typeof output["value"] !== "string") {
39463
+ return void 0;
39464
+ }
39465
+ capturedOutput = {
39466
+ type: output["type"],
39467
+ value: output["value"]
39468
+ };
38182
39469
  break;
39470
+ }
38183
39471
  case "json":
38184
39472
  case "error-json":
38185
- capturedOutput = { type: output.type, value: output.value };
39473
+ capturedOutput = {
39474
+ type: output["type"],
39475
+ value: output["value"]
39476
+ };
38186
39477
  break;
38187
39478
  case "execution-denied":
38188
39479
  capturedOutput = {
38189
- ...output.reason !== void 0 ? { reason: output.reason } : {},
39480
+ ...typeof output["reason"] === "string" ? { reason: output["reason"] } : {},
38190
39481
  type: "execution-denied"
38191
39482
  };
38192
39483
  break;
38193
- case "content":
39484
+ case "content": {
39485
+ if (!Array.isArray(output["value"])) {
39486
+ return void 0;
39487
+ }
39488
+ const value = [];
39489
+ for (const outputPart of output["value"]) {
39490
+ const captured = capturedEveModelContentPart(outputPart);
39491
+ if (captured) {
39492
+ value.push(captured);
39493
+ }
39494
+ }
38194
39495
  capturedOutput = {
38195
39496
  type: "content",
38196
- value: output.value.map(capturedEveModelContentPart)
39497
+ value
38197
39498
  };
38198
39499
  break;
39500
+ }
39501
+ default:
39502
+ return void 0;
38199
39503
  }
38200
39504
  return {
38201
39505
  output: capturedOutput,
38202
- toolCallId: part.toolCallId,
38203
- toolName: part.toolName,
39506
+ toolCallId: part["toolCallId"],
39507
+ toolName: part["toolName"],
38204
39508
  type: "tool-result"
38205
39509
  };
38206
39510
  }
38207
- case "tool-approval-request":
39511
+ case "tool-approval-request": {
39512
+ if (typeof part["approvalId"] !== "string" || typeof part["toolCallId"] !== "string") {
39513
+ return void 0;
39514
+ }
38208
39515
  return {
38209
- approvalId: part.approvalId,
38210
- ...part.isAutomatic !== void 0 ? { isAutomatic: part.isAutomatic } : {},
38211
- ...part.signature !== void 0 ? { signature: part.signature } : {},
38212
- toolCallId: part.toolCallId,
39516
+ approvalId: part["approvalId"],
39517
+ ...typeof part["isAutomatic"] === "boolean" ? { isAutomatic: part["isAutomatic"] } : {},
39518
+ ...typeof part["signature"] === "string" ? { signature: part["signature"] } : {},
39519
+ toolCallId: part["toolCallId"],
38213
39520
  type: "tool-approval-request"
38214
39521
  };
38215
- case "tool-approval-response":
39522
+ }
39523
+ case "tool-approval-response": {
39524
+ if (typeof part["approvalId"] !== "string" || typeof part["approved"] !== "boolean") {
39525
+ return void 0;
39526
+ }
38216
39527
  return {
38217
- approvalId: part.approvalId,
38218
- approved: part.approved,
38219
- ...part.providerExecuted !== void 0 ? { providerExecuted: part.providerExecuted } : {},
38220
- ...part.reason !== void 0 ? { reason: part.reason } : {},
39528
+ approvalId: part["approvalId"],
39529
+ approved: part["approved"],
39530
+ ...typeof part["providerExecuted"] === "boolean" ? { providerExecuted: part["providerExecuted"] } : {},
39531
+ ...typeof part["reason"] === "string" ? { reason: part["reason"] } : {},
38221
39532
  type: "tool-approval-response"
38222
39533
  };
39534
+ }
38223
39535
  case "file-data":
38224
- case "image-data":
39536
+ case "image-data": {
39537
+ if (typeof part["data"] !== "string" || typeof part["mediaType"] !== "string") {
39538
+ return void 0;
39539
+ }
38225
39540
  return {
38226
- data: part.data,
38227
- ...part.type === "file-data" && part.filename !== void 0 ? { filename: part.filename } : {},
38228
- mediaType: part.mediaType,
38229
- type: part.type
39541
+ data: part["data"],
39542
+ ...part["type"] === "file-data" && typeof part["filename"] === "string" ? { filename: part["filename"] } : {},
39543
+ mediaType: part["mediaType"],
39544
+ type: part["type"]
38230
39545
  };
39546
+ }
38231
39547
  case "file-url":
38232
- case "image-url":
39548
+ case "image-url": {
39549
+ if (typeof part["url"] !== "string") {
39550
+ return void 0;
39551
+ }
38233
39552
  return {
38234
- ...part.type === "file-url" && part.mediaType !== void 0 ? { mediaType: part.mediaType } : {},
38235
- type: part.type,
38236
- url: part.url
39553
+ ...part["type"] === "file-url" && typeof part["mediaType"] === "string" ? { mediaType: part["mediaType"] } : {},
39554
+ type: part["type"],
39555
+ url: part["url"]
38237
39556
  };
39557
+ }
38238
39558
  case "file-id":
38239
- case "image-file-id":
38240
- return { fileId: part.fileId, type: part.type };
39559
+ case "image-file-id": {
39560
+ const fileId = part["fileId"];
39561
+ if (typeof fileId !== "string" && !isObject(fileId)) {
39562
+ return void 0;
39563
+ }
39564
+ return { fileId, type: part["type"] };
39565
+ }
38241
39566
  case "file-reference":
38242
- case "image-file-reference":
39567
+ case "image-file-reference": {
39568
+ if (!isObject(part["providerReference"])) {
39569
+ return void 0;
39570
+ }
38243
39571
  return {
38244
- providerReference: part.providerReference,
38245
- type: part.type
39572
+ providerReference: part["providerReference"],
39573
+ type: part["type"]
38246
39574
  };
39575
+ }
39576
+ default:
39577
+ return void 0;
38247
39578
  }
38248
39579
  }
38249
39580
  function isCapturedModelInput(input) {
@@ -38379,18 +39710,54 @@ function createEveInstrumentationProvider(options = {}) {
38379
39710
  recordOutputs: true
38380
39711
  }),
38381
39712
  events: {
38382
- "action.completed": (event, context) => bridge.handleActionTerminal(event, context),
38383
- "action.failed": (event, context) => bridge.handleActionTerminal(event, context),
38384
- "action.started": (event, context) => bridge.handleActionStarted(event, context),
38385
- "model.call.completed": (event, context) => bridge.handleModelTerminal(event, context),
38386
- "model.call.failed": (event, context) => bridge.handleModelTerminal(event, context),
38387
- "model.call.started": (event, context) => bridge.handleModelStarted(event, context),
38388
- "step.attempt.completed": (event) => bridge.handleStepAttemptTerminal(event),
38389
- "step.attempt.failed": (event) => bridge.handleStepAttemptTerminal(event),
38390
- "turn.cancelled": (event, context) => bridge.handleTurnTerminal(event, context),
38391
- "turn.completed": (event, context) => bridge.handleTurnTerminal(event, context),
38392
- "turn.failed": (event, context) => bridge.handleTurnTerminal(event, context),
38393
- "turn.started": (event, context) => bridge.handleTurnStarted(event, context)
39713
+ "action.completed": providerHandler(
39714
+ "action.completed",
39715
+ bridge.handleActionTerminal.bind(bridge)
39716
+ ),
39717
+ "action.failed": providerHandler(
39718
+ "action.failed",
39719
+ bridge.handleActionTerminal.bind(bridge)
39720
+ ),
39721
+ "action.started": providerHandler(
39722
+ "action.started",
39723
+ bridge.handleActionStarted.bind(bridge)
39724
+ ),
39725
+ "model.call.completed": providerHandler(
39726
+ "model.call.completed",
39727
+ bridge.handleModelTerminal.bind(bridge)
39728
+ ),
39729
+ "model.call.failed": providerHandler(
39730
+ "model.call.failed",
39731
+ bridge.handleModelTerminal.bind(bridge)
39732
+ ),
39733
+ "model.call.started": providerHandler(
39734
+ "model.call.started",
39735
+ bridge.handleModelStarted.bind(bridge)
39736
+ ),
39737
+ "step.attempt.completed": providerHandler(
39738
+ "step.attempt.completed",
39739
+ (event) => bridge.handleStepAttemptTerminal(event)
39740
+ ),
39741
+ "step.attempt.failed": providerHandler(
39742
+ "step.attempt.failed",
39743
+ (event) => bridge.handleStepAttemptTerminal(event)
39744
+ ),
39745
+ "turn.cancelled": providerHandler(
39746
+ "turn.cancelled",
39747
+ bridge.handleTurnTerminal.bind(bridge)
39748
+ ),
39749
+ "turn.completed": providerHandler(
39750
+ "turn.completed",
39751
+ bridge.handleTurnTerminal.bind(bridge)
39752
+ ),
39753
+ "turn.failed": providerHandler(
39754
+ "turn.failed",
39755
+ bridge.handleTurnTerminal.bind(bridge)
39756
+ ),
39757
+ "turn.started": providerHandler(
39758
+ "turn.started",
39759
+ bridge.handleTurnStarted.bind(bridge)
39760
+ )
38394
39761
  },
38395
39762
  flush,
38396
39763
  setup: options.setup
@@ -38746,17 +40113,20 @@ function modelOutput(event) {
38746
40113
  const reasoning = [];
38747
40114
  const toolCalls = [];
38748
40115
  for (const part of content) {
38749
- if (part.type === "text") {
38750
- text += part.text;
38751
- } else if (part.type === "reasoning" && part.text.trim().length > 0) {
38752
- reasoning.push({ content: part.text });
38753
- } else if (part.type === "tool-call") {
40116
+ if (!isObject(part)) {
40117
+ continue;
40118
+ }
40119
+ if (part["type"] === "text" && typeof part["text"] === "string") {
40120
+ text += part["text"];
40121
+ } else if (part["type"] === "reasoning" && typeof part["text"] === "string" && part["text"].trim().length > 0) {
40122
+ reasoning.push({ content: part["text"] });
40123
+ } else if (part["type"] === "tool-call" && typeof part["toolName"] === "string" && typeof part["callId"] === "string") {
38754
40124
  toolCalls.push({
38755
40125
  function: {
38756
- arguments: safeJsonStringify(part.input),
38757
- name: part.toolName
40126
+ arguments: safeJsonStringify(part["input"]),
40127
+ name: part["toolName"]
38758
40128
  },
38759
- id: part.callId,
40129
+ id: part["callId"],
38760
40130
  type: "function"
38761
40131
  });
38762
40132
  }
@@ -38775,13 +40145,13 @@ function modelOutput(event) {
38775
40145
  ];
38776
40146
  }
38777
40147
  function usageMetrics(usage) {
38778
- const promptTokens = nonNegativeNumber(usage.inputTokens);
38779
- const completionTokens = nonNegativeNumber(usage.outputTokens);
40148
+ const promptTokens = nonNegativeNumber(usage?.inputTokens);
40149
+ const completionTokens = nonNegativeNumber(usage?.outputTokens);
38780
40150
  const cachedTokens = nonNegativeNumber(
38781
- usage.inputTokenDetails?.cacheReadTokens
40151
+ usage?.inputTokenDetails?.cacheReadTokens
38782
40152
  );
38783
40153
  const cacheCreationTokens = nonNegativeNumber(
38784
- usage.inputTokenDetails?.cacheWriteTokens
40154
+ usage?.inputTokenDetails?.cacheWriteTokens
38785
40155
  );
38786
40156
  return {
38787
40157
  ...promptTokens !== void 0 ? { prompt_tokens: promptTokens } : {},
@@ -38818,10 +40188,76 @@ function turnIdempotencyKey(sessionId, turnId) {
38818
40188
  function actionIdempotencyKey(sessionId, turnId, callId) {
38819
40189
  return `action:${sessionId}:${turnId}:${callId}`;
38820
40190
  }
40191
+ function providerHandler(type, handler) {
40192
+ return async (event, context) => {
40193
+ try {
40194
+ if (!isEveProviderEvent(event, type) || !isEveProviderContext(context)) {
40195
+ debugLogger.warn(`Ignoring malformed Eve provider ${type} event`);
40196
+ return;
40197
+ }
40198
+ await handler(event, context);
40199
+ } catch (error) {
40200
+ debugLogger.warn(`Error in Eve provider ${type}:`, error);
40201
+ }
40202
+ };
40203
+ }
40204
+ function isEveProviderEvent(event, type) {
40205
+ if (!isObject(event) || event["type"] !== type || typeof event["idempotencyKey"] !== "string" || event["idempotencyKey"].length === 0) {
40206
+ return false;
40207
+ }
40208
+ if (type === "turn.started") {
40209
+ const parentLineage = event["parentLineage"];
40210
+ 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));
40211
+ }
40212
+ if (type === "turn.cancelled" || type === "turn.completed" || type === "turn.failed") {
40213
+ return typeof event["sessionId"] === "string" && typeof event["turnId"] === "string";
40214
+ }
40215
+ if (!isEveProviderScope(event["scope"])) {
40216
+ return false;
40217
+ }
40218
+ if (type === "model.call.started") {
40219
+ const model = event["model"];
40220
+ return isObject(model) && typeof model["modelId"] === "string" && typeof model["provider"] === "string";
40221
+ }
40222
+ if (type === "model.call.completed") {
40223
+ return typeof event["finishReason"] === "string" && isObject(event["usage"]) && (event["content"] === void 0 || Array.isArray(event["content"]));
40224
+ }
40225
+ if (type === "model.call.failed") {
40226
+ return true;
40227
+ }
40228
+ if (type === "action.started") {
40229
+ 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");
40230
+ }
40231
+ if (type === "action.completed") {
40232
+ const output = event["output"];
40233
+ return event["outcome"] === "completed" && isObject(output) && (output["type"] === "result" || output["type"] === "error");
40234
+ }
40235
+ if (type === "action.failed") {
40236
+ return event["outcome"] === "abandoned" || event["outcome"] === "cancelled" || event["outcome"] === "failed" || event["outcome"] === "rejected";
40237
+ }
40238
+ return type === "step.attempt.completed" || type === "step.attempt.failed";
40239
+ }
40240
+ function isEveProviderContext(value) {
40241
+ if (!isObject(value) || !isObject(value["state"])) {
40242
+ return false;
40243
+ }
40244
+ return typeof value["state"]["get"] === "function" && typeof value["state"]["set"] === "function";
40245
+ }
40246
+ function isEveProviderScope(value) {
40247
+ 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");
40248
+ }
40249
+ function isEveProviderParentLineage(value) {
40250
+ return isObject(value) && typeof value["callId"] === "string" && typeof value["sessionId"] === "string" && typeof value["turnId"] === "string";
40251
+ }
38821
40252
 
38822
40253
  // src/instrumentation/plugins/eve-instrumentation.ts
38823
40254
  var EVE_INSTRUMENTATION_PROVIDER = /* @__PURE__ */ Symbol.for("eve.instrumentation.provider");
38824
40255
  function braintrustEveInstrumentation(options) {
40256
+ if (!options || typeof options !== "object") {
40257
+ throw new TypeError(
40258
+ "braintrustEveInstrumentation requires an options object"
40259
+ );
40260
+ }
38825
40261
  const definition = "defineState" in options ? createLegacyEveInstrumentation(options) : createEveInstrumentationProvider(options);
38826
40262
  const declaration = {
38827
40263
  ...definition,
@@ -38904,6 +40340,9 @@ var envIntegrationAliases = {
38904
40340
  "langchain-js": "langchain",
38905
40341
  "@langchain": "langchain",
38906
40342
  langgraph: "langgraph",
40343
+ langgraphsdk: "langgraphSDK",
40344
+ "langgraph-sdk": "langgraphSDK",
40345
+ "@langchain/langgraph-sdk": "langgraphSDK",
38907
40346
  langsmith: "langsmith",
38908
40347
  voyage: "voyageai",
38909
40348
  "voyage-ai": "voyageai",
@@ -38944,6 +40383,7 @@ function getDefaultInstrumentationIntegrations() {
38944
40383
  gitHubCopilot: true,
38945
40384
  langchain: true,
38946
40385
  langgraph: true,
40386
+ langgraphSDK: true,
38947
40387
  langsmith: true,
38948
40388
  voyageai: true,
38949
40389
  elevenlabs: true,