From 6750b123115f3f8f7815472a40d2fe1a772f1228 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 2 Jul 2025 14:39:20 -0400 Subject: [PATCH 1/4] feat(node): Update vercel ai integration attributes --- .../suites/tracing/vercelai/test.ts | 8 ++++---- packages/core/src/utils/vercel-ai.ts | 14 +++++++++++--- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts b/dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts index a10d602ee93a..4bde6b179b3d 100644 --- a/dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts @@ -182,10 +182,11 @@ describe('Vercel AI integration', () => { expect.objectContaining({ data: { 'ai.operationId': 'ai.toolCall', - 'ai.toolCall.id': 'call-1', - 'ai.toolCall.name': 'getWeather', 'gen_ai.tool.call.id': 'call-1', + 'gen_ai.tool.input': expect.any(String), 'gen_ai.tool.name': 'getWeather', + 'gen_ai.tool.output': expect.any(String), + 'gen_ai.tool.type': 'function', 'operation.name': 'ai.toolCall', 'sentry.op': 'gen_ai.execute_tool', 'sentry.origin': 'auto.vercelai.otel', @@ -390,11 +391,10 @@ describe('Vercel AI integration', () => { data: { 'ai.operationId': 'ai.toolCall', 'ai.toolCall.args': expect.any(String), - 'ai.toolCall.id': 'call-1', - 'ai.toolCall.name': 'getWeather', 'ai.toolCall.result': expect.any(String), 'gen_ai.tool.call.id': 'call-1', 'gen_ai.tool.name': 'getWeather', + 'gen_ai.tool.type': 'function', 'operation.name': 'ai.toolCall', 'sentry.op': 'gen_ai.execute_tool', 'sentry.origin': 'auto.vercelai.otel', diff --git a/packages/core/src/utils/vercel-ai.ts b/packages/core/src/utils/vercel-ai.ts index 2a653addd805..73c41f16267b 100644 --- a/packages/core/src/utils/vercel-ai.ts +++ b/packages/core/src/utils/vercel-ai.ts @@ -12,8 +12,10 @@ import { AI_RESPONSE_TEXT_ATTRIBUTE, AI_RESPONSE_TOOL_CALLS_ATTRIBUTE, AI_TELEMETRY_FUNCTION_ID_ATTRIBUTE, + AI_TOOL_CALL_ARGS_ATTRIBUTE, AI_TOOL_CALL_ID_ATTRIBUTE, AI_TOOL_CALL_NAME_ATTRIBUTE, + AI_TOOL_CALL_RESULT_ATTRIBUTE, AI_USAGE_COMPLETION_TOKENS_ATTRIBUTE, AI_USAGE_PROMPT_TOKENS_ATTRIBUTE, GEN_AI_RESPONSE_MODEL_ATTRIBUTE, @@ -111,8 +113,14 @@ function renameAttributeKey(attributes: Record, oldKey: string, function processToolCallSpan(span: Span, attributes: SpanAttributes): void { addOriginToSpan(span, 'auto.vercelai.otel'); span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'gen_ai.execute_tool'); - span.setAttribute('gen_ai.tool.call.id', attributes[AI_TOOL_CALL_ID_ATTRIBUTE]); - span.setAttribute('gen_ai.tool.name', attributes[AI_TOOL_CALL_NAME_ATTRIBUTE]); + renameAttributeKey(attributes, AI_TOOL_CALL_NAME_ATTRIBUTE, 'gen_ai.tool.name'); + renameAttributeKey(attributes, AI_TOOL_CALL_ID_ATTRIBUTE, 'gen_ai.tool.call.id'); + renameAttributeKey(attributes, AI_TOOL_CALL_ARGS_ATTRIBUTE, 'gen_ai.tool.input'); + renameAttributeKey(attributes, AI_TOOL_CALL_RESULT_ATTRIBUTE, 'gen_ai.tool.output'); + // https://opentelemetry.io/docs/specs/semconv/registry/attributes/gen-ai/#gen-ai-tool-type + if (!attributes['gen_ai.tool.type']) { + span.setAttribute('gen_ai.tool.type', 'function'); + } span.updateName(`execute_tool ${attributes[AI_TOOL_CALL_NAME_ATTRIBUTE]}`); } @@ -127,7 +135,7 @@ function processGenerateSpan(span: Span, name: string, attributes: SpanAttribute const functionId = attributes[AI_TELEMETRY_FUNCTION_ID_ATTRIBUTE]; if (functionId && typeof functionId === 'string' && name.split('.').length - 1 === 1) { span.updateName(`${nameWthoutAi} ${functionId}`); - span.setAttribute('ai.pipeline.name', functionId); + span.setAttribute('gen_ai.function_id', functionId); } if (attributes[AI_PROMPT_ATTRIBUTE]) { From aa812ab7d728fa741e32775b121fe23f3f68101f Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 2 Jul 2025 14:55:17 -0400 Subject: [PATCH 2/4] thanks cursor --- packages/core/src/utils/vercel-ai.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/utils/vercel-ai.ts b/packages/core/src/utils/vercel-ai.ts index 73c41f16267b..f5f1803c85c1 100644 --- a/packages/core/src/utils/vercel-ai.ts +++ b/packages/core/src/utils/vercel-ai.ts @@ -121,7 +121,7 @@ function processToolCallSpan(span: Span, attributes: SpanAttributes): void { if (!attributes['gen_ai.tool.type']) { span.setAttribute('gen_ai.tool.type', 'function'); } - span.updateName(`execute_tool ${attributes[AI_TOOL_CALL_NAME_ATTRIBUTE]}`); + span.updateName(`execute_tool ${attributes['gen_ai.tool.name']}`); } function processGenerateSpan(span: Span, name: string, attributes: SpanAttributes): void { From f5cc78c5c6181655436b328c6b7d3b5b2d36fb65 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 2 Jul 2025 15:14:53 -0400 Subject: [PATCH 3/4] fix tests --- .../node-integration-tests/suites/tracing/vercelai/test.ts | 6 ++---- packages/core/src/utils/vercel-ai.ts | 5 +++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts b/dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts index 4bde6b179b3d..3566d40322de 100644 --- a/dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts @@ -183,9 +183,7 @@ describe('Vercel AI integration', () => { data: { 'ai.operationId': 'ai.toolCall', 'gen_ai.tool.call.id': 'call-1', - 'gen_ai.tool.input': expect.any(String), 'gen_ai.tool.name': 'getWeather', - 'gen_ai.tool.output': expect.any(String), 'gen_ai.tool.type': 'function', 'operation.name': 'ai.toolCall', 'sentry.op': 'gen_ai.execute_tool', @@ -390,10 +388,10 @@ describe('Vercel AI integration', () => { expect.objectContaining({ data: { 'ai.operationId': 'ai.toolCall', - 'ai.toolCall.args': expect.any(String), - 'ai.toolCall.result': expect.any(String), 'gen_ai.tool.call.id': 'call-1', 'gen_ai.tool.name': 'getWeather', + 'gen_ai.tool.input': expect.any(String), + 'gen_ai.tool.output': expect.any(String), 'gen_ai.tool.type': 'function', 'operation.name': 'ai.toolCall', 'sentry.op': 'gen_ai.execute_tool', diff --git a/packages/core/src/utils/vercel-ai.ts b/packages/core/src/utils/vercel-ai.ts index f5f1803c85c1..3a1e14064d69 100644 --- a/packages/core/src/utils/vercel-ai.ts +++ b/packages/core/src/utils/vercel-ai.ts @@ -96,6 +96,9 @@ function processEndedVercelAiSpan(span: SpanJSON): void { renameAttributeKey(attributes, AI_RESPONSE_TEXT_ATTRIBUTE, 'gen_ai.response.text'); renameAttributeKey(attributes, AI_RESPONSE_TOOL_CALLS_ATTRIBUTE, 'gen_ai.response.tool_calls'); renameAttributeKey(attributes, AI_PROMPT_TOOLS_ATTRIBUTE, 'gen_ai.request.available_tools'); + + renameAttributeKey(attributes, AI_TOOL_CALL_ARGS_ATTRIBUTE, 'gen_ai.tool.input'); + renameAttributeKey(attributes, AI_TOOL_CALL_RESULT_ATTRIBUTE, 'gen_ai.tool.output'); } /** @@ -115,8 +118,6 @@ function processToolCallSpan(span: Span, attributes: SpanAttributes): void { span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'gen_ai.execute_tool'); renameAttributeKey(attributes, AI_TOOL_CALL_NAME_ATTRIBUTE, 'gen_ai.tool.name'); renameAttributeKey(attributes, AI_TOOL_CALL_ID_ATTRIBUTE, 'gen_ai.tool.call.id'); - renameAttributeKey(attributes, AI_TOOL_CALL_ARGS_ATTRIBUTE, 'gen_ai.tool.input'); - renameAttributeKey(attributes, AI_TOOL_CALL_RESULT_ATTRIBUTE, 'gen_ai.tool.output'); // https://opentelemetry.io/docs/specs/semconv/registry/attributes/gen-ai/#gen-ai-tool-type if (!attributes['gen_ai.tool.type']) { span.setAttribute('gen_ai.tool.type', 'function'); From c4f69a32e725189c626ec0c26542d7e72b418385 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 2 Jul 2025 15:30:52 -0400 Subject: [PATCH 4/4] be more strict about tool name --- packages/core/src/utils/vercel-ai.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/core/src/utils/vercel-ai.ts b/packages/core/src/utils/vercel-ai.ts index 3a1e14064d69..401c295c97c9 100644 --- a/packages/core/src/utils/vercel-ai.ts +++ b/packages/core/src/utils/vercel-ai.ts @@ -122,7 +122,10 @@ function processToolCallSpan(span: Span, attributes: SpanAttributes): void { if (!attributes['gen_ai.tool.type']) { span.setAttribute('gen_ai.tool.type', 'function'); } - span.updateName(`execute_tool ${attributes['gen_ai.tool.name']}`); + const toolName = attributes['gen_ai.tool.name']; + if (toolName) { + span.updateName(`execute_tool ${toolName}`); + } } function processGenerateSpan(span: Span, name: string, attributes: SpanAttributes): void {