Skip to content

Commit 1da1eb4

Browse files
authored
feat(ai): Add missing gen_ai fields (#5246)
Adds a couple of missing gen_ai fields, sentry convetions PR will be done as a follow up. Also marked all of the fields that report token counts as `pii = maybe` just in case we change scrubbing algorithm, we don't want to filter out those values. Closes [TET-1272: Add fields containing `token` to the scrubbing exceptions in relay](https://linear.app/getsentry/issue/TET-1272/add-fields-containing-token-to-the-scrubbing-exceptions-in-relay)
1 parent e0f4ee0 commit 1da1eb4

File tree

2 files changed

+45
-12
lines changed

2 files changed

+45
-12
lines changed

relay-event-schema/src/protocol/span.rs

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ pub struct SpanData {
468468
pub app_start_type: Annotated<Value>,
469469

470470
/// The maximum number of tokens that should be used by an LLM call.
471-
#[metastructure(field = "gen_ai.request.max_tokens")]
471+
#[metastructure(field = "gen_ai.request.max_tokens", pii = "maybe")]
472472
pub gen_ai_request_max_tokens: Annotated<Value>,
473473

474474
/// Name of the AI pipeline or chain being executed.
@@ -478,36 +478,61 @@ pub struct SpanData {
478478
/// The total tokens that were used by an LLM call
479479
#[metastructure(
480480
field = "gen_ai.usage.total_tokens",
481-
legacy_alias = "ai.total_tokens.used"
481+
legacy_alias = "ai.total_tokens.used",
482+
pii = "maybe"
482483
)]
483484
pub gen_ai_usage_total_tokens: Annotated<Value>,
484485

485486
/// The input tokens used by an LLM call (usually cheaper than output tokens)
486487
#[metastructure(
487488
field = "gen_ai.usage.input_tokens",
488489
legacy_alias = "ai.prompt_tokens.used",
489-
legacy_alias = "gen_ai.usage.prompt_tokens"
490+
legacy_alias = "gen_ai.usage.prompt_tokens",
491+
pii = "maybe"
490492
)]
491493
pub gen_ai_usage_input_tokens: Annotated<Value>,
492494

493495
/// The input tokens used by an LLM call that were cached
494496
/// (cheaper and faster than non-cached input tokens)
495-
#[metastructure(field = "gen_ai.usage.input_tokens.cached")]
497+
#[metastructure(field = "gen_ai.usage.input_tokens.cached", pii = "maybe")]
496498
pub gen_ai_usage_input_tokens_cached: Annotated<Value>,
497499

500+
/// The input tokens written to cache during an LLM call
501+
#[metastructure(field = "gen_ai.usage.input_tokens.cache_write", pii = "maybe")]
502+
pub gen_ai_usage_input_tokens_cache_write: Annotated<Value>,
503+
504+
/// The input tokens that missed the cache (DeepSeek provider)
505+
#[metastructure(field = "gen_ai.usage.input_tokens.cache_miss", pii = "maybe")]
506+
pub gen_ai_usage_input_tokens_cache_miss: Annotated<Value>,
507+
498508
/// The output tokens used by an LLM call (the ones the LLM actually generated)
499509
#[metastructure(
500510
field = "gen_ai.usage.output_tokens",
501511
legacy_alias = "ai.completion_tokens.used",
502-
legacy_alias = "gen_ai.usage.completion_tokens"
512+
legacy_alias = "gen_ai.usage.completion_tokens",
513+
pii = "maybe"
503514
)]
504515
pub gen_ai_usage_output_tokens: Annotated<Value>,
505516

506517
/// The output tokens used to represent the model's internal thought
507518
/// process while generating a response
508-
#[metastructure(field = "gen_ai.usage.output_tokens.reasoning")]
519+
#[metastructure(field = "gen_ai.usage.output_tokens.reasoning", pii = "maybe")]
509520
pub gen_ai_usage_output_tokens_reasoning: Annotated<Value>,
510521

