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 @@ -4,6 +4,7 @@

**Features**:

- Transform deprecated `gen_ai.request.messages`, `gen_ai.response.text`, and `gen_ai.response.tool_calls` attributes into their normalized replacements (`gen_ai.input.messages` and `gen_ai.output.messages`). ([#6201](https://github.com/getsentry/relay/pull/6201))
- Infer span descriptions via `sentry-conventions`. ([#6093](https://github.com/getsentry/relay/pull/6093))
- Raises the size limit for the flags context to 64KiB. ([#6137](https://github.com/getsentry/relay/pull/6137))
- Add segment_names field to Replay events. ([#6134](https://github.com/getsentry/relay/pull/6134))
Expand Down
11 changes: 11 additions & 0 deletions relay-conventions/build/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ pub enum DeprecationStatus {
Backfill,
/// Only write the replacement name.
Normalize,
/// Move the value to the replacement name and apply a value transformation.
///
/// For write behavior purposes, this produces `CurrentName` — the generic attribute
/// renaming logic leaves these attributes alone. Dedicated transformation code handles
/// the full move-and-reshape.
Transform,
}

/// Information about an attribute's deprecation.
Expand Down Expand Up @@ -126,6 +132,11 @@ fn format_write_behavior(deprecation: Option<&Deprecation>) -> String {
DeprecationStatus::Normalize => {
format!("WriteBehavior::NewName({name})")
}
DeprecationStatus::Transform => {
// Transformations are handled by dedicated code, not by the generic
// attribute renaming logic. Leave the attribute at its current name.
"WriteBehavior::CurrentName".to_owned()
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion relay-conventions/sentry-conventions
Submodule sentry-conventions updated 30 files
+0 −1 .github/workflows/changelog-preview.yml
+6 −0 CHANGELOG.md
+23 −0 CONTRIBUTING.md
+2 −1 docs/src/content.config.ts
+3 −0 javascript/sentry-conventions/attributes.d.ts
+3 −0 javascript/sentry-conventions/attributes.js
+3 −0 javascript/sentry-conventions/op.d.ts
+3 −0 javascript/sentry-conventions/op.js
+6 −2 javascript/sentry-conventions/package.json
+272 −6 javascript/sentry-conventions/src/attributes.ts
+64 −0 model/attribute_transformations/gen_ai_request_messages_to_input_messages.json
+80 −0 model/attribute_transformations/gen_ai_response_to_output_messages.json
+18 −0 model/attributes/db/db__response__status_code.json
+23 −0 model/attributes/gen_ai/gen_ai__cost__cache_creation__input_tokens.json
+23 −0 model/attributes/gen_ai/gen_ai__cost__cache_read__input_tokens.json
+2 −2 model/attributes/gen_ai/gen_ai__cost__input_tokens.json
+2 −2 model/attributes/gen_ai/gen_ai__cost__output_tokens.json
+23 −0 model/attributes/gen_ai/gen_ai__cost__reasoning__output_tokens.json
+3 −2 model/attributes/gen_ai/gen_ai__request__messages.json
+4 −3 model/attributes/gen_ai/gen_ai__response__text.json
+3 −2 model/attributes/gen_ai/gen_ai__response__tool_calls.json
+1 −1 python/pyproject.toml
+145 −9 python/src/sentry_conventions/attributes.py
+250 −250 python/uv.lock
+21 −3 schemas/attribute.schema.json
+84 −0 schemas/attribute_transformation.schema.json
+36 −4 scripts/generate_attributes.ts
+22 −1 scripts/types.ts
+132 −0 test/attribute-transformations.test.ts
+742 −88 yarn.lock
2 changes: 2 additions & 0 deletions relay-event-normalization/src/eap/ai.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use relay_event_schema::protocol::Attributes;
use relay_protocol::Annotated;

use crate::ModelMetadata;
use crate::eap::gen_ai_transform;
use crate::span::ai;
use crate::statsd::{Counters, map_origin_to_integration, platform_tag};

Expand Down Expand Up @@ -34,6 +35,7 @@ pub fn normalize_ai(
return;
}

gen_ai_transform::transform_gen_ai(attributes);
normalize_model(attributes);
normalize_ai_type(attributes);
normalize_total_tokens(attributes);
Comment on lines 35 to 41

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Deprecated AI attributes are not transformed if the span lacks an operation attribute, as the normalize_ai function is skipped, leading to data loss.
Severity: LOW

Suggested Fix

The transformation logic should be moved to a place where it can handle these legacy attributes unconditionally, or the is_ai_item() guard should be updated to also check for the presence of deprecated AI attributes to ensure they are always processed.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: relay-event-normalization/src/eap/ai.rs#L35-L41

Potential issue: The removal of `legacy_alias` for keys like `gen_ai.request.messages`
means they are no longer automatically remapped. The transformation now occurs in
`normalize_ai`, which is guarded by the `is_ai_item()` check. This check requires an
operation attribute like `gen_ai.operation.name` or a specific `sentry.op`. If a span
contains only deprecated AI attributes without these operation indicators,
`is_ai_item()` will return `false`, `normalize_ai` will be skipped, and the data under
the deprecated keys will be lost as it is never converted to its canonical form.

Expand Down
Loading