openlit 1.34.27__py3-none-any.whl → 1.34.29__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- openlit/__helpers.py +38 -0
- openlit/__init__.py +22 -155
- openlit/_instrumentors.py +144 -0
- openlit/guard/all.py +3 -3
- openlit/instrumentation/chroma/utils.py +2 -2
- openlit/instrumentation/controlflow/controlflow.py +2 -2
- openlit/instrumentation/embedchain/embedchain.py +4 -4
- openlit/instrumentation/groq/__init__.py +4 -4
- openlit/instrumentation/haystack/__init__.py +57 -28
- openlit/instrumentation/haystack/async_haystack.py +54 -0
- openlit/instrumentation/haystack/haystack.py +35 -65
- openlit/instrumentation/haystack/utils.py +377 -0
- openlit/instrumentation/julep/async_julep.py +2 -2
- openlit/instrumentation/julep/julep.py +2 -2
- openlit/instrumentation/langchain_community/utils.py +2 -2
- openlit/instrumentation/llamaindex/__init__.py +165 -37
- openlit/instrumentation/llamaindex/async_llamaindex.py +53 -0
- openlit/instrumentation/llamaindex/llamaindex.py +32 -64
- openlit/instrumentation/llamaindex/utils.py +412 -0
- openlit/instrumentation/mem0/mem0.py +2 -2
- openlit/instrumentation/openai/__init__.py +24 -24
- openlit/instrumentation/openai/utils.py +66 -27
- openlit/instrumentation/openai_agents/__init__.py +46 -26
- openlit/instrumentation/openai_agents/processor.py +600 -0
- openlit/instrumentation/pinecone/utils.py +2 -2
- openlit/instrumentation/qdrant/utils.py +2 -2
- openlit/instrumentation/together/__init__.py +8 -8
- openlit/semcov/__init__.py +80 -0
- {openlit-1.34.27.dist-info → openlit-1.34.29.dist-info}/METADATA +2 -1
- {openlit-1.34.27.dist-info → openlit-1.34.29.dist-info}/RECORD +32 -27
- openlit/instrumentation/openai_agents/openai_agents.py +0 -65
- {openlit-1.34.27.dist-info → openlit-1.34.29.dist-info}/LICENSE +0 -0
- {openlit-1.34.27.dist-info → openlit-1.34.29.dist-info}/WHEEL +0 -0
@@ -22,6 +22,14 @@ from openlit.__helpers import (
|
|
22
22
|
)
|
23
23
|
from openlit.semcov import SemanticConvention
|
24
24
|
|
25
|
+
def handle_not_given(value, default=None):
|
26
|
+
"""
|
27
|
+
Handle OpenAI's NotGiven values by converting them to appropriate defaults.
|
28
|
+
"""
|
29
|
+
if hasattr(value, '__class__') and value.__class__.__name__ == 'NotGiven':
|
30
|
+
return default
|
31
|
+
return value
|
32
|
+
|
25
33
|
def format_content(messages):
|
26
34
|
"""
|
27
35
|
Format the messages into a string for span events.
|
@@ -37,9 +45,15 @@ def format_content(messages):
|
|
37
45
|
|
38
46
|
# Handle list of messages
|
39
47
|
formatted_messages = []
|
48
|
+
|
40
49
|
for message in messages:
|
41
|
-
|
42
|
-
|
50
|
+
try:
|
51
|
+
role = message.get("role", "user") or message.role
|
52
|
+
content = message.get("content", "") or message.content
|
53
|
+
|
54
|
+
except:
|
55
|
+
role = "user"
|
56
|
+
content = str(messages)
|
43
57
|
|
44
58
|
if isinstance(content, list):
|
45
59
|
content_str_list = []
|
@@ -242,9 +256,15 @@ def common_response_logic(scope, pricing_info, environment, application_name, me
|
|
242
256
|
environment, application_name, is_stream, scope._tbt, scope._ttft, version)
|
243
257
|
|
244
258
|
# Span Attributes for Request parameters specific to responses API
|
245
|
-
scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_TEMPERATURE, scope._kwargs.get("temperature", 1.0))
|
246
|
-
scope._span.set_attribute(
|
247
|
-
|
259
|
+
scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_TEMPERATURE, handle_not_given(scope._kwargs.get("temperature"), 1.0))
|
260
|
+
scope._span.set_attribute(
|
261
|
+
SemanticConvention.GEN_AI_REQUEST_TOP_P,
|
262
|
+
handle_not_given(scope._kwargs.get("top_p"), 1.0)
|
263
|
+
)
|
264
|
+
scope._span.set_attribute(
|
265
|
+
SemanticConvention.GEN_AI_REQUEST_MAX_TOKENS,
|
266
|
+
handle_not_given(scope._kwargs.get("max_output_tokens"), -1)
|
267
|
+
)
|
248
268
|
|
249
269
|
# Reasoning parameters
|
250
270
|
reasoning = scope._kwargs.get("reasoning", {})
|
@@ -421,20 +441,30 @@ def common_chat_logic(scope, pricing_info, environment, application_name, metric
|
|
421
441
|
cost = get_chat_model_cost(request_model, pricing_info, input_tokens, output_tokens)
|
422
442
|
|
423
443
|
# Common Span Attributes
|
424
|
-
common_span_attributes(
|
425
|
-
|
426
|
-
|
427
|
-
|
444
|
+
common_span_attributes(
|
445
|
+
scope,
|
446
|
+
SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT,
|
447
|
+
SemanticConvention.GEN_AI_SYSTEM_OPENAI,
|
448
|
+
scope._server_address, scope._server_port, request_model,
|
449
|
+
scope._response_model, environment, application_name,
|
450
|
+
is_stream, scope._tbt, scope._ttft, version
|
451
|
+
)
|
428
452
|
|
429
453
|
# Span Attributes for Request parameters
|
430
|
-
scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_SEED, str(scope._kwargs.get("seed", "")))
|
431
|
-
scope._span.set_attribute(
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
scope._span.set_attribute(SemanticConvention.
|
436
|
-
scope._span.set_attribute(
|
437
|
-
|
454
|
+
scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_SEED, str(handle_not_given(scope._kwargs.get("seed"), "")))
|
455
|
+
scope._span.set_attribute(
|
456
|
+
SemanticConvention.GEN_AI_REQUEST_FREQUENCY_PENALTY,
|
457
|
+
handle_not_given(scope._kwargs.get("frequency_penalty"), 0.0)
|
458
|
+
)
|
459
|
+
scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_MAX_TOKENS, handle_not_given(scope._kwargs.get("max_tokens"), -1))
|
460
|
+
scope._span.set_attribute(
|
461
|
+
SemanticConvention.GEN_AI_REQUEST_PRESENCE_PENALTY,
|
462
|
+
handle_not_given(scope._kwargs.get("presence_penalty"), 0.0)
|
463
|
+
)
|
464
|
+
scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_STOP_SEQUENCES, handle_not_given(scope._kwargs.get("stop"), []))
|
465
|
+
scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_TEMPERATURE, handle_not_given(scope._kwargs.get("temperature"), 1.0))
|
466
|
+
scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_TOP_P, handle_not_given(scope._kwargs.get("top_p"), 1.0))
|
467
|
+
scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_USER, handle_not_given(scope._kwargs.get("user"), ""))
|
438
468
|
|
439
469
|
# Span Attributes for Response parameters
|
440
470
|
scope._span.set_attribute(SemanticConvention.GEN_AI_RESPONSE_ID, scope._response_id)
|
@@ -442,9 +472,9 @@ def common_chat_logic(scope, pricing_info, environment, application_name, metric
|
|
442
472
|
scope._span.set_attribute(SemanticConvention.GEN_AI_OUTPUT_TYPE, "text" if isinstance(scope._llmresponse, str) else "json")
|
443
473
|
|
444
474
|
# OpenAI-specific attributes
|
445
|
-
if hasattr(scope, "_system_fingerprint"):
|
475
|
+
if hasattr(scope, "_system_fingerprint") and scope._system_fingerprint:
|
446
476
|
scope._span.set_attribute(SemanticConvention.GEN_AI_RESPONSE_SYSTEM_FINGERPRINT, scope._system_fingerprint)
|
447
|
-
if hasattr(scope, "_service_tier"):
|
477
|
+
if hasattr(scope, "_service_tier") and scope._service_tier:
|
448
478
|
scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_SERVICE_TIER, scope._service_tier)
|
449
479
|
|
450
480
|
# Span Attributes for Tools - optimized
|
@@ -565,8 +595,11 @@ def common_embedding_logic(scope, request_model, pricing_info, environment, appl
|
|
565
595
|
environment, application_name, False, scope._tbt, scope._ttft, version)
|
566
596
|
|
567
597
|
# Span Attributes for Request parameters
|
568
|
-
scope._span.set_attribute(
|
569
|
-
|
598
|
+
scope._span.set_attribute(
|
599
|
+
SemanticConvention.GEN_AI_REQUEST_ENCODING_FORMATS,
|
600
|
+
[handle_not_given(scope._kwargs.get("encoding_format"), "float")]
|
601
|
+
)
|
602
|
+
scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_USER, handle_not_given(scope._kwargs.get("user"), ""))
|
570
603
|
|
571
604
|
# Span Attributes for Cost and Tokens
|
572
605
|
scope._span.set_attribute(SemanticConvention.GEN_AI_USAGE_INPUT_TOKENS, scope._input_tokens)
|
@@ -605,9 +638,12 @@ def common_image_logic(scope, request_model, pricing_info, environment, applicat
|
|
605
638
|
environment, application_name, False, scope._tbt, scope._ttft, version)
|
606
639
|
|
607
640
|
# Span Attributes for Request parameters
|
608
|
-
scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_IMAGE_SIZE, scope._kwargs.get("size", "1024x1024"))
|
609
|
-
scope._span.set_attribute(
|
610
|
-
|
641
|
+
scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_IMAGE_SIZE, handle_not_given(scope._kwargs.get("size"), "1024x1024"))
|
642
|
+
scope._span.set_attribute(
|
643
|
+
SemanticConvention.GEN_AI_REQUEST_IMAGE_QUALITY,
|
644
|
+
handle_not_given(scope._kwargs.get("quality"), "standard")
|
645
|
+
)
|
646
|
+
scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_USER, handle_not_given(scope._kwargs.get("user"), ""))
|
611
647
|
|
612
648
|
# Extract response data
|
613
649
|
response_dict = scope._response_dict
|
@@ -703,9 +739,12 @@ def common_audio_logic(scope, request_model, pricing_info, environment, applicat
|
|
703
739
|
environment, application_name, False, scope._tbt, scope._ttft, version)
|
704
740
|
|
705
741
|
# Span Attributes for Request parameters
|
706
|
-
scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_AUDIO_VOICE, scope._kwargs.get("voice", "alloy"))
|
707
|
-
scope._span.set_attribute(
|
708
|
-
|
742
|
+
scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_AUDIO_VOICE, handle_not_given(scope._kwargs.get("voice"), "alloy"))
|
743
|
+
scope._span.set_attribute(
|
744
|
+
SemanticConvention.GEN_AI_REQUEST_AUDIO_RESPONSE_FORMAT,
|
745
|
+
handle_not_given(scope._kwargs.get("response_format"), "mp3")
|
746
|
+
)
|
747
|
+
scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_AUDIO_SPEED, handle_not_given(scope._kwargs.get("speed"), 1.0))
|
709
748
|
|
710
749
|
# Span Attributes for Cost
|
711
750
|
scope._span.set_attribute(SemanticConvention.GEN_AI_USAGE_COST, cost)
|
@@ -1,42 +1,62 @@
|
|
1
|
-
"""
|
1
|
+
"""
|
2
|
+
OpenLIT OpenAI Agents Instrumentation - Native Tracing Integration
|
3
|
+
"""
|
2
4
|
|
3
5
|
from typing import Collection
|
4
6
|
import importlib.metadata
|
5
7
|
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
|
6
|
-
from wrapt import wrap_function_wrapper
|
7
8
|
|
8
|
-
from openlit.instrumentation.openai_agents.
|
9
|
-
create_agent
|
10
|
-
)
|
9
|
+
from openlit.instrumentation.openai_agents.processor import OpenLITTracingProcessor
|
11
10
|
|
12
|
-
_instruments = (
|
11
|
+
_instruments = ("openai-agents >= 0.0.3",)
|
13
12
|
|
14
13
|
class OpenAIAgentsInstrumentor(BaseInstrumentor):
|
15
|
-
"""
|
16
|
-
An instrumentor for openai-agents's client library.
|
17
|
-
"""
|
14
|
+
"""OpenLIT instrumentor for OpenAI Agents using native tracing system"""
|
18
15
|
|
19
16
|
def instrumentation_dependencies(self) -> Collection[str]:
|
20
17
|
return _instruments
|
21
18
|
|
22
19
|
def _instrument(self, **kwargs):
|
23
|
-
|
24
|
-
environment = kwargs.get(
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
disable_metrics = kwargs.get(
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
20
|
+
version = importlib.metadata.version("openai-agents")
|
21
|
+
environment = kwargs.get("environment", "default")
|
22
|
+
application_name = kwargs.get("application_name", "default")
|
23
|
+
tracer = kwargs.get("tracer")
|
24
|
+
pricing_info = kwargs.get("pricing_info", {})
|
25
|
+
capture_message_content = kwargs.get("capture_message_content", False)
|
26
|
+
metrics = kwargs.get("metrics_dict")
|
27
|
+
disable_metrics = kwargs.get("disable_metrics")
|
28
|
+
detailed_tracing = kwargs.get("detailed_tracing", False)
|
29
|
+
|
30
|
+
# Create our processor with OpenLIT enhancements
|
31
|
+
processor = OpenLITTracingProcessor(
|
32
|
+
tracer=tracer,
|
33
|
+
version=version,
|
34
|
+
environment=environment,
|
35
|
+
application_name=application_name,
|
36
|
+
pricing_info=pricing_info,
|
37
|
+
capture_message_content=capture_message_content,
|
38
|
+
metrics=metrics,
|
39
|
+
disable_metrics=disable_metrics,
|
40
|
+
detailed_tracing=detailed_tracing
|
38
41
|
)
|
39
42
|
|
43
|
+
# Integrate with OpenAI Agents' native tracing system
|
44
|
+
try:
|
45
|
+
from agents import set_trace_processors
|
46
|
+
# Replace existing processors with our enhanced processor
|
47
|
+
set_trace_processors([processor])
|
48
|
+
except ImportError:
|
49
|
+
# Fallback: Add our processor to existing ones
|
50
|
+
try:
|
51
|
+
from agents import add_trace_processor
|
52
|
+
add_trace_processor(processor)
|
53
|
+
except ImportError:
|
54
|
+
pass # Agents package may not have tracing
|
55
|
+
|
40
56
|
def _uninstrument(self, **kwargs):
|
41
|
-
#
|
42
|
-
|
57
|
+
# Clear our processors
|
58
|
+
try:
|
59
|
+
from agents import set_trace_processors
|
60
|
+
set_trace_processors([])
|
61
|
+
except ImportError:
|
62
|
+
pass
|