This release is a pre-release and may not be stable for production use.
Yanxu Harness
English | 简体中文
An embeddable Python agent runtime with durable execution, tool approvals, and recovery backed by operation evidence.
Build agents inside your application while keeping control of permissions, data, and business operations. Yanxu tracks execution progress, settles tool calls individually, and separates the full conversation from the context sent to the model. The base package has zero third-party runtime dependencies.
Alpha · Python 3.10+ · MIT. The release target is
0.4.0a1. APIs and persisted formats may change; see the public contract and verification record.
Quickstart · Scope and limits · Documentation · Report a bug
Why Yanxu?
An agent can stop after a tool has changed your data but before its result has been saved. Continuing that run requires knowing what happened outside the model conversation.
Yanxu makes those execution boundaries explicit:
- Recover with evidence. Reuse confirmed tool results. Pause for reconciliation when an operation's outcome cannot be proven.
- Keep business authority in your application. The host establishes identity, grants permissions, records approvals, and supplies tools. Model output and skill text cannot grant authority.
- Understand each run. Inspect persisted progress, waiting reasons, tool evidence, context decisions, and usage through a read-only API or CLI.
- Embed in an existing Python stack. Inject your provider, tools, persistence, and policy through explicit interfaces. SQLite reference implementations are included.
Useful for application agents that edit business data, wait for approval, or need to continue after a process restart. Bring your own tools and workspace when building a coding agent.
Quickstart
Install from PyPI
python -m pip install 'yanxu-harness==0.4.0a1'
This is an alpha pre-release; specify the version or use --pre. During release preparation, use the source or local wheel until the package-index upload completes. Optional adapters can be installed with python -m pip install 'yanxu-harness[yaml,pydantic,mcp]==0.4.0a1'.
Install from source
git clone https://github.com/SZWzz/yanxu-harness.git
cd yanxu-harness
python -m venv .venv
source .venv/bin/activate
python -m pip install .
On Windows, activate with .venv\Scripts\Activate.ps1 in PowerShell. Optional adapters: python -m pip install '.[yaml,pydantic]' adds local SKILL.md front-matter parsing and Pydantic tool argument models.
See recovery work — no API key needed
python examples/01_basic_dialogue.py
python examples/07_partial_batch_recovery.py
The recovery example starts a real child process, completes tool A, crashes inside tool B, and leaves tool C unstarted. A fresh harness reads the saved state and operation ledger. It waits for evidence about B, then finishes C after a host reconciler supplies that evidence.
Output, abridged:
step: crash
A settled and was committed; B is open; C never ran
step: recover-barrier
resumed, then stopped: B is unproven, so A was not re-run and C was not started
step: evidence
step: finish
A replayed, B proven by evidence, C run exactly once; the model saw all three
OK: a partially settled batch was recovered call by call
The model responses and the reconciler's sample evidence are scripted. The harness, tools, SQLite stores, process failure, and recovery are real; this demonstrates execution behavior, not model quality. In an application, the reconciler must obtain evidence from the business system. Temporary state is cleaned up after the example.
Optional MCP client adapter
MCP (Tools, stdio, Streamable HTTP) lives in the mcp extra and is never imported by
a base install:
python -m pip install '.[mcp]'
The first release pins protocol revisions 2025-11-25 and 2026-07-28 and SDK
mcp==2.3.0, with real-service tests across all four cells. MCP tools run through the
existing ToolDefinition → core_tool → ToolGateway → single operation ledger, and
one admission sends at most one remote tools/call. See the
MCP client guide (Chinese), the
MCP00 ADR and the
delivery report.
Optional extension packs
A host can assemble an explicitly bound pack of tools, skills and (optionally) MCP tools without adding a second loop, gateway or operation ledger:
plan = plan_extensions(manifests=[document], factories={"example.pack": host_factory},
bindings=[host_binding], local_tools=host_tools)
async with open_extensions(plan) as deployment:
gateway = ToolGateway(registry=deployment.registry, policy=host_policy,
approvals=host_approvals, backend=host_backend)
harness = deployment.bind_harness(
stream_fn=stream_fn, gateway_bindings=GatewayBindings(gateway=gateway, context=context),
persistence=persistence,
)
Manifests are bounded data, not authority: they cannot name a Python path, grant a tool or contain a credential. The host supplies the factory and the binding; assembly validates every contribution, publishes one frozen registry/skill view atomically, and rolls back a failed batch. A revoked/closed deployment refuses old tool, skill and harness references before a new intent. A changed extension version, binding revision or scope is refused on resume by the existing arrangement comparison; the same logical deployment reconstructs the same digest in a new process. Standard-library packs and the optional MCP helper are both supported. See the extension guide (Chinese), the ADR and the E0–E3 delivery report.
Install a local release wheel
If you have the verified local artifact bundle, install its wheel and check the version:
python -m pip install /path/to/yanxu_harness-0.4.0a1-py3-none-any.whl
python -c "import yanxu_harness; print(yanxu_harness.__version__)"
The bundle includes SHA256SUMS and verification reports. The base wheel needs no third-party runtime dependencies; optional adapters require their corresponding extras.
Connect your model
Set YANXU_BASE_URL to your OpenAI-compatible endpoint's base URL, YANXU_MODEL to its model name, and YANXU_API_KEY to your credential in your application's environment. This example makes a real network request:
import asyncio
import os
import uuid
from yanxu_harness.providers import (
CoreStreamBridge,
OpenAICompatibleProvider,
ProviderConfig,
SecretReference,
)
from yanxu_harness.runtime import (
DefaultHarness,
Principal,
RunContext,
RunIdentity,
RunRequest,
)
from yanxu_harness.storage import SqlitePersistence
async def main():
provider = OpenAICompatibleProvider(
ProviderConfig(
model=os.environ["YANXU_MODEL"],
base_url=os.environ["YANXU_BASE_URL"],
api_key=SecretReference("model-key"),
),
secrets={"model-key": os.environ["YANXU_API_KEY"]},
)
store = SqlitePersistence("runs.db")
try:
harness = DefaultHarness(
stream_fn=CoreStreamBridge(provider),
persistence=store,
system_prompt="Be concise and explain the basis for your answer.",
max_runtime_seconds=60,
)
context = RunContext(
identity=RunIdentity(
namespace="demo", session_id="s1",
run_id=uuid.uuid4().hex, attempt_id="a1",
),
principal=Principal(subject="local-user"),
)
outcome = await harness.start(
RunRequest(prompt="What makes an agent recoverable?", max_turns=3),
context,
)
print(outcome.status.value, outcome.stop_code)
print(outcome.final_text)
finally:
store.close()
asyncio.run(main())
This minimal run has no tools. Add tools through ToolDefinition → ToolGateway → core_tool; the approved-edit example shows the complete wiring. The real-model edit example uses the same deployment with a configured endpoint.
What is implemented
| Capability | What it gives your application |
|---|---|
| Explicit execution state | A pure state reducer and one Runner; versioned snapshots and commits before model/tool dispatch |
| Tool execution and recovery | Bounded concurrency, per-call settlement, stable operation identities, receipt reuse, and reconciliation barriers |
| Durable approvals | Preview and approval bindings tied to arguments, target versions, policy, and expiry; pause and resume across processes |
| Managed context | Separate transcript and request view, dependency-aware history selection, request budgets, output references, and optional bounded summaries |
| Provider integration | Neutral streaming protocol, OpenAI-compatible transport, cancellation, and host-supplied credentials |
| Skills and decision routing | On-demand skill metadata/body/resources; optional rule or model routers, within host permissions |
| Durable task orchestration | Persistent inboxes, bounded local scheduling, task deadlines, shared budgets, and recoverable parent/child tasks |
| Optional MCP tools | stdio and Streamable HTTP clients, explicit host bindings, and recovery through the same tool gateway and operation ledger |
| Extension packs | Atomic tools/skills/MCP composition, explicit host bindings, frozen deployment identity, revocation, and real recovery |
| Read-only diagnostics | JSON/Markdown reports with provenance, waiting reasons, tool evidence, stage timings, and usage coverage |
| Offline task evaluation | Frozen cases, independent verifiers, failure injection, and comparison of matching cases |
How execution works
The core decides the next action; the Runner performs it and returns an input event. Durable execution through DefaultHarness commits progress before dispatching external work.
flowchart TD
Host["Your Python application"] --> Runtime["DefaultHarness: start / resume / cancel / state"]
Runtime --> Core["Pure reducer: state + event → transition"]
Core --> Commit["Commit execution progress"]
Commit --> Store[("Run state and transcript")]
Commit --> Runner["Runner performs the next action"]
Runner --> Context["Prepare context and request facts"]
Context --> Core
Runner --> Model["Model provider"]
Runner --> Gateway["ToolGateway: policy, approval, operation evidence"]
Gateway --> Tools["Host tools and business data"]
Model --> Core
Gateway --> Core
The full transcript, the model's request view, and operation receipts have distinct roles. The Gateway or delegated host owns operation evidence; a saved conversation or a model's claim of completion cannot substitute for it. See the current architecture and recovery guide.
Pause, approve, and resume
Run the complete offline approval demo:
python examples/05_durable_approved_edit.py
To inspect a paused run yourself, choose a fresh state directory and start it separately:
python examples/05_durable_approved_edit.py --state build/approval-demo start --task "Update the welcome text"
python examples/05_durable_approved_edit.py --state build/approval-demo status --run edit-1
The output includes the preview and approval binding key. Use that key with the example's approve command, then its resume command; see the example's instructions. Approval is a trusted host operation. Passing {"approved": true} to resume() does not authorize a write.
Run outcomes distinguish completed, suspended, usage_limited, cancelled, failed, and rejected. Recovery checks the stored configuration baseline; instructions, tools, or policy drift can refuse a resume before dispatch. See the lifecycle contract.
Inspect and evaluate
Inspect the saved approval demo without executing tools or resuming the run:
python -m yanxu_harness.diagnostics inspect \
--runs build/approval-demo/runs.db \
--operations build/approval-demo/operations.db \
--namespace example-project --session session-1 --run-id edit-1 --format markdown
See a diagnostic report for a partially recovered batch. Reports distinguish actual, estimated, and unknown measurements; missing usage is not counted as zero.
Run the frozen offline task suite:
python -m yanxu_harness.evals run --root build/evals --out build/eval-report
python -m yanxu_harness.evals --help
The suite exercises defect location, implementation fixes, diff review, approval, recovery, refusal, and context cancellation. Independent verifiers check results. These scripted-model cases measure harness behavior; they do not establish real-model task performance. See the evaluation samples and comparison.
Scope and current limits
- Alpha compatibility: persisted formats are versioned. Unknown versions and older states that lack evidence required for safe recovery are refused.
- External effects: arbitrary tools and hooks do not get a blanket exactly-once guarantee. Reliable recovery needs durable receipts, idempotency, or host-provided business evidence; an uncertain outcome remains blocked.
- Host integration: the host owns authentication, permission grants, business transactions, and sandboxing. A custom operation ledger must implement the recovery capabilities the harness needs.
- Task deployment: durable inboxes, local scheduling, and parent/child tasks are implemented as libraries driven explicitly by the host. Distributed worker pools, a remote subagent protocol and production sandboxing are not provided. Extensions are a library-level, host-explicit mechanism: there is no plugin marketplace, arbitrary plugin-directory scan, remote install, dependency solver or capability sandbox.
- Evidence: model quality and platform support must be checked against the recorded version and environment. See verification, support, and the diagnostics/evaluation delivery report.
Examples and documentation
| Start here | Purpose |
|---|---|
| Basic dialogue | One model turn, streaming events, and a transcript |
| Approved data edit | Tool definitions, policy, and approval |
| Cross-process recovery | Reopen persisted execution in another process |
| Tools, skills, and decisions | Combine the optional layers |
| Durable approved edit | Preview → pause → approve → resume |
| Managed-context edit | Run a coding task with a bounded request view |
| Partial-batch recovery | Crash → reconcile → finish the remaining work |
| Durable input redelivery | Persist inputs and consume them once across recovery |
| Fair task scheduling | Schedule bounded local work and release slots while waiting |
| Parent/child recovery | Recover child results and continue the parent across processes |
| MCP over stdio | Discover and call a real local MCP server; requires the mcp extra |
| MCP HTTP recovery | Reconcile an uncertain remote write; requires the mcp extra |
| Extension tools and skills | Assemble a standard-library pack and run one real tool call |
| Extension MCP recovery | Pause on an MCP write, restart and resume; requires the mcp extra |
Use the documentation index for integration guides, current architecture, release evidence, and historical implementation/review records. Start with the public API contract, adapter guide, and recovery semantics.
Contributing
Integration feedback, small runnable failure cases, adapter improvements, and documentation fixes are useful contributions. Include expected behavior and the relevant environment; remove credentials and private data. For security reports, follow SECURITY.md.
python -m pip install -e '.[dev,yaml,pydantic]'
python -m pytest -q tests
python scripts/ci_check.py --prepare-wheelhouse build-wheelhouse
python scripts/ci_check.py --offline --wheelhouse build-wheelhouse
The wheelhouse preparation step uses the network; the subsequent gate installs and verifies artifacts offline. See CONTRIBUTING.md for the full workflow.
License and acknowledgements
MIT. The core's message types, event vocabulary, and parts of its loop behavior derive from pi-agent-core. Yanxu adds an explicit execution state machine, one Runner, durable commit boundaries, and its application integration layers. Attribution and the upstream MIT license are retained in THIRD_PARTY_NOTICES.md and LICENSES/.
Metadata
Release files for yanxu-harness 0.4.0a1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| yanxu_harness-0.4.0a1.tar.gz | 1.5 MB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| yanxu_harness-0.4.0a1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 2.1 MB
Release files / yanxu_harness-0.4.0a1.tar.gz
| Download URL | yanxu_harness-0.4.0a1.tar.gz |
|---|---|
| Size | 1.5 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
882f4b34c0ab66d7905f58d26c26cce5c1bff4c28b5f321ab2ce7dde9fc7a589
|
|
BLAKE2b-256 checksum How to use checksums |
9cb27a8b27c3f2a25360ba97f4c3bde9ac355ef145c5baef20527ddf60fbb213
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.
Transparency logRelease files / yanxu_harness-0.4.0a1-py3-none-any.whl
| Download URL | yanxu_harness-0.4.0a1-py3-none-any.whl |
|---|---|
| Size | 607.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
756dc3191ef16b564d7c183c73c35bbf42357992b606b997a4c80bb300187328
|
|
BLAKE2b-256 checksum How to use checksums |
61538d0821c00a765aaedfed069c660ffcf95a12fc6df4213b45e29f33df61b9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.
Transparency logSecurity for yanxu-harness 0.4.0a1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for yanxu_harness-0.4.0a1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.