braintrust 3.30.0 → 3.32.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 (55) hide show
  1. package/dev/dist/index.d.mts +740 -1
  2. package/dev/dist/index.d.ts +740 -1
  3. package/dev/dist/index.js +1307 -434
  4. package/dev/dist/index.mjs +886 -13
  5. package/dist/apply-auto-instrumentation.js +281 -216
  6. package/dist/apply-auto-instrumentation.mjs +66 -1
  7. package/dist/auto-instrumentations/bundler/esbuild.cjs +104 -2
  8. package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
  9. package/dist/auto-instrumentations/bundler/next.cjs +113 -5
  10. package/dist/auto-instrumentations/bundler/next.mjs +12 -6
  11. package/dist/auto-instrumentations/bundler/rollup.cjs +104 -2
  12. package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
  13. package/dist/auto-instrumentations/bundler/vite.cjs +104 -2
  14. package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
  15. package/dist/auto-instrumentations/bundler/webpack-loader.cjs +104 -2
  16. package/dist/auto-instrumentations/bundler/webpack.cjs +104 -2
  17. package/dist/auto-instrumentations/bundler/webpack.mjs +3 -3
  18. package/dist/auto-instrumentations/{chunk-U64OYU4Q.mjs → chunk-AFND2U7E.mjs} +38 -1
  19. package/dist/auto-instrumentations/{chunk-OXINGIEZ.mjs → chunk-QEEPRBIS.mjs} +1 -1
  20. package/dist/auto-instrumentations/{chunk-LW4HDHXT.mjs → chunk-RI4Y55ZF.mjs} +69 -2
  21. package/dist/auto-instrumentations/hook.mjs +126 -3
  22. package/dist/auto-instrumentations/index.cjs +39 -1
  23. package/dist/auto-instrumentations/index.d.mts +3 -1
  24. package/dist/auto-instrumentations/index.d.ts +3 -1
  25. package/dist/auto-instrumentations/index.mjs +3 -1
  26. package/dist/browser.d.mts +3052 -927
  27. package/dist/browser.d.ts +3052 -927
  28. package/dist/browser.js +1023 -18
  29. package/dist/browser.mjs +1023 -18
  30. package/dist/{chunk-BU6SM54N.mjs → chunk-4QSAHP7D.mjs} +834 -10
  31. package/dist/{chunk-2XDW3UCG.js → chunk-AW4QECG5.js} +47 -4
  32. package/dist/{chunk-TWCDSYJN.js → chunk-BTRLPQG5.js} +1679 -855
  33. package/dist/{chunk-N3JKQ3D3.mjs → chunk-WV6QZI2W.mjs} +46 -3
  34. package/dist/cli.js +950 -14
  35. package/dist/edge-light.d.mts +1 -1
  36. package/dist/edge-light.d.ts +1 -1
  37. package/dist/edge-light.js +1023 -18
  38. package/dist/edge-light.mjs +1023 -18
  39. package/dist/index.d.mts +3052 -927
  40. package/dist/index.d.ts +3052 -927
  41. package/dist/index.js +594 -450
  42. package/dist/index.mjs +149 -5
  43. package/dist/instrumentation/index.d.mts +434 -0
  44. package/dist/instrumentation/index.d.ts +434 -0
  45. package/dist/instrumentation/index.js +875 -12
  46. package/dist/instrumentation/index.mjs +875 -12
  47. package/dist/vitest-evals-reporter.js +16 -16
  48. package/dist/vitest-evals-reporter.mjs +2 -2
  49. package/dist/workerd.d.mts +1 -1
  50. package/dist/workerd.d.ts +1 -1
  51. package/dist/workerd.js +1023 -18
  52. package/dist/workerd.mjs +1023 -18
  53. package/package.json +1 -1
  54. package/util/dist/index.d.mts +326 -0
  55. package/util/dist/index.d.ts +326 -0
@@ -3115,6 +3115,14 @@ var ChatCompletionContentPartImageWithTitle = z6.object({
3115
3115
  ttl: z6.enum(["5m", "1h"]).optional()
3116
3116
  }).optional()
3117
3117
  });
3118
+ var ChatCompletionContentPartInputAudioWithTitle = z6.object({
3119
+ input_audio: z6.object({ data: z6.string(), format: z6.enum(["wav", "mp3"]) }),
3120
+ type: z6.literal("input_audio"),
3121
+ cache_control: z6.object({
3122
+ type: z6.literal("ephemeral"),
3123
+ ttl: z6.enum(["5m", "1h"]).optional()
3124
+ }).optional()
3125
+ });
3118
3126
  var ChatCompletionContentPartFileFile = z6.object({ file_data: z6.string(), filename: z6.string(), file_id: z6.string() }).partial();
