osmosis-ai 0.1.8__py3-none-any.whl → 0.1.9__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.

Potentially problematic release.


This version of osmosis-ai might be problematic. Click here for more details.

@@ -1,338 +0,0 @@
1
- """
2
- Langchain-Anthropic adapter for Osmosis
3
-
4
- This module provides monkey patching for the langchain-anthropic package.
5
- """
6
-
7
- import functools
8
- import sys
9
-
10
- from osmosis_ai import utils
11
- from osmosis_ai.utils import send_to_osmosis
12
- from osmosis_ai.logger import logger
13
-
14
-
15
- def wrap_langchain_anthropic() -> None:
16
- """
17
- Monkey patch langchain-anthropic's models to send all prompts and responses to OSMOSIS.
18
-
19
- This function should be called before using any langchain-anthropic models.
20
- """
21
- try:
22
- import langchain_anthropic
23
- except ImportError:
24
- logger.debug("langchain-anthropic package is not installed.")
25
- return
26
-
27
- _patch_anthropic_chat_models()
28
-
29
- logger.info("langchain-anthropic has been wrapped by osmosis-ai.")
30
-
31
-
32
- def _patch_anthropic_chat_models() -> None:
33
- """Patch langchain-anthropic chat model classes to send data to OSMOSIS."""
34
- try:
35
- # Try to import ChatAnthropic class
36
- try:
37
- from langchain_anthropic import ChatAnthropic
38
-
39
- logger.info("Successfully imported ChatAnthropic from langchain_anthropic")
40
- except ImportError:
41
- # Handle older versions if needed
42
- try:
43
- from langchain.chat_models.anthropic import ChatAnthropic
44
-
45
- logger.info("Found ChatAnthropic in langchain.chat_models.anthropic")
46
- except ImportError:
47
- logger.warning(
48
- "Could not find ChatAnthropic class in any expected location."
49
- )
50
- return
51
-
52
- # Log available methods on ChatAnthropic for debugging
53
- chat_methods = [
54
- method
55
- for method in dir(ChatAnthropic)
56
- if not method.startswith("__")
57
- or method in ["_generate", "_agenerate", "_call", "_acall"]
58
- ]
59
- logger.info(f"Found the following methods on ChatAnthropic: {chat_methods}")
60
-
61
- # Try to get the model attribute name - could be model or model_name
62
- model_attr = None
63
- for attr in ["model", "model_name"]:
64
- if hasattr(ChatAnthropic, attr):
65
- model_attr = attr
66
- logger.info(f"ChatAnthropic uses '{attr}' attribute for model name")
67
- break
68
-
69
- if not model_attr:
70
- model_attr = "model" # Default to 'model' if we can't determine it
71
- logger.info(
72
- f"Could not determine model attribute name, defaulting to '{model_attr}'"
73
- )
74
-
75
- # Patch the _generate method if it exists
76
- if hasattr(ChatAnthropic, "_generate"):
77
- original_generate = ChatAnthropic._generate
78
-
79
- if not hasattr(original_generate, "_osmosis_aiped"):
80
-
81
- @functools.wraps(original_generate)
82
- def wrapped_generate(
83
- self, messages, stop=None, run_manager=None, **kwargs
84
- ):
85
- # Get the response
86
- response = original_generate(
87
- self, messages, stop=stop, run_manager=run_manager, **kwargs
88
- )
89
-
90
- # Send to OSMOSIS if enabled
91
- if utils.enabled:
92
- # Create payload
93
- model_name = getattr(self, model_attr, "unknown_model")
94
- payload = {
95
- "model_type": "ChatAnthropic",
96
- "model_name": model_name,
97
- "messages": [
98
- str(msg) for msg in messages
99
- ], # Convert to strings for serialization
100
- "response": str(
101
- response
102
- ), # Convert to string since it may not be serializable
103
- "kwargs": {"stop": stop, **kwargs},
104
- }
105
-
106
- send_to_osmosis(
107
- query={
108
- "type": "langchain_anthropic_generate",
109
- "messages": [str(msg) for msg in messages],
110
- "model": model_name,
111
- },
112
- response=payload,
113
- status=200,
114
- )
115
-
116
- return response
117
-
118
- wrapped_generate._osmosis_aiped = True
119
- ChatAnthropic._generate = wrapped_generate
120
- logger.info("Successfully wrapped ChatAnthropic._generate method")
121
- else:
122
- logger.info("ChatAnthropic._generate already wrapped.")
123
- else:
124
- logger.info("ChatAnthropic does not have a _generate method, skipping.")
125
-
126
- # Patch the _agenerate method if it exists
127
- if hasattr(ChatAnthropic, "_agenerate"):
128
- original_agenerate = ChatAnthropic._agenerate
129
-
130
- if not hasattr(original_agenerate, "_osmosis_aiped"):
131
-
132
- @functools.wraps(original_agenerate)
133
- async def wrapped_agenerate(
134
- self, messages, stop=None, run_manager=None, **kwargs
135
- ):
136
- # Get the response
137
- response = await original_agenerate(
138
- self, messages, stop=stop, run_manager=run_manager, **kwargs
139
- )
140
-
141
- # Send to OSMOSIS if enabled
142
- if utils.enabled:
143
- # Create payload
144
- model_name = getattr(self, model_attr, "unknown_model")
145
- payload = {
146
- "model_type": "ChatAnthropic",
147
- "model_name": model_name,
148
- "messages": [
149
- str(msg) for msg in messages
150
- ], # Convert to strings for serialization
151
- "response": str(
152
- response
153
- ), # Convert to string since it may not be serializable
154
- "kwargs": {"stop": stop, **kwargs},
155
- }
156
-
157
- send_to_osmosis(
158
- query={
159
- "type": "langchain_anthropic_agenerate",
160
- "messages": [str(msg) for msg in messages],
161
- "model": model_name,
162
- },
163
- response=payload,
164
- status=200,
165
- )
166
-
167
- return response
168
-
169
- wrapped_agenerate._osmosis_aiped = True
170
- ChatAnthropic._agenerate = wrapped_agenerate
171
- logger.info("Successfully wrapped ChatAnthropic._agenerate method")
172
- else:
173
- logger.info("ChatAnthropic._agenerate already wrapped.")
174
- else:
175
- logger.info("ChatAnthropic does not have a _agenerate method, skipping.")
176
-
177
- # Patch _call method if it exists (used in newer versions)
178
- if hasattr(ChatAnthropic, "_call"):
179
- original_call = ChatAnthropic._call
180
-
181
- if not hasattr(original_call, "_osmosis_aiped"):
182
-
183
- @functools.wraps(original_call)
184
- def wrapped_call(self, messages, stop=None, run_manager=None, **kwargs):
185
- try:
186
- # Get the response
187
- response = original_call(
188
- self, messages, stop=stop, run_manager=run_manager, **kwargs
189
- )
190
-
191
- # Send to OSMOSIS if enabled
192
- if utils.enabled:
193
- # Create payload
194
- model_name = getattr(self, model_attr, "unknown_model")
195
- payload = {
196
- "model_type": "ChatAnthropic",
197
- "model_name": model_name,
198
- "messages": [
199
- str(msg) for msg in messages
200
- ], # Convert to strings for serialization
201
- "response": str(response),
202
- "kwargs": {"stop": stop, **kwargs},
203
- }
204
-
205
- send_to_osmosis(
206
- query={
207
- "type": "langchain_anthropic_call",
208
- "messages": [str(msg) for msg in messages],
209
- "model": model_name,
210
- },
211
- response=payload,
212
- status=200,
213
- )
214
-
215
- return response
216
- except TypeError as e:
217
- # Handle parameter mismatch gracefully
218
- logger.warning(
219
- f"TypeError in wrapped _call: {e}, trying without run_manager"
220
- )
221
- # Try calling without run_manager (older versions)
222
- response = original_call(self, messages, stop=stop, **kwargs)
223
-
224
- # Send to OSMOSIS if enabled
225
- if utils.enabled:
226
- model_name = getattr(self, model_attr, "unknown_model")
227
- payload = {
228
- "model_type": "ChatAnthropic",
229
- "model_name": model_name,
230
- "messages": [str(msg) for msg in messages],
231
- "response": str(response),
232
- "kwargs": {"stop": stop, **kwargs},
233
- }
234
-
235
- send_to_osmosis(
236
- query={
237
- "type": "langchain_anthropic_call_fallback",
238
- "messages": [str(msg) for msg in messages],
239
- "model": model_name,
240
- },
241
- response=payload,
242
- status=200,
243
- )
244
-
245
- return response
246
-
247
- wrapped_call._osmosis_aiped = True
248
- ChatAnthropic._call = wrapped_call
249
- logger.info("Successfully wrapped ChatAnthropic._call method")
250
- else:
251
- logger.info("ChatAnthropic._call already wrapped.")
252
- else:
253
- logger.info("ChatAnthropic does not have a _call method, skipping.")
254
-
255
- # Patch _acall method if it exists
256
- if hasattr(ChatAnthropic, "_acall"):
257
- original_acall = ChatAnthropic._acall
258
-
259
- if not hasattr(original_acall, "_osmosis_aiped"):
260
-
261
- @functools.wraps(original_acall)
262
- async def wrapped_acall(
263
- self, messages, stop=None, run_manager=None, **kwargs
264
- ):
265
- try:
266
- # Get the response
267
- response = await original_acall(
268
- self, messages, stop=stop, run_manager=run_manager, **kwargs
269
- )
270
-
271
- # Send to OSMOSIS if enabled
272
- if utils.enabled:
273
- # Create payload
274
- model_name = getattr(self, model_attr, "unknown_model")
275
- payload = {
276
- "model_type": "ChatAnthropic",
277
- "model_name": model_name,
278
- "messages": [
279
- str(msg) for msg in messages
280
- ], # Convert to strings for serialization
281
- "response": str(response),
282
- "kwargs": {"stop": stop, **kwargs},
283
- }
284
-
285
- send_to_osmosis(
286
- query={
287
- "type": "langchain_anthropic_acall",
288
- "messages": [str(msg) for msg in messages],
289
- "model": model_name,
290
- },
291
- response=payload,
292
- status=200,
293
- )
294
-
295
- return response
296
- except TypeError as e:
297
- # Handle parameter mismatch gracefully
298
- logger.warning(
299
- f"TypeError in wrapped _acall: {e}, trying without run_manager"
300
- )
301
- # Try calling without run_manager (older versions)
302
- response = await original_acall(
303
- self, messages, stop=stop, **kwargs
304
- )
305
-
306
- # Send to OSMOSIS if enabled
307
- if utils.enabled:
308
- model_name = getattr(self, model_attr, "unknown_model")
309
- payload = {
310
- "model_type": "ChatAnthropic",
311
- "model_name": model_name,
312
- "messages": [str(msg) for msg in messages],
313
- "response": str(response),
314
- "kwargs": {"stop": stop, **kwargs},
315
- }
316
-
317
- send_to_osmosis(
318
- query={
319
- "type": "langchain_anthropic_acall_fallback",
320
- "messages": [str(msg) for msg in messages],
321
- "model": model_name,
322
- },
323
- response=payload,
324
- status=200,
325
- )
326
-
327
- return response
328
-
329
- wrapped_acall._osmosis_aiped = True
330
- ChatAnthropic._acall = wrapped_acall
331
- logger.info("Successfully wrapped ChatAnthropic._acall method")
332
- else:
333
- logger.info("ChatAnthropic._acall already wrapped.")
334
- else:
335
- logger.info("ChatAnthropic does not have a _acall method, skipping.")
336
-
337
- except Exception as e:
338
- logger.error(f"Failed to patch langchain-anthropic chat model classes: {e}")