Skip to content

Commit a6bcceb

Browse files
committed
fix(core): Fix and add cache attributes in Vercel AI
1 parent 2e652f3 commit a6bcceb

File tree

3 files changed

+52
-14
lines changed

3 files changed

+52
-14
lines changed

packages/core/src/utils/ai/gen-ai-attributes.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,16 @@ export const GEN_AI_RESPONSE_STREAMING_ATTRIBUTE = 'gen_ai.response.streaming';
129129
*/
130130
export const GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE = 'gen_ai.response.tool_calls';
131131

132+
/**
133+
* The number of cache write input tokens used
134+
*/
135+
export const GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE = 'gen_ai.usage.input_tokens.cache_write';
136+
137+
/**
138+
* The number of cached input tokens that were used
139+
*/
140+
export const GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE = 'gen_ai.usage.input_tokens.cached';
141+
132142
// =============================================================================
133143
// OPENAI-SPECIFIC ATTRIBUTES
134144
// =============================================================================

packages/core/src/utils/vercel-ai/index.ts

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ import type { Client } from '../../client';
22
import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../../semanticAttributes';
33
import type { Event } from '../../types-hoist/event';
44
import type { Span, SpanAttributes, SpanAttributeValue, SpanJSON, SpanOrigin } from '../../types-hoist/span';
5+
import {
6+
GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE,
7+
GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE,
8+
} from '../ai/gen-ai-attributes';
59
import { spanToJSON } from '../spanUtils';
610
import { toolCallSpanMap } from './constants';
711
import type { TokenSummary } from './types';
@@ -23,6 +27,7 @@ import {
2327
AI_TOOL_CALL_ID_ATTRIBUTE,
2428
AI_TOOL_CALL_NAME_ATTRIBUTE,
2529
AI_TOOL_CALL_RESULT_ATTRIBUTE,
30+
AI_USAGE_CACHED_INPUT_TOKENS_ATTRIBUTE,
2631
AI_USAGE_COMPLETION_TOKENS_ATTRIBUTE,
2732
AI_USAGE_PROMPT_TOKENS_ATTRIBUTE,
2833
GEN_AI_RESPONSE_MODEL_ATTRIBUTE,
@@ -107,6 +112,7 @@ function processEndedVercelAiSpan(span: SpanJSON): void {
107112

108113
renameAttributeKey(attributes, AI_USAGE_COMPLETION_TOKENS_ATTRIBUTE, GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE);
109114
renameAttributeKey(attributes, AI_USAGE_PROMPT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE);
115+
renameAttributeKey(attributes, AI_USAGE_CACHED_INPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE);
110116

111117
if (
112118
typeof attributes[GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE] === 'number' &&
@@ -287,7 +293,7 @@ function addProviderMetadataToAttributes(attributes: SpanAttributes): void {
287293
if (providerMetadataObject.openai) {
288294
setAttributeIfDefined(
289295
attributes,
290-
'gen_ai.usage.input_tokens.cached',
296+
GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE,
291297
providerMetadataObject.openai.cachedPromptTokens,
292298
);
293299
setAttributeIfDefined(
@@ -309,35 +315,34 @@ function addProviderMetadataToAttributes(attributes: SpanAttributes): void {
309315
}
310316

311317
if (providerMetadataObject.anthropic) {
312-
setAttributeIfDefined(
313-
attributes,
314-
'gen_ai.usage.input_tokens.cached',
315-
providerMetadataObject.anthropic.cacheReadInputTokens,
316-
);
317-
setAttributeIfDefined(
318-
attributes,
319-
'gen_ai.usage.input_tokens.cache_write',
320-
providerMetadataObject.anthropic.cacheCreationInputTokens,
321-
);
318+
const cachedInputTokens =
319+
providerMetadataObject.anthropic.usage?.cache_read_input_tokens ??
320+
providerMetadataObject.anthropic.cacheCreationInputTokens;
321+
setAttributeIfDefined(attributes, GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE, cachedInputTokens);
322+
323+
const cacheWriteInputTokens =
324+
providerMetadataObject.anthropic.usage?.cache_creation_input_tokens ??
325+
providerMetadataObject.anthropic.cacheCreationInputTokens;
326+
setAttributeIfDefined(attributes, GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE, cacheWriteInputTokens);
322327
}
323328

324329
if (providerMetadataObject.bedrock?.usage) {
325330
setAttributeIfDefined(
326331
attributes,
327-
'gen_ai.usage.input_tokens.cached',
332+
GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE,
328333
providerMetadataObject.bedrock.usage.cacheReadInputTokens,
329334
);
330335
setAttributeIfDefined(
331336
attributes,
332-
'gen_ai.usage.input_tokens.cache_write',
337+
GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE,
333338
providerMetadataObject.bedrock.usage.cacheWriteInputTokens,
334339
);
335340
}
336341

337342
if (providerMetadataObject.deepseek) {
338343
setAttributeIfDefined(
339344
attributes,
340-
'gen_ai.usage.input_tokens.cached',
345+
GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE,
341346
providerMetadataObject.deepseek.promptCacheHitTokens,
342347
);
343348
setAttributeIfDefined(

packages/core/src/utils/vercel-ai/vercel-ai-attributes.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,14 @@ export const AI_RESPONSE_PROVIDER_METADATA_ATTRIBUTE = 'ai.response.providerMeta
288288
*/
289289
export const AI_SETTINGS_MAX_RETRIES_ATTRIBUTE = 'ai.settings.maxRetries';
290290

291+
/**
292+
* Basic LLM span information
293+
* Multiple spans
294+
*
295+
* The number of cached input tokens that were used
296+
* @see https://ai-sdk.dev/docs/ai-sdk-core/telemetry#basic-llm-span-information
297+
*/
298+
export const AI_USAGE_CACHED_INPUT_TOKENS_ATTRIBUTE = 'ai.usage.cachedInputTokens';
291299
/**
292300
* Basic LLM span information
293301
* Multiple spans
@@ -863,6 +871,21 @@ interface AnthropicProviderMetadata {
863871
* @see https://ai-sdk.dev/providers/ai-sdk-providers/anthropic#cache-control
864872
*/
865873
cacheReadInputTokens?: number;
874+
875+
/**
876+
* Usage metrics for the Anthropic model.
877+
*/
878+
usage?: {
879+
input_tokens: number;
880+
cache_creation_input_tokens?: number;
881+
cache_read_input_tokens?: number;
882+
cache_creation?: {
883+
ephemeral_5m_input_tokens?: number;
884+
ephemeral_1h_input_tokens?: number;
885+
};
886+
output_tokens?: number;
887+
service_tier?: string;
888+
};
866889
}
867890

868891
/**

0 commit comments

Comments
 (0)