tracelens 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.
- tracelens-0.1.0/.dockerignore +41 -0
- tracelens-0.1.0/.github/ISSUE_TEMPLATE/bug_report.md +52 -0
- tracelens-0.1.0/.github/ISSUE_TEMPLATE/feature_request.md +40 -0
- tracelens-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +41 -0
- tracelens-0.1.0/.github/workflows/ci.yml +157 -0
- tracelens-0.1.0/.github/workflows/release.yml +66 -0
- tracelens-0.1.0/.gitignore +88 -0
- tracelens-0.1.0/CHANGELOG.md +164 -0
- tracelens-0.1.0/CODE_OF_CONDUCT.md +85 -0
- tracelens-0.1.0/CONTRIBUTING.md +97 -0
- tracelens-0.1.0/Dockerfile +34 -0
- tracelens-0.1.0/LICENSE +21 -0
- tracelens-0.1.0/PKG-INFO +509 -0
- tracelens-0.1.0/README.md +463 -0
- tracelens-0.1.0/SECURITY.md +60 -0
- tracelens-0.1.0/benchmarks/high-stakes-autonomous/README.md +113 -0
- tracelens-0.1.0/benchmarks/high-stakes-autonomous/agent.py +93 -0
- tracelens-0.1.0/benchmarks/high-stakes-autonomous/graders.py +82 -0
- tracelens-0.1.0/benchmarks/high-stakes-autonomous/run_benchmark.py +256 -0
- tracelens-0.1.0/benchmarks/high-stakes-autonomous/tasks.json +78 -0
- tracelens-0.1.0/docker-compose.yml +52 -0
- tracelens-0.1.0/docs/accuracy.md +269 -0
- tracelens-0.1.0/docs/ci-cd-integration.md +795 -0
- tracelens-0.1.0/docs/evaluation-levels.md +706 -0
- tracelens-0.1.0/docs/getting-started.md +135 -0
- tracelens-0.1.0/docs/installation.md +303 -0
- tracelens-0.1.0/docs/quickstart.md +189 -0
- tracelens-0.1.0/docs/releasing.md +99 -0
- tracelens-0.1.0/docs/scenarios.md +119 -0
- tracelens-0.1.0/docs/user-guide.md +687 -0
- tracelens-0.1.0/examples/README.md +61 -0
- tracelens-0.1.0/examples/__init__.py +0 -0
- tracelens-0.1.0/examples/baselines.json +66 -0
- tracelens-0.1.0/examples/contract_eval.py +89 -0
- tracelens-0.1.0/examples/graders/__init__.py +0 -0
- tracelens-0.1.0/examples/graders/math_grader.py +50 -0
- tracelens-0.1.0/examples/graders/quality_grader.py +88 -0
- tracelens-0.1.0/examples/hello_world.py +111 -0
- tracelens-0.1.0/examples/http_agent_eval.py +96 -0
- tracelens-0.1.0/examples/noise_aware_regression.py +98 -0
- tracelens-0.1.0/examples/run_eval.py +108 -0
- tracelens-0.1.0/examples/tasks.json +54 -0
- tracelens-0.1.0/pyproject.toml +121 -0
- tracelens-0.1.0/src/tracelens/__init__.py +243 -0
- tracelens-0.1.0/src/tracelens/_version.py +8 -0
- tracelens-0.1.0/src/tracelens/baselines/__init__.py +27 -0
- tracelens-0.1.0/src/tracelens/baselines/comparison.py +476 -0
- tracelens-0.1.0/src/tracelens/baselines/manager.py +968 -0
- tracelens-0.1.0/src/tracelens/calibration/__init__.py +17 -0
- tracelens-0.1.0/src/tracelens/calibration/analyzer.py +250 -0
- tracelens-0.1.0/src/tracelens/cli/__init__.py +1 -0
- tracelens-0.1.0/src/tracelens/cli/calibrate.py +130 -0
- tracelens-0.1.0/src/tracelens/cli/main.py +255 -0
- tracelens-0.1.0/src/tracelens/contracts/__init__.py +5 -0
- tracelens-0.1.0/src/tracelens/contracts/contract.py +117 -0
- tracelens-0.1.0/src/tracelens/core/__init__.py +62 -0
- tracelens-0.1.0/src/tracelens/core/_time.py +12 -0
- tracelens-0.1.0/src/tracelens/core/decision_spec.py +579 -0
- tracelens-0.1.0/src/tracelens/core/grader.py +527 -0
- tracelens-0.1.0/src/tracelens/core/outcome.py +181 -0
- tracelens-0.1.0/src/tracelens/core/task.py +253 -0
- tracelens-0.1.0/src/tracelens/core/transcript.py +284 -0
- tracelens-0.1.0/src/tracelens/core/trial.py +309 -0
- tracelens-0.1.0/src/tracelens/execution/__init__.py +14 -0
- tracelens-0.1.0/src/tracelens/execution/agent_adapter.py +100 -0
- tracelens-0.1.0/src/tracelens/execution/http_adapter.py +240 -0
- tracelens-0.1.0/src/tracelens/execution/registry.py +42 -0
- tracelens-0.1.0/src/tracelens/execution/runner.py +233 -0
- tracelens-0.1.0/src/tracelens/graders/__init__.py +17 -0
- tracelens-0.1.0/src/tracelens/graders/event_chain.py +236 -0
- tracelens-0.1.0/src/tracelens/llm/__init__.py +6 -0
- tracelens-0.1.0/src/tracelens/llm/factory.py +66 -0
- tracelens-0.1.0/src/tracelens/llm/provider.py +37 -0
- tracelens-0.1.0/src/tracelens/metrics/__init__.py +27 -0
- tracelens-0.1.0/src/tracelens/metrics/budgets.py +265 -0
- tracelens-0.1.0/src/tracelens/metrics/validators.py +364 -0
- tracelens-0.1.0/src/tracelens/py.typed +1 -0
- tracelens-0.1.0/src/tracelens/reporting/__init__.py +9 -0
- tracelens-0.1.0/src/tracelens/reporting/generator.py +567 -0
- tracelens-0.1.0/src/tracelens/statistics/__init__.py +53 -0
- tracelens-0.1.0/src/tracelens/statistics/consistency.py +191 -0
- tracelens-0.1.0/src/tracelens/statistics/inference.py +549 -0
- tracelens-0.1.0/src/tracelens/statistics/latency.py +132 -0
- tracelens-0.1.0/src/tracelens/statistics/pass_at_k.py +197 -0
- tracelens-0.1.0/tests/__init__.py +1 -0
- tracelens-0.1.0/tests/conftest.py +183 -0
- tracelens-0.1.0/tests/integration/__init__.py +0 -0
- tracelens-0.1.0/tests/integration/test_comprehensive_e2e.py +587 -0
- tracelens-0.1.0/tests/integration/test_end_to_end.py +108 -0
- tracelens-0.1.0/tests/integration/test_week1_e2e.py +291 -0
- tracelens-0.1.0/tests/integration/test_week2_e2e.py +763 -0
- tracelens-0.1.0/tests/unit/__init__.py +1 -0
- tracelens-0.1.0/tests/unit/baselines/__init__.py +1 -0
- tracelens-0.1.0/tests/unit/baselines/test_comparison.py +396 -0
- tracelens-0.1.0/tests/unit/baselines/test_manager.py +186 -0
- tracelens-0.1.0/tests/unit/baselines/test_promotion.py +472 -0
- tracelens-0.1.0/tests/unit/calibration/__init__.py +0 -0
- tracelens-0.1.0/tests/unit/calibration/test_analyzer.py +215 -0
- tracelens-0.1.0/tests/unit/cli/__init__.py +0 -0
- tracelens-0.1.0/tests/unit/cli/test_main.py +213 -0
- tracelens-0.1.0/tests/unit/contracts/__init__.py +0 -0
- tracelens-0.1.0/tests/unit/contracts/test_contract.py +223 -0
- tracelens-0.1.0/tests/unit/core/__init__.py +1 -0
- tracelens-0.1.0/tests/unit/core/test_decision_spec.py +595 -0
- tracelens-0.1.0/tests/unit/core/test_eval_policy.py +218 -0
- tracelens-0.1.0/tests/unit/core/test_grader_roles.py +288 -0
- tracelens-0.1.0/tests/unit/core/test_outcome.py +134 -0
- tracelens-0.1.0/tests/unit/core/test_serialization.py +249 -0
- tracelens-0.1.0/tests/unit/core/test_task.py +248 -0
- tracelens-0.1.0/tests/unit/core/test_transcript.py +192 -0
- tracelens-0.1.0/tests/unit/core/test_trial.py +331 -0
- tracelens-0.1.0/tests/unit/execution/__init__.py +0 -0
- tracelens-0.1.0/tests/unit/execution/test_agent_adapter.py +153 -0
- tracelens-0.1.0/tests/unit/execution/test_http_adapter.py +300 -0
- tracelens-0.1.0/tests/unit/execution/test_registry.py +53 -0
- tracelens-0.1.0/tests/unit/execution/test_runner.py +421 -0
- tracelens-0.1.0/tests/unit/graders/__init__.py +0 -0
- tracelens-0.1.0/tests/unit/graders/test_event_chain.py +346 -0
- tracelens-0.1.0/tests/unit/llm/__init__.py +0 -0
- tracelens-0.1.0/tests/unit/llm/test_provider.py +134 -0
- tracelens-0.1.0/tests/unit/metrics/__init__.py +0 -0
- tracelens-0.1.0/tests/unit/metrics/test_budgets.py +484 -0
- tracelens-0.1.0/tests/unit/metrics/test_validators.py +508 -0
- tracelens-0.1.0/tests/unit/reporting/__init__.py +0 -0
- tracelens-0.1.0/tests/unit/reporting/test_generator.py +362 -0
- tracelens-0.1.0/tests/unit/statistics/__init__.py +1 -0
- tracelens-0.1.0/tests/unit/statistics/test_consistency.py +140 -0
- tracelens-0.1.0/tests/unit/statistics/test_inference.py +398 -0
- tracelens-0.1.0/tests/unit/statistics/test_latency.py +152 -0
- tracelens-0.1.0/tests/unit/statistics/test_pass_at_k.py +136 -0
- tracelens-0.1.0/uv.lock +1152 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Git
|
|
2
|
+
.git
|
|
3
|
+
.gitignore
|
|
4
|
+
|
|
5
|
+
# Python
|
|
6
|
+
__pycache__
|
|
7
|
+
*.py[cod]
|
|
8
|
+
*$py.class
|
|
9
|
+
*.egg-info
|
|
10
|
+
.eggs
|
|
11
|
+
dist
|
|
12
|
+
build
|
|
13
|
+
*.egg
|
|
14
|
+
|
|
15
|
+
# Virtual environments
|
|
16
|
+
.venv
|
|
17
|
+
venv
|
|
18
|
+
ENV
|
|
19
|
+
|
|
20
|
+
# IDE
|
|
21
|
+
.idea
|
|
22
|
+
.vscode
|
|
23
|
+
*.swp
|
|
24
|
+
*.swo
|
|
25
|
+
|
|
26
|
+
# Testing artifacts
|
|
27
|
+
.pytest_cache
|
|
28
|
+
.coverage
|
|
29
|
+
coverage/
|
|
30
|
+
htmlcov/
|
|
31
|
+
.mypy_cache
|
|
32
|
+
|
|
33
|
+
# Documentation
|
|
34
|
+
docs/_build
|
|
35
|
+
|
|
36
|
+
# OS
|
|
37
|
+
.DS_Store
|
|
38
|
+
Thumbs.db
|
|
39
|
+
|
|
40
|
+
# Claude
|
|
41
|
+
.claude/
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Report a defect with a minimal reproduction
|
|
4
|
+
title: "[bug] "
|
|
5
|
+
labels: bug
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## What happened
|
|
10
|
+
|
|
11
|
+
<!-- A clear, concise description of the bug. -->
|
|
12
|
+
|
|
13
|
+
## What you expected
|
|
14
|
+
|
|
15
|
+
<!-- What did you expect to happen instead? -->
|
|
16
|
+
|
|
17
|
+
## Minimal reproduction
|
|
18
|
+
|
|
19
|
+
<!--
|
|
20
|
+
Smallest possible code or eval-set snippet that reproduces the issue.
|
|
21
|
+
If it's CI-related, paste the relevant workflow + run URL.
|
|
22
|
+
-->
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
# repro
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Environment
|
|
29
|
+
|
|
30
|
+
- tracelens version: `pip show tracelens | grep Version`
|
|
31
|
+
- Python version: `python --version`
|
|
32
|
+
- OS: (macOS 14 / Ubuntu 22.04 / Windows 11 / ...)
|
|
33
|
+
- Install method: `pip` / `uv` / git clone
|
|
34
|
+
- Optional extras installed: `[llm]` / `[http]` / `[dev]` / none
|
|
35
|
+
|
|
36
|
+
## Logs / traceback
|
|
37
|
+
|
|
38
|
+
<details>
|
|
39
|
+
<summary>Full traceback</summary>
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
<paste here>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
</details>
|
|
46
|
+
|
|
47
|
+
## Anything else?
|
|
48
|
+
|
|
49
|
+
<!--
|
|
50
|
+
e.g., does it reproduce with `num_runs=1`? Does it reproduce on a fresh venv?
|
|
51
|
+
Does the same DecisionSpec fingerprint appear across runs?
|
|
52
|
+
-->
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature request
|
|
3
|
+
about: Propose a new capability or API change
|
|
4
|
+
title: "[feat] "
|
|
5
|
+
labels: enhancement
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## The agent / eval scenario you're trying to support
|
|
10
|
+
|
|
11
|
+
<!--
|
|
12
|
+
Start with the use case, not the API.
|
|
13
|
+
What kind of agent? What grading dimension? What guarantee do you need?
|
|
14
|
+
-->
|
|
15
|
+
|
|
16
|
+
## What's missing today
|
|
17
|
+
|
|
18
|
+
<!-- Why can't you express this with the current tracelens surface? -->
|
|
19
|
+
|
|
20
|
+
## Proposed API or behavior
|
|
21
|
+
|
|
22
|
+
<!--
|
|
23
|
+
Sketch the smallest API change you can imagine.
|
|
24
|
+
Code snippets > prose.
|
|
25
|
+
-->
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
# proposed usage
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Alternatives you considered
|
|
32
|
+
|
|
33
|
+
<!-- e.g. subclassing existing graders, writing a custom adapter, doing it out-of-band. -->
|
|
34
|
+
|
|
35
|
+
## Compatibility considerations
|
|
36
|
+
|
|
37
|
+
- [ ] Does this require a new `DecisionSpec` field? (If yes, fingerprint impact?)
|
|
38
|
+
- [ ] Does this change baseline / regression semantics?
|
|
39
|
+
- [ ] Does this add a new optional dependency?
|
|
40
|
+
- [ ] Could this be a separate package that depends on tracelens instead of living in core?
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Thanks for contributing to tracelens!
|
|
3
|
+
Please keep one logical change per PR. Split branches that touch
|
|
4
|
+
multiple layers (e.g. adapter + statistics) into separate PRs.
|
|
5
|
+
-->
|
|
6
|
+
|
|
7
|
+
## Summary
|
|
8
|
+
|
|
9
|
+
<!-- One paragraph: what does this PR change, from the user's perspective? -->
|
|
10
|
+
|
|
11
|
+
## Motivation
|
|
12
|
+
|
|
13
|
+
<!--
|
|
14
|
+
Why is this change needed? What problem does it solve?
|
|
15
|
+
What alternatives did you consider and why did you reject them?
|
|
16
|
+
-->
|
|
17
|
+
|
|
18
|
+
## Type of change
|
|
19
|
+
|
|
20
|
+
- [ ] Bug fix
|
|
21
|
+
- [ ] New feature (non-breaking)
|
|
22
|
+
- [ ] Breaking change (please flag in CHANGELOG under [Unreleased] → Changed)
|
|
23
|
+
- [ ] Docs / examples / benchmarks
|
|
24
|
+
- [ ] Internal refactor (no user-visible change)
|
|
25
|
+
|
|
26
|
+
## Verification
|
|
27
|
+
|
|
28
|
+
- [ ] `pytest -q` passes locally
|
|
29
|
+
- [ ] `ruff check src/ tests/` passes
|
|
30
|
+
- [ ] `mypy src/tracelens/` passes (strict)
|
|
31
|
+
- [ ] New / changed code is covered by tests
|
|
32
|
+
- [ ] If touching `DecisionSpec`, baseline, or regression logic: backwards-compat note added to `CHANGELOG.md`
|
|
33
|
+
- [ ] If adding to `src/tracelens/__init__.py`: this symbol is intended as stable public API
|
|
34
|
+
|
|
35
|
+
## Linked issues
|
|
36
|
+
|
|
37
|
+
<!-- Closes #123 / Refs #456 -->
|
|
38
|
+
|
|
39
|
+
## Notes for the reviewer
|
|
40
|
+
|
|
41
|
+
<!-- Anything subtle, controversial, or worth flagging. -->
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
# Cancel in-flight runs for the same branch/PR — keeps CI fast.
|
|
11
|
+
concurrency:
|
|
12
|
+
group: ci-${{ github.ref }}
|
|
13
|
+
cancel-in-progress: true
|
|
14
|
+
|
|
15
|
+
permissions:
|
|
16
|
+
contents: read
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
# ------------------------------------------------------------------
|
|
20
|
+
# core: install WITHOUT the [llm] extra and confirm the test suite
|
|
21
|
+
# still passes. tracelens has no optional-dep-gated tests after the
|
|
22
|
+
# LiteLLM wrapper was removed; this job exists to verify the core
|
|
23
|
+
# import graph stays clean under a minimal install.
|
|
24
|
+
# ------------------------------------------------------------------
|
|
25
|
+
core:
|
|
26
|
+
name: core (py${{ matrix.python }})
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
strategy:
|
|
29
|
+
fail-fast: false
|
|
30
|
+
matrix:
|
|
31
|
+
python: ["3.11", "3.12", "3.13"]
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@v4
|
|
34
|
+
- uses: actions/setup-python@v5
|
|
35
|
+
with:
|
|
36
|
+
python-version: ${{ matrix.python }}
|
|
37
|
+
cache: pip
|
|
38
|
+
- name: Install (core + dev)
|
|
39
|
+
run: |
|
|
40
|
+
python -m pip install --upgrade pip
|
|
41
|
+
pip install -e ".[dev,http]"
|
|
42
|
+
- name: Verify core-only import
|
|
43
|
+
run: |
|
|
44
|
+
python -c "import tracelens; print(f'{len(tracelens.__all__)} public exports')"
|
|
45
|
+
- name: Run tests
|
|
46
|
+
run: pytest -q --no-header
|
|
47
|
+
|
|
48
|
+
# ------------------------------------------------------------------
|
|
49
|
+
# with-llm: install the [llm] convenience bundle so subclasses of
|
|
50
|
+
# LLMProvider that happen to import openai/anthropic at module load
|
|
51
|
+
# keep working. Same test suite as core — nothing conditionally
|
|
52
|
+
# depends on these SDKs today.
|
|
53
|
+
# ------------------------------------------------------------------
|
|
54
|
+
with-llm:
|
|
55
|
+
name: with-llm (py3.13)
|
|
56
|
+
runs-on: ubuntu-latest
|
|
57
|
+
steps:
|
|
58
|
+
- uses: actions/checkout@v4
|
|
59
|
+
- uses: actions/setup-python@v5
|
|
60
|
+
with:
|
|
61
|
+
python-version: "3.13"
|
|
62
|
+
cache: pip
|
|
63
|
+
- name: Install (core + dev + llm + http)
|
|
64
|
+
run: |
|
|
65
|
+
python -m pip install --upgrade pip
|
|
66
|
+
pip install -e ".[dev,llm,http]"
|
|
67
|
+
- name: Run tests
|
|
68
|
+
run: pytest -q --no-header
|
|
69
|
+
|
|
70
|
+
# ------------------------------------------------------------------
|
|
71
|
+
# examples-smoke: end-to-end smoke test of the packaged example.
|
|
72
|
+
# Proves the CLI entry point is wired correctly and that a realistic
|
|
73
|
+
# user workflow (load tasks -> run agent -> grade -> report) works
|
|
74
|
+
# against the built package.
|
|
75
|
+
# ------------------------------------------------------------------
|
|
76
|
+
examples-smoke:
|
|
77
|
+
name: examples-smoke (py3.13)
|
|
78
|
+
runs-on: ubuntu-latest
|
|
79
|
+
steps:
|
|
80
|
+
- uses: actions/checkout@v4
|
|
81
|
+
- uses: actions/setup-python@v5
|
|
82
|
+
with:
|
|
83
|
+
python-version: "3.13"
|
|
84
|
+
cache: pip
|
|
85
|
+
- name: Install
|
|
86
|
+
run: |
|
|
87
|
+
python -m pip install --upgrade pip
|
|
88
|
+
pip install -e ".[http]"
|
|
89
|
+
- name: Run bundled example
|
|
90
|
+
run: python examples/run_eval.py
|
|
91
|
+
- name: Verify CLI entry point
|
|
92
|
+
run: tracelens --help
|
|
93
|
+
|
|
94
|
+
# ------------------------------------------------------------------
|
|
95
|
+
# lint: ruff check on source + tests.
|
|
96
|
+
# ------------------------------------------------------------------
|
|
97
|
+
lint:
|
|
98
|
+
name: lint
|
|
99
|
+
runs-on: ubuntu-latest
|
|
100
|
+
steps:
|
|
101
|
+
- uses: actions/checkout@v4
|
|
102
|
+
- uses: actions/setup-python@v5
|
|
103
|
+
with:
|
|
104
|
+
python-version: "3.13"
|
|
105
|
+
cache: pip
|
|
106
|
+
- name: Install ruff
|
|
107
|
+
run: pip install "ruff>=0.1"
|
|
108
|
+
- name: ruff check
|
|
109
|
+
run: ruff check src/ tests/
|
|
110
|
+
|
|
111
|
+
# ------------------------------------------------------------------
|
|
112
|
+
# typecheck: strict mypy check for the public typed package promise.
|
|
113
|
+
# ------------------------------------------------------------------
|
|
114
|
+
typecheck:
|
|
115
|
+
name: typecheck
|
|
116
|
+
runs-on: ubuntu-latest
|
|
117
|
+
steps:
|
|
118
|
+
- uses: actions/checkout@v4
|
|
119
|
+
- uses: actions/setup-python@v5
|
|
120
|
+
with:
|
|
121
|
+
python-version: "3.13"
|
|
122
|
+
cache: pip
|
|
123
|
+
- name: Install
|
|
124
|
+
run: |
|
|
125
|
+
python -m pip install --upgrade pip
|
|
126
|
+
pip install -e ".[dev]"
|
|
127
|
+
- name: mypy
|
|
128
|
+
run: mypy src/tracelens/
|
|
129
|
+
|
|
130
|
+
# ------------------------------------------------------------------
|
|
131
|
+
# build: prove that the source distribution and wheel are publishable
|
|
132
|
+
# on every PR and main commit. The release workflow reuses the same
|
|
133
|
+
# build path before uploading to PyPI.
|
|
134
|
+
# ------------------------------------------------------------------
|
|
135
|
+
build:
|
|
136
|
+
name: build artifacts
|
|
137
|
+
runs-on: ubuntu-latest
|
|
138
|
+
steps:
|
|
139
|
+
- uses: actions/checkout@v4
|
|
140
|
+
with:
|
|
141
|
+
fetch-depth: 0
|
|
142
|
+
- uses: actions/setup-python@v5
|
|
143
|
+
with:
|
|
144
|
+
python-version: "3.13"
|
|
145
|
+
cache: pip
|
|
146
|
+
- name: Build package
|
|
147
|
+
run: |
|
|
148
|
+
python -m pip install --upgrade pip
|
|
149
|
+
python -m pip install build twine
|
|
150
|
+
python -m build
|
|
151
|
+
python -m twine check dist/*
|
|
152
|
+
- name: Smoke install wheel
|
|
153
|
+
run: |
|
|
154
|
+
python -m venv /tmp/tracelens-smoke
|
|
155
|
+
/tmp/tracelens-smoke/bin/python -m pip install dist/*.whl
|
|
156
|
+
/tmp/tracelens-smoke/bin/python -c "import tracelens; print(tracelens.__version__)"
|
|
157
|
+
/tmp/tracelens-smoke/bin/tracelens --help
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*.*.*"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
publish:
|
|
13
|
+
name: publish to PyPI
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
environment: release
|
|
16
|
+
permissions:
|
|
17
|
+
contents: read
|
|
18
|
+
id-token: write
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
with:
|
|
22
|
+
fetch-depth: 0
|
|
23
|
+
|
|
24
|
+
- uses: actions/setup-python@v5
|
|
25
|
+
with:
|
|
26
|
+
python-version: "3.13"
|
|
27
|
+
cache: pip
|
|
28
|
+
|
|
29
|
+
- name: Build package
|
|
30
|
+
run: |
|
|
31
|
+
python -m pip install --upgrade pip
|
|
32
|
+
python -m pip install build twine
|
|
33
|
+
python -m build
|
|
34
|
+
python -m twine check dist/*
|
|
35
|
+
|
|
36
|
+
- name: Verify tag matches package version
|
|
37
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
38
|
+
run: |
|
|
39
|
+
python - <<'PY'
|
|
40
|
+
import email.parser
|
|
41
|
+
import os
|
|
42
|
+
import zipfile
|
|
43
|
+
from pathlib import Path
|
|
44
|
+
|
|
45
|
+
tag = os.environ["GITHUB_REF_NAME"].removeprefix("v")
|
|
46
|
+
wheel = next(Path("dist").glob("tracelens-*.whl"))
|
|
47
|
+
with zipfile.ZipFile(wheel) as zf:
|
|
48
|
+
metadata_name = next(
|
|
49
|
+
name for name in zf.namelist()
|
|
50
|
+
if name.endswith(".dist-info/METADATA")
|
|
51
|
+
)
|
|
52
|
+
metadata = email.parser.Parser().parsestr(
|
|
53
|
+
zf.read(metadata_name).decode()
|
|
54
|
+
)
|
|
55
|
+
version = metadata["Version"]
|
|
56
|
+
if version != tag:
|
|
57
|
+
raise SystemExit(
|
|
58
|
+
f"tag v{tag} does not match built package version {version}"
|
|
59
|
+
)
|
|
60
|
+
print(f"release version verified: {version}")
|
|
61
|
+
PY
|
|
62
|
+
|
|
63
|
+
- name: Publish to PyPI
|
|
64
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
65
|
+
with:
|
|
66
|
+
packages-dir: dist/
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
*.egg-info/
|
|
20
|
+
.installed.cfg
|
|
21
|
+
*.egg
|
|
22
|
+
|
|
23
|
+
# Virtual environments
|
|
24
|
+
.venv/
|
|
25
|
+
venv/
|
|
26
|
+
ENV/
|
|
27
|
+
env/
|
|
28
|
+
.env
|
|
29
|
+
|
|
30
|
+
# Testing
|
|
31
|
+
.pytest_cache/
|
|
32
|
+
.coverage
|
|
33
|
+
htmlcov/
|
|
34
|
+
coverage/
|
|
35
|
+
.tox/
|
|
36
|
+
.nox/
|
|
37
|
+
.cache/
|
|
38
|
+
|
|
39
|
+
# Type checking
|
|
40
|
+
.mypy_cache/
|
|
41
|
+
.dmypy.json
|
|
42
|
+
dmypy.json
|
|
43
|
+
|
|
44
|
+
# Lint caches
|
|
45
|
+
.ruff_cache/
|
|
46
|
+
|
|
47
|
+
# IDEs
|
|
48
|
+
.idea/
|
|
49
|
+
.vscode/
|
|
50
|
+
*.swp
|
|
51
|
+
*.swo
|
|
52
|
+
*~
|
|
53
|
+
.project
|
|
54
|
+
.pydevproject
|
|
55
|
+
.settings/
|
|
56
|
+
|
|
57
|
+
# OS
|
|
58
|
+
.DS_Store
|
|
59
|
+
Thumbs.db
|
|
60
|
+
|
|
61
|
+
# Claude / harness state
|
|
62
|
+
.claude/
|
|
63
|
+
.harness-mem/
|
|
64
|
+
.mcp.json
|
|
65
|
+
|
|
66
|
+
# Worktrees
|
|
67
|
+
.worktrees/
|
|
68
|
+
|
|
69
|
+
# Jupyter
|
|
70
|
+
.ipynb_checkpoints/
|
|
71
|
+
*.ipynb
|
|
72
|
+
|
|
73
|
+
# Build
|
|
74
|
+
*.manifest
|
|
75
|
+
*.spec
|
|
76
|
+
|
|
77
|
+
# Logs
|
|
78
|
+
*.log
|
|
79
|
+
pip-log.txt
|
|
80
|
+
pip-delete-this-directory.txt
|
|
81
|
+
|
|
82
|
+
# Generated reports
|
|
83
|
+
examples/report.html
|
|
84
|
+
report.html
|
|
85
|
+
|
|
86
|
+
# Benchmark artifacts — regenerate via benchmarks/*/README.md
|
|
87
|
+
benchmarks/**/baseline_*.json
|
|
88
|
+
benchmarks/**/run_*.json
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. The format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project
|
|
5
|
+
aims to follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html) —
|
|
6
|
+
but while `0.x`, minor bumps may contain breaking changes. Treat the
|
|
7
|
+
top-level `tracelens.*` imports as the stable surface; submodule paths may move.
|
|
8
|
+
|
|
9
|
+
## [Unreleased]
|
|
10
|
+
|
|
11
|
+
Everything under this heading is queued for the next tag-driven release. Two
|
|
12
|
+
themes:
|
|
13
|
+
|
|
14
|
+
1. **Productization pre-v1.0** — turn the engine into something an external
|
|
15
|
+
user can actually install, understand, and trust.
|
|
16
|
+
2. **Infra-noise differentiator** — implement Anthropic's "Quantifying
|
|
17
|
+
infrastructure noise in agentic coding evals" recommendations
|
|
18
|
+
(Feb 2026) as first-class framework features.
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- **`DecisionSpec.InfraConfig`.** Resource limits (CPU/memory guaranteed
|
|
23
|
+
vs. hard-limit), time budget, concurrency level, sandbox provider, and
|
|
24
|
+
harness version are now first-class experimental variables that feed
|
|
25
|
+
into the `DecisionSpec` SHA-256 fingerprint. Observational fields
|
|
26
|
+
(hostname, container ID, wall-clock start) are recorded but
|
|
27
|
+
intentionally excluded from the fingerprint, so two runs with identical
|
|
28
|
+
configs on different hosts collide to the same fingerprint. Based on
|
|
29
|
+
Anthropic's recommendation that "resource configuration ... [be]
|
|
30
|
+
documented and controlled with the same rigor as prompt format or
|
|
31
|
+
sampling temperature."
|
|
32
|
+
- **`TrialStatus.INFRA_ERROR` + `InfraError` exception.** The runner now
|
|
33
|
+
classifies `MemoryError`, `ConnectionError`, and adapter-raised
|
|
34
|
+
`InfraError` as infrastructure failures, distinct from task-level
|
|
35
|
+
`FAILED` status. `TrialBatch.infra_error_rate` and `infra_error_count`
|
|
36
|
+
aggregate at the suite level.
|
|
37
|
+
- **`RegressionDetector.compare_with_specs()`.** New method that diffs
|
|
38
|
+
the two runs' `InfraConfig`s. When they differ AND a regression's
|
|
39
|
+
absolute delta is below the 3pp noise band (Anthropic's threshold),
|
|
40
|
+
the regression is marked `within_noise_band=True` and filtered out
|
|
41
|
+
of `blocking_regressions`. Default `should_block_ci()` honors that
|
|
42
|
+
filter so CI doesn't gate on ambiguous noise.
|
|
43
|
+
- **`ReportGenerator` surfaces infra metrics.** `infra_error_rate`
|
|
44
|
+
appears in markdown, CI summary, and HTML outputs when non-zero.
|
|
45
|
+
Regression reports with an infra-config mismatch get an explicit
|
|
46
|
+
warning block plus a "blocking / total" breakdown in the CI line.
|
|
47
|
+
- **Flagship benchmark pack** at `benchmarks/high-stakes-autonomous/`.
|
|
48
|
+
Six tasks (safety GATE + resource-sensitive capability) plus a
|
|
49
|
+
runnable script that reproduces Anthropic's finding end-to-end:
|
|
50
|
+
same agent, same tasks, 100% → 50% pass rate purely from a memory
|
|
51
|
+
budget change, correctly attributed to infrastructure rather than
|
|
52
|
+
capability. Ships with a walkthrough README.
|
|
53
|
+
- **Three runnable examples** under `examples/`:
|
|
54
|
+
- `http_agent_eval.py` — `HTTPAPIAdapter` + `JsonSchemaGrader` against
|
|
55
|
+
an in-process stdlib HTTP server. Swap the URL for your real
|
|
56
|
+
service.
|
|
57
|
+
- `contract_eval.py` — `BehaviorContract.to_graders()` producing a
|
|
58
|
+
mixed GATE/WARN/TRACK grader suite from one declaration.
|
|
59
|
+
- `noise_aware_regression.py` — 98-line version of the infra-noise
|
|
60
|
+
differentiator: two runs, different memory budgets, fingerprint
|
|
61
|
+
mismatch, noise-aware regression report.
|
|
62
|
+
- **4-job GitHub Actions CI workflow** at `.github/workflows/ci.yml`:
|
|
63
|
+
`core` (Python 3.11 / 3.12 / 3.13), `with-llm`, `examples-smoke`, and
|
|
64
|
+
`lint`. Concurrency group cancels in-flight runs on re-push.
|
|
65
|
+
- **Tag-driven release workflow** at `.github/workflows/release.yml`.
|
|
66
|
+
Versions come from `vX.Y.Z` git tags via `hatch-vcs`; the workflow builds,
|
|
67
|
+
validates, checks the tag/version match, and publishes with PyPI trusted
|
|
68
|
+
publishing.
|
|
69
|
+
- **OSS launch guidance**: `docs/releasing.md`, `docs/scenarios.md`, and
|
|
70
|
+
`examples/README.md`.
|
|
71
|
+
- **Curated public API** at `tracelens/*` (83 symbols). Top-level imports
|
|
72
|
+
are the stable surface; submodules may move.
|
|
73
|
+
- **OSS hygiene files**: `LICENSE` (MIT), `CONTRIBUTING.md`,
|
|
74
|
+
`CODE_OF_CONDUCT.md` (Contributor Covenant 2.1), `SECURITY.md`,
|
|
75
|
+
`CHANGELOG.md` (this file), GitHub issue templates, and a pull
|
|
76
|
+
request template.
|
|
77
|
+
- **Typed package marker**: `src/tracelens/py.typed` now ships in
|
|
78
|
+
wheels so the `Typing :: Typed` classifier reflects the package
|
|
79
|
+
artifact.
|
|
80
|
+
|
|
81
|
+
### Changed
|
|
82
|
+
|
|
83
|
+
- **pyproject.toml metadata** — real author + project URLs (repo,
|
|
84
|
+
issues, changelog), richer classifiers, descriptive keywords. Moved
|
|
85
|
+
`[project.urls]` below `dependencies` to fix a hatchling editable-
|
|
86
|
+
install break.
|
|
87
|
+
- **Public installation docs** — first-path README, installation, and
|
|
88
|
+
CI/CD guidance now describe public GitHub installs instead of private
|
|
89
|
+
repository authentication.
|
|
90
|
+
- **CI type gate** — the workflow now runs strict mypy as a required
|
|
91
|
+
job, matching the contributor verification checklist.
|
|
92
|
+
- **sdist contents** — maintainer-local `CLAUDE.md` is excluded from
|
|
93
|
+
source distributions.
|
|
94
|
+
- **Ruff baseline** — applied autofixes to 67 pre-existing findings
|
|
95
|
+
(unused imports, `datetime.utcnow()` → `datetime.now(UTC)`, f-string
|
|
96
|
+
cleanup). Configured `ignore = ["E501", "UP042"]` for the remaining
|
|
97
|
+
23 long lines and 7 `str, Enum` sites as deferred cleanup.
|
|
98
|
+
- **Factory policy change for LLM providers** — `create_provider()`
|
|
99
|
+
now only supports `"in-memory"`; passing any other alias raises
|
|
100
|
+
`ValueError` with guidance to subclass `LLMProvider` directly. This
|
|
101
|
+
replaces the shipped LiteLLM wrapper with a documented subclassing
|
|
102
|
+
pattern; tracelens no longer tries to own the provider integration
|
|
103
|
+
layer.
|
|
104
|
+
|
|
105
|
+
### Removed
|
|
106
|
+
|
|
107
|
+
- **`WorkflowTask` / `WorkflowRunner` / `WorkflowAdapter`** (392 LOC +
|
|
108
|
+
tests). Codex found that `workflow_runner.py:158-194` computed per-
|
|
109
|
+
step grading outcomes then silently dropped them on the floor. No
|
|
110
|
+
example, benchmark, CLI, or README referenced the workflow layer.
|
|
111
|
+
Breaking change for the top-level API, but no known downstream user.
|
|
112
|
+
- **`LiteLLMProvider`** (`src/tracelens/llm/litellm_provider.py`, ~40
|
|
113
|
+
LOC). A thin wrapper over `litellm.acompletion` with no distinct
|
|
114
|
+
value over the vendor SDK. Users now subclass `LLMProvider`
|
|
115
|
+
directly; the factory module docstring shows the pattern. The
|
|
116
|
+
`[llm]` extra retains `openai` + `anthropic` as a convenience
|
|
117
|
+
bundle, minus `litellm`.
|
|
118
|
+
- **`BehaviorContract.tool_param_constraints`** and
|
|
119
|
+
**`BehaviorContract.max_cost_usd`**. Both declared, both unreferenced
|
|
120
|
+
in `to_graders()`. Surface area for placeholders that never did
|
|
121
|
+
anything.
|
|
122
|
+
- **Dead `if False` block + hardcoded `v0.1.0` strings** in
|
|
123
|
+
`ReportGenerator.render_html`. Version string now sourced from
|
|
124
|
+
`tracelens._version.__version__`.
|
|
125
|
+
|
|
126
|
+
### Fixed
|
|
127
|
+
|
|
128
|
+
- **Litellm-dependent tests FAIL vs. SKIP.** Guarded behind a
|
|
129
|
+
`pytest.mark.skipif(find_spec("litellm") is None)` marker so the
|
|
130
|
+
core-only CI job passes cleanly without the optional dep. Now
|
|
131
|
+
obsolete after the LiteLLMProvider removal, but preserved the
|
|
132
|
+
pattern for any future optional-dep-gated tests.
|
|
133
|
+
- **Degenerate regression samples no longer emit SciPy precision-loss
|
|
134
|
+
warnings.** Zero-variance current samples now short-circuit the
|
|
135
|
+
one-sample t-test and preserve the same significance outcome without
|
|
136
|
+
leaking runtime warnings during Python 3.13 test runs.
|
|
137
|
+
- **Core installs no longer require the `[http]` extra at import time.**
|
|
138
|
+
`HTTPAPIAdapter` still raises a targeted install hint when used
|
|
139
|
+
without `httpx`, but `import tracelens` and `tracelens --help` now work
|
|
140
|
+
from a base wheel install.
|
|
141
|
+
|
|
142
|
+
### Notes on backward compatibility
|
|
143
|
+
|
|
144
|
+
This is a `0.x` release, so breaking changes are allowed per the
|
|
145
|
+
version scheme noted at the top. The visible breaks are:
|
|
146
|
+
|
|
147
|
+
- `from tracelens import WorkflowTask` (and siblings) will now raise
|
|
148
|
+
`ImportError`. No known downstream user imports these, but flagging
|
|
149
|
+
the break in case you had one.
|
|
150
|
+
- `from tracelens.llm.litellm_provider import LiteLLMProvider` is gone;
|
|
151
|
+
write a `LLMProvider` subclass against your vendor SDK instead.
|
|
152
|
+
The pattern is in the `tracelens.llm.factory` module docstring.
|
|
153
|
+
- `BehaviorContract(tool_param_constraints=...)` or `max_cost_usd=...`
|
|
154
|
+
will now raise `pydantic.ValidationError`. Neither had any effect
|
|
155
|
+
before, so removing the kwarg is a no-op for real usage.
|
|
156
|
+
|
|
157
|
+
## [0.1.0] - Initial alpha
|
|
158
|
+
|
|
159
|
+
Initial scaffold shipped prior to this branch — `Task`, `Trial`,
|
|
160
|
+
`Grader`, `Transcript`, `AgentAdapter`, `EvaluationRunner`,
|
|
161
|
+
`BaselineManager`, `RegressionDetector`, `ReportGenerator`,
|
|
162
|
+
`DecisionSpec`, pass@k / pass^k / bootstrap CI statistics,
|
|
163
|
+
`tracelens run` CLI, etc. See git history before branch point for
|
|
164
|
+
the full list.
|