osmosis-ai 0.1.8__py3-none-any.whl → 0.2.4__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.
- osmosis_ai/__init__.py +19 -132
- osmosis_ai/cli.py +50 -0
- osmosis_ai/cli_commands.py +181 -0
- osmosis_ai/cli_services/__init__.py +60 -0
- osmosis_ai/cli_services/config.py +410 -0
- osmosis_ai/cli_services/dataset.py +175 -0
- osmosis_ai/cli_services/engine.py +421 -0
- osmosis_ai/cli_services/errors.py +7 -0
- osmosis_ai/cli_services/reporting.py +307 -0
- osmosis_ai/cli_services/session.py +174 -0
- osmosis_ai/cli_services/shared.py +209 -0
- osmosis_ai/consts.py +2 -16
- osmosis_ai/providers/__init__.py +36 -0
- osmosis_ai/providers/anthropic_provider.py +85 -0
- osmosis_ai/providers/base.py +60 -0
- osmosis_ai/providers/gemini_provider.py +314 -0
- osmosis_ai/providers/openai_family.py +607 -0
- osmosis_ai/providers/shared.py +92 -0
- osmosis_ai/rubric_eval.py +356 -0
- osmosis_ai/rubric_types.py +49 -0
- osmosis_ai/utils.py +284 -89
- osmosis_ai-0.2.4.dist-info/METADATA +314 -0
- osmosis_ai-0.2.4.dist-info/RECORD +27 -0
- osmosis_ai-0.2.4.dist-info/entry_points.txt +4 -0
- {osmosis_ai-0.1.8.dist-info → osmosis_ai-0.2.4.dist-info}/licenses/LICENSE +1 -1
- osmosis_ai/adapters/__init__.py +0 -9
- osmosis_ai/adapters/anthropic.py +0 -502
- osmosis_ai/adapters/langchain.py +0 -674
- osmosis_ai/adapters/langchain_anthropic.py +0 -338
- osmosis_ai/adapters/langchain_openai.py +0 -596
- osmosis_ai/adapters/openai.py +0 -900
- osmosis_ai/logger.py +0 -77
- osmosis_ai-0.1.8.dist-info/METADATA +0 -281
- osmosis_ai-0.1.8.dist-info/RECORD +0 -15
- {osmosis_ai-0.1.8.dist-info → osmosis_ai-0.2.4.dist-info}/WHEEL +0 -0
- {osmosis_ai-0.1.8.dist-info → osmosis_ai-0.2.4.dist-info}/top_level.txt +0 -0
osmosis_ai/adapters/anthropic.py
DELETED
|
@@ -1,502 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Anthropic adapter for Osmosis
|
|
3
|
-
|
|
4
|
-
This module provides monkey patching for the Anthropic Python client.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
import functools
|
|
8
|
-
import sys
|
|
9
|
-
|
|
10
|
-
from osmosis_ai.utils import send_to_osmosis
|
|
11
|
-
from osmosis_ai import utils
|
|
12
|
-
from osmosis_ai.logger import logger
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def wrap_anthropic() -> None:
|
|
16
|
-
"""
|
|
17
|
-
Monkey patch Anthropic's client to send all prompts and responses to OSMOSIS.
|
|
18
|
-
|
|
19
|
-
This function should be called before creating any Anthropic client instances.
|
|
20
|
-
|
|
21
|
-
Features supported:
|
|
22
|
-
- Basic message completions
|
|
23
|
-
- Async message completions
|
|
24
|
-
- Tool use (function calling)
|
|
25
|
-
- Tool responses
|
|
26
|
-
- Streaming (if available)
|
|
27
|
-
"""
|
|
28
|
-
try:
|
|
29
|
-
import anthropic
|
|
30
|
-
except ImportError:
|
|
31
|
-
logger.debug("anthropic package is not installed.")
|
|
32
|
-
return
|
|
33
|
-
|
|
34
|
-
logger.info(f"Wrapping Anthropic client, package version: {anthropic.__version__}")
|
|
35
|
-
|
|
36
|
-
# Check which version of Anthropic SDK we're dealing with
|
|
37
|
-
# v1.x has a "resources" attribute, v0.x doesn't
|
|
38
|
-
is_v1 = hasattr(anthropic, "resources")
|
|
39
|
-
|
|
40
|
-
if is_v1:
|
|
41
|
-
# Handle newer v1.x SDK
|
|
42
|
-
logger.info("Detected Anthropic SDK v1.x")
|
|
43
|
-
_ai_anthropic_v1(anthropic)
|
|
44
|
-
else:
|
|
45
|
-
# Handle older v0.x SDK
|
|
46
|
-
logger.info("Detected Anthropic SDK v0.x")
|
|
47
|
-
_ai_anthropic_v0(anthropic)
|
|
48
|
-
|
|
49
|
-
logger.info("Anthropic client has been wrapped by osmosis-ai.")
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
def _ai_anthropic_v1(anthropic_module):
|
|
53
|
-
"""Handle wrapping for newer v1.x SDK with resources structure"""
|
|
54
|
-
try:
|
|
55
|
-
# Get the resources.messages module and class
|
|
56
|
-
messages_module = anthropic_module.resources.messages
|
|
57
|
-
messages_class = messages_module.Messages
|
|
58
|
-
|
|
59
|
-
logger.info(f"Found Anthropic messages class: {messages_class}")
|
|
60
|
-
|
|
61
|
-
# Patch the Messages.create method
|
|
62
|
-
original_messages_create = messages_class.create
|
|
63
|
-
logger.info(f"Original create method: {original_messages_create}")
|
|
64
|
-
|
|
65
|
-
if not hasattr(original_messages_create, "_osmosis_aiped"):
|
|
66
|
-
|
|
67
|
-
@functools.wraps(original_messages_create)
|
|
68
|
-
def wrapped_messages_create(self, *args, **kwargs):
|
|
69
|
-
logger.debug(
|
|
70
|
-
f"Wrapped create called with args: {args}, kwargs: {kwargs}"
|
|
71
|
-
)
|
|
72
|
-
try:
|
|
73
|
-
# Check if the call includes tool use parameters
|
|
74
|
-
has_tools = "tools" in kwargs
|
|
75
|
-
if has_tools:
|
|
76
|
-
logger.debug(
|
|
77
|
-
f"Tool use detected with {len(kwargs['tools'])} tools"
|
|
78
|
-
)
|
|
79
|
-
|
|
80
|
-
# Check if this is a tool response message
|
|
81
|
-
if "messages" in kwargs:
|
|
82
|
-
for message in kwargs["messages"]:
|
|
83
|
-
if message.get("role") == "user" and isinstance(
|
|
84
|
-
message.get("content"), list
|
|
85
|
-
):
|
|
86
|
-
for content_item in message["content"]:
|
|
87
|
-
if (
|
|
88
|
-
isinstance(content_item, dict)
|
|
89
|
-
and content_item.get("type") == "tool_response"
|
|
90
|
-
):
|
|
91
|
-
logger.debug(
|
|
92
|
-
"Tool response detected in messages"
|
|
93
|
-
)
|
|
94
|
-
break
|
|
95
|
-
|
|
96
|
-
response = original_messages_create(self, *args, **kwargs)
|
|
97
|
-
|
|
98
|
-
if utils.enabled:
|
|
99
|
-
logger.debug("Sending success to OSMOSIS (success)")
|
|
100
|
-
send_to_osmosis(
|
|
101
|
-
query=kwargs,
|
|
102
|
-
response=(
|
|
103
|
-
response.model_dump()
|
|
104
|
-
if hasattr(response, "model_dump")
|
|
105
|
-
else response
|
|
106
|
-
),
|
|
107
|
-
status=200,
|
|
108
|
-
)
|
|
109
|
-
|
|
110
|
-
return response
|
|
111
|
-
except Exception as e:
|
|
112
|
-
logger.error(f"Error in wrapped create: {e}")
|
|
113
|
-
if utils.enabled:
|
|
114
|
-
error_response = {"error": str(e)}
|
|
115
|
-
send_to_osmosis(
|
|
116
|
-
query=kwargs, response=error_response, status=400
|
|
117
|
-
)
|
|
118
|
-
logger.debug("Sending error to OSMOSIS (success)")
|
|
119
|
-
raise # Re-raise the exception
|
|
120
|
-
|
|
121
|
-
wrapped_messages_create._osmosis_aiped = True
|
|
122
|
-
messages_class.create = wrapped_messages_create
|
|
123
|
-
logger.info("Successfully wrapped Messages.create method")
|
|
124
|
-
|
|
125
|
-
# Directly wrap the AsyncAnthropic client
|
|
126
|
-
try:
|
|
127
|
-
# Get the AsyncAnthropic class
|
|
128
|
-
AsyncAnthropicClass = anthropic_module.AsyncAnthropic
|
|
129
|
-
logger.info(f"Found AsyncAnthropic class: {AsyncAnthropicClass}")
|
|
130
|
-
|
|
131
|
-
# Store the original __init__ to keep track of created instances
|
|
132
|
-
original_async_init = AsyncAnthropicClass.__init__
|
|
133
|
-
|
|
134
|
-
if not hasattr(original_async_init, "_osmosis_aiped"):
|
|
135
|
-
|
|
136
|
-
@functools.wraps(original_async_init)
|
|
137
|
-
def wrapped_async_init(self, *args, **kwargs):
|
|
138
|
-
# Call the original init
|
|
139
|
-
result = original_async_init(self, *args, **kwargs)
|
|
140
|
-
|
|
141
|
-
logger.info(
|
|
142
|
-
"Wrapping new AsyncAnthropic instance's messages.create method"
|
|
143
|
-
)
|
|
144
|
-
|
|
145
|
-
# Get the messages client from this instance
|
|
146
|
-
async_messages = self.messages
|
|
147
|
-
|
|
148
|
-
# Store and patch the create method if not already wrapped
|
|
149
|
-
if hasattr(async_messages, "create") and not hasattr(
|
|
150
|
-
async_messages.create, "_osmosis_aiped"
|
|
151
|
-
):
|
|
152
|
-
original_async_messages_create = async_messages.create
|
|
153
|
-
|
|
154
|
-
@functools.wraps(original_async_messages_create)
|
|
155
|
-
async def wrapped_async_messages_create(*args, **kwargs):
|
|
156
|
-
logger.debug(
|
|
157
|
-
f"AsyncAnthropic.messages.create called with args: {args}, kwargs: {kwargs}"
|
|
158
|
-
)
|
|
159
|
-
try:
|
|
160
|
-
response = await original_async_messages_create(
|
|
161
|
-
*args, **kwargs
|
|
162
|
-
)
|
|
163
|
-
|
|
164
|
-
if utils.enabled:
|
|
165
|
-
logger.debug(
|
|
166
|
-
"Sending AsyncAnthropic response to OSMOSIS (success)"
|
|
167
|
-
)
|
|
168
|
-
send_to_osmosis(
|
|
169
|
-
query=kwargs,
|
|
170
|
-
response=(
|
|
171
|
-
response.model_dump()
|
|
172
|
-
if hasattr(response, "model_dump")
|
|
173
|
-
else response
|
|
174
|
-
),
|
|
175
|
-
status=200,
|
|
176
|
-
)
|
|
177
|
-
|
|
178
|
-
return response
|
|
179
|
-
except Exception as e:
|
|
180
|
-
logger.error(
|
|
181
|
-
f"Error in wrapped AsyncAnthropic.messages.create: {e}"
|
|
182
|
-
)
|
|
183
|
-
if utils.enabled:
|
|
184
|
-
logger.debug(
|
|
185
|
-
"Sending AsyncAnthropic error to OSMOSIS"
|
|
186
|
-
)
|
|
187
|
-
error_response = {"error": str(e)}
|
|
188
|
-
send_to_osmosis(
|
|
189
|
-
query=kwargs,
|
|
190
|
-
response=error_response,
|
|
191
|
-
status=400,
|
|
192
|
-
)
|
|
193
|
-
raise # Re-raise the exception
|
|
194
|
-
|
|
195
|
-
wrapped_async_messages_create._osmosis_aiped = True
|
|
196
|
-
async_messages.create = wrapped_async_messages_create
|
|
197
|
-
logger.info(
|
|
198
|
-
"Successfully wrapped AsyncAnthropic.messages.create method"
|
|
199
|
-
)
|
|
200
|
-
|
|
201
|
-
return result
|
|
202
|
-
|
|
203
|
-
wrapped_async_init._osmosis_aiped = True
|
|
204
|
-
AsyncAnthropicClass.__init__ = wrapped_async_init
|
|
205
|
-
logger.info(
|
|
206
|
-
"Successfully wrapped AsyncAnthropic.__init__ to patch message methods on new instances"
|
|
207
|
-
)
|
|
208
|
-
except (ImportError, AttributeError) as e:
|
|
209
|
-
logger.warning(
|
|
210
|
-
f"AsyncAnthropic class not found or has unexpected structure: {e}"
|
|
211
|
-
)
|
|
212
|
-
|
|
213
|
-
# For compatibility, still try to patch the old-style acreate method if it exists
|
|
214
|
-
if hasattr(messages_class, "acreate"):
|
|
215
|
-
original_acreate = messages_class.acreate
|
|
216
|
-
if not hasattr(original_acreate, "_osmosis_aiped"):
|
|
217
|
-
|
|
218
|
-
@functools.wraps(original_acreate)
|
|
219
|
-
async def wrapped_acreate(self, *args, **kwargs):
|
|
220
|
-
logger.debug(
|
|
221
|
-
f"Wrapped async create called with args: {args}, kwargs: {kwargs}"
|
|
222
|
-
)
|
|
223
|
-
try:
|
|
224
|
-
# Check if the async call includes tool use parameters
|
|
225
|
-
has_tools = "tools" in kwargs
|
|
226
|
-
if has_tools:
|
|
227
|
-
logger.debug(
|
|
228
|
-
f"Async tool use detected with {len(kwargs['tools'])} tools"
|
|
229
|
-
)
|
|
230
|
-
|
|
231
|
-
if "messages" in kwargs:
|
|
232
|
-
for message in kwargs["messages"]:
|
|
233
|
-
if message.get("role") == "user" and isinstance(
|
|
234
|
-
message.get("content"), list
|
|
235
|
-
):
|
|
236
|
-
for content_item in message["content"]:
|
|
237
|
-
if (
|
|
238
|
-
isinstance(content_item, dict)
|
|
239
|
-
and content_item.get("type")
|
|
240
|
-
== "tool_response"
|
|
241
|
-
):
|
|
242
|
-
logger.debug(
|
|
243
|
-
"Async tool response detected in messages"
|
|
244
|
-
)
|
|
245
|
-
break
|
|
246
|
-
|
|
247
|
-
response = await original_acreate(self, *args, **kwargs)
|
|
248
|
-
|
|
249
|
-
if utils.enabled:
|
|
250
|
-
logger.debug("Sending async response to OSMOSIS (success)")
|
|
251
|
-
send_to_osmosis(
|
|
252
|
-
query=kwargs,
|
|
253
|
-
response=(
|
|
254
|
-
response.model_dump()
|
|
255
|
-
if hasattr(response, "model_dump")
|
|
256
|
-
else response
|
|
257
|
-
),
|
|
258
|
-
status=200,
|
|
259
|
-
)
|
|
260
|
-
|
|
261
|
-
return response
|
|
262
|
-
except Exception as e:
|
|
263
|
-
logger.error(f"Error in wrapped async create: {e}")
|
|
264
|
-
if utils.enabled:
|
|
265
|
-
logger.debug("Sending async error to OSMOSIS")
|
|
266
|
-
error_response = {"error": str(e)}
|
|
267
|
-
send_to_osmosis(
|
|
268
|
-
query=kwargs, response=error_response, status=400
|
|
269
|
-
)
|
|
270
|
-
raise # Re-raise the exception
|
|
271
|
-
|
|
272
|
-
wrapped_acreate._osmosis_aiped = True
|
|
273
|
-
messages_class.acreate = wrapped_acreate
|
|
274
|
-
logger.info("Successfully wrapped Messages.acreate method")
|
|
275
|
-
else:
|
|
276
|
-
logger.info("No async acreate method found in Messages class")
|
|
277
|
-
|
|
278
|
-
# Check if Completions exists and wrap it if it does
|
|
279
|
-
try:
|
|
280
|
-
completions_module = anthropic_module.resources.completions
|
|
281
|
-
completions_class = completions_module.Completions
|
|
282
|
-
|
|
283
|
-
original_completions_create = completions_class.create
|
|
284
|
-
if not hasattr(original_completions_create, "_osmosis_aiped"):
|
|
285
|
-
|
|
286
|
-
@functools.wraps(original_completions_create)
|
|
287
|
-
def wrapped_completions_create(self, *args, **kwargs):
|
|
288
|
-
response = original_completions_create(self, *args, **kwargs)
|
|
289
|
-
|
|
290
|
-
if utils.enabled:
|
|
291
|
-
send_to_osmosis(
|
|
292
|
-
query=kwargs,
|
|
293
|
-
response=(
|
|
294
|
-
response.model_dump()
|
|
295
|
-
if hasattr(response, "model_dump")
|
|
296
|
-
else response
|
|
297
|
-
),
|
|
298
|
-
status=200,
|
|
299
|
-
)
|
|
300
|
-
|
|
301
|
-
return response
|
|
302
|
-
|
|
303
|
-
wrapped_completions_create._osmosis_aiped = True
|
|
304
|
-
completions_class.create = wrapped_completions_create
|
|
305
|
-
|
|
306
|
-
# Patch the async create method if it exists
|
|
307
|
-
if hasattr(completions_class, "acreate"):
|
|
308
|
-
original_completions_acreate = completions_class.acreate
|
|
309
|
-
if not hasattr(original_completions_acreate, "_osmosis_aiped"):
|
|
310
|
-
|
|
311
|
-
@functools.wraps(original_completions_acreate)
|
|
312
|
-
async def wrapped_completions_acreate(self, *args, **kwargs):
|
|
313
|
-
logger.debug(
|
|
314
|
-
f"Wrapped Completions async create called with args: {args}, kwargs: {kwargs}"
|
|
315
|
-
)
|
|
316
|
-
try:
|
|
317
|
-
response = await original_completions_acreate(
|
|
318
|
-
self, *args, **kwargs
|
|
319
|
-
)
|
|
320
|
-
|
|
321
|
-
if utils.enabled:
|
|
322
|
-
logger.debug(
|
|
323
|
-
"Sending Completions async response to OSMOSIS (success)"
|
|
324
|
-
)
|
|
325
|
-
send_to_osmosis(
|
|
326
|
-
query=kwargs,
|
|
327
|
-
response=(
|
|
328
|
-
response.model_dump()
|
|
329
|
-
if hasattr(response, "model_dump")
|
|
330
|
-
else response
|
|
331
|
-
),
|
|
332
|
-
status=200,
|
|
333
|
-
)
|
|
334
|
-
|
|
335
|
-
return response
|
|
336
|
-
except Exception as e:
|
|
337
|
-
logger.error(
|
|
338
|
-
f"Error in wrapped Completions async create: {e}"
|
|
339
|
-
)
|
|
340
|
-
if utils.enabled:
|
|
341
|
-
logger.debug(
|
|
342
|
-
"Sending Completions async error to OSMOSIS"
|
|
343
|
-
)
|
|
344
|
-
error_response = {"error": str(e)}
|
|
345
|
-
send_to_osmosis(
|
|
346
|
-
query=kwargs,
|
|
347
|
-
response=error_response,
|
|
348
|
-
status=400,
|
|
349
|
-
)
|
|
350
|
-
raise # Re-raise the exception
|
|
351
|
-
|
|
352
|
-
wrapped_completions_acreate._osmosis_aiped = True
|
|
353
|
-
completions_class.acreate = wrapped_completions_acreate
|
|
354
|
-
logger.info("Successfully wrapped Completions.acreate method")
|
|
355
|
-
else:
|
|
356
|
-
logger.info("Completions.acreate already wrapped")
|
|
357
|
-
else:
|
|
358
|
-
logger.info("No async acreate method found in Completions class")
|
|
359
|
-
else:
|
|
360
|
-
logger.info("Completions.create already wrapped")
|
|
361
|
-
except (ImportError, AttributeError) as e:
|
|
362
|
-
# Completions module may not exist in this version
|
|
363
|
-
logger.warning(
|
|
364
|
-
f"Completions module not found or has an unexpected structure: {e}"
|
|
365
|
-
)
|
|
366
|
-
except Exception as e:
|
|
367
|
-
logger.error(f"Error wrapping Anthropic v1.x client: {e}")
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
def _ai_anthropic_v0(anthropic_module):
|
|
371
|
-
"""Handle wrapping for older v0.x SDK without resources structure"""
|
|
372
|
-
try:
|
|
373
|
-
# Get the main Anthropic class
|
|
374
|
-
AnthropicClass = anthropic_module.Anthropic
|
|
375
|
-
logger.info(f"Found Anthropic class: {AnthropicClass}")
|
|
376
|
-
|
|
377
|
-
# Patch the create_completion method for v0.x
|
|
378
|
-
if hasattr(AnthropicClass, "complete"):
|
|
379
|
-
original_complete = AnthropicClass.complete
|
|
380
|
-
|
|
381
|
-
if not hasattr(original_complete, "_osmosis_aiped"):
|
|
382
|
-
|
|
383
|
-
@functools.wraps(original_complete)
|
|
384
|
-
def wrapped_complete(self, *args, **kwargs):
|
|
385
|
-
logger.debug(
|
|
386
|
-
f"Wrapped complete called with args: {args}, kwargs: {kwargs}"
|
|
387
|
-
)
|
|
388
|
-
try:
|
|
389
|
-
response = original_complete(self, *args, **kwargs)
|
|
390
|
-
|
|
391
|
-
if utils.enabled:
|
|
392
|
-
logger.debug("Sending success to OSMOSIS (success)")
|
|
393
|
-
send_to_osmosis(query=kwargs, response=response, status=200)
|
|
394
|
-
|
|
395
|
-
return response
|
|
396
|
-
except Exception as e:
|
|
397
|
-
logger.error(f"Error in wrapped complete: {e}")
|
|
398
|
-
if utils.enabled:
|
|
399
|
-
error_response = {"error": str(e)}
|
|
400
|
-
send_to_osmosis(
|
|
401
|
-
query=kwargs, response=error_response, status=400
|
|
402
|
-
)
|
|
403
|
-
logger.debug("Sending error to OSMOSIS (success)")
|
|
404
|
-
raise # Re-raise the exception
|
|
405
|
-
|
|
406
|
-
wrapped_complete._osmosis_aiped = True
|
|
407
|
-
AnthropicClass.complete = wrapped_complete
|
|
408
|
-
logger.info("Successfully wrapped Anthropic.complete method")
|
|
409
|
-
|
|
410
|
-
# Patch the create_message method for v0.x if it exists
|
|
411
|
-
if hasattr(AnthropicClass, "messages"):
|
|
412
|
-
logger.info("Found messages client on Anthropic class")
|
|
413
|
-
|
|
414
|
-
if hasattr(AnthropicClass.messages, "create"):
|
|
415
|
-
original_messages_create = AnthropicClass.messages.create
|
|
416
|
-
|
|
417
|
-
if not hasattr(original_messages_create, "_osmosis_aiped"):
|
|
418
|
-
|
|
419
|
-
@functools.wraps(original_messages_create)
|
|
420
|
-
def wrapped_messages_create(self, *args, **kwargs):
|
|
421
|
-
logger.debug(
|
|
422
|
-
f"Wrapped messages.create called with args: {args}, kwargs: {kwargs}"
|
|
423
|
-
)
|
|
424
|
-
try:
|
|
425
|
-
response = original_messages_create(self, *args, **kwargs)
|
|
426
|
-
|
|
427
|
-
if utils.enabled:
|
|
428
|
-
logger.debug("Sending success to OSMOSIS (success)")
|
|
429
|
-
send_to_osmosis(
|
|
430
|
-
query=kwargs, response=response, status=200
|
|
431
|
-
)
|
|
432
|
-
|
|
433
|
-
return response
|
|
434
|
-
except Exception as e:
|
|
435
|
-
logger.error(f"Error in wrapped messages.create: {e}")
|
|
436
|
-
if utils.enabled:
|
|
437
|
-
error_response = {"error": str(e)}
|
|
438
|
-
send_to_osmosis(
|
|
439
|
-
query=kwargs, response=error_response, status=400
|
|
440
|
-
)
|
|
441
|
-
logger.debug("Sending error to OSMOSIS (success)")
|
|
442
|
-
raise # Re-raise the exception
|
|
443
|
-
|
|
444
|
-
wrapped_messages_create._osmosis_aiped = True
|
|
445
|
-
AnthropicClass.messages.create = wrapped_messages_create
|
|
446
|
-
logger.info("Successfully wrapped Anthropic.messages.create method")
|
|
447
|
-
|
|
448
|
-
# Also try to patch instance methods by monkeypatching the __init__
|
|
449
|
-
original_init = AnthropicClass.__init__
|
|
450
|
-
|
|
451
|
-
if not hasattr(original_init, "_osmosis_aiped"):
|
|
452
|
-
|
|
453
|
-
@functools.wraps(original_init)
|
|
454
|
-
def wrapped_init(self, *args, **kwargs):
|
|
455
|
-
# Call the original init
|
|
456
|
-
result = original_init(self, *args, **kwargs)
|
|
457
|
-
|
|
458
|
-
# Wrap the instance methods if they exist
|
|
459
|
-
if hasattr(self, "complete") and not hasattr(
|
|
460
|
-
self.complete, "_osmosis_aiped"
|
|
461
|
-
):
|
|
462
|
-
original_instance_complete = self.complete
|
|
463
|
-
|
|
464
|
-
@functools.wraps(original_instance_complete)
|
|
465
|
-
def wrapped_instance_complete(*args, **kwargs):
|
|
466
|
-
logger.debug(
|
|
467
|
-
f"Instance complete called with args: {args}, kwargs: {kwargs}"
|
|
468
|
-
)
|
|
469
|
-
try:
|
|
470
|
-
response = original_instance_complete(*args, **kwargs)
|
|
471
|
-
|
|
472
|
-
if utils.enabled:
|
|
473
|
-
logger.debug("Sending success to OSMOSIS (success)")
|
|
474
|
-
send_to_osmosis(
|
|
475
|
-
query=kwargs, response=response, status=200
|
|
476
|
-
)
|
|
477
|
-
|
|
478
|
-
return response
|
|
479
|
-
except Exception as e:
|
|
480
|
-
logger.error(f"Error in wrapped instance complete: {e}")
|
|
481
|
-
if utils.enabled:
|
|
482
|
-
error_response = {"error": str(e)}
|
|
483
|
-
send_to_osmosis(
|
|
484
|
-
query=kwargs,
|
|
485
|
-
response=error_response,
|
|
486
|
-
status=400,
|
|
487
|
-
)
|
|
488
|
-
raise
|
|
489
|
-
|
|
490
|
-
wrapped_instance_complete._osmosis_aiped = True
|
|
491
|
-
self.complete = wrapped_instance_complete
|
|
492
|
-
|
|
493
|
-
return result
|
|
494
|
-
|
|
495
|
-
wrapped_init._osmosis_aiped = True
|
|
496
|
-
AnthropicClass.__init__ = wrapped_init
|
|
497
|
-
logger.info(
|
|
498
|
-
"Successfully wrapped Anthropic.__init__ to patch instance methods"
|
|
499
|
-
)
|
|
500
|
-
|
|
501
|
-
except Exception as e:
|
|
502
|
-
logger.error(f"Error wrapping Anthropic v0.x client: {e}")
|