1- from sentry_sdk .ai .utils import (
2- get_first_from_sources ,
3- transform_message_content ,
4- )
51from sentry_sdk .consts import SPANDATA
62
73from typing import TYPE_CHECKING
84
95if TYPE_CHECKING :
10- from typing import Any , Callable , Dict , List , Optional , Sequence , Tuple
6+ from typing import Any , Dict , Sequence , Tuple
117 from typing_extensions import TypedDict
128
139 # Source paths: list of attribute chains to try in order.
@@ -32,9 +28,6 @@ class ResponseConfig(TypedDict, total=False):
3228 sources : SourceMapping
3329 # Attributes extracted only when PII sending is enabled.
3430 pii_sources : SourceMapping
35- # Custom extractor for response text (PII only).
36- # Returns list of text strings, or None.
37- extract_text : Callable [[Any ], Optional [List [str ]]]
3831 # Declarative token usage paths.
3932 usage : UsageConfig
4033
@@ -47,10 +40,6 @@ class OperationConfig(TypedDict, total=False):
4740 params : Dict [str , str ]
4841 # Maps kwarg names to SPANDATA keys (only set when PII is enabled).
4942 pii_params : Dict [str , str ]
50- # Extracts messages from kwargs for the span.
51- extract_messages : Callable [[Dict [str , Any ]], Optional [List [Dict [str , Any ]]]]
52- # SPANDATA key for messages (default: GEN_AI_REQUEST_MESSAGES).
53- message_target : str
5443 # Non-streaming response config.
5544 response : ResponseConfig
5645 # Streaming response config (different attribute paths).
@@ -60,62 +49,6 @@ class OperationConfig(TypedDict, total=False):
6049 stream_response_object : SourcePaths
6150
6251
63- # ── Helpers ──────────────────────────────────────────────────────────────────
64-
65-
66- def _normalize_embedding_input (texts ):
67- # type: (Any) -> Any
68- if isinstance (texts , list ):
69- return texts
70- if isinstance (texts , tuple ):
71- return list (texts )
72- return [texts ]
73-
74-
75- def _extract_v1_messages (kwargs ):
76- # type: (dict[str, Any]) -> list[dict[str, str]]
77- messages = []
78- for x in kwargs .get ("chat_history" , []):
79- messages .append (
80- {
81- "role" : getattr (x , "role" , "" ),
82- "content" : transform_message_content (getattr (x , "message" , "" )),
83- }
84- )
85- message = kwargs .get ("message" )
86- if message :
87- messages .append ({"role" : "user" , "content" : transform_message_content (message )})
88- return messages
89-
90-
91- def _extract_v1_response_text (response ):
92- # type: (Any) -> list[str] | None
93- text = getattr (response , "text" , None )
94- return [text ] if text is not None else None
95-
96-
97- def _extract_v2_messages (messages ):
98- # type: (Any) -> list[dict[str, Any]]
99- result = []
100- for msg in messages :
101- role = msg ["role" ] if isinstance (msg , dict ) else getattr (msg , "role" , "unknown" )
102- content = (
103- msg ["content" ] if isinstance (msg , dict ) else getattr (msg , "content" , "" )
104- )
105- result .append ({"role" : role , "content" : transform_message_content (content )})
106- return result
107-
108-
109- def _extract_v2_response_text (response ):
110- # type: (Any) -> list[str] | None
111- content = get_first_from_sources (response , [("message" , "content" )], True )
112- if content :
113- texts = [item .text for item in content if hasattr (item , "text" )]
114- if texts :
115- return texts
116- return None
117-
118-
11952# ── Configs ──────────────────────────────────────────────────────────────────
12053
12154
@@ -125,10 +58,6 @@ def _extract_v2_response_text(response):
12558 SPANDATA .GEN_AI_OPERATION_NAME : "embeddings" ,
12659 },
12760 "params" : {"model" : SPANDATA .GEN_AI_REQUEST_MODEL },
128- "extract_messages" : lambda kw : (
129- _normalize_embedding_input (kw ["texts" ]) if "texts" in kw else None
130- ),
131- "message_target" : SPANDATA .GEN_AI_EMBEDDINGS_INPUT ,
13261 "response" : {
13362 "usage" : {
13463 "input_tokens" : [("meta" , "billed_units" , "input_tokens" )],
@@ -143,7 +72,6 @@ def _extract_v2_response_text(response):
14372 SPANDATA .GEN_AI_SYSTEM : "cohere" ,
14473 SPANDATA .GEN_AI_OPERATION_NAME : "chat" ,
14574 },
146- "extract_messages" : lambda kw : _extract_v1_messages (kw ),
14775 "response" : {
14876 "sources" : {
14977 SPANDATA .GEN_AI_RESPONSE_MODEL : [("model" ,)],
@@ -153,7 +81,6 @@ def _extract_v2_response_text(response):
15381 "pii_sources" : {
15482 SPANDATA .GEN_AI_RESPONSE_TOOL_CALLS : [("tool_calls" ,)],
15583 },
156- "extract_text" : _extract_v1_response_text ,
15784 "usage" : {
15885 "input_tokens" : [
15986 ("meta" , "billed_units" , "input_tokens" ),
@@ -180,7 +107,6 @@ def _extract_v2_response_text(response):
180107 "pii_params" : {
181108 "tools" : SPANDATA .GEN_AI_REQUEST_AVAILABLE_TOOLS ,
182109 },
183- "extract_messages" : lambda kw : _extract_v2_messages (kw .get ("messages" , [])),
184110 "response" : {
185111 "sources" : {
186112 SPANDATA .GEN_AI_RESPONSE_MODEL : [("model" ,)],
@@ -190,7 +116,6 @@ def _extract_v2_response_text(response):
190116 "pii_sources" : {
191117 SPANDATA .GEN_AI_RESPONSE_TOOL_CALLS : [("message" , "tool_calls" )],
192118 },
193- "extract_text" : _extract_v2_response_text ,
194119 "usage" : {
195120 "input_tokens" : [
196121 ("usage" , "billed_units" , "input_tokens" ),
0 commit comments