Skip to content

[Feature]: Per-alias agentRuntime override to support dual-route model configurations (Anthropic CLI + API) #82314

Description

@Adam-Researchh

Bug type

Feature request / architectural regression with direct billing consequences

Summary

OpenClaw 2026.5.12 consolidates per-transport provider namespaces (claude-cli/*, codex-cli/*, codex/*, google-gemini-cli/*) into canonical provider namespaces (anthropic/*, openai/*, google/*) with a separate `agentRuntime` hint. This is a sensible cleanup in principle, but it eliminates the only way to express "the same upstream model is reachable via two different transports" in a single agent config — and on the current Anthropic third-party billing policy, that means the legacy claude-cli/* namespace is the only path to subscription-rate Claude access from OpenClaw.

Why this is materially worse than a UX nit

Effective April 4, 2026 at noon PT, Anthropic deployed server-side checks that prevent third-party tools (Cline, OpenCode, aider, OpenClaw, Roo Code, etc.) from using subscription OAuth tokens. Per Anthropic's announcement:

  • OAuth subscription tokens (`sk-ant-oat01-*`) used through third-party tools are now billed at standard API rates ($3/$15 per 1M Sonnet input/output, $5/$25 per 1M Opus input/output) — NOT subscription quota.
  • Claude Code and Claude.ai remain flat-rate (subscription-included).
  • This means the only Claude path from OpenClaw that remains on Pro/Max subscription quota is the claude-cli binary spawn — because the binary identifies itself as Claude Code at the Anthropic server.

The legacy claude-cli/* namespace in OpenClaw is precisely how this distinction is currently expressed in config: `claude-cli/claude-opus-4-7` → shell out to `/opt/homebrew/bin/claude` (Pro subscription); `anthropic/claude-opus-4-7` → direct API with OAuth setup-token (now billed at API rates).

Sources: RelayPlane analysis, Sovereign Magazine coverage, The Register.

Reproduction

On 2026.5.12, declare both `claude-cli/` and `anthropic/` entries for the same model in `agents.defaults.models`. Common shape:

```jsonc
"claude-cli/claude-opus-4-7": { "alias": "opus47" }, // CLI binary → Pro subscription quota
"anthropic/claude-opus-4-7": { "alias": "opus47a" } // API direct → API-rate billing per April 4 policy
```

Run `openclaw doctor --fix`. Observe: `claude-cli/claude-opus-4-7` is silently deleted because `anthropic/claude-opus-4-7` already exists. The user's subscription-rate Claude path is gone, leaving only the API-rate path.

Source in `dist/cli-migration-BJQsc9PB.js` (`rewriteModelEntryMap`):

```javascript
for (const [rawKey, value] of Object.entries(models)) {
const converted = toAnthropicModelRef(rawKey);
if (!converted) continue;
if (converted === rawKey) continue;
if (!(converted in next)) next[converted] = value; // only copies if dest doesn't exist
delete next[rawKey]; // always deletes source
migrated.push(converted);
}
```

Why the migration design assumes a use case Anthropic just deprecated

The canonical `anthropic/*` shape implicitly assumes that all transports to a given model are economically equivalent — pick whichever is convenient and configure runtime separately. That was reasonable before April 4, 2026. Post-policy-change:

  • `anthropic/claude-opus-4-7` + default API runtime = $5/$25 per 1M tokens (real money)
  • `anthropic/claude-opus-4-7` + `runtime: claude-cli` (hypothetical) = subscription quota

These are not preference-level differences. They're cost differences of multiple dollars per turn for an active agent on a Pro subscription.

The 5.12 architecture currently has no way to express both routes in a single `agents.defaults.models` map, because keys must be unique. The legacy form's parallel namespaces (`claude-cli/` and `anthropic/`) was the only workable expression. Deleting it forces users to:

  1. Lose the subscription path entirely → start paying API rates for every Claude turn, OR
  2. Lose the API path entirely → can't use Claude from embedded runtimes / lossless-claw-compatible flows, OR
  3. Maintain two separate agents with different runtimes → significant UX downgrade and config duplication

Proposed solutions (ranked by my preference)

(a) Per-alias `agentRuntime` overrides — multiple aliases per model with per-alias runtime selection:
```jsonc
"anthropic/claude-opus-4-7": {
"aliases": [
{ "name": "opus47a", "runtime": "api", "authProfile": "anthropic:default" },
{ "name": "opus47", "runtime": "claude-cli", "authProfile": "anthropic:claude-cli" }
]
}
```

(b) Sibling-key convention like `anthropic/claude-opus-4-7@claude-cli` that targets the same model via a specific runtime, and surfaces in the model picker.

(c) Non-destructive migration on collision — `rewriteModelEntryMap` should preserve the source entry under a normalized form (e.g. rename `claude-cli/claude-opus-4-7` → `anthropic/claude-opus-4-7@claude-cli`) instead of silently deleting it. Plus a doctor warning surfacing the rename.

(d) At minimum: `doctor --fix` should grow per-migration `--only`/`--skip` flags so users can apply safe migrations (deprecated `session.maintenance.rotateBytes`, etc.) without triggering the dual-route-destroying rename.

Cross-references

Same family of "5.x tightening removed a useful expression and didn't replace it" pattern as:

Environment

  • OpenClaw `2026.5.12` (pnpm-global, macOS arm64)
  • Two anthropic auth profiles in `openclaw.json`: `anthropic:default` (API direct via OAuth setup-token) and `anthropic:claude-cli` (CLI via Keychain)
  • Persistent agent (`agent:main:main`) configured to route via either path depending on alias
  • lossless-claw 0.9.4 as context engine slot

Edit note (2026-05-15)

This issue was originally filed with a motivation paragraph that incorrectly claimed both anthropic OAuth routes use Pro subscription quota. The corrected version above reflects the actual Anthropic third-party tool billing policy effective April 4, 2026 — under which only the `claude-cli` binary path remains on subscription billing for OpenClaw users. The technical proposal (per-alias runtime override) is unchanged; the economic stakes are simply much higher than originally stated.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:auth-providerAuth, provider routing, model choice, or SecretRef resolution may break.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions