Skip to content

Commit e3cfd57

Browse files
committed
feat(node): Update vercel ai integration attributes
1 parent 63b255f commit e3cfd57

File tree

2 files changed

+18
-10
lines changed
  • dev-packages/node-integration-tests/suites/tracing/vercelai
  • packages/node/src/integrations/tracing/vercelai

2 files changed

+18
-10
lines changed

dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -182,10 +182,9 @@ describe('Vercel AI integration', () => {
182182
expect.objectContaining({
183183
data: {
184184
'ai.operationId': 'ai.toolCall',
185-
'ai.toolCall.id': 'call-1',
186-
'ai.toolCall.name': 'getWeather',
187185
'gen_ai.tool.call.id': 'call-1',
188186
'gen_ai.tool.name': 'getWeather',
187+
'gen_ai.tool.type': 'function',
189188
'operation.name': 'ai.toolCall',
190189
'sentry.op': 'gen_ai.execute_tool',
191190
'sentry.origin': 'auto.vercelai.otel',
@@ -389,12 +388,11 @@ describe('Vercel AI integration', () => {
389388
expect.objectContaining({
390389
data: {
391390
'ai.operationId': 'ai.toolCall',
392-
'ai.toolCall.args': expect.any(String),
393-
'ai.toolCall.id': 'call-1',
394-
'ai.toolCall.name': 'getWeather',
395-
'ai.toolCall.result': expect.any(String),
396391
'gen_ai.tool.call.id': 'call-1',
392+
'gen_ai.tool.input': expect.any(String),
397393
'gen_ai.tool.name': 'getWeather',
394+
'gen_ai.tool.output': expect.any(String),
395+
'gen_ai.tool.type': 'function',
398396
'operation.name': 'ai.toolCall',
399397
'sentry.op': 'gen_ai.execute_tool',
400398
'sentry.origin': 'auto.vercelai.otel',

packages/node/src/integrations/tracing/vercelai/index.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/* eslint-disable @typescript-eslint/no-dynamic-delete */
21
/* eslint-disable complexity */
32
import type { Client, IntegrationFn } from '@sentry/core';
43
import { defineIntegration, SEMANTIC_ATTRIBUTE_SENTRY_OP, spanToJSON } from '@sentry/core';
@@ -14,8 +13,10 @@ import {
1413
AI_RESPONSE_TEXT_ATTRIBUTE,
1514
AI_RESPONSE_TOOL_CALLS_ATTRIBUTE,
1615
AI_TELEMETRY_FUNCTION_ID_ATTRIBUTE,
16+
AI_TOOL_CALL_ARGS_ATTRIBUTE,
1717
AI_TOOL_CALL_ID_ATTRIBUTE,
1818
AI_TOOL_CALL_NAME_ATTRIBUTE,
19+
AI_TOOL_CALL_RESULT_ATTRIBUTE,
1920
AI_USAGE_COMPLETION_TOKENS_ATTRIBUTE,
2021
AI_USAGE_PROMPT_TOKENS_ATTRIBUTE,
2122
GEN_AI_RESPONSE_MODEL_ATTRIBUTE,
@@ -64,9 +65,17 @@ const _vercelAIIntegration = ((options: VercelAiOptions = {}) => {
6465
) {
6566
addOriginToSpan(span, 'auto.vercelai.otel');
6667
span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'gen_ai.execute_tool');
67-
span.setAttribute('gen_ai.tool.call.id', attributes[AI_TOOL_CALL_ID_ATTRIBUTE]);
68-
span.setAttribute('gen_ai.tool.name', attributes[AI_TOOL_CALL_NAME_ATTRIBUTE]);
68+
renameAttributeKey(attributes, AI_TOOL_CALL_NAME_ATTRIBUTE, 'gen_ai.tool.name');
69+
renameAttributeKey(attributes, AI_TOOL_CALL_ID_ATTRIBUTE, 'gen_ai.tool.call.id');
70+
renameAttributeKey(attributes, AI_TOOL_CALL_ARGS_ATTRIBUTE, 'gen_ai.tool.input');
71+
renameAttributeKey(attributes, AI_TOOL_CALL_RESULT_ATTRIBUTE, 'gen_ai.tool.output');
6972
span.updateName(`execute_tool ${attributes[AI_TOOL_CALL_NAME_ATTRIBUTE]}`);
73+
74+
// https://opentelemetry.io/docs/specs/semconv/registry/attributes/gen-ai/#gen-ai-tool-type
75+
if (!attributes['gen_ai.tool.type']) {
76+
span.setAttribute('gen_ai.tool.type', 'function');
77+
}
78+
7079
return;
7180
}
7281

@@ -93,7 +102,7 @@ const _vercelAIIntegration = ((options: VercelAiOptions = {}) => {
93102
}
94103

95104
if (attributes[AI_PROMPT_ATTRIBUTE]) {
96-
span.setAttribute('gen_ai.prompt', attributes[AI_PROMPT_ATTRIBUTE]);
105+
renameAttributeKey(attributes, AI_PROMPT_ATTRIBUTE, 'gen_ai.prompt');
97106
}
98107
if (attributes[AI_MODEL_ID_ATTRIBUTE] && !attributes[GEN_AI_RESPONSE_MODEL_ATTRIBUTE]) {
99108
span.setAttribute(GEN_AI_RESPONSE_MODEL_ATTRIBUTE, attributes[AI_MODEL_ID_ATTRIBUTE]);
@@ -268,6 +277,7 @@ export const vercelAIIntegration = defineIntegration(_vercelAIIntegration);
268277
function renameAttributeKey(attributes: Record<string, unknown>, oldKey: string, newKey: string): void {
269278
if (attributes[oldKey] != null) {
270279
attributes[newKey] = attributes[oldKey];
280+
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
271281
delete attributes[oldKey];
272282
}
273283
}

0 commit comments

Comments
 (0)