veris-ai 1.9.0__tar.gz → 1.10.0__tar.gz
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-1.9.0 → veris_ai-1.10.0}/CLAUDE.md +32 -10
- {veris_ai-1.9.0 → veris_ai-1.10.0}/PKG-INFO +34 -6
- {veris_ai-1.9.0 → veris_ai-1.10.0}/README.md +32 -5
- {veris_ai-1.9.0 → veris_ai-1.10.0}/examples/README.md +9 -6
- {veris_ai-1.9.0 → veris_ai-1.10.0}/pyproject.toml +2 -1
- {veris_ai-1.9.0 → veris_ai-1.10.0}/src/veris_ai/README.md +12 -11
- {veris_ai-1.9.0 → veris_ai-1.10.0}/src/veris_ai/agents_wrapper.py +2 -1
- {veris_ai-1.9.0 → veris_ai-1.10.0}/src/veris_ai/observability.py +8 -25
- {veris_ai-1.9.0 → veris_ai-1.10.0}/src/veris_ai/tool_mock.py +57 -8
- {veris_ai-1.9.0 → veris_ai-1.10.0}/src/veris_ai/utils.py +19 -4
- {veris_ai-1.9.0 → veris_ai-1.10.0}/tests/README.md +2 -2
- {veris_ai-1.9.0 → veris_ai-1.10.0}/tests/test_mcp_protocol_server_mocked.py +0 -2
- {veris_ai-1.9.0 → veris_ai-1.10.0}/tests/test_tool_mock.py +8 -2
- {veris_ai-1.9.0 → veris_ai-1.10.0}/tests/test_veris_runner_tool_options.py +1 -2
- {veris_ai-1.9.0 → veris_ai-1.10.0}/uv.lock +12 -1
- veris_ai-1.9.0/src/veris_ai/logging.py +0 -46
- {veris_ai-1.9.0 → veris_ai-1.10.0}/.cursor/rules/documentation-management.mdc +0 -0
- {veris_ai-1.9.0 → veris_ai-1.10.0}/.github/workflows/release.yml +0 -0
- {veris_ai-1.9.0 → veris_ai-1.10.0}/.github/workflows/test.yml +0 -0
- {veris_ai-1.9.0 → veris_ai-1.10.0}/.gitignore +0 -0
- {veris_ai-1.9.0 → veris_ai-1.10.0}/.pre-commit-config.yaml +0 -0
- {veris_ai-1.9.0 → veris_ai-1.10.0}/CHANGELOG.md +0 -0
- {veris_ai-1.9.0 → veris_ai-1.10.0}/LICENSE +0 -0
- {veris_ai-1.9.0 → veris_ai-1.10.0}/examples/__init__.py +0 -0
- {veris_ai-1.9.0 → veris_ai-1.10.0}/examples/import_options.py +0 -0
- {veris_ai-1.9.0 → veris_ai-1.10.0}/examples/openai_agents_example.py +0 -0
- {veris_ai-1.9.0 → veris_ai-1.10.0}/src/veris_ai/__init__.py +0 -0
- {veris_ai-1.9.0 → veris_ai-1.10.0}/src/veris_ai/api_client.py +0 -0
- {veris_ai-1.9.0 → veris_ai-1.10.0}/src/veris_ai/jaeger_interface/README.md +0 -0
- {veris_ai-1.9.0 → veris_ai-1.10.0}/src/veris_ai/jaeger_interface/__init__.py +0 -0
- {veris_ai-1.9.0 → veris_ai-1.10.0}/src/veris_ai/jaeger_interface/client.py +0 -0
- {veris_ai-1.9.0 → veris_ai-1.10.0}/src/veris_ai/jaeger_interface/models.py +0 -0
- {veris_ai-1.9.0 → veris_ai-1.10.0}/src/veris_ai/models.py +0 -0
- {veris_ai-1.9.0 → veris_ai-1.10.0}/tests/__init__.py +0 -0
- {veris_ai-1.9.0 → veris_ai-1.10.0}/tests/conftest.py +0 -0
- {veris_ai-1.9.0 → veris_ai-1.10.0}/tests/fixtures/__init__.py +0 -0
- {veris_ai-1.9.0 → veris_ai-1.10.0}/tests/fixtures/http_server.py +0 -0
- {veris_ai-1.9.0 → veris_ai-1.10.0}/tests/fixtures/simple_app.py +0 -0
- {veris_ai-1.9.0 → veris_ai-1.10.0}/tests/test_agents_wrapper_extract.py +0 -0
- {veris_ai-1.9.0 → veris_ai-1.10.0}/tests/test_agents_wrapper_simple.py +0 -0
- {veris_ai-1.9.0 → veris_ai-1.10.0}/tests/test_utils.py +0 -0
|
@@ -6,11 +6,12 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|
|
6
6
|
|
|
7
7
|
This is the Veris AI Python SDK - a package that provides simulation capabilities through decorator-based function mocking and FastAPI MCP (Model Context Protocol) integration. The core functionality revolves around:
|
|
8
8
|
- `VerisSDK` class in `src/veris_ai/tool_mock.py:27` - enables environment-aware execution where functions can be mocked in simulation mode, spied on, or executed normally in production
|
|
9
|
-
-
|
|
9
|
+
- `@veris.spy()` decorator - executes original functions while logging calls and responses via logging endpoints
|
|
10
10
|
- `convert_to_type()` function in `src/veris_ai/utils.py:5` - handles sophisticated type conversion from mock responses
|
|
11
11
|
- `FastApiMCPParams` model in `src/veris_ai/models.py:1` - provides configuration for integrating FastAPI applications with the Model Context Protocol
|
|
12
12
|
- `set_fastapi_mcp()` method in `src/veris_ai/tool_mock.py:54` - configures FastAPI MCP server with automatic OAuth2-based session management
|
|
13
13
|
- Logging utilities in `src/veris_ai/logging.py` - provide async and sync functions for logging tool calls and responses to VERIS endpoints
|
|
14
|
+
- `SimulatorAPIClient` class in `src/veris_ai/api_client.py` - centralized client for making requests to VERIS simulation endpoints with automatic authentication
|
|
14
15
|
|
|
15
16
|
## Development Commands
|
|
16
17
|
|
|
@@ -18,12 +19,18 @@ This project uses `uv` as the package manager and follows modern Python tooling
|
|
|
18
19
|
|
|
19
20
|
### Setup
|
|
20
21
|
```bash
|
|
22
|
+
# Install base package
|
|
23
|
+
uv add veris-ai
|
|
24
|
+
|
|
21
25
|
# Install with development dependencies
|
|
22
26
|
uv add "veris-ai[dev]"
|
|
23
27
|
|
|
24
28
|
# Install with FastAPI MCP integration
|
|
25
29
|
uv add "veris-ai[fastapi]"
|
|
26
30
|
|
|
31
|
+
# Install with all extras
|
|
32
|
+
uv add "veris-ai[dev,fastapi,observability,agents]"
|
|
33
|
+
|
|
27
34
|
# Set Python version (requires 3.11+)
|
|
28
35
|
pyenv local 3.11.0
|
|
29
36
|
```
|
|
@@ -75,10 +82,12 @@ uv build
|
|
|
75
82
|
- Main SDK class that provides decorator functionality:
|
|
76
83
|
- `@veris.mock()`: Dynamic mocking that calls external endpoints for responses
|
|
77
84
|
- `@veris.stub()`: Simple stubbing with fixed return values
|
|
78
|
-
-
|
|
85
|
+
- `@veris.spy()`: Logging decorator that executes original function and logs the call/response
|
|
86
|
+
- Session-based activation: Uses session ID presence to determine mocking behavior
|
|
79
87
|
- HTTP communication with mock endpoints via `httpx` (for mock decorator)
|
|
80
88
|
- Context extraction for session management via context variables
|
|
81
89
|
- Delegates type conversion to the utils module
|
|
90
|
+
- Automatic API endpoint configuration with production defaults
|
|
82
91
|
|
|
83
92
|
**API Surface** (`src/veris_ai/__init__.py:5`)
|
|
84
93
|
- Exports single `veris` instance for public use
|
|
@@ -101,10 +110,18 @@ uv build
|
|
|
101
110
|
|
|
102
111
|
### Environment Configuration
|
|
103
112
|
|
|
104
|
-
|
|
105
|
-
- `
|
|
106
|
-
- `VERIS_MOCK_TIMEOUT`: Request timeout in seconds (optional, default:
|
|
107
|
-
|
|
113
|
+
Environment variables:
|
|
114
|
+
- `VERIS_API_KEY`: API authentication key for VERIS services (optional, but recommended for production)
|
|
115
|
+
- `VERIS_MOCK_TIMEOUT`: Request timeout in seconds (optional, default: 90.0)
|
|
116
|
+
|
|
117
|
+
**Note**: The SDK automatically connects to the production VERIS API endpoint (`https://simulation.api.veris.ai/`). Only override `VERIS_API_URL` if you need to use a custom endpoint (rarely needed).
|
|
118
|
+
|
|
119
|
+
### Session-Based Activation
|
|
120
|
+
|
|
121
|
+
The SDK activates mocking based on session ID presence:
|
|
122
|
+
- **With session ID**: Routes calls to mock/simulator endpoint
|
|
123
|
+
- **Without session ID**: Executes original function
|
|
124
|
+
- Session IDs can be set manually via `veris.set_session_id()` or extracted automatically from OAuth2 tokens in FastAPI MCP integration
|
|
108
125
|
|
|
109
126
|
### Type System
|
|
110
127
|
|
|
@@ -123,8 +140,8 @@ The SDK handles sophisticated type conversion from mock responses:
|
|
|
123
140
|
|
|
124
141
|
**Key Test Fixtures**:
|
|
125
142
|
- `mock_context`: Provides mock context with session ID
|
|
126
|
-
- `simulation_env`: Sets up simulation
|
|
127
|
-
- `production_env`: Sets up production
|
|
143
|
+
- `simulation_env`: Sets up simulation mode with session ID
|
|
144
|
+
- `production_env`: Sets up production mode without session ID
|
|
128
145
|
|
|
129
146
|
**Test Coverage Areas**:
|
|
130
147
|
- Environment-based behavior switching
|
|
@@ -164,9 +181,14 @@ The SDK handles sophisticated type conversion from mock responses:
|
|
|
164
181
|
## Key Implementation Details
|
|
165
182
|
|
|
166
183
|
- **Decorator Pattern**: Functions are wrapped to intercept calls in simulation mode
|
|
167
|
-
-
|
|
168
|
-
-
|
|
184
|
+
- `@veris.mock()`: Sends function metadata to external endpoint for dynamic responses
|
|
185
|
+
- `@veris.stub()`: Returns predetermined values without external calls
|
|
186
|
+
- `@veris.spy()`: Executes original function while logging calls and responses
|
|
169
187
|
- **Session Management**: Extracts session ID from context for request correlation
|
|
188
|
+
- **API Client**: Centralized `SimulatorAPIClient` handles all API communication
|
|
189
|
+
- Automatic endpoint configuration with production defaults
|
|
190
|
+
- Built-in authentication via `VERIS_API_KEY` header
|
|
191
|
+
- Configurable timeout with `VERIS_MOCK_TIMEOUT`
|
|
170
192
|
- **Error Handling**: Comprehensive HTTP and type conversion error handling
|
|
171
193
|
- **Async Support**: Built with async/await pattern throughout
|
|
172
194
|
- **Type Safety**: Full type hints and runtime type conversion validation
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: veris-ai
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.10.0
|
|
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
|
|
@@ -20,6 +20,7 @@ Requires-Dist: opentelemetry-instrumentation>=0.55b1
|
|
|
20
20
|
Requires-Dist: opentelemetry-sdk>=1.34.1
|
|
21
21
|
Requires-Dist: pydantic>=2.0.0
|
|
22
22
|
Requires-Dist: requests>=2.31.0
|
|
23
|
+
Requires-Dist: tenacity>=9.1.2
|
|
23
24
|
Provides-Extra: agents
|
|
24
25
|
Requires-Dist: openai-agents>=0.0.1; extra == 'agents'
|
|
25
26
|
Provides-Extra: dev
|
|
@@ -90,7 +91,6 @@ from veris_ai import Runner, VerisConfig # Requires agents extras
|
|
|
90
91
|
|----------|---------|---------|
|
|
91
92
|
| `VERIS_API_KEY` | API authentication key | None |
|
|
92
93
|
| `VERIS_MOCK_TIMEOUT` | Request timeout (seconds) | `90.0` |
|
|
93
|
-
| `ENV` | Set to `"simulation"` for mock mode | Production |
|
|
94
94
|
|
|
95
95
|
**Advanced Configuration** (rarely needed):
|
|
96
96
|
- `VERIS_API_URL`: Override default API endpoint (defaults to production)
|
|
@@ -158,29 +158,57 @@ End-to-end propagation with the simulator:
|
|
|
158
158
|
|
|
159
159
|
**Semantic Tag**: `tool-mocking`
|
|
160
160
|
|
|
161
|
+
### Session-Based Activation
|
|
162
|
+
|
|
163
|
+
The SDK uses session-based activation to determine when to enable mocking. Choose one of these methods to set a session ID:
|
|
164
|
+
|
|
165
|
+
**Option 1: Manual Setting**
|
|
166
|
+
```python
|
|
167
|
+
from veris_ai import veris
|
|
168
|
+
|
|
169
|
+
# Explicitly set a session ID
|
|
170
|
+
veris.set_session_id("your-session-id")
|
|
171
|
+
|
|
172
|
+
# Now decorated functions will use mock responses
|
|
173
|
+
result = await your_mocked_function()
|
|
174
|
+
|
|
175
|
+
# Clear session to disable mocking
|
|
176
|
+
veris.clear_session_id()
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**Option 2: Automatic Extraction (FastAPI MCP)**
|
|
180
|
+
```python
|
|
181
|
+
# When using FastAPI MCP integration, session IDs are
|
|
182
|
+
# automatically extracted from OAuth2 bearer tokens
|
|
183
|
+
veris.set_fastapi_mcp(...)
|
|
184
|
+
# No manual session management needed
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**How it works internally**: Regardless of which method you use, session IDs are stored in Python context variables (`contextvars`). This ensures proper isolation between concurrent requests and automatic propagation through the call stack.
|
|
188
|
+
|
|
161
189
|
### Core Decorators
|
|
162
190
|
|
|
163
191
|
```python
|
|
164
192
|
from veris_ai import veris
|
|
165
193
|
|
|
166
|
-
# Mock
|
|
194
|
+
# Mock decorator: Returns simulated responses when session ID is set
|
|
167
195
|
@veris.mock()
|
|
168
196
|
async def your_function(param1: str, param2: int) -> dict:
|
|
169
197
|
"""Function documentation for LLM context."""
|
|
170
198
|
return {"result": "actual implementation"}
|
|
171
199
|
|
|
172
|
-
# Spy
|
|
200
|
+
# Spy decorator: Executes function and logs calls/responses
|
|
173
201
|
@veris.spy()
|
|
174
202
|
async def monitored_function(data: str) -> dict:
|
|
175
203
|
return process_data(data)
|
|
176
204
|
|
|
177
|
-
# Stub
|
|
205
|
+
# Stub decorator: Returns fixed value in simulation
|
|
178
206
|
@veris.stub(return_value={"status": "success"})
|
|
179
207
|
async def get_data() -> dict:
|
|
180
208
|
return await fetch_from_api()
|
|
181
209
|
```
|
|
182
210
|
|
|
183
|
-
**Behavior**:
|
|
211
|
+
**Behavior**: When a session ID is set, decorators activate their respective behaviors (mock responses, logging, or stubbed values). Without a session ID, functions execute normally.
|
|
184
212
|
|
|
185
213
|
**Implementation**: See [`src/veris_ai/tool_mock.py`](src/veris_ai/tool_mock.py) for decorator logic and API integration.
|
|
186
214
|
|
|
@@ -48,7 +48,6 @@ from veris_ai import Runner, VerisConfig # Requires agents extras
|
|
|
48
48
|
|----------|---------|---------|
|
|
49
49
|
| `VERIS_API_KEY` | API authentication key | None |
|
|
50
50
|
| `VERIS_MOCK_TIMEOUT` | Request timeout (seconds) | `90.0` |
|
|
51
|
-
| `ENV` | Set to `"simulation"` for mock mode | Production |
|
|
52
51
|
|
|
53
52
|
**Advanced Configuration** (rarely needed):
|
|
54
53
|
- `VERIS_API_URL`: Override default API endpoint (defaults to production)
|
|
@@ -116,29 +115,57 @@ End-to-end propagation with the simulator:
|
|
|
116
115
|
|
|
117
116
|
**Semantic Tag**: `tool-mocking`
|
|
118
117
|
|
|
118
|
+
### Session-Based Activation
|
|
119
|
+
|
|
120
|
+
The SDK uses session-based activation to determine when to enable mocking. Choose one of these methods to set a session ID:
|
|
121
|
+
|
|
122
|
+
**Option 1: Manual Setting**
|
|
123
|
+
```python
|
|
124
|
+
from veris_ai import veris
|
|
125
|
+
|
|
126
|
+
# Explicitly set a session ID
|
|
127
|
+
veris.set_session_id("your-session-id")
|
|
128
|
+
|
|
129
|
+
# Now decorated functions will use mock responses
|
|
130
|
+
result = await your_mocked_function()
|
|
131
|
+
|
|
132
|
+
# Clear session to disable mocking
|
|
133
|
+
veris.clear_session_id()
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Option 2: Automatic Extraction (FastAPI MCP)**
|
|
137
|
+
```python
|
|
138
|
+
# When using FastAPI MCP integration, session IDs are
|
|
139
|
+
# automatically extracted from OAuth2 bearer tokens
|
|
140
|
+
veris.set_fastapi_mcp(...)
|
|
141
|
+
# No manual session management needed
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**How it works internally**: Regardless of which method you use, session IDs are stored in Python context variables (`contextvars`). This ensures proper isolation between concurrent requests and automatic propagation through the call stack.
|
|
145
|
+
|
|
119
146
|
### Core Decorators
|
|
120
147
|
|
|
121
148
|
```python
|
|
122
149
|
from veris_ai import veris
|
|
123
150
|
|
|
124
|
-
# Mock
|
|
151
|
+
# Mock decorator: Returns simulated responses when session ID is set
|
|
125
152
|
@veris.mock()
|
|
126
153
|
async def your_function(param1: str, param2: int) -> dict:
|
|
127
154
|
"""Function documentation for LLM context."""
|
|
128
155
|
return {"result": "actual implementation"}
|
|
129
156
|
|
|
130
|
-
# Spy
|
|
157
|
+
# Spy decorator: Executes function and logs calls/responses
|
|
131
158
|
@veris.spy()
|
|
132
159
|
async def monitored_function(data: str) -> dict:
|
|
133
160
|
return process_data(data)
|
|
134
161
|
|
|
135
|
-
# Stub
|
|
162
|
+
# Stub decorator: Returns fixed value in simulation
|
|
136
163
|
@veris.stub(return_value={"status": "success"})
|
|
137
164
|
async def get_data() -> dict:
|
|
138
165
|
return await fetch_from_api()
|
|
139
166
|
```
|
|
140
167
|
|
|
141
|
-
**Behavior**:
|
|
168
|
+
**Behavior**: When a session ID is set, decorators activate their respective behaviors (mock responses, logging, or stubbed values). Without a session ID, functions execute normally.
|
|
142
169
|
|
|
143
170
|
**Implementation**: See [`src/veris_ai/tool_mock.py`](src/veris_ai/tool_mock.py) for decorator logic and API integration.
|
|
144
171
|
|
|
@@ -63,9 +63,9 @@ if os.getenv("USE_FASTAPI") == "true":
|
|
|
63
63
|
**Semantic Tag**: `integration-patterns`
|
|
64
64
|
|
|
65
65
|
### Decorator Usage
|
|
66
|
-
- **
|
|
67
|
-
- **Spy
|
|
68
|
-
- **Stub
|
|
66
|
+
- **Mock Decorator**: `@veris.mock()` for simulation mode
|
|
67
|
+
- **Spy Decorator**: `@veris.spy()` for logging calls and responses
|
|
68
|
+
- **Stub Decorator**: `@veris.stub(return_value={})` for fixed responses
|
|
69
69
|
|
|
70
70
|
### Error Handling
|
|
71
71
|
- **Graceful Import Failures**: Try/catch blocks for optional features
|
|
@@ -73,7 +73,8 @@ if os.getenv("USE_FASTAPI") == "true":
|
|
|
73
73
|
- **Feature Detection**: Runtime capability checking
|
|
74
74
|
|
|
75
75
|
### Configuration Management
|
|
76
|
-
- **Environment Variables**: `
|
|
76
|
+
- **Environment Variables**: `VERIS_API_KEY` for authentication, `VERIS_MOCK_TIMEOUT` for request timeout
|
|
77
|
+
- **Session Management**: Use `veris.set_session_id()` to enable mocking
|
|
77
78
|
- **Conditional Setup**: Feature flags for optional components
|
|
78
79
|
- **Service Configuration**: Dynamic service naming and endpoints
|
|
79
80
|
|
|
@@ -86,13 +87,15 @@ if os.getenv("USE_FASTAPI") == "true":
|
|
|
86
87
|
cd examples/
|
|
87
88
|
python import_options.py
|
|
88
89
|
|
|
89
|
-
# With
|
|
90
|
-
|
|
90
|
+
# With API key for production
|
|
91
|
+
VERIS_API_KEY=your-api-key python import_options.py
|
|
91
92
|
|
|
92
93
|
# Testing with different feature flags
|
|
93
94
|
ENABLE_TRACING=true USE_FASTAPI=true python import_options.py
|
|
94
95
|
```
|
|
95
96
|
|
|
97
|
+
**Note**: To enable mocking in your code, call `veris.set_session_id("your-session-id")`.
|
|
98
|
+
|
|
96
99
|
w### Observability Environment (optional)
|
|
97
100
|
|
|
98
101
|
If you want traces exported while running examples, set the following before execution:
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "veris-ai"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.10.0"
|
|
8
8
|
description = "A Python package for Veris AI tools"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -25,6 +25,7 @@ dependencies = [
|
|
|
25
25
|
"opentelemetry-instrumentation-mcp>=0.44.1",
|
|
26
26
|
"opentelemetry-api>=1.34.1",
|
|
27
27
|
"logfire>=4.3.3",
|
|
28
|
+
"tenacity>=9.1.2",
|
|
28
29
|
]
|
|
29
30
|
|
|
30
31
|
[project.optional-dependencies]
|
|
@@ -14,9 +14,10 @@ This module contains the core implementation of the Veris AI Python SDK. Each co
|
|
|
14
14
|
|
|
15
15
|
| Module | Purpose | Key Classes/Functions | Lines |
|
|
16
16
|
|--------|---------|----------------------|-------|
|
|
17
|
-
| [`tool_mock.py`](tool_mock.py) | Function mocking & FastAPI MCP | `VerisSDK`, `@mock`, `@stub` | 327 |
|
|
18
|
-
| [`utils.py`](utils.py) | Type utilities & JSON schema | `extract_json_schema()` | 272 |
|
|
19
|
-
| [`
|
|
17
|
+
| [`tool_mock.py`](tool_mock.py) | Function mocking & FastAPI MCP | `VerisSDK`, `@mock`, `@stub`, `@spy` | 327 |
|
|
18
|
+
| [`utils.py`](utils.py) | Type utilities & JSON schema | `extract_json_schema()`, `convert_to_type()` | 272 |
|
|
19
|
+
| [`api_client.py`](api_client.py) | Centralized API client | `SimulatorAPIClient` | 62 |
|
|
20
|
+
| [`logging.py`](logging.py) | Tool call/response logging | `log_tool_call()`, `log_tool_response()` | 116 |
|
|
20
21
|
| [`models.py`](models.py) | Data models | Type definitions | 12 |
|
|
21
22
|
| [`jaeger_interface/`](jaeger_interface/) | Jaeger Query API wrapper | `JaegerClient` | See module README |
|
|
22
23
|
|
|
@@ -26,16 +27,16 @@ This module contains the core implementation of the Veris AI Python SDK. Each co
|
|
|
26
27
|
|
|
27
28
|
### Mock Flow
|
|
28
29
|
1. **Decoration**: `@veris.mock()` captures function metadata
|
|
29
|
-
2. **
|
|
30
|
-
3. **API Call**: POST to
|
|
30
|
+
2. **Session Check**: Presence of session ID determines behavior
|
|
31
|
+
3. **API Call**: POST to VERIS API endpoint `/v2/tool_mock` (auto-configured)
|
|
31
32
|
4. **Type Conversion**: Response converted using `extract_json_schema()`
|
|
32
33
|
|
|
33
34
|
**Implementation**: [`tool_mock.py:200-250`](tool_mock.py)
|
|
34
35
|
|
|
35
36
|
### Spy Flow
|
|
36
|
-
1. **Pre-execution Logging**: Call details sent to `/
|
|
37
|
+
1. **Pre-execution Logging**: Call details sent to `/v2/simulations/{session_id}/log_tool_call`
|
|
37
38
|
2. **Function Execution**: Original function runs normally
|
|
38
|
-
3. **Post-execution Logging**: Response sent to `/
|
|
39
|
+
3. **Post-execution Logging**: Response sent to `/v2/simulations/{session_id}/log_tool_response`
|
|
39
40
|
|
|
40
41
|
**Implementation**: [`tool_mock.py:250-300`](tool_mock.py)
|
|
41
42
|
|
|
@@ -44,11 +45,11 @@ This module contains the core implementation of the Veris AI Python SDK. Each co
|
|
|
44
45
|
|
|
45
46
|
**Semantic Tag**: `module-config`
|
|
46
47
|
|
|
47
|
-
Environment variables are processed in [`
|
|
48
|
+
Environment variables are processed in [`api_client.py`](api_client.py):
|
|
48
49
|
|
|
49
|
-
- `
|
|
50
|
-
- `VERIS_MOCK_TIMEOUT`: Request timeout (default: 90s)
|
|
51
|
-
- `
|
|
50
|
+
- `VERIS_API_KEY`: API authentication key (optional, but recommended)
|
|
51
|
+
- `VERIS_MOCK_TIMEOUT`: Request timeout (default: 90s)
|
|
52
|
+
- `VERIS_API_URL`: Override default API endpoint (rarely needed - defaults to production)
|
|
52
53
|
|
|
53
54
|
### Observability (OTLP / Logfire)
|
|
54
55
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""OpenAI Agents wrapper for automatic tool mocking via Veris SDK."""
|
|
2
2
|
|
|
3
|
+
import json
|
|
3
4
|
import logging
|
|
4
5
|
from collections.abc import Callable
|
|
5
6
|
from typing import Any
|
|
@@ -88,7 +89,7 @@ def _wrap(
|
|
|
88
89
|
return mock_tool_call(
|
|
89
90
|
the_func,
|
|
90
91
|
session_id,
|
|
91
|
-
parameters,
|
|
92
|
+
json.loads(parameters),
|
|
92
93
|
tool_options.get(tool_name_inner),
|
|
93
94
|
)
|
|
94
95
|
# Fall back to original if we couldn't extract the function
|
|
@@ -28,6 +28,12 @@ def init_observability() -> None: # noqa: PLR0912
|
|
|
28
28
|
|
|
29
29
|
logfire.configure(scrubbing=False)
|
|
30
30
|
logfire.instrument_openai_agents()
|
|
31
|
+
try:
|
|
32
|
+
logfire.instrument_redis()
|
|
33
|
+
except Exception:
|
|
34
|
+
logger.warning("Failed to instrument redis")
|
|
35
|
+
logfire.instrument_mcp()
|
|
36
|
+
|
|
31
37
|
except Exception as e:
|
|
32
38
|
# Tracing is optional; continue without Traceloop
|
|
33
39
|
msg = "Logfire not found: " + str(e)
|
|
@@ -96,25 +102,6 @@ def init_observability() -> None: # noqa: PLR0912
|
|
|
96
102
|
msg = "OpenTelemetry not found: " + str(e)
|
|
97
103
|
raise RuntimeError(msg) from e
|
|
98
104
|
|
|
99
|
-
try:
|
|
100
|
-
from opentelemetry.instrumentation.httpx import (
|
|
101
|
-
HTTPXClientInstrumentor, # type: ignore[import-not-found]
|
|
102
|
-
)
|
|
103
|
-
|
|
104
|
-
HTTPXClientInstrumentor().instrument(request_hook=_log_request_headers)
|
|
105
|
-
except Exception as e:
|
|
106
|
-
msg = "OpenTelemetry not found: " + str(e)
|
|
107
|
-
raise RuntimeError(msg) from e
|
|
108
|
-
|
|
109
|
-
# Optionally enable MCP-specific spans
|
|
110
|
-
try:
|
|
111
|
-
from opentelemetry.instrumentation.mcp import McpInstrumentor # type: ignore[import-not-found]
|
|
112
|
-
|
|
113
|
-
McpInstrumentor().instrument()
|
|
114
|
-
except Exception as e:
|
|
115
|
-
msg = "OpenTelemetry not found: " + str(e)
|
|
116
|
-
raise RuntimeError(msg) from e
|
|
117
|
-
|
|
118
105
|
|
|
119
106
|
def instrument_fastapi_app(app: FastAPI) -> None:
|
|
120
107
|
"""Instrument a FastAPI app so inbound HTTP requests continue W3C traces.
|
|
@@ -122,10 +109,6 @@ def instrument_fastapi_app(app: FastAPI) -> None:
|
|
|
122
109
|
Safe to call even if the fastapi instrumentation package is not installed.
|
|
123
110
|
"""
|
|
124
111
|
|
|
125
|
-
|
|
126
|
-
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor # type: ignore[import-not-found]
|
|
112
|
+
import logfire
|
|
127
113
|
|
|
128
|
-
|
|
129
|
-
except Exception as e:
|
|
130
|
-
msg = "OpenTelemetry not found: " + str(e)
|
|
131
|
-
raise RuntimeError(msg) from e
|
|
114
|
+
logfire.instrument_fastapi(app)
|
|
@@ -5,6 +5,7 @@ from collections.abc import Callable
|
|
|
5
5
|
from contextlib import suppress
|
|
6
6
|
from contextvars import ContextVar
|
|
7
7
|
from functools import wraps
|
|
8
|
+
import tenacity
|
|
8
9
|
from typing import (
|
|
9
10
|
Any,
|
|
10
11
|
Literal,
|
|
@@ -13,10 +14,6 @@ from typing import (
|
|
|
13
14
|
)
|
|
14
15
|
|
|
15
16
|
|
|
16
|
-
from veris_ai.logging import (
|
|
17
|
-
log_tool_call,
|
|
18
|
-
log_tool_response,
|
|
19
|
-
)
|
|
20
17
|
from veris_ai.models import ResponseExpectation, ToolCallOptions
|
|
21
18
|
from veris_ai.api_client import get_api_client
|
|
22
19
|
from veris_ai.utils import convert_to_type, extract_json_schema, get_function_parameters
|
|
@@ -173,6 +170,9 @@ class VerisSDK:
|
|
|
173
170
|
"""Async wrapper."""
|
|
174
171
|
session_id = _session_id_context.get()
|
|
175
172
|
if not session_id:
|
|
173
|
+
logger.info(
|
|
174
|
+
f"No session ID found, executing original function: {func.__name__}"
|
|
175
|
+
)
|
|
176
176
|
return await func(*args, **kwargs)
|
|
177
177
|
parameters = get_function_parameters(func, args, kwargs)
|
|
178
178
|
return mock_tool_call(
|
|
@@ -190,6 +190,9 @@ class VerisSDK:
|
|
|
190
190
|
"""Sync wrapper."""
|
|
191
191
|
session_id = _session_id_context.get()
|
|
192
192
|
if not session_id:
|
|
193
|
+
logger.info(
|
|
194
|
+
f"No session ID found, executing original function: {func.__name__}"
|
|
195
|
+
)
|
|
193
196
|
return func(*args, **kwargs)
|
|
194
197
|
parameters = get_function_parameters(func, args, kwargs)
|
|
195
198
|
return mock_tool_call(
|
|
@@ -217,7 +220,9 @@ class VerisSDK:
|
|
|
217
220
|
**kwargs: Any, # noqa: ANN401
|
|
218
221
|
) -> object:
|
|
219
222
|
if not self.session_id:
|
|
220
|
-
|
|
223
|
+
logger.info(
|
|
224
|
+
f"No session ID found, executing original function: {func.__name__}"
|
|
225
|
+
)
|
|
221
226
|
return await func(*args, **kwargs)
|
|
222
227
|
logger.info(f"Stubbing function: {func.__name__}")
|
|
223
228
|
return return_value
|
|
@@ -225,7 +230,9 @@ class VerisSDK:
|
|
|
225
230
|
@wraps(func)
|
|
226
231
|
def sync_wrapper(*args: tuple[object, ...], **kwargs: Any) -> object: # noqa: ANN401
|
|
227
232
|
if not self.session_id:
|
|
228
|
-
|
|
233
|
+
logger.info(
|
|
234
|
+
f"No session ID found, executing original function: {func.__name__}"
|
|
235
|
+
)
|
|
229
236
|
return func(*args, **kwargs)
|
|
230
237
|
logger.info(f"Stubbing function: {func.__name__}")
|
|
231
238
|
return return_value
|
|
@@ -236,10 +243,15 @@ class VerisSDK:
|
|
|
236
243
|
return decorator
|
|
237
244
|
|
|
238
245
|
|
|
246
|
+
@tenacity.retry(
|
|
247
|
+
stop=tenacity.stop_after_attempt(3),
|
|
248
|
+
wait=tenacity.wait_exponential(multiplier=1, min=4, max=10),
|
|
249
|
+
reraise=True,
|
|
250
|
+
)
|
|
239
251
|
def mock_tool_call(
|
|
240
252
|
func: Callable,
|
|
241
253
|
session_id: str,
|
|
242
|
-
parameters: str,
|
|
254
|
+
parameters: dict[str, dict[str, str]],
|
|
243
255
|
options: ToolCallOptions | None = None,
|
|
244
256
|
) -> object:
|
|
245
257
|
"""Mock tool call."""
|
|
@@ -262,7 +274,7 @@ def mock_tool_call(
|
|
|
262
274
|
"cache_response": bool(options.cache_response),
|
|
263
275
|
"tool_call": {
|
|
264
276
|
"function_name": func.__name__,
|
|
265
|
-
"parameters":
|
|
277
|
+
"parameters": parameters,
|
|
266
278
|
"return_type": json.dumps(extract_json_schema(return_type_obj)),
|
|
267
279
|
"docstring": docstring,
|
|
268
280
|
},
|
|
@@ -278,4 +290,41 @@ def mock_tool_call(
|
|
|
278
290
|
return convert_to_type(mock_result, return_type_obj)
|
|
279
291
|
|
|
280
292
|
|
|
293
|
+
def log_tool_call(
|
|
294
|
+
session_id: str,
|
|
295
|
+
function_name: str,
|
|
296
|
+
parameters: dict[str, dict[str, str]],
|
|
297
|
+
docstring: str,
|
|
298
|
+
) -> None:
|
|
299
|
+
"""Log tool call synchronously to the VERIS logging endpoint."""
|
|
300
|
+
api_client = get_api_client()
|
|
301
|
+
endpoint = api_client.get_log_tool_call_endpoint(session_id)
|
|
302
|
+
payload = {
|
|
303
|
+
"function_name": function_name,
|
|
304
|
+
"parameters": parameters,
|
|
305
|
+
"docstring": docstring,
|
|
306
|
+
}
|
|
307
|
+
try:
|
|
308
|
+
api_client.post(endpoint, payload)
|
|
309
|
+
logger.debug(f"Tool call logged for {function_name}")
|
|
310
|
+
except Exception as e:
|
|
311
|
+
logger.warning(f"Failed to log tool call for {function_name}: {e}")
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
def log_tool_response(session_id: str, response: Any) -> None: # noqa: ANN401
|
|
315
|
+
"""Log tool response synchronously to the VERIS logging endpoint."""
|
|
316
|
+
api_client = get_api_client()
|
|
317
|
+
endpoint = api_client.get_log_tool_response_endpoint(session_id)
|
|
318
|
+
|
|
319
|
+
payload = {
|
|
320
|
+
"response": json.dumps(response, default=str),
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
try:
|
|
324
|
+
api_client.post(endpoint, payload)
|
|
325
|
+
logger.debug("Tool response logged")
|
|
326
|
+
except Exception as e:
|
|
327
|
+
logger.warning(f"Failed to log tool response: {e}")
|
|
328
|
+
|
|
329
|
+
|
|
281
330
|
veris = VerisSDK()
|
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
import inspect
|
|
2
|
-
import json
|
|
3
2
|
import sys
|
|
4
3
|
import types
|
|
5
4
|
import typing
|
|
6
5
|
from contextlib import suppress
|
|
7
|
-
from typing import
|
|
6
|
+
from typing import (
|
|
7
|
+
Any,
|
|
8
|
+
ForwardRef,
|
|
9
|
+
Literal,
|
|
10
|
+
NotRequired,
|
|
11
|
+
Required,
|
|
12
|
+
Union,
|
|
13
|
+
get_args,
|
|
14
|
+
get_origin,
|
|
15
|
+
get_type_hints,
|
|
16
|
+
)
|
|
8
17
|
from collections.abc import Callable
|
|
9
18
|
|
|
10
19
|
from pydantic import BaseModel
|
|
@@ -279,12 +288,18 @@ def extract_json_schema(target_type: Any) -> dict: # noqa: PLR0911, PLR0912, C9
|
|
|
279
288
|
|
|
280
289
|
def get_function_parameters(
|
|
281
290
|
func: Callable, args: tuple[object, ...], kwargs: dict[str, object]
|
|
282
|
-
) -> str:
|
|
291
|
+
) -> dict[str, dict[str, str]]:
|
|
283
292
|
"""Get the parameters for a function."""
|
|
293
|
+
params_info = {}
|
|
284
294
|
sig = inspect.signature(func)
|
|
285
295
|
bound_args = sig.bind(*args, **kwargs)
|
|
286
296
|
bound_args.apply_defaults()
|
|
287
297
|
_ = bound_args.arguments.pop("ctx", None)
|
|
288
298
|
_ = bound_args.arguments.pop("self", None)
|
|
289
299
|
_ = bound_args.arguments.pop("cls", None)
|
|
290
|
-
|
|
300
|
+
for param_name, param_value in bound_args.arguments.items():
|
|
301
|
+
params_info[param_name] = {
|
|
302
|
+
"value": str(param_value),
|
|
303
|
+
"type": str(get_type_hints(func).get(param_name, Any)),
|
|
304
|
+
}
|
|
305
|
+
return params_info
|
|
@@ -14,7 +14,7 @@ Test suite for the Veris AI Python SDK with comprehensive coverage of mocking, t
|
|
|
14
14
|
|
|
15
15
|
| Test File | Coverage | Key Areas | Lines |
|
|
16
16
|
|-----------|----------|-----------|-------|
|
|
17
|
-
| [`test_tool_mock.py`](test_tool_mock.py) | VerisSDK, decorators | Mock/spy
|
|
17
|
+
| [`test_tool_mock.py`](test_tool_mock.py) | VerisSDK, decorators | Mock/spy/stub decorators, FastAPI MCP | 530 |
|
|
18
18
|
| [`test_utils.py`](test_utils.py) | Type conversion utilities | JSON schema extraction | 438 |
|
|
19
19
|
| [`test_mcp_protocol_server_mocked.py`](test_mcp_protocol_server_mocked.py) | MCP integration | Protocol server mocking | 215 |
|
|
20
20
|
| [`conftest.py`](conftest.py) | Test configuration | Pytest fixtures, setup | 60 |
|
|
@@ -24,7 +24,7 @@ Test suite for the Veris AI Python SDK with comprehensive coverage of mocking, t
|
|
|
24
24
|
**Semantic Tag**: `test-fixtures`
|
|
25
25
|
|
|
26
26
|
### Core Fixtures (conftest.py)
|
|
27
|
-
- **Environment setup**: Mock
|
|
27
|
+
- **Environment setup**: Mock environment variables and session IDs
|
|
28
28
|
- **Async client**: HTTP client for testing API interactions
|
|
29
29
|
- **Session management**: Isolation between test runs
|
|
30
30
|
|
|
@@ -23,8 +23,6 @@ SERVER_NAME = "Test MCP Server"
|
|
|
23
23
|
|
|
24
24
|
def run_server_with_mock(server_port: int) -> None: # noqa: C901
|
|
25
25
|
"""Run server with mocked veris API client methods."""
|
|
26
|
-
# Ensure we're in simulation mode
|
|
27
|
-
os.environ["ENV"] = "simulation"
|
|
28
26
|
os.environ["VERIS_API_URL"] = "http://test-endpoint"
|
|
29
27
|
|
|
30
28
|
# Create a mock function for the API client
|
|
@@ -257,7 +257,10 @@ async def test_spy_decorator_with_session(simulation_env):
|
|
|
257
257
|
mock_log_call.assert_called_once_with(
|
|
258
258
|
session_id="spy-session-123",
|
|
259
259
|
function_name="test_func",
|
|
260
|
-
parameters=
|
|
260
|
+
parameters={
|
|
261
|
+
"x": {"value": "42", "type": "<class 'int'>"},
|
|
262
|
+
"y": {"value": "hello", "type": "<class 'str'>"},
|
|
263
|
+
},
|
|
261
264
|
docstring="A test function that returns a dict.",
|
|
262
265
|
)
|
|
263
266
|
mock_log_response.assert_called_once_with(
|
|
@@ -312,7 +315,10 @@ def test_spy_decorator_sync_function(simulation_env):
|
|
|
312
315
|
mock_log_call.assert_called_once_with(
|
|
313
316
|
session_id="sync-spy-session",
|
|
314
317
|
function_name="sync_func",
|
|
315
|
-
parameters=
|
|
318
|
+
parameters={
|
|
319
|
+
"a": {"value": "10", "type": "<class 'int'>"},
|
|
320
|
+
"b": {"value": "20", "type": "<class 'int'>"},
|
|
321
|
+
},
|
|
316
322
|
docstring="Adds two numbers.",
|
|
317
323
|
)
|
|
318
324
|
mock_log_response.assert_called_once_with(session_id="sync-spy-session", response=30)
|
|
@@ -131,8 +131,7 @@ def mock_api_client_with_options():
|
|
|
131
131
|
@pytest.mark.asyncio
|
|
132
132
|
async def test_tool_options_passed_to_mock_call(mock_api_client_with_options, multi_tool_agent):
|
|
133
133
|
"""Verify that ToolCallOptions are correctly passed to the mock_tool_call function."""
|
|
134
|
-
# Set up
|
|
135
|
-
os.environ["ENV"] = "simulation"
|
|
134
|
+
# Set up session for mocking
|
|
136
135
|
veris.set_session_id("test-session-tool-options")
|
|
137
136
|
|
|
138
137
|
try:
|
|
@@ -1433,6 +1433,15 @@ wheels = [
|
|
|
1433
1433
|
{ url = "https://files.pythonhosted.org/packages/f7/1f/b876b1f83aef204198a42dc101613fefccb32258e5428b5f9259677864b4/starlette-0.47.2-py3-none-any.whl", hash = "sha256:c5847e96134e5c5371ee9fac6fdf1a67336d5815e09eb2a01fdb57a351ef915b", size = 72984, upload-time = "2025-07-20T17:31:56.738Z" },
|
|
1434
1434
|
]
|
|
1435
1435
|
|
|
1436
|
+
[[package]]
|
|
1437
|
+
name = "tenacity"
|
|
1438
|
+
version = "9.1.2"
|
|
1439
|
+
source = { registry = "https://pypi.org/simple" }
|
|
1440
|
+
sdist = { url = "https://files.pythonhosted.org/packages/0a/d4/2b0cd0fe285e14b36db076e78c93766ff1d529d70408bd1d2a5a84f1d929/tenacity-9.1.2.tar.gz", hash = "sha256:1169d376c297e7de388d18b4481760d478b0e99a777cad3a9c86e556f4b697cb", size = 48036, upload-time = "2025-04-02T08:25:09.966Z" }
|
|
1441
|
+
wheels = [
|
|
1442
|
+
{ url = "https://files.pythonhosted.org/packages/e5/30/643397144bfbfec6f6ef821f36f33e57d35946c44a2352d3c9f0ae847619/tenacity-9.1.2-py3-none-any.whl", hash = "sha256:f77bf36710d8b73a50b2dd155c97b870017ad21afe6ab300326b0371b3b05138", size = 28248, upload-time = "2025-04-02T08:25:07.678Z" },
|
|
1443
|
+
]
|
|
1444
|
+
|
|
1436
1445
|
[[package]]
|
|
1437
1446
|
name = "tomli"
|
|
1438
1447
|
version = "2.2.1"
|
|
@@ -1556,7 +1565,7 @@ wheels = [
|
|
|
1556
1565
|
|
|
1557
1566
|
[[package]]
|
|
1558
1567
|
name = "veris-ai"
|
|
1559
|
-
version = "1.
|
|
1568
|
+
version = "1.9.0"
|
|
1560
1569
|
source = { editable = "." }
|
|
1561
1570
|
dependencies = [
|
|
1562
1571
|
{ name = "httpx" },
|
|
@@ -1571,6 +1580,7 @@ dependencies = [
|
|
|
1571
1580
|
{ name = "opentelemetry-sdk" },
|
|
1572
1581
|
{ name = "pydantic" },
|
|
1573
1582
|
{ name = "requests" },
|
|
1583
|
+
{ name = "tenacity" },
|
|
1574
1584
|
]
|
|
1575
1585
|
|
|
1576
1586
|
[package.optional-dependencies]
|
|
@@ -1637,6 +1647,7 @@ requires-dist = [
|
|
|
1637
1647
|
{ name = "pytest-cov", marker = "extra == 'dev'", specifier = ">=4.1.0" },
|
|
1638
1648
|
{ name = "requests", specifier = ">=2.31.0" },
|
|
1639
1649
|
{ name = "ruff", marker = "extra == 'dev'", specifier = ">=0.11.4" },
|
|
1650
|
+
{ name = "tenacity", specifier = ">=9.1.2" },
|
|
1640
1651
|
{ name = "wrapt", marker = "extra == 'instrument'" },
|
|
1641
1652
|
]
|
|
1642
1653
|
provides-extras = ["dev", "fastapi", "agents", "instrument"]
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
"""Logging utilities for VERIS tool calls and responses."""
|
|
2
|
-
|
|
3
|
-
import json
|
|
4
|
-
import logging
|
|
5
|
-
from typing import Any
|
|
6
|
-
|
|
7
|
-
from veris_ai.api_client import get_api_client
|
|
8
|
-
|
|
9
|
-
logger = logging.getLogger(__name__)
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def log_tool_call(
|
|
13
|
-
session_id: str,
|
|
14
|
-
function_name: str,
|
|
15
|
-
parameters: str,
|
|
16
|
-
docstring: str,
|
|
17
|
-
) -> None:
|
|
18
|
-
"""Log tool call synchronously to the VERIS logging endpoint."""
|
|
19
|
-
api_client = get_api_client()
|
|
20
|
-
endpoint = api_client.get_log_tool_call_endpoint(session_id)
|
|
21
|
-
payload = {
|
|
22
|
-
"function_name": function_name,
|
|
23
|
-
"parameters": json.loads(parameters),
|
|
24
|
-
"docstring": docstring,
|
|
25
|
-
}
|
|
26
|
-
try:
|
|
27
|
-
api_client.post(endpoint, payload)
|
|
28
|
-
logger.debug(f"Tool call logged for {function_name}")
|
|
29
|
-
except Exception as e:
|
|
30
|
-
logger.warning(f"Failed to log tool call for {function_name}: {e}")
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
def log_tool_response(session_id: str, response: Any) -> None: # noqa: ANN401
|
|
34
|
-
"""Log tool response synchronously to the VERIS logging endpoint."""
|
|
35
|
-
api_client = get_api_client()
|
|
36
|
-
endpoint = api_client.get_log_tool_response_endpoint(session_id)
|
|
37
|
-
|
|
38
|
-
payload = {
|
|
39
|
-
"response": json.dumps(response, default=str),
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
try:
|
|
43
|
-
api_client.post(endpoint, payload)
|
|
44
|
-
logger.debug("Tool response logged")
|
|
45
|
-
except Exception as e:
|
|
46
|
-
logger.warning(f"Failed to log tool response: {e}")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|