Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
- Use `gen_ai.function_id` as a fallback for `gen_ai.agent.name`. ([#5776](https://github.com/getsentry/relay/pull/5776))
- Add `gen_ai.input.messages` and `gen_ai.output.messages` as distinct fields for SpanData. ([#5797](https://github.com/getsentry/relay/pull/5797))
- Extract `http.query` and `url.query` attributes from `query_string` in transactions' request context. ([#5784](https://github.com/getsentry/relay/pull/5784))
- Add `ModelMetadata` config with context size and utilization. Compute `gen_ai.context.window_size` and `gen_ai.context.utilization` on AI spans. ([#5814](https://github.com/getsentry/relay/pull/5814))

**Internal**:

Expand Down
4 changes: 2 additions & 2 deletions relay-cabi/src/processing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,8 +267,8 @@ pub unsafe extern "C" fn relay_store_normalizer_normalize_event(
max_tag_value_length: usize::MAX,
span_description_rules: None,
performance_score: None,
geoip_lookup: None, // only supported in relay
ai_model_costs: None, // only supported in relay
geoip_lookup: None, // only supported in relay
ai_model_metadata: None, // only supported in relay
enable_trimming: config.enable_trimming.unwrap_or_default(),
measurements: None,
normalize_spans: config.normalize_spans,
Expand Down
2 changes: 2 additions & 0 deletions relay-conventions/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ convention_attributes!(
ENVIRONMENT => "sentry.environment",
EVENT_NAME => "event.name",
FAAS_TRIGGER => "faas.trigger",
GEN_AI_CONTEXT_UTILIZATION => "gen_ai.context.utilization",
GEN_AI_CONTEXT_WINDOW_SIZE => "gen_ai.context.window_size",
GEN_AI_COST_INPUT_TOKENS => "gen_ai.cost.input_tokens",
GEN_AI_COST_OUTPUT_TOKENS => "gen_ai.cost.output_tokens",
GEN_AI_COST_TOTAL_TOKENS => "gen_ai.cost.total_tokens",
Expand Down
47 changes: 46 additions & 1 deletion relay-dynamic-config/src/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ use std::io::BufReader;
use std::path::Path;

use relay_base_schema::metrics::MetricNamespace;
use relay_event_normalization::{MeasurementsConfig, ModelCosts, SpanOpDefaults};
use relay_event_normalization::{
MeasurementsConfig, ModelCosts, ModelMetadata, ModelMetadataEntry, SpanOpDefaults,
};
use relay_filter::GenericFiltersConfig;
use relay_quotas::Quota;
use serde::{Deserialize, Serialize, de};
Expand Down Expand Up @@ -49,6 +51,10 @@ pub struct GlobalConfig {
#[serde(skip_serializing_if = "is_model_costs_empty")]
pub ai_model_costs: ErrorBoundary<ModelCosts>,

/// Metadata for AI models including costs and context size.
#[serde(skip_serializing_if = "is_model_metadata_empty")]
pub ai_model_metadata: ErrorBoundary<ModelMetadata>,

/// Configuration to derive the `span.op` from other span fields.
#[serde(
deserialize_with = "default_on_error",
Expand All @@ -73,6 +79,41 @@ impl GlobalConfig {
}
}

/// Returns [`ModelMetadata`], preferring `ai_model_metadata` if present and falling
/// back to `ai_model_costs` (adapted to the new format) otherwise.
pub fn model_metadata(&self) -> Option<ModelMetadata> {
if let Some(metadata) = self
.ai_model_metadata
.as_ref()
.ok()
.filter(|m| m.is_enabled())
{
return Some(metadata.clone());
}

let costs = self
.ai_model_costs
.as_ref()
.ok()
.filter(|c| c.is_enabled())?;

let models = costs
.models
.iter()
.map(|(pattern, cost)| {
(
pattern.clone(),
ModelMetadataEntry {
costs: Some(*cost),
context_size: None,
},
)
})
.collect();

Some(ModelMetadata { version: 1, models })
}

/// Returns the generic inbound filters.
pub fn filters(&self) -> Option<&GenericFiltersConfig> {
match &self.filters {
Expand Down Expand Up @@ -335,6 +376,10 @@ fn is_model_costs_empty(value: &ErrorBoundary<ModelCosts>) -> bool {
matches!(value, ErrorBoundary::Ok(model_costs) if model_costs.is_empty())
}

fn is_model_metadata_empty(value: &ErrorBoundary<ModelMetadata>) -> bool {
matches!(value, ErrorBoundary::Ok(metadata) if metadata.is_empty())
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
Loading
Loading