braintrust 3.31.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 (62) hide show
  1. package/README.md +0 -43
  2. package/dev/dist/index.d.mts +767 -0
  3. package/dev/dist/index.d.ts +767 -0
  4. package/dev/dist/index.js +3115 -908
  5. package/dev/dist/index.mjs +2466 -259
  6. package/dist/apply-auto-instrumentation.js +325 -221
  7. package/dist/apply-auto-instrumentation.mjs +110 -6
  8. package/dist/auto-instrumentations/bundler/esbuild.cjs +182 -7
  9. package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
  10. package/dist/auto-instrumentations/bundler/next.cjs +182 -7
  11. package/dist/auto-instrumentations/bundler/next.mjs +3 -3
  12. package/dist/auto-instrumentations/bundler/rollup.cjs +182 -7
  13. package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
  14. package/dist/auto-instrumentations/bundler/vite.cjs +182 -7
  15. package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
  16. package/dist/auto-instrumentations/bundler/webpack-loader.cjs +182 -7
  17. package/dist/auto-instrumentations/bundler/webpack.cjs +182 -7
  18. package/dist/auto-instrumentations/bundler/webpack.mjs +3 -3
  19. package/dist/auto-instrumentations/{chunk-U64OYU4Q.mjs → chunk-T2DMPWFI.mjs} +113 -6
  20. package/dist/auto-instrumentations/{chunk-LW4HDHXT.mjs → chunk-UHJ2DNYJ.mjs} +74 -2
  21. package/dist/auto-instrumentations/{chunk-OXINGIEZ.mjs → chunk-W5QNG3PV.mjs} +1 -1
  22. package/dist/auto-instrumentations/hook.mjs +209 -9
  23. package/dist/auto-instrumentations/index.cjs +115 -6
  24. package/dist/auto-instrumentations/index.d.mts +5 -1
  25. package/dist/auto-instrumentations/index.d.ts +5 -1
  26. package/dist/auto-instrumentations/index.mjs +5 -1
  27. package/dist/browser.d.mts +2324 -342
  28. package/dist/browser.d.ts +2324 -342
  29. package/dist/browser.js +3573 -626
  30. package/dist/browser.mjs +3573 -626
  31. package/dist/chunk-7P6ASYW6.mjs +9 -0
  32. package/dist/{chunk-V32LW47Z.js → chunk-AXJTOUOC.js} +3022 -1131
  33. package/dist/{chunk-4AQGZS6X.js → chunk-G3VHOHRC.js} +85 -11
  34. package/dist/chunk-MLKGABMK.js +9 -0
  35. package/dist/{chunk-AJT4FR25.mjs → chunk-MZLBAFVJ.mjs} +2051 -160
  36. package/dist/{chunk-CE3BLB2L.mjs → chunk-TZVZN2JJ.mjs} +84 -10
  37. package/dist/cli.js +2614 -297
  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 +3573 -626
  45. package/dist/edge-light.mjs +3573 -626
  46. package/dist/index.d.mts +2324 -342
  47. package/dist/index.d.ts +2324 -342
  48. package/dist/index.js +1959 -969
  49. package/dist/index.mjs +1450 -460
  50. package/dist/instrumentation/index.d.mts +439 -245
  51. package/dist/instrumentation/index.d.ts +439 -245
  52. package/dist/instrumentation/index.js +2550 -258
  53. package/dist/instrumentation/index.mjs +2550 -258
  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 +3573 -626
  59. package/dist/workerd.mjs +3573 -626
  60. package/package.json +10 -2
  61. package/util/dist/index.d.mts +326 -0
  62. package/util/dist/index.d.ts +326 -0
