iris-eval 0.1.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.
- iris_eval-0.1.0/.gitignore +59 -0
- iris_eval-0.1.0/PKG-INFO +119 -0
- iris_eval-0.1.0/README.md +90 -0
- iris_eval-0.1.0/pyproject.toml +50 -0
- iris_eval-0.1.0/src/iris_eval/__init__.py +61 -0
- iris_eval-0.1.0/src/iris_eval/client.py +506 -0
- iris_eval-0.1.0/src/iris_eval/discovery.py +78 -0
- iris_eval-0.1.0/src/iris_eval/py.typed +0 -0
- iris_eval-0.1.0/src/iris_eval/pytest_plugin.py +106 -0
- iris_eval-0.1.0/src/iris_eval/types.py +120 -0
- iris_eval-0.1.0/tests/test_client.py +192 -0
- iris_eval-0.1.0/tests/test_discovery.py +60 -0
- iris_eval-0.1.0/tests/test_package.py +35 -0
- iris_eval-0.1.0/tests/test_plugin.py +118 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
.claude/
|
|
2
|
+
node_modules/
|
|
3
|
+
dist/
|
|
4
|
+
*.db
|
|
5
|
+
*.db-journal
|
|
6
|
+
*.db-wal
|
|
7
|
+
*.db-shm
|
|
8
|
+
coverage/
|
|
9
|
+
.env
|
|
10
|
+
.env.*
|
|
11
|
+
data/
|
|
12
|
+
.DS_Store
|
|
13
|
+
*.tsbuildinfo
|
|
14
|
+
.mcpregistry_*
|
|
15
|
+
demo-video/
|
|
16
|
+
.agents/
|
|
17
|
+
skills-lock.json
|
|
18
|
+
# Next.js build cache (website is in /website, but a stray `next build` from root leaves traces here)
|
|
19
|
+
.next/
|
|
20
|
+
# Playwright E2E artifacts
|
|
21
|
+
playwright-report/
|
|
22
|
+
test-results/
|
|
23
|
+
.playwright/
|
|
24
|
+
|
|
25
|
+
# Storybook build output — regenerated by `npm run build-storybook`
|
|
26
|
+
storybook-static/
|
|
27
|
+
|
|
28
|
+
# Truthbase test-counts cache — regenerated by `npm run claims:capture-tests` in CI
|
|
29
|
+
.claims-cache/
|
|
30
|
+
|
|
31
|
+
# Private planning notes. This repo is PUBLIC; planning docs belong to the
|
|
32
|
+
# private parent repo and must never be committed here.
|
|
33
|
+
#
|
|
34
|
+
# This lived only in .git/info/exclude, which is local to one clone and is
|
|
35
|
+
# never committed — so the protection did not travel. A fresh clone, a
|
|
36
|
+
# different machine, or CI had no exclusion at all, and the standard commit
|
|
37
|
+
# recipe for this repo is `git add -A`. Belongs in the tracked ignore file.
|
|
38
|
+
plans/
|
|
39
|
+
|
|
40
|
+
# UAT harness scratch: per-run IRIS_HOMEs and the generated report. The
|
|
41
|
+
# harness is the gate; its output is an artifact of one run on one machine.
|
|
42
|
+
tests/uat/.work/
|
|
43
|
+
tests/uat/UAT-REPORT.md
|
|
44
|
+
|
|
45
|
+
# proof:judge human-readable report — regenerated by each measurement run and
|
|
46
|
+
# uploaded as a workflow artifact. The machine-readable proof/judge-results.json
|
|
47
|
+
# IS committed (pending placeholder, then the lead commits the measured file).
|
|
48
|
+
proof/judge/RESULTS.md
|
|
49
|
+
|
|
50
|
+
# The stranger harness writes its records to a private directory; never commit a run here.
|
|
51
|
+
tests/acceptance/stranger/records/
|
|
52
|
+
stranger-records/
|
|
53
|
+
|
|
54
|
+
# The Python client (packages/python): its virtual environment and build artefacts
|
|
55
|
+
packages/python/.venv/
|
|
56
|
+
packages/python/dist/
|
|
57
|
+
packages/python/**/__pycache__/
|
|
58
|
+
packages/python/.pytest_cache/
|
|
59
|
+
packages/python/**/*.egg-info/
|
iris_eval-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: iris-eval
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: The Python client for Iris, the open-source agent-evaluation MCP server: log a trace, get its verdict, gate a test on it.
|
|
5
|
+
Project-URL: Homepage, https://iris-eval.com
|
|
6
|
+
Project-URL: Documentation, https://github.com/iris-eval/mcp-server/blob/main/packages/python/README.md
|
|
7
|
+
Project-URL: Source, https://github.com/iris-eval/mcp-server/tree/main/packages/python
|
|
8
|
+
Project-URL: Changelog, https://github.com/iris-eval/mcp-server/blob/main/CHANGELOG.md
|
|
9
|
+
Author: Iris
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
Keywords: agents,evaluation,iris,llm,mcp,pytest
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Framework :: Pytest
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Software Development :: Testing
|
|
22
|
+
Classifier: Typing :: Typed
|
|
23
|
+
Requires-Python: >=3.10
|
|
24
|
+
Requires-Dist: httpx<1,>=0.27
|
|
25
|
+
Provides-Extra: test
|
|
26
|
+
Requires-Dist: pytest-asyncio>=0.24; extra == 'test'
|
|
27
|
+
Requires-Dist: pytest>=8; extra == 'test'
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
|
|
30
|
+
# iris-eval — the Python client
|
|
31
|
+
|
|
32
|
+
[Iris](https://iris-eval.dev) is an open-source agent-evaluation MCP server: it stores your agent's traces and judges each one under 25 built-in rules — PII, injection, hallucination markers, tool loops, cost outliers, a regression watcher — with a verdict that says which layer decided and why. This package is the Python door to a running server: log a trace, get its verdict, gate a test on it.
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pip install iris-eval
|
|
36
|
+
npx -y @iris-eval/mcp-server --dashboard # the server, in another terminal (Node 22.13+)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from iris_eval import IrisClient
|
|
41
|
+
|
|
42
|
+
iris = IrisClient() # finds the server: IRIS_URL, or the runtime.json a running dashboard wrote
|
|
43
|
+
|
|
44
|
+
evaluation = iris.evaluate_output(
|
|
45
|
+
"The refund was approved and posts within five business days.",
|
|
46
|
+
input="Was the refund approved?",
|
|
47
|
+
agent_name="support-bot",
|
|
48
|
+
)
|
|
49
|
+
evaluation["verdict"] # {"state": "pass", "basis": "clean", "by": []}
|
|
50
|
+
|
|
51
|
+
logged = iris.log_trace("support-bot", input="…", output="…", run="nightly-42", case_key="refund-policy")
|
|
52
|
+
page = iris.get_traces(agent_name="support-bot", limit=20)
|
|
53
|
+
iris.health()["status"] # "ok" | "degraded"
|
|
54
|
+
iris.capabilities()["rules"] # every rule, what it needs, its published accuracy
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
A thin client over the HTTP API: the rules, the composer and the storage live in the server, and this package speaks to them — the same verdict the MCP tools, the dashboard and the CI gate read. `AsyncIrisClient` has the same methods, awaited.
|
|
58
|
+
|
|
59
|
+
## The methods
|
|
60
|
+
|
|
61
|
+
| Method | Route | What it answers |
|
|
62
|
+
|---|---|---|
|
|
63
|
+
| `log_trace(agent_name, *, input, output, tool_calls, latency_ms, token_usage, cost_usd, metadata, tools, run, case_key, session_id, spans, timestamp, evaluate, eval_type)` | `POST /api/v1/traces` | `{"trace_id", "status"}` — with `evaluate=True`, `"evaluation"` too |
|
|
64
|
+
| `evaluate_output(output, *, input, agent_name, eval_type, …)` | `POST /api/v1/traces` with `evaluate: true` | The evaluation: `verdict` (`state`, `basis`, `by`), `score`, `rule_results`, `critical_failures`, `coverage`, `provenance`. Over HTTP the evaluate door is the ingest door, so the output is stored as a trace of `agent_name` and shows on the dashboard |
|
|
65
|
+
| `get_traces(*, agent_name, framework, session, since, until, min_score, max_score, limit, offset, sort_by, sort_order, **extra)` | `GET /api/v1/traces` | `{"traces", "total", "limit", "offset"}` — any other keyword is sent as a query parameter as it is; one the server does not read is a 400 naming it |
|
|
66
|
+
| `get_trace(trace_id)` | `GET /api/v1/traces/:id` | `{"trace", "spans", "evals"}` |
|
|
67
|
+
| `health()` | `GET /api/v1/health` | Open, unkeyed; `status`, `version`, `checks` |
|
|
68
|
+
| `capabilities()` | `GET /api/v1/capabilities` | What this server can do |
|
|
69
|
+
|
|
70
|
+
Every answer is the route's JSON as a typed dictionary (`iris_eval.types`): the keys the [API reference](https://github.com/iris-eval/mcp-server/blob/main/docs/api-reference.md) documents, and any key the server adds later carried through.
|
|
71
|
+
|
|
72
|
+
**Errors.** A refusal raises `IrisError` with the server's own sentence, the status and the validation details: `IrisError: Invalid query parameters (GET /api/v1/traces → 400)`. A server that cannot be reached raises `IrisConnectionError` naming the URL and how to start one.
|
|
73
|
+
|
|
74
|
+
**Auth.** `IrisClient(api_key="…")` sends `Authorization: Bearer` — a server bound beyond loopback requires it; `IRIS_API_KEY` is read by the pytest fixture.
|
|
75
|
+
|
|
76
|
+
**Finding the server.** `IrisClient(base_url=None)`: `IRIS_URL` first (`http://host:port`), then the port the running dashboard recorded in `runtime.json` under `IRIS_HOME` (or `~/.iris`), verified with the health route before it is trusted. Nothing named: `IrisConnectionError` with the recipe.
|
|
77
|
+
|
|
78
|
+
## pytest
|
|
79
|
+
|
|
80
|
+
Installing the package registers a plugin. An `iris` fixture finds the server; `assert_iris` evaluates an output and asserts on the **verdict's state** — the composed verdict, never the score alone.
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
from iris_eval.pytest_plugin import assert_iris
|
|
84
|
+
|
|
85
|
+
def test_refund_answer(iris):
|
|
86
|
+
evaluation = assert_iris(
|
|
87
|
+
agent("Was the refund approved?"),
|
|
88
|
+
input="Was the refund approved?",
|
|
89
|
+
agent_name="support-bot",
|
|
90
|
+
client=iris,
|
|
91
|
+
)
|
|
92
|
+
assert evaluation["verdict"]["basis"] == "clean"
|
|
93
|
+
|
|
94
|
+
def test_the_leak_is_caught(iris):
|
|
95
|
+
assert_iris("The SSN is 123-45-6789.", input="q", expect="fail", client=iris)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
A failing assertion reads like the dashboard: `Iris verdict fail on detector_veto by no_pii (expected pass); score 0.4; evaluation eval_… on trace trace_…`. Without a server the tests are **skipped** with the sentence that says how to start one; set `IRIS_REQUIRE=1` in a CI job that must not pass green because no server ran. `--iris-url` and `--iris-api-key` override the environment.
|
|
99
|
+
|
|
100
|
+
In CI, start the server in the job and point the tests at it:
|
|
101
|
+
|
|
102
|
+
```yaml
|
|
103
|
+
- run: npx -y @iris-eval/mcp-server --dashboard --dashboard-port 6920 --api-key "$IRIS_API_KEY" &
|
|
104
|
+
- run: pip install iris-eval && pytest
|
|
105
|
+
env:
|
|
106
|
+
IRIS_URL: http://127.0.0.1:6920
|
|
107
|
+
IRIS_API_KEY: ${{ secrets.IRIS_API_KEY }}
|
|
108
|
+
IRIS_REQUIRE: "1"
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Or gate a traces file without a server at all — the [CI gate](https://github.com/iris-eval/mcp-server/blob/main/docs/ci-gate.md) and its GitHub Action.
|
|
112
|
+
|
|
113
|
+
## Tracing from Python
|
|
114
|
+
|
|
115
|
+
This package does not instrument your code. Iris reads the OpenTelemetry traces your framework already emits — Pydantic AI, Google ADK, LangGraph, CrewAI, Semantic Kernel and the others — through `POST /v1/traces` on the dashboard port ([docs/otel-integration.md](https://github.com/iris-eval/mcp-server/blob/main/docs/otel-integration.md)); a decorator SDK that built a second trace model is a maintenance surface Iris chose not to carry.
|
|
116
|
+
|
|
117
|
+
## Versions
|
|
118
|
+
|
|
119
|
+
The client follows the HTTP API, which the server versions; `iris_eval.__version__` is this package's own. Python 3.10+, `httpx` the only dependency. Source: [packages/python](https://github.com/iris-eval/mcp-server/tree/main/packages/python).
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# iris-eval — the Python client
|
|
2
|
+
|
|
3
|
+
[Iris](https://iris-eval.dev) is an open-source agent-evaluation MCP server: it stores your agent's traces and judges each one under 25 built-in rules — PII, injection, hallucination markers, tool loops, cost outliers, a regression watcher — with a verdict that says which layer decided and why. This package is the Python door to a running server: log a trace, get its verdict, gate a test on it.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
pip install iris-eval
|
|
7
|
+
npx -y @iris-eval/mcp-server --dashboard # the server, in another terminal (Node 22.13+)
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
```python
|
|
11
|
+
from iris_eval import IrisClient
|
|
12
|
+
|
|
13
|
+
iris = IrisClient() # finds the server: IRIS_URL, or the runtime.json a running dashboard wrote
|
|
14
|
+
|
|
15
|
+
evaluation = iris.evaluate_output(
|
|
16
|
+
"The refund was approved and posts within five business days.",
|
|
17
|
+
input="Was the refund approved?",
|
|
18
|
+
agent_name="support-bot",
|
|
19
|
+
)
|
|
20
|
+
evaluation["verdict"] # {"state": "pass", "basis": "clean", "by": []}
|
|
21
|
+
|
|
22
|
+
logged = iris.log_trace("support-bot", input="…", output="…", run="nightly-42", case_key="refund-policy")
|
|
23
|
+
page = iris.get_traces(agent_name="support-bot", limit=20)
|
|
24
|
+
iris.health()["status"] # "ok" | "degraded"
|
|
25
|
+
iris.capabilities()["rules"] # every rule, what it needs, its published accuracy
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
A thin client over the HTTP API: the rules, the composer and the storage live in the server, and this package speaks to them — the same verdict the MCP tools, the dashboard and the CI gate read. `AsyncIrisClient` has the same methods, awaited.
|
|
29
|
+
|
|
30
|
+
## The methods
|
|
31
|
+
|
|
32
|
+
| Method | Route | What it answers |
|
|
33
|
+
|---|---|---|
|
|
34
|
+
| `log_trace(agent_name, *, input, output, tool_calls, latency_ms, token_usage, cost_usd, metadata, tools, run, case_key, session_id, spans, timestamp, evaluate, eval_type)` | `POST /api/v1/traces` | `{"trace_id", "status"}` — with `evaluate=True`, `"evaluation"` too |
|
|
35
|
+
| `evaluate_output(output, *, input, agent_name, eval_type, …)` | `POST /api/v1/traces` with `evaluate: true` | The evaluation: `verdict` (`state`, `basis`, `by`), `score`, `rule_results`, `critical_failures`, `coverage`, `provenance`. Over HTTP the evaluate door is the ingest door, so the output is stored as a trace of `agent_name` and shows on the dashboard |
|
|
36
|
+
| `get_traces(*, agent_name, framework, session, since, until, min_score, max_score, limit, offset, sort_by, sort_order, **extra)` | `GET /api/v1/traces` | `{"traces", "total", "limit", "offset"}` — any other keyword is sent as a query parameter as it is; one the server does not read is a 400 naming it |
|
|
37
|
+
| `get_trace(trace_id)` | `GET /api/v1/traces/:id` | `{"trace", "spans", "evals"}` |
|
|
38
|
+
| `health()` | `GET /api/v1/health` | Open, unkeyed; `status`, `version`, `checks` |
|
|
39
|
+
| `capabilities()` | `GET /api/v1/capabilities` | What this server can do |
|
|
40
|
+
|
|
41
|
+
Every answer is the route's JSON as a typed dictionary (`iris_eval.types`): the keys the [API reference](https://github.com/iris-eval/mcp-server/blob/main/docs/api-reference.md) documents, and any key the server adds later carried through.
|
|
42
|
+
|
|
43
|
+
**Errors.** A refusal raises `IrisError` with the server's own sentence, the status and the validation details: `IrisError: Invalid query parameters (GET /api/v1/traces → 400)`. A server that cannot be reached raises `IrisConnectionError` naming the URL and how to start one.
|
|
44
|
+
|
|
45
|
+
**Auth.** `IrisClient(api_key="…")` sends `Authorization: Bearer` — a server bound beyond loopback requires it; `IRIS_API_KEY` is read by the pytest fixture.
|
|
46
|
+
|
|
47
|
+
**Finding the server.** `IrisClient(base_url=None)`: `IRIS_URL` first (`http://host:port`), then the port the running dashboard recorded in `runtime.json` under `IRIS_HOME` (or `~/.iris`), verified with the health route before it is trusted. Nothing named: `IrisConnectionError` with the recipe.
|
|
48
|
+
|
|
49
|
+
## pytest
|
|
50
|
+
|
|
51
|
+
Installing the package registers a plugin. An `iris` fixture finds the server; `assert_iris` evaluates an output and asserts on the **verdict's state** — the composed verdict, never the score alone.
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
from iris_eval.pytest_plugin import assert_iris
|
|
55
|
+
|
|
56
|
+
def test_refund_answer(iris):
|
|
57
|
+
evaluation = assert_iris(
|
|
58
|
+
agent("Was the refund approved?"),
|
|
59
|
+
input="Was the refund approved?",
|
|
60
|
+
agent_name="support-bot",
|
|
61
|
+
client=iris,
|
|
62
|
+
)
|
|
63
|
+
assert evaluation["verdict"]["basis"] == "clean"
|
|
64
|
+
|
|
65
|
+
def test_the_leak_is_caught(iris):
|
|
66
|
+
assert_iris("The SSN is 123-45-6789.", input="q", expect="fail", client=iris)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
A failing assertion reads like the dashboard: `Iris verdict fail on detector_veto by no_pii (expected pass); score 0.4; evaluation eval_… on trace trace_…`. Without a server the tests are **skipped** with the sentence that says how to start one; set `IRIS_REQUIRE=1` in a CI job that must not pass green because no server ran. `--iris-url` and `--iris-api-key` override the environment.
|
|
70
|
+
|
|
71
|
+
In CI, start the server in the job and point the tests at it:
|
|
72
|
+
|
|
73
|
+
```yaml
|
|
74
|
+
- run: npx -y @iris-eval/mcp-server --dashboard --dashboard-port 6920 --api-key "$IRIS_API_KEY" &
|
|
75
|
+
- run: pip install iris-eval && pytest
|
|
76
|
+
env:
|
|
77
|
+
IRIS_URL: http://127.0.0.1:6920
|
|
78
|
+
IRIS_API_KEY: ${{ secrets.IRIS_API_KEY }}
|
|
79
|
+
IRIS_REQUIRE: "1"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Or gate a traces file without a server at all — the [CI gate](https://github.com/iris-eval/mcp-server/blob/main/docs/ci-gate.md) and its GitHub Action.
|
|
83
|
+
|
|
84
|
+
## Tracing from Python
|
|
85
|
+
|
|
86
|
+
This package does not instrument your code. Iris reads the OpenTelemetry traces your framework already emits — Pydantic AI, Google ADK, LangGraph, CrewAI, Semantic Kernel and the others — through `POST /v1/traces` on the dashboard port ([docs/otel-integration.md](https://github.com/iris-eval/mcp-server/blob/main/docs/otel-integration.md)); a decorator SDK that built a second trace model is a maintenance surface Iris chose not to carry.
|
|
87
|
+
|
|
88
|
+
## Versions
|
|
89
|
+
|
|
90
|
+
The client follows the HTTP API, which the server versions; `iris_eval.__version__` is this package's own. Python 3.10+, `httpx` the only dependency. Source: [packages/python](https://github.com/iris-eval/mcp-server/tree/main/packages/python).
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.25"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "iris-eval"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "The Python client for Iris, the open-source agent-evaluation MCP server: log a trace, get its verdict, gate a test on it."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
authors = [{ name = "Iris" }]
|
|
13
|
+
keywords = ["iris", "evaluation", "agents", "llm", "mcp", "pytest"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 4 - Beta",
|
|
16
|
+
"Framework :: Pytest",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3.10",
|
|
21
|
+
"Programming Language :: Python :: 3.11",
|
|
22
|
+
"Programming Language :: Python :: 3.12",
|
|
23
|
+
"Programming Language :: Python :: 3.13",
|
|
24
|
+
"Topic :: Software Development :: Testing",
|
|
25
|
+
"Typing :: Typed",
|
|
26
|
+
]
|
|
27
|
+
dependencies = ["httpx>=0.27,<1"]
|
|
28
|
+
|
|
29
|
+
[project.optional-dependencies]
|
|
30
|
+
test = ["pytest>=8", "pytest-asyncio>=0.24"]
|
|
31
|
+
|
|
32
|
+
[project.urls]
|
|
33
|
+
Homepage = "https://iris-eval.com"
|
|
34
|
+
Documentation = "https://github.com/iris-eval/mcp-server/blob/main/packages/python/README.md"
|
|
35
|
+
Source = "https://github.com/iris-eval/mcp-server/tree/main/packages/python"
|
|
36
|
+
Changelog = "https://github.com/iris-eval/mcp-server/blob/main/CHANGELOG.md"
|
|
37
|
+
|
|
38
|
+
[project.entry-points.pytest11]
|
|
39
|
+
iris_eval = "iris_eval.pytest_plugin"
|
|
40
|
+
|
|
41
|
+
[tool.hatch.build.targets.wheel]
|
|
42
|
+
packages = ["src/iris_eval"]
|
|
43
|
+
|
|
44
|
+
[tool.hatch.build.targets.sdist]
|
|
45
|
+
include = ["src/iris_eval", "tests", "README.md", "pyproject.toml"]
|
|
46
|
+
|
|
47
|
+
[tool.pytest.ini_options]
|
|
48
|
+
testpaths = ["tests"]
|
|
49
|
+
asyncio_mode = "auto"
|
|
50
|
+
asyncio_default_fixture_loop_scope = "function"
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""iris-eval — the Python client for Iris, the open-source agent-evaluation MCP server.
|
|
2
|
+
|
|
3
|
+
from iris_eval import IrisClient
|
|
4
|
+
|
|
5
|
+
iris = IrisClient() # finds the server: IRIS_URL, or the runtime.json a running server wrote
|
|
6
|
+
logged = iris.log_trace("support-bot", input="Was the refund approved?", output="Yes, it posts within five days.")
|
|
7
|
+
evaluation = iris.evaluate_output("The refund was approved.", input="Was the refund approved?", agent_name="support-bot")
|
|
8
|
+
evaluation["verdict"]["state"] # "pass" | "fail" | "unknown"
|
|
9
|
+
|
|
10
|
+
A thin client over the HTTP API (docs/sdk-spec.md rules it so): the rules, the
|
|
11
|
+
composer and the storage live in the server; this package speaks to them. The
|
|
12
|
+
pytest plugin (``iris`` fixture, ``assert_iris``) rides on it.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from .client import (
|
|
16
|
+
DEFAULT_TIMEOUT,
|
|
17
|
+
AsyncIrisClient,
|
|
18
|
+
IrisClient,
|
|
19
|
+
IrisConnectionError,
|
|
20
|
+
IrisError,
|
|
21
|
+
)
|
|
22
|
+
from .discovery import ServerLocation, find_server
|
|
23
|
+
from .types import (
|
|
24
|
+
Capabilities,
|
|
25
|
+
Evaluation,
|
|
26
|
+
Health,
|
|
27
|
+
LoggedTrace,
|
|
28
|
+
RuleResult,
|
|
29
|
+
TokenUsage,
|
|
30
|
+
ToolCall,
|
|
31
|
+
Trace,
|
|
32
|
+
TraceDetail,
|
|
33
|
+
TracePage,
|
|
34
|
+
Verdict,
|
|
35
|
+
VerdictState,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
__version__ = "0.1.0"
|
|
39
|
+
|
|
40
|
+
__all__ = [
|
|
41
|
+
"AsyncIrisClient",
|
|
42
|
+
"Capabilities",
|
|
43
|
+
"DEFAULT_TIMEOUT",
|
|
44
|
+
"Evaluation",
|
|
45
|
+
"Health",
|
|
46
|
+
"IrisClient",
|
|
47
|
+
"IrisConnectionError",
|
|
48
|
+
"IrisError",
|
|
49
|
+
"LoggedTrace",
|
|
50
|
+
"RuleResult",
|
|
51
|
+
"ServerLocation",
|
|
52
|
+
"TokenUsage",
|
|
53
|
+
"ToolCall",
|
|
54
|
+
"Trace",
|
|
55
|
+
"TraceDetail",
|
|
56
|
+
"TracePage",
|
|
57
|
+
"Verdict",
|
|
58
|
+
"VerdictState",
|
|
59
|
+
"__version__",
|
|
60
|
+
"find_server",
|
|
61
|
+
]
|