diff --git a/bundles/amplifier-bundle-agent-adapter-designer/README.md b/bundles/amplifier-bundle-agent-adapter-designer/README.md new file mode 100644 index 00000000..172b461f --- /dev/null +++ b/bundles/amplifier-bundle-agent-adapter-designer/README.md @@ -0,0 +1,169 @@ +# amplifier-bundle-agent-adapter-designer + +An Amplifier bundle providing a **self-sufficient design workspace** for developers +integrating [`amplifier-agent`](https://github.com/microsoft/amplifier-agent) into +host applications. + +## What it does + +When you compose this bundle (or activate its mode), you get a focused workspace for +designing an `amplifier-agent` host adapter end-to-end. You come out the other side +with a concrete adapter design document covering your chosen integration surface, +borrowed patterns from real host adapters, cross-cutting decisions, and a risk register. + +### Coverage + +**Three integration surfaces:** +- `amplifier-agent-py` — Python Client SDK (single-turn subprocess) +- `amplifier-agent-ts` — TypeScript Client SDK (single-turn subprocess, Node >=20) +- `amplifier-agent serve chat-completions` — HTTP server (OpenAI-compatible sidecar) + +**Three host adapter case studies:** +- **opencode** → HTTP face: auto-start + model discovery + config-write pattern +- **paperclip** → TypeScript SDK: adapter registry + per-turn spawn + workspace isolation +- **nanoclaw** → TypeScript SDK in Docker: build-time priming + MCP passthrough + CI version-lint + +**All cross-cutting concerns:** credentials, MCP injection, bundle cache priming, protocol +version pinning, workspace isolation, env allowlist, binary discovery, multi-turn patterns, +DisplayEvent stream handling. + +--- + +## Usage + +### Activate the design mode + +``` +/mode amplifier-agent-adapter-designer +``` + +The mode is **self-sufficient** — it carries the full picture of surfaces, case studies, +and concerns. A fresh session entering the mode needs no prior context to begin productive +adapter design. + +The mode guides you through: +1. Host runtime characterization +2. Surface selection (with trade-off analysis) +3. Pattern borrowing from the closest case study +4. Cross-cutting checklist +5. Risk register +6. Producing a structured adapter design document (`adapter-design.md`) + +### Or delegate to the expert agent directly + +For a specific question without entering the full design mode: + +``` +delegate to agent-adapter-designer:adapter-design-expert + with: "Which surface fits a FastAPI host? What are the gotchas?" +``` + +--- + +## Architecture + +``` +bundle.md (thin) +├── behaviors/agent-adapter-designer.yaml # Wires agent + awareness context +│ ├── agents/adapter-design-expert.md # Context sink: full integration reference +│ └── context/adapter-design-awareness.md # Thin pointer (~200 tokens, always-loaded) +├── modes/amplifier-agent-adapter-designer.md # User-facing entry point +└── context/integration-reference.md # Full knowledge base (agent-only, ~2500 tokens) +``` + +### Context-sink discipline + +The full integration reference (~2,500 tokens: all surfaces, case studies, cross-cutting +concerns) lives in the **agent's context**. It is only loaded when the expert agent is +spawned — never in the root session or mode injection. Root sessions carry only the thin +awareness pointer (~200 tokens). + +This means: +- **Mode active**: ~900 tokens ephemeral injection (mode body) + ~200 tokens awareness +- **Agent delegated**: ~2,500 tokens in child session (disposable after agent completes) +- **No mode, no delegation**: ~200 tokens only + +--- + +## Mechanism mix + +| Mechanism | Name | Purpose | +|-----------|------|---------| +| Mode | `amplifier-agent-adapter-designer` | Design conversation, tool policies, workflow, document template | +| Agent | `adapter-design-expert` | Context sink: full integration reference, precise Q&A | +| Context (thin) | `adapter-design-awareness.md` | Root session pointer (~200 tokens, always) | +| Context (heavy) | `integration-reference.md` | Full knowledge base (agent-only, ~2500 tokens) | +| Behavior | `agent-adapter-designer-behavior` | Wires agent + awareness into composed sessions | + +**No recipe**: Design conversations are inherently interactive. A rigid multi-step recipe +would reduce the flexibility developers need when exploring unfamiliar integration surfaces. + +**No skill**: The agent covers all reference and reasoning needs. A skill would duplicate +the agent at higher per-turn visibility cost without additional capability. + +--- + +## Loading the bundle + +Add to your bundle's `includes:`: + +```yaml +includes: + - bundle: git+https://github.com/microsoft/amplifier-bundle-agent-adapter-designer@main +``` + +Or run standalone: + +```bash +amplifier run \ + --bundle git+https://github.com/microsoft/amplifier-bundle-agent-adapter-designer@main \ + "Help me design an amplifier-agent host adapter" +``` + +--- + +## Tool policies (design mode) + +The mode enforces a design-conversation-appropriate tool surface: + +| Policy | Tools | +|--------|-------| +| `safe` | `read_file`, `glob`, `grep`, `delegate`, `web_fetch`, `todo`, `load_skill`, `mode` | +| `warn` (1 confirmation) | `bash`, `write_file`, `edit_file` | +| `block` | Everything else | + +Shell commands (`bash`) and file writes (`write_file`, `edit_file`) require one +acknowledgment step. This prevents accidental file creation during a design conversation +while still allowing the final `write_file` call for the design document. + +--- + +## Repository structure + +``` +amplifier-bundle-agent-adapter-designer/ +├── bundle.md # Thin root bundle +├── README.md # This file +├── behaviors/ +│ └── agent-adapter-designer.yaml # Behavior: agent + awareness context +├── agents/ +│ └── adapter-design-expert.md # Expert agent (context sink) +├── context/ +│ ├── adapter-design-awareness.md # Thin awareness pointer +│ └── integration-reference.md # Full integration reference (agent-only) +├── modes/ +│ └── amplifier-agent-adapter-designer.md # Design mode +└── docs/ + └── BEHAVIORAL_MODEL.md # Pre-implementation verification artifact +``` + +--- + +## Design philosophy notes + +This bundle was designed following the Amplifier bundle lifecycle: +1. **Mechanism design** → Mode + Agent (context sink) + thin awareness context +2. **Behavioral model** → 10 scenarios covering surface selection, case study reference, cross-cutting concerns, design document production, and edge cases (wrong surface, env allowlist blocker, protocol mismatch) +3. **Verification** → Scenarios reviewed before implementation + +See `docs/BEHAVIORAL_MODEL.md` for the full behavioral model, including assumptions and known gaps. diff --git a/bundles/amplifier-bundle-agent-adapter-designer/agents/adapter-design-expert.md b/bundles/amplifier-bundle-agent-adapter-designer/agents/adapter-design-expert.md new file mode 100644 index 00000000..726ce967 --- /dev/null +++ b/bundles/amplifier-bundle-agent-adapter-designer/agents/adapter-design-expert.md @@ -0,0 +1,128 @@ +--- +meta: + name: adapter-design-expert + description: | + Authoritative expert on integrating amplifier-agent into host applications. + Carries the complete integration reference: all three surfaces, three host + adapter case studies, and all cross-cutting concerns. + + Use PROACTIVELY when the conversation needs: + - Surface selection recommendation (Python SDK vs TypeScript SDK vs HTTP server) + - Trade-off analysis when the right surface isn't obvious + - Deep detail on opencode, paperclip, or nanoclaw adapter patterns + - Specific API signatures, function names, or env var names + - Cross-cutting concern guidance: credentials, MCP injection, bundle priming, + protocol version pinning, workspace isolation, env allowlist, binary discovery + - DisplayEvent stream handling patterns + - Review of a draft adapter design document for gaps or risks + + **Authoritative on:** amplifier-agent-py, amplifier-agent-ts, chat-completions + server, opencode adapter, paperclip adapter, nanoclaw adapter, + PROTOCOL_VERSION_REQUIRED_BY_WRAPPER, spawn_agent, spawnAgent, + ChildProcessFactory, AMPLIFIER_MCP_CONFIG, AMPLIFIER_AGENT_BIN, + AMPLIFIER_AGENT_HTTP_API_KEY, workspace slug, bundle cache priming, + amplifier-agent prepare, env allowlist, env_injection_rejected, + DisplayEvent, allowProtocolSkew, resume turn, push buffering + + Examples: + + + user: 'My host is a FastAPI service. Which integration surface should I use?' + assistant: 'I will delegate to adapter-design-expert for a specific, evidence-backed + recommendation for your Python stack.' + Python host → Python SDK. Expert confirms with API details and surfaces + gotchas (not on PyPI, protocol pin). Never gives vague "it depends" answers. + + + + user: 'How did nanoclaw handle the cold-start problem in their Docker product?' + assistant: 'Let me delegate to adapter-design-expert — it has the full nanoclaw case study.' + Case study question requires the nanoclaw pattern layers: build-time install, + prepare + doctor RUN steps, CI version-lint gate. Expert cites exactly. + + + + user: 'What env vars are blocked when I use env.extra?' + assistant: 'I will use adapter-design-expert to give you the exact allowlist and blocklist.' + Precise technical question. Expert has the exact list and the error name + (env_injection_rejected). No guessing needed. + + + + user: 'I have a draft adapter design. Can you review it for gaps?' + assistant: 'I will delegate to adapter-design-expert to review the draft systematically + against known cross-cutting concerns and case study patterns.' + Design review requires checking all 10 cross-cutting concerns. Expert + knows which items are commonly omitted (bundle priming, workspace slug, MCP method). + + + + user: 'My TypeScript host already calls the OpenAI API. What is the fastest path to integration?' + assistant: 'This sounds like an HTTP face case. Let me delegate to adapter-design-expert to + confirm and explain the opencode-pattern integration.' + OpenAI-shaped host → HTTP face. Expert explains auto-start + model discovery + + config-write pattern from opencode. + + model_role: [reasoning, general] +--- + +# Adapter Design Expert + +You are an authoritative expert on integrating `amplifier-agent` into host applications. +You carry the complete integration reference — all three surfaces, all three host adapter +case studies, and every cross-cutting concern — and answer questions with precision +and evidence. You do not speculate; you cite the source material. + +**Execution model:** You run as a one-shot sub-session. Return a complete, structured +answer. The parent session needs your response to be immediately actionable. + +## Your Role + +Answer questions developers have when designing a host adapter for `amplifier-agent`: + +1. **Surface recommendation** — Given the host's runtime, requirements, and constraints, + which surface fits? Always explain what the recommended surface is wrong for. + +2. **Case study reference** — How did opencode, paperclip, or nanoclaw approach a specific + problem? Cite the exact pattern layer (e.g., "nanoclaw pattern 2: `amplifier-agent prepare` + + `doctor --strict` as Dockerfile RUN steps"). + +3. **Cross-cutting guidance** — Specific and unambiguous: name the env var, function, + constant, or error code. Never say "it depends" without following up with the actual + answer for the specific case. + +4. **Design review** — Given a draft adapter design, check it systematically against + the cross-cutting checklist. Flag gaps. Suggest the closest case study pattern for + any unaddressed concern. + +## Answer Principles + +- **Name everything.** `AMPLIFIER_MCP_CONFIG`, not "an env var". `PROTOCOL_VERSION_REQUIRED_BY_WRAPPER`, + not "a version constant". `env_injection_rejected`, not "an error". +- **Cite case studies.** When a pattern matches something opencode/paperclip/nanoclaw did, + name the adapter and describe the pattern layer. +- **Surface wrong cases.** Every surface recommendation MUST include when it's wrong. +- **Flag gotchas.** Protocol skew, env allowlist blocklist, cold-start cliff, MCP injection + method, workspace slug grammar — mention when they apply to the question. +- **Distinguish v1 limitations.** Several limitations apply to v1 of the HTTP face: + no per-request MCP, no HITL approval, no per-request workspace isolation. Say "in v1" + explicitly so the developer knows to watch for changes in future versions. + +## Output Contract + +Every response MUST include: +- A direct answer to the question asked +- Specific names (API function, env var, constant, error code, endpoint) when applicable +- A "When wrong" or "Trade-offs" section when recommending a surface (always) +- A "Gotchas" section when cross-cutting concerns apply + +Mark any section N/A when it genuinely does not apply (e.g., a pure factual lookup +of an env var name needs no trade-offs section). + +--- + +@agent-adapter-designer:context/integration-reference.md + +--- + +@foundation:context/shared/common-agent-base.md diff --git a/bundles/amplifier-bundle-agent-adapter-designer/behaviors/agent-adapter-designer.yaml b/bundles/amplifier-bundle-agent-adapter-designer/behaviors/agent-adapter-designer.yaml new file mode 100644 index 00000000..c61a210d --- /dev/null +++ b/bundles/amplifier-bundle-agent-adapter-designer/behaviors/agent-adapter-designer.yaml @@ -0,0 +1,15 @@ +bundle: + name: agent-adapter-designer-behavior + version: 1.0.0 + description: >- + Behavior adding amplifier-agent adapter design expertise to a session. + Provides the expert agent (context sink for full integration reference) + and a thin awareness pointer for root sessions. + +agents: + include: + - agent-adapter-designer:adapter-design-expert + +context: + include: + - agent-adapter-designer:context/adapter-design-awareness.md diff --git a/bundles/amplifier-bundle-agent-adapter-designer/bundle.md b/bundles/amplifier-bundle-agent-adapter-designer/bundle.md new file mode 100644 index 00000000..0481b49a --- /dev/null +++ b/bundles/amplifier-bundle-agent-adapter-designer/bundle.md @@ -0,0 +1,30 @@ +--- +bundle: + name: agent-adapter-designer + version: 1.0.0 + description: >- + Design workspace for integrating amplifier-agent into host applications. + Provides surface selection guidance, host adapter case study patterns, + cross-cutting concern coverage, and produces a concrete adapter design document. + Activate /mode amplifier-agent-adapter-designer to begin. + +includes: + - bundle: git+https://github.com/microsoft/amplifier-foundation@main + - bundle: agent-adapter-designer:behaviors/agent-adapter-designer +--- + +# amplifier-agent Adapter Designer + +This session is equipped for designing host adapter integrations for `amplifier-agent`. + +Activate the design mode to begin a guided, self-sufficient design conversation: + + /mode amplifier-agent-adapter-designer + +Or delegate directly to the expert agent for specific questions: + + delegate to agent-adapter-designer:adapter-design-expert + +--- + +@foundation:context/shared/common-system-base.md diff --git a/bundles/amplifier-bundle-agent-adapter-designer/context/adapter-design-awareness.md b/bundles/amplifier-bundle-agent-adapter-designer/context/adapter-design-awareness.md new file mode 100644 index 00000000..05a70b08 --- /dev/null +++ b/bundles/amplifier-bundle-agent-adapter-designer/context/adapter-design-awareness.md @@ -0,0 +1,30 @@ +# amplifier-agent Adapter Design + +This session can design host adapter integrations for `amplifier-agent` — +Microsoft's modular AI agent engine for embedding Amplifier inside host applications. + +## What this capability covers + +**Three integration surfaces:** +- **Python SDK** (`amplifier-agent-py`) — single-turn subprocess for Python hosts +- **TypeScript SDK** (`amplifier-agent-ts`) — single-turn subprocess for Node.js >=20 hosts +- **HTTP server** (`amplifier-agent serve chat-completions`) — OpenAI-compatible sidecar + +**Three host adapter case studies** with pattern-layer analysis: +- **opencode** — HTTP face (CLI, OpenAI-shaped host, auto-start + model discovery) +- **paperclip** — TypeScript SDK (Node SaaS, adapter registry pattern) +- **nanoclaw** — TypeScript SDK inside Docker (container product, build-time priming) + +**All cross-cutting concerns:** credentials, MCP injection, bundle cache priming, +protocol version pinning, workspace isolation, env allowlist, binary discovery, +multi-turn patterns, DisplayEvent handling. + +## Entry points + +**Design mode** (recommended) — self-sufficient workspace with design journey and document template: + + /mode amplifier-agent-adapter-designer + +**Expert agent** — direct access to the full integration reference: + + delegate to agent-adapter-designer:adapter-design-expert diff --git a/bundles/amplifier-bundle-agent-adapter-designer/context/integration-reference.md b/bundles/amplifier-bundle-agent-adapter-designer/context/integration-reference.md new file mode 100644 index 00000000..dee63005 --- /dev/null +++ b/bundles/amplifier-bundle-agent-adapter-designer/context/integration-reference.md @@ -0,0 +1,517 @@ +# amplifier-agent Integration Reference + +Complete reference for host adapter engineers integrating `amplifier-agent` into a +host application. Covers all three integration surfaces, all three host adapter +case studies, and all cross-cutting concerns. + +--- + +## Integration Surfaces + +### 1. Python Client SDK (`amplifier-agent-py`) + +**Summary**: Spawns `amplifier-agent` as a single-turn subprocess from a Python host. +The SDK manages process lifecycle; the host yields `DisplayEvent` objects from the +`submit()` call. + +#### API + +**Async (primary)**: +```python +from amplifier_agent_py import spawn_agent + +handle = await spawn_agent( + session_id="my-session-id", + display_mode="ndjson", # "ndjson" for JSON events; default is human text + workspace="my-app-", # optional workspace slug +) +async for event in handle.submit("User prompt here"): + # event is a DisplayEvent object + process(event) +``` + +**Sync (context-manager)**: +```python +from amplifier_agent_py import spawn_agent_sync + +with spawn_agent_sync(session_id="...", display_mode="ndjson") as handle: + for event in handle.submit("User prompt"): + process(event) +``` + +#### When Right +- Python hosts: Django, Flask, FastAPI, Celery workers, scripts, CLI tools +- Single-turn request/response model +- Need sync-compatible interface (context manager variant) + +#### When Wrong +- Node.js hosts (use TypeScript SDK instead) +- Multi-turn burst within a single subprocess call +- Mid-turn HITL approval callbacks +- Bidirectional streaming while the agent runs + +#### Protocol +Pinned to `0.3.0` via compiled constant `PROTOCOL_VERSION_REQUIRED_BY_WRAPPER`. +SDK probes engine with `amplifier-agent version --json` at startup. + +#### Install +Not yet on PyPI. Install from git source: +```bash +pip install git+https://github.com/microsoft/amplifier-agent-py.git +# or: +uv add git+https://github.com/microsoft/amplifier-agent-py.git +``` + +--- + +### 2. TypeScript Client SDK (`amplifier-agent-ts`) + +**Summary**: Equivalent subprocess model for Node.js hosts. Zero npm runtime +dependencies. Ships a `ChildProcessFactory` injection point for testing. + +#### API + +```typescript +import { spawnAgent } from 'amplifier-agent-ts'; +import { randomUUID } from 'crypto'; + +const session = await spawnAgent({ + lifecycle: 'one-shot', + sessionId: randomUUID(), + workspace: 'my-app-', // optional +}); + +for await (const ev of session.submit("User prompt here")) { + // ev is a DisplayEvent discriminated union + switch (ev.type) { + case 'text': handleText(ev); break; + case 'tool_call': handleToolCall(ev); break; + // ... + } +} +``` + +#### ChildProcessFactory (for testing/sandboxing) + +```typescript +import { spawnAgent, ChildProcessFactory } from 'amplifier-agent-ts'; + +const session = await spawnAgent({ + lifecycle: 'one-shot', + sessionId: randomUUID(), + processFactory: new MockChildProcessFactory(), // injected in tests +}); +``` + +#### When Right +- Node.js hosts (version >=20) +- TypeScript/JavaScript codebases +- Need process isolation with zero npm runtime dependencies +- Test-time subprocess injection via `ChildProcessFactory` + +#### When Wrong +- Python hosts (use Python SDK instead) +- In-process burst without subprocess overhead +- Mid-turn HITL approval callbacks (not supported in v1) + +#### Protocol +README in the repo says 0.1.0 — **this is outdated**. The source code says 0.3.0. +Trust the source: `PROTOCOL_VERSION_REQUIRED_BY_WRAPPER = "0.3.0"`. + +--- + +### 3. HTTP Chat-Completions Server + +**Summary**: OpenAI-compatible HTTP server. Start it as a sidecar; host connects to +it as any OpenAI client. Amortizes bundle-load cost across requests. + +#### Start + +```bash +amplifier-agent serve chat-completions \ + --port 9099 \ + --config /path/to/host_config.json +``` + +#### Endpoints + +| Endpoint | Method | Response | Notes | +|----------|--------|----------|-------| +| `/v1/chat/completions` | POST | SSE or JSON | Standard OpenAI shape | +| `/v1/models` | GET | OpenAI shape + extensions | Includes amplifier-specific metadata | + +#### Key Environment Variables + +| Var | Purpose | +|-----|---------| +| `AMPLIFIER_AGENT_HTTP_API_KEY` | Auth key required in `Authorization: Bearer` header | +| `AMPLIFIER_AGENT_HTTP_PORT` | Port override (default 9099) | +| `AMPLIFIER_AGENT_HTTP_BIND` | Bind address | +| `AMPLIFIER_AGENT_HTTP_WORKSPACE` | Workspace slug for all requests | +| `AMPLIFIER_AGENT_HTTP_CONFIG_PATH` | Override config file path | + +#### host_config.json requirement + +The `providers` block is **required**. Missing providers block → exit code 2. + +```json +{ + "providers": [ + { "name": "anthropic", "api_key": "${ANTHROPIC_API_KEY}" } + ] +} +``` + +#### When Right +- Host already speaks OpenAI API (minimal adaptation code) +- Multi-provider routing from a single endpoint +- Long-lived server amortizes bundle-load cost over many requests +- Host is language-agnostic or polyglot + +#### When Wrong +- Per-turn MCP injection (server-level only in v1; no per-request MCP) +- HITL approval (HTTP face auto-approves all tool confirmations in v1) +- Per-request workspace isolation (process-scope only; all requests share one workspace in v1) + +--- + +## Host Adapter Case Studies + +### opencode — HTTP Face + +**Integration surface**: HTTP chat-completions server + +**Architecture**: The opencode CLI spawns `amplifier-agent serve chat-completions` +as a background process, waits for it to become ready, then execs `opencode`. + +#### Pattern Layers + +1. **Auto-start + readiness poll**: CLI starts server, polls `GET /v1/models` until 200. +2. **Model discovery**: Reads model list from `/v1/models` endpoint. +3. **Config write**: Writes opencode `provider` block from discovered models (no manual config). +4. **Credential auto-detect**: Automatically detects 4 providers: Anthropic, OpenAI, Azure OpenAI, Ollama. +5. **Session correlation**: Client sends `X-Client-Session-Id` header; server returns `X-Session-Id`. + +#### Key Lesson + +When the host already speaks OpenAI API, HTTP face integration is nearly free. The host +needs almost zero adaptation code — it talks to amplifier-agent the same way it talks to +any OpenAI-compatible provider. Model discovery + config-write automation means the +developer doesn't even need to manually configure the opencode provider block. + +--- + +### paperclip — TypeScript SDK + +**Integration surface**: TypeScript Client SDK (`amplifier-agent-ts`) + +**Architecture**: Per-turn subprocess via `spawnAgent()`. amplifier-agent is one +provider in a mutable adapter registry — hosts can register/unregister adapters at +runtime without forking core. + +#### Pattern Layers + +1. **Adapter registry**: `registerServerAdapter()` / `registerUIAdapter()` at startup. + amplifier-agent is registered as one entry in this registry alongside other providers. +2. **Runtime validation**: Adapters are validated at registration time, not at call time. +3. **Per-turn spawn**: Each agent turn creates a fresh `spawnAgent()` subprocess. Stateless. +4. **Workspace-per-agent**: Workspace slug format: `pc--`. + Per-agent isolation prevents state cross-contamination. + +#### Key Lesson + +The adapter-registry pattern lets a host treat amplifier-agent as one provider among many +without touching core dispatch logic. When an agent is selected, the registry finds the +right adapter and calls it. amplifier-agent is just another adapter — no special-casing. +Workspace slug discipline (`pc--`) provides clean per-agent isolation. + +--- + +### nanoclaw — TypeScript SDK Inside Docker + +**Integration surface**: TypeScript Client SDK inside a Docker container product. + +**Architecture**: `AmplifierAgentProvider` implements NanoClaw's `AgentProvider` +interface. amplifier-agent is installed at image build time. + +#### Pattern Layers + +1. **Binary install at build**: `uv tool install amplifier-agent` in `Dockerfile`. + Binary is baked into the image. +2. **Bundle priming at build**: `amplifier-agent prepare` + `amplifier-agent doctor --strict` + as `Dockerfile RUN` steps. Bundle cache is warm before any user request. +3. **MCP passthrough**: Write MCP config to a 0600 tempfile; set `AMPLIFIER_MCP_CONFIG`. +4. **Host-mounted state volume**: amplifier-agent state directory is a Docker volume. + State persists across container restarts and upgrades. +5. **Push buffering**: Buffered event queue with cap=256. Visible-drop on overflow + (log + discard) to avoid backpressure deadlock. +6. **Chained turns with `resume: true`**: Multi-turn conversations resume previous session. +7. **Auto-allow approval**: HITL gates auto-approved for automated container flows. +8. **CI version-lint gate**: CI pipeline checks `amplifier-agent version --json` against + pinned version. Build fails if version drifts. + +#### Key Lesson + +Container integration means bundle cache cost is paid once at `docker build` (or image +pull) time, not at first user request. A warm `docker pull` starts instantly; a cold +`amplifier-agent` would take 5–30s. The CI version-lint gate catches silent engine upgrades +before they reach production. + +--- + +## Cross-Cutting Concerns + +### 1. Credential Management + +Provider keys are passed via environment variables: + +| Provider | Environment Variable(s) | +|----------|------------------------| +| Anthropic | `ANTHROPIC_API_KEY` | +| OpenAI | `OPENAI_API_KEY` | +| Azure OpenAI | `AZURE_OPENAI_API_KEY` + `AZURE_OPENAI_ENDPOINT` | +| Ollama | `OLLAMA_HOST` | + +**HTTP face**: `providers` block in `host_config.json` is **required**. Absent → exit code 2 +with a clear error. The `providers` block must list the keys explicitly (no env-var auto-detect +in v1 HTTP face). + +--- + +### 2. MCP Config Injection + +**Rule: Never a CLI flag.** + +``` +1. Write MCP config JSON to a 0600 tempfile +2. Set AMPLIFIER_MCP_CONFIG=/path/to/tmpfile +3. Launch amplifier-agent (SDK handles this; HTTP face: server-level only) +``` + +Python and TypeScript SDKs pass the tempfile path automatically when you use their +`mcpConfig` option. For the HTTP face in v1, MCP config is server-level only — you +cannot inject different MCP configs per-request. + +**nanoclaw pattern** (production-verified): +```typescript +const tmpfile = writeTempFile(JSON.stringify(mcpConfig), { mode: 0o600 }); +process.env.AMPLIFIER_MCP_CONFIG = tmpfile.path; +const session = await spawnAgent({ ... }); +``` + +--- + +### 3. Bundle Cache Priming + +**Cold-start cliff**: 5–30 seconds on first call (git clone ~11 module repos + pip install). + +**Cache location**: `~/.cache/amplifier-agent/prepared///` + +**Solutions by deployment type**: + +| Deployment | Pattern | +|------------|---------| +| `uv tool install` | `amplifier-agent-post-install` hook runs `prepare` automatically | +| Manual install | Run `amplifier-agent prepare` after install | +| Docker | Add `RUN amplifier-agent prepare && amplifier-agent doctor --strict` to Dockerfile | +| CI | Add prepare step after install in CI pipeline | + +After priming, subsequent starts are near-instant (bundle already materialized). + +--- + +### 4. Protocol Version Pinning + +SDKs verify engine compatibility at startup: + +```bash +amplifier-agent version --json +# → { "protocol_version": "0.3.0", ... } +``` + +Compiled constant in SDKs: `PROTOCOL_VERSION_REQUIRED_BY_WRAPPER = "0.3.0"` + +**Mismatch behavior** (Design D6 — strict refuse): +- Throws `AaaError(protocol_version_mismatch)` +- Error body contains exact reinstall commands (self-remediating error) +- No silent degradation + +**Override** (use sparingly): +```python +# Python +handle = await spawn_agent(..., allow_protocol_skew=True) +``` +```typescript +// TypeScript +const session = await spawnAgent({ ..., allowProtocolSkew: true }); +``` +Or set the env var (exact name varies by SDK version — check README). + +--- + +### 5. Binary Discovery Order + +**Resolution sequence** (first match wins): +1. `AMPLIFIER_AGENT_BIN` environment variable (absolute path) +2. `which amplifier-agent` (PATH lookup) + +No constructor parameter — binary path is NOT configurable in the SDK API. +Inspect the resolved path after startup: +```python +info = await handle.get_engine_info() +print(info.binary_path) +``` +```typescript +const info = await session.getEngineInfo(); +console.log(info.binaryPath); +``` + +--- + +### 6. Env Allowlist + +The subprocess only receives a restricted set of environment variables: + +**Always inherited**: `PATH HOME USER LANG TERM TMPDIR`, all `AMPLIFIER_*`, all `LC_*` + +**Extend with** `env.extra` in SDK config (key–value pairs). + +**Blocked in `env.extra`** (throws `env_injection_rejected`): +``` +PYTHONPATH +LD_PRELOAD +LD_LIBRARY_PATH +PYTHONSTARTUP +PYTHONHOME +PYTHONNOUSERSITE +DYLD_INSERT_LIBRARIES +DYLD_LIBRARY_PATH +``` + +If you need to pass these to the subprocess, set them in the parent process before +spawning the SDK — they will be inherited via the OS (not via `env.extra`). + +--- + +### 7. Workspace Isolation + +Route per-agent state via `--workspace `: + +**State path**: `~/.amplifier-agent/state/workspaces//sessions//` + +**Slug grammar**: `[a-z0-9][a-z0-9-]{0,63}` (starts with alphanumeric, up to 64 chars) + +**Rule**: Multi-agent hosts **MUST** set per-agent workspace slugs to prevent cross-contamination. + +| Host | Slug pattern | Example | +|------|-------------|---------| +| paperclip | `pc--` | `pc-acme-7f3a` | +| nanoclaw | host-mounted volume at workspace path | `nc-session-` | + +**Docker**: Mount the workspace directory as a Docker volume to persist state across +container restarts: +```dockerfile +VOLUME /root/.amplifier-agent/state/workspaces/ +``` + +--- + +### 8. Sync vs Async Ergonomics + +| SDK | Async | Sync | +|-----|-------|------| +| Python (`amplifier-agent-py`) | ✓ `await spawn_agent(...)` | ✓ `spawn_agent_sync(...)` context manager | +| TypeScript (`amplifier-agent-ts`) | ✓ `await spawnAgent(...)` | ✗ async-only | + +Neither SDK supports mid-turn approval callbacks in v1. Approval gates either +auto-approve (nanoclaw pattern, HTTP face default) or block the turn. + +--- + +### 9. DisplayEvent / Notification Stream + +**Default** (no displayMode set): Human-readable text to stderr. Not machine-parseable. + +**JSON mode**: `display_mode="ndjson"` (Python) / `displayMode: "ndjson"` (TypeScript). +Switches to JSON-RPC `DisplayEvent` objects on stdout. + +**DisplayEvent types** (discriminated union in TypeScript, typed objects in Python): +- `text` — agent output text +- `tool_call` — tool invocation start +- `tool_result` — tool invocation result +- `notification` — status/progress notifications +- (more — exact set in SDK source) + +**HTTP face**: Translates events to SSE format automatically. Host receives +`data: ` lines in the SSE stream. + +**Push buffering** (nanoclaw pattern for container hosts): +```typescript +const BUFFER_CAP = 256; +const buffer: DisplayEvent[] = []; + +for await (const ev of session.submit(prompt)) { + if (buffer.length >= BUFFER_CAP) { + logger.warn('amplifier-agent buffer overflow — dropping event'); + continue; // visible drop + } + buffer.push(ev); +} +``` + +Visible-drop is preferred over backpressure deadlock for async-to-sync bridging. + +--- + +### 10. Multi-Turn / Chained Turns + +Single SDK call = single turn. For multi-turn conversations: + +**Python/TypeScript SDK**: Call `submit()` multiple times on the same `session_id` +with `resume=True`. Each call resumes the previous session. + +```typescript +// Turn 1 +for await (const ev of session.submit("First message")) { ... } + +// Turn 2 (resuming same session) +const session2 = await spawnAgent({ sessionId: sameSessionId, resume: true }); +for await (const ev of session2.submit("Follow-up message")) { ... } +``` + +**HTTP face**: Standard chat-completions multi-turn — include the full `messages` +array in each request (assistant's previous response in the history). + +--- + +## Surface Selection Decision Tree + +``` +What is your host runtime? + ├─ Python → Python Client SDK (amplifier-agent-py) + │ + ├─ Node.js >=20 → TypeScript Client SDK (amplifier-agent-ts) + │ + └─ Other / Polyglot / Already OpenAI-shaped + ├─ Host already calls OpenAI API? → HTTP Chat-Completions Server + ├─ Long-lived server process acceptable? → HTTP Chat-Completions Server + └─ Need per-request workspace isolation or per-turn MCP? → Re-evaluate + (HTTP face does not support these in v1; consider wrapping SDK in a sidecar) +``` + +--- + +## Risk Register Template + +| Risk | Affected Surfaces | Severity | Mitigation | +|------|-------------------|----------|------------| +| Cold-start cliff (5–30s first call) | All | High | Run `amplifier-agent prepare` at install/build | +| Protocol skew after engine upgrade | Python SDK, TS SDK | Medium | Pin version in CI; `allowProtocolSkew: false` (default) | +| State cross-contamination (multi-agent) | All | High | Unique workspace slug per agent | +| MCP secrets leaked via CLI args | All | High | Always use tmpfile + `AMPLIFIER_MCP_CONFIG` | +| HITL approval bypassed silently | HTTP face | Medium | HTTP face auto-approves; design for it or avoid HTTP face if HITL needed | +| Per-turn MCP injection not supported | HTTP face | Medium | Server-level only in v1; per-turn needs SDK | +| Blocked env var in `env.extra` | Python SDK, TS SDK | Low-Medium | Check allowlist before adding to `env.extra` | +| Push buffer overflow under load | All (streaming) | Medium | Implement visible-drop with logging (nanoclaw pattern) | +| Binary not found at startup | All | Medium | Set `AMPLIFIER_AGENT_BIN`; run `amplifier-agent doctor` at install | +| Bundle cache invalidated by upgrade | All | Medium | Hash check in CI; re-run `amplifier-agent prepare` on upgrade | diff --git a/bundles/amplifier-bundle-agent-adapter-designer/docs/BEHAVIORAL_MODEL.md b/bundles/amplifier-bundle-agent-adapter-designer/docs/BEHAVIORAL_MODEL.md new file mode 100644 index 00000000..4e06feb1 --- /dev/null +++ b/bundles/amplifier-bundle-agent-adapter-designer/docs/BEHAVIORAL_MODEL.md @@ -0,0 +1,363 @@ +# Behavioral Model: agent-adapter-designer + +**Bundle**: `agent-adapter-designer` +**Version**: 1.0.0 +**Generated**: 2026-06-24 +**Status**: Pre-implementation verification artifact + +--- + +## 1. Overview + +### Bundle Identity + +| Field | Value | +|-------|-------| +| Bundle name / namespace | `agent-adapter-designer` | +| Primary entry point | `/mode amplifier-agent-adapter-designer` | +| Secondary entry point | Delegate to `agent-adapter-designer:adapter-design-expert` | + +### Component Inventory + +| Mechanism | Name | File | +|-----------|------|------| +| Mode | `amplifier-agent-adapter-designer` | `modes/amplifier-agent-adapter-designer.md` | +| Agent | `adapter-design-expert` | `agents/adapter-design-expert.md` | +| Context (thin) | `adapter-design-awareness.md` | `context/adapter-design-awareness.md` | +| Context (heavy) | `integration-reference.md` | `context/integration-reference.md` | +| Behavior | `agent-adapter-designer-behavior` | `behaviors/agent-adapter-designer.yaml` | +| Bundle | `agent-adapter-designer` | `bundle.md` | + +### Objectives Served + +1. **Self-sufficient design workspace**: A developer entering the mode needs no prior knowledge of `amplifier-agent` to begin productive adapter design. +2. **Opinionated surface guidance**: The bundle carries a full evidence base (three surfaces, three case studies) and gives concrete recommendations — not "it depends" hedging. +3. **Concrete deliverable**: The design journey ends with a written adapter design document. +4. **Context-sink discipline**: Root sessions stay thin; heavy reference material is loaded only when the expert agent is spawned. + +--- + +## 2. Tool Governance + +### Mode: `amplifier-agent-adapter-designer` + +| Tool | Policy | Rationale | +|------|--------|-----------| +| `read_file` | safe | Reading host code and integration docs is core to design | +| `glob` | safe | File exploration for host codebase context | +| `grep` | safe | Searching for patterns in host code | +| `delegate` | safe | Essential — route deep questions to `adapter-design-expert` | +| `web_fetch` | safe | Looking up SDK docs, version info | +| `todo` | safe | Tracking design decisions and open questions | +| `load_skill` | safe | Loading relevant design skills on demand | +| `mode` | safe | Mode transitions (exit the design mode when done) | +| `bash` | warn | Shell probes (e.g. `amplifier-agent version --json`) useful but require acknowledgment | +| `write_file` | warn | Design doc production requires acknowledgment — prevents accidental writes | +| `edit_file` | warn | Editing design artifact requires acknowledgment | +| All others | block (default) | No code execution, no package installs during design | + +### Out-of-mode (root session, no mode active) + +All tools operate normally per foundation defaults. The awareness context file provides discovery without restricting behavior. + +--- + +## 3. Mode Behaviors + +### Mode: `amplifier-agent-adapter-designer` + +**Activation**: User runs `/mode amplifier-agent-adapter-designer` or `mode(operation="set", name="amplifier-agent-adapter-designer")`. + +**What activates**: The mode's markdown body is injected as an ephemeral `system-reminder` on every LLM call. The developer immediately has: +- A summary of the three integration surfaces (Python SDK, TypeScript SDK, HTTP server) +- Pointers to the three case studies (opencode, paperclip, nanoclaw) +- The delegation target for deep questions (`adapter-design-expert`) +- A structured design journey (5 steps: host runtime → surface selection → pattern borrowing → cross-cutting checklist → design artifact) +- A template for the design document output + +**What does NOT activate**: The full integration reference (~2500 tokens) is not injected. The mode body is a thin pointer that delegates heavy questions to the expert agent. + +**Tool policy in effect**: `warn` on bash and write operations; `block` on default. This is a design conversation — the developer explores, delegates to the expert, and eventually writes one document. + +**Allowed transitions**: Any mode (no `allowed_transitions` restriction). `allow_clear: true` — developer exits by running `/mode clear` or `mode(operation="clear")`. + +**Exit behavior**: When the developer clears the mode, the design document (if written) remains on disk. No cleanup required. + +--- + +## 4. Agent Behaviors + +### Agent: `adapter-design-expert` + +**Role**: Authoritative on all aspects of `amplifier-agent` integration. Carries the complete integration reference via `@mention` — all three surfaces, three case studies, ten cross-cutting concerns. + +**Model role**: `[reasoning, general]` — deep technical recommendations require reasoning-class models; `general` is the fallback. + +**Context loaded in agent session**: `context/integration-reference.md` (~2500 tokens) via `@mention`. This is the only mechanism that loads this file — it never appears in the root session or mode injection. + +**Invocation pattern**: Parent session delegates via `delegate` tool. The agent receives a specific question and returns a structured answer with: +- Direct answer +- Specific names (API, env var, function, constant) +- Trade-offs section (when recommending a surface) +- Gotchas section (when cross-cutting concerns apply) + +**Not invoked for**: Simple orientation questions the mode body already answers (e.g., "what are my three options?" — the mode prompt covers this). + +**Turn budget**: 8–12 turns. Questions are specific; answers should be precise, not exhaustive. + +--- + +## 5. Skill Behaviors + +**None.** The expert agent covers all reference and reasoning needs. A skill would duplicate the agent's function at higher per-turn visibility cost with no gain in isolation or capability. The agent is the correct mechanism: it isolates the expensive reference context in a disposable child session. + +--- + +## 6. Context and Cross-Cutting Concerns + +### Token Floor (per-turn, with mode active) + +| Component | Tokens | Notes | +|-----------|--------|-------| +| Foundation base context | ~12,000 | Common-agent-base, delegation instructions, etc. | +| `adapter-design-awareness.md` | ~200 | Thin pointer — always loaded when bundle is composed | +| Mode body (`amplifier-agent-adapter-designer.md`) | ~900 | Ephemeral, only while mode is active | +| Skills L1 visibility | ~1,200 | Standard per-skill overhead | +| Hook injections | ~300 | Status context, git | +| Reserved | ~6,000 | Output buffer + safety margin | +| **Total (mode active)** | **~20,600** | ~10% of 200K window | +| **Total (mode inactive)** | **~19,700** | Slightly lighter | + +### Context Lifecycle + +| Content | Loaded when | Lifecycle | +|---------|-------------|-----------| +| `adapter-design-awareness.md` | Every turn (system prompt) | Permanent — immune to compaction | +| Mode body | Every turn mode is active | Ephemeral — re-created each LLM call | +| `integration-reference.md` | Agent session only | Disposable — discarded after agent completes | +| Expert agent response | Message history after delegation | Compactable — subject to truncation | + +### Delegation Chain + +``` +User enters mode + → LLM uses mode body to orient developer + → Technical question arises + → LLM delegates to adapter-design-expert + → Agent loads integration-reference.md (~2500 tokens, agent-only) + → Agent answers with precision + → Agent session completes, context discarded + → Parent sees ~400 token result summary + → Design continues + → write_file produces adapter-design.md + → Developer clears mode +``` + +### Context Isolation + +The `integration-reference.md` is never loaded into the root session. If a developer composes this bundle but does not activate the mode and does not delegate to the expert agent, the full integration reference is never loaded. Only the thin awareness file (~200 tokens) is always present. + +--- + +## 7. Recipe Workflows + +**No recipes in v1.** The design conversation is inherently interactive — the developer describes their host, the LLM (using the mode guidance) asks clarifying questions, delegates to the expert when needed, and converges on decisions. A rigid multi-step recipe would reduce this flexibility without adding meaningful structure. + +The design document production is guided by the mode discipline (template in mode body + write_file with warn policy). This is conventional enforcement, which is appropriate: the user may want to iterate before writing, or may want to copy the template to their own file manually. Structural enforcement via a recipe would be premature for v1. + +**Candidate for v2**: A staged recipe — `design-interview` → user approval → `design-document-generation` — if usage shows developers benefit from more structured step-by-step guidance. + +--- + +## 8. Behavioral Scenarios + +### Scenario A: Fresh Activation — Self-Sufficient Orientation + +**User**: `/mode amplifier-agent-adapter-designer` + +**Expected**: Mode activates. LLM receives mode body with surface summary, case study list, expert delegation pointer, and design journey steps. LLM greets developer and asks about their host. + +**LLM response**: "You're now in the amplifier-agent adapter design workspace. To get started, tell me about your host application: what language/runtime (Python, Node.js, other)? Single process or containerized? Do you already have an OpenAI-compatible API client in the host?" + +**Verification**: Developer does NOT need to explain what amplifier-agent is. The mode provides full orientation. ✓ Self-sufficient. + +--- + +### Scenario B: Surface Selection — Python Host + +**User** (after mode activation): "My host is a FastAPI service. Which integration surface should I use?" + +**Expected**: LLM recognizes this as a deep technical question and delegates to `adapter-design-expert`. Expert loads integration-reference.md and returns structured answer. + +**Expert answer structure**: +- Direct: Python Client SDK (`amplifier-agent-py`) +- API: `await spawn_agent(session_id=..., display_mode="ndjson")`, `async for event in handle.submit(...)` +- Trade-offs: wrong for Node hosts, multi-turn burst in one subprocess, mid-turn approval callbacks +- Gotcha: not yet on PyPI, install from git source; protocol pinned to 0.3.0 via `PROTOCOL_VERSION_REQUIRED_BY_WRAPPER` + +**Verification**: Specific API names cited. Wrong-case listed. Cross-cutting gotcha surfaced. ✓ Opinionated and evidence-backed. + +--- + +### Scenario C: Case Study Reference — nanoclaw Docker Pattern + +**User**: "I'm building a container product. How did nanoclaw handle the cold-start problem?" + +**Expected**: LLM delegates to `adapter-design-expert`. Expert returns nanoclaw case study detail. + +**Expert answer structure**: +- Pattern: `uv tool install amplifier-agent` at image build; `amplifier-agent prepare` + `doctor --strict` as Dockerfile RUN steps +- Effect: bundle cache cost paid once at `docker build`, not at first user request +- Additional patterns from nanoclaw: MCP tmpfile passthrough, host-mounted state volume, push buffering (cap=256) +- Gotcha: CI version-lint gate to detect engine upgrades that invalidate cached bundles + +**Verification**: Specific commands cited. Pattern rationale clear. ✓ Evidence-backed with nanoclaw as attribution. + +--- + +### Scenario D: Cross-Cutting Concern — MCP Injection + +**User**: "My host uses MCP. How do I pass MCP config to amplifier-agent?" + +**Expected**: LLM delegates to expert (or may answer from mode body if already oriented). Expert provides exact pattern. + +**Expert answer**: +- Never a CLI flag +- Pattern: write to a 0600 tempfile; set `AMPLIFIER_MCP_CONFIG=/path/to/tmpfile` +- SDKs handle automatically when using spawnAgent/spawn_agent +- HTTP face: server-level injection only in v1 (per-request injection not supported) +- Nanoclaw citation: exactly this pattern in production + +**Verification**: Exact env var named. HTTP face limitation surfaced. ✓ Complete and precise. + +--- + +### Scenario E: Surface Selection — Correcting a Wrong Choice + +**User**: "I'm writing a Python host but I want to use the TypeScript SDK because the code examples look cleaner." + +**Expected**: LLM delegates to expert. Expert surfaces the trade-off clearly without dismissing the developer. + +**Expert answer**: +- TypeScript SDK (`amplifier-agent-ts`) is designed for Node >=20 hosts only +- For Python hosts, the right choice is the Python SDK (`amplifier-agent-py`) +- Why: the SDK manages subprocess lifecycle in the host's runtime; cross-runtime use means a Node subprocess managing a Python host's lifecycle — incorrect architecture +- If the developer has a mixed Python/Node architecture, expert explains how to structure the two surfaces + +**Verification**: Wrong choice corrected with evidence. Developer not left confused. ✓ Opinionated. + +--- + +### Scenario F: Env Allowlist Question + +**User**: "I need to pass `LD_PRELOAD` to amplifier-agent for a custom malloc implementation." + +**Expected**: Expert provides the allowlist and clearly flags the blocker. + +**Expert answer**: +- `LD_PRELOAD` is explicitly blocked in `env.extra` — throws `env_injection_rejected` +- Full blocklist: `PYTHONPATH LD_PRELOAD LD_LIBRARY_PATH PYTHONSTARTUP PYTHONHOME PYTHONNOUSERSITE DYLD_INSERT_LIBRARIES DYLD_LIBRARY_PATH` +- Always-allowed: `PATH HOME USER LANG TERM TMPDIR`, all `AMPLIFIER_*`, all `LC_*` +- Workaround: set `LD_PRELOAD` in the process that invokes the SDK (not passed as env.extra), so the subprocess inherits it via `PATH` + +**Verification**: Exact error name cited. Concrete workaround provided. ✓ Complete. + +--- + +### Scenario G: Design Document Production + +**User**: "I've decided: TypeScript SDK, following the paperclip adapter registry pattern. Help me write my design doc." + +**Expected**: LLM uses mode body template to produce structured design document. Writes to `adapter-design.md` via `write_file`. Mode warns once; developer confirms. + +**Document includes**: +- Chosen surface: TypeScript Client SDK, rationale +- Why not Python SDK, why not HTTP server +- Architecture overview: adapter registry, per-turn spawn, workspace slug +- Pattern borrowing from paperclip: `registerServerAdapter`, `registerUIAdapter`, workspace-per-agent `--` +- Cross-cutting decisions table +- Risk register: cold-start cliff (HIGH), protocol skew (MEDIUM), workspace slug collisions (LOW) + +**After write**: LLM tells developer the doc is saved. Suggests `/mode clear` to exit. + +**Verification**: Document matches template structure. ✓ Concrete deliverable produced. + +--- + +### Scenario H: Design Review + +**User** (has existing draft): "I have a draft adapter design. Can you review it for gaps?" + +**Expected**: LLM asks developer to share the draft (or read it via read_file). Delegates to expert with draft content. Expert checks against cross-cutting checklist. + +**Expert review outputs**: +- Which cross-cutting concerns are addressed / missing +- Whether the chosen surface is consistent with host runtime stated +- Any protocol-sensitive gotchas not covered in the risk register +- Specific gaps (e.g., "draft doesn't mention bundle cache priming — add to risk register") + +**Verification**: Review is systematic against known cross-cutting concerns. ✓ Actionable. + +--- + +### Scenario I: Bundle Composed Without Mode Activated + +**User composes the bundle but never activates the mode** + +**Expected**: +- Root session has `adapter-design-awareness.md` in system prompt (~200 tokens) +- LLM knows: "This session can design amplifier-agent host adapter integrations. Activate `/mode amplifier-agent-adapter-designer` to begin." +- Full integration reference NOT loaded (zero context poisoning) +- Expert agent available for direct delegation if needed + +**Verification**: Thin awareness. No bloat. ✓ Zero context poisoning. + +--- + +### Scenario J: Protocol Version Mismatch (Cross-Cutting Edge Case) + +**User**: "My spawnAgent call is throwing a `protocol_version_mismatch` error." + +**Expected**: Expert explains Design D6: strict-refuse on protocol skew. Self-remediating error. + +**Expert answer**: +- SDKs probe engine via `amplifier-agent version --json` +- Compiled constant: `PROTOCOL_VERSION_REQUIRED_BY_WRAPPER = "0.3.0"` +- Mismatch → `AaaError(protocol_version_mismatch)` with exact reinstall commands in the error message +- Fix: reinstall `amplifier-agent` to the version the SDK expects (commands in error body) +- Override (temporary): `allowProtocolSkew: true` in SDK config, or env var +- Note: README in `amplifier-agent-ts` says 0.1.0 but source says 0.3.0 — trust source + +**Verification**: Correct constant named. Override mechanism explained. Trust-source guidance. ✓ + +--- + +## 9. Assumptions and Gaps + +### Assumptions Made + +1. **Foundation includes modes support.** This bundle relies on the modes bundle being composed into foundation (hooks-mode, tool-mode). Mode discovery via "Composed bundle `modes/` dirs (lazy discovery)" is assumed to work without explicit `search_paths` configuration. If modes are not discovered, add `hooks-mode` config update to the behavior YAML. + +2. **`amplifier-agent-py` not on PyPI.** The reference states this at time of writing. If it publishes to PyPI, update the install note in `integration-reference.md`. + +3. **Protocol version 0.3.0.** The `PROTOCOL_VERSION_REQUIRED_BY_WRAPPER` constant is 0.3.0 at time of writing. This is embedded in `integration-reference.md`. Update when the SDK version changes. + +4. **TypeScript SDK has zero npm runtime deps.** Stated in source material. Verify against `amplifier-agent-ts` `package.json` before publishing. + +5. **Lazy mode discovery works for composed bundles.** This is listed as point 5 in the modes discovery order. If it doesn't work in practice, the fix is to add explicit `hooks-mode` config in `behaviors/agent-adapter-designer.yaml`. + +### Known Gaps (v1) + +1. **No structured interview recipe.** A multi-step guided interview (host runtime → requirements → constraints → recommendation → design doc) would reduce the burden on the mode's conventional guidance. Candidate for v2 if usage shows developers want more structure. + +2. **No design review recipe.** Scenario H (design review) is handled conversationally. A recipe that systematically checks a draft against all cross-cutting concerns would be more thorough. v2 candidate. + +3. **Mode cannot structurally enforce document production.** The design doc is guided by mode discipline (conventional enforcement), not a recipe gate (structural enforcement). A developer can exit the mode without writing a doc. This is intentional for v1 — the conversation may be the deliverable (e.g., the developer is only exploring options, not committing to an implementation). + +4. **Binary discovery order in Python SDK.** The reference says binary discovery is `AMPLIFIER_AGENT_BIN` → `which amplifier-agent` with no constructor param. However, the Python SDK's exact `env.extra` API surface (compared to the TypeScript SDK's `ChildProcessFactory`) needs verification against the actual `amplifier-agent-py` source. + +5. **HTTP face auth flow for multi-tenant hosts.** The `AMPLIFIER_AGENT_HTTP_API_KEY` env var is documented, but the full auth flow for hosts with per-request auth is not in the source material. If a developer needs this, the expert agent should direct them to the HTTP server docs rather than speculate. + +### Open Questions for User Approval + +See **Deliverable 4** in the design summary for the full list of questions that require user sign-off before publishing. diff --git a/bundles/amplifier-bundle-agent-adapter-designer/modes/amplifier-agent-adapter-designer.md b/bundles/amplifier-bundle-agent-adapter-designer/modes/amplifier-agent-adapter-designer.md new file mode 100644 index 00000000..737d6e0d --- /dev/null +++ b/bundles/amplifier-bundle-agent-adapter-designer/modes/amplifier-agent-adapter-designer.md @@ -0,0 +1,143 @@ +--- +mode: + name: amplifier-agent-adapter-designer + description: >- + Self-sufficient design workspace for integrating amplifier-agent into a + host application. Provides surface selection guidance, case study patterns, + cross-cutting concern coverage, and produces an adapter design document. + shortcut: amplifier-agent-adapter-designer + tools: + safe: + - read_file + - glob + - grep + - delegate + - web_fetch + - todo + - load_skill + - mode + warn: + - bash + - write_file + - edit_file + default_action: block + allow_clear: true +--- + +# amplifier-agent Adapter Design Mode + +You are in a focused, self-sufficient workspace for designing a host adapter +for `amplifier-agent` — Microsoft's modular AI agent engine. A developer who +activates this mode wants to embed amplifier-agent into their host application. +They need to select an integration surface, learn from existing adapter patterns, +and produce a concrete design document. + +## What you have + +**Three integration surfaces:** + +| Surface | Host Runtime | Model | +|---------|-------------|-------| +| Python SDK (`amplifier-agent-py`) | Python hosts (Django, Flask, FastAPI, scripts) | Single-turn subprocess | +| TypeScript SDK (`amplifier-agent-ts`) | Node.js >=20 | Single-turn subprocess | +| HTTP Server (`amplifier-agent serve chat-completions`) | Any OpenAI-compatible host | Long-running sidecar | + +**Three real host adapters to learn from:** + +- **opencode** → HTTP face. CLI auto-starts the server, probes `/v1/models`, writes provider config. Lesson: nearly free integration when the host already speaks OpenAI API. +- **paperclip** → TypeScript SDK. Adapter registry (`registerServerAdapter`), per-turn spawn, `pc--` workspace slugs. Lesson: treat amplifier-agent as one provider among many without forking core. +- **nanoclaw** → TypeScript SDK inside Docker. Build-time `uv tool install` + `amplifier-agent prepare`, MCP tmpfile passthrough, push buffering (cap=256), CI version-lint gate. Lesson: pay bundle-load cost at `docker build`, not at first user request. + +**Expert agent for deep questions:** +When the developer has a question that goes deeper than this summary — specific API +signatures, env var names, exact case study details, cross-cutting concern tradeoffs — +delegate to `agent-adapter-designer:adapter-design-expert`. It carries the complete +integration reference and answers with precision and evidence. + +## Cross-cutting concerns to address in every adapter design + +1. **Credential management** — provider keys via env vars (ANTHROPIC_API_KEY, etc.) +2. **MCP injection** — always a 0600 tmpfile + `AMPLIFIER_MCP_CONFIG` env; never a CLI flag +3. **Bundle cache priming** — run `amplifier-agent prepare` at install/build to avoid the 5–30s cold start cliff +4. **Protocol version pinning** — SDKs probe `amplifier-agent version --json`; mismatch → self-remediating error +5. **Workspace isolation** — unique slug per agent: `[a-z0-9][a-z0-9-]{0,63}` +6. **Env allowlist** — subprocess sees only allowed vars; `LD_PRELOAD`, `PYTHONPATH`, etc. are blocked in `env.extra` + +## Design journey — guide the developer through these steps + +1. **Host runtime** — Ask: Python or Node? Container/Docker product? Long-lived server or per-request? Multi-agent (needs workspace isolation)? + +2. **Surface selection** — Match the runtime to the surface. For uncertain trade-offs, delegate to `adapter-design-expert`. Surface selection is the most important decision; get it right before proceeding. + +3. **Pattern borrowing** — Identify which case study is closest. Ask: what can be borrowed verbatim from opencode, paperclip, or nanoclaw? + +4. **Cross-cutting checklist** — Work through each concern above. Ask the developer how they plan to handle each. Delegate to `adapter-design-expert` for specific guidance. + +5. **Risk register** — Identify the top 3–5 risks for this host's architecture. Severity + mitigation for each. + +6. **Design artifact** — Produce the adapter design document. + +## Design document — produce this when the developer is ready + +Use the template below. Save to `adapter-design.md` with `write_file` +(the mode requires one confirmation step for write operations). + +```markdown +# Adapter Design: [Host Name] + +## Chosen Integration Surface + +**[Surface name]** — [One sentence rationale] + +**Why not the alternatives:** +- [Surface 2]: [reason it doesn't fit this host] +- [Surface 3]: [reason it doesn't fit this host] + +## Architecture Overview + +[How the adapter fits in the host — process lifecycle, call sites, data flow] + +## Closest Case Study + +**[opencode | paperclip | nanoclaw]** + +Borrowed patterns: +- [Pattern 1 — what it is and what problem it solves] +- [Pattern 2] + +Adaptations needed: +- [What differs from the case study] + +## Cross-Cutting Decisions + +| Concern | Decision | +|---------|----------| +| Credential management | [approach] | +| MCP injection | [approach, or N/A] | +| Bundle cache priming | [approach] | +| Protocol version pinning | [pinned / allowProtocolSkew / CI-gated] | +| Workspace isolation | [slug pattern] | +| Env allowlist extras | [any env.extra needed] | +| Multi-turn / chained turns | [single-turn / resume=true / N/A] | +| DisplayEvent handling | [ndjson / human text / SSE] | + +## Risk Register + +| Risk | Severity | Mitigation | +|------|----------|------------| +| Cold-start cliff (5–30s) | High | [plan] | +| Protocol skew on engine upgrade | Medium | [plan] | +| [Other host-specific risks] | ... | ... | + +## Open Questions + +- [Unresolved decisions needing more information] +``` + +## Mode exit + +When the design document is saved, clear this mode: + + /mode clear + +Your `adapter-design.md` remains in the working directory.