3119
3127
  var ChatCompletionContentPartFileWithTitle = z6.object({
3120
3128
  file: ChatCompletionContentPartFileFile,
@@ -3127,6 +3135,7 @@ var ChatCompletionContentPartFileWithTitle = z6.object({
3127
3135
  var ChatCompletionContentPart = z6.union([
3128
3136
  ChatCompletionContentPartTextWithTitle,
3129
3137
  ChatCompletionContentPartImageWithTitle,
3138
+ ChatCompletionContentPartInputAudioWithTitle,
3130
3139
  ChatCompletionContentPartFileWithTitle
3131
3140
  ]);
3132
3141
  var ChatCompletionContentPartText = z6.object({
@@ -4118,6 +4127,7 @@ var ProjectSettings = z6.union([
4118
4127
  ]),
4119
4128
  disable_realtime_queries: z6.union([z6.boolean(), z6.null()]),
4120
4129
  monitor_charts_use_metrics_start: z6.union([z6.boolean(), z6.null()]),
4130
+ blind_reviews: z6.union([z6.boolean(), z6.null()]),
4121
4131
  default_preprocessor: NullableSavedFunctionId
4122
4132
  }).partial(),
4123
4133
  z6.null()
@@ -4179,6 +4189,7 @@ var WindowedAutomationConfig = z6.object({
4179
4189
  auto_approve_tools: z6.array(z6.string().min(1)).optional().default([]),
4180
4190
  harness: z6.enum(["native", "codex", "claude-code"]).optional(),
4181
4191
  model: z6.string().min(1).optional(),
4192
+ endpoint_name: z6.string().min(1).optional(),
4182
4193
  reasoning_effort: z6.enum(["none", "minimal", "low", "medium", "high", "xhigh", "max"]).optional()
4183
4194
  }).optional(),
4184
4195
  actions: z6.array(
@@ -5952,6 +5963,7 @@ var INSTRUMENTATION_NAMES = {
5952
5963
  GENKIT: "genkit",
5953
5964
  GITHUB_COPILOT: "github-copilot",
5954
5965
  GOOGLE_ADK: "google-adk",
5966
+ GOOGLE_GENERATIVE_AI: "google-generative-ai",
5955
5967
  GOOGLE_GENAI: "google-genai",
5956
5968
  GROQ: "groq",
5957
5969
  HUGGINGFACE: "huggingface",
@@ -5967,12 +5979,13 @@ var INSTRUMENTATION_NAMES = {
5967
5979
  OPENROUTER_AGENT: "openrouter-agent",
5968
5980
  PI_CODING_AGENT: "pi-coding-agent",
5969
5981
  STRANDS_AGENT_SDK: "strands-agent-sdk",
5970
- VOYAGEAI: "voyageai"
5982
+ VOYAGEAI: "voyageai",
5983
+ ELEVENLABS: "elevenlabs"
5971
5984
  };
5972
5985
  var INTERNAL_SPAN_INSTRUMENTATION_NAME = /* @__PURE__ */ Symbol.for(
5973
5986
  "braintrust.spanInstrumentationName"
5974
5987
  );
5975
- var SDK_VERSION = true ? "3.30.0" : "0.0.0";
5988
+ var SDK_VERSION = true ? "3.32.0" : "0.0.0";
5976
5989
  function withSpanInstrumentationName(args, instrumentationName) {
5977
5990
  return {
5978
5991
  ...args,
@@ -11146,6 +11159,16 @@ function renderMessageImpl(render, message, variables) {
11146
11159
  }
11147
11160
  }
11148
11161
  ];
11162
+ case "input_audio":
11163
+ return [
11164
+ {
11165
+ ...c,
11166
+ input_audio: {
11167
+ ...c.input_audio,
11168
+ data: render(c.input_audio.data)
11169
+ }
11170
+ }
11171
+ ];
11149
11172
  case "file":
11150
11173
  return [
11151
11174
  {
@@ -19197,6 +19220,12 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
19197
19220
  if (!activeEntry) {
19198
19221
  return result;
19199
19222
  }
19223
+ const executionOptions = args[1];
19224
+ const toolCallId = isObject(executionOptions) ? executionOptions.toolCallId : void 0;
19225
+ const toolInput = {
19226
+ input: serializeToolExecutionInput(args),
19227
+ ...typeof toolCallId === "string" ? { metadata: { toolCallId } } : {}
19228
+ };
19200
19229
  if (isAsyncGenerator(result)) {
19201
19230
  return (async function* () {
19202
19231
  const span = activeEntry.parentSpan.startSpan(
@@ -19210,7 +19239,7 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
19210
19239
  INSTRUMENTATION_NAMES.AI_SDK
19211
19240
  )
19212
19241
  );
19213
- span.log({ input: serializeToolExecutionInput(args) });
19242
+ span.log(toolInput);
19214
19243
  try {
19215
19244
  let lastValue;
19216
19245
  for await (const value of result) {
@@ -19228,7 +19257,7 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
19228
19257
  }
19229
19258
  return activeEntry.parentSpan.traced(
19230
19259
  async (span) => {
19231
- span.log({ input: serializeToolExecutionInput(args) });
19260
+ span.log(toolInput);
19232
19261
  const awaitedResult = await result;
19233
19262
  span.log({ output: awaitedResult });
19234
19263
  return awaitedResult;
@@ -23632,6 +23661,342 @@ var OpenAIAgentsPlugin = class extends BasePlugin {
23632
23661
  }
23633
23662
  };
23634
23663
 
23664
+ // src/instrumentation/plugins/google-generative-ai-channels.ts
23665
+ var googleGenerativeAIChannels = defineChannels(
23666
+ "@google/generative-ai",
23667
+ {
23668
+ generateContent: channel({ channelName: "GenerativeModel.generateContent", kind: "async" }),
23669
+ generateContentStream: channel({ channelName: "GenerativeModel.generateContentStream", kind: "async" }),
23670
+ embedContent: channel({ channelName: "GenerativeModel.embedContent", kind: "async" }),
23671
+ batchEmbedContents: channel({ channelName: "GenerativeModel.batchEmbedContents", kind: "async" }),
23672
+ sendMessage: channel({ channelName: "ChatSession.sendMessage", kind: "async" }),
23673
+ sendMessageStream: channel({ channelName: "ChatSession.sendMessageStream", kind: "async" })
23674
+ },
23675
+ { instrumentationName: INSTRUMENTATION_NAMES.GOOGLE_GENERATIVE_AI }
23676
+ );
23677
+
23678
+ // src/instrumentation/plugins/google-generative-ai-plugin.ts
23679
+ var GENERATION_CONFIG_KEYS = [
23680
+ "temperature",
23681
+ "topP",
23682
+ "topK",
23683
+ "candidateCount",
23684
+ "maxOutputTokens",
23685
+ "stopSequences",
23686
+ "responseMimeType",
23687
+ "responseSchema",
23688
+ "presencePenalty",
23689
+ "frequencyPenalty",
23690
+ "responseLogprobs",
23691
+ "logprobs",
23692
+ "thinkingConfig"
23693
+ ];
23694
+ var GoogleGenerativeAIPlugin = class extends BasePlugin {
23695
+ onEnable() {
23696
+ this.unsubscribers.push(
23697
+ interceptCall(
23698
+ googleGenerativeAIChannels.generateContent,
23699
+ "generateContent"
23700
+ ),
23701
+ interceptCall(
23702
+ googleGenerativeAIChannels.generateContentStream,
23703
+ "generateContentStream"
23704
+ ),
23705
+ interceptCall(googleGenerativeAIChannels.sendMessage, "sendMessage"),
23706
+ interceptCall(
23707
+ googleGenerativeAIChannels.sendMessageStream,
23708
+ "sendMessageStream"
23709
+ ),
23710
+ interceptCall(googleGenerativeAIChannels.embedContent, "embedContent"),
23711
+ interceptCall(
23712
+ googleGenerativeAIChannels.batchEmbedContents,
23713
+ "batchEmbedContents"
23714
+ )
23715
+ );
23716
+ }
23717
+ onDisable() {
23718
+ this.unsubscribers = unsubscribeAll(this.unsubscribers);
23719
+ }
23720
+ };
23721
+ function interceptCall(channel2, operation) {
23722
+ return channel2.intercept((target, thisArg, args) => {
23723
+ const invokeTarget = () => Reflect.apply(target, thisArg, args);
23724
+ if (isAutoInstrumentationSuppressed()) return invokeTarget();
23725
+ const self = thisArg;
23726
+ const chat = operation.startsWith("sendMessage");
23727
+ const embedding = operation === "embedContent" || operation === "batchEmbedContents";
23728
+ const start = getCurrentUnixTimestamp();
23729
+ let span;
23730
+ try {
23731
+ span = startSpan(
23732
+ withSpanInstrumentationName(
23733
+ {
23734
+ name: embedding ? operation === "embedContent" ? "embed_content" : "batch_embed_contents" : "generate_content",
23735
+ spanAttributes: { type: "llm" /* LLM */ },
23736
+ event: extractInput(self, args[0], operation)
23737
+ },
23738
+ INSTRUMENTATION_NAMES.GOOGLE_GENERATIVE_AI
23739
+ )
23740
+ );
23741
+ } catch (error) {
23742
+ debugLogger.error("Error starting Google Generative AI span:", error);
23743
+ return invokeTarget();
23744
+ }
23745
+ let ended = false;
23746
+ const finish = (log2) => {
23747
+ if (ended) return;
23748
+ ended = true;
23749
+ try {
23750
+ log2();
23751
+ } catch (error) {
23752
+ debugLogger.error("Error logging Google Generative AI span:", error);
23753
+ }
23754
+ try {
23755
+ span.end();
23756
+ } catch (error) {
23757
+ debugLogger.error("Error ending Google Generative AI span:", error);
23758
+ }
23759
+ };
23760
+ if (chat) {
23761
+ try {
23762
+ void self._sendPromise.then(
23763
+ () => {
23764
+ try {
23765
+ span.log(extractInput(self, args[0], operation));
23766
+ } catch (error) {
23767
+ debugLogger.error("Error capturing Google chat history:", error);
23768
+ }
23769
+ },
23770
+ () => {
23771
+ }
23772
+ );
23773
+ } catch (error) {
23774
+ debugLogger.error("Error observing Google chat history:", error);
23775
+ }
23776
+ }
23777
+ let result;
23778
+ try {
23779
+ result = withCurrent(
23780
+ span,
23781
+ () => runWithAutoInstrumentationSuppressed(invokeTarget)
23782
+ );
23783
+ } catch (error) {
23784
+ finish(() => span.log({ error }));
23785
+ throw error;
23786
+ }
23787
+ void Promise.resolve(result).then(
23788
+ (value) => {
23789
+ try {
23790
+ if ("stream" in value) {
23791
+ let firstToken = false;
23792
+ const partial = { candidates: [] };
23793
+ const candidates = /* @__PURE__ */ new Map();
23794
+ patchStreamIfNeeded(value.stream, {
23795
+ aroundNext: (callback) => withCurrent(span, callback),
23796
+ onChunk: (chunk) => {
23797
+ for (const candidate of chunk.candidates ?? []) {
23798
+ const index = candidate.index ?? 0;
23799
+ const previous = candidates.get(index);
23800
+ const parts = [...previous?.content?.parts ?? []];
23801
+ for (const part of candidate.content?.parts ?? []) {
23802
+ const last = parts[parts.length - 1];
23803
+ if (part.text !== void 0 && last?.text !== void 0) {
23804
+ parts[parts.length - 1] = {
23805
+ ...last,
23806
+ text: last.text + part.text
23807
+ };
23808
+ } else parts.push(part);
23809
+ }
23810
+ candidates.set(index, {
23811
+ ...previous,
23812
+ ...candidate,
23813
+ content: {
23814
+ role: candidate.content?.role ?? previous?.content?.role ?? "model",
23815
+ parts
23816
+ }
23817
+ });
23818
+ }
23819
+ partial.candidates = Array.from(candidates.values());
23820
+ if (chunk.usageMetadata)
23821
+ partial.usageMetadata = chunk.usageMetadata;
23822
+ if (!firstToken && chunk.candidates?.some(
23823
+ (candidate) => candidate.content?.parts.some(
23824
+ (part) => part.text !== void 0 ? part.text.length > 0 : Object.keys(part).length > 0
23825
+ )
23826
+ )) {
23827
+ firstToken = true;
23828
+ span.log({
23829
+ metrics: {
23830
+ time_to_first_token: getCurrentUnixTimestamp() - start
23831
+ }
23832
+ });
23833
+ }
23834
+ },
23835
+ onComplete: () => {
23836
+ },
23837
+ onError: (error) => finish(() => {
23838
+ logResponse(span, partial);
23839
+ span.log({ error });
23840
+ }),
23841
+ onCancel: () => finish(() => logResponse(span, partial))
23842
+ });
23843
+ void value.response.then(
23844
+ (response) => finish(() => logResponse(span, response)),
23845
+ (error) => finish(() => {
23846
+ logResponse(span, partial);
23847
+ span.log({ error });
23848
+ })
23849
+ );
23850
+ } else if ("response" in value) {
23851
+ finish(() => logResponse(span, value.response));
23852
+ } else {
23853
+ const metrics = {};
23854
+ const promptTokens = value.usageMetadata?.promptTokenCount;
23855
+ if (typeof promptTokens === "number" && Number.isFinite(promptTokens) && promptTokens >= 0) {
23856
+ metrics.prompt_tokens = promptTokens;
23857
+ metrics.tokens = promptTokens;
23858
+ }
23859
+ for (const detail of value.usageMetadata?.promptTokenDetails ?? []) {
23860
+ if (detail.modality === "AUDIO" && typeof detail.tokenCount === "number" && Number.isFinite(detail.tokenCount) && detail.tokenCount >= 0) {
23861
+ metrics.prompt_audio_tokens = (metrics.prompt_audio_tokens ?? 0) + detail.tokenCount;
23862
+ }
23863
+ }
23864
+ finish(
23865
+ () => span.log({
23866
+ metrics,
23867
+ output: {
23868
+ count: value.embeddings?.length ?? (value.embedding ? 1 : 0)
23869
+ }
23870
+ })
23871
+ );
23872
+ }
23873
+ } catch (error) {
23874
+ debugLogger.error(
23875
+ "Error observing Google Generative AI result:",
23876
+ error
23877
+ );
23878
+ finish(() => {
23879
+ });
23880
+ }
23881
+ },
23882
+ (error) => finish(() => span.log({ error }))
23883
+ );
23884
+ return result;
23885
+ });
23886
+ }
23887
+ function normalizeContent(message) {
23888
+ const parts = (typeof message === "string" ? [message] : message).map(
23889
+ (part) => typeof part === "string" ? { text: part } : part
23890
+ );
23891
+ return {
23892
+ role: parts.some((part) => part.functionResponse) ? "function" : "user",
23893
+ parts
23894
+ };
23895
+ }
23896
+ function extractInput(self, request, operation) {
23897
+ const model = self.model.replace(/^models\//, "");
23898
+ if (operation === "embedContent" || operation === "batchEmbedContents") {
23899
+ const requests = operation === "batchEmbedContents" ? request.requests : [
23900
+ typeof request === "string" || Array.isArray(request) ? { content: normalizeContent(request) } : request
23901
+ ];
23902
+ const dimensions = requests[0]?.outputDimensionality;
23903
+ return {
23904
+ input: {
23905
+ inputs: convertAttachments(requests).map((item) => ({
23906
+ content: item.content.parts.length === 1 && item.content.parts[0].text !== void 0 ? item.content.parts[0].text : item.content.parts.map((part) => {
23907
+ if (part.text !== void 0)
23908
+ return { type: "text", text: part.text };
23909
+ const mimeType = part.inlineData?.mimeType ?? part.fileData?.mimeType;
23910
+ const data = part.inlineData ? typeof part.inlineData.data === "string" ? `data:${mimeType};base64,${part.inlineData.data}` : part.inlineData.data : part.fileData?.fileUri;
23911
+ return mimeType?.startsWith("image/") ? { type: "image_url", image_url: { url: data } } : { type: "file", file: { file_data: data } };
23912
+ })
23913
+ })),
23914
+ ...dimensions !== void 0 && requests.every((item) => item.outputDimensionality === dimensions) ? { output_dimensions: dimensions } : {}
23915
+ },
23916
+ metadata: { model, provider: "google" }
23917
+ };
23918
+ }
23919
+ const chat = operation.startsWith("sendMessage");
23920
+ const config = chat ? self.params ?? {} : self;
23921
+ const params = typeof request === "string" || Array.isArray(request) ? { contents: [normalizeContent(request)] } : request;
23922
+ const system = params.systemInstruction ?? config.systemInstruction;
23923
+ const systemContent = typeof system === "string" ? { role: "system", parts: [{ text: system }] } : system && "parts" in system ? { ...system, role: "system" } : system ? { role: "system", parts: [system] } : void 0;
23924
+ const contents = [
23925
+ ...systemContent ? [systemContent] : [],
23926
+ ...chat ? self._history : [],
23927
+ ...params.contents
23928
+ ];
23929
+ const metadata = { model, provider: "google" };
23930
+ const generation = params.generationConfig ?? config.generationConfig;
23931
+ for (const key of GENERATION_CONFIG_KEYS) {
23932
+ if (generation && Object.hasOwn(generation, key))
23933
+ metadata[key] = generation[key];
23934
+ }
23935
+ for (const key of ["tools", "toolConfig", "safetySettings"]) {
23936
+ const value = params[key] ?? config[key];
23937
+ if (value !== void 0) metadata[key] = value;
23938
+ }
23939
+ const cached = params.cachedContent ?? config.cachedContent;
23940
+ if (cached)
23941
+ metadata.cachedContent = typeof cached === "string" ? cached : cached.name;
23942
+ return { input: convertAttachments({ model, contents }), metadata };
23943
+ }
23944
+ function convertAttachments(value) {
23945
+ const convert = (node) => {
23946
+ if (Array.isArray(node)) return node.map(convert);
23947
+ if (!isObject(node)) return node;
23948
+ if (isObject(node.inlineData)) {
23949
+ const { data, mimeType } = node.inlineData;
23950
+ const processed = processInputAttachments({
23951
+ type: "file",
23952
+ file: { file_data: `data:${mimeType};base64,${data}` }
23953
+ });
23954
+ if (typeof processed.file.file_data === "string")
23955
+ throw new Error("Unable to convert Google inline data");
23956
+ return {
23957
+ ...node,
23958
+ inlineData: { ...node.inlineData, data: processed.file.file_data }
23959
+ };
23960
+ }
23961
+ return Object.fromEntries(
23962
+ Object.entries(node).map(([key, item]) => [key, convert(item)])
23963
+ );
23964
+ };
23965
+ try {
23966
+ return convert(value);
23967
+ } catch (error) {
23968
+ debugLogger.error(
23969
+ "Error converting Google Generative AI attachments:",
23970
+ error
23971
+ );
23972
+ return value;
23973
+ }
23974
+ }
23975
+ function logResponse(span, response) {
23976
+ const usage = response.usageMetadata;
23977
+ const metrics = {};
23978
+ if (usage) {
23979
+ if (usage.promptTokenCount !== void 0)
23980
+ metrics.prompt_tokens = usage.promptTokenCount;
23981
+ if (usage.candidatesTokenCount !== void 0 || usage.thoughtsTokenCount !== void 0)
23982
+ metrics.completion_tokens = (usage.candidatesTokenCount ?? 0) + (usage.thoughtsTokenCount ?? 0);
23983
+ if (usage.totalTokenCount !== void 0)
23984
+ metrics.tokens = usage.totalTokenCount;
23985
+ if (usage.cachedContentTokenCount !== void 0)
23986
+ metrics.prompt_cached_tokens = usage.cachedContentTokenCount;
23987
+ if (usage.thoughtsTokenCount !== void 0)
23988
+ metrics.completion_reasoning_tokens = usage.thoughtsTokenCount;
23989
+ }
23990
+ span.log({
23991
+ output: convertAttachments({
23992
+ candidates: response.candidates,
23993
+ promptFeedback: response.promptFeedback
23994
+ }),
23995
+ metrics,
23996
+ ...response.modelVersion ? { metadata: { model: response.modelVersion } } : {}
23997
+ });
23998
+ }
23999
+
23635
24000
  // src/instrumentation/plugins/google-genai-channels.ts
23636
24001
  var googleGenAIChannels = defineChannels(
23637
24002
  "@google/genai",
@@ -25275,7 +25640,7 @@ var HuggingFaceTransformersPlugin = class extends BasePlugin {
25275
25640
  getTask(event)
25276
25641
  ),
25277
25642
  extractInput: (args, event) => ({
25278
- input: extractInput(
25643
+ input: extractInput2(
25279
25644
  getTask(event),
25280
25645
  args
25281
25646
  ),
@@ -25365,7 +25730,7 @@ function modelIdentifier(pipeline) {
25365
25730
  }
25366
25731
  return void 0;
25367
25732
  }
25368
- function extractInput(task, args) {
25733
+ function extractInput2(task, args) {
25369
25734
  switch (task) {
25370
25735
  case "feature-extraction":
25371
25736
  return args[0];
@@ -33350,14 +33715,17 @@ function getMetricsFromResponse(response) {
33350
33715
  if (!isRecord(usageMetadata)) {
33351
33716
  continue;
33352
33717
  }
33353
- const inputTokenDetails = usageMetadata.input_token_details;
33718
+ const inputTokenDetails = isRecord(usageMetadata.input_token_details) ? usageMetadata.input_token_details : {};
33354
33719
  const outputTokenDetails = usageMetadata.output_token_details;
33355
33720
  return normalizeTokenMetrics({
33356
33721
  total_tokens: usageMetadata.total_tokens,
33357
33722
  prompt_tokens: usageMetadata.input_tokens,
33358
33723
  completion_tokens: usageMetadata.output_tokens,
33359
- prompt_cache_creation_tokens: isRecord(inputTokenDetails) ? inputTokenDetails.cache_creation : void 0,
33360
- prompt_cached_tokens: isRecord(inputTokenDetails) ? inputTokenDetails.cache_read : void 0,
33724
+ // Prefer TTL-specific cache writes over the aggregate when available.
33725
+ prompt_cache_creation_tokens: inputTokenDetails.ephemeral_5m_input_tokens == null && inputTokenDetails.ephemeral_1h_input_tokens == null ? inputTokenDetails.cache_creation : void 0,
33726
+ prompt_cache_creation_5m_tokens: inputTokenDetails.ephemeral_5m_input_tokens,
33727
+ prompt_cache_creation_1h_tokens: inputTokenDetails.ephemeral_1h_input_tokens,
33728
+ prompt_cached_tokens: inputTokenDetails.cache_read,
33361
33729
  completion_reasoning_tokens: isRecord(outputTokenDetails) ? outputTokenDetails.reasoning : void 0
33362
33730
  });
33363
33731
  }
@@ -35716,6 +36084,477 @@ function logInstrumentationError5(context, error) {
35716
36084
  debugLogger.debug(`${context}:`, error);
35717
36085
  }
35718
36086
 
36087
+ // src/instrumentation/plugins/elevenlabs-channels.ts
36088
+ var elevenLabsChannels = defineChannels(
36089
+ "@elevenlabs/elevenlabs-js",
36090
+ {
36091
+ convert: channel({
36092
+ channelName: "textToSpeech.convert",
36093
+ kind: "async"
36094
+ }),
36095
+ stream: channel({
36096
+ channelName: "textToSpeech.stream",
36097
+ kind: "async"
36098
+ }),
36099
+ convertWithTimestamps: channel({ channelName: "textToSpeech.convertWithTimestamps", kind: "async" }),
36100
+ streamWithTimestamps: channel({ channelName: "textToSpeech.streamWithTimestamps", kind: "async" }),
36101
+ transcribe: channel({ channelName: "speechToText.convert", kind: "async" })
36102
+ },
36103
+ { instrumentationName: INSTRUMENTATION_NAMES.ELEVENLABS }
36104
+ );
36105
+
36106
+ // src/instrumentation/plugins/elevenlabs-plugin.ts
36107
+ var ElevenLabsPlugin = class extends BasePlugin {
36108
+ onEnable() {
36109
+ for (const method of [
36110
+ "convert",
36111
+ "stream",
36112
+ "convertWithTimestamps",
36113
+ "streamWithTimestamps"
36114
+ ]) {
36115
+ this.unsubscribers.push(
36116
+ interceptCall2(
36117
+ elevenLabsChannels[method],
36118
+ `elevenlabs.textToSpeech.${method}`,
36119
+ ([voice, request]) => ({
36120
+ input: {
36121
+ operation: "speech",
36122
+ prompt: request.text,
36123
+ parameters: {
36124
+ voice,
36125
+ format: request.outputFormat,
36126
+ language: request.languageCode,
36127
+ speed: request.voiceSettings?.speed
36128
+ }
36129
+ },
36130
+ metadata: {
36131
+ provider: "elevenlabs",
36132
+ model: request.modelId ?? "eleven_multilingual_v2"
36133
+ }
36134
+ }),
36135
+ (value, args, span, finish, headers, started) => captureSpeech(
36136
+ value,
36137
+ args[1],
36138
+ method,
36139
+ span,
36140
+ finish,
36141
+ started,
36142
+ headers
36143
+ )
36144
+ )
36145
+ );
36146
+ }
36147
+ this.unsubscribers.push(
36148
+ interceptCall2(
36149
+ elevenLabsChannels.transcribe,
36150
+ "elevenlabs.speechToText.convert",
36151
+ ([request]) => {
36152
+ if (request.webhook) return void 0;
36153
+ const file = request.file;
36154
+ const filename = typeof File !== "undefined" && file instanceof File ? file.name : "audio";
36155
+ const contentType = file instanceof Blob ? file.type || "application/octet-stream" : "application/octet-stream";
36156
+ 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;
36157
+ const fileData = blob ? new Attachment({ data: blob, filename, contentType }) : request.cloudStorageUrl;
36158
+ return {
36159
+ input: {
36160
+ operation: "transcribe",
36161
+ content: fileData ? [{ type: "file", file: { filename, file_data: fileData } }] : [],
36162
+ parameters: {
36163
+ language: request.languageCode,
36164
+ timestamp_granularities: request.timestampsGranularity
36165
+ }
36166
+ },
36167
+ metadata: { provider: "elevenlabs", model: request.modelId }
36168
+ };
36169
+ },
36170
+ (value, _args, span, finish) => {
36171
+ const result = value;
36172
+ const transcripts = result.transcripts ?? [result];
36173
+ span.log({
36174
+ output: {
36175
+ content: transcripts.flatMap(
36176
+ (transcript) => typeof transcript.text === "string" ? [{ type: "text", text: transcript.text }] : []
36177
+ ),
36178
+ annotations: {
36179
+ language: result.languageCode,
36180
+ words: result.words ?? (result.transcripts ? result.transcripts.flatMap(
36181
+ (transcript) => transcript.words ?? []
36182
+ ) : void 0)
36183
+ }
36184
+ }
36185
+ });
36186
+ finish();
36187
+ },
36188
+ ([request], span) => {
36189
+ const file = request.file;
36190
+ if (!isAsyncIterable(file)) return;
36191
+ const chunks = [];
36192
+ const filename = isObject(file) && typeof file.path === "string" ? file.path.split(/[\\/]/).pop() || "audio" : "audio";
36193
+ observeAudioStream(
36194
+ file,
36195
+ (chunk) => chunks.push(new Uint8Array(chunk)),
36196
+ () => {
36197
+ const contentType = "application/octet-stream";
36198
+ const data = new Blob(chunks, {
36199
+ type: contentType
36200
+ });
36201
+ chunks.length = 0;
36202
+ span.log({
36203
+ input: {
36204
+ content: [
36205
+ {
36206
+ type: "file",
36207
+ file: {
36208
+ filename,
36209
+ file_data: new Attachment({
36210
+ data,
36211
+ filename,
36212
+ contentType
36213
+ })
36214
+ }
36215
+ }
36216
+ ]
36217
+ }
36218
+ });
36219
+ },
36220
+ () => {
36221
+ chunks.length = 0;
36222
+ },
36223
+ span
36224
+ );
36225
+ }
36226
+ )
36227
+ );
36228
+ }
36229
+ onDisable() {
36230
+ this.unsubscribers = unsubscribeAll(this.unsubscribers);
36231
+ }
36232
+ };
36233
+ function interceptCall2(channel2, name, input, output, beforeInvoke) {
36234
+ return channel2.intercept((target, self, args) => {
36235
+ const invoke2 = () => Reflect.apply(target, self, args);
36236
+ if (isAutoInstrumentationSuppressed()) return invoke2();
36237
+ const started = Date.now() / 1e3;
36238
+ let span;
36239
+ try {
36240
+ const event = input(args);
36241
+ if (event !== void 0)
36242
+ span = startSpan(
36243
+ withSpanInstrumentationName(
36244
+ {
36245
+ name,
36246
+ spanAttributes: { type: "llm" /* LLM */ },
36247
+ event
36248
+ },
36249
+ INSTRUMENTATION_NAMES.ELEVENLABS
36250
+ )
36251
+ );
36252
+ } catch (error) {
36253
+ debugLogger.error("Error starting ElevenLabs span", error);
36254
+ return invoke2();
36255
+ }
36256
+ if (!span) return invoke2();
36257
+ const activeSpan = span;
36258
+ let ended = false;
36259
+ const finish = (error) => {
36260
+ if (ended) return;
36261
+ ended = true;
36262
+ try {
36263
+ if (error !== void 0) activeSpan.log({ error });
36264
+ activeSpan.end();
36265
+ } catch (loggingError) {
36266
+ debugLogger.error("Error ending ElevenLabs span", loggingError);
36267
+ }
36268
+ };
36269
+ try {
36270
+ beforeInvoke?.(args, span);
36271
+ } catch (error) {
36272
+ debugLogger.error("Error observing ElevenLabs input", error);
36273
+ }
36274
+ let result;
36275
+ try {
36276
+ result = withCurrent(
36277
+ span,
36278
+ () => runWithAutoInstrumentationSuppressed(invoke2)
36279
+ );
36280
+ } catch (error) {
36281
+ finish(error);
36282
+ throw error;
36283
+ }
36284
+ const capture = (value, headers) => {
36285
+ try {
36286
+ output(value, args, span, finish, headers, started);
36287
+ } catch (error) {
36288
+ debugLogger.error("Error capturing ElevenLabs output", error);
36289
+ finish();
36290
+ }
36291
+ };
36292
+ try {
36293
+ if (isObject(result) && typeof result.withRawResponse === "function") {
36294
+ void result.withRawResponse().then(
36295
+ ({
36296
+ data,
36297
+ rawResponse
36298
+ }) => capture(data, rawResponse?.headers),
36299
+ finish
36300
+ );
36301
+ } else {
36302
+ void Promise.resolve(result).then((value) => capture(value), finish);
36303
+ }
36304
+ } catch (error) {
36305
+ debugLogger.error("Error observing ElevenLabs result", error);
36306
+ finish();
36307
+ }
36308
+ return result;
36309
+ });
36310
+ }
36311
+ function captureSpeech(value, request, method, span, finish, started, headers) {
36312
+ const format = request.outputFormat ?? "mp3_44100_128";
36313
+ 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;
36314
+ const headerType = headers?.get("content-type")?.split(";")[0];
36315
+ const contentType = headerType?.startsWith("audio/") ? headerType : formatType;
36316
+ const disposition = headers?.get("content-disposition");
36317
+ const headerFilename = disposition?.match(
36318
+ /filename="([^"]+)"|filename=([^;]+)/i
36319
+ );
36320
+ const filename = headerFilename?.[1] ?? headerFilename?.[2]?.trim() ?? `speech.${contentType ? getExtensionFromMediaType(contentType) : "bin"}`;
36321
+ const chunks = [];
36322
+ const alignments = [];
36323
+ let bytes = 0;
36324
+ let first = true;
36325
+ let stopped = false;
36326
+ const observe = (chunk) => {
36327
+ if (stopped || chunk.byteLength === 0) return;
36328
+ if (first && method.startsWith("stream")) {
36329
+ span.log({
36330
+ metrics: { time_to_first_token: Date.now() / 1e3 - started }
36331
+ });
36332
+ }
36333
+ first = false;
36334
+ chunks.push(new Uint8Array(chunk));
36335
+ bytes += chunk.byteLength;
36336
+ };
36337
+ const complete = () => {
36338
+ if (stopped) return;
36339
+ stopped = true;
36340
+ try {
36341
+ const content = [];
36342
+ if (contentType && bytes) {
36343
+ const data = new Uint8Array(bytes);
36344
+ let offset = 0;
36345
+ for (const chunk of chunks) {
36346
+ data.set(chunk, offset);
36347
+ offset += chunk.length;
36348
+ }
36349
+ content.push({
36350
+ type: "file",
36351
+ file: {
36352
+ filename,
36353
+ byte_size: bytes,
36354
+ file_data: new Attachment({
36355
+ data: new Blob([data], { type: contentType }),
36356
+ filename,
36357
+ contentType
36358
+ })
36359
+ }
36360
+ });
36361
+ }
36362
+ span.log({
36363
+ output: {
36364
+ content,
36365
+ ...alignments.length ? { annotations: alignments } : {}
36366
+ }
36367
+ });
36368
+ } finally {
36369
+ chunks.length = 0;
36370
+ finish();
36371
+ }
36372
+ };
36373
+ const cancel = (error) => {
36374
+ stopped = true;
36375
+ chunks.length = 0;
36376
+ finish(error);
36377
+ };
36378
+ const timestampChunk = (chunk) => {
36379
+ const binary = atob(chunk.audioBase64);
36380
+ observe(Uint8Array.from(binary, (character) => character.charCodeAt(0)));
36381
+ if (chunk.alignment || chunk.normalizedAlignment)
36382
+ alignments.push({
36383
+ alignment: chunk.alignment,
36384
+ normalized_alignment: chunk.normalizedAlignment
36385
+ });
36386
+ };
36387
+ if (method === "convertWithTimestamps") {
36388
+ timestampChunk(value);
36389
+ complete();
36390
+ } else if (method === "streamWithTimestamps") {
36391
+ patchStreamIfNeeded(value, {
36392
+ shouldCollect: (chunk) => {
36393
+ try {
36394
+ timestampChunk(chunk);
36395
+ } catch (error) {
36396
+ debugLogger.error("Error collecting ElevenLabs timestamps", error);
36397
+ cancel();
36398
+ }
36399
+ return false;
36400
+ },
36401
+ onComplete: complete,
36402
+ onCancel: () => cancel(),
36403
+ onError: cancel,
36404
+ aroundNext: (next) => withCurrent(span, next)
36405
+ });
36406
+ } else {
36407
+ observeAudioStream(value, observe, complete, cancel, span);
36408
+ }
36409
+ }
36410
+ function observeAudioStream(value, observe, complete, cancel, span) {
36411
+ let ended = false;
36412
+ const safeObserve = (chunk) => {
36413
+ if (ended) return;
36414
+ try {
36415
+ observe(chunk);
36416
+ } catch (error) {
36417
+ debugLogger.error("Error collecting ElevenLabs audio", error);
36418
+ end(false);
36419
+ }
36420
+ };
36421
+ const end = (success, error) => {
36422
+ if (ended) return;
36423
+ ended = true;
36424
+ try {
36425
+ if (success) complete();
36426
+ else cancel(error);
36427
+ } catch (loggingError) {
36428
+ debugLogger.error("Error logging ElevenLabs audio", loggingError);
36429
+ cancel();
36430
+ }
36431
+ };
36432
+ if (!isObject(value) || !Object.isExtensible(value)) {
36433
+ end(false);
36434
+ return;
36435
+ }
36436
+ if (typeof value.read === "function" && typeof value.on === "function") {
36437
+ value.on("end", () => end(true));
36438
+ value.on("close", () => end(false));
36439
+ const emit2 = value.emit;
36440
+ if (typeof emit2 === "function")
36441
+ value.emit = function(event, ...args) {
36442
+ if (event === "data" && args[0] instanceof Uint8Array)
36443
+ safeObserve(args[0]);
36444
+ if (event === "error") end(false, args[0]);
36445
+ return Reflect.apply(emit2, this, [event, ...args]);
36446
+ };
36447
+ return;
36448
+ }
36449
+ if (typeof value.getReader === "function") {
36450
+ const webStream = value;
36451
+ const pipeTo = webStream.pipeTo;
36452
+ const pipeThrough = webStream.pipeThrough;
36453
+ webStream.pipeTo = function(destination, options) {
36454
+ if (!isObject(destination) || this.locked || destination.locked)
36455
+ return pipeTo.call(this, destination, options);
36456
+ const tap = new TransformStream({
36457
+ transform(chunk, controller) {
36458
+ safeObserve(chunk);
36459
+ controller.enqueue(chunk);
36460
+ },
36461
+ flush() {
36462
+ end(true);
36463
+ }
36464
+ });
36465
+ const observed = pipeThrough.call(
36466
+ this,
36467
+ tap,
36468
+ options
36469
+ );
36470
+ return observed.pipeTo(destination, options).catch((error) => {
36471
+ end(false, error);
36472
+ throw error;
36473
+ });
36474
+ };
36475
+ webStream.pipeThrough = function(transform, options) {
36476
+ if (this.locked || transform.writable.locked || transform.readable.locked)
36477
+ return pipeThrough.call(this, transform, options);
36478
+ const result = webStream.pipeTo.call(this, transform.writable, options);
36479
+ void result.catch(() => {
36480
+ });
36481
+ return transform.readable;
36482
+ };
36483
+ const getReader = value.getReader;
36484
+ value.getReader = function(...args) {
36485
+ const reader = Reflect.apply(getReader, this, args);
36486
+ const read2 = reader.read;
36487
+ reader.read = function(...readArgs) {
36488
+ return Promise.resolve(
36489
+ withCurrent(span, () => Reflect.apply(read2, this, readArgs))
36490
+ ).then(
36491
+ (result) => {
36492
+ if (result.value) safeObserve(result.value);
36493
+ if (result.done) end(true);
36494
+ return result;
36495
+ },
36496
+ (error) => {
36497
+ end(false, error);
36498
+ throw error;
36499
+ }
36500
+ );
36501
+ };
36502
+ const readerCancel = reader.cancel;
36503
+ reader.cancel = function(...cancelArgs) {
36504
+ const result = Reflect.apply(readerCancel, this, cancelArgs);
36505
+ end(false);
36506
+ return result;
36507
+ };
36508
+ return reader;
36509
+ };
36510
+ const streamCancel = value.cancel;
36511
+ if (typeof streamCancel === "function")
36512
+ value.cancel = function(...args) {
36513
+ const result = Reflect.apply(streamCancel, this, args);
36514
+ void Promise.resolve(result).then(
36515
+ () => end(false),
36516
+ () => {
36517
+ }
36518
+ );
36519
+ return result;
36520
+ };
36521
+ }
36522
+ if (typeof value.getReader === "function" && typeof value.values === "function") {
36523
+ const values = value.values;
36524
+ const iterate = function(...args) {
36525
+ const iterator = Reflect.apply(values, this, args);
36526
+ patchStreamIfNeeded(iterator, {
36527
+ shouldCollect(chunk) {
36528
+ safeObserve(chunk);
36529
+ return false;
36530
+ },
36531
+ onComplete: () => end(true),
36532
+ onCancel: () => end(false),
36533
+ onError: (error) => end(false, error),
36534
+ aroundNext: (next) => withCurrent(span, next)
36535
+ });
36536
+ return iterator;
36537
+ };
36538
+ value.values = iterate;
36539
+ Object.defineProperty(value, Symbol.asyncIterator, {
36540
+ configurable: true,
36541
+ writable: true,
36542
+ value: iterate
36543
+ });
36544
+ } else if (isAsyncIterable(value)) {
36545
+ patchStreamIfNeeded(value, {
36546
+ shouldCollect: (chunk) => {
36547
+ safeObserve(chunk);
36548
+ return false;
36549
+ },
36550
+ onComplete: () => end(true),
36551
+ onCancel: () => end(false),
36552
+ onError: (error) => end(false, error),
36553
+ aroundNext: (next) => withCurrent(span, next)
36554
+ });
36555
+ } else if (typeof value.getReader !== "function") end(false);
36556
+ }
36557
+
35719
36558
  // src/instrumentation/plugins/voyageai-channels.ts
35720
36559
  var voyageAIChannels = defineChannels(
35721
36560
  "voyageai",
@@ -35783,7 +36622,7 @@ var VoyageAIPlugin = class extends BasePlugin {
35783
36622
  this.unsubscribers = unsubscribeAll(this.unsubscribers);
35784
36623
  }
35785
36624
  };
35786
- function interceptVoyageAICall(channel2, name, extractInput2, extractOutput2, extractMetrics2 = extractUsageMetrics3) {
36625
+ function interceptVoyageAICall(channel2, name, extractInput3, extractOutput2, extractMetrics2 = extractUsageMetrics3) {
35787
36626
  return channel2.intercept((target, thisArg, args) => {
35788
36627
  const invokeTarget = () => Reflect.apply(target, thisArg, args);
35789
36628
  if (isAutoInstrumentationSuppressed()) {
@@ -35791,7 +36630,7 @@ function interceptVoyageAICall(channel2, name, extractInput2, extractOutput2, ex
35791
36630
  }
35792
36631
  let span;
35793
36632
  try {
35794
- const { input, metadata } = extractInput2(args);
36633
+ const { input, metadata } = extractInput3(args);
35795
36634
  span = startSpan(
35796
36635
  withSpanInstrumentationName(
35797
36636
  {
@@ -36567,6 +37406,7 @@ var BraintrustPlugin = class extends BasePlugin {
36567
37406
  cloudflareThinkPlugin = null;
36568
37407
  cursorSDKPlugin = null;
36569
37408
  openAIAgentsPlugin = null;
37409
+ googleGenerativeAIPlugin = null;
36570
37410
  googleGenAIPlugin = null;
36571
37411
  huggingFacePlugin = null;
36572
37412
  huggingFaceTransformersPlugin = null;
@@ -36585,6 +37425,7 @@ var BraintrustPlugin = class extends BasePlugin {
36585
37425
  langSmithPlugin = null;
36586
37426
  piCodingAgentPlugin = null;
36587
37427
  strandsAgentSDKPlugin = null;
37428
+ elevenLabsPlugin = null;
36588
37429
  voyageAIPlugin = null;
36589
37430
  cloudflareAIChatPlugin = null;
36590
37431
  cloudflareAgentsPlugin = null;
@@ -36626,6 +37467,10 @@ var BraintrustPlugin = class extends BasePlugin {
36626
37467
  this.openAIAgentsPlugin = new OpenAIAgentsPlugin();
36627
37468
  this.openAIAgentsPlugin.enable();
36628
37469
  }
37470
+ if (integrations.googleGenerativeAI !== false) {
37471
+ this.googleGenerativeAIPlugin = new GoogleGenerativeAIPlugin();
37472
+ this.googleGenerativeAIPlugin.enable();
37473
+ }
36629
37474
  if (integrations.googleGenAI !== false && integrations.google !== false) {
36630
37475
  this.googleGenAIPlugin = new GoogleGenAIPlugin();
36631
37476
  this.googleGenAIPlugin.enable();
@@ -36660,6 +37505,10 @@ var BraintrustPlugin = class extends BasePlugin {
36660
37505
  this.coherePlugin = new CoherePlugin();
36661
37506
  this.coherePlugin.enable();
36662
37507
  }
37508
+ if (integrations.elevenlabs !== false) {
37509
+ this.elevenLabsPlugin = new ElevenLabsPlugin();
37510
+ this.elevenLabsPlugin.enable();
37511
+ }
36663
37512
  if (integrations.voyageai !== false) {
36664
37513
  this.voyageAIPlugin = new VoyageAIPlugin();
36665
37514
  this.voyageAIPlugin.enable();
@@ -36744,6 +37593,10 @@ var BraintrustPlugin = class extends BasePlugin {
36744
37593
  this.openAIAgentsPlugin.disable();
36745
37594
  this.openAIAgentsPlugin = null;
36746
37595
  }
37596
+ if (this.googleGenerativeAIPlugin) {
37597
+ this.googleGenerativeAIPlugin.disable();
37598
+ this.googleGenerativeAIPlugin = null;
37599
+ }
36747
37600
  if (this.googleGenAIPlugin) {
36748
37601
  this.googleGenAIPlugin.disable();
36749
37602
  this.googleGenAIPlugin = null;
@@ -36780,6 +37633,10 @@ var BraintrustPlugin = class extends BasePlugin {
36780
37633
  this.coherePlugin.disable();
36781
37634
  this.coherePlugin = null;
36782
37635
  }
37636
+ if (this.elevenLabsPlugin) {
37637
+ this.elevenLabsPlugin.disable();
37638
+ this.elevenLabsPlugin = null;
37639
+ }
36783
37640
  if (this.voyageAIPlugin) {
36784
37641
  this.voyageAIPlugin.disable();
36785
37642
  this.voyageAIPlugin = null;
@@ -36873,6 +37730,8 @@ var envIntegrationAliases = {
36873
37730
  "openai-agents-core": "openAIAgents",
36874
37731
  openaiagentscore: "openAIAgents",
36875
37732
  google: "google",
37733
+ "google-generative-ai": "googleGenerativeAI",
37734
+ googlegenerativeai: "googleGenerativeAI",
36876
37735
  "google-genai": "googleGenAI",
36877
37736
  googlegenai: "googleGenAI",
36878
37737
  huggingface: "huggingface",
@@ -36906,7 +37765,9 @@ var envIntegrationAliases = {
36906
37765
  langsmith: "langsmith",
36907
37766
  voyage: "voyageai",
36908
37767
  "voyage-ai": "voyageai",
36909
- voyageai: "voyageai"
37768
+ voyageai: "voyageai",
37769
+ elevenlabs: "elevenlabs",
37770
+ "@elevenlabs/elevenlabs-js": "elevenlabs"
36910
37771
  };
36911
37772
  function getDefaultInstrumentationIntegrations() {
36912
37773
  return {
@@ -36917,6 +37778,7 @@ function getDefaultInstrumentationIntegrations() {
36917
37778
  aisdk: true,
36918
37779
  google: true,
36919
37780
  googleGenAI: true,
37781
+ googleGenerativeAI: true,
36920
37782
  googleADK: true,
36921
37783
  huggingface: true,
36922
37784
  claudeAgentSDK: true,
@@ -36942,6 +37804,7 @@ function getDefaultInstrumentationIntegrations() {
36942
37804
  langgraph: true,
36943
37805
  langsmith: true,
36944
37806
  voyageai: true,
37807
+ elevenlabs: true,
36945
37808
  piCodingAgent: true,
36946
37809
  strandsAgentSDK: true,
36947
37810
  cloudflareAgents: true
@@ -39371,19 +40234,29 @@ function buildSpanScores(results) {
39371
40234
  function _internalPrepareEvaluatorScore(scoreValue, name) {
39372
40235
  if (scoreValue === null) return { results: null };
39373
40236
  if (Array.isArray(scoreValue)) {
40237
+ const names = /* @__PURE__ */ new Set();
39374
40238
  for (const score of scoreValue) {
39375
40239
  if (!(typeof score === "object" && !isEmpty2(score))) {
39376
40240
  throw new Error(
39377
40241
  `When returning an array of scores, each score must be a non-empty object. Got: ${JSON.stringify(score)}`
39378
40242
  );
39379
40243
  }
40244
+ if (typeof score.name !== "string") {
40245
+ throw new Error(
40246
+ `When returning an array of scores, each score must have a name. Got: ${JSON.stringify(score)}`
40247
+ );
40248
+ }
40249
+ if (names.has(score.name)) {
40250
+ throw new Error(`Duplicate score name '${score.name}' in score array`);
40251
+ }
40252
+ names.add(score.name);
39380
40253
  }
39381
40254
  }
39382
40255
  let results;
39383
40256
  if (Array.isArray(scoreValue)) {
39384
40257
  results = scoreValue;
39385
40258
  } else if (typeof scoreValue === "object" && !isEmpty2(scoreValue)) {
39386
- results = [scoreValue];
40259
+ results = [{ ...scoreValue, name: scoreValue.name ?? name }];
39387
40260
  } else {
39388
40261
  results = [{ name, score: scoreValue }];
39389
40262
  }