veris-ai 1.13.0__py3-none-any.whl → 1.14.1__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 veris-ai might be problematic. Click here for more details.
- veris_ai/api_client.py +20 -8
- veris_ai/tool_mock.py +14 -2
- veris_ai/utils.py +72 -0
- {veris_ai-1.13.0.dist-info → veris_ai-1.14.1.dist-info}/METADATA +1 -1
- {veris_ai-1.13.0.dist-info → veris_ai-1.14.1.dist-info}/RECORD +7 -7
- {veris_ai-1.13.0.dist-info → veris_ai-1.14.1.dist-info}/WHEEL +0 -0
- {veris_ai-1.13.0.dist-info → veris_ai-1.14.1.dist-info}/licenses/LICENSE +0 -0
veris_ai/api_client.py
CHANGED
|
@@ -20,9 +20,15 @@ class SimulatorAPIClient:
|
|
|
20
20
|
changes reflected without recreating the singleton.
|
|
21
21
|
"""
|
|
22
22
|
|
|
23
|
-
def __init__(self) -> None:
|
|
23
|
+
def __init__(self, timeout: float | None = None, base_url: str | None = None) -> None:
|
|
24
24
|
"""Initialize the API client with static timeout configuration."""
|
|
25
|
-
self.
|
|
25
|
+
self._timeout = timeout or float(os.getenv("VERIS_MOCK_TIMEOUT", "300.0"))
|
|
26
|
+
self._base_url = base_url
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def base_url(self) -> str:
|
|
30
|
+
"""Get the resolved base URL."""
|
|
31
|
+
return self._get_base_url()
|
|
26
32
|
|
|
27
33
|
def _get_base_url(self) -> str:
|
|
28
34
|
"""Resolve the base URL from environment.
|
|
@@ -33,7 +39,7 @@ class SimulatorAPIClient:
|
|
|
33
39
|
(do not fall back). This supports tests expecting connection
|
|
34
40
|
failures when an invalid endpoint is provided.
|
|
35
41
|
"""
|
|
36
|
-
return os.getenv("VERIS_API_URL") or "https://simulator.api.veris.ai"
|
|
42
|
+
return self._base_url or os.getenv("VERIS_API_URL") or "https://simulator.api.veris.ai"
|
|
37
43
|
|
|
38
44
|
def _build_headers(self) -> dict[str, str] | None:
|
|
39
45
|
"""Build headers including OpenTelemetry tracing and API key."""
|
|
@@ -55,7 +61,7 @@ class SimulatorAPIClient:
|
|
|
55
61
|
if not endpoint.startswith(("http://", "https://")):
|
|
56
62
|
raise httpx.ConnectError("Invalid endpoint URL (not absolute): {endpoint}")
|
|
57
63
|
|
|
58
|
-
with httpx.Client(timeout=self.
|
|
64
|
+
with httpx.Client(timeout=self._timeout) as client:
|
|
59
65
|
response = client.post(endpoint, json=payload, headers=headers)
|
|
60
66
|
response.raise_for_status()
|
|
61
67
|
return response.json() if response.content else None
|
|
@@ -73,7 +79,7 @@ class SimulatorAPIClient:
|
|
|
73
79
|
error_msg = f"Invalid endpoint URL (not absolute): {endpoint}"
|
|
74
80
|
raise httpx.ConnectError(error_msg)
|
|
75
81
|
|
|
76
|
-
async with httpx.AsyncClient(timeout=self.
|
|
82
|
+
async with httpx.AsyncClient(timeout=self._timeout) as client:
|
|
77
83
|
response = await client.post(endpoint, json=payload, headers=headers)
|
|
78
84
|
response.raise_for_status()
|
|
79
85
|
return response.json() if response.content else None
|
|
@@ -81,15 +87,15 @@ class SimulatorAPIClient:
|
|
|
81
87
|
@property
|
|
82
88
|
def tool_mock_endpoint(self) -> str:
|
|
83
89
|
"""Get the tool mock endpoint URL."""
|
|
84
|
-
return urljoin(self.
|
|
90
|
+
return urljoin(self.base_url, "v3/tool_mock")
|
|
85
91
|
|
|
86
92
|
def get_log_tool_call_endpoint(self, session_id: str) -> str:
|
|
87
93
|
"""Get the log tool call endpoint URL."""
|
|
88
|
-
return urljoin(self.
|
|
94
|
+
return urljoin(self.base_url, f"v3/log_tool_call?session_id={session_id}")
|
|
89
95
|
|
|
90
96
|
def get_log_tool_response_endpoint(self, session_id: str) -> str:
|
|
91
97
|
"""Get the log tool response endpoint URL."""
|
|
92
|
-
return urljoin(self.
|
|
98
|
+
return urljoin(self.base_url, f"v3/log_tool_response?session_id={session_id}")
|
|
93
99
|
|
|
94
100
|
|
|
95
101
|
# Global singleton instance
|
|
@@ -99,3 +105,9 @@ _api_client = SimulatorAPIClient()
|
|
|
99
105
|
def get_api_client() -> SimulatorAPIClient:
|
|
100
106
|
"""Get the global API client instance."""
|
|
101
107
|
return _api_client
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def set_api_client_params(base_url: str | None = None, timeout: float | None = None) -> None:
|
|
111
|
+
"""Set the global API client instance for testing purposes."""
|
|
112
|
+
global _api_client # noqa: PLW0603
|
|
113
|
+
_api_client = SimulatorAPIClient(base_url=base_url, timeout=timeout)
|
veris_ai/tool_mock.py
CHANGED
|
@@ -16,14 +16,16 @@ from typing import (
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
from veris_ai.models import ResponseExpectation, ToolCallOptions
|
|
19
|
-
from veris_ai.api_client import get_api_client
|
|
19
|
+
from veris_ai.api_client import get_api_client, set_api_client_params
|
|
20
20
|
from veris_ai.utils import (
|
|
21
21
|
convert_to_type,
|
|
22
22
|
execute_callback,
|
|
23
|
+
execute_combined_callback,
|
|
23
24
|
extract_json_schema,
|
|
24
25
|
get_function_parameters,
|
|
25
26
|
get_input_parameters,
|
|
26
27
|
launch_callback_task,
|
|
28
|
+
launch_combined_callback_task,
|
|
27
29
|
)
|
|
28
30
|
|
|
29
31
|
logger = logging.getLogger(__name__)
|
|
@@ -90,6 +92,8 @@ class VerisSDK:
|
|
|
90
92
|
|
|
91
93
|
self._set_session_id(token_data["session_id"])
|
|
92
94
|
self._set_thread_id(token_data["thread_id"])
|
|
95
|
+
if token_data.get("api_url"):
|
|
96
|
+
set_api_client_params(base_url=token_data["api_url"])
|
|
93
97
|
logger.info(
|
|
94
98
|
f"Session ID set to {token_data['session_id']}, "
|
|
95
99
|
f"Thread ID set to {token_data['thread_id']} - mocking enabled"
|
|
@@ -245,13 +249,14 @@ class VerisSDK:
|
|
|
245
249
|
|
|
246
250
|
return decorator
|
|
247
251
|
|
|
248
|
-
def mock( # noqa: C901, PLR0915
|
|
252
|
+
def mock( # noqa: C901, PLR0915, PLR0913
|
|
249
253
|
self,
|
|
250
254
|
mode: Literal["tool", "function"] = "tool",
|
|
251
255
|
expects_response: bool | None = None,
|
|
252
256
|
cache_response: bool | None = None,
|
|
253
257
|
input_callback: Callable[..., Any] | None = None,
|
|
254
258
|
output_callback: Callable[[Any], Any] | None = None,
|
|
259
|
+
combined_callback: Callable[..., Any] | None = None,
|
|
255
260
|
) -> Callable:
|
|
256
261
|
"""Decorator for mocking tool calls.
|
|
257
262
|
|
|
@@ -261,6 +266,7 @@ class VerisSDK:
|
|
|
261
266
|
cache_response: Whether to cache the response
|
|
262
267
|
input_callback: Callable that receives input parameters as individual arguments
|
|
263
268
|
output_callback: Callable that receives the output value
|
|
269
|
+
combined_callback: Callable that receives both input parameters and mock_output
|
|
264
270
|
"""
|
|
265
271
|
response_expectation = (
|
|
266
272
|
ResponseExpectation.NONE
|
|
@@ -306,6 +312,7 @@ class VerisSDK:
|
|
|
306
312
|
input_params = get_input_parameters(func, args, kwargs)
|
|
307
313
|
launch_callback_task(input_callback, input_params, unpack=True)
|
|
308
314
|
launch_callback_task(output_callback, result, unpack=False)
|
|
315
|
+
launch_combined_callback_task(combined_callback, input_params, result)
|
|
309
316
|
|
|
310
317
|
return result
|
|
311
318
|
|
|
@@ -337,6 +344,7 @@ class VerisSDK:
|
|
|
337
344
|
input_params = get_input_parameters(func, args, kwargs)
|
|
338
345
|
execute_callback(input_callback, input_params, unpack=True)
|
|
339
346
|
execute_callback(output_callback, result, unpack=False)
|
|
347
|
+
execute_combined_callback(combined_callback, input_params, result)
|
|
340
348
|
|
|
341
349
|
return result
|
|
342
350
|
|
|
@@ -350,6 +358,7 @@ class VerisSDK:
|
|
|
350
358
|
return_value: Any, # noqa: ANN401
|
|
351
359
|
input_callback: Callable[..., Any] | None = None,
|
|
352
360
|
output_callback: Callable[[Any], Any] | None = None,
|
|
361
|
+
combined_callback: Callable[..., Any] | None = None,
|
|
353
362
|
) -> Callable:
|
|
354
363
|
"""Decorator for stubbing tool calls.
|
|
355
364
|
|
|
@@ -357,6 +366,7 @@ class VerisSDK:
|
|
|
357
366
|
return_value: The value to return when the function is stubbed
|
|
358
367
|
input_callback: Callable that receives input parameters as individual arguments
|
|
359
368
|
output_callback: Callable that receives the output value
|
|
369
|
+
combined_callback: Callable that receives both input parameters and mock_output
|
|
360
370
|
"""
|
|
361
371
|
|
|
362
372
|
def decorator(func: Callable) -> Callable:
|
|
@@ -380,6 +390,7 @@ class VerisSDK:
|
|
|
380
390
|
input_params = get_input_parameters(func, args, kwargs)
|
|
381
391
|
launch_callback_task(input_callback, input_params, unpack=True)
|
|
382
392
|
launch_callback_task(output_callback, return_value, unpack=False)
|
|
393
|
+
launch_combined_callback_task(combined_callback, input_params, return_value)
|
|
383
394
|
|
|
384
395
|
return return_value
|
|
385
396
|
|
|
@@ -397,6 +408,7 @@ class VerisSDK:
|
|
|
397
408
|
input_params = get_input_parameters(func, args, kwargs)
|
|
398
409
|
execute_callback(input_callback, input_params, unpack=True)
|
|
399
410
|
execute_callback(output_callback, return_value, unpack=False)
|
|
411
|
+
execute_combined_callback(combined_callback, input_params, return_value)
|
|
400
412
|
|
|
401
413
|
return return_value
|
|
402
414
|
|
veris_ai/utils.py
CHANGED
|
@@ -489,3 +489,75 @@ def launch_callback_task(
|
|
|
489
489
|
except RuntimeError:
|
|
490
490
|
# If no event loop is running, log a warning
|
|
491
491
|
logger.warning("Cannot launch callback task: no event loop running")
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
def execute_combined_callback(
|
|
495
|
+
callback: Callable | None,
|
|
496
|
+
input_params: dict[str, Any],
|
|
497
|
+
mock_output: Any, # noqa: ANN401
|
|
498
|
+
) -> None:
|
|
499
|
+
"""Execute a combined callback synchronously with input parameters and mock output.
|
|
500
|
+
|
|
501
|
+
Args:
|
|
502
|
+
callback: The callback callable to execute
|
|
503
|
+
input_params: Dictionary of input parameters
|
|
504
|
+
mock_output: The output from the mock/stub call
|
|
505
|
+
|
|
506
|
+
Note:
|
|
507
|
+
Exceptions in callbacks are caught and logged to prevent breaking the main flow.
|
|
508
|
+
"""
|
|
509
|
+
if callback is None:
|
|
510
|
+
return
|
|
511
|
+
|
|
512
|
+
try:
|
|
513
|
+
# Combine input params with mock_output
|
|
514
|
+
combined_data = {**input_params, "mock_output": mock_output}
|
|
515
|
+
# Filter parameters to match callback signature
|
|
516
|
+
filtered_data = filter_callback_parameters(callback, combined_data)
|
|
517
|
+
callback(**filtered_data)
|
|
518
|
+
except Exception as e:
|
|
519
|
+
logger.warning(f"Combined callback execution failed: {e}", exc_info=True)
|
|
520
|
+
|
|
521
|
+
|
|
522
|
+
def launch_combined_callback_task(
|
|
523
|
+
callback: Callable | None,
|
|
524
|
+
input_params: dict[str, Any],
|
|
525
|
+
mock_output: Any, # noqa: ANN401
|
|
526
|
+
) -> None:
|
|
527
|
+
"""Launch a combined callback as a background task (fire-and-forget).
|
|
528
|
+
|
|
529
|
+
Args:
|
|
530
|
+
callback: The callback callable to execute (can be sync or async)
|
|
531
|
+
input_params: Dictionary of input parameters
|
|
532
|
+
mock_output: The output from the mock/stub call
|
|
533
|
+
|
|
534
|
+
Note:
|
|
535
|
+
This launches the callback without blocking. Errors are logged but won't
|
|
536
|
+
affect the main execution flow.
|
|
537
|
+
"""
|
|
538
|
+
if callback is None:
|
|
539
|
+
return
|
|
540
|
+
|
|
541
|
+
async def _run_callback() -> None:
|
|
542
|
+
"""Wrapper to run combined callback with error handling."""
|
|
543
|
+
try:
|
|
544
|
+
# Combine input params with mock_output
|
|
545
|
+
combined_data = {**input_params, "mock_output": mock_output}
|
|
546
|
+
# Filter parameters to match callback signature
|
|
547
|
+
filtered_data = filter_callback_parameters(callback, combined_data)
|
|
548
|
+
|
|
549
|
+
if inspect.iscoroutinefunction(callback):
|
|
550
|
+
await callback(**filtered_data)
|
|
551
|
+
else:
|
|
552
|
+
result = callback(**filtered_data)
|
|
553
|
+
if inspect.iscoroutine(result):
|
|
554
|
+
await result
|
|
555
|
+
except Exception as e:
|
|
556
|
+
logger.warning(f"Combined callback execution failed: {e}", exc_info=True)
|
|
557
|
+
|
|
558
|
+
# Create task without awaiting (fire-and-forget)
|
|
559
|
+
try:
|
|
560
|
+
asyncio.create_task(_run_callback())
|
|
561
|
+
except RuntimeError:
|
|
562
|
+
# If no event loop is running, log a warning
|
|
563
|
+
logger.warning("Cannot launch combined callback task: no event loop running")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: veris-ai
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.14.1
|
|
4
4
|
Summary: A Python package for Veris AI tools
|
|
5
5
|
Project-URL: Homepage, https://github.com/veris-ai/veris-python-sdk
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/veris-ai/veris-python-sdk/issues
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
veris_ai/README.md,sha256=Mxg9fyNt6hFkQaFBYZq85Kw9akw4cN2uu6j_mXZtNCs,3871
|
|
2
2
|
veris_ai/__init__.py,sha256=enl_gEa6BQAjWvzCtsn_hFVJVVlJZ_dMsLL--E5W3nU,1907
|
|
3
3
|
veris_ai/agents_wrapper.py,sha256=gLUd_0TyCVsqqilQLvsSJIpsU5uu2CdjjWOQ4QJjoJk,12786
|
|
4
|
-
veris_ai/api_client.py,sha256=
|
|
4
|
+
veris_ai/api_client.py,sha256=ZtxskNdAG_ASx_y2VhzV0vdG2kW5Ph5gPDBn-FG44-4,4654
|
|
5
5
|
veris_ai/models.py,sha256=xKeheSJQle2tBeJG1DsGJzMDwv24p5jECjX6RAa39n4,495
|
|
6
6
|
veris_ai/observability.py,sha256=eSIXmk6fpOAoWM-sDbsvzyUASh1ZwU6tRIPduy09RxY,4206
|
|
7
|
-
veris_ai/tool_mock.py,sha256=
|
|
8
|
-
veris_ai/utils.py,sha256=
|
|
7
|
+
veris_ai/tool_mock.py,sha256=A1k_llfjbMsMXP9J1M9pLhYVyNGxaLACaL6vsTc0zoI,25108
|
|
8
|
+
veris_ai/utils.py,sha256=qwPPxS0CrsS36OoN_924hricz9jGRXx9FSDgLok0wgY,18940
|
|
9
9
|
veris_ai/jaeger_interface/README.md,sha256=kd9rKcE5xf3EyNaiHu0tjn-0oES9sfaK6Ih-OhhTyCM,2821
|
|
10
10
|
veris_ai/jaeger_interface/__init__.py,sha256=KD7NSiMYRG_2uF6dOLKkGG5lNQe4K9ptEwucwMT4_aw,1128
|
|
11
11
|
veris_ai/jaeger_interface/client.py,sha256=yJrh86wRR0Dk3Gq12DId99WogcMIVbL0QQFqVSevvlE,8772
|
|
12
12
|
veris_ai/jaeger_interface/models.py,sha256=e64VV6IvOEFuzRUgvDAMQFyOZMRb56I-PUPZLBZ3rX0,1864
|
|
13
|
-
veris_ai-1.
|
|
14
|
-
veris_ai-1.
|
|
15
|
-
veris_ai-1.
|
|
16
|
-
veris_ai-1.
|
|
13
|
+
veris_ai-1.14.1.dist-info/METADATA,sha256=C2JsiZwQNZcdW5uIX45fN2-sU3feqUyZJYMLR--VWKk,16684
|
|
14
|
+
veris_ai-1.14.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
15
|
+
veris_ai-1.14.1.dist-info/licenses/LICENSE,sha256=2g4i20atAgtD5einaKzhQrIB-JrPhyQgD3bC0wkHcCI,1065
|
|
16
|
+
veris_ai-1.14.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|