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
@@ -33,6 +33,7 @@ import {
33
33
  isSupportedHuggingFaceTransformersTask,
34
34
  isomorph_default,
35
35
  langChainChannels,
36
+ langGraphSDKChannels,
36
37
  langSmithChannels,
37
38
  mergeSpanOriginContext,
38
39
  mistralChannels,
@@ -54,7 +55,7 @@ import {
54
55
  strandsAgentSDKChannels,
55
56
  voyageAIChannels,
56
57
  withSpanInstrumentationName
57
- } from "./chunk-WV6QZI2W.mjs";
58
+ } from "./chunk-TZVZN2JJ.mjs";
58
59
 
59
60
  // src/id-gen.ts
60
61
  import { v4 as uuidv4 } from "uuid";
@@ -8587,6 +8588,38 @@ function getSpanParentObjectAndPropagatedState(options) {
8587
8588
  function getSpanParentObject(options) {
8588
8589
  return getSpanParentObjectAndPropagatedState(options).parentObject;
8589
8590
  }
8591
+ function _internalExportParentSynchronously(parent) {
8592
+ if ("toStr" in parent) {
8593
+ return parent.toStr();
8594
+ }
8595
+ if ("getParentInfo" in parent) {
8596
+ const parentInfo = parent.getParentInfo();
8597
+ if (!parentInfo) {
8598
+ return void 0;
8599
+ }
8600
+ const objectId = parentInfo.objectId.getSync().value;
8601
+ if (!objectId && !parentInfo.computeObjectMetadataArgs) {
8602
+ return void 0;
8603
+ }
8604
+ return new SpanComponentsV4({
8605
+ object_type: parentInfo.objectType,
8606
+ ...objectId ? { object_id: objectId } : {
8607
+ compute_object_metadata_args: parentInfo.computeObjectMetadataArgs ?? {}
8608
+ },
8609
+ row_id: parent.id,
8610
+ root_span_id: parent.rootSpanId,
8611
+ span_id: parent.spanId
8612
+ }).toStr();
8613
+ }
8614
+ const components = braintrustParentToComponents(parent._getOtelParent());
8615
+ if (!components) {
8616
+ return void 0;
8617
+ }
8618
+ return new SpanComponentsV4({
8619
+ object_type: components.objectType,
8620
+ ...components.objectId ? { object_id: components.objectId } : { compute_object_metadata_args: components.computeArgs ?? {} }
8621
+ }).toStr();
8622
+ }
8590
8623
  function currentBraintrustParent(state) {
8591
8624
  const resolvedState = state ?? _globalState;
8592
8625
  const experiment = currentExperiment({ state: resolvedState });
@@ -10198,10 +10231,16 @@ var SpanImpl = class _SpanImpl {
10198
10231
  inject(carrier) {
10199
10232
  const resolvedCarrier = carrier ?? {};
10200
10233
  try {
10234
+ const braintrustParent = this._getOtelParent() ?? this._propagatedState?.braintrustParent;
10235
+ if (!braintrustParent) {
10236
+ debugLogger.forState(this._state).warn(
10237
+ "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."
10238
+ );
10239
+ }
10201
10240
  _injectIntoCarrier(resolvedCarrier, {
10202
10241
  traceId: this._rootSpanId,
10203
10242
  spanId: this._spanId,
10204
- braintrustParent: this._getOtelParent() ?? this._propagatedState?.braintrustParent,
10243
+ braintrustParent,
10205
10244
  propagatedState: this._propagatedState
10206
10245
  });
10207
10246
  } catch (e) {
@@ -12935,27 +12974,8 @@ function continuationParentFromCreateSessionParams(params) {
12935
12974
  }
12936
12975
  return context.parent;
12937
12976
  }
12938
- function exportSpanSynchronously(span) {
12939
- const parentInfo = span.getParentInfo();
12940
- if (!parentInfo) {
12941
- return void 0;
12942
- }
12943
- const objectId = parentInfo.objectId.getSync().value;
12944
- if (!objectId && !parentInfo.computeObjectMetadataArgs) {
12945
- return void 0;
12946
- }
12947
- return new SpanComponentsV4({
12948
- object_type: parentInfo.objectType,
12949
- ...objectId ? { object_id: objectId } : {
12950
- compute_object_metadata_args: parentInfo.computeObjectMetadataArgs ?? {}
12951
- },
12952
- row_id: span.id,
12953
- root_span_id: span.rootSpanId,
12954
- span_id: span.spanId
12955
- }).toStr();
12956
- }
12957
12977
  function exportedParent(parent) {
12958
- return typeof parent === "string" ? parent : exportSpanSynchronously(parent);
12978
+ return typeof parent === "string" ? parent : _internalExportParentSynchronously(parent);
12959
12979
  }
12960
12980
  function addSerializedContext(args) {
12961
12981
  if (!isObject(args.continuation) || args.sessionId === void 0) {
@@ -15316,9 +15336,9 @@ function patchAISDKStreamingResult(args) {
15316
15336
  }
15317
15337
  finalize({ metrics, output });
15318
15338
  } catch (error) {
15319
- const loggedError = toLoggedError(error);
15339
+ const loggedError2 = toLoggedError(error);
15320
15340
  try {
15321
- span.log({ error: loggedError });
15341
+ span.log({ error: loggedError2 });
15322
15342
  } catch (loggingError) {
15323
15343
  debugLogger.error(
15324
15344
  "Error logging AI SDK streaming failure:",
@@ -15326,7 +15346,7 @@ function patchAISDKStreamingResult(args) {
15326
15346
  );
15327
15347
  }
15328
15348
  finalize({
15329
- error: error instanceof Error ? error : new Error(String(loggedError))
15349
+ error: error instanceof Error ? error : new Error(String(loggedError2))
15330
15350
  });
15331
15351
  }
15332
15352
  };
@@ -15439,9 +15459,9 @@ function patchAISDKStreamingResult(args) {
15439
15459
  }
15440
15460
  controller.enqueue(value);
15441
15461
  } catch (error) {
15442
- const loggedError = toLoggedError(error);
15462
+ const loggedError2 = toLoggedError(error);
15443
15463
  try {
15444
- span.log({ error: loggedError });
15464
+ span.log({ error: loggedError2 });
15445
15465
  } catch (loggingError) {
15446
15466
  debugLogger.error(
15447
15467
  "Error logging AI SDK base stream failure:",
@@ -15449,7 +15469,7 @@ function patchAISDKStreamingResult(args) {
15449
15469
  );
15450
15470
  }
15451
15471
  finalize({
15452
- error: error instanceof Error ? error : new Error(String(loggedError))
15472
+ error: error instanceof Error ? error : new Error(String(loggedError2))
15453
15473
  });
15454
15474
  controller.error(error);
15455
15475
  }
@@ -16849,16 +16869,16 @@ function braintrustAISDKTelemetry() {
16849
16869
  if (!toolCallId || !state) {
16850
16870
  return;
16851
16871
  }
16852
- const toolOutput = event.toolOutput;
16872
+ const toolOutput2 = event.toolOutput;
16853
16873
  const workflowToolError = event.success === false && "error" in event ? event.error : void 0;
16854
- if (toolOutput?.type === "tool-error" || workflowToolError !== void 0) {
16855
- const error = toolOutput?.error ?? workflowToolError;
16874
+ if (toolOutput2?.type === "tool-error" || workflowToolError !== void 0) {
16875
+ const error = toolOutput2?.error ?? workflowToolError;
16856
16876
  state.span.log({
16857
16877
  error: error instanceof Error ? error.message : String(error),
16858
16878
  metrics: typeof event.durationMs === "number" ? { duration_ms: event.durationMs } : {}
16859
16879
  });
16860
16880
  } else {
16861
- const output = toolOutput && "output" in toolOutput ? toolOutput.output : event.output;
16881
+ const output = toolOutput2 && "output" in toolOutput2 ? toolOutput2.output : event.output;
16862
16882
  state.span.log({
16863
16883
  ...shouldRecordOutputs(event) ? { output } : {},
16864
16884
  metrics: typeof event.durationMs === "number" ? { duration_ms: event.durationMs } : {}
@@ -18720,6 +18740,23 @@ function processImagesInOutput(output) {
18720
18740
  return output;
18721
18741
  }
18722
18742
 
18743
+ // src/instrumentation/plugins/openai-manual-instrumentation-utils.ts
18744
+ async function deterministicDigest(namespace, ...parts) {
18745
+ const encoded = new TextEncoder().encode(
18746
+ [namespace, ...parts].map((part) => `${part.length}:${part}`).join("\0")
18747
+ );
18748
+ return new Uint8Array(
18749
+ await globalThis.crypto.subtle.digest("SHA-256", encoded)
18750
+ );
18751
+ }
18752
+ function digestHex(bytes, length) {
18753
+ return Array.from(bytes.slice(0, length)).map((byte) => byte.toString(16).padStart(2, "0")).join("");
18754
+ }
18755
+ function digestUuid(bytes) {
18756
+ const hex = digestHex(bytes, 16);
18757
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
18758
+ }
18759
+
18723
18760
  // src/instrumentation/plugins/openai-batch-instrumentation.ts
18724
18761
  var SUPPORTED_ENDPOINTS = /* @__PURE__ */ new Set(["/v1/chat/completions", "/v1/responses"]);
18725
18762
  var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
@@ -18760,21 +18797,6 @@ async function exportParent(parent) {
18760
18797
  }
18761
18798
  return void 0;
18762
18799
  }
18763
- async function deterministicDigest(namespace, ...parts) {
18764
- const encoded = new TextEncoder().encode(
18765
- [namespace, ...parts].map((part) => `${part.length}:${part}`).join("\0")
18766
- );
18767
- return new Uint8Array(
18768
- await globalThis.crypto.subtle.digest("SHA-256", encoded)
18769
- );
18770
- }
18771
- function digestHex(bytes, length) {
18772
- return Array.from(bytes.slice(0, length)).map((byte) => byte.toString(16).padStart(2, "0")).join("");
18773
- }
18774
- function digestUuid(bytes) {
18775
- const hex = digestHex(bytes, 16);
18776
- return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
18777
- }
18778
18800
  async function batchSpanIds(inputFileId) {
18779
18801
  const [row, span, root] = await Promise.all([
18780
18802
  deterministicDigest("openai:batch:row", inputFileId),
@@ -19265,6 +19287,628 @@ var interceptOpenAIBatchTraceComplete = (target, thisArg, args) => Promise.resol
19265
19287
  return result;
19266
19288
  });
19267
19289
 
19290
+ // src/instrumentation/plugins/openai-agents-api-instrumentation.ts
19291
+ var TERMINAL_TURN_EVENTS = /* @__PURE__ */ new Set([
19292
+ "agent.session.turn.completed",
19293
+ "agent.session.turn.failed",
19294
+ "agent.session.turn.cancelled"
19295
+ ]);
19296
+ var TURN_LIFECYCLE_EVENTS = /* @__PURE__ */ new Set([
19297
+ "agent.session.turn.created",
19298
+ "agent.session.turn.in_progress",
19299
+ ...TERMINAL_TURN_EVENTS
19300
+ ]);
19301
+ var SESSION_EVENTS = /* @__PURE__ */ new Set([
19302
+ "agent.session.created",
19303
+ "agent.session.failed",
19304
+ "agent.session.idle",
19305
+ "agent.session.in_progress",
19306
+ "agent.session.requires_action"
19307
+ ]);
19308
+ var SUBAGENT_EVENTS = /* @__PURE__ */ new Set([
19309
+ "agent.session.subagent.active",
19310
+ "agent.session.subagent.closed",
19311
+ "agent.session.subagent.created"
19312
+ ]);
19313
+ function read2(value, key) {
19314
+ if (!isObject(value)) {
19315
+ return void 0;
19316
+ }
19317
+ try {
19318
+ return Reflect.get(value, key);
19319
+ } catch {
19320
+ return void 0;
19321
+ }
19322
+ }
19323
+ function stringValue(value) {
19324
+ return typeof value === "string" && value.length > 0 ? value : void 0;
19325
+ }
19326
+ function recordValue(record, key) {
19327
+ return Object.hasOwn(record, key) ? record[key] : void 0;
19328
+ }
19329
+ function setRecordValue(record, key, value) {
19330
+ Object.defineProperty(record, key, {
19331
+ configurable: true,
19332
+ enumerable: true,
19333
+ value,
19334
+ writable: true
19335
+ });
19336
+ }
19337
+ function loggedError(value, fallback) {
19338
+ if (value instanceof Error) {
19339
+ return value;
19340
+ }
19341
+ const message = stringValue(read2(value, "message"));
19342
+ return new Error(message ?? (typeof value === "string" ? value : fallback));
19343
+ }
19344
+ function logInstrumentationError2(context, error) {
19345
+ debugLogger.debug(`OpenAI Agents API instrumentation ${context}:`, error);
19346
+ }
19347
+ async function childSpanIds2(rootKey, kind, providerId) {
19348
+ const [row, span] = await Promise.all([
19349
+ deterministicDigest("openai:agents:row", rootKey, kind, providerId),
19350
+ deterministicDigest("openai:agents:span", rootKey, kind, providerId)
19351
+ ]);
19352
+ return { rowId: digestUuid(row), spanId: digestHex(span, 8) };
19353
+ }
19354
+ function traceMetadata(args) {
19355
+ const metadata = {};
19356
+ const suppliedMetadata = read2(args, "metadata");
19357
+ if (isObject(suppliedMetadata)) {
19358
+ try {
19359
+ for (const key of Object.keys(suppliedMetadata)) {
19360
+ metadata[key] = read2(suppliedMetadata, key);
19361
+ }
19362
+ } catch (error) {
19363
+ logInstrumentationError2("could not read supplied metadata", error);
19364
+ }
19365
+ }
19366
+ const agent = read2(args, "agent");
19367
+ const agentId = stringValue(read2(agent, "id")) ?? stringValue(read2(args, "agent_id"));
19368
+ const agentName = stringValue(read2(agent, "name"));
19369
+ const model = stringValue(read2(agent, "model"));
19370
+ return {
19371
+ ...metadata,
19372
+ api: "agents",
19373
+ ...agentId ? { agent_id: agentId } : {},
19374
+ ...agentName ? { agent_name: agentName } : {},
19375
+ ...model ? { model } : {},
19376
+ provider: "openai"
19377
+ };
19378
+ }
19379
+ function copyState(state) {
19380
+ return {
19381
+ ...state,
19382
+ callItems: { ...state.callItems },
19383
+ eventIds: [...state.eventIds],
19384
+ openTools: { ...state.openTools },
19385
+ subagents: { ...state.subagents },
19386
+ turnSubagents: { ...state.turnSubagents }
19387
+ };
19388
+ }
19389
+ function startRootSpan(state) {
19390
+ const root = SpanComponentsV4.fromStr(state.root);
19391
+ const parent = SpanComponentsV4.fromStr(state.rootParent);
19392
+ const rowId = stringValue(root.data.row_id);
19393
+ const rootSpanId = stringValue(root.data.root_span_id);
19394
+ const spanId = stringValue(root.data.span_id);
19395
+ if (!rowId || !rootSpanId || !spanId) {
19396
+ throw new Error("OpenAI Agents trace root is invalid");
19397
+ }
19398
+ const hasParentSpan = Boolean(
19399
+ parent.data.row_id && parent.data.span_id && parent.data.root_span_id
19400
+ );
19401
+ return withCurrent(
19402
+ NOOP_SPAN,
19403
+ () => _internalStartSpanWithInitialMergeAndParentSpanIds(
19404
+ withSpanInstrumentationName(
19405
+ {
19406
+ name: "openai.agents.turn",
19407
+ type: "task" /* TASK */,
19408
+ parent: state.rootParent,
19409
+ ...!hasParentSpan ? {
19410
+ parentSpanIds: {
19411
+ parentSpanIds: [],
19412
+ rootSpanId
19413
+ }
19414
+ } : {},
19415
+ spanId,
19416
+ startTime: state.startTime,
19417
+ event: { id: rowId }
19418
+ },
19419
+ INSTRUMENTATION_NAMES.OPENAI
19420
+ )
19421
+ )
19422
+ );
19423
+ }
19424
+ async function startSubagentSpan(state, subagentId, input, metadata, visiting = /* @__PURE__ */ new Set()) {
19425
+ const subagent = recordValue(state.subagents, subagentId);
19426
+ let parent = state.root;
19427
+ if (subagent?.parentAgentId && subagent.parentAgentId !== subagentId && recordValue(state.subagents, subagent.parentAgentId) && !visiting.has(subagent.parentAgentId)) {
19428
+ visiting.add(subagentId);
19429
+ parent = await (await startSubagentSpan(
19430
+ state,
19431
+ subagent.parentAgentId,
19432
+ void 0,
19433
+ void 0,
19434
+ visiting
19435
+ )).export();
19436
+ }
19437
+ const ids = await childSpanIds2(state.rootKey, "subagent", subagentId);
19438
+ return withCurrent(
19439
+ NOOP_SPAN,
19440
+ () => _internalStartSpanWithInitialMerge(
19441
+ withSpanInstrumentationName(
19442
+ {
19443
+ name: "openai.agents.subagent",
19444
+ type: "task" /* TASK */,
19445
+ parent,
19446
+ spanId: ids.spanId,
19447
+ startTime: subagent?.openedAt,
19448
+ event: {
19449
+ id: ids.rowId,
19450
+ ...input !== void 0 ? { input } : {},
19451
+ metadata: {
19452
+ ...metadata,
19453
+ agent_id: subagentId,
19454
+ ...subagent?.parentAgentId ? { parent_agent_id: subagent.parentAgentId } : {},
19455
+ provider: "openai"
19456
+ }
19457
+ }
19458
+ },
19459
+ INSTRUMENTATION_NAMES.OPENAI
19460
+ )
19461
+ )
19462
+ );
19463
+ }
19464
+ async function parentForTurn(state, turnId) {
19465
+ const subagentId = turnId ? recordValue(state.turnSubagents, turnId) : void 0;
19466
+ if (!subagentId) {
19467
+ return state.root;
19468
+ }
19469
+ return await (await startSubagentSpan(state, subagentId)).export();
19470
+ }
19471
+ async function startToolSpan(state, tool, input) {
19472
+ const ids = await childSpanIds2(state.rootKey, "tool", tool.itemId);
19473
+ return withCurrent(
19474
+ NOOP_SPAN,
19475
+ async () => _internalStartSpanWithInitialMerge(
19476
+ withSpanInstrumentationName(
19477
+ {
19478
+ name: tool.name,
19479
+ type: "tool" /* TOOL */,
19480
+ parent: await parentForTurn(state, tool.turnId),
19481
+ spanId: ids.spanId,
19482
+ startTime: tool.startTime,
19483
+ event: {
19484
+ id: ids.rowId,
19485
+ ...input !== void 0 ? { input } : {},
19486
+ metadata: {
19487
+ item_id: tool.itemId,
19488
+ provider: "openai",
19489
+ tool_type: tool.toolType,
19490
+ ...tool.turnId ? { turn_id: tool.turnId } : {}
19491
+ }
19492
+ }
19493
+ },
19494
+ INSTRUMENTATION_NAMES.OPENAI
19495
+ )
19496
+ )
19497
+ );
19498
+ }
19499
+ function toolFromItem(item, observedAt) {
19500
+ const itemId = stringValue(read2(item, "id"));
19501
+ const toolType = stringValue(read2(item, "type"));
19502
+ if (!itemId || !toolType) {
19503
+ return void 0;
19504
+ }
19505
+ const turnId = stringValue(read2(item, "turn_id"));
19506
+ switch (toolType) {
19507
+ case "function_call":
19508
+ return {
19509
+ input: read2(item, "arguments"),
19510
+ tool: {
19511
+ itemId,
19512
+ name: stringValue(read2(item, "name")) ?? "Function call",
19513
+ startTime: observedAt,
19514
+ toolType,
19515
+ ...turnId ? { turnId } : {}
19516
+ }
19517
+ };
19518
+ case "mcp_call": {
19519
+ const name = stringValue(read2(item, "name")) ?? "MCP call";
19520
+ const server = stringValue(read2(item, "server_label"));
19521
+ return {
19522
+ input: read2(item, "arguments"),
19523
+ tool: {
19524
+ itemId,
19525
+ name: server ? `${server}.${name}` : name,
19526
+ startTime: observedAt,
19527
+ toolType,
19528
+ ...turnId ? { turnId } : {}
19529
+ }
19530
+ };
19531
+ }
19532
+ case "web_search_call":
19533
+ return {
19534
+ input: read2(item, "action"),
19535
+ tool: {
19536
+ itemId,
19537
+ name: "Web search",
19538
+ startTime: observedAt,
19539
+ toolType,
19540
+ ...turnId ? { turnId } : {}
19541
+ }
19542
+ };
19543
+ case "command_execution":
19544
+ return {
19545
+ input: {
19546
+ command: read2(item, "command"),
19547
+ cwd: read2(item, "cwd")
19548
+ },
19549
+ tool: {
19550
+ itemId,
19551
+ name: "Command execution",
19552
+ startTime: observedAt,
19553
+ toolType,
19554
+ ...turnId ? { turnId } : {}
19555
+ }
19556
+ };
19557
+ default:
19558
+ return void 0;
19559
+ }
19560
+ }
19561
+ function textFromContent(content) {
19562
+ if (!Array.isArray(content)) {
19563
+ return void 0;
19564
+ }
19565
+ const text = [];
19566
+ for (const part of content) {
19567
+ const partText = read2(part, "text");
19568
+ if (read2(part, "type") === "output_text" && typeof partText === "string") {
19569
+ text.push(partText);
19570
+ }
19571
+ }
19572
+ return text.length > 0 ? text.join("") : void 0;
19573
+ }
19574
+ function toolOutput(item, toolType) {
19575
+ switch (toolType) {
19576
+ case "function_call":
19577
+ return read2(item, "output");
19578
+ case "mcp_call":
19579
+ return read2(item, "output");
19580
+ case "web_search_call":
19581
+ return read2(item, "action");
19582
+ case "command_execution":
19583
+ return read2(item, "output");
19584
+ default:
19585
+ return void 0;
19586
+ }
19587
+ }
19588
+ function toolFailed(item, toolType) {
19589
+ const status = read2(item, "status");
19590
+ const explicitError = read2(item, "error");
19591
+ if (explicitError !== void 0 && explicitError !== null) {
19592
+ return loggedError(explicitError, `OpenAI ${toolType} failed`);
19593
+ }
19594
+ if (status === "failed" || status === "incomplete") {
19595
+ return new Error(`OpenAI ${toolType} ${status}`);
19596
+ }
19597
+ if (toolType === "command_execution" && typeof read2(item, "exit_code") === "number" && read2(item, "exit_code") !== 0) {
19598
+ return new Error(
19599
+ `OpenAI command exited with code ${read2(item, "exit_code")}`
19600
+ );
19601
+ }
19602
+ return void 0;
19603
+ }
19604
+ async function completeTool(state, tool, item, endTime) {
19605
+ const span = await startToolSpan(state, tool);
19606
+ const output = toolOutput(item, tool.toolType);
19607
+ const error = toolFailed(item, tool.toolType);
19608
+ span.log({
19609
+ ...output !== void 0 ? { output } : {},
19610
+ ...error ? { error } : {},
19611
+ metadata: {
19612
+ status: read2(item, "status"),
19613
+ ...tool.toolType === "command_execution" ? { exit_code: read2(item, "exit_code") } : {}
19614
+ }
19615
+ });
19616
+ span.end({ endTime });
19617
+ Reflect.deleteProperty(state.openTools, tool.itemId);
19618
+ }
19619
+ async function captureMessage(state, item) {
19620
+ if (read2(item, "type") !== "message" || read2(item, "role") !== "assistant" || read2(item, "phase") !== "final_answer") {
19621
+ return;
19622
+ }
19623
+ const output = textFromContent(read2(item, "content"));
19624
+ if (output === void 0) {
19625
+ return;
19626
+ }
19627
+ const turnId = stringValue(read2(item, "turn_id"));
19628
+ const subagentId = turnId ? recordValue(state.turnSubagents, turnId) : void 0;
19629
+ if (subagentId) {
19630
+ (await startSubagentSpan(state, subagentId)).log({ output });
19631
+ } else {
19632
+ startRootSpan(state).log({ output });
19633
+ }
19634
+ }
19635
+ async function captureItem(state, item, isDone, observedAt) {
19636
+ await captureMessage(state, item);
19637
+ const itemType = stringValue(read2(item, "type"));
19638
+ if (itemType === "function_call_output") {
19639
+ const callId = stringValue(read2(item, "call_id"));
19640
+ const itemId = callId ? recordValue(state.callItems, callId) : void 0;
19641
+ const tool2 = itemId ? recordValue(state.openTools, itemId) : void 0;
19642
+ if (tool2) {
19643
+ await completeTool(state, tool2, item, observedAt);
19644
+ }
19645
+ return;
19646
+ }
19647
+ const descriptor = toolFromItem(item, observedAt);
19648
+ if (!descriptor) {
19649
+ return;
19650
+ }
19651
+ const existing = recordValue(state.openTools, descriptor.tool.itemId);
19652
+ const tool = existing ?? descriptor.tool;
19653
+ setRecordValue(state.openTools, tool.itemId, tool);
19654
+ if (itemType === "function_call") {
19655
+ const callId = stringValue(read2(item, "call_id"));
19656
+ if (callId) {
19657
+ setRecordValue(state.callItems, callId, tool.itemId);
19658
+ }
19659
+ }
19660
+ await startToolSpan(state, tool, descriptor.input);
19661
+ const status = read2(item, "status");
19662
+ const terminalFunctionCall = itemType === "function_call" && (status === "failed" || status === "incomplete");
19663
+ if (itemType !== "function_call" && (isDone || status !== "in_progress") || terminalFunctionCall) {
19664
+ await completeTool(state, tool, item, observedAt);
19665
+ }
19666
+ }
19667
+ function updateSessionMetadata(state, session) {
19668
+ const sessionId = stringValue(read2(session, "id"));
19669
+ const agent = read2(session, "agent");
19670
+ startRootSpan(state).log({
19671
+ metadata: {
19672
+ ...sessionId ? { session_id: sessionId } : {},
19673
+ ...stringValue(read2(agent, "id")) ? { agent_id: read2(agent, "id") } : {},
19674
+ ...stringValue(read2(agent, "name")) ? { agent_name: read2(agent, "name") } : {},
19675
+ ...stringValue(read2(agent, "model")) ? { model: read2(agent, "model") } : {}
19676
+ }
19677
+ });
19678
+ }
19679
+ async function captureSubagent(state, eventType, subagent, observedAt) {
19680
+ const subagentId = stringValue(read2(subagent, "id"));
19681
+ if (!subagentId) {
19682
+ return;
19683
+ }
19684
+ const existing = recordValue(state.subagents, subagentId);
19685
+ const observedOpenedAt = read2(subagent, "opened_at");
19686
+ const openedAt = typeof observedOpenedAt === "number" && Number.isFinite(observedOpenedAt) && observedOpenedAt >= 0 ? observedOpenedAt : existing?.openedAt ?? observedAt;
19687
+ const observedClosedAt = read2(subagent, "closed_at");
19688
+ const closedAt = typeof observedClosedAt === "number" && Number.isFinite(observedClosedAt) && observedClosedAt >= 0 ? observedClosedAt : existing?.closedAt;
19689
+ const parentAgentId = stringValue(read2(subagent, "parent_agent_id")) ?? existing?.parentAgentId;
19690
+ setRecordValue(state.subagents, subagentId, {
19691
+ ...closedAt !== void 0 ? { closedAt } : {},
19692
+ openedAt,
19693
+ ...parentAgentId ? { parentAgentId } : {}
19694
+ });
19695
+ const span = await startSubagentSpan(
19696
+ state,
19697
+ subagentId,
19698
+ read2(subagent, "instructions"),
19699
+ {
19700
+ ...stringValue(read2(subagent, "name")) ? { agent_name: read2(subagent, "name") } : {},
19701
+ status: read2(subagent, "status")
19702
+ }
19703
+ );
19704
+ if (eventType === "agent.session.subagent.closed") {
19705
+ span.end({ endTime: closedAt ?? observedAt });
19706
+ }
19707
+ }
19708
+ async function closeTrace(state, endTime, error, usage) {
19709
+ if (state.ended) {
19710
+ return;
19711
+ }
19712
+ for (const tool of Object.values(state.openTools)) {
19713
+ const span = await startToolSpan(state, tool);
19714
+ span.log({
19715
+ error: error ?? new Error("OpenAI Agents turn ended before tool completion")
19716
+ });
19717
+ span.end({ endTime });
19718
+ }
19719
+ state.openTools = {};
19720
+ for (const subagentId of Object.keys(state.subagents)) {
19721
+ const subagent = state.subagents[subagentId];
19722
+ const span = await startSubagentSpan(state, subagentId);
19723
+ span.end({ endTime: subagent.closedAt ?? endTime });
19724
+ }
19725
+ const root = startRootSpan(state);
19726
+ root.log({
19727
+ ...error ? { error } : {},
19728
+ metrics: parseMetricsFromUsage(usage)
19729
+ });
19730
+ root.end({ endTime });
19731
+ state.ended = true;
19732
+ }
19733
+ async function captureTurnLifecycle(state, event, eventType, observedAt) {
19734
+ const turn = read2(event, "turn");
19735
+ const turnId = stringValue(read2(event, "turn_id")) ?? stringValue(read2(turn, "id"));
19736
+ const subagentId = stringValue(read2(turn, "subagent_id"));
19737
+ if (turnId && subagentId) {
19738
+ setRecordValue(state.turnSubagents, turnId, subagentId);
19739
+ if (!recordValue(state.subagents, subagentId)) {
19740
+ const createdAt = read2(turn, "created_at");
19741
+ setRecordValue(state.subagents, subagentId, {
19742
+ openedAt: typeof createdAt === "number" && Number.isFinite(createdAt) && createdAt >= 0 ? createdAt : observedAt
19743
+ });
19744
+ }
19745
+ await startSubagentSpan(state, subagentId);
19746
+ }
19747
+ const sessionId = stringValue(read2(event, "session_id"));
19748
+ if (sessionId) {
19749
+ startRootSpan(state).log({ metadata: { session_id: sessionId } });
19750
+ }
19751
+ if (!TERMINAL_TURN_EVENTS.has(eventType) || subagentId) {
19752
+ if (subagentId && eventType === "agent.session.turn.failed") {
19753
+ (await startSubagentSpan(state, subagentId)).log({
19754
+ error: loggedError(read2(turn, "error"), "OpenAI subagent turn failed")
19755
+ });
19756
+ }
19757
+ return;
19758
+ }
19759
+ const completedAt = read2(turn, "completed_at");
19760
+ const endTime = typeof completedAt === "number" && Number.isFinite(completedAt) && completedAt >= 0 ? completedAt : observedAt;
19761
+ const usage = read2(event, "usage") ?? read2(turn, "usage");
19762
+ const error = eventType === "agent.session.turn.completed" ? void 0 : loggedError(
19763
+ read2(turn, "error"),
19764
+ eventType === "agent.session.turn.cancelled" ? "OpenAI Agents turn cancelled" : "OpenAI Agents turn failed"
19765
+ );
19766
+ await closeTrace(state, endTime, error, usage);
19767
+ }
19768
+ async function captureEvent(state, event) {
19769
+ if (state.ended) {
19770
+ return state;
19771
+ }
19772
+ const eventType = stringValue(read2(event, "type"));
19773
+ const eventId = stringValue(read2(event, "event_id"));
19774
+ if (!eventType || eventId && state.eventIds.includes(eventId)) {
19775
+ return state;
19776
+ }
19777
+ const next = copyState(state);
19778
+ const observedAt = getCurrentUnixTimestamp();
19779
+ let handled = false;
19780
+ if (SESSION_EVENTS.has(eventType)) {
19781
+ const session = read2(event, "session");
19782
+ if (session) {
19783
+ updateSessionMetadata(next, session);
19784
+ }
19785
+ handled = true;
19786
+ }
19787
+ if (eventType === "agent.session.turn.item.added") {
19788
+ await captureItem(next, read2(event, "item"), false, observedAt);
19789
+ handled = true;
19790
+ } else if (eventType === "agent.session.turn.item.done") {
19791
+ await captureItem(next, read2(event, "item"), true, observedAt);
19792
+ handled = true;
19793
+ } else if (TURN_LIFECYCLE_EVENTS.has(eventType)) {
19794
+ await captureTurnLifecycle(next, event, eventType, observedAt);
19795
+ handled = true;
19796
+ } else if (SUBAGENT_EVENTS.has(eventType)) {
19797
+ await captureSubagent(next, eventType, read2(event, "subagent"), observedAt);
19798
+ handled = true;
19799
+ } else if (eventType === "agent.session.turn.output_text.delta" && next.firstTokenAt === void 0 && stringValue(read2(event, "delta"))) {
19800
+ next.firstTokenAt = observedAt;
19801
+ startRootSpan(next).log({
19802
+ metrics: { time_to_first_token: observedAt - next.startTime }
19803
+ });
19804
+ handled = true;
19805
+ } else if (eventType === "agent.session.failed") {
19806
+ const session = read2(event, "session");
19807
+ const lastActiveAt = read2(session, "last_active_at");
19808
+ const endTime = typeof lastActiveAt === "number" && Number.isFinite(lastActiveAt) && lastActiveAt >= 0 ? lastActiveAt : observedAt;
19809
+ await closeTrace(
19810
+ next,
19811
+ endTime,
19812
+ loggedError(read2(session, "error"), "OpenAI Agents session failed"),
19813
+ read2(session, "usage")
19814
+ );
19815
+ handled = true;
19816
+ } else if (eventType === "error") {
19817
+ await closeTrace(
19818
+ next,
19819
+ observedAt,
19820
+ loggedError(read2(event, "error"), "OpenAI Agents session failed")
19821
+ );
19822
+ handled = true;
19823
+ }
19824
+ if (!handled) {
19825
+ return state;
19826
+ }
19827
+ if (eventId) {
19828
+ next.eventIds.push(eventId);
19829
+ }
19830
+ return next;
19831
+ }
19832
+ var interceptOpenAIAgentsTraceStart = async (target, thisArg, args) => {
19833
+ const fallback = await Reflect.apply(target, thisArg, args);
19834
+ try {
19835
+ const state = args[0].state;
19836
+ const parent = state.rootParent;
19837
+ const traceArgs = args[0].args;
19838
+ const parentComponents = SpanComponentsV4.fromStr(parent);
19839
+ const hasParentSpan = Boolean(
19840
+ parentComponents.data.row_id && parentComponents.data.span_id && parentComponents.data.root_span_id
19841
+ );
19842
+ const rootComponents = SpanComponentsV4.fromStr(state.root);
19843
+ const rowId = stringValue(rootComponents.data.row_id);
19844
+ const rootSpanId = stringValue(rootComponents.data.root_span_id);
19845
+ const spanId = stringValue(rootComponents.data.span_id);
19846
+ if (!rowId || !rootSpanId || !spanId) {
19847
+ throw new Error("OpenAI Agents trace root is invalid");
19848
+ }
19849
+ withCurrent(
19850
+ NOOP_SPAN,
19851
+ () => _internalStartSpanWithInitialMergeAndParentSpanIds(
19852
+ withSpanInstrumentationName(
19853
+ {
19854
+ name: "openai.agents.turn",
19855
+ type: "task" /* TASK */,
19856
+ parent,
19857
+ ...!hasParentSpan ? {
19858
+ parentSpanIds: {
19859
+ parentSpanIds: [],
19860
+ rootSpanId
19861
+ }
19862
+ } : {},
19863
+ spanId,
19864
+ startTime: state.startTime,
19865
+ event: {
19866
+ id: rowId,
19867
+ input: read2(traceArgs, "input"),
19868
+ metadata: traceMetadata(traceArgs)
19869
+ }
19870
+ },
19871
+ INSTRUMENTATION_NAMES.OPENAI
19872
+ )
19873
+ )
19874
+ );
19875
+ return state;
19876
+ } catch (error) {
19877
+ logInstrumentationError2("could not start trace", error);
19878
+ return fallback;
19879
+ }
19880
+ };
19881
+ var interceptOpenAIAgentsTraceCapture = async (target, thisArg, args) => {
19882
+ const fallback = await Reflect.apply(target, thisArg, args);
19883
+ if (!args[0].state) {
19884
+ return fallback;
19885
+ }
19886
+ try {
19887
+ return await captureEvent(args[0].state, args[0].event);
19888
+ } catch (error) {
19889
+ logInstrumentationError2("could not capture event", error);
19890
+ return fallback;
19891
+ }
19892
+ };
19893
+ var interceptOpenAIAgentsTraceFail = async (target, thisArg, args) => {
19894
+ const fallback = await Reflect.apply(target, thisArg, args);
19895
+ if (!args[0].state) {
19896
+ return fallback;
19897
+ }
19898
+ try {
19899
+ const next = copyState(args[0].state);
19900
+ await closeTrace(
19901
+ next,
19902
+ getCurrentUnixTimestamp(),
19903
+ loggedError(args[0].error, "OpenAI Agents request failed")
19904
+ );
19905
+ return next;
19906
+ } catch (error) {
19907
+ logInstrumentationError2("could not fail trace", error);
19908
+ return fallback;
19909
+ }
19910
+ };
19911
+
19268
19912
  // src/instrumentation/plugins/openai-plugin.ts
19269
19913
  var OpenAIPlugin = class extends BasePlugin {
19270
19914
  constructor() {
@@ -19272,6 +19916,13 @@ var OpenAIPlugin = class extends BasePlugin {
19272
19916
  }
19273
19917
  onEnable() {
19274
19918
  this.unsubscribers.push(
19919
+ openAIChannels.agentsTraceStart.intercept(
19920
+ interceptOpenAIAgentsTraceStart
19921
+ ),
19922
+ openAIChannels.agentsTraceCapture.intercept(
19923
+ interceptOpenAIAgentsTraceCapture
19924
+ ),
19925
+ openAIChannels.agentsTraceFail.intercept(interceptOpenAIAgentsTraceFail),
19275
19926
  openAIChannels.filesCreateTraced.intercept(
19276
19927
  interceptOpenAIFilesCreateTraced
19277
19928
  ),
@@ -19816,7 +20467,7 @@ async function* patchCodexEventStream(events, state) {
19816
20467
  try {
19817
20468
  await handleCodexEvent(state, event);
19818
20469
  } catch (error) {
19819
- logInstrumentationError2("OpenAI Codex stream event", error);
20470
+ logInstrumentationError3("OpenAI Codex stream event", error);
19820
20471
  }
19821
20472
  yield event;
19822
20473
  }
@@ -20316,10 +20967,10 @@ function safeLog2(span, event) {
20316
20967
  try {
20317
20968
  span.log(event);
20318
20969
  } catch (error) {
20319
- logInstrumentationError2("OpenAI Codex span log", error);
20970
+ logInstrumentationError3("OpenAI Codex span log", error);
20320
20971
  }
20321
20972
  }
20322
- function logInstrumentationError2(context, error) {
20973
+ function logInstrumentationError3(context, error) {
20323
20974
  debugLogger.error(`Error processing ${context}:`, error);
20324
20975
  }
20325
20976
 
@@ -23499,7 +24150,7 @@ function wrapSendOptionsCallbacks(options, state) {
23499
24150
  try {
23500
24151
  await handleInteractionUpdate(state, args.update);
23501
24152
  } catch (error) {
23502
- logInstrumentationError3("Cursor SDK onDelta", error);
24153
+ logInstrumentationError4("Cursor SDK onDelta", error);
23503
24154
  }
23504
24155
  if (originalOnDelta) {
23505
24156
  return originalOnDelta(args);
@@ -23509,7 +24160,7 @@ function wrapSendOptionsCallbacks(options, state) {
23509
24160
  try {
23510
24161
  handleStepUpdate(state, args.step);
23511
24162
  } catch (error) {
23512
- logInstrumentationError3("Cursor SDK onStep", error);
24163
+ logInstrumentationError4("Cursor SDK onStep", error);
23513
24164
  }
23514
24165
  if (originalOnStep) {
23515
24166
  return originalOnStep(args);
@@ -23591,7 +24242,7 @@ async function* patchCursorStream(stream, state) {
23591
24242
  try {
23592
24243
  await handleStreamMessage2(state, message);
23593
24244
  } catch (error) {
23594
- logInstrumentationError3("Cursor SDK stream", error);
24245
+ logInstrumentationError4("Cursor SDK stream", error);
23595
24246
  }
23596
24247
  yield message;
23597
24248
  }
@@ -23655,7 +24306,7 @@ async function handleToolUpdate(state, update) {
23655
24306
  if (!state.activeToolSpans.has(callId)) {
23656
24307
  state.activeToolSpans.set(
23657
24308
  callId,
23658
- await startToolSpan(state, {
24309
+ await startToolSpan2(state, {
23659
24310
  args,
23660
24311
  callId,
23661
24312
  name,
@@ -23666,7 +24317,7 @@ async function handleToolUpdate(state, update) {
23666
24317
  }
23667
24318
  return;
23668
24319
  }
23669
- const toolState = state.activeToolSpans.get(callId) ?? await startToolSpan(state, {
24320
+ const toolState = state.activeToolSpans.get(callId) ?? await startToolSpan2(state, {
23670
24321
  args,
23671
24322
  callId,
23672
24323
  name,
@@ -23703,7 +24354,7 @@ async function handleStreamMessage2(state, message) {
23703
24354
  } else if (block?.type === "tool_use" && block.id) {
23704
24355
  state.activeToolSpans.set(
23705
24356
  block.id,
23706
- await startToolSpan(state, {
24357
+ await startToolSpan2(state, {
23707
24358
  args: block.input,
23708
24359
  callId: block.id,
23709
24360
  name: block.name,
@@ -23738,7 +24389,7 @@ async function handleToolMessage(state, message) {
23738
24389
  if (!state.activeToolSpans.has(callId)) {
23739
24390
  state.activeToolSpans.set(
23740
24391
  callId,
23741
- await startToolSpan(state, {
24392
+ await startToolSpan2(state, {
23742
24393
  args: message.args,
23743
24394
  callId,
23744
24395
  name: message.name,
@@ -23749,7 +24400,7 @@ async function handleToolMessage(state, message) {
23749
24400
  }
23750
24401
  return;
23751
24402
  }
23752
- const toolState = state.activeToolSpans.get(callId) ?? await startToolSpan(state, {
24403
+ const toolState = state.activeToolSpans.get(callId) ?? await startToolSpan2(state, {
23753
24404
  args: message.args,
23754
24405
  callId,
23755
24406
  name: message.name,
@@ -23776,7 +24427,7 @@ async function handleConversation(state, turns) {
23776
24427
  const command = turn.turn?.shellCommand?.command;
23777
24428
  if (command) {
23778
24429
  const callId = `shell:${state.activeToolSpans.size}:${command}`;
23779
- const toolState = await startToolSpan(state, {
24430
+ const toolState = await startToolSpan2(state, {
23780
24431
  args: turn.turn?.shellCommand,
23781
24432
  callId,
23782
24433
  name: "shell",
@@ -23800,7 +24451,7 @@ async function handleConversationStep(state, step) {
23800
24451
  }
23801
24452
  const toolCall = step.message;
23802
24453
  const callId = typeof toolCall?.callId === "string" ? toolCall.callId : `conversation-tool:${state.activeToolSpans.size}`;
23803
- const toolState = await startToolSpan(state, {
24454
+ const toolState = await startToolSpan2(state, {
23804
24455
  args: extractToolArgs(toolCall),
23805
24456
  callId,
23806
24457
  name: extractToolName(toolCall),
@@ -23831,7 +24482,7 @@ function handleStepUpdate(state, step) {
23831
24482
  state.stepText.push(step.message.text);
23832
24483
  }
23833
24484
  }
23834
- async function startToolSpan(state, args) {
24485
+ async function startToolSpan2(state, args) {
23835
24486
  const name = args.name || "unknown";
23836
24487
  const metadata = {
23837
24488
  "cursor_sdk.tool.status": args.status,
@@ -24118,10 +24769,10 @@ function safeLog3(span, event) {
24118
24769
  try {
24119
24770
  span.log(event);
24120
24771
  } catch (error) {
24121
- logInstrumentationError3("Cursor SDK span log", error);
24772
+ logInstrumentationError4("Cursor SDK span log", error);
24122
24773
  }
24123
24774
  }
24124
- function logInstrumentationError3(context, error) {
24775
+ function logInstrumentationError4(context, error) {
24125
24776
  debugLogger.error(`Error processing ${context}:`, error);
24126
24777
  }
24127
24778
  function cleanMetrics2(metrics) {
@@ -25045,13 +25696,45 @@ var GoogleGenAIPlugin = class extends BasePlugin {
25045
25696
  subscribeToEmbedContentChannel() {
25046
25697
  const tracingChannel = googleGenAIChannels.embedContent.tracingChannel();
25047
25698
  const states = /* @__PURE__ */ new WeakMap();
25699
+ const embeddingSpans = /* @__PURE__ */ new WeakSet();
25700
+ this.unsubscribers.push(
25701
+ googleGenAIChannels.httpResponseJson.intercept(
25702
+ (target, thisArg, args) => {
25703
+ const span = currentSpan();
25704
+ const result = Reflect.apply(target, thisArg, args);
25705
+ if (embeddingSpans.has(span)) {
25706
+ void Promise.resolve(result).then(
25707
+ (response) => {
25708
+ try {
25709
+ const metrics = cleanMetrics3(
25710
+ extractEmbedContentMetrics(response)
25711
+ );
25712
+ if (embeddingSpans.has(span) && Object.keys(metrics).length > 0) {
25713
+ span.log({ metrics });
25714
+ }
25715
+ } catch (error) {
25716
+ debugLogger.error(
25717
+ "Error reading Google GenAI embedding usage:",
25718
+ error
25719
+ );
25720
+ }
25721
+ },
25722
+ () => {
25723
+ }
25724
+ // The embedding channel handles the original rejection.
25725
+ );
25726
+ }
25727
+ return result;
25728
+ }
25729
+ )
25730
+ );
25048
25731
  const unbindCurrentSpanStore = bindCurrentSpanStoreToStart2(
25049
25732
  tracingChannel,
25050
25733
  states,
25051
25734
  (event) => {
25052
25735
  const params = event.arguments[0];
25053
25736
  const input = serializeEmbedContentInput(params);
25054
- const metadata = extractEmbedContentMetadata(params);
25737
+ const metadata = { provider: "google", model: params.model };
25055
25738
  const span = startSpan(
25056
25739
  withSpanInstrumentationName(
25057
25740
  {
@@ -25064,6 +25747,7 @@ var GoogleGenAIPlugin = class extends BasePlugin {
25064
25747
  INSTRUMENTATION_NAMES.GOOGLE_GENAI
25065
25748
  )
25066
25749
  );
25750
+ embeddingSpans.add(span);
25067
25751
  return {
25068
25752
  span,
25069
25753
  startTime: getCurrentUnixTimestamp()
@@ -25075,7 +25759,7 @@ var GoogleGenAIPlugin = class extends BasePlugin {
25075
25759
  ensureSpanState(states, event, () => {
25076
25760
  const params = event.arguments[0];
25077
25761
  const input = serializeEmbedContentInput(params);
25078
- const metadata = extractEmbedContentMetadata(params);
25762
+ const metadata = { provider: "google", model: params.model };
25079
25763
  const span = startSpan(
25080
25764
  withSpanInstrumentationName(
25081
25765
  {
@@ -25088,6 +25772,7 @@ var GoogleGenAIPlugin = class extends BasePlugin {
25088
25772
  INSTRUMENTATION_NAMES.GOOGLE_GENAI
25089
25773
  )
25090
25774
  );
25775
+ embeddingSpans.add(span);
25091
25776
  return {
25092
25777
  span,
25093
25778
  startTime: getCurrentUnixTimestamp()
@@ -25100,20 +25785,28 @@ var GoogleGenAIPlugin = class extends BasePlugin {
25100
25785
  return;
25101
25786
  }
25102
25787
  try {
25103
- const output = summarizeEmbedContentOutput(event.result);
25104
25788
  spanState.span.log({
25105
- ...output ? { output } : {},
25789
+ output: summarizeEmbedContentOutput(event.result),
25106
25790
  metrics: cleanMetrics3(
25107
25791
  extractEmbedContentMetrics(event.result, spanState.startTime)
25108
25792
  )
25109
25793
  });
25110
25794
  } finally {
25795
+ embeddingSpans.delete(spanState.span);
25111
25796
  spanState.span.end();
25112
25797
  states.delete(event);
25113
25798
  }
25114
25799
  },
25115
25800
  error: (event) => {
25116
- logErrorAndEndSpan(states, event);
25801
+ const spanState = states.get(event);
25802
+ if (!spanState) return;
25803
+ try {
25804
+ spanState.span.log({ error: event.error, output: { count: 0 } });
25805
+ } finally {
25806
+ embeddingSpans.delete(spanState.span);
25807
+ spanState.span.end();
25808
+ states.delete(event);
25809
+ }
25117
25810
  }
25118
25811
  };
25119
25812
  tracingChannel.subscribe(handlers);
@@ -25348,15 +26041,53 @@ function serializeGenerateContentInput(params) {
25348
26041
  return input;
25349
26042
  }
25350
26043
  function serializeEmbedContentInput(params) {
26044
+ let contents = Array.isArray(params.contents) ? params.contents : [params.contents];
26045
+ if (params.model.includes("gemini-embedding-2") && contents.length > 0 && contents.every(
26046
+ (content) => typeof content === "string" || !Array.isArray(content) && !("parts" in content)
26047
+ )) {
26048
+ contents = [contents];
26049
+ }
25351
26050
  const input = {
25352
- model: params.model,
25353
- contents: serializeContentCollection(params.contents)
26051
+ inputs: contents.map((content) => {
26052
+ const parts = typeof content === "string" ? [content] : Array.isArray(content) ? content : "parts" in content ? content.parts : [content];
26053
+ const normalized = parts.flatMap((part) => {
26054
+ if (typeof part === "string") return [{ type: "text", text: part }];
26055
+ if (part.text !== void 0) return [{ type: "text", text: part.text }];
26056
+ const media = part.inlineData ?? part.fileData;
26057
+ if (!media) return [];
26058
+ const data = "data" in media ? `data:${media.mimeType};base64,${typeof media.data === "string" ? media.data : uint8ArrayToBase64(media.data)}` : media.fileUri;
26059
+ return media.mimeType?.startsWith("image/") ? [{ type: "image_url", image_url: { url: data } }] : [
26060
+ {
26061
+ type: "file",
26062
+ file: {
26063
+ file_data: data,
26064
+ ..."displayName" in media && media.displayName ? { filename: media.displayName } : {}
26065
+ }
26066
+ }
26067
+ ];
26068
+ });
26069
+ return {
26070
+ content: normalized.length === 1 && normalized[0].type === "text" ? normalized[0].text : normalized
26071
+ };
26072
+ }),
26073
+ ...params.config?.outputDimensionality !== void 0 ? { output_dimensions: params.config.outputDimensionality } : {}
25354
26074
  };
25355
- const config = params.config ? tryToDict(params.config) : null;
25356
- if (config) {
25357
- input.config = config;
26075
+ try {
26076
+ const processed = processInputAttachments(input);
26077
+ const hasInlineMedia = processed.inputs.some(
26078
+ ({ content }) => Array.isArray(content) && content.some((part) => {
26079
+ const data = part.type === "image_url" ? part.image_url.url : part.type === "file" ? part.file.file_data : void 0;
26080
+ return typeof data === "string" && data.startsWith("data:");
26081
+ })
26082
+ );
26083
+ return hasInlineMedia ? input : processed;
26084
+ } catch (error) {
26085
+ debugLogger.error(
26086
+ "Error processing Google GenAI embedding attachments:",
26087
+ error
26088
+ );
26089
+ return input;
25358
26090
  }
25359
- return input;
25360
26091
  }
25361
26092
  function serializeInteractionInput(params) {
25362
26093
  const input = {
@@ -25544,19 +26275,6 @@ function extractGenerateContentMetadata(params) {
25544
26275
  }
25545
26276
  return metadata;
25546
26277
  }
25547
- function extractEmbedContentMetadata(params) {
25548
- const metadata = {};
25549
- if (params.model) {
25550
- metadata.model = params.model;
25551
- }
25552
- const config = params.config ? tryToDict(params.config) : null;
25553
- if (config) {
25554
- Object.keys(config).forEach((key) => {
25555
- metadata[key] = config[key];
25556
- });
25557
- }
25558
- return metadata;
25559
- }
25560
26278
  function extractGenerateContentMetrics(response, startTime) {
25561
26279
  const metrics = {};
25562
26280
  if (startTime !== void 0) {
@@ -25576,15 +26294,23 @@ function extractEmbedContentMetrics(response, startTime) {
25576
26294
  const end = getCurrentUnixTimestamp();
25577
26295
  metrics.start = startTime;
25578
26296
  metrics.end = end;
25579
- metrics.duration = end - startTime;
25580
- }
25581
- if (response?.usageMetadata) {
25582
- populateUsageMetrics(metrics, response.usageMetadata);
25583
26297
  }
25584
26298
  const embeddingTokenCount = extractEmbedPromptTokenCount(response);
25585
26299
  if (embeddingTokenCount !== void 0) {
25586
26300
  metrics.prompt_tokens = embeddingTokenCount;
25587
- metrics.tokens = embeddingTokenCount;
26301
+ }
26302
+ const totalTokens = response?.usageMetadata?.totalTokenCount ?? embeddingTokenCount;
26303
+ if (totalTokens !== void 0) {
26304
+ metrics.tokens = totalTokens;
26305
+ }
26306
+ const audioTokens = (response?.usageMetadata?.promptTokenDetails ?? response?.usageMetadata?.promptTokensDetails)?.filter(
26307
+ (detail) => detail.modality === "AUDIO" && detail.tokenCount !== void 0
26308
+ );
26309
+ if (audioTokens?.length) {
26310
+ metrics.prompt_audio_tokens = audioTokens.reduce(
26311
+ (sum, detail) => sum + (detail.tokenCount ?? 0),
26312
+ 0
26313
+ );
25588
26314
  }
25589
26315
  return metrics;
25590
26316
  }
@@ -25623,41 +26349,25 @@ function extractEmbedPromptTokenCount(response) {
25623
26349
  if (typeof usagePromptTokens === "number" && Number.isFinite(usagePromptTokens)) {
25624
26350
  return usagePromptTokens;
25625
26351
  }
25626
- const usageTotalTokens = response.usageMetadata?.totalTokenCount;
25627
- if (typeof usageTotalTokens === "number" && Number.isFinite(usageTotalTokens)) {
25628
- return usageTotalTokens;
25629
- }
25630
26352
  const embeddings = Array.isArray(response.embeddings) ? response.embeddings : response.embedding ? [response.embedding] : [];
25631
26353
  if (embeddings.length === 0) {
25632
26354
  return void 0;
25633
26355
  }
25634
26356
  let total = 0;
25635
- let sawAny = false;
25636
26357
  for (const embedding of embeddings) {
25637
26358
  const embeddingStats = tryToDict(tryToDict(embedding)?.statistics);
25638
26359
  const tokenCount2 = embeddingStats?.tokenCount;
25639
26360
  if (typeof tokenCount2 === "number" && Number.isFinite(tokenCount2)) {
25640
26361
  total += tokenCount2;
25641
- sawAny = true;
26362
+ } else {
26363
+ return void 0;
25642
26364
  }
25643
26365
  }
25644
- return sawAny ? total : void 0;
26366
+ return total;
25645
26367
  }
25646
26368
  function summarizeEmbedContentOutput(response) {
25647
- if (!response) {
25648
- return void 0;
25649
- }
25650
- const embeddings = Array.isArray(response.embeddings) ? response.embeddings : response.embedding ? [response.embedding] : [];
25651
- if (embeddings.length === 0) {
25652
- return void 0;
25653
- }
25654
- const firstValues = embeddings[0]?.values;
25655
- if (!Array.isArray(firstValues)) {
25656
- return void 0;
25657
- }
25658
26369
  return {
25659
- embedding_count: embeddings.length,
25660
- embedding_length: firstValues.length
26370
+ count: Array.isArray(response?.embeddings) ? response.embeddings.length : response?.embedding ? 1 : 0
25661
26371
  };
25662
26372
  }
25663
26373
  function populateUsageMetrics(metrics, usage) {
@@ -29108,6 +29818,363 @@ function aggregateMistralStreamChunks(chunks) {
29108
29818
  };
29109
29819
  }
29110
29820
 
29821
+ // src/instrumentation/plugins/langgraph-sdk-plugin.ts
29822
+ var LangGraphSDKPlugin = class extends BasePlugin {
29823
+ onEnable() {
29824
+ this.unsubscribers.push(
29825
+ langGraphSDKChannels.wait.intercept(
29826
+ (target, self, args) => instrumentRun("wait", args, () => Reflect.apply(target, self, args))
29827
+ ),
29828
+ langGraphSDKChannels.stream.intercept(
29829
+ (target, self, args) => instrumentRun("stream", args, () => Reflect.apply(target, self, args))
29830
+ )
29831
+ );
29832
+ }
29833
+ onDisable() {
29834
+ this.unsubscribers = unsubscribeAll(this.unsubscribers);
29835
+ }
29836
+ };
29837
+ function normalizeMessage(value) {
29838
+ if (!isObject(value)) return value;
29839
+ 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);
29840
+ if (typeof role !== "string") return value;
29841
+ const message = {
29842
+ role,
29843
+ content: value.content ?? ""
29844
+ };
29845
+ for (const key of ["name", "tool_call_id", "refusal"]) {
29846
+ if (value[key] !== void 0) message[key] = value[key];
29847
+ }
29848
+ const additional = isObject(value.additional_kwargs) ? value.additional_kwargs : {};
29849
+ const toolCalls = Array.isArray(value.tool_calls) && value.tool_calls.length ? value.tool_calls : additional.tool_calls;
29850
+ if (Array.isArray(toolCalls) && toolCalls.length > 0) {
29851
+ message.tool_calls = toolCalls.map((call) => {
29852
+ if (!isObject(call)) return call;
29853
+ if (isObject(call.function)) return call;
29854
+ return {
29855
+ id: call.id,
29856
+ type: "function",
29857
+ function: {
29858
+ name: call.name,
29859
+ arguments: typeof call.args === "string" ? call.args : JSON.stringify(call.args ?? {})
29860
+ }
29861
+ };
29862
+ });
29863
+ }
29864
+ if (Array.isArray(value.invalid_tool_calls) && value.invalid_tool_calls.length > 0)
29865
+ message.invalid_tool_calls = value.invalid_tool_calls;
29866
+ if (message.refusal === void 0 && additional.refusal !== void 0)
29867
+ message.refusal = additional.refusal;
29868
+ return message;
29869
+ }
29870
+ function normalizeRunError(value) {
29871
+ let name;
29872
+ let message;
29873
+ if (value instanceof Error) {
29874
+ name = value.name;
29875
+ message = value.message;
29876
+ } else if (isObject(value) && typeof value.error === "string" && typeof value.message === "string") {
29877
+ name = value.error;
29878
+ message = value.message;
29879
+ } else {
29880
+ return value;
29881
+ }
29882
+ for (let depth = 0; depth < 3; depth++) {
29883
+ try {
29884
+ const nested = JSON.parse(
29885
+ message.startsWith(`${name}: `) ? message.slice(name.length + 2) : message
29886
+ );
29887
+ if (!isObject(nested) || typeof nested.error !== "string" || typeof nested.message !== "string")
29888
+ break;
29889
+ name = nested.error;
29890
+ message = nested.message;
29891
+ } catch {
29892
+ break;
29893
+ }
29894
+ }
29895
+ if (value instanceof Error && name === value.name && message === value.message)
29896
+ return value;
29897
+ return Object.assign(new Error(message), { name });
29898
+ }
29899
+ function normalizeState(value) {
29900
+ if (!isObject(value)) return value;
29901
+ return Object.fromEntries(
29902
+ Object.entries(value).map(([key, field]) => {
29903
+ if (key === "messages" && Array.isArray(field))
29904
+ return [key, field.map(normalizeMessage)];
29905
+ if (key === "__error__") {
29906
+ const error = normalizeRunError(field);
29907
+ if (error instanceof Error)
29908
+ return [key, { error: error.name, message: error.message }];
29909
+ }
29910
+ return [key, field];
29911
+ })
29912
+ );
29913
+ }
29914
+ function normalizeRunOutput(value, input) {
29915
+ if (!isObject(value)) return value;
29916
+ if (Array.isArray(value.messages)) {
29917
+ if (value.__interrupt__ !== void 0 || value.__error__ !== void 0)
29918
+ return void 0;
29919
+ const inputMessages = isObject(input) && Array.isArray(input.messages) ? input.messages : [];
29920
+ let inputPrefixLength = 0;
29921
+ while (inputPrefixLength < inputMessages.length) {
29922
+ const previous = inputMessages[inputPrefixLength];
29923
+ const message = value.messages[inputPrefixLength];
29924
+ 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)))
29925
+ break;
29926
+ inputPrefixLength++;
29927
+ }
29928
+ for (let index = value.messages.length - 1; index >= inputPrefixLength; index--) {
29929
+ const message = value.messages[index];
29930
+ const normalized = normalizeMessage(message);
29931
+ if (!isObject(normalized)) continue;
29932
+ if (normalized.role === "user") return void 0;
29933
+ if (normalized.role !== "assistant") continue;
29934
+ if (inputMessages.some((previous) => {
29935
+ if (!isObject(previous) || !isObject(message)) return false;
29936
+ return previous.id !== void 0 && previous.id === message.id && JSON.stringify(normalizeMessage(previous)) === JSON.stringify(normalized);
29937
+ }))
29938
+ continue;
29939
+ return normalized;
29940
+ }
29941
+ return void 0;
29942
+ }
29943
+ const result = Object.fromEntries(
29944
+ Object.entries(value).filter(
29945
+ ([key]) => key !== "__interrupt__" && key !== "__error__"
29946
+ )
29947
+ );
29948
+ return !Object.keys(result).length && (value.__interrupt__ !== void 0 || value.__error__ !== void 0) ? void 0 : result;
29949
+ }
29950
+ function instrumentRun(operation, [threadId, assistantId, options], invoke) {
29951
+ if (isAutoInstrumentationSuppressed()) return invoke();
29952
+ const start = getCurrentUnixTimestamp();
29953
+ let span;
29954
+ try {
29955
+ const metadata = {
29956
+ "langgraph.thread_id": threadId,
29957
+ "langgraph.assistant_id": assistantId
29958
+ };
29959
+ for (const key of [
29960
+ "streamMode",
29961
+ "streamSubgraphs",
29962
+ "interruptBefore",
29963
+ "interruptAfter",
29964
+ "multitaskStrategy",
29965
+ "durability"
29966
+ ]) {
29967
+ if (options?.[key] !== void 0) metadata[key] = options[key];
29968
+ }
29969
+ span = startSpan(
29970
+ withSpanInstrumentationName(
29971
+ {
29972
+ name: `langgraph.runs.${operation}`,
29973
+ spanAttributes: { type: "task" /* TASK */ },
29974
+ event: {
29975
+ input: options?.command === void 0 ? normalizeState(options?.input) : {
29976
+ input: normalizeState(options.input),
29977
+ command: options.command
29978
+ },
29979
+ metadata
29980
+ }
29981
+ },
29982
+ INSTRUMENTATION_NAMES.LANGGRAPH_SDK
29983
+ )
29984
+ );
29985
+ } catch (error) {
29986
+ debugLogger.error("Error starting LangGraph SDK span:", error);
29987
+ return invoke();
29988
+ }
29989
+ let ended = false;
29990
+ let output;
29991
+ let streamError;
29992
+ let firstToken;
29993
+ const updates = [];
29994
+ const usageByMessage = /* @__PURE__ */ new Map();
29995
+ const captureUsage = (id, usage) => {
29996
+ if (!isObject(usage)) return;
29997
+ const metrics = {};
29998
+ for (const [source, destination] of [
29999
+ ["input_tokens", "prompt_tokens"],
30000
+ ["output_tokens", "completion_tokens"],
30001
+ ["total_tokens", "tokens"]
30002
+ ]) {
30003
+ const value = usage[source];
30004
+ if (typeof value === "number" && Number.isFinite(value) && value >= 0)
30005
+ metrics[destination] = value;
30006
+ }
30007
+ if (metrics.tokens === void 0 && metrics.prompt_tokens !== void 0 && metrics.completion_tokens !== void 0)
30008
+ metrics.tokens = metrics.prompt_tokens + metrics.completion_tokens;
30009
+ usageByMessage.set(id, { ...usageByMessage.get(id), ...metrics });
30010
+ };
30011
+ const messages = /* @__PURE__ */ new Map();
30012
+ const messageSnapshots = /* @__PURE__ */ new Map();
30013
+ const finish = (error) => {
30014
+ if (ended) return;
30015
+ ended = true;
30016
+ try {
30017
+ const metrics = {};
30018
+ for (const usage of usageByMessage.values()) {
30019
+ for (const [key, value] of Object.entries(usage))
30020
+ metrics[key] = (metrics[key] ?? 0) + value;
30021
+ }
30022
+ if (firstToken !== void 0)
30023
+ metrics.time_to_first_token = firstToken - start;
30024
+ const finalMessages = [
30025
+ ...new Map([...messages, ...messageSnapshots]).values()
30026
+ ];
30027
+ let loggedOutput = normalizeRunOutput(output, options?.input);
30028
+ if (loggedOutput === void 0 && finalMessages.length)
30029
+ loggedOutput = normalizeRunOutput(
30030
+ { messages: finalMessages },
30031
+ void 0
30032
+ );
30033
+ if (output === void 0 && !finalMessages.length && updates.length) {
30034
+ const results = updates.map((update) => normalizeRunOutput(update, options?.input)).filter((update) => update !== void 0);
30035
+ if (results.length) loggedOutput = { updates: results };
30036
+ }
30037
+ const interrupted = [output, ...updates].find(
30038
+ (state) => isObject(state) && state.__interrupt__ !== void 0
30039
+ );
30040
+ span.log({
30041
+ ...loggedOutput !== void 0 ? { output: loggedOutput } : {},
30042
+ ...isObject(interrupted) ? { metadata: { "langgraph.interrupts": interrupted.__interrupt__ } } : {},
30043
+ ...error !== void 0 || streamError !== void 0 ? { error: normalizeRunError(error ?? streamError) } : {},
30044
+ metrics
30045
+ });
30046
+ } catch (error2) {
30047
+ debugLogger.error("Error logging LangGraph SDK span:", error2);
30048
+ }
30049
+ try {
30050
+ span.end();
30051
+ } catch (error2) {
30052
+ debugLogger.error("Error ending LangGraph SDK span:", error2);
30053
+ }
30054
+ };
30055
+ const observeMessages = (value, streaming) => {
30056
+ if (!isObject(value) || !Array.isArray(value.messages)) return;
30057
+ const inputMessages = isObject(options?.input) && Array.isArray(options.input.messages) ? options.input.messages : [];
30058
+ for (const message of value.messages) {
30059
+ if (!isObject(message) || message.type !== "ai" && message.role !== "assistant")
30060
+ continue;
30061
+ if (message.id !== void 0 && inputMessages.some(
30062
+ (input) => isObject(input) && input.id === message.id
30063
+ ))
30064
+ continue;
30065
+ captureUsage(
30066
+ typeof message.id === "string" ? message.id : "message",
30067
+ message.usage_metadata
30068
+ );
30069
+ if (streaming && (typeof message.content === "string" ? message.content.length > 0 : Array.isArray(message.content) && message.content.some(
30070
+ (part) => isObject(part) && typeof part.text === "string" && part.text.length > 0
30071
+ )))
30072
+ firstToken ??= getCurrentUnixTimestamp();
30073
+ }
30074
+ };
30075
+ const onChunk = ({ event, data }) => {
30076
+ if (ended) return;
30077
+ if (event === "metadata" && isObject(data)) {
30078
+ if (typeof data.run_id === "string")
30079
+ span.log({ metadata: { "langgraph.run_id": data.run_id } });
30080
+ } else if (event === "error") {
30081
+ streamError = normalizeRunError(data);
30082
+ } else if (event === "values") {
30083
+ output = data;
30084
+ observeMessages(data, true);
30085
+ } else if (event === "updates") {
30086
+ if (isObject(data)) {
30087
+ const stateUpdates = [];
30088
+ for (const [node, update] of Object.entries(data)) {
30089
+ observeMessages(update, true);
30090
+ if (isObject(update) && Array.isArray(update.messages)) {
30091
+ for (const message of update.messages) {
30092
+ if (isObject(message))
30093
+ messageSnapshots.set(
30094
+ typeof message.id === "string" ? message.id : `update-${messageSnapshots.size}`,
30095
+ message
30096
+ );
30097
+ }
30098
+ const state = Object.fromEntries(
30099
+ Object.entries(update).filter(([key]) => key !== "messages")
30100
+ );
30101
+ if (Object.keys(state).length) stateUpdates.push([node, state]);
30102
+ } else {
30103
+ stateUpdates.push([node, update]);
30104
+ }
30105
+ }
30106
+ if (stateUpdates.length) updates.push(Object.fromEntries(stateUpdates));
30107
+ } else {
30108
+ updates.push(data);
30109
+ }
30110
+ } else if ((event === "messages" || event === "messages/partial" || event === "messages/complete") && Array.isArray(data)) {
30111
+ const parts = event === "messages" ? [data[0]] : data;
30112
+ for (const part of parts) {
30113
+ if (!isObject(part)) continue;
30114
+ const id = typeof part.id === "string" ? part.id : "message";
30115
+ captureUsage(id, part.usage_metadata);
30116
+ const previous = messages.get(id);
30117
+ messages.set(
30118
+ id,
30119
+ event === "messages" && previous && typeof part.content === "string" && typeof previous.content === "string" ? { ...part, content: previous.content + part.content } : part
30120
+ );
30121
+ if (typeof part.content === "string" && part.content.length > 0)
30122
+ firstToken ??= getCurrentUnixTimestamp();
30123
+ }
30124
+ }
30125
+ };
30126
+ let result;
30127
+ try {
30128
+ result = withCurrent(
30129
+ span,
30130
+ () => runWithAutoInstrumentationSuppressed(invoke)
30131
+ );
30132
+ } catch (error) {
30133
+ finish(error);
30134
+ throw error;
30135
+ }
30136
+ if (operation === "stream") {
30137
+ try {
30138
+ patchStreamIfNeeded(result, {
30139
+ shouldCollect: (chunk) => {
30140
+ try {
30141
+ onChunk(chunk);
30142
+ } catch (error) {
30143
+ debugLogger.error(
30144
+ "Error processing LangGraph stream event:",
30145
+ error
30146
+ );
30147
+ }
30148
+ return false;
30149
+ },
30150
+ aroundNext: (next) => withCurrent(span, () => runWithAutoInstrumentationSuppressed(next)),
30151
+ onComplete: () => finish(),
30152
+ onCancel: () => finish(),
30153
+ onError: (error) => finish(error)
30154
+ });
30155
+ } catch (error) {
30156
+ debugLogger.error("Error observing LangGraph stream:", error);
30157
+ finish();
30158
+ }
30159
+ } else {
30160
+ void Promise.resolve(result).then(
30161
+ (value) => {
30162
+ try {
30163
+ output = value;
30164
+ observeMessages(value, false);
30165
+ if (isObject(value) && isObject(value.__error__))
30166
+ streamError = normalizeRunError(value.__error__);
30167
+ finish();
30168
+ } catch (error) {
30169
+ finish(error);
30170
+ }
30171
+ },
30172
+ (error) => finish(error)
30173
+ );
30174
+ }
30175
+ return result;
30176
+ }
30177
+
29111
30178
  // src/instrumentation/plugins/ollama-plugin.ts
29112
30179
  var OllamaPlugin = class extends BasePlugin {
29113
30180
  onEnable() {
@@ -29297,7 +30364,7 @@ function normalizeTextAndImages(content, images) {
29297
30364
  ...unrecognizedImages.length > 0 ? { unrecognizedImages } : {}
29298
30365
  };
29299
30366
  }
29300
- function normalizeMessage(message, toolCallId, syntheticToolCallIdOffset = 0) {
30367
+ function normalizeMessage2(message, toolCallId, syntheticToolCallIdOffset = 0) {
29301
30368
  if (typeof message.role !== "string") {
29302
30369
  return void 0;
29303
30370
  }
@@ -29343,7 +30410,7 @@ function normalizeMessages(messages) {
29343
30410
  toolCallId = pendingToolCallIds.get(toolName)?.shift();
29344
30411
  }
29345
30412
  }
29346
- const normalized = normalizeMessage(
30413
+ const normalized = normalizeMessage2(
29347
30414
  ollamaMessage,
29348
30415
  toolCallId,
29349
30416
  syntheticToolCallIdOffset
@@ -29462,7 +30529,7 @@ function extractOllamaChatOutput(result, syntheticToolCallIdOffset = 0) {
29462
30529
  if (!isObject(result) || !isObject(result.message)) {
29463
30530
  return void 0;
29464
30531
  }
29465
- const message = normalizeMessage(
30532
+ const message = normalizeMessage2(
29466
30533
  result.message,
29467
30534
  void 0,
29468
30535
  syntheticToolCallIdOffset
@@ -32053,14 +33120,14 @@ function extractActionSpanMetadata(args) {
32053
33120
  const options = extractRunInNewSpanOptions(args);
32054
33121
  const labels = isObject(options?.labels) ? options.labels : void 0;
32055
33122
  const metadata = isObject(options?.metadata) ? options.metadata : void 0;
32056
- const actionType = stringValue(labels?.["genkit:metadata:subtype"]);
32057
- const name = stringValue(metadata?.name);
33123
+ const actionType = stringValue2(labels?.["genkit:metadata:subtype"]);
33124
+ const name = stringValue2(metadata?.name);
32058
33125
  if (!actionType || !name) {
32059
33126
  return void 0;
32060
33127
  }
32061
33128
  return {
32062
33129
  actionType,
32063
- key: stringValue(labels?.["genkit:key"]),
33130
+ key: stringValue2(labels?.["genkit:key"]),
32064
33131
  name
32065
33132
  };
32066
33133
  }
@@ -32170,7 +33237,7 @@ function pickNumberMetrics(values) {
32170
33237
  })
32171
33238
  );
32172
33239
  }
32173
- function stringValue(value) {
33240
+ function stringValue2(value) {
32174
33241
  return typeof value === "string" ? value : void 0;
32175
33242
  }
32176
33243
 
@@ -32873,10 +33940,10 @@ var LangSmithPlugin = class extends BasePlugin {
32873
33940
  const creates = ownValue(batch, "runCreates");
32874
33941
  if (Array.isArray(creates)) {
32875
33942
  const parentFirst = [...creates].sort((left, right) => {
32876
- const leftId = stringValue2(ownValue(left, "id"));
32877
- const rightId = stringValue2(ownValue(right, "id"));
32878
- const leftParent = stringValue2(ownValue(left, "parent_run_id"));
32879
- const rightParent = stringValue2(ownValue(right, "parent_run_id"));
33943
+ const leftId = stringValue3(ownValue(left, "id"));
33944
+ const rightId = stringValue3(ownValue(right, "id"));
33945
+ const leftParent = stringValue3(ownValue(left, "parent_run_id"));
33946
+ const rightParent = stringValue3(ownValue(right, "parent_run_id"));
32880
33947
  if (leftParent && leftParent === rightId) {
32881
33948
  return 1;
32882
33949
  }
@@ -32895,13 +33962,13 @@ var LangSmithPlugin = class extends BasePlugin {
32895
33962
  if (Array.isArray(updates)) {
32896
33963
  for (const run of updates) {
32897
33964
  this.containLifecycleFailure("batchIngestRuns update", () => {
32898
- this.processUpdate(stringValue2(ownValue(run, "id")) ?? "", run);
33965
+ this.processUpdate(stringValue3(ownValue(run, "id")) ?? "", run);
32899
33966
  });
32900
33967
  }
32901
33968
  }
32902
33969
  }
32903
33970
  processCreate(run) {
32904
- const id = stringValue2(ownValue(run, "id"));
33971
+ const id = stringValue3(ownValue(run, "id"));
32905
33972
  if (!id || this.completedRuns.get(id)) {
32906
33973
  return;
32907
33974
  }
@@ -32934,7 +34001,7 @@ var LangSmithPlugin = class extends BasePlugin {
32934
34001
  this.endIfComplete(id, activeRun, run);
32935
34002
  }
32936
34003
  processUpdate(explicitId, run) {
32937
- const id = stringValue2(explicitId) ?? stringValue2(ownValue(run, "id"));
34004
+ const id = stringValue3(explicitId) ?? stringValue3(ownValue(run, "id"));
32938
34005
  if (!id || this.completedRuns.get(id)) {
32939
34006
  return;
32940
34007
  }
@@ -32957,13 +34024,13 @@ var LangSmithPlugin = class extends BasePlugin {
32957
34024
  this.endIfComplete(id, active, active.run);
32958
34025
  }
32959
34026
  startRunSpan(id, run) {
32960
- const traceId = stringValue2(ownValue(run, "trace_id")) ?? id;
32961
- const parentId = stringValue2(ownValue(run, "parent_run_id")) ?? stringValue2(ownValue(ownValue(run, "parent_run"), "id"));
34027
+ const traceId = stringValue3(ownValue(run, "trace_id")) ?? id;
34028
+ const parentId = stringValue3(ownValue(run, "parent_run_id")) ?? stringValue3(ownValue(ownValue(run, "parent_run"), "id"));
32962
34029
  const startTime = timestampSeconds(ownValue(run, "start_time"));
32963
34030
  return startSpan(
32964
34031
  withSpanInstrumentationName(
32965
34032
  {
32966
- name: stringValue2(ownValue(run, "name")) ?? "LangSmith run",
34033
+ name: stringValue3(ownValue(run, "name")) ?? "LangSmith run",
32967
34034
  spanId: id,
32968
34035
  parentSpanIds: {
32969
34036
  parentSpanIds: parentId ? [parentId] : [],
@@ -33055,7 +34122,7 @@ function mergeRuns(previous, current) {
33055
34122
  function isRecord2(value) {
33056
34123
  return typeof value === "object" && value !== null && !Array.isArray(value);
33057
34124
  }
33058
- function stringValue2(value) {
34125
+ function stringValue3(value) {
33059
34126
  return typeof value === "string" && value.length > 0 ? value : void 0;
33060
34127
  }
33061
34128
  function timestampSeconds(value) {
@@ -33073,7 +34140,7 @@ function timestampSeconds(value) {
33073
34140
  return void 0;
33074
34141
  }
33075
34142
  function dottedOrderDepth(run) {
33076
- const dottedOrder = stringValue2(ownValue(run, "dotted_order"));
34143
+ const dottedOrder = stringValue3(ownValue(run, "dotted_order"));
33077
34144
  return dottedOrder ? dottedOrder.split(".").length : Number.MAX_SAFE_INTEGER;
33078
34145
  }
33079
34146
  function mapRunType(runType) {
@@ -33266,7 +34333,7 @@ var PiCodingAgentPlugin = class extends BasePlugin {
33266
34333
  }
33267
34334
  );
33268
34335
  } catch (error) {
33269
- logInstrumentationError4("Pi Coding Agent prompt start", error);
34336
+ logInstrumentationError5("Pi Coding Agent prompt start", error);
33270
34337
  }
33271
34338
  if (!state) {
33272
34339
  return runWithAutoInstrumentationSuppressed(invokeTarget);
@@ -33399,12 +34466,12 @@ function installPiAgentInstrumentation(agent) {
33399
34466
  () => handlePiAgentEvent(state, event)
33400
34467
  );
33401
34468
  } catch (error) {
33402
- logInstrumentationError4("Pi Coding Agent event", error);
34469
+ logInstrumentationError5("Pi Coding Agent event", error);
33403
34470
  }
33404
34471
  });
33405
34472
  piAgentEventSubscriptions.add(agent);
33406
34473
  } catch (error) {
33407
- logInstrumentationError4("Pi Coding Agent event subscription", error);
34474
+ logInstrumentationError5("Pi Coding Agent event subscription", error);
33408
34475
  }
33409
34476
  }
33410
34477
  function makeInstrumentedStreamFunction(agent, originalStreamFunction, property) {
@@ -33454,7 +34521,7 @@ function wrapPiToolExecutors(tools) {
33454
34521
  });
33455
34522
  tool.execute = wrappedExecute;
33456
34523
  } catch (error) {
33457
- logInstrumentationError4("Pi Coding Agent tool wrapping", error);
34524
+ logInstrumentationError5("Pi Coding Agent tool wrapping", error);
33458
34525
  }
33459
34526
  }
33460
34527
  }
@@ -33533,7 +34600,7 @@ function patchAssistantMessageStream(stream, promptState, llmState) {
33533
34600
  try {
33534
34601
  await iterator.return();
33535
34602
  } catch (cleanupError) {
33536
- logInstrumentationError4(
34603
+ logInstrumentationError5(
33537
34604
  "Pi Coding Agent stream cleanup",
33538
34605
  cleanupError
33539
34606
  );
@@ -33698,7 +34765,7 @@ function finishPiPromptRun(state, error) {
33698
34765
  try {
33699
34766
  state.span.end();
33700
34767
  } catch (endError) {
33701
- logInstrumentationError4("Pi Coding Agent prompt end", endError);
34768
+ logInstrumentationError5("Pi Coding Agent prompt end", endError);
33702
34769
  }
33703
34770
  }
33704
34771
  }
@@ -34030,10 +35097,10 @@ function safeLog4(span, event) {
34030
35097
  try {
34031
35098
  span.log(event);
34032
35099
  } catch (error) {
34033
- logInstrumentationError4("Pi Coding Agent span log", error);
35100
+ logInstrumentationError5("Pi Coding Agent span log", error);
34034
35101
  }
34035
35102
  }
34036
- function logInstrumentationError4(context, error) {
35103
+ function logInstrumentationError5(context, error) {
34037
35104
  debugLogger.debug(`${context}:`, error);
34038
35105
  }
34039
35106
 
@@ -34251,7 +35318,7 @@ function handleAgentStreamEvent(state, event) {
34251
35318
  finalizeModelSpan(state, event);
34252
35319
  break;
34253
35320
  case "beforeToolCallEvent":
34254
- startToolSpan2(state, event);
35321
+ startToolSpan3(state, event);
34255
35322
  break;
34256
35323
  case "afterToolCallEvent":
34257
35324
  finalizeToolSpan(state, event);
@@ -34276,7 +35343,7 @@ function handleAgentStreamEvent(state, event) {
34276
35343
  break;
34277
35344
  }
34278
35345
  } catch (error) {
34279
- logInstrumentationError5("Strands Agent SDK event", error);
35346
+ logInstrumentationError6("Strands Agent SDK event", error);
34280
35347
  }
34281
35348
  }
34282
35349
  function handleMultiAgentStreamEvent(state, event, activeChildParents) {
@@ -34312,7 +35379,7 @@ function handleMultiAgentStreamEvent(state, event, activeChildParents) {
34312
35379
  break;
34313
35380
  }
34314
35381
  } catch (error) {
34315
- logInstrumentationError5("Strands Agent SDK multi-agent event", error);
35382
+ logInstrumentationError6("Strands Agent SDK multi-agent event", error);
34316
35383
  }
34317
35384
  }
34318
35385
  function buildModelSpanInput(event, attachmentCache) {
@@ -34391,7 +35458,7 @@ function finalizeModelSpan(state, event) {
34391
35458
  });
34392
35459
  modelState.span.end();
34393
35460
  }
34394
- function startToolSpan2(state, event) {
35461
+ function startToolSpan3(state, event) {
34395
35462
  const toolUse = event.toolUse;
34396
35463
  const key = toolKey2(toolUse);
34397
35464
  if (state.activeTools.has(key)) {
@@ -34671,7 +35738,7 @@ function getModelConfig(model) {
34671
35738
  try {
34672
35739
  return model.getConfig();
34673
35740
  } catch (error) {
34674
- logInstrumentationError5("Strands Agent SDK model config", error);
35741
+ logInstrumentationError6("Strands Agent SDK model config", error);
34675
35742
  return void 0;
34676
35743
  }
34677
35744
  }
@@ -34754,7 +35821,7 @@ function processStrandsInputAttachments(input, cache = createStrandsAttachmentCa
34754
35821
  try {
34755
35822
  return processStrandsInputNode(input, cache);
34756
35823
  } catch (error) {
34757
- logInstrumentationError5("Strands Agent SDK input attachments", error);
35824
+ logInstrumentationError6("Strands Agent SDK input attachments", error);
34758
35825
  return input;
34759
35826
  }
34760
35827
  }
@@ -34974,10 +36041,10 @@ function safeLog5(span, event) {
34974
36041
  try {
34975
36042
  span.log(event);
34976
36043
  } catch (error) {
34977
- logInstrumentationError5("Strands Agent SDK span log", error);
36044
+ logInstrumentationError6("Strands Agent SDK span log", error);
34978
36045
  }
34979
36046
  }
34980
- function logInstrumentationError5(context, error) {
36047
+ function logInstrumentationError6(context, error) {
34981
36048
  debugLogger.debug(`${context}:`, error);
34982
36049
  }
34983
36050
 
@@ -35361,10 +36428,10 @@ function observeAudioStream(value, observe, complete, cancel, span) {
35361
36428
  const getReader = value.getReader;
35362
36429
  value.getReader = function(...args) {
35363
36430
  const reader = Reflect.apply(getReader, this, args);
35364
- const read2 = reader.read;
36431
+ const read3 = reader.read;
35365
36432
  reader.read = function(...readArgs) {
35366
36433
  return Promise.resolve(
35367
- withCurrent(span, () => Reflect.apply(read2, this, readArgs))
36434
+ withCurrent(span, () => Reflect.apply(read3, this, readArgs))
35368
36435
  ).then(
35369
36436
  (result) => {
35370
36437
  if (result.value) safeObserve(result.value);
@@ -35841,14 +36908,14 @@ var CloudflareAIChatPlugin = class extends BasePlugin {
35841
36908
  const result = event.arguments[0];
35842
36909
  state = agent ? this.findResponseState(
35843
36910
  agent,
35844
- stringValue3(ownValue2(result, "requestId"))
36911
+ stringValue4(ownValue2(result, "requestId"))
35845
36912
  ) : void 0;
35846
36913
  if (!state) {
35847
36914
  return;
35848
36915
  }
35849
36916
  state.responseObserved = true;
35850
36917
  const output = serializeMessage(ownValue2(result, "message"));
35851
- const status = stringValue3(ownValue2(result, "status"));
36918
+ const status = stringValue4(ownValue2(result, "status"));
35852
36919
  const error = ownValue2(result, "error");
35853
36920
  const input = ownValue2(result, "continuation") === true ? state.input : serializeMessages(readProperty(agent, "messages"))?.filter(
35854
36921
  (message) => typeof output?.id !== "string" || message.id !== output.id
@@ -35895,7 +36962,7 @@ var CloudflareAIChatPlugin = class extends BasePlugin {
35895
36962
  }
35896
36963
  try {
35897
36964
  const agent = asObject(event.self);
35898
- const requestId = stringValue3(event.arguments[0]);
36965
+ const requestId = stringValue4(event.arguments[0]);
35899
36966
  const key = requestId ?? /* @__PURE__ */ Symbol("cloudflare-ai-chat-turn");
35900
36967
  const activeForAgent = agent ? this.getActiveTurns(agent) : void 0;
35901
36968
  const existing = activeForAgent?.get(key);
@@ -36064,7 +37131,7 @@ function ownValue2(value, key) {
36064
37131
  const descriptor = Object.getOwnPropertyDescriptor(object, key);
36065
37132
  return descriptor && "value" in descriptor ? descriptor.value : void 0;
36066
37133
  }
36067
- function stringValue3(value) {
37134
+ function stringValue4(value) {
36068
37135
  return typeof value === "string" ? value : void 0;
36069
37136
  }
36070
37137
  function serializeMessages(value) {
@@ -36170,7 +37237,7 @@ var CloudflareAgentsPlugin = class extends BasePlugin {
36170
37237
  );
36171
37238
  spans.set(event, span);
36172
37239
  } catch (error) {
36173
- logInstrumentationError6("start", error);
37240
+ logInstrumentationError7("start", error);
36174
37241
  }
36175
37242
  },
36176
37243
  asyncEnd: (event) => {
@@ -36190,7 +37257,7 @@ var CloudflareAgentsPlugin = class extends BasePlugin {
36190
37257
  }
36191
37258
  }
36192
37259
  } catch (error) {
36193
- logInstrumentationError6("completion", error);
37260
+ logInstrumentationError7("completion", error);
36194
37261
  } finally {
36195
37262
  safelyEndSpan(span);
36196
37263
  }
@@ -36204,7 +37271,7 @@ var CloudflareAgentsPlugin = class extends BasePlugin {
36204
37271
  try {
36205
37272
  span.log({ error: event.error });
36206
37273
  } catch (error) {
36207
- logInstrumentationError6("rejection", error);
37274
+ logInstrumentationError7("rejection", error);
36208
37275
  } finally {
36209
37276
  safelyEndSpan(span);
36210
37277
  }
@@ -36234,10 +37301,10 @@ function safelyEndSpan(span) {
36234
37301
  try {
36235
37302
  span.end();
36236
37303
  } catch (error) {
36237
- logInstrumentationError6("span end", error);
37304
+ logInstrumentationError7("span end", error);
36238
37305
  }
36239
37306
  }
36240
- function logInstrumentationError6(operation, error) {
37307
+ function logInstrumentationError7(operation, error) {
36241
37308
  debugLogger.error(
36242
37309
  `Failed to process Cloudflare Agents ${operation} instrumentation:`,
36243
37310
  error
@@ -36262,6 +37329,7 @@ var BraintrustPlugin = class extends BasePlugin {
36262
37329
  openRouterPlugin = null;
36263
37330
  openRouterAgentPlugin = null;
36264
37331
  mistralPlugin = null;
37332
+ langGraphSDKPlugin = null;
36265
37333
  ollamaPlugin = null;
36266
37334
  googleADKPlugin = null;
36267
37335
  coherePlugin = null;
@@ -36342,6 +37410,10 @@ var BraintrustPlugin = class extends BasePlugin {
36342
37410
  this.mistralPlugin = new MistralPlugin();
36343
37411
  this.mistralPlugin.enable();
36344
37412
  }
37413
+ if (integrations.langgraphSDK !== false) {
37414
+ this.langGraphSDKPlugin = new LangGraphSDKPlugin();
37415
+ this.langGraphSDKPlugin.enable();
37416
+ }
36345
37417
  if (integrations.ollama !== false) {
36346
37418
  this.ollamaPlugin = new OllamaPlugin();
36347
37419
  this.ollamaPlugin.enable();
@@ -36470,6 +37542,10 @@ var BraintrustPlugin = class extends BasePlugin {
36470
37542
  this.mistralPlugin.disable();
36471
37543
  this.mistralPlugin = null;
36472
37544
  }
37545
+ if (this.langGraphSDKPlugin) {
37546
+ this.langGraphSDKPlugin.disable();
37547
+ this.langGraphSDKPlugin = null;
37548
+ }
36473
37549
  if (this.ollamaPlugin) {
36474
37550
  this.ollamaPlugin.disable();
36475
37551
  this.ollamaPlugin = null;
@@ -37316,6 +38392,7 @@ export {
37316
38392
  IDGenerator,
37317
38393
  UUIDGenerator,
37318
38394
  OTELIDGenerator,
38395
+ resolveUseLegacyUuidIds,
37319
38396
  getIdGenerator,
37320
38397
  TRACEPARENT_HEADER,
37321
38398
  TRACESTATE_HEADER,
@@ -37404,6 +38481,7 @@ export {
37404
38481
  currentLogger,
37405
38482
  currentSpan,
37406
38483
  getSpanParentObject,
38484
+ _internalExportParentSynchronously,
37407
38485
  injectTraceContext,
37408
38486
  extractTraceContextFromHeaders,
37409
38487
  logError,