Skip to content

Commit 92ecc88

Browse files
merge
2 parents 4aed172 + a6152fe commit 92ecc88

2 files changed

Lines changed: 1175 additions & 434 deletions

File tree

sentry_sdk/integrations/openai.py

Lines changed: 89 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import sys
22
from functools import wraps
3+
from collections.abc import Iterable
34

45
import sentry_sdk
56
from sentry_sdk import consts
@@ -32,7 +33,6 @@
3233
AsyncIterator,
3334
Iterator,
3435
Union,
35-
Iterable,
3636
)
3737
from sentry_sdk.tracing import Span
3838
from sentry_sdk._types import TextPart
@@ -206,37 +206,31 @@ def _is_system_instruction_completions(message: "ChatCompletionMessageParam") ->
206206

207207
def _get_system_instructions_completions(
208208
messages: "Iterable[ChatCompletionMessageParam]",
209-
) -> "list[ChatCompletionSystemMessageParam]":
210-
system_instructions = []
211-
212-
for message in messages:
213-
if _is_system_instruction_completions(message):
214-
system_instructions.append(message)
209+
) -> "list[ChatCompletionMessageParam]":
210+
if not isinstance(messages, Iterable):
211+
return []
215212

216-
return system_instructions
213+
return [
214+
message for message in messages if _is_system_instruction_completions(message)
215+
]
217216

218217

219218
def _is_system_instruction_responses(message: "ResponseInputItemParam") -> bool:
220-
return (
221-
isinstance(message, dict)
222-
and message.get("type") == "message"
223-
and message.get("role") == "system"
224-
)
219+
if not isinstance(message, dict) or not message.get("role") == "system":
220+
return False
221+
222+
return "type" not in message or message["type"] == "message"
225223

226224

227225
def _get_system_instructions_responses(
228226
messages: "Union[str, ResponseInputParam]",
229227
) -> "list[ResponseInputItemParam]":
230-
if isinstance(messages, str):
228+
if not isinstance(messages, list):
231229
return []
232230

233-
system_instructions = []
234-
235-
for message in messages:
236-
if _is_system_instruction_responses(message):
237-
system_instructions.append(message)
238-
239-
return system_instructions
231+
return [
232+
message for message in messages if _is_system_instruction_responses(message)
233+
]
240234

241235

