Skip to content

Commit 3d7d58f

Browse files
andreisavuclaude
andauthored
Add multi-adapter support (claude / codex / opencode) (#14)
* Add multi-adapter support (claude / codex / opencode) Allow selecting the execution adapter via TRIVIA_ADAPTER env var (or `make agent ADAPTER=codex`). This demonstrates WINK's portability across harnesses. Default remains claude for backward compatibility. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Allow Bedrock auth for claude adapter in integration tests The skip logic only checked ANTHROPIC_API_KEY but the agent also supports CLAUDE_CODE_USE_BEDROCK for authentication. Accept either. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update README to document multi-adapter support Reflect that the same agent runs on Claude, Codex, and OpenCode adapters. Update Quick Start, Configuration Reference, architecture diagram, development commands, and troubleshooting sections. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 8e5157e commit 3d7d58f

10 files changed

Lines changed: 356 additions & 85 deletions

File tree

AGENTS.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,20 @@ make check
3434

3535
# Start Redis and run the agent
3636
make redis
37-
make agent
37+
make agent # Default: claude adapter
38+
make agent ADAPTER=codex # Use Codex adapter
39+
make agent ADAPTER=opencode # Use OpenCode adapter
3840

3941
# Ask about secrets
4042
make dispatch QUESTION="What is the secret number?"
4143
make dispatch QUESTION="What is the secret word?"
4244

4345
# Run evals
4446
make dispatch-eval QUESTION="What is the secret number?" EXPECTED="42"
47+
48+
# Integration tests with different adapters
49+
make integration-test # Default: claude
50+
make integration-test ADAPTER=codex # Test with Codex
4551
```
4652

4753
## Repository Structure

Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ help:
1111
@echo ""
1212
@echo "Run:"
1313
@echo " make agent Start the Secret Trivia agent worker"
14+
@echo " make agent ADAPTER=codex Start with Codex adapter"
15+
@echo " make agent ADAPTER=opencode Start with OpenCode adapter"
1416
@echo " make dispatch Submit a test question (set QUESTION=...)"
1517
@echo " make dispatch-eval Submit an eval case with experiment metadata"
1618
@echo ""
@@ -66,9 +68,11 @@ EXPECTED ?= ""
6668
EXPERIMENT ?= cli-eval
6769
OWNER ?=
6870
DESCRIPTION ?=
71+
ADAPTER ?= claude
6972

7073
agent:
7174
REDIS_URL=$(REDIS_URL) \
75+
TRIVIA_ADAPTER=$(ADAPTER) \
7276
TRIVIA_DEBUG_BUNDLES_DIR=$(TRIVIA_DEBUG_BUNDLES_DIR) \
7377
TRIVIA_PROMPT_OVERRIDES_DIR=$(TRIVIA_PROMPT_OVERRIDES_DIR) \
7478
uv run trivia-agent
@@ -103,7 +107,7 @@ test:
103107
uv run pytest tests -v
104108

105109
integration-test:
106-
uv run pytest integration-tests/ -v --timeout=300 --no-cov
110+
TRIVIA_ADAPTER=$(ADAPTER) uv run pytest integration-tests/ -v --timeout=300 --no-cov
107111

108112
# =============================================================================
109113
# Cleanup

README.md

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ This simple concept naturally demonstrates all of WINK's key capabilities:
3838
- Planning/act loop, sandboxing, tool-call orchestration
3939
- Scheduling, crash recovery, operational guardrails
4040

41-
**WINK's thesis**: Harnesses keep changing (and increasingly come from vendor runtimes), but your agent definition should not. WINK makes the definition a first-class artifact you can version, review, test, and port across runtimes via adapters.
41+
**WINK's thesis**: Harnesses keep changing (and increasingly come from vendor runtimes), but your agent definition should not. WINK makes the definition a first-class artifact you can version, review, test, and port across runtimes via adapters. This starter demonstrates that portability — the same trivia agent runs on **Claude Agent SDK**, **Codex App Server**, and **OpenCode ACP** by switching a single environment variable.
4242

4343
## Project Structure
4444

@@ -84,17 +84,30 @@ make install
8484
make redis
8585
```
8686

87-
### 3. Set your API key
87+
### 3. Configure authentication
88+
89+
The starter supports three execution adapters. Set up credentials for the one you plan to use:
8890

8991
```bash
92+
# Claude (default) — Anthropic API or AWS Bedrock
9093
export ANTHROPIC_API_KEY=your-api-key
94+
# or
95+
export CLAUDE_CODE_USE_BEDROCK=1
96+
97+
# Codex — requires the codex CLI on PATH
98+
# (no extra env vars needed)
99+
100+
# OpenCode — requires the opencode CLI on PATH
101+
# (no extra env vars needed)
91102
```
92103

93104
### 4. Run the agent
94105

95106
In one terminal, start the worker:
96107
```bash
97-
make agent
108+
make agent # Claude adapter (default)
109+
make agent ADAPTER=codex # Codex adapter
110+
make agent ADAPTER=opencode # OpenCode adapter
98111
```
99112

100113
In another terminal, ask about secrets:
@@ -296,7 +309,8 @@ The evaluator checks:
296309

297310
| Variable | Required | Default | Description |
298311
|----------|----------|---------|-------------|
299-
| `ANTHROPIC_API_KEY` | Yes | - | Anthropic API key |
312+
| `TRIVIA_ADAPTER` | No | `claude` | Adapter backend: `claude`, `codex`, or `opencode` |
313+
| `ANTHROPIC_API_KEY` | Claude only | - | Anthropic API key (or set `CLAUDE_CODE_USE_BEDROCK`) |
300314
| `REDIS_URL` | No | `redis://localhost:6379` | Redis connection URL |
301315
| `TRIVIA_REQUESTS_QUEUE` | No | `trivia:requests` | Request queue name |
302316
| `TRIVIA_EVAL_REQUESTS_QUEUE` | No | `trivia:eval:requests` | Eval queue name |
@@ -308,7 +322,9 @@ The evaluator checks:
308322
```bash
309323
make check # Format, lint, typecheck, test
310324
make test # Run unit tests with coverage
311-
make integration-test # Run integration tests (requires Redis + API key)
325+
make integration-test # Run integration tests (default: claude adapter)
326+
make integration-test ADAPTER=codex # Integration tests with Codex
327+
make integration-test ADAPTER=opencode # Integration tests with OpenCode
312328
make format # Format code
313329
```
314330

@@ -343,8 +359,12 @@ make format # Format code
343359
344360
345361
┌────────────────────────────────────────────────────────────────┐
346-
│ Claude Agent SDK (Harness) │
347-
│ - Planning/act loop, sandboxing, tool-call orchestration │
362+
│ Execution Harness (via Adapter) │
363+
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
364+
│ │ Claude Agent │ │ Codex App │ │ OpenCode ACP │ │
365+
│ │ SDK │ │ Server │ │ │ │
366+
│ └──────────────┘ └──────────────┘ └──────────────────────┘ │
367+
│ Set TRIVIA_ADAPTER=claude|codex|opencode (default: claude) │
348368
└────────────────────────────────────────────────────────────────┘
349369
350370
@@ -378,7 +398,7 @@ Then read the TOOLS guide and explain how tools work in WINK.
378398

379399
### Manual Testing
380400

381-
With `ANTHROPIC_API_KEY` and `REDIS_URL` set in your environment, Claude can perform end-to-end manual testing:
401+
With your adapter configured and `REDIS_URL` set, Claude can perform end-to-end manual testing:
382402

383403
```
384404
Start Redis and the agent, then test all four secrets by dispatching
@@ -465,6 +485,8 @@ Query the debug bundles to show me what data is captured during execution:
465485

466486
**"Connection refused" errors**: Make sure Redis is running (`make redis`).
467487

468-
**"API key not found"**: Ensure `ANTHROPIC_API_KEY` is set.
488+
**"API key not found"**: Only applies to the claude adapter. Set `ANTHROPIC_API_KEY` or `CLAUDE_CODE_USE_BEDROCK`.
489+
490+
**"codex/opencode binary not found"**: Install the respective CLI and ensure it's on your `PATH`.
469491

470492
**Agent doesn't know secrets**: Check that `skills/secret-trivia/SKILL.md` exists and contains the answers.

integration-tests/conftest.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from __future__ import annotations
44

55
import os
6+
import shutil
67

78
import pytest
89

@@ -19,10 +20,24 @@ def pytest_collection_modifyitems(
1920
config: pytest.Config,
2021
items: list[pytest.Item],
2122
) -> None:
22-
"""Skip integration tests if ANTHROPIC_API_KEY is not set."""
23-
if not os.environ.get("ANTHROPIC_API_KEY"):
24-
skip_marker = pytest.mark.skip(
25-
reason="ANTHROPIC_API_KEY not set - skipping integration tests"
26-
)
23+
"""Skip integration tests based on adapter prerequisites."""
24+
adapter = os.environ.get("TRIVIA_ADAPTER", "claude")
25+
26+
skip_reason: str | None = None
27+
28+
if adapter == "claude":
29+
if not os.environ.get("ANTHROPIC_API_KEY") and not os.environ.get(
30+
"CLAUDE_CODE_USE_BEDROCK"
31+
):
32+
skip_reason = "ANTHROPIC_API_KEY not set - skipping integration tests"
33+
elif adapter == "codex":
34+
if shutil.which("codex") is None:
35+
skip_reason = "codex binary not found on PATH - skipping integration tests"
36+
elif adapter == "opencode":
37+
if shutil.which("opencode") is None:
38+
skip_reason = "opencode binary not found on PATH - skipping integration tests"
39+
40+
if skip_reason:
41+
skip_marker = pytest.mark.skip(reason=skip_reason)
2742
for item in items:
2843
item.add_marker(skip_marker)

integration-tests/test_evals.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ def agent(redis_url: str) -> Generator[subprocess.Popen[bytes], None, None]:
6666
"""Start the trivia agent."""
6767
env = os.environ.copy()
6868
env["REDIS_URL"] = redis_url
69+
env["TRIVIA_ADAPTER"] = os.environ.get("TRIVIA_ADAPTER", "claude")
6970

7071
# Enable debug bundle generation
7172
project_root = Path(__file__).parent.parent

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ description = "Secret Trivia Agent - a WINK starter demonstrating background age
55
requires-python = ">=3.12"
66
dependencies = [
77
"redis",
8-
"weakincentives[claude-agent-sdk,redis,skills]",
8+
"weakincentives[claude-agent-sdk,acp,redis,skills]",
99
]
1010

1111
[project.scripts]

0 commit comments

Comments
 (0)