522+
/// The output tokens for accepted predictions (OpenAI provider)
523+
#[metastructure(
524+
field = "gen_ai.usage.output_tokens.prediction_accepted",
525+
pii = "maybe"
526+
)]
527+
pub gen_ai_usage_output_tokens_prediction_accepted: Annotated<Value>,
528+
529+
/// The output tokens for rejected predictions (OpenAI provider)
530+
#[metastructure(
531+
field = "gen_ai.usage.output_tokens.prediction_rejected",
532+
pii = "maybe"
533+
)]
534+
pub gen_ai_usage_output_tokens_prediction_rejected: Annotated<Value>,
535+
511536
// Exact model used to generate the response (e.g. gpt-4o-mini-2024-07-18)
512537
#[metastructure(field = "gen_ai.response.model")]
513538
pub gen_ai_response_model: Annotated<Value>,
@@ -521,15 +546,15 @@ pub struct SpanData {
521546
pub gen_ai_usage_total_cost: Annotated<Value>,
522547

523548
/// The total cost for the tokens used (duplicate field for migration)
524-
#[metastructure(field = "gen_ai.cost.total_tokens")]
549+
#[metastructure(field = "gen_ai.cost.total_tokens", pii = "maybe")]
525550
pub gen_ai_cost_total_tokens: Annotated<Value>,
526551

527552
/// The cost for input tokens used
528-
#[metastructure(field = "gen_ai.cost.input_tokens")]
553+
#[metastructure(field = "gen_ai.cost.input_tokens", pii = "maybe")]
529554
pub gen_ai_cost_input_tokens: Annotated<Value>,
530555

531556
/// The cost for output tokens used
532-
#[metastructure(field = "gen_ai.cost.output_tokens")]
557+
#[metastructure(field = "gen_ai.cost.output_tokens", pii = "maybe")]
533558
pub gen_ai_cost_output_tokens: Annotated<Value>,
534559

535560
/// Prompt passed to LLM (Vercel AI SDK)
@@ -587,7 +612,7 @@ pub struct SpanData {
587612
pub gen_ai_response_streaming: Annotated<Value>,
588613

589614
/// Total output tokens per seconds throughput
590-
#[metastructure(field = "gen_ai.response.tokens_per_second")]
615+
#[metastructure(field = "gen_ai.response.tokens_per_second", pii = "maybe")]
591616
pub gen_ai_response_tokens_per_second: Annotated<Value>,
592617

593618
/// The available tools for a request to an LLM
@@ -1444,16 +1469,20 @@ mod tests {
14441469
.unwrap()
14451470
.into_value()
14461471
.unwrap();
1447-
insta::assert_debug_snapshot!(data, @r###"
1472+
insta::assert_debug_snapshot!(data, @r#"
14481473
SpanData {
14491474
app_start_type: ~,
14501475
gen_ai_request_max_tokens: ~,
14511476
gen_ai_pipeline_name: ~,
14521477
gen_ai_usage_total_tokens: ~,
14531478
gen_ai_usage_input_tokens: ~,
14541479
gen_ai_usage_input_tokens_cached: ~,
1480+
gen_ai_usage_input_tokens_cache_write: ~,
1481+
gen_ai_usage_input_tokens_cache_miss: ~,
14551482
gen_ai_usage_output_tokens: ~,
14561483
gen_ai_usage_output_tokens_reasoning: ~,
1484+
gen_ai_usage_output_tokens_prediction_accepted: ~,
1485+
gen_ai_usage_output_tokens_prediction_rejected: ~,
14571486
gen_ai_response_model: ~,
14581487
gen_ai_request_model: ~,
14591488
gen_ai_usage_total_cost: ~,
@@ -1581,7 +1610,7 @@ mod tests {
15811610
),
15821611
},
15831612
}
1584-
"###);
1613+
"#);
15851614

15861615
assert_eq!(data.get_value("foo"), Some(Val::U64(2)));
15871616
assert_eq!(data.get_value("bar"), Some(Val::String("3")));

relay-event-schema/src/protocol/span/convert.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,12 @@ mod tests {
160160
gen_ai_usage_total_tokens: ~,
161161
gen_ai_usage_input_tokens: ~,
162162
gen_ai_usage_input_tokens_cached: ~,
163+
gen_ai_usage_input_tokens_cache_write: ~,
164+
gen_ai_usage_input_tokens_cache_miss: ~,
163165
gen_ai_usage_output_tokens: ~,
164166
gen_ai_usage_output_tokens_reasoning: ~,
167+
gen_ai_usage_output_tokens_prediction_accepted: ~,
168+
gen_ai_usage_output_tokens_prediction_rejected: ~,
165169
gen_ai_response_model: ~,
166170
gen_ai_request_model: ~,
167171
gen_ai_usage_total_cost: ~,

0 commit comments

Comments
 (0)