Skip to main content

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).

Metadata

Release files for skilltest-sdk 0.12.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for skilltest-sdk 0.12.0
File Size Uploaded
skilltest_sdk-0.12.0.tar.gz 41.9 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for skilltest-sdk 0.12.0
File
skilltest_sdk-0.12.0-py3-none-manylinux_2_17_x86_64.whl Python 3 none Linux glibc 2.17+ x86-64 Details
skilltest_sdk-0.12.0-py3-none-manylinux_2_17_aarch64.whl Python 3 none Linux glibc 2.17+ ARM64 Details
skilltest_sdk-0.12.0-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details
skilltest_sdk-0.12.0-py3-none-macosx_10_12_x86_64.whl Python 3 none macOS 10.12+ x86-64 Details
skilltest_sdk-0.12.0-py3-none-any.whl Python 3 none any Details

Total release size: 7.1 MB

Release files / skilltest_sdk-0.12.0.tar.gz

Download URL skilltest_sdk-0.12.0.tar.gz
Size 41.9 kB
Tags Source
SHA-256 checksum
How to use checksums
3cff92ef9b8f18081bbb3d4584caa2e883fd552868a1cd29fdff608b0a829662
BLAKE2b-256 checksum
How to use checksums
41f17002ec55441e408355cf7f9e9b361a589233f18b90180bd6d2e61ee087cf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.22 {"installer":{"name":"uv","version":"0.12.22","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.12.0-py3-none-manylinux_2_17_x86_64.whl

Download URL skilltest_sdk-0.12.0-py3-none-manylinux_2_17_x86_64.whl
Size 1.9 MB
Tags Linux glibc 2.17+ x86-64 Python 3
SHA-256 checksum
How to use checksums
5d11a87b185fbf8de44b461fa62dfcbfd15958c4525206aed52ef7b12dddcbbd
BLAKE2b-256 checksum
How to use checksums
212cc3fab2103cb7fb29f3ab9a94dad4f71adc807e0d469992653c17865485dd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.22 {"installer":{"name":"uv","version":"0.12.22","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.12.0-py3-none-manylinux_2_17_aarch64.whl

Download URL skilltest_sdk-0.12.0-py3-none-manylinux_2_17_aarch64.whl
Size 1.8 MB
Tags Linux glibc 2.17+ ARM64 Python 3
SHA-256 checksum
How to use checksums
4c4c858208ccb4dd111247382da2ec8218d361c9095c7918b4e5af1bbfdac155
BLAKE2b-256 checksum
How to use checksums
8aad0c42d2159443ee711a212d6e9d25a19f446e8108d32b5ba88d1607263a3a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.22 {"installer":{"name":"uv","version":"0.12.22","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.12.0-py3-none-macosx_11_0_arm64.whl

Download URL skilltest_sdk-0.12.0-py3-none-macosx_11_0_arm64.whl
Size 1.6 MB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
0b1b9f665a27000bbbff1c003a3289a8876c87a5fd146f8c0dfd52cd96aacd42
BLAKE2b-256 checksum
How to use checksums
237a6d45ff1a5f624bdc1584e9dac83fc6dd790abfa6d5c29c7e89e9e1dd76e5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.22 {"installer":{"name":"uv","version":"0.12.22","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.12.0-py3-none-macosx_10_12_x86_64.whl

Download URL skilltest_sdk-0.12.0-py3-none-macosx_10_12_x86_64.whl
Size 1.7 MB
Tags Python 3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
1bb7bc69914004aea0d0a8da09ff6f33f40348527a31642137f0279fc97195c6
BLAKE2b-256 checksum
How to use checksums
4cdbd9684922a0d4ca15c0cbe7daaaf062abfadfc1f0d0686fab4750c769e506
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.22 {"installer":{"name":"uv","version":"0.12.22","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.12.0-py3-none-any.whl

Download URL skilltest_sdk-0.12.0-py3-none-any.whl
Size 35.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
08c43f2d267a378bb3e2e539db9022eb2ec5aaea1ead8ac17d3c0e6b92ae640d
BLAKE2b-256 checksum
How to use checksums
782465678208752680e3d9c4f823b8292c1c293689ecbf8efbf2cc6a16e52d91
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.22 {"installer":{"name":"uv","version":"0.12.22","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 history Release notifications | RSS feed

0.13.0

8 release files

This release

0.12.0 This release

6 release files

0.11.2

6 release files

0.11.1

6 release files

0.11.0

6 release files

0.10.3

6 release files

0.10.2

6 release files

0.10.1

6 release files

0.9.0

6 release files

0.8.0

6 release files

0.7.0

6 release files

0.6.0

6 release files

0.5.0

6 release files

0.4.0

6 release files

0.3.0

6 release files

0.2.2

6 release files

0.2.1

6 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page