package/dist/cli.js CHANGED
@@ -41,7 +41,7 @@ var require_async = __commonJS({
41
41
  "use strict";
42
42
  Object.defineProperty(exports2, "__esModule", { value: true });
43
43
  exports2.read = void 0;
44
- function read2(path9, settings, callback) {
44
+ function read3(path9, settings, callback) {
45
45
  settings.fs.lstat(path9, (lstatError, lstat) => {
46
46
  if (lstatError !== null) {
47
47
  callFailureCallback(callback, lstatError);
@@ -67,7 +67,7 @@ var require_async = __commonJS({
67
67
  });
68
68
  });
69
69
  }
70
- exports2.read = read2;
70
+ exports2.read = read3;
71
71
  function callFailureCallback(callback, error2) {
72
72
  callback(error2);
73
73
  }
@@ -83,7 +83,7 @@ var require_sync = __commonJS({
83
83
  "use strict";
84
84
  Object.defineProperty(exports2, "__esModule", { value: true });
85
85
  exports2.read = void 0;
86
- function read2(path9, settings) {
86
+ function read3(path9, settings) {
87
87
  const lstat = settings.fs.lstatSync(path9);
88
88
  if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) {
89
89
  return lstat;
@@ -101,7 +101,7 @@ var require_sync = __commonJS({
101
101
  throw error2;
102
102
  }
103
103
  }
104
- exports2.read = read2;
104
+ exports2.read = read3;
105
105
  }
106
106
  });
107
107
 
@@ -327,14 +327,14 @@ var require_async2 = __commonJS({
327
327
  var constants_1 = require_constants();
328
328
  var utils = require_utils();
329
329
  var common = require_common();
330
- function read2(directory, settings, callback) {
330
+ function read3(directory, settings, callback) {
331
331
  if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) {
332
332
  readdirWithFileTypes(directory, settings, callback);
333
333
  return;
334
334
  }
335
335
  readdir2(directory, settings, callback);
336
336
  }
337
- exports2.read = read2;
337
+ exports2.read = read3;
338
338
  function readdirWithFileTypes(directory, settings, callback) {
339
339
  settings.fs.readdir(directory, { withFileTypes: true }, (readdirError, dirents) => {
340
340
  if (readdirError !== null) {
@@ -436,13 +436,13 @@ var require_sync2 = __commonJS({
436
436
  var constants_1 = require_constants();
437
437
  var utils = require_utils();
438
438
  var common = require_common();
439
- function read2(directory, settings) {
439
+ function read3(directory, settings) {
440
440
  if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) {
441
441
  return readdirWithFileTypes(directory, settings);
442
442
  }
443
443
  return readdir2(directory, settings);
444
444
  }
445
- exports2.read = read2;
445
+ exports2.read = read3;
446
446
  function readdirWithFileTypes(directory, settings) {
447
447
  const dirents = settings.fs.readdirSync(directory, { withFileTypes: true });
448
448
  return dirents.map((dirent) => {
@@ -1236,7 +1236,7 @@ var require_package = __commonJS({
1236
1236
  "package.json"(exports2, module2) {
1237
1237
  module2.exports = {
1238
1238
  name: "braintrust",
1239
- version: "3.31.0",
1239
+ version: "3.33.0",
1240
1240
  description: "SDK for integrating Braintrust",
1241
1241
  repository: {
1242
1242
  type: "git",
@@ -1273,6 +1273,13 @@ var require_package = __commonJS({
1273
1273
  require: "./dist/index.js",
1274
1274
  default: "./dist/index.mjs"
1275
1275
  },
1276
+ "./custom-views": {
1277
+ types: "./dist/custom-views.d.ts",
1278
+ import: "./dist/custom-views.mjs",
1279
+ module: "./dist/custom-views.mjs",
1280
+ require: "./dist/custom-views.js",
1281
+ default: "./dist/custom-views.mjs"
1282
+ },
1276
1283
  "./workerd": {
1277
1284
  import: "./dist/workerd.mjs",
1278
1285
  require: "./dist/workerd.js",
@@ -1444,12 +1451,13 @@ var require_package = __commonJS({
1444
1451
  typescript: "5.4.4",
1445
1452
  vite: "^8.1.5",
1446
1453
  "vite-tsconfig-paths": "^4.3.2",
1447
- vitest: "4.1.5",
1454
+ vitest: "4.1.11",
1448
1455
  webpack: "^5.106.2",
1449
1456
  zod: "^3.25.34"
1450
1457
  },
1451
1458
  dependencies: {
1452
1459
  "@next/env": "^14.2.3",
1460
+ "@types/react": "^18.3.1",
1453
1461
  "@vercel/functions": "^1.0.2",
1454
1462
  acorn: "^8.16.0",
1455
1463
  "acorn-import-attributes": "^1.9.5",
@@ -1516,7 +1524,7 @@ var import_node_util5 = __toESM(require("node:util"));
1516
1524
  var fsWalk = __toESM(require_out3());
1517
1525
  var import_minimatch = require("minimatch");
1518
1526
  var import_argparse = require("argparse");
1519
- var import_uuid3 = require("uuid");
1527
+ var import_uuid4 = require("uuid");
1520
1528
  var import_pluralize4 = __toESM(require("pluralize"));
1521
1529
 
1522
1530
  // src/logger.ts
@@ -4353,6 +4361,14 @@ var ChatCompletionContentPartImageWithTitle = import_v36.z.object({
4353
4361
  ttl: import_v36.z.enum(["5m", "1h"]).optional()
4354
4362
  }).optional()
4355
4363
  });
4364
+ var ChatCompletionContentPartInputAudioWithTitle = import_v36.z.object({
4365
+ input_audio: import_v36.z.object({ data: import_v36.z.string(), format: import_v36.z.enum(["wav", "mp3"]) }),
4366
+ type: import_v36.z.literal("input_audio"),
4367
+ cache_control: import_v36.z.object({
4368
+ type: import_v36.z.literal("ephemeral"),
4369
+ ttl: import_v36.z.enum(["5m", "1h"]).optional()
4370
+ }).optional()
4371
+ });
4356
4372
  var ChatCompletionContentPartFileFile = import_v36.z.object({ file_data: import_v36.z.string(), filename: import_v36.z.string(), file_id: import_v36.z.string() }).partial();
4357
4373
  var ChatCompletionContentPartFileWithTitle = import_v36.z.object({
4358
4374
  file: ChatCompletionContentPartFileFile,
@@ -4365,6 +4381,7 @@ var ChatCompletionContentPartFileWithTitle = import_v36.z.object({
4365
4381
  var ChatCompletionContentPart = import_v36.z.union([
4366
4382
  ChatCompletionContentPartTextWithTitle,
4367
4383
  ChatCompletionContentPartImageWithTitle,
4384
+ ChatCompletionContentPartInputAudioWithTitle,
4368
4385
  ChatCompletionContentPartFileWithTitle
4369
4386
  ]);
4370
4387
  var ChatCompletionContentPartText = import_v36.z.object({
@@ -7190,6 +7207,7 @@ var INSTRUMENTATION_NAMES = {
7190
7207
  GENKIT: "genkit",
7191
7208
  GITHUB_COPILOT: "github-copilot",
7192
7209
  GOOGLE_ADK: "google-adk",
7210
+ GOOGLE_GENERATIVE_AI: "google-generative-ai",
7193
7211
  GOOGLE_GENAI: "google-genai",
7194
7212
  GROQ: "groq",
7195
7213
  HUGGINGFACE: "huggingface",
@@ -7197,6 +7215,7 @@ var INSTRUMENTATION_NAMES = {
7197
7215
  LANGSMITH: "langsmith",
7198
7216
  MASTRA: "mastra",
7199
7217
  MISTRAL: "mistral",
7218
+ LANGGRAPH_SDK: "langgraph-sdk",
7200
7219
  OLLAMA: "ollama",
7201
7220
  OPENAI: "openai",
7202
7221
  OPENAI_AGENTS: "openai-agents",
@@ -7205,12 +7224,13 @@ var INSTRUMENTATION_NAMES = {
7205
7224
  OPENROUTER_AGENT: "openrouter-agent",
7206
7225
  PI_CODING_AGENT: "pi-coding-agent",
7207
7226
  STRANDS_AGENT_SDK: "strands-agent-sdk",
7208
- VOYAGEAI: "voyageai"
7227
+ VOYAGEAI: "voyageai",
7228
+ ELEVENLABS: "elevenlabs"
7209
7229
  };
7210
7230
  var INTERNAL_SPAN_INSTRUMENTATION_NAME = /* @__PURE__ */ Symbol.for(
7211
7231
  "braintrust.spanInstrumentationName"
7212
7232
  );
7213
- var SDK_VERSION = true ? "3.31.0" : "0.0.0";
7233
+ var SDK_VERSION = true ? "3.33.0" : "0.0.0";
7214
7234
  function withSpanInstrumentationName(args, instrumentationName) {
7215
7235
  return {
7216
7236
  ...args,
@@ -10451,6 +10471,38 @@ function getSpanParentObjectAndPropagatedState(options) {
10451
10471
  function getSpanParentObject(options) {
10452
10472
  return getSpanParentObjectAndPropagatedState(options).parentObject;
10453
10473
  }
10474
+ function _internalExportParentSynchronously(parent) {
10475
+ if ("toStr" in parent) {
10476
+ return parent.toStr();
10477
+ }
10478
+ if ("getParentInfo" in parent) {
10479
+ const parentInfo = parent.getParentInfo();
10480
+ if (!parentInfo) {
10481
+ return void 0;
10482
+ }
10483
+ const objectId = parentInfo.objectId.getSync().value;
10484
+ if (!objectId && !parentInfo.computeObjectMetadataArgs) {
10485
+ return void 0;
10486
+ }
10487
+ return new SpanComponentsV4({
10488
+ object_type: parentInfo.objectType,
10489
+ ...objectId ? { object_id: objectId } : {
10490
+ compute_object_metadata_args: parentInfo.computeObjectMetadataArgs ?? {}
10491
+ },
10492
+ row_id: parent.id,
10493
+ root_span_id: parent.rootSpanId,
10494
+ span_id: parent.spanId
10495
+ }).toStr();
10496
+ }
10497
+ const components = braintrustParentToComponents(parent._getOtelParent());
10498
+ if (!components) {
10499
+ return void 0;
10500
+ }
10501
+ return new SpanComponentsV4({
10502
+ object_type: components.objectType,
10503
+ ...components.objectId ? { object_id: components.objectId } : { compute_object_metadata_args: components.computeArgs ?? {} }
10504
+ }).toStr();
10505
+ }
10454
10506
  function currentBraintrustParent(state) {
10455
10507
  const resolvedState = state ?? _globalState;
10456
10508
  const experiment = currentExperiment({ state: resolvedState });
@@ -11831,10 +11883,16 @@ var SpanImpl = class _SpanImpl {
11831
11883
  inject(carrier) {
11832
11884
  const resolvedCarrier = carrier ?? {};
11833
11885
  try {
11886
+ const braintrustParent = this._getOtelParent() ?? this._propagatedState?.braintrustParent;
11887
+ if (!braintrustParent) {
11888
+ debugLogger.forState(this._state).warn(
11889
+ "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."
11890
+ );
11891
+ }
11834
11892
  _injectIntoCarrier(resolvedCarrier, {
11835
11893
  traceId: this._rootSpanId,
11836
11894
  spanId: this._spanId,
11837
- braintrustParent: this._getOtelParent() ?? this._propagatedState?.braintrustParent,
11895
+ braintrustParent,
11838
11896
  propagatedState: this._propagatedState
11839
11897
  });
11840
11898
  } catch (e) {
@@ -12384,6 +12442,16 @@ function renderMessageImpl(render, message, variables) {
12384
12442
  }
12385
12443
  }
12386
12444
  ];
12445
+ case "input_audio":
12446
+ return [
12447
+ {
12448
+ ...c,
12449
+ input_audio: {
12450
+ ...c.input_audio,
12451
+ data: render(c.input_audio.data)
12452
+ }
12453
+ }
12454
+ ];
12387
12455
  case "file":
12388
12456
  return [
12389
12457
  {
@@ -13889,6 +13957,9 @@ function waterfall(tasks, callback) {
13889
13957
  }
13890
13958
  var waterfall$1 = awaitify(waterfall);
13891
13959
 
13960
+ // src/framework.ts
13961
+ var import_uuid3 = require("uuid");
13962
+
13892
13963
  // src/functions/invoke.ts
13893
13964
  async function invoke(args) {
13894
13965
  const {
@@ -13971,11 +14042,268 @@ async function invoke(args) {
13971
14042
  }
13972
14043
 
13973
14044
  // src/trace.ts
14045
+ var spanFilterFields = /* @__PURE__ */ new Set([
14046
+ "spanType",
14047
+ "name",
14048
+ "hasError",
14049
+ "metadata",
14050
+ "duration"
14051
+ ]);
14052
+ function isRecord(value) {
14053
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
14054
+ return false;
14055
+ }
14056
+ const prototype2 = Object.getPrototypeOf(value);
14057
+ return prototype2 === Object.prototype || prototype2 === null;
14058
+ }
14059
+ function validateMetadataValue(value, ancestors) {
14060
+ if (value === null || typeof value === "string" || typeof value === "boolean") {
14061
+ return;
14062
+ }
14063
+ if (typeof value === "number") {
14064
+ if (Number.isFinite(value)) {
14065
+ return;
14066
+ }
14067
+ throw new Error("filters.metadata numbers must be finite");
14068
+ }
14069
+ if (typeof value !== "object" || value === null) {
14070
+ throw new Error("filters.metadata values must be JSON-serializable");
14071
+ }
14072
+ if (!Array.isArray(value) && !isRecord(value)) {
14073
+ throw new Error("filters.metadata values must be JSON-serializable");
14074
+ }
14075
+ if (ancestors.has(value)) {
14076
+ throw new Error("filters.metadata must not contain cycles");
14077
+ }
14078
+ ancestors.add(value);
14079
+ if (Array.isArray(value)) {
14080
+ for (let index = 0; index < value.length; index++) {
14081
+ validateMetadataValue(value[index], ancestors);
14082
+ }
14083
+ } else {
14084
+ if (Object.getOwnPropertySymbols(value).length > 0) {
14085
+ throw new Error("filters.metadata keys must be strings");
14086
+ }
14087
+ for (const nested of Object.values(value)) {
14088
+ validateMetadataValue(nested, ancestors);
14089
+ }
14090
+ }
14091
+ ancestors.delete(value);
14092
+ }
14093
+ function compileMetadataLeaves(metadata, path9 = [], ancestors = /* @__PURE__ */ new WeakSet()) {
14094
+ if (Object.getOwnPropertySymbols(metadata).length > 0) {
14095
+ throw new Error("filters.metadata keys must be strings");
14096
+ }
14097
+ if (ancestors.has(metadata)) {
14098
+ throw new Error("filters.metadata must not contain cycles");
14099
+ }
14100
+ ancestors.add(metadata);
14101
+ const leaves = [];
14102
+ for (const [key, value] of Object.entries(metadata)) {
14103
+ const childPath = [...path9, key];
14104
+ if (isRecord(value)) {
14105
+ leaves.push(...compileMetadataLeaves(value, childPath, ancestors));
14106
+ } else {
14107
+ validateMetadataValue(value, ancestors);
14108
+ leaves.push([childPath, value]);
14109
+ }
14110
+ }
14111
+ ancestors.delete(metadata);
14112
+ return leaves;
14113
+ }
14114
+ function normalizeSpanFilters(filters, spanType) {
14115
+ if (filters != null && !isRecord(filters)) {
14116
+ throw new Error("filters must be an object");
14117
+ }
14118
+ const values = { ...filters ?? {} };
14119
+ if (spanType !== void 0) {
14120
+ if (!Array.isArray(spanType) || !spanType.every((item) => typeof item === "string")) {
14121
+ throw new Error("spanType must be an array of strings");
14122
+ }
14123
+ if (Object.hasOwn(values, "spanType")) {
14124
+ throw new Error(
14125
+ "spanType cannot be provided both directly and in filters"
14126
+ );
14127
+ }
14128
+ if (spanType.length > 0) {
14129
+ values.spanType = spanType;
14130
+ }
14131
+ }
14132
+ if (Object.keys(values).some((field) => !spanFilterFields.has(field))) {
14133
+ throw new Error("Unsupported span filter fields");
14134
+ }
14135
+ for (const field of ["spanType", "name"]) {
14136
+ if (Object.hasOwn(values, field)) {
14137
+ const items = values[field];
14138
+ if (!Array.isArray(items) || !items.every((item) => typeof item === "string")) {
14139
+ throw new Error(`filters.${field} must be an array of strings`);
14140
+ }
14141
+ }
14142
+ }
14143
+ if (Object.hasOwn(values, "hasError") && typeof values.hasError !== "boolean") {
14144
+ throw new Error("filters.hasError must be a boolean");
14145
+ }
14146
+ let compiledMetadataLeaves = [];
14147
+ if (Object.hasOwn(values, "metadata")) {
14148
+ if (!isRecord(values.metadata)) {
14149
+ throw new Error("filters.metadata must be an object");
14150
+ }
14151
+ compiledMetadataLeaves = compileMetadataLeaves(values.metadata);
14152
+ }
14153
+ if (Object.hasOwn(values, "duration")) {
14154
+ if (!isRecord(values.duration) || Object.keys(values.duration).some(
14155
+ (bound) => bound !== "min" && bound !== "max"
14156
+ )) {
14157
+ throw new Error("filters.duration must contain only min and/or max");
14158
+ }
14159
+ if (Object.values(values.duration).some(
14160
+ (bound) => typeof bound !== "number" || !Number.isFinite(bound)
14161
+ )) {
14162
+ throw new Error("filters.duration bounds must be finite numbers");
14163
+ }
14164
+ }
14165
+ const normalized = {};
14166
+ if (Array.isArray(values.spanType)) {
14167
+ normalized.spanType = values.spanType;
14168
+ }
14169
+ if (Array.isArray(values.name)) {
14170
+ normalized.name = values.name;
14171
+ }
14172
+ if (typeof values.hasError === "boolean") {
14173
+ normalized.hasError = values.hasError;
14174
+ }
14175
+ if (isRecord(values.metadata)) {
14176
+ normalized.metadata = values.metadata;
14177
+ }
14178
+ if (isRecord(values.duration)) {
14179
+ normalized.duration = {};
14180
+ if (typeof values.duration.min === "number") {
14181
+ normalized.duration.min = values.duration.min;
14182
+ }
14183
+ if (typeof values.duration.max === "number") {
14184
+ normalized.duration.max = values.duration.max;
14185
+ }
14186
+ }
14187
+ return { filters: normalized, metadataLeaves: compiledMetadataLeaves };
14188
+ }
14189
+ function metadataEqual(actual, expected) {
14190
+ if (expected === null) {
14191
+ return actual === null || actual === void 0;
14192
+ }
14193
+ if (Array.isArray(expected)) {
14194
+ return Array.isArray(actual) && actual.length === expected.length && expected.every((value, index) => metadataEqual(actual[index], value));
14195
+ }
14196
+ if (isRecord(expected)) {
14197
+ if (!isRecord(actual)) {
14198
+ return false;
14199
+ }
14200
+ const expectedKeys = Object.keys(expected);
14201
+ const actualKeys = Object.keys(actual);
14202
+ return actualKeys.length === expectedKeys.length && expectedKeys.every(
14203
+ (key) => Object.hasOwn(actual, key) && metadataEqual(actual[key], expected[key])
14204
+ );
14205
+ }
14206
+ return actual === expected;
14207
+ }
14208
+ function matchesSpanFilters(span, compiledFilters) {
14209
+ const { filters, metadataLeaves } = compiledFilters;
14210
+ if (filters.spanType !== void 0 && !filters.spanType.includes(span.span_attributes?.type ?? "")) {
14211
+ return false;
14212
+ }
14213
+ if (filters.name !== void 0 && !filters.name.includes(span.span_attributes?.name ?? "")) {
14214
+ return false;
14215
+ }
14216
+ if (filters.hasError !== void 0 && (span.error !== null && span.error !== void 0) !== filters.hasError) {
14217
+ return false;
14218
+ }
14219
+ for (const [path9, expected] of metadataLeaves) {
14220
+ let actual = span.metadata;
14221
+ for (const key of path9) {
14222
+ actual = isRecord(actual) && Object.hasOwn(actual, key) ? actual[key] : void 0;
14223
+ }
14224
+ if (!metadataEqual(actual, expected)) {
14225
+ return false;
14226
+ }
14227
+ }
14228
+ if (filters.duration && Object.keys(filters.duration).length > 0) {
14229
+ const metrics = span.metrics;
14230
+ const start = isRecord(metrics) ? metrics.start : void 0;
14231
+ const end = isRecord(metrics) ? metrics.end : void 0;
14232
+ if (typeof start !== "number" || !Number.isFinite(start) || typeof end !== "number" || !Number.isFinite(end)) {
14233
+ return false;
14234
+ }
14235
+ const elapsed = end - start;
14236
+ if (filters.duration.min !== void 0 && elapsed < filters.duration.min) {
14237
+ return false;
14238
+ }
14239
+ if (filters.duration.max !== void 0 && elapsed > filters.duration.max) {
14240
+ return false;
14241
+ }
14242
+ }
14243
+ return true;
14244
+ }
14245
+ function btqlComparison(op, name, value) {
14246
+ return {
14247
+ op,
14248
+ left: { op: "ident", name },
14249
+ right: { op: "literal", value }
14250
+ };
14251
+ }
14252
+ function btqlNullCheck(op, name) {
14253
+ return { op, expr: { op: "ident", name } };
14254
+ }
14255
+ function spanFilterClauses(compiledFilters) {
14256
+ const { filters, metadataLeaves } = compiledFilters;
14257
+ const children = [];
14258
+ for (const [field, attribute] of [
14259
+ ["spanType", "type"],
14260
+ ["name", "name"]
14261
+ ]) {
14262
+ const values = filters[field];
14263
+ if (values !== void 0) {
14264
+ children.push(
14265
+ values.length > 0 ? btqlComparison("in", ["span_attributes", attribute], values) : { op: "literal", value: false }
14266
+ );
14267
+ }
14268
+ }
14269
+ if (filters.hasError !== void 0) {
14270
+ children.push(
14271
+ btqlNullCheck(filters.hasError ? "isnotnull" : "isnull", ["error"])
14272
+ );
14273
+ }
14274
+ for (const [path9, value] of metadataLeaves) {
14275
+ const name = ["metadata", ...path9];
14276
+ children.push(
14277
+ value === null ? btqlNullCheck("isnull", name) : btqlComparison("eq", name, value)
14278
+ );
14279
+ }
14280
+ const elapsed = {
14281
+ op: "sub",
14282
+ left: { op: "ident", name: ["metrics", "end"] },
14283
+ right: { op: "ident", name: ["metrics", "start"] }
14284
+ };
14285
+ if (filters.duration?.min !== void 0) {
14286
+ children.push({
14287
+ op: "ge",
14288
+ left: elapsed,
14289
+ right: { op: "literal", value: filters.duration.min }
14290
+ });
14291
+ }
14292
+ if (filters.duration?.max !== void 0) {
14293
+ children.push({
14294
+ op: "le",
14295
+ left: elapsed,
14296
+ right: { op: "literal", value: filters.duration.max }
14297
+ });
14298
+ }
14299
+ return children;
14300
+ }
13974
14301
  var SpanFetcher = class _SpanFetcher extends ObjectFetcher {
13975
- constructor(objectType, _objectId, rootSpanId, _state, spanTypeFilter, includeScorers = false, brainstoreRealtime = true) {
14302
+ constructor(objectType, _objectId, rootSpanId, _state, spanTypeFilter, includeScorers = false, brainstoreRealtime = true, filters) {
14303
+ const normalizedFilters = normalizeSpanFilters(filters, spanTypeFilter);
13976
14304
  const filterExpr = _SpanFetcher.buildFilter(
13977
14305
  rootSpanId,
13978
- spanTypeFilter,
14306
+ normalizedFilters,
13979
14307
  includeScorers
13980
14308
  );
13981
14309
  super(
@@ -13996,42 +14324,22 @@ var SpanFetcher = class _SpanFetcher extends ObjectFetcher {
13996
14324
  rootSpanId;
13997
14325
  _state;
13998
14326
  spanTypeFilter;
13999
- static buildFilter(rootSpanId, spanTypeFilter, includeScorers = false) {
14327
+ static buildFilter(rootSpanId, filters, includeScorers = false) {
14328
+ const purpose = ["span_attributes", "purpose"];
14000
14329
  const children = [
14001
- // Base filter: root_span_id = 'value'
14002
- {
14003
- op: "eq",
14004
- left: { op: "ident", name: ["root_span_id"] },
14005
- right: { op: "literal", value: rootSpanId }
14006
- }
14330
+ btqlComparison("eq", ["root_span_id"], rootSpanId)
14007
14331
  ];
14008
14332
  if (!includeScorers) {
14009
14333
  children.push({
14010
14334
  op: "or",
14011
14335
  children: [
14012
- {
14013
- op: "isnull",
14014
- expr: { op: "ident", name: ["span_attributes", "purpose"] }
14015
- },
14016
- {
14017
- op: "ne",
14018
- left: { op: "ident", name: ["span_attributes", "purpose"] },
14019
- right: { op: "literal", value: "scorer" }
14020
- }
14336
+ btqlNullCheck("isnull", purpose),
14337
+ btqlComparison("ne", purpose, "scorer")
14021
14338
  ]
14022
14339
  });
14023
14340
  }
14024
- if (spanTypeFilter && spanTypeFilter.length > 0) {
14025
- children.push({
14026
- op: "in",
14027
- left: { op: "ident", name: ["span_attributes", "type"] },
14028
- right: { op: "literal", value: spanTypeFilter }
14029
- });
14030
- }
14031
- return {
14032
- op: "and",
14033
- children
14034
- };
14341
+ children.push(...spanFilterClauses(filters));
14342
+ return { op: "and", children };
14035
14343
  }
14036
14344
  get id() {
14037
14345
  return Promise.resolve(this._objectId);
@@ -14046,67 +14354,80 @@ var CachedSpanFetcher = class {
14046
14354
  fetchFn;
14047
14355
  constructor(objectTypeOrFetchFn, objectId, rootSpanId, getState, brainstoreRealtime = true) {
14048
14356
  if (typeof objectTypeOrFetchFn === "function") {
14049
- this.fetchFn = (spanType) => objectTypeOrFetchFn(spanType);
14357
+ this.fetchFn = async (filters) => (await objectTypeOrFetchFn(filters.filters.spanType)).filter(
14358
+ (span) => matchesSpanFilters(span, filters)
14359
+ );
14050
14360
  } else {
14051
14361
  const objectType = objectTypeOrFetchFn;
14052
- this.fetchFn = async (spanType, includeScorers) => {
14362
+ this.fetchFn = async (filters, includeScorers) => {
14053
14363
  const state = await getState();
14054
14364
  const fetcher = new SpanFetcher(
14055
14365
  objectType,
14056
14366
  objectId,
14057
14367
  rootSpanId,
14058
14368
  state,
14059
- spanType,
14369
+ void 0,
14060
14370
  includeScorers,
14061
- brainstoreRealtime
14371
+ brainstoreRealtime,
14372
+ filters.filters
14062
14373
  );
14063
- const rows = await fetcher.fetchedData();
14064
- return rows.map((row) => ({
14065
- input: row.input,
14066
- output: row.output,
14067
- expected: row.expected,
14068
- error: row.error,
14069
- scores: row.scores,
14070
- metrics: row.metrics,
14071
- metadata: row.metadata,
14072
- span_id: row.span_id,
14073
- span_parents: row.span_parents,
14074
- is_root: row.is_root,
14075
- span_attributes: row.span_attributes,
14076
- id: row.id,
14077
- _xact_id: row._xact_id,
14078
- _pagination_key: row._pagination_key,
14079
- root_span_id: row.root_span_id,
14080
- created: row.created,
14081
- tags: row.tags
14082
- }));
14374
+ let spans = (await fetcher.fetchedData()).map(
14375
+ (row) => ({ ...row })
14376
+ );
14377
+ if (filters.filters.metadata !== void 0) {
14378
+ spans = spans.filter((span) => matchesSpanFilters(span, filters));
14379
+ }
14380
+ return spans;
14083
14381
  };
14084
14382
  }
14085
14383
  }
14086
14384
  async getSpans({
14087
- spanType,
14385
+ spanType: requestedSpanType,
14386
+ filters,
14088
14387
  includeScorers = false
14089
14388
  } = {}) {
14389
+ const normalizedFilters = normalizeSpanFilters(filters, requestedSpanType);
14390
+ const spanType = normalizedFilters.filters.spanType;
14391
+ const hasAdvancedFilters = Object.keys(normalizedFilters.filters).some(
14392
+ (field) => field !== "spanType"
14393
+ );
14394
+ if (spanType?.length === 0) {
14395
+ return [];
14396
+ }
14090
14397
  if (includeScorers) {
14091
- return this.fetchFn(spanType, true);
14398
+ return this.fetchFn(normalizedFilters, true);
14092
14399
  }
14093
14400
  if (this.allFetched) {
14094
- return this.getFromCache(spanType);
14401
+ const spans = this.getFromCache(spanType);
14402
+ return hasAdvancedFilters ? spans.filter((span) => matchesSpanFilters(span, normalizedFilters)) : spans;
14095
14403
  }
14096
- if (!spanType || spanType.length === 0) {
14404
+ if (hasAdvancedFilters && spanType && spanType.every((type) => this.spanCache.has(type))) {
14405
+ return this.getFromCache(spanType).filter(
14406
+ (span) => matchesSpanFilters(span, normalizedFilters)
14407
+ );
14408
+ }
14409
+ if (hasAdvancedFilters) {
14410
+ return this.fetchFn(normalizedFilters, false);
14411
+ }
14412
+ if (!spanType) {
14413
+ this.spanCache.clear();
14097
14414
  await this.fetchSpans(void 0);
14098
- this.allFetched = true;
14415
+ if (this.spanCache.size > 0) {
14416
+ this.allFetched = true;
14417
+ }
14099
14418
  return this.getFromCache(void 0);
14100
14419
  }
14101
- const missingTypes = spanType.filter((t) => !this.spanCache.has(t));
14102
- if (missingTypes.length === 0) {
14103
- return this.getFromCache(spanType);
14420
+ const missingTypes = spanType.filter((type) => !this.spanCache.has(type));
14421
+ if (missingTypes.length > 0) {
14422
+ await this.fetchSpans(missingTypes);
14104
14423
  }
14105
- await this.fetchSpans(missingTypes);
14106
14424
  return this.getFromCache(spanType);
14107
14425
  }
14108
14426
  async fetchSpans(spanType) {
14109
- const spans = await this.fetchFn(spanType, false);
14427
+ const spans = await this.fetchFn(
14428
+ normalizeSpanFilters(spanType ? { spanType } : void 0),
14429
+ false
14430
+ );
14110
14431
  for (const span of spans) {
14111
14432
  const type = span.span_attributes?.type ?? "";
14112
14433
  const existing = this.spanCache.get(type) ?? [];
@@ -14186,34 +14507,20 @@ var LocalTrace = class {
14186
14507
  */
14187
14508
  async getSpans({
14188
14509
  spanType,
14510
+ filters,
14189
14511
  includeScorers = false
14190
14512
  } = {}) {
14513
+ const normalizedFilters = normalizeSpanFilters(filters, spanType);
14191
14514
  const cachedSpans = this.state.spanCache.getByRootSpanId(this.rootSpanId);
14192
14515
  if (cachedSpans && cachedSpans.length > 0) {
14193
- let spans = includeScorers ? cachedSpans : cachedSpans.filter(
14194
- (span) => span.span_attributes?.purpose !== "scorer"
14195
- );
14196
- if (spanType && spanType.length > 0) {
14197
- spans = spans.filter(
14198
- (span) => spanType.includes(span.span_attributes?.type ?? "")
14199
- );
14200
- }
14201
- return spans.map((span) => ({
14202
- input: span.input,
14203
- output: span.output,
14204
- expected: span.expected,
14205
- error: span.error,
14206
- scores: span.scores,
14207
- metrics: span.metrics,
14208
- metadata: span.metadata,
14209
- span_id: span.span_id,
14210
- span_parents: span.span_parents,
14211
- is_root: span.is_root,
14212
- span_attributes: span.span_attributes,
14213
- tags: span.tags
14214
- }));
14516
+ return cachedSpans.filter(
14517
+ (span) => (includeScorers || span.span_attributes?.purpose !== "scorer") && matchesSpanFilters({ ...span }, normalizedFilters)
14518
+ ).map((span) => ({ ...span }));
14215
14519
  }
14216
- return this.cachedFetcher.getSpans({ spanType, includeScorers });
14520
+ return this.cachedFetcher.getSpans({
14521
+ filters: normalizedFilters.filters,
14522
+ includeScorers
14523
+ });
14217
14524
  }
14218
14525
  /**
14219
14526
  * Get the thread (preprocessed messages) for this trace.
@@ -14620,7 +14927,7 @@ async function Eval(name, evaluator, reporterOrOpts) {
14620
14927
  data,
14621
14928
  { disabled: Boolean(options.parent || options.noSendLogs) }
14622
14929
  );
14623
- if (experiment && typeof process !== "undefined" && globalThis.BRAINTRUST_CONTEXT_MANAGER !== void 0) {
14930
+ if (experiment) {
14624
14931
  await experiment._waitForId();
14625
14932
  }
14626
14933
  if (experiment && options.onStart) {
@@ -14952,6 +15259,10 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
14952
15259
  } : void 0;
14953
15260
  const parsedDatumOrigin = ObjectReference.safeParse(datum.origin);
14954
15261
  const origin = inlineDatasetOrigin ?? (parsedDatumOrigin?.success ? parsedDatumOrigin.data : void 0);
15262
+ const upsertId = datum.upsert_id && trialIndex > 0 ? (0, import_uuid3.v5)(
15263
+ `braintrust:eval:${datum.upsert_id}:trial:${trialIndex}`,
15264
+ import_uuid3.v5.URL
15265
+ ) : datum.upsert_id;
14955
15266
  const baseEvent = {
14956
15267
  name: "eval",
14957
15268
  spanAttributes: {
@@ -14962,7 +15273,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
14962
15273
  expected: "expected" in datum ? datum.expected : void 0,
14963
15274
  tags: datum.tags,
14964
15275
  origin,
14965
- ...datum.upsert_id ? { id: datum.upsert_id } : {}
15276
+ ...upsertId ? { id: upsertId } : {}
14966
15277
  }
14967
15278
  };
14968
15279
  const callback = async (rootSpan) => {
@@ -17270,6 +17581,18 @@ function defineChannels(pkg, channels, options) {
17270
17581
  var openAIChannels = defineChannels(
17271
17582
  "openai",
17272
17583
  {
17584
+ agentsTraceStart: channel({
17585
+ channelName: "agents.trace.start",
17586
+ kind: "async"
17587
+ }),
17588
+ agentsTraceCapture: channel({
17589
+ channelName: "agents.trace.capture",
17590
+ kind: "async"
17591
+ }),
17592
+ agentsTraceFail: channel({
17593
+ channelName: "agents.trace.fail",
17594
+ kind: "async"
17595
+ }),
17273
17596
  filesCreateTraced: channel({
17274
17597
  channelName: "files.create-traced",
17275
17598
  kind: "async"
@@ -17638,6 +17961,23 @@ function getCachedMetricFromHeaders(headers) {
17638
17961
  return parseCachedHeader(headers.get(LEGACY_CACHED_HEADER));
17639
17962
  }
17640
17963
 
17964
+ // src/instrumentation/plugins/openai-manual-instrumentation-utils.ts
17965
+ async function deterministicDigest(namespace, ...parts) {
17966
+ const encoded = new TextEncoder().encode(
17967
+ [namespace, ...parts].map((part) => `${part.length}:${part}`).join("\0")
17968
+ );
17969
+ return new Uint8Array(
17970
+ await globalThis.crypto.subtle.digest("SHA-256", encoded)
17971
+ );
17972
+ }
17973
+ function digestHex(bytes, length) {
17974
+ return Array.from(bytes.slice(0, length)).map((byte) => byte.toString(16).padStart(2, "0")).join("");
17975
+ }
17976
+ function digestUuid(bytes) {
17977
+ const hex = digestHex(bytes, 16);
17978
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
17979
+ }
17980
+
17641
17981
  // src/instrumentation/plugins/openai-batch-instrumentation.ts
17642
17982
  var SUPPORTED_ENDPOINTS = /* @__PURE__ */ new Set(["/v1/chat/completions", "/v1/responses"]);
17643
17983
  var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
@@ -17678,21 +18018,6 @@ async function exportParent(parent) {
17678
18018
  }
17679
18019
  return void 0;
17680
18020
  }
17681
- async function deterministicDigest(namespace, ...parts) {
17682
- const encoded = new TextEncoder().encode(
17683
- [namespace, ...parts].map((part) => `${part.length}:${part}`).join("\0")
17684
- );
17685
- return new Uint8Array(
17686
- await globalThis.crypto.subtle.digest("SHA-256", encoded)
17687
- );
17688
- }
17689
- function digestHex(bytes, length) {
17690
- return Array.from(bytes.slice(0, length)).map((byte) => byte.toString(16).padStart(2, "0")).join("");
17691
- }
17692
- function digestUuid(bytes) {
17693
- const hex = digestHex(bytes, 16);
17694
- return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
17695
- }
17696
18021
  async function batchSpanIds(inputFileId) {
17697
18022
  const [row, span, root] = await Promise.all([
17698
18023
  deterministicDigest("openai:batch:row", inputFileId),
@@ -18183,6 +18508,628 @@ var interceptOpenAIBatchTraceComplete = (target, thisArg, args) => Promise.resol
18183
18508
  return result;
18184
18509
  });
18185
18510
 
18511
+ // src/instrumentation/plugins/openai-agents-api-instrumentation.ts
18512
+ var TERMINAL_TURN_EVENTS = /* @__PURE__ */ new Set([
18513
+ "agent.session.turn.completed",
18514
+ "agent.session.turn.failed",
18515
+ "agent.session.turn.cancelled"
18516
+ ]);
18517
+ var TURN_LIFECYCLE_EVENTS = /* @__PURE__ */ new Set([
18518
+ "agent.session.turn.created",
18519
+ "agent.session.turn.in_progress",
18520
+ ...TERMINAL_TURN_EVENTS
18521
+ ]);
18522
+ var SESSION_EVENTS = /* @__PURE__ */ new Set([
18523
+ "agent.session.created",
18524
+ "agent.session.failed",
18525
+ "agent.session.idle",
18526
+ "agent.session.in_progress",
18527
+ "agent.session.requires_action"
18528
+ ]);
18529
+ var SUBAGENT_EVENTS = /* @__PURE__ */ new Set([
18530
+ "agent.session.subagent.active",
18531
+ "agent.session.subagent.closed",
18532
+ "agent.session.subagent.created"
18533
+ ]);
18534
+ function read2(value, key) {
18535
+ if (!isObject(value)) {
18536
+ return void 0;
18537
+ }
18538
+ try {
18539
+ return Reflect.get(value, key);
18540
+ } catch {
18541
+ return void 0;
18542
+ }
18543
+ }
18544
+ function stringValue(value) {
18545
+ return typeof value === "string" && value.length > 0 ? value : void 0;
18546
+ }
18547
+ function recordValue(record, key) {
18548
+ return Object.hasOwn(record, key) ? record[key] : void 0;
18549
+ }
18550
+ function setRecordValue(record, key, value) {
18551
+ Object.defineProperty(record, key, {
18552
+ configurable: true,
18553
+ enumerable: true,
18554
+ value,
18555
+ writable: true
18556
+ });
18557
+ }
18558
+ function loggedError(value, fallback2) {
18559
+ if (value instanceof Error) {
18560
+ return value;
18561
+ }
18562
+ const message = stringValue(read2(value, "message"));
18563
+ return new Error(message ?? (typeof value === "string" ? value : fallback2));
18564
+ }
18565
+ function logInstrumentationError(context2, error2) {
18566
+ debugLogger.debug(`OpenAI Agents API instrumentation ${context2}:`, error2);
18567
+ }
18568
+ async function childSpanIds2(rootKey, kind, providerId) {
18569
+ const [row, span] = await Promise.all([
18570
+ deterministicDigest("openai:agents:row", rootKey, kind, providerId),
18571
+ deterministicDigest("openai:agents:span", rootKey, kind, providerId)
18572
+ ]);
18573
+ return { rowId: digestUuid(row), spanId: digestHex(span, 8) };
18574
+ }
18575
+ function traceMetadata(args) {
18576
+ const metadata = {};
18577
+ const suppliedMetadata = read2(args, "metadata");
18578
+ if (isObject(suppliedMetadata)) {
18579
+ try {
18580
+ for (const key of Object.keys(suppliedMetadata)) {
18581
+ metadata[key] = read2(suppliedMetadata, key);
18582
+ }
18583
+ } catch (error2) {
18584
+ logInstrumentationError("could not read supplied metadata", error2);
18585
+ }
18586
+ }
18587
+ const agent = read2(args, "agent");
18588
+ const agentId = stringValue(read2(agent, "id")) ?? stringValue(read2(args, "agent_id"));
18589
+ const agentName = stringValue(read2(agent, "name"));
18590
+ const model = stringValue(read2(agent, "model"));
18591
+ return {
18592
+ ...metadata,
18593
+ api: "agents",
18594
+ ...agentId ? { agent_id: agentId } : {},
18595
+ ...agentName ? { agent_name: agentName } : {},
18596
+ ...model ? { model } : {},
18597
+ provider: "openai"
18598
+ };
18599
+ }
18600
+ function copyState(state) {
18601
+ return {
18602
+ ...state,
18603
+ callItems: { ...state.callItems },
18604
+ eventIds: [...state.eventIds],
18605
+ openTools: { ...state.openTools },
18606
+ subagents: { ...state.subagents },
18607
+ turnSubagents: { ...state.turnSubagents }
18608
+ };
18609
+ }
18610
+ function startRootSpan(state) {
18611
+ const root = SpanComponentsV4.fromStr(state.root);
18612
+ const parent = SpanComponentsV4.fromStr(state.rootParent);
18613
+ const rowId = stringValue(root.data.row_id);
18614
+ const rootSpanId = stringValue(root.data.root_span_id);
18615
+ const spanId = stringValue(root.data.span_id);
18616
+ if (!rowId || !rootSpanId || !spanId) {
18617
+ throw new Error("OpenAI Agents trace root is invalid");
18618
+ }
18619
+ const hasParentSpan = Boolean(
18620
+ parent.data.row_id && parent.data.span_id && parent.data.root_span_id
18621
+ );
18622
+ return withCurrent(
18623
+ NOOP_SPAN,
18624
+ () => _internalStartSpanWithInitialMergeAndParentSpanIds(
18625
+ withSpanInstrumentationName(
18626
+ {
18627
+ name: "openai.agents.turn",
18628
+ type: "task" /* TASK */,
18629
+ parent: state.rootParent,
18630
+ ...!hasParentSpan ? {
18631
+ parentSpanIds: {
18632
+ parentSpanIds: [],
18633
+ rootSpanId
18634
+ }
18635
+ } : {},
18636
+ spanId,
18637
+ startTime: state.startTime,
18638
+ event: { id: rowId }
18639
+ },
18640
+ INSTRUMENTATION_NAMES.OPENAI
18641
+ )
18642
+ )
18643
+ );
18644
+ }
18645
+ async function startSubagentSpan(state, subagentId, input, metadata, visiting = /* @__PURE__ */ new Set()) {
18646
+ const subagent = recordValue(state.subagents, subagentId);
18647
+ let parent = state.root;
18648
+ if (subagent?.parentAgentId && subagent.parentAgentId !== subagentId && recordValue(state.subagents, subagent.parentAgentId) && !visiting.has(subagent.parentAgentId)) {
18649
+ visiting.add(subagentId);
18650
+ parent = await (await startSubagentSpan(
18651
+ state,
18652
+ subagent.parentAgentId,
18653
+ void 0,
18654
+ void 0,
18655
+ visiting
18656
+ )).export();
18657
+ }
18658
+ const ids = await childSpanIds2(state.rootKey, "subagent", subagentId);
18659
+ return withCurrent(
18660
+ NOOP_SPAN,
18661
+ () => _internalStartSpanWithInitialMerge(
18662
+ withSpanInstrumentationName(
18663
+ {
18664
+ name: "openai.agents.subagent",
18665
+ type: "task" /* TASK */,
18666
+ parent,
18667
+ spanId: ids.spanId,
18668
+ startTime: subagent?.openedAt,
18669
+ event: {
18670
+ id: ids.rowId,
18671
+ ...input !== void 0 ? { input } : {},
18672
+ metadata: {
18673
+ ...metadata,
18674
+ agent_id: subagentId,
18675
+ ...subagent?.parentAgentId ? { parent_agent_id: subagent.parentAgentId } : {},
18676
+ provider: "openai"
18677
+ }
18678
+ }
18679
+ },
18680
+ INSTRUMENTATION_NAMES.OPENAI
18681
+ )
18682
+ )
18683
+ );
18684
+ }
18685
+ async function parentForTurn(state, turnId) {
18686
+ const subagentId = turnId ? recordValue(state.turnSubagents, turnId) : void 0;
18687
+ if (!subagentId) {
18688
+ return state.root;
18689
+ }
18690
+ return await (await startSubagentSpan(state, subagentId)).export();
18691
+ }
18692
+ async function startToolSpan(state, tool, input) {
18693
+ const ids = await childSpanIds2(state.rootKey, "tool", tool.itemId);
18694
+ return withCurrent(
18695
+ NOOP_SPAN,
18696
+ async () => _internalStartSpanWithInitialMerge(
18697
+ withSpanInstrumentationName(
18698
+ {
18699
+ name: tool.name,
18700
+ type: "tool" /* TOOL */,
18701
+ parent: await parentForTurn(state, tool.turnId),
18702
+ spanId: ids.spanId,
18703
+ startTime: tool.startTime,
18704
+ event: {
18705
+ id: ids.rowId,
18706
+ ...input !== void 0 ? { input } : {},
18707
+ metadata: {
18708
+ item_id: tool.itemId,
18709
+ provider: "openai",
18710
+ tool_type: tool.toolType,
18711
+ ...tool.turnId ? { turn_id: tool.turnId } : {}
18712
+ }
18713
+ }
18714
+ },
18715
+ INSTRUMENTATION_NAMES.OPENAI
18716
+ )
18717
+ )
18718
+ );
18719
+ }
18720
+ function toolFromItem(item, observedAt) {
18721
+ const itemId = stringValue(read2(item, "id"));
18722
+ const toolType = stringValue(read2(item, "type"));
18723
+ if (!itemId || !toolType) {
18724
+ return void 0;
18725
+ }
18726
+ const turnId = stringValue(read2(item, "turn_id"));
18727
+ switch (toolType) {
18728
+ case "function_call":
18729
+ return {
18730
+ input: read2(item, "arguments"),
18731
+ tool: {
18732
+ itemId,
18733
+ name: stringValue(read2(item, "name")) ?? "Function call",
18734
+ startTime: observedAt,
18735
+ toolType,
18736
+ ...turnId ? { turnId } : {}
18737
+ }
18738
+ };
18739
+ case "mcp_call": {
18740
+ const name = stringValue(read2(item, "name")) ?? "MCP call";
18741
+ const server = stringValue(read2(item, "server_label"));
18742
+ return {
18743
+ input: read2(item, "arguments"),
18744
+ tool: {
18745
+ itemId,
18746
+ name: server ? `${server}.${name}` : name,
18747
+ startTime: observedAt,
18748
+ toolType,
18749
+ ...turnId ? { turnId } : {}
18750
+ }
18751
+ };
18752
+ }
18753
+ case "web_search_call":
18754
+ return {
18755
+ input: read2(item, "action"),
18756
+ tool: {
18757
+ itemId,
18758
+ name: "Web search",
18759
+ startTime: observedAt,
18760
+ toolType,
18761
+ ...turnId ? { turnId } : {}
18762
+ }
18763
+ };
18764
+ case "command_execution":
18765
+ return {
18766
+ input: {
18767
+ command: read2(item, "command"),
18768
+ cwd: read2(item, "cwd")
18769
+ },
18770
+ tool: {
18771
+ itemId,
18772
+ name: "Command execution",
18773
+ startTime: observedAt,
18774
+ toolType,
18775
+ ...turnId ? { turnId } : {}
18776
+ }
18777
+ };
18778
+ default:
18779
+ return void 0;
18780
+ }
18781
+ }
18782
+ function textFromContent(content) {
18783
+ if (!Array.isArray(content)) {
18784
+ return void 0;
18785
+ }
18786
+ const text = [];
18787
+ for (const part of content) {
18788
+ const partText = read2(part, "text");
18789
+ if (read2(part, "type") === "output_text" && typeof partText === "string") {
18790
+ text.push(partText);
18791
+ }
18792
+ }
18793
+ return text.length > 0 ? text.join("") : void 0;
18794
+ }
18795
+ function toolOutput(item, toolType) {
18796
+ switch (toolType) {
18797
+ case "function_call":
18798
+ return read2(item, "output");
18799
+ case "mcp_call":
18800
+ return read2(item, "output");
18801
+ case "web_search_call":
18802
+ return read2(item, "action");
18803
+ case "command_execution":
18804
+ return read2(item, "output");
18805
+ default:
18806
+ return void 0;
18807
+ }
18808
+ }
18809
+ function toolFailed(item, toolType) {
18810
+ const status = read2(item, "status");
18811
+ const explicitError = read2(item, "error");
18812
+ if (explicitError !== void 0 && explicitError !== null) {
18813
+ return loggedError(explicitError, `OpenAI ${toolType} failed`);
18814
+ }
18815
+ if (status === "failed" || status === "incomplete") {
18816
+ return new Error(`OpenAI ${toolType} ${status}`);
18817
+ }
18818
+ if (toolType === "command_execution" && typeof read2(item, "exit_code") === "number" && read2(item, "exit_code") !== 0) {
18819
+ return new Error(
18820
+ `OpenAI command exited with code ${read2(item, "exit_code")}`
18821
+ );
18822
+ }
18823
+ return void 0;
18824
+ }
18825
+ async function completeTool(state, tool, item, endTime) {
18826
+ const span = await startToolSpan(state, tool);
18827
+ const output = toolOutput(item, tool.toolType);
18828
+ const error2 = toolFailed(item, tool.toolType);
18829
+ span.log({
18830
+ ...output !== void 0 ? { output } : {},
18831
+ ...error2 ? { error: error2 } : {},
18832
+ metadata: {
18833
+ status: read2(item, "status"),
18834
+ ...tool.toolType === "command_execution" ? { exit_code: read2(item, "exit_code") } : {}
18835
+ }
18836
+ });
18837
+ span.end({ endTime });
18838
+ Reflect.deleteProperty(state.openTools, tool.itemId);
18839
+ }
18840
+ async function captureMessage(state, item) {
18841
+ if (read2(item, "type") !== "message" || read2(item, "role") !== "assistant" || read2(item, "phase") !== "final_answer") {
18842
+ return;
18843
+ }
18844
+ const output = textFromContent(read2(item, "content"));
18845
+ if (output === void 0) {
18846
+ return;
18847
+ }
18848
+ const turnId = stringValue(read2(item, "turn_id"));
18849
+ const subagentId = turnId ? recordValue(state.turnSubagents, turnId) : void 0;
18850
+ if (subagentId) {
18851
+ (await startSubagentSpan(state, subagentId)).log({ output });
18852
+ } else {
18853
+ startRootSpan(state).log({ output });
18854
+ }
18855
+ }
18856
+ async function captureItem(state, item, isDone, observedAt) {
18857
+ await captureMessage(state, item);
18858
+ const itemType = stringValue(read2(item, "type"));
18859
+ if (itemType === "function_call_output") {
18860
+ const callId = stringValue(read2(item, "call_id"));
18861
+ const itemId = callId ? recordValue(state.callItems, callId) : void 0;
18862
+ const tool2 = itemId ? recordValue(state.openTools, itemId) : void 0;
18863
+ if (tool2) {
18864
+ await completeTool(state, tool2, item, observedAt);
18865
+ }
18866
+ return;
18867
+ }
18868
+ const descriptor = toolFromItem(item, observedAt);
18869
+ if (!descriptor) {
18870
+ return;
18871
+ }
18872
+ const existing = recordValue(state.openTools, descriptor.tool.itemId);
18873
+ const tool = existing ?? descriptor.tool;
18874
+ setRecordValue(state.openTools, tool.itemId, tool);
18875
+ if (itemType === "function_call") {
18876
+ const callId = stringValue(read2(item, "call_id"));
18877
+ if (callId) {
18878
+ setRecordValue(state.callItems, callId, tool.itemId);
18879
+ }
18880
+ }
18881
+ await startToolSpan(state, tool, descriptor.input);
18882
+ const status = read2(item, "status");
18883
+ const terminalFunctionCall = itemType === "function_call" && (status === "failed" || status === "incomplete");
18884
+ if (itemType !== "function_call" && (isDone || status !== "in_progress") || terminalFunctionCall) {
18885
+ await completeTool(state, tool, item, observedAt);
18886
+ }
18887
+ }
18888
+ function updateSessionMetadata(state, session) {
18889
+ const sessionId = stringValue(read2(session, "id"));
18890
+ const agent = read2(session, "agent");
18891
+ startRootSpan(state).log({
18892
+ metadata: {
18893
+ ...sessionId ? { session_id: sessionId } : {},
18894
+ ...stringValue(read2(agent, "id")) ? { agent_id: read2(agent, "id") } : {},
18895
+ ...stringValue(read2(agent, "name")) ? { agent_name: read2(agent, "name") } : {},
18896
+ ...stringValue(read2(agent, "model")) ? { model: read2(agent, "model") } : {}
18897
+ }
18898
+ });
18899
+ }
18900
+ async function captureSubagent(state, eventType, subagent, observedAt) {
18901
+ const subagentId = stringValue(read2(subagent, "id"));
18902
+ if (!subagentId) {
18903
+ return;
18904
+ }
18905
+ const existing = recordValue(state.subagents, subagentId);
18906
+ const observedOpenedAt = read2(subagent, "opened_at");
18907
+ const openedAt = typeof observedOpenedAt === "number" && Number.isFinite(observedOpenedAt) && observedOpenedAt >= 0 ? observedOpenedAt : existing?.openedAt ?? observedAt;
18908
+ const observedClosedAt = read2(subagent, "closed_at");
18909
+ const closedAt = typeof observedClosedAt === "number" && Number.isFinite(observedClosedAt) && observedClosedAt >= 0 ? observedClosedAt : existing?.closedAt;
18910
+ const parentAgentId = stringValue(read2(subagent, "parent_agent_id")) ?? existing?.parentAgentId;
18911
+ setRecordValue(state.subagents, subagentId, {
18912
+ ...closedAt !== void 0 ? { closedAt } : {},
18913
+ openedAt,
18914
+ ...parentAgentId ? { parentAgentId } : {}
18915
+ });
18916
+ const span = await startSubagentSpan(
18917
+ state,
18918
+ subagentId,
18919
+ read2(subagent, "instructions"),
18920
+ {
18921
+ ...stringValue(read2(subagent, "name")) ? { agent_name: read2(subagent, "name") } : {},
18922
+ status: read2(subagent, "status")
18923
+ }
18924
+ );
18925
+ if (eventType === "agent.session.subagent.closed") {
18926
+ span.end({ endTime: closedAt ?? observedAt });
18927
+ }
18928
+ }
18929
+ async function closeTrace(state, endTime, error2, usage) {
18930
+ if (state.ended) {
18931
+ return;
18932
+ }
18933
+ for (const tool of Object.values(state.openTools)) {
18934
+ const span = await startToolSpan(state, tool);
18935
+ span.log({
18936
+ error: error2 ?? new Error("OpenAI Agents turn ended before tool completion")
18937
+ });
18938
+ span.end({ endTime });
18939
+ }
18940
+ state.openTools = {};
18941
+ for (const subagentId of Object.keys(state.subagents)) {
18942
+ const subagent = state.subagents[subagentId];
18943
+ const span = await startSubagentSpan(state, subagentId);
18944
+ span.end({ endTime: subagent.closedAt ?? endTime });
18945
+ }
18946
+ const root = startRootSpan(state);
18947
+ root.log({
18948
+ ...error2 ? { error: error2 } : {},
18949
+ metrics: parseMetricsFromUsage(usage)
18950
+ });
18951
+ root.end({ endTime });
18952
+ state.ended = true;
18953
+ }
18954
+ async function captureTurnLifecycle(state, event, eventType, observedAt) {
18955
+ const turn = read2(event, "turn");
18956
+ const turnId = stringValue(read2(event, "turn_id")) ?? stringValue(read2(turn, "id"));
18957
+ const subagentId = stringValue(read2(turn, "subagent_id"));
18958
+ if (turnId && subagentId) {
18959
+ setRecordValue(state.turnSubagents, turnId, subagentId);
18960
+ if (!recordValue(state.subagents, subagentId)) {
18961
+ const createdAt = read2(turn, "created_at");
18962
+ setRecordValue(state.subagents, subagentId, {
18963
+ openedAt: typeof createdAt === "number" && Number.isFinite(createdAt) && createdAt >= 0 ? createdAt : observedAt
18964
+ });
18965
+ }
18966
+ await startSubagentSpan(state, subagentId);
18967
+ }
18968
+ const sessionId = stringValue(read2(event, "session_id"));
18969
+ if (sessionId) {
18970
+ startRootSpan(state).log({ metadata: { session_id: sessionId } });
18971
+ }
18972
+ if (!TERMINAL_TURN_EVENTS.has(eventType) || subagentId) {
18973
+ if (subagentId && eventType === "agent.session.turn.failed") {
18974
+ (await startSubagentSpan(state, subagentId)).log({
18975
+ error: loggedError(read2(turn, "error"), "OpenAI subagent turn failed")
18976
+ });
18977
+ }
18978
+ return;
18979
+ }
18980
+ const completedAt = read2(turn, "completed_at");
18981
+ const endTime = typeof completedAt === "number" && Number.isFinite(completedAt) && completedAt >= 0 ? completedAt : observedAt;
18982
+ const usage = read2(event, "usage") ?? read2(turn, "usage");
18983
+ const error2 = eventType === "agent.session.turn.completed" ? void 0 : loggedError(
18984
+ read2(turn, "error"),
18985
+ eventType === "agent.session.turn.cancelled" ? "OpenAI Agents turn cancelled" : "OpenAI Agents turn failed"
18986
+ );
18987
+ await closeTrace(state, endTime, error2, usage);
18988
+ }
18989
+ async function captureEvent(state, event) {
18990
+ if (state.ended) {
18991
+ return state;
18992
+ }
18993
+ const eventType = stringValue(read2(event, "type"));
18994
+ const eventId = stringValue(read2(event, "event_id"));
18995
+ if (!eventType || eventId && state.eventIds.includes(eventId)) {
18996
+ return state;
18997
+ }
18998
+ const next = copyState(state);
18999
+ const observedAt = getCurrentUnixTimestamp();
19000
+ let handled = false;
19001
+ if (SESSION_EVENTS.has(eventType)) {
19002
+ const session = read2(event, "session");
19003
+ if (session) {
19004
+ updateSessionMetadata(next, session);
19005
+ }
19006
+ handled = true;
19007
+ }
19008
+ if (eventType === "agent.session.turn.item.added") {
19009
+ await captureItem(next, read2(event, "item"), false, observedAt);
19010
+ handled = true;
19011
+ } else if (eventType === "agent.session.turn.item.done") {
19012
+ await captureItem(next, read2(event, "item"), true, observedAt);
19013
+ handled = true;
19014
+ } else if (TURN_LIFECYCLE_EVENTS.has(eventType)) {
19015
+ await captureTurnLifecycle(next, event, eventType, observedAt);
19016
+ handled = true;
19017
+ } else if (SUBAGENT_EVENTS.has(eventType)) {
19018
+ await captureSubagent(next, eventType, read2(event, "subagent"), observedAt);
19019
+ handled = true;
19020
+ } else if (eventType === "agent.session.turn.output_text.delta" && next.firstTokenAt === void 0 && stringValue(read2(event, "delta"))) {
19021
+ next.firstTokenAt = observedAt;
19022
+ startRootSpan(next).log({
19023
+ metrics: { time_to_first_token: observedAt - next.startTime }
19024
+ });
19025
+ handled = true;
19026
+ } else if (eventType === "agent.session.failed") {
19027
+ const session = read2(event, "session");
19028
+ const lastActiveAt = read2(session, "last_active_at");
19029
+ const endTime = typeof lastActiveAt === "number" && Number.isFinite(lastActiveAt) && lastActiveAt >= 0 ? lastActiveAt : observedAt;
19030
+ await closeTrace(
19031
+ next,
19032
+ endTime,
19033
+ loggedError(read2(session, "error"), "OpenAI Agents session failed"),
19034
+ read2(session, "usage")
19035
+ );
19036
+ handled = true;
19037
+ } else if (eventType === "error") {
19038
+ await closeTrace(
19039
+ next,
19040
+ observedAt,
19041
+ loggedError(read2(event, "error"), "OpenAI Agents session failed")
19042
+ );
19043
+ handled = true;
19044
+ }
19045
+ if (!handled) {
19046
+ return state;
19047
+ }
19048
+ if (eventId) {
19049
+ next.eventIds.push(eventId);
19050
+ }
19051
+ return next;
19052
+ }
19053
+ var interceptOpenAIAgentsTraceStart = async (target, thisArg, args) => {
19054
+ const fallback2 = await Reflect.apply(target, thisArg, args);
19055
+ try {
19056
+ const state = args[0].state;
19057
+ const parent = state.rootParent;
19058
+ const traceArgs = args[0].args;
19059
+ const parentComponents = SpanComponentsV4.fromStr(parent);
19060
+ const hasParentSpan = Boolean(
19061
+ parentComponents.data.row_id && parentComponents.data.span_id && parentComponents.data.root_span_id
19062
+ );
19063
+ const rootComponents = SpanComponentsV4.fromStr(state.root);
19064
+ const rowId = stringValue(rootComponents.data.row_id);
19065
+ const rootSpanId = stringValue(rootComponents.data.root_span_id);
19066
+ const spanId = stringValue(rootComponents.data.span_id);
19067
+ if (!rowId || !rootSpanId || !spanId) {
19068
+ throw new Error("OpenAI Agents trace root is invalid");
19069
+ }
19070
+ withCurrent(
19071
+ NOOP_SPAN,
19072
+ () => _internalStartSpanWithInitialMergeAndParentSpanIds(
19073
+ withSpanInstrumentationName(
19074
+ {
19075
+ name: "openai.agents.turn",
19076
+ type: "task" /* TASK */,
19077
+ parent,
19078
+ ...!hasParentSpan ? {
19079
+ parentSpanIds: {
19080
+ parentSpanIds: [],
19081
+ rootSpanId
19082
+ }
19083
+ } : {},
19084
+ spanId,
19085
+ startTime: state.startTime,
19086
+ event: {
19087
+ id: rowId,
19088
+ input: read2(traceArgs, "input"),
19089
+ metadata: traceMetadata(traceArgs)
19090
+ }
19091
+ },
19092
+ INSTRUMENTATION_NAMES.OPENAI
19093
+ )
19094
+ )
19095
+ );
19096
+ return state;
19097
+ } catch (error2) {
19098
+ logInstrumentationError("could not start trace", error2);
19099
+ return fallback2;
19100
+ }
19101
+ };
19102
+ var interceptOpenAIAgentsTraceCapture = async (target, thisArg, args) => {
19103
+ const fallback2 = await Reflect.apply(target, thisArg, args);
19104
+ if (!args[0].state) {
19105
+ return fallback2;
19106
+ }
19107
+ try {
19108
+ return await captureEvent(args[0].state, args[0].event);
19109
+ } catch (error2) {
19110
+ logInstrumentationError("could not capture event", error2);
19111
+ return fallback2;
19112
+ }
19113
+ };
19114
+ var interceptOpenAIAgentsTraceFail = async (target, thisArg, args) => {
19115
+ const fallback2 = await Reflect.apply(target, thisArg, args);
19116
+ if (!args[0].state) {
19117
+ return fallback2;
19118
+ }
19119
+ try {
19120
+ const next = copyState(args[0].state);
19121
+ await closeTrace(
19122
+ next,
19123
+ getCurrentUnixTimestamp(),
19124
+ loggedError(args[0].error, "OpenAI Agents request failed")
19125
+ );
19126
+ return next;
19127
+ } catch (error2) {
19128
+ logInstrumentationError("could not fail trace", error2);
19129
+ return fallback2;
19130
+ }
19131
+ };
19132
+
18186
19133
  // src/instrumentation/plugins/openai-plugin.ts
18187
19134
  var OpenAIPlugin = class extends BasePlugin {
18188
19135
  constructor() {
@@ -18190,6 +19137,13 @@ var OpenAIPlugin = class extends BasePlugin {
18190
19137
  }
18191
19138
  onEnable() {
18192
19139
  this.unsubscribers.push(
19140
+ openAIChannels.agentsTraceStart.intercept(
19141
+ interceptOpenAIAgentsTraceStart
19142
+ ),
19143
+ openAIChannels.agentsTraceCapture.intercept(
19144
+ interceptOpenAIAgentsTraceCapture
19145
+ ),
19146
+ openAIChannels.agentsTraceFail.intercept(interceptOpenAIAgentsTraceFail),
18193
19147
  openAIChannels.filesCreateTraced.intercept(
18194
19148
  interceptOpenAIFilesCreateTraced
18195
19149
  ),
@@ -18750,7 +19704,7 @@ async function* patchCodexEventStream(events, state) {
18750
19704
  try {
18751
19705
  await handleCodexEvent(state, event);
18752
19706
  } catch (error2) {
18753
- logInstrumentationError("OpenAI Codex stream event", error2);
19707
+ logInstrumentationError2("OpenAI Codex stream event", error2);
18754
19708
  }
18755
19709
  yield event;
18756
19710
  }
@@ -19250,10 +20204,10 @@ function safeLog(span, event) {
19250
20204
  try {
19251
20205
  span.log(event);
19252
20206
  } catch (error2) {
19253
- logInstrumentationError("OpenAI Codex span log", error2);
20207
+ logInstrumentationError2("OpenAI Codex span log", error2);
19254
20208
  }
19255
20209
  }
19256
- function logInstrumentationError(context2, error2) {
20210
+ function logInstrumentationError2(context2, error2) {
19257
20211
  debugLogger.error(`Error processing ${context2}:`, error2);
19258
20212
  }
19259
20213
 
@@ -20635,27 +21589,8 @@ function continuationParentFromCreateSessionParams(params) {
20635
21589
  }
20636
21590
  return context2.parent;
20637
21591
  }
20638
- function exportSpanSynchronously(span) {
20639
- const parentInfo = span.getParentInfo();
20640
- if (!parentInfo) {
20641
- return void 0;
20642
- }
20643
- const objectId = parentInfo.objectId.getSync().value;
20644
- if (!objectId && !parentInfo.computeObjectMetadataArgs) {
20645
- return void 0;
20646
- }
20647
- return new SpanComponentsV4({
20648
- object_type: parentInfo.objectType,
20649
- ...objectId ? { object_id: objectId } : {
20650
- compute_object_metadata_args: parentInfo.computeObjectMetadataArgs ?? {}
20651
- },
20652
- row_id: span.id,
20653
- root_span_id: span.rootSpanId,
20654
- span_id: span.spanId
20655
- }).toStr();
20656
- }
20657
21592
  function exportedParent(parent) {
20658
- return typeof parent === "string" ? parent : exportSpanSynchronously(parent);
21593
+ return typeof parent === "string" ? parent : _internalExportParentSynchronously(parent);
20659
21594
  }
20660
21595
  function addSerializedContext(args) {
20661
21596
  if (!isObject(args.continuation) || args.sessionId === void 0) {
@@ -21412,16 +22347,16 @@ function braintrustAISDKTelemetry() {
21412
22347
  if (!toolCallId || !state) {
21413
22348
  return;
21414
22349
  }
21415
- const toolOutput = event.toolOutput;
22350
+ const toolOutput2 = event.toolOutput;
21416
22351
  const workflowToolError = event.success === false && "error" in event ? event.error : void 0;
21417
- if (toolOutput?.type === "tool-error" || workflowToolError !== void 0) {
21418
- const error2 = toolOutput?.error ?? workflowToolError;
22352
+ if (toolOutput2?.type === "tool-error" || workflowToolError !== void 0) {
22353
+ const error2 = toolOutput2?.error ?? workflowToolError;
21419
22354
  state.span.log({
21420
22355
  error: error2 instanceof Error ? error2.message : String(error2),
21421
22356
  metrics: typeof event.durationMs === "number" ? { duration_ms: event.durationMs } : {}
21422
22357
  });
21423
22358
  } else {
21424
- const output = toolOutput && "output" in toolOutput ? toolOutput.output : event.output;
22359
+ const output = toolOutput2 && "output" in toolOutput2 ? toolOutput2.output : event.output;
21425
22360
  state.span.log({
21426
22361
  ...shouldRecordOutputs(event) ? { output } : {},
21427
22362
  metrics: typeof event.durationMs === "number" ? { duration_ms: event.durationMs } : {}
@@ -23880,9 +24815,9 @@ function patchAISDKStreamingResult(args) {
23880
24815
  }
23881
24816
  finalize({ metrics, output });
23882
24817
  } catch (error2) {
23883
- const loggedError = toLoggedError(error2);
24818
+ const loggedError2 = toLoggedError(error2);
23884
24819
  try {
23885
- span.log({ error: loggedError });
24820
+ span.log({ error: loggedError2 });
23886
24821
  } catch (loggingError) {
23887
24822
  debugLogger.error(
23888
24823
  "Error logging AI SDK streaming failure:",
@@ -23890,7 +24825,7 @@ function patchAISDKStreamingResult(args) {
23890
24825
  );
23891
24826
  }
23892
24827
  finalize({
23893
- error: error2 instanceof Error ? error2 : new Error(String(loggedError))
24828
+ error: error2 instanceof Error ? error2 : new Error(String(loggedError2))
23894
24829
  });
23895
24830
  }
23896
24831
  };
@@ -24003,9 +24938,9 @@ function patchAISDKStreamingResult(args) {
24003
24938
  }
24004
24939
  controller.enqueue(value);
24005
24940
  } catch (error2) {
24006
- const loggedError = toLoggedError(error2);
24941
+ const loggedError2 = toLoggedError(error2);
24007
24942
  try {
24008
- span.log({ error: loggedError });
24943
+ span.log({ error: loggedError2 });
24009
24944
  } catch (loggingError) {
24010
24945
  debugLogger.error(
24011
24946
  "Error logging AI SDK base stream failure:",
@@ -24013,7 +24948,7 @@ function patchAISDKStreamingResult(args) {
24013
24948
  );
24014
24949
  }
24015
24950
  finalize({
24016
- error: error2 instanceof Error ? error2 : new Error(String(loggedError))
24951
+ error: error2 instanceof Error ? error2 : new Error(String(loggedError2))
24017
24952
  });
24018
24953
  controller.error(error2);
24019
24954
  }
@@ -26907,7 +27842,7 @@ function wrapSendOptionsCallbacks(options, state) {
26907
27842
  try {
26908
27843
  await handleInteractionUpdate(state, args.update);
26909
27844
  } catch (error2) {
26910
- logInstrumentationError2("Cursor SDK onDelta", error2);
27845
+ logInstrumentationError3("Cursor SDK onDelta", error2);
26911
27846
  }
26912
27847
  if (originalOnDelta) {
26913
27848
  return originalOnDelta(args);
@@ -26917,7 +27852,7 @@ function wrapSendOptionsCallbacks(options, state) {
26917
27852
  try {
26918
27853
  handleStepUpdate(state, args.step);
26919
27854
  } catch (error2) {
26920
- logInstrumentationError2("Cursor SDK onStep", error2);
27855
+ logInstrumentationError3("Cursor SDK onStep", error2);
26921
27856
  }
26922
27857
  if (originalOnStep) {
26923
27858
  return originalOnStep(args);
@@ -26999,7 +27934,7 @@ async function* patchCursorStream(stream, state) {
26999
27934
  try {
27000
27935
  await handleStreamMessage2(state, message);
27001
27936
  } catch (error2) {
27002
- logInstrumentationError2("Cursor SDK stream", error2);
27937
+ logInstrumentationError3("Cursor SDK stream", error2);
27003
27938
  }
27004
27939
  yield message;
27005
27940
  }
@@ -27063,7 +27998,7 @@ async function handleToolUpdate(state, update) {
27063
27998
  if (!state.activeToolSpans.has(callId)) {
27064
27999
  state.activeToolSpans.set(
27065
28000
  callId,
27066
- await startToolSpan(state, {
28001
+ await startToolSpan2(state, {
27067
28002
  args,
27068
28003
  callId,
27069
28004
  name,
@@ -27074,7 +28009,7 @@ async function handleToolUpdate(state, update) {
27074
28009
  }
27075
28010
  return;
27076
28011
  }
27077
- const toolState = state.activeToolSpans.get(callId) ?? await startToolSpan(state, {
28012
+ const toolState = state.activeToolSpans.get(callId) ?? await startToolSpan2(state, {
27078
28013
  args,
27079
28014
  callId,
27080
28015
  name,
@@ -27111,7 +28046,7 @@ async function handleStreamMessage2(state, message) {
27111
28046
  } else if (block?.type === "tool_use" && block.id) {
27112
28047
  state.activeToolSpans.set(
27113
28048
  block.id,
27114
- await startToolSpan(state, {
28049
+ await startToolSpan2(state, {
27115
28050
  args: block.input,
27116
28051
  callId: block.id,
27117
28052
  name: block.name,
@@ -27146,7 +28081,7 @@ async function handleToolMessage(state, message) {
27146
28081
  if (!state.activeToolSpans.has(callId)) {
27147
28082
  state.activeToolSpans.set(
27148
28083
  callId,
27149
- await startToolSpan(state, {
28084
+ await startToolSpan2(state, {
27150
28085
  args: message.args,
27151
28086
  callId,
27152
28087
  name: message.name,
@@ -27157,7 +28092,7 @@ async function handleToolMessage(state, message) {
27157
28092
  }
27158
28093
  return;
27159
28094
  }
27160
- const toolState = state.activeToolSpans.get(callId) ?? await startToolSpan(state, {
28095
+ const toolState = state.activeToolSpans.get(callId) ?? await startToolSpan2(state, {
27161
28096
  args: message.args,
27162
28097
  callId,
27163
28098
  name: message.name,
@@ -27184,7 +28119,7 @@ async function handleConversation(state, turns) {
27184
28119
  const command = turn.turn?.shellCommand?.command;
27185
28120
  if (command) {
27186
28121
  const callId = `shell:${state.activeToolSpans.size}:${command}`;
27187
- const toolState = await startToolSpan(state, {
28122
+ const toolState = await startToolSpan2(state, {
27188
28123
  args: turn.turn?.shellCommand,
27189
28124
  callId,
27190
28125
  name: "shell",
@@ -27208,7 +28143,7 @@ async function handleConversationStep(state, step) {
27208
28143
  }
27209
28144
  const toolCall = step.message;
27210
28145
  const callId = typeof toolCall?.callId === "string" ? toolCall.callId : `conversation-tool:${state.activeToolSpans.size}`;
27211
- const toolState = await startToolSpan(state, {
28146
+ const toolState = await startToolSpan2(state, {
27212
28147
  args: extractToolArgs(toolCall),
27213
28148
  callId,
27214
28149
  name: extractToolName(toolCall),
@@ -27239,7 +28174,7 @@ function handleStepUpdate(state, step) {
27239
28174
  state.stepText.push(step.message.text);
27240
28175
  }
27241
28176
  }
27242
- async function startToolSpan(state, args) {
28177
+ async function startToolSpan2(state, args) {
27243
28178
  const name = args.name || "unknown";
27244
28179
  const metadata = {
27245
28180
  "cursor_sdk.tool.status": args.status,
@@ -27526,10 +28461,10 @@ function safeLog2(span, event) {
27526
28461
  try {
27527
28462
  span.log(event);
27528
28463
  } catch (error2) {
27529
- logInstrumentationError2("Cursor SDK span log", error2);
28464
+ logInstrumentationError3("Cursor SDK span log", error2);
27530
28465
  }
27531
28466
  }
27532
- function logInstrumentationError2(context2, error2) {
28467
+ function logInstrumentationError3(context2, error2) {
27533
28468
  debugLogger.error(`Error processing ${context2}:`, error2);
27534
28469
  }
27535
28470
  function cleanMetrics2(metrics) {
@@ -28015,6 +28950,342 @@ var OpenAIAgentsPlugin = class extends BasePlugin {
28015
28950
  }
28016
28951
  };
28017
28952
 
28953
+ // src/instrumentation/plugins/google-generative-ai-channels.ts
28954
+ var googleGenerativeAIChannels = defineChannels(
28955
+ "@google/generative-ai",
28956
+ {
28957
+ generateContent: channel({ channelName: "GenerativeModel.generateContent", kind: "async" }),
28958
+ generateContentStream: channel({ channelName: "GenerativeModel.generateContentStream", kind: "async" }),
28959
+ embedContent: channel({ channelName: "GenerativeModel.embedContent", kind: "async" }),
28960
+ batchEmbedContents: channel({ channelName: "GenerativeModel.batchEmbedContents", kind: "async" }),
28961
+ sendMessage: channel({ channelName: "ChatSession.sendMessage", kind: "async" }),
28962
+ sendMessageStream: channel({ channelName: "ChatSession.sendMessageStream", kind: "async" })
28963
+ },
28964
+ { instrumentationName: INSTRUMENTATION_NAMES.GOOGLE_GENERATIVE_AI }
28965
+ );
28966
+
28967
+ // src/instrumentation/plugins/google-generative-ai-plugin.ts
28968
+ var GENERATION_CONFIG_KEYS = [
28969
+ "temperature",
28970
+ "topP",
28971
+ "topK",
28972
+ "candidateCount",
28973
+ "maxOutputTokens",
28974
+ "stopSequences",
28975
+ "responseMimeType",
28976
+ "responseSchema",
28977
+ "presencePenalty",
28978
+ "frequencyPenalty",
28979
+ "responseLogprobs",
28980
+ "logprobs",
28981
+ "thinkingConfig"
28982
+ ];
28983
+ var GoogleGenerativeAIPlugin = class extends BasePlugin {
28984
+ onEnable() {
28985
+ this.unsubscribers.push(
28986
+ interceptCall(
28987
+ googleGenerativeAIChannels.generateContent,
28988
+ "generateContent"
28989
+ ),
28990
+ interceptCall(
28991
+ googleGenerativeAIChannels.generateContentStream,
28992
+ "generateContentStream"
28993
+ ),
28994
+ interceptCall(googleGenerativeAIChannels.sendMessage, "sendMessage"),
28995
+ interceptCall(
28996
+ googleGenerativeAIChannels.sendMessageStream,
28997
+ "sendMessageStream"
28998
+ ),
28999
+ interceptCall(googleGenerativeAIChannels.embedContent, "embedContent"),
29000
+ interceptCall(
29001
+ googleGenerativeAIChannels.batchEmbedContents,
29002
+ "batchEmbedContents"
29003
+ )
29004
+ );
29005
+ }
29006
+ onDisable() {
29007
+ this.unsubscribers = unsubscribeAll(this.unsubscribers);
29008
+ }
29009
+ };
29010
+ function interceptCall(channel2, operation) {
29011
+ return channel2.intercept((target, thisArg, args) => {
29012
+ const invokeTarget = () => Reflect.apply(target, thisArg, args);
29013
+ if (isAutoInstrumentationSuppressed()) return invokeTarget();
29014
+ const self = thisArg;
29015
+ const chat = operation.startsWith("sendMessage");
29016
+ const embedding = operation === "embedContent" || operation === "batchEmbedContents";
29017
+ const start = getCurrentUnixTimestamp();
29018
+ let span;
29019
+ try {
29020
+ span = startSpan(
29021
+ withSpanInstrumentationName(
29022
+ {
29023
+ name: embedding ? operation === "embedContent" ? "embed_content" : "batch_embed_contents" : "generate_content",
29024
+ spanAttributes: { type: "llm" /* LLM */ },
29025
+ event: extractInput(self, args[0], operation)
29026
+ },
29027
+ INSTRUMENTATION_NAMES.GOOGLE_GENERATIVE_AI
29028
+ )
29029
+ );
29030
+ } catch (error2) {
29031
+ debugLogger.error("Error starting Google Generative AI span:", error2);
29032
+ return invokeTarget();
29033
+ }
29034
+ let ended = false;
29035
+ const finish = (log2) => {
29036
+ if (ended) return;
29037
+ ended = true;
29038
+ try {
29039
+ log2();
29040
+ } catch (error2) {
29041
+ debugLogger.error("Error logging Google Generative AI span:", error2);
29042
+ }
29043
+ try {
29044
+ span.end();
29045
+ } catch (error2) {
29046
+ debugLogger.error("Error ending Google Generative AI span:", error2);
29047
+ }
29048
+ };
29049
+ if (chat) {
29050
+ try {
29051
+ void self._sendPromise.then(
29052
+ () => {
29053
+ try {
29054
+ span.log(extractInput(self, args[0], operation));
29055
+ } catch (error2) {
29056
+ debugLogger.error("Error capturing Google chat history:", error2);
29057
+ }
29058
+ },
29059
+ () => {
29060
+ }
29061
+ );
29062
+ } catch (error2) {
29063
+ debugLogger.error("Error observing Google chat history:", error2);
29064
+ }
29065
+ }
29066
+ let result;
29067
+ try {
29068
+ result = withCurrent(
29069
+ span,
29070
+ () => runWithAutoInstrumentationSuppressed(invokeTarget)
29071
+ );
29072
+ } catch (error2) {
29073
+ finish(() => span.log({ error: error2 }));
29074
+ throw error2;
29075
+ }
29076
+ void Promise.resolve(result).then(
29077
+ (value) => {
29078
+ try {
29079
+ if ("stream" in value) {
29080
+ let firstToken = false;
29081
+ const partial = { candidates: [] };
29082
+ const candidates = /* @__PURE__ */ new Map();
29083
+ patchStreamIfNeeded(value.stream, {
29084
+ aroundNext: (callback) => withCurrent(span, callback),
29085
+ onChunk: (chunk) => {
29086
+ for (const candidate of chunk.candidates ?? []) {
29087
+ const index = candidate.index ?? 0;
29088
+ const previous = candidates.get(index);
29089
+ const parts = [...previous?.content?.parts ?? []];
29090
+ for (const part of candidate.content?.parts ?? []) {
29091
+ const last = parts[parts.length - 1];
29092
+ if (part.text !== void 0 && last?.text !== void 0) {
29093
+ parts[parts.length - 1] = {
29094
+ ...last,
29095
+ text: last.text + part.text
29096
+ };
29097
+ } else parts.push(part);
29098
+ }
29099
+ candidates.set(index, {
29100
+ ...previous,
29101
+ ...candidate,
29102
+ content: {
29103
+ role: candidate.content?.role ?? previous?.content?.role ?? "model",
29104
+ parts
29105
+ }
29106
+ });
29107
+ }
29108
+ partial.candidates = Array.from(candidates.values());
29109
+ if (chunk.usageMetadata)
29110
+ partial.usageMetadata = chunk.usageMetadata;
29111
+ if (!firstToken && chunk.candidates?.some(
29112
+ (candidate) => candidate.content?.parts.some(
29113
+ (part) => part.text !== void 0 ? part.text.length > 0 : Object.keys(part).length > 0
29114
+ )
29115
+ )) {
29116
+ firstToken = true;
29117
+ span.log({
29118
+ metrics: {
29119
+ time_to_first_token: getCurrentUnixTimestamp() - start
29120
+ }
29121
+ });
29122
+ }
29123
+ },
29124
+ onComplete: () => {
29125
+ },
29126
+ onError: (error2) => finish(() => {
29127
+ logResponse(span, partial);
29128
+ span.log({ error: error2 });
29129
+ }),
29130
+ onCancel: () => finish(() => logResponse(span, partial))
29131
+ });
29132
+ void value.response.then(
29133
+ (response) => finish(() => logResponse(span, response)),
29134
+ (error2) => finish(() => {
29135
+ logResponse(span, partial);
29136
+ span.log({ error: error2 });
29137
+ })
29138
+ );
29139
+ } else if ("response" in value) {
29140
+ finish(() => logResponse(span, value.response));
29141
+ } else {
29142
+ const metrics = {};
29143
+ const promptTokens = value.usageMetadata?.promptTokenCount;
29144
+ if (typeof promptTokens === "number" && Number.isFinite(promptTokens) && promptTokens >= 0) {
29145
+ metrics.prompt_tokens = promptTokens;
29146
+ metrics.tokens = promptTokens;
29147
+ }
29148
+ for (const detail of value.usageMetadata?.promptTokenDetails ?? []) {
29149
+ if (detail.modality === "AUDIO" && typeof detail.tokenCount === "number" && Number.isFinite(detail.tokenCount) && detail.tokenCount >= 0) {
29150
+ metrics.prompt_audio_tokens = (metrics.prompt_audio_tokens ?? 0) + detail.tokenCount;
29151
+ }
29152
+ }
29153
+ finish(
29154
+ () => span.log({
29155
+ metrics,
29156
+ output: {
29157
+ count: value.embeddings?.length ?? (value.embedding ? 1 : 0)
29158
+ }
29159
+ })
29160
+ );
29161
+ }
29162
+ } catch (error2) {
29163
+ debugLogger.error(
29164
+ "Error observing Google Generative AI result:",
29165
+ error2
29166
+ );
29167
+ finish(() => {
29168
+ });
29169
+ }
29170
+ },
29171
+ (error2) => finish(() => span.log({ error: error2 }))
29172
+ );
29173
+ return result;
29174
+ });
29175
+ }
29176
+ function normalizeContent(message) {
29177
+ const parts = (typeof message === "string" ? [message] : message).map(
29178
+ (part) => typeof part === "string" ? { text: part } : part
29179
+ );
29180
+ return {
29181
+ role: parts.some((part) => part.functionResponse) ? "function" : "user",
29182
+ parts
29183
+ };
29184
+ }
29185
+ function extractInput(self, request, operation) {
29186
+ const model = self.model.replace(/^models\//, "");
29187
+ if (operation === "embedContent" || operation === "batchEmbedContents") {
29188
+ const requests = operation === "batchEmbedContents" ? request.requests : [
29189
+ typeof request === "string" || Array.isArray(request) ? { content: normalizeContent(request) } : request
29190
+ ];
29191
+ const dimensions = requests[0]?.outputDimensionality;
29192
+ return {
29193
+ input: {
29194
+ inputs: convertAttachments(requests).map((item) => ({
29195
+ content: item.content.parts.length === 1 && item.content.parts[0].text !== void 0 ? item.content.parts[0].text : item.content.parts.map((part) => {
29196
+ if (part.text !== void 0)
29197
+ return { type: "text", text: part.text };
29198
+ const mimeType = part.inlineData?.mimeType ?? part.fileData?.mimeType;
29199
+ const data = part.inlineData ? typeof part.inlineData.data === "string" ? `data:${mimeType};base64,${part.inlineData.data}` : part.inlineData.data : part.fileData?.fileUri;
29200
+ return mimeType?.startsWith("image/") ? { type: "image_url", image_url: { url: data } } : { type: "file", file: { file_data: data } };
29201
+ })
29202
+ })),
29203
+ ...dimensions !== void 0 && requests.every((item) => item.outputDimensionality === dimensions) ? { output_dimensions: dimensions } : {}
29204
+ },
29205
+ metadata: { model, provider: "google" }
29206
+ };
29207
+ }
29208
+ const chat = operation.startsWith("sendMessage");
29209
+ const config3 = chat ? self.params ?? {} : self;
29210
+ const params = typeof request === "string" || Array.isArray(request) ? { contents: [normalizeContent(request)] } : request;
29211
+ const system = params.systemInstruction ?? config3.systemInstruction;
29212
+ const systemContent = typeof system === "string" ? { role: "system", parts: [{ text: system }] } : system && "parts" in system ? { ...system, role: "system" } : system ? { role: "system", parts: [system] } : void 0;
29213
+ const contents = [
29214
+ ...systemContent ? [systemContent] : [],
29215
+ ...chat ? self._history : [],
29216
+ ...params.contents
29217
+ ];
29218
+ const metadata = { model, provider: "google" };
29219
+ const generation = params.generationConfig ?? config3.generationConfig;
29220
+ for (const key of GENERATION_CONFIG_KEYS) {
29221
+ if (generation && Object.hasOwn(generation, key))
29222
+ metadata[key] = generation[key];
29223
+ }
29224
+ for (const key of ["tools", "toolConfig", "safetySettings"]) {
29225
+ const value = params[key] ?? config3[key];
29226
+ if (value !== void 0) metadata[key] = value;
29227
+ }
29228
+ const cached = params.cachedContent ?? config3.cachedContent;
29229
+ if (cached)
29230
+ metadata.cachedContent = typeof cached === "string" ? cached : cached.name;
29231
+ return { input: convertAttachments({ model, contents }), metadata };
29232
+ }
29233
+ function convertAttachments(value) {
29234
+ const convert = (node) => {
29235
+ if (Array.isArray(node)) return node.map(convert);
29236
+ if (!isObject(node)) return node;
29237
+ if (isObject(node.inlineData)) {
29238
+ const { data, mimeType } = node.inlineData;
29239
+ const processed = processInputAttachments({
29240
+ type: "file",
29241
+ file: { file_data: `data:${mimeType};base64,${data}` }
29242
+ });
29243
+ if (typeof processed.file.file_data === "string")
29244
+ throw new Error("Unable to convert Google inline data");
29245
+ return {
29246
+ ...node,
29247
+ inlineData: { ...node.inlineData, data: processed.file.file_data }
29248
+ };
29249
+ }
29250
+ return Object.fromEntries(
29251
+ Object.entries(node).map(([key, item]) => [key, convert(item)])
29252
+ );
29253
+ };
29254
+ try {
29255
+ return convert(value);
29256
+ } catch (error2) {
29257
+ debugLogger.error(
29258
+ "Error converting Google Generative AI attachments:",
29259
+ error2
29260
+ );
29261
+ return value;
29262
+ }
29263
+ }
29264
+ function logResponse(span, response) {
29265
+ const usage = response.usageMetadata;
29266
+ const metrics = {};
29267
+ if (usage) {
29268
+ if (usage.promptTokenCount !== void 0)
29269
+ metrics.prompt_tokens = usage.promptTokenCount;
29270
+ if (usage.candidatesTokenCount !== void 0 || usage.thoughtsTokenCount !== void 0)
29271
+ metrics.completion_tokens = (usage.candidatesTokenCount ?? 0) + (usage.thoughtsTokenCount ?? 0);
29272
+ if (usage.totalTokenCount !== void 0)
29273
+ metrics.tokens = usage.totalTokenCount;
29274
+ if (usage.cachedContentTokenCount !== void 0)
29275
+ metrics.prompt_cached_tokens = usage.cachedContentTokenCount;
29276
+ if (usage.thoughtsTokenCount !== void 0)
29277
+ metrics.completion_reasoning_tokens = usage.thoughtsTokenCount;
29278
+ }
29279
+ span.log({
29280
+ output: convertAttachments({
29281
+ candidates: response.candidates,
29282
+ promptFeedback: response.promptFeedback
29283
+ }),
29284
+ metrics,
29285
+ ...response.modelVersion ? { metadata: { model: response.modelVersion } } : {}
29286
+ });
29287
+ }
29288
+
28018
29289
  // src/instrumentation/plugins/google-genai-channels.ts
28019
29290
  var googleGenAIChannels = defineChannels(
28020
29291
  "@google/genai",
@@ -28031,6 +29302,10 @@ var googleGenAIChannels = defineChannels(
28031
29302
  channelName: "models.embedContent",
28032
29303
  kind: "async"
28033
29304
  }),
29305
+ httpResponseJson: channel({
29306
+ channelName: "httpResponse.json",
29307
+ kind: "async"
29308
+ }),
28034
29309
  interactionsCreate: channel({
28035
29310
  channelName: "interactions.create",
28036
29311
  kind: "async"
@@ -28179,13 +29454,45 @@ var GoogleGenAIPlugin = class extends BasePlugin {
28179
29454
  subscribeToEmbedContentChannel() {
28180
29455
  const tracingChannel = googleGenAIChannels.embedContent.tracingChannel();
28181
29456
  const states = /* @__PURE__ */ new WeakMap();
29457
+ const embeddingSpans = /* @__PURE__ */ new WeakSet();
29458
+ this.unsubscribers.push(
29459
+ googleGenAIChannels.httpResponseJson.intercept(
29460
+ (target, thisArg, args) => {
29461
+ const span = currentSpan();
29462
+ const result = Reflect.apply(target, thisArg, args);
29463
+ if (embeddingSpans.has(span)) {
29464
+ void Promise.resolve(result).then(
29465
+ (response) => {
29466
+ try {
29467
+ const metrics = cleanMetrics3(
29468
+ extractEmbedContentMetrics(response)
29469
+ );
29470
+ if (embeddingSpans.has(span) && Object.keys(metrics).length > 0) {
29471
+ span.log({ metrics });
29472
+ }
29473
+ } catch (error2) {
29474
+ debugLogger.error(
29475
+ "Error reading Google GenAI embedding usage:",
29476
+ error2
29477
+ );
29478
+ }
29479
+ },
29480
+ () => {
29481
+ }
29482
+ // The embedding channel handles the original rejection.
29483
+ );
29484
+ }
29485
+ return result;
29486
+ }
29487
+ )
29488
+ );
28182
29489
  const unbindCurrentSpanStore = bindCurrentSpanStoreToStart2(
28183
29490
  tracingChannel,
28184
29491
  states,
28185
29492
  (event) => {
28186
29493
  const params = event.arguments[0];
28187
29494
  const input = serializeEmbedContentInput(params);
28188
- const metadata = extractEmbedContentMetadata(params);
29495
+ const metadata = { provider: "google", model: params.model };
28189
29496
  const span = startSpan(
28190
29497
  withSpanInstrumentationName(
28191
29498
  {
@@ -28198,6 +29505,7 @@ var GoogleGenAIPlugin = class extends BasePlugin {
28198
29505
  INSTRUMENTATION_NAMES.GOOGLE_GENAI
28199
29506
  )
28200
29507
  );
29508
+ embeddingSpans.add(span);
28201
29509
  return {
28202
29510
  span,
28203
29511
  startTime: getCurrentUnixTimestamp()
@@ -28209,7 +29517,7 @@ var GoogleGenAIPlugin = class extends BasePlugin {
28209
29517
  ensureSpanState(states, event, () => {
28210
29518
  const params = event.arguments[0];
28211
29519
  const input = serializeEmbedContentInput(params);
28212
- const metadata = extractEmbedContentMetadata(params);
29520
+ const metadata = { provider: "google", model: params.model };
28213
29521
  const span = startSpan(
28214
29522
  withSpanInstrumentationName(
28215
29523
  {
@@ -28222,6 +29530,7 @@ var GoogleGenAIPlugin = class extends BasePlugin {
28222
29530
  INSTRUMENTATION_NAMES.GOOGLE_GENAI
28223
29531
  )
28224
29532
  );
29533
+ embeddingSpans.add(span);
28225
29534
  return {
28226
29535
  span,
28227
29536
  startTime: getCurrentUnixTimestamp()
@@ -28234,20 +29543,28 @@ var GoogleGenAIPlugin = class extends BasePlugin {
28234
29543
  return;
28235
29544
  }
28236
29545
  try {
28237
- const output = summarizeEmbedContentOutput(event.result);
28238
29546
  spanState.span.log({
28239
- ...output ? { output } : {},
29547
+ output: summarizeEmbedContentOutput(event.result),
28240
29548
  metrics: cleanMetrics3(
28241
29549
  extractEmbedContentMetrics(event.result, spanState.startTime)
28242
29550
  )
28243
29551
  });
28244
29552
  } finally {
29553
+ embeddingSpans.delete(spanState.span);
28245
29554
  spanState.span.end();
28246
29555
  states.delete(event);
28247
29556
  }
28248
29557
  },
28249
29558
  error: (event) => {
28250
- logErrorAndEndSpan(states, event);
29559
+ const spanState = states.get(event);
29560
+ if (!spanState) return;
29561
+ try {
29562
+ spanState.span.log({ error: event.error, output: { count: 0 } });
29563
+ } finally {
29564
+ embeddingSpans.delete(spanState.span);
29565
+ spanState.span.end();
29566
+ states.delete(event);
29567
+ }
28251
29568
  }
28252
29569
  };
28253
29570
  tracingChannel.subscribe(handlers);
@@ -28482,15 +29799,53 @@ function serializeGenerateContentInput(params) {
28482
29799
  return input;
28483
29800
  }
28484
29801
  function serializeEmbedContentInput(params) {
29802
+ let contents = Array.isArray(params.contents) ? params.contents : [params.contents];
29803
+ if (params.model.includes("gemini-embedding-2") && contents.length > 0 && contents.every(
29804
+ (content) => typeof content === "string" || !Array.isArray(content) && !("parts" in content)
29805
+ )) {
29806
+ contents = [contents];
29807
+ }
28485
29808
  const input = {
28486
- model: params.model,
28487
- contents: serializeContentCollection(params.contents)
29809
+ inputs: contents.map((content) => {
29810
+ const parts = typeof content === "string" ? [content] : Array.isArray(content) ? content : "parts" in content ? content.parts : [content];
29811
+ const normalized = parts.flatMap((part) => {
29812
+ if (typeof part === "string") return [{ type: "text", text: part }];
29813
+ if (part.text !== void 0) return [{ type: "text", text: part.text }];
29814
+ const media = part.inlineData ?? part.fileData;
29815
+ if (!media) return [];
29816
+ const data = "data" in media ? `data:${media.mimeType};base64,${typeof media.data === "string" ? media.data : uint8ArrayToBase64(media.data)}` : media.fileUri;
29817
+ return media.mimeType?.startsWith("image/") ? [{ type: "image_url", image_url: { url: data } }] : [
29818
+ {
29819
+ type: "file",
29820
+ file: {
29821
+ file_data: data,
29822
+ ..."displayName" in media && media.displayName ? { filename: media.displayName } : {}
29823
+ }
29824
+ }
29825
+ ];
29826
+ });
29827
+ return {
29828
+ content: normalized.length === 1 && normalized[0].type === "text" ? normalized[0].text : normalized
29829
+ };
29830
+ }),
29831
+ ...params.config?.outputDimensionality !== void 0 ? { output_dimensions: params.config.outputDimensionality } : {}
28488
29832
  };
28489
- const config3 = params.config ? tryToDict(params.config) : null;
28490
- if (config3) {
28491
- input.config = config3;
29833
+ try {
29834
+ const processed = processInputAttachments(input);
29835
+ const hasInlineMedia = processed.inputs.some(
29836
+ ({ content }) => Array.isArray(content) && content.some((part) => {
29837
+ const data = part.type === "image_url" ? part.image_url.url : part.type === "file" ? part.file.file_data : void 0;
29838
+ return typeof data === "string" && data.startsWith("data:");
29839
+ })
29840
+ );
29841
+ return hasInlineMedia ? input : processed;
29842
+ } catch (error2) {
29843
+ debugLogger.error(
29844
+ "Error processing Google GenAI embedding attachments:",
29845
+ error2
29846
+ );
29847
+ return input;
28492
29848
  }
28493
- return input;
28494
29849
  }
28495
29850
  function serializeInteractionInput(params) {
28496
29851
  const input = {
@@ -28678,19 +30033,6 @@ function extractGenerateContentMetadata(params) {
28678
30033
  }
28679
30034
  return metadata;
28680
30035
  }
28681
- function extractEmbedContentMetadata(params) {
28682
- const metadata = {};
28683
- if (params.model) {
28684
- metadata.model = params.model;
28685
- }
28686
- const config3 = params.config ? tryToDict(params.config) : null;
28687
- if (config3) {
28688
- Object.keys(config3).forEach((key) => {
28689
- metadata[key] = config3[key];
28690
- });
28691
- }
28692
- return metadata;
28693
- }
28694
30036
  function extractGenerateContentMetrics(response, startTime) {
28695
30037
  const metrics = {};
28696
30038
  if (startTime !== void 0) {
@@ -28710,15 +30052,23 @@ function extractEmbedContentMetrics(response, startTime) {
28710
30052
  const end = getCurrentUnixTimestamp();
28711
30053
  metrics.start = startTime;
28712
30054
  metrics.end = end;
28713
- metrics.duration = end - startTime;
28714
- }
28715
- if (response?.usageMetadata) {
28716
- populateUsageMetrics(metrics, response.usageMetadata);
28717
30055
  }
28718
30056
  const embeddingTokenCount = extractEmbedPromptTokenCount(response);
28719
30057
  if (embeddingTokenCount !== void 0) {
28720
30058
  metrics.prompt_tokens = embeddingTokenCount;
28721
- metrics.tokens = embeddingTokenCount;
30059
+ }
30060
+ const totalTokens = response?.usageMetadata?.totalTokenCount ?? embeddingTokenCount;
30061
+ if (totalTokens !== void 0) {
30062
+ metrics.tokens = totalTokens;
30063
+ }
30064
+ const audioTokens = (response?.usageMetadata?.promptTokenDetails ?? response?.usageMetadata?.promptTokensDetails)?.filter(
30065
+ (detail) => detail.modality === "AUDIO" && detail.tokenCount !== void 0
30066
+ );
30067
+ if (audioTokens?.length) {
30068
+ metrics.prompt_audio_tokens = audioTokens.reduce(
30069
+ (sum, detail) => sum + (detail.tokenCount ?? 0),
30070
+ 0
30071
+ );
28722
30072
  }
28723
30073
  return metrics;
28724
30074
  }
@@ -28757,41 +30107,25 @@ function extractEmbedPromptTokenCount(response) {
28757
30107
  if (typeof usagePromptTokens === "number" && Number.isFinite(usagePromptTokens)) {
28758
30108
  return usagePromptTokens;
28759
30109
  }
28760
- const usageTotalTokens = response.usageMetadata?.totalTokenCount;
28761
- if (typeof usageTotalTokens === "number" && Number.isFinite(usageTotalTokens)) {
28762
- return usageTotalTokens;
28763
- }
28764
30110
  const embeddings = Array.isArray(response.embeddings) ? response.embeddings : response.embedding ? [response.embedding] : [];
28765
30111
  if (embeddings.length === 0) {
28766
30112
  return void 0;
28767
30113
  }
28768
30114
  let total = 0;
28769
- let sawAny = false;
28770
30115
  for (const embedding of embeddings) {
28771
30116
  const embeddingStats = tryToDict(tryToDict(embedding)?.statistics);
28772
30117
  const tokenCount2 = embeddingStats?.tokenCount;
28773
30118
  if (typeof tokenCount2 === "number" && Number.isFinite(tokenCount2)) {
28774
30119
  total += tokenCount2;
28775
- sawAny = true;
30120
+ } else {
30121
+ return void 0;
28776
30122
  }
28777
30123
  }
28778
- return sawAny ? total : void 0;
30124
+ return total;
28779
30125
  }
28780
30126
  function summarizeEmbedContentOutput(response) {
28781
- if (!response) {
28782
- return void 0;
28783
- }
28784
- const embeddings = Array.isArray(response.embeddings) ? response.embeddings : response.embedding ? [response.embedding] : [];
28785
- if (embeddings.length === 0) {
28786
- return void 0;
28787
- }
28788
- const firstValues = embeddings[0]?.values;
28789
- if (!Array.isArray(firstValues)) {
28790
- return void 0;
28791
- }
28792
30127
  return {
28793
- embedding_count: embeddings.length,
28794
- embedding_length: firstValues.length
30128
+ count: Array.isArray(response?.embeddings) ? response.embeddings.length : response?.embedding ? 1 : 0
28795
30129
  };
28796
30130
  }
28797
30131
  function populateUsageMetrics(metrics, usage) {
@@ -29658,7 +30992,7 @@ var HuggingFaceTransformersPlugin = class extends BasePlugin {
29658
30992
  getTask(event)
29659
30993
  ),
29660
30994
  extractInput: (args, event) => ({
29661
- input: extractInput(
30995
+ input: extractInput2(
29662
30996
  getTask(event),
29663
30997
  args
29664
30998
  ),
@@ -29748,7 +31082,7 @@ function modelIdentifier(pipeline) {
29748
31082
  }
29749
31083
  return void 0;
29750
31084
  }
29751
- function extractInput(task, args) {
31085
+ function extractInput2(task, args) {
29752
31086
  switch (task) {
29753
31087
  case "feature-extraction":
29754
31088
  return args[0];
@@ -32418,6 +33752,379 @@ function aggregateMistralStreamChunks(chunks) {
32418
33752
  };
32419
33753
  }
32420
33754
 
33755
+ // src/instrumentation/plugins/langgraph-sdk-channels.ts
33756
+ var langGraphSDKChannels = defineChannels(
33757
+ "@langchain/langgraph-sdk",
33758
+ {
33759
+ wait: channel({
33760
+ channelName: "runs.wait",
33761
+ kind: "async"
33762
+ }),
33763
+ stream: channel({
33764
+ channelName: "runs.stream",
33765
+ kind: "sync-stream"
33766
+ })
33767
+ },
33768
+ { instrumentationName: INSTRUMENTATION_NAMES.LANGGRAPH_SDK }
33769
+ );
33770
+
33771
+ // src/instrumentation/plugins/langgraph-sdk-plugin.ts
33772
+ var LangGraphSDKPlugin = class extends BasePlugin {
33773
+ onEnable() {
33774
+ this.unsubscribers.push(
33775
+ langGraphSDKChannels.wait.intercept(
33776
+ (target, self, args) => instrumentRun("wait", args, () => Reflect.apply(target, self, args))
33777
+ ),
33778
+ langGraphSDKChannels.stream.intercept(
33779
+ (target, self, args) => instrumentRun("stream", args, () => Reflect.apply(target, self, args))
33780
+ )
33781
+ );
33782
+ }
33783
+ onDisable() {
33784
+ this.unsubscribers = unsubscribeAll(this.unsubscribers);
33785
+ }
33786
+ };
33787
+ function normalizeMessage(value) {
33788
+ if (!isObject(value)) return value;
33789
+ 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);
33790
+ if (typeof role !== "string") return value;
33791
+ const message = {
33792
+ role,
33793
+ content: value.content ?? ""
33794
+ };
33795
+ for (const key of ["name", "tool_call_id", "refusal"]) {
33796
+ if (value[key] !== void 0) message[key] = value[key];
33797
+ }
33798
+ const additional = isObject(value.additional_kwargs) ? value.additional_kwargs : {};
33799
+ const toolCalls = Array.isArray(value.tool_calls) && value.tool_calls.length ? value.tool_calls : additional.tool_calls;
33800
+ if (Array.isArray(toolCalls) && toolCalls.length > 0) {
33801
+ message.tool_calls = toolCalls.map((call) => {
33802
+ if (!isObject(call)) return call;
33803
+ if (isObject(call.function)) return call;
33804
+ return {
33805
+ id: call.id,
33806
+ type: "function",
33807
+ function: {
33808
+ name: call.name,
33809
+ arguments: typeof call.args === "string" ? call.args : JSON.stringify(call.args ?? {})
33810
+ }
33811
+ };
33812
+ });
33813
+ }
33814
+ if (Array.isArray(value.invalid_tool_calls) && value.invalid_tool_calls.length > 0)
33815
+ message.invalid_tool_calls = value.invalid_tool_calls;
33816
+ if (message.refusal === void 0 && additional.refusal !== void 0)
33817
+ message.refusal = additional.refusal;
33818
+ return message;
33819
+ }
33820
+ function normalizeRunError(value) {
33821
+ let name;
33822
+ let message;
33823
+ if (value instanceof Error) {
33824
+ name = value.name;
33825
+ message = value.message;
33826
+ } else if (isObject(value) && typeof value.error === "string" && typeof value.message === "string") {
33827
+ name = value.error;
33828
+ message = value.message;
33829
+ } else {
33830
+ return value;
33831
+ }
33832
+ for (let depth = 0; depth < 3; depth++) {
33833
+ try {
33834
+ const nested = JSON.parse(
33835
+ message.startsWith(`${name}: `) ? message.slice(name.length + 2) : message
33836
+ );
33837
+ if (!isObject(nested) || typeof nested.error !== "string" || typeof nested.message !== "string")
33838
+ break;
33839
+ name = nested.error;
33840
+ message = nested.message;
33841
+ } catch {
33842
+ break;
33843
+ }
33844
+ }
33845
+ if (value instanceof Error && name === value.name && message === value.message)
33846
+ return value;
33847
+ return Object.assign(new Error(message), { name });
33848
+ }
33849
+ function normalizeState(value) {
33850
+ if (!isObject(value)) return value;
33851
+ return Object.fromEntries(
33852
+ Object.entries(value).map(([key, field]) => {
33853
+ if (key === "messages" && Array.isArray(field))
33854
+ return [key, field.map(normalizeMessage)];
33855
+ if (key === "__error__") {
33856
+ const error2 = normalizeRunError(field);
33857
+ if (error2 instanceof Error)
33858
+ return [key, { error: error2.name, message: error2.message }];
33859
+ }
33860
+ return [key, field];
33861
+ })
33862
+ );
33863
+ }
33864
+ function normalizeRunOutput(value, input) {
33865
+ if (!isObject(value)) return value;
33866
+ if (Array.isArray(value.messages)) {
33867
+ if (value.__interrupt__ !== void 0 || value.__error__ !== void 0)
33868
+ return void 0;
33869
+ const inputMessages = isObject(input) && Array.isArray(input.messages) ? input.messages : [];
33870
+ let inputPrefixLength = 0;
33871
+ while (inputPrefixLength < inputMessages.length) {
33872
+ const previous = inputMessages[inputPrefixLength];
33873
+ const message = value.messages[inputPrefixLength];
33874
+ 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)))
33875
+ break;
33876
+ inputPrefixLength++;
33877
+ }
33878
+ for (let index = value.messages.length - 1; index >= inputPrefixLength; index--) {
33879
+ const message = value.messages[index];
33880
+ const normalized = normalizeMessage(message);
33881
+ if (!isObject(normalized)) continue;
33882
+ if (normalized.role === "user") return void 0;
33883
+ if (normalized.role !== "assistant") continue;
33884
+ if (inputMessages.some((previous) => {
33885
+ if (!isObject(previous) || !isObject(message)) return false;
33886
+ return previous.id !== void 0 && previous.id === message.id && JSON.stringify(normalizeMessage(previous)) === JSON.stringify(normalized);
33887
+ }))
33888
+ continue;
33889
+ return normalized;
33890
+ }
33891
+ return void 0;
33892
+ }
33893
+ const result = Object.fromEntries(
33894
+ Object.entries(value).filter(
33895
+ ([key]) => key !== "__interrupt__" && key !== "__error__"
33896
+ )
33897
+ );
33898
+ return !Object.keys(result).length && (value.__interrupt__ !== void 0 || value.__error__ !== void 0) ? void 0 : result;
33899
+ }
33900
+ function instrumentRun(operation, [threadId, assistantId, options], invoke2) {
33901
+ if (isAutoInstrumentationSuppressed()) return invoke2();
33902
+ const start = getCurrentUnixTimestamp();
33903
+ let span;
33904
+ try {
33905
+ const metadata = {
33906
+ "langgraph.thread_id": threadId,
33907
+ "langgraph.assistant_id": assistantId
33908
+ };
33909
+ for (const key of [
33910
+ "streamMode",
33911
+ "streamSubgraphs",
33912
+ "interruptBefore",
33913
+ "interruptAfter",
33914
+ "multitaskStrategy",
33915
+ "durability"
33916
+ ]) {
33917
+ if (options?.[key] !== void 0) metadata[key] = options[key];
33918
+ }
33919
+ span = startSpan(
33920
+ withSpanInstrumentationName(
33921
+ {
33922
+ name: `langgraph.runs.${operation}`,
33923
+ spanAttributes: { type: "task" /* TASK */ },
33924
+ event: {
33925
+ input: options?.command === void 0 ? normalizeState(options?.input) : {
33926
+ input: normalizeState(options.input),
33927
+ command: options.command
33928
+ },
33929
+ metadata
33930
+ }
33931
+ },
33932
+ INSTRUMENTATION_NAMES.LANGGRAPH_SDK
33933
+ )
33934
+ );
33935
+ } catch (error2) {
33936
+ debugLogger.error("Error starting LangGraph SDK span:", error2);
33937
+ return invoke2();
33938
+ }
33939
+ let ended = false;
33940
+ let output;
33941
+ let streamError;
33942
+ let firstToken;
33943
+ const updates = [];
33944
+ const usageByMessage = /* @__PURE__ */ new Map();
33945
+ const captureUsage = (id, usage) => {
33946
+ if (!isObject(usage)) return;
33947
+ const metrics = {};
33948
+ for (const [source, destination] of [
33949
+ ["input_tokens", "prompt_tokens"],
33950
+ ["output_tokens", "completion_tokens"],
33951
+ ["total_tokens", "tokens"]
33952
+ ]) {
33953
+ const value = usage[source];
33954
+ if (typeof value === "number" && Number.isFinite(value) && value >= 0)
33955
+ metrics[destination] = value;
33956
+ }
33957
+ if (metrics.tokens === void 0 && metrics.prompt_tokens !== void 0 && metrics.completion_tokens !== void 0)
33958
+ metrics.tokens = metrics.prompt_tokens + metrics.completion_tokens;
33959
+ usageByMessage.set(id, { ...usageByMessage.get(id), ...metrics });
33960
+ };
33961
+ const messages = /* @__PURE__ */ new Map();
33962
+ const messageSnapshots = /* @__PURE__ */ new Map();
33963
+ const finish = (error2) => {
33964
+ if (ended) return;
33965
+ ended = true;
33966
+ try {
33967
+ const metrics = {};
33968
+ for (const usage of usageByMessage.values()) {
33969
+ for (const [key, value] of Object.entries(usage))
33970
+ metrics[key] = (metrics[key] ?? 0) + value;
33971
+ }
33972
+ if (firstToken !== void 0)
33973
+ metrics.time_to_first_token = firstToken - start;
33974
+ const finalMessages = [
33975
+ ...new Map([...messages, ...messageSnapshots]).values()
33976
+ ];
33977
+ let loggedOutput = normalizeRunOutput(output, options?.input);
33978
+ if (loggedOutput === void 0 && finalMessages.length)
33979
+ loggedOutput = normalizeRunOutput(
33980
+ { messages: finalMessages },
33981
+ void 0
33982
+ );
33983
+ if (output === void 0 && !finalMessages.length && updates.length) {
33984
+ const results = updates.map((update) => normalizeRunOutput(update, options?.input)).filter((update) => update !== void 0);
33985
+ if (results.length) loggedOutput = { updates: results };
33986
+ }
33987
+ const interrupted = [output, ...updates].find(
33988
+ (state) => isObject(state) && state.__interrupt__ !== void 0
33989
+ );
33990
+ span.log({
33991
+ ...loggedOutput !== void 0 ? { output: loggedOutput } : {},
33992
+ ...isObject(interrupted) ? { metadata: { "langgraph.interrupts": interrupted.__interrupt__ } } : {},
33993
+ ...error2 !== void 0 || streamError !== void 0 ? { error: normalizeRunError(error2 ?? streamError) } : {},
33994
+ metrics
33995
+ });
33996
+ } catch (error3) {
33997
+ debugLogger.error("Error logging LangGraph SDK span:", error3);
33998
+ }
33999
+ try {
34000
+ span.end();
34001
+ } catch (error3) {
34002
+ debugLogger.error("Error ending LangGraph SDK span:", error3);
34003
+ }
34004
+ };
34005
+ const observeMessages = (value, streaming) => {
34006
+ if (!isObject(value) || !Array.isArray(value.messages)) return;
34007
+ const inputMessages = isObject(options?.input) && Array.isArray(options.input.messages) ? options.input.messages : [];
34008
+ for (const message of value.messages) {
34009
+ if (!isObject(message) || message.type !== "ai" && message.role !== "assistant")
34010
+ continue;
34011
+ if (message.id !== void 0 && inputMessages.some(
34012
+ (input) => isObject(input) && input.id === message.id
34013
+ ))
34014
+ continue;
34015
+ captureUsage(
34016
+ typeof message.id === "string" ? message.id : "message",
34017
+ message.usage_metadata
34018
+ );
34019
+ if (streaming && (typeof message.content === "string" ? message.content.length > 0 : Array.isArray(message.content) && message.content.some(
34020
+ (part) => isObject(part) && typeof part.text === "string" && part.text.length > 0
34021
+ )))
34022
+ firstToken ??= getCurrentUnixTimestamp();
34023
+ }
34024
+ };
34025
+ const onChunk = ({ event, data }) => {
34026
+ if (ended) return;
34027
+ if (event === "metadata" && isObject(data)) {
34028
+ if (typeof data.run_id === "string")
34029
+ span.log({ metadata: { "langgraph.run_id": data.run_id } });
34030
+ } else if (event === "error") {
34031
+ streamError = normalizeRunError(data);
34032
+ } else if (event === "values") {
34033
+ output = data;
34034
+ observeMessages(data, true);
34035
+ } else if (event === "updates") {
34036
+ if (isObject(data)) {
34037
+ const stateUpdates = [];
34038
+ for (const [node, update] of Object.entries(data)) {
34039
+ observeMessages(update, true);
34040
+ if (isObject(update) && Array.isArray(update.messages)) {
34041
+ for (const message of update.messages) {
34042
+ if (isObject(message))
34043
+ messageSnapshots.set(
34044
+ typeof message.id === "string" ? message.id : `update-${messageSnapshots.size}`,
34045
+ message
34046
+ );
34047
+ }
34048
+ const state = Object.fromEntries(
34049
+ Object.entries(update).filter(([key]) => key !== "messages")
34050
+ );
34051
+ if (Object.keys(state).length) stateUpdates.push([node, state]);
34052
+ } else {
34053
+ stateUpdates.push([node, update]);
34054
+ }
34055
+ }
34056
+ if (stateUpdates.length) updates.push(Object.fromEntries(stateUpdates));
34057
+ } else {
34058
+ updates.push(data);
34059
+ }
34060
+ } else if ((event === "messages" || event === "messages/partial" || event === "messages/complete") && Array.isArray(data)) {
34061
+ const parts = event === "messages" ? [data[0]] : data;
34062
+ for (const part of parts) {
34063
+ if (!isObject(part)) continue;
34064
+ const id = typeof part.id === "string" ? part.id : "message";
34065
+ captureUsage(id, part.usage_metadata);
34066
+ const previous = messages.get(id);
34067
+ messages.set(
34068
+ id,
34069
+ event === "messages" && previous && typeof part.content === "string" && typeof previous.content === "string" ? { ...part, content: previous.content + part.content } : part
34070
+ );
34071
+ if (typeof part.content === "string" && part.content.length > 0)
34072
+ firstToken ??= getCurrentUnixTimestamp();
34073
+ }
34074
+ }
34075
+ };
34076
+ let result;
34077
+ try {
34078
+ result = withCurrent(
34079
+ span,
34080
+ () => runWithAutoInstrumentationSuppressed(invoke2)
34081
+ );
34082
+ } catch (error2) {
34083
+ finish(error2);
34084
+ throw error2;
34085
+ }
34086
+ if (operation === "stream") {
34087
+ try {
34088
+ patchStreamIfNeeded(result, {
34089
+ shouldCollect: (chunk) => {
34090
+ try {
34091
+ onChunk(chunk);
34092
+ } catch (error2) {
34093
+ debugLogger.error(
34094
+ "Error processing LangGraph stream event:",
34095
+ error2
34096
+ );
34097
+ }
34098
+ return false;
34099
+ },
34100
+ aroundNext: (next) => withCurrent(span, () => runWithAutoInstrumentationSuppressed(next)),
34101
+ onComplete: () => finish(),
34102
+ onCancel: () => finish(),
34103
+ onError: (error2) => finish(error2)
34104
+ });
34105
+ } catch (error2) {
34106
+ debugLogger.error("Error observing LangGraph stream:", error2);
34107
+ finish();
34108
+ }
34109
+ } else {
34110
+ void Promise.resolve(result).then(
34111
+ (value) => {
34112
+ try {
34113
+ output = value;
34114
+ observeMessages(value, false);
34115
+ if (isObject(value) && isObject(value.__error__))
34116
+ streamError = normalizeRunError(value.__error__);
34117
+ finish();
34118
+ } catch (error2) {
34119
+ finish(error2);
34120
+ }
34121
+ },
34122
+ (error2) => finish(error2)
34123
+ );
34124
+ }
34125
+ return result;
34126
+ }
34127
+
32421
34128
  // src/instrumentation/plugins/ollama-channels.ts
32422
34129
  var ollamaChannels = defineChannels(
32423
34130
  "ollama",
@@ -32627,7 +34334,7 @@ function normalizeTextAndImages(content, images) {
32627
34334
  ...unrecognizedImages.length > 0 ? { unrecognizedImages } : {}
32628
34335
  };
32629
34336
  }
32630
- function normalizeMessage(message, toolCallId, syntheticToolCallIdOffset = 0) {
34337
+ function normalizeMessage2(message, toolCallId, syntheticToolCallIdOffset = 0) {
32631
34338
  if (typeof message.role !== "string") {
32632
34339
  return void 0;
32633
34340
  }
@@ -32673,7 +34380,7 @@ function normalizeMessages(messages) {
32673
34380
  toolCallId = pendingToolCallIds.get(toolName)?.shift();
32674
34381
  }
32675
34382
  }
32676
- const normalized = normalizeMessage(
34383
+ const normalized = normalizeMessage2(
32677
34384
  ollamaMessage,
32678
34385
  toolCallId,
32679
34386
  syntheticToolCallIdOffset
@@ -32792,7 +34499,7 @@ function extractOllamaChatOutput(result, syntheticToolCallIdOffset = 0) {
32792
34499
  if (!isObject(result) || !isObject(result.message)) {
32793
34500
  return void 0;
32794
34501
  }
32795
- const message = normalizeMessage(
34502
+ const message = normalizeMessage2(
32796
34503
  result.message,
32797
34504
  void 0,
32798
34505
  syntheticToolCallIdOffset
@@ -35512,14 +37219,14 @@ function extractActionSpanMetadata(args) {
35512
37219
  const options = extractRunInNewSpanOptions(args);
35513
37220
  const labels = isObject(options?.labels) ? options.labels : void 0;
35514
37221
  const metadata = isObject(options?.metadata) ? options.metadata : void 0;
35515
- const actionType = stringValue(labels?.["genkit:metadata:subtype"]);
35516
- const name = stringValue(metadata?.name);
37222
+ const actionType = stringValue2(labels?.["genkit:metadata:subtype"]);
37223
+ const name = stringValue2(metadata?.name);
35517
37224
  if (!actionType || !name) {
35518
37225
  return void 0;
35519
37226
  }
35520
37227
  return {
35521
37228
  actionType,
35522
- key: stringValue(labels?.["genkit:key"]),
37229
+ key: stringValue2(labels?.["genkit:key"]),
35523
37230
  name
35524
37231
  };
35525
37232
  }
@@ -35629,7 +37336,7 @@ function pickNumberMetrics(values) {
35629
37336
  })
35630
37337
  );
35631
37338
  }
35632
- function stringValue(value) {
37339
+ function stringValue2(value) {
35633
37340
  return typeof value === "string" ? value : void 0;
35634
37341
  }
35635
37342
 
@@ -36314,7 +38021,7 @@ function subscribeToFlueContext(value, state) {
36314
38021
  try {
36315
38022
  unsubscribe?.();
36316
38023
  } catch (error2) {
36317
- logInstrumentationError3("Flue context unsubscribe", error2);
38024
+ logInstrumentationError4("Flue context unsubscribe", error2);
36318
38025
  }
36319
38026
  };
36320
38027
  try {
@@ -36330,7 +38037,7 @@ function subscribeToFlueContext(value, state) {
36330
38037
  });
36331
38038
  state.contexts.add(value);
36332
38039
  } catch (error2) {
36333
- logInstrumentationError3("Flue context subscription", error2);
38040
+ logInstrumentationError4("Flue context subscription", error2);
36334
38041
  }
36335
38042
  }
36336
38043
  function isAutoContextTerminalEvent(event, ctx) {
@@ -36386,7 +38093,7 @@ var FlueObserveBridge = class {
36386
38093
  try {
36387
38094
  this.handleEvent(event, flueContextFromUnknown(ctx));
36388
38095
  } catch (error2) {
36389
- logInstrumentationError3("Flue observe", error2);
38096
+ logInstrumentationError4("Flue observe", error2);
36390
38097
  }
36391
38098
  }
36392
38099
  reset() {
@@ -36403,7 +38110,7 @@ var FlueObserveBridge = class {
36403
38110
  try {
36404
38111
  span = this.spanForExecutionOperation(operation, executionContext);
36405
38112
  } catch (error2) {
36406
- logInstrumentationError3("Flue execution interceptor", error2);
38113
+ logInstrumentationError4("Flue execution interceptor", error2);
36407
38114
  }
36408
38115
  return span ? runWithCurrentSpanStore(span, next) : next();
36409
38116
  }
@@ -36609,7 +38316,7 @@ var FlueObserveBridge = class {
36609
38316
  this.runsById.delete(event.runId);
36610
38317
  }
36611
38318
  void flush().catch((error2) => {
36612
- logInstrumentationError3("Flue flush", error2);
38319
+ logInstrumentationError4("Flue flush", error2);
36613
38320
  });
36614
38321
  }
36615
38322
  handleOperationStart(event) {
@@ -37384,17 +39091,17 @@ function safeLog3(span, event) {
37384
39091
  try {
37385
39092
  span.log(event);
37386
39093
  } catch (error2) {
37387
- logInstrumentationError3("Flue span log", error2);
39094
+ logInstrumentationError4("Flue span log", error2);
37388
39095
  }
37389
39096
  }
37390
39097
  function safeEnd(span, endTime) {
37391
39098
  try {
37392
39099
  span.end(endTime === void 0 ? void 0 : { endTime });
37393
39100
  } catch (error2) {
37394
- logInstrumentationError3("Flue span end", error2);
39101
+ logInstrumentationError4("Flue span end", error2);
37395
39102
  }
37396
39103
  }
37397
- function logInstrumentationError3(label, error2) {
39104
+ function logInstrumentationError4(label, error2) {
37398
39105
  debugLogger.debug(`Error in ${label} instrumentation:`, error2);
37399
39106
  }
37400
39107
 
@@ -37694,11 +39401,11 @@ function walkGenerations(response) {
37694
39401
  for (const batch of generations) {
37695
39402
  if (Array.isArray(batch)) {
37696
39403
  for (const generation of batch) {
37697
- if (isRecord(generation)) {
39404
+ if (isRecord2(generation)) {
37698
39405
  result.push(generation);
37699
39406
  }
37700
39407
  }
37701
- } else if (isRecord(batch)) {
39408
+ } else if (isRecord2(batch)) {
37702
39409
  result.push(batch);
37703
39410
  }
37704
39411
  }
@@ -37707,11 +39414,11 @@ function walkGenerations(response) {
37707
39414
  function getModelNameFromResponse(response) {
37708
39415
  for (const generation of walkGenerations(response)) {
37709
39416
  const message = generation.message;
37710
- if (!isRecord(message)) {
39417
+ if (!isRecord2(message)) {
37711
39418
  continue;
37712
39419
  }
37713
39420
  const responseMetadata = message.response_metadata;
37714
- if (!isRecord(responseMetadata)) {
39421
+ if (!isRecord2(responseMetadata)) {
37715
39422
  continue;
37716
39423
  }
37717
39424
  const modelName3 = responseMetadata.model_name ?? responseMetadata.model;
@@ -37726,14 +39433,14 @@ function getModelNameFromResponse(response) {
37726
39433
  function getMetricsFromResponse(response) {
37727
39434
  for (const generation of walkGenerations(response)) {
37728
39435
  const message = generation.message;
37729
- if (!isRecord(message)) {
39436
+ if (!isRecord2(message)) {
37730
39437
  continue;
37731
39438
  }
37732
39439
  const usageMetadata = message.usage_metadata;
37733
- if (!isRecord(usageMetadata)) {
39440
+ if (!isRecord2(usageMetadata)) {
37734
39441
  continue;
37735
39442
  }
37736
- const inputTokenDetails = isRecord(usageMetadata.input_token_details) ? usageMetadata.input_token_details : {};
39443
+ const inputTokenDetails = isRecord2(usageMetadata.input_token_details) ? usageMetadata.input_token_details : {};
37737
39444
  const outputTokenDetails = usageMetadata.output_token_details;
37738
39445
  return normalizeTokenMetrics({
37739
39446
  total_tokens: usageMetadata.total_tokens,
@@ -37744,11 +39451,11 @@ function getMetricsFromResponse(response) {
37744
39451
  prompt_cache_creation_5m_tokens: inputTokenDetails.ephemeral_5m_input_tokens,
37745
39452
  prompt_cache_creation_1h_tokens: inputTokenDetails.ephemeral_1h_input_tokens,
37746
39453
  prompt_cached_tokens: inputTokenDetails.cache_read,
37747
- completion_reasoning_tokens: isRecord(outputTokenDetails) ? outputTokenDetails.reasoning : void 0
39454
+ completion_reasoning_tokens: isRecord2(outputTokenDetails) ? outputTokenDetails.reasoning : void 0
37748
39455
  });
37749
39456
  }
37750
39457
  const llmOutput = response.llmOutput || {};
37751
- const tokenUsage = isRecord(llmOutput.tokenUsage) ? llmOutput.tokenUsage : isRecord(llmOutput.estimatedTokens) ? llmOutput.estimatedTokens : {};
39458
+ const tokenUsage = isRecord2(llmOutput.tokenUsage) ? llmOutput.tokenUsage : isRecord2(llmOutput.estimatedTokens) ? llmOutput.estimatedTokens : {};
37752
39459
  return normalizeTokenMetrics({
37753
39460
  total_tokens: tokenUsage.totalTokens,
37754
39461
  prompt_tokens: tokenUsage.promptTokens,
@@ -37762,7 +39469,7 @@ function safeJsonParse(input) {
37762
39469
  return input;
37763
39470
  }
37764
39471
  }
37765
- function isRecord(value) {
39472
+ function isRecord2(value) {
37766
39473
  return typeof value === "object" && value !== null && !Array.isArray(value);
37767
39474
  }
37768
39475
 
@@ -37956,16 +39663,16 @@ var LangSmithPlugin = class extends BasePlugin {
37956
39663
  this.completedRuns.clear();
37957
39664
  }
37958
39665
  processBatch(batch) {
37959
- if (!isRecord2(batch)) {
39666
+ if (!isRecord3(batch)) {
37960
39667
  return;
37961
39668
  }
37962
39669
  const creates = ownValue(batch, "runCreates");
37963
39670
  if (Array.isArray(creates)) {
37964
39671
  const parentFirst = [...creates].sort((left, right) => {
37965
- const leftId = stringValue2(ownValue(left, "id"));
37966
- const rightId = stringValue2(ownValue(right, "id"));
37967
- const leftParent = stringValue2(ownValue(left, "parent_run_id"));
37968
- const rightParent = stringValue2(ownValue(right, "parent_run_id"));
39672
+ const leftId = stringValue3(ownValue(left, "id"));
39673
+ const rightId = stringValue3(ownValue(right, "id"));
39674
+ const leftParent = stringValue3(ownValue(left, "parent_run_id"));
39675
+ const rightParent = stringValue3(ownValue(right, "parent_run_id"));
37969
39676
  if (leftParent && leftParent === rightId) {
37970
39677
  return 1;
37971
39678
  }
@@ -37984,13 +39691,13 @@ var LangSmithPlugin = class extends BasePlugin {
37984
39691
  if (Array.isArray(updates)) {
37985
39692
  for (const run2 of updates) {
37986
39693
  this.containLifecycleFailure("batchIngestRuns update", () => {
37987
- this.processUpdate(stringValue2(ownValue(run2, "id")) ?? "", run2);
39694
+ this.processUpdate(stringValue3(ownValue(run2, "id")) ?? "", run2);
37988
39695
  });
37989
39696
  }
37990
39697
  }
37991
39698
  }
37992
39699
  processCreate(run2) {
37993
- const id = stringValue2(ownValue(run2, "id"));
39700
+ const id = stringValue3(ownValue(run2, "id"));
37994
39701
  if (!id || this.completedRuns.get(id)) {
37995
39702
  return;
37996
39703
  }
@@ -38023,7 +39730,7 @@ var LangSmithPlugin = class extends BasePlugin {
38023
39730
  this.endIfComplete(id, activeRun, run2);
38024
39731
  }
38025
39732
  processUpdate(explicitId, run2) {
38026
- const id = stringValue2(explicitId) ?? stringValue2(ownValue(run2, "id"));
39733
+ const id = stringValue3(explicitId) ?? stringValue3(ownValue(run2, "id"));
38027
39734
  if (!id || this.completedRuns.get(id)) {
38028
39735
  return;
38029
39736
  }
@@ -38046,13 +39753,13 @@ var LangSmithPlugin = class extends BasePlugin {
38046
39753
  this.endIfComplete(id, active, active.run);
38047
39754
  }
38048
39755
  startRunSpan(id, run2) {
38049
- const traceId = stringValue2(ownValue(run2, "trace_id")) ?? id;
38050
- const parentId = stringValue2(ownValue(run2, "parent_run_id")) ?? stringValue2(ownValue(ownValue(run2, "parent_run"), "id"));
39756
+ const traceId = stringValue3(ownValue(run2, "trace_id")) ?? id;
39757
+ const parentId = stringValue3(ownValue(run2, "parent_run_id")) ?? stringValue3(ownValue(ownValue(run2, "parent_run"), "id"));
38051
39758
  const startTime = timestampSeconds(ownValue(run2, "start_time"));
38052
39759
  return startSpan(
38053
39760
  withSpanInstrumentationName(
38054
39761
  {
38055
- name: stringValue2(ownValue(run2, "name")) ?? "LangSmith run",
39762
+ name: stringValue3(ownValue(run2, "name")) ?? "LangSmith run",
38056
39763
  spanId: id,
38057
39764
  parentSpanIds: {
38058
39765
  parentSpanIds: parentId ? [parentId] : [],
@@ -38098,7 +39805,7 @@ var LangSmithPlugin = class extends BasePlugin {
38098
39805
  return false;
38099
39806
  }
38100
39807
  const serialized = ownValue(run2, "serialized");
38101
- return isRecord2(serialized) && ownValue(serialized, "lc") === 1;
39808
+ return isRecord3(serialized) && ownValue(serialized, "lc") === 1;
38102
39809
  }
38103
39810
  containLifecycleFailure(operation, fn) {
38104
39811
  try {
@@ -38112,14 +39819,14 @@ var LangSmithPlugin = class extends BasePlugin {
38112
39819
  }
38113
39820
  };
38114
39821
  function ownValue(value, key) {
38115
- if (!isRecord2(value)) {
39822
+ if (!isRecord3(value)) {
38116
39823
  return void 0;
38117
39824
  }
38118
39825
  const descriptor = Object.getOwnPropertyDescriptor(value, key);
38119
39826
  return descriptor && "value" in descriptor ? descriptor.value : void 0;
38120
39827
  }
38121
39828
  function preferOwnValue(current, previous, key) {
38122
- const currentDescriptor = isRecord2(current) ? Object.getOwnPropertyDescriptor(current, key) : void 0;
39829
+ const currentDescriptor = isRecord3(current) ? Object.getOwnPropertyDescriptor(current, key) : void 0;
38123
39830
  if (currentDescriptor && "value" in currentDescriptor) {
38124
39831
  return currentDescriptor.value;
38125
39832
  }
@@ -38128,7 +39835,7 @@ function preferOwnValue(current, previous, key) {
38128
39835
  function mergeRuns(previous, current) {
38129
39836
  const entries = /* @__PURE__ */ new Map();
38130
39837
  for (const value of [previous, current]) {
38131
- if (!isRecord2(value)) {
39838
+ if (!isRecord3(value)) {
38132
39839
  continue;
38133
39840
  }
38134
39841
  for (const [key, descriptor] of Object.entries(
@@ -38141,10 +39848,10 @@ function mergeRuns(previous, current) {
38141
39848
  }
38142
39849
  return Object.fromEntries(entries);
38143
39850
  }
38144
- function isRecord2(value) {
39851
+ function isRecord3(value) {
38145
39852
  return typeof value === "object" && value !== null && !Array.isArray(value);
38146
39853
  }
38147
- function stringValue2(value) {
39854
+ function stringValue3(value) {
38148
39855
  return typeof value === "string" && value.length > 0 ? value : void 0;
38149
39856
  }
38150
39857
  function timestampSeconds(value) {
@@ -38162,7 +39869,7 @@ function timestampSeconds(value) {
38162
39869
  return void 0;
38163
39870
  }
38164
39871
  function dottedOrderDepth(run2) {
38165
- const dottedOrder = stringValue2(ownValue(run2, "dotted_order"));
39872
+ const dottedOrder = stringValue3(ownValue(run2, "dotted_order"));
38166
39873
  return dottedOrder ? dottedOrder.split(".").length : Number.MAX_SAFE_INTEGER;
38167
39874
  }
38168
39875
  function mapRunType(runType) {
@@ -38180,7 +39887,7 @@ function mapRunType(runType) {
38180
39887
  function extractMetadata2(run2, previous) {
38181
39888
  const extra = preferOwnValue(run2, previous, "extra");
38182
39889
  const rawMetadata = ownValue(extra, "metadata");
38183
- if (!isRecord2(rawMetadata)) {
39890
+ if (!isRecord3(rawMetadata)) {
38184
39891
  return void 0;
38185
39892
  }
38186
39893
  const metadata = {};
@@ -38367,7 +40074,7 @@ var PiCodingAgentPlugin = class extends BasePlugin {
38367
40074
  }
38368
40075
  );
38369
40076
  } catch (error2) {
38370
- logInstrumentationError4("Pi Coding Agent prompt start", error2);
40077
+ logInstrumentationError5("Pi Coding Agent prompt start", error2);
38371
40078
  }
38372
40079
  if (!state) {
38373
40080
  return runWithAutoInstrumentationSuppressed(invokeTarget);
@@ -38500,12 +40207,12 @@ function installPiAgentInstrumentation(agent) {
38500
40207
  () => handlePiAgentEvent(state, event)
38501
40208
  );
38502
40209
  } catch (error2) {
38503
- logInstrumentationError4("Pi Coding Agent event", error2);
40210
+ logInstrumentationError5("Pi Coding Agent event", error2);
38504
40211
  }
38505
40212
  });
38506
40213
  piAgentEventSubscriptions.add(agent);
38507
40214
  } catch (error2) {
38508
- logInstrumentationError4("Pi Coding Agent event subscription", error2);
40215
+ logInstrumentationError5("Pi Coding Agent event subscription", error2);
38509
40216
  }
38510
40217
  }
38511
40218
  function makeInstrumentedStreamFunction(agent, originalStreamFunction, property) {
@@ -38555,7 +40262,7 @@ function wrapPiToolExecutors(tools) {
38555
40262
  });
38556
40263
  tool.execute = wrappedExecute;
38557
40264
  } catch (error2) {
38558
- logInstrumentationError4("Pi Coding Agent tool wrapping", error2);
40265
+ logInstrumentationError5("Pi Coding Agent tool wrapping", error2);
38559
40266
  }
38560
40267
  }
38561
40268
  }
@@ -38634,7 +40341,7 @@ function patchAssistantMessageStream(stream, promptState, llmState) {
38634
40341
  try {
38635
40342
  await iterator.return();
38636
40343
  } catch (cleanupError) {
38637
- logInstrumentationError4(
40344
+ logInstrumentationError5(
38638
40345
  "Pi Coding Agent stream cleanup",
38639
40346
  cleanupError
38640
40347
  );
@@ -38799,7 +40506,7 @@ function finishPiPromptRun(state, error2) {
38799
40506
  try {
38800
40507
  state.span.end();
38801
40508
  } catch (endError) {
38802
- logInstrumentationError4("Pi Coding Agent prompt end", endError);
40509
+ logInstrumentationError5("Pi Coding Agent prompt end", endError);
38803
40510
  }
38804
40511
  }
38805
40512
  }
@@ -39131,10 +40838,10 @@ function safeLog4(span, event) {
39131
40838
  try {
39132
40839
  span.log(event);
39133
40840
  } catch (error2) {
39134
- logInstrumentationError4("Pi Coding Agent span log", error2);
40841
+ logInstrumentationError5("Pi Coding Agent span log", error2);
39135
40842
  }
39136
40843
  }
39137
- function logInstrumentationError4(context2, error2) {
40844
+ function logInstrumentationError5(context2, error2) {
39138
40845
  debugLogger.debug(`${context2}:`, error2);
39139
40846
  }
39140
40847
 
@@ -39372,7 +41079,7 @@ function handleAgentStreamEvent(state, event) {
39372
41079
  finalizeModelSpan(state, event);
39373
41080
  break;
39374
41081
  case "beforeToolCallEvent":
39375
- startToolSpan2(state, event);
41082
+ startToolSpan3(state, event);
39376
41083
  break;
39377
41084
  case "afterToolCallEvent":
39378
41085
  finalizeToolSpan(state, event);
@@ -39397,7 +41104,7 @@ function handleAgentStreamEvent(state, event) {
39397
41104
  break;
39398
41105
  }
39399
41106
  } catch (error2) {
39400
- logInstrumentationError5("Strands Agent SDK event", error2);
41107
+ logInstrumentationError6("Strands Agent SDK event", error2);
39401
41108
  }
39402
41109
  }
39403
41110
  function handleMultiAgentStreamEvent(state, event, activeChildParents) {
@@ -39433,7 +41140,7 @@ function handleMultiAgentStreamEvent(state, event, activeChildParents) {
39433
41140
  break;
39434
41141
  }
39435
41142
  } catch (error2) {
39436
- logInstrumentationError5("Strands Agent SDK multi-agent event", error2);
41143
+ logInstrumentationError6("Strands Agent SDK multi-agent event", error2);
39437
41144
  }
39438
41145
  }
39439
41146
  function buildModelSpanInput(event, attachmentCache) {
@@ -39512,7 +41219,7 @@ function finalizeModelSpan(state, event) {
39512
41219
  });
39513
41220
  modelState.span.end();
39514
41221
  }
39515
- function startToolSpan2(state, event) {
41222
+ function startToolSpan3(state, event) {
39516
41223
  const toolUse = event.toolUse;
39517
41224
  const key = toolKey2(toolUse);
39518
41225
  if (state.activeTools.has(key)) {
@@ -39792,7 +41499,7 @@ function getModelConfig(model) {
39792
41499
  try {
39793
41500
  return model.getConfig();
39794
41501
  } catch (error2) {
39795
- logInstrumentationError5("Strands Agent SDK model config", error2);
41502
+ logInstrumentationError6("Strands Agent SDK model config", error2);
39796
41503
  return void 0;
39797
41504
  }
39798
41505
  }
@@ -39875,7 +41582,7 @@ function processStrandsInputAttachments(input, cache = createStrandsAttachmentCa
39875
41582
  try {
39876
41583
  return processStrandsInputNode(input, cache);
39877
41584
  } catch (error2) {
39878
- logInstrumentationError5("Strands Agent SDK input attachments", error2);
41585
+ logInstrumentationError6("Strands Agent SDK input attachments", error2);
39879
41586
  return input;
39880
41587
  }
39881
41588
  }
@@ -40095,13 +41802,484 @@ function safeLog5(span, event) {
40095
41802
  try {
40096
41803
  span.log(event);
40097
41804
  } catch (error2) {
40098
- logInstrumentationError5("Strands Agent SDK span log", error2);
41805
+ logInstrumentationError6("Strands Agent SDK span log", error2);
40099
41806
  }
40100
41807
  }
40101
- function logInstrumentationError5(context2, error2) {
41808
+ function logInstrumentationError6(context2, error2) {
40102
41809
  debugLogger.debug(`${context2}:`, error2);
40103
41810
  }
40104
41811
 
41812
+ // src/instrumentation/plugins/elevenlabs-channels.ts
41813
+ var elevenLabsChannels = defineChannels(
41814
+ "@elevenlabs/elevenlabs-js",
41815
+ {
41816
+ convert: channel({
41817
+ channelName: "textToSpeech.convert",
41818
+ kind: "async"
41819
+ }),
41820
+ stream: channel({
41821
+ channelName: "textToSpeech.stream",
41822
+ kind: "async"
41823
+ }),
41824
+ convertWithTimestamps: channel({ channelName: "textToSpeech.convertWithTimestamps", kind: "async" }),
41825
+ streamWithTimestamps: channel({ channelName: "textToSpeech.streamWithTimestamps", kind: "async" }),
41826
+ transcribe: channel({ channelName: "speechToText.convert", kind: "async" })
41827
+ },
41828
+ { instrumentationName: INSTRUMENTATION_NAMES.ELEVENLABS }
41829
+ );
41830
+
41831
+ // src/instrumentation/plugins/elevenlabs-plugin.ts
41832
+ var ElevenLabsPlugin = class extends BasePlugin {
41833
+ onEnable() {
41834
+ for (const method of [
41835
+ "convert",
41836
+ "stream",
41837
+ "convertWithTimestamps",
41838
+ "streamWithTimestamps"
41839
+ ]) {
41840
+ this.unsubscribers.push(
41841
+ interceptCall2(
41842
+ elevenLabsChannels[method],
41843
+ `elevenlabs.textToSpeech.${method}`,
41844
+ ([voice, request]) => ({
41845
+ input: {
41846
+ operation: "speech",
41847
+ prompt: request.text,
41848
+ parameters: {
41849
+ voice,
41850
+ format: request.outputFormat,
41851
+ language: request.languageCode,
41852
+ speed: request.voiceSettings?.speed
41853
+ }
41854
+ },
41855
+ metadata: {
41856
+ provider: "elevenlabs",
41857
+ model: request.modelId ?? "eleven_multilingual_v2"
41858
+ }
41859
+ }),
41860
+ (value, args, span, finish, headers, started) => captureSpeech(
41861
+ value,
41862
+ args[1],
41863
+ method,
41864
+ span,
41865
+ finish,
41866
+ started,
41867
+ headers
41868
+ )
41869
+ )
41870
+ );
41871
+ }
41872
+ this.unsubscribers.push(
41873
+ interceptCall2(
41874
+ elevenLabsChannels.transcribe,
41875
+ "elevenlabs.speechToText.convert",
41876
+ ([request]) => {
41877
+ if (request.webhook) return void 0;
41878
+ const file = request.file;
41879
+ const filename = typeof File !== "undefined" && file instanceof File ? file.name : "audio";
41880
+ const contentType = file instanceof Blob ? file.type || "application/octet-stream" : "application/octet-stream";
41881
+ const blob = file instanceof Blob ? file : file instanceof Uint8Array ? new Blob([new Uint8Array(file)], { type: contentType }) : file instanceof ArrayBuffer ? new Blob([file.slice(0)], { type: contentType }) : void 0;
41882
+ const fileData = blob ? new Attachment({ data: blob, filename, contentType }) : request.cloudStorageUrl;
41883
+ return {
41884
+ input: {
41885
+ operation: "transcribe",
41886
+ content: fileData ? [{ type: "file", file: { filename, file_data: fileData } }] : [],
41887
+ parameters: {
41888
+ language: request.languageCode,
41889
+ timestamp_granularities: request.timestampsGranularity
41890
+ }
41891
+ },
41892
+ metadata: { provider: "elevenlabs", model: request.modelId }
41893
+ };
41894
+ },
41895
+ (value, _args, span, finish) => {
41896
+ const result = value;
41897
+ const transcripts = result.transcripts ?? [result];
41898
+ span.log({
41899
+ output: {
41900
+ content: transcripts.flatMap(
41901
+ (transcript) => typeof transcript.text === "string" ? [{ type: "text", text: transcript.text }] : []
41902
+ ),
41903
+ annotations: {
41904
+ language: result.languageCode,
41905
+ words: result.words ?? (result.transcripts ? result.transcripts.flatMap(
41906
+ (transcript) => transcript.words ?? []
41907
+ ) : void 0)
41908
+ }
41909
+ }
41910
+ });
41911
+ finish();
41912
+ },
41913
+ ([request], span) => {
41914
+ const file = request.file;
41915
+ if (!isAsyncIterable3(file)) return;
41916
+ const chunks = [];
41917
+ const filename = isObject(file) && typeof file.path === "string" ? file.path.split(/[\\/]/).pop() || "audio" : "audio";
41918
+ observeAudioStream(
41919
+ file,
41920
+ (chunk) => chunks.push(new Uint8Array(chunk)),
41921
+ () => {
41922
+ const contentType = "application/octet-stream";
41923
+ const data = new Blob(chunks, {
41924
+ type: contentType
41925
+ });
41926
+ chunks.length = 0;
41927
+ span.log({
41928
+ input: {
41929
+ content: [
41930
+ {
41931
+ type: "file",
41932
+ file: {
41933
+ filename,
41934
+ file_data: new Attachment({
41935
+ data,
41936
+ filename,
41937
+ contentType
41938
+ })
41939
+ }
41940
+ }
41941
+ ]
41942
+ }
41943
+ });
41944
+ },
41945
+ () => {
41946
+ chunks.length = 0;
41947
+ },
41948
+ span
41949
+ );
41950
+ }
41951
+ )
41952
+ );
41953
+ }
41954
+ onDisable() {
41955
+ this.unsubscribers = unsubscribeAll(this.unsubscribers);
41956
+ }
41957
+ };
41958
+ function interceptCall2(channel2, name, input, output, beforeInvoke) {
41959
+ return channel2.intercept((target, self, args) => {
41960
+ const invoke2 = () => Reflect.apply(target, self, args);
41961
+ if (isAutoInstrumentationSuppressed()) return invoke2();
41962
+ const started = Date.now() / 1e3;
41963
+ let span;
41964
+ try {
41965
+ const event = input(args);
41966
+ if (event !== void 0)
41967
+ span = startSpan(
41968
+ withSpanInstrumentationName(
41969
+ {
41970
+ name,
41971
+ spanAttributes: { type: "llm" /* LLM */ },
41972
+ event
41973
+ },
41974
+ INSTRUMENTATION_NAMES.ELEVENLABS
41975
+ )
41976
+ );
41977
+ } catch (error2) {
41978
+ debugLogger.error("Error starting ElevenLabs span", error2);
41979
+ return invoke2();
41980
+ }
41981
+ if (!span) return invoke2();
41982
+ const activeSpan = span;
41983
+ let ended = false;
41984
+ const finish = (error2) => {
41985
+ if (ended) return;
41986
+ ended = true;
41987
+ try {
41988
+ if (error2 !== void 0) activeSpan.log({ error: error2 });
41989
+ activeSpan.end();
41990
+ } catch (loggingError) {
41991
+ debugLogger.error("Error ending ElevenLabs span", loggingError);
41992
+ }
41993
+ };
41994
+ try {
41995
+ beforeInvoke?.(args, span);
41996
+ } catch (error2) {
41997
+ debugLogger.error("Error observing ElevenLabs input", error2);
41998
+ }
41999
+ let result;
42000
+ try {
42001
+ result = withCurrent(
42002
+ span,
42003
+ () => runWithAutoInstrumentationSuppressed(invoke2)
42004
+ );
42005
+ } catch (error2) {
42006
+ finish(error2);
42007
+ throw error2;
42008
+ }
42009
+ const capture = (value, headers) => {
42010
+ try {
42011
+ output(value, args, span, finish, headers, started);
42012
+ } catch (error2) {
42013
+ debugLogger.error("Error capturing ElevenLabs output", error2);
42014
+ finish();
42015
+ }
42016
+ };
42017
+ try {
42018
+ if (isObject(result) && typeof result.withRawResponse === "function") {
42019
+ void result.withRawResponse().then(
42020
+ ({
42021
+ data,
42022
+ rawResponse
42023
+ }) => capture(data, rawResponse?.headers),
42024
+ finish
42025
+ );
42026
+ } else {
42027
+ void Promise.resolve(result).then((value) => capture(value), finish);
42028
+ }
42029
+ } catch (error2) {
42030
+ debugLogger.error("Error observing ElevenLabs result", error2);
42031
+ finish();
42032
+ }
42033
+ return result;
42034
+ });
42035
+ }
42036
+ function captureSpeech(value, request, method, span, finish, started, headers) {
42037
+ const format = request.outputFormat ?? "mp3_44100_128";
42038
+ const formatType = format.startsWith("mp3_") ? "audio/mpeg" : format.startsWith("pcm_") ? "audio/pcm" : format.startsWith("opus_") ? "audio/ogg" : format.startsWith("ulaw_") ? "audio/basic" : format.startsWith("alaw_") ? "audio/x-alaw" : void 0;
42039
+ const headerType = headers?.get("content-type")?.split(";")[0];
42040
+ const contentType = headerType?.startsWith("audio/") ? headerType : formatType;
42041
+ const disposition = headers?.get("content-disposition");
42042
+ const headerFilename = disposition?.match(
42043
+ /filename="([^"]+)"|filename=([^;]+)/i
42044
+ );
42045
+ const filename = headerFilename?.[1] ?? headerFilename?.[2]?.trim() ?? `speech.${contentType ? getExtensionFromMediaType(contentType) : "bin"}`;
42046
+ const chunks = [];
42047
+ const alignments = [];
42048
+ let bytes = 0;
42049
+ let first = true;
42050
+ let stopped = false;
42051
+ const observe = (chunk) => {
42052
+ if (stopped || chunk.byteLength === 0) return;
42053
+ if (first && method.startsWith("stream")) {
42054
+ span.log({
42055
+ metrics: { time_to_first_token: Date.now() / 1e3 - started }
42056
+ });
42057
+ }
42058
+ first = false;
42059
+ chunks.push(new Uint8Array(chunk));
42060
+ bytes += chunk.byteLength;
42061
+ };
42062
+ const complete = () => {
42063
+ if (stopped) return;
42064
+ stopped = true;
42065
+ try {
42066
+ const content = [];
42067
+ if (contentType && bytes) {
42068
+ const data = new Uint8Array(bytes);
42069
+ let offset = 0;
42070
+ for (const chunk of chunks) {
42071
+ data.set(chunk, offset);
42072
+ offset += chunk.length;
42073
+ }
42074
+ content.push({
42075
+ type: "file",
42076
+ file: {
42077
+ filename,
42078
+ byte_size: bytes,
42079
+ file_data: new Attachment({
42080
+ data: new Blob([data], { type: contentType }),
42081
+ filename,
42082
+ contentType
42083
+ })
42084
+ }
42085
+ });
42086
+ }
42087
+ span.log({
42088
+ output: {
42089
+ content,
42090
+ ...alignments.length ? { annotations: alignments } : {}
42091
+ }
42092
+ });
42093
+ } finally {
42094
+ chunks.length = 0;
42095
+ finish();
42096
+ }
42097
+ };
42098
+ const cancel = (error2) => {
42099
+ stopped = true;
42100
+ chunks.length = 0;
42101
+ finish(error2);
42102
+ };
42103
+ const timestampChunk = (chunk) => {
42104
+ const binary = atob(chunk.audioBase64);
42105
+ observe(Uint8Array.from(binary, (character) => character.charCodeAt(0)));
42106
+ if (chunk.alignment || chunk.normalizedAlignment)
42107
+ alignments.push({
42108
+ alignment: chunk.alignment,
42109
+ normalized_alignment: chunk.normalizedAlignment
42110
+ });
42111
+ };
42112
+ if (method === "convertWithTimestamps") {
42113
+ timestampChunk(value);
42114
+ complete();
42115
+ } else if (method === "streamWithTimestamps") {
42116
+ patchStreamIfNeeded(value, {
42117
+ shouldCollect: (chunk) => {
42118
+ try {
42119
+ timestampChunk(chunk);
42120
+ } catch (error2) {
42121
+ debugLogger.error("Error collecting ElevenLabs timestamps", error2);
42122
+ cancel();
42123
+ }
42124
+ return false;
42125
+ },
42126
+ onComplete: complete,
42127
+ onCancel: () => cancel(),
42128
+ onError: cancel,
42129
+ aroundNext: (next) => withCurrent(span, next)
42130
+ });
42131
+ } else {
42132
+ observeAudioStream(value, observe, complete, cancel, span);
42133
+ }
42134
+ }
42135
+ function observeAudioStream(value, observe, complete, cancel, span) {
42136
+ let ended = false;
42137
+ const safeObserve = (chunk) => {
42138
+ if (ended) return;
42139
+ try {
42140
+ observe(chunk);
42141
+ } catch (error2) {
42142
+ debugLogger.error("Error collecting ElevenLabs audio", error2);
42143
+ end(false);
42144
+ }
42145
+ };
42146
+ const end = (success, error2) => {
42147
+ if (ended) return;
42148
+ ended = true;
42149
+ try {
42150
+ if (success) complete();
42151
+ else cancel(error2);
42152
+ } catch (loggingError) {
42153
+ debugLogger.error("Error logging ElevenLabs audio", loggingError);
42154
+ cancel();
42155
+ }
42156
+ };
42157
+ if (!isObject(value) || !Object.isExtensible(value)) {
42158
+ end(false);
42159
+ return;
42160
+ }
42161
+ if (typeof value.read === "function" && typeof value.on === "function") {
42162
+ value.on("end", () => end(true));
42163
+ value.on("close", () => end(false));
42164
+ const emit2 = value.emit;
42165
+ if (typeof emit2 === "function")
42166
+ value.emit = function(event, ...args) {
42167
+ if (event === "data" && args[0] instanceof Uint8Array)
42168
+ safeObserve(args[0]);
42169
+ if (event === "error") end(false, args[0]);
42170
+ return Reflect.apply(emit2, this, [event, ...args]);
42171
+ };
42172
+ return;
42173
+ }
42174
+ if (typeof value.getReader === "function") {
42175
+ const webStream = value;
42176
+ const pipeTo = webStream.pipeTo;
42177
+ const pipeThrough = webStream.pipeThrough;
42178
+ webStream.pipeTo = function(destination, options) {
42179
+ if (!isObject(destination) || this.locked || destination.locked)
42180
+ return pipeTo.call(this, destination, options);
42181
+ const tap = new TransformStream({
42182
+ transform(chunk, controller) {
42183
+ safeObserve(chunk);
42184
+ controller.enqueue(chunk);
42185
+ },
42186
+ flush() {
42187
+ end(true);
42188
+ }
42189
+ });
42190
+ const observed = pipeThrough.call(
42191
+ this,
42192
+ tap,
42193
+ options
42194
+ );
42195
+ return observed.pipeTo(destination, options).catch((error2) => {
42196
+ end(false, error2);
42197
+ throw error2;
42198
+ });
42199
+ };
42200
+ webStream.pipeThrough = function(transform, options) {
42201
+ if (this.locked || transform.writable.locked || transform.readable.locked)
42202
+ return pipeThrough.call(this, transform, options);
42203
+ const result = webStream.pipeTo.call(this, transform.writable, options);
42204
+ void result.catch(() => {
42205
+ });
42206
+ return transform.readable;
42207
+ };
42208
+ const getReader = value.getReader;
42209
+ value.getReader = function(...args) {
42210
+ const reader = Reflect.apply(getReader, this, args);
42211
+ const read3 = reader.read;
42212
+ reader.read = function(...readArgs) {
42213
+ return Promise.resolve(
42214
+ withCurrent(span, () => Reflect.apply(read3, this, readArgs))
42215
+ ).then(
42216
+ (result) => {
42217
+ if (result.value) safeObserve(result.value);
42218
+ if (result.done) end(true);
42219
+ return result;
42220
+ },
42221
+ (error2) => {
42222
+ end(false, error2);
42223
+ throw error2;
42224
+ }
42225
+ );
42226
+ };
42227
+ const readerCancel = reader.cancel;
42228
+ reader.cancel = function(...cancelArgs) {
42229
+ const result = Reflect.apply(readerCancel, this, cancelArgs);
42230
+ end(false);
42231
+ return result;
42232
+ };
42233
+ return reader;
42234
+ };
42235
+ const streamCancel = value.cancel;
42236
+ if (typeof streamCancel === "function")
42237
+ value.cancel = function(...args) {
42238
+ const result = Reflect.apply(streamCancel, this, args);
42239
+ void Promise.resolve(result).then(
42240
+ () => end(false),
42241
+ () => {
42242
+ }
42243
+ );
42244
+ return result;
42245
+ };
42246
+ }
42247
+ if (typeof value.getReader === "function" && typeof value.values === "function") {
42248
+ const values = value.values;
42249
+ const iterate = function(...args) {
42250
+ const iterator = Reflect.apply(values, this, args);
42251
+ patchStreamIfNeeded(iterator, {
42252
+ shouldCollect(chunk) {
42253
+ safeObserve(chunk);
42254
+ return false;
42255
+ },
42256
+ onComplete: () => end(true),
42257
+ onCancel: () => end(false),
42258
+ onError: (error2) => end(false, error2),
42259
+ aroundNext: (next) => withCurrent(span, next)
42260
+ });
42261
+ return iterator;
42262
+ };
42263
+ value.values = iterate;
42264
+ Object.defineProperty(value, Symbol.asyncIterator, {
42265
+ configurable: true,
42266
+ writable: true,
42267
+ value: iterate
42268
+ });
42269
+ } else if (isAsyncIterable3(value)) {
42270
+ patchStreamIfNeeded(value, {
42271
+ shouldCollect: (chunk) => {
42272
+ safeObserve(chunk);
42273
+ return false;
42274
+ },
42275
+ onComplete: () => end(true),
42276
+ onCancel: () => end(false),
42277
+ onError: (error2) => end(false, error2),
42278
+ aroundNext: (next) => withCurrent(span, next)
42279
+ });
42280
+ } else if (typeof value.getReader !== "function") end(false);
42281
+ }
42282
+
40105
42283
  // src/instrumentation/plugins/voyageai-channels.ts
40106
42284
  var voyageAIChannels = defineChannels(
40107
42285
  "voyageai",
@@ -40169,7 +42347,7 @@ var VoyageAIPlugin = class extends BasePlugin {
40169
42347
  this.unsubscribers = unsubscribeAll(this.unsubscribers);
40170
42348
  }
40171
42349
  };
40172
- function interceptVoyageAICall(channel2, name, extractInput2, extractOutput2, extractMetrics2 = extractUsageMetrics3) {
42350
+ function interceptVoyageAICall(channel2, name, extractInput3, extractOutput2, extractMetrics2 = extractUsageMetrics3) {
40173
42351
  return channel2.intercept((target, thisArg, args) => {
40174
42352
  const invokeTarget = () => Reflect.apply(target, thisArg, args);
40175
42353
  if (isAutoInstrumentationSuppressed()) {
@@ -40177,7 +42355,7 @@ function interceptVoyageAICall(channel2, name, extractInput2, extractOutput2, ex
40177
42355
  }
40178
42356
  let span;
40179
42357
  try {
40180
- const { input, metadata } = extractInput2(args);
42358
+ const { input, metadata } = extractInput3(args);
40181
42359
  span = startSpan(
40182
42360
  withSpanInstrumentationName(
40183
42361
  {
@@ -40527,14 +42705,14 @@ var CloudflareAIChatPlugin = class extends BasePlugin {
40527
42705
  const result = event.arguments[0];
40528
42706
  state = agent ? this.findResponseState(
40529
42707
  agent,
40530
- stringValue3(ownValue2(result, "requestId"))
42708
+ stringValue4(ownValue2(result, "requestId"))
40531
42709
  ) : void 0;
40532
42710
  if (!state) {
40533
42711
  return;
40534
42712
  }
40535
42713
  state.responseObserved = true;
40536
42714
  const output = serializeMessage(ownValue2(result, "message"));
40537
- const status = stringValue3(ownValue2(result, "status"));
42715
+ const status = stringValue4(ownValue2(result, "status"));
40538
42716
  const error2 = ownValue2(result, "error");
40539
42717
  const input = ownValue2(result, "continuation") === true ? state.input : serializeMessages(readProperty(agent, "messages"))?.filter(
40540
42718
  (message) => typeof output?.id !== "string" || message.id !== output.id
@@ -40581,7 +42759,7 @@ var CloudflareAIChatPlugin = class extends BasePlugin {
40581
42759
  }
40582
42760
  try {
40583
42761
  const agent = asObject(event.self);
40584
- const requestId = stringValue3(event.arguments[0]);
42762
+ const requestId = stringValue4(event.arguments[0]);
40585
42763
  const key = requestId ?? /* @__PURE__ */ Symbol("cloudflare-ai-chat-turn");
40586
42764
  const activeForAgent = agent ? this.getActiveTurns(agent) : void 0;
40587
42765
  const existing = activeForAgent?.get(key);
@@ -40750,7 +42928,7 @@ function ownValue2(value, key) {
40750
42928
  const descriptor = Object.getOwnPropertyDescriptor(object, key);
40751
42929
  return descriptor && "value" in descriptor ? descriptor.value : void 0;
40752
42930
  }
40753
- function stringValue3(value) {
42931
+ function stringValue4(value) {
40754
42932
  return typeof value === "string" ? value : void 0;
40755
42933
  }
40756
42934
  function serializeMessages(value) {
@@ -40868,7 +43046,7 @@ var CloudflareAgentsPlugin = class extends BasePlugin {
40868
43046
  );
40869
43047
  spans.set(event, span);
40870
43048
  } catch (error2) {
40871
- logInstrumentationError6("start", error2);
43049
+ logInstrumentationError7("start", error2);
40872
43050
  }
40873
43051
  },
40874
43052
  asyncEnd: (event) => {
@@ -40888,7 +43066,7 @@ var CloudflareAgentsPlugin = class extends BasePlugin {
40888
43066
  }
40889
43067
  }
40890
43068
  } catch (error2) {
40891
- logInstrumentationError6("completion", error2);
43069
+ logInstrumentationError7("completion", error2);
40892
43070
  } finally {
40893
43071
  safelyEndSpan(span);
40894
43072
  }
@@ -40902,7 +43080,7 @@ var CloudflareAgentsPlugin = class extends BasePlugin {
40902
43080
  try {
40903
43081
  span.log({ error: event.error });
40904
43082
  } catch (error2) {
40905
- logInstrumentationError6("rejection", error2);
43083
+ logInstrumentationError7("rejection", error2);
40906
43084
  } finally {
40907
43085
  safelyEndSpan(span);
40908
43086
  }
@@ -40932,10 +43110,10 @@ function safelyEndSpan(span) {
40932
43110
  try {
40933
43111
  span.end();
40934
43112
  } catch (error2) {
40935
- logInstrumentationError6("span end", error2);
43113
+ logInstrumentationError7("span end", error2);
40936
43114
  }
40937
43115
  }
40938
- function logInstrumentationError6(operation, error2) {
43116
+ function logInstrumentationError7(operation, error2) {
40939
43117
  debugLogger.error(
40940
43118
  `Failed to process Cloudflare Agents ${operation} instrumentation:`,
40941
43119
  error2
@@ -40953,12 +43131,14 @@ var BraintrustPlugin = class extends BasePlugin {
40953
43131
  cloudflareThinkPlugin = null;
40954
43132
  cursorSDKPlugin = null;
40955
43133
  openAIAgentsPlugin = null;
43134
+ googleGenerativeAIPlugin = null;
40956
43135
  googleGenAIPlugin = null;
40957
43136
  huggingFacePlugin = null;
40958
43137
  huggingFaceTransformersPlugin = null;
40959
43138
  openRouterPlugin = null;
40960
43139
  openRouterAgentPlugin = null;
40961
43140
  mistralPlugin = null;
43141
+ langGraphSDKPlugin = null;
40962
43142
  ollamaPlugin = null;
40963
43143
  googleADKPlugin = null;
40964
43144
  coherePlugin = null;
@@ -40971,6 +43151,7 @@ var BraintrustPlugin = class extends BasePlugin {
40971
43151
  langSmithPlugin = null;
40972
43152
  piCodingAgentPlugin = null;
40973
43153
  strandsAgentSDKPlugin = null;
43154
+ elevenLabsPlugin = null;
40974
43155
  voyageAIPlugin = null;
40975
43156
  cloudflareAIChatPlugin = null;
40976
43157
  cloudflareAgentsPlugin = null;
@@ -41012,6 +43193,10 @@ var BraintrustPlugin = class extends BasePlugin {
41012
43193
  this.openAIAgentsPlugin = new OpenAIAgentsPlugin();
41013
43194
  this.openAIAgentsPlugin.enable();
41014
43195
  }
43196
+ if (integrations.googleGenerativeAI !== false) {
43197
+ this.googleGenerativeAIPlugin = new GoogleGenerativeAIPlugin();
43198
+ this.googleGenerativeAIPlugin.enable();
43199
+ }
41015
43200
  if (integrations.googleGenAI !== false && integrations.google !== false) {
41016
43201
  this.googleGenAIPlugin = new GoogleGenAIPlugin();
41017
43202
  this.googleGenAIPlugin.enable();
@@ -41034,6 +43219,10 @@ var BraintrustPlugin = class extends BasePlugin {
41034
43219
  this.mistralPlugin = new MistralPlugin();
41035
43220
  this.mistralPlugin.enable();
41036
43221
  }
43222
+ if (integrations.langgraphSDK !== false) {
43223
+ this.langGraphSDKPlugin = new LangGraphSDKPlugin();
43224
+ this.langGraphSDKPlugin.enable();
43225
+ }
41037
43226
  if (integrations.ollama !== false) {
41038
43227
  this.ollamaPlugin = new OllamaPlugin();
41039
43228
  this.ollamaPlugin.enable();
@@ -41046,6 +43235,10 @@ var BraintrustPlugin = class extends BasePlugin {
41046
43235
  this.coherePlugin = new CoherePlugin();
41047
43236
  this.coherePlugin.enable();
41048
43237
  }
43238
+ if (integrations.elevenlabs !== false) {
43239
+ this.elevenLabsPlugin = new ElevenLabsPlugin();
43240
+ this.elevenLabsPlugin.enable();
43241
+ }
41049
43242
  if (integrations.voyageai !== false) {
41050
43243
  this.voyageAIPlugin = new VoyageAIPlugin();
41051
43244
  this.voyageAIPlugin.enable();
@@ -41130,6 +43323,10 @@ var BraintrustPlugin = class extends BasePlugin {
41130
43323
  this.openAIAgentsPlugin.disable();
41131
43324
  this.openAIAgentsPlugin = null;
41132
43325
  }
43326
+ if (this.googleGenerativeAIPlugin) {
43327
+ this.googleGenerativeAIPlugin.disable();
43328
+ this.googleGenerativeAIPlugin = null;
43329
+ }
41133
43330
  if (this.googleGenAIPlugin) {
41134
43331
  this.googleGenAIPlugin.disable();
41135
43332
  this.googleGenAIPlugin = null;
@@ -41154,6 +43351,10 @@ var BraintrustPlugin = class extends BasePlugin {
41154
43351
  this.mistralPlugin.disable();
41155
43352
  this.mistralPlugin = null;
41156
43353
  }
43354
+ if (this.langGraphSDKPlugin) {
43355
+ this.langGraphSDKPlugin.disable();
43356
+ this.langGraphSDKPlugin = null;
43357
+ }
41157
43358
  if (this.ollamaPlugin) {
41158
43359
  this.ollamaPlugin.disable();
41159
43360
  this.ollamaPlugin = null;
@@ -41166,6 +43367,10 @@ var BraintrustPlugin = class extends BasePlugin {
41166
43367
  this.coherePlugin.disable();
41167
43368
  this.coherePlugin = null;
41168
43369
  }
43370
+ if (this.elevenLabsPlugin) {
43371
+ this.elevenLabsPlugin.disable();
43372
+ this.elevenLabsPlugin = null;
43373
+ }
41169
43374
  if (this.voyageAIPlugin) {
41170
43375
  this.voyageAIPlugin.disable();
41171
43376
  this.voyageAIPlugin = null;
@@ -41259,6 +43464,8 @@ var envIntegrationAliases = {
41259
43464
  "openai-agents-core": "openAIAgents",
41260
43465
  openaiagentscore: "openAIAgents",
41261
43466
  google: "google",
43467
+ "google-generative-ai": "googleGenerativeAI",
43468
+ googlegenerativeai: "googleGenerativeAI",
41262
43469
  "google-genai": "googleGenAI",
41263
43470
  googlegenai: "googleGenAI",
41264
43471
  huggingface: "huggingface",
@@ -41289,10 +43496,15 @@ var envIntegrationAliases = {
41289
43496
  "langchain-js": "langchain",
41290
43497
  "@langchain": "langchain",
41291
43498
  langgraph: "langgraph",
43499
+ langgraphsdk: "langgraphSDK",
43500
+ "langgraph-sdk": "langgraphSDK",
43501
+ "@langchain/langgraph-sdk": "langgraphSDK",
41292
43502
  langsmith: "langsmith",
41293
43503
  voyage: "voyageai",
41294
43504
  "voyage-ai": "voyageai",
41295
- voyageai: "voyageai"
43505
+ voyageai: "voyageai",
43506
+ elevenlabs: "elevenlabs",
43507
+ "@elevenlabs/elevenlabs-js": "elevenlabs"
41296
43508
  };
41297
43509
  function getDefaultInstrumentationIntegrations() {
41298
43510
  return {
@@ -41303,6 +43515,7 @@ function getDefaultInstrumentationIntegrations() {
41303
43515
  aisdk: true,
41304
43516
  google: true,
41305
43517
  googleGenAI: true,
43518
+ googleGenerativeAI: true,
41306
43519
  googleADK: true,
41307
43520
  huggingface: true,
41308
43521
  claudeAgentSDK: true,
@@ -41326,8 +43539,10 @@ function getDefaultInstrumentationIntegrations() {
41326
43539
  gitHubCopilot: true,
41327
43540
  langchain: true,
41328
43541
  langgraph: true,
43542
+ langgraphSDK: true,
41329
43543
  langsmith: true,
41330
43544
  voyageai: true,
43545
+ elevenlabs: true,
41331
43546
  piCodingAgent: true,
41332
43547
  strandsAgentSDK: true,
41333
43548
  cloudflareAgents: true
@@ -42021,8 +44236,8 @@ var import_node_url = require("node:url");
42021
44236
  // src/auto-instrumentations/configs/ai-sdk.ts
42022
44237
  var aiSDKConfigs = [
42023
44238
  // HarnessAgent turn methods are published only from the package's ESM
42024
- // `./agent` entrypoint. The compiled class expression is anonymous, so match
42025
- // the first async method with each public name instead of a class name.
44239
+ // `./agent` entrypoint. Target the class binding so similarly named getters
44240
+ // on stream result classes are not mistaken for agent turn methods.
42026
44241
  ...[
42027
44242
  ["createSession", harnessAgentChannels.createSession.channelName],
42028
44243
  ["generate", harnessAgentChannels.generate.channelName],
@@ -42037,6 +44252,7 @@ var aiSDKConfigs = [
42037
44252
  filePath: "dist/agent/index.js"
42038
44253
  },
42039
44254
  functionQuery: {
44255
+ className: "HarnessAgent",
42040
44256
  methodName,
42041
44257
  kind: "Async",
42042
44258
  index: 0
@@ -42442,9 +44658,9 @@ var aiSDKConfigs = [
42442
44658
  // src/auto-instrumentations/configs/anthropic.ts
42443
44659
  var anthropicConfigs = [
42444
44660
  // Each logical target is listed for both published module formats:
42445
- // `.mjs` covers ESM imports, while `.js` covers CJS requires. The Bedrock
42446
- // SDK delegates CJS `messages.create` calls through these Anthropic SDK
42447
- // `.js` resource files.
44661
+ // `.mjs` covers ESM imports, while `.js` covers CJS requires. Both
44662
+ // @anthropic-ai/bedrock-sdk and @anthropic-ai/vertex-sdk instantiate these
44663
+ // shared Anthropic resources, so they use the same targets and channels.
42448
44664
  // Messages API - create in older SDK layouts (supports streaming via stream=true parameter)
42449
44665
  {
42450
44666
  channelName: anthropicChannels.messagesCreate.channelName,
@@ -43534,6 +45750,26 @@ var googleADKConfigs = [
43534
45750
  }
43535
45751
  ];
43536
45752
 
45753
+ // src/auto-instrumentations/configs/google-generative-ai.ts
45754
+ var googleGenerativeAIConfigs = [
45755
+ "dist/index.js",
45756
+ "dist/index.mjs"
45757
+ ].flatMap(
45758
+ (filePath) => Object.entries(googleGenerativeAIChannels).map(([methodName, channel2]) => ({
45759
+ channelName: channel2.channelName,
45760
+ module: {
45761
+ name: "@google/generative-ai",
45762
+ versionRange: ">=0.24.0 <0.25.0",
45763
+ filePath
45764
+ },
45765
+ functionQuery: {
45766
+ className: methodName.startsWith("sendMessage") ? "ChatSession" : "GenerativeModel",
45767
+ methodName,
45768
+ kind: "Async"
45769
+ }
45770
+ }))
45771
+ );
45772
+
43537
45773
  // src/auto-instrumentations/configs/google-genai.ts
43538
45774
  var googleGenAIConfigs = [
43539
45775
  // Models.generateContentInternal - The actual class method (Node.js entry point)
@@ -43595,6 +45831,21 @@ var googleGenAIConfigs = [
43595
45831
  kind: "Async"
43596
45832
  }
43597
45833
  },
45834
+ // The SDK's embedding response converter drops usageMetadata. Observe the
45835
+ // parsed HTTP response before conversion; the plugin scopes this to embeddings.
45836
+ {
45837
+ channelName: googleGenAIChannels.httpResponseJson.channelName,
45838
+ module: {
45839
+ name: "@google/genai",
45840
+ versionRange: ">=1.0.0",
45841
+ filePath: "dist/node/index.mjs"
45842
+ },
45843
+ functionQuery: {
45844
+ className: "HttpResponse",
45845
+ methodName: "json",
45846
+ kind: "Async"
45847
+ }
45848
+ },
43598
45849
  // BaseInteractions.create - Interactions API entry point
43599
45850
  {
43600
45851
  channelName: googleGenAIChannels.interactionsCreate.channelName,
@@ -44302,6 +46553,26 @@ var mistralConfigs = [
44302
46553
  }
44303
46554
  ];
44304
46555
 
46556
+ // src/auto-instrumentations/configs/langgraph-sdk.ts
46557
+ var langGraphSDKConfigs = [
46558
+ "js",
46559
+ "cjs"
46560
+ ].flatMap(
46561
+ (extension) => ["wait", "stream"].map((methodName) => ({
46562
+ channelName: langGraphSDKChannels[methodName].channelName,
46563
+ module: {
46564
+ name: "@langchain/langgraph-sdk",
46565
+ versionRange: ">=1.9.25 <2.0.0",
46566
+ filePath: `dist/client/runs/index.${extension}`
46567
+ },
46568
+ functionQuery: {
46569
+ className: "RunsClient",
46570
+ methodName,
46571
+ kind: methodName === "stream" ? "Sync" : "Async"
46572
+ }
46573
+ }))
46574
+ );
46575
+
44305
46576
  // src/auto-instrumentations/configs/ollama.ts
44306
46577
  var methods = [
44307
46578
  ["chat", ollamaChannels.chat.channelName],
@@ -44722,6 +46993,41 @@ var strandsAgentSDKConfigs = [
44722
46993
  }
44723
46994
  ];
44724
46995
 
46996
+ // src/auto-instrumentations/configs/elevenlabs.ts
46997
+ var elevenLabsConfigs = [
46998
+ ...[
46999
+ "convert",
47000
+ "stream",
47001
+ "convertWithTimestamps",
47002
+ "streamWithTimestamps"
47003
+ ].map((methodName) => ({
47004
+ channelName: elevenLabsChannels[methodName].channelName,
47005
+ module: {
47006
+ name: "@elevenlabs/elevenlabs-js",
47007
+ versionRange: ">=2.67.0 <3.0.0",
47008
+ filePath: "api/resources/textToSpeech/client/Client.js"
47009
+ },
47010
+ functionQuery: {
47011
+ className: "TextToSpeechClient",
47012
+ methodName,
47013
+ kind: "Async"
47014
+ }
47015
+ })),
47016
+ {
47017
+ channelName: elevenLabsChannels.transcribe.channelName,
47018
+ module: {
47019
+ name: "@elevenlabs/elevenlabs-js",
47020
+ versionRange: ">=2.67.0 <3.0.0",
47021
+ filePath: "api/resources/speechToText/client/Client.js"
47022
+ },
47023
+ functionQuery: {
47024
+ className: "SpeechToTextClient",
47025
+ methodName: "convert",
47026
+ kind: "Async"
47027
+ }
47028
+ }
47029
+ ];
47030
+
44725
47031
  // src/auto-instrumentations/configs/voyageai.ts
44726
47032
  var GENERATED_CLIENT_MODULES = [
44727
47033
  "dist/cjs/Client.js",
@@ -44806,6 +47112,10 @@ var defaultInstrumentationConfigGroups = [
44806
47112
  integrations: ["openAIAgents"],
44807
47113
  configs: openAIAgentsCoreConfigs
44808
47114
  },
47115
+ {
47116
+ integrations: ["googleGenerativeAI"],
47117
+ configs: googleGenerativeAIConfigs
47118
+ },
44809
47119
  {
44810
47120
  integrations: ["google", "googleGenAI"],
44811
47121
  configs: googleGenAIConfigs
@@ -44825,6 +47135,7 @@ var defaultInstrumentationConfigGroups = [
44825
47135
  configs: openRouterAgentConfigs
44826
47136
  },
44827
47137
  { integrations: ["mistral"], configs: mistralConfigs },
47138
+ { integrations: ["langgraphSDK"], configs: langGraphSDKConfigs },
44828
47139
  { integrations: ["ollama"], configs: ollamaConfigs },
44829
47140
  { integrations: ["googleADK"], configs: googleADKConfigs },
44830
47141
  { integrations: ["cohere"], configs: cohereConfigs },
@@ -44849,6 +47160,10 @@ var defaultInstrumentationConfigGroups = [
44849
47160
  integrations: ["flue"],
44850
47161
  configs: flueConfigs
44851
47162
  },
47163
+ {
47164
+ integrations: ["elevenlabs"],
47165
+ configs: elevenLabsConfigs
47166
+ },
44852
47167
  {
44853
47168
  integrations: ["voyageai"],
44854
47169
  configs: voyageAIConfigs
@@ -47931,9 +50246,10 @@ async function initFile({
47931
50246
  outFile: bundleFile,
47932
50247
  tsconfig,
47933
50248
  plugins: [],
47934
- externalPackages
50249
+ externalPackages,
50250
+ markKnownPackagesExternal: false
47935
50251
  }),
47936
- external: ["fsevents", "chokidar"],
50252
+ external: ["fsevents", "chokidar", ...externalPackages ?? []],
47937
50253
  write: true,
47938
50254
  minify: true,
47939
50255
  sourcemap: true
@@ -48241,12 +50557,13 @@ function buildOpts({
48241
50557
  outFile,
48242
50558
  tsconfig,
48243
50559
  plugins: argPlugins,
48244
- externalPackages
50560
+ externalPackages,
50561
+ markKnownPackagesExternal = true
48245
50562
  }) {
48246
50563
  const plugins = [
48247
50564
  braintrustEsbuildPlugin(),
48248
50565
  nativeNodeModulesPlugin,
48249
- createMarkKnownPackagesExternalPlugin(externalPackages),
50566
+ ...markKnownPackagesExternal ? [createMarkKnownPackagesExternalPlugin(externalPackages)] : [],
48250
50567
  ...(argPlugins || []).map((fn) => fn(fileName))
48251
50568
  ];
48252
50569
  return {
@@ -48291,13 +50608,13 @@ async function initializeHandles({
48291
50608
  );
48292
50609
  process.exit(0);
48293
50610
  }
48294
- const tmpDir = import_node_path7.default.join(import_node_os.default.tmpdir(), `btevals-${(0, import_uuid3.v4)().slice(0, 8)}`);
50611
+ const tmpDir = import_node_path7.default.join(import_node_os.default.tmpdir(), `btevals-${(0, import_uuid4.v4)().slice(0, 8)}`);
48295
50612
  const initPromises = [];
48296
50613
  for (const file of Object.keys(files)) {
48297
50614
  const baseName = `${import_node_path7.default.basename(
48298
50615
  file,
48299
50616
  import_node_path7.default.extname(file)
48300
- )}-${(0, import_uuid3.v4)().slice(0, 8)}`;
50617
+ )}-${(0, import_uuid4.v4)().slice(0, 8)}`;
48301
50618
  const outFile = import_node_path7.default.join(tmpDir, `${baseName}.${OUT_EXT}`);
48302
50619
  const bundleFile = import_node_path7.default.join(tmpDir, `${baseName}.bundle.js`);
48303
50620
  initPromises.push(