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
@@ -5770,6 +5770,7 @@ var INSTRUMENTATION_NAMES = {
5770
5770
  LANGSMITH: "langsmith",
5771
5771
  MASTRA: "mastra",
5772
5772
  MISTRAL: "mistral",
5773
+ LANGGRAPH_SDK: "langgraph-sdk",
5773
5774
  OLLAMA: "ollama",
5774
5775
  OPENAI: "openai",
5775
5776
  OPENAI_AGENTS: "openai-agents",
@@ -5784,7 +5785,7 @@ var INSTRUMENTATION_NAMES = {
5784
5785
  var INTERNAL_SPAN_INSTRUMENTATION_NAME = /* @__PURE__ */ Symbol.for(
5785
5786
  "braintrust.spanInstrumentationName"
5786
5787
  );
5787
- var SDK_VERSION = true ? "3.32.0" : "0.0.0";
5788
+ var SDK_VERSION = true ? "3.33.0" : "0.0.0";
5788
5789
  function withSpanInstrumentationName(args, instrumentationName) {
5789
5790
  return {
5790
5791
  ...args,
@@ -8503,6 +8504,38 @@ function getSpanParentObjectAndPropagatedState(options) {
8503
8504
  function getSpanParentObject(options) {
8504
8505
  return getSpanParentObjectAndPropagatedState(options).parentObject;
8505
8506
  }
8507
+ function _internalExportParentSynchronously(parent) {
8508
+ if ("toStr" in parent) {
8509
+ return parent.toStr();
8510
+ }
8511
+ if ("getParentInfo" in parent) {
8512
+ const parentInfo = parent.getParentInfo();
8513
+ if (!parentInfo) {
8514
+ return void 0;
8515
+ }
8516
+ const objectId = parentInfo.objectId.getSync().value;
8517
+ if (!objectId && !parentInfo.computeObjectMetadataArgs) {
8518
+ return void 0;
8519
+ }
8520
+ return new SpanComponentsV4({
8521
+ object_type: parentInfo.objectType,
8522
+ ...objectId ? { object_id: objectId } : {
8523
+ compute_object_metadata_args: parentInfo.computeObjectMetadataArgs ?? {}
8524
+ },
8525
+ row_id: parent.id,
8526
+ root_span_id: parent.rootSpanId,
8527
+ span_id: parent.spanId
8528
+ }).toStr();
8529
+ }
8530
+ const components = braintrustParentToComponents(parent._getOtelParent());
8531
+ if (!components) {
8532
+ return void 0;
8533
+ }
8534
+ return new SpanComponentsV4({
8535
+ object_type: components.objectType,
8536
+ ...components.objectId ? { object_id: components.objectId } : { compute_object_metadata_args: components.computeArgs ?? {} }
8537
+ }).toStr();
8538
+ }
8506
8539
  function currentBraintrustParent(state) {
8507
8540
  const resolvedState = state ?? _globalState;
8508
8541
  const experiment = currentExperiment({ state: resolvedState });
@@ -9809,10 +9842,16 @@ var SpanImpl = class _SpanImpl {
9809
9842
  inject(carrier) {
9810
9843
  const resolvedCarrier = carrier ?? {};
9811
9844
  try {
9845
+ const braintrustParent = this._getOtelParent() ?? this._propagatedState?.braintrustParent;
9846
+ if (!braintrustParent) {
9847
+ debugLogger.forState(this._state).warn(
9848
+ "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."
9849
+ );
9850
+ }
9812
9851
  _injectIntoCarrier(resolvedCarrier, {
9813
9852
  traceId: this._rootSpanId,
9814
9853
  spanId: this._spanId,
9815
- braintrustParent: this._getOtelParent() ?? this._propagatedState?.braintrustParent,
9854
+ braintrustParent,
9816
9855
  propagatedState: this._propagatedState
9817
9856
  });
9818
9857
  } catch (e) {
@@ -11895,6 +11934,18 @@ function defineChannels(pkg, channels, options) {
11895
11934
  var openAIChannels = defineChannels(
11896
11935
  "openai",
11897
11936
  {
11937
+ agentsTraceStart: channel({
11938
+ channelName: "agents.trace.start",
11939
+ kind: "async"
11940
+ }),
11941
+ agentsTraceCapture: channel({
11942
+ channelName: "agents.trace.capture",
11943
+ kind: "async"
11944
+ }),
11945
+ agentsTraceFail: channel({
11946
+ channelName: "agents.trace.fail",
11947
+ kind: "async"
11948
+ }),
11898
11949
  filesCreateTraced: channel({
11899
11950
  channelName: "files.create-traced",
11900
11951
  kind: "async"
@@ -12263,6 +12314,23 @@ function getCachedMetricFromHeaders(headers) {
12263
12314
  return parseCachedHeader(headers.get(LEGACY_CACHED_HEADER));
12264
12315
  }
12265
12316
 
12317
+ // src/instrumentation/plugins/openai-manual-instrumentation-utils.ts
12318
+ async function deterministicDigest(namespace, ...parts) {
12319
+ const encoded = new TextEncoder().encode(
12320
+ [namespace, ...parts].map((part) => `${part.length}:${part}`).join("\0")
12321
+ );
12322
+ return new Uint8Array(
12323
+ await globalThis.crypto.subtle.digest("SHA-256", encoded)
12324
+ );
12325
+ }
12326
+ function digestHex(bytes, length) {
12327
+ return Array.from(bytes.slice(0, length)).map((byte) => byte.toString(16).padStart(2, "0")).join("");
12328
+ }
12329
+ function digestUuid(bytes) {
12330
+ const hex = digestHex(bytes, 16);
12331
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
12332
+ }
12333
+
12266
12334
  // src/instrumentation/plugins/openai-batch-instrumentation.ts
12267
12335
  var SUPPORTED_ENDPOINTS = /* @__PURE__ */ new Set(["/v1/chat/completions", "/v1/responses"]);
12268
12336
  var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
@@ -12303,21 +12371,6 @@ async function exportParent(parent) {
12303
12371
  }
12304
12372
  return void 0;
12305
12373
  }
12306
- async function deterministicDigest(namespace, ...parts) {
12307
- const encoded = new TextEncoder().encode(
12308
- [namespace, ...parts].map((part) => `${part.length}:${part}`).join("\0")
12309
- );
12310
- return new Uint8Array(
12311
- await globalThis.crypto.subtle.digest("SHA-256", encoded)
12312
- );
12313
- }
12314
- function digestHex(bytes, length) {
12315
- return Array.from(bytes.slice(0, length)).map((byte) => byte.toString(16).padStart(2, "0")).join("");
12316
- }
12317
- function digestUuid(bytes) {
12318
- const hex = digestHex(bytes, 16);
12319
- return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
12320
- }
12321
12374
  async function batchSpanIds(inputFileId) {
12322
12375
  const [row, span, root] = await Promise.all([
12323
12376
  deterministicDigest("openai:batch:row", inputFileId),
@@ -12808,6 +12861,628 @@ var interceptOpenAIBatchTraceComplete = (target, thisArg, args) => Promise.resol
12808
12861
  return result;
12809
12862
  });
12810
12863
 
12864
+ // src/instrumentation/plugins/openai-agents-api-instrumentation.ts
12865
+ var TERMINAL_TURN_EVENTS = /* @__PURE__ */ new Set([
12866
+ "agent.session.turn.completed",
12867
+ "agent.session.turn.failed",
12868
+ "agent.session.turn.cancelled"
12869
+ ]);
12870
+ var TURN_LIFECYCLE_EVENTS = /* @__PURE__ */ new Set([
12871
+ "agent.session.turn.created",
12872
+ "agent.session.turn.in_progress",
12873
+ ...TERMINAL_TURN_EVENTS
12874
+ ]);
12875
+ var SESSION_EVENTS = /* @__PURE__ */ new Set([
12876
+ "agent.session.created",
12877
+ "agent.session.failed",
12878
+ "agent.session.idle",
12879
+ "agent.session.in_progress",
12880
+ "agent.session.requires_action"
12881
+ ]);
12882
+ var SUBAGENT_EVENTS = /* @__PURE__ */ new Set([
12883
+ "agent.session.subagent.active",
12884
+ "agent.session.subagent.closed",
12885
+ "agent.session.subagent.created"
12886
+ ]);
12887
+ function read2(value, key) {
12888
+ if (!isObject(value)) {
12889
+ return void 0;
12890
+ }
12891
+ try {
12892
+ return Reflect.get(value, key);
12893
+ } catch {
12894
+ return void 0;
12895
+ }
12896
+ }
12897
+ function stringValue(value) {
12898
+ return typeof value === "string" && value.length > 0 ? value : void 0;
12899
+ }
12900
+ function recordValue(record, key) {
12901
+ return Object.hasOwn(record, key) ? record[key] : void 0;
12902
+ }
12903
+ function setRecordValue(record, key, value) {
12904
+ Object.defineProperty(record, key, {
12905
+ configurable: true,
12906
+ enumerable: true,
12907
+ value,
12908
+ writable: true
12909
+ });
12910
+ }
12911
+ function loggedError(value, fallback) {
12912
+ if (value instanceof Error) {
12913
+ return value;
12914
+ }
12915
+ const message = stringValue(read2(value, "message"));
12916
+ return new Error(message ?? (typeof value === "string" ? value : fallback));
12917
+ }
12918
+ function logInstrumentationError(context, error) {
12919
+ debugLogger.debug(`OpenAI Agents API instrumentation ${context}:`, error);
12920
+ }
12921
+ async function childSpanIds2(rootKey, kind, providerId) {
12922
+ const [row, span] = await Promise.all([
12923
+ deterministicDigest("openai:agents:row", rootKey, kind, providerId),
12924
+ deterministicDigest("openai:agents:span", rootKey, kind, providerId)
12925
+ ]);
12926
+ return { rowId: digestUuid(row), spanId: digestHex(span, 8) };
12927
+ }
12928
+ function traceMetadata(args) {
12929
+ const metadata = {};
12930
+ const suppliedMetadata = read2(args, "metadata");
12931
+ if (isObject(suppliedMetadata)) {
12932
+ try {
12933
+ for (const key of Object.keys(suppliedMetadata)) {
12934
+ metadata[key] = read2(suppliedMetadata, key);
12935
+ }
12936
+ } catch (error) {
12937
+ logInstrumentationError("could not read supplied metadata", error);
12938
+ }
12939
+ }
12940
+ const agent = read2(args, "agent");
12941
+ const agentId = stringValue(read2(agent, "id")) ?? stringValue(read2(args, "agent_id"));
12942
+ const agentName = stringValue(read2(agent, "name"));
12943
+ const model = stringValue(read2(agent, "model"));
12944
+ return {
12945
+ ...metadata,
12946
+ api: "agents",
12947
+ ...agentId ? { agent_id: agentId } : {},
12948
+ ...agentName ? { agent_name: agentName } : {},
12949
+ ...model ? { model } : {},
12950
+ provider: "openai"
12951
+ };
12952
+ }
12953
+ function copyState(state) {
12954
+ return {
12955
+ ...state,
12956
+ callItems: { ...state.callItems },
12957
+ eventIds: [...state.eventIds],
12958
+ openTools: { ...state.openTools },
12959
+ subagents: { ...state.subagents },
12960
+ turnSubagents: { ...state.turnSubagents }
12961
+ };
12962
+ }
12963
+ function startRootSpan(state) {
12964
+ const root = SpanComponentsV4.fromStr(state.root);
12965
+ const parent = SpanComponentsV4.fromStr(state.rootParent);
12966
+ const rowId = stringValue(root.data.row_id);
12967
+ const rootSpanId = stringValue(root.data.root_span_id);
12968
+ const spanId = stringValue(root.data.span_id);
12969
+ if (!rowId || !rootSpanId || !spanId) {
12970
+ throw new Error("OpenAI Agents trace root is invalid");
12971
+ }
12972
+ const hasParentSpan = Boolean(
12973
+ parent.data.row_id && parent.data.span_id && parent.data.root_span_id
12974
+ );
12975
+ return withCurrent(
12976
+ NOOP_SPAN,
12977
+ () => _internalStartSpanWithInitialMergeAndParentSpanIds(
12978
+ withSpanInstrumentationName(
12979
+ {
12980
+ name: "openai.agents.turn",
12981
+ type: "task" /* TASK */,
12982
+ parent: state.rootParent,
12983
+ ...!hasParentSpan ? {
12984
+ parentSpanIds: {
12985
+ parentSpanIds: [],
12986
+ rootSpanId
12987
+ }
12988
+ } : {},
12989
+ spanId,
12990
+ startTime: state.startTime,
12991
+ event: { id: rowId }
12992
+ },
12993
+ INSTRUMENTATION_NAMES.OPENAI
12994
+ )
12995
+ )
12996
+ );
12997
+ }
12998
+ async function startSubagentSpan(state, subagentId, input, metadata, visiting = /* @__PURE__ */ new Set()) {
12999
+ const subagent = recordValue(state.subagents, subagentId);
13000
+ let parent = state.root;
13001
+ if (subagent?.parentAgentId && subagent.parentAgentId !== subagentId && recordValue(state.subagents, subagent.parentAgentId) && !visiting.has(subagent.parentAgentId)) {
13002
+ visiting.add(subagentId);
13003
+ parent = await (await startSubagentSpan(
13004
+ state,
13005
+ subagent.parentAgentId,
13006
+ void 0,
13007
+ void 0,
13008
+ visiting
13009
+ )).export();
13010
+ }
13011
+ const ids = await childSpanIds2(state.rootKey, "subagent", subagentId);
13012
+ return withCurrent(
13013
+ NOOP_SPAN,
13014
+ () => _internalStartSpanWithInitialMerge(
13015
+ withSpanInstrumentationName(
13016
+ {
13017
+ name: "openai.agents.subagent",
13018
+ type: "task" /* TASK */,
13019
+ parent,
13020
+ spanId: ids.spanId,
13021
+ startTime: subagent?.openedAt,
13022
+ event: {
13023
+ id: ids.rowId,
13024
+ ...input !== void 0 ? { input } : {},
13025
+ metadata: {
13026
+ ...metadata,
13027
+ agent_id: subagentId,
13028
+ ...subagent?.parentAgentId ? { parent_agent_id: subagent.parentAgentId } : {},
13029
+ provider: "openai"
13030
+ }
13031
+ }
13032
+ },
13033
+ INSTRUMENTATION_NAMES.OPENAI
13034
+ )
13035
+ )
13036
+ );
13037
+ }
13038
+ async function parentForTurn(state, turnId) {
13039
+ const subagentId = turnId ? recordValue(state.turnSubagents, turnId) : void 0;
13040
+ if (!subagentId) {
13041
+ return state.root;
13042
+ }
13043
+ return await (await startSubagentSpan(state, subagentId)).export();
13044
+ }
13045
+ async function startToolSpan(state, tool, input) {
13046
+ const ids = await childSpanIds2(state.rootKey, "tool", tool.itemId);
13047
+ return withCurrent(
13048
+ NOOP_SPAN,
13049
+ async () => _internalStartSpanWithInitialMerge(
13050
+ withSpanInstrumentationName(
13051
+ {
13052
+ name: tool.name,
13053
+ type: "tool" /* TOOL */,
13054
+ parent: await parentForTurn(state, tool.turnId),
13055
+ spanId: ids.spanId,
13056
+ startTime: tool.startTime,
13057
+ event: {
13058
+ id: ids.rowId,
13059
+ ...input !== void 0 ? { input } : {},
13060
+ metadata: {
13061
+ item_id: tool.itemId,
13062
+ provider: "openai",
13063
+ tool_type: tool.toolType,
13064
+ ...tool.turnId ? { turn_id: tool.turnId } : {}
13065
+ }
13066
+ }
13067
+ },
13068
+ INSTRUMENTATION_NAMES.OPENAI
13069
+ )
13070
+ )
13071
+ );
13072
+ }
13073
+ function toolFromItem(item, observedAt) {
13074
+ const itemId = stringValue(read2(item, "id"));
13075
+ const toolType = stringValue(read2(item, "type"));
13076
+ if (!itemId || !toolType) {
13077
+ return void 0;
13078
+ }
13079
+ const turnId = stringValue(read2(item, "turn_id"));
13080
+ switch (toolType) {
13081
+ case "function_call":
13082
+ return {
13083
+ input: read2(item, "arguments"),
13084
+ tool: {
13085
+ itemId,
13086
+ name: stringValue(read2(item, "name")) ?? "Function call",
13087
+ startTime: observedAt,
13088
+ toolType,
13089
+ ...turnId ? { turnId } : {}
13090
+ }
13091
+ };
13092
+ case "mcp_call": {
13093
+ const name = stringValue(read2(item, "name")) ?? "MCP call";
13094
+ const server = stringValue(read2(item, "server_label"));
13095
+ return {
13096
+ input: read2(item, "arguments"),
13097
+ tool: {
13098
+ itemId,
13099
+ name: server ? `${server}.${name}` : name,
13100
+ startTime: observedAt,
13101
+ toolType,
13102
+ ...turnId ? { turnId } : {}
13103
+ }
13104
+ };
13105
+ }
13106
+ case "web_search_call":
13107
+ return {
13108
+ input: read2(item, "action"),
13109
+ tool: {
13110
+ itemId,
13111
+ name: "Web search",
13112
+ startTime: observedAt,
13113
+ toolType,
13114
+ ...turnId ? { turnId } : {}
13115
+ }
13116
+ };
13117
+ case "command_execution":
13118
+ return {
13119
+ input: {
13120
+ command: read2(item, "command"),
13121
+ cwd: read2(item, "cwd")
13122
+ },
13123
+ tool: {
13124
+ itemId,
13125
+ name: "Command execution",
13126
+ startTime: observedAt,
13127
+ toolType,
13128
+ ...turnId ? { turnId } : {}
13129
+ }
13130
+ };
13131
+ default:
13132
+ return void 0;
13133
+ }
13134
+ }
13135
+ function textFromContent(content) {
13136
+ if (!Array.isArray(content)) {
13137
+ return void 0;
13138
+ }
13139
+ const text = [];
13140
+ for (const part of content) {
13141
+ const partText = read2(part, "text");
13142
+ if (read2(part, "type") === "output_text" && typeof partText === "string") {
13143
+ text.push(partText);
13144
+ }
13145
+ }
13146
+ return text.length > 0 ? text.join("") : void 0;
13147
+ }
13148
+ function toolOutput(item, toolType) {
13149
+ switch (toolType) {
13150
+ case "function_call":
13151
+ return read2(item, "output");
13152
+ case "mcp_call":
13153
+ return read2(item, "output");
13154
+ case "web_search_call":
13155
+ return read2(item, "action");
13156
+ case "command_execution":
13157
+ return read2(item, "output");
13158
+ default:
13159
+ return void 0;
13160
+ }
13161
+ }
13162
+ function toolFailed(item, toolType) {
13163
+ const status = read2(item, "status");
13164
+ const explicitError = read2(item, "error");
13165
+ if (explicitError !== void 0 && explicitError !== null) {
13166
+ return loggedError(explicitError, `OpenAI ${toolType} failed`);
13167
+ }
13168
+ if (status === "failed" || status === "incomplete") {
13169
+ return new Error(`OpenAI ${toolType} ${status}`);
13170
+ }
13171
+ if (toolType === "command_execution" && typeof read2(item, "exit_code") === "number" && read2(item, "exit_code") !== 0) {
13172
+ return new Error(
13173
+ `OpenAI command exited with code ${read2(item, "exit_code")}`
13174
+ );
13175
+ }
13176
+ return void 0;
13177
+ }
13178
+ async function completeTool(state, tool, item, endTime) {
13179
+ const span = await startToolSpan(state, tool);
13180
+ const output = toolOutput(item, tool.toolType);
13181
+ const error = toolFailed(item, tool.toolType);
13182
+ span.log({
13183
+ ...output !== void 0 ? { output } : {},
13184
+ ...error ? { error } : {},
13185
+ metadata: {
13186
+ status: read2(item, "status"),
13187
+ ...tool.toolType === "command_execution" ? { exit_code: read2(item, "exit_code") } : {}
13188
+ }
13189
+ });
13190
+ span.end({ endTime });
13191
+ Reflect.deleteProperty(state.openTools, tool.itemId);
13192
+ }
13193
+ async function captureMessage(state, item) {
13194
+ if (read2(item, "type") !== "message" || read2(item, "role") !== "assistant" || read2(item, "phase") !== "final_answer") {
13195
+ return;
13196
+ }
13197
+ const output = textFromContent(read2(item, "content"));
13198
+ if (output === void 0) {
13199
+ return;
13200
+ }
13201
+ const turnId = stringValue(read2(item, "turn_id"));
13202
+ const subagentId = turnId ? recordValue(state.turnSubagents, turnId) : void 0;
13203
+ if (subagentId) {
13204
+ (await startSubagentSpan(state, subagentId)).log({ output });
13205
+ } else {
13206
+ startRootSpan(state).log({ output });
13207
+ }
13208
+ }
13209
+ async function captureItem(state, item, isDone, observedAt) {
13210
+ await captureMessage(state, item);
13211
+ const itemType = stringValue(read2(item, "type"));
13212
+ if (itemType === "function_call_output") {
13213
+ const callId = stringValue(read2(item, "call_id"));
13214
+ const itemId = callId ? recordValue(state.callItems, callId) : void 0;
13215
+ const tool2 = itemId ? recordValue(state.openTools, itemId) : void 0;
13216
+ if (tool2) {
13217
+ await completeTool(state, tool2, item, observedAt);
13218
+ }
13219
+ return;
13220
+ }
13221
+ const descriptor = toolFromItem(item, observedAt);
13222
+ if (!descriptor) {
13223
+ return;
13224
+ }
13225
+ const existing = recordValue(state.openTools, descriptor.tool.itemId);
13226
+ const tool = existing ?? descriptor.tool;
13227
+ setRecordValue(state.openTools, tool.itemId, tool);
13228
+ if (itemType === "function_call") {
13229
+ const callId = stringValue(read2(item, "call_id"));
13230
+ if (callId) {
13231
+ setRecordValue(state.callItems, callId, tool.itemId);
13232
+ }
13233
+ }
13234
+ await startToolSpan(state, tool, descriptor.input);
13235
+ const status = read2(item, "status");
13236
+ const terminalFunctionCall = itemType === "function_call" && (status === "failed" || status === "incomplete");
13237
+ if (itemType !== "function_call" && (isDone || status !== "in_progress") || terminalFunctionCall) {
13238
+ await completeTool(state, tool, item, observedAt);
13239
+ }
13240
+ }
13241
+ function updateSessionMetadata(state, session) {
13242
+ const sessionId = stringValue(read2(session, "id"));
13243
+ const agent = read2(session, "agent");
13244
+ startRootSpan(state).log({
13245
+ metadata: {
13246
+ ...sessionId ? { session_id: sessionId } : {},
13247
+ ...stringValue(read2(agent, "id")) ? { agent_id: read2(agent, "id") } : {},
13248
+ ...stringValue(read2(agent, "name")) ? { agent_name: read2(agent, "name") } : {},
13249
+ ...stringValue(read2(agent, "model")) ? { model: read2(agent, "model") } : {}
13250
+ }
13251
+ });
13252
+ }
13253
+ async function captureSubagent(state, eventType, subagent, observedAt) {
13254
+ const subagentId = stringValue(read2(subagent, "id"));
13255
+ if (!subagentId) {
13256
+ return;
13257
+ }
13258
+ const existing = recordValue(state.subagents, subagentId);
13259
+ const observedOpenedAt = read2(subagent, "opened_at");
13260
+ const openedAt = typeof observedOpenedAt === "number" && Number.isFinite(observedOpenedAt) && observedOpenedAt >= 0 ? observedOpenedAt : existing?.openedAt ?? observedAt;
13261
+ const observedClosedAt = read2(subagent, "closed_at");
13262
+ const closedAt = typeof observedClosedAt === "number" && Number.isFinite(observedClosedAt) && observedClosedAt >= 0 ? observedClosedAt : existing?.closedAt;
13263
+ const parentAgentId = stringValue(read2(subagent, "parent_agent_id")) ?? existing?.parentAgentId;
13264
+ setRecordValue(state.subagents, subagentId, {
13265
+ ...closedAt !== void 0 ? { closedAt } : {},
13266
+ openedAt,
13267
+ ...parentAgentId ? { parentAgentId } : {}
13268
+ });
13269
+ const span = await startSubagentSpan(
13270
+ state,
13271
+ subagentId,
13272
+ read2(subagent, "instructions"),
13273
+ {
13274
+ ...stringValue(read2(subagent, "name")) ? { agent_name: read2(subagent, "name") } : {},
13275
+ status: read2(subagent, "status")
13276
+ }
13277
+ );
13278
+ if (eventType === "agent.session.subagent.closed") {
13279
+ span.end({ endTime: closedAt ?? observedAt });
13280
+ }
13281
+ }
13282
+ async function closeTrace(state, endTime, error, usage) {
13283
+ if (state.ended) {
13284
+ return;
13285
+ }
13286
+ for (const tool of Object.values(state.openTools)) {
13287
+ const span = await startToolSpan(state, tool);
13288
+ span.log({
13289
+ error: error ?? new Error("OpenAI Agents turn ended before tool completion")
13290
+ });
13291
+ span.end({ endTime });
13292
+ }
13293
+ state.openTools = {};
13294
+ for (const subagentId of Object.keys(state.subagents)) {
13295
+ const subagent = state.subagents[subagentId];
13296
+ const span = await startSubagentSpan(state, subagentId);
13297
+ span.end({ endTime: subagent.closedAt ?? endTime });
13298
+ }
13299
+ const root = startRootSpan(state);
13300
+ root.log({
13301
+ ...error ? { error } : {},
13302
+ metrics: parseMetricsFromUsage(usage)
13303
+ });
13304
+ root.end({ endTime });
13305
+ state.ended = true;
13306
+ }
13307
+ async function captureTurnLifecycle(state, event, eventType, observedAt) {
13308
+ const turn = read2(event, "turn");
13309
+ const turnId = stringValue(read2(event, "turn_id")) ?? stringValue(read2(turn, "id"));
13310
+ const subagentId = stringValue(read2(turn, "subagent_id"));
13311
+ if (turnId && subagentId) {
13312
+ setRecordValue(state.turnSubagents, turnId, subagentId);
13313
+ if (!recordValue(state.subagents, subagentId)) {
13314
+ const createdAt = read2(turn, "created_at");
13315
+ setRecordValue(state.subagents, subagentId, {
13316
+ openedAt: typeof createdAt === "number" && Number.isFinite(createdAt) && createdAt >= 0 ? createdAt : observedAt
13317
+ });
13318
+ }
13319
+ await startSubagentSpan(state, subagentId);
13320
+ }
13321
+ const sessionId = stringValue(read2(event, "session_id"));
13322
+ if (sessionId) {
13323
+ startRootSpan(state).log({ metadata: { session_id: sessionId } });
13324
+ }
13325
+ if (!TERMINAL_TURN_EVENTS.has(eventType) || subagentId) {
13326
+ if (subagentId && eventType === "agent.session.turn.failed") {
13327
+ (await startSubagentSpan(state, subagentId)).log({
13328
+ error: loggedError(read2(turn, "error"), "OpenAI subagent turn failed")
13329
+ });
13330
+ }
13331
+ return;
13332
+ }
13333
+ const completedAt = read2(turn, "completed_at");
13334
+ const endTime = typeof completedAt === "number" && Number.isFinite(completedAt) && completedAt >= 0 ? completedAt : observedAt;
13335
+ const usage = read2(event, "usage") ?? read2(turn, "usage");
13336
+ const error = eventType === "agent.session.turn.completed" ? void 0 : loggedError(
13337
+ read2(turn, "error"),
13338
+ eventType === "agent.session.turn.cancelled" ? "OpenAI Agents turn cancelled" : "OpenAI Agents turn failed"
13339
+ );
13340
+ await closeTrace(state, endTime, error, usage);
13341
+ }
13342
+ async function captureEvent(state, event) {
13343
+ if (state.ended) {
13344
+ return state;
13345
+ }
13346
+ const eventType = stringValue(read2(event, "type"));
13347
+ const eventId = stringValue(read2(event, "event_id"));
13348
+ if (!eventType || eventId && state.eventIds.includes(eventId)) {
13349
+ return state;
13350
+ }
13351
+ const next = copyState(state);
13352
+ const observedAt = getCurrentUnixTimestamp();
13353
+ let handled = false;
13354
+ if (SESSION_EVENTS.has(eventType)) {
13355
+ const session = read2(event, "session");
13356
+ if (session) {
13357
+ updateSessionMetadata(next, session);
13358
+ }
13359
+ handled = true;
13360
+ }
13361
+ if (eventType === "agent.session.turn.item.added") {
13362
+ await captureItem(next, read2(event, "item"), false, observedAt);
13363
+ handled = true;
13364
+ } else if (eventType === "agent.session.turn.item.done") {
13365
+ await captureItem(next, read2(event, "item"), true, observedAt);
13366
+ handled = true;
13367
+ } else if (TURN_LIFECYCLE_EVENTS.has(eventType)) {
13368
+ await captureTurnLifecycle(next, event, eventType, observedAt);
13369
+ handled = true;
13370
+ } else if (SUBAGENT_EVENTS.has(eventType)) {
13371
+ await captureSubagent(next, eventType, read2(event, "subagent"), observedAt);
13372
+ handled = true;
13373
+ } else if (eventType === "agent.session.turn.output_text.delta" && next.firstTokenAt === void 0 && stringValue(read2(event, "delta"))) {
13374
+ next.firstTokenAt = observedAt;
13375
+ startRootSpan(next).log({
13376
+ metrics: { time_to_first_token: observedAt - next.startTime }
13377
+ });
13378
+ handled = true;
13379
+ } else if (eventType === "agent.session.failed") {
13380
+ const session = read2(event, "session");
13381
+ const lastActiveAt = read2(session, "last_active_at");
13382
+ const endTime = typeof lastActiveAt === "number" && Number.isFinite(lastActiveAt) && lastActiveAt >= 0 ? lastActiveAt : observedAt;
13383
+ await closeTrace(
13384
+ next,
13385
+ endTime,
13386
+ loggedError(read2(session, "error"), "OpenAI Agents session failed"),
13387
+ read2(session, "usage")
13388
+ );
13389
+ handled = true;
13390
+ } else if (eventType === "error") {
13391
+ await closeTrace(
13392
+ next,
13393
+ observedAt,
13394
+ loggedError(read2(event, "error"), "OpenAI Agents session failed")
13395
+ );
13396
+ handled = true;
13397
+ }
13398
+ if (!handled) {
13399
+ return state;
13400
+ }
13401
+ if (eventId) {
13402
+ next.eventIds.push(eventId);
13403
+ }
13404
+ return next;
13405
+ }
13406
+ var interceptOpenAIAgentsTraceStart = async (target, thisArg, args) => {
13407
+ const fallback = await Reflect.apply(target, thisArg, args);
13408
+ try {
13409
+ const state = args[0].state;
13410
+ const parent = state.rootParent;
13411
+ const traceArgs = args[0].args;
13412
+ const parentComponents = SpanComponentsV4.fromStr(parent);
13413
+ const hasParentSpan = Boolean(
13414
+ parentComponents.data.row_id && parentComponents.data.span_id && parentComponents.data.root_span_id
13415
+ );
13416
+ const rootComponents = SpanComponentsV4.fromStr(state.root);
13417
+ const rowId = stringValue(rootComponents.data.row_id);
13418
+ const rootSpanId = stringValue(rootComponents.data.root_span_id);
13419
+ const spanId = stringValue(rootComponents.data.span_id);
13420
+ if (!rowId || !rootSpanId || !spanId) {
13421
+ throw new Error("OpenAI Agents trace root is invalid");
13422
+ }
13423
+ withCurrent(
13424
+ NOOP_SPAN,
13425
+ () => _internalStartSpanWithInitialMergeAndParentSpanIds(
13426
+ withSpanInstrumentationName(
13427
+ {
13428
+ name: "openai.agents.turn",
13429
+ type: "task" /* TASK */,
13430
+ parent,
13431
+ ...!hasParentSpan ? {
13432
+ parentSpanIds: {
13433
+ parentSpanIds: [],
13434
+ rootSpanId
13435
+ }
13436
+ } : {},
13437
+ spanId,
13438
+ startTime: state.startTime,
13439
+ event: {
13440
+ id: rowId,
13441
+ input: read2(traceArgs, "input"),
13442
+ metadata: traceMetadata(traceArgs)
13443
+ }
13444
+ },
13445
+ INSTRUMENTATION_NAMES.OPENAI
13446
+ )
13447
+ )
13448
+ );
13449
+ return state;
13450
+ } catch (error) {
13451
+ logInstrumentationError("could not start trace", error);
13452
+ return fallback;
13453
+ }
13454
+ };
13455
+ var interceptOpenAIAgentsTraceCapture = async (target, thisArg, args) => {
13456
+ const fallback = await Reflect.apply(target, thisArg, args);
13457
+ if (!args[0].state) {
13458
+ return fallback;
13459
+ }
13460
+ try {
13461
+ return await captureEvent(args[0].state, args[0].event);
13462
+ } catch (error) {
13463
+ logInstrumentationError("could not capture event", error);
13464
+ return fallback;
13465
+ }
13466
+ };
13467
+ var interceptOpenAIAgentsTraceFail = async (target, thisArg, args) => {
13468
+ const fallback = await Reflect.apply(target, thisArg, args);
13469
+ if (!args[0].state) {
13470
+ return fallback;
13471
+ }
13472
+ try {
13473
+ const next = copyState(args[0].state);
13474
+ await closeTrace(
13475
+ next,
13476
+ getCurrentUnixTimestamp(),
13477
+ loggedError(args[0].error, "OpenAI Agents request failed")
13478
+ );
13479
+ return next;
13480
+ } catch (error) {
13481
+ logInstrumentationError("could not fail trace", error);
13482
+ return fallback;
13483
+ }
13484
+ };
13485
+
12811
13486
  // src/instrumentation/plugins/openai-plugin.ts
12812
13487
  var OpenAIPlugin = class extends BasePlugin {
12813
13488
  constructor() {
@@ -12815,6 +13490,13 @@ var OpenAIPlugin = class extends BasePlugin {
12815
13490
  }
12816
13491
  onEnable() {
12817
13492
  this.unsubscribers.push(
13493
+ openAIChannels.agentsTraceStart.intercept(
13494
+ interceptOpenAIAgentsTraceStart
13495
+ ),
13496
+ openAIChannels.agentsTraceCapture.intercept(
13497
+ interceptOpenAIAgentsTraceCapture
13498
+ ),
13499
+ openAIChannels.agentsTraceFail.intercept(interceptOpenAIAgentsTraceFail),
12818
13500
  openAIChannels.filesCreateTraced.intercept(
12819
13501
  interceptOpenAIFilesCreateTraced
12820
13502
  ),
@@ -13375,7 +14057,7 @@ async function* patchCodexEventStream(events, state) {
13375
14057
  try {
13376
14058
  await handleCodexEvent(state, event);
13377
14059
  } catch (error) {
13378
- logInstrumentationError("OpenAI Codex stream event", error);
14060
+ logInstrumentationError2("OpenAI Codex stream event", error);
13379
14061
  }
13380
14062
  yield event;
13381
14063
  }
@@ -13875,10 +14557,10 @@ function safeLog(span, event) {
13875
14557
  try {
13876
14558
  span.log(event);
13877
14559
  } catch (error) {
13878
- logInstrumentationError("OpenAI Codex span log", error);
14560
+ logInstrumentationError2("OpenAI Codex span log", error);
13879
14561
  }
13880
14562
  }
13881
- function logInstrumentationError(context, error) {
14563
+ function logInstrumentationError2(context, error) {
13882
14564
  debugLogger.error(`Error processing ${context}:`, error);
13883
14565
  }
13884
14566
 
@@ -15260,27 +15942,8 @@ function continuationParentFromCreateSessionParams(params) {
15260
15942
  }
15261
15943
  return context.parent;
15262
15944
  }
15263
- function exportSpanSynchronously(span) {
15264
- const parentInfo = span.getParentInfo();
15265
- if (!parentInfo) {
15266
- return void 0;
15267
- }
15268
- const objectId = parentInfo.objectId.getSync().value;
15269
- if (!objectId && !parentInfo.computeObjectMetadataArgs) {
15270
- return void 0;
15271
- }
15272
- return new SpanComponentsV4({
15273
- object_type: parentInfo.objectType,
15274
- ...objectId ? { object_id: objectId } : {
15275
- compute_object_metadata_args: parentInfo.computeObjectMetadataArgs ?? {}
15276
- },
15277
- row_id: span.id,
15278
- root_span_id: span.rootSpanId,
15279
- span_id: span.spanId
15280
- }).toStr();
15281
- }
15282
15945
  function exportedParent(parent) {
15283
- return typeof parent === "string" ? parent : exportSpanSynchronously(parent);
15946
+ return typeof parent === "string" ? parent : _internalExportParentSynchronously(parent);
15284
15947
  }
15285
15948
  function addSerializedContext(args) {
15286
15949
  if (!isObject(args.continuation) || args.sessionId === void 0) {
@@ -16037,16 +16700,16 @@ function braintrustAISDKTelemetry() {
16037
16700
  if (!toolCallId || !state) {
16038
16701
  return;
16039
16702
  }
16040
- const toolOutput = event.toolOutput;
16703
+ const toolOutput2 = event.toolOutput;
16041
16704
  const workflowToolError = event.success === false && "error" in event ? event.error : void 0;
16042
- if (toolOutput?.type === "tool-error" || workflowToolError !== void 0) {
16043
- const error = toolOutput?.error ?? workflowToolError;
16705
+ if (toolOutput2?.type === "tool-error" || workflowToolError !== void 0) {
16706
+ const error = toolOutput2?.error ?? workflowToolError;
16044
16707
  state.span.log({
16045
16708
  error: error instanceof Error ? error.message : String(error),
16046
16709
  metrics: typeof event.durationMs === "number" ? { duration_ms: event.durationMs } : {}
16047
16710
  });
16048
16711
  } else {
16049
- const output = toolOutput && "output" in toolOutput ? toolOutput.output : event.output;
16712
+ const output = toolOutput2 && "output" in toolOutput2 ? toolOutput2.output : event.output;
16050
16713
  state.span.log({
16051
16714
  ...shouldRecordOutputs(event) ? { output } : {},
16052
16715
  metrics: typeof event.durationMs === "number" ? { duration_ms: event.durationMs } : {}
@@ -18505,9 +19168,9 @@ function patchAISDKStreamingResult(args) {
18505
19168
  }
18506
19169
  finalize({ metrics, output });
18507
19170
  } catch (error) {
18508
- const loggedError = toLoggedError(error);
19171
+ const loggedError2 = toLoggedError(error);
18509
19172
  try {
18510
- span.log({ error: loggedError });
19173
+ span.log({ error: loggedError2 });
18511
19174
  } catch (loggingError) {
18512
19175
  debugLogger.error(
18513
19176
  "Error logging AI SDK streaming failure:",
@@ -18515,7 +19178,7 @@ function patchAISDKStreamingResult(args) {
18515
19178
  );
18516
19179
  }
18517
19180
  finalize({
18518
- error: error instanceof Error ? error : new Error(String(loggedError))
19181
+ error: error instanceof Error ? error : new Error(String(loggedError2))
18519
19182
  });
18520
19183
  }
18521
19184
  };
@@ -18628,9 +19291,9 @@ function patchAISDKStreamingResult(args) {
18628
19291
  }
18629
19292
  controller.enqueue(value);
18630
19293
  } catch (error) {
18631
- const loggedError = toLoggedError(error);
19294
+ const loggedError2 = toLoggedError(error);
18632
19295
  try {
18633
- span.log({ error: loggedError });
19296
+ span.log({ error: loggedError2 });
18634
19297
  } catch (loggingError) {
18635
19298
  debugLogger.error(
18636
19299
  "Error logging AI SDK base stream failure:",
@@ -18638,7 +19301,7 @@ function patchAISDKStreamingResult(args) {
18638
19301
  );
18639
19302
  }
18640
19303
  finalize({
18641
- error: error instanceof Error ? error : new Error(String(loggedError))
19304
+ error: error instanceof Error ? error : new Error(String(loggedError2))
18642
19305
  });
18643
19306
  controller.error(error);
18644
19307
  }
@@ -21532,7 +22195,7 @@ function wrapSendOptionsCallbacks(options, state) {
21532
22195
  try {
21533
22196
  await handleInteractionUpdate(state, args.update);
21534
22197
  } catch (error) {
21535
- logInstrumentationError2("Cursor SDK onDelta", error);
22198
+ logInstrumentationError3("Cursor SDK onDelta", error);
21536
22199
  }
21537
22200
  if (originalOnDelta) {
21538
22201
  return originalOnDelta(args);
@@ -21542,7 +22205,7 @@ function wrapSendOptionsCallbacks(options, state) {
21542
22205
  try {
21543
22206
  handleStepUpdate(state, args.step);
21544
22207
  } catch (error) {
21545
- logInstrumentationError2("Cursor SDK onStep", error);
22208
+ logInstrumentationError3("Cursor SDK onStep", error);
21546
22209
  }
21547
22210
  if (originalOnStep) {
21548
22211
  return originalOnStep(args);
@@ -21624,7 +22287,7 @@ async function* patchCursorStream(stream, state) {
21624
22287
  try {
21625
22288
  await handleStreamMessage2(state, message);
21626
22289
  } catch (error) {
21627
- logInstrumentationError2("Cursor SDK stream", error);
22290
+ logInstrumentationError3("Cursor SDK stream", error);
21628
22291
  }
21629
22292
  yield message;
21630
22293
  }
@@ -21688,7 +22351,7 @@ async function handleToolUpdate(state, update) {
21688
22351
  if (!state.activeToolSpans.has(callId)) {
21689
22352
  state.activeToolSpans.set(
21690
22353
  callId,
21691
- await startToolSpan(state, {
22354
+ await startToolSpan2(state, {
21692
22355
  args,
21693
22356
  callId,
21694
22357
  name,
@@ -21699,7 +22362,7 @@ async function handleToolUpdate(state, update) {
21699
22362
  }
21700
22363
  return;
21701
22364
  }
21702
- const toolState = state.activeToolSpans.get(callId) ?? await startToolSpan(state, {
22365
+ const toolState = state.activeToolSpans.get(callId) ?? await startToolSpan2(state, {
21703
22366
  args,
21704
22367
  callId,
21705
22368
  name,
@@ -21736,7 +22399,7 @@ async function handleStreamMessage2(state, message) {
21736
22399
  } else if (block?.type === "tool_use" && block.id) {
21737
22400
  state.activeToolSpans.set(
21738
22401
  block.id,
21739
- await startToolSpan(state, {
22402
+ await startToolSpan2(state, {
21740
22403
  args: block.input,
21741
22404
  callId: block.id,
21742
22405
  name: block.name,
@@ -21771,7 +22434,7 @@ async function handleToolMessage(state, message) {
21771
22434
  if (!state.activeToolSpans.has(callId)) {
21772
22435
  state.activeToolSpans.set(
21773
22436
  callId,
21774
- await startToolSpan(state, {
22437
+ await startToolSpan2(state, {
21775
22438
  args: message.args,
21776
22439
  callId,
21777
22440
  name: message.name,
@@ -21782,7 +22445,7 @@ async function handleToolMessage(state, message) {
21782
22445
  }
21783
22446
  return;
21784
22447
  }
21785
- const toolState = state.activeToolSpans.get(callId) ?? await startToolSpan(state, {
22448
+ const toolState = state.activeToolSpans.get(callId) ?? await startToolSpan2(state, {
21786
22449
  args: message.args,
21787
22450
  callId,
21788
22451
  name: message.name,
@@ -21809,7 +22472,7 @@ async function handleConversation(state, turns) {
21809
22472
  const command = turn.turn?.shellCommand?.command;
21810
22473
  if (command) {
21811
22474
  const callId = `shell:${state.activeToolSpans.size}:${command}`;
21812
- const toolState = await startToolSpan(state, {
22475
+ const toolState = await startToolSpan2(state, {
21813
22476
  args: turn.turn?.shellCommand,
21814
22477
  callId,
21815
22478
  name: "shell",
@@ -21833,7 +22496,7 @@ async function handleConversationStep(state, step) {
21833
22496
  }
21834
22497
  const toolCall = step.message;
21835
22498
  const callId = typeof toolCall?.callId === "string" ? toolCall.callId : `conversation-tool:${state.activeToolSpans.size}`;
21836
- const toolState = await startToolSpan(state, {
22499
+ const toolState = await startToolSpan2(state, {
21837
22500
  args: extractToolArgs(toolCall),
21838
22501
  callId,
21839
22502
  name: extractToolName(toolCall),
@@ -21864,7 +22527,7 @@ function handleStepUpdate(state, step) {
21864
22527
  state.stepText.push(step.message.text);
21865
22528
  }
21866
22529
  }
21867
- async function startToolSpan(state, args) {
22530
+ async function startToolSpan2(state, args) {
21868
22531
  const name = args.name || "unknown";
21869
22532
  const metadata = {
21870
22533
  "cursor_sdk.tool.status": args.status,
@@ -22151,10 +22814,10 @@ function safeLog2(span, event) {
22151
22814
  try {
22152
22815
  span.log(event);
22153
22816
  } catch (error) {
22154
- logInstrumentationError2("Cursor SDK span log", error);
22817
+ logInstrumentationError3("Cursor SDK span log", error);
22155
22818
  }
22156
22819
  }
22157
- function logInstrumentationError2(context, error) {
22820
+ function logInstrumentationError3(context, error) {
22158
22821
  debugLogger.error(`Error processing ${context}:`, error);
22159
22822
  }
22160
22823
  function cleanMetrics2(metrics) {
@@ -22992,6 +23655,10 @@ var googleGenAIChannels = defineChannels(
22992
23655
  channelName: "models.embedContent",
22993
23656
  kind: "async"
22994
23657
  }),
23658
+ httpResponseJson: channel({
23659
+ channelName: "httpResponse.json",
23660
+ kind: "async"
23661
+ }),
22995
23662
  interactionsCreate: channel({
22996
23663
  channelName: "interactions.create",
22997
23664
  kind: "async"
@@ -23140,13 +23807,45 @@ var GoogleGenAIPlugin = class extends BasePlugin {
23140
23807
  subscribeToEmbedContentChannel() {
23141
23808
  const tracingChannel = googleGenAIChannels.embedContent.tracingChannel();
23142
23809
  const states = /* @__PURE__ */ new WeakMap();
23810
+ const embeddingSpans = /* @__PURE__ */ new WeakSet();
23811
+ this.unsubscribers.push(
23812
+ googleGenAIChannels.httpResponseJson.intercept(
23813
+ (target, thisArg, args) => {
23814
+ const span = currentSpan();
23815
+ const result = Reflect.apply(target, thisArg, args);
23816
+ if (embeddingSpans.has(span)) {
23817
+ void Promise.resolve(result).then(
23818
+ (response) => {
23819
+ try {
23820
+ const metrics = cleanMetrics3(
23821
+ extractEmbedContentMetrics(response)
23822
+ );
23823
+ if (embeddingSpans.has(span) && Object.keys(metrics).length > 0) {
23824
+ span.log({ metrics });
23825
+ }
23826
+ } catch (error) {
23827
+ debugLogger.error(
23828
+ "Error reading Google GenAI embedding usage:",
23829
+ error
23830
+ );
23831
+ }
23832
+ },
23833
+ () => {
23834
+ }
23835
+ // The embedding channel handles the original rejection.
23836
+ );
23837
+ }
23838
+ return result;
23839
+ }
23840
+ )
23841
+ );
23143
23842
  const unbindCurrentSpanStore = bindCurrentSpanStoreToStart2(
23144
23843
  tracingChannel,
23145
23844
  states,
23146
23845
  (event) => {
23147
23846
  const params = event.arguments[0];
23148
23847
  const input = serializeEmbedContentInput(params);
23149
- const metadata = extractEmbedContentMetadata(params);
23848
+ const metadata = { provider: "google", model: params.model };
23150
23849
  const span = startSpan(
23151
23850
  withSpanInstrumentationName(
23152
23851
  {
@@ -23159,6 +23858,7 @@ var GoogleGenAIPlugin = class extends BasePlugin {
23159
23858
  INSTRUMENTATION_NAMES.GOOGLE_GENAI
23160
23859
  )
23161
23860
  );
23861
+ embeddingSpans.add(span);
23162
23862
  return {
23163
23863
  span,
23164
23864
  startTime: getCurrentUnixTimestamp()
@@ -23170,7 +23870,7 @@ var GoogleGenAIPlugin = class extends BasePlugin {
23170
23870
  ensureSpanState(states, event, () => {
23171
23871
  const params = event.arguments[0];
23172
23872
  const input = serializeEmbedContentInput(params);
23173
- const metadata = extractEmbedContentMetadata(params);
23873
+ const metadata = { provider: "google", model: params.model };
23174
23874
  const span = startSpan(
23175
23875
  withSpanInstrumentationName(
23176
23876
  {
@@ -23183,6 +23883,7 @@ var GoogleGenAIPlugin = class extends BasePlugin {
23183
23883
  INSTRUMENTATION_NAMES.GOOGLE_GENAI
23184
23884
  )
23185
23885
  );
23886
+ embeddingSpans.add(span);
23186
23887
  return {
23187
23888
  span,
23188
23889
  startTime: getCurrentUnixTimestamp()
@@ -23195,20 +23896,28 @@ var GoogleGenAIPlugin = class extends BasePlugin {
23195
23896
  return;
23196
23897
  }
23197
23898
  try {
23198
- const output = summarizeEmbedContentOutput(event.result);
23199
23899
  spanState.span.log({
23200
- ...output ? { output } : {},
23900
+ output: summarizeEmbedContentOutput(event.result),
23201
23901
  metrics: cleanMetrics3(
23202
23902
  extractEmbedContentMetrics(event.result, spanState.startTime)
23203
23903
  )
23204
23904
  });
23205
23905
  } finally {
23906
+ embeddingSpans.delete(spanState.span);
23206
23907
  spanState.span.end();
23207
23908
  states.delete(event);
23208
23909
  }
23209
23910
  },
23210
23911
  error: (event) => {
23211
- logErrorAndEndSpan(states, event);
23912
+ const spanState = states.get(event);
23913
+ if (!spanState) return;
23914
+ try {
23915
+ spanState.span.log({ error: event.error, output: { count: 0 } });
23916
+ } finally {
23917
+ embeddingSpans.delete(spanState.span);
23918
+ spanState.span.end();
23919
+ states.delete(event);
23920
+ }
23212
23921
  }
23213
23922
  };
23214
23923
  tracingChannel.subscribe(handlers);
@@ -23443,15 +24152,53 @@ function serializeGenerateContentInput(params) {
23443
24152
  return input;
23444
24153
  }
23445
24154
  function serializeEmbedContentInput(params) {
24155
+ let contents = Array.isArray(params.contents) ? params.contents : [params.contents];
24156
+ if (params.model.includes("gemini-embedding-2") && contents.length > 0 && contents.every(
24157
+ (content) => typeof content === "string" || !Array.isArray(content) && !("parts" in content)
24158
+ )) {
24159
+ contents = [contents];
24160
+ }
23446
24161
  const input = {
23447
- model: params.model,
23448
- contents: serializeContentCollection(params.contents)
24162
+ inputs: contents.map((content) => {
24163
+ const parts = typeof content === "string" ? [content] : Array.isArray(content) ? content : "parts" in content ? content.parts : [content];
24164
+ const normalized = parts.flatMap((part) => {
24165
+ if (typeof part === "string") return [{ type: "text", text: part }];
24166
+ if (part.text !== void 0) return [{ type: "text", text: part.text }];
24167
+ const media = part.inlineData ?? part.fileData;
24168
+ if (!media) return [];
24169
+ const data = "data" in media ? `data:${media.mimeType};base64,${typeof media.data === "string" ? media.data : uint8ArrayToBase64(media.data)}` : media.fileUri;
24170
+ return media.mimeType?.startsWith("image/") ? [{ type: "image_url", image_url: { url: data } }] : [
24171
+ {
24172
+ type: "file",
24173
+ file: {
24174
+ file_data: data,
24175
+ ..."displayName" in media && media.displayName ? { filename: media.displayName } : {}
24176
+ }
24177
+ }
24178
+ ];
24179
+ });
24180
+ return {
24181
+ content: normalized.length === 1 && normalized[0].type === "text" ? normalized[0].text : normalized
24182
+ };
24183
+ }),
24184
+ ...params.config?.outputDimensionality !== void 0 ? { output_dimensions: params.config.outputDimensionality } : {}
23449
24185
  };
23450
- const config = params.config ? tryToDict(params.config) : null;
23451
- if (config) {
23452
- input.config = config;
24186
+ try {
24187
+ const processed = processInputAttachments(input);
24188
+ const hasInlineMedia = processed.inputs.some(
24189
+ ({ content }) => Array.isArray(content) && content.some((part) => {
24190
+ const data = part.type === "image_url" ? part.image_url.url : part.type === "file" ? part.file.file_data : void 0;
24191
+ return typeof data === "string" && data.startsWith("data:");
24192
+ })
24193
+ );
24194
+ return hasInlineMedia ? input : processed;
24195
+ } catch (error) {
24196
+ debugLogger.error(
24197
+ "Error processing Google GenAI embedding attachments:",
24198
+ error
24199
+ );
24200
+ return input;
23453
24201
  }
23454
- return input;
23455
24202
  }
23456
24203
  function serializeInteractionInput(params) {
23457
24204
  const input = {
@@ -23639,19 +24386,6 @@ function extractGenerateContentMetadata(params) {
23639
24386
  }
23640
24387
  return metadata;
23641
24388
  }
23642
- function extractEmbedContentMetadata(params) {
23643
- const metadata = {};
23644
- if (params.model) {
23645
- metadata.model = params.model;
23646
- }
23647
- const config = params.config ? tryToDict(params.config) : null;
23648
- if (config) {
23649
- Object.keys(config).forEach((key) => {
23650
- metadata[key] = config[key];
23651
- });
23652
- }
23653
- return metadata;
23654
- }
23655
24389
  function extractGenerateContentMetrics(response, startTime) {
23656
24390
  const metrics = {};
23657
24391
  if (startTime !== void 0) {
@@ -23671,15 +24405,23 @@ function extractEmbedContentMetrics(response, startTime) {
23671
24405
  const end = getCurrentUnixTimestamp();
23672
24406
  metrics.start = startTime;
23673
24407
  metrics.end = end;
23674
- metrics.duration = end - startTime;
23675
- }
23676
- if (response?.usageMetadata) {
23677
- populateUsageMetrics(metrics, response.usageMetadata);
23678
24408
  }
23679
24409
  const embeddingTokenCount = extractEmbedPromptTokenCount(response);
23680
24410
  if (embeddingTokenCount !== void 0) {
23681
24411
  metrics.prompt_tokens = embeddingTokenCount;
23682
- metrics.tokens = embeddingTokenCount;
24412
+ }
24413
+ const totalTokens = response?.usageMetadata?.totalTokenCount ?? embeddingTokenCount;
24414
+ if (totalTokens !== void 0) {
24415
+ metrics.tokens = totalTokens;
24416
+ }
24417
+ const audioTokens = (response?.usageMetadata?.promptTokenDetails ?? response?.usageMetadata?.promptTokensDetails)?.filter(
24418
+ (detail) => detail.modality === "AUDIO" && detail.tokenCount !== void 0
24419
+ );
24420
+ if (audioTokens?.length) {
24421
+ metrics.prompt_audio_tokens = audioTokens.reduce(
24422
+ (sum, detail) => sum + (detail.tokenCount ?? 0),
24423
+ 0
24424
+ );
23683
24425
  }
23684
24426
  return metrics;
23685
24427
  }
@@ -23718,41 +24460,25 @@ function extractEmbedPromptTokenCount(response) {
23718
24460
  if (typeof usagePromptTokens === "number" && Number.isFinite(usagePromptTokens)) {
23719
24461
  return usagePromptTokens;
23720
24462
  }
23721
- const usageTotalTokens = response.usageMetadata?.totalTokenCount;
23722
- if (typeof usageTotalTokens === "number" && Number.isFinite(usageTotalTokens)) {
23723
- return usageTotalTokens;
23724
- }
23725
24463
  const embeddings = Array.isArray(response.embeddings) ? response.embeddings : response.embedding ? [response.embedding] : [];
23726
24464
  if (embeddings.length === 0) {
23727
24465
  return void 0;
23728
24466
  }
23729
24467
  let total = 0;
23730
- let sawAny = false;
23731
24468
  for (const embedding of embeddings) {
23732
24469
  const embeddingStats = tryToDict(tryToDict(embedding)?.statistics);
23733
24470
  const tokenCount2 = embeddingStats?.tokenCount;
23734
24471
  if (typeof tokenCount2 === "number" && Number.isFinite(tokenCount2)) {
23735
24472
  total += tokenCount2;
23736
- sawAny = true;
24473
+ } else {
24474
+ return void 0;
23737
24475
  }
23738
24476
  }
23739
- return sawAny ? total : void 0;
24477
+ return total;
23740
24478
  }
23741
24479
  function summarizeEmbedContentOutput(response) {
23742
- if (!response) {
23743
- return void 0;
23744
- }
23745
- const embeddings = Array.isArray(response.embeddings) ? response.embeddings : response.embedding ? [response.embedding] : [];
23746
- if (embeddings.length === 0) {
23747
- return void 0;
23748
- }
23749
- const firstValues = embeddings[0]?.values;
23750
- if (!Array.isArray(firstValues)) {
23751
- return void 0;
23752
- }
23753
24480
  return {
23754
- embedding_count: embeddings.length,
23755
- embedding_length: firstValues.length
24481
+ count: Array.isArray(response?.embeddings) ? response.embeddings.length : response?.embedding ? 1 : 0
23756
24482
  };
23757
24483
  }
23758
24484
  function populateUsageMetrics(metrics, usage) {
@@ -27379,6 +28105,379 @@ function aggregateMistralStreamChunks(chunks) {
27379
28105
  };
27380
28106
  }
27381
28107
 
28108
+ // src/instrumentation/plugins/langgraph-sdk-channels.ts
28109
+ var langGraphSDKChannels = defineChannels(
28110
+ "@langchain/langgraph-sdk",
28111
+ {
28112
+ wait: channel({
28113
+ channelName: "runs.wait",
28114
+ kind: "async"
28115
+ }),
28116
+ stream: channel({
28117
+ channelName: "runs.stream",
28118
+ kind: "sync-stream"
28119
+ })
28120
+ },
28121
+ { instrumentationName: INSTRUMENTATION_NAMES.LANGGRAPH_SDK }
28122
+ );
28123
+
28124
+ // src/instrumentation/plugins/langgraph-sdk-plugin.ts
28125
+ var LangGraphSDKPlugin = class extends BasePlugin {
28126
+ onEnable() {
28127
+ this.unsubscribers.push(
28128
+ langGraphSDKChannels.wait.intercept(
28129
+ (target, self, args) => instrumentRun("wait", args, () => Reflect.apply(target, self, args))
28130
+ ),
28131
+ langGraphSDKChannels.stream.intercept(
28132
+ (target, self, args) => instrumentRun("stream", args, () => Reflect.apply(target, self, args))
28133
+ )
28134
+ );
28135
+ }
28136
+ onDisable() {
28137
+ this.unsubscribers = unsubscribeAll(this.unsubscribers);
28138
+ }
28139
+ };
28140
+ function normalizeMessage(value) {
28141
+ if (!isObject(value)) return value;
28142
+ 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);
28143
+ if (typeof role !== "string") return value;
28144
+ const message = {
28145
+ role,
28146
+ content: value.content ?? ""
28147
+ };
28148
+ for (const key of ["name", "tool_call_id", "refusal"]) {
28149
+ if (value[key] !== void 0) message[key] = value[key];
28150
+ }
28151
+ const additional = isObject(value.additional_kwargs) ? value.additional_kwargs : {};
28152
+ const toolCalls = Array.isArray(value.tool_calls) && value.tool_calls.length ? value.tool_calls : additional.tool_calls;
28153
+ if (Array.isArray(toolCalls) && toolCalls.length > 0) {
28154
+ message.tool_calls = toolCalls.map((call) => {
28155
+ if (!isObject(call)) return call;
28156
+ if (isObject(call.function)) return call;
28157
+ return {
28158
+ id: call.id,
28159
+ type: "function",
28160
+ function: {
28161
+ name: call.name,
28162
+ arguments: typeof call.args === "string" ? call.args : JSON.stringify(call.args ?? {})
28163
+ }
28164
+ };
28165
+ });
28166
+ }
28167
+ if (Array.isArray(value.invalid_tool_calls) && value.invalid_tool_calls.length > 0)
28168
+ message.invalid_tool_calls = value.invalid_tool_calls;
28169
+ if (message.refusal === void 0 && additional.refusal !== void 0)
28170
+ message.refusal = additional.refusal;
28171
+ return message;
28172
+ }
28173
+ function normalizeRunError(value) {
28174
+ let name;
28175
+ let message;
28176
+ if (value instanceof Error) {
28177
+ name = value.name;
28178
+ message = value.message;
28179
+ } else if (isObject(value) && typeof value.error === "string" && typeof value.message === "string") {
28180
+ name = value.error;
28181
+ message = value.message;
28182
+ } else {
28183
+ return value;
28184
+ }
28185
+ for (let depth = 0; depth < 3; depth++) {
28186
+ try {
28187
+ const nested = JSON.parse(
28188
+ message.startsWith(`${name}: `) ? message.slice(name.length + 2) : message
28189
+ );
28190
+ if (!isObject(nested) || typeof nested.error !== "string" || typeof nested.message !== "string")
28191
+ break;
28192
+ name = nested.error;
28193
+ message = nested.message;
28194
+ } catch {
28195
+ break;
28196
+ }
28197
+ }
28198
+ if (value instanceof Error && name === value.name && message === value.message)
28199
+ return value;
28200
+ return Object.assign(new Error(message), { name });
28201
+ }
28202
+ function normalizeState(value) {
28203
+ if (!isObject(value)) return value;
28204
+ return Object.fromEntries(
28205
+ Object.entries(value).map(([key, field]) => {
28206
+ if (key === "messages" && Array.isArray(field))
28207
+ return [key, field.map(normalizeMessage)];
28208
+ if (key === "__error__") {
28209
+ const error = normalizeRunError(field);
28210
+ if (error instanceof Error)
28211
+ return [key, { error: error.name, message: error.message }];
28212
+ }
28213
+ return [key, field];
28214
+ })
28215
+ );
28216
+ }
28217
+ function normalizeRunOutput(value, input) {
28218
+ if (!isObject(value)) return value;
28219
+ if (Array.isArray(value.messages)) {
28220
+ if (value.__interrupt__ !== void 0 || value.__error__ !== void 0)
28221
+ return void 0;
28222
+ const inputMessages = isObject(input) && Array.isArray(input.messages) ? input.messages : [];
28223
+ let inputPrefixLength = 0;
28224
+ while (inputPrefixLength < inputMessages.length) {
28225
+ const previous = inputMessages[inputPrefixLength];
28226
+ const message = value.messages[inputPrefixLength];
28227
+ 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)))
28228
+ break;
28229
+ inputPrefixLength++;
28230
+ }
28231
+ for (let index = value.messages.length - 1; index >= inputPrefixLength; index--) {
28232
+ const message = value.messages[index];
28233
+ const normalized = normalizeMessage(message);
28234
+ if (!isObject(normalized)) continue;
28235
+ if (normalized.role === "user") return void 0;
28236
+ if (normalized.role !== "assistant") continue;
28237
+ if (inputMessages.some((previous) => {
28238
+ if (!isObject(previous) || !isObject(message)) return false;
28239
+ return previous.id !== void 0 && previous.id === message.id && JSON.stringify(normalizeMessage(previous)) === JSON.stringify(normalized);
28240
+ }))
28241
+ continue;
28242
+ return normalized;
28243
+ }
28244
+ return void 0;
28245
+ }
28246
+ const result = Object.fromEntries(
28247
+ Object.entries(value).filter(
28248
+ ([key]) => key !== "__interrupt__" && key !== "__error__"
28249
+ )
28250
+ );
28251
+ return !Object.keys(result).length && (value.__interrupt__ !== void 0 || value.__error__ !== void 0) ? void 0 : result;
28252
+ }
28253
+ function instrumentRun(operation, [threadId, assistantId, options], invoke) {
28254
+ if (isAutoInstrumentationSuppressed()) return invoke();
28255
+ const start = getCurrentUnixTimestamp();
28256
+ let span;
28257
+ try {
28258
+ const metadata = {
28259
+ "langgraph.thread_id": threadId,
28260
+ "langgraph.assistant_id": assistantId
28261
+ };
28262
+ for (const key of [
28263
+ "streamMode",
28264
+ "streamSubgraphs",
28265
+ "interruptBefore",
28266
+ "interruptAfter",
28267
+ "multitaskStrategy",
28268
+ "durability"
28269
+ ]) {
28270
+ if (options?.[key] !== void 0) metadata[key] = options[key];
28271
+ }
28272
+ span = startSpan(
28273
+ withSpanInstrumentationName(
28274
+ {
28275
+ name: `langgraph.runs.${operation}`,
28276
+ spanAttributes: { type: "task" /* TASK */ },
28277
+ event: {
28278
+ input: options?.command === void 0 ? normalizeState(options?.input) : {
28279
+ input: normalizeState(options.input),
28280
+ command: options.command
28281
+ },
28282
+ metadata
28283
+ }
28284
+ },
28285
+ INSTRUMENTATION_NAMES.LANGGRAPH_SDK
28286
+ )
28287
+ );
28288
+ } catch (error) {
28289
+ debugLogger.error("Error starting LangGraph SDK span:", error);
28290
+ return invoke();
28291
+ }
28292
+ let ended = false;
28293
+ let output;
28294
+ let streamError;
28295
+ let firstToken;
28296
+ const updates = [];
28297
+ const usageByMessage = /* @__PURE__ */ new Map();
28298
+ const captureUsage = (id, usage) => {
28299
+ if (!isObject(usage)) return;
28300
+ const metrics = {};
28301
+ for (const [source, destination] of [
28302
+ ["input_tokens", "prompt_tokens"],
28303
+ ["output_tokens", "completion_tokens"],
28304
+ ["total_tokens", "tokens"]
28305
+ ]) {
28306
+ const value = usage[source];
28307
+ if (typeof value === "number" && Number.isFinite(value) && value >= 0)
28308
+ metrics[destination] = value;
28309
+ }
28310
+ if (metrics.tokens === void 0 && metrics.prompt_tokens !== void 0 && metrics.completion_tokens !== void 0)
28311
+ metrics.tokens = metrics.prompt_tokens + metrics.completion_tokens;
28312
+ usageByMessage.set(id, { ...usageByMessage.get(id), ...metrics });
28313
+ };
28314
+ const messages = /* @__PURE__ */ new Map();
28315
+ const messageSnapshots = /* @__PURE__ */ new Map();
28316
+ const finish = (error) => {
28317
+ if (ended) return;
28318
+ ended = true;
28319
+ try {
28320
+ const metrics = {};
28321
+ for (const usage of usageByMessage.values()) {
28322
+ for (const [key, value] of Object.entries(usage))
28323
+ metrics[key] = (metrics[key] ?? 0) + value;
28324
+ }
28325
+ if (firstToken !== void 0)
28326
+ metrics.time_to_first_token = firstToken - start;
28327
+ const finalMessages = [
28328
+ ...new Map([...messages, ...messageSnapshots]).values()
28329
+ ];
28330
+ let loggedOutput = normalizeRunOutput(output, options?.input);
28331
+ if (loggedOutput === void 0 && finalMessages.length)
28332
+ loggedOutput = normalizeRunOutput(
28333
+ { messages: finalMessages },
28334
+ void 0
28335
+ );
28336
+ if (output === void 0 && !finalMessages.length && updates.length) {
28337
+ const results = updates.map((update) => normalizeRunOutput(update, options?.input)).filter((update) => update !== void 0);
28338
+ if (results.length) loggedOutput = { updates: results };
28339
+ }
28340
+ const interrupted = [output, ...updates].find(
28341
+ (state) => isObject(state) && state.__interrupt__ !== void 0
28342
+ );
28343
+ span.log({
28344
+ ...loggedOutput !== void 0 ? { output: loggedOutput } : {},
28345
+ ...isObject(interrupted) ? { metadata: { "langgraph.interrupts": interrupted.__interrupt__ } } : {},
28346
+ ...error !== void 0 || streamError !== void 0 ? { error: normalizeRunError(error ?? streamError) } : {},
28347
+ metrics
28348
+ });
28349
+ } catch (error2) {
28350
+ debugLogger.error("Error logging LangGraph SDK span:", error2);
28351
+ }
28352
+ try {
28353
+ span.end();
28354
+ } catch (error2) {
28355
+ debugLogger.error("Error ending LangGraph SDK span:", error2);
28356
+ }
28357
+ };
28358
+ const observeMessages = (value, streaming) => {
28359
+ if (!isObject(value) || !Array.isArray(value.messages)) return;
28360
+ const inputMessages = isObject(options?.input) && Array.isArray(options.input.messages) ? options.input.messages : [];
28361
+ for (const message of value.messages) {
28362
+ if (!isObject(message) || message.type !== "ai" && message.role !== "assistant")
28363
+ continue;
28364
+ if (message.id !== void 0 && inputMessages.some(
28365
+ (input) => isObject(input) && input.id === message.id
28366
+ ))
28367
+ continue;
28368
+ captureUsage(
28369
+ typeof message.id === "string" ? message.id : "message",
28370
+ message.usage_metadata
28371
+ );
28372
+ if (streaming && (typeof message.content === "string" ? message.content.length > 0 : Array.isArray(message.content) && message.content.some(
28373
+ (part) => isObject(part) && typeof part.text === "string" && part.text.length > 0
28374
+ )))
28375
+ firstToken ??= getCurrentUnixTimestamp();
28376
+ }
28377
+ };
28378
+ const onChunk = ({ event, data }) => {
28379
+ if (ended) return;
28380
+ if (event === "metadata" && isObject(data)) {
28381
+ if (typeof data.run_id === "string")
28382
+ span.log({ metadata: { "langgraph.run_id": data.run_id } });
28383
+ } else if (event === "error") {
28384
+ streamError = normalizeRunError(data);
28385
+ } else if (event === "values") {
28386
+ output = data;
28387
+ observeMessages(data, true);
28388
+ } else if (event === "updates") {
28389
+ if (isObject(data)) {
28390
+ const stateUpdates = [];
28391
+ for (const [node, update] of Object.entries(data)) {
28392
+ observeMessages(update, true);
28393
+ if (isObject(update) && Array.isArray(update.messages)) {
28394
+ for (const message of update.messages) {
28395
+ if (isObject(message))
28396
+ messageSnapshots.set(
28397
+ typeof message.id === "string" ? message.id : `update-${messageSnapshots.size}`,
28398
+ message
28399
+ );
28400
+ }
28401
+ const state = Object.fromEntries(
28402
+ Object.entries(update).filter(([key]) => key !== "messages")
28403
+ );
28404
+ if (Object.keys(state).length) stateUpdates.push([node, state]);
28405
+ } else {
28406
+ stateUpdates.push([node, update]);
28407
+ }
28408
+ }
28409
+ if (stateUpdates.length) updates.push(Object.fromEntries(stateUpdates));
28410
+ } else {
28411
+ updates.push(data);
28412
+ }
28413
+ } else if ((event === "messages" || event === "messages/partial" || event === "messages/complete") && Array.isArray(data)) {
28414
+ const parts = event === "messages" ? [data[0]] : data;
28415
+ for (const part of parts) {
28416
+ if (!isObject(part)) continue;
28417
+ const id = typeof part.id === "string" ? part.id : "message";
28418
+ captureUsage(id, part.usage_metadata);
28419
+ const previous = messages.get(id);
28420
+ messages.set(
28421
+ id,
28422
+ event === "messages" && previous && typeof part.content === "string" && typeof previous.content === "string" ? { ...part, content: previous.content + part.content } : part
28423
+ );
28424
+ if (typeof part.content === "string" && part.content.length > 0)
28425
+ firstToken ??= getCurrentUnixTimestamp();
28426
+ }
28427
+ }
28428
+ };
28429
+ let result;
28430
+ try {
28431
+ result = withCurrent(
28432
+ span,
28433
+ () => runWithAutoInstrumentationSuppressed(invoke)
28434
+ );
28435
+ } catch (error) {
28436
+ finish(error);
28437
+ throw error;
28438
+ }
28439
+ if (operation === "stream") {
28440
+ try {
28441
+ patchStreamIfNeeded(result, {
28442
+ shouldCollect: (chunk) => {
28443
+ try {
28444
+ onChunk(chunk);
28445
+ } catch (error) {
28446
+ debugLogger.error(
28447
+ "Error processing LangGraph stream event:",
28448
+ error
28449
+ );
28450
+ }
28451
+ return false;
28452
+ },
28453
+ aroundNext: (next) => withCurrent(span, () => runWithAutoInstrumentationSuppressed(next)),
28454
+ onComplete: () => finish(),
28455
+ onCancel: () => finish(),
28456
+ onError: (error) => finish(error)
28457
+ });
28458
+ } catch (error) {
28459
+ debugLogger.error("Error observing LangGraph stream:", error);
28460
+ finish();
28461
+ }
28462
+ } else {
28463
+ void Promise.resolve(result).then(
28464
+ (value) => {
28465
+ try {
28466
+ output = value;
28467
+ observeMessages(value, false);
28468
+ if (isObject(value) && isObject(value.__error__))
28469
+ streamError = normalizeRunError(value.__error__);
28470
+ finish();
28471
+ } catch (error) {
28472
+ finish(error);
28473
+ }
28474
+ },
28475
+ (error) => finish(error)
28476
+ );
28477
+ }
28478
+ return result;
28479
+ }
28480
+
27382
28481
  // src/instrumentation/plugins/ollama-channels.ts
27383
28482
  var ollamaChannels = defineChannels(
27384
28483
  "ollama",
@@ -27588,7 +28687,7 @@ function normalizeTextAndImages(content, images) {
27588
28687
  ...unrecognizedImages.length > 0 ? { unrecognizedImages } : {}
27589
28688
  };
27590
28689
  }
27591
- function normalizeMessage(message, toolCallId, syntheticToolCallIdOffset = 0) {
28690
+ function normalizeMessage2(message, toolCallId, syntheticToolCallIdOffset = 0) {
27592
28691
  if (typeof message.role !== "string") {
27593
28692
  return void 0;
27594
28693
  }
@@ -27634,7 +28733,7 @@ function normalizeMessages(messages) {
27634
28733
  toolCallId = pendingToolCallIds.get(toolName)?.shift();
27635
28734
  }
27636
28735
  }
27637
- const normalized = normalizeMessage(
28736
+ const normalized = normalizeMessage2(
27638
28737
  ollamaMessage,
27639
28738
  toolCallId,
27640
28739
  syntheticToolCallIdOffset
@@ -27753,7 +28852,7 @@ function extractOllamaChatOutput(result, syntheticToolCallIdOffset = 0) {
27753
28852
  if (!isObject(result) || !isObject(result.message)) {
27754
28853
  return void 0;
27755
28854
  }
27756
- const message = normalizeMessage(
28855
+ const message = normalizeMessage2(
27757
28856
  result.message,
27758
28857
  void 0,
27759
28858
  syntheticToolCallIdOffset
@@ -30473,14 +31572,14 @@ function extractActionSpanMetadata(args) {
30473
31572
  const options = extractRunInNewSpanOptions(args);
30474
31573
  const labels = isObject(options?.labels) ? options.labels : void 0;
30475
31574
  const metadata = isObject(options?.metadata) ? options.metadata : void 0;
30476
- const actionType = stringValue(labels?.["genkit:metadata:subtype"]);
30477
- const name = stringValue(metadata?.name);
31575
+ const actionType = stringValue2(labels?.["genkit:metadata:subtype"]);
31576
+ const name = stringValue2(metadata?.name);
30478
31577
  if (!actionType || !name) {
30479
31578
  return void 0;
30480
31579
  }
30481
31580
  return {
30482
31581
  actionType,
30483
- key: stringValue(labels?.["genkit:key"]),
31582
+ key: stringValue2(labels?.["genkit:key"]),
30484
31583
  name
30485
31584
  };
30486
31585
  }
@@ -30590,7 +31689,7 @@ function pickNumberMetrics(values) {
30590
31689
  })
30591
31690
  );
30592
31691
  }
30593
- function stringValue(value) {
31692
+ function stringValue2(value) {
30594
31693
  return typeof value === "string" ? value : void 0;
30595
31694
  }
30596
31695
 
@@ -31275,7 +32374,7 @@ function subscribeToFlueContext(value, state) {
31275
32374
  try {
31276
32375
  unsubscribe?.();
31277
32376
  } catch (error) {
31278
- logInstrumentationError3("Flue context unsubscribe", error);
32377
+ logInstrumentationError4("Flue context unsubscribe", error);
31279
32378
  }
31280
32379
  };
31281
32380
  try {
@@ -31291,7 +32390,7 @@ function subscribeToFlueContext(value, state) {
31291
32390
  });
31292
32391
  state.contexts.add(value);
31293
32392
  } catch (error) {
31294
- logInstrumentationError3("Flue context subscription", error);
32393
+ logInstrumentationError4("Flue context subscription", error);
31295
32394
  }
31296
32395
  }
31297
32396
  function isAutoContextTerminalEvent(event, ctx) {
@@ -31347,7 +32446,7 @@ var FlueObserveBridge = class {
31347
32446
  try {
31348
32447
  this.handleEvent(event, flueContextFromUnknown(ctx));
31349
32448
  } catch (error) {
31350
- logInstrumentationError3("Flue observe", error);
32449
+ logInstrumentationError4("Flue observe", error);
31351
32450
  }
31352
32451
  }
31353
32452
  reset() {
@@ -31364,7 +32463,7 @@ var FlueObserveBridge = class {
31364
32463
  try {
31365
32464
  span = this.spanForExecutionOperation(operation, executionContext);
31366
32465
  } catch (error) {
31367
- logInstrumentationError3("Flue execution interceptor", error);
32466
+ logInstrumentationError4("Flue execution interceptor", error);
31368
32467
  }
31369
32468
  return span ? runWithCurrentSpanStore(span, next) : next();
31370
32469
  }
@@ -31570,7 +32669,7 @@ var FlueObserveBridge = class {
31570
32669
  this.runsById.delete(event.runId);
31571
32670
  }
31572
32671
  void flush().catch((error) => {
31573
- logInstrumentationError3("Flue flush", error);
32672
+ logInstrumentationError4("Flue flush", error);
31574
32673
  });
31575
32674
  }
31576
32675
  handleOperationStart(event) {
@@ -32345,17 +33444,17 @@ function safeLog3(span, event) {
32345
33444
  try {
32346
33445
  span.log(event);
32347
33446
  } catch (error) {
32348
- logInstrumentationError3("Flue span log", error);
33447
+ logInstrumentationError4("Flue span log", error);
32349
33448
  }
32350
33449
  }
32351
33450
  function safeEnd(span, endTime) {
32352
33451
  try {
32353
33452
  span.end(endTime === void 0 ? void 0 : { endTime });
32354
33453
  } catch (error) {
32355
- logInstrumentationError3("Flue span end", error);
33454
+ logInstrumentationError4("Flue span end", error);
32356
33455
  }
32357
33456
  }
32358
- function logInstrumentationError3(label, error) {
33457
+ function logInstrumentationError4(label, error) {
32359
33458
  debugLogger.debug(`Error in ${label} instrumentation:`, error);
32360
33459
  }
32361
33460
 
@@ -32923,10 +34022,10 @@ var LangSmithPlugin = class extends BasePlugin {
32923
34022
  const creates = ownValue(batch, "runCreates");
32924
34023
  if (Array.isArray(creates)) {
32925
34024
  const parentFirst = [...creates].sort((left, right) => {
32926
- const leftId = stringValue2(ownValue(left, "id"));
32927
- const rightId = stringValue2(ownValue(right, "id"));
32928
- const leftParent = stringValue2(ownValue(left, "parent_run_id"));
32929
- const rightParent = stringValue2(ownValue(right, "parent_run_id"));
34025
+ const leftId = stringValue3(ownValue(left, "id"));
34026
+ const rightId = stringValue3(ownValue(right, "id"));
34027
+ const leftParent = stringValue3(ownValue(left, "parent_run_id"));
34028
+ const rightParent = stringValue3(ownValue(right, "parent_run_id"));
32930
34029
  if (leftParent && leftParent === rightId) {
32931
34030
  return 1;
32932
34031
  }
@@ -32945,13 +34044,13 @@ var LangSmithPlugin = class extends BasePlugin {
32945
34044
  if (Array.isArray(updates)) {
32946
34045
  for (const run of updates) {
32947
34046
  this.containLifecycleFailure("batchIngestRuns update", () => {
32948
- this.processUpdate(stringValue2(ownValue(run, "id")) ?? "", run);
34047
+ this.processUpdate(stringValue3(ownValue(run, "id")) ?? "", run);
32949
34048
  });
32950
34049
  }
32951
34050
  }
32952
34051
  }
32953
34052
  processCreate(run) {
32954
- const id = stringValue2(ownValue(run, "id"));
34053
+ const id = stringValue3(ownValue(run, "id"));
32955
34054
  if (!id || this.completedRuns.get(id)) {
32956
34055
  return;
32957
34056
  }
@@ -32984,7 +34083,7 @@ var LangSmithPlugin = class extends BasePlugin {
32984
34083
  this.endIfComplete(id, activeRun, run);
32985
34084
  }
32986
34085
  processUpdate(explicitId, run) {
32987
- const id = stringValue2(explicitId) ?? stringValue2(ownValue(run, "id"));
34086
+ const id = stringValue3(explicitId) ?? stringValue3(ownValue(run, "id"));
32988
34087
  if (!id || this.completedRuns.get(id)) {
32989
34088
  return;
32990
34089
  }
@@ -33007,13 +34106,13 @@ var LangSmithPlugin = class extends BasePlugin {
33007
34106
  this.endIfComplete(id, active, active.run);
33008
34107
  }
33009
34108
  startRunSpan(id, run) {
33010
- const traceId = stringValue2(ownValue(run, "trace_id")) ?? id;
33011
- const parentId = stringValue2(ownValue(run, "parent_run_id")) ?? stringValue2(ownValue(ownValue(run, "parent_run"), "id"));
34109
+ const traceId = stringValue3(ownValue(run, "trace_id")) ?? id;
34110
+ const parentId = stringValue3(ownValue(run, "parent_run_id")) ?? stringValue3(ownValue(ownValue(run, "parent_run"), "id"));
33012
34111
  const startTime = timestampSeconds(ownValue(run, "start_time"));
33013
34112
  return startSpan(
33014
34113
  withSpanInstrumentationName(
33015
34114
  {
33016
- name: stringValue2(ownValue(run, "name")) ?? "LangSmith run",
34115
+ name: stringValue3(ownValue(run, "name")) ?? "LangSmith run",
33017
34116
  spanId: id,
33018
34117
  parentSpanIds: {
33019
34118
  parentSpanIds: parentId ? [parentId] : [],
@@ -33105,7 +34204,7 @@ function mergeRuns(previous, current) {
33105
34204
  function isRecord2(value) {
33106
34205
  return typeof value === "object" && value !== null && !Array.isArray(value);
33107
34206
  }
33108
- function stringValue2(value) {
34207
+ function stringValue3(value) {
33109
34208
  return typeof value === "string" && value.length > 0 ? value : void 0;
33110
34209
  }
33111
34210
  function timestampSeconds(value) {
@@ -33123,7 +34222,7 @@ function timestampSeconds(value) {
33123
34222
  return void 0;
33124
34223
  }
33125
34224
  function dottedOrderDepth(run) {
33126
- const dottedOrder = stringValue2(ownValue(run, "dotted_order"));
34225
+ const dottedOrder = stringValue3(ownValue(run, "dotted_order"));
33127
34226
  return dottedOrder ? dottedOrder.split(".").length : Number.MAX_SAFE_INTEGER;
33128
34227
  }
33129
34228
  function mapRunType(runType) {
@@ -33328,7 +34427,7 @@ var PiCodingAgentPlugin = class extends BasePlugin {
33328
34427
  }
33329
34428
  );
33330
34429
  } catch (error) {
33331
- logInstrumentationError4("Pi Coding Agent prompt start", error);
34430
+ logInstrumentationError5("Pi Coding Agent prompt start", error);
33332
34431
  }
33333
34432
  if (!state) {
33334
34433
  return runWithAutoInstrumentationSuppressed(invokeTarget);
@@ -33461,12 +34560,12 @@ function installPiAgentInstrumentation(agent) {
33461
34560
  () => handlePiAgentEvent(state, event)
33462
34561
  );
33463
34562
  } catch (error) {
33464
- logInstrumentationError4("Pi Coding Agent event", error);
34563
+ logInstrumentationError5("Pi Coding Agent event", error);
33465
34564
  }
33466
34565
  });
33467
34566
  piAgentEventSubscriptions.add(agent);
33468
34567
  } catch (error) {
33469
- logInstrumentationError4("Pi Coding Agent event subscription", error);
34568
+ logInstrumentationError5("Pi Coding Agent event subscription", error);
33470
34569
  }
33471
34570
  }
33472
34571
  function makeInstrumentedStreamFunction(agent, originalStreamFunction, property) {
@@ -33516,7 +34615,7 @@ function wrapPiToolExecutors(tools) {
33516
34615
  });
33517
34616
  tool.execute = wrappedExecute;
33518
34617
  } catch (error) {
33519
- logInstrumentationError4("Pi Coding Agent tool wrapping", error);
34618
+ logInstrumentationError5("Pi Coding Agent tool wrapping", error);
33520
34619
  }
33521
34620
  }
33522
34621
  }
@@ -33595,7 +34694,7 @@ function patchAssistantMessageStream(stream, promptState, llmState) {
33595
34694
  try {
33596
34695
  await iterator.return();
33597
34696
  } catch (cleanupError) {
33598
- logInstrumentationError4(
34697
+ logInstrumentationError5(
33599
34698
  "Pi Coding Agent stream cleanup",
33600
34699
  cleanupError
33601
34700
  );
@@ -33760,7 +34859,7 @@ function finishPiPromptRun(state, error) {
33760
34859
  try {
33761
34860
  state.span.end();
33762
34861
  } catch (endError) {
33763
- logInstrumentationError4("Pi Coding Agent prompt end", endError);
34862
+ logInstrumentationError5("Pi Coding Agent prompt end", endError);
33764
34863
  }
33765
34864
  }
33766
34865
  }
@@ -34092,10 +35191,10 @@ function safeLog4(span, event) {
34092
35191
  try {
34093
35192
  span.log(event);
34094
35193
  } catch (error) {
34095
- logInstrumentationError4("Pi Coding Agent span log", error);
35194
+ logInstrumentationError5("Pi Coding Agent span log", error);
34096
35195
  }
34097
35196
  }
34098
- function logInstrumentationError4(context, error) {
35197
+ function logInstrumentationError5(context, error) {
34099
35198
  debugLogger.debug(`${context}:`, error);
34100
35199
  }
34101
35200
 
@@ -34333,7 +35432,7 @@ function handleAgentStreamEvent(state, event) {
34333
35432
  finalizeModelSpan(state, event);
34334
35433
  break;
34335
35434
  case "beforeToolCallEvent":
34336
- startToolSpan2(state, event);
35435
+ startToolSpan3(state, event);
34337
35436
  break;
34338
35437
  case "afterToolCallEvent":
34339
35438
  finalizeToolSpan(state, event);
@@ -34358,7 +35457,7 @@ function handleAgentStreamEvent(state, event) {
34358
35457
  break;
34359
35458
  }
34360
35459
  } catch (error) {
34361
- logInstrumentationError5("Strands Agent SDK event", error);
35460
+ logInstrumentationError6("Strands Agent SDK event", error);
34362
35461
  }
34363
35462
  }
34364
35463
  function handleMultiAgentStreamEvent(state, event, activeChildParents) {
@@ -34394,7 +35493,7 @@ function handleMultiAgentStreamEvent(state, event, activeChildParents) {
34394
35493
  break;
34395
35494
  }
34396
35495
  } catch (error) {
34397
- logInstrumentationError5("Strands Agent SDK multi-agent event", error);
35496
+ logInstrumentationError6("Strands Agent SDK multi-agent event", error);
34398
35497
  }
34399
35498
  }
34400
35499
  function buildModelSpanInput(event, attachmentCache) {
@@ -34473,7 +35572,7 @@ function finalizeModelSpan(state, event) {
34473
35572
  });
34474
35573
  modelState.span.end();
34475
35574
  }
34476
- function startToolSpan2(state, event) {
35575
+ function startToolSpan3(state, event) {
34477
35576
  const toolUse = event.toolUse;
34478
35577
  const key = toolKey2(toolUse);
34479
35578
  if (state.activeTools.has(key)) {
@@ -34753,7 +35852,7 @@ function getModelConfig(model) {
34753
35852
  try {
34754
35853
  return model.getConfig();
34755
35854
  } catch (error) {
34756
- logInstrumentationError5("Strands Agent SDK model config", error);
35855
+ logInstrumentationError6("Strands Agent SDK model config", error);
34757
35856
  return void 0;
34758
35857
  }
34759
35858
  }
@@ -34836,7 +35935,7 @@ function processStrandsInputAttachments(input, cache = createStrandsAttachmentCa
34836
35935
  try {
34837
35936
  return processStrandsInputNode(input, cache);
34838
35937
  } catch (error) {
34839
- logInstrumentationError5("Strands Agent SDK input attachments", error);
35938
+ logInstrumentationError6("Strands Agent SDK input attachments", error);
34840
35939
  return input;
34841
35940
  }
34842
35941
  }
@@ -35056,10 +36155,10 @@ function safeLog5(span, event) {
35056
36155
  try {
35057
36156
  span.log(event);
35058
36157
  } catch (error) {
35059
- logInstrumentationError5("Strands Agent SDK span log", error);
36158
+ logInstrumentationError6("Strands Agent SDK span log", error);
35060
36159
  }
35061
36160
  }
35062
- function logInstrumentationError5(context, error) {
36161
+ function logInstrumentationError6(context, error) {
35063
36162
  debugLogger.debug(`${context}:`, error);
35064
36163
  }
35065
36164
 
@@ -35462,10 +36561,10 @@ function observeAudioStream(value, observe, complete, cancel, span) {
35462
36561
  const getReader = value.getReader;
35463
36562
  value.getReader = function(...args) {
35464
36563
  const reader = Reflect.apply(getReader, this, args);
35465
- const read2 = reader.read;
36564
+ const read3 = reader.read;
35466
36565
  reader.read = function(...readArgs) {
35467
36566
  return Promise.resolve(
35468
- withCurrent(span, () => Reflect.apply(read2, this, readArgs))
36567
+ withCurrent(span, () => Reflect.apply(read3, this, readArgs))
35469
36568
  ).then(
35470
36569
  (result) => {
35471
36570
  if (result.value) safeObserve(result.value);
@@ -35959,14 +37058,14 @@ var CloudflareAIChatPlugin = class extends BasePlugin {
35959
37058
  const result = event.arguments[0];
35960
37059
  state = agent ? this.findResponseState(
35961
37060
  agent,
35962
- stringValue3(ownValue2(result, "requestId"))
37061
+ stringValue4(ownValue2(result, "requestId"))
35963
37062
  ) : void 0;
35964
37063
  if (!state) {
35965
37064
  return;
35966
37065
  }
35967
37066
  state.responseObserved = true;
35968
37067
  const output = serializeMessage(ownValue2(result, "message"));
35969
- const status = stringValue3(ownValue2(result, "status"));
37068
+ const status = stringValue4(ownValue2(result, "status"));
35970
37069
  const error = ownValue2(result, "error");
35971
37070
  const input = ownValue2(result, "continuation") === true ? state.input : serializeMessages(readProperty(agent, "messages"))?.filter(
35972
37071
  (message) => typeof output?.id !== "string" || message.id !== output.id
@@ -36013,7 +37112,7 @@ var CloudflareAIChatPlugin = class extends BasePlugin {
36013
37112
  }
36014
37113
  try {
36015
37114
  const agent = asObject(event.self);
36016
- const requestId = stringValue3(event.arguments[0]);
37115
+ const requestId = stringValue4(event.arguments[0]);
36017
37116
  const key = requestId ?? /* @__PURE__ */ Symbol("cloudflare-ai-chat-turn");
36018
37117
  const activeForAgent = agent ? this.getActiveTurns(agent) : void 0;
36019
37118
  const existing = activeForAgent?.get(key);
@@ -36182,7 +37281,7 @@ function ownValue2(value, key) {
36182
37281
  const descriptor = Object.getOwnPropertyDescriptor(object, key);
36183
37282
  return descriptor && "value" in descriptor ? descriptor.value : void 0;
36184
37283
  }
36185
- function stringValue3(value) {
37284
+ function stringValue4(value) {
36186
37285
  return typeof value === "string" ? value : void 0;
36187
37286
  }
36188
37287
  function serializeMessages(value) {
@@ -36300,7 +37399,7 @@ var CloudflareAgentsPlugin = class extends BasePlugin {
36300
37399
  );
36301
37400
  spans.set(event, span);
36302
37401
  } catch (error) {
36303
- logInstrumentationError6("start", error);
37402
+ logInstrumentationError7("start", error);
36304
37403
  }
36305
37404
  },
36306
37405
  asyncEnd: (event) => {
@@ -36320,7 +37419,7 @@ var CloudflareAgentsPlugin = class extends BasePlugin {
36320
37419
  }
36321
37420
  }
36322
37421
  } catch (error) {
36323
- logInstrumentationError6("completion", error);
37422
+ logInstrumentationError7("completion", error);
36324
37423
  } finally {
36325
37424
  safelyEndSpan(span);
36326
37425
  }
@@ -36334,7 +37433,7 @@ var CloudflareAgentsPlugin = class extends BasePlugin {
36334
37433
  try {
36335
37434
  span.log({ error: event.error });
36336
37435
  } catch (error) {
36337
- logInstrumentationError6("rejection", error);
37436
+ logInstrumentationError7("rejection", error);
36338
37437
  } finally {
36339
37438
  safelyEndSpan(span);
36340
37439
  }
@@ -36364,10 +37463,10 @@ function safelyEndSpan(span) {
36364
37463
  try {
36365
37464
  span.end();
36366
37465
  } catch (error) {
36367
- logInstrumentationError6("span end", error);
37466
+ logInstrumentationError7("span end", error);
36368
37467
  }
36369
37468
  }
36370
- function logInstrumentationError6(operation, error) {
37469
+ function logInstrumentationError7(operation, error) {
36371
37470
  debugLogger.error(
36372
37471
  `Failed to process Cloudflare Agents ${operation} instrumentation:`,
36373
37472
  error
@@ -36392,6 +37491,7 @@ var BraintrustPlugin = class extends BasePlugin {
36392
37491
  openRouterPlugin = null;
36393
37492
  openRouterAgentPlugin = null;
36394
37493
  mistralPlugin = null;
37494
+ langGraphSDKPlugin = null;
36395
37495
  ollamaPlugin = null;
36396
37496
  googleADKPlugin = null;
36397
37497
  coherePlugin = null;
@@ -36472,6 +37572,10 @@ var BraintrustPlugin = class extends BasePlugin {
36472
37572
  this.mistralPlugin = new MistralPlugin();
36473
37573
  this.mistralPlugin.enable();
36474
37574
  }
37575
+ if (integrations.langgraphSDK !== false) {
37576
+ this.langGraphSDKPlugin = new LangGraphSDKPlugin();
37577
+ this.langGraphSDKPlugin.enable();
37578
+ }
36475
37579
  if (integrations.ollama !== false) {
36476
37580
  this.ollamaPlugin = new OllamaPlugin();
36477
37581
  this.ollamaPlugin.enable();
@@ -36600,6 +37704,10 @@ var BraintrustPlugin = class extends BasePlugin {
36600
37704
  this.mistralPlugin.disable();
36601
37705
  this.mistralPlugin = null;
36602
37706
  }
37707
+ if (this.langGraphSDKPlugin) {
37708
+ this.langGraphSDKPlugin.disable();
37709
+ this.langGraphSDKPlugin = null;
37710
+ }
36603
37711
  if (this.ollamaPlugin) {
36604
37712
  this.ollamaPlugin.disable();
36605
37713
  this.ollamaPlugin = null;
@@ -36674,7 +37782,31 @@ var MAX_STORED_LLM_INPUTS = 100;
36674
37782
  var MAX_STORED_REASONING_BLOCKS = 100;
36675
37783
  var MAX_STORED_SPAN_REFERENCES = 1e4;
36676
37784
  var MAX_STORED_STEP_STARTS = 1e4;
37785
+ var EVE_HANDLED_EVENT_TYPES = /* @__PURE__ */ new Set([
37786
+ "action.result",
37787
+ "actions.requested",
37788
+ "message.completed",
37789
+ "message.received",
37790
+ "reasoning.completed",
37791
+ "result.completed",
37792
+ "session.completed",
37793
+ "session.failed",
37794
+ "session.started",
37795
+ "step.completed",
37796
+ "step.failed",
37797
+ "step.started",
37798
+ "subagent.called",
37799
+ "subagent.completed",
37800
+ "turn.completed",
37801
+ "turn.failed",
37802
+ "turn.started"
37803
+ ]);
36677
37804
  function braintrustEveHook(options) {
37805
+ if (!options || typeof options.defineState !== "function") {
37806
+ throw new TypeError(
37807
+ "braintrustEveHook requires Eve's defineState function"
37808
+ );
37809
+ }
36678
37810
  const state = options.defineState(EVE_TRACE_STATE_KEY, emptyEveTraceState);
36679
37811
  const bridge = new EveBridge(state);
36680
37812
  return {
@@ -36686,15 +37818,27 @@ function braintrustEveHook(options) {
36686
37818
  };
36687
37819
  }
36688
37820
  function createLegacyEveInstrumentation(options) {
37821
+ if (!options || typeof options.defineState !== "function") {
37822
+ throw new TypeError(
37823
+ "braintrustEveInstrumentation requires Eve's defineState function"
37824
+ );
37825
+ }
36689
37826
  const state = options.defineState(EVE_TRACE_STATE_KEY, emptyEveTraceState);
36690
37827
  return {
36691
37828
  events: {
36692
37829
  "step.started": (input) => {
36693
37830
  try {
37831
+ if (!isEveInstrumentationStepStartedEventInput(input)) {
37832
+ debugLogger.warn(
37833
+ "Ignoring malformed Eve instrumentation step.started event"
37834
+ );
37835
+ return void 0;
37836
+ }
36694
37837
  captureEveModelInput(state, input);
36695
37838
  } catch (error) {
36696
37839
  debugLogger.warn("Error in Eve LLM input capture:", error);
36697
37840
  }
37841
+ return void 0;
36698
37842
  }
36699
37843
  },
36700
37844
  recordInputs: false,
@@ -36703,7 +37847,77 @@ function createLegacyEveInstrumentation(options) {
36703
37847
  };
36704
37848
  }
36705
37849
  function isEveHandleMessageStreamEvent(event) {
36706
- return isObject(event) && typeof event["type"] === "string";
37850
+ if (!isObject(event) || typeof event["type"] !== "string") {
37851
+ return false;
37852
+ }
37853
+ const type = event["type"];
37854
+ if (type === "session.completed") {
37855
+ return true;
37856
+ }
37857
+ if (!isObject(event["data"])) {
37858
+ return false;
37859
+ }
37860
+ const data = event["data"];
37861
+ if (type === "session.started") {
37862
+ return true;
37863
+ }
37864
+ if (type === "session.failed") {
37865
+ return typeof data["sessionId"] === "string" && typeof data["code"] === "string" && typeof data["message"] === "string";
37866
+ }
37867
+ if (type === "session.waiting") {
37868
+ return data["wait"] === "next-user-message";
37869
+ }
37870
+ if (typeof data["turnId"] !== "string" || typeof data["sequence"] !== "number" || !Number.isFinite(data["sequence"])) {
37871
+ return false;
37872
+ }
37873
+ if (type === "turn.started" || type === "turn.completed" || type === "subagent.called" || type === "subagent.completed") {
37874
+ if (type === "subagent.called") {
37875
+ return typeof data["callId"] === "string" && typeof data["childSessionId"] === "string" && typeof data["name"] === "string";
37876
+ }
37877
+ if (type === "subagent.completed") {
37878
+ return typeof data["callId"] === "string" && typeof data["subagentName"] === "string";
37879
+ }
37880
+ return true;
37881
+ }
37882
+ if (type === "turn.failed") {
37883
+ return typeof data["code"] === "string" && typeof data["message"] === "string";
37884
+ }
37885
+ if (type === "message.received") {
37886
+ return typeof data["message"] === "string";
37887
+ }
37888
+ if (typeof data["stepIndex"] !== "number" || !Number.isFinite(data["stepIndex"]) || data["stepIndex"] < 0) {
37889
+ return false;
37890
+ }
37891
+ switch (type) {
37892
+ case "step.started":
37893
+ return true;
37894
+ case "message.completed":
37895
+ return typeof data["finishReason"] === "string" && (typeof data["message"] === "string" || data["message"] === null);
37896
+ case "reasoning.completed":
37897
+ return typeof data["reasoning"] === "string";
37898
+ case "result.completed":
37899
+ return true;
37900
+ case "step.completed":
37901
+ return typeof data["finishReason"] === "string";
37902
+ case "step.failed":
37903
+ return typeof data["code"] === "string" && typeof data["message"] === "string";
37904
+ case "actions.requested":
37905
+ return Array.isArray(data["actions"]);
37906
+ case "action.result":
37907
+ return isObject(data["result"]) && (data["status"] === "completed" || data["status"] === "failed" || data["status"] === "rejected");
37908
+ default:
37909
+ return false;
37910
+ }
37911
+ }
37912
+ function isEveInstrumentationStepStartedEventInput(input) {
37913
+ if (!isObject(input)) {
37914
+ return false;
37915
+ }
37916
+ const modelInput = input["modelInput"];
37917
+ const session = input["session"];
37918
+ const step = input["step"];
37919
+ const turn = input["turn"];
37920
+ 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"]);
36707
37921
  }
36708
37922
  var ResumedEveSpan = class {
36709
37923
  constructor(reference) {
@@ -36872,7 +38086,17 @@ var EveBridge = class {
36872
38086
  });
36873
38087
  }
36874
38088
  async handle(event, ctx, hookMetadata) {
38089
+ try {
38090
+ await this.handleUnchecked(event, ctx, hookMetadata);
38091
+ } catch (error) {
38092
+ debugLogger.warn("Error in Eve hook instrumentation:", error);
38093
+ }
38094
+ }
38095
+ async handleUnchecked(event, ctx, hookMetadata) {
36875
38096
  if (!isEveHandleMessageStreamEvent(event)) {
38097
+ if (isObject(event) && typeof event["type"] === "string" && EVE_HANDLED_EVENT_TYPES.has(event["type"])) {
38098
+ debugLogger.warn(`Ignoring malformed Eve hook ${event["type"]} event`);
38099
+ }
36876
38100
  return;
36877
38101
  }
36878
38102
  const run = async () => {
@@ -37198,9 +38422,14 @@ var EveBridge = class {
37198
38422
  }
37199
38423
  for (const action of traceActions) {
37200
38424
  const name = action.kind === "tool-call" ? action.toolName : action.subagentName ?? action.name ?? "agent";
38425
+ let args = "null";
38426
+ try {
38427
+ args = JSON.stringify(action.input) ?? "null";
38428
+ } catch {
38429
+ }
37201
38430
  toolCallsById.set(action.callId, {
37202
38431
  function: {
37203
- arguments: JSON.stringify(action.input),
38432
+ arguments: args,
37204
38433
  name
37205
38434
  },
37206
38435
  id: action.callId,
@@ -38069,17 +39298,33 @@ function consumeCapturedEveModelInput(state, sessionId, turnId, stepIndex) {
38069
39298
  }
38070
39299
  }
38071
39300
  function capturedModelInput(modelInput) {
38072
- const { instructions, messages } = modelInput;
38073
- const value = [];
38074
- if (typeof instructions === "string") {
38075
- value.push({ content: instructions, role: "system" });
38076
- } else if (Array.isArray(instructions)) {
38077
- value.push(...instructions.map(capturedEveModelMessage));
38078
- } else if (instructions) {
38079
- value.push(capturedEveModelMessage(instructions));
38080
- }
38081
- value.push(...messages.map(capturedEveModelMessage));
38082
39301
  try {
39302
+ if (!isObject(modelInput) || !Array.isArray(modelInput["messages"])) {
39303
+ return void 0;
39304
+ }
39305
+ const value = [];
39306
+ const instructions = modelInput["instructions"];
39307
+ if (typeof instructions === "string") {
39308
+ value.push({ content: instructions, role: "system" });
39309
+ } else if (Array.isArray(instructions)) {
39310
+ for (const instruction of instructions) {
39311
+ const captured = capturedEveModelMessage(instruction);
39312
+ if (captured?.role === "system") {
39313
+ value.push(captured);
39314
+ }
39315
+ }
39316
+ } else {
39317
+ const captured = capturedEveModelMessage(instructions);
39318
+ if (captured?.role === "system") {
39319
+ value.push(captured);
39320
+ }
39321
+ }
39322
+ for (const message of modelInput["messages"]) {
39323
+ const captured = capturedEveModelMessage(message);
39324
+ if (captured) {
39325
+ value.push(captured);
39326
+ }
39327
+ }
38083
39328
  const cloned = JSON.parse(JSON.stringify(value));
38084
39329
  if (!Array.isArray(cloned)) {
38085
39330
  return void 0;
@@ -38090,116 +39335,202 @@ function capturedModelInput(modelInput) {
38090
39335
  }
38091
39336
  }
38092
39337
  function capturedEveModelMessage(message) {
38093
- const { content, role } = message;
39338
+ if (!isObject(message)) {
39339
+ return void 0;
39340
+ }
39341
+ const role = message["role"];
39342
+ if (role !== "system" && role !== "user" && role !== "assistant" && role !== "tool") {
39343
+ return void 0;
39344
+ }
39345
+ const content = message["content"];
38094
39346
  if (typeof content === "string") {
38095
39347
  return { content, role };
38096
39348
  }
38097
- return { content: content.map(capturedEveModelContentPart), role };
39349
+ if (!Array.isArray(content)) {
39350
+ return void 0;
39351
+ }
39352
+ const capturedContent = [];
39353
+ for (const part of content) {
39354
+ const captured = capturedEveModelContentPart(part);
39355
+ if (captured) {
39356
+ capturedContent.push(captured);
39357
+ }
39358
+ }
39359
+ return { content: capturedContent, role };
38098
39360
  }
38099
39361
  function capturedEveModelContentPart(part) {
38100
- switch (part.type) {
39362
+ if (!isObject(part) || typeof part["type"] !== "string") {
39363
+ return void 0;
39364
+ }
39365
+ switch (part["type"]) {
38101
39366
  case "text":
38102
- case "reasoning":
38103
- return { text: part.text, type: part.type };
39367
+ case "reasoning": {
39368
+ const text = part["text"];
39369
+ return typeof text === "string" ? { text, type: part["type"] } : void 0;
39370
+ }
38104
39371
  case "image":
39372
+ if (!Object.hasOwn(part, "image")) {
39373
+ return void 0;
39374
+ }
38105
39375
  return {
38106
- image: part.image,
38107
- ...part.mediaType !== void 0 ? { mediaType: part.mediaType } : {},
39376
+ image: part["image"],
39377
+ ...typeof part["mediaType"] === "string" ? { mediaType: part["mediaType"] } : {},
38108
39378
  type: "image"
38109
39379
  };
38110
39380
  case "file":
38111
- case "reasoning-file":
39381
+ case "reasoning-file": {
39382
+ if (!Object.hasOwn(part, "data") || typeof part["mediaType"] !== "string") {
39383
+ return void 0;
39384
+ }
38112
39385
  return {
38113
- data: part.data,
38114
- ...part.type === "file" && part.filename !== void 0 ? { filename: part.filename } : {},
38115
- mediaType: part.mediaType,
38116
- type: part.type
39386
+ data: part["data"],
39387
+ ...part["type"] === "file" && typeof part["filename"] === "string" ? { filename: part["filename"] } : {},
39388
+ mediaType: part["mediaType"],
39389
+ type: part["type"]
38117
39390
  };
39391
+ }
38118
39392
  case "custom":
38119
39393
  return {
38120
- ..."kind" in part ? { kind: part.kind } : {},
39394
+ ...typeof part["kind"] === "string" ? { kind: part["kind"] } : {},
38121
39395
  type: "custom"
38122
39396
  };
38123
- case "tool-call":
39397
+ case "tool-call": {
39398
+ if (typeof part["toolCallId"] !== "string" || typeof part["toolName"] !== "string") {
39399
+ return void 0;
39400
+ }
38124
39401
  return {
38125
- input: part.input,
38126
- ...part.providerExecuted !== void 0 ? { providerExecuted: part.providerExecuted } : {},
38127
- toolCallId: part.toolCallId,
38128
- toolName: part.toolName,
39402
+ input: part["input"],
39403
+ ...typeof part["providerExecuted"] === "boolean" ? { providerExecuted: part["providerExecuted"] } : {},
39404
+ toolCallId: part["toolCallId"],
39405
+ toolName: part["toolName"],
38129
39406
  type: "tool-call"
38130
39407
  };
39408
+ }
38131
39409
  case "tool-result": {
38132
- const output = part.output;
39410
+ const output = part["output"];
39411
+ if (typeof part["toolCallId"] !== "string" || typeof part["toolName"] !== "string" || !isObject(output) || typeof output["type"] !== "string") {
39412
+ return void 0;
39413
+ }
38133
39414
  let capturedOutput;
38134
- switch (output.type) {
39415
+ switch (output["type"]) {
38135
39416
  case "text":
38136
- case "error-text":
38137
- capturedOutput = { type: output.type, value: output.value };
39417
+ case "error-text": {
39418
+ if (typeof output["value"] !== "string") {
39419
+ return void 0;
39420
+ }
39421
+ capturedOutput = {
39422
+ type: output["type"],
39423
+ value: output["value"]
39424
+ };
38138
39425
  break;
39426
+ }
38139
39427
  case "json":
38140
39428
  case "error-json":
38141
- capturedOutput = { type: output.type, value: output.value };
39429
+ capturedOutput = {
39430
+ type: output["type"],
39431
+ value: output["value"]
39432
+ };
38142
39433
  break;
38143
39434
  case "execution-denied":
38144
39435
  capturedOutput = {
38145
- ...output.reason !== void 0 ? { reason: output.reason } : {},
39436
+ ...typeof output["reason"] === "string" ? { reason: output["reason"] } : {},
38146
39437
  type: "execution-denied"
38147
39438
  };
38148
39439
  break;
38149
- case "content":
39440
+ case "content": {
39441
+ if (!Array.isArray(output["value"])) {
39442
+ return void 0;
39443
+ }
39444
+ const value = [];
39445
+ for (const outputPart of output["value"]) {
39446
+ const captured = capturedEveModelContentPart(outputPart);
39447
+ if (captured) {
39448
+ value.push(captured);
39449
+ }
39450
+ }
38150
39451
  capturedOutput = {
38151
39452
  type: "content",
38152
- value: output.value.map(capturedEveModelContentPart)
39453
+ value
38153
39454
  };
38154
39455
  break;
39456
+ }
39457
+ default:
39458
+ return void 0;
38155
39459
  }
38156
39460
  return {
38157
39461
  output: capturedOutput,
38158
- toolCallId: part.toolCallId,
38159
- toolName: part.toolName,
39462
+ toolCallId: part["toolCallId"],
39463
+ toolName: part["toolName"],
38160
39464
  type: "tool-result"
38161
39465
  };
38162
39466
  }
38163
- case "tool-approval-request":
39467
+ case "tool-approval-request": {
39468
+ if (typeof part["approvalId"] !== "string" || typeof part["toolCallId"] !== "string") {
39469
+ return void 0;
39470
+ }
38164
39471
  return {
38165
- approvalId: part.approvalId,
38166
- ...part.isAutomatic !== void 0 ? { isAutomatic: part.isAutomatic } : {},
38167
- ...part.signature !== void 0 ? { signature: part.signature } : {},
38168
- toolCallId: part.toolCallId,
39472
+ approvalId: part["approvalId"],
39473
+ ...typeof part["isAutomatic"] === "boolean" ? { isAutomatic: part["isAutomatic"] } : {},
39474
+ ...typeof part["signature"] === "string" ? { signature: part["signature"] } : {},
39475
+ toolCallId: part["toolCallId"],
38169
39476
  type: "tool-approval-request"
38170
39477
  };
38171
- case "tool-approval-response":
39478
+ }
39479
+ case "tool-approval-response": {
39480
+ if (typeof part["approvalId"] !== "string" || typeof part["approved"] !== "boolean") {
39481
+ return void 0;
39482
+ }
38172
39483
  return {
38173
- approvalId: part.approvalId,
38174
- approved: part.approved,
38175
- ...part.providerExecuted !== void 0 ? { providerExecuted: part.providerExecuted } : {},
38176
- ...part.reason !== void 0 ? { reason: part.reason } : {},
39484
+ approvalId: part["approvalId"],
39485
+ approved: part["approved"],
39486
+ ...typeof part["providerExecuted"] === "boolean" ? { providerExecuted: part["providerExecuted"] } : {},
39487
+ ...typeof part["reason"] === "string" ? { reason: part["reason"] } : {},
38177
39488
  type: "tool-approval-response"
38178
39489
  };
39490
+ }
38179
39491
  case "file-data":
38180
- case "image-data":
39492
+ case "image-data": {
39493
+ if (typeof part["data"] !== "string" || typeof part["mediaType"] !== "string") {
39494
+ return void 0;
39495
+ }
38181
39496
  return {
38182
- data: part.data,
38183
- ...part.type === "file-data" && part.filename !== void 0 ? { filename: part.filename } : {},
38184
- mediaType: part.mediaType,
38185
- type: part.type
39497
+ data: part["data"],
39498
+ ...part["type"] === "file-data" && typeof part["filename"] === "string" ? { filename: part["filename"] } : {},
39499
+ mediaType: part["mediaType"],
39500
+ type: part["type"]
38186
39501
  };
39502
+ }
38187
39503
  case "file-url":
38188
- case "image-url":
39504
+ case "image-url": {
39505
+ if (typeof part["url"] !== "string") {
39506
+ return void 0;
39507
+ }
38189
39508
  return {
38190
- ...part.type === "file-url" && part.mediaType !== void 0 ? { mediaType: part.mediaType } : {},
38191
- type: part.type,
38192
- url: part.url
39509
+ ...part["type"] === "file-url" && typeof part["mediaType"] === "string" ? { mediaType: part["mediaType"] } : {},
39510
+ type: part["type"],
39511
+ url: part["url"]
38193
39512
  };
39513
+ }
38194
39514
  case "file-id":
38195
- case "image-file-id":
38196
- return { fileId: part.fileId, type: part.type };
39515
+ case "image-file-id": {
39516
+ const fileId = part["fileId"];
39517
+ if (typeof fileId !== "string" && !isObject(fileId)) {
39518
+ return void 0;
39519
+ }
39520
+ return { fileId, type: part["type"] };
39521
+ }
38197
39522
  case "file-reference":
38198
- case "image-file-reference":
39523
+ case "image-file-reference": {
39524
+ if (!isObject(part["providerReference"])) {
39525
+ return void 0;
39526
+ }
38199
39527
  return {
38200
- providerReference: part.providerReference,
38201
- type: part.type
39528
+ providerReference: part["providerReference"],
39529
+ type: part["type"]
38202
39530
  };
39531
+ }
39532
+ default:
39533
+ return void 0;
38203
39534
  }
38204
39535
  }
38205
39536
  function isCapturedModelInput(input) {
@@ -38335,18 +39666,54 @@ function createEveInstrumentationProvider(options = {}) {
38335
39666
  recordOutputs: true
38336
39667
  }),
38337
39668
  events: {
38338
- "action.completed": (event, context) => bridge.handleActionTerminal(event, context),
38339
- "action.failed": (event, context) => bridge.handleActionTerminal(event, context),
38340
- "action.started": (event, context) => bridge.handleActionStarted(event, context),
38341
- "model.call.completed": (event, context) => bridge.handleModelTerminal(event, context),
38342
- "model.call.failed": (event, context) => bridge.handleModelTerminal(event, context),
38343
- "model.call.started": (event, context) => bridge.handleModelStarted(event, context),
38344
- "step.attempt.completed": (event) => bridge.handleStepAttemptTerminal(event),
38345
- "step.attempt.failed": (event) => bridge.handleStepAttemptTerminal(event),
38346
- "turn.cancelled": (event, context) => bridge.handleTurnTerminal(event, context),
38347
- "turn.completed": (event, context) => bridge.handleTurnTerminal(event, context),
38348
- "turn.failed": (event, context) => bridge.handleTurnTerminal(event, context),
38349
- "turn.started": (event, context) => bridge.handleTurnStarted(event, context)
39669
+ "action.completed": providerHandler(
39670
+ "action.completed",
39671
+ bridge.handleActionTerminal.bind(bridge)
39672
+ ),
39673
+ "action.failed": providerHandler(
39674
+ "action.failed",
39675
+ bridge.handleActionTerminal.bind(bridge)
39676
+ ),
39677
+ "action.started": providerHandler(
39678
+ "action.started",
39679
+ bridge.handleActionStarted.bind(bridge)
39680
+ ),
39681
+ "model.call.completed": providerHandler(
39682
+ "model.call.completed",
39683
+ bridge.handleModelTerminal.bind(bridge)
39684
+ ),
39685
+ "model.call.failed": providerHandler(
39686
+ "model.call.failed",
39687
+ bridge.handleModelTerminal.bind(bridge)
39688
+ ),
39689
+ "model.call.started": providerHandler(
39690
+ "model.call.started",
39691
+ bridge.handleModelStarted.bind(bridge)
39692
+ ),
39693
+ "step.attempt.completed": providerHandler(
39694
+ "step.attempt.completed",
39695
+ (event) => bridge.handleStepAttemptTerminal(event)
39696
+ ),
39697
+ "step.attempt.failed": providerHandler(
39698
+ "step.attempt.failed",
39699
+ (event) => bridge.handleStepAttemptTerminal(event)
39700
+ ),
39701
+ "turn.cancelled": providerHandler(
39702
+ "turn.cancelled",
39703
+ bridge.handleTurnTerminal.bind(bridge)
39704
+ ),
39705
+ "turn.completed": providerHandler(
39706
+ "turn.completed",
39707
+ bridge.handleTurnTerminal.bind(bridge)
39708
+ ),
39709
+ "turn.failed": providerHandler(
39710
+ "turn.failed",
39711
+ bridge.handleTurnTerminal.bind(bridge)
39712
+ ),
39713
+ "turn.started": providerHandler(
39714
+ "turn.started",
39715
+ bridge.handleTurnStarted.bind(bridge)
39716
+ )
38350
39717
  },
38351
39718
  flush,
38352
39719
  setup: options.setup
@@ -38702,17 +40069,20 @@ function modelOutput(event) {
38702
40069
  const reasoning = [];
38703
40070
  const toolCalls = [];
38704
40071
  for (const part of content) {
38705
- if (part.type === "text") {
38706
- text += part.text;
38707
- } else if (part.type === "reasoning" && part.text.trim().length > 0) {
38708
- reasoning.push({ content: part.text });
38709
- } else if (part.type === "tool-call") {
40072
+ if (!isObject(part)) {
40073
+ continue;
40074
+ }
40075
+ if (part["type"] === "text" && typeof part["text"] === "string") {
40076
+ text += part["text"];
40077
+ } else if (part["type"] === "reasoning" && typeof part["text"] === "string" && part["text"].trim().length > 0) {
40078
+ reasoning.push({ content: part["text"] });
40079
+ } else if (part["type"] === "tool-call" && typeof part["toolName"] === "string" && typeof part["callId"] === "string") {
38710
40080
  toolCalls.push({
38711
40081
  function: {
38712
- arguments: safeJsonStringify(part.input),
38713
- name: part.toolName
40082
+ arguments: safeJsonStringify(part["input"]),
40083
+ name: part["toolName"]
38714
40084
  },
38715
- id: part.callId,
40085
+ id: part["callId"],
38716
40086
  type: "function"
38717
40087
  });
38718
40088
  }
@@ -38731,13 +40101,13 @@ function modelOutput(event) {
38731
40101
  ];
38732
40102
  }
38733
40103
  function usageMetrics(usage) {
38734
- const promptTokens = nonNegativeNumber(usage.inputTokens);
38735
- const completionTokens = nonNegativeNumber(usage.outputTokens);
40104
+ const promptTokens = nonNegativeNumber(usage?.inputTokens);
40105
+ const completionTokens = nonNegativeNumber(usage?.outputTokens);
38736
40106
  const cachedTokens = nonNegativeNumber(
38737
- usage.inputTokenDetails?.cacheReadTokens
40107
+ usage?.inputTokenDetails?.cacheReadTokens
38738
40108
  );
38739
40109
  const cacheCreationTokens = nonNegativeNumber(
38740
- usage.inputTokenDetails?.cacheWriteTokens
40110
+ usage?.inputTokenDetails?.cacheWriteTokens
38741
40111
  );
38742
40112
  return {
38743
40113
  ...promptTokens !== void 0 ? { prompt_tokens: promptTokens } : {},
@@ -38774,10 +40144,76 @@ function turnIdempotencyKey(sessionId, turnId) {
38774
40144
  function actionIdempotencyKey(sessionId, turnId, callId) {
38775
40145
  return `action:${sessionId}:${turnId}:${callId}`;
38776
40146
  }
40147
+ function providerHandler(type, handler) {
40148
+ return async (event, context) => {
40149
+ try {
40150
+ if (!isEveProviderEvent(event, type) || !isEveProviderContext(context)) {
40151
+ debugLogger.warn(`Ignoring malformed Eve provider ${type} event`);
40152
+ return;
40153
+ }
40154
+ await handler(event, context);
40155
+ } catch (error) {
40156
+ debugLogger.warn(`Error in Eve provider ${type}:`, error);
40157
+ }
40158
+ };
40159
+ }
40160
+ function isEveProviderEvent(event, type) {
40161
+ if (!isObject(event) || event["type"] !== type || typeof event["idempotencyKey"] !== "string" || event["idempotencyKey"].length === 0) {
40162
+ return false;
40163
+ }
40164
+ if (type === "turn.started") {
40165
+ const parentLineage = event["parentLineage"];
40166
+ 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));
40167
+ }
40168
+ if (type === "turn.cancelled" || type === "turn.completed" || type === "turn.failed") {
40169
+ return typeof event["sessionId"] === "string" && typeof event["turnId"] === "string";
40170
+ }
40171
+ if (!isEveProviderScope(event["scope"])) {
40172
+ return false;
40173
+ }
40174
+ if (type === "model.call.started") {
40175
+ const model = event["model"];
40176
+ return isObject(model) && typeof model["modelId"] === "string" && typeof model["provider"] === "string";
40177
+ }
40178
+ if (type === "model.call.completed") {
40179
+ return typeof event["finishReason"] === "string" && isObject(event["usage"]) && (event["content"] === void 0 || Array.isArray(event["content"]));
40180
+ }
40181
+ if (type === "model.call.failed") {
40182
+ return true;
40183
+ }
40184
+ if (type === "action.started") {
40185
+ 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");
40186
+ }
40187
+ if (type === "action.completed") {
40188
+ const output = event["output"];
40189
+ return event["outcome"] === "completed" && isObject(output) && (output["type"] === "result" || output["type"] === "error");
40190
+ }
40191
+ if (type === "action.failed") {
40192
+ return event["outcome"] === "abandoned" || event["outcome"] === "cancelled" || event["outcome"] === "failed" || event["outcome"] === "rejected";
40193
+ }
40194
+ return type === "step.attempt.completed" || type === "step.attempt.failed";
40195
+ }
40196
+ function isEveProviderContext(value) {
40197
+ if (!isObject(value) || !isObject(value["state"])) {
40198
+ return false;
40199
+ }
40200
+ return typeof value["state"]["get"] === "function" && typeof value["state"]["set"] === "function";
40201
+ }
40202
+ function isEveProviderScope(value) {
40203
+ 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");
40204
+ }
40205
+ function isEveProviderParentLineage(value) {
40206
+ return isObject(value) && typeof value["callId"] === "string" && typeof value["sessionId"] === "string" && typeof value["turnId"] === "string";
40207
+ }
38777
40208
 
38778
40209
  // src/instrumentation/plugins/eve-instrumentation.ts
38779
40210
  var EVE_INSTRUMENTATION_PROVIDER = /* @__PURE__ */ Symbol.for("eve.instrumentation.provider");
38780
40211
  function braintrustEveInstrumentation(options) {
40212
+ if (!options || typeof options !== "object") {
40213
+ throw new TypeError(
40214
+ "braintrustEveInstrumentation requires an options object"
40215
+ );
40216
+ }
38781
40217
  const definition = "defineState" in options ? createLegacyEveInstrumentation(options) : createEveInstrumentationProvider(options);
38782
40218
  const declaration = {
38783
40219
  ...definition,
@@ -38860,6 +40296,9 @@ var envIntegrationAliases = {
38860
40296
  "langchain-js": "langchain",
38861
40297
  "@langchain": "langchain",
38862
40298
  langgraph: "langgraph",
40299
+ langgraphsdk: "langgraphSDK",
40300
+ "langgraph-sdk": "langgraphSDK",
40301
+ "@langchain/langgraph-sdk": "langgraphSDK",
38863
40302
  langsmith: "langsmith",
38864
40303
  voyage: "voyageai",
38865
40304
  "voyage-ai": "voyageai",
@@ -38900,6 +40339,7 @@ function getDefaultInstrumentationIntegrations() {
38900
40339
  gitHubCopilot: true,
38901
40340
  langchain: true,
38902
40341
  langgraph: true,
40342
+ langgraphSDK: true,
38903
40343
  langsmith: true,
38904
40344
  voyageai: true,
38905
40345
  elevenlabs: true,