veris-ai 1.10.0__tar.gz → 1.11.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.

Files changed (40) hide show
  1. {veris_ai-1.10.0 → veris_ai-1.11.0}/.github/workflows/test.yml +1 -1
  2. {veris_ai-1.10.0 → veris_ai-1.11.0}/PKG-INFO +56 -20
  3. {veris_ai-1.10.0 → veris_ai-1.11.0}/README.md +55 -1
  4. {veris_ai-1.10.0 → veris_ai-1.11.0}/pyproject.toml +26 -30
  5. {veris_ai-1.10.0 → veris_ai-1.11.0}/src/veris_ai/api_client.py +31 -9
  6. {veris_ai-1.10.0 → veris_ai-1.11.0}/src/veris_ai/tool_mock.py +29 -6
  7. {veris_ai-1.10.0 → veris_ai-1.11.0}/tests/test_agents_wrapper_simple.py +1 -1
  8. {veris_ai-1.10.0 → veris_ai-1.11.0}/tests/test_tool_mock.py +9 -5
  9. {veris_ai-1.10.0 → veris_ai-1.11.0}/uv.lock +409 -428
  10. {veris_ai-1.10.0 → veris_ai-1.11.0}/.cursor/rules/documentation-management.mdc +0 -0
  11. {veris_ai-1.10.0 → veris_ai-1.11.0}/.github/workflows/release.yml +0 -0
  12. {veris_ai-1.10.0 → veris_ai-1.11.0}/.gitignore +0 -0
  13. {veris_ai-1.10.0 → veris_ai-1.11.0}/.pre-commit-config.yaml +0 -0
  14. {veris_ai-1.10.0 → veris_ai-1.11.0}/CHANGELOG.md +0 -0
  15. {veris_ai-1.10.0 → veris_ai-1.11.0}/CLAUDE.md +0 -0
  16. {veris_ai-1.10.0 → veris_ai-1.11.0}/LICENSE +0 -0
  17. {veris_ai-1.10.0 → veris_ai-1.11.0}/examples/README.md +0 -0
  18. {veris_ai-1.10.0 → veris_ai-1.11.0}/examples/__init__.py +0 -0
  19. {veris_ai-1.10.0 → veris_ai-1.11.0}/examples/import_options.py +0 -0
  20. {veris_ai-1.10.0 → veris_ai-1.11.0}/examples/openai_agents_example.py +0 -0
  21. {veris_ai-1.10.0 → veris_ai-1.11.0}/src/veris_ai/README.md +0 -0
  22. {veris_ai-1.10.0 → veris_ai-1.11.0}/src/veris_ai/__init__.py +0 -0
  23. {veris_ai-1.10.0 → veris_ai-1.11.0}/src/veris_ai/agents_wrapper.py +0 -0
  24. {veris_ai-1.10.0 → veris_ai-1.11.0}/src/veris_ai/jaeger_interface/README.md +0 -0
  25. {veris_ai-1.10.0 → veris_ai-1.11.0}/src/veris_ai/jaeger_interface/__init__.py +0 -0
  26. {veris_ai-1.10.0 → veris_ai-1.11.0}/src/veris_ai/jaeger_interface/client.py +0 -0
  27. {veris_ai-1.10.0 → veris_ai-1.11.0}/src/veris_ai/jaeger_interface/models.py +0 -0
  28. {veris_ai-1.10.0 → veris_ai-1.11.0}/src/veris_ai/models.py +0 -0
  29. {veris_ai-1.10.0 → veris_ai-1.11.0}/src/veris_ai/observability.py +0 -0
  30. {veris_ai-1.10.0 → veris_ai-1.11.0}/src/veris_ai/utils.py +0 -0
  31. {veris_ai-1.10.0 → veris_ai-1.11.0}/tests/README.md +0 -0
  32. {veris_ai-1.10.0 → veris_ai-1.11.0}/tests/__init__.py +0 -0
  33. {veris_ai-1.10.0 → veris_ai-1.11.0}/tests/conftest.py +0 -0
  34. {veris_ai-1.10.0 → veris_ai-1.11.0}/tests/fixtures/__init__.py +0 -0
  35. {veris_ai-1.10.0 → veris_ai-1.11.0}/tests/fixtures/http_server.py +0 -0
  36. {veris_ai-1.10.0 → veris_ai-1.11.0}/tests/fixtures/simple_app.py +0 -0
  37. {veris_ai-1.10.0 → veris_ai-1.11.0}/tests/test_agents_wrapper_extract.py +0 -0
  38. {veris_ai-1.10.0 → veris_ai-1.11.0}/tests/test_mcp_protocol_server_mocked.py +0 -0
  39. {veris_ai-1.10.0 → veris_ai-1.11.0}/tests/test_utils.py +0 -0
  40. {veris_ai-1.10.0 → veris_ai-1.11.0}/tests/test_veris_runner_tool_options.py +0 -0
