From 4fa02f8afd551cf81680ced4d21b2448bbf517ad Mon Sep 17 00:00:00 2001 From: Nicolas Hrubec Date: Thu, 23 Jul 2026 12:06:32 +0200 Subject: [PATCH] feat(core)!: Remove `sentry.sdk_meta.gen_ai.input.messages.original_length` attribute This internal SDK-meta span attribute only ever signaled how many gen_ai input messages existed before truncation dropped some. It carries no meaning for consumers on its own and is being removed ahead of the truncation removal. Text truncation itself is unchanged by this commit. Co-Authored-By: Claude Opus 4.8 (1M context) --- MIGRATION.md | 1 + .../suites/tracing/anthropic/test.ts | 6 --- .../suites/tracing/google-genai/test.ts | 4 -- .../suites/tracing/langchain/test.ts | 20 ++++---- .../suites/tracing/langchain/v1/test.ts | 19 ++++--- .../suites/tracing/langgraph/test.ts | 2 - .../tracing/openai/openai-tool-calls/test.ts | 17 ------- .../suites/tracing/openai/test.ts | 49 ------------------- .../suites/tracing/openai/v6/test.ts | 35 ------------- .../vercelai/span-streaming-v4/test.ts | 2 - .../vercelai/span-streaming-v6/test.ts | 2 - .../suites/tracing/vercelai/test.ts | 8 --- packages/core/src/server-exports.ts | 6 +-- .../core/src/tracing/ai/gen-ai-attributes.ts | 5 -- .../core/src/tracing/anthropic-ai/utils.ts | 11 +---- .../core/src/tracing/google-genai/index.ts | 3 -- packages/core/src/tracing/langchain/utils.ts | 5 -- packages/core/src/tracing/langgraph/index.ts | 3 -- packages/core/src/tracing/openai/index.ts | 7 --- packages/core/src/tracing/vercel-ai/utils.ts | 6 --- packages/core/src/tracing/workers-ai/utils.ts | 6 --- .../vercel-ai-request-messages.test.ts | 4 -- .../test/lib/utils/anthropic-utils.test.ts | 3 -- .../src/vercel-ai/vercel-ai-dc-subscriber.ts | 3 -- 24 files changed, 26 insertions(+), 201 deletions(-) diff --git a/MIGRATION.md b/MIGRATION.md index fd633ac0d9ea..d37a78304379 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -393,6 +393,7 @@ Sentry.init({ ### AI integrations - The `enableTruncation` and `streamGenAiSpans` flags were removed. The new default is no truncation and to always stream gen AI spans. +- The internal `sentry.sdk_meta.gen_ai.input.messages.original_length` span attribute was removed. - (Vercel AI) The internal JSON-stringify workaround for array span attributes was removed. - AI integrations are no longer available in the browser SDK. They remain available in the server-side SDKs. diff --git a/dev-packages/node-integration-tests/suites/tracing/anthropic/test.ts b/dev-packages/node-integration-tests/suites/tracing/anthropic/test.ts index 5546aa8abd66..43dd96dfce5c 100644 --- a/dev-packages/node-integration-tests/suites/tracing/anthropic/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/anthropic/test.ts @@ -1,7 +1,6 @@ import { afterAll, describe, expect } from 'vitest'; import { GEN_AI_INPUT_MESSAGES_ATTRIBUTE, - GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, GEN_AI_OPERATION_NAME_ATTRIBUTE, GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE, GEN_AI_REQUEST_MAX_TOKENS_ATTRIBUTE, @@ -634,7 +633,6 @@ describe('Anthropic integration', () => { expect(truncatedSpan!.attributes['sentry.origin'].value).toBe('auto.ai.anthropic'); expect(truncatedSpan!.attributes[GEN_AI_SYSTEM_ATTRIBUTE].value).toBe('anthropic'); expect(truncatedSpan!.attributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE].value).toBe('claude-3-haiku-20240307'); - expect(truncatedSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE].value).toBe(3); const smallMessageSpan = container.items.find( span => span.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE]?.value === smallMsgValue, @@ -649,7 +647,6 @@ describe('Anthropic integration', () => { expect(smallMessageSpan!.attributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE].value).toBe( 'claude-3-haiku-20240307', ); - expect(smallMessageSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE].value).toBe(3); }, }) .start() @@ -700,7 +697,6 @@ describe('Anthropic integration', () => { expect(firstSpan!.attributes['sentry.origin'].value).toBe('auto.ai.anthropic'); expect(firstSpan!.attributes[GEN_AI_SYSTEM_ATTRIBUTE].value).toBe('anthropic'); expect(firstSpan!.attributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE].value).toBe('claude-3-haiku-20240307'); - expect(firstSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE].value).toBe(2); }, }) .start() @@ -767,13 +763,11 @@ describe('Anthropic integration', () => { span => span.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE]?.value === expectedAllMessages, ); expect(conversationSpan).toBeDefined(); - expect(conversationSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE].value).toBe(3); const longStringSpan = container.items.find( span => span.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE]?.value === expectedLongString, ); expect(longStringSpan).toBeDefined(); - expect(longStringSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE].value).toBe(1); }, }) .start() diff --git a/dev-packages/node-integration-tests/suites/tracing/google-genai/test.ts b/dev-packages/node-integration-tests/suites/tracing/google-genai/test.ts index 3332ff1d862c..81b983ea4231 100644 --- a/dev-packages/node-integration-tests/suites/tracing/google-genai/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/google-genai/test.ts @@ -3,7 +3,6 @@ import { GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ATTRIBUTE, GEN_AI_OPERATION_NAME_ATTRIBUTE, - GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE, GEN_AI_REQUEST_MAX_TOKENS_ATTRIBUTE, GEN_AI_REQUEST_MODEL_ATTRIBUTE, @@ -368,7 +367,6 @@ describe('Google GenAI integration', () => { expect(truncatedSpan!.name).toBe('generate_content gemini-1.5-flash'); expect(truncatedSpan!.status).toBe('ok'); expect(truncatedSpan!.attributes[GEN_AI_OPERATION_NAME_ATTRIBUTE].value).toBe('generate_content'); - expect(truncatedSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE].value).toBe(3); const smallMessageSpan = container.items.find( span => @@ -384,7 +382,6 @@ describe('Google GenAI integration', () => { expect(smallMessageSpan!.name).toBe('generate_content gemini-1.5-flash'); expect(smallMessageSpan!.status).toBe('ok'); expect(smallMessageSpan!.attributes[GEN_AI_OPERATION_NAME_ATTRIBUTE].value).toBe('generate_content'); - expect(smallMessageSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE].value).toBe(3); }, }) .start() @@ -532,7 +529,6 @@ describe('Google GenAI integration', () => { { role: 'user', parts: [{ text: 'Follow-up question' }] }, ]), ); - expect(firstSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE].value).toBe(3); }, }) .start() diff --git a/dev-packages/node-integration-tests/suites/tracing/langchain/test.ts b/dev-packages/node-integration-tests/suites/tracing/langchain/test.ts index ed342ce9d1a2..d2b94f200c62 100644 --- a/dev-packages/node-integration-tests/suites/tracing/langchain/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/langchain/test.ts @@ -3,7 +3,6 @@ import { GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE, GEN_AI_EMBEDDINGS_OPERATION_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ATTRIBUTE, - GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, GEN_AI_OPERATION_NAME_ATTRIBUTE, GEN_AI_REQUEST_DIMENSIONS_ATTRIBUTE, GEN_AI_REQUEST_MAX_TOKENS_ATTRIBUTE, @@ -210,20 +209,25 @@ describe('LangChain integration', () => { .expect({ span: container => { expect(container.items).toHaveLength(3); + // The string-input span has no system message (and therefore no system instructions), + // while the array-input span does — use that to distinguish the two truncated spans. + const truncatedContent = /^\[\{"role":"user","content":"C+"\}\]$/; const stringInputSpan = container.items.find( - span => span.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]?.value === 1, + span => + span.attributes[GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE] === undefined && + getStringAttributeValue(span.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE]?.value)?.match( + truncatedContent, + ), ); expect(stringInputSpan).toBeDefined(); expect(stringInputSpan!.name).toBe('chat claude-3-5-sonnet-20241022'); - expect(stringInputSpan!.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE].value).toMatch( - /^\[\{"role":"user","content":"C+"\}\]$/, - ); + expect(stringInputSpan!.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE].value).toMatch(truncatedContent); const arrayInputSpan = container.items.find( span => - span.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]?.value === 2 && + span.attributes[GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE] !== undefined && getStringAttributeValue(span.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE]?.value)?.match( - /^\[\{"role":"user","content":"C+"\}\]$/, + truncatedContent, ), ); expect(arrayInputSpan).toBeDefined(); @@ -237,7 +241,6 @@ describe('LangChain integration', () => { ); expect(smallMessageSpan).toBeDefined(); expect(smallMessageSpan!.name).toBe('chat claude-3-5-sonnet-20241022'); - expect(smallMessageSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE].value).toBe(2); expect(smallMessageSpan!.attributes[GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE]).toBeDefined(); }, }) @@ -476,7 +479,6 @@ describe('LangChain integration', () => { { role: 'user', content: 'Follow-up question' }, ]), ); - expect(firstSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE].value).toBe(3); }, }) .start() diff --git a/dev-packages/node-integration-tests/suites/tracing/langchain/v1/test.ts b/dev-packages/node-integration-tests/suites/tracing/langchain/v1/test.ts index b555e48229e4..9d5c5e7ba1a3 100644 --- a/dev-packages/node-integration-tests/suites/tracing/langchain/v1/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/langchain/v1/test.ts @@ -1,7 +1,6 @@ import { afterAll, expect } from 'vitest'; import { GEN_AI_INPUT_MESSAGES_ATTRIBUTE, - GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, GEN_AI_OPERATION_NAME_ATTRIBUTE, GEN_AI_REQUEST_MAX_TOKENS_ATTRIBUTE, GEN_AI_REQUEST_MODEL_ATTRIBUTE, @@ -226,20 +225,25 @@ conditionalTest({ min: 20 })('LangChain integration (v1)', () => { .expect({ span: container => { expect(container.items).toHaveLength(3); + // The string-input span has no system message (and therefore no system instructions), + // while the array-input span does — use that to distinguish the two truncated spans. + const truncatedContent = /^\[\{"role":"user","content":"C+"\}\]$/; const stringInputSpan = container.items.find( - span => span.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]?.value === 1, + span => + span.attributes[GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE] === undefined && + getStringAttributeValue(span.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE]?.value)?.match( + truncatedContent, + ), ); expect(stringInputSpan).toBeDefined(); expect(stringInputSpan!.name).toBe('chat claude-3-5-sonnet-20241022'); - expect(stringInputSpan!.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE].value).toMatch( - /^\[\{"role":"user","content":"C+"\}\]$/, - ); + expect(stringInputSpan!.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE].value).toMatch(truncatedContent); const arrayInputSpan = container.items.find( span => - span.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]?.value === 2 && + span.attributes[GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE] !== undefined && getStringAttributeValue(span.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE]?.value)?.match( - /^\[\{"role":"user","content":"C+"\}\]$/, + truncatedContent, ), ); expect(arrayInputSpan).toBeDefined(); @@ -255,7 +259,6 @@ conditionalTest({ min: 20 })('LangChain integration (v1)', () => { ); expect(smallMessageSpan).toBeDefined(); expect(smallMessageSpan!.name).toBe('chat claude-3-5-sonnet-20241022'); - expect(smallMessageSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE].value).toBe(2); expect(smallMessageSpan!.attributes[GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE].value).toMatch( /^\[\{"type":"text","content":"A+"\}\]$/, ); diff --git a/dev-packages/node-integration-tests/suites/tracing/langgraph/test.ts b/dev-packages/node-integration-tests/suites/tracing/langgraph/test.ts index f293ba29218e..ed104fa52933 100644 --- a/dev-packages/node-integration-tests/suites/tracing/langgraph/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/langgraph/test.ts @@ -4,7 +4,6 @@ import { GEN_AI_AGENT_NAME_ATTRIBUTE, GEN_AI_CONVERSATION_ID_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ATTRIBUTE, - GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, GEN_AI_OPERATION_NAME_ATTRIBUTE, GEN_AI_PIPELINE_NAME_ATTRIBUTE, GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE, @@ -305,7 +304,6 @@ describe('LangGraph integration', () => { expect(invokeAgentSpan).toBeDefined(); expect(invokeAgentSpan!.name).toBe('invoke_agent weather_assistant'); - expect(invokeAgentSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE].value).toBe(3); }, }) .start() diff --git a/dev-packages/node-integration-tests/suites/tracing/openai/openai-tool-calls/test.ts b/dev-packages/node-integration-tests/suites/tracing/openai/openai-tool-calls/test.ts index 0895e6dffd19..7caf0d745237 100644 --- a/dev-packages/node-integration-tests/suites/tracing/openai/openai-tool-calls/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/openai/openai-tool-calls/test.ts @@ -2,7 +2,6 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from ' import { afterAll, describe, expect } from 'vitest'; import { GEN_AI_INPUT_MESSAGES_ATTRIBUTE, - GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, GEN_AI_OPERATION_NAME_ATTRIBUTE, GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE, GEN_AI_REQUEST_MODEL_ATTRIBUTE, @@ -355,10 +354,6 @@ describe('OpenAI Tool Calls integration', () => { type: 'string', value: 'gpt-4', }); - expect(chatToolsSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]).toEqual({ - type: 'integer', - value: 1, - }); expect(chatToolsSpan!.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE]).toEqual({ type: 'string', value: '[{"role":"user","content":"What is the weather like in Paris today?"}]', @@ -430,10 +425,6 @@ describe('OpenAI Tool Calls integration', () => { type: 'boolean', value: true, }); - expect(streamingChatToolsSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]).toEqual({ - type: 'integer', - value: 1, - }); expect(streamingChatToolsSpan!.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE]).toEqual({ type: 'string', value: '[{"role":"user","content":"What is the weather like in Paris today?"}]', @@ -502,10 +493,6 @@ describe('OpenAI Tool Calls integration', () => { value: 'gpt-4', }); expect(responsesToolsSpan!.attributes[GEN_AI_REQUEST_STREAM_ATTRIBUTE]).toBeUndefined(); - expect(responsesToolsSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]).toEqual({ - type: 'integer', - value: 1, - }); expect(responsesToolsSpan!.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE]).toEqual({ type: 'string', value: '[{"role":"user","content":"What is the weather like in Paris today?"}]', @@ -573,10 +560,6 @@ describe('OpenAI Tool Calls integration', () => { type: 'boolean', value: true, }); - expect(streamingResponsesToolsSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]).toEqual({ - type: 'integer', - value: 1, - }); expect(streamingResponsesToolsSpan!.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE]).toEqual({ type: 'string', value: '[{"role":"user","content":"What is the weather like in Paris today?"}]', diff --git a/dev-packages/node-integration-tests/suites/tracing/openai/test.ts b/dev-packages/node-integration-tests/suites/tracing/openai/test.ts index 3f102d360e40..bbb93952136a 100644 --- a/dev-packages/node-integration-tests/suites/tracing/openai/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/openai/test.ts @@ -4,7 +4,6 @@ import { GEN_AI_CONVERSATION_ID_ATTRIBUTE, GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ATTRIBUTE, - GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, GEN_AI_OPERATION_NAME_ATTRIBUTE, GEN_AI_REQUEST_DIMENSIONS_ATTRIBUTE, GEN_AI_REQUEST_ENCODING_FORMAT_ATTRIBUTE, @@ -368,10 +367,6 @@ describe('OpenAI integration', () => { type: 'double', value: 0.7, }); - expect(chatCompletionSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]).toEqual({ - type: 'integer', - value: 1, - }); expect(chatCompletionSpan!.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE]).toEqual({ type: 'string', value: '[{"role":"user","content":"What is the capital of France?"}]', @@ -432,10 +427,6 @@ describe('OpenAI integration', () => { type: 'string', value: 'gpt-3.5-turbo', }); - expect(responsesSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]).toEqual({ - type: 'integer', - value: 1, - }); expect(responsesSpan!.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE]).toEqual({ type: 'string', value: 'Translate this to French: Hello', @@ -497,10 +488,6 @@ describe('OpenAI integration', () => { type: 'string', value: 'error-model', }); - expect(nonStreamingErrorSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]).toEqual({ - type: 'integer', - value: 1, - }); expect(nonStreamingErrorSpan!.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE]).toEqual({ type: 'string', value: '[{"role":"user","content":"This will fail"}]', @@ -540,10 +527,6 @@ describe('OpenAI integration', () => { type: 'boolean', value: true, }); - expect(streamingChatCompletionSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]).toEqual({ - type: 'integer', - value: 1, - }); expect(streamingChatCompletionSpan!.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE]).toEqual({ type: 'string', value: '[{"role":"user","content":"Tell me about streaming"}]', @@ -615,10 +598,6 @@ describe('OpenAI integration', () => { type: 'boolean', value: true, }); - expect(streamingResponsesSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]).toEqual({ - type: 'integer', - value: 1, - }); expect(streamingResponsesSpan!.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE]).toEqual({ type: 'string', value: 'Test streaming responses API', @@ -675,10 +654,6 @@ describe('OpenAI integration', () => { type: 'boolean', value: true, }); - expect(streamingErrorSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]).toEqual({ - type: 'integer', - value: 1, - }); expect(streamingErrorSpan!.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE]).toEqual({ type: 'string', value: '[{"role":"user","content":"This will fail"}]', @@ -781,10 +756,6 @@ describe('OpenAI integration', () => { { role: 'user', content: 'Follow-up question' }, ]), }); - expect(chatCompletionSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]).toMatchObject({ - type: 'integer', - value: 3, - }); const responsesSpan = container.items.find( span => span.attributes[GEN_AI_RESPONSE_ID_ATTRIBUTE]?.value === 'resp_mock456', @@ -798,10 +769,6 @@ describe('OpenAI integration', () => { type: 'string', value: 'B'.repeat(50_000), }); - expect(responsesSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]).toMatchObject({ - type: 'integer', - value: 1, - }); }, }) .start() @@ -1220,10 +1187,6 @@ describe('OpenAI integration', () => { type: 'string', value: 'gpt-3.5-turbo', }); - expect(truncatedMessageSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]).toEqual({ - type: 'integer', - value: 2, - }); expect(truncatedMessageSpan!.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE].value).toMatch( /^\[\{"role":"user","content":"C+"\}\]$/, ); @@ -1265,10 +1228,6 @@ describe('OpenAI integration', () => { { role: 'user', content: 'This is a small message that fits within the limit' }, ]), }); - expect(smallMessageSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]).toEqual({ - type: 'integer', - value: 2, - }); expect(smallMessageSpan!.attributes[GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE].value).toMatch( /^\[\{"type":"text","content":"A+"\}\]$/, ); @@ -1315,10 +1274,6 @@ describe('OpenAI integration', () => { type: 'string', value: 'gpt-3.5-turbo', }); - expect(firstSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]).toEqual({ - type: 'integer', - value: 1, - }); expect(firstSpan!.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE].value).toMatch(/^A+$/); }, }) @@ -1627,10 +1582,6 @@ describe('OpenAI integration', () => { expect(span!.status).toBe('ok'); expect(span!.attributes[GEN_AI_OPERATION_NAME_ATTRIBUTE]).toEqual({ type: 'string', value: 'chat' }); expect(span!.attributes[GEN_AI_REQUEST_MODEL_ATTRIBUTE]).toEqual({ type: 'string', value: 'gpt-4o' }); - expect(span!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]).toEqual({ - type: 'integer', - value: 1, - }); expect(span!.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE].value).toContain('[Blob substitute]'); } }, diff --git a/dev-packages/node-integration-tests/suites/tracing/openai/v6/test.ts b/dev-packages/node-integration-tests/suites/tracing/openai/v6/test.ts index 0530d1575845..0c44b5b02be7 100644 --- a/dev-packages/node-integration-tests/suites/tracing/openai/v6/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/openai/v6/test.ts @@ -3,7 +3,6 @@ import { afterAll, describe, expect } from 'vitest'; import { GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ATTRIBUTE, - GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, GEN_AI_OPERATION_NAME_ATTRIBUTE, GEN_AI_REQUEST_DIMENSIONS_ATTRIBUTE, GEN_AI_REQUEST_ENCODING_FORMAT_ATTRIBUTE, @@ -381,10 +380,6 @@ describe('OpenAI integration (V6)', () => { type: 'double', value: 0.7, }); - expect(chatCompletionSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]).toEqual({ - type: 'integer', - value: 1, - }); expect(chatCompletionSpan!.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE]).toEqual({ type: 'string', value: '[{"role":"user","content":"What is the capital of France?"}]', @@ -445,10 +440,6 @@ describe('OpenAI integration (V6)', () => { type: 'string', value: 'gpt-3.5-turbo', }); - expect(responsesSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]).toEqual({ - type: 'integer', - value: 1, - }); expect(responsesSpan!.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE]).toEqual({ type: 'string', value: 'Translate this to French: Hello', @@ -510,10 +501,6 @@ describe('OpenAI integration (V6)', () => { type: 'string', value: 'error-model', }); - expect(nonStreamingErrorSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]).toEqual({ - type: 'integer', - value: 1, - }); expect(nonStreamingErrorSpan!.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE]).toEqual({ type: 'string', value: '[{"role":"user","content":"This will fail"}]', @@ -553,10 +540,6 @@ describe('OpenAI integration (V6)', () => { type: 'boolean', value: true, }); - expect(streamingChatCompletionSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]).toEqual({ - type: 'integer', - value: 1, - }); expect(streamingChatCompletionSpan!.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE]).toEqual({ type: 'string', value: '[{"role":"user","content":"Tell me about streaming"}]', @@ -628,10 +611,6 @@ describe('OpenAI integration (V6)', () => { type: 'boolean', value: true, }); - expect(streamingResponsesSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]).toEqual({ - type: 'integer', - value: 1, - }); expect(streamingResponsesSpan!.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE]).toEqual({ type: 'string', value: 'Test streaming responses API', @@ -688,10 +667,6 @@ describe('OpenAI integration (V6)', () => { type: 'boolean', value: true, }); - expect(streamingErrorSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]).toEqual({ - type: 'integer', - value: 1, - }); expect(streamingErrorSpan!.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE]).toEqual({ type: 'string', value: '[{"role":"user","content":"This will fail"}]', @@ -738,10 +713,6 @@ describe('OpenAI integration (V6)', () => { ); expect(chatCompletionSpan).toBeDefined(); expect(chatCompletionSpan!.attributes[GEN_AI_REQUEST_STREAM_ATTRIBUTE]).toBeUndefined(); - expect(chatCompletionSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]).toMatchObject({ - type: 'integer', - value: 1, - }); expect(chatCompletionSpan!.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE]).toMatchObject({ type: 'string', value: expect.any(String), @@ -763,12 +734,6 @@ describe('OpenAI integration (V6)', () => { type: 'boolean', value: true, }); - expect( - streamingChatCompletionSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE], - ).toMatchObject({ - type: 'integer', - value: 1, - }); expect(streamingChatCompletionSpan!.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE]).toMatchObject({ type: 'string', value: expect.any(String), diff --git a/dev-packages/node-integration-tests/suites/tracing/vercelai/span-streaming-v4/test.ts b/dev-packages/node-integration-tests/suites/tracing/vercelai/span-streaming-v4/test.ts index f28559c4b9e9..f522f7766822 100644 --- a/dev-packages/node-integration-tests/suites/tracing/vercelai/span-streaming-v4/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/vercelai/span-streaming-v4/test.ts @@ -2,7 +2,6 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from ' import { afterAll, describe, expect } from 'vitest'; import { GEN_AI_INPUT_MESSAGES_ATTRIBUTE, - GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, GEN_AI_OPERATION_NAME_ATTRIBUTE, GEN_AI_OUTPUT_MESSAGES_ATTRIBUTE, GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE, @@ -141,7 +140,6 @@ describe('Vercel AI integration (streaming v4)', () => { name: 'invoke_agent', status: 'ok', attributes: expect.objectContaining({ - [GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]: attr(1), [GEN_AI_INPUT_MESSAGES_ATTRIBUTE]: attr('[{"role":"user","content":"Where is the first span?"}]'), [GEN_AI_OUTPUT_MESSAGES_ATTRIBUTE]: attr( '[{"role":"assistant","parts":[{"type":"text","content":"First span here!"}],"finish_reason":"stop"}]', diff --git a/dev-packages/node-integration-tests/suites/tracing/vercelai/span-streaming-v6/test.ts b/dev-packages/node-integration-tests/suites/tracing/vercelai/span-streaming-v6/test.ts index 2e8ccc0c1602..68e6660524e4 100644 --- a/dev-packages/node-integration-tests/suites/tracing/vercelai/span-streaming-v6/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/vercelai/span-streaming-v6/test.ts @@ -2,7 +2,6 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from ' import { afterAll, describe, expect } from 'vitest'; import { GEN_AI_INPUT_MESSAGES_ATTRIBUTE, - GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, GEN_AI_OPERATION_NAME_ATTRIBUTE, GEN_AI_OUTPUT_MESSAGES_ATTRIBUTE, GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE, @@ -135,7 +134,6 @@ describe('Vercel AI integration (streaming, v6)', () => { name: 'invoke_agent', status: 'ok', attributes: expect.objectContaining({ - [GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]: attr(1), [GEN_AI_INPUT_MESSAGES_ATTRIBUTE]: attr('[{"role":"user","content":"Where is the first span?"}]'), [GEN_AI_OUTPUT_MESSAGES_ATTRIBUTE]: attr( '[{"role":"assistant","parts":[{"type":"text","content":"First span here!"}],"finish_reason":"stop"}]', 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 b759495545cc..1c79760227c9 100644 --- a/dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts @@ -3,7 +3,6 @@ import { afterAll, describe, expect } from 'vitest'; import { GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ATTRIBUTE, - GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, GEN_AI_OPERATION_NAME_ATTRIBUTE, GEN_AI_OUTPUT_MESSAGES_ATTRIBUTE, GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE, @@ -501,9 +500,6 @@ describe('Vercel AI integration (v4)', () => { expect(truncatedInvokeAgentSpan).toBeDefined(); expect(truncatedInvokeAgentSpan!.name).toBe('invoke_agent'); expect(truncatedInvokeAgentSpan!.attributes['sentry.op'].value).toBe('gen_ai.invoke_agent'); - expect(truncatedInvokeAgentSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE].value).toBe( - 3, - ); expect(truncatedInvokeAgentSpan!.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE].value).toMatch( /^\[.*"(?:text|content)":"C+".*\]$/, ); @@ -518,9 +514,6 @@ describe('Vercel AI integration (v4)', () => { expect(smallMessageInvokeAgentSpan).toBeDefined(); expect(smallMessageInvokeAgentSpan!.name).toBe('invoke_agent'); expect(smallMessageInvokeAgentSpan!.attributes['sentry.op'].value).toBe('gen_ai.invoke_agent'); - expect( - smallMessageInvokeAgentSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE].value, - ).toBe(3); expect(smallMessageInvokeAgentSpan!.attributes[GEN_AI_INPUT_MESSAGES_ATTRIBUTE].value).toContain( 'This is a small message that fits within the limit', ); @@ -655,7 +648,6 @@ describe('Vercel AI integration (v4)', () => { { role: 'user', content: 'Follow-up question' }, ]), ); - expect(invokeAgentSpan!.attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE].value).toBe(3); const generateContentSpan = container.items.find(span => span.name === 'generate_content mock-model-id'); expect(generateContentSpan).toBeDefined(); diff --git a/packages/core/src/server-exports.ts b/packages/core/src/server-exports.ts index 32b54720a83e..8288320bbed9 100644 --- a/packages/core/src/server-exports.ts +++ b/packages/core/src/server-exports.ts @@ -58,11 +58,7 @@ export type { // avoid shipping the AI tracing code in browser bundles. export { addVercelAiProcessors, getProviderMetadataAttributes } from './tracing/vercel-ai'; export { getTruncatedJsonString, shouldEnableTruncation, resolveAIRecordingOptions } from './tracing/ai/utils'; -export { - GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, - GEN_AI_REQUEST_MODEL_ATTRIBUTE, - GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE, -} from './tracing/ai/gen-ai-attributes'; +export { GEN_AI_REQUEST_MODEL_ATTRIBUTE, GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE } from './tracing/ai/gen-ai-attributes'; export { _INTERNAL_getSpanContextForToolCallId, _INTERNAL_cleanupToolCallSpanContext } from './tracing/vercel-ai/utils'; export { toolCallSpanContextMap as _INTERNAL_toolCallSpanContextMap } from './tracing/vercel-ai/constants'; export { diff --git a/packages/core/src/tracing/ai/gen-ai-attributes.ts b/packages/core/src/tracing/ai/gen-ai-attributes.ts index 16cdfa17b4b3..526715ac9c2f 100644 --- a/packages/core/src/tracing/ai/gen-ai-attributes.ts +++ b/packages/core/src/tracing/ai/gen-ai-attributes.ts @@ -115,11 +115,6 @@ export const GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE = 'gen_ai.usage.total_tokens'; */ export const GEN_AI_OPERATION_NAME_ATTRIBUTE = 'gen_ai.operation.name'; -/** - * Original length of messages array, used to indicate truncations had occured - */ -export const GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE = 'sentry.sdk_meta.gen_ai.input.messages.original_length'; - /** * The prompt messages * Only recorded when recordInputs is enabled diff --git a/packages/core/src/tracing/anthropic-ai/utils.ts b/packages/core/src/tracing/anthropic-ai/utils.ts index 5fbde951343f..5989247c111c 100644 --- a/packages/core/src/tracing/anthropic-ai/utils.ts +++ b/packages/core/src/tracing/anthropic-ai/utils.ts @@ -2,18 +2,13 @@ import { captureException } from '../../exports'; import { SPAN_STATUS_ERROR } from '../../tracing'; import type { Span } from '../../types/span'; import type { SpanStatusType } from '../../types/spanStatus'; -import { - GEN_AI_INPUT_MESSAGES_ATTRIBUTE, - GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, - GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE, -} from '../ai/gen-ai-attributes'; +import { GEN_AI_INPUT_MESSAGES_ATTRIBUTE, GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE } from '../ai/gen-ai-attributes'; import { extractSystemInstructions, getTruncatedJsonString } from '../ai/utils'; import { stringify } from '../../utils/string'; import type { AnthropicAiResponse } from './types'; /** - * Set the messages and messages original length attributes. - * Extracts system instructions before truncation. + * Set the input messages attribute, extracting system instructions before truncation. */ export function setMessagesAttribute(span: Span, messages: unknown, enableTruncation: boolean): void { if (Array.isArray(messages) && messages.length === 0) { @@ -28,12 +23,10 @@ export function setMessagesAttribute(span: Span, messages: unknown, enableTrunca }); } - const filteredLength = Array.isArray(filteredMessages) ? filteredMessages.length : 1; span.setAttributes({ [GEN_AI_INPUT_MESSAGES_ATTRIBUTE]: enableTruncation ? getTruncatedJsonString(filteredMessages) : stringify(filteredMessages), - [GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]: filteredLength, }); } diff --git a/packages/core/src/tracing/google-genai/index.ts b/packages/core/src/tracing/google-genai/index.ts index 68e4d414586a..1909a0903764 100644 --- a/packages/core/src/tracing/google-genai/index.ts +++ b/packages/core/src/tracing/google-genai/index.ts @@ -8,7 +8,6 @@ import { handleCallbackErrors } from '../../utils/handleCallbackErrors'; import { GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ATTRIBUTE, - GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, GEN_AI_OPERATION_NAME_ATTRIBUTE, GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE, GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE, @@ -192,9 +191,7 @@ export function addPrivateRequestAttributes( span.setAttribute(GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE, systemInstructions); } - const filteredLength = Array.isArray(filteredMessages) ? filteredMessages.length : 0; span.setAttributes({ - [GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]: filteredLength, [GEN_AI_INPUT_MESSAGES_ATTRIBUTE]: enableTruncation ? getTruncatedJsonString(filteredMessages) : stringify(filteredMessages), diff --git a/packages/core/src/tracing/langchain/utils.ts b/packages/core/src/tracing/langchain/utils.ts index 0f95464788da..db5fffa0e000 100644 --- a/packages/core/src/tracing/langchain/utils.ts +++ b/packages/core/src/tracing/langchain/utils.ts @@ -4,7 +4,6 @@ import { stringify } from '../../utils/string'; import { GEN_AI_AGENT_NAME_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ATTRIBUTE, - GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, GEN_AI_OPERATION_NAME_ATTRIBUTE, GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE, GEN_AI_REQUEST_MAX_TOKENS_ATTRIBUTE, @@ -288,7 +287,6 @@ export function extractLLMRequestAttributes( const attrs = baseRequestAttributes(system, modelName, llm, invocationParams, langSmithMetadata); if (recordInputs && Array.isArray(prompts) && prompts.length > 0) { - setIfDefined(attrs, GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, prompts.length); const messages = prompts.map(p => ({ role: 'user', content: p })); setIfDefined( attrs, @@ -331,9 +329,6 @@ export function extractChatModelRequestAttributes( setIfDefined(attrs, GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE, systemInstructions); } - const filteredLength = Array.isArray(filteredMessages) ? filteredMessages.length : 0; - setIfDefined(attrs, GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, filteredLength); - setIfDefined( attrs, GEN_AI_INPUT_MESSAGES_ATTRIBUTE, diff --git a/packages/core/src/tracing/langgraph/index.ts b/packages/core/src/tracing/langgraph/index.ts index bcbd120b38e1..ea6653e28bd1 100644 --- a/packages/core/src/tracing/langgraph/index.ts +++ b/packages/core/src/tracing/langgraph/index.ts @@ -5,7 +5,6 @@ import { GEN_AI_AGENT_NAME_ATTRIBUTE, GEN_AI_CONVERSATION_ID_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ATTRIBUTE, - GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, GEN_AI_INVOKE_AGENT_OPERATION_ATTRIBUTE, GEN_AI_OPERATION_NAME_ATTRIBUTE, GEN_AI_PIPELINE_NAME_ATTRIBUTE, @@ -224,12 +223,10 @@ export function instrumentCompiledGraphInvoke( } const enableTruncation = shouldEnableTruncation(options.enableTruncation); - const filteredLength = Array.isArray(filteredMessages) ? filteredMessages.length : 0; span.setAttributes({ [GEN_AI_INPUT_MESSAGES_ATTRIBUTE]: enableTruncation ? getTruncatedJsonString(filteredMessages) : stringify(filteredMessages), - [GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]: filteredLength, }); } diff --git a/packages/core/src/tracing/openai/index.ts b/packages/core/src/tracing/openai/index.ts index 821e9c68e0ff..c15b10856f8e 100644 --- a/packages/core/src/tracing/openai/index.ts +++ b/packages/core/src/tracing/openai/index.ts @@ -8,7 +8,6 @@ import { debug } from '../../utils/debug-logger'; import { GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ATTRIBUTE, - GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, GEN_AI_OPERATION_NAME_ATTRIBUTE, GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE, GEN_AI_REQUEST_MODEL_ATTRIBUTE, @@ -130,12 +129,6 @@ export function addRequestAttributes( GEN_AI_INPUT_MESSAGES_ATTRIBUTE, enableTruncation ? getTruncatedJsonString(filteredMessages) : stringify(filteredMessages), ); - - if (Array.isArray(filteredMessages)) { - span.setAttribute(GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, filteredMessages.length); - } else { - span.setAttribute(GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, 1); - } } /** diff --git a/packages/core/src/tracing/vercel-ai/utils.ts b/packages/core/src/tracing/vercel-ai/utils.ts index b57a43666202..d5c01f6302a8 100644 --- a/packages/core/src/tracing/vercel-ai/utils.ts +++ b/packages/core/src/tracing/vercel-ai/utils.ts @@ -2,7 +2,6 @@ import type { TraceContext } from '../../types/context'; import type { Span, SpanAttributes, SpanJSON } from '../../types/span'; import { GEN_AI_INPUT_MESSAGES_ATTRIBUTE, - GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE, GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE, GEN_AI_TOOL_DESCRIPTION_ATTRIBUTE, @@ -241,13 +240,11 @@ export function requestMessagesFromPrompt(span: Span, attributes: SpanAttributes span.setAttribute(GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE, systemInstructions); } - const filteredLength = Array.isArray(filteredMessages) ? filteredMessages.length : 0; const messagesJson = enableTruncation ? getTruncatedJsonString(filteredMessages) : stringify(filteredMessages); span.setAttributes({ [AI_PROMPT_ATTRIBUTE]: messagesJson, [GEN_AI_INPUT_MESSAGES_ATTRIBUTE]: messagesJson, - [GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]: filteredLength, }); } } else if (typeof attributes[AI_PROMPT_MESSAGES_ATTRIBUTE] === 'string') { @@ -263,8 +260,6 @@ export function requestMessagesFromPrompt(span: Span, attributes: SpanAttributes span.setAttribute(GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE, systemInstructions); } - const filteredLength = Array.isArray(filteredMessages) ? filteredMessages.length : 0; - // `extractSystemInstructions` returns the original array reference unchanged when no // system message is extracted. When truncation is also disabled, re-serializing would // reproduce the SDK's own input string, so we reuse it instead of allocating a second @@ -279,7 +274,6 @@ export function requestMessagesFromPrompt(span: Span, attributes: SpanAttributes span.setAttributes({ [AI_PROMPT_MESSAGES_ATTRIBUTE]: messagesJson, [GEN_AI_INPUT_MESSAGES_ATTRIBUTE]: messagesJson, - [GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]: filteredLength, }); } // eslint-disable-next-line no-empty diff --git a/packages/core/src/tracing/workers-ai/utils.ts b/packages/core/src/tracing/workers-ai/utils.ts index 23eac0eaa6fc..42ad16328982 100644 --- a/packages/core/src/tracing/workers-ai/utils.ts +++ b/packages/core/src/tracing/workers-ai/utils.ts @@ -15,7 +15,6 @@ import { import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../../semanticAttributes'; import type { Span, SpanAttributeValue } from '../../types/span'; import { - GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, GEN_AI_OUTPUT_MESSAGES_ATTRIBUTE, GEN_AI_REQUEST_STREAM_ATTRIBUTE, GEN_AI_RESPONSE_TEXT_ATTRIBUTE, @@ -129,11 +128,6 @@ export function addRequestAttributes( GEN_AI_INPUT_MESSAGES, enableTruncation ? getTruncatedJsonString(filteredMessages) : stringify(filteredMessages), ); - - span.setAttribute( - GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, - Array.isArray(filteredMessages) ? filteredMessages.length : 1, - ); } /** diff --git a/packages/core/test/lib/tracing/vercel-ai-request-messages.test.ts b/packages/core/test/lib/tracing/vercel-ai-request-messages.test.ts index b2230c917344..25e9ed53f1eb 100644 --- a/packages/core/test/lib/tracing/vercel-ai-request-messages.test.ts +++ b/packages/core/test/lib/tracing/vercel-ai-request-messages.test.ts @@ -3,7 +3,6 @@ import { getTruncatedJsonString } from '../../../src/tracing/ai/utils'; import { stringify } from '../../../src/utils/string'; import { GEN_AI_INPUT_MESSAGES_ATTRIBUTE, - GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE, } from '../../../src/tracing/ai/gen-ai-attributes'; import { requestMessagesFromPrompt } from '../../../src/tracing/vercel-ai/utils'; @@ -40,7 +39,6 @@ describe('requestMessagesFromPrompt (ai.prompt.messages string branch)', () => { expect(recorded[AI_PROMPT_MESSAGES_ATTRIBUTE]).toBe(original); expect(recorded[GEN_AI_INPUT_MESSAGES_ATTRIBUTE]).toBe(original); - expect(recorded[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]).toBe(1); expect(recorded[GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE]).toBeUndefined(); }); @@ -59,7 +57,6 @@ describe('requestMessagesFromPrompt (ai.prompt.messages string branch)', () => { // System message removed; output is the SDK's own serialization of just the remainder. expect(recorded[AI_PROMPT_MESSAGES_ATTRIBUTE]).toBe(stringify([{ role: 'user', content: 'hello' }])); expect(recorded[AI_PROMPT_MESSAGES_ATTRIBUTE]).not.toBe(original); - expect(recorded[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]).toBe(1); }); it('keeps the truncation path untouched when truncation is on', () => { @@ -79,7 +76,6 @@ describe('requestMessagesFromPrompt (ai.prompt.messages string branch)', () => { expect(recorded[AI_PROMPT_MESSAGES_ATTRIBUTE]).toBe(getTruncatedJsonString(messages)); expect(recorded[AI_PROMPT_MESSAGES_ATTRIBUTE]).not.toBe(original); // Original (pre-truncation) message count is still reported. - expect(recorded[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]).toBe(2); }); it('does not throw and sets no attributes for malformed JSON', () => { diff --git a/packages/core/test/lib/utils/anthropic-utils.test.ts b/packages/core/test/lib/utils/anthropic-utils.test.ts index 6880310c2064..59b6dd63fad2 100644 --- a/packages/core/test/lib/utils/anthropic-utils.test.ts +++ b/packages/core/test/lib/utils/anthropic-utils.test.ts @@ -101,7 +101,6 @@ describe('anthropic-ai-utils', () => { setMessagesAttribute(span, [{ role: 'user', content }], true); const result = [{ role: 'user', content: 'A'.repeat(19970) }]; expect(mock.attributes).toStrictEqual({ - 'sentry.sdk_meta.gen_ai.input.messages.original_length': 1, 'gen_ai.input.messages': JSON.stringify(result), }); }); @@ -109,7 +108,6 @@ describe('anthropic-ai-utils', () => { it('sets length to 1 for non-array input', () => { setMessagesAttribute(span, { content: 'hello, world' }, true); expect(mock.attributes).toStrictEqual({ - 'sentry.sdk_meta.gen_ai.input.messages.original_length': 1, 'gen_ai.input.messages': '{"content":"hello, world"}', }); }); @@ -117,7 +115,6 @@ describe('anthropic-ai-utils', () => { it('ignores empty array', () => { setMessagesAttribute(span, [], true); expect(mock.attributes).toStrictEqual({ - 'sentry.sdk_meta.gen_ai.input.messages.original_length': 1, 'gen_ai.input.messages': '{"content":"hello, world"}', }); }); diff --git a/packages/server-utils/src/vercel-ai/vercel-ai-dc-subscriber.ts b/packages/server-utils/src/vercel-ai/vercel-ai-dc-subscriber.ts index 0b9e7f39e101..bafc3b51bbd9 100644 --- a/packages/server-utils/src/vercel-ai/vercel-ai-dc-subscriber.ts +++ b/packages/server-utils/src/vercel-ai/vercel-ai-dc-subscriber.ts @@ -30,7 +30,6 @@ import type { Span, SpanAttributes } from '@sentry/core'; import { captureException, GEN_AI_CONVERSATION_ID_ATTRIBUTE, - GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE, getClient, getProviderMetadataAttributes, @@ -740,8 +739,6 @@ function buildInputMessageAttributes( const messages = event.messages ?? event.prompt; if (messages !== undefined) { attributes[GEN_AI_INPUT_MESSAGES] = enableTruncation ? getTruncatedJsonString(messages) : stringify(messages); - // The original (pre-truncation) message count, so the product can show how many were dropped. - attributes[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE] = Array.isArray(messages) ? messages.length : 1; } return attributes;