# Claude Runtime

Duoduo supports Claude and Codex as **peer agent runtimes**. Either,
both, or neither can be installed; the daemon probes both at boot and
adapts to whichever are available.

This document describes how to use the Claude side. See
`codex-runtime.md` for the Codex side. The two have symmetric setup
shapes; the differences are listed under Caveats below.

## Prerequisites

Aladuo embeds the Anthropic Claude Code SDK and ships the native
platform binary as an npm optional dependency.

- `npm install -g @openduo/duoduo` brings the SDK in automatically.
- Verify your install isn't missing the platform binary by running:

```bash
duoduo daemon start
```

If the daemon refuses to start with "no agent runtime available",
either reinstall without `--omit=optional` (so the platform binary
package is included), or install the `@anthropic-ai/claude-code` CLI
and point at it via `CLAUDE_CODE_EXECUTABLE`.

## Authentication

Pick ONE of three sources during `duoduo onboard`:

| Source                | Setup                                              |
| --------------------- | -------------------------------------------------- |
| `claude_code_local`   | You've run `claude login` on this machine.         |
| `anthropic_api_key`   | Set `ANTHROPIC_API_KEY` (env or `onboard` answer). |
| `compatible_endpoint` | OpenAI-compatible endpoint (sglang, vLLM, etc).    |

The wizard stores your choice in `~/.config/duoduo/config.json`.

## Selecting Claude as the default runtime

Claude is the conservative fallback when no other declaration applies.
See `codex-runtime.md` for the full fallback chain; the short version:
unless an actor explicitly declares `runtime: codex` (in descriptor,
job frontmatter, or partition frontmatter), and unless
`ALADUO_DEFAULT_RUNTIME=codex` is set, every actor lands on Claude.

## Environment Variables

| Variable                    | Required                                       | Values                     | Default  |
| --------------------------- | ---------------------------------------------- | -------------------------- | -------- |
| `ALADUO_DEFAULT_RUNTIME`    | No                                             | `claude`, `codex`          | `claude` |
| `ALADUO_CLAUDE_AUTH_SOURCE` | No                                             | (see Authentication table) | unset    |
| `ANTHROPIC_API_KEY`         | If using `anthropic_api_key`                   |                            |          |
| `ANTHROPIC_BASE_URL`        | If using `compatible_endpoint`                 |                            |          |
| `ANTHROPIC_AUTH_TOKEN`      | If using `compatible_endpoint`                 |                            |          |
| `CLAUDE_CODE_EXECUTABLE`    | Escape hatch: point at a non-SDK Claude binary | unset                      |

## Usage

When Claude is available, every actor that does not declare a different
runtime uses the embedded SDK. Streaming channel sessions, jobs, and
subconscious partitions all share one in-process adapter — Claude does
not spawn an external CLI per turn (unlike Codex's app-server model).

Subagents are discovered via `.claude/agents/*.md` files in the actor's
cwd. The Claude SDK auto-loads these and exposes them as named
arguments to the `Agent` tool.

## Caveats

- `streamingAdapter` sessionId is sticky — once a streaming-input
  session is spawned, the SDK subprocess is bound to that session ID
  for its whole lifetime. Aladuo handles this internally; user code
  doesn't see the binding.
- CLAUDE.md / @imports load happens inside the SDK process — partition
  prompt edits take effect after the next `query()` call (each drain
  is one query).
- The native binary lives in `node_modules/@anthropic-ai/claude-agent-sdk-<platform>-<arch>/claude`.
  Removing it (e.g. `npm install --omit=optional`) makes the runtime
  unavailable; the daemon will report `claude: unavailable` at probe
  time and only `codex` in `available_runtimes`.