@@ -28,7 +28,7 @@ jobs:
28
28
 
29
29
  - name: Install dependencies
30
30
  run: |
31
- uv sync --all-extras
31
+ uv sync --all-groups
32
32
 
33
33
  - name: Run code quality checks with Ruff
34
34
  run: |
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: veris-ai
3
- Version: 1.10.0
3
+ Version: 1.11.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
@@ -21,28 +21,12 @@ Requires-Dist: opentelemetry-sdk>=1.34.1
21
21
  Requires-Dist: pydantic>=2.0.0
22
22
  Requires-Dist: requests>=2.31.0
23
23
  Requires-Dist: tenacity>=9.1.2
24
- Provides-Extra: agents
25
- Requires-Dist: openai-agents>=0.0.1; extra == 'agents'
26
- Provides-Extra: dev
27
- Requires-Dist: black>=23.7.0; extra == 'dev'
28
- Requires-Dist: mypy>=1.5.1; extra == 'dev'
29
- Requires-Dist: openai-agents>=0.2.5; extra == 'dev'
30
- Requires-Dist: pre-commit>=3.3.3; extra == 'dev'
31
- Requires-Dist: pytest-asyncio>=0.21.1; extra == 'dev'
32
- Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
33
- Requires-Dist: pytest>=7.4.0; extra == 'dev'
34
- Requires-Dist: ruff>=0.11.4; extra == 'dev'
35
- Provides-Extra: fastapi
36
- Requires-Dist: fastapi; extra == 'fastapi'
37
- Requires-Dist: fastapi-mcp>=0.4.0; extra == 'fastapi'
38
- Provides-Extra: instrument
39
- Requires-Dist: opentelemetry-api; extra == 'instrument'
40
- Requires-Dist: opentelemetry-sdk; extra == 'instrument'
41
- Requires-Dist: wrapt; extra == 'instrument'
42
24
  Description-Content-Type: text/markdown
43
25
 
44
26
  # Veris AI Python SDK
45
27
 
28
+ For more information visit us at https://veris.ai
29
+
46
30
  A Python package for Veris AI tools with simulation capabilities and FastAPI MCP (Model Context Protocol) integration.
47
31
 
48
32
  ## Quick Reference
@@ -151,7 +135,7 @@ What this enables:
151
135
 
152
136
  End-to-end propagation with the simulator:
153
137
  - The simulator injects W3C headers when connecting to your FastAPI MCP endpoints
154
- - The SDK injects W3C headers on `/api/v2/tool_mock` and logging requests back to the simulator
138
+ - The SDK injects W3C headers on `/v2/tool_mock` and logging requests back to the simulator
155
139
  - Result: customer agent spans and tool mocks appear under the same distributed trace
156
140
 
157
141
  ## Function Mocking
@@ -212,6 +196,58 @@ async def get_data() -> dict:
212
196
 
213
197
  **Implementation**: See [`src/veris_ai/tool_mock.py`](src/veris_ai/tool_mock.py) for decorator logic and API integration.
214
198
 
