Skip to main content

Meristem

The in-run agent harness. Meristem supports and guides agent execution through explicit dependency DAGs and received ordered plans. Inspired by espalier-trained growth, it provides structure for execution, not model-weight training. It applies the decisions it is given; it does not store, decide, serve or connect on its own.

Meristem is distributed as agent-utilities and imported as agent_utilities. Repository, package, CLI and API identifiers remain unchanged.

PyPI - Version Build

Version: 4.0.0

What it contains

Module What it does inside one run
agent_utilities.graph Applies a received ordered plan or dependency DAG. It enforces task slots and shared budgets, and emits ordered execution events.
agent_utilities.rlm Runs recursive model queries with shared request and tool limits and bounded concurrent model requests.
agent_utilities.harness.edit_engine Parses model-proposed edits (search/replace blocks, unified diffs), applies them with graduated matching, and re-prompts on malformed or unmatched edits.
agent_utilities.harness.contract_validator Checks a tool call's pre-conditions and its output's schema and verifier.
agent_utilities.harness.constraint_engine Enforces hierarchical constraints on tool calls (prompt, tool description, middleware, implementation) and escalates repeated violations.
agent_utilities.harness.quality_gates The pre-emit gate: antipattern detection, a preflight checklist and a multi-dimensional critique, in warn or block mode.
agent_utilities.runtime The developer workspace: typed actions and observations, a stateful shell, local and container backends, a policy gate it is given, and the browser and computer-use tier ports.
agent_utilities.host_ports The protocols the host fills: native and remote toolsets, tool clients, outbound credentials, delegated identity, the fleet catalog and the session keepalive. Without a host every binding port fails closed.
agent_utilities.core.paths Resolves the platform config, data, cache and log directories (ARBORA_CONFIG_DIR, XDG).

Where everything else lives

  • Medulla: facts, records, vocabulary, storage and queries, ingest, retrieval, reasoning, memory, decisions, and learning (evaluation, harness evolution, reward and trace records).
  • arbora: admission, auth, served operations (MCP, REST, A2A), messaging front-ends, the registry and the multiplexer. arbora hosts this harness and registers the host_ports providers.
  • Scion SDK: connector contracts, transports, the A2A protocol library and connector helpers.

Install and use

pip install agent-utilities
from agent_utilities.runtime import create_workspace
from agent_utilities.runtime.events import CmdRunAction, TestRunAction

async with create_workspace(run_id="r1", prefer_docker=False) as ws:
    await ws.act(CmdRunAction(command="git status"))
    result = await ws.act(TestRunAction(selector="tests"))

Run measurements

The graph run result and terminal event include metrics from a monotonic client clock: run_elapsed_ms and ordered model_requests with client_request_elapsed_ms, outcome, model/provider attribution and validated per-response token counts. The sample list is bounded; coverage: "partial" means some observed requests were omitted. Failed requests have no invented token counts. These measurements are emitted through the host event sink for shared backend consumption; AU stores no session totals.

Run time includes planning, tools and retries. Client request time includes transport and provider waiting. Neither is provider generation time, and neither is used to derive generation TPS. Provider queue wait, generation duration and TTFT are absent unless a future adapter measures and identifies them explicitly.

Received dependency plans

A host can pass RunPlan(dependency_plan=DependencyPlan(...)) to the same run or iterate_run entry point. Do not also set serial steps. DependencyPlan contains ordered RunTask(task_id, prompt, depends_on) values, an output_task_id, a max_concurrency task cap and an optional plan_id. The host gets the plan from EG and admits it through Arbora. AU does not turn free text into a plan or authorize a task.

A completed task frees a slot at once. A dependent task can start while an unrelated task still runs. Every prerequisite must succeed. Each task gets a fresh history with only its direct dependency outputs. The output task must be the sole sink. Failed or stopped plans never return a partial child answer as a completed parent result.

