agent-skill-eval 0.2.1__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.
Files changed (53) hide show
  1. agent_skill_eval-0.2.1/.github/ISSUE_TEMPLATE/bug_report.yml +38 -0
  2. agent_skill_eval-0.2.1/.github/ISSUE_TEMPLATE/feature_request.yml +23 -0
  3. agent_skill_eval-0.2.1/.github/actions/setup/action.yml +19 -0
  4. agent_skill_eval-0.2.1/.github/workflows/ci.yml +62 -0
  5. agent_skill_eval-0.2.1/.github/workflows/publish.yml +50 -0
  6. agent_skill_eval-0.2.1/.gitignore +11 -0
  7. agent_skill_eval-0.2.1/AGENTS.md +66 -0
  8. agent_skill_eval-0.2.1/CHANGELOG.md +83 -0
  9. agent_skill_eval-0.2.1/CODE_OF_CONDUCT.md +39 -0
  10. agent_skill_eval-0.2.1/CONTRIBUTING.md +42 -0
  11. agent_skill_eval-0.2.1/LICENSE +21 -0
  12. agent_skill_eval-0.2.1/PKG-INFO +335 -0
  13. agent_skill_eval-0.2.1/README.md +304 -0
  14. agent_skill_eval-0.2.1/TODO.md +105 -0
  15. agent_skill_eval-0.2.1/examples/commit-push-pr/evals/evals.json +64 -0
  16. agent_skill_eval-0.2.1/examples/commit-push-pr/evals/files/sample_change.py +2 -0
  17. agent_skill_eval-0.2.1/examples/fix-failing-tests/evals/evals.json +54 -0
  18. agent_skill_eval-0.2.1/examples/fix-failing-tests/evals/files/calculator.py +28 -0
  19. agent_skill_eval-0.2.1/examples/fix-failing-tests/evals/files/conftest.py +4 -0
  20. agent_skill_eval-0.2.1/examples/fix-failing-tests/evals/files/test_calculator.py +54 -0
  21. agent_skill_eval-0.2.1/examples/write-release-notes/evals/evals.json +44 -0
  22. agent_skill_eval-0.2.1/examples/write-release-notes/evals/files/commits.txt +10 -0
  23. agent_skill_eval-0.2.1/pyproject.toml +60 -0
  24. agent_skill_eval-0.2.1/schemas/evals.schema.json +83 -0
  25. agent_skill_eval-0.2.1/scripts/record-demo.sh +45 -0
  26. agent_skill_eval-0.2.1/skills/commit-push-pr/SKILL.md +113 -0
  27. agent_skill_eval-0.2.1/skills/fix-failing-tests/SKILL.md +90 -0
  28. agent_skill_eval-0.2.1/skills/write-release-notes/SKILL.md +76 -0
  29. agent_skill_eval-0.2.1/src/skill_eval/__init__.py +8 -0
  30. agent_skill_eval-0.2.1/src/skill_eval/__main__.py +3 -0
  31. agent_skill_eval-0.2.1/src/skill_eval/cli.py +844 -0
  32. agent_skill_eval-0.2.1/src/skill_eval/git_state.py +227 -0
  33. agent_skill_eval-0.2.1/src/skill_eval/graders/__init__.py +810 -0
  34. agent_skill_eval-0.2.1/src/skill_eval/harnesses/__init__.py +337 -0
  35. agent_skill_eval-0.2.1/src/skill_eval/models.py +146 -0
  36. agent_skill_eval-0.2.1/src/skill_eval/runner.py +424 -0
  37. agent_skill_eval-0.2.1/src/skill_eval/skills.py +88 -0
  38. agent_skill_eval-0.2.1/src/skill_eval/workspace.py +101 -0
  39. agent_skill_eval-0.2.1/tests/__init__.py +0 -0
  40. agent_skill_eval-0.2.1/tests/conftest.py +64 -0
  41. agent_skill_eval-0.2.1/tests/fixtures/evals/format-json.json +32 -0
  42. agent_skill_eval-0.2.1/tests/fixtures/skills/format-json/SKILL.md +10 -0
  43. agent_skill_eval-0.2.1/tests/test_cli_smoke.py +92 -0
  44. agent_skill_eval-0.2.1/tests/test_fuzz_grader.py +132 -0
  45. agent_skill_eval-0.2.1/tests/test_git_state.py +155 -0
  46. agent_skill_eval-0.2.1/tests/test_graders.py +961 -0
  47. agent_skill_eval-0.2.1/tests/test_harnesses.py +132 -0
  48. agent_skill_eval-0.2.1/tests/test_launch_features.py +489 -0
  49. agent_skill_eval-0.2.1/tests/test_llm_grader.py +306 -0
  50. agent_skill_eval-0.2.1/tests/test_runner.py +815 -0
  51. agent_skill_eval-0.2.1/tests/test_skill_validation.py +114 -0
  52. agent_skill_eval-0.2.1/tests/test_skills.py +104 -0
  53. agent_skill_eval-0.2.1/tests/test_workspace.py +117 -0
