pytest-skill-engineering 1.0.3__tar.gz → 1.0.4__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 (55) hide show
  1. pytest_skill_engineering-1.0.4/PKG-INFO +175 -0
  2. pytest_skill_engineering-1.0.4/README.md +127 -0
  3. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/pyproject.toml +14 -14
  4. pytest_skill_engineering-1.0.3/PKG-INFO +0 -182
  5. pytest_skill_engineering-1.0.3/README.md +0 -134
  6. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/.gitignore +0 -0
  7. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/LICENSE +0 -0
  8. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/__init__.py +0 -0
  9. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/copilot/__init__.py +0 -0
  10. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/copilot/api.py +0 -0
  11. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/copilot/client.py +0 -0
  12. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/copilot/config.py +0 -0
  13. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/copilot/contracts.py +0 -0
  14. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/copilot/controls.py +0 -0
  15. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/copilot/eval.py +0 -0
  16. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/copilot/events.py +0 -0
  17. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/copilot/fixtures.py +0 -0
  18. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/copilot/personas.py +0 -0
  19. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/copilot/requests.py +0 -0
  20. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/copilot/result.py +0 -0
  21. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/copilot/runner.py +0 -0
  22. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/copilot/skills.py +0 -0
  23. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/core/__init__.py +0 -0
  24. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/core/errors.py +0 -0
  25. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/core/evals.py +0 -0
  26. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/core/plugin.py +0 -0
  27. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/core/prompt.py +0 -0
  28. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/core/result.py +0 -0
  29. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/core/serialization.py +0 -0
  30. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/core/skill.py +0 -0
  31. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/core/skill_evals.py +0 -0
  32. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/core/skill_grading.py +0 -0
  33. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/core/validation.py +0 -0
  34. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/execution/__init__.py +0 -0
  35. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/execution/cost.py +0 -0
  36. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/execution/rate_limiter.py +0 -0
  37. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/execution/servers.py +0 -0
  38. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/execution/skill_tools.py +0 -0
  39. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/fixtures/__init__.py +0 -0
  40. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/fixtures/factories.py +0 -0
  41. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/fixtures/iteration.py +0 -0
  42. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/onboarding.py +0 -0
  43. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/plugin.py +0 -0
  44. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/plugin_options.py +0 -0
  45. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/plugin_report.py +0 -0
  46. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/reporting/__init__.py +0 -0
  47. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/reporting/collector.py +0 -0
  48. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/reporting/generator.py +0 -0
  49. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/reporting/schema.py +0 -0
  50. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/testing/__init__.py +0 -0
  51. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/testing/banking.py +0 -0
  52. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/testing/banking_mcp.py +0 -0
  53. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/testing/todo.py +0 -0
  54. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/testing/todo_mcp.py +0 -0
  55. {pytest_skill_engineering-1.0.3 → pytest_skill_engineering-1.0.4}/src/pytest_skill_engineering/testing/types.py +0 -0
