skilltest-sdk
The Python SDK for the skilltest
CLI. A thin, typed wrapper and nothing else: it runs the CLI as a subprocess and
parses the stable --format json contract into Pydantic models. Test-framework
integrations build on it — use skilltest-pytest if you
want pytest collection; use this package directly from any other Python code.
Define the whole case — skill, input, evals, an optional simulated user, mocks —
in code and pass it straight to run_skill. Everything a case YAML carries has
a typed builder, so the case and its checks live in one place:
from skilltest_sdk import TestCase, run_skill, boolean, numeric, describe_failures, assistant_text
case = TestCase(
skill="skills/greeter", # resolved relative to the working dir
input="Greet Dr. Smith, who has an appointment today.",
evals=[
boolean("the reply greets Dr. Smith by name"),
numeric("how warm is the tone", min=0, max=10, threshold=7),
],
)
report = run_skill(case)
assert report.passed, describe_failures(report)
# Mix in deterministic checks on the transcript:
assert "Dr. Smith" in assistant_text(report.runs[0].transcript)
Add user(persona=..., done_when=...) for a multi-turn case, and mocks=[...]
of stub/spy/deny/rewrite (a called / not_called eval takes the
mock object itself, or a name= you gave it). Validate a skill definition with
validate_skill("skills/greeter").
Or point at existing YAML cases
run_skill also takes a path to a test-case YAML file — or a directory of
them — so a suite that keeps cases as data works unchanged, and the
pytest plugin auto-discovers *.skilltest.yaml files
with no code at all:
report = run_skill("cases/greet.yaml") # or run_skill("cases/") for the tree
The field reference for both forms is docs/schema.md.
Tool events
Each assistant turn carries the normalized tool events the skill took (shell
commands, file edits, tool uses), lifted from oneharness's --events. Assert on
what the skill did with tool_calls (the tool_call events across a
transcript, in order); each ToolEvent has kind, name, input, output,
index:
from skilltest_sdk import TestCase, run_skill, tool_calls, boolean
case = TestCase(
skill="skills/editor",
input="Update the config and commit it.",
evals=[boolean("the change was committed")],
)
report = run_skill(case)
calls = tool_calls(report.runs[0].transcript)
assert any("git commit" in str(c.input) for c in calls)
assert not any("rm -rf" in str(c.input) for c in calls) # never destructive
Streaming (opt-in)
stream_skill takes the same case (or path) and returns a SkillStream you
iterate with async for to receive each event live, and break to
short-circuit — closing the stream tears the harness down, so a bad turn is
cut off instead of paid for in full. .report holds the final report once the
stream runs to completion:
from skilltest_sdk import stream_skill
async def guard(case):
stream = stream_skill(case)
async for ev in stream: # ev: StreamEvent — .case/.platform/.model/.turn/.event
if ev.event.name == "bash" and "rm -rf" in str(ev.event.input):
break
return stream.report
The skilltest binary is resolved from the bin= argument, the
SKILLTEST_BIN env var, or PATH; a provider override comes from provider=
or SKILLTEST_PROVIDER. A failing eval is reported (report.passed is
false), not raised; bad input raises SkilltestUsageError (CLI exit 2) and
provider problems raise SkilltestProviderError (exit 3).
The Pydantic models are generated from the golden schemas in schemas/ —
themselves generated from the CLI's own types — via just gen-contract, and a
drift gate in CI fails if anything is stale, so the models cannot diverge from
the binary. That covers both directions: the report models the SDK parses
(_report.py) and the case models the builders construct (_case.py).
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file skilltest_sdk-0.7.0.tar.gz.
File metadata
- Download URL: skilltest_sdk-0.7.0.tar.gz
- Upload date:
- Size: 62.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.27 {"installer":{"name":"uv","version":"0.11.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
47a304369329be769897a0d565faae7822f327834650d44d51788969ece45fbc
|
|
| MD5 |
f384decb45f304d9af178085681d77c0
|
|
| BLAKE2b-256 |
7dd4278d30e5275a5706a5dc7e3efd1cf0ea194555dddf94da11bf31e9ccd527
|
File details
Details for the file skilltest_sdk-0.7.0-py3-none-manylinux_2_17_x86_64.whl.
File metadata
- Download URL: skilltest_sdk-0.7.0-py3-none-manylinux_2_17_x86_64.whl
- Upload date:
- Size: 1.9 MB
- Tags: Python 3, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.27 {"installer":{"name":"uv","version":"0.11.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
970057e2266ae7053ac7104064ecf984d49b1ff6a4cd0e9f7687867add39952d
|
|
| MD5 |
0f68309feb730184f1de68c837085048
|
|
| BLAKE2b-256 |
8ffe5f84ad15a9b2127ea58417fe44b3f7ec25a73b4a990bc9afd97551f9d4f5
|
File details
Details for the file skilltest_sdk-0.7.0-py3-none-manylinux_2_17_aarch64.whl.
File metadata
- Download URL: skilltest_sdk-0.7.0-py3-none-manylinux_2_17_aarch64.whl
- Upload date:
- Size: 1.8 MB
- Tags: Python 3, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.27 {"installer":{"name":"uv","version":"0.11.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
39c6a553b77a01e72118f63fdddab33bf57bcfb91a88eda645728ce31a2a0b05
|
|
| MD5 |
e8e064fd7ecfbb884ef7da520b388e1c
|
|
| BLAKE2b-256 |
ee5ca48f3511ead35170d434daf97ce53f3decbe186a962d5d2ccbeea7643370
|
File details
Details for the file skilltest_sdk-0.7.0-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: skilltest_sdk-0.7.0-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 1.7 MB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.27 {"installer":{"name":"uv","version":"0.11.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2323313487d8e5c17fd3ec9ed352edc8716c140ecd1397a0c6cae57c74fd4e59
|
|
| MD5 |
7454581e1006537b8a363d74bdfb5991
|
|
| BLAKE2b-256 |
8e3f82707b2ad7531b4def0970eb7b1223647c310b0cbff1cff775ee82d96e67
|
File details
Details for the file skilltest_sdk-0.7.0-py3-none-macosx_10_12_x86_64.whl.
File metadata
- Download URL: skilltest_sdk-0.7.0-py3-none-macosx_10_12_x86_64.whl
- Upload date:
- Size: 1.8 MB
- Tags: Python 3, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.27 {"installer":{"name":"uv","version":"0.11.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
91948c68a35077ba859aae094b36b79b810cdbb59c96fc82439bb0af7fc990ca
|
|
| MD5 |
0071e8eb862bd6d9ba70e0c37c8a822b
|
|
| BLAKE2b-256 |
24034f3635960798f74dd6941d1bf6272f8ac36a49ab48f394040d2518cb44fe
|
File details
Details for the file skilltest_sdk-0.7.0-py3-none-any.whl.
File metadata
- Download URL: skilltest_sdk-0.7.0-py3-none-any.whl
- Upload date:
- Size: 29.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.27 {"installer":{"name":"uv","version":"0.11.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
defc01c4cc8112b1df5b1447d97b5617be086ba5906d3f9e1cd5fe62027faca3
|
|
| MD5 |
56cdbfa7848b9575f02d1c023c0f0df8
|
|
| BLAKE2b-256 |
70c52301f664cbf951424cbd564f8dcfa6c1e9eee3109b0c4b6cf70078a015e7
|