Skip to main content

verify-sdk

This skill should be used to "verify SDK behavior", "check an SDK change against the feature map", "run the SDK feature map", "maintain the SDK feature map", or "run the daily SDK map pass". It holds the maintained map of what the OpenHands SDK does in-process (agent loop, LLMs, conversations, events, condensers, skills, plugins, MCP, hooks, sub-agents, critic, security, tools, workspaces, settings, observability, ACP), the control-sdk driver its recipes use, and sdk-map (check, owners, baseline, run, report).

Source facts

Repository
OpenHands/software-agent-sdk
Last source activity
November 11, 2026 at 11:16
Detected SKILL.md language
English
Stars
1,385
Forks
773

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
100 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
verify-sdk
description
This skill should be used to "verify SDK behavior", "check an SDK change against the feature map", "run the SDK feature map", "maintain the SDK feature map", or "run the daily SDK map pass". It holds the maintained map of what the OpenHands SDK does in-process (agent loop, LLMs, conversations, events, condensers, skills, plugins, MCP, hooks, sub-agents, critic, security, tools, workspaces, settings, observability, ACP), the control-sdk driver its recipes use, and sdk-map (check, owners, baseline, run, report).
triggers
["/verify-sdk","sdk feature map"]
# Verify the OpenHands SDK in-process The "user" here is a Python program that imports `openhands.sdk` and runs an agent in its own process. This skill proves that program's view of the SDK: each recipe builds an agent with the public API, runs it, and checks what came out (state, files, events, payloads), with a scripted model where the model cannot matter and a real one where it can. It never reruns the unit tests: CI does that on every PR, and each row links them on its `Unit:` line. The agent server is a separate surface with its own skill, [`verify-agent-server`](../verify-agent-server/SKILL.md); what the server adds on top of the SDK belongs there. ## Launch There is no server. Prepare the checkout once, then start a run per scenario: ```sh uv sync --dev export PATH="$PWD/.agents/skills/verify-sdk/scripts:$PATH" export SDK_VERIFY_RUN=$(control-sdk new --field run) # scripted export SDK_VERIFY_RUN=$(control-sdk new --llm deepseek-flash --field run) # live ``` A run has its own HOME, `OH_PERSISTENCE_DIR`, conversation store, workspace and tmux server, and drops the caller's `LLM_*` and `OH_*` variables, so it never touches a developer's `~/.openhands`. Live runs read `DEEPSEEK_API_KEY` when a model is called; without it they exit 3 and report `blocked`. ## Doctor `sdk-map check` is the read-only health check: it validates the map's structure and IDs, the index counts, the baseline line, and that every path the map cites still exists. Run it first and whenever a recipe surprises you. For the environment, `uv run python -c "import openhands.sdk, openhands.tools, openhands.workspace"` must succeed. ## Drive `control-sdk` does one thing per command and prints JSON; `--check FIELD OP VALUE` asserts on it and `--field PATH` prints one value for the shell: ```sh CID=$(control-sdk conversation new --script S05/write_and_read.json --field id) control-sdk conversation send "$CID" --text "write notes.txt" --run --check execution_status eq finished control-sdk conversation events "$CID" --kind ActionEvent --check count eq 4 control-sdk program S05/reload_events --arg "$CID" --check roundtrip_equal eq true control-sdk exec --model-env -- python examples/01_standalone_sdk/01_hello_world.py ``` Conversations persist in the run, so each command resumes the one before. Programs under [`programs/`](programs/) are short scripts like the examples that print one JSON result. [references/recipes.md](references/recipes.md) explains scripts, programs, live runs and conventions. Each family file in [the map](references/feature-map/README.md) lists its sub-features and a `Driving it` section of bullets, each naming the IDs it proves and carrying `sh` blocks. Run them literally from the repository root, or let the tool replay them: ```sh sdk-map run --file S05 # one family sdk-map run --file S05 --only S05.event-base # the bullets that name these IDs sdk-map run --all --out "$SDK_VERIFY_HOME/full" # the whole map ``` A bullet passes when every block it ran exits 0; exit 3 means blocked. A block that needs a real model (a live run, `--model-env`, an example script or the integration runner) runs only with `DEEPSEEK_API_KEY` set and is skipped whole otherwise. An integration run passes only when its `results.json` shows every requested test succeeded, because the runner exits 0 on failed tests. Each block runs in its own process group, which is killed when the block ends or times out. ## Evidence `sdk-map run` writes one ledger row per sub-feature to `<out>/ledger.jsonl` and each bullet's transcript to `<out>/transcripts/`. `<out>` is a new directory under `$SDK_VERIFY_HOME` (default `$TMPDIR/sdk-verify`) unless `--out` names one. `sdk-map report --runs <out> [...]` renders the latest result per sub-feature, fail first; `--baseline <earlier run>` lists what changed since then. Proof standards: drive the public API a program uses, not internal setters or the unit tests; assert state, files and events, never a model's wording; a scripted model (`TestLLM`) through the real agent loop is the deterministic proof, a live run, example or integration run the real-model one, and a row says which it got (`scripted`, `live`, `example`, `integration`). Unreachable is `blocked` with the missing prerequisite, never a pass. ## Cleanup Recipes write into their run's workspace, under `$SDK_VERIFY_HOME` (default `$TMPDIR/sdk-verify`), never the checkout. Keep the run directories while the evidence matters; `git status` should show nothing a recipe created. ## Workflows - **Verify a change or a PR**: `sdk-map owners --changed origin/main...HEAD` maps the changed paths to the families whose `Source:` lines own them, and lists product paths no family claims (a map gap). Run those families with `sdk-map run`, with `DEEPSEEK_API_KEY` set for the live bullets, and report per [the agent-server report contract](../verify-agent-server/references/report.md). - **Run the daily pass**: follow [references/daily.md](references/daily.md): `sdk-map check`, the families changed since the `Maintenance baseline` line (`sdk-map owners` with no arguments), and nothing else: families nothing in the range touched wait for the weekly pass, and a pass with no new commits on `main` stops early. - **Maintain the map (periodic or weekly)**: follow [references/maintenance.md](references/maintenance.md): a frozen BASE/TARGET, a PR-intent ledger, a source wave, a full replay with a model key, and at most one PR of proven corrections. ## Triage what you find - **Map drift**: the map describes something the SDK no longer does by design. Fix the entry with current source and a passing recipe. - **Harness gap**: the SDK works but no recipe shows it yet. Write the program or `control-sdk` step that does; adding unit tests to the product is a separate PR. - **Product bug**: the SDK is broken. Keep the transcript, search existing issues, and file it in this repository; mark the bullet's expected result with `Known failure (reproduced <date>, #<issue>)`. Never rewrite an expected result to bless broken behavior, and never fix product code inside a pass. - **Blocked**: name the missing prerequisite (key, Docker, Chromium, account, interactive login) and the command attempted. See [references/adaptation.md](references/adaptation.md) for where these ideas come from.
View on GitHub