@@ -0,0 +1,38 @@
1
+ name: Bug Report
2
+ description: Report a bug or unexpected behavior
3
+ labels: ["bug"]
4
+ body:
5
+ - type: textarea
6
+ id: description
7
+ attributes:
8
+ label: Description
9
+ description: A clear description of the bug
10
+ validations:
11
+ required: true
12
+ - type: textarea
13
+ id: reproduction
14
+ attributes:
15
+ label: Steps to reproduce
16
+ description: Minimal steps to reproduce the behavior
17
+ placeholder: |
18
+ 1. skill-eval run --skill ... --evals ... --agent opencode
19
+ 2. ...
20
+ validations:
21
+ required: true
22
+ - type: textarea
23
+ id: expected
24
+ attributes:
25
+ label: Expected behavior
26
+ description: What you expected to happen
27
+ validations:
28
+ required: true
29
+ - type: input
30
+ id: version
31
+ attributes:
32
+ label: Version
33
+ description: Output of `skill-eval --version`
34
+ - type: input
35
+ id: python
36
+ attributes:
37
+ label: Python version
38
+ description: Output of `python --version`
@@ -0,0 +1,23 @@
1
+ name: Feature Request
2
+ description: Suggest a new feature or improvement
3
+ labels: ["enhancement"]
4
+ body:
5
+ - type: textarea
6
+ id: problem
7
+ attributes:
8
+ label: Problem
9
+ description: What problem does this feature solve?
10
+ validations:
11
+ required: true
12
+ - type: textarea
13
+ id: solution
14
+ attributes:
15
+ label: Proposed solution
16
+ description: How would this feature work?
17
+ validations:
18
+ required: true
19
+ - type: textarea
20
+ id: alternatives
21
+ attributes:
22
+ label: Alternatives considered
23
+ description: Any alternative approaches you've considered
@@ -0,0 +1,19 @@
1
+ name: Setup Python and install dependencies
2
+ description: Shared setup for lint and test jobs
3
+
4
+ inputs:
5
+ python-version:
6
+ description: Python version to use
7
+ required: true
8
+
9
+ runs:
10
+ using: composite
11
+ steps:
12
+ - uses: actions/setup-python@v5
13
+ with:
14
+ python-version: ${{ inputs.python-version }}
15
+ cache: 'pip'
16
+
17
+ - name: Install dependencies
18
+ shell: bash
19
+ run: pip install -e ".[dev]"
@@ -0,0 +1,62 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ concurrency:
10
+ group: ci-${{ github.ref }}
11
+ cancel-in-progress: true
12
+
13
+ permissions:
14
+ contents: read
15
+
16
+ jobs:
17
+ lint:
18
+ runs-on: ubuntu-latest
19
+ strategy:
20
+ matrix:
21
+ python-version: ["3.11", "3.12", "3.13"]
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+ - uses: ./.github/actions/setup
25
+ with:
26
+ python-version: ${{ matrix.python-version }}
27
+ - run: ruff check src/ tests/
28
+ - run: ruff format --check src/ tests/
29
+
30
+ test:
31
+ runs-on: ubuntu-latest
32
+ strategy:
33
+ matrix:
34
+ python-version: ["3.11", "3.12", "3.13"]
35
+ steps:
36
+ - uses: actions/checkout@v4
37
+ - uses: ./.github/actions/setup
38
+ with:
39
+ python-version: ${{ matrix.python-version }}
40
+ - run: pytest -v --junitxml=results.xml --cov=skill_eval --cov-report=xml:coverage.xml
41
+ - name: Upload test results
42
+ if: always()
43
+ uses: actions/upload-artifact@v4
44
+ with:
45
+ name: test-results-${{ matrix.python-version }}
46
+ path: results.xml
47
+ - name: Upload coverage
48
+ if: always()
49
+ uses: actions/upload-artifact@v4
50
+ with:
51
+ name: coverage-${{ matrix.python-version }}
52
+ path: coverage.xml
53
+
54
+ smoke:
55
+ runs-on: ubuntu-latest
56
+ needs: [lint, test]
57
+ steps:
58
+ - uses: actions/checkout@v4
59
+ - uses: ./.github/actions/setup
60
+ with:
61
+ python-version: "3.12"
62
+ - run: pytest -v tests/test_cli_smoke.py
@@ -0,0 +1,50 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ build:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ - uses: actions/setup-python@v5
17
+ with:
18
+ python-version: "3.12"
19
+ - name: Check tag matches package version
20
+ run: |
21
+ version=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
22
+ tag="${GITHUB_REF_NAME#v}"
23
+ if [ "$tag" != "$version" ]; then
24
+ echo "Tag v$tag does not match pyproject.toml version $version" >&2
25
+ exit 1
26
+ fi
27
+ - name: Build sdist and wheel
28
+ run: |
29
+ python -m pip install --upgrade build
30
+ python -m build
31
+ - uses: actions/upload-artifact@v4
32
+ with:
33
+ name: dist
34
+ path: dist/
35
+
36
+ publish:
37
+ needs: build
38
+ runs-on: ubuntu-latest
39
+ environment:
40
+ name: pypi
41
+ url: https://pypi.org/p/skill-eval
42
+ permissions:
43
+ # Required for PyPI trusted publishing (OIDC).
44
+ id-token: write
45
+ steps:
46
+ - uses: actions/download-artifact@v4
47
+ with:
48
+ name: dist
49
+ path: dist/
50
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,11 @@
1
+ __pycache__/
2
+ *.pyc
3
+ *.pyo
4
+ .venv/
5
+ *.egg-info/
6
+ dist/
7
+ build/
8
+ eval-workspace/
9
+ .env
10
+ uv.lock
11
+ .coverage
@@ -0,0 +1,66 @@
1
+ # AGENTS.md
2
+
3
+ ## Project
4
+
5
+ Python CLI framework (`skill-eval`) for evaluating agent skills across OpenCode, Claude Code, and Codex. Uses Typer, Pydantic, OpenAI SDK, and Rich.
6
+
7
+ ## Quick commands
8
+
9
+ ```bash
10
+ # Install (editable + dev deps)
11
+ uv pip install -e ".[dev]"
12
+
13
+ # Run tests
14
+ uv run --extra dev pytest -q
15
+
16
+ # Lint + format check (CI runs both)
17
+ uv run --extra dev ruff check src/ tests/
18
+ uv run --extra dev ruff format --check src/ tests/
19
+
20
+ # Run all checks before committing
21
+ uv run --extra dev ruff check src/ tests/ && uv run --extra dev ruff format --check src/ tests/ && uv run --extra dev pytest -q
22
+ ```
23
+
24
+ ## Architecture
25
+
26
+ ```
27
+ src/skill_eval/
28
+ ├── cli.py # Typer CLI app (run, report, grade, cleanup, init)
29
+ ├── runner.py # EvalRunner orchestrates eval execution
30
+ ├── graders/__init__.py # DeterministicGrader + LLMGrader (700+ lines, single file)
31
+ ├── harnesses/__init__.py # Agent harnesses (opencode, claude-code, codex, fake)
32
+ ├── models.py # Pydantic models for eval config
33
+ ├── git_state.py # Pre/post git/PR state snapshots
34
+ ├── skills.py # Skill installer
35
+ └── workspace.py # Workspace creation (fresh git init or clone)
36
+ ```
37
+
38
+ - Entry point: `skill_eval.cli:app` (registered as `skill-eval` console script)
39
+ - Package layout: `src/skill_eval/` (hatchling build, wheel packages `src/skill_eval`)
40
+ - The `fake` harness (used in tests) is a no-op agent that produces deterministic output
41
+
42
+ ## Testing
43
+
44
+ - Test files mirror source: `test_runner.py`, `test_graders.py`, `test_harnesses.py`, etc.
45
+ - Fixtures live in `tests/fixtures/` — skills and evals JSON used by smoke tests
46
+ - `test_cli_smoke.py` is the integration test: runs full `run -> report -> init` cycle with `--agent fake`
47
+ - Tests use `tmp_path` for workspace isolation; no shared state
48
+ - Shared fixtures in `tests/conftest.py` (`_init_git_workspace`, `grader`, `evals_path`)
49
+
50
+ ## Conventions
51
+
52
+ - Python 3.11+ required (`requires-python = ">=3.11"`)
53
+ - Ruff config: `line-length = 120`, rules `["E", "F", "I"]`
54
+ - All imports use `from __future__ import annotations`
55
+ - Pydantic v2 models throughout
56
+ - CLI uses Typer with `CliRunner` for testing
57
+ - `.env` file loaded via `python-dotenv` (not committed)
58
+
59
+ ## Key gotchas
60
+
61
+ - Default grader model `deepseek/deepseek-v4-flash` is a valid OpenRouter model. Override with `--grader-model` or set a real model.
62
+ - `graders/__init__.py` is a monolith (700+ lines) containing both deterministic and LLM graders
63
+ - `harnesses/__init__.py` has a dead `cost_usd` read at line ~140 (no-op code)
64
+ - `compute_benchmark` returns delta=0.0 for multi-agent runs (known bug)
65
+ - Workspace paths must contain literal `with_skill`/`without_skill` substrings or grading breaks silently
66
+ - `uv.lock` is gitignored — not tracked in version control
@@ -0,0 +1,83 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## [0.2.0] - 2026-06-10
6
+
7
+ ### Added
8
+ - `write-release-notes` example skill + eval suite: exercises LLM rubric grading (grouping, breaking-change prominence, anti-fabrication) instead of git-state checks
9
+ - `--runs N` repeats every (eval, agent, config); `benchmark.json` now reports `full_pass_rate`, `pass_at_k`, and `k`
10
+ - `--agent-model agent=model` (repeatable) and `--harness-base-url` to pin models and endpoints per agent CLI
11
+ - `--timeout` / `--retries` flags; harnesses retry on timeout or non-zero exit with backoff and record `exit_code`, `timed_out`, `retries` in `timing.json`
12
+ - `skill-eval validate`: schema + fixture-existence + duplicate-id checks for evals.json
13
+ - `skill-eval list`: discover eval suites and skills under a directory
14
+ - `skill-eval compare`: side-by-side pass rates of two iterations
15
+ - `report --format markdown` and `report --show-evidence` (failed/skipped assertion evidence)
16
+ - JSON Schema for the eval suite format at `schemas/evals.schema.json` (with a sync test)
17
+ - SKILL.md frontmatter validation warning on `run` (missing name/description, name mismatch)
18
+ - Richer `init` scaffold: SKILL.md frontmatter template + negative-control eval case
19
+ - PyPI trusted-publishing workflow on version tags (`.github/workflows/publish.yml`)
20
+ - Demo recording script (`scripts/record-demo.sh`)
21
+
22
+ ### Changed
23
+ - Assertions that cannot be graded (no API key, LLM grader error) are now **skipped** and excluded from the pass rate instead of counted as failures; `grading.json` gains `method` and `skipped` fields
24
+ - `run` warns upfront when no grader API key is set; `grade` warns that LLM verdicts may flip on re-grade
25
+ - README restructured around the full-harness pitch, with a documented table of recognized deterministic assertion patterns
26
+
27
+ ### Fixed
28
+ - Multi-agent runs no longer report a misleading `Delta: 0.0%`: `benchmark.json` now has per-agent `deltas`; the legacy `delta` field is only set for single-agent runs (otherwise `null`)
29
+ - Removed dead `cost_usd` handling in the Claude Code output parser
30
+
31
+ ## [0.1.0-alpha.3] - 2026-06-07
32
+
33
+ ### Added
34
+ - Shared test fixtures in `conftest.py`
35
+ - `test_llm_grader.py`: 18 tests covering client, prompts, JSON parsing, errors
36
+ - `test_fuzz_grader.py` rewrite: real handler tests instead of mocked dispatch
37
+ - `test_compute_benchmark` with xfail for known multi-agent delta=0 bug
38
+ - EvalCase validation tests (valid, negative control, contradiction)
39
+ - `SkillInstaller.uninstall` tests, `WorkspaceManager._clone_repo` test
40
+ - `github_repo_slug` tests for URLs without `.git` suffix
41
+
42
+ ### Changed
43
+ - CI uses setup-python's built-in cache instead of separate `actions/cache`
44
+
45
+ ### Fixed
46
+ - EvalCase contradiction validator (`force_skill_invocation` + `should_trigger`)
47
+ - LLMGrader now fails on missing assertions instead of silently dropping them
48
+
49
+ ## [0.1.0-alpha.2] - 2026-06-02
50
+
51
+ ### Added
52
+ - CI workflow with Python 3.11/3.12/3.13 matrix, caching, coverage, and smoke test
53
+ - CLI smoke test (`test_cli_smoke.py`) for full run -> report -> init cycle
54
+
55
+ ### Changed
56
+ - Tightened evals with state-delta grading and scoped cleanup
57
+ - Improved `commit-push-pr` skill to 100% pass rate
58
+
59
+ ### Fixed
60
+ - `github_repo_slug` function to parse GitHub URLs correctly
61
+ - Handoff review fixes and PR grading tightening
62
+
63
+ ## [0.1.0-alpha.1] - 2026-05-27
64
+
65
+ ### Added
66
+ - Initial release: skill evaluation framework for OpenCode, Claude Code, and Codex
67
+ - `run`, `report`, `grade`, `cleanup`, and `init` CLI commands
68
+ - Multi-agent support with baseline (with-skill / without-skill) comparison
69
+ - State-delta grading using pre/post git snapshots (`pre_state.json` / `post_state.json`)
70
+ - Deterministic assertions: branch, commit, push, PR, file existence, content matching
71
+ - LLM rubric grading via configurable model (`--grader-model`)
72
+ - Negative-control support (`should_trigger: false`) to catch accidental skill triggering
73
+ - Scoped cleanup via `cleanup.json` manifest (never closes unrelated PRs)
74
+ - `commit-push-pr` example skill with 5 eval cases
75
+ - Lazy-initialized OpenAI client with API key validation
76
+ - OpenRouter grader support via `OPENROUTER_API_KEY`
77
+ - Workspace isolation with fresh git repos per eval run
78
+ - Token/timing extraction from each agent's native output format
79
+ - `python -m skill_eval` entry point
80
+
81
+ ### Fixed
82
+ - OpenRouter grader model resolution and opencode parser output handling
83
+ - Workspace-aware grading and dotenv loading
@@ -0,0 +1,39 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our
6
+ community a harassment-free experience for everyone, regardless of age, body
7
+ size, visible or invisible disability, ethnicity, sex characteristics, gender
8
+ identity and expression, level of experience, education, socio-economic status,
9
+ nationality, personal appearance, race, religion, or sexual identity
10
+ and orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to a positive environment:
15
+
16
+ - Using welcoming and inclusive language
17
+ - Being respectful of differing viewpoints and experiences
18
+ - Gracefully accepting constructive criticism
19
+ - Focusing on what is best for the community
20
+ - Showing empathy towards other community members
21
+
22
+ Examples of unacceptable behavior:
23
+
24
+ - The use of sexualized language or imagery and unwelcome sexual attention or advances
25
+ - Trolling, insulting or derogatory comments, and personal or political attacks
26
+ - Public or private harassment
27
+ - Publishing others' private information without explicit permission
28
+ - Other conduct which could reasonably be considered inappropriate in a professional setting
29
+
30
+ ## Enforcement
31
+
32
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
33
+ reported to the project maintainers. All complaints will be reviewed and
34
+ investigated and will result in a response that is deemed necessary and
35
+ appropriate to the circumstances.
36
+
37
+ ## Attribution
38
+
39
+ This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/), version 2.1.
@@ -0,0 +1,42 @@
1
+ # Contributing
2
+
3
+ ## Setup
4
+
5
+ ```bash
6
+ git clone https://github.com/tardigrde/skill-evals.git
7
+ cd skill-evals
8
+ uv venv
9
+ uv pip install -e ".[dev]"
10
+ ```
11
+
12
+ ## Running checks
13
+
14
+ ```bash
15
+ uv run --extra dev pytest -q
16
+ uv run --extra dev ruff check src/ tests/
17
+ uv run --extra dev ruff format --check src/ tests/
18
+ ```
19
+
20
+ Run all three before committing:
21
+
22
+ ```bash
23
+ uv run --extra dev ruff check src/ tests/ && uv run --extra dev ruff format --check src/ tests/ && uv run --extra dev pytest -q
24
+ ```
25
+
26
+ ## Code style
27
+
28
+ - Python 3.11+ required
29
+ - Ruff for linting and formatting (`line-length = 120`)
30
+ - All imports use `from __future__ import annotations`
31
+ - Pydantic v2 models throughout
32
+
33
+ ## Pull requests
34
+
35
+ 1. Fork the repo and create a feature branch.
36
+ 2. Add tests for new functionality.
37
+ 3. Ensure all checks pass.
38
+ 4. Open a PR with a clear description of the change.
39
+
40
+ ## Issues
41
+
42
+ Use the GitHub issue templates to report bugs or request features.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 skill-eval contributors
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.