199
+ ### Core Instrument
200
+
201
+ Instrument OpenAI agents without changing tool code by using the SDK's Runner (extends OpenAI's Runner) and an optional VerisConfig for fine control.
202
+
203
+ Requirements:
204
+ - Install extras: `uv add "veris-ai[agents]"`
205
+ - Set `ENV=simulation` to enable mock behavior (otherwise passes through)
206
+
207
+ Minimal usage:
208
+
209
+ ```python
210
+ from veris_ai import Runner
211
+
212
+ result = await Runner.run(agent, "What's 10 + 5?")
213
+ ```
214
+
215
+ Select tools to intercept (include/exclude):
216
+
217
+ ```python
218
+ from veris_ai import Runner, VerisConfig
219
+
220
+ config = VerisConfig(include_tools=["calculator", "search_web"]) # or exclude_tools=[...]
221
+ result = await Runner.run(agent, "Process this", veris_config=config)
222
+ ```
223
+
224
+ Per‑tool behavior via ToolCallOptions:
225
+
226
+ ```python
227
+ from veris_ai import Runner, VerisConfig, ToolCallOptions, ResponseExpectation
228
+
229
+ config = VerisConfig(
230
+ tool_options={
231
+ "calculator": ToolCallOptions(
232
+ response_expectation=ResponseExpectation.REQUIRED,
233
+ cache_response=True,
234
+ mode="tool",
235
+ ),
236
+ "search_web": ToolCallOptions(
237
+ response_expectation=ResponseExpectation.NONE,
238
+ cache_response=False,
239
+ mode="spy",
240
+ ),
241
+ }
242
+ )
243
+
244
+ result = await Runner.run(agent, "Calculate and search", veris_config=config)
245
+ ```
246
+
247
+ Notes:
248
+ - Runner is a drop‑in enhancement over OpenAI's Runner (full details in [OpenAI Agents Integration](#openai-agents-integration))
249
+ - See complete examples in [`examples/openai_agents_example.py`](examples/openai_agents_example.py)
250
+
215
251
  ## OpenAI Agents Integration
216
252
 
217
253
  **Semantic Tag**: `openai-agents`
@@ -1,5 +1,7 @@
1
1
  # Veris AI Python SDK
2
2
 
3
+ For more information visit us at https://veris.ai
4
+
3
5
  A Python package for Veris AI tools with simulation capabilities and FastAPI MCP (Model Context Protocol) integration.
4
6
 
5
7
  ## Quick Reference
@@ -108,7 +110,7 @@ What this enables:
108
110
 
109
111
  End-to-end propagation with the simulator:
110
112
  - The simulator injects W3C headers when connecting to your FastAPI MCP endpoints
111
- - The SDK injects W3C headers on `/api/v2/tool_mock` and logging requests back to the simulator
113
+ - The SDK injects W3C headers on `/v2/tool_mock` and logging requests back to the simulator
112
114
  - Result: customer agent spans and tool mocks appear under the same distributed trace
113
115
 
114
116
  ## Function Mocking
@@ -169,6 +171,58 @@ async def get_data() -> dict:
169
171
 
170
172
  **Implementation**: See [`src/veris_ai/tool_mock.py`](src/veris_ai/tool_mock.py) for decorator logic and API integration.
171
173
 
174
+ ### Core Instrument
175
+
176
+ Instrument OpenAI agents without changing tool code by using the SDK's Runner (extends OpenAI's Runner) and an optional VerisConfig for fine control.
177
+
178
+ Requirements:
179
+ - Install extras: `uv add "veris-ai[agents]"`
180
+ - Set `ENV=simulation` to enable mock behavior (otherwise passes through)
181
+
182
+ Minimal usage:
183
+
184
+ ```python
185
+ from veris_ai import Runner
186
+
187
+ result = await Runner.run(agent, "What's 10 + 5?")
188
+ ```
189
+
190
+ Select tools to intercept (include/exclude):
191
+
192
+ ```python
193
+ from veris_ai import Runner, VerisConfig
194
+
195
+ config = VerisConfig(include_tools=["calculator", "search_web"]) # or exclude_tools=[...]
196
+ result = await Runner.run(agent, "Process this", veris_config=config)
197
+ ```
198
+
199
+ Per‑tool behavior via ToolCallOptions:
200
+
201
+ ```python
202
+ from veris_ai import Runner, VerisConfig, ToolCallOptions, ResponseExpectation
203
+
204
+ config = VerisConfig(
205
+ tool_options={
206
+ "calculator": ToolCallOptions(
207
+ response_expectation=ResponseExpectation.REQUIRED,
208
+ cache_response=True,
209
+ mode="tool",
210
+ ),
211
+ "search_web": ToolCallOptions(
212
+ response_expectation=ResponseExpectation.NONE,
213
+ cache_response=False,
214
+ mode="spy",
215
+ ),
216
+ }
217
+ )
218
+
219
+ result = await Runner.run(agent, "Calculate and search", veris_config=config)
220
+ ```
221
+
222
+ Notes:
223
+ - Runner is a drop‑in enhancement over OpenAI's Runner (full details in [OpenAI Agents Integration](#openai-agents-integration))
224
+ - See complete examples in [`examples/openai_agents_example.py`](examples/openai_agents_example.py)
225
+
172
226
  ## OpenAI Agents Integration
