Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,20 @@ make check

# Start Redis and run the agent
make redis
make agent
make agent # Default: claude adapter
make agent ADAPTER=codex # Use Codex adapter
make agent ADAPTER=opencode # Use OpenCode adapter

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

# Run evals
make dispatch-eval QUESTION="What is the secret number?" EXPECTED="42"

# Integration tests with different adapters
make integration-test # Default: claude
make integration-test ADAPTER=codex # Test with Codex
```

## Repository Structure
Expand Down
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ help:
@echo ""
@echo "Run:"
@echo " make agent Start the Secret Trivia agent worker"
@echo " make agent ADAPTER=codex Start with Codex adapter"
@echo " make agent ADAPTER=opencode Start with OpenCode adapter"
@echo " make dispatch Submit a test question (set QUESTION=...)"
@echo " make dispatch-eval Submit an eval case with experiment metadata"
@echo ""
Expand Down Expand Up @@ -66,9 +68,11 @@ EXPECTED ?= ""
EXPERIMENT ?= cli-eval
OWNER ?=
DESCRIPTION ?=
ADAPTER ?= claude

agent:
REDIS_URL=$(REDIS_URL) \
TRIVIA_ADAPTER=$(ADAPTER) \
TRIVIA_DEBUG_BUNDLES_DIR=$(TRIVIA_DEBUG_BUNDLES_DIR) \
TRIVIA_PROMPT_OVERRIDES_DIR=$(TRIVIA_PROMPT_OVERRIDES_DIR) \
uv run trivia-agent
Expand Down Expand Up @@ -103,7 +107,7 @@ test:
uv run pytest tests -v

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

# =============================================================================
# Cleanup
Expand Down
40 changes: 31 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ This simple concept naturally demonstrates all of WINK's key capabilities:
- Planning/act loop, sandboxing, tool-call orchestration
- Scheduling, crash recovery, operational guardrails

**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.
**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.

## Project Structure

Expand Down Expand Up @@ -84,17 +84,30 @@ make install
make redis
```

### 3. Set your API key
### 3. Configure authentication

The starter supports three execution adapters. Set up credentials for the one you plan to use:

```bash
# Claude (default) — Anthropic API or AWS Bedrock
export ANTHROPIC_API_KEY=your-api-key
# or
export CLAUDE_CODE_USE_BEDROCK=1

# Codex — requires the codex CLI on PATH
# (no extra env vars needed)

# OpenCode — requires the opencode CLI on PATH
# (no extra env vars needed)
```

### 4. Run the agent

In one terminal, start the worker:
```bash
make agent
make agent # Claude adapter (default)
make agent ADAPTER=codex # Codex adapter
make agent ADAPTER=opencode # OpenCode adapter
```

In another terminal, ask about secrets:
Expand Down Expand Up @@ -296,7 +309,8 @@ The evaluator checks:

| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `ANTHROPIC_API_KEY` | Yes | - | Anthropic API key |
| `TRIVIA_ADAPTER` | No | `claude` | Adapter backend: `claude`, `codex`, or `opencode` |
| `ANTHROPIC_API_KEY` | Claude only | - | Anthropic API key (or set `CLAUDE_CODE_USE_BEDROCK`) |
| `REDIS_URL` | No | `redis://localhost:6379` | Redis connection URL |
| `TRIVIA_REQUESTS_QUEUE` | No | `trivia:requests` | Request queue name |
| `TRIVIA_EVAL_REQUESTS_QUEUE` | No | `trivia:eval:requests` | Eval queue name |
Expand All @@ -308,7 +322,9 @@ The evaluator checks:
```bash
make check # Format, lint, typecheck, test
make test # Run unit tests with coverage
make integration-test # Run integration tests (requires Redis + API key)
make integration-test # Run integration tests (default: claude adapter)
make integration-test ADAPTER=codex # Integration tests with Codex
make integration-test ADAPTER=opencode # Integration tests with OpenCode
make format # Format code
```

Expand Down Expand Up @@ -343,8 +359,12 @@ make format # Format code
┌────────────────────────────────────────────────────────────────┐
│ Claude Agent SDK (Harness) │
│ - Planning/act loop, sandboxing, tool-call orchestration │
│ Execution Harness (via Adapter) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
│ │ Claude Agent │ │ Codex App │ │ OpenCode ACP │ │
│ │ SDK │ │ Server │ │ │ │
│ └──────────────┘ └──────────────┘ └──────────────────────┘ │
│ Set TRIVIA_ADAPTER=claude|codex|opencode (default: claude) │
└────────────────────────────────────────────────────────────────┘
Expand Down Expand Up @@ -378,7 +398,7 @@ Then read the TOOLS guide and explain how tools work in WINK.

### Manual Testing

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

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

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

**"API key not found"**: Ensure `ANTHROPIC_API_KEY` is set.
**"API key not found"**: Only applies to the claude adapter. Set `ANTHROPIC_API_KEY` or `CLAUDE_CODE_USE_BEDROCK`.

**"codex/opencode binary not found"**: Install the respective CLI and ensure it's on your `PATH`.

**Agent doesn't know secrets**: Check that `skills/secret-trivia/SKILL.md` exists and contains the answers.
25 changes: 20 additions & 5 deletions integration-tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from __future__ import annotations

import os
import shutil

import pytest

Expand All @@ -19,10 +20,24 @@ def pytest_collection_modifyitems(
config: pytest.Config,
items: list[pytest.Item],
) -> None:
"""Skip integration tests if ANTHROPIC_API_KEY is not set."""
if not os.environ.get("ANTHROPIC_API_KEY"):
skip_marker = pytest.mark.skip(
reason="ANTHROPIC_API_KEY not set - skipping integration tests"
)
"""Skip integration tests based on adapter prerequisites."""
adapter = os.environ.get("TRIVIA_ADAPTER", "claude")

skip_reason: str | None = None

if adapter == "claude":
if not os.environ.get("ANTHROPIC_API_KEY") and not os.environ.get(
"CLAUDE_CODE_USE_BEDROCK"
):
skip_reason = "ANTHROPIC_API_KEY not set - skipping integration tests"
elif adapter == "codex":
if shutil.which("codex") is None:
skip_reason = "codex binary not found on PATH - skipping integration tests"
elif adapter == "opencode":
if shutil.which("opencode") is None:
skip_reason = "opencode binary not found on PATH - skipping integration tests"

if skip_reason:
skip_marker = pytest.mark.skip(reason=skip_reason)
for item in items:
item.add_marker(skip_marker)
1 change: 1 addition & 0 deletions integration-tests/test_evals.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def agent(redis_url: str) -> Generator[subprocess.Popen[bytes], None, None]:
"""Start the trivia agent."""
env = os.environ.copy()
env["REDIS_URL"] = redis_url
env["TRIVIA_ADAPTER"] = os.environ.get("TRIVIA_ADAPTER", "claude")

# Enable debug bundle generation
project_root = Path(__file__).parent.parent
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description = "Secret Trivia Agent - a WINK starter demonstrating background age
requires-python = ">=3.12"
dependencies = [
"redis",
"weakincentives[claude-agent-sdk,redis,skills]",
"weakincentives[claude-agent-sdk,acp,redis,skills]",
]

[project.scripts]
Expand Down
Loading