Skip to content

Releases: microsoft/amplifier-agent

v0.9.0

23 Jun 06:58
c285512

Choose a tag to compare

What's new in 0.9.0

The headline: opencode and any OpenAI-compatible client now get full session continuity with zero config. Before 0.9.0, every chat-completions request created a new amplifier session with a random sid; one opencode conversation fragmented into N session dirs. With 0.9.0, the amplifier session_id is derived from the client's session header (sent automatically by Vercel AI SDK), so one opencode conversation = one amplifier session — unified audit trail, persistent hook state across turns, append-mode events.jsonl.

Added

  • Chat-completions session resume via X-Client-Session-Id / X-Session-Id. Server now uses a deterministic http-<client_sid> as the amplifier session_id, auto-detects first-turn vs continuation by checking if the session state dir exists on disk, and passes is_resumed to the kernel resume mechanism (same primitive amplifier-agent run --resume uses). One client conversation = one amplifier session. (#71)

  • X-Session-Id header fallback — opencode and other Vercel AI SDK-based clients send this header automatically. amplifier-agent now recognizes it as a fallback for X-Client-Session-Id, so session-resume works out of the box for opencode with zero client config. X-Client-Session-Id (our amplifier-native convention) remains authoritative when both are present. (#72)

  • Client-authoritative transcript reconciliation in _reconciler.py. The chat-completions wire is stateless — clients send full history every turn. On divergence between stored and incoming, the client wins by fiat: we persist their view over ours without any rewind ceremony. (#71)

Changed

  • reconcile_client_history now runs foundation's transcript-repair pass before persisting. Catches broken chat-completions clients (orphaned tool_use without paired tool_result, ordering violations, incomplete assistant turns) that would otherwise cause Anthropic to reject the next LLM call with HTTP 400. Mirrors _runtime.py:_repair_loaded_transcript_if_needed from the CLI face. Healthy transcripts pass through unchanged (<10ms diagnostic). (#73)

  • Workspace name is no longer suffixed with the client session id. Previously, X-Client-Session-Id: abc would route requests into workspaces/<base>-abc/. Now the workspace stays at <base> and per-client distinction is purely at the session_id level (workspaces/<base>/sessions/http-abc/). This keeps workspace-level hook state shared across all sessions of the same server process, where it belongs. (#72)

Wire protocol

Unchanged at 0.3.0. No wrapper bump. TypeScript wrapper stays at 0.7.0.

Backward compatibility

  • Clients NOT sending X-Client-Session-Id or X-Session-Id: behavior unchanged — random sid per turn, no resume.
  • Clients sending only X-Client-Session-Id: behavior unchanged from PR #71.
  • Clients sending only X-Session-Id (opencode default): NEW — gets full session continuity.
  • Clients sending both: X-Client-Session-Id wins.

The wire format (request body, response body, headers) is unchanged. The only observable difference for existing clients is the on-disk workspace dir layout — workspace name is no longer suffixed with the client session id.

See CHANGELOG.md [0.9.0] for full details, including the [0.8.0] section which still applies.

v0.8.0

22 Jun 07:18
f6e1a6e

Choose a tag to compare

What's new in 0.8.0

Added

  • OpenAI-compatible chat-completions HTTP face (amplifier-agent serve chat-completions) — /v1/models + /v1/chat/completions over HTTP with bearer-token auth. Streams responses, multi-provider routing via served-models registry, workspace correlation through X-Client-Session-Id header. Enables direct integration with opencode via the amplifier-app-opencode wrapper and any OpenAI-compatible client. (#65)

  • amplifier-agent auth subcommand — set/list/remove/status/clear actions over ~/.amplifier-agent/credentials.json (mode 0600). Resolution chain is env-first: shell env vars (ANTHROPIC_API_KEY, …) win over the file so existing shell-rc workflows are unchanged. "Set once, works everywhere" UX matching claude login / gh auth login / aws configure without the OAuth ceremony. (#65)

  • Host-tool delegation — tools declared by the host (host_config.json:host_tools) are surfaced to the model with stub schemas; on invocation, server emits a signal tool_call back to the client (same chunk_id), client executes host-side, returns result for the model to continue. Lets the host own filesystem, shell, browser, or any custom tool without bundling into amplifier-agent. (#65)

  • Model routing matrix integration — per-role provider/model preferences resolved per turn. (#64)

  • cost_usd in chat-completions usage envelope — non-standard field carrying the actual dollar cost provider modules computed, accumulated across sub-turns, serialized as a string for Decimal precision. Standard OpenAI clients ignore the field; cost-aware clients render the real per-turn $$. (#68)

  • host_config.providers (plural) registry — declares which providers the server-mode lifespan loads and how to instantiate each. Schema: providers: {<provider_id>: {module?: str, config?: dict}}. Module defaults to provider_id when omitted; each provider's config is passed as extra_config into list_provider_models(). (#69)

  • amplifier-agent serve status / stop / restart subcommands — operational lifecycle for the chat-completions HTTP server. Status reports running/stale/not-running, where it's reachable, and how many models from which providers it's serving (self-cleans stale state files when the PID is gone). Stop sends SIGTERM with a configurable graceful-exit window (--timeout), escalating to SIGKILL on expiry or on --force. Restart performs an identity-restart using the args stored at original launch. State is tracked in ~/.amplifier-agent/state/serve.json (mode 0600, parent dir 0700; api_key is sensitive and never logged). (#69)

Changed

  • Breaking (server mode only): amplifier-agent serve chat-completions now requires host_config.providers to be a non-empty dict. Any provider declared there that cannot initialize (missing credentials, module not installed, list_models() raises, returns 0 models) causes the server to exit 2 with a structured error listing every problem. The previous behavior — iterating a hardcoded KNOWN_PROVIDERS list, silently skipping unreachable providers, and falling back to an unusable placeholder amplifier model — is gone. Single-turn mode (amplifier-agent run) is unaffected. (#69)

  • POST /v1/chat/completions now validates model against the served registry. Requests with an unknown model return HTTP 400 {"error": {"code": "unknown_model", ...}} immediately, instead of being silently routed to whichever provider loaded first and failing 4 seconds later with an upstream not_found_error embedded in delta.content. (#69)

  • stream: false is now honored. Requests with that flag return a single JSON body; only stream: true (or absent) uses SSE. (#69)

  • Upstream errors raised before any content chunks are emitted now surface as HTTP 502 with a structured OpenAI-shape error envelope, instead of being embedded inside delta.content of a 200 SSE response. (Mid-stream errors after the first chunk remain embedded in delta.content — once SSE starts, the status line is committed.) (#69)

  • /v1/models no longer falls back to a placeholder {"id": "amplifier", ...} entry. The lifespan guarantees served_models_registry is non-empty (or the server exits at boot), so the fallback was unreachable in practice. (#69)

  • Lifespan provider iteration now reads from host_config.providers instead of the hardcoded KNOWN_PROVIDERS catalog. The CLI's KNOWN_PROVIDERS constant stays defined for single-turn mode and other CLI commands. (#69)

  • /v1/models response surfaces a _provider tag per model so OpenAI-compatible clients can see which provider serves each entry. (#65)

  • Usage-counter telemetry in chat-completions responses correctly reflects the provider that actually served the turn. (#65)

Wire protocol

Unchanged at 0.3.0 — no wrapper bump. TypeScript wrapper stays at 0.7.0, Python wrapper stays at 0.3.0.

Migration

Existing server-mode users (anyone running amplifier-agent serve chat-completions on a 0.7.x or pre-#69 0.8.0 commit): Add a providers block to your host_config.json. Minimum to keep working with just Anthropic:

{
  "providers": {
    "anthropic": {}
  }
}

Multi-provider example:

{
  "providers": {
    "anthropic": {},
    "openai":    {"config": {"base_url": "https://api.openai.com/v1"}}
  }
}

Without host_config.providers, the server will exit at boot with a clear error message rather than running in a broken half-state.

No other breaking changes. Existing CLI (run, models list), JSON-RPC wire, single-turn mode, and HTTP clients reading standard OpenAI fields all continue to work.

See CHANGELOG.md [0.8.0] for full details.

v0.7.0

17 Jun 18:59
cef3fb5

Choose a tag to compare

What's Changed

  • feat(wrapper-py): replace amplifier-agent-client with amplifier-agent-py at protocol 0.3.0 by @manojp99 in #56
  • refactor(persistence): align cwd-derived workspace slug with amplifier-app-cli by @manojp99 in #57
  • docs: scrub README + add AGENTS.md by @manojp99 in #58
  • feat(engine): replace built-in bundle with vendored behavioral-anchor by @manojp99 in #59
  • chore(release): bump engine to 0.7.0 by @manojp99 in #63

Full Changelog: v0.6.0...v0.7.0

What's Changed

  • feat(wrapper-py): replace amplifier-agent-client with amplifier-agent-py at protocol 0.3.0 by @manojp99 in #56
  • refactor(persistence): align cwd-derived workspace slug with amplifier-app-cli by @manojp99 in #57
  • docs: scrub README + add AGENTS.md by @manojp99 in #58
  • feat(engine): replace built-in bundle with vendored behavioral-anchor by @manojp99 in #59
  • chore(release): bump engine to 0.7.0 by @manojp99 in #63
  • feat(routing): integrate model routing with per-provider matrix selection by @manojp99 in #64

Full Changelog: v0.6.0...v0.7.0

v0.6.0

12 Jun 20:30
dc535ac

Choose a tag to compare

What's Changed

  • feat(streaming-hook): enrich wire events with cost, LLM timing, model, thinking, and sub-agent attribution by @manojp99 in #45
  • feat: workspace identity + per-workspace storage + context-intelligence hook (with fork-pin disclosure) by @manojp99 in #46
  • Feat/workspace implementation by @manojp99 in #47
  • feat: structured NDJSON wire-event consumption, --workspace forwarding, prepare script by @manojp99 in #48
  • feat(storage): unify on ~/.amplifier-agent, drop XDG path resolution by @manojp99 in #50
  • feat: model/effort overrides + models list discovery command by @manojp99 in #49
  • feat(cli): default --output to text, reject conflicting flag combinations by @manojp99 in #51
  • refactor(migration): make migrations user-invoked via 'amplifier-agent migrate' by @manojp99 in #52
  • feat(wrapper-ts): add listAllModels() for aggregate provider discovery by @manojp99 in #54
  • chore(release): bump engine to 0.6.0 and TS wrapper to 0.7.0 by @manojp99 in #55

Full Changelog: v0.5.2...v0.6.0

wrapper-v0.7.0

12 Jun 20:30
dc535ac

Choose a tag to compare

wrapper-v0.7.0 Pre-release
Pre-release

What's Changed

  • feat(streaming-hook): enrich wire events with cost, LLM timing, model, thinking, and sub-agent attribution by @manojp99 in #45
  • feat: workspace identity + per-workspace storage + context-intelligence hook (with fork-pin disclosure) by @manojp99 in #46
  • Feat/workspace implementation by @manojp99 in #47
  • feat: structured NDJSON wire-event consumption, --workspace forwarding, prepare script by @manojp99 in #48
  • feat(storage): unify on ~/.amplifier-agent, drop XDG path resolution by @manojp99 in #50
  • feat: model/effort overrides + models list discovery command by @manojp99 in #49
  • feat(cli): default --output to text, reject conflicting flag combinations by @manojp99 in #51
  • refactor(migration): make migrations user-invoked via 'amplifier-agent migrate' by @manojp99 in #52
  • feat(wrapper-ts): add listAllModels() for aggregate provider discovery by @manojp99 in #54
  • chore(release): bump engine to 0.6.0 and TS wrapper to 0.7.0 by @manojp99 in #55

Full Changelog: v0.5.2...wrapper-v0.7.0

v0.5.2

09 Jun 04:02
daec637

Choose a tag to compare

What's Changed

  • fix: make timeout opt-in instead of silently imposing 10-min wall-clock cap by @bkrabach in #41
  • fix(runtime): repair orphaned tool calls in resumed transcripts by @manojp99 in #43
  • chore: bump amplifier-agent to 0.5.2 by @manojp99 in #44

New Contributors

Full Changelog: v0.5.1...v0.5.2

wrapper-v0.6.2

08 Jun 18:59

Choose a tag to compare

wrapper-v0.6.2 Pre-release
Pre-release

What's Changed

  • fix: make timeout opt-in instead of silently imposing 10-min wall-clock cap by @bkrabach in #41

New Contributors

Full Changelog: v0.5.1...wrapper-v0.6.2

v0.5.1 — hooks-approval unmounted from default bundle

05 Jun 13:04
0c69c88

Choose a tag to compare

Highlights

hooks-approval is no longer mounted by default. Per the upstream USAGE_GUIDE"Backward compatible — Tools work without approval hook." — the module is opt-in. The engine's default bundle had been mounting it unconditionally, which caused sub-session delegation to auto-deny any command that fell outside the bundled DEFAULT_RULES auto-approve list (e.g. cat, env, curl).

What changed

  • Removed hooks-approval from the default bundle composition (src/amplifier_agent_lib/bundle/bundle.md)
  • Updated admin/doctor.py to drop the hooks-approval presence check (it would have permanently failed post-unmount)
  • Updated tests/test_admin_doctor_phase2.py to match the new doctor expectations
  • Added ISSUES.md tracking the deferred work needed to re-wire hooks-approval end-to-end in the future (5 concrete pieces — see ISSUE-001)
  • Bumped pyproject.toml: 0.5.00.5.1

The LICENSE is unchanged. Pre-PR 0.5.0-era sessions remain resumable but delegation flows will still hit the old auto-deny behavior on those sessions; start a fresh session to get the new behavior.

How to install

uv tool install --reinstall --force git+https://github.com/microsoft/amplifier-agent@v0.5.1

Compatibility

  • Wire protocol: 0.3.0 (unchanged from 0.5.0)
  • amplifier-agent-ts wrapper: >= 0.6.1
  • Hosts: any caller using host_config.approval.mode = "yes" or passing -y works unchanged

Why this matters

For hosts running headless (paperclip, CI/CD), the engine no longer requires a separate hooks-approval registration step. For interactive CLI use, add hooks-approval to your profile per the USAGE_GUIDE.

Reference

🤖 Generated with Amplifier

What's Changed

  • feat(wrapper-ts)!: hardening release 0.6.0 (NDJSON events, configPath, approval, getEngineInfo, +5 more) by @manojp99 in #36
  • fix(wrapper-ts): transport test timeout for CI (v0.6.1, supersedes failed 0.6.0 publish) by @manojp99 in #37
  • feat(cli): amplifier-agent update subcommand (v0.5.0) by @manojp99 in #38
  • fix(bundle): unmount hooks-approval from default mount (v0.5.1) by @manojp99 in #40

Full Changelog: v0.4.1...v0.5.1

v0.4.1

04 Jun 00:39
99abe41

Choose a tag to compare

What's Changed

  • fix(packaging): drop non-existent uv workspace members (v0.4.1) by @manojp99 in #35

Full Changelog: v0.4.0...v0.4.1

v0.4.0

03 Jun 21:10
caa9d45

Choose a tag to compare

What's Changed

  • fix(catalog): default openai to gpt-5.5 (matches bundle's extended_thinking=true) by @manojp99 in #20
  • docs(readme): align with Mode A pivot, protocol 0.2.0, and shipped L3 wrappers by @manojp99 in #21
  • fix(cli,lib): wire PROTOCOL_VERSION import + track pyproject for version by @manojp99 in #22
  • fix(cli): align Azure provider env var with docs (prefer AZURE_OPENAI_API_KEY, accept legacy AZURE_OPENAI_KEY) by @manojp99 in #23
  • chore(deps-dev): Bump vitest from 1.6.1 to 4.1.0 by @dependabot[bot] in #26
  • fix(wire): align all sites to protocol 0.2.0 (--mcp-config-path, schema rename, fixture bump) by @manojp99 in #24
  • docs: add canonical Microsoft Trademarks section to README by @sadlilas in #28
  • feat: host config layer + drop hostCapabilities surface by @manojp99 in #27
  • chore(cli)!: drop --mcp-config-path argv flag (subsumed by host config + env var) by @manojp99 in #29
  • feat: host-config skills: block (D11/D12/D13) + tool-skills bundle composition by @manojp99 in #30
  • chore(wrappers)!: drop env-allowlist, env-extra, allow-protocol-skew from wrappers (sync with engine) by @manojp99 in #31
  • chore(conformance): restore wrapper-engine cross-validation (post-#24, #27, #29, #31) by @manojp99 in #32
  • feat: engine-hardening — fail-fast on headless approval ambiguity (G3) + mcp engine dependency (G4) + host_config schema reference (N1/N2) by @manojp99 in #34
  • chore!: release 0.4.0 — host config layer, surface cleanup, conformance restored by @manojp99 in #33

New Contributors

Full Changelog: wrapper-v0.4.0...v0.4.0