242236
def _transform_system_instructions(
@@ -313,47 +307,63 @@ def _set_responses_api_input_data(
313307
kwargs: "dict[str, Any]",
314308
integration: "OpenAIIntegration",
315309
) -> None:
310+
explicit_instructions: "Union[Optional[str], Omit]" = kwargs.get("instructions")
316311
messages: "Optional[Union[str, ResponseInputParam]]" = kwargs.get("input")
317312

318-
if messages is None:
313+
if not should_send_default_pii() or not integration.include_prompts:
319314
set_data_normalized(span, SPANDATA.GEN_AI_OPERATION_NAME, "responses")
320315
_commmon_set_input_data(span, kwargs)
321316
return
322317

323-
explicit_instructions: "Union[Optional[str], Omit]" = kwargs.get("instructions")
324-
system_instructions = _get_system_instructions_responses(messages)
325318
if (
326-
(
327-
(explicit_instructions is not None and _is_given(explicit_instructions))
328-
or len(system_instructions) > 0
329-
)
330-
and should_send_default_pii()
331-
and integration.include_prompts
319+
messages is None
320+
and explicit_instructions is not None
321+
and _is_given(explicit_instructions)
332322
):
333-
instructions_text_parts: "list[TextPart]" = []
334-
if explicit_instructions is not None and _is_given(explicit_instructions):
335-
instructions_text_parts.append(
323+
set_data_normalized(
324+
span,
325+
SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS,
326+
[
336327
{
337328
"type": "text",
338329
"content": explicit_instructions,
339330
}
340-
)
341-
# Deliberate use of function accepting completions API type because
342-
# of shared structure FOR THIS PURPOSE ONLY.
343-
instructions_text_parts += _transform_system_instructions(system_instructions)
331+
],
332+
unpack=False,
333+
)
334+
335+
set_data_normalized(span, SPANDATA.GEN_AI_OPERATION_NAME, "responses")
336+
_commmon_set_input_data(span, kwargs)
337+
return
344338

339+
if messages is None:
340+
set_data_normalized(span, SPANDATA.GEN_AI_OPERATION_NAME, "responses")
341+
_commmon_set_input_data(span, kwargs)
342+
return
343+
344+
instructions_text_parts: "list[TextPart]" = []
345+
if explicit_instructions is not None and _is_given(explicit_instructions):
346+
instructions_text_parts.append(
347+
{
348+
"type": "text",
349+
"content": explicit_instructions,
350+
}
351+
)
352+
353+
system_instructions = _get_system_instructions_responses(messages)
354+
# Deliberate use of function accepting completions API type because
355+
# of shared structure FOR THIS PURPOSE ONLY.
356+
instructions_text_parts += _transform_system_instructions(system_instructions)
357+
358+
if len(instructions_text_parts) > 0:
345359
set_data_normalized(
346360
span,
347361
SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS,
348362
instructions_text_parts,
349363
unpack=False,
350364
)
351365

352-
if (
353-
isinstance(messages, str)
354-
and should_send_default_pii()
355-
and integration.include_prompts
356-
):
366+
if isinstance(messages, str):
357367
normalized_messages = normalize_message_roles([messages]) # type: ignore
358368
scope = sentry_sdk.get_current_scope()
359369
messages_data = truncate_and_annotate_messages(normalized_messages, span, scope)
@@ -362,22 +372,21 @@ def _set_responses_api_input_data(
362372
span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data, unpack=False
363373
)
364374

365-
elif should_send_default_pii() and integration.include_prompts:
366-
non_system_messages = [
367-
message
368-
for message in messages
369-
if not _is_system_instruction_responses(message)
370-
]
371-
if len(non_system_messages) > 0:
372-
normalized_messages = normalize_message_roles(non_system_messages) # type: ignore
373-
scope = sentry_sdk.get_current_scope()
374-
messages_data = truncate_and_annotate_messages(
375-
normalized_messages, span, scope
375+
set_data_normalized(span, SPANDATA.GEN_AI_OPERATION_NAME, "responses")
376+
_commmon_set_input_data(span, kwargs)
377+
return
378+
379+
non_system_messages = [
380+
message for message in messages if not _is_system_instruction_responses(message)
381+
]
382+
if len(non_system_messages) > 0:
383+
normalized_messages = normalize_message_roles(non_system_messages)
384+
scope = sentry_sdk.get_current_scope()
385+
messages_data = truncate_and_annotate_messages(normalized_messages, span, scope)
386+
if messages_data is not None:
387+
set_data_normalized(
388+
span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data, unpack=False
376389
)
377-
if messages_data is not None:
378-
set_data_normalized(
379-
span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data, unpack=False
380-
)
381390

382391
set_data_normalized(span, SPANDATA.GEN_AI_OPERATION_NAME, "responses")
383392
_commmon_set_input_data(span, kwargs)
@@ -392,52 +401,50 @@ def _set_completions_api_input_data(
392401
"messages"
393402
)
394403

404+
if not should_send_default_pii() or not integration.include_prompts:
405+
set_data_normalized(span, SPANDATA.GEN_AI_OPERATION_NAME, "responses")
406+
_commmon_set_input_data(span, kwargs)
407+
return
408+
395409
if messages is None:
396410
set_data_normalized(span, SPANDATA.GEN_AI_OPERATION_NAME, "chat")
397411
_commmon_set_input_data(span, kwargs)
398412
return
399413

400414
system_instructions = _get_system_instructions_completions(messages)
401-
if (
402-
len(system_instructions) > 0
403-
and should_send_default_pii()
404-
and integration.include_prompts
405-
):
415+
if len(system_instructions) > 0:
406416
set_data_normalized(
407417
span,
408418
SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS,
409419
_transform_system_instructions(system_instructions),
410420
unpack=False,
411421
)
412422

413-
if (
414-
isinstance(messages, str)
415-
and should_send_default_pii()
416-
and integration.include_prompts
417-
):
423+
if isinstance(messages, str):
418424
normalized_messages = normalize_message_roles([messages]) # type: ignore
419425
scope = sentry_sdk.get_current_scope()
420426
messages_data = truncate_and_annotate_messages(normalized_messages, span, scope)
421427
if messages_data is not None:
422428
set_data_normalized(
423429
span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data, unpack=False
424430
)
425-
elif should_send_default_pii() and integration.include_prompts:
426-
non_system_messages = [
427-
message
428-
for message in messages
429-
if not _is_system_instruction_completions(message)
430-
]
431-
if len(non_system_messages) > 0:
432-
normalized_messages = normalize_message_roles(non_system_messages) # type: ignore
433-
scope = sentry_sdk.get_current_scope()
434-
messages_data = truncate_and_annotate_messages(
435-
normalized_messages, span, scope
431+
set_data_normalized(span, SPANDATA.GEN_AI_OPERATION_NAME, "chat")
432+
_commmon_set_input_data(span, kwargs)
433+
return
434+
435+
non_system_messages = [
436+
message
437+
for message in messages
438+
if not _is_system_instruction_completions(message)
439+
]
440+
if len(non_system_messages) > 0:
441+
normalized_messages = normalize_message_roles(non_system_messages) # type: ignore
442+
scope = sentry_sdk.get_current_scope()
443+
messages_data = truncate_and_annotate_messages(normalized_messages, span, scope)
444+
if messages_data is not None:
445+
set_data_normalized(
446+
span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data, unpack=False
436447
)
437-
if messages_data is not None:
438-
set_data_normalized(
439-
span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages_data, unpack=False
440-
)
441448

442449
set_data_normalized(span, SPANDATA.GEN_AI_OPERATION_NAME, "chat")
443450
_commmon_set_input_data(span, kwargs)

0 commit comments

Comments
 (0)