Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ All notable changes to ReadyAgents Core.

## Unreleased

## 2.0.12 — 2026-09-30

### Added

- Every approval `decision` audit line (approve and reject, classic and
Expand All @@ -12,6 +14,11 @@ All notable changes to ReadyAgents Core.
re-baselined to the new prompt, so the re-approval's line carries the new
digest, not the one on the original `paused` line.

### Docs

- `docs/cli.md` shows the pip path for the gate example
(`readyagents new g --from-example approval_gate`).

## 2.0.11 — 2026-09-30

### Added
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ This repository is the free core. You keep the provider account and the bill. In

## 60-second start

Requires **Python 3.11–3.14** on Linux, macOS, or Windows. Current version is **2.0.11**. Install with `pip install readyagentsdev`, or from this clone. The `2` versions the [core contract](docs/stability.md#what-the-version-number-means) only; extras carry their own maturity tiers.
Requires **Python 3.11–3.14** on Linux, macOS, or Windows. Current version is **2.0.12**. Install with `pip install readyagentsdev`, or from this clone. The `2` versions the [core contract](docs/stability.md#what-the-version-number-means) only; extras carry their own maturity tiers.

```bash
pip install readyagentsdev
Expand Down Expand Up @@ -232,7 +232,7 @@ flowchart LR
- [Compliance evidence](docs/compliance.md) (Articles 12–14 mapping; not certification)
- [Observability](docs/observability.md)
- [Changelog](CHANGELOG.md)
- [Release notes 2.0.11](RELEASE_NOTES.md)
- [Release notes 2.0.12](RELEASE_NOTES.md)

## Install extras

Expand Down
28 changes: 28 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,31 @@
# ReadyAgents Core 2.0.12

**The decision line records which prompt was approved.**

- Every approval `decision` audit line (approve and reject, classic and
enterprise gates) now carries `prompt_sha256`, the digest of the prompt the
decision was made on.
- After a `reapprove_required` refusal the pause is re-baselined to the new
prompt, so the re-approval's `decision` line carries the new digest, not the
one on the original `paused` line.
- `docs/cli.md` shows the pip path for the gate example:
`readyagents new g --from-example approval_gate`.

## Try it

```bash
pip install readyagentsdev==2.0.12
readyagents new /tmp/gate212 --from-example approval_gate
readyagents run /tmp/gate212/workflow.yaml # exit 2, paused
# edit the gate prompt in workflow.yaml, then:
readyagents resume <run_id> --approve gate --json # exit 3, reason reapprove_required
readyagents resume <run_id> --approve gate # exit 0; decision line has the new prompt_sha256
```

Or clone https://github.com/readyagentsdev/readyagents-core and `pip install -e .`.



# ReadyAgents Core 2.0.11

**Approve what you saw: approval prompt digest and `reapprove_required`.**
Expand Down
2 changes: 2 additions & 0 deletions docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ readyagents new demo --template gated
readyagents run demo/workflow.yaml --approve gate
readyagents new --list-examples
readyagents new f --from-example calc_pipeline
readyagents new g --from-example approval_gate # pip path for examples/approval_gate.yaml
readyagents run g/workflow.yaml
```

Templates: `basic`, `approval`, `research` (parallel + approval), `pipeline` (default; calc/json/condition), `review` (read_file + approval), `foreach`, `agent-tools`, `gated`, `decide` (confidence-gated triage; keyless run is not calibration).
Expand Down
6 changes: 3 additions & 3 deletions docs/first-ten-minutes.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# First ten minutes
> **Tier:** stable — core, covered by the stability contract. See [stability](stability.md).

No API keys. Current version is **2.0.11** (`readyagents version`). Install from PyPI
No API keys. Current version is **2.0.12** (`readyagents version`). Install from PyPI
(`pip install readyagentsdev`) or from a clone (`pip install -e .`) as in the
[README](../README.md). The wheel ships `examples/`; one road below serves both.
The `2` versions the [core contract](stability.md#what-the-version-number-means)
Expand Down Expand Up @@ -144,9 +144,9 @@ Same pattern for `composed_gate` (add `--approve gate`).

Full syntax: [workflows.md](workflows.md). Gate mechanics: [approvals.md](approvals.md).

## Optional (2.0.11 surface)
## Optional (2.0.12 surface)

**2.0.11** includes connectors, sovereign, memory, and A2A. Keyless examples
**2.0.12** includes connectors, sovereign, memory, and A2A. Keyless examples
(each materialized first, same as above):

```bash
Expand Down
2 changes: 1 addition & 1 deletion docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

## Install

Current version is **2.0.11**. Preferred install is from PyPI:
Current version is **2.0.12**. Preferred install is from PyPI:

```bash
python -m venv .venv
Expand Down
4 changes: 2 additions & 2 deletions docs/mcp-plugs.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# MCP paste catalog (client plugs)
> **Tier:** stable — documentation only. See [stability](stability.md). Companion to [mcp.md](mcp.md).

Curated **one-shot / client-side** MCP plugs for local workflow YAML. Current package **2.0.11**: `pip install "readyagentsdev[mcp]"`.
Curated **one-shot / client-side** MCP plugs for local workflow YAML. Current package **2.0.12**: `pip install "readyagentsdev[mcp]"`.

| This is | This is not |
| --- | --- |
Expand All @@ -17,7 +17,7 @@ Prefer ReadyAgents builtins (`list_dir`, `read_file`, `write_file`, `http_get` o
```bash
pip install "readyagentsdev[mcp]"
# or: pip install -U "readyagentsdev[mcp]"
readyagents version # expect 2.0.11
readyagents version # expect 2.0.12
```

1. Paste a block under top-level **`mcp_servers:`** in your workflow YAML.
Expand Down
10 changes: 5 additions & 5 deletions docs/why-readyagents.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ MCP connectivity is not durable orchestration.

This page records two public reports about gaps between MCP wiring and durable
workflow execution, plus one design note about how modern MCP asks a question. It
states plainly what ReadyAgents 2.0.11 does and does not do. Each verdict is about
states plainly what ReadyAgents 2.0.12 does and does not do. Each verdict is about
our own software only.

## Why not LangGraph HITL / n8n MCP?

If you need **hosted**, always-on MCP recovery or a managed HITL control plane, use those products' hosted surfaces. ReadyAgents **2.0.11** is local persist/resume with an explicit foreground door: an approval pause is exit **2** (not a crash) and continues with `readyagents resume … --approve` — and process death still loses the in-flight executor. The sections below give PARTIAL verdicts on each MCP surface only; they are not a claim that ReadyAgents replaces LangGraph Platform HITL or n8n's MCP Server Trigger end-to-end.
If you need **hosted**, always-on MCP recovery or a managed HITL control plane, use those products' hosted surfaces. ReadyAgents **2.0.12** is local persist/resume with an explicit foreground door: an approval pause is exit **2** (not a crash) and continues with `readyagents resume … --approve` — and process death still loses the in-flight executor. The sections below give PARTIAL verdicts on each MCP surface only; they are not a claim that ReadyAgents replaces LangGraph Platform HITL or n8n's MCP Server Trigger end-to-end.

## LangGraph MCP surface: MCP-exposed runs remain stateless

Expand All @@ -24,7 +24,7 @@ Quote LangSmith docs:

> The current LangGraph MCP implementation does not support sessions. Each `/mcp` request is stateless and independent.

ReadyAgents 2.0.11: PARTIAL. We persist local workflow state and support resume/approval pauses. The official `io.modelcontextprotocol/tasks` extension (and the deprecated `/runs` alias) returns a durable `taskId`/`run_id` that can be polled, approved via `tasks/update`, or cancelled without holding the original request open. That is a local authenticated task handle, not a hosted recovery surface: stopping the command stops the listener and in-process executor. A record may remain on disk; nothing resumes it automatically. This comparison is about the MCP surface, not LangGraph's other surfaces.
ReadyAgents 2.0.12: PARTIAL. We persist local workflow state and support resume/approval pauses. The official `io.modelcontextprotocol/tasks` extension (and the deprecated `/runs` alias) returns a durable `taskId`/`run_id` that can be polled, approved via `tasks/update`, or cancelled without holding the original request open. That is a local authenticated task handle, not a hosted recovery surface: stopping the command stops the listener and in-process executor. A record may remain on disk; nothing resumes it automatically. This comparison is about the MCP surface, not LangGraph's other surfaces.

## n8n MCP Server Trigger: a long synchronous call can lose the result, and HITL is unsupported

Expand All @@ -42,7 +42,7 @@ Quote the current MCP tools reference:

> Executing workflows with multi-step forms or any kind of human-in-the-loop interactions isn't supported.

ReadyAgents 2.0.11: PARTIAL. We checkpoint locally and have an approval node. A disconnected 2026 MCP client can recover a local result by polling `tasks/get` after `CreateTaskResult`, and can decide (`tasks/update`) or cooperatively cancel on the same authenticated loopback door. That does not make ReadyAgents a hosted MCP Server Trigger: the door is an explicit foreground command, and process death loses the in-flight executor. n8n's instance-level `execute_workflow` already returns an execution ID immediately; this page is only about the MCP Server Trigger surface.
ReadyAgents 2.0.12: PARTIAL. We checkpoint locally and have an approval node. A disconnected 2026 MCP client can recover a local result by polling `tasks/get` after `CreateTaskResult`, and can decide (`tasks/update`) or cooperatively cancel on the same authenticated loopback door. That does not make ReadyAgents a hosted MCP Server Trigger: the door is an explicit foreground command, and process death loses the in-flight executor. n8n's instance-level `execute_workflow` already returns an execution ID immediately; this page is only about the MCP Server Trigger surface.

## Design note: modern MCP uses retry-shaped multi-round trips

Expand All @@ -56,7 +56,7 @@ Quote the Python SDK:

> A resolver works on every connection. For a client on a legacy connection the SDK sends it the question directly; on a 2026-07-28 connection the SDK returns the question from the call, and the client's next attempt carries the answer.

This is a design note, not a competitor gap. The ask is now a stateless retry-shaped resolver. ReadyAgents 2.0.11 surfaces a paused approval as `tasks/get` `input_required` and accepts `tasks/update` `inputResponses`, routed through the same signed/RBAC/audit path as `readyagents decide`. That is protocol-native HITL on a durable run record, not a hosted elicitation service. Process death still loses the in-flight executor. The localhost approval page remains an additional local door, not a substitute for MCP.
This is a design note, not a competitor gap. The ask is now a stateless retry-shaped resolver. ReadyAgents 2.0.12 surfaces a paused approval as `tasks/get` `input_required` and accepts `tasks/update` `inputResponses`, routed through the same signed/RBAC/audit path as `readyagents decide`. That is protocol-native HITL on a durable run record, not a hosted elicitation service. Process death still loses the in-flight executor. The localhost approval page remains an additional local door, not a substitute for MCP.

## A2A: a projection, not a second runtime

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "readyagentsdev"
version = "2.0.11"
version = "2.0.12"
description = "Local one-shot YAML/JSON agent workflow engine + MCP toolkit (BYOK)."
readme = "README.md"
license = { text = "Apache-2.0" }
Expand Down
2 changes: 1 addition & 1 deletion schemas/workflow-v1.json
Original file line number Diff line number Diff line change
Expand Up @@ -4331,5 +4331,5 @@
],
"title": "ReadyAgents workflow",
"type": "object",
"x-readyagents-version": "2.0.11"
"x-readyagents-version": "2.0.12"
}
4 changes: 2 additions & 2 deletions server.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
"url": "https://github.com/readyagentsdev/readyagents-core",
"source": "github"
},
"version": "2.0.11",
"version": "2.0.12",
"packages": [
{
"registryType": "pypi",
"registryBaseUrl": "https://pypi.org",
"identifier": "readyagentsdev",
"version": "2.0.11",
"version": "2.0.12",
"packageArguments": [
{
"type": "positional",
Expand Down
2 changes: 1 addition & 1 deletion src/readyagents/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from __future__ import annotations

__version__ = "2.0.11"
__version__ = "2.0.12"

from readyagents.errors import (
ApprovalRequired,
Expand Down
4 changes: 2 additions & 2 deletions src/readyagents/skills/agents_md.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@
HEADER = """# AGENTS.md

This is a ReadyAgents Core repository: a local one-shot YAML/JSON agent workflow
engine. Current **2.0.11** — soft path is `pip install readyagentsdev`, then
engine. Current **2.0.12** — soft path is `pip install readyagentsdev`, then
`readyagents new f --from-example calc_pipeline`. Always-on packs are optional
and not required to run or validate workflows.

## Run

```sh
# PyPI soft path (Current 2.0.11)
# PyPI soft path (Current 2.0.12)
pip install readyagentsdev
readyagents new f --from-example calc_pipeline
readyagents run f/workflow.yaml
Expand Down
20 changes: 10 additions & 10 deletions tests/test_publish_mcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@
import pytest

ROOT = Path(__file__).resolve().parents[1]
PYPI_JSON = "https://pypi.org/pypi/readyagentsdev/2.0.11/json"
PYPI_JSON = "https://pypi.org/pypi/readyagentsdev/2.0.12/json"
VERSION_NOT_FOUND = (
'Error: publish failed: server returned status 400: {"title":"Bad Request",'
'"status":400,"detail":"Failed to publish server","errors":[{"message":'
'"registry validation failed for package 0 (readyagentsdev): PyPI package '
"'readyagentsdev' exists, but version '2.0.11' was not found (status: 404). "
"'readyagentsdev' exists, but version '2.0.12' was not found (status: 404). "
"A newly published release can take a moment to appear on PyPI. Wait and "
"retry, or publish version '2.0.11' before registering it\"}]}"
"retry, or publish version '2.0.12' before registering it\"}]}"
)
OWNERSHIP_400 = (
'Error: publish failed: server returned status 400: {"title":"Bad Request",'
Expand Down Expand Up @@ -61,7 +61,7 @@ def get(url: str) -> int:

wait_pypi.wait_until_pypi_version_visible(
"readyagentsdev",
"2.0.11",
"2.0.12",
timeout=60,
interval=10,
get=get,
Expand All @@ -87,7 +87,7 @@ def get(url: str) -> int:

wait_pypi.wait_until_pypi_version_visible(
"readyagentsdev",
"2.0.11",
"2.0.12",
timeout=60,
interval=10,
get=get,
Expand All @@ -112,7 +112,7 @@ def get(url: str) -> int:
with pytest.raises(wait_pypi.PyPIVersionNotVisible, match="was not found") as exc:
wait_pypi.wait_until_pypi_version_visible(
"readyagentsdev",
"2.0.11",
"2.0.12",
timeout=30,
interval=10,
get=get,
Expand All @@ -135,7 +135,7 @@ def get(url: str) -> int:
with pytest.raises(wait_pypi.PyPIVersionNotVisible, match="last status: 500"):
wait_pypi.wait_until_pypi_version_visible(
"readyagentsdev",
"2.0.11",
"2.0.12",
timeout=20,
interval=10,
get=get,
Expand All @@ -148,7 +148,7 @@ def test_wait_first_try_200_does_not_sleep() -> None:
clock = _Clock()
wait_pypi.wait_until_pypi_version_visible(
"readyagentsdev",
"2.0.11",
"2.0.12",
timeout=600,
interval=15,
get=lambda url: 200,
Expand Down Expand Up @@ -238,7 +238,7 @@ def get(url: str) -> int:
"--package",
"readyagentsdev",
"--version",
"2.0.11",
"2.0.12",
"--timeout",
"60",
"--interval",
Expand All @@ -254,7 +254,7 @@ def test_main_wait_timeout_exits_1(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setattr(wait_pypi, "http_get", lambda url: 404)
monkeypatch.setattr(wait_pypi, "sleep", clock.sleep)
monkeypatch.setattr(wait_pypi, "monotonic", clock.monotonic)
rc = wait_pypi.main(["wait", "--version", "2.0.11", "--timeout", "20", "--interval", "10"])
rc = wait_pypi.main(["wait", "--version", "2.0.12", "--timeout", "20", "--interval", "10"])
assert rc == 1


Expand Down
Loading