Expand description
Provider + model resolution. Mirrors the Anthropic-protocol slice of the
TS packages/coding-agent/src/core/model-resolver.ts (resolveCliModel +
the provider/id[:thinking] parsing in crate::args).
v1 is Anthropic-protocol only (plan §5.16: “OAuth/Copilot skipped v1;
API-key auth only” — now extended to include third-party Anthropic-compatible
endpoints via ANTHROPIC_BASE_URL + ANTHROPIC_AUTH_TOKEN and a
~/.rpi/models.json catalog; OAuth is still deferred). The TS
ModelRuntime/ModelRegistry multi-provider machinery is not ported; this
module builds a single AnthropicProvider from a resolved credential and
resolves a Model + ThinkingLevel against the catalog.
§Auth resolution precedence (mirrors upstream anthropic.ts:resolve)
--api-key→ provider default key (sent asx-api-key).~/.rpi/auth.jsonanthropic.api_key.key— the persistentrpi auth logincredential (sent asx-api-key). This is the “logged-in” path.~/.rpi/models.jsonprovider withauthHeader: true+apiKey→Authorization: Bearer <key>(a static gateway credential — the models.json file alone is a complete third-party-endpoint setup, no env var needed).ANTHROPIC_AUTH_TOKENenv →Authorization: Bearer <token>(folded into each model’sheaders; the provider’shas_header_authrecognizes it and skipsx-api-key, so a token-only setup does not error on a missing key).ANTHROPIC_API_KEYenv → provider default key (x-api-key).- None of the above ⇒
ResolveError::NoApiKey.
When a Bearer source (item 3 or 4) wins, the provider is built with
api_key = None — the header on each model carries the auth. When a key
source wins (1, 2, or 5), the provider carries the key as x-api-key.
§Endpoint + catalog
--base-url/ANTHROPIC_BASE_URLoverridesmodel.base_urlat resolve time (the request URL is built from it per-request in rpi-ai).~/.rpi/models.json(if present) merges/overrides the built-in catalog: eachanthropic-messagesprovider contributes its models, with provider-levelbase_url/headers/authHeaderfolded in. The models.json provider id (e.g.gateway) is config-namespacing only in v1: every models.json model is stampedprovider = "anthropic"so it routes through the singleAnthropicProvider(the per-modelbase_url+headerscarry the endpoint/auth differentiation). A--model gateway/custom-claudejust strips thegateway/prefix and matches thecustom-claudeid.
§Model pattern precedence (mirrors resolveCliModel)
--modelmay carryprovider/id[:thinking]. A leadinganthropic/(case-insensitive) is stripped; any otherfoo/prefix is also stripped so amodels.jsonprovider id (e.g.gateway/…) addresses its model.- Otherwise treat
--modelasid[:thinking]: if a trailing:levelis a valid thinking level, strip it and apply it (overriding--thinking); else the whole string is the id. - A
--providerthat isn’tanthropicis a hard error (v1 has no other provider).--provider anthropicis accepted and just confirms the default. - The model id is matched exactly, case-insensitively against the
catalog. The TS resolver additionally does fuzzy/partial matching; v1
keeps it exact to avoid surprising model picks (partial match is a common
source of “got the wrong model” bugs — documented as a divergence in
docs/m6-cli-open-questions.md). - No
--model⇒ [pick_default_model]: (a) the built-in default (DEFAULT_MODEL_ID=claude-sonnet-5) if it is already authenticated (has a folded Bearer, or the provider holds anx-api-key); otherwise (b) the first authenticated model in the catalog — mirroring the TSfindInitialModelstep-4 fallbackavailableModels[0]over the auth-filtered snapshot. This lets amodels.json-only gateway config “just work”: the built-in Anthropic models carry no auth, so the gateway model (the only authenticated one) is picked. The all-builtin/no-custom-code default (ANTHROPIC_API_KEYpath) still selectsclaude-sonnet-5. Last resort falls back toDEFAULT_MODEL_ID(or the catalog head) — unreachable in practice because the auth gate refuses an unauthed catalog earlier.
Structs§
- Resolved
Model - The resolved run configuration: the provider handle, the chosen model, and
the effective thinking level (after
--thinking/:level/ model-clamp).
Enums§
- Resolve
Error - A resolution error. The TS resolver returns
{ error, warning }; v1 folds both into a single enum since the CLI treats them the same (print + non-zero exit) exceptNoApiKey, which prints guidance then exits.
Constants§
- ANTHROPIC_
API_ KEY_ ENV - The env var consulted for the API key. Mirrors TS
ANTHROPIC_API_KEY. - ANTHROPIC_
AUTH_ TOKEN_ ENV - The env var consulted for a bearer token (routed as
Authorization: Bearer). Mirrors TSANTHROPIC_AUTH_TOKEN— used by third-party Anthropic-compatible gateways (one-api/new-api/claude-code-router and private reverse proxies) that authenticate viaAuthorizationrather thanx-api-key. - ANTHROPIC_
BASE_ URL_ ENV - The env var that overrides the Anthropic endpoint base URL. Mirrors TS
ANTHROPIC_BASE_URL— point this at a gateway/proxy that speaks the/v1/messagesprotocol. - DEFAULT_
MODEL_ ID - The v1-default model id when
--modelis absent. Mirrors the TSdefaultModelPerProvider["anthropic"](the first current-generation reasoning model in the catalog). - DEFAULT_
THINKING_ LEVEL - The default thinking level when neither
--thinkingnor a:levelsuffix is present. Mirrors the TSDEFAULT_THINKING_LEVEL("medium", clamped to model capabilities by the harness’s provider build_params). - NO_
API_ KEY_ HINT - Hint text surfaced when no credential source is available. Lists every accepted source so the user can pick the one that fits their setup.
Functions§
- resolve
- Resolve the provider + model + thinking level from the CLI flags + env +
~/.rpi/config.