Decomposing the AI agent monolith into composable microservices — JSON-RPC today, Dapr-native containers tomorrow.
Every tool, hook, and provider shares a single process. One package conflict breaks everything. Anthropic SDK pins clash with OpenAI pins.
Dynamic import_and_create() machinery ties every component to Python. No path to Rust tools, Go providers, or TypeScript hooks.
A crashing tool takes down the entire agent session. No process isolation means no fault boundaries.
The in-process architecture that got Amplifier to v1 becomes the ceiling that prevents v2. Every component shares memory, shares dependencies, shares fate.
Every component runs as its own subprocess. A central Host routes messages over JSON-RPC 2.0 via stdio. Fresh processes per turn — no stale state, no concurrency bugs.
Host spawns all service subprocesses from isolated uv virtualenvs. Each service gets its own dependency tree. ~200ms startup cost, paid once per turn.
Host sends describe to every service — builds a routing table of tools, hooks, providers, and content manifests. No static config needed.
Orchestrator drives the agent loop. All tool calls, provider requests, and hook events flow through the Host as a dumb message bus. Fan-out, chaining, parallel dispatch.
Turn completes. SIGTERM all services, SIGKILL after timeout. Next turn starts fresh — clean processes, clean state, zero stale memory.
User-facing entry point — Click + Rich + prompt-toolkit
Dumb message bus — spawns services, routes requests, persists transcripts
Agent loop driver — calls providers, tools, hooks via JSON-RPC
LLM adapters — Anthropic, OpenAI, Azure, Gemini, Ollama, and more. Each in its own subprocess with its own SDK version.
File I/O, search, bash, web, delegation, tasks, todos. Parallel dispatch via asyncio.gather across service boundaries.
Logging, redaction, modes, routing, progress monitoring. Priority-ordered fan-out with DENY/MODIFY/INJECT semantics.
The Host does NOT interpret hook results, drive the agent loop, hold conversation state, or call LLMs. It's a router. The orchestrator owns all logic.
Orchestrator, context manager, core tools, hooks — the kitchen sink behavior
8 LLM provider adapters with streaming support
Runtime mode overlays — tool + hook for mode switching
Domain knowledge discovery and loading
Model routing via curated matrices
Content-only — recipe definitions
Content-only — core context docs
amplifier-amplifier, filesystem, browser-tester, design-intelligence, superpowers, system-design-intelligence
A service is a Python package that exposes components via decorators. The host discovers components automatically — no YAML registration of individual tools. Just decorate your classes and describe finds them.
The next evolution: replace the entire IPC layer with Dapr-native microservices. Every behavior becomes its own container.
28,262 lines of tests covering 26,300 lines of source across 147 test files. The protocol library has zero external dependencies — pure Python.
394 of 407 commits by Paul Payne (payneio) between March 20–30, 2026 — a complete IPC rewrite in 10 days, with AI-assisted development.
A crashing tool can't take down the orchestrator. Each service has its own memory space, its own dependencies, its own fault boundary.
Services are born fresh and die clean every turn. No stale state, no memory leaks, no concurrency bugs. Process startup (~200ms) is the only cost.
JSON-RPC 2.0 over stdio today, standard HTTP tomorrow. Write tools in Rust, hooks in Go, providers in TypeScript. The wire format doesn't care.
Agent definitions compose behaviors by URL. Each behavior activates components from services. Mix and match orchestrators, tools, and hooks freely.
Each service gets its own uv virtualenv. Anthropic SDK v0.40 and OpenAI SDK v1.60 coexist without conflict. No diamond dependency problem.
The IPC boundary is the future network boundary. Today's subprocess becomes tomorrow's container. Business logic doesn't change — only the transport.
Sessions survive across turns. Resume with amplifier-ipc session resume <id>. Full transcript history in ~/.amplifier/sessions.
Settings merge from global (~/.amplifier/settings.yaml), project (.amplifier/settings.yaml), and local (.amplifier/settings.local.yaml).
Repository: payneio/amplifier-ipc (GitHub)
amplifier-ipc-protocol sub-package definitionsCode analysis:
host/host.py (1,295 lines), protocol/server.py (884 lines), host/spawner.py (560 lines), host/router.py (295 lines)services/, each with its own pyproject.tomlGit history: git log --all — 407 commits, March 20–30, 2026. 394 by Paul Payne, 13 by Amplifier Implementer.
Team knowledge: Amplifier team knowledge base — capability entries for all 13 IPC services plus the amplifier-ipc-protocol package, and the architecture overview DOT diagram.
Category: Architecture & Philosophy · Primary contributor: payneio · Accent: #42A5F5 (infrastructure blue)