veris-ai 1.7.0__tar.gz → 1.8.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.7.0 → veris_ai-1.8.0}/.github/workflows/test.yml +1 -1
- {veris_ai-1.7.0 → veris_ai-1.8.0}/.pre-commit-config.yaml +3 -3
- {veris_ai-1.7.0 → veris_ai-1.8.0}/PKG-INFO +42 -10
- {veris_ai-1.7.0 → veris_ai-1.8.0}/README.md +37 -7
- {veris_ai-1.7.0 → veris_ai-1.8.0}/examples/README.md +11 -0
- veris_ai-1.8.0/examples/openai_agents_example.py +176 -0
- {veris_ai-1.7.0 → veris_ai-1.8.0}/pyproject.toml +6 -3
- {veris_ai-1.7.0 → veris_ai-1.8.0}/src/veris_ai/README.md +27 -2
- veris_ai-1.8.0/src/veris_ai/__init__.py +70 -0
- veris_ai-1.8.0/src/veris_ai/agents_wrapper.py +266 -0
- veris_ai-1.8.0/src/veris_ai/api_client.py +68 -0
- veris_ai-1.8.0/src/veris_ai/logging.py +87 -0
- {veris_ai-1.7.0 → veris_ai-1.8.0}/src/veris_ai/observability.py +8 -10
- {veris_ai-1.7.0 → veris_ai-1.8.0}/src/veris_ai/tool_mock.py +23 -83
- {veris_ai-1.7.0 → veris_ai-1.8.0}/src/veris_ai/utils.py +15 -0
- veris_ai-1.8.0/tests/test_agents_wrapper_simple.py +301 -0
- {veris_ai-1.7.0 → veris_ai-1.8.0}/tests/test_mcp_protocol_server_mocked.py +49 -70
- {veris_ai-1.7.0 → veris_ai-1.8.0}/tests/test_tool_mock.py +54 -128
- veris_ai-1.8.0/uv.lock +1737 -0
- veris_ai-1.7.0/src/veris_ai/__init__.py +0 -17
- veris_ai-1.7.0/src/veris_ai/logging.py +0 -153
- veris_ai-1.7.0/uv.lock +0 -2880
- {veris_ai-1.7.0 → veris_ai-1.8.0}/.cursor/rules/documentation-management.mdc +0 -0
- {veris_ai-1.7.0 → veris_ai-1.8.0}/.github/workflows/release.yml +0 -0
- {veris_ai-1.7.0 → veris_ai-1.8.0}/.gitignore +0 -0
- {veris_ai-1.7.0 → veris_ai-1.8.0}/CHANGELOG.md +0 -0
- {veris_ai-1.7.0 → veris_ai-1.8.0}/CLAUDE.md +0 -0
- {veris_ai-1.7.0 → veris_ai-1.8.0}/LICENSE +0 -0
- {veris_ai-1.7.0 → veris_ai-1.8.0}/examples/__init__.py +0 -0
- {veris_ai-1.7.0 → veris_ai-1.8.0}/examples/import_options.py +0 -0
- {veris_ai-1.7.0 → veris_ai-1.8.0}/src/veris_ai/jaeger_interface/README.md +0 -0
- {veris_ai-1.7.0 → veris_ai-1.8.0}/src/veris_ai/jaeger_interface/__init__.py +0 -0
- {veris_ai-1.7.0 → veris_ai-1.8.0}/src/veris_ai/jaeger_interface/client.py +0 -0
- {veris_ai-1.7.0 → veris_ai-1.8.0}/src/veris_ai/jaeger_interface/models.py +0 -0
- {veris_ai-1.7.0 → veris_ai-1.8.0}/src/veris_ai/models.py +0 -0
- {veris_ai-1.7.0 → veris_ai-1.8.0}/tests/README.md +0 -0
- {veris_ai-1.7.0 → veris_ai-1.8.0}/tests/__init__.py +0 -0
- {veris_ai-1.7.0 → veris_ai-1.8.0}/tests/conftest.py +0 -0
- {veris_ai-1.7.0 → veris_ai-1.8.0}/tests/fixtures/__init__.py +0 -0
- {veris_ai-1.7.0 → veris_ai-1.8.0}/tests/fixtures/http_server.py +0 -0
- {veris_ai-1.7.0 → veris_ai-1.8.0}/tests/fixtures/simple_app.py +0 -0
- {veris_ai-1.7.0 → veris_ai-1.8.0}/tests/test_utils.py +0 -0
|
@@ -3,21 +3,21 @@ repos:
|
|
|
3
3
|
hooks:
|
|
4
4
|
- id: ruff-check
|
|
5
5
|
name: Ruff lint
|
|
6
|
-
entry: uv run ruff check .
|
|
6
|
+
entry: uv run ruff check --fix .
|
|
7
7
|
language: system
|
|
8
8
|
pass_filenames: false
|
|
9
9
|
types: [python]
|
|
10
10
|
|
|
11
11
|
- id: ruff-format-check
|
|
12
12
|
name: Ruff format (check)
|
|
13
|
-
entry: uv run ruff format
|
|
13
|
+
entry: uv run ruff format
|
|
14
14
|
language: system
|
|
15
15
|
pass_filenames: false
|
|
16
16
|
types: [python]
|
|
17
17
|
|
|
18
18
|
- id: mypy
|
|
19
19
|
name: Mypy type check
|
|
20
|
-
entry: uv run mypy src/veris_ai
|
|
20
|
+
entry: uv run mypy src/veris_ai
|
|
21
21
|
language: system
|
|
22
22
|
pass_filenames: false
|
|
23
23
|
types: [python]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: veris-ai
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.8.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
|
|
@@ -9,6 +9,7 @@ License-Expression: MIT
|
|
|
9
9
|
License-File: LICENSE
|
|
10
10
|
Requires-Python: >=3.11
|
|
11
11
|
Requires-Dist: httpx>=0.24.0
|
|
12
|
+
Requires-Dist: logfire>=4.3.3
|
|
12
13
|
Requires-Dist: opentelemetry-api>=1.34.1
|
|
13
14
|
Requires-Dist: opentelemetry-exporter-otlp>=1.34.1
|
|
14
15
|
Requires-Dist: opentelemetry-instrumentation-fastapi>=0.55b1
|
|
@@ -19,11 +20,12 @@ Requires-Dist: opentelemetry-instrumentation>=0.55b1
|
|
|
19
20
|
Requires-Dist: opentelemetry-sdk>=1.34.1
|
|
20
21
|
Requires-Dist: pydantic>=2.0.0
|
|
21
22
|
Requires-Dist: requests>=2.31.0
|
|
22
|
-
|
|
23
|
+
Provides-Extra: agents
|
|
24
|
+
Requires-Dist: openai-agents>=0.0.1; extra == 'agents'
|
|
23
25
|
Provides-Extra: dev
|
|
24
26
|
Requires-Dist: black>=23.7.0; extra == 'dev'
|
|
25
27
|
Requires-Dist: mypy>=1.5.1; extra == 'dev'
|
|
26
|
-
Requires-Dist: openai-agents>=0.
|
|
28
|
+
Requires-Dist: openai-agents>=0.2.5; extra == 'dev'
|
|
27
29
|
Requires-Dist: pre-commit>=3.3.3; extra == 'dev'
|
|
28
30
|
Requires-Dist: pytest-asyncio>=0.21.1; extra == 'dev'
|
|
29
31
|
Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
|
|
@@ -45,7 +47,7 @@ A Python package for Veris AI tools with simulation capabilities and FastAPI MCP
|
|
|
45
47
|
## Quick Reference
|
|
46
48
|
|
|
47
49
|
**Purpose**: Tool mocking, tracing, and FastAPI MCP integration for AI agent development
|
|
48
|
-
**Core Components**: [`tool_mock`](#function-mocking) • [`observability`](#sdk-observability-helpers) • [`fastapi_mcp`](#fastapi-mcp-integration) • [`jaeger_interface`](#jaeger-trace-interface)
|
|
50
|
+
**Core Components**: [`tool_mock`](#function-mocking) • [`api_client`](src/veris_ai/api_client.py) • [`observability`](#sdk-observability-helpers) • [`fastapi_mcp`](#fastapi-mcp-integration) • [`jaeger_interface`](#jaeger-trace-interface)
|
|
49
51
|
**Deep Dive**: [`Module Architecture`](src/veris_ai/README.md) • [`Testing Guide`](tests/README.md) • [`Usage Examples`](examples/README.md)
|
|
50
52
|
**Source of Truth**: Implementation details in [`src/veris_ai/`](src/veris_ai/) source code
|
|
51
53
|
|
|
@@ -84,13 +86,14 @@ from veris_ai import init_observability, instrument_fastapi_app # Provided by S
|
|
|
84
86
|
|
|
85
87
|
| Variable | Purpose | Default |
|
|
86
88
|
|----------|---------|---------|
|
|
87
|
-
| `
|
|
89
|
+
| `VERIS_API_KEY` | API authentication key | None |
|
|
88
90
|
| `VERIS_MOCK_TIMEOUT` | Request timeout (seconds) | `90.0` |
|
|
89
91
|
| `ENV` | Set to `"simulation"` for mock mode | Production |
|
|
90
|
-
| `VERIS_SERVICE_NAME` | Tracing service name | Auto-detected |
|
|
91
|
-
| `VERIS_OTLP_ENDPOINT` | OpenTelemetry collector | *Required for tracing* |
|
|
92
92
|
|
|
93
|
-
**Configuration
|
|
93
|
+
**Advanced Configuration** (rarely needed):
|
|
94
|
+
- `VERIS_API_URL`: Override default API endpoint (defaults to production)
|
|
95
|
+
|
|
96
|
+
**Configuration Details**: See [`src/veris_ai/api_client.py`](src/veris_ai/api_client.py) for API configuration and [`src/veris_ai/tool_mock.py`](src/veris_ai/tool_mock.py) for environment handling logic.
|
|
94
97
|
|
|
95
98
|
|
|
96
99
|
### SDK Observability Helpers
|
|
@@ -102,7 +105,7 @@ from fastapi import FastAPI
|
|
|
102
105
|
from veris_ai import init_observability, instrument_fastapi_app
|
|
103
106
|
|
|
104
107
|
# Initialize tracing/export early (no-op if dependencies are absent)
|
|
105
|
-
init_observability(
|
|
108
|
+
init_observability()
|
|
106
109
|
|
|
107
110
|
app = FastAPI()
|
|
108
111
|
|
|
@@ -110,6 +113,35 @@ app = FastAPI()
|
|
|
110
113
|
instrument_fastapi_app(app)
|
|
111
114
|
```
|
|
112
115
|
|
|
116
|
+
#### Observability Environment
|
|
117
|
+
|
|
118
|
+
Set these environment variables to enable exporting traces via OTLP (Logfire) and ensure consistent service naming:
|
|
119
|
+
|
|
120
|
+
| Variable | Example | Notes |
|
|
121
|
+
|----------|---------|-------|
|
|
122
|
+
| `OTEL_SERVICE_NAME` | `simulation-server` | Should match `VERIS_SERVICE_NAME` used elsewhere to keep traces aligned |
|
|
123
|
+
| `OTEL_EXPORTER_OTLP_ENDPOINT` | `https://logfire-api.pydantic.dev` | OTLP HTTP endpoint |
|
|
124
|
+
| `LOGFIRE_TOKEN` | `FILL_IN` | Logfire API token used by the exporter |
|
|
125
|
+
| `OTEL_EXPORTER_OTLP_HEADERS` | `'Authorization=FILL_IN'` | Include quotes to preserve the `=`; often `Authorization=Bearer <LOGFIRE_TOKEN>` |
|
|
126
|
+
|
|
127
|
+
Quick setup example:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
export OTEL_SERVICE_NAME="simulation-server"
|
|
131
|
+
export OTEL_EXPORTER_OTLP_ENDPOINT="https://logfire-api.pydantic.dev"
|
|
132
|
+
export LOGFIRE_TOKEN="<your-token>"
|
|
133
|
+
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=${LOGFIRE_TOKEN}"
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Then initialize in code early in your process:
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
from veris_ai import init_observability, instrument_fastapi_app
|
|
140
|
+
init_observability()
|
|
141
|
+
app = FastAPI()
|
|
142
|
+
instrument_fastapi_app(app)
|
|
143
|
+
```
|
|
144
|
+
|
|
113
145
|
What this enables:
|
|
114
146
|
- Sets global W3C propagator (TraceContext + Baggage)
|
|
115
147
|
- Optionally instruments FastAPI, requests, httpx, MCP client if installed
|
|
@@ -222,7 +254,7 @@ pytest --cov=veris_ai # Test with coverage
|
|
|
222
254
|
|
|
223
255
|
**Semantic Tag**: `module-architecture`
|
|
224
256
|
|
|
225
|
-
**Core Modules**: `tool_mock` (mocking), `jaeger_interface` (trace queries), `utils` (schema conversion)
|
|
257
|
+
**Core Modules**: `tool_mock` (mocking), `api_client` (centralized API), `jaeger_interface` (trace queries), `utils` (schema conversion)
|
|
226
258
|
|
|
227
259
|
**Complete Architecture**: See [`src/veris_ai/README.md`](src/veris_ai/README.md) for module overview, implementation flows, and configuration details.
|
|
228
260
|
|
|
@@ -5,7 +5,7 @@ A Python package for Veris AI tools with simulation capabilities and FastAPI MCP
|
|
|
5
5
|
## Quick Reference
|
|
6
6
|
|
|
7
7
|
**Purpose**: Tool mocking, tracing, and FastAPI MCP integration for AI agent development
|
|
8
|
-
**Core Components**: [`tool_mock`](#function-mocking) • [`observability`](#sdk-observability-helpers) • [`fastapi_mcp`](#fastapi-mcp-integration) • [`jaeger_interface`](#jaeger-trace-interface)
|
|
8
|
+
**Core Components**: [`tool_mock`](#function-mocking) • [`api_client`](src/veris_ai/api_client.py) • [`observability`](#sdk-observability-helpers) • [`fastapi_mcp`](#fastapi-mcp-integration) • [`jaeger_interface`](#jaeger-trace-interface)
|
|
9
9
|
**Deep Dive**: [`Module Architecture`](src/veris_ai/README.md) • [`Testing Guide`](tests/README.md) • [`Usage Examples`](examples/README.md)
|
|
10
10
|
**Source of Truth**: Implementation details in [`src/veris_ai/`](src/veris_ai/) source code
|
|
11
11
|
|
|
@@ -44,13 +44,14 @@ from veris_ai import init_observability, instrument_fastapi_app # Provided by S
|
|
|
44
44
|
|
|
45
45
|
| Variable | Purpose | Default |
|
|
46
46
|
|----------|---------|---------|
|
|
47
|
-
| `
|
|
47
|
+
| `VERIS_API_KEY` | API authentication key | None |
|
|
48
48
|
| `VERIS_MOCK_TIMEOUT` | Request timeout (seconds) | `90.0` |
|
|
49
49
|
| `ENV` | Set to `"simulation"` for mock mode | Production |
|
|
50
|
-
| `VERIS_SERVICE_NAME` | Tracing service name | Auto-detected |
|
|
51
|
-
| `VERIS_OTLP_ENDPOINT` | OpenTelemetry collector | *Required for tracing* |
|
|
52
50
|
|
|
53
|
-
**Configuration
|
|
51
|
+
**Advanced Configuration** (rarely needed):
|
|
52
|
+
- `VERIS_API_URL`: Override default API endpoint (defaults to production)
|
|
53
|
+
|
|
54
|
+
**Configuration Details**: See [`src/veris_ai/api_client.py`](src/veris_ai/api_client.py) for API configuration and [`src/veris_ai/tool_mock.py`](src/veris_ai/tool_mock.py) for environment handling logic.
|
|
54
55
|
|
|
55
56
|
|
|
56
57
|
### SDK Observability Helpers
|
|
@@ -62,7 +63,7 @@ from fastapi import FastAPI
|
|
|
62
63
|
from veris_ai import init_observability, instrument_fastapi_app
|
|
63
64
|
|
|
64
65
|
# Initialize tracing/export early (no-op if dependencies are absent)
|
|
65
|
-
init_observability(
|
|
66
|
+
init_observability()
|
|
66
67
|
|
|
67
68
|
app = FastAPI()
|
|
68
69
|
|
|
@@ -70,6 +71,35 @@ app = FastAPI()
|
|
|
70
71
|
instrument_fastapi_app(app)
|
|
71
72
|
```
|
|
72
73
|
|
|
74
|
+
#### Observability Environment
|
|
75
|
+
|
|
76
|
+
Set these environment variables to enable exporting traces via OTLP (Logfire) and ensure consistent service naming:
|
|
77
|
+
|
|
78
|
+
| Variable | Example | Notes |
|
|
79
|
+
|----------|---------|-------|
|
|
80
|
+
| `OTEL_SERVICE_NAME` | `simulation-server` | Should match `VERIS_SERVICE_NAME` used elsewhere to keep traces aligned |
|
|
81
|
+
| `OTEL_EXPORTER_OTLP_ENDPOINT` | `https://logfire-api.pydantic.dev` | OTLP HTTP endpoint |
|
|
82
|
+
| `LOGFIRE_TOKEN` | `FILL_IN` | Logfire API token used by the exporter |
|
|
83
|
+
| `OTEL_EXPORTER_OTLP_HEADERS` | `'Authorization=FILL_IN'` | Include quotes to preserve the `=`; often `Authorization=Bearer <LOGFIRE_TOKEN>` |
|
|
84
|
+
|
|
85
|
+
Quick setup example:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
export OTEL_SERVICE_NAME="simulation-server"
|
|
89
|
+
export OTEL_EXPORTER_OTLP_ENDPOINT="https://logfire-api.pydantic.dev"
|
|
90
|
+
export LOGFIRE_TOKEN="<your-token>"
|
|
91
|
+
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=${LOGFIRE_TOKEN}"
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Then initialize in code early in your process:
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
from veris_ai import init_observability, instrument_fastapi_app
|
|
98
|
+
init_observability()
|
|
99
|
+
app = FastAPI()
|
|
100
|
+
instrument_fastapi_app(app)
|
|
101
|
+
```
|
|
102
|
+
|
|
73
103
|
What this enables:
|
|
74
104
|
- Sets global W3C propagator (TraceContext + Baggage)
|
|
75
105
|
- Optionally instruments FastAPI, requests, httpx, MCP client if installed
|
|
@@ -182,7 +212,7 @@ pytest --cov=veris_ai # Test with coverage
|
|
|
182
212
|
|
|
183
213
|
**Semantic Tag**: `module-architecture`
|
|
184
214
|
|
|
185
|
-
**Core Modules**: `tool_mock` (mocking), `jaeger_interface` (trace queries), `utils` (schema conversion)
|
|
215
|
+
**Core Modules**: `tool_mock` (mocking), `api_client` (centralized API), `jaeger_interface` (trace queries), `utils` (schema conversion)
|
|
186
216
|
|
|
187
217
|
**Complete Architecture**: See [`src/veris_ai/README.md`](src/veris_ai/README.md) for module overview, implementation flows, and configuration details.
|
|
188
218
|
|
|
@@ -93,6 +93,17 @@ ENV=simulation VERIS_ENDPOINT_URL=http://localhost:8000 python import_options.py
|
|
|
93
93
|
ENABLE_TRACING=true USE_FASTAPI=true python import_options.py
|
|
94
94
|
```
|
|
95
95
|
|
|
96
|
+
w### Observability Environment (optional)
|
|
97
|
+
|
|
98
|
+
If you want traces exported while running examples, set the following before execution:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
export OTEL_SERVICE_NAME="simulation-server"
|
|
102
|
+
export OTEL_EXPORTER_OTLP_ENDPOINT="https://logfire-api.pydantic.dev"
|
|
103
|
+
export LOGFIRE_TOKEN="<your-token>"
|
|
104
|
+
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=${LOGFIRE_TOKEN}"
|
|
105
|
+
```
|
|
106
|
+
|
|
96
107
|
## Development Notes
|
|
97
108
|
|
|
98
109
|
**Semantic Tag**: `example-development`
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"""Example of using the Veris SDK with OpenAI agents to intercept tool calls."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import os
|
|
5
|
+
import sys
|
|
6
|
+
|
|
7
|
+
from veris_ai import veris, wrap
|
|
8
|
+
|
|
9
|
+
# Ensure the openai-agents package is installed
|
|
10
|
+
try:
|
|
11
|
+
from agents import Agent, Runner, function_tool
|
|
12
|
+
except ImportError:
|
|
13
|
+
print("Please install the openai-agents package: pip install veris-ai[agents]")
|
|
14
|
+
sys.exit(1)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# Define some example tools
|
|
18
|
+
@function_tool
|
|
19
|
+
def calculator(x: int, y: int, operation: str = "add") -> int:
|
|
20
|
+
"""Performs arithmetic operations on two numbers."""
|
|
21
|
+
if operation == "add":
|
|
22
|
+
return x + y
|
|
23
|
+
if operation == "multiply":
|
|
24
|
+
return x * y
|
|
25
|
+
if operation == "subtract":
|
|
26
|
+
return x - y
|
|
27
|
+
if operation == "divide":
|
|
28
|
+
return x // y if y != 0 else 0
|
|
29
|
+
return 0
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@function_tool
|
|
33
|
+
def search_web(query: str) -> str:
|
|
34
|
+
"""Searches the web for information."""
|
|
35
|
+
return f"Search results for: {query}"
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@function_tool
|
|
39
|
+
def get_weather(location: str) -> str:
|
|
40
|
+
"""Gets current weather for a location."""
|
|
41
|
+
return f"Weather in {location}: Sunny, 72°F"
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
async def example_basic_wrap() -> None:
|
|
45
|
+
"""Basic example: Wrap all tools."""
|
|
46
|
+
print("\n" + "=" * 60)
|
|
47
|
+
print("Example 1: Basic Wrap - All Tools Intercepted")
|
|
48
|
+
print("=" * 60)
|
|
49
|
+
|
|
50
|
+
# Create an agent with tools
|
|
51
|
+
agent = Agent(
|
|
52
|
+
name="Assistant",
|
|
53
|
+
model="gpt-4",
|
|
54
|
+
tools=[calculator, search_web, get_weather],
|
|
55
|
+
instructions="You are a helpful assistant with various tools.",
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
# Wrap the Runner.run method - all tools will be intercepted
|
|
59
|
+
wrapped_run = wrap(Runner.run)
|
|
60
|
+
|
|
61
|
+
# Use it like normal Runner.run
|
|
62
|
+
result = await wrapped_run(agent, "What's 10 + 5? Also search for Python tutorials.")
|
|
63
|
+
print(f"Result: {result.output}")
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
async def example_selective_wrap() -> None:
|
|
67
|
+
"""Example with selective tool interception."""
|
|
68
|
+
print("\n" + "=" * 60)
|
|
69
|
+
print("Example 2: Selective Wrap - Only Specific Tools")
|
|
70
|
+
print("=" * 60)
|
|
71
|
+
|
|
72
|
+
agent = Agent(
|
|
73
|
+
name="Assistant",
|
|
74
|
+
model="gpt-4",
|
|
75
|
+
tools=[calculator, search_web, get_weather],
|
|
76
|
+
instructions="You are a helpful assistant.",
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
# Only intercept calculator and search_web
|
|
80
|
+
wrapped_run = wrap(Runner.run, include_tools=["calculator", "search_web"])
|
|
81
|
+
|
|
82
|
+
print("📝 Only 'calculator' and 'search_web' will be mocked via Veris")
|
|
83
|
+
print(" 'get_weather' will run normally")
|
|
84
|
+
|
|
85
|
+
result = await wrapped_run(agent, "Calculate 5+3 and check weather in NYC")
|
|
86
|
+
print(f"Result: {result.output}")
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
async def example_exclude_tools() -> None:
|
|
90
|
+
"""Example excluding specific tools from interception."""
|
|
91
|
+
print("\n" + "=" * 60)
|
|
92
|
+
print("Example 3: Exclude Tools - Keep Some Tools Normal")
|
|
93
|
+
print("=" * 60)
|
|
94
|
+
|
|
95
|
+
agent = Agent(
|
|
96
|
+
name="Assistant",
|
|
97
|
+
model="gpt-4",
|
|
98
|
+
tools=[calculator, search_web, get_weather],
|
|
99
|
+
instructions="You are a helpful assistant.",
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
# Intercept everything EXCEPT get_weather
|
|
103
|
+
wrapped_run = wrap(Runner.run, exclude_tools=["get_weather"])
|
|
104
|
+
|
|
105
|
+
print("📝 All tools EXCEPT 'get_weather' will be mocked via Veris")
|
|
106
|
+
|
|
107
|
+
result = await wrapped_run(agent, "Calculate 10*5 and check weather in London")
|
|
108
|
+
print(f"Result: {result.output}")
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
async def example_coroutine_wrap() -> None:
|
|
112
|
+
"""Example wrapping a coroutine directly."""
|
|
113
|
+
print("\n" + "=" * 60)
|
|
114
|
+
print("Example 4: Direct Coroutine Wrap")
|
|
115
|
+
print("=" * 60)
|
|
116
|
+
|
|
117
|
+
agent = Agent(
|
|
118
|
+
name="Assistant",
|
|
119
|
+
model="gpt-4",
|
|
120
|
+
tools=[calculator],
|
|
121
|
+
instructions="You are a helpful assistant.",
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
# Wrap the coroutine directly
|
|
125
|
+
result = await wrap(Runner.run(agent, "What's 7 * 8?"))
|
|
126
|
+
print(f"Result: {result.output}")
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
async def main() -> None:
|
|
130
|
+
"""Run all examples."""
|
|
131
|
+
print("\n🚀 VERIS SDK - OPENAI AGENTS WRAPPER EXAMPLES")
|
|
132
|
+
print("\nThese examples demonstrate different ways to intercept tool calls")
|
|
133
|
+
print("from OpenAI agents and route them through the Veris SDK.\n")
|
|
134
|
+
|
|
135
|
+
# Set up the environment
|
|
136
|
+
# In production, these would be set as environment variables
|
|
137
|
+
if not os.getenv("VERIS_ENDPOINT_URL"):
|
|
138
|
+
print("⚠️ VERIS_ENDPOINT_URL not set. Using demo endpoint.")
|
|
139
|
+
os.environ["VERIS_ENDPOINT_URL"] = "http://demo.veris.ai"
|
|
140
|
+
|
|
141
|
+
# Set a session ID to enable mocking
|
|
142
|
+
veris.set_session_id("example-session-123")
|
|
143
|
+
print(f"✅ Session ID set: {veris.session_id}")
|
|
144
|
+
|
|
145
|
+
# Check if OpenAI API key is set
|
|
146
|
+
if not os.getenv("OPENAI_API_KEY"):
|
|
147
|
+
print("\n⚠️ Note: OPENAI_API_KEY not set.")
|
|
148
|
+
print(" The examples will show the pattern but won't actually run.")
|
|
149
|
+
print(" Set your API key to see real agent execution.\n")
|
|
150
|
+
|
|
151
|
+
try:
|
|
152
|
+
# Run examples
|
|
153
|
+
await example_basic_wrap()
|
|
154
|
+
await example_selective_wrap()
|
|
155
|
+
await example_exclude_tools()
|
|
156
|
+
await example_coroutine_wrap()
|
|
157
|
+
except Exception as e:
|
|
158
|
+
print(f"\n❌ Error: {e}")
|
|
159
|
+
print("\nMake sure to:")
|
|
160
|
+
print("1. Set OPENAI_API_KEY environment variable")
|
|
161
|
+
print("2. Set VERIS_ENDPOINT_URL to your Veris endpoint")
|
|
162
|
+
print("3. Install dependencies: pip install veris-ai[agents]")
|
|
163
|
+
finally:
|
|
164
|
+
# Clear session when done
|
|
165
|
+
veris.clear_session_id()
|
|
166
|
+
print("\n✅ Session cleared")
|
|
167
|
+
|
|
168
|
+
print("\n✨ Examples complete!")
|
|
169
|
+
print("\nNext steps:")
|
|
170
|
+
print("1. Set up your Veris endpoint")
|
|
171
|
+
print("2. Configure your OpenAI API key")
|
|
172
|
+
print("3. Use wrap() to intercept tool calls in your agents")
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
if __name__ == "__main__":
|
|
176
|
+
asyncio.run(main())
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "veris-ai"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.8.0"
|
|
8
8
|
description = "A Python package for Veris AI tools"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -23,8 +23,8 @@ dependencies = [
|
|
|
23
23
|
"opentelemetry-instrumentation-requests>=0.55b1",
|
|
24
24
|
"opentelemetry-instrumentation-httpx>=0.55b1",
|
|
25
25
|
"opentelemetry-instrumentation-mcp>=0.44.1",
|
|
26
|
-
"traceloop-sdk>=0.45.4",
|
|
27
26
|
"opentelemetry-api>=1.34.1",
|
|
27
|
+
"logfire>=4.3.3",
|
|
28
28
|
]
|
|
29
29
|
|
|
30
30
|
[project.optional-dependencies]
|
|
@@ -36,12 +36,15 @@ dev = [
|
|
|
36
36
|
"black>=23.7.0",
|
|
37
37
|
"mypy>=1.5.1",
|
|
38
38
|
"pre-commit>=3.3.3",
|
|
39
|
-
"openai-agents>=0.
|
|
39
|
+
"openai-agents>=0.2.5",
|
|
40
40
|
]
|
|
41
41
|
fastapi = [
|
|
42
42
|
"fastapi",
|
|
43
43
|
"fastapi-mcp>=0.4.0",
|
|
44
44
|
]
|
|
45
|
+
agents = [
|
|
46
|
+
"openai-agents>=0.0.1",
|
|
47
|
+
]
|
|
45
48
|
instrument = [
|
|
46
49
|
"wrapt",
|
|
47
50
|
"opentelemetry-api",
|
|
@@ -49,8 +49,33 @@ Environment variables are processed in [`tool_mock.py`](tool_mock.py):
|
|
|
49
49
|
- `VERIS_ENDPOINT_URL`: Mock server endpoint
|
|
50
50
|
- `VERIS_MOCK_TIMEOUT`: Request timeout (default: 90s)
|
|
51
51
|
- `ENV`: Set to `"simulation"` for mock mode
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
|
|
53
|
+
### Observability (OTLP / Logfire)
|
|
54
|
+
|
|
55
|
+
When using the observability helpers (`init_observability`, `instrument_fastapi_app`), configure the following environment variables so traces export correctly and are attributed to the right service name:
|
|
56
|
+
|
|
57
|
+
- `OTEL_SERVICE_NAME` — e.g. `simulation-server` (keep consistent with any `VERIS_SERVICE_NAME` you use)
|
|
58
|
+
- `OTEL_EXPORTER_OTLP_ENDPOINT` — e.g. `https://logfire-api.pydantic.dev`
|
|
59
|
+
- `LOGFIRE_TOKEN` — API token for Logfire
|
|
60
|
+
- `OTEL_EXPORTER_OTLP_HEADERS` — e.g. `Authorization=Bearer <LOGFIRE_TOKEN>` (quote the value)
|
|
61
|
+
|
|
62
|
+
Minimal shell setup:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
export OTEL_SERVICE_NAME="simulation-server"
|
|
66
|
+
export OTEL_EXPORTER_OTLP_ENDPOINT="https://logfire-api.pydantic.dev"
|
|
67
|
+
export LOGFIRE_TOKEN="<your-token>"
|
|
68
|
+
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=${LOGFIRE_TOKEN}"
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Then in code:
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
from veris_ai import init_observability, instrument_fastapi_app
|
|
75
|
+
init_observability()
|
|
76
|
+
app = FastAPI()
|
|
77
|
+
instrument_fastapi_app(app)
|
|
78
|
+
```
|
|
54
79
|
|
|
55
80
|
## Development Notes
|
|
56
81
|
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"""Veris AI Python SDK."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
__version__ = "0.1.0"
|
|
6
|
+
|
|
7
|
+
# Import lightweight modules that only use base dependencies
|
|
8
|
+
from .jaeger_interface import JaegerClient
|
|
9
|
+
from .models import ResponseExpectation
|
|
10
|
+
from .observability import init_observability, instrument_fastapi_app
|
|
11
|
+
from .tool_mock import veris
|
|
12
|
+
|
|
13
|
+
# Lazy import for modules with heavy dependencies
|
|
14
|
+
_veris_runner = None
|
|
15
|
+
_VerisConfig = None
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def veris_runner(*args: Any, **kwargs: Any) -> Any: # noqa: ANN401
|
|
19
|
+
"""Lazy loader for the veris_runner function from agents_wrapper.
|
|
20
|
+
|
|
21
|
+
This function wraps OpenAI agents Runner.run to intercept tool calls
|
|
22
|
+
through the Veris SDK's mocking infrastructure.
|
|
23
|
+
|
|
24
|
+
This function requires the 'agents' extra dependencies:
|
|
25
|
+
pip install veris-ai[agents]
|
|
26
|
+
"""
|
|
27
|
+
global _veris_runner # noqa: PLW0603
|
|
28
|
+
if _veris_runner is None:
|
|
29
|
+
try:
|
|
30
|
+
from .agents_wrapper import veris_runner as _veris_runner_impl # noqa: PLC0415
|
|
31
|
+
|
|
32
|
+
_veris_runner = _veris_runner_impl
|
|
33
|
+
except ImportError as e:
|
|
34
|
+
error_msg = (
|
|
35
|
+
"The 'veris_runner' function requires additional dependencies. "
|
|
36
|
+
"Please install them with: pip install veris-ai[agents]"
|
|
37
|
+
)
|
|
38
|
+
raise ImportError(error_msg) from e
|
|
39
|
+
return _veris_runner(*args, **kwargs)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def __getattr__(name: str) -> Any: # noqa: ANN401
|
|
43
|
+
"""Lazy load VerisConfig class."""
|
|
44
|
+
global _VerisConfig # noqa: PLW0603
|
|
45
|
+
if name == "VerisConfig":
|
|
46
|
+
if _VerisConfig is None:
|
|
47
|
+
try:
|
|
48
|
+
from .agents_wrapper import VerisConfig as _VerisConfig_impl # noqa: PLC0415
|
|
49
|
+
|
|
50
|
+
_VerisConfig = _VerisConfig_impl
|
|
51
|
+
except ImportError as e:
|
|
52
|
+
error_msg = (
|
|
53
|
+
"The 'VerisConfig' class requires additional dependencies. "
|
|
54
|
+
"Please install them with: pip install veris-ai[agents]"
|
|
55
|
+
)
|
|
56
|
+
raise ImportError(error_msg) from e
|
|
57
|
+
return _VerisConfig
|
|
58
|
+
msg = f"module {__name__!r} has no attribute {name!r}"
|
|
59
|
+
raise AttributeError(msg)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
__all__ = [
|
|
63
|
+
"veris",
|
|
64
|
+
"JaegerClient",
|
|
65
|
+
"ResponseExpectation",
|
|
66
|
+
"init_observability",
|
|
67
|
+
"instrument_fastapi_app",
|
|
68
|
+
"veris_runner",
|
|
69
|
+
"VerisConfig",
|
|
70
|
+
]
|