@@ -0,0 +1,175 @@
1
+ Metadata-Version: 2.5
2
+ Name: pytest-skill-engineering
3
+ Version: 1.0.4
4
+ Summary: Reliable Copilot execution and evidence for coding-agent-led testing of MCP servers, CLI tools, skills, and custom agents.
5
+ Project-URL: Homepage, https://github.com/sbroenne/pytest-skill-engineering
6
+ Project-URL: Repository, https://github.com/sbroenne/pytest-skill-engineering
7
+ Author: Stefan Brunner
8
+ License: MIT
9
+ License-File: LICENSE
10
+ Keywords: agents,ai,custom-agents,llm,mcp,pytest,skill-engineering,skills,testing
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Framework :: Pytest
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Software Development :: Testing
21
+ Requires-Python: >=3.11
22
+ Requires-Dist: github-copilot-sdk>=1.0.28
23
+ Requires-Dist: httpx>=0.28.1
24
+ Requires-Dist: mcp>=2.3.0
25
+ Requires-Dist: pydantic>=2.14.1
26
+ Requires-Dist: pytest-asyncio>=1.4.1
27
+ Requires-Dist: pytest>=9.2.0
28
+ Requires-Dist: python-frontmatter>=1.3.0
29
+ Requires-Dist: tomlkit>=0.15.2
30
+ Requires-Dist: trio>=0.34.0
31
+ Requires-Dist: websockets>=17.3
32
+ Provides-Extra: dev
33
+ Requires-Dist: pre-commit>=4.7.0; extra == 'dev'
34
+ Requires-Dist: pyright>=1.1.414; extra == 'dev'
35
+ Requires-Dist: pytest-cov>=7.1.0; extra == 'dev'
36
+ Requires-Dist: python-dotenv>=1.2.4; extra == 'dev'
37
+ Requires-Dist: ruff>=0.17.3; extra == 'dev'
38
+ Requires-Dist: typeguard>=4.6.0; extra == 'dev'
39
+ Provides-Extra: docs
40
+ Requires-Dist: cairosvg>=2.9.1; extra == 'docs'
41
+ Requires-Dist: mkdocs-material<9.8,>=9.7.7; extra == 'docs'
42
+ Requires-Dist: mkdocs>=1.6.1; extra == 'docs'
43
+ Requires-Dist: mkdocstrings[python]>=1.0.8; extra == 'docs'
44
+ Requires-Dist: pillow>=13.0.0; extra == 'docs'
45
+ Provides-Extra: test
46
+ Requires-Dist: syrupy<7,>=6.1.1; extra == 'test'
47
+ Description-Content-Type: text/markdown
48
+
49
+ # pytest-skill-engineering
50
+
51
+ [![PyPI version](https://img.shields.io/pypi/v/pytest-skill-engineering)](https://pypi.org/project/pytest-skill-engineering/)
52
+ [![CI](https://github.com/sbroenne/pytest-skill-engineering/actions/workflows/ci.yml/badge.svg)](https://github.com/sbroenne/pytest-skill-engineering/actions/workflows/ci.yml)
53
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
54
+
55
+ **Test whether GitHub Copilot can complete tasks with your tools and instructions.**
56
+
57
+ pytest-skill-engineering runs real Copilot sessions from pytest. Give Copilot a
58
+ task, check the actual output with ordinary assertions, and save the execution
59
+ as JSON.
60
+
61
+ Use it to test MCP servers, CLI tools, skills, system prompts, plugins, and custom
62
+ agents. It answers a different question from your tool's unit tests: **can
63
+ Copilot use the interface correctly?** A working tool can still have confusing
64
+ descriptions or arguments that lead the agent to the wrong result.
65
+
66
+ You define what correctness means. The framework manages the Copilot session,
67
+ execution limits, usage, and evidence; it does not grade answers with another AI.
68
+
69
+ ## Quick start
70
+
71
+ You need Python 3.11+, [uv](https://docs.astral.sh/uv/), and a GitHub account with
72
+ Copilot access.
73
+
74
+ Run these commands in an existing Python project with a `pyproject.toml`:
75
+
76
+ ```bash
77
+ uv add pytest-skill-engineering
78
+ gh auth login --hostname github.com
79
+ uv run pytest-skill-engineering init
80
+ uv run pytest-skill-engineering doctor
81
+ uv run python -m pytest tests/test_copilot_eval.py -v
82
+ ```
83
+
84
+ `init` creates a test using the bundled Todo MCP server, configures JSON output,
85
+ and adds starter-model rates to `pricing.toml`. It reports conflicts rather than
86
+ overwriting existing files or settings. `doctor` checks setup and Copilot access.
87
+ Real task execution may consume Copilot premium requests.
88
+
89
+ The test checks the tool's arguments and returned task state. pytest prints the
90
+ result; `aitest-reports/results.json` preserves the execution. See the
91
+ [setup guide](docs/getting-started/index.md) or the standalone
92
+ [quickstart project](examples/quickstart/).
93
+
94
+ ## A test that checks the result
95
+
96
+ ```python
97
+ from __future__ import annotations
98
+
99
+ import json
100
+
101
+ from pytest_skill_engineering.copilot import CopilotEval
102
+
103
+
104
+ async def test_order_total(copilot_eval, tmp_path):
105
+ agent = CopilotEval(
106
+ name="order-total",
107
+ model="gpt-5.6-sol",
108
+ instructions="Save the requested output as JSON. Use integer cents.",
109
+ working_directory=str(tmp_path),
110
+ )
111
+ result = await copilot_eval(
112
+ agent,
113
+ "Save order.json for two items at 1250 cents each plus 20% tax. "
114
+ "Include subtotal_cents, tax_cents, and total_cents.",
115
+ )
116
+ assert result.success, result.error
117
+ output = tmp_path / "order.json"
118
+ assert output.is_file()
119
+ assert json.loads(output.read_text(encoding="utf-8")) == {
120
+ "subtotal_cents": 2500,
121
+ "tax_cents": 500,
122
+ "total_cents": 3000,
123
+ }
124
+ ```
125
+
126
+ `CopilotEval` configures the session. The second argument to `copilot_eval` is
127
+ the user task. `result.success` checks execution completion; the file assertions
128
+ check that the task produced the right result.
129
+
130
+ For your own tools, check the resulting application state, saved files, or
131
+ operation output. A tool call or a model's claim is not proof of task success.
132
+ Use approved isolation for live tests: a temporary directory is not a sandbox,
133
+ and generated code or tool calls can act with your user's access.
134
+
135
+ ## What the framework provides
136
+
137
+ | You need | Use |
138
+ | --- | --- |
139
+ | Real task execution | `CopilotEval` and the `copilot_eval` pytest fixture |
140
+ | Controlled runs | Timeouts, tool budgets, request controls, and permission settings |
141
+ | Debugging evidence | Configuration, calls, arguments, outputs, errors, and completion records |
142
+ | Repeatable comparisons | `ab_run` and pytest repetitions |
143
+ | Usage visibility | Captured tokens, Copilot premium requests, and explicit price estimates |
144
+ | Saved results | Native JSON with execution evidence and ordinary pytest outcomes |
145
+
146
+ Your tests supply application fixtures, guarded tool adapters, and independent
147
+ output checks. The framework makes one execution attempt per call; it does not
148
+ retry failures automatically. Missing usage, prices, and incomplete evidence
149
+ remain visible.
150
+
151
+ ## Investigate and compare
152
+
153
+ Give your coding agent a failed test, its JSON evidence, the requirements, and
154
+ the relevant source. It can investigate the failure and help you change the
155
+ interface. Keep the success criteria fixed when rerunning a comparison.
156
+
157
+ For A/B tests, record verification separately for each side: both saved
158
+ executions share one pytest outcome. That outcome alone cannot establish
159
+ independent pass rates or a causal improvement. See
160
+ [comparing configurations](docs/getting-started/comparing.md).
161
+
162
+ ## Documentation
163
+
164
+ - [Getting started](https://sbroenne.github.io/pytest-skill-engineering/getting-started/)
165
+ - [Task guides](docs/how-to/index.md) and [API reference](docs/reference/api.md)
166
+ - [Examples](examples/README.md), including historical skill comparisons
167
+ - [Upgrading from 0.6.x](docs/migration.md): 1.0 removed AI judging, renderers,
168
+ rankings, and skill refinement
169
+
170
+ No framework companion skill is required or distributed. Testing your own
171
+ domain skills is supported.
172
+
173
+ ## License
174
+
175
+ MIT. Inspired by [agent-benchmark](https://github.com/mykhaliev/agent-benchmark).
@@ -0,0 +1,127 @@
1
+ # pytest-skill-engineering
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/pytest-skill-engineering)](https://pypi.org/project/pytest-skill-engineering/)
4
+ [![CI](https://github.com/sbroenne/pytest-skill-engineering/actions/workflows/ci.yml/badge.svg)](https://github.com/sbroenne/pytest-skill-engineering/actions/workflows/ci.yml)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
6
+
7
+ **Test whether GitHub Copilot can complete tasks with your tools and instructions.**
8
+
9
+ pytest-skill-engineering runs real Copilot sessions from pytest. Give Copilot a
10
+ task, check the actual output with ordinary assertions, and save the execution
11
+ as JSON.
12
+
13
+ Use it to test MCP servers, CLI tools, skills, system prompts, plugins, and custom
14
+ agents. It answers a different question from your tool's unit tests: **can
15
+ Copilot use the interface correctly?** A working tool can still have confusing
16
+ descriptions or arguments that lead the agent to the wrong result.
17
+
18
+ You define what correctness means. The framework manages the Copilot session,
19
+ execution limits, usage, and evidence; it does not grade answers with another AI.
20
+
21
+ ## Quick start
22
+
23
+ You need Python 3.11+, [uv](https://docs.astral.sh/uv/), and a GitHub account with
24
+ Copilot access.
25
+
26
+ Run these commands in an existing Python project with a `pyproject.toml`:
27
+
28
+ ```bash
29
+ uv add pytest-skill-engineering
30
+ gh auth login --hostname github.com
31
+ uv run pytest-skill-engineering init
32
+ uv run pytest-skill-engineering doctor
33
+ uv run python -m pytest tests/test_copilot_eval.py -v
34
+ ```
35
+
36
+ `init` creates a test using the bundled Todo MCP server, configures JSON output,
37
+ and adds starter-model rates to `pricing.toml`. It reports conflicts rather than
38
+ overwriting existing files or settings. `doctor` checks setup and Copilot access.
39
+ Real task execution may consume Copilot premium requests.
40
+
41
+ The test checks the tool's arguments and returned task state. pytest prints the
42
+ result; `aitest-reports/results.json` preserves the execution. See the
43
+ [setup guide](docs/getting-started/index.md) or the standalone
44
+ [quickstart project](examples/quickstart/).
45
+
46
+ ## A test that checks the result
47
+
48
+ ```python
49
+ from __future__ import annotations
50
+
51
+ import json
52
+
53
+ from pytest_skill_engineering.copilot import CopilotEval
54
+
55
+
56
+ async def test_order_total(copilot_eval, tmp_path):
57
+ agent = CopilotEval(
58
+ name="order-total",
59
+ model="gpt-5.6-sol",
60
+ instructions="Save the requested output as JSON. Use integer cents.",
61
+ working_directory=str(tmp_path),
62
+ )
63
+ result = await copilot_eval(
64
+ agent,
65
+ "Save order.json for two items at 1250 cents each plus 20% tax. "
66
+ "Include subtotal_cents, tax_cents, and total_cents.",
67
+ )
68
+ assert result.success, result.error
69
+ output = tmp_path / "order.json"
70
+ assert output.is_file()
71
+ assert json.loads(output.read_text(encoding="utf-8")) == {
72
+ "subtotal_cents": 2500,
73
+ "tax_cents": 500,
74
+ "total_cents": 3000,
75
+ }
76
+ ```
77
+
78
+ `CopilotEval` configures the session. The second argument to `copilot_eval` is
79
+ the user task. `result.success` checks execution completion; the file assertions
80
+ check that the task produced the right result.
81
+
82
+ For your own tools, check the resulting application state, saved files, or
83
+ operation output. A tool call or a model's claim is not proof of task success.
84
+ Use approved isolation for live tests: a temporary directory is not a sandbox,
85
+ and generated code or tool calls can act with your user's access.
86
+
87
+ ## What the framework provides
88
+
89
+ | You need | Use |
90
+ | --- | --- |
91
+ | Real task execution | `CopilotEval` and the `copilot_eval` pytest fixture |
92
+ | Controlled runs | Timeouts, tool budgets, request controls, and permission settings |
93
+ | Debugging evidence | Configuration, calls, arguments, outputs, errors, and completion records |
94
+ | Repeatable comparisons | `ab_run` and pytest repetitions |
95
+ | Usage visibility | Captured tokens, Copilot premium requests, and explicit price estimates |
96
+ | Saved results | Native JSON with execution evidence and ordinary pytest outcomes |
97
+
98
+ Your tests supply application fixtures, guarded tool adapters, and independent
99
+ output checks. The framework makes one execution attempt per call; it does not
100
+ retry failures automatically. Missing usage, prices, and incomplete evidence
101
+ remain visible.
102
+
103
+ ## Investigate and compare
104
+
105
+ Give your coding agent a failed test, its JSON evidence, the requirements, and
106
+ the relevant source. It can investigate the failure and help you change the
107
+ interface. Keep the success criteria fixed when rerunning a comparison.
108
+
109
+ For A/B tests, record verification separately for each side: both saved
110
+ executions share one pytest outcome. That outcome alone cannot establish
111
+ independent pass rates or a causal improvement. See
112
+ [comparing configurations](docs/getting-started/comparing.md).
113
+
114
+ ## Documentation
115
+
116
+ - [Getting started](https://sbroenne.github.io/pytest-skill-engineering/getting-started/)
117
+ - [Task guides](docs/how-to/index.md) and [API reference](docs/reference/api.md)
118
+ - [Examples](examples/README.md), including historical skill comparisons
119
+ - [Upgrading from 0.6.x](docs/migration.md): 1.0 removed AI judging, renderers,
120
+ rankings, and skill refinement
121
+
122
+ No framework companion skill is required or distributed. Testing your own
123
+ domain skills is supported.
124
+
125
+ ## License
126
+
127
+ MIT. Inspired by [agent-benchmark](https://github.com/mykhaliev/agent-benchmark).
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "pytest-skill-engineering"
7
- version = "1.0.3"
7
+ version = "1.0.4"
8
8
  description = "Reliable Copilot execution and evidence for coding-agent-led testing of MCP servers, CLI tools, skills, and custom agents."
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -26,25 +26,25 @@ classifiers = [
26
26
  "Topic :: Software Development :: Testing",
27
27
  ]
28
28
  dependencies = [
29
- "pytest>=9.1.1",
30
- "mcp>=2.2.0",
31
- "pydantic>=2.13.5",
29
+ "pytest>=9.2.0",
30
+ "mcp>=2.3.0",
31
+ "pydantic>=2.14.1",
32
32
  "python-frontmatter>=1.3.0",
33
- "github-copilot-sdk>=1.0.16",
33
+ "github-copilot-sdk>=1.0.28",
34
34
  "httpx>=0.28.1",
35
35
  "trio>=0.34.0",
36
- "tomlkit>=0.15.1",
37
- "pytest-asyncio>=1.4.0",
38
- "websockets>=17.1",
36
+ "tomlkit>=0.15.2",
37
+ "pytest-asyncio>=1.4.1",
38
+ "websockets>=17.3",
39
39
  ]
40
40
 
41
41
  [project.optional-dependencies]
42
42
  dev = [
43
43
  "pytest-cov>=7.1.0",
44
- "python-dotenv>=1.2.3",
45
- "ruff>=0.16.9",
44
+ "python-dotenv>=1.2.4",
45
+ "ruff>=0.17.3",
46
46
  "pyright>=1.1.414",
47
- "pre-commit>=4.6.2",
47
+ "pre-commit>=4.7.0",
48
48
  "typeguard>=4.6.0",
49
49
  ]
50
50
  test = [
@@ -53,8 +53,8 @@ test = [
53
53
  docs = [
54
54
  "mkdocs>=1.6.1",
55
55
  "mkdocs-material>=9.7.7,<9.8",
56
- "mkdocstrings[python]>=1.0.6",
57
- "pillow>=12.3.0",
56
+ "mkdocstrings[python]>=1.0.8",
57
+ "pillow>=13.0.0",
58
58
  "cairosvg>=2.9.1",
59
59
  ]
60
60
 
@@ -98,7 +98,7 @@ quote-style = "double"
98
98
  indent-style = "space"
99
99
 
100
100
  [tool.pyright]
101
- include = ["src", "tests", "examples/skill-dogfood"]
101
+ include = ["src", "tests", "examples/skill-dogfood", "examples/excel-skill-value"]
102
102
  pythonVersion = "3.11"
103
103
  typeCheckingMode = "basic"
104
104
 
@@ -1,182 +0,0 @@
1
- Metadata-Version: 2.5
2
- Name: pytest-skill-engineering
3
- Version: 1.0.3
4
- Summary: Reliable Copilot execution and evidence for coding-agent-led testing of MCP servers, CLI tools, skills, and custom agents.
5
- Project-URL: Homepage, https://github.com/sbroenne/pytest-skill-engineering
6
- Project-URL: Repository, https://github.com/sbroenne/pytest-skill-engineering
7
- Author: Stefan Brunner
8
- License: MIT
9
- License-File: LICENSE
10
- Keywords: agents,ai,custom-agents,llm,mcp,pytest,skill-engineering,skills,testing
11
- Classifier: Development Status :: 4 - Beta
12
- Classifier: Framework :: Pytest
13
- Classifier: Intended Audience :: Developers
14
- Classifier: License :: OSI Approved :: MIT License
15
- Classifier: Operating System :: OS Independent
16
- Classifier: Programming Language :: Python :: 3
17
- Classifier: Programming Language :: Python :: 3.11
18
- Classifier: Programming Language :: Python :: 3.12
19
- Classifier: Programming Language :: Python :: 3.13
20
- Classifier: Topic :: Software Development :: Testing
21
- Requires-Python: >=3.11
22
- Requires-Dist: github-copilot-sdk>=1.0.16
23
- Requires-Dist: httpx>=0.28.1
24
- Requires-Dist: mcp>=2.2.0
25
- Requires-Dist: pydantic>=2.13.5
26
- Requires-Dist: pytest-asyncio>=1.4.0
27
- Requires-Dist: pytest>=9.1.1
28
- Requires-Dist: python-frontmatter>=1.3.0
29
- Requires-Dist: tomlkit>=0.15.1
30
- Requires-Dist: trio>=0.34.0
31
- Requires-Dist: websockets>=17.1
32
- Provides-Extra: dev
33
- Requires-Dist: pre-commit>=4.6.2; extra == 'dev'
34
- Requires-Dist: pyright>=1.1.414; extra == 'dev'
35
- Requires-Dist: pytest-cov>=7.1.0; extra == 'dev'
36
- Requires-Dist: python-dotenv>=1.2.3; extra == 'dev'
37
- Requires-Dist: ruff>=0.16.9; extra == 'dev'
38
- Requires-Dist: typeguard>=4.6.0; extra == 'dev'
39
- Provides-Extra: docs
40
- Requires-Dist: cairosvg>=2.9.1; extra == 'docs'
41
- Requires-Dist: mkdocs-material<9.8,>=9.7.7; extra == 'docs'
42
- Requires-Dist: mkdocs>=1.6.1; extra == 'docs'
43
- Requires-Dist: mkdocstrings[python]>=1.0.6; extra == 'docs'
44
- Requires-Dist: pillow>=12.3.0; extra == 'docs'
45
- Provides-Extra: test
46
- Requires-Dist: syrupy<7,>=6.1.1; extra == 'test'
47
- Description-Content-Type: text/markdown
48
-
49
- # pytest-skill-engineering
50
-
51
- [![PyPI version](https://img.shields.io/pypi/v/pytest-skill-engineering)](https://pypi.org/project/pytest-skill-engineering/)
52
- [![CI](https://github.com/sbroenne/pytest-skill-engineering/actions/workflows/ci.yml/badge.svg)](https://github.com/sbroenne/pytest-skill-engineering/actions/workflows/ci.yml)
53
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
54
-
55
- **A test runner for people working with coding agents.**
56
-
57
- Test whether real GitHub Copilot sessions can use your MCP servers, CLI tools,
58
- skills, system prompts, and custom agents. Write a user task, execute it through
59
- pytest, and verify the actual output with ordinary assertions.
60
-
61
- The framework runs the task and records what happened. Your existing coding agent
62
- investigates the evidence, reads the source, and helps you improve the interface.
63
- **Version 1.0 removes AI judging, report dashboards, rankings, and skill refinement.**
64
- See the [migration guide](docs/migration.md) for this breaking change.
65
-
66
- ## Why this exists
67
-
68
- Your tool can pass its own tests while Copilot chooses the wrong operation,
69
- supplies the wrong arguments, or misunderstands its descriptions. That is a
70
- different question from whether the tool implementation works.
71
-
72
- Use real task execution to test the AI-facing interface, and independent output
73
- checks to establish correctness. A completed session or a tool call by itself
74
- does not prove that the requested task succeeded.
75
-
76
- ## Quick start
77
-
78
- You need Python 3.11+, [uv](https://docs.astral.sh/uv/), and a GitHub account with
79
- Copilot access.
80
-
81
- ```powershell
82
- uv add pytest-skill-engineering
83
- gh auth login --hostname github.com
84
- uv run pytest-skill-engineering init
85
- uv run pytest-skill-engineering doctor
86
- uv run python -m pytest "tests\test_copilot_eval.py" -v
87
- ```
88
-
89
- `init` creates a Todo MCP starter test, explicit JSON evidence settings, and
90
- explicit starter-model rates in `pricing.toml`. It refuses conflicting settings
91
- or an existing starter. Live execution can consume Copilot premium requests.
92
-
93
- pytest shows ordinary test results and assertion failures. Give your coding
94
- agent `aitest-reports\results.json` and the relevant source to investigate what
95
- happened. No dashboard or second AI judgment is generated.
96
-
97
- ## What we learned by testing our own idea
98
-
99
- We evaluated a companion skill for coding agents using this framework and chose
100
- not to ship it. The comparison did not demonstrate a benefit; adding general
101
- test-writing advice was not evidence that users needed another product layer.
102
- Use the documentation, examples, and native evidence directly.
103
-
104
- The [case study](docs/use-cases/companion-skill.md) records the actual results,
105
- failures, limitations, and removal decision. Its
106
- [historical experiment](examples/skill-dogfood/) remains reproducible with a
107
- frozen test fixture, not an installable companion skill. Default sample checks
108
- are offline; live execution is explicit. The [quickstart](examples/quickstart/)
109
- is the smaller first example.
110
-
111
- Testing your own domain skills remains a supported framework capability.
112
-
113
- ## A test that checks the result
114
-
115
- ```python
116
- from __future__ import annotations
117
-
118
- import subprocess
119
- import sys
120
-
121
- from pytest_skill_engineering.copilot import CopilotEval
122
-
123
-
124
- async def test_addition(copilot_eval, tmp_path):
125
- agent = CopilotEval(
126
- name="addition",
127
- model="gpt-5.6-luna",
128
- instructions="Write Python code and save the requested file.",
129
- working_directory=str(tmp_path),
130
- )
131
- result = await copilot_eval(agent, "Create calc.py with add(a, b) returning a + b.")
132
- assert result.success, result.error
133
- assert (tmp_path / "calc.py").is_file()
134
- checked = subprocess.run(
135
- [
136
- sys.executable,
137
- "-c",
138
- "from calc import add; assert add(2, 3) == 5; assert add(-2, 2) == 0",
139
- ],
140
- cwd=tmp_path,
141
- capture_output=True,
142
- text=True,
143
- timeout=10,
144
- )
145
- assert checked.returncode == 0, checked.stderr
146
- ```
147
-
148
- Use your approved isolation when executing generated code. A temporary directory
149
- is not a security sandbox.
150
-
151
- ## What stays in the framework
152
-
153
- | Capability | What it provides |
154
- | --- | --- |
155
- | `CopilotEval` and `copilot_eval` | Real SDK sessions with explicit configuration |
156
- | MCP, CLI, skills, plugins, custom agents | The interfaces and definitions under test |
157
- | Execution controls | Time, usage, request, tool, and permission controls; one attempt per execution |
158
- | Captured evidence | Configuration, calls, arguments, outputs, completion flags, errors, and usage |
159
- | Ordinary pytest checks | Consumer-owned verification and recorded properties |
160
- | `ab_run` and repetitions | Isolated working directories and repeated observations |
161
- | Structured JSON | Captured execution and ordinary pytest outcomes, without rankings or advice |
162
- | Pricing | Explicit USD estimates and recorded Copilot premium requests |
163
-
164
- A/B entries share one pytest outcome. Record side-specific checks; do not read
165
- that shared outcome as independent per-side success or causal improvement.
166
- Missing prices and incomplete evidence are recorded explicitly.
167
-
168
- ## Let your coding agent investigate
169
-
170
- Ask your existing coding agent to inspect a failed test, its saved JSON evidence,
171
- and the source. It can explain the supported cause and help fix it, without
172
- changing the test's success criteria after seeing the failure.
173
-
174
- Reading current schema-4.0 evidence needs no authentication or paid call.
175
- The framework records results; the coding agent interprets them. Subjective
176
- review is advice, not an automatic pytest verdict.
177
-
178
- Read the [full documentation](https://sbroenne.github.io/pytest-skill-engineering/).
179
-
180
- ## License
181
-
182
- MIT. Inspired by [agent-benchmark](https://github.com/mykhaliev/agent-benchmark).
@@ -1,134 +0,0 @@
1
- # pytest-skill-engineering
2
-
3
- [![PyPI version](https://img.shields.io/pypi/v/pytest-skill-engineering)](https://pypi.org/project/pytest-skill-engineering/)
4
- [![CI](https://github.com/sbroenne/pytest-skill-engineering/actions/workflows/ci.yml/badge.svg)](https://github.com/sbroenne/pytest-skill-engineering/actions/workflows/ci.yml)
5
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
6
-
7
- **A test runner for people working with coding agents.**
8
-
9
- Test whether real GitHub Copilot sessions can use your MCP servers, CLI tools,
10
- skills, system prompts, and custom agents. Write a user task, execute it through
11
- pytest, and verify the actual output with ordinary assertions.
12
-
13
- The framework runs the task and records what happened. Your existing coding agent
14
- investigates the evidence, reads the source, and helps you improve the interface.
15
- **Version 1.0 removes AI judging, report dashboards, rankings, and skill refinement.**
16
- See the [migration guide](docs/migration.md) for this breaking change.
17
-
18
- ## Why this exists
19
-
20
- Your tool can pass its own tests while Copilot chooses the wrong operation,
21
- supplies the wrong arguments, or misunderstands its descriptions. That is a
22
- different question from whether the tool implementation works.
23
-
24
- Use real task execution to test the AI-facing interface, and independent output
25
- checks to establish correctness. A completed session or a tool call by itself
26
- does not prove that the requested task succeeded.
27
-
28
- ## Quick start
29
-
30
- You need Python 3.11+, [uv](https://docs.astral.sh/uv/), and a GitHub account with
31
- Copilot access.
32
-
33
- ```powershell
34
- uv add pytest-skill-engineering
35
- gh auth login --hostname github.com
36
- uv run pytest-skill-engineering init
37
- uv run pytest-skill-engineering doctor
38
- uv run python -m pytest "tests\test_copilot_eval.py" -v
39
- ```
40
-
41
- `init` creates a Todo MCP starter test, explicit JSON evidence settings, and
42
- explicit starter-model rates in `pricing.toml`. It refuses conflicting settings
43
- or an existing starter. Live execution can consume Copilot premium requests.
44
-
45
- pytest shows ordinary test results and assertion failures. Give your coding
46
- agent `aitest-reports\results.json` and the relevant source to investigate what
47
- happened. No dashboard or second AI judgment is generated.
48
-
49
- ## What we learned by testing our own idea
50
-
51
- We evaluated a companion skill for coding agents using this framework and chose
52
- not to ship it. The comparison did not demonstrate a benefit; adding general
53
- test-writing advice was not evidence that users needed another product layer.
54
- Use the documentation, examples, and native evidence directly.
55
-
56
- The [case study](docs/use-cases/companion-skill.md) records the actual results,
57
- failures, limitations, and removal decision. Its
58
- [historical experiment](examples/skill-dogfood/) remains reproducible with a
59
- frozen test fixture, not an installable companion skill. Default sample checks
60
- are offline; live execution is explicit. The [quickstart](examples/quickstart/)
61
- is the smaller first example.
62
-
63
- Testing your own domain skills remains a supported framework capability.
64
-
65
- ## A test that checks the result
66
-
67
- ```python
68
- from __future__ import annotations
69
-
70
- import subprocess
71
- import sys
72
-
73
- from pytest_skill_engineering.copilot import CopilotEval
74
-
75
-
76
- async def test_addition(copilot_eval, tmp_path):
77
- agent = CopilotEval(
78
- name="addition",
79
- model="gpt-5.6-luna",
80
- instructions="Write Python code and save the requested file.",
81
- working_directory=str(tmp_path),
82
- )
83
- result = await copilot_eval(agent, "Create calc.py with add(a, b) returning a + b.")
84
- assert result.success, result.error
85
- assert (tmp_path / "calc.py").is_file()
86
- checked = subprocess.run(
87
- [
88
- sys.executable,
89
- "-c",
90
- "from calc import add; assert add(2, 3) == 5; assert add(-2, 2) == 0",
91
- ],
92
- cwd=tmp_path,
93
- capture_output=True,
94
- text=True,
95
- timeout=10,
96
- )
97
- assert checked.returncode == 0, checked.stderr
98
- ```
99
-
100
- Use your approved isolation when executing generated code. A temporary directory
101
- is not a security sandbox.
102
-
103
- ## What stays in the framework
104
-
105
- | Capability | What it provides |
106
- | --- | --- |
107
- | `CopilotEval` and `copilot_eval` | Real SDK sessions with explicit configuration |
108
- | MCP, CLI, skills, plugins, custom agents | The interfaces and definitions under test |
109
- | Execution controls | Time, usage, request, tool, and permission controls; one attempt per execution |
110
- | Captured evidence | Configuration, calls, arguments, outputs, completion flags, errors, and usage |
111
- | Ordinary pytest checks | Consumer-owned verification and recorded properties |
112
- | `ab_run` and repetitions | Isolated working directories and repeated observations |
113
- | Structured JSON | Captured execution and ordinary pytest outcomes, without rankings or advice |
114
- | Pricing | Explicit USD estimates and recorded Copilot premium requests |
115
-
116
- A/B entries share one pytest outcome. Record side-specific checks; do not read
117
- that shared outcome as independent per-side success or causal improvement.
118
- Missing prices and incomplete evidence are recorded explicitly.
119
-
120
- ## Let your coding agent investigate
121
-
122
- Ask your existing coding agent to inspect a failed test, its saved JSON evidence,
123
- and the source. It can explain the supported cause and help fix it, without
124
- changing the test's success criteria after seeing the failure.
125
-
126
- Reading current schema-4.0 evidence needs no authentication or paid call.
127
- The framework records results; the coding agent interprets them. Subjective
128
- review is advice, not an automatic pytest verdict.
129
-
130
- Read the [full documentation](https://sbroenne.github.io/pytest-skill-engineering/).
131
-
132
- ## License
133
-
134
- MIT. Inspired by [agent-benchmark](https://github.com/mykhaliev/agent-benchmark).