openlit 1.34.30__py3-none-any.whl → 1.34.32__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 +19 -14
- 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 +113 -6
- openlit/instrumentation/ag2/ag2.py +459 -17
- openlit/instrumentation/ag2/async_ag2.py +459 -17
- openlit/instrumentation/ag2/utils.py +475 -31
- 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 +40 -15
- openlit/instrumentation/crewai/async_crewai.py +32 -7
- openlit/instrumentation/crewai/crewai.py +32 -7
- openlit/instrumentation/crewai/utils.py +159 -56
- 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 +304 -102
- 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 +657 -185
- openlit/instrumentation/openai_agents/__init__.py +5 -1
- openlit/instrumentation/openai_agents/processor.py +110 -90
- 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 +82 -6
- {openlit-1.34.30.dist-info → openlit-1.34.32.dist-info}/METADATA +2 -1
- openlit-1.34.32.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.30.dist-info/RECORD +0 -168
- {openlit-1.34.30.dist-info → openlit-1.34.32.dist-info}/LICENSE +0 -0
- {openlit-1.34.30.dist-info → openlit-1.34.32.dist-info}/WHEEL +0 -0
openlit/guard/utils.py
CHANGED
@@ -16,6 +16,7 @@ from openlit.semcov import SemanticConvention
|
|
16
16
|
# Initialize logger for logging potential issues and operations
|
17
17
|
logger = logging.getLogger(__name__)
|
18
18
|
|
19
|
+
|
19
20
|
class JsonOutput(BaseModel):
|
20
21
|
"""
|
21
22
|
A model representing the structure of JSON output for prompt injection detection.
|
@@ -34,13 +35,17 @@ class JsonOutput(BaseModel):
|
|
34
35
|
classification: str
|
35
36
|
explanation: str
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
38
|
+
|
39
|
+
def setup_provider(
|
40
|
+
provider: Optional[str],
|
41
|
+
api_key: Optional[str],
|
42
|
+
model: Optional[str],
|
43
|
+
base_url: Optional[str],
|
44
|
+
) -> Tuple[Optional[str], Optional[str], Optional[str]]:
|
40
45
|
"""Function to setup LLM provider"""
|
41
46
|
provider_configs = {
|
42
47
|
"openai": {"env_var": "OPENAI_API_KEY"},
|
43
|
-
"anthropic": {"env_var": "ANTHROPIC_API_KEY"}
|
48
|
+
"anthropic": {"env_var": "ANTHROPIC_API_KEY"},
|
44
49
|
}
|
45
50
|
|
46
51
|
if provider is None:
|
@@ -60,7 +65,9 @@ def setup_provider(provider: Optional[str], api_key: Optional[str],
|
|
60
65
|
|
61
66
|
if not api_key:
|
62
67
|
# pylint: disable=line-too-long
|
63
|
-
raise ValueError(
|
68
|
+
raise ValueError(
|
69
|
+
f"API key required via 'api_key' parameter or '{env_var}' environment variable"
|
70
|
+
)
|
64
71
|
|
65
72
|
return api_key, model, base_url
|
66
73
|
|
@@ -69,6 +76,7 @@ def format_prompt(system_prompt: str, text: str) -> str:
|
|
69
76
|
"""Function to format the prompt"""
|
70
77
|
return system_prompt.replace("{{prompt}}", text)
|
71
78
|
|
79
|
+
|
72
80
|
def llm_response(provider: str, prompt: str, model: str, base_url: str) -> str:
|
73
81
|
"""Function to get LLM response based on provider"""
|
74
82
|
# pylint: disable=no-else-return
|
@@ -79,6 +87,7 @@ def llm_response(provider: str, prompt: str, model: str, base_url: str) -> str:
|
|
79
87
|
else:
|
80
88
|
raise ValueError(f"Unsupported provider: {provider}")
|
81
89
|
|
90
|
+
|
82
91
|
def llm_response_openai(prompt: str, model: str, base_url: str) -> str:
|
83
92
|
"""Function to make LLM call to OpenAI"""
|
84
93
|
client = OpenAI(base_url=base_url)
|
@@ -95,10 +104,11 @@ def llm_response_openai(prompt: str, model: str, base_url: str) -> str:
|
|
95
104
|
{"role": "user", "content": prompt},
|
96
105
|
],
|
97
106
|
temperature=0.0,
|
98
|
-
response_format=JsonOutput
|
107
|
+
response_format=JsonOutput,
|
99
108
|
)
|
100
109
|
return response.choices[0].message.content
|
101
110
|
|
111
|
+
|
102
112
|
def llm_response_anthropic(prompt: str, model: str) -> str:
|
103
113
|
"""Function to make LLM call to Anthropic"""
|
104
114
|
client = Anthropic()
|
@@ -113,26 +123,42 @@ def llm_response_anthropic(prompt: str, model: str) -> str:
|
|
113
123
|
"input_schema": {
|
114
124
|
"type": "object",
|
115
125
|
"properties": {
|
116
|
-
"verdict": {
|
126
|
+
"verdict": {
|
127
|
+
"type": "string",
|
128
|
+
"description": "Verdict of guardrail",
|
129
|
+
},
|
117
130
|
"guard": {"type": "string", "description": "Type of guard"},
|
118
|
-
"score": {
|
119
|
-
|
120
|
-
|
131
|
+
"score": {
|
132
|
+
"type": "number",
|
133
|
+
"description": "Prompt score from Guard.",
|
134
|
+
},
|
135
|
+
"classification": {
|
136
|
+
"type": "string",
|
137
|
+
"description": "Incorrect prompt type",
|
138
|
+
},
|
139
|
+
"explanation": {
|
140
|
+
"type": "string",
|
141
|
+
"description": "Reason for classification",
|
142
|
+
},
|
121
143
|
},
|
122
|
-
"required": [
|
123
|
-
|
144
|
+
"required": [
|
145
|
+
"verdict",
|
146
|
+
"guard",
|
147
|
+
"score",
|
148
|
+
"classification",
|
149
|
+
"explanation",
|
150
|
+
],
|
151
|
+
},
|
124
152
|
}
|
125
153
|
]
|
126
154
|
|
127
155
|
response = client.messages.create(
|
128
156
|
model=model,
|
129
|
-
messages=[
|
130
|
-
{"role": "user", "content": prompt}
|
131
|
-
],
|
157
|
+
messages=[{"role": "user", "content": prompt}],
|
132
158
|
max_tokens=2000,
|
133
159
|
temperature=0.0,
|
134
160
|
tools=tools,
|
135
|
-
stream=False
|
161
|
+
stream=False,
|
136
162
|
)
|
137
163
|
|
138
164
|
for content in response.content:
|
@@ -142,6 +168,7 @@ def llm_response_anthropic(prompt: str, model: str) -> str:
|
|
142
168
|
|
143
169
|
return response
|
144
170
|
|
171
|
+
|
145
172
|
def parse_llm_response(response) -> JsonOutput:
|
146
173
|
"""
|
147
174
|
Parses the LLM response into a JsonOutput object.
|
@@ -163,8 +190,14 @@ def parse_llm_response(response) -> JsonOutput:
|
|
163
190
|
return JsonOutput(**data)
|
164
191
|
except (json.JSONDecodeError, TypeError) as e:
|
165
192
|
logger.error("Error parsing LLM response: '%s'", e)
|
166
|
-
return JsonOutput(
|
167
|
-
|
193
|
+
return JsonOutput(
|
194
|
+
score=0,
|
195
|
+
classification="none",
|
196
|
+
explanation="none",
|
197
|
+
verdict="none",
|
198
|
+
guard="none",
|
199
|
+
)
|
200
|
+
|
168
201
|
|
169
202
|
def custom_rule_detection(text: str, custom_rules: list) -> JsonOutput:
|
170
203
|
"""
|
@@ -183,10 +216,12 @@ def custom_rule_detection(text: str, custom_rules: list) -> JsonOutput:
|
|
183
216
|
guard=rule.get("guard", "prompt_injection"),
|
184
217
|
score=rule.get("score", 0.5),
|
185
218
|
classification=rule.get("classification", "custom"),
|
186
|
-
explanation=rule.get("explanation", "Matched custom rule pattern.")
|
219
|
+
explanation=rule.get("explanation", "Matched custom rule pattern."),
|
187
220
|
)
|
188
|
-
return JsonOutput(
|
189
|
-
|
221
|
+
return JsonOutput(
|
222
|
+
score=0, classification="none", explanation="none", verdict="none", guard="none"
|
223
|
+
)
|
224
|
+
|
190
225
|
|
191
226
|
def guard_metrics():
|
192
227
|
"""
|
@@ -204,11 +239,12 @@ def guard_metrics():
|
|
204
239
|
guard_requests = meter.create_counter(
|
205
240
|
name=SemanticConvention.GUARD_REQUESTS,
|
206
241
|
description="Counter for Guard requests",
|
207
|
-
unit="1"
|
242
|
+
unit="1",
|
208
243
|
)
|
209
244
|
|
210
245
|
return guard_requests
|
211
246
|
|
247
|
+
|
212
248
|
def guard_metric_attributes(verdict, score, validator, classification, explanation):
|
213
249
|
"""
|
214
250
|
Initializes OpenTelemetry attributes for metrics.
|
@@ -6,14 +6,25 @@ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
|
|
6
6
|
from wrapt import wrap_function_wrapper
|
7
7
|
|
8
8
|
from openlit.instrumentation.ag2.ag2 import (
|
9
|
-
conversable_agent,
|
9
|
+
conversable_agent,
|
10
|
+
agent_run,
|
11
|
+
agent_generate_reply,
|
12
|
+
agent_receive,
|
13
|
+
agent_send,
|
14
|
+
groupchat_manager_run_chat,
|
15
|
+
groupchat_select_speaker,
|
10
16
|
)
|
11
17
|
from openlit.instrumentation.ag2.async_ag2 import (
|
12
|
-
async_conversable_agent,
|
18
|
+
async_conversable_agent,
|
19
|
+
async_agent_run,
|
20
|
+
async_agent_generate_reply,
|
21
|
+
async_agent_receive,
|
22
|
+
async_agent_send,
|
13
23
|
)
|
14
24
|
|
15
25
|
_instruments = ("ag2 >= 0.3.2",)
|
16
26
|
|
27
|
+
|
17
28
|
class AG2Instrumentor(BaseInstrumentor):
|
18
29
|
"""
|
19
30
|
An instrumentor for AG2 client library.
|
@@ -36,16 +47,112 @@ class AG2Instrumentor(BaseInstrumentor):
|
|
36
47
|
wrap_function_wrapper(
|
37
48
|
"autogen.agentchat.conversable_agent",
|
38
49
|
"ConversableAgent.__init__",
|
39
|
-
conversable_agent(
|
40
|
-
|
50
|
+
conversable_agent(
|
51
|
+
version,
|
52
|
+
environment,
|
53
|
+
application_name,
|
54
|
+
tracer,
|
55
|
+
pricing_info,
|
56
|
+
capture_message_content,
|
57
|
+
metrics,
|
58
|
+
disable_metrics,
|
59
|
+
),
|
41
60
|
)
|
42
61
|
|
43
62
|
# sync agent run
|
44
63
|
wrap_function_wrapper(
|
45
64
|
"autogen.agentchat.conversable_agent",
|
46
65
|
"ConversableAgent.run",
|
47
|
-
agent_run(
|
48
|
-
|
66
|
+
agent_run(
|
67
|
+
version,
|
68
|
+
environment,
|
69
|
+
application_name,
|
70
|
+
tracer,
|
71
|
+
pricing_info,
|
72
|
+
capture_message_content,
|
73
|
+
metrics,
|
74
|
+
disable_metrics,
|
75
|
+
),
|
76
|
+
)
|
77
|
+
|
78
|
+
# sync agent generate_reply
|
79
|
+
wrap_function_wrapper(
|
80
|
+
"autogen.agentchat.conversable_agent",
|
81
|
+
"ConversableAgent.generate_reply",
|
82
|
+
agent_generate_reply(
|
83
|
+
version,
|
84
|
+
environment,
|
85
|
+
application_name,
|
86
|
+
tracer,
|
87
|
+
pricing_info,
|
88
|
+
capture_message_content,
|
89
|
+
metrics,
|
90
|
+
disable_metrics,
|
91
|
+
),
|
92
|
+
)
|
93
|
+
|
94
|
+
# sync agent receive
|
95
|
+
wrap_function_wrapper(
|
96
|
+
"autogen.agentchat.conversable_agent",
|
97
|
+
"ConversableAgent.receive",
|
98
|
+
agent_receive(
|
99
|
+
version,
|
100
|
+
environment,
|
101
|
+
application_name,
|
102
|
+
tracer,
|
103
|
+
pricing_info,
|
104
|
+
capture_message_content,
|
105
|
+
metrics,
|
106
|
+
disable_metrics,
|
107
|
+
),
|
108
|
+
)
|
109
|
+
|
110
|
+
# sync agent send
|
111
|
+
wrap_function_wrapper(
|
112
|
+
"autogen.agentchat.conversable_agent",
|
113
|
+
"ConversableAgent.send",
|
114
|
+
agent_send(
|
115
|
+
version,
|
116
|
+
environment,
|
117
|
+
application_name,
|
118
|
+
tracer,
|
119
|
+
pricing_info,
|
120
|
+
capture_message_content,
|
121
|
+
metrics,
|
122
|
+
disable_metrics,
|
123
|
+
),
|
124
|
+
)
|
125
|
+
|
126
|
+
# sync groupchat manager run_chat
|
127
|
+
wrap_function_wrapper(
|
128
|
+
"autogen.agentchat.groupchat",
|
129
|
+
"GroupChatManager.run_chat",
|
130
|
+
groupchat_manager_run_chat(
|
131
|
+
version,
|
132
|
+
environment,
|
133
|
+
application_name,
|
134
|
+
tracer,
|
135
|
+
pricing_info,
|
136
|
+
capture_message_content,
|
137
|
+
metrics,
|
138
|
+
disable_metrics,
|
139
|
+
),
|
140
|
+
)
|
141
|
+
|
142
|
+
# sync groupchat select_speaker
|
143
|
+
wrap_function_wrapper(
|
144
|
+
"autogen.agentchat.groupchat",
|
145
|
+
"GroupChat.select_speaker",
|
146
|
+
groupchat_select_speaker(
|
147
|
+
version,
|
148
|
+
environment,
|
149
|
+
application_name,
|
150
|
+
tracer,
|
151
|
+
pricing_info,
|
152
|
+
capture_message_content,
|
153
|
+
metrics,
|
154
|
+
disable_metrics,
|
155
|
+
),
|
49
156
|
)
|
50
157
|
|
51
158
|
def _uninstrument(self, **kwargs):
|