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").
A stub can answer successive calls differently: pass responses instead of
output, and the n-th call it intercepts in a run gets the n-th item, with
the last item repeating. So
stub("jobctl status", responses=["queued", {"output": "failed", "exit_code": 1}, "passed"])
answers failed on its second call and passed on every call after that.
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 default provider drives oneharness,
which installs with this package (the oneharness-cli dependency) — no separate
step. The SDK points the CLI at it via SKILLTEST_ONEHARNESS_BIN; set that
variable, or a config provider.bin, to use a different oneharness.
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).
Full run settings are available through YAML, derived environment variables,
CLI --set, and generated SDK config overrides. See the
configuration contract for precedence,
evaluator role inheritance, value grammar and path resolution.
Metadata
Release files for skilltest-sdk 0.13.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| skilltest_sdk-0.13.0.tar.gz | 55.8 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| skilltest_sdk-0.13.0-py3-none-win_arm64.whl | Python 3 | none | Windows ARM64 | Details |
| skilltest_sdk-0.13.0-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details |
| skilltest_sdk-0.13.0-py3-none-manylinux_2_17_x86_64.whl | Python 3 | none | Linux glibc 2.17+ x86-64 | Details |
| skilltest_sdk-0.13.0-py3-none-manylinux_2_17_aarch64.whl | Python 3 | none | Linux glibc 2.17+ ARM64 | Details |
| skilltest_sdk-0.13.0-py3-none-macosx_11_0_arm64.whl | Python 3 | none | macOS 11.0+ ARM64 | Details |
| skilltest_sdk-0.13.0-py3-none-macosx_10_12_x86_64.whl | Python 3 | none | macOS 10.12+ x86-64 | Details |
| skilltest_sdk-0.13.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 14.1 MB
Release files / skilltest_sdk-0.13.0.tar.gz
| Download URL | skilltest_sdk-0.13.0.tar.gz |
|---|---|
| Size | 55.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2b3ad55ffb93f650be8559be73c3b15c21bfa5992e61ab025dbefb75115f378d
|
|
BLAKE2b-256 checksum How to use checksums |
b2c8682b3123b4503d14cd184f145cffa66f165e7b81375133fc31579b6dac30
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","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}
|
Release files / skilltest_sdk-0.13.0-py3-none-win_arm64.whl
| Download URL | skilltest_sdk-0.13.0-py3-none-win_arm64.whl |
|---|---|
| Size | 2.1 MB |
| Tags | Python 3 Windows ARM64 |
|
SHA-256 checksum How to use checksums |
0677ad5fa57eaa6375a06afc0078a6c833f0e7910d33a6748bd51d9a0705c61b
|
|
BLAKE2b-256 checksum How to use checksums |
d650c1ed64c7a4cf41e609cd6cefe270ff9d8cab7969c6303262fd92e56900d7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","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}
|
Release files / skilltest_sdk-0.13.0-py3-none-win_amd64.whl
| Download URL | skilltest_sdk-0.13.0-py3-none-win_amd64.whl |
|---|---|
| Size | 2.3 MB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
92796afae6d0ee24b54a0d4b2a4d5e65d0a20e80b93d12c91ec669945f239e20
|
|
BLAKE2b-256 checksum How to use checksums |
add914540cd2979d2f89ee52181e2dff3b68039a8d2b469378809e10730efc34
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","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}
|
Release files / skilltest_sdk-0.13.0-py3-none-manylinux_2_17_x86_64.whl
| Download URL | skilltest_sdk-0.13.0-py3-none-manylinux_2_17_x86_64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | Linux glibc 2.17+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
236a48b15bbd3a0eb06711a22817fbabadfd6b9f57c7ccaa55feea14233acfba
|
|
BLAKE2b-256 checksum How to use checksums |
940e1925bd312042e9fffdae08c038319e8f36954a0df895ad7b507488ffdb11
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","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}
|
Release files / skilltest_sdk-0.13.0-py3-none-manylinux_2_17_aarch64.whl
| Download URL | skilltest_sdk-0.13.0-py3-none-manylinux_2_17_aarch64.whl |
|---|---|
| Size | 2.4 MB |
| Tags | Linux glibc 2.17+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
4d520ce7d18f109a6a2012259e1a51c52baf0f39af99adee66d457e96897ef8b
|
|
BLAKE2b-256 checksum How to use checksums |
c8facc5cc2d9ca4b485f2f7ce5f888f84fd19609c26829938e5957998679e128
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","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}
|
Release files / skilltest_sdk-0.13.0-py3-none-macosx_11_0_arm64.whl
| Download URL | skilltest_sdk-0.13.0-py3-none-macosx_11_0_arm64.whl |
|---|---|
| Size | 2.3 MB |
| Tags | Python 3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
ae1528f8cc59f99f6792d93581f5d43bd02051adca5596671a71cbefbbd119e2
|
|
BLAKE2b-256 checksum How to use checksums |
aef2142c941e3308599182b16cdccc68022db0e3cc5ba4945468926d35347df8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","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}
|
Release files / skilltest_sdk-0.13.0-py3-none-macosx_10_12_x86_64.whl
| Download URL | skilltest_sdk-0.13.0-py3-none-macosx_10_12_x86_64.whl |
|---|---|
| Size | 2.4 MB |
| Tags | Python 3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
44951aeefe18ca48fc7f2c779a559ad7c0fbd4119bd1a5c0a17ef6e8b6e2fff6
|
|
BLAKE2b-256 checksum How to use checksums |
4ddd934b3b3140584db3b8829ee2b49d803d033ece1f2067e56b28d95d9eb2af
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","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}
|
Release files / skilltest_sdk-0.13.0-py3-none-any.whl
| Download URL | skilltest_sdk-0.13.0-py3-none-any.whl |
|---|---|
| Size | 43.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7cb8bf752bc887324cf9f17f38c2ebd7507b7ec692d2911fcf9d7fe039c1a288
|
|
BLAKE2b-256 checksum How to use checksums |
ebb15e1d92aa4a233a61af224e21c3ec925c5bf4529baff6e49ce998a915fe02
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","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}
|