From 0251861fd363efe56c4e9e40a30aac37d7bc1331 Mon Sep 17 00:00:00 2001 From: Manoj Prabhakar Paidiparthy Date: Thu, 28 May 2026 13:53:49 -0700 Subject: [PATCH 1/4] docs(readme): align with Mode A pivot, protocol 0.2.0, and shipped L3 wrappers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This README was significantly out of date with recent changes: - PR #8 (Mode A pivot): Replaced stdio JSON-RPC wire protocol with subprocess driver model (argv in / JSON envelope out). README still documented Mode B (--stdio flag, agent/initialize JSON-RPC methods) as primary interface. - PR #17: Bumped protocol version 0.1.0 → 0.2.0, changed --mcp-servers (inline JSON) to --mcp-config-path (file path) for MCP config delivery. Neither reflected in README. - PR #20: Changed OpenAI default from gpt-4 to gpt-5.5 (matches extended_thinking=true in bundle). README used outdated default. - PR #7: TypeScript wrapper shipped at 0.4.0 on npm, Python wrapper shipped in wrappers/python/. README claimed L3 wrappers were 'designed, implementation next'. Applied 10 targeted corrections across README: 1. 'What it is' section — removed Mode B bullet, fixed lifecycle 2. 'Why' section — removed JSON-RPC-mirrors-MCP claim 3. 'Quick start' — removed --stdio example, pointed at wrapper SDKs 4. 'Modes' table — collapsed to Mode A only, added historical design-doc note 5. 'Admin commands' — added missing 'prepare' and 'verify' commands 6. 'Approval flow' — removed unimplemented 'c' response, removed stdio paragraph 7. 'Embedding in Python' — replaced broken classmethod example with correct constructor and instance method usage 8. 'Architecture diagram' — updated arrow label to reflect Mode A transport 9. 'Wire protocol' section — replaced Mode B docs with Mode A (0.2.0 argv flags, JSON envelope schema, stdout/stderr split) 10. 'Status' — updated from 'Phase 1, L3 next' to shipped state (0.3.0 engine, 0.4.0 TS wrapper, Python wrapper, 0.2.0 protocol, conformance suite, path-based MCP) with next steps (L2 host adapters, container packaging). Generated with [Amplifier](https://github.com/microsoft/amplifier) Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com> --- README.md | 130 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 90 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index a972776..06c7edd 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,10 @@ A single binary that: -- **Accepts a prompt and returns a result** (Mode A, single-turn): `amplifier-agent run "your prompt"` -- **Speaks JSON-RPC over stdio for multi-turn conversations** (Mode B): `amplifier-agent run --stdio` +- **Accepts a prompt and returns a result** (single-turn): `amplifier-agent run "your prompt"` +- **Emits one JSON envelope on stdout per invocation** — wrappers spawn one process per turn and pass `--session-id` for continuity -It is *not* a server, daemon, or long-lived service. Each invocation is a fresh process that exits when its caller closes stdin or sends `agent/shutdown`. +It is *not* a server, daemon, or long-lived service. Each invocation is a fresh process that runs one turn and exits. Multi-turn conversations are managed at the wrapper or session-ID layer — not inside a persistent process. The engine library inside (`amplifier_agent_lib`) is transport-free Python that any Python app can also embed in-process — no subprocess needed. @@ -19,7 +19,7 @@ The engine library inside (`amplifier_agent_lib`) is transport-free Python that Existing AI agent infrastructure assumes you're building a chat product. `amplifier-agent` is the opposite: it's an *engine you point other software at*. The CLI is the universal adapter — wherever you can shell out, you can use Amplifier. -The wire protocol intentionally mirrors [MCP](https://modelcontextprotocol.io/) (JSON-RPC over stdio, server-initiated bidirectional requests, capability negotiation) so existing host clients can integrate with minimal new infrastructure. +The Mode A wire protocol is intentionally simple: the engine takes a single invocation (argv + env), runs one turn, and writes one JSON result envelope to stdout. Wrapper SDKs (TypeScript and Python) handle spawning, result parsing, and session continuity on top. ## Install @@ -49,12 +49,7 @@ Run a one-shot turn: amplifier-agent run "Summarize the README of github.com/microsoft/amplifier" ``` -Or wire it into a host as a JSON-RPC subprocess: - -```bash -amplifier-agent run --stdio -# Then write JSON-RPC requests to stdin, read events from stdout -``` +The TypeScript and Python wrapper SDKs handle subprocess management automatically. See `wrappers/typescript/` (`amplifier-agent-ts` on npm) and `wrappers/python/` for ready-to-use clients. ## Provider configuration @@ -71,10 +66,9 @@ Override with `--provider `. No `settings.yaml` to maintain. | Mode | Invocation | Caller | Lifecycle | |---|---|---|---| -| **A** (single-turn) | `amplifier-agent run "prompt"` | Shell scripts, OpenClaw skills, ad-hoc CLI use | Spawn → init → one turn → exit | -| **B** (multi-turn stdio) | `amplifier-agent run --stdio` | Wrapper SDKs, conversational host adapters | Spawn → init → many turns → exit on EOF | +| **A** (single-turn) | `amplifier-agent run "prompt"` | Shell scripts, wrapper SDKs, host adapters, ad-hoc CLI use | Spawn → one turn → JSON envelope on stdout → exit | -Both modes share the same engine; the only difference is who drives the I/O loop. +Multi-turn conversations are built by the caller: spawn one process per turn, passing `--session-id` for continuity. A persistent stdio JSON-RPC mode (Mode B) was originally designed but was superseded by the Mode A subprocess driver in PR #8 (see `docs/designs/2026-05-24-aaa-v2-mode-a-pivot-amendment.md`). ## Session continuity @@ -95,6 +89,8 @@ Sessions are persisted as transcript JSONL in `$XDG_STATE_HOME/amplifier-agent/s ```bash amplifier-agent doctor # Diagnose env, providers, paths, bundle cache +amplifier-agent prepare # Pre-warm bundle cache (run once after install) +amplifier-agent verify # Verify install integrity amplifier-agent config show # Print resolved config with source annotations amplifier-agent cache clear # Invalidate the prepared-bundle cache amplifier-agent --version # Print version @@ -102,31 +98,53 @@ amplifier-agent --version # Print version ## Approval flow -Some tools (file writes, command execution) request approval before acting. In single-turn mode: +Some tools (file writes, command execution) request approval before acting: -- **Interactive terminal**: prompted on stderr; respond `y` / `N` / `c` +- **Interactive terminal**: prompted on stderr; respond `y` to approve, anything else to decline - **Non-interactive (CI, pipe, background)**: denied by default - **Override**: `-y` accepts all, `-n` denies all (apt-style) -In stdio mode, approval flows over the wire as `approval/request` server-initiated JSON-RPC requests. Wrapper SDKs implement the host-side handler (callback, message-back, email, or anything else creative — adapter's choice). +Wrapper SDKs can install their own approval handler (callback, message-back, email, or anything else creative — adapter's choice) via the `ApprovalSystem` protocol point on the engine library. ## Embedding in your own Python host Skip the CLI entirely if your host is Python: ```python -from amplifier_agent_lib import Engine +import sys +from amplifier_agent_lib import __version__ +from amplifier_agent_lib._runtime import make_turn_handler +from amplifier_agent_lib.bundle.cache import load_and_prepare_cached +from amplifier_agent_lib.engine import Engine +from amplifier_agent_lib.protocol import PROTOCOL_VERSION from amplifier_agent_lib.protocol_points.defaults_cli import CliApprovalSystem, CliDisplaySystem -engine = await Engine.boot( - approval_system=CliApprovalSystem(mode="auto"), - display_system=CliDisplaySystem(verbosity="normal"), +prepared = await load_and_prepare_cached(aaa_version=__version__) +handler = make_turn_handler(prepared, cwd=None, is_resumed=False, mcp_config_path=None) + +engine = Engine( + turn_handler=handler, + protocol_points={ + "approval": CliApprovalSystem(mode="no"), + "display": CliDisplaySystem(verbosity="normal", stream=sys.stderr), + }, ) -result = await engine.submit_turn(prompt="Hello!", session_id="my-session") +await engine.boot({ + "protocolVersion": PROTOCOL_VERSION, + "clientInfo": {"name": "my-host", "version": "0.1.0"}, + "capabilities": {}, + "sessionId": "my-session", + "resume": False, +}) +result = await engine.submit_turn({ + "sessionId": "my-session", + "turnId": "turn-1", + "prompt": "Hello!", +}) await engine.shutdown() ``` -See `src/amplifier_agent_lib/` for the full library surface. +`Engine.boot()` is an instance method that takes a params dict. The constructor requires both `turn_handler` (built from a `PreparedBundle`) and the `protocol_points` dict. See `src/amplifier_agent_lib/` for the full library surface. ## Architecture at a glance @@ -138,7 +156,7 @@ Host Application ← your code Adapter (host-specific glue) ← per-host integration ↓ Language Wrapper (TypeScript or Python) ← typed SDK - ↓ JSON-RPC over stdio (or in-process) + ↓ subprocess (argv in / JSON envelope out, or in-process) amplifier-agent CLI ← this repo ↓ (in-process) amplifier_agent_lib (engine library) ← this repo @@ -148,22 +166,46 @@ Amplifier Kernel (amplifier-core, amplifier-foundation) The CLI binary (`amplifier-agent`) is a thin I/O adapter on top of `amplifier_agent_lib`. The library is transport-free — Python hosts can skip the subprocess entirely. -## Wire protocol (Mode B) +## Wire protocol (Mode A) + +Protocol version: **`0.2.0`** (defined in `src/amplifier_agent_lib/protocol/methods.py`; breaking changes bump this). Wrappers must pass `--protocol-version 0.2.0` — version mismatches return a `protocol_version_mismatch` error and exit non-zero rather than silently misbehave. + +Mode A uses a single subprocess invocation per turn. The wrapper passes flags as argv; the engine writes one JSON envelope line to stdout on completion. -Mode B speaks JSON-RPC 2.0 over newline-delimited stdin/stdout: +**Input (selected argv flags):** -| Method | Direction | Purpose | +| Flag | Type | Purpose | |---|---|---| -| `agent/initialize` | Host → Agent | Capability negotiation | -| `session/create` | Host → Agent | Open a new session | -| `turn/submit` | Host → Agent | Submit a turn; agent streams notifications + returns result | -| `turn/cancel` | Host → Agent | Cancel an in-flight turn | -| `session/end` | Host → Agent | Close session and persist state | -| `agent/shutdown` | Host → Agent | Graceful exit | -| `approval/request` | Agent → Host | Request approval for a sensitive action | -| `notifications/*` | Agent → Host | Streaming events (`result/delta`, `result/final`, `tool/started`, `tool/completed`, `progress`, `thinking/*`, `usage`, `error`) | +| `PROMPT` | positional | The turn prompt | +| `--session-id` | str | Session ID for continuity | +| `--resume` | flag | Resume from saved transcript | +| `--fresh` | flag | Discard saved state and start over | +| `--protocol-version` | str | Wrapper's pinned protocol version; engine validates match | +| `--mcp-config-path` | path | Path to MCP server config JSON (written by the wrapper) | +| `--host-capabilities` | JSON | Host capability advertisement | +| `-y` / `-n` | flag | Auto-approve / auto-deny all approval requests | +| `--output` | text \| json | `json` (default) emits full envelope; `text` emits the reply only | + +**Output (stdout, single JSON line):** + +```json +{ + "protocolVersion": "0.2.0", + "sessionId": "...", + "turnId": "turn-1", + "reply": "...", + "error": null, + "metadata": { + "tokensIn": 0, "tokensOut": 0, "durationMs": 0, + "bundleDigest": "...", "engineVersion": "...", + "protocolVersion": "0.2.0", "correlationId": "..." + } +} +``` + +Diagnostic events (tool calls, thinking, progress) go to **stderr** only — stdout is reserved for the single envelope so callers can parse it with `JSON.parse(line)` without filtering. -Notifications are one-way (no `id`). Server-initiated requests use the same ID-correlation as host-initiated ones, just in reverse. +The TypeScript and Python wrapper SDKs (`wrappers/typescript/`, `wrappers/python/`) handle all of this: they spawn `amplifier-agent run`, write the MCP config tmpfile, parse the envelope, and expose a typed async API. ## Related repositories @@ -176,13 +218,21 @@ Notifications are one-way (no `id`). Server-initiated requests use the same ID-c ## Status -Phase 1 — Layer 4 (engine library + CLI) ships in this release. Roadmap: +Current versions: engine `0.3.0`, TypeScript wrapper `amplifier-agent-ts@0.4.0`, Python wrapper `amplifier_agent_client` (see `wrappers/python/`). Wire protocol: `0.2.0`. + +**Shipped:** + +- L4 — Engine library + CLI (Mode A) +- L3 — TypeScript + Python wrapper SDKs (`amplifier-agent-ts` on npm, `amplifier_agent_client` in `wrappers/python/`) +- Protocol schemas + cross-language conformance test suite (`wrappers/conformance/`) +- Path-based MCP config delivery (`--mcp-config-path`) + +**In progress / next:** -- L3 language wrappers (TypeScript + Python SDKs) — designed, implementation next -- L2 host adapters (NanoClaw, Paperclip) — designed, implementation after L3 -- Install paths, container packaging, full execution plan — deferred sections of the design checkpoint +- L2 — Host adapters (NanoClaw, Paperclip) — see `docs/designs/2026-05-22-aaa-v2-amplifier-agent-nc-provider.md` +- Container packaging, install-path finalization -See [`docs/designs/`](docs/designs/) and the [pull requests](https://github.com/microsoft/amplifier-agent/pulls) for design history and roadmap. +See [`docs/designs/`](docs/designs/) and the [pull requests](https://github.com/microsoft/amplifier-agent/pulls) for design history and roadmap. The Mode A pivot is captured in [`docs/designs/2026-05-24-aaa-v2-mode-a-pivot-amendment.md`](docs/designs/2026-05-24-aaa-v2-mode-a-pivot-amendment.md). ## Contributing From 8676843b12e4ebdd75ffb2b7f71111ec1e606acd Mon Sep 17 00:00:00 2001 From: Manoj Prabhakar Paidiparthy Date: Thu, 28 May 2026 14:14:24 -0700 Subject: [PATCH 2/4] docs(readme): add TypeScript SDK section and fix git+URL install command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Added "TypeScript / Node.js SDK" section documenting the shipped npm package (amplifier-agent-ts@0.4.0) with install command, quick-start example, Node ≥ 20 requirement, and pointers to full README and type definitions. - Fixed broken Python install commands: replaced bare PyPI references (uv tool install / pipx install) with git+URL form pinned to engine-v0.3.0. Package is not yet published to PyPI; this fixes the broken install path demonstrated by user feedback. Added explanatory note about separate engine vs wrapper version tagging (engine-v0.3.0 vs wrapper-v0.4.0). Both gaps were identified during PR #21 review: TypeScript SDK was effectively undocumented for consumers despite npm publication, and Python install was impossible without the git+URL form. Generated with [Amplifier](https://github.com/microsoft/amplifier) Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com> --- README.md | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 06c7edd..f99de0c 100644 --- a/README.md +++ b/README.md @@ -23,15 +23,19 @@ The Mode A wire protocol is intentionally simple: the engine takes a single invo ## Install +The Python engine is not yet published to PyPI — install directly from the tagged git release: + ```bash -uv tool install amplifier-agent +uv tool install "amplifier-agent @ git+https://github.com/microsoft/amplifier-agent@engine-v0.3.0" amplifier-agent doctor # verify environment ``` Other install methods: -- `pipx install amplifier-agent` -- From source: `git clone … && cd amplifier-agent && uv sync && uv tool install -e .` +- `pipx install "amplifier-agent @ git+https://github.com/microsoft/amplifier-agent@engine-v0.3.0"` +- From source: `git clone https://github.com/microsoft/amplifier-agent.git && cd amplifier-agent && uv sync && uv tool install -e .` + +The current engine tag is `engine-v0.3.0`. Wrapper releases are tagged separately (e.g. `wrapper-v0.4.0`) — see `git tag -l` for the full list. First-run will prepare the built-in bundle and cache it to `$XDG_CACHE_HOME/amplifier-agent/`. Subsequent invocations skip this step. @@ -146,6 +150,39 @@ await engine.shutdown() `Engine.boot()` is an instance method that takes a params dict. The constructor requires both `turn_handler` (built from a `PreparedBundle`) and the `protocol_points` dict. See `src/amplifier_agent_lib/` for the full library surface. +## TypeScript / Node.js SDK + +For Node.js and TypeScript hosts, use the `amplifier-agent-ts` npm package. It is a thin process supervisor that spawns the Python `amplifier-agent` CLI per turn (Mode A) and exposes a typed async API — all inference, tool execution, and session state live in the Python engine. + +You need **both** packages installed: the npm SDK *and* the Python engine (see [Install](#install) above — the Python CLI must be on `PATH`). + +```bash +npm install amplifier-agent-ts +``` + +```typescript +import { spawnAgent, AaaError } from 'amplifier-agent-ts'; +import { randomUUID } from 'node:crypto'; + +const session = await spawnAgent({ + lifecycle: 'one-shot', + sessionId: randomUUID(), +}); + +try { + const result = await session.submit({ prompt: 'Hello, agent.' }); + console.log(result.reply); +} catch (err) { + if (err instanceof AaaError) { + console.error(`[${err.code}] ${err.message}`); + } else { + throw err; + } +} +``` + +Requires Node.js ≥ 20. Zero npm runtime dependencies. Full API surface in [`wrappers/typescript/README.md`](wrappers/typescript/README.md) and the type definitions at `wrappers/typescript/dist/index.d.ts`. The Python sibling SDK lives at [`wrappers/python/`](wrappers/python/). + ## Architecture at a glance amplifier-agent is one layer of the larger Amplifier ecosystem: From 11e9a444ef3155ae227321b251d6691b2f144bcf Mon Sep 17 00:00:00 2001 From: Manoj Prabhakar Paidiparthy Date: Thu, 28 May 2026 14:19:43 -0700 Subject: [PATCH 3/4] docs(readme): replace registry install with from-source instructions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Python engine hasn't been published to any registry. Removed all registry-style install commands (uv tool install amplifier-agent, pipx install amplifier-agent, and git+URL forms with PEP 508 specs) as they were misleading. From-source install via git clone + uv tool install -e . is now the only documented path. Added note that engine and wrapper releases are tagged separately (engine-v0.3.0 vs wrapper-v0.4.0) so users can git checkout before installing if they want a pinned version. This does not affect the TypeScript section — amplifier-agent-ts is published to npm and npm install amplifier-agent-ts is correct. 🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier) Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com> --- README.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index f99de0c..4576940 100644 --- a/README.md +++ b/README.md @@ -23,19 +23,17 @@ The Mode A wire protocol is intentionally simple: the engine takes a single invo ## Install -The Python engine is not yet published to PyPI — install directly from the tagged git release: +The Python engine is not yet published to any package registry. Install from source: ```bash -uv tool install "amplifier-agent @ git+https://github.com/microsoft/amplifier-agent@engine-v0.3.0" +git clone https://github.com/microsoft/amplifier-agent.git +cd amplifier-agent +uv sync +uv tool install -e . amplifier-agent doctor # verify environment ``` -Other install methods: - -- `pipx install "amplifier-agent @ git+https://github.com/microsoft/amplifier-agent@engine-v0.3.0"` -- From source: `git clone https://github.com/microsoft/amplifier-agent.git && cd amplifier-agent && uv sync && uv tool install -e .` - -The current engine tag is `engine-v0.3.0`. Wrapper releases are tagged separately (e.g. `wrapper-v0.4.0`) — see `git tag -l` for the full list. +Engine and wrapper releases are tagged separately — `engine-v0.3.0` and `wrapper-v0.4.0` respectively. Check out a specific tag (`git checkout engine-v0.3.0`) before `uv tool install -e .` if you need a pinned version. Run `git tag -l` to see the full list. First-run will prepare the built-in bundle and cache it to `$XDG_CACHE_HOME/amplifier-agent/`. Subsequent invocations skip this step. From fd5fb9bdcf123c1c95240f7926d61fc03653cf1a Mon Sep 17 00:00:00 2001 From: Manoj Prabhakar Paidiparthy Date: Thu, 28 May 2026 14:23:37 -0700 Subject: [PATCH 4/4] docs(readme): use uv tool install with bare git+URL (no registry needed) uv tool install works fine with a raw git+https://... argument; no PEP 508 name @ url wrapper, no registry, no separate clone+sync step. Pinning supported via @. From-source editable install retained as a contributor note. Generated with [Amplifier](https://github.com/microsoft/amplifier) Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com> --- README.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 4576940..6edcf98 100644 --- a/README.md +++ b/README.md @@ -23,17 +23,20 @@ The Mode A wire protocol is intentionally simple: the engine takes a single invo ## Install -The Python engine is not yet published to any package registry. Install from source: +The Python engine is not yet published to a package registry, but `uv tool install` installs it directly from git: ```bash -git clone https://github.com/microsoft/amplifier-agent.git -cd amplifier-agent -uv sync -uv tool install -e . +uv tool install git+https://github.com/microsoft/amplifier-agent amplifier-agent doctor # verify environment ``` -Engine and wrapper releases are tagged separately — `engine-v0.3.0` and `wrapper-v0.4.0` respectively. Check out a specific tag (`git checkout engine-v0.3.0`) before `uv tool install -e .` if you need a pinned version. Run `git tag -l` to see the full list. +Pin to a specific engine release by appending a tag: + +```bash +uv tool install git+https://github.com/microsoft/amplifier-agent@engine-v0.3.0 +``` + +Engine and wrapper releases are tagged separately (`engine-v0.3.0`, `wrapper-v0.4.0`). For local development against a checkout, `git clone` the repo and run `uv tool install -e .` from inside it. First-run will prepare the built-in bundle and cache it to `$XDG_CACHE_HOME/amplifier-agent/`. Subsequent invocations skip this step.