173
227
 
174
228
  **Semantic Tag**: `openai-agents`
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "veris-ai"
7
- version = "1.10.0"
7
+ version = "1.11.0"
8
8
  description = "A Python package for Veris AI tools"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -28,30 +28,6 @@ dependencies = [
28
28
  "tenacity>=9.1.2",
29
29
  ]
30
30
 
31
- [project.optional-dependencies]
32
- dev = [
33
- "ruff>=0.11.4",
34
- "pytest>=7.4.0",
35
- "pytest-asyncio>=0.21.1",
36
- "pytest-cov>=4.1.0",
37
- "black>=23.7.0",
38
- "mypy>=1.5.1",
39
- "pre-commit>=3.3.3",
40
- "openai-agents>=0.2.5",
41
- ]
42
- fastapi = [
43
- "fastapi",
44
- "fastapi-mcp>=0.4.0",
45
- ]
46
- agents = [
47
- "openai-agents>=0.0.1",
48
- ]
49
- instrument = [
50
- "wrapt",
51
- "opentelemetry-api",
52
- "opentelemetry-sdk",
53
- ]
54
-
55
31
  [project.urls]
56
32
  "Homepage" = "https://github.com/veris-ai/veris-python-sdk"
57
33
  "Bug Tracker" = "https://github.com/veris-ai/veris-python-sdk/issues"
@@ -63,6 +39,17 @@ packages = ["src/veris_ai"]
63
39
  testpaths = ["tests"]
64
40
  python_files = ["test_*.py"]
65
41
 
42
+ [tool.mypy]
43
+ ignore_missing_imports = false
44
+
45
+ [[tool.mypy.overrides]]
46
+ module = [
47
+ "fastapi.*",
48
+ "fastapi_mcp.*",
49
+ "agents.*",
50
+ ]
51
+ ignore_missing_imports = true
52
+
66
53
  [tool.ruff]
67
54
  line-length = 100
68
55
  target-version = "py311"
@@ -171,13 +158,22 @@ veris-ai = { workspace = true }
171
158
 
172
159
  [dependency-groups]
173
160
  dev = [
174
- "fastapi>=0.116.1",
175
- "fastapi-mcp>=0.4.0",
176
- "mypy>=1.17.0",
177
- "openai-agents>=0.0.1",
161
+ "ruff>=0.12.4",
178
162
  "pytest>=8.4.1",
179
163
  "pytest-asyncio>=1.1.0",
180
164
  "pytest-cov>=6.2.1",
181
- "ruff>=0.12.4",
165
+ "mypy>=1.17.0",
182
166
  "types-requests>=2.32.4.20250611",
167
+ "pre-commit>=3.3.3",
168
+ "uvicorn>=0.30.0",
169
+ ]
170
+ fastapi = [
171
+ "fastapi>=0.116.1",
172
+ "fastapi-mcp>=0.4.0",
173
+ ]
174
+ agents = [
175
+ "openai-agents>=0.2.5",
176
+ ]
177
+ instrument = [
178
+ "wrapt>=1.14.0",
183
179
  ]
@@ -11,28 +11,50 @@ logger = logging.getLogger(__name__)
11
11
 
12
12
 
13
13
  class SimulatorAPIClient:
14
- """Centralized client for making requests to VERIS simulation endpoints."""
14
+ """Centralized client for making requests to VERIS simulation endpoints.
15
+
16
+ Note:
17
+ This client intentionally reads configuration (base URL and API key)
18
+ from environment variables at call-time instead of at construction
19
+ time. This allows tests to patch environment variables and have those
20
+ changes reflected without recreating the singleton.
21
+ """
15
22
 
16
23
  def __init__(self) -> None:
17
- """Initialize the API client with configuration from environment variables."""
18
- self.base_url = os.getenv("VERIS_API_URL", "https://simulation.api.veris.ai/")
19
- self.api_key = os.getenv("VERIS_API_KEY")
24
+ """Initialize the API client with static timeout configuration."""
20
25
  self.timeout = float(os.getenv("VERIS_MOCK_TIMEOUT", "90.0"))
21
26
 
27
+ def _get_base_url(self) -> str:
28
+ """Resolve the base URL from environment.
29
+
30
+ Behavior:
31
+ - If VERIS_API_URL is unset, default to the dev simulator URL.
32
+ - If VERIS_API_URL is set to an empty string, treat it as empty
33
+ (do not fall back). This supports tests expecting connection
34
+ failures when an invalid endpoint is provided.
35
+ """
36
+ return os.getenv("VERIS_API_URL") or "https://simulator.api.veris.ai"
37
+
22
38
  def _build_headers(self) -> dict[str, str] | None:
23
39
  """Build headers including OpenTelemetry tracing and API key."""
24
40
  headers: dict[str, str] | None = None
25
41
  # Add API key header if available
26
- if self.api_key:
42
+ api_key = os.getenv("VERIS_API_KEY")
43
+ if api_key:
27
44
  if headers is None:
28
45
  headers = {}
29
- headers["x-api-key"] = self.api_key
46
+ headers["x-api-key"] = api_key
30
47
 
31
48
  return headers
32
49
 
33
50
  def post(self, endpoint: str, payload: dict[str, Any]) -> Any: # noqa: ANN401
34
51
  """Make a synchronous POST request to the specified endpoint."""
35
52
  headers = self._build_headers()
53
+ # Validate endpoint URL; raise ConnectError for non-absolute URLs to
54
+ # mirror connection failures in tests when base URL is intentionally invalid.
55
+ if not endpoint.startswith(("http://", "https://")):
56
+ raise httpx.ConnectError("Invalid endpoint URL (not absolute): {endpoint}")
57
+
36
58
  with httpx.Client(timeout=self.timeout) as client:
37
59
  response = client.post(endpoint, json=payload, headers=headers)
38
60
  response.raise_for_status()
@@ -41,15 +63,15 @@ class SimulatorAPIClient:
41
63
  @property
42
64
  def tool_mock_endpoint(self) -> str:
43
65
  """Get the tool mock endpoint URL."""
44
- return urljoin(self.base_url, "v2/tool_mock")
66
+ return urljoin(self._get_base_url(), "v2/tool_mock")
45
67
 
46
68
  def get_log_tool_call_endpoint(self, session_id: str) -> str:
47
69
  """Get the log tool call endpoint URL."""
48
- return urljoin(self.base_url, f"v2/simulations/{session_id}/log_tool_call")
70
+ return urljoin(self._get_base_url(), f"v2/simulations/{session_id}/log_tool_call")
49
71
 
50
72
  def get_log_tool_response_endpoint(self, session_id: str) -> str:
51
73
  """Get the log tool response endpoint URL."""
52
- return urljoin(self.base_url, f"v2/simulations/{session_id}/log_tool_response")
74
+ return urljoin(self._get_base_url(), f"v2/simulations/{session_id}/log_tool_response")
53
75
 
54
76
 
55
77
  # Global singleton instance
@@ -62,13 +62,14 @@ class VerisSDK:
62
62
  FastApiMCP,
63
63
  )
64
64
 
65
- oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
65
+ oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token", auto_error=False)
66
66
 
67
67
  async def authenticate_request(
68
- _: Request,
69
- token: str = Depends(oauth2_scheme), # noqa: ARG001
68
+ request: Request, # noqa: ARG001
69
+ token: str | None = Depends(oauth2_scheme),
70
70
  ) -> None:
71
- self.set_session_id(token)
71
+ if token:
72
+ self.set_session_id(token)
72
73
 
73
74
  # Create auth config with dependencies
