openlit 1.34.29__py3-none-any.whl → 1.34.31__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 +235 -86
- openlit/__init__.py +16 -13
- openlit/_instrumentors.py +2 -1
- openlit/evals/all.py +50 -21
- openlit/evals/bias_detection.py +47 -20
- openlit/evals/hallucination.py +53 -22
- openlit/evals/toxicity.py +50 -21
- openlit/evals/utils.py +54 -30
- openlit/guard/all.py +61 -19
- openlit/guard/prompt_injection.py +34 -14
- openlit/guard/restrict_topic.py +46 -15
- openlit/guard/sensitive_topic.py +34 -14
- openlit/guard/utils.py +58 -22
- openlit/instrumentation/ag2/__init__.py +24 -8
- openlit/instrumentation/ag2/ag2.py +34 -13
- openlit/instrumentation/ag2/async_ag2.py +34 -13
- openlit/instrumentation/ag2/utils.py +133 -30
- openlit/instrumentation/ai21/__init__.py +43 -14
- openlit/instrumentation/ai21/ai21.py +47 -21
- openlit/instrumentation/ai21/async_ai21.py +47 -21
- openlit/instrumentation/ai21/utils.py +299 -78
- openlit/instrumentation/anthropic/__init__.py +21 -4
- openlit/instrumentation/anthropic/anthropic.py +28 -17
- openlit/instrumentation/anthropic/async_anthropic.py +28 -17
- openlit/instrumentation/anthropic/utils.py +145 -35
- openlit/instrumentation/assemblyai/__init__.py +11 -2
- openlit/instrumentation/assemblyai/assemblyai.py +15 -4
- openlit/instrumentation/assemblyai/utils.py +120 -25
- openlit/instrumentation/astra/__init__.py +43 -10
- openlit/instrumentation/astra/astra.py +28 -5
- openlit/instrumentation/astra/async_astra.py +28 -5
- openlit/instrumentation/astra/utils.py +151 -55
- openlit/instrumentation/azure_ai_inference/__init__.py +43 -10
- openlit/instrumentation/azure_ai_inference/async_azure_ai_inference.py +53 -21
- openlit/instrumentation/azure_ai_inference/azure_ai_inference.py +53 -21
- openlit/instrumentation/azure_ai_inference/utils.py +307 -83
- openlit/instrumentation/bedrock/__init__.py +21 -4
- openlit/instrumentation/bedrock/bedrock.py +63 -25
- openlit/instrumentation/bedrock/utils.py +139 -30
- openlit/instrumentation/chroma/__init__.py +89 -16
- openlit/instrumentation/chroma/chroma.py +28 -6
- openlit/instrumentation/chroma/utils.py +167 -51
- openlit/instrumentation/cohere/__init__.py +63 -18
- openlit/instrumentation/cohere/async_cohere.py +63 -24
- openlit/instrumentation/cohere/cohere.py +63 -24
- openlit/instrumentation/cohere/utils.py +286 -73
- openlit/instrumentation/controlflow/__init__.py +35 -9
- openlit/instrumentation/controlflow/controlflow.py +66 -33
- openlit/instrumentation/crawl4ai/__init__.py +25 -10
- openlit/instrumentation/crawl4ai/async_crawl4ai.py +78 -31
- openlit/instrumentation/crawl4ai/crawl4ai.py +78 -31
- openlit/instrumentation/crewai/__init__.py +111 -24
- openlit/instrumentation/crewai/async_crewai.py +114 -0
- openlit/instrumentation/crewai/crewai.py +104 -131
- openlit/instrumentation/crewai/utils.py +615 -0
- openlit/instrumentation/dynamiq/__init__.py +46 -12
- openlit/instrumentation/dynamiq/dynamiq.py +74 -33
- openlit/instrumentation/elevenlabs/__init__.py +23 -4
- openlit/instrumentation/elevenlabs/async_elevenlabs.py +16 -4
- openlit/instrumentation/elevenlabs/elevenlabs.py +16 -4
- openlit/instrumentation/elevenlabs/utils.py +128 -25
- openlit/instrumentation/embedchain/__init__.py +11 -2
- openlit/instrumentation/embedchain/embedchain.py +68 -35
- openlit/instrumentation/firecrawl/__init__.py +24 -7
- openlit/instrumentation/firecrawl/firecrawl.py +46 -20
- openlit/instrumentation/google_ai_studio/__init__.py +45 -10
- openlit/instrumentation/google_ai_studio/async_google_ai_studio.py +67 -44
- openlit/instrumentation/google_ai_studio/google_ai_studio.py +67 -44
- openlit/instrumentation/google_ai_studio/utils.py +180 -67
- openlit/instrumentation/gpt4all/__init__.py +22 -7
- openlit/instrumentation/gpt4all/gpt4all.py +67 -29
- openlit/instrumentation/gpt4all/utils.py +285 -61
- openlit/instrumentation/gpu/__init__.py +128 -47
- openlit/instrumentation/groq/__init__.py +21 -4
- openlit/instrumentation/groq/async_groq.py +33 -21
- openlit/instrumentation/groq/groq.py +33 -21
- openlit/instrumentation/groq/utils.py +192 -55
- openlit/instrumentation/haystack/__init__.py +70 -24
- openlit/instrumentation/haystack/async_haystack.py +28 -6
- openlit/instrumentation/haystack/haystack.py +28 -6
- openlit/instrumentation/haystack/utils.py +196 -74
- openlit/instrumentation/julep/__init__.py +69 -19
- openlit/instrumentation/julep/async_julep.py +53 -27
- openlit/instrumentation/julep/julep.py +53 -28
- openlit/instrumentation/langchain/__init__.py +74 -63
- openlit/instrumentation/langchain/callback_handler.py +1100 -0
- openlit/instrumentation/langchain_community/__init__.py +13 -2
- openlit/instrumentation/langchain_community/async_langchain_community.py +23 -5
- openlit/instrumentation/langchain_community/langchain_community.py +23 -5
- openlit/instrumentation/langchain_community/utils.py +35 -9
- openlit/instrumentation/letta/__init__.py +68 -15
- openlit/instrumentation/letta/letta.py +99 -54
- openlit/instrumentation/litellm/__init__.py +43 -14
- openlit/instrumentation/litellm/async_litellm.py +51 -26
- openlit/instrumentation/litellm/litellm.py +51 -26
- openlit/instrumentation/litellm/utils.py +312 -101
- openlit/instrumentation/llamaindex/__init__.py +267 -90
- openlit/instrumentation/llamaindex/async_llamaindex.py +28 -6
- openlit/instrumentation/llamaindex/llamaindex.py +28 -6
- openlit/instrumentation/llamaindex/utils.py +204 -91
- openlit/instrumentation/mem0/__init__.py +11 -2
- openlit/instrumentation/mem0/mem0.py +50 -29
- openlit/instrumentation/milvus/__init__.py +10 -2
- openlit/instrumentation/milvus/milvus.py +31 -6
- openlit/instrumentation/milvus/utils.py +166 -67
- openlit/instrumentation/mistral/__init__.py +63 -18
- openlit/instrumentation/mistral/async_mistral.py +63 -24
- openlit/instrumentation/mistral/mistral.py +63 -24
- openlit/instrumentation/mistral/utils.py +277 -69
- openlit/instrumentation/multion/__init__.py +69 -19
- openlit/instrumentation/multion/async_multion.py +57 -26
- openlit/instrumentation/multion/multion.py +57 -26
- openlit/instrumentation/ollama/__init__.py +39 -18
- openlit/instrumentation/ollama/async_ollama.py +57 -26
- openlit/instrumentation/ollama/ollama.py +57 -26
- openlit/instrumentation/ollama/utils.py +226 -50
- openlit/instrumentation/openai/__init__.py +156 -32
- openlit/instrumentation/openai/async_openai.py +147 -67
- openlit/instrumentation/openai/openai.py +150 -67
- openlit/instrumentation/openai/utils.py +660 -186
- openlit/instrumentation/openai_agents/__init__.py +6 -2
- openlit/instrumentation/openai_agents/processor.py +409 -537
- openlit/instrumentation/phidata/__init__.py +13 -5
- openlit/instrumentation/phidata/phidata.py +67 -32
- openlit/instrumentation/pinecone/__init__.py +48 -9
- openlit/instrumentation/pinecone/async_pinecone.py +27 -5
- openlit/instrumentation/pinecone/pinecone.py +27 -5
- openlit/instrumentation/pinecone/utils.py +153 -47
- openlit/instrumentation/premai/__init__.py +22 -7
- openlit/instrumentation/premai/premai.py +51 -26
- openlit/instrumentation/premai/utils.py +246 -59
- openlit/instrumentation/pydantic_ai/__init__.py +49 -22
- openlit/instrumentation/pydantic_ai/pydantic_ai.py +69 -16
- openlit/instrumentation/pydantic_ai/utils.py +89 -24
- openlit/instrumentation/qdrant/__init__.py +19 -4
- openlit/instrumentation/qdrant/async_qdrant.py +33 -7
- openlit/instrumentation/qdrant/qdrant.py +33 -7
- openlit/instrumentation/qdrant/utils.py +228 -93
- openlit/instrumentation/reka/__init__.py +23 -10
- openlit/instrumentation/reka/async_reka.py +17 -11
- openlit/instrumentation/reka/reka.py +17 -11
- openlit/instrumentation/reka/utils.py +138 -36
- openlit/instrumentation/together/__init__.py +44 -12
- openlit/instrumentation/together/async_together.py +50 -27
- openlit/instrumentation/together/together.py +50 -27
- openlit/instrumentation/together/utils.py +301 -71
- openlit/instrumentation/transformers/__init__.py +2 -1
- openlit/instrumentation/transformers/transformers.py +13 -3
- openlit/instrumentation/transformers/utils.py +139 -36
- openlit/instrumentation/vertexai/__init__.py +81 -16
- openlit/instrumentation/vertexai/async_vertexai.py +33 -15
- openlit/instrumentation/vertexai/utils.py +123 -27
- openlit/instrumentation/vertexai/vertexai.py +33 -15
- openlit/instrumentation/vllm/__init__.py +12 -5
- openlit/instrumentation/vllm/utils.py +121 -31
- openlit/instrumentation/vllm/vllm.py +16 -10
- openlit/otel/events.py +35 -10
- openlit/otel/metrics.py +32 -24
- openlit/otel/tracing.py +24 -9
- openlit/semcov/__init__.py +101 -7
- {openlit-1.34.29.dist-info → openlit-1.34.31.dist-info}/METADATA +2 -1
- openlit-1.34.31.dist-info/RECORD +166 -0
- openlit/instrumentation/langchain/async_langchain.py +0 -102
- openlit/instrumentation/langchain/langchain.py +0 -102
- openlit/instrumentation/langchain/utils.py +0 -252
- openlit-1.34.29.dist-info/RECORD +0 -166
- {openlit-1.34.29.dist-info → openlit-1.34.31.dist-info}/LICENSE +0 -0
- {openlit-1.34.29.dist-info → openlit-1.34.31.dist-info}/WHEEL +0 -0
@@ -1,6 +1,7 @@
|
|
1
1
|
"""
|
2
2
|
Groq OpenTelemetry instrumentation utility functions
|
3
3
|
"""
|
4
|
+
|
4
5
|
import time
|
5
6
|
|
6
7
|
from opentelemetry.trace import Status, StatusCode
|
@@ -15,6 +16,7 @@ from openlit.__helpers import (
|
|
15
16
|
)
|
16
17
|
from openlit.semcov import SemanticConvention
|
17
18
|
|
19
|
+
|
18
20
|
def format_content(messages):
|
19
21
|
"""
|
20
22
|
Process a list of messages to extract content.
|
@@ -27,8 +29,9 @@ def format_content(messages):
|
|
27
29
|
|
28
30
|
if isinstance(content, list):
|
29
31
|
content_str = ", ".join(
|
30
|
-
f
|
31
|
-
if "type" in item
|
32
|
+
f"{item['type']}: {item['text'] if 'text' in item else item['image_url']}"
|
33
|
+
if "type" in item
|
34
|
+
else f"text: {item['text']}"
|
32
35
|
for item in content
|
33
36
|
)
|
34
37
|
formatted_messages.append(f"{role}: {content_str}")
|
@@ -37,6 +40,7 @@ def format_content(messages):
|
|
37
40
|
|
38
41
|
return "\n".join(formatted_messages)
|
39
42
|
|
43
|
+
|
40
44
|
def process_chunk(scope, chunk):
|
41
45
|
"""
|
42
46
|
Process a chunk of response data and update state.
|
@@ -53,27 +57,41 @@ def process_chunk(scope, chunk):
|
|
53
57
|
chunked = response_as_dict(chunk)
|
54
58
|
|
55
59
|
# Collect message IDs and aggregated response from events
|
56
|
-
if (
|
57
|
-
|
58
|
-
"
|
59
|
-
|
60
|
+
if (
|
61
|
+
len(chunked.get("choices", [])) > 0
|
62
|
+
and "delta" in chunked.get("choices")[0]
|
63
|
+
and "content" in chunked.get("choices")[0].get("delta", {})
|
64
|
+
):
|
60
65
|
content = chunked.get("choices")[0].get("delta").get("content")
|
61
66
|
if content:
|
62
67
|
scope._llmresponse += content
|
63
68
|
|
64
|
-
if chunked.get(
|
65
|
-
if chunked.get(
|
66
|
-
scope._input_tokens =
|
67
|
-
|
68
|
-
|
69
|
-
scope.
|
70
|
-
|
71
|
-
|
69
|
+
if chunked.get("x_groq") is not None:
|
70
|
+
if chunked.get("x_groq").get("usage") is not None:
|
71
|
+
scope._input_tokens = (
|
72
|
+
chunked.get("x_groq").get("usage").get("prompt_tokens")
|
73
|
+
)
|
74
|
+
scope._output_tokens = (
|
75
|
+
chunked.get("x_groq").get("usage").get("completion_tokens")
|
76
|
+
)
|
77
|
+
scope._response_id = chunked.get("x_groq").get("id")
|
78
|
+
scope._response_model = chunked.get("x_groq").get("model")
|
79
|
+
scope._finish_reason = chunked.get("choices", [{}])[0].get("finish_reason")
|
80
|
+
scope._system_fingerprint = chunked.get("x_groq").get("system_fingerprint")
|
72
81
|
scope._end_time = time.time()
|
73
82
|
|
74
83
|
|
75
|
-
def common_chat_logic(
|
76
|
-
|
84
|
+
def common_chat_logic(
|
85
|
+
scope,
|
86
|
+
pricing_info,
|
87
|
+
environment,
|
88
|
+
application_name,
|
89
|
+
metrics,
|
90
|
+
capture_message_content,
|
91
|
+
disable_metrics,
|
92
|
+
version,
|
93
|
+
is_stream,
|
94
|
+
):
|
77
95
|
"""
|
78
96
|
Process chat request and generate Telemetry
|
79
97
|
"""
|
@@ -84,47 +102,107 @@ def common_chat_logic(scope, pricing_info, environment, application_name, metric
|
|
84
102
|
prompt = format_content(scope._kwargs.get("messages", []))
|
85
103
|
request_model = scope._kwargs.get("model", "mixtral-8x7b-32768")
|
86
104
|
|
87
|
-
cost = get_chat_model_cost(
|
105
|
+
cost = get_chat_model_cost(
|
106
|
+
request_model, pricing_info, scope._input_tokens, scope._output_tokens
|
107
|
+
)
|
88
108
|
|
89
109
|
# Common Span Attributes
|
90
|
-
common_span_attributes(
|
91
|
-
|
92
|
-
|
93
|
-
|
110
|
+
common_span_attributes(
|
111
|
+
scope,
|
112
|
+
SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT,
|
113
|
+
SemanticConvention.GEN_AI_SYSTEM_GROQ,
|
114
|
+
scope._server_address,
|
115
|
+
scope._server_port,
|
116
|
+
request_model,
|
117
|
+
scope._response_model,
|
118
|
+
environment,
|
119
|
+
application_name,
|
120
|
+
is_stream,
|
121
|
+
scope._tbt,
|
122
|
+
scope._ttft,
|
123
|
+
version,
|
124
|
+
)
|
94
125
|
|
95
126
|
# Span Attributes for Request parameters
|
96
|
-
scope._span.set_attribute(
|
97
|
-
|
98
|
-
|
99
|
-
scope._span.set_attribute(
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
scope._span.set_attribute(
|
104
|
-
|
127
|
+
scope._span.set_attribute(
|
128
|
+
SemanticConvention.GEN_AI_REQUEST_SEED, scope._kwargs.get("seed", "")
|
129
|
+
)
|
130
|
+
scope._span.set_attribute(
|
131
|
+
SemanticConvention.GEN_AI_REQUEST_FREQUENCY_PENALTY,
|
132
|
+
scope._kwargs.get("frequency_penalty", 0.0),
|
133
|
+
)
|
134
|
+
scope._span.set_attribute(
|
135
|
+
SemanticConvention.GEN_AI_REQUEST_MAX_TOKENS,
|
136
|
+
scope._kwargs.get("max_completion_tokens", -1),
|
137
|
+
)
|
138
|
+
scope._span.set_attribute(
|
139
|
+
SemanticConvention.GEN_AI_REQUEST_PRESENCE_PENALTY,
|
140
|
+
scope._kwargs.get("presence_penalty", 0.0),
|
141
|
+
)
|
142
|
+
scope._span.set_attribute(
|
143
|
+
SemanticConvention.GEN_AI_REQUEST_STOP_SEQUENCES, scope._kwargs.get("stop", [])
|
144
|
+
)
|
145
|
+
scope._span.set_attribute(
|
146
|
+
SemanticConvention.GEN_AI_REQUEST_TEMPERATURE,
|
147
|
+
scope._kwargs.get("temperature", 1.0),
|
148
|
+
)
|
149
|
+
scope._span.set_attribute(
|
150
|
+
SemanticConvention.GEN_AI_REQUEST_TOP_P, scope._kwargs.get("top_p", 1.0)
|
151
|
+
)
|
152
|
+
scope._span.set_attribute(
|
153
|
+
SemanticConvention.GEN_AI_REQUEST_USER, scope._kwargs.get("user", "")
|
154
|
+
)
|
155
|
+
scope._span.set_attribute(
|
156
|
+
SemanticConvention.GEN_AI_REQUEST_SERVICE_TIER,
|
157
|
+
scope._kwargs.get("service_tier", "on_demand"),
|
158
|
+
)
|
105
159
|
|
106
160
|
# Span Attributes for Response parameters
|
107
161
|
scope._span.set_attribute(SemanticConvention.GEN_AI_RESPONSE_ID, scope._response_id)
|
108
|
-
scope._span.set_attribute(
|
109
|
-
|
110
|
-
|
162
|
+
scope._span.set_attribute(
|
163
|
+
SemanticConvention.GEN_AI_RESPONSE_FINISH_REASON, [scope._finish_reason]
|
164
|
+
)
|
165
|
+
scope._span.set_attribute(
|
166
|
+
SemanticConvention.GEN_AI_RESPONSE_SYSTEM_FINGERPRINT, scope._system_fingerprint
|
167
|
+
)
|
168
|
+
scope._span.set_attribute(
|
169
|
+
SemanticConvention.GEN_AI_OUTPUT_TYPE,
|
170
|
+
"text" if isinstance(scope._llmresponse, str) else "json",
|
171
|
+
)
|
111
172
|
|
112
173
|
# Span Attributes for Cost and Tokens
|
113
|
-
scope._span.set_attribute(
|
114
|
-
|
115
|
-
|
174
|
+
scope._span.set_attribute(
|
175
|
+
SemanticConvention.GEN_AI_USAGE_INPUT_TOKENS, scope._input_tokens
|
176
|
+
)
|
177
|
+
scope._span.set_attribute(
|
178
|
+
SemanticConvention.GEN_AI_USAGE_OUTPUT_TOKENS, scope._output_tokens
|
179
|
+
)
|
180
|
+
scope._span.set_attribute(
|
181
|
+
SemanticConvention.GEN_AI_CLIENT_TOKEN_USAGE,
|
182
|
+
scope._input_tokens + scope._output_tokens,
|
183
|
+
)
|
116
184
|
scope._span.set_attribute(SemanticConvention.GEN_AI_USAGE_COST, cost)
|
117
185
|
|
118
186
|
# Span Attributes for Tools
|
119
187
|
if scope._tools:
|
120
|
-
scope._span.set_attribute(
|
121
|
-
|
122
|
-
|
188
|
+
scope._span.set_attribute(
|
189
|
+
SemanticConvention.GEN_AI_TOOL_NAME,
|
190
|
+
scope._tools.get("function", {}).get("name", ""),
|
191
|
+
)
|
192
|
+
scope._span.set_attribute(
|
193
|
+
SemanticConvention.GEN_AI_TOOL_CALL_ID, str(scope._tools.get("id", ""))
|
194
|
+
)
|
195
|
+
scope._span.set_attribute(
|
196
|
+
SemanticConvention.GEN_AI_TOOL_ARGS,
|
197
|
+
str(scope._tools.get("function", {}).get("arguments", "")),
|
198
|
+
)
|
123
199
|
|
124
200
|
# Span Attributes for Content
|
125
201
|
if capture_message_content:
|
126
202
|
scope._span.set_attribute(SemanticConvention.GEN_AI_CONTENT_PROMPT, prompt)
|
127
|
-
scope._span.set_attribute(
|
203
|
+
scope._span.set_attribute(
|
204
|
+
SemanticConvention.GEN_AI_CONTENT_COMPLETION, scope._llmresponse
|
205
|
+
)
|
128
206
|
|
129
207
|
# To be removed one the change to span_attributes (from span events) is complete
|
130
208
|
scope._span.add_event(
|
@@ -144,23 +222,69 @@ def common_chat_logic(scope, pricing_info, environment, application_name, metric
|
|
144
222
|
|
145
223
|
# Metrics
|
146
224
|
if not disable_metrics:
|
147
|
-
record_completion_metrics(
|
148
|
-
|
149
|
-
|
150
|
-
|
225
|
+
record_completion_metrics(
|
226
|
+
metrics,
|
227
|
+
SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT,
|
228
|
+
SemanticConvention.GEN_AI_SYSTEM_GROQ,
|
229
|
+
scope._server_address,
|
230
|
+
scope._server_port,
|
231
|
+
request_model,
|
232
|
+
scope._response_model,
|
233
|
+
environment,
|
234
|
+
application_name,
|
235
|
+
scope._start_time,
|
236
|
+
scope._end_time,
|
237
|
+
scope._input_tokens,
|
238
|
+
scope._output_tokens,
|
239
|
+
cost,
|
240
|
+
scope._tbt,
|
241
|
+
scope._ttft,
|
242
|
+
)
|
151
243
|
|
152
|
-
|
153
|
-
|
244
|
+
|
245
|
+
def process_streaming_chat_response(
|
246
|
+
scope,
|
247
|
+
pricing_info,
|
248
|
+
environment,
|
249
|
+
application_name,
|
250
|
+
metrics,
|
251
|
+
capture_message_content=False,
|
252
|
+
disable_metrics=False,
|
253
|
+
version="",
|
254
|
+
):
|
154
255
|
"""
|
155
256
|
Process chat request and generate Telemetry
|
156
257
|
"""
|
157
258
|
|
158
|
-
common_chat_logic(
|
159
|
-
|
259
|
+
common_chat_logic(
|
260
|
+
scope,
|
261
|
+
pricing_info,
|
262
|
+
environment,
|
263
|
+
application_name,
|
264
|
+
metrics,
|
265
|
+
capture_message_content,
|
266
|
+
disable_metrics,
|
267
|
+
version,
|
268
|
+
is_stream=True,
|
269
|
+
)
|
270
|
+
|
160
271
|
|
161
|
-
def process_chat_response(
|
162
|
-
|
163
|
-
|
272
|
+
def process_chat_response(
|
273
|
+
response,
|
274
|
+
request_model,
|
275
|
+
pricing_info,
|
276
|
+
server_port,
|
277
|
+
server_address,
|
278
|
+
environment,
|
279
|
+
application_name,
|
280
|
+
metrics,
|
281
|
+
start_time,
|
282
|
+
span,
|
283
|
+
capture_message_content=False,
|
284
|
+
disable_metrics=False,
|
285
|
+
version="1.0.0",
|
286
|
+
**kwargs,
|
287
|
+
):
|
164
288
|
"""
|
165
289
|
Process chat request and generate Telemetry
|
166
290
|
"""
|
@@ -185,15 +309,28 @@ def process_chat_response(response, request_model, pricing_info, server_port, se
|
|
185
309
|
scope._server_address, scope._server_port = server_address, server_port
|
186
310
|
scope._kwargs = kwargs
|
187
311
|
scope._system_fingerprint = response_dict.get("system_fingerprint")
|
188
|
-
scope._finish_reason = str(
|
312
|
+
scope._finish_reason = str(
|
313
|
+
response_dict.get("choices", [])[0].get("finish_reason", "")
|
314
|
+
)
|
189
315
|
|
190
316
|
# Handle tool calls
|
191
317
|
if scope._kwargs.get("tools"):
|
192
|
-
scope._tools =
|
318
|
+
scope._tools = (
|
319
|
+
response_dict.get("choices", [{}])[0].get("message", {}).get("tool_calls")
|
320
|
+
)
|
193
321
|
else:
|
194
322
|
scope._tools = None
|
195
323
|
|
196
|
-
common_chat_logic(
|
197
|
-
|
324
|
+
common_chat_logic(
|
325
|
+
scope,
|
326
|
+
pricing_info,
|
327
|
+
environment,
|
328
|
+
application_name,
|
329
|
+
metrics,
|
330
|
+
capture_message_content,
|
331
|
+
disable_metrics,
|
332
|
+
version,
|
333
|
+
is_stream=False,
|
334
|
+
)
|
198
335
|
|
199
336
|
return response
|
@@ -12,6 +12,7 @@ from openlit.instrumentation.haystack.async_haystack import async_general_wrap
|
|
12
12
|
|
13
13
|
_instruments = ("haystack-ai >= 2.0.0",)
|
14
14
|
|
15
|
+
|
15
16
|
class HaystackInstrumentor(BaseInstrumentor):
|
16
17
|
"""Optimized instrumentor for Haystack with minimal overhead"""
|
17
18
|
|
@@ -32,16 +33,34 @@ class HaystackInstrumentor(BaseInstrumentor):
|
|
32
33
|
# Pipeline operations (always enabled)
|
33
34
|
try:
|
34
35
|
wrap_function_wrapper(
|
35
|
-
"haystack",
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
"haystack",
|
37
|
+
"Pipeline.run",
|
38
|
+
general_wrap(
|
39
|
+
"pipeline",
|
40
|
+
version,
|
41
|
+
environment,
|
42
|
+
application_name,
|
43
|
+
tracer,
|
44
|
+
pricing_info,
|
45
|
+
capture_message_content,
|
46
|
+
metrics,
|
47
|
+
disable_metrics,
|
48
|
+
),
|
39
49
|
)
|
40
50
|
wrap_function_wrapper(
|
41
|
-
"haystack",
|
42
|
-
|
43
|
-
|
44
|
-
|
51
|
+
"haystack",
|
52
|
+
"AsyncPipeline.run_async",
|
53
|
+
async_general_wrap(
|
54
|
+
"pipeline",
|
55
|
+
version,
|
56
|
+
environment,
|
57
|
+
application_name,
|
58
|
+
tracer,
|
59
|
+
pricing_info,
|
60
|
+
capture_message_content,
|
61
|
+
metrics,
|
62
|
+
disable_metrics,
|
63
|
+
),
|
45
64
|
)
|
46
65
|
except Exception:
|
47
66
|
pass
|
@@ -49,27 +68,54 @@ class HaystackInstrumentor(BaseInstrumentor):
|
|
49
68
|
# Component operations (only if detailed_tracing enabled)
|
50
69
|
if detailed_tracing:
|
51
70
|
components = [
|
52
|
-
(
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
(
|
63
|
-
|
71
|
+
(
|
72
|
+
"haystack.components.retrievers.in_memory",
|
73
|
+
"InMemoryBM25Retriever.run",
|
74
|
+
"bm25_retriever",
|
75
|
+
),
|
76
|
+
(
|
77
|
+
"haystack.components.builders.prompt_builder",
|
78
|
+
"PromptBuilder.run",
|
79
|
+
"prompt_builder",
|
80
|
+
),
|
81
|
+
(
|
82
|
+
"haystack.components.generators.openai",
|
83
|
+
"OpenAIGenerator.run",
|
84
|
+
"openai_generator",
|
85
|
+
),
|
86
|
+
(
|
87
|
+
"haystack.components.generators.chat.openai",
|
88
|
+
"OpenAIChatGenerator.run",
|
89
|
+
"openai_chat_generator",
|
90
|
+
),
|
91
|
+
(
|
92
|
+
"haystack.components.embedders.openai_text_embedder",
|
93
|
+
"OpenAITextEmbedder.run",
|
94
|
+
"text_embedder",
|
95
|
+
),
|
96
|
+
(
|
97
|
+
"haystack.components.embedders.openai_document_embedder",
|
98
|
+
"OpenAIDocumentEmbedder.run",
|
99
|
+
"document_embedder",
|
100
|
+
),
|
64
101
|
]
|
65
102
|
|
66
103
|
for module, method, component_type in components:
|
67
104
|
try:
|
68
105
|
wrap_function_wrapper(
|
69
|
-
module,
|
70
|
-
|
71
|
-
|
72
|
-
|
106
|
+
module,
|
107
|
+
method,
|
108
|
+
general_wrap(
|
109
|
+
component_type,
|
110
|
+
version,
|
111
|
+
environment,
|
112
|
+
application_name,
|
113
|
+
tracer,
|
114
|
+
pricing_info,
|
115
|
+
capture_message_content,
|
116
|
+
metrics,
|
117
|
+
disable_metrics,
|
118
|
+
),
|
73
119
|
)
|
74
120
|
except Exception:
|
75
121
|
pass
|
@@ -12,8 +12,18 @@ from openlit.instrumentation.haystack.utils import (
|
|
12
12
|
set_server_address_and_port,
|
13
13
|
)
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
|
16
|
+
def async_general_wrap(
|
17
|
+
endpoint,
|
18
|
+
version,
|
19
|
+
environment,
|
20
|
+
application_name,
|
21
|
+
tracer,
|
22
|
+
pricing_info,
|
23
|
+
capture_message_content,
|
24
|
+
metrics,
|
25
|
+
disable_metrics,
|
26
|
+
):
|
17
27
|
"""Optimized async wrapper for Haystack operations"""
|
18
28
|
|
19
29
|
async def wrapper(wrapped, instance, args, kwargs):
|
@@ -41,10 +51,22 @@ def async_general_wrap(endpoint, version, environment, application_name,
|
|
41
51
|
|
42
52
|
try:
|
43
53
|
response = process_haystack_response(
|
44
|
-
response,
|
45
|
-
|
46
|
-
|
47
|
-
|
54
|
+
response,
|
55
|
+
operation_type,
|
56
|
+
server_address,
|
57
|
+
server_port,
|
58
|
+
environment,
|
59
|
+
application_name,
|
60
|
+
metrics,
|
61
|
+
start_time,
|
62
|
+
span,
|
63
|
+
capture_message_content,
|
64
|
+
disable_metrics,
|
65
|
+
version,
|
66
|
+
instance,
|
67
|
+
args,
|
68
|
+
endpoint=endpoint,
|
69
|
+
**kwargs,
|
48
70
|
)
|
49
71
|
except Exception as e:
|
50
72
|
handle_exception(span, e)
|
@@ -12,8 +12,18 @@ from openlit.instrumentation.haystack.utils import (
|
|
12
12
|
set_server_address_and_port,
|
13
13
|
)
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
|
16
|
+
def general_wrap(
|
17
|
+
endpoint,
|
18
|
+
version,
|
19
|
+
environment,
|
20
|
+
application_name,
|
21
|
+
tracer,
|
22
|
+
pricing_info,
|
23
|
+
capture_message_content,
|
24
|
+
metrics,
|
25
|
+
disable_metrics,
|
26
|
+
):
|
17
27
|
"""Optimized wrapper for Haystack operations"""
|
18
28
|
|
19
29
|
def wrapper(wrapped, instance, args, kwargs):
|
@@ -41,10 +51,22 @@ def general_wrap(endpoint, version, environment, application_name,
|
|
41
51
|
|
42
52
|
try:
|
43
53
|
response = process_haystack_response(
|
44
|
-
response,
|
45
|
-
|
46
|
-
|
47
|
-
|
54
|
+
response,
|
55
|
+
operation_type,
|
56
|
+
server_address,
|
57
|
+
server_port,
|
58
|
+
environment,
|
59
|
+
application_name,
|
60
|
+
metrics,
|
61
|
+
start_time,
|
62
|
+
span,
|
63
|
+
capture_message_content,
|
64
|
+
disable_metrics,
|
65
|
+
version,
|
66
|
+
instance,
|
67
|
+
args,
|
68
|
+
endpoint=endpoint,
|
69
|
+
**kwargs,
|
48
70
|
)
|
49
71
|
except Exception as e:
|
50
72
|
handle_exception(span, e)
|