Skip to content

Architecture Overview

Amplifier is built on a modular architecture inspired by the Linux kernel model. This page provides a comprehensive overview of how all the pieces fit together.

The Linux Kernel Analogy

Amplifier mirrors Linux kernel concepts:

Linux Concept Amplifier Analog Purpose
Ring 0 kernel amplifier-core Mechanisms only, never policy
Syscalls Session operations Few, sharp APIs
Loadable drivers Modules Compete at edges
Signals/Netlink Event bus / hooks Observe and control
/proc & dmesg JSONL logs Single canonical stream
Capabilities Approval system Deny-by-default
Scheduler Orchestrator modules Swap execution strategies
VM/Memory Context manager Conversation memory

System Layers

Layer 1: Application

The application layer (e.g., amplifier-app-cli) handles:

  • User interaction (CLI, REPL)
  • Configuration resolution (profiles, settings)
  • Mount Plan creation
  • Approval and display systems
# Application creates Mount Plan
mount_plan = compile_profile_to_mount_plan(profile)

# Application creates session
session = AmplifierSession(mount_plan)
await session.initialize()
response = await session.execute(prompt)

Layer 2: Kernel

The kernel (amplifier-core, ~2,600 lines) provides:

  • Mount Plan validation
  • Module discovery and loading
  • Session lifecycle management
  • Event emission
  • Coordinator infrastructure
# Kernel validates and loads
session.validate_mount_plan(mount_plan)
await session.load_modules()

# Kernel coordinates
coordinator.mount("providers", provider, name="anthropic")
await coordinator.hooks.emit("session:start", data)

Layer 3: Modules

Modules implement specific functionality:

  • Providers: LLM API integrations
  • Tools: Agent capabilities
  • Orchestrators: Execution strategies
  • Contexts: Memory management
  • Hooks: Observability and control
# Module implements contract
class AnthropicProvider:
    async def complete(self, request: ChatRequest) -> ChatResponse:
        # Provider-specific implementation
        ...

Component Relationships

┌─────────────────────────────────────────────────────────────────┐
│                        Application                               │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐             │
│  │   Profiles  │  │   Config    │  │  Collections│             │
│  └──────┬──────┘  └──────┬──────┘  └──────┬──────┘             │
│         │                │                │                      │
│         └────────────────┼────────────────┘                      │
│                          │                                       │
│                          ▼                                       │
│                   ┌─────────────┐                                │
│                   │ Mount Plan  │                                │
│                   └──────┬──────┘                                │
└──────────────────────────┼──────────────────────────────────────┘
┌──────────────────────────┼──────────────────────────────────────┐
│                        Kernel                                    │
│                   ┌─────────────┐                                │
│                   │   Session   │                                │
│                   └──────┬──────┘                                │
│                          │                                       │
│                          ▼                                       │
│                   ┌─────────────┐                                │
│                   │ Coordinator │                                │
│                   └──────┬──────┘                                │
│         ┌────────────────┼────────────────┐                      │
│         ▼                ▼                ▼                      │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐             │
│  │   Loader    │  │    Hooks    │  │   Events    │             │
│  └─────────────┘  └─────────────┘  └─────────────┘             │
└──────────────────────────┼──────────────────────────────────────┘
┌──────────────────────────┼──────────────────────────────────────┐
│                       Modules                                    │
│  ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐       │
│  │ Providers │ │   Tools   │ │Orchestratr│ │  Context  │       │
│  └───────────┘ └───────────┘ └───────────┘ └───────────┘       │
│                                                                  │
│  ┌───────────────────────────────────────────────────────┐      │
│  │                        Hooks                           │      │
│  │  ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐     │      │
│  │  │ Logging │ │ Approval│ │Redaction│ │Streaming│     │      │
│  │  └─────────┘ └─────────┘ └─────────┘ └─────────┘     │      │
│  └───────────────────────────────────────────────────────┘      │
└─────────────────────────────────────────────────────────────────┘

Session Execution Flow

User Prompt
┌─────────────────────────────────────────────────────────────┐
│ 1. Session receives prompt                                   │
│    emit("prompt:submit", {prompt})                          │
└──────┬──────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 2. Orchestrator takes control                                │
│    orchestrator.execute(prompt, context, providers, tools)  │
└──────┬──────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 3. Add prompt to context                                     │
│    context.add_message({role: "user", content: prompt})     │
└──────┬──────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 4. Call provider                                             │
│    emit("provider:request", {...})                          │
│    response = provider.complete(messages)                    │
│    emit("provider:response", {...})                         │
└──────┬──────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 5. Process tool calls (if any)                               │
│    for tool_call in response.tool_calls:                    │
│        emit("tool:pre", {...})                              │
│        result = tool.execute(input)                         │
│        emit("tool:post", {...})                             │
│        context.add_message({role: "tool", ...})             │
│    → Loop back to step 4 if more tool calls                 │
└──────┬──────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 6. Return final response                                     │
│    emit("prompt:complete", {...})                           │
│    return response.text                                      │
└─────────────────────────────────────────────────────────────┘

Key Design Decisions

Why a Tiny Kernel?

  1. Stability: Fewer changes = fewer breaking changes
  2. Auditability: Can be reviewed in an afternoon
  3. Maintainability: Single-throat-to-choke ownership
  4. Flexibility: All innovation happens at edges

Why Module Contracts?

  1. Independence: Modules develop independently
  2. Swappability: Replace any module without touching others
  3. Testing: Mock modules for isolated testing
  4. Competition: Multiple implementations can compete

Why Events?

  1. Observability: Everything important is observable
  2. Decoupling: Emitters don't know about observers
  3. Debugging: Complete audit trail
  4. Extensions: Add behavior via hooks, not code changes

Libraries

Supporting libraries provide higher-level functionality:

Library Purpose
amplifier-profiles Profile loading and inheritance
amplifier-collections Collection discovery and management
amplifier-config Three-scope configuration
amplifier-module-resolution Module source resolution

These libraries are not part of the kernel—they're application-layer concerns.

For Different Audiences

Now that you understand the architecture, here's where to go based on what you want to do:

I Want to Use Amplifier

→ Start with Getting Started
→ Read CLI User Guide for the amplifier-app-cli application

I Want to Extend Amplifier with Modules

→ Read this Architecture section to understand the system
→ Follow Module Developer Guide for creating custom providers, tools, hooks

I Want to Build Applications on Amplifier

→ Read this Architecture section to understand the foundation
→ Follow Application Developer Guide for building apps on amplifier-core
→ Study Foundation Guide for using the core and libraries

I Want to Contribute to Amplifier Core

→ Read this Architecture section + Kernel Philosophy
→ Follow Foundation Developer Guide for working with the kernel and libraries
→ See Contributing for contribution guidelines

Next Steps

References