diff --git a/javascript/sentry-conventions/src/attributes.ts b/javascript/sentry-conventions/src/attributes.ts index f5a668e7..9525a2ba 100644 --- a/javascript/sentry-conventions/src/attributes.ts +++ b/javascript/sentry-conventions/src/attributes.ts @@ -7748,6 +7748,50 @@ export const GEN_AI_CONTEXT_WINDOW_SIZE = 'gen_ai.context.window_size'; */ export type GEN_AI_CONTEXT_WINDOW_SIZE_TYPE = number; +// Path: model/attributes/gen_ai/gen_ai__conversation__compacted.json + +/** + * Indicates whether the effective conversation context used for this operation is a compacted view of a prior conversation. `gen_ai.conversation.compacted` + * + * Attribute Value Type: `boolean` {@link GEN_AI_CONVERSATION_COMPACTED_TYPE} + * + * Apply Scrubbing: manual + * + * Attribute defined in OTEL: Yes + * Visibility: public + * + * @example true + */ +export const GEN_AI_CONVERSATION_COMPACTED = 'gen_ai.conversation.compacted'; + +/** + * Type for {@link GEN_AI_CONVERSATION_COMPACTED} gen_ai.conversation.compacted + */ +export type GEN_AI_CONVERSATION_COMPACTED_TYPE = boolean; + +// Path: model/attributes/gen_ai/gen_ai__conversation__compaction__reason.json + +/** + * What triggered the compaction of the conversation context. `gen_ai.conversation.compaction.reason` + * + * Attribute Value Type: `string` {@link GEN_AI_CONVERSATION_COMPACTION_REASON_TYPE} + * + * Apply Scrubbing: manual + * + * Attribute defined in OTEL: No + * Visibility: public + * + * @example "manual" + * @example "threshold" + * @example "overflow" + */ +export const GEN_AI_CONVERSATION_COMPACTION_REASON = 'gen_ai.conversation.compaction.reason'; + +/** + * Type for {@link GEN_AI_CONVERSATION_COMPACTION_REASON} gen_ai.conversation.compaction.reason + */ +export type GEN_AI_CONVERSATION_COMPACTION_REASON_TYPE = string; + // Path: model/attributes/gen_ai/gen_ai__conversation__id.json /** @@ -8084,6 +8128,7 @@ export type GEN_AI_MEMORY_STORE_ID_TYPE = string; * * Well-defined Values: * - `chat` + * - `compact` - Compaction of the conversation context, such as summarizing earlier messages to fit the context window. Not an OpenTelemetry value. * - `create_agent` * - `create_memory` * - `create_memory_store` @@ -8127,7 +8172,7 @@ export type GEN_AI_OPERATION_NAME_TYPE = string; * - `tool` - execute_tool spans * - `handoff` - handoff spans * - `memory` - gen_ai.memory.client spans - * - `other` - input and output processors, skill loading, guardrails etc. + * - `other` - input and output processors, skill loading, guardrails, compact spans etc. * * @example "tool" */ @@ -20790,6 +20835,8 @@ export const ATTRIBUTE_TYPE: Record = { 'gen_ai.agent.name': 'string', 'gen_ai.context.utilization': 'double', 'gen_ai.context.window_size': 'integer', + 'gen_ai.conversation.compacted': 'boolean', + 'gen_ai.conversation.compaction.reason': 'string', 'gen_ai.conversation.id': 'string', 'gen_ai.cost.cache_creation.input_tokens': 'double', 'gen_ai.cost.cache_read.input_tokens': 'double', @@ -21699,6 +21746,8 @@ export type AttributeName = | typeof GEN_AI_AGENT_NAME | typeof GEN_AI_CONTEXT_UTILIZATION | typeof GEN_AI_CONTEXT_WINDOW_SIZE + | typeof GEN_AI_CONVERSATION_COMPACTED + | typeof GEN_AI_CONVERSATION_COMPACTION_REASON | typeof GEN_AI_CONVERSATION_ID | typeof GEN_AI_COST_CACHE_CREATION_INPUT_TOKENS | typeof GEN_AI_COST_CACHE_READ_INPUT_TOKENS @@ -27669,6 +27718,39 @@ export const ATTRIBUTE_METADATA: Record = { example: 128000, changelog: [{ version: '0.5.0', prs: [315], description: 'Added gen_ai.context.window_size attribute' }], }, + 'gen_ai.conversation.compacted': { + brief: + 'Indicates whether the effective conversation context used for this operation is a compacted view of a prior conversation.', + type: 'boolean', + keys: ['gen_ai.conversation.compacted'], + applyScrubbing: { + key: 'manual', + }, + isInOtel: true, + visibility: 'public', + example: true, + examples: [true], + changelog: [{ version: 'next', prs: [723], description: 'Added gen_ai.conversation.compacted attribute' }], + additionalContext: [ + 'This attribute is a positive indicator of context compaction. Instrumentations SHOULD set it to `true` only when they can reliably determine that context compaction was applied. Instrumentations SHOULD NOT set it to `false`; they SHOULD leave it unset otherwise.', + ], + }, + 'gen_ai.conversation.compaction.reason': { + brief: 'What triggered the compaction of the conversation context.', + type: 'string', + keys: ['gen_ai.conversation.compaction.reason'], + applyScrubbing: { + key: 'manual', + }, + isInOtel: false, + visibility: 'public', + example: 'manual', + examples: ['manual', 'threshold', 'overflow'], + changelog: [{ version: 'next', prs: [723], description: 'Added gen_ai.conversation.compaction.reason attribute' }], + additionalContext: [ + 'Set on the `gen_ai.compact` span. Model requests that write the compacted context are its child spans; requests that later run on the compacted context set `gen_ai.conversation.compacted`. Common values are `manual` (requested by the user), `threshold` (the context reached a configured limit) and `overflow` (recovering from a context window overflow).', + ], + }, 'gen_ai.conversation.id': { brief: 'The unique identifier for a conversation (session, thread), used to store and correlate messages within this conversation.', @@ -27933,6 +28015,7 @@ export const ATTRIBUTE_METADATA: Record = { visibility: 'public', example: 'chat', changelog: [ + { version: 'next', prs: [723], description: "Added 'compact' to the well-known values" }, { version: '0.27.0', prs: [653, 680], @@ -27955,6 +28038,7 @@ export const ATTRIBUTE_METADATA: Record = { visibility: 'public', example: 'tool', changelog: [ + { version: 'next', prs: [723], description: "Documented that compact spans map to 'other'" }, { version: '0.27.0', prs: [653], description: "Added 'memory' value" }, { version: '0.4.0', prs: [257] }, { version: '0.1.0', prs: [113, 127] }, @@ -37556,6 +37640,8 @@ export type Attributes = { [GEN_AI_AGENT_NAME]?: GEN_AI_AGENT_NAME_TYPE; [GEN_AI_CONTEXT_UTILIZATION]?: GEN_AI_CONTEXT_UTILIZATION_TYPE; [GEN_AI_CONTEXT_WINDOW_SIZE]?: GEN_AI_CONTEXT_WINDOW_SIZE_TYPE; + [GEN_AI_CONVERSATION_COMPACTED]?: GEN_AI_CONVERSATION_COMPACTED_TYPE; + [GEN_AI_CONVERSATION_COMPACTION_REASON]?: GEN_AI_CONVERSATION_COMPACTION_REASON_TYPE; [GEN_AI_CONVERSATION_ID]?: GEN_AI_CONVERSATION_ID_TYPE; [GEN_AI_COST_CACHE_CREATION_INPUT_TOKENS]?: GEN_AI_COST_CACHE_CREATION_INPUT_TOKENS_TYPE; [GEN_AI_COST_CACHE_READ_INPUT_TOKENS]?: GEN_AI_COST_CACHE_READ_INPUT_TOKENS_TYPE; diff --git a/javascript/sentry-conventions/src/op.ts b/javascript/sentry-conventions/src/op.ts index dfc3dc35..877ee681 100644 --- a/javascript/sentry-conventions/src/op.ts +++ b/javascript/sentry-conventions/src/op.ts @@ -376,6 +376,11 @@ export const GEN_AI_TEXT_COMPLETION = 'gen_ai.text_completion'; */ export const GEN_AI_MEMORY_CLIENT = 'gen_ai.memory.client'; +/** + * Compaction of a generative AI conversation's context, such as summarizing earlier messages to fit the context window. Model requests that write the summary are child spans. + */ +export const GEN_AI_COMPACT = 'gen_ai.compact'; + // Path: model/op/general.json // Name: general diff --git a/javascript/sentry-conventions/src/search.ts b/javascript/sentry-conventions/src/search.ts index 663e145e..48b014e2 100644 --- a/javascript/sentry-conventions/src/search.ts +++ b/javascript/sentry-conventions/src/search.ts @@ -1980,6 +1980,16 @@ export const SEARCH_GEN_AI__CONTEXT__UTILIZATION = 'gen_ai.context.utilization'; */ export const SEARCH_GEN_AI__CONTEXT__WINDOW_SIZE = 'gen_ai.context.window_size'; +/** + * Search name for {@link attributes.GEN_AI_CONVERSATION_COMPACTED}. `gen_ai.conversation.compacted` + */ +export const SEARCH_GEN_AI__CONVERSATION__COMPACTED = 'gen_ai.conversation.compacted'; + +/** + * Search name for {@link attributes.GEN_AI_CONVERSATION_COMPACTION_REASON}. `gen_ai.conversation.compaction.reason` + */ +export const SEARCH_GEN_AI__CONVERSATION__COMPACTION__REASON = 'gen_ai.conversation.compaction.reason'; + /** * Search name for {@link attributes.GEN_AI_CONVERSATION_ID}. `gen_ai.conversation.id` */ @@ -5605,6 +5615,8 @@ export type AttributeSearchName = | typeof SEARCH_GEN_AI__AGENT__NAME | typeof SEARCH_GEN_AI__CONTEXT__UTILIZATION | typeof SEARCH_GEN_AI__CONTEXT__WINDOW_SIZE + | typeof SEARCH_GEN_AI__CONVERSATION__COMPACTED + | typeof SEARCH_GEN_AI__CONVERSATION__COMPACTION__REASON | typeof SEARCH_GEN_AI__CONVERSATION__ID | typeof SEARCH_GEN_AI__COST__CACHE_CREATION__INPUT_TOKENS | typeof SEARCH_GEN_AI__COST__CACHE_READ__INPUT_TOKENS @@ -8422,6 +8434,19 @@ export const ATTRIBUTE_SEARCH_METADATA: Record brief: 'The maximum context window size supported by the model for this generation.', deprecationChain: ['gen_ai.context.window_size'], }, + 'gen_ai.conversation.compacted': { + canonicalName: 'gen_ai.conversation.compacted', + type: 'boolean', + brief: + 'Indicates whether the effective conversation context used for this operation is a compacted view of a prior conversation.', + deprecationChain: ['gen_ai.conversation.compacted'], + }, + 'gen_ai.conversation.compaction.reason': { + canonicalName: 'gen_ai.conversation.compaction.reason', + type: 'string', + brief: 'What triggered the compaction of the conversation context.', + deprecationChain: ['gen_ai.conversation.compaction.reason'], + }, 'gen_ai.conversation.id': { canonicalName: 'gen_ai.conversation.id', type: 'string', diff --git a/model/attributes/gen_ai/gen_ai__conversation__compacted.json b/model/attributes/gen_ai/gen_ai__conversation__compacted.json new file mode 100644 index 00000000..17def612 --- /dev/null +++ b/model/attributes/gen_ai/gen_ai__conversation__compacted.json @@ -0,0 +1,21 @@ +{ + "key": "gen_ai.conversation.compacted", + "brief": "Indicates whether the effective conversation context used for this operation is a compacted view of a prior conversation.", + "type": "boolean", + "apply_scrubbing": { + "key": "manual" + }, + "is_in_otel": true, + "visibility": "public", + "examples": [true], + "additional_context": [ + "This attribute is a positive indicator of context compaction. Instrumentations SHOULD set it to `true` only when they can reliably determine that context compaction was applied. Instrumentations SHOULD NOT set it to `false`; they SHOULD leave it unset otherwise." + ], + "changelog": [ + { + "version": "next", + "prs": [723], + "description": "Added gen_ai.conversation.compacted attribute" + } + ] +} diff --git a/model/attributes/gen_ai/gen_ai__conversation__compaction__reason.json b/model/attributes/gen_ai/gen_ai__conversation__compaction__reason.json new file mode 100644 index 00000000..2a9cf986 --- /dev/null +++ b/model/attributes/gen_ai/gen_ai__conversation__compaction__reason.json @@ -0,0 +1,21 @@ +{ + "key": "gen_ai.conversation.compaction.reason", + "brief": "What triggered the compaction of the conversation context.", + "type": "string", + "apply_scrubbing": { + "key": "manual" + }, + "is_in_otel": false, + "visibility": "public", + "examples": ["manual", "threshold", "overflow"], + "additional_context": [ + "Set on the `gen_ai.compact` span. Model requests that write the compacted context are its child spans; requests that later run on the compacted context set `gen_ai.conversation.compacted`. Common values are `manual` (requested by the user), `threshold` (the context reached a configured limit) and `overflow` (recovering from a context window overflow)." + ], + "changelog": [ + { + "version": "next", + "prs": [723], + "description": "Added gen_ai.conversation.compaction.reason attribute" + } + ] +} diff --git a/model/attributes/gen_ai/gen_ai__operation__name.json b/model/attributes/gen_ai/gen_ai__operation__name.json index 93909997..51def8bf 100644 --- a/model/attributes/gen_ai/gen_ai__operation__name.json +++ b/model/attributes/gen_ai/gen_ai__operation__name.json @@ -11,6 +11,10 @@ { "value": "chat" }, + { + "value": "compact", + "brief": "Compaction of the conversation context, such as summarizing earlier messages to fit the context window. Not an OpenTelemetry value." + }, { "value": "create_agent" }, @@ -59,6 +63,11 @@ ], "visibility": "public", "changelog": [ + { + "version": "next", + "prs": [723], + "description": "Added 'compact' to the well-known values" + }, { "version": "0.27.0", "prs": [653, 680], diff --git a/model/attributes/gen_ai/gen_ai__operation__type.json b/model/attributes/gen_ai/gen_ai__operation__type.json index 9829b089..27df5d2d 100644 --- a/model/attributes/gen_ai/gen_ai__operation__type.json +++ b/model/attributes/gen_ai/gen_ai__operation__type.json @@ -30,11 +30,16 @@ }, { "value": "other", - "brief": "input and output processors, skill loading, guardrails etc." + "brief": "input and output processors, skill loading, guardrails, compact spans etc." } ], "visibility": "public", "changelog": [ + { + "version": "next", + "prs": [723], + "description": "Documented that compact spans map to 'other'" + }, { "version": "0.27.0", "prs": [653], diff --git a/model/description/gen_ai.json b/model/description/gen_ai.json index 276d0c1d..636fce24 100644 --- a/model/description/gen_ai.json +++ b/model/description/gen_ai.json @@ -54,6 +54,13 @@ "ops": ["gen_ai.memory.client"], "templates": ["{{gen_ai.operation.name}}"], "examples": ["upsert_memory", "search_memory", "create_memory", "delete_memory"] + }, + { + "name": "Compaction", + "brief": "Generative AI conversation compaction. Compacting a conversation's context, such as summarizing earlier messages to fit the context window.", + "ops": ["gen_ai.compact"], + "templates": ["{{gen_ai.operation.name}}"], + "examples": ["compact"] } ] } diff --git a/model/name/gen_ai.json b/model/name/gen_ai.json index e998fa88..b6fe4526 100644 --- a/model/name/gen_ai.json +++ b/model/name/gen_ai.json @@ -61,6 +61,15 @@ "ops": ["gen_ai.memory.client"], "templates": ["{{gen_ai.operation.name}}", "Generative AI memory operation"], "examples": ["upsert_memory", "search_memory", "create_memory", "delete_memory"] + }, + { + "name": "Compaction", + "brief": "Generative AI conversation compaction. Compacting a conversation's context, such as summarizing earlier messages to fit the context window.", + "is_in_otel": false, + "otel_notes": "The \"gen_ai.compact\" operation is not present in OpenTelemetry.", + "ops": ["gen_ai.compact"], + "templates": ["{{gen_ai.operation.name}}", "Generative AI compaction operation"], + "examples": ["compact"] } ] } diff --git a/model/op/gen_ai.json b/model/op/gen_ai.json index cac23444..a41a6eca 100644 --- a/model/op/gen_ai.json +++ b/model/op/gen_ai.json @@ -56,6 +56,10 @@ { "name": "gen_ai.memory.client", "description": "A memory store or memory record operation performed by a generative AI agent" + }, + { + "name": "gen_ai.compact", + "description": "Compaction of a generative AI conversation's context, such as summarizing earlier messages to fit the context window. Model requests that write the summary are child spans." } ] } diff --git a/python/src/sentry_conventions/attributes.py b/python/src/sentry_conventions/attributes.py index bc1cf32c..960a87f8 100644 --- a/python/src/sentry_conventions/attributes.py +++ b/python/src/sentry_conventions/attributes.py @@ -4788,6 +4788,34 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): Example: 128000 """ + # Path: model/attributes/gen_ai/gen_ai__conversation__compacted.json + GEN_AI_CONVERSATION_COMPACTED: Literal["gen_ai.conversation.compacted"] = ( + "gen_ai.conversation.compacted" + ) + """Indicates whether the effective conversation context used for this operation is a compacted view of a prior conversation. + + Type: bool + Apply Scrubbing: manual + Defined in OTEL: Yes + Visibility: public + Example: true + """ + + # Path: model/attributes/gen_ai/gen_ai__conversation__compaction__reason.json + GEN_AI_CONVERSATION_COMPACTION_REASON: Literal[ + "gen_ai.conversation.compaction.reason" + ] = "gen_ai.conversation.compaction.reason" + """What triggered the compaction of the conversation context. + + Type: str + Apply Scrubbing: manual + Defined in OTEL: No + Visibility: public + Example: "manual" + Example: "threshold" + Example: "overflow" + """ + # Path: model/attributes/gen_ai/gen_ai__conversation__id.json GEN_AI_CONVERSATION_ID: Literal["gen_ai.conversation.id"] = "gen_ai.conversation.id" """The unique identifier for a conversation (session, thread), used to store and correlate messages within this conversation. @@ -4988,6 +5016,7 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): Visibility: public Well-defined Values: - `chat` + - `compact` - Compaction of the conversation context, such as summarizing earlier messages to fit the context window. Not an OpenTelemetry value. - `create_agent` - `create_memory` - `create_memory_store` @@ -5020,7 +5049,7 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): - `tool` - execute_tool spans - `handoff` - handoff spans - `memory` - gen_ai.memory.client spans - - `other` - input and output processors, skill loading, guardrails etc. + - `other` - input and output processors, skill loading, guardrails, compact spans etc. Example: "tool" """ @@ -18435,6 +18464,46 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): ), ], ), + "gen_ai.conversation.compacted": AttributeMetadata( + brief="Indicates whether the effective conversation context used for this operation is a compacted view of a prior conversation.", + type=AttributeType.BOOLEAN, + keys=("gen_ai.conversation.compacted",), + apply_scrubbing=ApplyScrubbingInfo(key=ApplyScrubbing.MANUAL), + is_in_otel=True, + visibility=Visibility.PUBLIC, + example=True, + examples=[True], + changelog=[ + ChangelogEntry( + version="next", + prs=[723], + description="Added gen_ai.conversation.compacted attribute", + ), + ], + additional_context=[ + "This attribute is a positive indicator of context compaction. Instrumentations SHOULD set it to `true` only when they can reliably determine that context compaction was applied. Instrumentations SHOULD NOT set it to `false`; they SHOULD leave it unset otherwise." + ], + ), + "gen_ai.conversation.compaction.reason": AttributeMetadata( + brief="What triggered the compaction of the conversation context.", + type=AttributeType.STRING, + keys=("gen_ai.conversation.compaction.reason",), + apply_scrubbing=ApplyScrubbingInfo(key=ApplyScrubbing.MANUAL), + is_in_otel=False, + visibility=Visibility.PUBLIC, + example="manual", + examples=["manual", "threshold", "overflow"], + changelog=[ + ChangelogEntry( + version="next", + prs=[723], + description="Added gen_ai.conversation.compaction.reason attribute", + ), + ], + additional_context=[ + "Set on the `gen_ai.compact` span. Model requests that write the compacted context are its child spans; requests that later run on the compacted context set `gen_ai.conversation.compacted`. Common values are `manual` (requested by the user), `threshold` (the context reached a configured limit) and `overflow` (recovering from a context window overflow)." + ], + ), "gen_ai.conversation.id": AttributeMetadata( brief="The unique identifier for a conversation (session, thread), used to store and correlate messages within this conversation.", type=AttributeType.STRING, @@ -18727,6 +18796,11 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): visibility=Visibility.PUBLIC, example="chat", changelog=[ + ChangelogEntry( + version="next", + prs=[723], + description="Added 'compact' to the well-known values", + ), ChangelogEntry( version="0.27.0", prs=[653, 680], @@ -18745,6 +18819,11 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): visibility=Visibility.PUBLIC, example="tool", changelog=[ + ChangelogEntry( + version="next", + prs=[723], + description="Documented that compact spans map to 'other'", + ), ChangelogEntry( version="0.27.0", prs=[653], description="Added 'memory' value" ), @@ -29589,6 +29668,8 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): "gen_ai.agent.name": str, "gen_ai.context.utilization": float, "gen_ai.context.window_size": int, + "gen_ai.conversation.compacted": bool, + "gen_ai.conversation.compaction.reason": str, "gen_ai.conversation.id": str, "gen_ai.cost.cache_creation.input_tokens": float, "gen_ai.cost.cache_read.input_tokens": float, diff --git a/rust/src/op.rs b/rust/src/op.rs index 01c7b6ac..ccdf6032 100644 --- a/rust/src/op.rs +++ b/rust/src/op.rs @@ -243,6 +243,9 @@ pub const GEN_AI_TEXT_COMPLETION: &str = "gen_ai.text_completion"; /// A memory store or memory record operation performed by a generative AI agent pub const GEN_AI_MEMORY_CLIENT: &str = "gen_ai.memory.client"; +/// Compaction of a generative AI conversation's context, such as summarizing earlier messages to fit the context window. Model requests that write the summary are child spans. +pub const GEN_AI_COMPACT: &str = "gen_ai.compact"; + // Path: model/op/general.json // Name: general