Skip to content

Commit 0d87458

Browse files
.
1 parent 1d05771 commit 0d87458

2 files changed

Lines changed: 95 additions & 42 deletions

File tree

sentry_sdk/integrations/langchain.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,6 @@ def _create_span(
302302
origin: str,
303303
) -> "WatchedSpan":
304304
watched_span: "Optional[WatchedSpan]" = None
305-
span_streaming = has_span_streaming_enabled(sentry_sdk.get_client().options)
306305
if parent_id:
307306
parent_span: "Optional[WatchedSpan]" = self.span_map.get(parent_id)
308307
if parent_span:
@@ -317,14 +316,15 @@ def _create_span(
317316
},
318317
)
319318
)
320-
if span_streaming
319+
if isinstance(parent_span, StreamedSpan)
321320
else WatchedSpan(
322321
parent_span.span.start_child(op=op, name=name, origin=origin)
323322
)
324323
)
325324
parent_span.children.append(watched_span)
326325

327326
if watched_span is None:
327+
span_streaming = has_span_streaming_enabled(sentry_sdk.get_client().options)
328328
watched_span = (
329329
WatchedSpan(
330330
sentry_sdk.traces.start_span(
@@ -933,7 +933,7 @@ def _simplify_langchain_tools(tools: "Any") -> "Optional[List[Any]]":
933933
return simplified_tools if simplified_tools else None
934934

935935

936-
def _set_tools_on_span(span: "Span", tools: "Any") -> None:
936+
def _set_tools_on_span(span: "Union[Span, StreamedSpan]", tools: "Any") -> None:
937937
"""Set available tools data on a span if tools are provided."""
938938
if tools is not None:
939939
simplified_tools = _simplify_langchain_tools(tools)

sentry_sdk/integrations/langgraph.py

Lines changed: 92 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from sentry_sdk.consts import OP, SPANDATA
1212
from sentry_sdk.integrations import DidNotEnable, Integration
1313
from sentry_sdk.scope import should_send_default_pii
14+
from sentry_sdk.tracing_utils import has_span_streaming_enabled
1415
from sentry_sdk.utils import safe_serialize
1516

1617
try:
@@ -151,7 +152,8 @@ def new_compile(self: "Any", *args: "Any", **kwargs: "Any") -> "Any":
151152
def _wrap_pregel_invoke(f: "Callable[..., Any]") -> "Callable[..., Any]":
152153
@wraps(f)
153154
def new_invoke(self: "Any", *args: "Any", **kwargs: "Any") -> "Any":
154-
integration = sentry_sdk.get_client().get_integration(LanggraphIntegration)
155+
client = sentry_sdk.get_client()
156+
integration = client.get_integration(LanggraphIntegration)
155157
if integration is None:
156158
return f(self, *args, **kwargs)
157159

@@ -160,50 +162,101 @@ def new_invoke(self: "Any", *args: "Any", **kwargs: "Any") -> "Any":
160162
f"invoke_agent {graph_name}".strip() if graph_name else "invoke_agent"
161163
)
162164

163-
with get_start_span_function()(
164-
op=OP.GEN_AI_INVOKE_AGENT,
165-
name=span_name,
166-
origin=LanggraphIntegration.origin,
167-
) as span:
168-
if graph_name:
169-
span.set_data(SPANDATA.GEN_AI_PIPELINE_NAME, graph_name)
170-
span.set_data(SPANDATA.GEN_AI_AGENT_NAME, graph_name)
171-
172-
span.set_data(SPANDATA.GEN_AI_OPERATION_NAME, "invoke_agent")
173-
174-
# Store input messages to later compare with output
175-
input_messages = None
176-
if (
177-
len(args) > 0
178-
and should_send_default_pii()
179-
and integration.include_prompts
180-
):
181-
input_messages = _parse_langgraph_messages(args[0])
182-
if input_messages:
183-
normalized_input_messages = normalize_message_roles(input_messages)
165+
if has_span_streaming_enabled(client.options):
166+
with sentry_sdk.traces.start_span(
167+
name=span_name,
168+
attributes={
169+
"sentry.op": OP.GEN_AI_INVOKE_AGENT,
170+
"sentry.origin": LanggraphIntegration.origin,
171+
SPANDATA.GEN_AI_OPERATION_NAME: "invoke_agent",
172+
},
173+
) as span:
174+
if graph_name:
175+
span.set_attribute(SPANDATA.GEN_AI_PIPELINE_NAME, graph_name)
176+
span.set_attribute(SPANDATA.GEN_AI_AGENT_NAME, graph_name)
177+
178+
# Store input messages to later compare with output
179+
input_messages = None
180+
if (
181+
len(args) > 0
182+
and should_send_default_pii()
183+
and integration.include_prompts
184+
):
185+
input_messages = _parse_langgraph_messages(args[0])
186+
if input_messages:
187+
normalized_input_messages = normalize_message_roles(
188+
input_messages
189+
)
184190

185-
client = sentry_sdk.get_client()
186-
scope = sentry_sdk.get_current_scope()
187-
messages_data = (
188-
normalized_input_messages
189-
if client.options.get("stream_gen_ai_spans", False)
190-
else truncate_and_annotate_messages(
191-
normalized_input_messages, span, scope
191+
client = sentry_sdk.get_client()
192+
scope = sentry_sdk.get_current_scope()
193+
messages_data = (
194+
normalized_input_messages
195+
if client.options.get("stream_gen_ai_spans", False)
196+
else truncate_and_annotate_messages(
197+
normalized_input_messages, span, scope
198+
)
192199
)
193-
)
194-
if messages_data is not None:
195-
set_data_normalized(
196-
span,
197-
SPANDATA.GEN_AI_REQUEST_MESSAGES,
198-
messages_data,
199-
unpack=False,
200+
if messages_data is not None:
201+
set_data_normalized(
202+
span,
203+
SPANDATA.GEN_AI_REQUEST_MESSAGES,
204+
messages_data,
205+
unpack=False,
206+
)
207+
208+
result = f(self, *args, **kwargs)
209+
210+
_set_response_attributes(span, input_messages, result, integration)
211+
212+
return result
213+
else:
214+
with get_start_span_function()(
215+
op=OP.GEN_AI_INVOKE_AGENT,
216+
name=span_name,
217+
origin=LanggraphIntegration.origin,
218+
) as span:
219+
if graph_name:
220+
span.set_data(SPANDATA.GEN_AI_PIPELINE_NAME, graph_name)
221+
span.set_data(SPANDATA.GEN_AI_AGENT_NAME, graph_name)
222+
223+
span.set_data(SPANDATA.GEN_AI_OPERATION_NAME, "invoke_agent")
224+
225+
# Store input messages to later compare with output
226+
input_messages = None
227+
if (
228+
len(args) > 0
229+
and should_send_default_pii()
230+
and integration.include_prompts
231+
):
232+
input_messages = _parse_langgraph_messages(args[0])
233+
if input_messages:
234+
normalized_input_messages = normalize_message_roles(
235+
input_messages
200236
)
201237

202-
result = f(self, *args, **kwargs)
238+
client = sentry_sdk.get_client()
239+
scope = sentry_sdk.get_current_scope()
240+
messages_data = (
241+
normalized_input_messages
242+
if client.options.get("stream_gen_ai_spans", False)
243+
else truncate_and_annotate_messages(
244+
normalized_input_messages, span, scope
245+
)
246+
)
247+
if messages_data is not None:
248+
set_data_normalized(
249+
span,
250+
SPANDATA.GEN_AI_REQUEST_MESSAGES,
251+
messages_data,
252+
unpack=False,
253+
)
203254

204-
_set_response_attributes(span, input_messages, result, integration)
255+
result = f(self, *args, **kwargs)
205256

206-
return result
257+
_set_response_attributes(span, input_messages, result, integration)
258+
259+
return result
207260

208261
return new_invoke
209262

0 commit comments

Comments
 (0)