@traceloop/instrumentation-anthropic 0.22.5 → 0.23.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.
package/dist/index.d.ts CHANGED
@@ -13,6 +13,7 @@ interface AnthropicInstrumentationConfig extends InstrumentationConfig {
13
13
  exceptionLogger?: (e: Error) => void;
14
14
  }
15
15
 
16
+ declare const anthropicFinishReasonMap: Record<string, string>;
16
17
  declare class AnthropicInstrumentation extends InstrumentationBase {
17
18
  protected _config: AnthropicInstrumentationConfig;
18
19
  constructor(config?: AnthropicInstrumentationConfig);
@@ -29,5 +30,5 @@ declare class AnthropicInstrumentation extends InstrumentationBase {
29
30
  private _shouldSendPrompts;
30
31
  }
31
32
 
32
- export { AnthropicInstrumentation };
33
+ export { AnthropicInstrumentation, anthropicFinishReasonMap };
33
34
  export type { AnthropicInstrumentationConfig };
package/dist/index.js CHANGED
@@ -4,10 +4,18 @@ var tslib = require('tslib');
4
4
  var api = require('@opentelemetry/api');
5
5
  var instrumentation = require('@opentelemetry/instrumentation');
6
6
  var aiSemanticConventions = require('@traceloop/ai-semantic-conventions');
7
+ var instrumentationUtils = require('@traceloop/instrumentation-utils');
7
8
  var incubating = require('@opentelemetry/semantic-conventions/incubating');
8
9
 
9
- var version = "0.22.5";
10
+ var version = "0.23.0";
10
11
 
12
+ // Mapping of Anthropic-specific stop reasons to standardized finish reasons
13
+ const anthropicFinishReasonMap = {
14
+ end_turn: aiSemanticConventions.FinishReasons.STOP,
15
+ max_tokens: aiSemanticConventions.FinishReasons.LENGTH,
16
+ stop_sequence: aiSemanticConventions.FinishReasons.STOP,
17
+ tool_use: aiSemanticConventions.FinishReasons.TOOL_CALL,
18
+ };
11
19
  class AnthropicInstrumentation extends instrumentation.InstrumentationBase {
12
20
  constructor(config = {}) {
13
21
  super("@traceloop/instrumentation-anthropic", version, config);
@@ -17,9 +25,9 @@ class AnthropicInstrumentation extends instrumentation.InstrumentationBase {
17
25
  }
18
26
  manuallyInstrument(module) {
19
27
  this._diag.debug(`Patching @anthropic-ai/sdk manually`);
20
- this._wrap(module.Anthropic.Completions.prototype, "create", this.patchAnthropic("completion", module));
21
- this._wrap(module.Anthropic.Messages.prototype, "create", this.patchAnthropic("chat", module));
22
- this._wrap(module.Anthropic.Beta.Messages.prototype, "create", this.patchAnthropic("chat", module));
28
+ this._wrap(module.Anthropic.Completions.prototype, "create", this.patchAnthropic(incubating.GEN_AI_OPERATION_NAME_VALUE_TEXT_COMPLETION, module));
29
+ this._wrap(module.Anthropic.Messages.prototype, "create", this.patchAnthropic(incubating.GEN_AI_OPERATION_NAME_VALUE_CHAT, module));
30
+ this._wrap(module.Anthropic.Beta.Messages.prototype, "create", this.patchAnthropic(incubating.GEN_AI_OPERATION_NAME_VALUE_CHAT, module));
23
31
  }
24
32
  init() {
25
33
  const module = new instrumentation.InstrumentationNodeModuleDefinition("@anthropic-ai/sdk", [">=0.9.1"], this.patch.bind(this), this.unpatch.bind(this));
@@ -27,9 +35,9 @@ class AnthropicInstrumentation extends instrumentation.InstrumentationBase {
27
35
  }
28
36
  patch(moduleExports, moduleVersion) {
29
37
  this._diag.debug(`Patching @anthropic-ai/sdk@${moduleVersion}`);
30
- this._wrap(moduleExports.Anthropic.Completions.prototype, "create", this.patchAnthropic("completion", moduleExports));
31
- this._wrap(moduleExports.Anthropic.Messages.prototype, "create", this.patchAnthropic("chat", moduleExports));
32
- this._wrap(moduleExports.Anthropic.Beta.Messages.prototype, "create", this.patchAnthropic("chat", moduleExports));
38
+ this._wrap(moduleExports.Anthropic.Completions.prototype, "create", this.patchAnthropic(incubating.GEN_AI_OPERATION_NAME_VALUE_TEXT_COMPLETION, moduleExports));
39
+ this._wrap(moduleExports.Anthropic.Messages.prototype, "create", this.patchAnthropic(incubating.GEN_AI_OPERATION_NAME_VALUE_CHAT, moduleExports));
40
+ this._wrap(moduleExports.Anthropic.Beta.Messages.prototype, "create", this.patchAnthropic(incubating.GEN_AI_OPERATION_NAME_VALUE_CHAT, moduleExports));
33
41
  return moduleExports;
34
42
  }
35
43
  unpatch(moduleExports, moduleVersion) {
@@ -44,13 +52,13 @@ class AnthropicInstrumentation extends instrumentation.InstrumentationBase {
44
52
  // eslint-disable-next-line
45
53
  return (original) => {
46
54
  return function method(...args) {
47
- const span = type === "chat"
55
+ const span = type === incubating.GEN_AI_OPERATION_NAME_VALUE_CHAT
48
56
  ? plugin.startSpan({
49
57
  type,
50
58
  params: args[0],
51
59
  })
52
60
  : plugin.startSpan({
53
- type,
61
+ type: incubating.GEN_AI_OPERATION_NAME_VALUE_TEXT_COMPLETION,
54
62
  params: args[0],
55
63
  });
56
64
  const execContext = api.trace.setSpan(api.context.active(), span);
@@ -80,24 +88,25 @@ class AnthropicInstrumentation extends instrumentation.InstrumentationBase {
80
88
  };
81
89
  }
82
90
  startSpan({ type, params, }) {
83
- var _a, _b;
91
+ var _a, _b, _c;
84
92
  const attributes = {
85
- [incubating.ATTR_GEN_AI_SYSTEM]: "Anthropic",
86
- [aiSemanticConventions.SpanAttributes.LLM_REQUEST_TYPE]: type,
93
+ [incubating.ATTR_GEN_AI_PROVIDER_NAME]: incubating.GEN_AI_PROVIDER_NAME_VALUE_ANTHROPIC,
94
+ [incubating.ATTR_GEN_AI_OPERATION_NAME]: type,
87
95
  };
88
96
  try {
89
97
  attributes[incubating.ATTR_GEN_AI_REQUEST_MODEL] = params.model;
90
98
  attributes[incubating.ATTR_GEN_AI_REQUEST_TEMPERATURE] = params.temperature;
91
99
  attributes[incubating.ATTR_GEN_AI_REQUEST_TOP_P] = params.top_p;
92
- attributes[aiSemanticConventions.SpanAttributes.LLM_TOP_K] = params.top_k;
100
+ attributes[incubating.ATTR_GEN_AI_REQUEST_TOP_K] = params.top_k;
93
101
  // Handle thinking parameters (for beta messages)
94
102
  const betaParams = params;
95
103
  if (betaParams.thinking && betaParams.thinking.type === "enabled") {
96
- attributes["llm.request.thinking.type"] = betaParams.thinking.type;
97
- attributes["llm.request.thinking.budget_tokens"] =
104
+ attributes[aiSemanticConventions.SpanAttributes.GEN_AI_REQUEST_THINKING_TYPE] =
105
+ betaParams.thinking.type;
106
+ attributes[aiSemanticConventions.SpanAttributes.GEN_AI_REQUEST_THINKING_BUDGET_TOKENS] =
98
107
  betaParams.thinking.budget_tokens;
99
108
  }
100
- if (type === "completion") {
109
+ if (type === incubating.GEN_AI_OPERATION_NAME_VALUE_TEXT_COMPLETION) {
101
110
  attributes[incubating.ATTR_GEN_AI_REQUEST_MAX_TOKENS] =
102
111
  params.max_tokens_to_sample;
103
112
  }
@@ -111,34 +120,16 @@ class AnthropicInstrumentation extends instrumentation.InstrumentationBase {
111
120
  });
112
121
  }
113
122
  if (this._shouldSendPrompts()) {
114
- if (type === "chat") {
115
- let promptIndex = 0;
116
- // If a system prompt is provided, it should always be first
123
+ if (type === incubating.GEN_AI_OPERATION_NAME_VALUE_CHAT) {
117
124
  if ("system" in params && params.system !== undefined) {
118
- attributes[`${incubating.ATTR_GEN_AI_PROMPT}.0.role`] = "system";
119
- attributes[`${incubating.ATTR_GEN_AI_PROMPT}.0.content`] =
120
- typeof params.system === "string"
121
- ? params.system
122
- : JSON.stringify(params.system);
123
- promptIndex += 1;
125
+ attributes[incubating.ATTR_GEN_AI_SYSTEM_INSTRUCTIONS] =
126
+ instrumentationUtils.formatSystemInstructions(params.system);
124
127
  }
125
- params.messages.forEach((message, index) => {
126
- const currentIndex = index + promptIndex;
127
- attributes[`${incubating.ATTR_GEN_AI_PROMPT}.${currentIndex}.role`] =
128
- message.role;
129
- if (typeof message.content === "string") {
130
- attributes[`${incubating.ATTR_GEN_AI_PROMPT}.${currentIndex}.content`] =
131
- message.content || "";
132
- }
133
- else {
134
- attributes[`${incubating.ATTR_GEN_AI_PROMPT}.${currentIndex}.content`] =
135
- JSON.stringify(message.content);
136
- }
137
- });
128
+ attributes[incubating.ATTR_GEN_AI_INPUT_MESSAGES] = instrumentationUtils.formatInputMessages(params.messages, instrumentationUtils.mapAnthropicContentBlock);
138
129
  }
139
130
  else {
140
- attributes[`${incubating.ATTR_GEN_AI_PROMPT}.0.role`] = "user";
141
- attributes[`${incubating.ATTR_GEN_AI_PROMPT}.0.content`] = params.prompt;
131
+ attributes[incubating.ATTR_GEN_AI_INPUT_MESSAGES] =
132
+ instrumentationUtils.formatInputMessagesFromPrompt(params.prompt);
142
133
  }
143
134
  }
144
135
  }
@@ -146,7 +137,7 @@ class AnthropicInstrumentation extends instrumentation.InstrumentationBase {
146
137
  this._diag.debug(e);
147
138
  (_b = (_a = this._config).exceptionLogger) === null || _b === void 0 ? void 0 : _b.call(_a, e);
148
139
  }
149
- return this.tracer.startSpan(`anthropic.${type}`, {
140
+ return this.tracer.startSpan(`${type} ${(_c = params === null || params === void 0 ? void 0 : params.model) !== null && _c !== void 0 ? _c : "unknown"}`, {
150
141
  kind: api.SpanKind.CLIENT,
151
142
  attributes,
152
143
  });
@@ -157,7 +148,7 @@ class AnthropicInstrumentation extends instrumentation.InstrumentationBase {
157
148
  var _a, e_1, _b, _c, _d, e_2, _e, _f;
158
149
  var _g, _h, _j, _k;
159
150
  try {
160
- if (type === "chat") {
151
+ if (type === incubating.GEN_AI_OPERATION_NAME_VALUE_CHAT) {
161
152
  const result = {
162
153
  id: "0",
163
154
  type: "message",
@@ -168,11 +159,8 @@ class AnthropicInstrumentation extends instrumentation.InstrumentationBase {
168
159
  usage: {
169
160
  input_tokens: 0,
170
161
  output_tokens: 0,
171
- cache_creation: null,
172
162
  cache_creation_input_tokens: null,
173
163
  cache_read_input_tokens: null,
174
- server_tool_use: null,
175
- service_tier: null,
176
164
  },
177
165
  content: [],
178
166
  };
@@ -292,7 +280,7 @@ class AnthropicInstrumentation extends instrumentation.InstrumentationBase {
292
280
  _wrapPromise(type, span, promise) {
293
281
  return promise
294
282
  .then((result) => {
295
- if (type === "chat") {
283
+ if (type === incubating.GEN_AI_OPERATION_NAME_VALUE_CHAT) {
296
284
  this._endSpan({
297
285
  type,
298
286
  span,
@@ -319,31 +307,38 @@ class AnthropicInstrumentation extends instrumentation.InstrumentationBase {
319
307
  });
320
308
  }
321
309
  _endSpan({ span, type, result, }) {
322
- var _a, _b, _c, _d, _e, _f;
310
+ var _a, _b, _c;
323
311
  try {
324
312
  span.setAttribute(incubating.ATTR_GEN_AI_RESPONSE_MODEL, result.model);
325
- if (type === "chat" && result.usage) {
326
- span.setAttribute(aiSemanticConventions.SpanAttributes.LLM_USAGE_TOTAL_TOKENS, ((_a = result.usage) === null || _a === void 0 ? void 0 : _a.input_tokens) + ((_b = result.usage) === null || _b === void 0 ? void 0 : _b.output_tokens));
327
- span.setAttribute(incubating.ATTR_GEN_AI_USAGE_COMPLETION_TOKENS, (_c = result.usage) === null || _c === void 0 ? void 0 : _c.output_tokens);
328
- span.setAttribute(incubating.ATTR_GEN_AI_USAGE_PROMPT_TOKENS, (_d = result.usage) === null || _d === void 0 ? void 0 : _d.input_tokens);
329
- }
313
+ // Always set finish_reason it's metadata, not user content
330
314
  if (result.stop_reason) {
331
- span.setAttribute(`${incubating.ATTR_GEN_AI_COMPLETION}.0.finish_reason`, result.stop_reason);
315
+ const mappedReason = (_a = anthropicFinishReasonMap[result.stop_reason]) !== null && _a !== void 0 ? _a : result.stop_reason;
316
+ span.setAttribute(incubating.ATTR_GEN_AI_RESPONSE_FINISH_REASONS, [mappedReason]);
332
317
  }
333
- if (this._shouldSendPrompts()) {
334
- if (type === "chat") {
335
- span.setAttribute(`${incubating.ATTR_GEN_AI_COMPLETION}.0.role`, "assistant");
336
- span.setAttribute(`${incubating.ATTR_GEN_AI_COMPLETION}.0.content`, JSON.stringify(result.content));
318
+ if (type === incubating.GEN_AI_OPERATION_NAME_VALUE_CHAT && result.usage) {
319
+ span.setAttribute(aiSemanticConventions.SpanAttributes.GEN_AI_USAGE_TOTAL_TOKENS, result.usage.input_tokens + result.usage.output_tokens);
320
+ span.setAttribute(incubating.ATTR_GEN_AI_USAGE_OUTPUT_TOKENS, result.usage.output_tokens);
321
+ span.setAttribute(incubating.ATTR_GEN_AI_USAGE_INPUT_TOKENS, result.usage.input_tokens);
322
+ // Cache token attributes (v1.40)
323
+ if (result.usage.cache_creation_input_tokens != null) {
324
+ span.setAttribute(incubating.ATTR_GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS, result.usage.cache_creation_input_tokens);
337
325
  }
338
- else {
339
- span.setAttribute(`${incubating.ATTR_GEN_AI_COMPLETION}.0.role`, "assistant");
340
- span.setAttribute(`${incubating.ATTR_GEN_AI_COMPLETION}.0.content`, result.completion);
326
+ if (result.usage.cache_read_input_tokens != null) {
327
+ span.setAttribute(incubating.ATTR_GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS, result.usage.cache_read_input_tokens);
341
328
  }
342
329
  }
330
+ // Only set output message content when tracing content
331
+ if (this._shouldSendPrompts()) {
332
+ const content = type === incubating.GEN_AI_OPERATION_NAME_VALUE_CHAT
333
+ ? result.content
334
+ : result.completion;
335
+ const outputMessages = instrumentationUtils.formatOutputMessage(content, result.stop_reason, anthropicFinishReasonMap, type, instrumentationUtils.mapAnthropicContentBlock);
336
+ span.setAttribute(incubating.ATTR_GEN_AI_OUTPUT_MESSAGES, outputMessages);
337
+ }
343
338
  }
344
339
  catch (e) {
345
340
  this._diag.debug(e);
346
- (_f = (_e = this._config).exceptionLogger) === null || _f === void 0 ? void 0 : _f.call(_e, e);
341
+ (_c = (_b = this._config).exceptionLogger) === null || _c === void 0 ? void 0 : _c.call(_b, e);
347
342
  }
348
343
  span.end();
349
344
  }
@@ -361,4 +356,5 @@ class AnthropicInstrumentation extends instrumentation.InstrumentationBase {
361
356
  }
362
357
 
363
358
  exports.AnthropicInstrumentation = AnthropicInstrumentation;
359
+ exports.anthropicFinishReasonMap = anthropicFinishReasonMap;
364
360
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/instrumentation.ts"],"sourcesContent":["/*\n * Copyright Traceloop\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n context,\n trace,\n Span,\n Attributes,\n SpanKind,\n SpanStatusCode,\n} from \"@opentelemetry/api\";\nimport {\n InstrumentationBase,\n InstrumentationModuleDefinition,\n InstrumentationNodeModuleDefinition,\n safeExecuteInTheMiddle,\n} from \"@opentelemetry/instrumentation\";\nimport {\n CONTEXT_KEY_ALLOW_TRACE_CONTENT,\n SpanAttributes,\n} from \"@traceloop/ai-semantic-conventions\";\nimport {\n ATTR_GEN_AI_COMPLETION,\n ATTR_GEN_AI_PROMPT,\n ATTR_GEN_AI_REQUEST_MAX_TOKENS,\n ATTR_GEN_AI_REQUEST_MODEL,\n ATTR_GEN_AI_REQUEST_TEMPERATURE,\n ATTR_GEN_AI_REQUEST_TOP_P,\n ATTR_GEN_AI_RESPONSE_MODEL,\n ATTR_GEN_AI_SYSTEM,\n ATTR_GEN_AI_USAGE_COMPLETION_TOKENS,\n ATTR_GEN_AI_USAGE_PROMPT_TOKENS,\n} from \"@opentelemetry/semantic-conventions/incubating\";\nimport { AnthropicInstrumentationConfig } from \"./types\";\nimport { version } from \"../package.json\";\nimport type * as anthropic from \"@anthropic-ai/sdk\";\nimport type {\n CompletionCreateParamsNonStreaming,\n CompletionCreateParamsStreaming,\n Completion,\n} from \"@anthropic-ai/sdk/resources/completions\";\nimport type {\n MessageCreateParamsNonStreaming,\n MessageCreateParamsStreaming,\n Message,\n MessageStreamEvent,\n} from \"@anthropic-ai/sdk/resources/messages\";\nimport type { MessageCreateParamsNonStreaming as BetaMessageCreateParamsNonStreaming } from \"@anthropic-ai/sdk/resources/beta/messages\";\nimport type { Stream } from \"@anthropic-ai/sdk/streaming\";\nimport type { APIPromise, BaseAnthropic } from \"@anthropic-ai/sdk\";\n\nexport class AnthropicInstrumentation extends InstrumentationBase {\n declare protected _config: AnthropicInstrumentationConfig;\n\n constructor(config: AnthropicInstrumentationConfig = {}) {\n super(\"@traceloop/instrumentation-anthropic\", version, config);\n }\n\n public override setConfig(config: AnthropicInstrumentationConfig = {}) {\n super.setConfig(config);\n }\n\n public manuallyInstrument(module: typeof anthropic) {\n this._diag.debug(`Patching @anthropic-ai/sdk manually`);\n\n this._wrap(\n module.Anthropic.Completions.prototype,\n \"create\",\n this.patchAnthropic(\"completion\", module),\n );\n this._wrap(\n module.Anthropic.Messages.prototype,\n \"create\",\n this.patchAnthropic(\"chat\", module),\n );\n this._wrap(\n module.Anthropic.Beta.Messages.prototype,\n \"create\",\n this.patchAnthropic(\"chat\", module),\n );\n }\n\n protected init(): InstrumentationModuleDefinition {\n const module = new InstrumentationNodeModuleDefinition(\n \"@anthropic-ai/sdk\",\n [\">=0.9.1\"],\n this.patch.bind(this),\n this.unpatch.bind(this),\n );\n return module;\n }\n\n private patch(moduleExports: typeof anthropic, moduleVersion?: string) {\n this._diag.debug(`Patching @anthropic-ai/sdk@${moduleVersion}`);\n\n this._wrap(\n moduleExports.Anthropic.Completions.prototype,\n \"create\",\n this.patchAnthropic(\"completion\", moduleExports),\n );\n this._wrap(\n moduleExports.Anthropic.Messages.prototype,\n \"create\",\n this.patchAnthropic(\"chat\", moduleExports),\n );\n this._wrap(\n moduleExports.Anthropic.Beta.Messages.prototype,\n \"create\",\n this.patchAnthropic(\"chat\", moduleExports),\n );\n return moduleExports;\n }\n\n private unpatch(\n moduleExports: typeof anthropic,\n moduleVersion?: string,\n ): void {\n this._diag.debug(`Unpatching @anthropic-ai/sdk@${moduleVersion}`);\n\n this._unwrap(moduleExports.Anthropic.Completions.prototype, \"create\");\n this._unwrap(moduleExports.Anthropic.Messages.prototype, \"create\");\n this._unwrap(moduleExports.Anthropic.Beta.Messages.prototype, \"create\");\n }\n\n private patchAnthropic(\n type: \"chat\" | \"completion\",\n moduleExports: typeof anthropic,\n ) {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const plugin = this;\n // eslint-disable-next-line\n return (original: Function) => {\n return function method(this: any, ...args: unknown[]) {\n const span =\n type === \"chat\"\n ? plugin.startSpan({\n type,\n params: args[0] as MessageCreateParamsNonStreaming & {\n extraAttributes?: Record<string, any>;\n },\n })\n : plugin.startSpan({\n type,\n params: args[0] as CompletionCreateParamsNonStreaming & {\n extraAttributes?: Record<string, any>;\n },\n });\n\n const execContext = trace.setSpan(context.active(), span);\n const execPromise = safeExecuteInTheMiddle(\n () => {\n return context.with(execContext, () => {\n if ((args?.[0] as any)?.extraAttributes) {\n delete (args[0] as any).extraAttributes;\n }\n return original.apply(this, args);\n });\n },\n (e) => {\n if (e) {\n plugin._diag.error(\"Error in Anthropic instrumentation\", e);\n }\n },\n );\n\n if (\n (\n args[0] as\n | MessageCreateParamsStreaming\n | CompletionCreateParamsStreaming\n ).stream\n ) {\n return context.bind(\n execContext,\n plugin._streamingWrapPromise(this._client, moduleExports, {\n span,\n type,\n promise: execPromise,\n }),\n );\n }\n\n const wrappedPromise = plugin._wrapPromise(type, span, execPromise);\n\n return context.bind(execContext, wrappedPromise as any);\n };\n };\n }\n\n private startSpan({\n type,\n params,\n }:\n | {\n type: \"chat\";\n params: MessageCreateParamsNonStreaming & {\n extraAttributes?: Record<string, any>;\n };\n }\n | {\n type: \"completion\";\n params: CompletionCreateParamsNonStreaming & {\n extraAttributes?: Record<string, any>;\n };\n }): Span {\n const attributes: Attributes = {\n [ATTR_GEN_AI_SYSTEM]: \"Anthropic\",\n [SpanAttributes.LLM_REQUEST_TYPE]: type,\n };\n\n try {\n attributes[ATTR_GEN_AI_REQUEST_MODEL] = params.model;\n attributes[ATTR_GEN_AI_REQUEST_TEMPERATURE] = params.temperature;\n attributes[ATTR_GEN_AI_REQUEST_TOP_P] = params.top_p;\n attributes[SpanAttributes.LLM_TOP_K] = params.top_k;\n\n // Handle thinking parameters (for beta messages)\n const betaParams = params as BetaMessageCreateParamsNonStreaming;\n if (betaParams.thinking && betaParams.thinking.type === \"enabled\") {\n attributes[\"llm.request.thinking.type\"] = betaParams.thinking.type;\n attributes[\"llm.request.thinking.budget_tokens\"] =\n betaParams.thinking.budget_tokens;\n }\n\n if (type === \"completion\") {\n attributes[ATTR_GEN_AI_REQUEST_MAX_TOKENS] =\n params.max_tokens_to_sample;\n } else {\n attributes[ATTR_GEN_AI_REQUEST_MAX_TOKENS] = params.max_tokens;\n }\n\n if (\n params.extraAttributes !== undefined &&\n typeof params.extraAttributes === \"object\"\n ) {\n Object.keys(params.extraAttributes).forEach((key: string) => {\n attributes[key] = params.extraAttributes![key];\n });\n }\n\n if (this._shouldSendPrompts()) {\n if (type === \"chat\") {\n let promptIndex = 0;\n\n // If a system prompt is provided, it should always be first\n if (\"system\" in params && params.system !== undefined) {\n attributes[`${ATTR_GEN_AI_PROMPT}.0.role`] = \"system\";\n attributes[`${ATTR_GEN_AI_PROMPT}.0.content`] =\n typeof params.system === \"string\"\n ? params.system\n : JSON.stringify(params.system);\n promptIndex += 1;\n }\n\n params.messages.forEach((message, index) => {\n const currentIndex = index + promptIndex;\n attributes[`${ATTR_GEN_AI_PROMPT}.${currentIndex}.role`] =\n message.role;\n if (typeof message.content === \"string\") {\n attributes[`${ATTR_GEN_AI_PROMPT}.${currentIndex}.content`] =\n (message.content as string) || \"\";\n } else {\n attributes[`${ATTR_GEN_AI_PROMPT}.${currentIndex}.content`] =\n JSON.stringify(message.content);\n }\n });\n } else {\n attributes[`${ATTR_GEN_AI_PROMPT}.0.role`] = \"user\";\n attributes[`${ATTR_GEN_AI_PROMPT}.0.content`] = params.prompt;\n }\n }\n } catch (e) {\n this._diag.debug(e);\n this._config.exceptionLogger?.(e);\n }\n\n return this.tracer.startSpan(`anthropic.${type}`, {\n kind: SpanKind.CLIENT,\n attributes,\n });\n }\n\n private _streamingWrapPromise(\n client: BaseAnthropic,\n moduleExports: typeof anthropic,\n {\n span,\n type,\n promise,\n }:\n | {\n span: Span;\n type: \"chat\";\n promise: APIPromise<Stream<MessageStreamEvent>>;\n }\n | {\n span: Span;\n type: \"completion\";\n promise: APIPromise<Stream<Completion>>;\n },\n ) {\n async function* iterateStream(\n this: AnthropicInstrumentation,\n stream: Stream<MessageStreamEvent> | Stream<Completion>,\n ) {\n try {\n if (type === \"chat\") {\n const result: Message = {\n id: \"0\",\n type: \"message\",\n model: \"\",\n role: \"assistant\",\n stop_reason: null,\n stop_sequence: null,\n usage: {\n input_tokens: 0,\n output_tokens: 0,\n cache_creation: null,\n cache_creation_input_tokens: null,\n cache_read_input_tokens: null,\n server_tool_use: null,\n service_tier: null,\n },\n content: [],\n };\n\n for await (const chunk of stream) {\n yield chunk;\n\n try {\n switch (chunk.type) {\n case \"message_start\":\n result.id = chunk.message.id;\n result.model = chunk.message.model;\n Object.assign(result.usage, chunk.message.usage);\n break;\n case \"message_delta\":\n if (chunk.usage) {\n Object.assign(result.usage, chunk.usage);\n }\n break;\n case \"content_block_start\":\n if (result.content.length <= chunk.index) {\n result.content.push({ ...chunk.content_block });\n }\n break;\n\n case \"content_block_delta\":\n if (chunk.index < result.content.length) {\n const current = result.content[chunk.index];\n if (\n current.type === \"text\" &&\n chunk.delta.type === \"text_delta\"\n ) {\n result.content[chunk.index] = {\n type: \"text\",\n text: current.text + chunk.delta.text,\n citations: current.citations,\n };\n }\n }\n break;\n }\n } catch (e) {\n this._diag.debug(e);\n this._config.exceptionLogger?.(e);\n }\n }\n\n this._endSpan({ span, type, result });\n } else {\n const result: Completion = {\n id: \"0\",\n type: \"completion\",\n model: \"\",\n completion: \"\",\n stop_reason: null,\n };\n for await (const chunk of stream as Stream<Completion>) {\n yield chunk;\n\n try {\n result.id = chunk.id;\n result.model = chunk.model;\n\n if (chunk.stop_reason) {\n result.stop_reason = chunk.stop_reason;\n }\n if (chunk.model) {\n result.model = chunk.model;\n }\n if (chunk.completion) {\n result.completion += chunk.completion;\n }\n } catch (e) {\n this._diag.debug(e);\n this._config.exceptionLogger?.(e);\n }\n }\n\n this._endSpan({ span, type, result });\n }\n } catch (error) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error.message,\n });\n span.recordException(error);\n span.end();\n throw error;\n }\n }\n\n return new moduleExports.APIPromise(\n client,\n (promise as any).responsePromise,\n async (client, props) => {\n const realStream = await (promise as any).parseResponse(client, props);\n\n // take the incoming stream, iterate it using our instrumented function, and wrap it in a new stream to keep the rich object type the same\n return new realStream.constructor(\n () => iterateStream.call(this, realStream),\n realStream.controller,\n );\n },\n ) as\n | APIPromise<Stream<MessageStreamEvent>>\n | APIPromise<Stream<Completion>>;\n }\n\n private _wrapPromise<T>(\n type: \"chat\" | \"completion\",\n span: Span,\n promise: Promise<T>,\n ): Promise<T> {\n return promise\n .then((result) => {\n if (type === \"chat\") {\n this._endSpan({\n type,\n span,\n result: result as Message,\n });\n } else {\n this._endSpan({\n type,\n span,\n result: result as Completion,\n });\n }\n\n return result;\n })\n .catch((error: Error) => {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error.message,\n });\n span.recordException(error);\n span.end();\n\n throw error;\n });\n }\n\n private _endSpan({\n span,\n type,\n result,\n }:\n | { span: Span; type: \"chat\"; result: Message }\n | {\n span: Span;\n type: \"completion\";\n result: Completion;\n }) {\n try {\n span.setAttribute(ATTR_GEN_AI_RESPONSE_MODEL, result.model);\n if (type === \"chat\" && result.usage) {\n span.setAttribute(\n SpanAttributes.LLM_USAGE_TOTAL_TOKENS,\n result.usage?.input_tokens + result.usage?.output_tokens,\n );\n span.setAttribute(\n ATTR_GEN_AI_USAGE_COMPLETION_TOKENS,\n result.usage?.output_tokens,\n );\n span.setAttribute(\n ATTR_GEN_AI_USAGE_PROMPT_TOKENS,\n result.usage?.input_tokens,\n );\n }\n\n if (result.stop_reason) {\n span.setAttribute(\n `${ATTR_GEN_AI_COMPLETION}.0.finish_reason`,\n result.stop_reason,\n );\n }\n\n if (this._shouldSendPrompts()) {\n if (type === \"chat\") {\n span.setAttribute(`${ATTR_GEN_AI_COMPLETION}.0.role`, \"assistant\");\n span.setAttribute(\n `${ATTR_GEN_AI_COMPLETION}.0.content`,\n JSON.stringify(result.content),\n );\n } else {\n span.setAttribute(`${ATTR_GEN_AI_COMPLETION}.0.role`, \"assistant\");\n span.setAttribute(\n `${ATTR_GEN_AI_COMPLETION}.0.content`,\n result.completion,\n );\n }\n }\n } catch (e) {\n this._diag.debug(e);\n this._config.exceptionLogger?.(e);\n }\n\n span.end();\n }\n\n private _shouldSendPrompts() {\n const contextShouldSendPrompts = context\n .active()\n .getValue(CONTEXT_KEY_ALLOW_TRACE_CONTENT);\n\n if (contextShouldSendPrompts !== undefined) {\n return contextShouldSendPrompts;\n }\n\n return this._config.traceContent !== undefined\n ? this._config.traceContent\n : true;\n }\n}\n"],"names":["InstrumentationBase","InstrumentationNodeModuleDefinition","trace","context","safeExecuteInTheMiddle","ATTR_GEN_AI_SYSTEM","SpanAttributes","ATTR_GEN_AI_REQUEST_MODEL","ATTR_GEN_AI_REQUEST_TEMPERATURE","ATTR_GEN_AI_REQUEST_TOP_P","ATTR_GEN_AI_REQUEST_MAX_TOKENS","ATTR_GEN_AI_PROMPT","SpanKind","__asyncValues","__await","SpanStatusCode","__awaiter","ATTR_GEN_AI_RESPONSE_MODEL","ATTR_GEN_AI_USAGE_COMPLETION_TOKENS","ATTR_GEN_AI_USAGE_PROMPT_TOKENS","ATTR_GEN_AI_COMPLETION","CONTEXT_KEY_ALLOW_TRACE_CONTENT"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../src/instrumentation.ts"],"sourcesContent":["/*\n * Copyright Traceloop\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n context,\n trace,\n Span,\n Attributes,\n SpanKind,\n SpanStatusCode,\n} from \"@opentelemetry/api\";\nimport {\n InstrumentationBase,\n InstrumentationModuleDefinition,\n InstrumentationNodeModuleDefinition,\n safeExecuteInTheMiddle,\n} from \"@opentelemetry/instrumentation\";\nimport {\n CONTEXT_KEY_ALLOW_TRACE_CONTENT,\n SpanAttributes,\n FinishReasons,\n} from \"@traceloop/ai-semantic-conventions\";\nimport {\n formatSystemInstructions,\n formatInputMessages,\n formatInputMessagesFromPrompt,\n formatOutputMessage,\n mapAnthropicContentBlock,\n} from \"@traceloop/instrumentation-utils\";\nimport {\n ATTR_GEN_AI_OUTPUT_MESSAGES,\n ATTR_GEN_AI_INPUT_MESSAGES,\n ATTR_GEN_AI_REQUEST_MAX_TOKENS,\n ATTR_GEN_AI_REQUEST_MODEL,\n ATTR_GEN_AI_REQUEST_TEMPERATURE,\n ATTR_GEN_AI_REQUEST_TOP_P,\n ATTR_GEN_AI_RESPONSE_MODEL,\n ATTR_GEN_AI_REQUEST_TOP_K,\n ATTR_GEN_AI_PROVIDER_NAME,\n GEN_AI_PROVIDER_NAME_VALUE_ANTHROPIC,\n ATTR_GEN_AI_OPERATION_NAME,\n ATTR_GEN_AI_SYSTEM_INSTRUCTIONS,\n ATTR_GEN_AI_USAGE_OUTPUT_TOKENS,\n ATTR_GEN_AI_USAGE_INPUT_TOKENS,\n ATTR_GEN_AI_RESPONSE_FINISH_REASONS,\n ATTR_GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS,\n ATTR_GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS,\n GEN_AI_OPERATION_NAME_VALUE_CHAT,\n GEN_AI_OPERATION_NAME_VALUE_TEXT_COMPLETION,\n} from \"@opentelemetry/semantic-conventions/incubating\";\nimport { AnthropicInstrumentationConfig } from \"./types\";\nimport { version } from \"../package.json\";\nimport type * as anthropic from \"@anthropic-ai/sdk\";\nimport type {\n CompletionCreateParamsNonStreaming,\n CompletionCreateParamsStreaming,\n Completion,\n} from \"@anthropic-ai/sdk/resources/completions\";\nimport type {\n MessageCreateParamsNonStreaming,\n MessageCreateParamsStreaming,\n Message,\n MessageStreamEvent,\n} from \"@anthropic-ai/sdk/resources/messages\";\nimport type { MessageCreateParamsNonStreaming as BetaMessageCreateParamsNonStreaming } from \"@anthropic-ai/sdk/resources/beta/messages\";\nimport type { Stream } from \"@anthropic-ai/sdk/streaming\";\nimport type { APIPromise, BaseAnthropic } from \"@anthropic-ai/sdk\";\n\n// Mapping of Anthropic-specific stop reasons to standardized finish reasons\nexport const anthropicFinishReasonMap: Record<string, string> = {\n end_turn: FinishReasons.STOP,\n max_tokens: FinishReasons.LENGTH,\n stop_sequence: FinishReasons.STOP,\n tool_use: FinishReasons.TOOL_CALL,\n};\n\nexport class AnthropicInstrumentation extends InstrumentationBase {\n declare protected _config: AnthropicInstrumentationConfig;\n\n constructor(config: AnthropicInstrumentationConfig = {}) {\n super(\"@traceloop/instrumentation-anthropic\", version, config);\n }\n\n public override setConfig(config: AnthropicInstrumentationConfig = {}) {\n super.setConfig(config);\n }\n\n public manuallyInstrument(module: typeof anthropic) {\n this._diag.debug(`Patching @anthropic-ai/sdk manually`);\n\n this._wrap(\n module.Anthropic.Completions.prototype,\n \"create\",\n this.patchAnthropic(GEN_AI_OPERATION_NAME_VALUE_TEXT_COMPLETION, module),\n );\n this._wrap(\n module.Anthropic.Messages.prototype,\n \"create\",\n this.patchAnthropic(GEN_AI_OPERATION_NAME_VALUE_CHAT, module),\n );\n this._wrap(\n module.Anthropic.Beta.Messages.prototype,\n \"create\",\n this.patchAnthropic(GEN_AI_OPERATION_NAME_VALUE_CHAT, module),\n );\n }\n\n protected init(): InstrumentationModuleDefinition {\n const module = new InstrumentationNodeModuleDefinition(\n \"@anthropic-ai/sdk\",\n [\">=0.9.1\"],\n this.patch.bind(this),\n this.unpatch.bind(this),\n );\n return module;\n }\n\n private patch(moduleExports: typeof anthropic, moduleVersion?: string) {\n this._diag.debug(`Patching @anthropic-ai/sdk@${moduleVersion}`);\n\n this._wrap(\n moduleExports.Anthropic.Completions.prototype,\n \"create\",\n this.patchAnthropic(\n GEN_AI_OPERATION_NAME_VALUE_TEXT_COMPLETION,\n moduleExports,\n ),\n );\n this._wrap(\n moduleExports.Anthropic.Messages.prototype,\n \"create\",\n this.patchAnthropic(GEN_AI_OPERATION_NAME_VALUE_CHAT, moduleExports),\n );\n this._wrap(\n moduleExports.Anthropic.Beta.Messages.prototype,\n \"create\",\n this.patchAnthropic(GEN_AI_OPERATION_NAME_VALUE_CHAT, moduleExports),\n );\n return moduleExports;\n }\n\n private unpatch(\n moduleExports: typeof anthropic,\n moduleVersion?: string,\n ): void {\n this._diag.debug(`Unpatching @anthropic-ai/sdk@${moduleVersion}`);\n\n this._unwrap(moduleExports.Anthropic.Completions.prototype, \"create\");\n this._unwrap(moduleExports.Anthropic.Messages.prototype, \"create\");\n this._unwrap(moduleExports.Anthropic.Beta.Messages.prototype, \"create\");\n }\n\n private patchAnthropic(\n type:\n | typeof GEN_AI_OPERATION_NAME_VALUE_CHAT\n | typeof GEN_AI_OPERATION_NAME_VALUE_TEXT_COMPLETION,\n moduleExports: typeof anthropic,\n ) {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const plugin = this;\n // eslint-disable-next-line\n return (original: Function) => {\n return function method(this: any, ...args: unknown[]) {\n const span =\n type === GEN_AI_OPERATION_NAME_VALUE_CHAT\n ? plugin.startSpan({\n type,\n params: args[0] as MessageCreateParamsNonStreaming & {\n extraAttributes?: Record<string, any>;\n },\n })\n : plugin.startSpan({\n type: GEN_AI_OPERATION_NAME_VALUE_TEXT_COMPLETION,\n params: args[0] as CompletionCreateParamsNonStreaming & {\n extraAttributes?: Record<string, any>;\n },\n });\n\n const execContext = trace.setSpan(context.active(), span);\n const execPromise = safeExecuteInTheMiddle(\n () => {\n return context.with(execContext, () => {\n if ((args?.[0] as any)?.extraAttributes) {\n delete (args[0] as any).extraAttributes;\n }\n return original.apply(this, args);\n });\n },\n (e) => {\n if (e) {\n plugin._diag.error(\"Error in Anthropic instrumentation\", e);\n }\n },\n );\n\n if (\n (\n args[0] as\n | MessageCreateParamsStreaming\n | CompletionCreateParamsStreaming\n ).stream\n ) {\n return context.bind(\n execContext,\n plugin._streamingWrapPromise(this._client, moduleExports, {\n span,\n type,\n promise: execPromise,\n }),\n );\n }\n\n const wrappedPromise = plugin._wrapPromise(type, span, execPromise);\n\n return context.bind(execContext, wrappedPromise as any);\n };\n };\n }\n\n private startSpan({\n type,\n params,\n }:\n | {\n type: typeof GEN_AI_OPERATION_NAME_VALUE_CHAT;\n params: MessageCreateParamsNonStreaming & {\n extraAttributes?: Record<string, any>;\n };\n }\n | {\n type: typeof GEN_AI_OPERATION_NAME_VALUE_TEXT_COMPLETION;\n params: CompletionCreateParamsNonStreaming & {\n extraAttributes?: Record<string, any>;\n };\n }): Span {\n const attributes: Attributes = {\n [ATTR_GEN_AI_PROVIDER_NAME]: GEN_AI_PROVIDER_NAME_VALUE_ANTHROPIC,\n [ATTR_GEN_AI_OPERATION_NAME]: type,\n };\n\n try {\n attributes[ATTR_GEN_AI_REQUEST_MODEL] = params.model;\n attributes[ATTR_GEN_AI_REQUEST_TEMPERATURE] = params.temperature;\n attributes[ATTR_GEN_AI_REQUEST_TOP_P] = params.top_p;\n attributes[ATTR_GEN_AI_REQUEST_TOP_K] = params.top_k;\n\n // Handle thinking parameters (for beta messages)\n const betaParams = params as BetaMessageCreateParamsNonStreaming;\n if (betaParams.thinking && betaParams.thinking.type === \"enabled\") {\n attributes[SpanAttributes.GEN_AI_REQUEST_THINKING_TYPE] =\n betaParams.thinking.type;\n attributes[SpanAttributes.GEN_AI_REQUEST_THINKING_BUDGET_TOKENS] =\n betaParams.thinking.budget_tokens;\n }\n\n if (type === GEN_AI_OPERATION_NAME_VALUE_TEXT_COMPLETION) {\n attributes[ATTR_GEN_AI_REQUEST_MAX_TOKENS] =\n params.max_tokens_to_sample;\n } else {\n attributes[ATTR_GEN_AI_REQUEST_MAX_TOKENS] = params.max_tokens;\n }\n\n if (\n params.extraAttributes !== undefined &&\n typeof params.extraAttributes === \"object\"\n ) {\n Object.keys(params.extraAttributes).forEach((key: string) => {\n attributes[key] = params.extraAttributes![key];\n });\n }\n\n if (this._shouldSendPrompts()) {\n if (type === GEN_AI_OPERATION_NAME_VALUE_CHAT) {\n if (\"system\" in params && params.system !== undefined) {\n attributes[ATTR_GEN_AI_SYSTEM_INSTRUCTIONS] =\n formatSystemInstructions(params.system);\n }\n\n attributes[ATTR_GEN_AI_INPUT_MESSAGES] = formatInputMessages(\n params.messages,\n mapAnthropicContentBlock,\n );\n } else {\n attributes[ATTR_GEN_AI_INPUT_MESSAGES] =\n formatInputMessagesFromPrompt(params.prompt);\n }\n }\n } catch (e) {\n this._diag.debug(e);\n this._config.exceptionLogger?.(e);\n }\n\n return this.tracer.startSpan(`${type} ${params?.model ?? \"unknown\"}`, {\n kind: SpanKind.CLIENT,\n attributes,\n });\n }\n\n private _streamingWrapPromise(\n client: BaseAnthropic,\n moduleExports: typeof anthropic,\n {\n span,\n type,\n promise,\n }:\n | {\n span: Span;\n type: typeof GEN_AI_OPERATION_NAME_VALUE_CHAT;\n promise: APIPromise<Stream<MessageStreamEvent>>;\n }\n | {\n span: Span;\n type: typeof GEN_AI_OPERATION_NAME_VALUE_TEXT_COMPLETION;\n promise: APIPromise<Stream<Completion>>;\n },\n ) {\n async function* iterateStream(\n this: AnthropicInstrumentation,\n stream: Stream<MessageStreamEvent> | Stream<Completion>,\n ) {\n try {\n if (type === GEN_AI_OPERATION_NAME_VALUE_CHAT) {\n const result = {\n id: \"0\",\n type: \"message\",\n model: \"\",\n role: \"assistant\",\n stop_reason: null,\n stop_sequence: null,\n usage: {\n input_tokens: 0,\n output_tokens: 0,\n cache_creation_input_tokens: null,\n cache_read_input_tokens: null,\n },\n content: [],\n } as unknown as Message;\n\n for await (const chunk of stream) {\n yield chunk;\n\n try {\n switch (chunk.type) {\n case \"message_start\":\n result.id = chunk.message.id;\n result.model = chunk.message.model;\n Object.assign(result.usage, chunk.message.usage);\n break;\n case \"message_delta\":\n if (chunk.usage) {\n Object.assign(result.usage, chunk.usage);\n }\n break;\n case \"content_block_start\":\n if (result.content.length <= chunk.index) {\n result.content.push({ ...chunk.content_block });\n }\n break;\n\n case \"content_block_delta\":\n if (chunk.index < result.content.length) {\n const current = result.content[chunk.index];\n if (\n current.type === \"text\" &&\n chunk.delta.type === \"text_delta\"\n ) {\n result.content[chunk.index] = {\n type: \"text\",\n text: current.text + chunk.delta.text,\n citations: current.citations,\n };\n }\n }\n break;\n }\n } catch (e) {\n this._diag.debug(e);\n this._config.exceptionLogger?.(e);\n }\n }\n\n this._endSpan({ span, type, result });\n } else {\n const result: Completion = {\n id: \"0\",\n type: \"completion\",\n model: \"\",\n completion: \"\",\n stop_reason: null,\n };\n for await (const chunk of stream as Stream<Completion>) {\n yield chunk;\n\n try {\n result.id = chunk.id;\n result.model = chunk.model;\n\n if (chunk.stop_reason) {\n result.stop_reason = chunk.stop_reason;\n }\n if (chunk.model) {\n result.model = chunk.model;\n }\n if (chunk.completion) {\n result.completion += chunk.completion;\n }\n } catch (e) {\n this._diag.debug(e);\n this._config.exceptionLogger?.(e);\n }\n }\n\n this._endSpan({ span, type, result });\n }\n } catch (error) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error.message,\n });\n span.recordException(error);\n span.end();\n throw error;\n }\n }\n\n return new moduleExports.APIPromise(\n client,\n (promise as any).responsePromise,\n async (client, props) => {\n const realStream = await (promise as any).parseResponse(client, props);\n\n // take the incoming stream, iterate it using our instrumented function, and wrap it in a new stream to keep the rich object type the same\n return new realStream.constructor(\n () => iterateStream.call(this, realStream),\n realStream.controller,\n );\n },\n ) as\n | APIPromise<Stream<MessageStreamEvent>>\n | APIPromise<Stream<Completion>>;\n }\n\n private _wrapPromise<T>(\n type:\n | typeof GEN_AI_OPERATION_NAME_VALUE_CHAT\n | typeof GEN_AI_OPERATION_NAME_VALUE_TEXT_COMPLETION,\n span: Span,\n promise: Promise<T>,\n ): Promise<T> {\n return promise\n .then((result) => {\n if (type === GEN_AI_OPERATION_NAME_VALUE_CHAT) {\n this._endSpan({\n type,\n span,\n result: result as Message,\n });\n } else {\n this._endSpan({\n type,\n span,\n result: result as Completion,\n });\n }\n\n return result;\n })\n .catch((error: Error) => {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error.message,\n });\n span.recordException(error);\n span.end();\n\n throw error;\n });\n }\n\n private _endSpan({\n span,\n type,\n result,\n }:\n | {\n span: Span;\n type: typeof GEN_AI_OPERATION_NAME_VALUE_CHAT;\n result: Message;\n }\n | {\n span: Span;\n type: typeof GEN_AI_OPERATION_NAME_VALUE_TEXT_COMPLETION;\n result: Completion;\n }) {\n try {\n span.setAttribute(ATTR_GEN_AI_RESPONSE_MODEL, result.model);\n\n // Always set finish_reason — it's metadata, not user content\n if (result.stop_reason) {\n const mappedReason =\n anthropicFinishReasonMap[result.stop_reason] ?? result.stop_reason;\n span.setAttribute(ATTR_GEN_AI_RESPONSE_FINISH_REASONS, [mappedReason]);\n }\n\n if (type === GEN_AI_OPERATION_NAME_VALUE_CHAT && result.usage) {\n span.setAttribute(\n SpanAttributes.GEN_AI_USAGE_TOTAL_TOKENS,\n result.usage.input_tokens + result.usage.output_tokens,\n );\n span.setAttribute(\n ATTR_GEN_AI_USAGE_OUTPUT_TOKENS,\n result.usage.output_tokens,\n );\n span.setAttribute(\n ATTR_GEN_AI_USAGE_INPUT_TOKENS,\n result.usage.input_tokens,\n );\n\n // Cache token attributes (v1.40)\n if (result.usage.cache_creation_input_tokens != null) {\n span.setAttribute(\n ATTR_GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS,\n result.usage.cache_creation_input_tokens,\n );\n }\n if (result.usage.cache_read_input_tokens != null) {\n span.setAttribute(\n ATTR_GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS,\n result.usage.cache_read_input_tokens,\n );\n }\n }\n\n // Only set output message content when tracing content\n if (this._shouldSendPrompts()) {\n const content =\n type === GEN_AI_OPERATION_NAME_VALUE_CHAT\n ? result.content\n : result.completion;\n const outputMessages = formatOutputMessage(\n content,\n result.stop_reason,\n anthropicFinishReasonMap,\n type,\n mapAnthropicContentBlock,\n );\n\n span.setAttribute(ATTR_GEN_AI_OUTPUT_MESSAGES, outputMessages);\n }\n } catch (e) {\n this._diag.debug(e);\n this._config.exceptionLogger?.(e);\n }\n\n span.end();\n }\n\n private _shouldSendPrompts() {\n const contextShouldSendPrompts = context\n .active()\n .getValue(CONTEXT_KEY_ALLOW_TRACE_CONTENT);\n\n if (contextShouldSendPrompts !== undefined) {\n return contextShouldSendPrompts;\n }\n\n return this._config.traceContent !== undefined\n ? this._config.traceContent\n : true;\n }\n}\n"],"names":["FinishReasons","InstrumentationBase","GEN_AI_OPERATION_NAME_VALUE_TEXT_COMPLETION","GEN_AI_OPERATION_NAME_VALUE_CHAT","InstrumentationNodeModuleDefinition","trace","context","safeExecuteInTheMiddle","ATTR_GEN_AI_PROVIDER_NAME","GEN_AI_PROVIDER_NAME_VALUE_ANTHROPIC","ATTR_GEN_AI_OPERATION_NAME","ATTR_GEN_AI_REQUEST_MODEL","ATTR_GEN_AI_REQUEST_TEMPERATURE","ATTR_GEN_AI_REQUEST_TOP_P","ATTR_GEN_AI_REQUEST_TOP_K","SpanAttributes","ATTR_GEN_AI_REQUEST_MAX_TOKENS","ATTR_GEN_AI_SYSTEM_INSTRUCTIONS","formatSystemInstructions","ATTR_GEN_AI_INPUT_MESSAGES","formatInputMessages","mapAnthropicContentBlock","formatInputMessagesFromPrompt","SpanKind","__asyncValues","__await","SpanStatusCode","__awaiter","ATTR_GEN_AI_RESPONSE_MODEL","ATTR_GEN_AI_RESPONSE_FINISH_REASONS","ATTR_GEN_AI_USAGE_OUTPUT_TOKENS","ATTR_GEN_AI_USAGE_INPUT_TOKENS","ATTR_GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS","ATTR_GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS","formatOutputMessage","ATTR_GEN_AI_OUTPUT_MESSAGES","CONTEXT_KEY_ALLOW_TRACE_CONTENT"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -1,11 +1,19 @@
1
1
  import { __awaiter, __asyncGenerator, __asyncValues, __await } from 'tslib';
2
2
  import { trace, context, SpanKind, SpanStatusCode } from '@opentelemetry/api';
3
3
  import { InstrumentationBase, InstrumentationNodeModuleDefinition, safeExecuteInTheMiddle } from '@opentelemetry/instrumentation';
4
- import { SpanAttributes, CONTEXT_KEY_ALLOW_TRACE_CONTENT } from '@traceloop/ai-semantic-conventions';
5
- import { ATTR_GEN_AI_REQUEST_MODEL, ATTR_GEN_AI_REQUEST_TEMPERATURE, ATTR_GEN_AI_REQUEST_TOP_P, ATTR_GEN_AI_REQUEST_MAX_TOKENS, ATTR_GEN_AI_PROMPT, ATTR_GEN_AI_RESPONSE_MODEL, ATTR_GEN_AI_USAGE_COMPLETION_TOKENS, ATTR_GEN_AI_USAGE_PROMPT_TOKENS, ATTR_GEN_AI_COMPLETION, ATTR_GEN_AI_SYSTEM } from '@opentelemetry/semantic-conventions/incubating';
4
+ import { FinishReasons, SpanAttributes, CONTEXT_KEY_ALLOW_TRACE_CONTENT } from '@traceloop/ai-semantic-conventions';
5
+ import { formatSystemInstructions, formatInputMessages, mapAnthropicContentBlock, formatInputMessagesFromPrompt, formatOutputMessage } from '@traceloop/instrumentation-utils';
6
+ import { GEN_AI_OPERATION_NAME_VALUE_TEXT_COMPLETION, GEN_AI_OPERATION_NAME_VALUE_CHAT, GEN_AI_PROVIDER_NAME_VALUE_ANTHROPIC, ATTR_GEN_AI_REQUEST_MODEL, ATTR_GEN_AI_REQUEST_TEMPERATURE, ATTR_GEN_AI_REQUEST_TOP_P, ATTR_GEN_AI_REQUEST_TOP_K, ATTR_GEN_AI_REQUEST_MAX_TOKENS, ATTR_GEN_AI_SYSTEM_INSTRUCTIONS, ATTR_GEN_AI_INPUT_MESSAGES, ATTR_GEN_AI_RESPONSE_MODEL, ATTR_GEN_AI_RESPONSE_FINISH_REASONS, ATTR_GEN_AI_USAGE_OUTPUT_TOKENS, ATTR_GEN_AI_USAGE_INPUT_TOKENS, ATTR_GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS, ATTR_GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS, ATTR_GEN_AI_OUTPUT_MESSAGES, ATTR_GEN_AI_OPERATION_NAME, ATTR_GEN_AI_PROVIDER_NAME } from '@opentelemetry/semantic-conventions/incubating';
6
7
 
7
- var version = "0.22.5";
8
+ var version = "0.23.0";
8
9
 
10
+ // Mapping of Anthropic-specific stop reasons to standardized finish reasons
11
+ const anthropicFinishReasonMap = {
12
+ end_turn: FinishReasons.STOP,
13
+ max_tokens: FinishReasons.LENGTH,
14
+ stop_sequence: FinishReasons.STOP,
15
+ tool_use: FinishReasons.TOOL_CALL,
16
+ };
9
17
  class AnthropicInstrumentation extends InstrumentationBase {
10
18
  constructor(config = {}) {
11
19
  super("@traceloop/instrumentation-anthropic", version, config);
@@ -15,9 +23,9 @@ class AnthropicInstrumentation extends InstrumentationBase {
15
23
  }
16
24
  manuallyInstrument(module) {
17
25
  this._diag.debug(`Patching @anthropic-ai/sdk manually`);
18
- this._wrap(module.Anthropic.Completions.prototype, "create", this.patchAnthropic("completion", module));
19
- this._wrap(module.Anthropic.Messages.prototype, "create", this.patchAnthropic("chat", module));
20
- this._wrap(module.Anthropic.Beta.Messages.prototype, "create", this.patchAnthropic("chat", module));
26
+ this._wrap(module.Anthropic.Completions.prototype, "create", this.patchAnthropic(GEN_AI_OPERATION_NAME_VALUE_TEXT_COMPLETION, module));
27
+ this._wrap(module.Anthropic.Messages.prototype, "create", this.patchAnthropic(GEN_AI_OPERATION_NAME_VALUE_CHAT, module));
28
+ this._wrap(module.Anthropic.Beta.Messages.prototype, "create", this.patchAnthropic(GEN_AI_OPERATION_NAME_VALUE_CHAT, module));
21
29
  }
22
30
  init() {
23
31
  const module = new InstrumentationNodeModuleDefinition("@anthropic-ai/sdk", [">=0.9.1"], this.patch.bind(this), this.unpatch.bind(this));
@@ -25,9 +33,9 @@ class AnthropicInstrumentation extends InstrumentationBase {
25
33
  }
26
34
  patch(moduleExports, moduleVersion) {
27
35
  this._diag.debug(`Patching @anthropic-ai/sdk@${moduleVersion}`);
28
- this._wrap(moduleExports.Anthropic.Completions.prototype, "create", this.patchAnthropic("completion", moduleExports));
29
- this._wrap(moduleExports.Anthropic.Messages.prototype, "create", this.patchAnthropic("chat", moduleExports));
30
- this._wrap(moduleExports.Anthropic.Beta.Messages.prototype, "create", this.patchAnthropic("chat", moduleExports));
36
+ this._wrap(moduleExports.Anthropic.Completions.prototype, "create", this.patchAnthropic(GEN_AI_OPERATION_NAME_VALUE_TEXT_COMPLETION, moduleExports));
37
+ this._wrap(moduleExports.Anthropic.Messages.prototype, "create", this.patchAnthropic(GEN_AI_OPERATION_NAME_VALUE_CHAT, moduleExports));
38
+ this._wrap(moduleExports.Anthropic.Beta.Messages.prototype, "create", this.patchAnthropic(GEN_AI_OPERATION_NAME_VALUE_CHAT, moduleExports));
31
39
  return moduleExports;
32
40
  }
33
41
  unpatch(moduleExports, moduleVersion) {
@@ -42,13 +50,13 @@ class AnthropicInstrumentation extends InstrumentationBase {
42
50
  // eslint-disable-next-line
43
51
  return (original) => {
44
52
  return function method(...args) {
45
- const span = type === "chat"
53
+ const span = type === GEN_AI_OPERATION_NAME_VALUE_CHAT
46
54
  ? plugin.startSpan({
47
55
  type,
48
56
  params: args[0],
49
57
  })
50
58
  : plugin.startSpan({
51
- type,
59
+ type: GEN_AI_OPERATION_NAME_VALUE_TEXT_COMPLETION,
52
60
  params: args[0],
53
61
  });
54
62
  const execContext = trace.setSpan(context.active(), span);
@@ -78,24 +86,25 @@ class AnthropicInstrumentation extends InstrumentationBase {
78
86
  };
79
87
  }
80
88
  startSpan({ type, params, }) {
81
- var _a, _b;
89
+ var _a, _b, _c;
82
90
  const attributes = {
83
- [ATTR_GEN_AI_SYSTEM]: "Anthropic",
84
- [SpanAttributes.LLM_REQUEST_TYPE]: type,
91
+ [ATTR_GEN_AI_PROVIDER_NAME]: GEN_AI_PROVIDER_NAME_VALUE_ANTHROPIC,
92
+ [ATTR_GEN_AI_OPERATION_NAME]: type,
85
93
  };
86
94
  try {
87
95
  attributes[ATTR_GEN_AI_REQUEST_MODEL] = params.model;
88
96
  attributes[ATTR_GEN_AI_REQUEST_TEMPERATURE] = params.temperature;
89
97
  attributes[ATTR_GEN_AI_REQUEST_TOP_P] = params.top_p;
90
- attributes[SpanAttributes.LLM_TOP_K] = params.top_k;
98
+ attributes[ATTR_GEN_AI_REQUEST_TOP_K] = params.top_k;
91
99
  // Handle thinking parameters (for beta messages)
92
100
  const betaParams = params;
93
101
  if (betaParams.thinking && betaParams.thinking.type === "enabled") {
94
- attributes["llm.request.thinking.type"] = betaParams.thinking.type;
95
- attributes["llm.request.thinking.budget_tokens"] =
102
+ attributes[SpanAttributes.GEN_AI_REQUEST_THINKING_TYPE] =
103
+ betaParams.thinking.type;
104
+ attributes[SpanAttributes.GEN_AI_REQUEST_THINKING_BUDGET_TOKENS] =
96
105
  betaParams.thinking.budget_tokens;
97
106
  }
98
- if (type === "completion") {
107
+ if (type === GEN_AI_OPERATION_NAME_VALUE_TEXT_COMPLETION) {
99
108
  attributes[ATTR_GEN_AI_REQUEST_MAX_TOKENS] =
100
109
  params.max_tokens_to_sample;
101
110
  }
@@ -109,34 +118,16 @@ class AnthropicInstrumentation extends InstrumentationBase {
109
118
  });
110
119
  }
111
120
  if (this._shouldSendPrompts()) {
112
- if (type === "chat") {
113
- let promptIndex = 0;
114
- // If a system prompt is provided, it should always be first
121
+ if (type === GEN_AI_OPERATION_NAME_VALUE_CHAT) {
115
122
  if ("system" in params && params.system !== undefined) {
116
- attributes[`${ATTR_GEN_AI_PROMPT}.0.role`] = "system";
117
- attributes[`${ATTR_GEN_AI_PROMPT}.0.content`] =
118
- typeof params.system === "string"
119
- ? params.system
120
- : JSON.stringify(params.system);
121
- promptIndex += 1;
123
+ attributes[ATTR_GEN_AI_SYSTEM_INSTRUCTIONS] =
124
+ formatSystemInstructions(params.system);
122
125
  }
123
- params.messages.forEach((message, index) => {
124
- const currentIndex = index + promptIndex;
125
- attributes[`${ATTR_GEN_AI_PROMPT}.${currentIndex}.role`] =
126
- message.role;
127
- if (typeof message.content === "string") {
128
- attributes[`${ATTR_GEN_AI_PROMPT}.${currentIndex}.content`] =
129
- message.content || "";
130
- }
131
- else {
132
- attributes[`${ATTR_GEN_AI_PROMPT}.${currentIndex}.content`] =
133
- JSON.stringify(message.content);
134
- }
135
- });
126
+ attributes[ATTR_GEN_AI_INPUT_MESSAGES] = formatInputMessages(params.messages, mapAnthropicContentBlock);
136
127
  }
137
128
  else {
138
- attributes[`${ATTR_GEN_AI_PROMPT}.0.role`] = "user";
139
- attributes[`${ATTR_GEN_AI_PROMPT}.0.content`] = params.prompt;
129
+ attributes[ATTR_GEN_AI_INPUT_MESSAGES] =
130
+ formatInputMessagesFromPrompt(params.prompt);
140
131
  }
141
132
  }
142
133
  }
@@ -144,7 +135,7 @@ class AnthropicInstrumentation extends InstrumentationBase {
144
135
  this._diag.debug(e);
145
136
  (_b = (_a = this._config).exceptionLogger) === null || _b === void 0 ? void 0 : _b.call(_a, e);
146
137
  }
147
- return this.tracer.startSpan(`anthropic.${type}`, {
138
+ return this.tracer.startSpan(`${type} ${(_c = params === null || params === void 0 ? void 0 : params.model) !== null && _c !== void 0 ? _c : "unknown"}`, {
148
139
  kind: SpanKind.CLIENT,
149
140
  attributes,
150
141
  });
@@ -155,7 +146,7 @@ class AnthropicInstrumentation extends InstrumentationBase {
155
146
  var _a, e_1, _b, _c, _d, e_2, _e, _f;
156
147
  var _g, _h, _j, _k;
157
148
  try {
158
- if (type === "chat") {
149
+ if (type === GEN_AI_OPERATION_NAME_VALUE_CHAT) {
159
150
  const result = {
160
151
  id: "0",
161
152
  type: "message",
@@ -166,11 +157,8 @@ class AnthropicInstrumentation extends InstrumentationBase {
166
157
  usage: {
167
158
  input_tokens: 0,
168
159
  output_tokens: 0,
169
- cache_creation: null,
170
160
  cache_creation_input_tokens: null,
171
161
  cache_read_input_tokens: null,
172
- server_tool_use: null,
173
- service_tier: null,
174
162
  },
175
163
  content: [],
176
164
  };
@@ -290,7 +278,7 @@ class AnthropicInstrumentation extends InstrumentationBase {
290
278
  _wrapPromise(type, span, promise) {
291
279
  return promise
292
280
  .then((result) => {
293
- if (type === "chat") {
281
+ if (type === GEN_AI_OPERATION_NAME_VALUE_CHAT) {
294
282
  this._endSpan({
295
283
  type,
296
284
  span,
@@ -317,31 +305,38 @@ class AnthropicInstrumentation extends InstrumentationBase {
317
305
  });
318
306
  }
319
307
  _endSpan({ span, type, result, }) {
320
- var _a, _b, _c, _d, _e, _f;
308
+ var _a, _b, _c;
321
309
  try {
322
310
  span.setAttribute(ATTR_GEN_AI_RESPONSE_MODEL, result.model);
323
- if (type === "chat" && result.usage) {
324
- span.setAttribute(SpanAttributes.LLM_USAGE_TOTAL_TOKENS, ((_a = result.usage) === null || _a === void 0 ? void 0 : _a.input_tokens) + ((_b = result.usage) === null || _b === void 0 ? void 0 : _b.output_tokens));
325
- span.setAttribute(ATTR_GEN_AI_USAGE_COMPLETION_TOKENS, (_c = result.usage) === null || _c === void 0 ? void 0 : _c.output_tokens);
326
- span.setAttribute(ATTR_GEN_AI_USAGE_PROMPT_TOKENS, (_d = result.usage) === null || _d === void 0 ? void 0 : _d.input_tokens);
327
- }
311
+ // Always set finish_reason it's metadata, not user content
328
312
  if (result.stop_reason) {
329
- span.setAttribute(`${ATTR_GEN_AI_COMPLETION}.0.finish_reason`, result.stop_reason);
313
+ const mappedReason = (_a = anthropicFinishReasonMap[result.stop_reason]) !== null && _a !== void 0 ? _a : result.stop_reason;
314
+ span.setAttribute(ATTR_GEN_AI_RESPONSE_FINISH_REASONS, [mappedReason]);
330
315
  }
331
- if (this._shouldSendPrompts()) {
332
- if (type === "chat") {
333
- span.setAttribute(`${ATTR_GEN_AI_COMPLETION}.0.role`, "assistant");
334
- span.setAttribute(`${ATTR_GEN_AI_COMPLETION}.0.content`, JSON.stringify(result.content));
316
+ if (type === GEN_AI_OPERATION_NAME_VALUE_CHAT && result.usage) {
317
+ span.setAttribute(SpanAttributes.GEN_AI_USAGE_TOTAL_TOKENS, result.usage.input_tokens + result.usage.output_tokens);
318
+ span.setAttribute(ATTR_GEN_AI_USAGE_OUTPUT_TOKENS, result.usage.output_tokens);
319
+ span.setAttribute(ATTR_GEN_AI_USAGE_INPUT_TOKENS, result.usage.input_tokens);
320
+ // Cache token attributes (v1.40)
321
+ if (result.usage.cache_creation_input_tokens != null) {
322
+ span.setAttribute(ATTR_GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS, result.usage.cache_creation_input_tokens);
335
323
  }
336
- else {
337
- span.setAttribute(`${ATTR_GEN_AI_COMPLETION}.0.role`, "assistant");
338
- span.setAttribute(`${ATTR_GEN_AI_COMPLETION}.0.content`, result.completion);
324
+ if (result.usage.cache_read_input_tokens != null) {
325
+ span.setAttribute(ATTR_GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS, result.usage.cache_read_input_tokens);
339
326
  }
340
327
  }
328
+ // Only set output message content when tracing content
329
+ if (this._shouldSendPrompts()) {
330
+ const content = type === GEN_AI_OPERATION_NAME_VALUE_CHAT
331
+ ? result.content
332
+ : result.completion;
333
+ const outputMessages = formatOutputMessage(content, result.stop_reason, anthropicFinishReasonMap, type, mapAnthropicContentBlock);
334
+ span.setAttribute(ATTR_GEN_AI_OUTPUT_MESSAGES, outputMessages);
335
+ }
341
336
  }
342
337
  catch (e) {
343
338
  this._diag.debug(e);
344
- (_f = (_e = this._config).exceptionLogger) === null || _f === void 0 ? void 0 : _f.call(_e, e);
339
+ (_c = (_b = this._config).exceptionLogger) === null || _c === void 0 ? void 0 : _c.call(_b, e);
345
340
  }
346
341
  span.end();
347
342
  }
@@ -358,5 +353,5 @@ class AnthropicInstrumentation extends InstrumentationBase {
358
353
  }
359
354
  }
360
355
 
361
- export { AnthropicInstrumentation };
356
+ export { AnthropicInstrumentation, anthropicFinishReasonMap };
362
357
  //# sourceMappingURL=index.mjs.map
@@ -1,6 +1,7 @@
1
1
  import { InstrumentationBase, InstrumentationModuleDefinition } from "@opentelemetry/instrumentation";
2
2
  import { AnthropicInstrumentationConfig } from "./types";
3
3
  import type * as anthropic from "@anthropic-ai/sdk";
4
+ export declare const anthropicFinishReasonMap: Record<string, string>;
4
5
  export declare class AnthropicInstrumentation extends InstrumentationBase {
5
6
  protected _config: AnthropicInstrumentationConfig;
6
7
  constructor(config?: AnthropicInstrumentationConfig);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@traceloop/instrumentation-anthropic",
3
- "version": "0.22.5",
3
+ "version": "0.23.0",
4
4
  "description": "Anthropic Instrumentaion",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -41,12 +41,13 @@
41
41
  "@opentelemetry/api": "^1.9.0",
42
42
  "@opentelemetry/core": "^2.0.1",
43
43
  "@opentelemetry/instrumentation": "^0.203.0",
44
- "@opentelemetry/semantic-conventions": "^1.38.0",
45
- "@traceloop/ai-semantic-conventions": "0.22.5",
44
+ "@opentelemetry/semantic-conventions": "^1.40.0",
45
+ "@traceloop/ai-semantic-conventions": "0.23.0",
46
+ "@traceloop/instrumentation-utils": "0.23.0",
46
47
  "tslib": "^2.8.1"
47
48
  },
48
49
  "devDependencies": {
49
- "@anthropic-ai/sdk": "^0.71.0",
50
+ "@anthropic-ai/sdk": "^0.80.0",
50
51
  "@opentelemetry/context-async-hooks": "^2.0.1",
51
52
  "@opentelemetry/sdk-trace-node": "^2.0.1",
52
53
  "@pollyjs/adapter-fetch": "^6.0.7",
@@ -54,8 +55,9 @@
54
55
  "@pollyjs/core": "^6.0.6",
55
56
  "@pollyjs/persister-fs": "^6.0.6",
56
57
  "@types/mocha": "^10.0.10",
58
+ "qs": "^6.14.1",
57
59
  "ts-mocha": "^11.1.0"
58
60
  },
59
61
  "homepage": "https://github.com/traceloop/openllmetry-js/tree/main/packages/instrumentation-anthropic",
60
- "gitHead": "f480743514f70ab20669987d040bfec8be33fcb4"
62
+ "gitHead": "0b94ccef9d48518f125c3c549ea8f224b8dfe8d2"
61
63
  }