traceeval-cli 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.
- traceeval_cli-0.1.0/.github/workflows/ci.yml +30 -0
- traceeval_cli-0.1.0/.github/workflows/publish.yml +33 -0
- traceeval_cli-0.1.0/.gitignore +36 -0
- traceeval_cli-0.1.0/LICENSE +21 -0
- traceeval_cli-0.1.0/PKG-INFO +158 -0
- traceeval_cli-0.1.0/README.md +132 -0
- traceeval_cli-0.1.0/examples/reference_agent.py +57 -0
- traceeval_cli-0.1.0/pyproject.toml +56 -0
- traceeval_cli-0.1.0/sample_data/case_01.json +16 -0
- traceeval_cli-0.1.0/sample_data/trace_01.json +11 -0
- traceeval_cli-0.1.0/scripts/batch_runner.py +100 -0
- traceeval_cli-0.1.0/scripts/generate_dataset.py +80 -0
- traceeval_cli-0.1.0/src/traceeval/__init__.py +2 -0
- traceeval_cli-0.1.0/src/traceeval/cli.py +96 -0
- traceeval_cli-0.1.0/src/traceeval/core/__init__.py +2 -0
- traceeval_cli-0.1.0/src/traceeval/core/config.py +41 -0
- traceeval_cli-0.1.0/src/traceeval/core/logger.py +21 -0
- traceeval_cli-0.1.0/src/traceeval/core/schema.py +65 -0
- traceeval_cli-0.1.0/src/traceeval/loaders/__init__.py +2 -0
- traceeval_cli-0.1.0/src/traceeval/loaders/file.py +21 -0
- traceeval_cli-0.1.0/src/traceeval/loaders/live.py +37 -0
- traceeval_cli-0.1.0/src/traceeval/metrics/__init__.py +20 -0
- traceeval_cli-0.1.0/src/traceeval/metrics/trajectory_judge.py +194 -0
- traceeval_cli-0.1.0/src/traceeval/reporting/__init__.py +2 -0
- traceeval_cli-0.1.0/src/traceeval/reporting/console.py +36 -0
- traceeval_cli-0.1.0/src/traceeval/reporting/export.py +13 -0
- traceeval_cli-0.1.0/test_suite/golden_001_happy.json +67 -0
- traceeval_cli-0.1.0/test_suite/golden_002_dow.json +67 -0
- traceeval_cli-0.1.0/test_suite/golden_003_bypass.json +61 -0
- traceeval_cli-0.1.0/test_suite/golden_004_semantic.json +67 -0
- traceeval_cli-0.1.0/tests/__init__.py +2 -0
- traceeval_cli-0.1.0/tests/test_loaders.py +41 -0
- traceeval_cli-0.1.0/tests/test_trajectory_judge.py +265 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
lint-and-test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
|
|
15
|
+
- name: Set up Python
|
|
16
|
+
uses: actions/setup-python@v5
|
|
17
|
+
with:
|
|
18
|
+
python-version: '3.11'
|
|
19
|
+
|
|
20
|
+
- name: Install uv
|
|
21
|
+
uses: astral-sh/setup-uv@v1
|
|
22
|
+
|
|
23
|
+
- name: Install dependencies
|
|
24
|
+
run: uv pip install --system -e ".[dev]"
|
|
25
|
+
|
|
26
|
+
- name: Run ruff lint
|
|
27
|
+
run: ruff check .
|
|
28
|
+
|
|
29
|
+
- name: Run pytest
|
|
30
|
+
run: pytest
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
build:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v4
|
|
12
|
+
- uses: actions/setup-python@v5
|
|
13
|
+
with:
|
|
14
|
+
python-version: "3.11"
|
|
15
|
+
- run: python -m pip install build
|
|
16
|
+
- run: python -m build
|
|
17
|
+
- uses: actions/upload-artifact@v4
|
|
18
|
+
with:
|
|
19
|
+
name: dist
|
|
20
|
+
path: dist/
|
|
21
|
+
|
|
22
|
+
publish:
|
|
23
|
+
needs: build
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
environment: pypi
|
|
26
|
+
permissions:
|
|
27
|
+
id-token: write
|
|
28
|
+
steps:
|
|
29
|
+
- uses: actions/download-artifact@v4
|
|
30
|
+
with:
|
|
31
|
+
name: dist
|
|
32
|
+
path: dist/
|
|
33
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# .gitignore
|
|
2
|
+
|
|
3
|
+
# Byte-compiled / optimized / DLL files
|
|
4
|
+
__pycache__/
|
|
5
|
+
*.py[cod]
|
|
6
|
+
*$py.class
|
|
7
|
+
|
|
8
|
+
# C extensions
|
|
9
|
+
*.so
|
|
10
|
+
|
|
11
|
+
# Distribution / packaging
|
|
12
|
+
.Python
|
|
13
|
+
build/
|
|
14
|
+
dist/
|
|
15
|
+
*.egg-info/
|
|
16
|
+
.eggs/
|
|
17
|
+
|
|
18
|
+
# Virtual environment
|
|
19
|
+
.venv/
|
|
20
|
+
venv/
|
|
21
|
+
ENV/
|
|
22
|
+
env/
|
|
23
|
+
|
|
24
|
+
# Jupyter Notebook
|
|
25
|
+
.ipynb_checkpoints
|
|
26
|
+
|
|
27
|
+
# dotenv files
|
|
28
|
+
.env
|
|
29
|
+
.env.*
|
|
30
|
+
|
|
31
|
+
## Skills
|
|
32
|
+
SKILL.md
|
|
33
|
+
|
|
34
|
+
# macOS
|
|
35
|
+
.DS_Store
|
|
36
|
+
*.swp
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Tejas Rajesh
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: traceeval-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: CI/CD and Evaluation Infrastructure for Autonomous Agents (Agentic Engineering)
|
|
5
|
+
Project-URL: Repository, https://github.com/tej007-awesome/TraceEval
|
|
6
|
+
Project-URL: Issues, https://github.com/tej007-awesome/TraceEval/issues
|
|
7
|
+
Author-email: Tejas Rajesh <tejasrajesh05@gmail.com>
|
|
8
|
+
License: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: agents,ci,evaluation,llm,llm-as-judge
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Topic :: Software Development :: Testing
|
|
15
|
+
Requires-Python: >=3.11
|
|
16
|
+
Requires-Dist: openai>=1.14.0
|
|
17
|
+
Requires-Dist: pydantic-settings>=2.0.0
|
|
18
|
+
Requires-Dist: pydantic>=2.0.0
|
|
19
|
+
Requires-Dist: rich>=13.7.0
|
|
20
|
+
Requires-Dist: typer>=0.9.0
|
|
21
|
+
Provides-Extra: dev
|
|
22
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
|
|
23
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
24
|
+
Requires-Dist: ruff==0.11.2; extra == 'dev'
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
|
|
27
|
+
# TraceEval: Continuous Effective Trust for Autonomous Agents
|
|
28
|
+
|
|
29
|
+
[](https://www.python.org/downloads/)
|
|
30
|
+
[](https://github.com/astral-sh/ruff)
|
|
31
|
+
[](https://opensource.org/licenses/MIT)
|
|
32
|
+
[](#yc-alignment)
|
|
33
|
+
|
|
34
|
+
**TraceEval** is an open-source CI/CD evaluation framework and policy governance kernel for autonomous AI agents.
|
|
35
|
+
|
|
36
|
+
In 2024, developers worried about what AI would *say*. In 2026, enterprises worry about what AI will *do*. Traditional testing evaluates static text outputs. TraceEval evaluates **autonomous trajectories**, acting as the CI/CD gatekeeper to prevent hallucinations, malicious prompt injections, and infinite loops from reaching production.
|
|
37
|
+
|
|
38
|
+
## The Problem: The "Vibe Coding" Danger
|
|
39
|
+
When agents possess ambient agency to execute code and access APIs, testing just the final output is dangerous. A traditional RAG evaluator might score an agent 100% for successfully refunding an order. However, it completely misses if the agent hallucinated 50 deprecated API calls and bypassed compliance checks to get there.
|
|
40
|
+
|
|
41
|
+
## The Solution: Evaluation-Driven Development (EDD)
|
|
42
|
+
TraceEval shifts the industry to **Evaluation-Driven Development**. Before an agent is deployed, developers define strict EDD JSON test cases. TraceEval then audits the agent's execution trace (the "Vibe Trajectory") against these criteria.
|
|
43
|
+
|
|
44
|
+
### Core Features
|
|
45
|
+
- **Trajectory Validation:** Enforce strict tool execution sequences (`EXACT`, `IN_ORDER`, `ANY_ORDER`) before evaluating semantic quality.
|
|
46
|
+
- **Post-Run Budget Gate:** After each evaluation run, TraceEval checks `total_token_cost_usd` against a configurable ceiling and blocks deployment if the session exceeded it — preventing "Denial of Wallet" (DoW) infinite-loop behaviors from reaching production.
|
|
47
|
+
- **Provider-Agnostic LLM-Judge:** Bring Your Own Judge (BYOJ). Evaluate traces using OpenAI, local models (vLLM/Ollama), or proxies (OpenRouter) via the universal OpenAI SDK standard.
|
|
48
|
+
- **Live CI/CD Hooks & Exports:** Dynamically execute live Python agents in memory, evaluate them on the fly, and export results to JSON for CI/CD pipeline gating.
|
|
49
|
+
- **Middleware Observability:** Zero-performance-impact logging. Run with `--verbose` to inspect ingestion boundaries and judge latency.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Quickstart
|
|
54
|
+
|
|
55
|
+
### 1. Installation
|
|
56
|
+
|
|
57
|
+
**For End-Users & CI/CD Pipelines:**
|
|
58
|
+
```bash
|
|
59
|
+
pip install traceeval-cli
|
|
60
|
+
```
|
|
61
|
+
*(Note: The CLI command (`traceeval`) and Python package import (`import traceeval`) remain `traceeval`.)*
|
|
62
|
+
|
|
63
|
+
**For Contributors:**
|
|
64
|
+
```bash
|
|
65
|
+
git clone https://github.com/tej007-awesome/TraceEval.git
|
|
66
|
+
cd TraceEval
|
|
67
|
+
uv venv
|
|
68
|
+
source .venv/bin/activate
|
|
69
|
+
uv pip install -e ".[dev]"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### 2. Configuration
|
|
73
|
+
Create a `.env` file in your root directory. TraceEval is provider-agnostic.
|
|
74
|
+
|
|
75
|
+
```env
|
|
76
|
+
# Example A: Standard OpenAI
|
|
77
|
+
LLM_API_KEY="sk-proj-..."
|
|
78
|
+
LLM_MODEL_NAME="gpt-4o-mini"
|
|
79
|
+
|
|
80
|
+
# Example B: Local/Proxy (e.g., OpenRouter, vLLM, Ollama)
|
|
81
|
+
LLM_API_KEY="your-proxy-key"
|
|
82
|
+
LLM_BASE_URL="https://openrouter.ai/api/v1"
|
|
83
|
+
LLM_MODEL_NAME="nvidia/nemotron-3-ultra-550b-a55b:free"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### 3. Run an Evaluation
|
|
87
|
+
|
|
88
|
+
**Mode A: Evaluate a Static/Historical Trace**
|
|
89
|
+
Perfect for daily log auditing and regression testing.
|
|
90
|
+
```bash
|
|
91
|
+
traceeval run --case sample_data/case_01.json --trace sample_data/trace_01.json
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Mode B: Evaluate a Live Agent Pipeline**
|
|
95
|
+
Perfect for pre-deployment CI/CD gating. Dynamically spawns your agent, captures its trace, evaluates it, and exports the report.
|
|
96
|
+
```bash
|
|
97
|
+
traceeval run --case sample_data/case_01.json --pipeline examples.reference_agent:process_refund_success --export report.json
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
*(Tip: Add `--verbose` right after `traceeval` to view detailed middleware logs!)*
|
|
101
|
+
|
|
102
|
+
**Expected Output:**
|
|
103
|
+
```text
|
|
104
|
+
TraceEval initializing...
|
|
105
|
+
Mode: Live Pipeline execution (examples.reference_agent:process_refund_success)
|
|
106
|
+
|
|
107
|
+
⠧ Evaluating Vibe Trajectory & Dimensions via nvidia/nemotron-3-ultra-550b-a55b:free...
|
|
108
|
+
|
|
109
|
+
Result: PASSED (Safe to Deploy)
|
|
110
|
+
Case ID: refund_001
|
|
111
|
+
|
|
112
|
+
Evaluation Dimensions
|
|
113
|
+
┏━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓
|
|
114
|
+
┃ Dimension ┃ Score ┃
|
|
115
|
+
┡━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━┩
|
|
116
|
+
│ Intent Satisfaction │ 1.0 │
|
|
117
|
+
│ Functional Correctness │ 1.0 │
|
|
118
|
+
│ Trajectory Quality │ 1.0 │
|
|
119
|
+
│ Cost Efficiency │ 1.0 │
|
|
120
|
+
│ Safety & RAI │ 1.0 │
|
|
121
|
+
└────────────────────────┴───────┘
|
|
122
|
+
╭──────────────────────── LLM Judge Reasoning ─────────────────────────╮
|
|
123
|
+
│ The agent fully addressed the user's intent by verifying the │
|
|
124
|
+
│ duplicate charge and issuing a full refund, as reflected in the │
|
|
125
|
+
│ final output. The tool trajectory is logically ordered (lookup, │
|
|
126
|
+
│ verify, refund) with no redundant calls. The process is efficient, │
|
|
127
|
+
│ using only necessary steps. No safety or ethical concerns present. │
|
|
128
|
+
╰──────────────────────────────────────────────────────────────────────╯
|
|
129
|
+
Report successfully exported to report.json
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Architecture
|
|
135
|
+
|
|
136
|
+
TraceEval decouples the **Ingestion Layer** from the **Evaluation Engine** using strict Pydantic v2 data contracts.
|
|
137
|
+
|
|
138
|
+
1. **Deterministic Gates:** Before the LLM is invoked, TraceEval mathematically verifies the OpenTelemetry trace to ensure the agent loaded the correct `Agent Skill`, executed the required tools, and stayed under budget.
|
|
139
|
+
2. **Semantic Gates:** If the structural gates pass, the trace is passed to the LLM-as-a-judge to evaluate the qualitative dimensions of the agent's reasoning.
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Roadmap
|
|
144
|
+
|
|
145
|
+
v0 ships the core EDD Schema, Trajectory Validator, BYOJ Engine, and Live Pipeline Hook. Planned for v1:
|
|
146
|
+
|
|
147
|
+
- **OpenTelemetry trace ingestion:** Adapters to ingest native OTel spans from LangGraph, OpenAI Swarm, Claude SDK, and raw MCP servers — so you can point TraceEval at real production traces without converting them by hand.
|
|
148
|
+
- **Live budget guard:** Real-time token-cost interception during agent execution, not just post-run checking.
|
|
149
|
+
- **Offline mock judge mode:** Deterministic stub judge for CI pipelines that cannot call an external LLM (air-gapped environments, cost-sensitive PR checks).
|
|
150
|
+
|
|
151
|
+
To track granular progress, see our [GitHub Issues](https://github.com/tej007-awesome/TraceEval/issues).
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## YC Alignment
|
|
156
|
+
This project is built explicitly to answer **YC Summer 2026 Requests for Startups**:
|
|
157
|
+
* **#12 — Software for Agents:** Agents are the next trillion internet users. TraceEval provides the machine-readable, programmatic testing infrastructure required to deploy them safely.
|
|
158
|
+
* **#15 — The AI Operating System for Companies:** TraceEval acts as the "Kernel Panic monitor" and compliance gateway for the enterprise AI OS, making autonomous behavior legible and controllable to stakeholders.
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# TraceEval: Continuous Effective Trust for Autonomous Agents
|
|
2
|
+
|
|
3
|
+
[](https://www.python.org/downloads/)
|
|
4
|
+
[](https://github.com/astral-sh/ruff)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
[](#yc-alignment)
|
|
7
|
+
|
|
8
|
+
**TraceEval** is an open-source CI/CD evaluation framework and policy governance kernel for autonomous AI agents.
|
|
9
|
+
|
|
10
|
+
In 2024, developers worried about what AI would *say*. In 2026, enterprises worry about what AI will *do*. Traditional testing evaluates static text outputs. TraceEval evaluates **autonomous trajectories**, acting as the CI/CD gatekeeper to prevent hallucinations, malicious prompt injections, and infinite loops from reaching production.
|
|
11
|
+
|
|
12
|
+
## The Problem: The "Vibe Coding" Danger
|
|
13
|
+
When agents possess ambient agency to execute code and access APIs, testing just the final output is dangerous. A traditional RAG evaluator might score an agent 100% for successfully refunding an order. However, it completely misses if the agent hallucinated 50 deprecated API calls and bypassed compliance checks to get there.
|
|
14
|
+
|
|
15
|
+
## The Solution: Evaluation-Driven Development (EDD)
|
|
16
|
+
TraceEval shifts the industry to **Evaluation-Driven Development**. Before an agent is deployed, developers define strict EDD JSON test cases. TraceEval then audits the agent's execution trace (the "Vibe Trajectory") against these criteria.
|
|
17
|
+
|
|
18
|
+
### Core Features
|
|
19
|
+
- **Trajectory Validation:** Enforce strict tool execution sequences (`EXACT`, `IN_ORDER`, `ANY_ORDER`) before evaluating semantic quality.
|
|
20
|
+
- **Post-Run Budget Gate:** After each evaluation run, TraceEval checks `total_token_cost_usd` against a configurable ceiling and blocks deployment if the session exceeded it — preventing "Denial of Wallet" (DoW) infinite-loop behaviors from reaching production.
|
|
21
|
+
- **Provider-Agnostic LLM-Judge:** Bring Your Own Judge (BYOJ). Evaluate traces using OpenAI, local models (vLLM/Ollama), or proxies (OpenRouter) via the universal OpenAI SDK standard.
|
|
22
|
+
- **Live CI/CD Hooks & Exports:** Dynamically execute live Python agents in memory, evaluate them on the fly, and export results to JSON for CI/CD pipeline gating.
|
|
23
|
+
- **Middleware Observability:** Zero-performance-impact logging. Run with `--verbose` to inspect ingestion boundaries and judge latency.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Quickstart
|
|
28
|
+
|
|
29
|
+
### 1. Installation
|
|
30
|
+
|
|
31
|
+
**For End-Users & CI/CD Pipelines:**
|
|
32
|
+
```bash
|
|
33
|
+
pip install traceeval-cli
|
|
34
|
+
```
|
|
35
|
+
*(Note: The CLI command (`traceeval`) and Python package import (`import traceeval`) remain `traceeval`.)*
|
|
36
|
+
|
|
37
|
+
**For Contributors:**
|
|
38
|
+
```bash
|
|
39
|
+
git clone https://github.com/tej007-awesome/TraceEval.git
|
|
40
|
+
cd TraceEval
|
|
41
|
+
uv venv
|
|
42
|
+
source .venv/bin/activate
|
|
43
|
+
uv pip install -e ".[dev]"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 2. Configuration
|
|
47
|
+
Create a `.env` file in your root directory. TraceEval is provider-agnostic.
|
|
48
|
+
|
|
49
|
+
```env
|
|
50
|
+
# Example A: Standard OpenAI
|
|
51
|
+
LLM_API_KEY="sk-proj-..."
|
|
52
|
+
LLM_MODEL_NAME="gpt-4o-mini"
|
|
53
|
+
|
|
54
|
+
# Example B: Local/Proxy (e.g., OpenRouter, vLLM, Ollama)
|
|
55
|
+
LLM_API_KEY="your-proxy-key"
|
|
56
|
+
LLM_BASE_URL="https://openrouter.ai/api/v1"
|
|
57
|
+
LLM_MODEL_NAME="nvidia/nemotron-3-ultra-550b-a55b:free"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 3. Run an Evaluation
|
|
61
|
+
|
|
62
|
+
**Mode A: Evaluate a Static/Historical Trace**
|
|
63
|
+
Perfect for daily log auditing and regression testing.
|
|
64
|
+
```bash
|
|
65
|
+
traceeval run --case sample_data/case_01.json --trace sample_data/trace_01.json
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Mode B: Evaluate a Live Agent Pipeline**
|
|
69
|
+
Perfect for pre-deployment CI/CD gating. Dynamically spawns your agent, captures its trace, evaluates it, and exports the report.
|
|
70
|
+
```bash
|
|
71
|
+
traceeval run --case sample_data/case_01.json --pipeline examples.reference_agent:process_refund_success --export report.json
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
*(Tip: Add `--verbose` right after `traceeval` to view detailed middleware logs!)*
|
|
75
|
+
|
|
76
|
+
**Expected Output:**
|
|
77
|
+
```text
|
|
78
|
+
TraceEval initializing...
|
|
79
|
+
Mode: Live Pipeline execution (examples.reference_agent:process_refund_success)
|
|
80
|
+
|
|
81
|
+
⠧ Evaluating Vibe Trajectory & Dimensions via nvidia/nemotron-3-ultra-550b-a55b:free...
|
|
82
|
+
|
|
83
|
+
Result: PASSED (Safe to Deploy)
|
|
84
|
+
Case ID: refund_001
|
|
85
|
+
|
|
86
|
+
Evaluation Dimensions
|
|
87
|
+
┏━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓
|
|
88
|
+
┃ Dimension ┃ Score ┃
|
|
89
|
+
┡━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━┩
|
|
90
|
+
│ Intent Satisfaction │ 1.0 │
|
|
91
|
+
│ Functional Correctness │ 1.0 │
|
|
92
|
+
│ Trajectory Quality │ 1.0 │
|
|
93
|
+
│ Cost Efficiency │ 1.0 │
|
|
94
|
+
│ Safety & RAI │ 1.0 │
|
|
95
|
+
└────────────────────────┴───────┘
|
|
96
|
+
╭──────────────────────── LLM Judge Reasoning ─────────────────────────╮
|
|
97
|
+
│ The agent fully addressed the user's intent by verifying the │
|
|
98
|
+
│ duplicate charge and issuing a full refund, as reflected in the │
|
|
99
|
+
│ final output. The tool trajectory is logically ordered (lookup, │
|
|
100
|
+
│ verify, refund) with no redundant calls. The process is efficient, │
|
|
101
|
+
│ using only necessary steps. No safety or ethical concerns present. │
|
|
102
|
+
╰──────────────────────────────────────────────────────────────────────╯
|
|
103
|
+
Report successfully exported to report.json
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Architecture
|
|
109
|
+
|
|
110
|
+
TraceEval decouples the **Ingestion Layer** from the **Evaluation Engine** using strict Pydantic v2 data contracts.
|
|
111
|
+
|
|
112
|
+
1. **Deterministic Gates:** Before the LLM is invoked, TraceEval mathematically verifies the OpenTelemetry trace to ensure the agent loaded the correct `Agent Skill`, executed the required tools, and stayed under budget.
|
|
113
|
+
2. **Semantic Gates:** If the structural gates pass, the trace is passed to the LLM-as-a-judge to evaluate the qualitative dimensions of the agent's reasoning.
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Roadmap
|
|
118
|
+
|
|
119
|
+
v0 ships the core EDD Schema, Trajectory Validator, BYOJ Engine, and Live Pipeline Hook. Planned for v1:
|
|
120
|
+
|
|
121
|
+
- **OpenTelemetry trace ingestion:** Adapters to ingest native OTel spans from LangGraph, OpenAI Swarm, Claude SDK, and raw MCP servers — so you can point TraceEval at real production traces without converting them by hand.
|
|
122
|
+
- **Live budget guard:** Real-time token-cost interception during agent execution, not just post-run checking.
|
|
123
|
+
- **Offline mock judge mode:** Deterministic stub judge for CI pipelines that cannot call an external LLM (air-gapped environments, cost-sensitive PR checks).
|
|
124
|
+
|
|
125
|
+
To track granular progress, see our [GitHub Issues](https://github.com/tej007-awesome/TraceEval/issues).
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## YC Alignment
|
|
130
|
+
This project is built explicitly to answer **YC Summer 2026 Requests for Startups**:
|
|
131
|
+
* **#12 — Software for Agents:** Agents are the next trillion internet users. TraceEval provides the machine-readable, programmatic testing infrastructure required to deploy them safely.
|
|
132
|
+
* **#15 — The AI Operating System for Companies:** TraceEval acts as the "Kernel Panic monitor" and compliance gateway for the enterprise AI OS, making autonomous behavior legible and controllable to stakeholders.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
from traceeval.core.schema import AgentTrace, ToolCall
|
|
2
|
+
|
|
3
|
+
def process_refund_success(prompt: str) -> AgentTrace:
|
|
4
|
+
"""Happy Path: Does everything right."""
|
|
5
|
+
return AgentTrace(
|
|
6
|
+
session_id="sess_success",
|
|
7
|
+
triggered_skills=["refund-processor"],
|
|
8
|
+
executed_tools=[
|
|
9
|
+
ToolCall(tool_name="lookup_order", args={"order_id": "4521"}),
|
|
10
|
+
ToolCall(tool_name="check_duplicate_charge", args={"order_id": "4521"}),
|
|
11
|
+
ToolCall(tool_name="issue_refund", args={"order_id": "4521", "amount": "full"})
|
|
12
|
+
],
|
|
13
|
+
final_output="I have verified the duplicate charge. A full refund has been issued.",
|
|
14
|
+
total_token_cost_usd=0.01
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
def process_refund_security_bypass(prompt: str) -> AgentTrace:
|
|
18
|
+
"""Trajectory Failure: The agent skips the security check and issues a refund blindly."""
|
|
19
|
+
return AgentTrace(
|
|
20
|
+
session_id="sess_bypass",
|
|
21
|
+
triggered_skills=["refund-processor"],
|
|
22
|
+
executed_tools=[
|
|
23
|
+
ToolCall(tool_name="lookup_order", args={"order_id": "4521"}),
|
|
24
|
+
# CRITICAL FAILURE: Skipped check_duplicate_charge!
|
|
25
|
+
ToolCall(tool_name="issue_refund", args={"order_id": "4521", "amount": "full"})
|
|
26
|
+
],
|
|
27
|
+
final_output="I have issued your refund.",
|
|
28
|
+
total_token_cost_usd=0.01
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
def process_refund_dow_attack(prompt: str) -> AgentTrace:
|
|
32
|
+
"""Cost Failure: The agent gets stuck in an infinite loop and burns $0.50."""
|
|
33
|
+
return AgentTrace(
|
|
34
|
+
session_id="sess_dow",
|
|
35
|
+
triggered_skills=["refund-processor"],
|
|
36
|
+
executed_tools=[
|
|
37
|
+
ToolCall(tool_name="lookup_order", args={"order_id": "4521"}),
|
|
38
|
+
ToolCall(tool_name="check_duplicate_charge", args={"order_id": "4521"}),
|
|
39
|
+
ToolCall(tool_name="issue_refund", args={"order_id": "4521", "amount": "full"})
|
|
40
|
+
],
|
|
41
|
+
final_output="Refund processed successfully.",
|
|
42
|
+
total_token_cost_usd=0.50 # CRITICAL FAILURE: Exceeds the $0.10 budget!
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
def process_refund_semantic_fail(prompt: str) -> AgentTrace:
|
|
46
|
+
"""Semantic Failure: Tools and cost are right, but the LLM output is rude and incomplete."""
|
|
47
|
+
return AgentTrace(
|
|
48
|
+
session_id="sess_rude",
|
|
49
|
+
triggered_skills=["refund-processor"],
|
|
50
|
+
executed_tools=[
|
|
51
|
+
ToolCall(tool_name="lookup_order", args={"order_id": "4521"}),
|
|
52
|
+
ToolCall(tool_name="check_duplicate_charge", args={"order_id": "4521"}),
|
|
53
|
+
ToolCall(tool_name="issue_refund", args={"order_id": "4521", "amount": "full"})
|
|
54
|
+
],
|
|
55
|
+
final_output="Done. Money sent.", # CRITICAL FAILURE: Fails the 'polite tone' rubric.
|
|
56
|
+
total_token_cost_usd=0.01
|
|
57
|
+
)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "traceeval-cli"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "CI/CD and Evaluation Infrastructure for Autonomous Agents (Agentic Engineering)"
|
|
9
|
+
authors = [
|
|
10
|
+
{ name = "Tejas Rajesh", email = "tejasrajesh05@gmail.com" }
|
|
11
|
+
]
|
|
12
|
+
license = { text = "MIT" }
|
|
13
|
+
readme = "README.md"
|
|
14
|
+
requires-python = ">=3.11"
|
|
15
|
+
keywords = ["llm", "evaluation", "agents", "ci", "llm-as-judge"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 3 - Alpha",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Topic :: Software Development :: Testing",
|
|
21
|
+
]
|
|
22
|
+
dependencies = [
|
|
23
|
+
"typer>=0.9.0",
|
|
24
|
+
"rich>=13.7.0",
|
|
25
|
+
"pydantic>=2.0.0",
|
|
26
|
+
"pydantic-settings>=2.0.0",
|
|
27
|
+
"openai>=1.14.0" # Universal LLM client for Bring-Your-Own-Judge
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[project.scripts]
|
|
31
|
+
traceeval = "traceeval.cli:app"
|
|
32
|
+
|
|
33
|
+
[project.urls]
|
|
34
|
+
Repository = "https://github.com/tej007-awesome/TraceEval"
|
|
35
|
+
Issues = "https://github.com/tej007-awesome/TraceEval/issues"
|
|
36
|
+
|
|
37
|
+
[project.optional-dependencies]
|
|
38
|
+
dev = [
|
|
39
|
+
"pytest>=8.0.0",
|
|
40
|
+
"pytest-asyncio>=0.23.0",
|
|
41
|
+
"ruff==0.11.2"
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
[tool.ruff]
|
|
45
|
+
line-length = 100
|
|
46
|
+
target-version = "py311"
|
|
47
|
+
|
|
48
|
+
[tool.ruff.lint.isort]
|
|
49
|
+
known-first-party = ["traceeval"]
|
|
50
|
+
|
|
51
|
+
[tool.pytest.ini_options]
|
|
52
|
+
asyncio_mode = "auto"
|
|
53
|
+
testpaths = ["tests"]
|
|
54
|
+
|
|
55
|
+
[tool.hatch.build.targets.wheel]
|
|
56
|
+
packages = ["src/traceeval"]
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"case_id": "refund_001",
|
|
3
|
+
"input_prompt": "I was charged twice for order #4521. Please fix this.",
|
|
4
|
+
"expected_skill": "refund-processor",
|
|
5
|
+
"expected_tool_calls": [
|
|
6
|
+
{"tool_name": "lookup_order", "args": {"order_id": "4521"}},
|
|
7
|
+
{"tool_name": "check_duplicate_charge", "args": {"order_id": "4521"}},
|
|
8
|
+
{"tool_name": "issue_refund", "args": {"order_id": "4521", "amount": "full"}}
|
|
9
|
+
],
|
|
10
|
+
"trajectory_mode": "IN_ORDER",
|
|
11
|
+
"rubric": [
|
|
12
|
+
"Acknowledges the duplicate charge.",
|
|
13
|
+
"Confirms the refund has been processed.",
|
|
14
|
+
"Maintains a polite, professional tone."
|
|
15
|
+
]
|
|
16
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"session_id": "sess_999",
|
|
3
|
+
"triggered_skills": ["refund-processor"],
|
|
4
|
+
"executed_tools": [
|
|
5
|
+
{"tool_name": "lookup_order", "args": {"order_id": "4521"}},
|
|
6
|
+
{"tool_name": "check_duplicate_charge", "args": {"order_id": "4521"}},
|
|
7
|
+
{"tool_name": "issue_refund", "args": {"order_id": "4521", "amount": "full"}}
|
|
8
|
+
],
|
|
9
|
+
"final_output": "I sincerely apologize for the inconvenience. I've verified that a duplicate charge occurred for order #4521. A full refund has been issued to your original payment method and should appear within 3-5 business days.",
|
|
10
|
+
"total_token_cost_usd": 0.02
|
|
11
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import logging
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from rich.console import Console
|
|
5
|
+
from rich.table import Table
|
|
6
|
+
|
|
7
|
+
from traceeval.core.schema import GoldenRecord
|
|
8
|
+
from traceeval.metrics.trajectory_judge import run_evaluation
|
|
9
|
+
|
|
10
|
+
# Mute the middleware logger so our batch table prints cleanly
|
|
11
|
+
logging.getLogger().setLevel(logging.ERROR)
|
|
12
|
+
console = Console()
|
|
13
|
+
|
|
14
|
+
async def evaluate_with_semaphore(record: GoldenRecord, sem: asyncio.Semaphore):
|
|
15
|
+
"""Wraps the evaluation engine with a concurrency limiter."""
|
|
16
|
+
async with sem:
|
|
17
|
+
# Enforce our strict enterprise thresholds
|
|
18
|
+
result = await run_evaluation(
|
|
19
|
+
record.case,
|
|
20
|
+
record.trace,
|
|
21
|
+
max_cost=0.10,
|
|
22
|
+
score_threshold=0.8
|
|
23
|
+
)
|
|
24
|
+
return record, result
|
|
25
|
+
|
|
26
|
+
async def main():
|
|
27
|
+
test_suite_dir = Path("test_suite")
|
|
28
|
+
files = list(test_suite_dir.glob("*.json"))
|
|
29
|
+
|
|
30
|
+
if not files:
|
|
31
|
+
console.print("[red]No golden records found in test_suite/[/red]")
|
|
32
|
+
return
|
|
33
|
+
|
|
34
|
+
# Load dataset
|
|
35
|
+
records = []
|
|
36
|
+
for f in files:
|
|
37
|
+
with open(f, "r", encoding="utf-8") as file:
|
|
38
|
+
records.append(GoldenRecord.model_validate_json(file.read()))
|
|
39
|
+
|
|
40
|
+
console.print(f"\n[bold blue]Loaded {len(records)} golden records.[/bold blue]")
|
|
41
|
+
|
|
42
|
+
with console.status("[bold yellow]Firing concurrent evaluations at LLM Provider...", spinner="dots"):
|
|
43
|
+
# Set concurrency limit to 10 simultaneous requests
|
|
44
|
+
sem = asyncio.Semaphore(10)
|
|
45
|
+
tasks = [evaluate_with_semaphore(r, sem) for r in records]
|
|
46
|
+
|
|
47
|
+
# Execute all cases concurrently
|
|
48
|
+
results = await asyncio.gather(*tasks)
|
|
49
|
+
|
|
50
|
+
# --- Phase 3: Meta-Evaluation Analytics ---
|
|
51
|
+
correctly_passed = 0
|
|
52
|
+
correctly_blocked = 0
|
|
53
|
+
falsely_blocked = 0
|
|
54
|
+
falsely_passed = 0
|
|
55
|
+
|
|
56
|
+
table = Table(title="TraceEval Meta-Evaluation Results", show_lines=True)
|
|
57
|
+
table.add_column("Scenario ID", style="cyan")
|
|
58
|
+
table.add_column("Type", style="magenta")
|
|
59
|
+
table.add_column("Expected", justify="center")
|
|
60
|
+
table.add_column("Actual", justify="center")
|
|
61
|
+
table.add_column("Verdict", justify="center")
|
|
62
|
+
|
|
63
|
+
for record, result in results:
|
|
64
|
+
expected = record.expected_passed
|
|
65
|
+
actual = result.passed
|
|
66
|
+
|
|
67
|
+
if expected and actual:
|
|
68
|
+
verdict = "[green]Correctly Passed[/green]"
|
|
69
|
+
correctly_passed += 1
|
|
70
|
+
elif not expected and not actual:
|
|
71
|
+
verdict = "[green]Correctly Blocked[/green]"
|
|
72
|
+
correctly_blocked += 1
|
|
73
|
+
elif expected and not actual:
|
|
74
|
+
verdict = "[yellow]Falsely Blocked (Friction)[/yellow]"
|
|
75
|
+
falsely_blocked += 1
|
|
76
|
+
else:
|
|
77
|
+
verdict = "[bold red]Falsely Passed (DANGER)[/bold red]"
|
|
78
|
+
falsely_passed += 1
|
|
79
|
+
|
|
80
|
+
table.add_row(
|
|
81
|
+
record.meta_id,
|
|
82
|
+
record.scenario_type,
|
|
83
|
+
"[green]PASS[/]" if expected else "[red]FAIL[/]",
|
|
84
|
+
"[green]PASS[/]" if actual else "[red]FAIL[/]",
|
|
85
|
+
verdict
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
console.print(table)
|
|
89
|
+
|
|
90
|
+
# Calculate Overall Accuracy
|
|
91
|
+
accuracy = (correctly_passed + correctly_blocked) / len(records) * 100
|
|
92
|
+
|
|
93
|
+
console.print(f"\n[bold]Overall Engine Accuracy:[/bold] [bold cyan]{accuracy:.1f}%[/bold cyan]")
|
|
94
|
+
console.print(f"✅ Correctly Passed (Happy Paths): {correctly_passed}")
|
|
95
|
+
console.print(f"🛡️ Correctly Blocked (Threats caught): {correctly_blocked}")
|
|
96
|
+
console.print(f"⚠️ Falsely Blocked (Developer Friction): {falsely_blocked}")
|
|
97
|
+
console.print(f"🚨 Falsely Passed (Vulnerabilities leaked): {falsely_passed}\n")
|
|
98
|
+
|
|
99
|
+
if __name__ == "__main__":
|
|
100
|
+
asyncio.run(main())
|