The trusted host can pass prior measured consumption as RunPlan.initial_usage (a pydantic_ai.usage.RunUsage) and initial_elapsed_seconds. Both default to zero. Keep RunBudget at its original bounds; do not subtract this usage in the host or add it to AU's result again. AU snapshots the reported request, tool and token counters. It includes them once in terminal aggregate usage. It subtracts the elapsed time once from the execution deadline. Exhausted initial model bounds stop before model binding or child dispatch. Prior tool usage above the tool limit also stops. At the exact tool limit, model-only answers remain allowed, but additional tools do not. Invalid counters or time fail closed. Model proposals, request metadata and scaffold updates cannot set this host-only input. Unreported token usage remains zero, not an estimate.

If measured host work fails before a plan can return, the decision provider can raise RunPlanFailure(error, initial_usage=usage, initial_elapsed_seconds=elapsed). AU validates the same inputs and includes the counters once in the terminal event and result. It preserves the original failure or cancellation, without dispatching work or replacing a budget. Do not wrap a provider failure without a reported usage ledger or add these counters again in the host.

run() returns a failed RunResult. AgentRunExecutor.execute_agent() raises RunFailed, a RuntimeError subclass with the same error message. Its immutable result snapshot retains that aggregate receipt, with run_id and usage properties. The allowed host facade agent_utilities.runtime lazily re-exports the same run executor, plans, tasks, bounds, stop rule and failure types. Hosts must check the exception type and expected run identity before copying these counters. Keep the outcome failed; do not publish a partial answer or add the counters again. Successful and stopped returns, cancellation, and empty unreported ledgers keep their existing behavior.

Request and tool reservations are shared across tasks and validation retries. An unspecified parallel tool limit uses a finite fallback of fifty calls. Token limits use reported usage, including fallback attempts. In-flight token use is not known in advance. RunBudget.max_concurrent_requests also caps model requests (fallback: four); the task cap can be lower. On cancellation, AU drains child coroutines before invoking host-scope exit. Hosts own the cancellation safety of their asynchronous scope exits; repeated cancellation can interrupt that host cleanup. Host tools also own external work that cannot stop with their coroutine. No elapsed cleanup bound is promised for handlers that do not cooperate.

RLMConfig.max_concurrent_requests and tool_calls_limit bound recursive model calls and tool fan-out (fallbacks: four and fifty). A parent releases its model-request slot before waiting for a child, including at capacity one. The parent model still chooses its next tool batch after the current batch returns. That model-choice boundary is not a declared dependency DAG.

Public lifecycle events have a per-run sequence and stable event_id. Task events carry task_id, parent_run_id, plan_id and depends_on. They report execution state, not private model reasoning. Arbora owns their safe replay projection and access checks.

A DAG driver owns the deadline after setup, using the same absolute deadline. A paused event reader cannot delay task dispatch or timeout cleanup. Consumers must finish or close the iterator. Pausing can delay the parent terminal event and host-scope release, even after all task work has stopped. Request handlers finish asynchronous cleanup before cancellation returns, including nested runs.

Develop

uv sync --group dev
uv run ruff check . && uv run ruff format --check .
uv run mypy agent_utilities
uv run pytest -q

License

MIT, see LICENSE.

Metadata

Release files for meristem 4.0.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 meristem 4.0.0
File Size Uploaded Provenance
meristem-4.0.0.tar.gz 130.8 kB Without provenance Details

Built distribution (wheel)

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

Total release size: 225.3 kB

Release files / meristem-4.0.0.tar.gz

Download URL meristem-4.0.0.tar.gz
Size 130.8 kB
Tags Source
SHA-256 checksum
How to use checksums
fdfa2dea19f4a370667198260e378616192f249fd21461694468c97f75fb6899
BLAKE2b-256 checksum
How to use checksums
0e86e8606ea4949fa5bd174899e914a2c15848801447867d30a7c1bab4dfac5f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / meristem-4.0.0-py3-none-any.whl

Download URL meristem-4.0.0-py3-none-any.whl
Size 94.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9b5996ebef27c304d6e643c4509827c7d29cc09c589be4838a85e4fb466d8c12
BLAKE2b-256 checksum
How to use checksums
5f303029674f77a01f8fba1359d373f165fbb6e45e50f95bab84f134c659ad1b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for meristem 4.0.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

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