74
75
  auth_config = AuthConfig(
@@ -267,6 +268,17 @@ def mock_tool_call(
267
268
  return_type_obj = type_hints.pop("return", Any)
268
269
  # Get function docstring
269
270
  docstring = inspect.getdoc(func) or ""
271
+
272
+ # Clean up parameters for V3 - just send values, not the nested dict
273
+ clean_params: dict[str, Any] = {}
274
+ for key, value in parameters.items():
275
+ if isinstance(value, dict) and "value" in value:
276
+ # Extract just the value from the nested structure
277
+ clean_params[key] = value["value"]
278
+ else:
279
+ # Already clean or unexpected format
280
+ clean_params[key] = value
281
+
270
282
  # Determine response expectation
271
283
  payload = {
272
284
  "session_id": session_id,
@@ -274,7 +286,7 @@ def mock_tool_call(
274
286
  "cache_response": bool(options.cache_response),
275
287
  "tool_call": {
276
288
  "function_name": func.__name__,
277
- "parameters": parameters,
289
+ "parameters": clean_params,
278
290
  "return_type": json.dumps(extract_json_schema(return_type_obj)),
279
291
  "docstring": docstring,
280
292
  },
@@ -299,9 +311,20 @@ def log_tool_call(
299
311
  """Log tool call synchronously to the VERIS logging endpoint."""
300
312
  api_client = get_api_client()
301
313
  endpoint = api_client.get_log_tool_call_endpoint(session_id)
314
+
315
+ # Clean up parameters for V3 - just send values, not the nested dict
316
+ clean_params: dict[str, Any] = {}
317
+ for key, value in parameters.items():
318
+ if isinstance(value, dict) and "value" in value:
319
+ # Extract just the value from the nested structure
320
+ clean_params[key] = value["value"]
321
+ else:
322
+ # Already clean or unexpected format
323
+ clean_params[key] = value
324
+
302
325
  payload = {
303
326
  "function_name": function_name,
304
- "parameters": parameters,
327
+ "parameters": clean_params,
305
328
  "docstring": docstring,
306
329
  }
307
330
  try:
@@ -244,7 +244,7 @@ async def test_runner_with_session_calls_endpoint(
244
244
 
245
245
  # Verify the call had correct structure
246
246
  first_call = mock_veris_endpoint["calls"][0]
247
- assert first_call["endpoint"] == "http://localhost:8000/api/v2/tool_mock"
247
+ assert first_call["endpoint"] == "http://localhost:8000/v2/tool_mock"
248
248
  assert first_call["payload"]["session_id"] == "test-session-123"
249
249
  assert "add_numbers" in str(first_call["payload"]) or "veris_tool_function" in str(
250
250
  first_call["payload"]
@@ -91,8 +91,9 @@ async def test_mock_http_error(simulation_env):
91
91
 
92
92
  @pytest.mark.asyncio
93
93
  async def test_mock_missing_endpoint():
94
- """Test that missing endpoint raises ValueError when function is called in simulation mode."""
95
- with patch.dict(os.environ, {"VERIS_API_URL": ""}):
94
+ """Test that missing endpoint raises ConnectError when invalid URL is used."""
95
+ # Use invalid URL that will trigger ConnectError
96
+ with patch.dict(os.environ, {"VERIS_API_URL": "http://invalid-nonexistent-domain-12345.local"}):
96
97
 
97
98
  @veris.mock()
98
99
  async def test_func():
@@ -101,15 +102,18 @@ async def test_mock_missing_endpoint():
101
102
  # Set session_id to enable simulation mode
102
103
  veris.set_session_id("test-session")
103
104
 
104
- # Since VERIS_API_URL has a default value, the function will try to connect
105
- # We'll test that the connection fails with httpx.ConnectError
105
+ # Invalid domain will cause ConnectError
106
106
  with pytest.raises(httpx.ConnectError):
107
107
  await test_func()
108
108
 
109
109
 
110
110
  @pytest.mark.asyncio
111
111
  async def test_mock_invalid_endpoint(simulation_env):
112
- with patch.dict(os.environ, {"VERIS_API_URL": ""}), pytest.raises(httpx.ConnectError):
112
+ # Use invalid URL that will trigger ConnectError
113
+ with (
114
+ patch.dict(os.environ, {"VERIS_API_URL": "http://invalid-nonexistent-domain-67890.local"}),
115
+ pytest.raises(httpx.ConnectError),
116
+ ):
113
117
 
114
118
  @veris.mock()
115
119
  async def test_func():