Skip to main content

ancha

Ancha for Python. Two parts, one import ancha:

  • Tool wrappers (no dependencies): wrap your agent's own tools once with @ancha.tool or ancha.wrap_tools, and run the agent through ancha.entry. In production nothing changes. In an Ancha test made from a production trace, each call answers as production did. See Tool wrappers.
  • A pytest plugin (pip install "ancha[pytest]"): a fresh simulated world for each test. See Test with pytest.
pip install ancha
import ancha

@ancha.tool
def lookup_order(order_id: str) -> dict: ...

ancha.entry(lambda input: run_agent(input["task"]))

The pytest plugin

pytest for Ancha: a fresh simulated world for each test, your agent run against it, and checks on what people learned and what the tools hold. It drives the ancha CLI. This development version needs the matching CLI with world capture and world record; published CLI 0.1.4 does not support run recording. ANCHA_CLI names another CLI command.

import ancha, pytest

@pytest.mark.ancha(test="ancha/tests/relay-export-bug.yaml")
@ancha.attempts(10, min_pass_rate=0.9)
def test_relay(world):
    world.start("npm start")                 # the agent gets world.env: the tools' URLs and fake credentials, ANCHA_TASK
    world.wait_until_quiet()
    assert world.people["ben"].knows("laura.beta_on")
    assert world.slack.messages(to="laura", in_thread_of="$laura_report", from_="$slack_bot")
    assert not world.people["laura"].knows("ben.root_cause")
  • @pytest.mark.ancha(test=…, scene=…, world=…, on="local"|"cloud", seed=…, ttl=…) says what the world fixture starts (ancha world up). Without it, the one scene ancha.yaml names.
  • world.env, world.task; world.start(command), world.wait_until_quiet(timeout), world.log(), world.stop().
  • world.check() applies the test's own checks; world.check({...}) applies check objects (the kinds in ancha docs scenes). A report is truthy when every check passed; report.failures has expected and actual.
  • world.people[ref].knows(fact), .decided(decision, option); world.slack.messages(to=, in_=, in_thread_of=, from_=, text_contains=, fact=).
  • world.state(), world.trace(); world.fresh() for another world; the fixture removes its world (ancha world down).
  • @ancha.attempts(n, min_pass_rate) runs the test in n fresh worlds and passes when enough of them do.

An evaluated check that fails returns a false CheckReport; report.failures explains the expected and actual values. A check that cannot be evaluated raises ancha.AnchaError instead. For example, a knows check naming an unknown person raises an error with code == "USAGE" and a message naming the invalid reference. Correct the test definition; this error is not a verdict on the agent. The people and Slack helpers use the same check path and can raise the same error. CLI failures also raise AnchaError, retaining the CLI's code, message and optional hint.

Worlds start locally by default, including after ancha login. Run pytest --on cloud to put worlds in your hosted workspace; pytest and the agent still run on your machine. --on local forces local worlds. The pytest option overrides the marker's on="local" or on="cloud"; without either, the CLI's normal world selection applies. An explicit server URL can also select a world server. Never give the agent the test files or the checks.

Recorded runs

While the plugin is enabled, each executed pytest item creates one local run under .ancha/runs/, with source: pytest and target: local. This includes tests without a world, parameterized cases and skipped tests. Collection alone creates no records. Disable the plugin with -p no:ancha for suites that should not record. Run files stay local even when worlds run in the cloud; uploading pytest records is not supported.

ancha --local runs list --json
ancha --local runs show <run-id> --json
ancha --local explain <run-id> --json

Pytest assertions decide the test outcome. A deliberately false world.check() remains evidence and does not fail a passing negative assertion. Records preserve setup, call and teardown outcomes separately. Skipped and expected-failure cases are ungraded; setup, capture and cleanup failures are invalid, not failed agent answers. @ancha.attempts records each invocation and its fresh world under the same run, including failed attempts when the overall pass-rate threshold is met. The requested repetition count is recorded before execution. Reports keep every requested attempt in the pass-rate denominator, including invalid, skipped and missing attempts; all-k requires all requested attempts to finish validly and pass. Thresholds use exact integer counts. An old baseline without verified requested counts must be regenerated before comparison.

The plugin stops its agent, captures a coherent world observation, then removes the world. This observation is not a sealed managed-trial capture. Capture failures remain visible and cleanup is still attempted. Recording failures are reported and make an otherwise successful pytest session fail.

Parameter values in test IDs are replaced by a hash. Records omit environment values, raw exception messages, captured pytest output and agent logs. Known credentials are redacted from evidence; keep .ancha/ private and out of version control. Abrupt termination such as SIGKILL cannot finish a record or guarantee cleanup; world TTLs still apply.

Metadata

Release files for ancha 0.1.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 ancha 0.1.0
File Size Uploaded Provenance Actions
ancha-0.1.0.tar.gz 24.4 kB Without provenance Details for ancha-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for ancha 0.1.0
File Interpreter ABI Platform Actions
ancha-0.1.0-py3-none-any.whl Python 3 none any Details for ancha-0.1.0-py3-none-any.whl

Total release size: 41.5 kB

Release files / ancha-0.1.0.tar.gz

Download URL ancha-0.1.0.tar.gz
Size 24.4 kB
Tags Source
SHA-256 checksum
How to use checksums
18e7ee2e5ca93db1787e252ede506f1d705025a4d33cd682f93e037dec4a3730
BLAKE2b-256 checksum
How to use checksums
5d1a00326a1ab7de41ae57401491798710723eff60e02d97bd4abada792a333c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.3

Release files / ancha-0.1.0-py3-none-any.whl

Download URL ancha-0.1.0-py3-none-any.whl
Size 17.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e53378faa98dfc1e299b17a70ca48609d8946e59f99d260fe40b6e627e78e54d
BLAKE2b-256 checksum
How to use checksums
4dd76503314b57d3b429c1476680b5af9d2eba1f94943ee45b394c7bfaf21be3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.3

Security for ancha 0.1.0

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

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

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

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