Skip to content

Commit 7f9b5e6

Browse files
committed
for you cursor
1 parent 7b731ab commit 7f9b5e6

File tree

1 file changed

+61
-15
lines changed

1 file changed

+61
-15
lines changed

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

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
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';
4-
import type { Span, SpanAttributes, SpanJSON, SpanOrigin } from '../types-hoist/span';
4+
import type { Span, SpanAttributes, SpanAttributeValue, SpanJSON, SpanOrigin } from '../types-hoist/span';
55
import { spanToJSON } from './spanUtils';
66
import type { ProviderMetadata } from './vercel-ai-attributes';
77
import {
@@ -245,32 +245,78 @@ function addProviderMetadataToAttributes(attributes: SpanAttributes): void {
245245
try {
246246
const providerMetadataObject = JSON.parse(providerMetadata) as ProviderMetadata;
247247
if (providerMetadataObject.openai) {
248-
attributes['gen_ai.usage.input_tokens.cached'] = providerMetadataObject.openai.cachedPromptTokens;
249-
attributes['gen_ai.usage.output_tokens.reasoning'] = providerMetadataObject.openai.reasoningTokens;
250-
attributes['gen_ai.usage.output_tokens.prediction_accepted'] =
251-
providerMetadataObject.openai.acceptedPredictionTokens;
252-
attributes['gen_ai.usage.output_tokens.prediction_rejected'] =
253-
providerMetadataObject.openai.rejectedPredictionTokens;
254-
attributes['gen_ai.conversation.id'] = providerMetadataObject.openai.responseId;
248+
setAttributeIfDefined(
249+
attributes,
250+
'gen_ai.usage.input_tokens.cached',
251+
providerMetadataObject.openai.cachedPromptTokens,
252+
);
253+
setAttributeIfDefined(
254+
attributes,
255+
'gen_ai.usage.output_tokens.reasoning',
256+
providerMetadataObject.openai.reasoningTokens,
257+
);
258+
setAttributeIfDefined(
259+
attributes,
260+
'gen_ai.usage.output_tokens.prediction_accepted',
261+
providerMetadataObject.openai.acceptedPredictionTokens,
262+
);
263+
setAttributeIfDefined(
264+
attributes,
265+
'gen_ai.usage.output_tokens.prediction_rejected',
266+
providerMetadataObject.openai.rejectedPredictionTokens,
267+
);
268+
setAttributeIfDefined(attributes, 'gen_ai.conversation.id', providerMetadataObject.openai.responseId);
255269
}
256270

257271
if (providerMetadataObject.anthropic) {
258-
attributes['gen_ai.usage.input_tokens.cached'] = providerMetadataObject.anthropic.cacheReadInputTokens;
259-
attributes['gen_ai.usage.input_tokens.cache_write'] = providerMetadataObject.anthropic.cacheCreationInputTokens;
272+
setAttributeIfDefined(
273+
attributes,
274+
'gen_ai.usage.input_tokens.cached',
275+
providerMetadataObject.anthropic.cacheReadInputTokens,
276+
);
277+
setAttributeIfDefined(
278+
attributes,
279+
'gen_ai.usage.input_tokens.cache_write',
280+
providerMetadataObject.anthropic.cacheCreationInputTokens,
281+
);
260282
}
261283

262284
if (providerMetadataObject.bedrock?.usage) {
263-
attributes['gen_ai.usage.input_tokens.cached'] = providerMetadataObject.bedrock.usage.cacheReadInputTokens;
264-
attributes['gen_ai.usage.input_tokens.cache_write'] =
265-
providerMetadataObject.bedrock.usage.cacheWriteInputTokens;
285+
setAttributeIfDefined(
286+
attributes,
287+
'gen_ai.usage.input_tokens.cached',
288+
providerMetadataObject.bedrock.usage.cacheReadInputTokens,
289+
);
290+
setAttributeIfDefined(
291+
attributes,
292+
'gen_ai.usage.input_tokens.cache_write',
293+
providerMetadataObject.bedrock.usage.cacheWriteInputTokens,
294+
);
266295
}
267296

268297
if (providerMetadataObject.deepseek) {
269-
attributes['gen_ai.usage.input_tokens.cached'] = providerMetadataObject.deepseek.promptCacheHitTokens;
270-
attributes['gen_ai.usage.input_tokens.cache_miss'] = providerMetadataObject.deepseek.promptCacheMissTokens;
298+
setAttributeIfDefined(
299+
attributes,
300+
'gen_ai.usage.input_tokens.cached',
301+
providerMetadataObject.deepseek.promptCacheHitTokens,
302+
);
303+
setAttributeIfDefined(
304+
attributes,
305+
'gen_ai.usage.input_tokens.cache_miss',
306+
providerMetadataObject.deepseek.promptCacheMissTokens,
307+
);
271308
}
272309
} catch {
273310
// Ignore
274311
}
275312
}
276313
}
314+
315+
/**
316+
* Sets an attribute only if the value is not null or undefined.
317+
*/
318+
function setAttributeIfDefined(attributes: SpanAttributes, key: string, value: SpanAttributeValue | undefined): void {
319+
if (value != null) {
320+
attributes[key] = value;
321+
}
322+
}

0 commit comments

Comments
 (0)