diff --git a/.github/AUTHOR_MAP b/.github/AUTHOR_MAP index cb71a4762f..4a33e57bbb 100644 --- a/.github/AUTHOR_MAP +++ b/.github/AUTHOR_MAP @@ -263,3 +263,6 @@ Arlo = Arlo <253300483+xiaoray-blip@users.noreply.github.com> xyzs996 = Mark Yan <396284+xyzs996@users.noreply.github.com> xyzs996@gmail.com = Mark Yan <396284+xyzs996@users.noreply.github.com> Mark Yan = Mark Yan <396284+xyzs996@users.noreply.github.com> +henrikdukefoss = Henrik Bakke Dukefoss <76407537+henrikdukefoss@users.noreply.github.com> +Henrik Bakke Dukefoss = Henrik Bakke Dukefoss <76407537+henrikdukefoss@users.noreply.github.com> +henrikdukef@gmail.com = Henrik Bakke Dukefoss <76407537+henrikdukefoss@users.noreply.github.com> diff --git a/.github/workflows/ohos.yml b/.github/workflows/ohos.yml index 73b5835b4a..9e9e35d40a 100644 --- a/.github/workflows/ohos.yml +++ b/.github/workflows/ohos.yml @@ -10,6 +10,7 @@ on: - 'crates/**' - 'scripts/ohos/**' - 'scripts/ohos-env.sh' + - 'scripts/ohos-env.ps1' - 'scripts/release/check-ohos-deps.sh' pull_request: branches: [main, master] @@ -20,6 +21,7 @@ on: - 'crates/**' - 'scripts/ohos/**' - 'scripts/ohos-env.sh' + - 'scripts/ohos-env.ps1' - 'scripts/release/check-ohos-deps.sh' schedule: - cron: '47 7 * * 1' @@ -66,7 +68,7 @@ jobs: # (checksum-verified from the GitHub mirror below). cache: ${{ github.ref == 'refs/heads/main' }} mirror: true - - name: Check Codewhale TUI with the real SDK/sysroot + - name: Check Codewhale TUI and CLI with the real SDK/sysroot shell: bash env: OHOS_NATIVE_SDK: ${{ steps.ohos-sdk.outputs.ohos_sdk_native }} @@ -75,4 +77,4 @@ jobs: test -x "${OHOS_NATIVE_SDK}/llvm/bin/clang" test -d "${OHOS_NATIVE_SDK}/sysroot" . ./scripts/ohos-env.sh - cargo check --target aarch64-unknown-linux-ohos -p codewhale-tui --locked + cargo check --target aarch64-unknown-linux-ohos -p codewhale-tui -p codewhale-cli --locked diff --git a/CHANGELOG.md b/CHANGELOG.md index c6fd3495a5..86f064e49b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.10.2] - 2026-10-10 +- OpenHarmony builds on Windows select Ninja, with an SDK-bundled fallback and + a clear error when it is unavailable. The CLI keeps its download and Work + context integrity checks available on OHOS by sharing an ungated SHA-256 + helper (thanks @shenjackyuanjie, #6989; reported in #6988). + - Desktop and HTTP app-server turns feed an existing shared pet companion when its followed session has no live producer. Automatic selection is checked atomically by the owner; a live TUI keeps its source. The Runtime producer @@ -473,6 +478,8 @@ launcher guidance. ### Contributors +- **[@henrikdukefoss](https://github.com/henrikdukefoss)** — added the Standard Compute compatible-host descriptor, with live model discovery and its billing basis kept Unknown ([#6985](https://github.com/codewhale-hq/Codewhale/pull/6985)). +- **[@shenjackyuanjie](https://github.com/shenjackyuanjie)** — diagnosed and fixed the Windows OpenHarmony CMake generator and CLI hashing-module build failures ([#6988](https://github.com/codewhale-hq/Codewhale/issues/6988), [#6989](https://github.com/codewhale-hq/Codewhale/pull/6989)). - **[@LIghtJUNction](https://github.com/LIghtJUNction)** — plugin shell install and in-TUI plugin OAuth sign-in ([#6950](https://github.com/codewhale-hq/Codewhale/pull/6950)). - **[@SparkofSpike](https://github.com/SparkofSpike)** — live network-policy updates and goal milestone hand-back ([#6928](https://github.com/codewhale-hq/Codewhale/pull/6928), [#6930](https://github.com/codewhale-hq/Codewhale/pull/6930)), and a relocated Codewhale home ([#6947](https://github.com/codewhale-hq/Codewhale/issues/6947)). - **[@dajiaohuang](https://github.com/dajiaohuang)** — cache-write token accounting ([#6913](https://github.com/codewhale-hq/Codewhale/pull/6913)). diff --git a/crates/cli/src/cloud.rs b/crates/cli/src/cloud.rs index de2ee35131..dba2048199 100644 --- a/crates/cli/src/cloud.rs +++ b/crates/cli/src/cloud.rs @@ -1498,7 +1498,7 @@ impl<'a, T: CloudTransport> CloudClient<'a, T> { return Err(response_error(&response)); } if response.body.len() as u64 != metadata.size - || crate::update::sha256_hex(&response.body) != metadata.sha256 + || crate::hashing::sha256_hex(&response.body) != metadata.sha256 { bail!( "The downloaded file did not match its saved size and SHA-256; nothing was written" @@ -1959,7 +1959,7 @@ fn dispatch_stamp(objective: &str) -> String { .duration_since(std::time::UNIX_EPOCH) .map_or(0, |elapsed| elapsed.as_nanos()); let seed = format!("{nanos}:{}:{objective}", std::process::id()); - crate::update::sha256_hex(seed.as_bytes())[..24].to_string() + crate::hashing::sha256_hex(seed.as_bytes())[..24].to_string() } pub(crate) enum AccountDispatch { diff --git a/crates/cli/src/cloud/work.rs b/crates/cli/src/cloud/work.rs index 9eca98a5d4..21f972e136 100644 --- a/crates/cli/src/cloud/work.rs +++ b/crates/cli/src/cloud/work.rs @@ -233,7 +233,7 @@ pub(super) fn assign( bail!("The Codewhale service returned Work for a different Agent"); } if let Some(context) = task_context { - let digest = crate::update::sha256_hex(&serde_json::to_vec(context)?); + let digest = crate::hashing::sha256_hex(&serde_json::to_vec(context)?); if item.task_context_digest != digest { return Err(CloudTransportError::new("The Work reply does not confirm the requested source context; replay the same message and context", std::io::Error::other("task context mismatch")).into()); } diff --git a/crates/cli/src/hashing.rs b/crates/cli/src/hashing.rs new file mode 100644 index 0000000000..e776cb70a4 --- /dev/null +++ b/crates/cli/src/hashing.rs @@ -0,0 +1,16 @@ +/// Compute the SHA256 hex digest of data. +pub(crate) fn sha256_hex(data: &[u8]) -> String { + use sha2::Digest; + let hash = sha2::Sha256::digest(data); + hex_bytes(hash) +} + +fn hex_bytes(bytes: impl AsRef<[u8]>) -> String { + let bytes = bytes.as_ref(); + let mut out = String::with_capacity(bytes.len() * 2); + for byte in bytes { + use std::fmt::Write as _; + let _ = write!(&mut out, "{byte:02x}"); + } + out +} diff --git a/crates/cli/src/lib.rs b/crates/cli/src/lib.rs index b6d60f1766..fcac3f6e0e 100644 --- a/crates/cli/src/lib.rs +++ b/crates/cli/src/lib.rs @@ -4,6 +4,7 @@ mod cloud; mod config_bundles; mod credential_handoff; mod dispatch; +mod hashing; mod metrics; #[cfg(not(target_env = "ohos"))] mod update; diff --git a/crates/cli/src/update.rs b/crates/cli/src/update.rs index 2ff5bf1d85..06519c4418 100644 --- a/crates/cli/src/update.rs +++ b/crates/cli/src/update.rs @@ -26,6 +26,8 @@ use std::io::Write; use std::sync::Arc; use std::time::Duration; +use crate::hashing::sha256_hex; + mod compiled_host; const GITHUB_LATEST_RELEASE_PAGE_URL: &str = @@ -1841,23 +1843,6 @@ fn download_url_once_with( Ok((status, bytes)) } -/// Compute the SHA256 hex digest of data. -pub(crate) fn sha256_hex(data: &[u8]) -> String { - use sha2::Digest; - let hash = sha2::Sha256::digest(data); - hex_bytes(hash) -} - -fn hex_bytes(bytes: impl AsRef<[u8]>) -> String { - let bytes = bytes.as_ref(); - let mut out = String::with_capacity(bytes.len() * 2); - for byte in bytes { - use std::fmt::Write as _; - let _ = write!(&mut out, "{byte:02x}"); - } - out -} - #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] struct GlibcVersion { major: u32, diff --git a/crates/config/assets/provider_descriptors.json b/crates/config/assets/provider_descriptors.json index fa54659090..3ea2241c78 100644 --- a/crates/config/assets/provider_descriptors.json +++ b/crates/config/assets/provider_descriptors.json @@ -2227,6 +2227,21 @@ "meituan-sensenova-cn" ] }, + { + "id": "standardcompute", + "label": "Standard Compute", + "wire": "openai-compatible", + "base_url": "https://api.stdcmpt.com/v1", + "api_key_env": "STANDARDCOMPUTE_API_KEY", + "default_model": "standardcompute", + "discovery": "models_endpoint", + "docs_url": "https://docs.standardcompute.com/quickstart", + "credential_url": "https://standardcompute.com/dashboard/api-keys", + "guidance": "OpenAI-compatible host (Chat Completions + GET /v1/models). The standardcompute model id routes each request across models and providers; vendor-prefixed ids such as deepseek/deepseek-v4-pro pin one model. Live /v1/models is the model authority. Store STANDARDCOMPUTE_API_KEY, not a raw key.", + "aliases": [ + "standard-compute" + ] + }, { "id": "tsubasa", "label": "Tsubasa", diff --git a/crates/config/src/descriptors.rs b/crates/config/src/descriptors.rs index a613c66558..f4548592e6 100644 --- a/crates/config/src/descriptors.rs +++ b/crates/config/src/descriptors.rs @@ -312,6 +312,20 @@ mod tests { ); } + #[test] + fn standard_compute_is_a_descriptor_row() { + let row = provider_descriptor("standard-compute").expect("standardcompute"); + assert_eq!(row.id, "standardcompute"); + assert_eq!(row.wire, DescriptorWire::OpenaiCompatible); + assert_eq!(row.base_url, "https://api.stdcmpt.com/v1"); + assert_eq!(row.api_key_env, "STANDARDCOMPUTE_API_KEY"); + assert_eq!(row.default_model, "standardcompute"); + assert_eq!( + provider_descriptor("standard_compute").map(|row| row.id.as_str()), + Some("standardcompute") + ); + } + #[test] fn descriptors_do_not_embed_model_rosters() { let raw = DESCRIPTORS_JSON; @@ -404,6 +418,6 @@ mod tests { // reusing its name; compatible-host lookup remains separately scoped. assert!(provider_descriptor("openai").is_none()); assert!(provider_descriptor("deepseek").is_none()); - assert_eq!(bundled_provider_descriptors().len(), 10); + assert_eq!(bundled_provider_descriptors().len(), 11); } } diff --git a/crates/tui/CHANGELOG.md b/crates/tui/CHANGELOG.md index b26cc864c9..0cdd472c38 100644 --- a/crates/tui/CHANGELOG.md +++ b/crates/tui/CHANGELOG.md @@ -13,6 +13,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.10.2] - 2026-10-10 +- OpenHarmony builds on Windows select Ninja, with an SDK-bundled fallback and + a clear error when it is unavailable. The CLI keeps its download and Work + context integrity checks available on OHOS by sharing an ungated SHA-256 + helper (thanks @shenjackyuanjie, #6989; reported in #6988). + - Desktop and HTTP app-server turns feed an existing shared pet companion when its followed session has no live producer. Automatic selection is checked atomically by the owner; a live TUI keeps its source. The Runtime producer @@ -473,6 +478,8 @@ launcher guidance. ### Contributors +- **[@henrikdukefoss](https://github.com/henrikdukefoss)** — added the Standard Compute compatible-host descriptor, with live model discovery and its billing basis kept Unknown ([#6985](https://github.com/codewhale-hq/Codewhale/pull/6985)). +- **[@shenjackyuanjie](https://github.com/shenjackyuanjie)** — diagnosed and fixed the Windows OpenHarmony CMake generator and CLI hashing-module build failures ([#6988](https://github.com/codewhale-hq/Codewhale/issues/6988), [#6989](https://github.com/codewhale-hq/Codewhale/pull/6989)). - **[@LIghtJUNction](https://github.com/LIghtJUNction)** — plugin shell install and in-TUI plugin OAuth sign-in ([#6950](https://github.com/codewhale-hq/Codewhale/pull/6950)). - **[@SparkofSpike](https://github.com/SparkofSpike)** — live network-policy updates and goal milestone hand-back ([#6928](https://github.com/codewhale-hq/Codewhale/pull/6928), [#6930](https://github.com/codewhale-hq/Codewhale/pull/6930)), and a relocated Codewhale home ([#6947](https://github.com/codewhale-hq/Codewhale/issues/6947)). - **[@dajiaohuang](https://github.com/dajiaohuang)** — cache-write token accounting ([#6913](https://github.com/codewhale-hq/Codewhale/pull/6913)). diff --git a/crates/tui/src/pricing/default_coverage_tests.rs b/crates/tui/src/pricing/default_coverage_tests.rs index 3addaa09e3..ad5b65eaa1 100644 --- a/crates/tui/src/pricing/default_coverage_tests.rs +++ b/crates/tui/src/pricing/default_coverage_tests.rs @@ -149,7 +149,7 @@ fn shipped_default_routes_have_reviewed_pricing_coverage() { assert_eq!(built_in_count, 51, "review changed shipped-default breadth"); assert_eq!( defaults.len() - built_in_count, - 10, + 11, "review compatible-default breadth" ); let recorded_at = Utc.with_ymd_and_hms(2026, 9, 8, 12, 0, 0).unwrap(); diff --git a/crates/tui/src/pricing/default_coverage_unpriced.json b/crates/tui/src/pricing/default_coverage_unpriced.json index 987494d634..307bd36478 100644 --- a/crates/tui/src/pricing/default_coverage_unpriced.json +++ b/crates/tui/src/pricing/default_coverage_unpriced.json @@ -36,7 +36,7 @@ }, { "reason": "unknown_billing_basis", - "review": "No mode/credential product is supplied. Both MiniMax dialects share a PAYG/plan endpoint that cannot prove product (route_billing.rs:253,402; pricing.rs:534); Ollama Cloud is unclassified possible spend, not local/free (pricing.rs:411). Generic Custom and nine non-Baseten compatible defaults are transport descriptors without a reviewed product; production envelope refuses Unknown at cost_status.rs:239. AICraft is the sixth compatible default: dc170add3 restored its row from the closed PR #6171 with endpoint, credential env and bootstrap model only, and no billing product or pricing row was reviewed for it. Its default is claude-4.6-sonnet, which has no bundled/hand row either; that omission is recorded here on the shape of the descriptor, and a real source review of AICraft's billing basis is still owed. Tsubasa (#6695) is the seventh: endpoint, credential env and bootstrap model tsubasa-pro only; its public site lists prepaid-credit per-token rates, but no pricing row was reviewed or frozen for it, so it stays Unknown here too. Yolo-Auto is the eighth: its row carries endpoint, credential env and bootstrap model (qwen3.8-flash, the vendor's recommended start model on free and paid plans) only, the gateway sells flat-rate subscription tiers with no published per-token catalog to review, and the URL proves no plan product, so the route stays Unknown rather than being guessed into subscription or local-no-bill; a source review of Yolo-Auto's billing basis is owed. Cheaper Inference is the ninth non-Baseten compatible default: its gpt-5.4-mini bootstrap model and API endpoint do not establish a billing product or reviewed price, so it also remains Unknown. ChatGPT source review: the official API endpoint alone does not prove a ChatGPT plan product. route_billing.rs capture_product requires the Config's owned official registration for Subscription; the offline default inventory has none and remains Unknown. The retired backend endpoint supplies no transport or billing authority.", + "review": "No mode/credential product is supplied. Both MiniMax dialects share a PAYG/plan endpoint that cannot prove product (route_billing.rs:253,402; pricing.rs:534); Ollama Cloud is unclassified possible spend, not local/free (pricing.rs:411). Generic Custom and ten non-Baseten compatible defaults are transport descriptors without a reviewed product; production envelope refuses Unknown at cost_status.rs:239. AICraft is the sixth compatible default: dc170add3 restored its row from the closed PR #6171 with endpoint, credential env and bootstrap model only, and no billing product or pricing row was reviewed for it. Its default is claude-4.6-sonnet, which has no bundled/hand row either; that omission is recorded here on the shape of the descriptor, and a real source review of AICraft's billing basis is still owed. Tsubasa (#6695) is the seventh: endpoint, credential env and bootstrap model tsubasa-pro only; its public site lists prepaid-credit per-token rates, but no pricing row was reviewed or frozen for it, so it stays Unknown here too. Yolo-Auto is the eighth: its row carries endpoint, credential env and bootstrap model (qwen3.8-flash, the vendor's recommended start model on free and paid plans) only, the gateway sells flat-rate subscription tiers with no published per-token catalog to review, and the URL proves no plan product, so the route stays Unknown rather than being guessed into subscription or local-no-bill; a source review of Yolo-Auto's billing basis is owed. Cheaper Inference is the ninth non-Baseten compatible default: its gpt-5.4-mini bootstrap model and API endpoint do not establish a billing product or reviewed price, so it also remains Unknown. Standard Compute is the tenth: its row carries endpoint, credential env and the standardcompute router id only; the gateway sells flat monthly plans with a per-plan compute budget, and neither the URL nor the router id proves a plan product or per-request price, so the route stays Unknown. ChatGPT source review: the official API endpoint alone does not prove a ChatGPT plan product. route_billing.rs capture_product requires the Config's owned official registration for Subscription; the offline default inventory has none and remains Unknown. The retired backend endpoint supplies no transport or billing authority.", "routes": [ ["aicraft", "claude-4.6-sonnet", "https://aicraftapi.com/v1", "chat_completions", "unknown"], ["cerebras", "llama-3.3-70b", "https://api.cerebras.ai/v1", "chat_completions", "unknown"], @@ -50,6 +50,7 @@ ["ollama-cloud", "gpt-oss:120b", "https://ollama.com/v1", "chat_completions", "unknown"], ["openai-codex", "gpt-5.6", "https://api.openai.com/v1", "responses", "unknown"], ["sensenova", "deepseek-v4-flash", "https://token.sensenova.cn/v1", "chat_completions", "unknown"], + ["standardcompute", "standardcompute", "https://api.stdcmpt.com/v1", "chat_completions", "unknown"], ["tsubasa", "tsubasa-pro", "https://api.tsubasa.sh/v1", "chat_completions", "unknown"], ["yolo-auto", "qwen3.8-flash", "https://yolo-auto.com/v1", "chat_completions", "unknown"] ] diff --git a/docs/CONTRIBUTORS.md b/docs/CONTRIBUTORS.md index aac1a109a1..073873cbdd 100644 --- a/docs/CONTRIBUTORS.md +++ b/docs/CONTRIBUTORS.md @@ -41,6 +41,8 @@ changelog or release notes, and this contributor record. **Contributions** +- **[Henrik Bakke Dukefoss / henrikdukefoss](https://github.com/henrikdukefoss)** — added the Standard Compute compatible-host descriptor, with live model discovery and its billing basis kept Unknown ([#6985](https://github.com/codewhale-hq/Codewhale/pull/6985)). +- **[shenjackyuanjie](https://github.com/shenjackyuanjie)** — diagnosed and fixed the Windows OpenHarmony CMake generator and CLI hashing-module build failures ([#6988](https://github.com/codewhale-hq/Codewhale/issues/6988), [#6989](https://github.com/codewhale-hq/Codewhale/pull/6989)). - **[Sh1Zuku / SparkofSpike](https://github.com/SparkofSpike)** — live network-policy updates and goal milestone hand-back ([#6928](https://github.com/codewhale-hq/Codewhale/pull/6928), [#6930](https://github.com/codewhale-hq/Codewhale/pull/6930)), and a Codewhale home reached through a symlink or junction ([#6947](https://github.com/codewhale-hq/Codewhale/issues/6947)). - **[dajiaohuang](https://github.com/dajiaohuang)** — cache-write token accounting, with missing and explicit-zero usage preserved ([#6913](https://github.com/codewhale-hq/Codewhale/pull/6913)). - **[gaord](https://github.com/gaord)** — embedder-declared telemetry surface support without changing collection policy ([#6916](https://github.com/codewhale-hq/Codewhale/pull/6916)). diff --git a/docs/PROVIDERS.md b/docs/PROVIDERS.md index f6a92bdc0f..839b01dc40 100644 --- a/docs/PROVIDERS.md +++ b/docs/PROVIDERS.md @@ -49,6 +49,7 @@ against the vendor's own docs before trusting any value here: | Tsubasa | `https://api.tsubasa.sh/v1` | `tsubasa-pro`, `tsubasa-fast` (32,768-token context) | `TSUBASA_API_KEY` | | Cheaper Inference | `https://api.cheaperinference.com/v1` | `gpt-5.4-mini`, `claude-sonnet-5`, `gemini-3.1-pro` | `CHEAPER_INFERENCE_API_KEY` | | Yolo-Auto | `https://yolo-auto.com/v1` | `qwen3.8-flash`; `yolo` / `yolo-small` | `YOLO_AUTO_API_KEY` | +| Standard Compute | `https://api.stdcmpt.com/v1` | `standardcompute` (router); `deepseek/deepseek-v4-pro`, `anthropic/claude-sonnet-5.5` | `STANDARDCOMPUTE_API_KEY` | AICraft's roster spans DeepSeek, Anthropic Claude, Google Gemini, Qwen, GLM, MiniMax and Doubao ids on its OpenAI-compatible endpoint. The authority is @@ -65,6 +66,15 @@ Pricing varies by model and route; consult the provider’s current catalog. The authority is `GET https://api.cheaperinference.com/v1/models` with your key. Docs: . +Standard Compute offers flat monthly plans with a compute budget. By default, +requests return HTTP 402 when it is used; eligible plans can enable Pay as you go +to continue with additional prepaid charges. See its +[budget policy](https://docs.standardcompute.com/budgets-and-limits). +The `standardcompute` model id routes each request across models and providers; +vendor-prefixed ids such as `deepseek/deepseek-v4-pro` pin one model. The +authority is `GET https://api.stdcmpt.com/v1/models`. +Docs: . + OpenCode Zen and OpenCode Go are first-class provider routes, configured like any other provider below; they are not part of this table. In `/provider`, type to filter the list (letters not bound to a row action); `Ctrl+T` probes the diff --git a/docs/zh_hans/PROVIDERS.md b/docs/zh_hans/PROVIDERS.md index 546d4c6dcc..f2c3b95eeb 100644 --- a/docs/zh_hans/PROVIDERS.md +++ b/docs/zh_hans/PROVIDERS.md @@ -25,11 +25,13 @@ DeepSeek 仍是默认提供商,但 `ProviderKind::ALL` 中的每个条目都 | Tsubasa | `https://api.tsubasa.sh/v1` | `tsubasa-pro`, `tsubasa-fast`(32,768 token 上下文) | `TSUBASA_API_KEY` | | Yolo-Auto | `https://yolo-auto.com/v1` | `qwen3.8-flash`;`yolo` / `yolo-small` | `YOLO_AUTO_API_KEY` | | Cheaper Inference | `https://api.cheaperinference.com/v1` | `gpt-5.4-mini`、`claude-sonnet-5`、`gemini-3.1-pro` | `CHEAPER_INFERENCE_API_KEY` | +| Standard Compute | `https://api.stdcmpt.com/v1` | `standardcompute`(路由);`deepseek/deepseek-v4-pro`、`anthropic/claude-sonnet-5.5` | `STANDARDCOMPUTE_API_KEY` | AICraft 的 OpenAI 兼容端点提供 DeepSeek、Anthropic Claude、Google Gemini、Qwen、GLM、MiniMax 和 Doubao 的模型 ID。权威来源是带上你的密钥请求 `GET https://aicraftapi.com/v1/models` 的结果:请从该列表中选择模型,而不是从上表中选。 Tsubasa 只实现了 `GET /v1/models` 和 Chat Completions。它的两个公开模型 ID 共用 32,768 token 的上下文,小于 Codewhale 对未知模型假定的 128,000 token,因此保存后请在该路由上设置: `codewhale config set providers.tsubasa.context_window 32768`。 Cheaper Inference 是 OpenAI 兼容网关,模型 ID 不带前缀(例如 `gpt-5.4-mini`、`claude-sonnet-5`),以带密钥请求 `GET https://api.cheaperinference.com/v1/models` 的结果为准;价格随模型和路由而变,请以提供商的实时目录为准。 +Standard Compute 提供按月固定套餐和算力预算。默认情况下,预算用尽后请求返回 HTTP 402;符合条件的套餐可启用按量付费,通过额外预付费用继续请求,详见其[预算政策](https://docs.standardcompute.com/budgets-and-limits)。模型 ID `standardcompute` 会在多个模型和提供商之间路由每个请求;带厂商前缀的 ID(例如 `deepseek/deepseek-v4-pro`)则固定使用单个模型,以 `GET https://api.stdcmpt.com/v1/models` 的结果为准。 OpenCode Zen 和 OpenCode Go 是一等提供商路由,配置方式与下文其他提供商相同;它们不在上表之列。在 `/provider` 中,直接输入即可筛选列表(未绑定行操作的字母);`Ctrl+T` 探测所选行的 `/models`,只记录可达性(2xx 并不代表模型可用)。 需要保持同步的来源: diff --git a/scripts/ohos-env.ps1 b/scripts/ohos-env.ps1 index cd4c2ce90d..cebc4519bf 100644 --- a/scripts/ohos-env.ps1 +++ b/scripts/ohos-env.ps1 @@ -52,6 +52,14 @@ $env:CC_SHELL_ESCAPED_FLAGS = "1" Set-Item -Path "Env:CFLAGS_$target" -Value $commonFlags Set-Item -Path "Env:CXXFLAGS_$target" -Value $commonFlags Set-Item -Path "Env:CMAKE_TOOLCHAIN_FILE_$target" -Value $cmakeToolchain +$env:CMAKE_GENERATOR = "Ninja" +if (-not (Get-Command ninja -ErrorAction SilentlyContinue)) { + $sdkNinja = [System.IO.Path]::Combine($sdk, "build-tools", "cmake", "bin") + if (-not (Test-Path -LiteralPath ([System.IO.Path]::Combine($sdkNinja, "ninja.exe")) -PathType Leaf)) { + Stop-OhosEnv "ninja was not found on PATH and the OpenHarmony SDK does not bundle build-tools/cmake/bin/ninja.exe; install ninja so CMake-based crates such as aws-lc-sys can build for $target." + } + $env:PATH = "$sdkNinja;$env:PATH" +} $env:LIBCLANG_PATH = [System.IO.Path]::GetDirectoryName($libclang) Set-Item -Path "Env:BINDGEN_EXTRA_CLANG_ARGS_$target" -Value $commonFlags diff --git a/web/data/agent-docs.generated.json b/web/data/agent-docs.generated.json index 624ab46678..6b194d90f0 100644 --- a/web/data/agent-docs.generated.json +++ b/web/data/agent-docs.generated.json @@ -48,8 +48,8 @@ "sources": [ { "path": "docs/PROVIDERS.md", - "sha256": "6d578f231ebdb823023bf233f1163026a72ed636e2c377385e1e83e77efc28c6", - "content": "# Provider Registry\n\n> 阅读简体中文版:[zh_hans/PROVIDERS.md](zh_hans/PROVIDERS.md)\n\nSpeech recognition, synthesis, translation and video have separate execution\npaths. See [media models](MEDIA_MODELS.md) for current support and reviewed\nupstream candidates; a chat catalogue row alone does not add a media backend.\n\nThis registry describes provider behavior that is wired into the current\nCodewhale codebase. It is intentionally conservative: shipped entries are\nlimited to provider IDs, config keys, auth paths, base URLs, model resolution,\nand capability metadata that the code already knows about.\n\nDeepSeek remains the default provider, but every entry in `ProviderKind::ALL`\nis a first-class selectable provider route. `ALL` is the catalog/picker\nsurface — one identity per vendor. Dual-wire dialect kinds (`*Anthropic`, e.g.\n`deepseek-anthropic`) and the Model Studio plan variants stay on the enum for\nserde and `provider_for_kind` but are deliberately **not** catalog rows:\na plan is `mode`/`base_url` and a dialect is `wire = openai|anthropic` on the\nprimary provider config (`crates/config/src/provider_kind.rs:221-226`). Hosted\nroutes, generic OpenAI-compatible endpoints, the OpenAI Codex/ChatGPT route,\nnative Anthropic, and local runtimes all run the same terminal harness against\nthe selected provider/model/base URL.\n\nA host reached over plain Chat Completions is an ordinary named provider,\nnot a `ProviderKind`: enum variants are reserved for distinct *wires*\n(Anthropic Messages, Codex Responses, Google thought signatures). Any such\nhost is a `[providers.]` table with a base URL, a model, and a key env\n(`docs/CONFIGURATION.md`); `/provider` and `/setup` keep a \"paste a Base URL\nand a key\" path for exactly this. Offerings come from live `GET /v1/models`\nplus the Codewhale catalog rather than a compiled roster (#5350, #6289).\n\nKnown-good hosts. These ship as bundled descriptor rows in\n`crates/config/assets/provider_descriptors.json` (compiled in by\n`crates/config/src/descriptors.rs`): each row says how to reach the host — wire,\nbase URL, key env, aliases — while model ids stay live from `GET /v1/models`\nand the Codewhale catalog; the example model is only a bootstrap hint. Verify\nagainst the vendor's own docs before trusting any value here:\n\n| Host | Base URL | Example models | API key env |\n| --- | --- | --- | --- |\n| SenseNova | `https://token.sensenova.cn/v1` | `deepseek-v4-flash` | `SENSENOVA_API_KEY` |\n| Baseten | `https://inference.baseten.co/v1` | `deepseek-ai/DeepSeek-V4-Pro` | `BASETEN_API_KEY` |\n| Groq | `https://api.groq.com/openai/v1` | `llama-3.3-70b-versatile` | `GROQ_API_KEY` |\n| Cerebras | `https://api.cerebras.ai/v1` | `llama-3.3-70b` | `CEREBRAS_API_KEY` |\n| Command Code | `https://api.commandcode.ai/provider/v1` | `deepseek/deepseek-v4-flash` | `COMMAND_CODE_API_KEY` |\n| Alibaba Model Studio (DashScope) | `https://dashscope-intl.aliyuncs.com/compatible-mode/v1` | `qwen3.8-flash` | `DASHSCOPE_API_KEY` |\n| AICraft | `https://aicraftapi.com/v1` | `claude-4.6-sonnet`; DeepSeek / Claude / Gemini / Qwen / GLM / MiniMax / Doubao families | `AICRAFT_API_KEY` |\n| Tsubasa | `https://api.tsubasa.sh/v1` | `tsubasa-pro`, `tsubasa-fast` (32,768-token context) | `TSUBASA_API_KEY` |\n| Cheaper Inference | `https://api.cheaperinference.com/v1` | `gpt-5.4-mini`, `claude-sonnet-5`, `gemini-3.1-pro` | `CHEAPER_INFERENCE_API_KEY` |\n| Yolo-Auto | `https://yolo-auto.com/v1` | `qwen3.8-flash`; `yolo` / `yolo-small` | `YOLO_AUTO_API_KEY` |\n\nAICraft's roster spans DeepSeek, Anthropic Claude, Google Gemini, Qwen, GLM,\nMiniMax and Doubao ids on its OpenAI-compatible endpoint. The authority is\n`GET https://aicraftapi.com/v1/models` with your key — pick a model from that\nlist, not from this table.\nTsubasa implements only `GET /v1/models` and Chat Completions. Its two public\nmodel ids share a 32,768-token context, smaller than the 128,000 tokens Codewhale assumes\nfor an unknown model, so set it on the route after saving:\n`codewhale config set providers.tsubasa.context_window 32768`.\n\nCheaper Inference is an OpenAI-compatible gateway with one key for models from\nseveral labs. Model ids are bare, such as `gpt-5.4-mini` or `claude-sonnet-5`.\nPricing varies by model and route; consult the provider’s current catalog.\nThe authority is `GET https://api.cheaperinference.com/v1/models` with your key.\nDocs: .\n\nOpenCode Zen and OpenCode Go are first-class provider routes, configured like\nany other provider below; they are not part of this table. In `/provider`,\ntype to filter the list (letters not bound to a row action); `Ctrl+T` probes the\nselected row's `/models` and records reachability only (a 2xx is not\nmodel-ready).\n\nSources to keep in sync:\n\n- `crates/config/assets/provider_descriptors.json` - built-in and compatible-host\n labels, defaults, aliases, key-env lists, config/secret slots, and credential\n guidance. `crates/config/build.rs` generates immutable typed views and the\n existing constant projections from this one data owner.\n- `crates/config/src/provider_kind.rs` and `src/lib.rs` - legacy identity serde,\n config schema, environment precedence and Rust route/auth behavior.\n- `crates/tui/src/config.rs` - captures and verifies exact configured provider\n identities and keeps provider-specific credential and route policy in Rust.\n- `crates/config/assets/catalog_corrections.json` `reviewed` - intrinsic facts,\n scoped selector aliases, completion references and pure transport metadata.\n The existing seed renderer embeds this reviewed supplement in Models.dev.\n- `crates/agent/src/lib.rs` - compatibility projection of those shared selector\n rows, used by `codewhale model resolve` (and the `[model]` config surface).\n `codewhale model list` reads the resolved provider lake instead, so a single\n list shows bundled, live and configured rows together.\n- `config.example.toml` and `docs/CONFIGURATION.md` - user-facing config\n examples and environment variable reference.\n- `scripts/check-provider-registry.py` - drift check for canonical provider\n IDs, live TUI provider IDs, TOML table names, static registry rows, and\n documented defaults.\n\n## Captured Provider Identity\n\nPresentation names, labels, aliases, and historical wire tags come from\n`provider_descriptors.json`. `ProviderKind` remains the Rust-owned intrinsic\ncredential, protocol, and region distinction. A configured route captures both\nits kind and exact table key; a custom table named `openai` stays custom and\ndoes not acquire OpenAI credentials or protocol rules from its name. Case is\nsignificant for custom keys.\n\nDeepSeek China has three preserved representations: `deepseek_c_n` in released\nTUI serde wrappers, `deepseek-cn` as its captured route ID, and `deepseek_cn` as\nits config leaf. Its intrinsic kind is DeepSeek, while its table and endpoint\nstay distinct.\n\nAn old custom route without an additive provider ID can resume only with a\nverified root `base_url` migration into the active `providers.custom` table.\nThat private receipt is bound to the parsed table generation. A table-only,\nprofile-only, conflicting, or later replaced table cannot establish the\nmissing identity; an explicit empty ID is refused. Writes reuse the existing\nlocked config mutation and undo comparison, obtain the fresh migration receipt\nunder that lock, and verify the captured table before changing a leaf.\n\nIn-flight requests retain their captured identity, endpoint, and credential\ngeneration. Health lookup cannot treat an opaque credential reference as ready\nmerely because an earlier request used the same authentication class.\n\n## Provider Selection\n\nWith no saved model, no `default_text_model`, and no `CODEWHALE_MODEL` or\nprovider-specific model variable, a fresh install runs `deepseek-flash` on the\nDeepSeek provider. Precedence is the active provider's configured default, then\nits catalog default — so an explicit `default_text_model` is not silently\noverridden by whichever model the shipped catalog lists first.\n\nRefresh model catalogs without installing a new Codewhale release:\n\n```sh\ncodewhale models --update\ncodewhale models --update --provider openai\ncodewhale models --provider openai --json\n```\n\n`models --update` (also `--refresh`) updates the shared Models.dev metadata\nand calls the existing `/models` endpoint for each configured provider with\nits own credentials. `--provider ID` restricts the refresh to that exact\nprovider, including named custom endpoints. It makes no inference requests\nand never changes the saved provider or model. A command-line API key is\nconfined to the active provider; other routes are reported as skipped for\nthat invocation.\n\nPlain `models` lists the active provider's saved catalog without provider requests.\nFor ChatGPT, it validates the selected registration locally before reading\nthat account's saved roster. Successful refreshes are saved under Codewhale's\ncatalog directory and used by the model/provider pickers. Cache files are\nscoped to provider identity and endpoint; a failed refresh preserves prior\nrows. Text output reports source, last successful fetch time (Unix seconds),\nand freshness. `--update --json` adds per-source receipts and aggregate counts;\npartial failures return a nonzero exit code after writing those receipts.\nOrdinary `models --json` keeps its model-array format. Bundled/configured\nfallbacks are not proof that an account can use every listed model.\n\n### Sign in with ChatGPT\n\nThe `openai-codex` provider ID now uses OpenAI's official open-source\n[Sign in with ChatGPT flow](https://developers.openai.com/siwc/token-sharing-open-source).\nSign in and refresh the selected account's catalog:\n\n```sh\ncodewhale auth chatgpt\ncodewhale models --update --provider openai-codex\ncodewhale --provider openai-codex\n```\n\nSign-in opens your system browser, uses a loopback callback and PKCE, validates\nthe returned identity, and stores the issued registration and renewable tokens\nin Codewhale's protected credential storage. Permission to use your ChatGPT\nplan is separate from identity sign-in. A declined or missing plan grant stops\ninference; choose another provider explicitly if you want another billing path.\n`codewhale auth chatgpt-revoke` signs out of the Codewhale-owned session.\nThis experimental implementation retains one active registration. A picker\nfor multiple saved ChatGPT accounts is not implemented yet.\n\nModel discovery uses your granted bearer token at\n`GET https://api.openai.com/v1/models`; inference uses the public\n`POST https://api.openai.com/v1/responses` endpoint. The model picker keeps\nOpenAI's display labels and order and lists only entries with `visibility: list`.\nThe catalog contains no credentials and is bound to the verified issuer,\nissued client ID, and account subject. Another account or workspace never\ninherits those model choices. Missing, invalid, or older-than-one-day rosters\nare reported explicitly and provide no account entitlement evidence. Run the\nrefresh command after signing in. Neither model discovery nor ordinary listing\nstarts an inference request. Imported Codex CLI tokens and legacy process-token\nvariables cannot authorize this official plan route.\n\nEligible requests consume your ChatGPT plan or credits. ChatGPT Plus's\nfive-hour allowance is shared across apps; each app receives no separate\nallowance. The documented five-hour limit does not apply to Pro. App-specific\nlimits can also apply. Review limits and access in\n[ChatGPT usage settings](https://chatgpt.com/settings/usage). Codewhale does\nnot silently switch to an API key or another provider when a limit is reached.\n\nThis is an OpenAI preview for open-source/local apps. It does not grant access\nto ChatGPT conversation history. Requests stream with `store: false` and\n`stream: true`, while Codewhale retains its own session history and tools.\nOpenAI-hosted image generation, file search, Code Interpreter, native computer\nuse, hosted MCP/connectors, and Responses `tool_search` are unavailable on this\nroute; Codewhale's own tools use supported function/custom tool calls.\nThe ChatGPT preview requests one function call at a time.\nSee [preview limitations](https://developers.openai.com/siwc/token-sharing-open-source/preview-limitations).\nPaid or remotely hosted applications require the\n[commercial partner interest process](https://openai.com/form/sign-in-with-chatgpt-interest/);\nthis local integration is not commercial approval.\n\nThe canonical provider IDs are the entries of `ProviderKind::ALL`\n(`crates/config/src/provider_kind.rs`), in that order:\n\n`deepseek`, `nvidia-nim`, `openai`, `atlascloud`, `wanjie-ark`, `volcengine`,\n`openrouter`, `orcarouter`, `xiaomi-mimo`, `novita`, `fireworks`, `siliconflow`, `arcee`,\n`siliconflow-CN`, `moonshot`, `sglang`, `vllm`, `ollama`, `ollama-cloud`, `huggingface`,\n`together`, `qianfan`, `openai-codex`, `anthropic`, `openmodel`, `zai`,\n`stepfun`, `minimax`, `deepinfra`, `sakana`, `longcat`, `opencode-go`,\n`opencode-zen`, `meta`, `xai`, `mistral`, `telecomjs`, `modelstudio-token-plan`, `modelscope`,\n`google`, `edenai`, `zenmux`, `csdn`, `concentrate`, `codewhale`, and `custom`.\n\n`deepseek-anthropic` is *not* on this list — it is a wire dialect of\n`deepseek`, reached with `wire = \"anthropic\"`, not a separate route to select.\n\nUse any of these surfaces to select a provider:\n\n- CLI: `codewhale --provider `\n- TUI: `/provider ` or the provider picker\n- Env: `CODEWHALE_PROVIDER=`; `DEEPSEEK_PROVIDER=` is the legacy alias\n- Config: `provider = \"\"`\n\n`deepseek-cn`, `deepseek_china`, `deepseekcn`, and `deepseek-china` are accepted\nas legacy aliases for `deepseek`. They do not select a different official host;\nDeepSeek uses the same official API host worldwide.\n\n`deepseek_anthropic`, `deepseek-claude`, and `deepseek_claude` select\n`deepseek-anthropic`, the opt-in DeepSeek route that speaks the Anthropic\nMessages API at `https://api.deepseek.com/anthropic`. It keeps the normal\nDeepSeek API key path but uses `x-api-key` plus `anthropic-version: 2023-06-01`\ninstead of Bearer auth. If the key already lives in official DeepSeek Harness\n(`dsh`) at `$DSH_HOME/.credentials.yaml`, grant read-only access with\n`codewhale auth external-consent --provider deepseek --mode read-only`.\nCodewhale never writes that file and only reads `DEEPSEEK_API_KEY`.\n\n`huggingface`, `hugging-face`, `hugging_face`, and `hf` all select the\nHugging Face Inference Providers route. This is the OpenAI-compatible router\npath for chat/inference, not Hub browsing, model-card inspection, uploads, or\nartifact export.\n\n`telecomjs`, `telecom-js`, `telecom_js`, `telecomjs-cn`, and `tokenhub` all\nselect the TelecomJS TokenHub route. Its authenticated `/models` catalog is\nkey-scoped and remains isolated from every other provider's live snapshot.\n\nFresh shared config writes to `~/.codewhale/config.toml`. Existing\n`~/.deepseek/config.toml` files are still read for compatibility.\n\n### Legacy Antigravity tombstone\n\nAntigravity is not a Codewhale provider and cannot be selected or run. Existing\nlegacy Antigravity provider state is recognized only as a non-runnable migration\ntombstone. Run `codewhale auth clear --provider antigravity` to forget only\nCodewhale-owned legacy configuration and consent metadata. This does not sign\nout of, revoke, read, or otherwise alter any official Google or Antigravity\nsession. For Gemini, select the supported `google` provider and supply\n`GEMINI_API_KEY`.\n\n### Wire Protocol Compatibility\n\nProvider selection is explicit. A model string prefix such as\n`deepseek-ai/...`, `deepseek/...`, `qwen/...`, or `arcee-ai/...` is a\nprovider-owned wire ID or catalog namespace hint under the selected provider.\nIt is not a provider switch and must not be treated as proof that the route is\nDeepSeek, OpenRouter, or any other provider.\n\nSet the route with `provider = \"\"`, `CODEWHALE_PROVIDER=`, or\n`codewhale --provider `. Set the request model with `CODEWHALE_MODEL`, a\nprovider-specific model env var, top-level `default_text_model`, or\n`[providers.].model`. Set the endpoint with `CODEWHALE_BASE_URL`, a\nprovider-specific base URL env var, or `[providers.
].base_url`. Set auth\nwith `codewhale auth set --provider `, `[providers.
].api_key`, or\nthe listed provider env vars.\n\n| Provider ID | TOML table | Wire protocol | Auth env vars |\n| --- | --- | --- | --- |\n| `deepseek` | `[providers.deepseek]` | Model-aware: Responses default (`deepseek-flash`); Chat Completions (`deepseek-v4-pro`) | `DEEPSEEK_API_KEY` |\n| `deepseek-anthropic` | `[providers.deepseek_anthropic]` | Anthropic Messages | `DEEPSEEK_API_KEY` |\n| `nvidia-nim` | `[providers.nvidia_nim]` | OpenAI Chat Completions | `NVIDIA_API_KEY`, `NVIDIA_NIM_API_KEY` |\n| `openai` | `[providers.openai]` | OpenAI Chat Completions | `OPENAI_API_KEY` |\n| `atlascloud` | `[providers.atlascloud]` | OpenAI Chat Completions | `ATLASCLOUD_API_KEY` |\n| `wanjie-ark` | `[providers.wanjie_ark]` | OpenAI Chat Completions | `WANJIE_ARK_API_KEY`, `WANJIE_API_KEY`, `WANJIE_MAAS_API_KEY` |\n| `volcengine` | `[providers.volcengine]` | OpenAI Chat Completions | `VOLCENGINE_API_KEY`, `VOLCENGINE_ARK_API_KEY`, `ARK_API_KEY` |\n| `openrouter` | `[providers.openrouter]` | OpenAI Chat Completions | `OPENROUTER_API_KEY` |\n| `xiaomi-mimo` | `[providers.xiaomi_mimo]` | OpenAI Chat Completions | `XIAOMI_MIMO_TOKEN_PLAN_API_KEY`, `MIMO_TOKEN_PLAN_API_KEY`, `XIAOMI_MIMO_API_KEY`, `XIAOMI_API_KEY`, `MIMO_API_KEY` |\n| `novita` | `[providers.novita]` | OpenAI Chat Completions | `NOVITA_API_KEY` |\n| `fireworks` | `[providers.fireworks]` | OpenAI Chat Completions | `FIREWORKS_API_KEY` |\n| `siliconflow` | `[providers.siliconflow]` | OpenAI Chat Completions | `SILICONFLOW_API_KEY` |\n| `arcee` | `[providers.arcee]` | OpenAI Chat Completions | `ARCEE_API_KEY` |\n| `siliconflow-CN` | `[providers.siliconflow_cn]` | OpenAI Chat Completions | `SILICONFLOW_API_KEY` |\n| `moonshot` | `[providers.moonshot]` | OpenAI Chat Completions | `MOONSHOT_API_KEY`, `KIMI_API_KEY` |\n| `sglang` | `[providers.sglang]` | OpenAI Chat Completions | `SGLANG_API_KEY` |\n| `vllm` | `[providers.vllm]` | OpenAI Chat Completions | `VLLM_API_KEY` |\n| `ollama` | `[providers.ollama]` | Local OpenAI-compatible Chat Completions | `OLLAMA_API_KEY` (optional; only for an authenticated local route) |\n| `ollama-cloud` | `[providers.ollama_cloud]` | Hosted OpenAI-compatible Chat Completions | `OLLAMA_CLOUD_API_KEY`, `OLLAMA_API_KEY` |\n| `huggingface` | `[providers.huggingface]` | OpenAI Chat Completions | `HUGGINGFACE_API_KEY`, `HF_TOKEN` |\n| `modelscope` | `[providers.modelscope]` | OpenAI Chat Completions | `MODELSCOPE_API_KEY` |\n| `together` | `[providers.together]` | OpenAI Chat Completions | `TOGETHER_API_KEY` |\n| `qianfan` | `[providers.qianfan]` | OpenAI Chat Completions | `QIANFAN_API_KEY`, `BAIDU_QIANFAN_API_KEY` |\n| `openai-codex` | `[providers.openai_codex]` | OpenAI Responses | Official Sign in with ChatGPT (`codewhale auth chatgpt`) with a validated Codewhale-owned plan grant |\n| `anthropic` | `[providers.anthropic]` | Anthropic Messages | `ANTHROPIC_API_KEY` or `codewhale auth claude` |\n| `openmodel` | `[providers.openmodel]` | Anthropic Messages | `OPENMODEL_API_KEY` |\n| `zai` | `[providers.zai]` | OpenAI Chat Completions | `ZAI_API_KEY`, `Z_AI_API_KEY` |\n| `stepfun` | `[providers.stepfun]` | OpenAI Chat Completions | `STEPFUN_API_KEY`, `STEP_API_KEY` |\n| `minimax` | `[providers.minimax]` | OpenAI Chat Completions | `MINIMAX_API_KEY` |\n| `deepinfra` | `[providers.deepinfra]` | OpenAI Chat Completions | `DEEPINFRA_API_KEY`, `DEEPINFRA_TOKEN` |\n| `sakana` | `[providers.sakana]` | OpenAI Chat Completions | `FUGU_API_KEY`, `SAKANA_API_KEY` |\n| `longcat` | `[providers.longcat]` | OpenAI Chat Completions | `LONGCAT_API_KEY` |\n| `opencode-go` | `[providers.opencode_go]` | OpenAI Chat Completions | `OPENCODE_GO_API_KEY` |\n| `opencode-zen` | `[providers.opencode_zen]` | Model-aware: OpenAI Responses, Anthropic Messages, or OpenAI Chat Completions | `OPENCODE_ZEN_API_KEY`, `OPENCODE_API_KEY` |\n| `meta` | `[providers.meta]` | OpenAI Chat Completions | `META_MODEL_API_KEY`, `MODEL_API_KEY` |\n| `telecomjs` | `[providers.telecomjs]` | OpenAI Chat Completions | `TELECOMJS_API_KEY` |\n| `xai` | `[providers.xai]` | OpenAI Chat Completions | `XAI_API_KEY` |\n| `mistral` | `[providers.mistral]` | OpenAI Chat Completions | `MISTRAL_API_KEY` |\n| `google` | `[providers.google]` | OpenAI Chat Completions (official Gemini OpenAI-compat route; captures and replays thought signatures on tool calls) | `GOOGLE_API_KEY`, `GEMINI_API_KEY` |\n| `edenai` | `[providers.edenai]` | OpenAI Chat Completions | `EDENAI_API_KEY` |\n| `zenmux` | `[providers.zenmux]` | OpenAI Chat Completions | `ZENMUX_API_KEY` |\n| `csdn` | `[providers.csdn]` | OpenAI Chat Completions | `CSDN_API_KEY` |\n| `concentrate` | `[providers.concentrate]` | OpenAI Responses (`/v1/responses`) | `CONCENTRATE_API_KEY` |\n| `codewhale` | `[providers.codewhale]` | Model-aware: OpenAI Chat Completions (`/v1/chat/completions`) or Anthropic Messages (`/v1/messages`), chosen per model by the account catalog | `CODEWHALE_API_KEY` |\n| `modelstudio-token-plan` | `[providers.modelstudio_token_plan]` | OpenAI Chat Completions | `MODELSTUDIO_API_KEY`, `DASHSCOPE_API_KEY` |\n| `modelstudio-token-plan-anthropic` | `[providers.modelstudio_token_plan_anthropic]` | Anthropic Messages | `MODELSTUDIO_API_KEY`, `DASHSCOPE_API_KEY` |\n| `modelstudio-coding-plan` | `[providers.modelstudio_coding_plan]` | OpenAI Chat Completions | `MODELSTUDIO_API_KEY`, `DASHSCOPE_API_KEY` |\n| `modelstudio-coding-plan-anthropic` | `[providers.modelstudio_coding_plan_anthropic]` | Anthropic Messages | `MODELSTUDIO_API_KEY`, `DASHSCOPE_API_KEY` |\n\nDefault base URLs and models for each route are listed in the shipped provider\ntable below. The wire protocol values above are derived from\n`crates/config/src/provider.rs`: `ChatCompletions` is the default,\n`openai-codex` overrides to `Responses`; `deepseek-anthropic`, `anthropic`, and\n`openmodel` override to `AnthropicMessages`; `opencode-zen` resolves the\nprotocol from the selected model's curated offering; and `deepseek` is\nmodel-aware — the shipped default `deepseek-flash` (and legacy\n`deepseek-v4-flash`) rides the Responses endpoint while `deepseek-v4-pro`\nstays on Chat Completions.\n\n## Auth And Env Rules\n\nFor hosted providers, `codewhale auth set --provider ` saves an API key for\nthat provider. API-key environment variables are fallback inputs after saved\nconfig and keyring credentials; an explicit process-level `--api-key` still\nwins for that launch.\n\nFor base URL and model selection, prefer:\n\n- `CODEWHALE_BASE_URL` / `CODEWHALE_MODEL` for the active provider.\n- Provider-specific base URL/model env vars when listed below.\n- `DEEPSEEK_BASE_URL`, `DEEPSEEK_MODEL`, and `DEEPSEEK_DEFAULT_TEXT_MODEL` as\n legacy aliases.\n\nNon-local `http://` base URLs are rejected unless\n`DEEPSEEK_ALLOW_INSECURE_HTTP=1` is set. Loopback HTTP URLs are allowed for\nself-hosted runtimes.\n\n## Custom DeepSeek-Compatible Endpoints\n\nMost custom DeepSeek-compatible deployments can use an existing provider ID.\nDo not create `[providers.deepseek_custom]`; the provider table names are fixed.\nInstead, choose the closest shipped route and override its endpoint/model:\n\n- DeepSeek-compatible hosted API: keep `provider = \"deepseek\"` and set\n `[providers.deepseek].base_url` plus `[providers.deepseek].model`, or launch\n with `DEEPSEEK_BASE_URL` and `DEEPSEEK_MODEL`.\n- Generic OpenAI-compatible gateway: use `provider = \"openai\"` with\n `[providers.openai].base_url` plus `[providers.openai].model`, or launch with\n `OPENAI_BASE_URL` and `OPENAI_MODEL`.\n- Multiple named OpenAI-compatible gateways, or local routes you want to pin\n from an AgentProfile, can use a custom table such as\n `[providers.lm-studio] kind = \"openai-compatible\"` and select it with\n `provider = \"lm-studio\"` or a profile `provider = \"lm-studio\"`.\n- Local OpenAI-compatible runtimes: use `provider = \"vllm\"`, `\"sglang\"`, or\n `\"ollama\"` with the matching provider-specific base URL/model values.\n\nExample user config for a DeepSeek-compatible host:\n\n```toml\nprovider = \"deepseek\"\n\n[providers.deepseek]\napi_key = \"YOUR_API_KEY\"\nbase_url = \"https://your-provider.example/v1\"\nmodel = \"deepseek-ai/DeepSeek-V4-Pro\"\n```\n\nExample user config for a generic gateway:\n\n```toml\nprovider = \"openai\"\n\n[providers.openai]\napi_key = \"YOUR_GATEWAY_API_KEY\"\nbase_url = \"https://gateway.example/v1\"\nmodel = \"your-deepseek-compatible-model\"\n```\n\nAlibaba Cloud Model Studio (Bailian / DashScope) is a first-class provider as\nof v0.9.4 with two plan profiles: Token Plan (Personal / Team) and Coding Plan.\nBoth plans expose an OpenAI-compatible Chat Completions endpoint and an\nAnthropic-compatible Messages endpoint.\n\n**Token Plan** (Personal and Team share the same AP-Southeast endpoint):\n\n```toml\nprovider = \"modelstudio-token-plan\"\n\n[providers.modelstudio_token_plan]\napi_key = \"YOUR_MODELSTUDIO_API_KEY\"\n# base_url defaults to https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1\nmodel = \"qwen3.8-max\" # or qwen3.8-max-preview | qwen3.7-plus | qwen3.7-max |\n # qwen3.6-flash | deepseek-v4-pro | deepseek-v4-flash-0731 |\n # glm-5.2\n```\n\n**Coding Plan** (separate international endpoint):\n\n```toml\nprovider = \"modelstudio-coding-plan\"\n\n[providers.modelstudio_coding_plan]\napi_key = \"YOUR_MODELSTUDIO_API_KEY\"\n# base_url defaults to https://coding-intl.dashscope.aliyuncs.com/v1\nmodel = \"qwen3.8-max\"\n```\n\n**Anthropic-compatible dialect** — both plans also expose a native Anthropic\nMessages path. Select it with the `-anthropic` provider suffix:\n\n```toml\nprovider = \"modelstudio-token-plan-anthropic\"\n\n[providers.modelstudio_token_plan_anthropic]\napi_key = \"YOUR_MODELSTUDIO_API_KEY\"\n# base_url defaults to https://token-plan.ap-southeast-1.maas.aliyuncs.com/apps/anthropic\nmodel = \"qwen3.8-max\"\n```\n\nCreate or copy a Model Studio API key from the\n[Bailian console](https://bailian.console.aliyun.com/). The API key is shared\nacross all four provider IDs above; only the base URL and wire protocol differ.\n\n**Thinking / reasoning.** Reasoning surfaces in the TUI's Thinking view on both\ndialects, per Model Studio's\n[deep-thinking docs](https://www.alibabacloud.com/help/en/model-studio/deep-thinking).\n\nOn the OpenAI-compatible routes the top-level controls are **route- and\nmodel-specific**, and Codewhale fails closed: they are sent only when the\nconfigured `base_url` is an official Alibaba Chat Completions host\n(`*.maas.aliyuncs.com/compatible-mode/v1`, including workspace-scoped hosts, or\n`coding-intl.dashscope.aliyuncs.com/v1`). A custom `base_url` on the same\nprovider ID gets `thinking`, `enable_thinking`, `preserve_thinking`, and\n`reasoning_effort` stripped, so an arbitrary OpenAI-compatible gateway is never\nhanded Alibaba's dialect. On a verified host:\n\n- **Hybrid models** (`qwen3.7-*`, `qwen3.6-*`, `deepseek-v4*`, `glm-*`,\n `kimi-k2.6*`) get `enable_thinking`: `false` for `off`, `true` otherwise.\n- **Thinking-only models** — `qwen3.8-max` (catalogued `thinking: always_on`),\n `qwen3.8-max-preview` (effort/budget options, no toggle), and\n `kimi-k2.7-code` — get **no** enable/disable switch at all. Sending one is at\n best ignored.\n- `preserve_thinking` is sent for the models documented to accept it\n (`qwen3.7-max`/`-plus`, `qwen3.6-max-preview`/`-plus`/`-flash`, `kimi-k2.6*`,\n `kimi-k2.7-code`), so the next turn keeps the assistant's trace.\n- `reasoning_effort` is sent only for the two families with a documented ladder\n — `deepseek-v4*` and `glm-5`/`5.1`/`5.2` — mapped to `high` or `max`.\n\nReasoning streams back as `delta.reasoning_content`. It is replayed to the\nprovider on later turns only for the `preserve_thinking` models above and the\nthinking-only models; `deepseek-v3.1`, `deepseek-v3.2`, and `glm-*` history\nstays stripped pending live confirmation that DashScope accepts\n`reasoning_content` in input messages. (`deepseek-v4*` replays regardless — the\nDeepSeek thinking-mode contract requires it on every provider.)\n\nOn the Anthropic-compatible routes, thinking uses the documented\n`{\"type\":\"enabled\",\"budget_tokens\":N}` / `{\"type\":\"disabled\"}` shapes from the\n[Anthropic-compatible Messages API](https://www.alibabacloud.com/help/en/model-studio/anthropic-api-messages),\nwith `budget_tokens` derived from the effort level.\n\nDeepSeek (`deepseek-v4-pro`, `deepseek-v4-flash-0731`) and GLM (`glm-5.2`)\nmodels served by Model Studio are provider-scoped and do not collide with the\nfirst-party DeepSeek or Zhipu/Z.ai routes. Model Studio publishes no `glm-5.3`\nentry, so Codewhale does not offer one on this route.\nPay-as-you-go workspace-id templating is not yet in the built-in provider; use\na custom provider entry for that plan until a follow-up adds it.\n\nPrivate gateways with broken or intercepted certificates should use\n`SSL_CERT_FILE` with a trusted CA bundle. The legacy\n`insecure_skip_tls_verify = true` key is still parsed so `codewhale doctor` can\nreport stale configs, but provider clients reject it instead of skipping TLS\ncertificate verification.\n\nKeep `provider`, `api_key`, and `base_url` in user config or process\nenvironment. Project-local config overlays intentionally cannot set those keys,\nso a repository cannot silently redirect prompts or credentials to another\nendpoint.\n\n## Local Models (DS4, Ollama, vLLM, SGLang)\n\nSelf-hosted OpenAI-compatible runtimes are first-class routes and are keyless\nby default — set an API key only when your server requires one. Start your\nrunner, then point Codewhale at it with `--provider` / `/provider` or a config\ntable.\n\n| Runner | Default base URL | Default model | Base URL override |\n| --- | --- | --- | --- |\n| `ollama` | `http://localhost:11434/v1` | live tag from `GET /v1/models` (pre-refresh: `unknown`) | `OLLAMA_BASE_URL` |\n| `vllm` | `http://localhost:8000/v1` | `deepseek-ai/DeepSeek-V4-Pro` | `VLLM_BASE_URL` |\n| `sglang` | `http://localhost:30000/v1` | `deepseek-ai/DeepSeek-V4-Pro` | `SGLANG_BASE_URL` |\n\n### DS4 (DwarfStar)\n\n[DS4](https://github.com/antirez/ds4/tree/84cc882352757baf628a1776badf7cc54d584e28)\nserves DeepSeek V4 Flash and Pro locally\nthrough an OpenAI-compatible API. Start DS4, then open Codewhale's prefilled,\nkeyless setup form:\n\n```bash\n./ds4-server --ctx 100000 --kv-disk-dir /tmp/ds4-kv --kv-disk-space-mb 8192\ncodewhale\n# In Codewhale: /setup provider ds4\n```\n\nReview the prefilled route and press Enter to save it. The preset budgets a\n100,000-token context to match that starter command and defaults to the Flash\ncompatibility alias. Check the local route explicitly with\n`codewhale doctor --probe-local`.\n\nDS4 loads the actual GGUF when the server starts. Its `deepseek-v4-flash` and\n`deepseek-v4-pro` API ids are compatibility aliases; changing `/model` does\nnot swap the resident model. To run Pro, download the supported Pro weights\nand start `ds4-server -m ...` as described by DS4. Update\n`context_window` whenever the server's `--ctx` value changes.\n\nThe equivalent config is:\n\n```toml\nprovider = \"ds4\"\n\n[providers.ds4]\nkind = \"openai-compatible\"\nbase_url = \"http://127.0.0.1:8000/v1\"\nmodel = \"deepseek-v4-flash\"\nauth_mode = \"none\"\ncontext_window = 100000\n```\n\nCodewhale reuses its existing OpenAI-compatible transport and DeepSeek\nreasoning/tool-call shaping for DS4. It does not invent an API key, confuse an\nAPI alias with the loaded GGUF, or silently switch to a hosted DeepSeek route.\nThe pinned DS4 [agent-client contract](https://github.com/antirez/ds4/blob/84cc882352757baf628a1776badf7cc54d584e28/README.md#agent-client-usage)\ndocuments Chat Completions at `/v1`, DeepSeek thinking replay, streamed usage,\n`max_tokens`, and no strict-tool mode; Codewhale follows those exact route\nfacts instead of inheriting unsupported capabilities from a generic gateway.\nThe primary sources for model-facing behavior are DeepSeek's official\n[thinking-mode](https://api-docs.deepseek.com/guides/thinking_mode),\n[tool-call](https://api-docs.deepseek.com/guides/tool_calls), and\n[Chat Completion](https://api-docs.deepseek.com/api/create-chat-completion)\ncontracts. The pinned\n[DeepSeek Harness adapter](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/packages/llm/llm-deepseek/README.md)\nis only a secondary implementation cross-check; it is not the API contract.\n\n### Ollama\n\n```bash\nollama serve # if not already running\nollama pull # e.g. deepseek-v4-flash, or any tag you prefer\ncodewhale --provider ollama --model \n```\n\nProvider-hinted model names are sent as-is, so `--model qwen3:8b` works with\nany tag Ollama has pulled.\n\n### Ollama Cloud\n\nOllama Cloud is a separate hosted provider. It uses the authenticated\nOpenAI-compatible `/v1/chat/completions` route and defaults to `gpt-oss:120b`:\n\n```toml\nprovider = \"ollama-cloud\"\n\n[providers.ollama_cloud]\nbase_url = \"https://ollama.com/v1\"\nmodel = \"gpt-oss:120b\"\n```\n\nCreate a key in [Ollama account settings](https://ollama.com/settings/keys),\nthen run `codewhale auth set --provider ollama-cloud`. For ambient auth,\n`OLLAMA_CLOUD_API_KEY` wins over Ollama's official `OLLAMA_API_KEY`.\n`OLLAMA_CLOUD_BASE_URL` and `OLLAMA_CLOUD_MODEL` override the Cloud defaults;\narbitrary provider-owned model IDs pass through unchanged. Local `ollama`\nremains a separate, keyless-by-default provider.\n\nCompatibility is read-only and in memory: a released config that selected\n`provider = \"ollama\"` with the exact normalized\n`[providers.ollama] base_url = \"https://ollama.com/v1\"` tuple is treated as\n`ollama-cloud` at runtime. Only that exact tuple may fall back to the legacy\n`ollama` secret slot. Codewhale does not rewrite the config, copy or delete a\nsecret, migrate neighboring paths, or make an explicit `ollama-cloud` route\nconsume the legacy slot.\n\n### vLLM\n\n```bash\nvllm serve --port 8000\n# or: python -m vllm.entrypoints.openai.api_server --model --port 8000\ncodewhale --provider vllm --model \n```\n\nvLLM's OpenAI-compatible server listens on port 8000 by default, matching\nCodewhale's `VLLM_BASE_URL`.\n\n### SGLang\n\n```bash\npython -m sglang.launch_server --model-path --port 30000\ncodewhale --provider sglang --model \n```\n\nSGLang's default port 30000 matches Codewhale's `SGLANG_BASE_URL`.\n\n### Pinning a local route in config\n\n```toml\nprovider = \"ollama\" # or \"vllm\" / \"sglang\"\n\n[providers.ollama]\nmodel = \"qwen3:8b\" # default is deepseek-v4-flash\n# base_url defaults to http://localhost:11434/v1\n```\n\nLocal models that print tool-call JSON without the wire markers: see\n[When a Local Model Prints Tool JSON](#when-a-local-model-prints-tool-json).\n\n## Credential Links\n\nProvider setup surfaces use the same typed credential metadata as onboarding,\n`/provider`, `/links`, setup receipts, and doctor output. A missing URL is\nintentional: local, OAuth-only, and user-defined routes show their supported\nconfiguration path instead of guessing a vendor page.\n\n| Provider ID | Credential or console link |\n| --- | --- |\n| `deepseek`, `deepseek-anthropic` | [DeepSeek API keys](https://platform.deepseek.com/api_keys) |\n| `nvidia-nim` | [NVIDIA NIM API keys](https://build.nvidia.com/settings/api-keys) |\n| `openai` | [OpenAI API keys](https://platform.openai.com/api-keys) |\n| `atlascloud` | [Atlas Cloud API keys](https://atlascloud.ai/docs/en/api-keys) |\n| `wanjie-ark` | [Wanjie MaaS APIKEY docs](https://docs.wanjiedata.com/maas/maas-openapi-v1.html) |\n| `volcengine` | [Volcengine Ark API keys](https://console.volcengine.com/ark/apiKey) |\n| `openrouter` | [OpenRouter keys](https://openrouter.ai/settings/keys) |\n| `xiaomi-mimo` | [Xiaomi MiMo Token Plan](https://platform.xiaomimimo.com/token-plan) |\n| `novita` | [Novita key management](https://novita.ai/en/settings/key-management) |\n| `fireworks` | [Fireworks API keys](https://fireworks.ai/api-keys) |\n| `siliconflow` | [SiliconFlow global API keys](https://cloud.siliconflow.com/account/ak) |\n| `siliconflow-CN` | [SiliconFlow China API keys](https://cloud.siliconflow.cn/account/ak) |\n| `arcee` | [Arcee API key guide](https://docs.arcee.ai/other/create-your-first-api-key) |\n| `moonshot` | [Kimi API platform keys](https://platform.kimi.ai/console/api-keys) or [Kimi Code membership console](https://www.kimi.com/code/console) |\n| `zai` | [Z.ai model API](https://z.ai/model-api) |\n| `stepfun` | [StepFun Open Platform](https://platform.stepfun.ai/) |\n| `minimax`, `minimax-anthropic` | [MiniMax interface keys](https://platform.minimax.io/user-center/basic-information/interface-key) |\n| `huggingface` | [Hugging Face tokens](https://huggingface.co/settings/tokens) |\n| `modelscope` | [ModelScope API Keys](https://modelscope.cn/my/settings/token) |\n| `deepinfra` | [DeepInfra API keys](https://deepinfra.com/dash/api_keys) |\n| `together` | [Together API keys](https://api.together.ai/settings/api-keys) |\n| `qianfan` | [Baidu Cloud access keys](https://console.bce.baidu.com/iam/#/iam/accesslist) |\n| `anthropic` | [Anthropic API keys](https://console.anthropic.com/settings/keys) |\n| `openmodel` | [OpenModel console](https://console.openmodel.ai/) ([authentication guide](https://docs.openmodel.ai/en/docs/getting-started/authentication)) |\n| `openai-codex` | Official Sign in with ChatGPT via `codewhale auth chatgpt` (eligible ChatGPT plan or credits, Codewhale-owned tokens). The `openai` API-key route has separate billing. Legacy imported Codex credentials do not authorize this route. |\n| `sglang`, `vllm` | Local OpenAI-compatible endpoints are keyless by default; configure a key only when the server requires one. |\n| `ollama` | Local Ollama is keyless by default; configure a key only when the local server requires one. |\n| `ollama-cloud` | Create an [Ollama API key](https://ollama.com/settings/keys), save it with `codewhale auth set --provider ollama-cloud`, or set `OLLAMA_CLOUD_API_KEY` / `OLLAMA_API_KEY` in that precedence order. |\n| `sakana` | [Sakana AI API keys](https://console.sakana.ai/api-keys) ([get started](https://console.sakana.ai/get-started)) |\n| `longcat` | [Meituan LongCat platform](https://longcat.chat/platform) |\n| `opencode-go` | [OpenCode Go](https://opencode.ai/docs/go/) |\n| `opencode-zen` | [OpenCode Zen](https://opencode.ai/docs/zen/) |\n| `meta` | [Meta Model API](https://developer.meta.com/ai/) |\n| `telecomjs` | [TelecomJS TokenHub](https://aigw.telecomjs.com/) |\n| `xai` | [xAI Console](https://console.x.ai/) for an API key, Codewhale-owned device login, or explicitly consented read-only Grok CLI credentials. |\n| `mistral` | [Mistral Console (la Plateforme)](https://console.mistral.ai/api-keys) |\n| `google` | [Google AI Studio](https://aistudio.google.com/apikey) — Codewhale uses the official Gemini OpenAI-compatible endpoint and never reads Google OAuth files. |\n| `edenai` | [Eden AI API keys](https://app.edenai.run/settings/api-keys) |\n| `zenmux` | [ZenMux API keys](https://zenmux.ai/platform/pay-as-you-go) |\n| `csdn` | [CSDN 星图 console](https://ai.csdn.net/workbench/api-key) — choose the Coding Plan key type for the `glm_for_coding` plan route; a general key bills metered. Docs: [Coding Plan](https://ai.csdn.net/coding-plan). |\n| `concentrate` | [Concentrate dashboard](https://concentrate.ai/) → API Keys → Create API Key (a Universal API key); docs: [API introduction](https://concentrate.ai/docs/api-reference/introduction). BYOK only — the key stays in the local secret store. |\n| `modelstudio-token-plan`, `modelstudio-token-plan-anthropic`, `modelstudio-coding-plan`, `modelstudio-coding-plan-anthropic` | [Alibaba Cloud Model Studio (Bailian console)](https://bailian.console.aliyun.com/) — create or copy a Model Studio API key. |\n| `codewhale` | [Codewhale account settings](https://app.codewhale.net/settings?section=api) — create an API key with the `models:infer` scope, or run `codewhale account api-keys create --name --use`. |\n| `custom` | Set the named provider's `base_url` and `api_key_env` or `api_key`; no canonical vendor credential page exists. |\n\nFor Kimi, the official [quickstart](https://platform.kimi.ai/docs/overview)\ndirects users to sign in, open **API Keys**, create and copy a key, and keep it\nsecret. Codewhale links straight to that console and accepts the copied key.\nIt never probes or impersonates `kimi_cli`/`kimi_code_cli`; first-class Kimi\nOAuth remains blocked on a vendor-registered Codewhale identity.\n\n### Subscription sign-in accounts (ChatGPT, xAI)\n\nCodewhale keeps one sign-in of its own per subscription provider. It is\nseparate from the browser, the ChatGPT or Grok apps, and the Codex or Grok\nCLIs, so those can be signed in to a different account. A successful login\nreplaces the previous owned grant; there is no picker for multiple saved\nChatGPT accounts.\n\n- **See which account is signed in.** `codewhale auth status --provider\n openai-codex` (or `--provider xai`) and `codewhale auth list` show an account\n label when the ID token contains an email. ChatGPT plan and workspace\n details appear only when those claims are present; a workspace label uses\n the first characters of its account ID. The label is display metadata, not\n proof of plan entitlement. A valid sign-in may have no email label. Status\n reads local credential state without contacting the issuer: an expired\n access token with a stored refresh token remains structurally usable, while\n missing or invalid storage, or an expired token without a refresh token,\n is reported unusable. The provider picker shows the label of the sign-in\n the route would use (for xAI this includes a consented Grok CLI import).\n Successful login reports the account when known and whether it replaced\n an earlier sign-in, in the TUI's selected language. No token is printed.\n- **Reauthorize ChatGPT.** Run `/auth chatgpt` inside Codewhale to update the\n running session, or `codewhale auth chatgpt` from a shell and restart open\n Codewhale sessions. Ordinary login reuses the selected account/workspace's\n issued client ID and checks that the returned account is the same. The\n browser opens with `prompt=login`; `CODEWHALE_CHATGPT_OAUTH_NO_PROMPT=1`\n omits that parameter if the issuer refuses it.\n- **Replace the ChatGPT account or workspace.** From a shell, run\n `CODEWHALE_CHATGPT_NEW_ACCOUNT=1 codewhale auth chatgpt`, then refresh its\n model catalog and restart open Codewhale sessions. If the browser holds the\n wrong account, sign out there or open the printed URL in a private window.\n Only a fully validated new grant replaces the active owned sign-in.\n- **Switch xAI accounts.** Run `/auth xai-device` inside Codewhale, or\n `codewhale auth xai-device` from a shell and restart open sessions. The\n device page approves with whichever account the browser holds; sign out\n there or use a private window to approve another account. The login names\n the account it replaced, or says it is the same account as before.\n- **Usage limits.** ChatGPT plan requests can fail with\n `subscription_sharing_usage_limit_exceeded` or\n `subscription_sharing_usage_unavailable`. These errors, and subscription\n quota errors from other providers, name the account that made the request\n when its label is known and offer recovery guidance. Codewhale does not\n retry these terminal errors or silently choose another billing route. An\n xAI route set to OAuth that fell back to an API key gets no sign-in\n guidance, since no sign-in was used.\n- **ChatGPT credential authority.** The official ChatGPT plan route uses\n only its selected, verified Codewhale-owned grant.\n `OPENAI_CODEX_ACCESS_TOKEN`, `CODEX_ACCESS_TOKEN`, and consented Codex CLI\n tokens cannot override or authorize this route.\n\n### External CLI credential consent\n\nCredential files owned by another CLI are disabled by default. Without an\nexplicit grant, provider discovery, setup, routing, `auth status`, and doctor\ndo not stat, read, refresh, contact an identity provider for, or rewrite Codex,\nGrok, Kimi, or future external credential files.\n\nCodewhale currently supports exact-path, provider-scoped **read-only** grants\nfor the Codex CLI and Grok CLI. Codex grants remain available for legacy\ncredential inspection only; they cannot authorize the official ChatGPT plan\nroute. Use `codewhale auth chatgpt` for that route.\n\n```bash\n# Legacy Codex credential inspection; does not authorize ChatGPT plan requests.\ncodex login\ncodewhale auth external-consent --provider openai-codex --mode read-only\n\ngrok login\ncodewhale auth external-consent --provider xai --mode read-only\n\ncodewhale auth status --provider openai-codex\ncodewhale auth external-revoke --provider openai-codex\n```\n\nPass `--path /absolute/path/to/auth.json` when the external CLI uses a custom\nlocation. Consent persists the provider, external owner, exact absolute path,\nand consent schema version. Later environment-variable changes do not redirect\nthat authority to a different file. Read-only grants never refresh, contact an\nidentity/discovery service, or rewrite the external file. Supported routes such\nas xAI may use the external token after explicit selection. The official ChatGPT\nplan route ignores imported Codex tokens and requires its own verified grant.\nAn expired external token fails with login guidance. Doctor reports structural\nconsent/config state without\nopening credential files and is always non-mutating.\n\n`managed` is reserved for a future provider-specific preservation adapter.\nv0.9.1 rejects it before file or network I/O because no reviewed adapter can\nyet preserve every unknown external schema field safely. Codewhale-started xAI\ndevice login instead atomically activates a Codewhale-owned generation named\n`$CODEWHALE_HOME/credentials/xai-auth-.json`, stores only that\nvalidated basename in config, and revokes any Grok-file grant. Superseded\ngenerations are cleaned only after the new config pointer commits.\nKimi remains API-key-only; external consent for Kimi is rejected.\n\nThe official DeepSeek Harness (`dsh`) is a third read-only credential owner:\n`codewhale auth external-consent --provider deepseek --mode read-only` grants\nexact-path read access to `DEEPSEEK_API_KEY` in `$DSH_HOME/.credentials.yaml`\n(or `~/.dsh/.credentials.yaml`), which Codewhale never writes, refreshes, or\nloads into the process environment. This is separate from the DSH *harness*\nintegration (`codewhale integrations dsh …`, see\n[INTEGRATIONS_DSH.md](INTEGRATIONS_DSH.md)), which never touches credentials\nin either direction: it pins Codewhale's route identity into a `--patch`\noverlay and lets DSH resolve its own keys.\n\n## Shipped Providers\n\n| Provider ID | TOML table | Auth env | Base URL env and default | Default or static models | Notes |\n| --- | --- | --- | --- | --- | --- |\n| `deepseek` | `[providers.deepseek]` | `DEEPSEEK_API_KEY` | `CODEWHALE_BASE_URL` / `DEEPSEEK_BASE_URL`; default `https://api.deepseek.com/beta` | `deepseek-flash` (shipped default; V4.1 Flash, unversioned id), `deepseek-v4-pro`, `deepseek-v4-flash`, experimental `deepseek-v4-flash-vision-exp`; vision aliases `flash-vision`, `deepseek-v4flashvisionexp`; compatibility aliases `deepseek-chat`, `deepseek-reasoner` | First-class default. The live Pro backend is labeled `DeepSeek-V4-Pro-0813`; the callable API ID remains `deepseek-v4-pro`. Beta URL enables strict tool mode, chat prefix completion, and FIM completion. The documented V4 routes can use provider-native web search through a separate bounded Responses request; compatible custom endpoints do not inherit that capability. Set `https://api.deepseek.com` or `/v1` explicitly to opt out of beta-only features. The shipped default `deepseek-flash` speaks the Responses API (DeepSeek's documented path for Codex-style integration, since the 2026-07-31 Flash production update); the Chat-only controls (the `thinking` toggle and strict-tool `/beta` routing) apply to Chat Completions routes, and `deepseek-v4-pro` stays on Chat Completions until its announced Responses rollout. Reasoning effort follows DeepSeek's documented requested-to-actual mapping: `minimal`/`low` land on `low`, `medium`/`xhigh` on `high`, and `max`/`ultra` on `max`; `off` disables thinking (`thinking: {\"type\":\"disabled\"}` on Chat, `reasoning.effort: \"none\"` on Responses). The experimental vision ID was observed in the authenticated `/models` roster on 2026-08-21 and is advertised as image-input capable on the direct Chat Completions route only. Its limits, reasoning, and tool-call flags provisionally inherit Flash; pricing remains unknown, and no funded image round trip was made during this release work. |\n| `deepseek-anthropic` | `[providers.deepseek_anthropic]` | `DEEPSEEK_API_KEY` | `DEEPSEEK_ANTHROPIC_BASE_URL`; default `https://api.deepseek.com/anthropic` | `deepseek-v4-pro`, `deepseek-v4-flash`; compatibility aliases `deepseek-chat`, `deepseek-reasoner` | Opt-in DeepSeek route for the Anthropic Messages wire protocol. Uses `/v1/messages`, `x-api-key`, and `anthropic-version: 2023-06-01`. Keep `provider = \"deepseek\"` for the default Chat Completions path. |\n| `nvidia-nim` | `[providers.nvidia_nim]` | `NVIDIA_API_KEY`, `NVIDIA_NIM_API_KEY` | `NVIDIA_NIM_BASE_URL`, `NIM_BASE_URL`, `NVIDIA_BASE_URL`; default `https://integrate.api.nvidia.com/v1` | `deepseek-ai/deepseek-v4-pro`, `deepseek-ai/deepseek-v4-flash` | Hosted DeepSeek V4 through NVIDIA NIM. `NVIDIA_NIM_MODEL` is accepted by the TUI config path. |\n| `openai` | `[providers.openai]` | `OPENAI_API_KEY` | `OPENAI_BASE_URL`; default `https://api.openai.com/v1` | `gpt-5.6` (default), `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna` | Generic OpenAI-compatible route whose built-in endpoint and fallback catalog are native to OpenAI. The [GPT-5.6 family](https://developers.openai.com/api/docs/models/gpt-5.6-sol) uses OpenAI's documented 1.05M context, 128K max output, and reasoning levels. Custom gateways remain free to select an explicit gateway-owned model. `OPENAI_MODEL` is accepted. |\n| `atlascloud` | `[providers.atlascloud]` | `ATLASCLOUD_API_KEY` | `ATLASCLOUD_BASE_URL`; default `https://api.atlascloud.ai/v1` | Default `deepseek-ai/deepseek-v4-flash`; explicit `vendor/model-id` values pass through when AtlasCloud is selected | OpenAI-compatible hosted route. `ATLASCLOUD_MODEL` is accepted by the TUI config path, the static `ModelRegistry` keeps DeepSeek V4 fallback rows, and provider-hinted CLI model IDs are sent to AtlasCloud exactly as requested. Use Atlas Cloud's own catalog or Coding Plan page for the current provider-owned model list and pricing. |\n| `wanjie-ark` | `[providers.wanjie_ark]` | `WANJIE_ARK_API_KEY`, `WANJIE_API_KEY`, `WANJIE_MAAS_API_KEY` | `WANJIE_ARK_BASE_URL`, `WANJIE_BASE_URL`, `WANJIE_MAAS_BASE_URL`; default `https://maas-openapi.wanjiedata.com/api/v1` | `deepseek-reasoner` | OpenAI-compatible hosted route. `WANJIE_ARK_MODEL`, `WANJIE_MODEL`, and `WANJIE_MAAS_MODEL` are accepted. |\n| `volcengine` | `[providers.volcengine]` | `VOLCENGINE_API_KEY`, `VOLCENGINE_ARK_API_KEY`, `ARK_API_KEY` | `VOLCENGINE_BASE_URL`, `VOLCENGINE_ARK_BASE_URL`, `ARK_BASE_URL`; default `https://ark.cn-beijing.volces.com/api/coding/v3` | `DeepSeek-V4-Pro`, `DeepSeek-V4-Flash` | Volcengine/Volcano Engine Ark OpenAI-compatible coding endpoint. `VOLCENGINE_MODEL` and `VOLCENGINE_ARK_MODEL` are accepted. |\n| `openrouter` | `[providers.openrouter]` | `OPENROUTER_API_KEY` | `OPENROUTER_BASE_URL`; default `https://openrouter.ai/api/v1` | `deepseek/deepseek-v4-pro`, `deepseek/deepseek-v4-flash`; recent large IDs include `arcee-ai/trinity-large-thinking`, `minimax/minimax-m3`, `xiaomi/mimo-v2.5-pro`, `qwen/qwen3.6-flash`, `qwen/qwen3.6-35b-a3b`, `qwen/qwen3.6-max-preview`, `qwen/qwen3.6-27b`, `qwen/qwen3.6-plus`, `google/gemma-4-31b-it`, `z-ai/glm-5.1`, `z-ai/glm-5.2`, `moonshotai/kimi-k2.7-code`, `moonshotai/kimi-k2.6` | Additive open-model routing layer. It does not replace DeepSeek; it lets users route supported model IDs through OpenRouter when they choose it. |\n| `orcarouter` | `[providers.orcarouter]` | `ORCAROUTER_API_KEY` | `ORCAROUTER_BASE_URL`; default `https://api.orcarouter.ai/v1` | `deepseek/deepseek-v4-pro`, `deepseek/deepseek-v4-flash`; router alias `orcarouter/auto`; recent large IDs mirror the OpenRouter namespaced catalog | [OrcaRouter](https://www.orcarouter.ai) OpenAI-compatible aggregation gateway. Shares the namespaced `vendor/model` wire-model format and DeepSeek model set with OpenRouter, so the OpenRouter base-URL and model-normalization rules apply. `ORCAROUTER_MODEL` is accepted. Provider aliases: `orcarouter`, `orca_router`, `orca`. |\n| `xiaomi-mimo` | `[providers.xiaomi_mimo]` | `XIAOMI_MIMO_TOKEN_PLAN_API_KEY`, `MIMO_TOKEN_PLAN_API_KEY`, `XIAOMI_MIMO_API_KEY`, `XIAOMI_API_KEY`, `MIMO_API_KEY` | `XIAOMI_MIMO_BASE_URL`, `MIMO_BASE_URL`, `XIAOMI_MIMO_MODE`, `MIMO_MODE`; default `https://token-plan-sgp.xiaomimimo.com/v1` | Chat: `mimo-v2.5-pro`, `mimo-v2.5-pro-ultraspeed`, `mimo-v2.5`; speech/TTS: `mimo-v2.5-tts`, `mimo-v2.5-tts-voicedesign`, `mimo-v2.5-tts-voiceclone`, `mimo-v2-tts` | Xiaomi MiMo OpenAI-compatible chat completions route. `mimo-v2.5-pro` and `mimo-v2.5` can use the documented provider-native web-search plugin; ultraspeed, speech/TTS, and custom-compatible routes do not inherit it. Token Plan keys (`tp-...`) use `api-key` auth and the token-plan endpoint by default; pay-as-you-go mode uses standard API keys (`sk-...`) and `https://api.xiaomimimo.com/v1`. It sends `max_completion_tokens` and uses MiMo's `thinking` field for reasoning control. Token Plan cost/usage is credit/quota based; Codewhale shows it as unknown until Xiaomi exposes a reliable balance API. `codewhale speech` / `tts` uses the TTS models. |\n| `novita` | `[providers.novita]` | `NOVITA_API_KEY` | `NOVITA_BASE_URL`; default `https://api.novita.ai/openai/v1` | `deepseek/deepseek-v4-pro`, `deepseek/deepseek-v4-flash` | OpenAI-compatible hosted route for DeepSeek model IDs. Use config or `CODEWHALE_MODEL` / `DEEPSEEK_MODEL` for model overrides. |\n| `fireworks` | `[providers.fireworks]` | `FIREWORKS_API_KEY` | `FIREWORKS_BASE_URL`; default `https://api.fireworks.ai/inference/v1` | `accounts/fireworks/models/deepseek-v4-pro` | OpenAI-compatible hosted route. Use config or `CODEWHALE_MODEL` / `DEEPSEEK_MODEL` for model overrides. |\n| `siliconflow` | `[providers.siliconflow]` | `SILICONFLOW_API_KEY` | `SILICONFLOW_BASE_URL`; default `https://api.siliconflow.com/v1` | `deepseek-ai/DeepSeek-V4-Pro`, `deepseek-ai/DeepSeek-V4-Flash` | OpenAI-compatible hosted route. Official docs use the `.com` endpoint. `SILICONFLOW_MODEL` is accepted. Reasoning aliases `deepseek-reasoner` and `deepseek-r1` map to Pro; `deepseek-chat` and `deepseek-v3` map to Flash. |\n| `siliconflow-CN` | `[providers.siliconflow_cn]` | `SILICONFLOW_API_KEY` | `SILICONFLOW_BASE_URL`; default `https://api.siliconflow.cn/v1` | Uses the SiliconFlow model set | China regional SiliconFlow route. Falls back to `[providers.siliconflow]` for api_key / base_url / model when unset. Select it with `provider = \"siliconflow-CN\"` or `CODEWHALE_PROVIDER=siliconflow-CN`. |\n| `arcee` | `[providers.arcee]` | `ARCEE_API_KEY` | `ARCEE_BASE_URL`; default `https://api.arcee.ai/api/v1` | `trinity-large-thinking`, `trinity-large-preview` | Arcee AI direct OpenAI-compatible route, tracked as 256K-context BF16 serving. `ARCEE_MODEL` is accepted. OpenRouter's `arcee-ai/trinity-large-thinking` remains the OpenRouter namespaced model ID; direct Arcee uses the bare `trinity-large-thinking` ID. |\n| `moonshot` | `[providers.moonshot]` | `MOONSHOT_API_KEY`, `KIMI_API_KEY` | `MOONSHOT_BASE_URL`, `KIMI_BASE_URL`; default `https://api.moonshot.ai/v1` | Direct Moonshot: `kimi-k3`, `kimi-k2.7-code`, `kimi-k2.7-code-highspeed`, `kimi-k2.6`; Kimi Code membership: `k3`, `kimi-for-coding`, `kimi-for-coding-highspeed` at `https://api.kimi.com/coding/v1` | Moonshot/Kimi route. Exact direct `kimi-k3` routes use the documented Formula web-search tool/fiber loop; direct `kimi-k2.6` retains the built-in `$web_search` contract, and exact Kimi Code membership routes use their structured `/search` service. Adjacent paths, K2.7 direct models, and cross-product model IDs do not inherit native search. `kimi` and `kimi-k2` aliases select `kimi-k2.7-code`; `MOONSHOT_MODEL`, `KIMI_MODEL_NAME`, and `KIMI_MODEL` are accepted. Kimi thinking streams through `reasoning_content`; Codewhale keeps it in Thinking cells and replays it for thinking/tool-call continuity. For direct K3, use exact `base_url = \"https://api.moonshot.ai/v1\"` and `model = \"kimi-k3\"`; it is always-thinking and receives top-level `reasoning_effort = \"low\" | \"high\" | \"max\"` (`off` normalizes to `low`), uses only `max_completion_tokens`, and omits `temperature`/`top_p` per the [K3 quickstart](https://platform.kimi.ai/docs/guide/kimi-k3-quickstart). For Kimi Code K3, use a key from the [Kimi Code console](https://www.kimi.com/code/console), exact `base_url = \"https://api.kimi.com/coding/v1\"`, and bare `model = \"k3\"`; `off` becomes enabled `low`, while normal dispatched `auto` selects and sends a concrete Codewhale tier. Only an omitted reasoning setting leaves the provider default in control. That membership route defaults safely to 262,144 context tokens; the [Kimi Code model-tier table](https://www.kimi.com/code/docs/en/kimi-code/models.html) grants Allegretto and higher plans up to 1M, which those plans may express as `context_window = 1048576`. `k3[1m]` is Claude Code-only and Codewhale rejects it. `kimi-for-coding` remains the valid K2.7 membership route, and `kimi-for-coding-highspeed` is its own high-speed roster entry (262,144 context); membership ids are rejected on the direct platform endpoint, and `kimi-k3` stays rejected on the membership endpoint. Billing is decided by the endpoint the route resolves to, judged once against the two exact product endpoints: direct Moonshot (`https://api.moonshot.ai/v1` or the default) bills metered with dollar estimates, the exact Kimi Code membership endpoint bills as Kimi Code quota and never shows dollar estimates, and anything else — a gateway host, a neighboring Kimi-hosted path — reports `cost: unknown` rather than borrowing either product. An imported Kimi Code token with no `base_url` in its table still resolves to the membership endpoint, so it bills as Kimi Code quota and never accrues dollars. A completed turn, parent or sub-agent, is billed from the immutable endpoint receipt its own client was built with, never from a later config re-read: `MOONSHOT_BASE_URL`/`KIMI_BASE_URL` are merged into the *active* provider's table only, and an in-turn provider switch can move the ambient config off the route that actually ran. Legacy `auth_mode = \"kimi_oauth\"` fails to API-key guidance without probing Kimi CLI files. Codewhale does not impersonate `kimi_cli` or `kimi_code_cli`. **China-region keys:** contributor field evidence (@vFONGv, PR #5229, verified on Windows 10) reports that a China-region Moonshot key must be paired with `base_url = \"https://api.moonshot.cn/v1\"`; left on the default international host (`https://api.moonshot.ai/v1`) it fails authentication. We have no China-region key to verify this ourselves, so it is recorded as a user report rather than a tested route. Note also that editing `base_url` alone does not take effect until `codewhale auth set` is re-run for that provider. |\n| `google` | `[providers.google]` | `GOOGLE_API_KEY`, `GEMINI_API_KEY` | `GOOGLE_BASE_URL`, `GEMINI_BASE_URL`; default `https://generativelanguage.googleapis.com/v1beta/openai/` | `gemini-3.1-pro-preview` (default); `/model` also lists `gemini-3-pro-preview`, `gemini-3.7-flash`, `gemini-3.6-flash`, `gemini-3.5-flash`, `gemini-3.5-flash-lite`, `gemini-2.5-pro`, `gemini-2.5-flash` | Google Gemini as its own backend on the official OpenAI-compatible Chat Completions route. Thinking models capture `extra_content.google.thought_signature` on tool calls and replay it with the assistant tool-call messages; replaying a tool call whose signature was not captured fails closed with an actionable error instead of letting the tool loop break. `gemini-2.5-flash-lite` ships thinking off and degrades with a warning instead. Reasoning effort maps onto the documented `google.thinking_config.thinking_level` (`low`/`high`). The dialect binds to the exact official base URL: a `google` row pointed at another gateway gets plain OpenAI semantics and no signature requirements. Codewhale never reads Google OAuth files; only an AI Studio API key is used. Not live-tested against the real endpoint in this environment. |\n| `zai` | `[providers.zai]` | `ZAI_API_KEY`, `Z_AI_API_KEY`, `ZHIPU_API_KEY`, `GLM_API_KEY` | `ZAI_BASE_URL`, `Z_AI_BASE_URL`; default `https://api.z.ai/api/coding/paas/v4`; general APIs `https://api.z.ai/api/paas/v4` and `https://open.bigmodel.cn/api/paas/v4` | `GLM-5.3` default; `/model` also lists `GLM-5.3-Flash`, `GLM-5.2`, `GLM-5.1`, and `GLM-5-Turbo` | Z.AI GLM Coding Plan route. All three first-party Chat routes (both api.z.ai products and BigModel's general platform endpoint) share one request dialect, so reasoning controls — the GLM-5.2 thinking toggle, tiered effort, and the forced-thinking GLM-5.3 rewrite that sends `off` as `enabled` + `reasoning_effort: \"low\"` — apply on BigModel too; neighboring paths such as `/preview` stay fail-closed. The two general API products expose structured provider-native web search (`search-prime` globally, `search_std` in China); Coding Plan and compatible custom endpoints do not inherit it. `GLM-5.3` is the default and a first-class picker row (`model = \"GLM-5.3\"` or `ZAI_MODEL=GLM-5.3`); `GLM-5.3-Flash` is the 1M multimodal fast sibling (`model = \"GLM-5.3-Flash\"`). An explicit `GLM-5.2` selection keeps its own id. Limits and reasoning options for 5.3 are inherited from `GLM-5.2` until Z.ai publishes distinct 5.3 metadata; 5.3 carries no price. Flash ships the published $0.15/$0.50 list. A live call can still 429 with entitlement code 1311 on accounts that are not provisioned for 5.3. |\n| `stepfun` | `[providers.stepfun]` | `STEPFUN_API_KEY`, `STEP_API_KEY` | `STEPFUN_BASE_URL`, `STEP_BASE_URL`; default `https://api.stepfun.ai/v1`; Coding Plan endpoint `https://api.stepfun.ai/step_plan/v1` | `step-3.7-flash` | StepFun / StepFlash direct OpenAI-compatible route. `/provider` setup asks which billing route the key belongs to — pay-as-you-go or Step Plan — validates the key against the chosen endpoint, and writes the answer to `[providers.stepfun].base_url` only. A base URL that is neither recognized route is left alone and the question is skipped. You can also set `[providers.stepfun].base_url` or `STEP_BASE_URL` to the Coding Plan URL by hand. Offline accounting labels recognized routes as `stepfun-payg` or `stepfun-plan` without persisting the raw endpoint, and only the standard PAYG route receives token pricing. `STEPFUN_MODEL` and `STEP_MODEL` are accepted. |\n| `minimax` | `[providers.minimax]` | `MINIMAX_API_KEY` | `MINIMAX_BASE_URL`; default `https://api.minimax.io/v1`; China `https://api.minimaxi.com/v1` | `MiniMax-M3`, `MiniMax-M2.7`, `MiniMax-M2.7-highspeed`, `MiniMax-M2.5`, `MiniMax-M2.5-highspeed`, `MiniMax-M2.1`, `MiniMax-M2.1-highspeed`, `MiniMax-M2` | MiniMax direct OpenAI-compatible route. Codewhale sends `reasoning_split = true` so MiniMax thinking arrives separately from answer text. Both MiniMax dialects sell pay-as-you-go and Token Plan over the same endpoints and the same key, so billing is classified from the credential *product*, never from the endpoint or from a default. `mode = \"token-plan\"` in `[providers.minimax]`/`[providers.minimax_anthropic]`, or a Token Plan key shaped `sk-cp…`, bills as MiniMax Token Plan quota with no dollar estimates; an explicit pay-as-you-go mode (`pay-as-you-go`/`payg`/`metered`) wins over key shape. The key's product prefix is only visible when the key is in config, bound by `api_key_env`, or exported as `MINIMAX_API_KEY` on an official endpoint — a key saved through `codewhale auth set` (secret store / OS keyring) is deliberately not read to classify billing. With no explicit mode and no visible product marker the route reports `cost: unknown` rather than assuming pay-as-you-go, so a Token Plan account is never charged invented dollars. Custom/gateway endpoints also fail closed with `cost: unknown`. Official M3 input modalities are text, image, and video; M2.7 is text-only. |\n| `minimax-anthropic` | `[providers.minimax_anthropic]` | `MINIMAX_API_KEY` | `MINIMAX_ANTHROPIC_BASE_URL`; default `https://api.minimax.io/anthropic`; China `https://api.minimaxi.com/anthropic` | `MiniMax-M3`, `MiniMax-M2.7` | MiniMax direct Anthropic-compatible Messages route. Keep the `/anthropic` suffix because Codewhale appends `/v1/messages`; the route uses `x-api-key`. M3 supports adaptive or disabled thinking. M2.7 always keeps thinking enabled. |\n| `sglang` | `[providers.sglang]` | Optional `SGLANG_API_KEY` | `SGLANG_BASE_URL`; default `http://localhost:30000/v1` | `deepseek-ai/DeepSeek-V4-Pro`, `deepseek-ai/DeepSeek-V4-Flash` | Self-hosted OpenAI-compatible route. Localhost deployments commonly omit auth. `SGLANG_MODEL` is accepted. |\n| `vllm` | `[providers.vllm]` | Optional `VLLM_API_KEY` | `VLLM_BASE_URL`; default `http://localhost:8000/v1` | `deepseek-ai/DeepSeek-V4-Pro`, `deepseek-ai/DeepSeek-V4-Flash` | Self-hosted vLLM OpenAI-compatible route. Localhost deployments commonly omit auth. `VLLM_MODEL` is accepted. |\n| `ollama` | `[providers.ollama]` | Local optional `OLLAMA_API_KEY` | `OLLAMA_BASE_URL`; default `http://localhost:11434/v1` | live tag from the local catalog; pre-refresh placeholder `unknown`; provider-hinted custom tags pass through | Local Ollama is keyless by default. `OLLAMA_MODEL` is accepted. The header must not paint a hosted id the local daemon did not list. |\n| `ollama-cloud` | `[providers.ollama_cloud]` | `OLLAMA_CLOUD_API_KEY`, then `OLLAMA_API_KEY` | `OLLAMA_CLOUD_BASE_URL`; default `https://ollama.com/v1` | `gpt-oss:120b`; arbitrary provider-owned IDs pass through | Hosted OpenAI-compatible `/v1/chat/completions` route. Save credentials under `ollama-cloud`; the exact released `ollama` + Cloud URL tuple has bounded read-only in-memory compatibility with its legacy table and secret slot. `OLLAMA_CLOUD_MODEL` is accepted. |\n| `huggingface` | `[providers.huggingface]` | `HUGGINGFACE_API_KEY`, `HF_TOKEN` | `HUGGINGFACE_BASE_URL`, `HF_BASE_URL`; default `https://router.huggingface.co/v1` | `deepseek-ai/DeepSeek-V4-Pro`, `deepseek-ai/DeepSeek-V4-Flash` | Hugging Face Inference Providers OpenAI-compatible router route. Accepted aliases: `huggingface`, `hugging-face`, `hugging_face`, `hf`. Org-prefixed model IDs pass through. `HUGGINGFACE_MODEL` and `HF_MODEL` are accepted. Hub browsing/export are separate future features. |\n| `modelscope` | `[providers.modelscope]` | `MODELSCOPE_API_KEY` | `MODELSCOPE_BASE_URL`; default `https://api-inference.modelscope.cn/v1` | `Qwen/Qwen3.5-397B-A17B` (default), `Qwen/Qwen3.5-122B-A10B`, `Qwen/Qwen3.5-27B`, `Qwen/Qwen3.5-35B-A3B`, `Qwen/Qwen3.8-27B`, `Qwen/Qwen3.8-Flash-Next`, `deepseek-ai/DeepSeek-V4-Pro`, `deepseek-ai/DeepSeek-V4-Pro-0813`, `deepseek-ai/DeepSeek-V4.1-Flash`, `ZhipuAI/GLM-4.7-Flash`, `ZhipuAI/GLM-5.2` | ModelScope OpenAI-compatible inference route. Org-prefixed model IDs pass through. `MODELSCOPE_MODEL` is accepted. |\n| `deepinfra` | `[providers.deepinfra]` | `DEEPINFRA_API_KEY`, `DEEPINFRA_TOKEN` | `DEEPINFRA_BASE_URL`; default `https://api.deepinfra.com/v1/openai` | `deepseek-ai/DeepSeek-V4-Pro`, `deepseek-ai/DeepSeek-V4-Flash` | DeepInfra OpenAI-compatible route. Drop-in replacement for OpenAI SDK. |\n| `together` | `[providers.together]` | `TOGETHER_API_KEY` | `TOGETHER_BASE_URL`; default `https://api.together.xyz/v1` | `deepseek-ai/DeepSeek-V4-Pro`, `deepseek-ai/DeepSeek-V4-Flash`, `thinkingmachines/inkling` | Together AI OpenAI-compatible route. `TOGETHER_MODEL` is accepted. Model aliases `deepseek-v4-pro` and `deepseek-v4-flash` normalize to Together's org-prefixed IDs; `inkling` and `together-inkling` normalize to Together's published lowercase Inkling wire ID. Inkling uses the exact `none`/`minimal`/`low`/`medium`/`high`/`max` reasoning vocabulary from Thinking Machines' [official model repository](https://huggingface.co/thinkingmachines/Inkling). Together's [launch post](https://www.together.ai/blog/together-ai-brings-thinking-machines-labs-new-model-inkling-on-day-0) currently says Inkling is live with 1M context, while its [model detail page](https://www.together.ai/models/inkling) says coming soon with 256K context and publishes no price. Until Together's active `/models` endpoint and the Models.dev catalog resolve that conflict, Inkling is not seeded into Codewhale's offline picker and no route-specific context or cost is inferred. |\n| `qianfan` | `[providers.qianfan]` | `QIANFAN_API_KEY`, `BAIDU_QIANFAN_API_KEY` | `QIANFAN_BASE_URL`, `BAIDU_QIANFAN_BASE_URL`; default `https://api.baiduqianfan.ai/v1` | `ernie-4.0-turbo-8k`; provider-scoped custom Qianfan service/model IDs pass through | Baidu Qianfan OpenAI-compatible route. Requests use Bearer auth and Chat Completions payloads. `QIANFAN_MODEL` and `BAIDU_QIANFAN_MODEL` are accepted; aliases `baidu-qianfan`, `baidu_qianfan`, and `baidu` resolve to this provider. Tool/function calling is model-scoped in Qianfan docs, so Codewhale preserves the selected wire model and leaves live capability proof to follow-up route/capability work. |\n| `openai-codex` | `[providers.openai_codex]` | Official Sign in with ChatGPT (`codewhale auth chatgpt` / `/provider setup openai-codex`) | Official `https://api.openai.com/v1` | Selected account catalog; configured model IDs remain explicit selections | **Experimental.** Public Responses endpoint (`/v1/responses`) with a validated `chatgpt.tokens.use.direct` grant. Dynamic OSS registration issues a client ID for the selected account/workspace; Codewhale protects and renews its own tokens. The account catalog supplies selectable models; public model lists and legacy Codex tokens do not establish plan permission. No silent billing fallback. See [Sign in with ChatGPT](#sign-in-with-chatgpt) for setup, usage limits, and preview boundaries. |\n| `anthropic` | `[providers.anthropic]` | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL`; default `https://api.anthropic.com` | `claude-opus-4-8`, `claude-sonnet-4-6` (default), `claude-haiku-4-5` | Native Anthropic Messages API route (`/v1/messages`, `x-api-key` + `anthropic-version: 2023-06-01`) — not OpenAI-compatible. Prompt caching via `cache_control` breakpoints, adaptive thinking + `output_config.effort`, signed thinking blocks replayed verbatim, cache telemetry normalized per #2961. `ANTHROPIC_MODEL` is accepted. |\n| `openmodel` | `[providers.openmodel]` | `OPENMODEL_API_KEY` | `OPENMODEL_BASE_URL`; default `https://api.openmodel.ai` | `deepseek-v4-flash`; provider-scoped custom model IDs pass through | OpenModel Anthropic-compatible Messages route. Uses `/v1/messages`, Bearer auth, and `anthropic-version: 2023-06-01`; OpenModel selects DeepSeek, DashScope, Xiaomi, Claude, and other routes by model id. `OPENMODEL_MODEL` is accepted. |\n| `sakana` | `[providers.sakana]` | `FUGU_API_KEY`, `SAKANA_API_KEY` | `SAKANA_BASE_URL`; default `https://api.sakana.ai/v1` | `fugu` (default), `fugu-ultra-20260615` | Sakana AI Fugu OpenAI-compatible route. Standard Chat Completions wire protocol; streaming supported. `fugu-ultra-20260615` is the heavy/reasoning variant. Env var aliases: `FUGU_API_KEY` (primary), `SAKANA_API_KEY`; provider aliases: `sakana-ai`, `sakana_ai`, `fugu`. |\n| `longcat` | `[providers.longcat]` | `LONGCAT_API_KEY` | `LONGCAT_BASE_URL`; default `https://api.longcat.chat/openai/v1` | `LongCat-2.0` (default) | Meituan LongCat curated model gateway. OpenAI-compatible Chat Completions wire protocol. Sign up at https://longcat.chat/platform for an API key. Provider aliases: `long-cat`, `meituan-longcat`, `meituan`. |\n| `opencode-go` | `[providers.opencode_go]` | `OPENCODE_GO_API_KEY` | `OPENCODE_GO_BASE_URL`; default `https://opencode.ai/zen/go/v1` | `deepseek-v4-pro` (default), `grok-4.5`, `glm-5.2`, `glm-5.1`, `kimi-k3`, `kimi-k2.7-code`, `kimi-k2.6`, `deepseek-v4-flash`, `mimo-v2.5`, `mimo-v2.5-pro` | [OpenCode Go](https://opencode.ai/docs/go/) subscription route using OpenAI-compatible Chat Completions. `OPENCODE_GO_MODEL` is accepted. Codewhale uses bare wire IDs; familiar `opencode-go/` input aliases normalize to the bare ID. Go models documented only on the Anthropic `/messages` endpoint are deliberately not advertised by this route until Codewhale supports per-model wire selection. Billing surfaces show the Go allowance instead of token-price estimates. |\n| `opencode-zen` | `[providers.opencode_zen]` | `OPENCODE_ZEN_API_KEY`, fallback `OPENCODE_API_KEY` | `OPENCODE_ZEN_BASE_URL`; default `https://opencode.ai/zen/v1` | `gpt-5.6` (default); current GPT, Claude, Qwen, DeepSeek, MiniMax, GLM, Kimi, Grok, Muse Spark, and free-model IDs | [OpenCode Zen](https://opencode.ai/docs/zen/) model-aware gateway. `OPENCODE_ZEN_MODEL` is accepted, and official `opencode/` selectors normalize to bare wire IDs. Each model's wire comes from the curated snapshot, then from the AI SDK package its [Models.dev](https://models.dev) row names: GPT, Grok, and Muse Spark rows use `/responses`; Claude and most Qwen rows use `/messages`; DeepSeek, MiniMax, GLM, Kimi, `qwen3.8-max`, and the free rows use `/chat/completions`. Responses and Chat Completions authenticate with Bearer `Authorization`, while Anthropic Messages uses `x-api-key`; none of these routes use ChatGPT/Codex OAuth guidance or headers. Gemini fails closed because its model-specific Google wire protocol is not implemented; Models.dev rows marked `deprecated` and models no loaded catalog lists also fail closed. See [OpenCode Zen protocol catalog](#opencode-zen-protocol-catalog). |\n| `meta` | `[providers.meta]` | `META_MODEL_API_KEY`, `MODEL_API_KEY` | `META_MODEL_API_BASE_URL`, `MODEL_API_BASE_URL`; default `https://api.meta.ai/v1` | `muse-spark-1.2` (default) | [Meta Model API](https://developer.meta.com/ai/resources/blog/build-with-muse-spark/) public-preview route using OpenAI-compatible Chat Completions. Muse Spark 1.2 keeps its wire ID, tool support, 1M context, 32K output metadata, and `none` through `xhigh` reasoning effort. `META_MODEL_API_MODEL` and `MODEL_API_MODEL` are accepted. Provider aliases: `meta-ai`, `meta_model_api`, `muse`, `muse-spark`. |\n| `telecomjs` | `[providers.telecomjs]` | `TELECOMJS_API_KEY` | `TELECOMJS_BASE_URL`; default `https://aigw.telecomjs.com/v1` | `deepseek-v4-pro` conservative fallback; authenticated `/models` rows when a key is configured | TelecomJS TokenHub OpenAI-compatible Chat Completions route. Live catalogs are isolated by provider and key fingerprint, stale rows survive transient refresh failures, and unsupported reasoning request fields are omitted. `TELECOMJS_MODEL` is accepted. Provider aliases: `telecom-js`, `telecom_js`, `telecomjs-cn`, `tokenhub`. |\n| `mistral` | `[providers.mistral]` | `MISTRAL_API_KEY` | `MISTRAL_BASE_URL`; default `https://api.mistral.ai/v1` | `mistral-code-latest` (default; `codestral-latest` accepted as alias), `mistral-medium-latest` (aliases: `mistral-medium-3-5`), `mistral-small-latest` (aliases: `mistral-small-2603`), `mistral-large-latest` | Mistral AI (la Plateforme) OpenAI-compatible Chat route. On the documented first-party HTTPS `/v1` hosts, Medium and Small send adjustable `reasoning_effort` (`none` or `high` only), parse Mistral's polymorphic thinking/text blocks, and replay stored thinking in that same wire shape. Deprecated native Magistral IDs remain explicit-configuration compatibility routes: they are always-reasoning and never receive the adjustable effort field. Code and Large are non-reasoning. A custom `MISTRAL_BASE_URL` keeps generic Chat semantics unless it is one of the documented first-party hosts. `MISTRAL_MODEL` is accepted. Provider aliases: `mistral-ai`, `mistralai`, `la-plateforme`. |\n| `edenai` | `[providers.edenai]` | `EDENAI_API_KEY` | `EDENAI_BASE_URL`; default `https://api.edenai.run/v3`; EU `https://api.eu.edenai.run/v3` | `deepseek/deepseek-v4-pro` (default); live `/models` catalog of `provider/model` ids | Eden AI OpenAI-compatible aggregation gateway. Catalog rows remain provider-scoped; generic reasoning controls are omitted because supported fields depend on the selected upstream family. `EDENAI_MODEL` is accepted. The default `deepseek/deepseek-v4-pro` is listed on the global catalog only; on the EU endpoint set `EDENAI_MODEL` (or `model`) to a row from the EU `/models` list, for example `qwen/deepseek-v4-pro`. Provider aliases: `eden-ai`, `eden_ai`. |\n| `zenmux` | `[providers.zenmux]` | `ZENMUX_API_KEY` | `ZENMUX_BASE_URL`; default `https://zenmux.ai/api/v1` | `deepseek/deepseek-v4.1-flash` (default); live `/models` catalog of `provider/model` ids (keyless-readable) | ZenMux OpenAI-compatible aggregation gateway (~190 models). Catalog rows remain provider-scoped; generic reasoning controls are omitted because supported fields depend on the selected upstream family. `ZENMUX_MODEL` is accepted. Provider aliases: `zen-mux`, `zen_mux`. |\n| `csdn` | `[providers.csdn]` | `CSDN_API_KEY` | `CSDN_BASE_URL`; default `https://ai.csdn.net/api/model/v1` | `glm_for_coding` (default; the Coding Plan's dedicated model id); other marketplace model ids pass through | CSDN 星图 (Starmap) OpenAI-compatible hosted platform. Coding Plan keys and general marketplace keys share the one endpoint, so billing follows the credential product, never the URL alone: routing `glm_for_coding` — the shipped default — or setting `mode = \"coding_plan\"`/`\"plan\"`/`\"subscription\"` bills as CSDN Coding Plan quota with no dollar estimates; any other model, or an explicit `pay-as-you-go`/`metered` mode, bills metered; an unrecognized mode or an endpoint off `ai.csdn.net/api/model/v1` reports `cost: unknown`. `CSDN_MODEL` is accepted. Provider aliases: `csdn-ai`, `csdn_ai`, `csdn-coding-plan`, `csdn_coding_plan`, `starmap`. |\n| `concentrate` | `[providers.concentrate]` | `CONCENTRATE_API_KEY` | `CONCENTRATE_BASE_URL`; default `https://api.concentrate.ai/v1` | `deepseek-v4-pro` (default; a plain catalog id lets the gateway pick the upstream provider); `provider/model` ids such as `openai/gpt-5.6-sol` pin one upstream; `concentrate/auto` is the gateway's own router; unauthenticated live `/v1/models` catalog | Concentrate OpenAI Responses-compatible gateway (`POST /v1/responses`, bearer Universal API key). Opt-in and BYOK only: your key, your Concentrate bill, zero Codewhale fee, no managed default. Requests carry only documented fields (the system prompt rides as a `system` input item). Contract: [API introduction](https://concentrate.ai/docs/api-reference/introduction), [request parameters](https://concentrate.ai/docs/api-reference/endpoint/request-parameters), [streaming](https://concentrate.ai/docs/api-reference/endpoint/streaming), [errors](https://concentrate.ai/docs/api-reference/endpoint/errors). See [Concentrate Notes](#concentrate-notes). |\n| `codewhale` | `[providers.codewhale]` | `CODEWHALE_API_KEY` | `CODEWHALE_API_BASE`; default `https://api.codewhale.net/v1` | `deepseek/deepseek-v4-pro` (default), `anthropic/claude-sonnet-5`, `openai/gpt-5.6` are offline bootstrap rows only; the authenticated `GET /v1/models` listing of the account's connected providers is the catalog authority | Codewhale API: account-backed model access over the provider keys the customer connected to their Codewhale account. One `cwc_key_…` account API key with the `models:infer` scope authenticates every model. Model ids are `provider/model` exactly as the account catalog returns them, and each row states its protocol (`chat-completions` → `/v1/chat/completions`, `anthropic-messages` → `/v1/messages`, `responses` → `/v1/responses`); every protocol uses `Authorization: Bearer`, never `x-api-key`. `CODEWHALE_API_BASE` must be HTTPS except on loopback. Connect provider keys with `codewhale account keys set `. Provider aliases: `codewhale-api`, `cw-api`, `codewhale-cloud`. |\n| `xai` | `[providers.xai]` | `XAI_API_KEY`, Codewhale-owned device OAuth, or explicit read-only Grok CLI consent | `XAI_BASE_URL`; default `https://api.x.ai/v1` | `grok-4.6` (default), `grok-4.7`, `grok-4.5`, `grok-4.3`, `grok-build`, `grok-composer-2.5-fast`, `grok-4.20-0309-reasoning`, `grok-4.20-0309-non-reasoning` | xAI/Grok OpenAI-compatible Chat Completions route. Grok 4.6 has a 500K context window, text/image input, function calls, structured output, server-side web search, and `low`/`medium`/`high`/`xhigh` reasoning (default `high`). [Grok 4.7](https://docs.x.ai/docs/models/grok-4.7) has the same 500K window, text/image input, function calls, structured output, reasoning ladder and $2.00 / $0.50 cached / $6.00 rates; xAI documents no web-search support for it yet, so Codewhale does not claim it. Grok reasoning cannot be disabled ([reasoning guide](https://docs.x.ai/docs/guides/reasoning)). Its standard rates double when the prompt reaches 200K tokens; the same 2x long-context rule applies to `grok-4.5` (500K context, $2.00 / $0.30 cached / $6.00) and `grok-4.3` (1M context, $1.25 / $0.20 cached / $2.50) per their [model pages](https://docs.x.ai/docs/models/grok-4.5). There is no documented `latest`/`fast` alias and no published numeric output limit. **API-key** (default): Bearer token from console.x.ai via `XAI_API_KEY` / keyring / `api_key`. **OAuth**: `codewhale auth xai-device` uses SSH-friendly device login and Codewhale-owned storage, which may refresh itself. Existing Grok CLI credentials require `codewhale auth external-consent --provider xai --mode read-only`; the granted external file is never refreshed or rewritten. OAuth may return HTTP 403 on some SuperGrok tiers — keep API-key as the reliable fallback. `XAI_MODEL` is accepted. Provider aliases: `x-ai`, `x_ai`, `grok`. |\n| `modelstudio-token-plan` | `[providers.modelstudio_token_plan]` | `MODELSTUDIO_API_KEY`, `DASHSCOPE_API_KEY` | `MODELSTUDIO_TOKEN_PLAN_BASE_URL`; default `https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1` | `qwen3.8-max` (default), `qwen3.8-max-preview`, `qwen3.7-plus`, `qwen3.7-max`, `qwen3.6-flash`, `deepseek-v4-pro`, `deepseek-v4-flash-0731`, `glm-5.2` | Alibaba Cloud Model Studio Token Plan OpenAI-compatible Chat Completions route. Token Plan Personal and Team share this endpoint. `qwen3.8-max`, `qwen3.7-plus`, and `qwen3.7-max` can use provider-native web search through the Token Plan Responses Harness; the preview, Coding Plan, and Anthropic routes do not inherit that capability. All listed models are reasoning-capable text/coding models. DeepSeek and GLM entries are provider-scoped and do not collide with first-party routes. `MODELSTUDIO_TOKEN_PLAN_MODEL` is accepted. Provider aliases: `modelstudio-token-plan`, `alibaba-token-plan`, `dashscope-token-plan`. |\n| `modelstudio-token-plan-anthropic` | `[providers.modelstudio_token_plan_anthropic]` | `MODELSTUDIO_API_KEY`, `DASHSCOPE_API_KEY` | default `https://token-plan.ap-southeast-1.maas.aliyuncs.com/apps/anthropic` | Same model catalog as `modelstudio-token-plan` | Token Plan Anthropic-compatible Messages route (`/apps/anthropic`). Same API key as the OpenAI dialect. Provider aliases: `modelstudio-token-plan-anthropic`, `alibaba-token-plan-anthropic`. |\n| `modelstudio-coding-plan` | `[providers.modelstudio_coding_plan]` | `MODELSTUDIO_API_KEY`, `DASHSCOPE_API_KEY` | `MODELSTUDIO_CODING_PLAN_BASE_URL`; default `https://coding-intl.dashscope.aliyuncs.com/v1` | `qwen3.8-max` (default); same catalog as Token Plan | Alibaba Cloud Model Studio Coding Plan OpenAI-compatible Chat Completions route. `MODELSTUDIO_CODING_PLAN_MODEL` is accepted. Provider aliases: `modelstudio-coding-plan`, `alibaba-coding-plan`, `dashscope-coding-plan`. |\n| `modelstudio-coding-plan-anthropic` | `[providers.modelstudio_coding_plan_anthropic]` | `MODELSTUDIO_API_KEY`, `DASHSCOPE_API_KEY` | default `https://coding-intl.dashscope.aliyuncs.com/apps/anthropic` | Same model catalog as `modelstudio-coding-plan` | Coding Plan Anthropic-compatible Messages route (`/apps/anthropic`). Provider aliases: `modelstudio-coding-plan-anthropic`, `alibaba-coding-plan-anthropic`. |\n\nStepFun's four coding models are available through both its standard API and\n[Step Plan](https://platform.stepfun.ai/docs/en/step-plan/integrations/reasoning-api).\nChoose the billing route in `/provider`, then the model in `/model`; existing\nStep 3.7 selections remain unchanged. [Step 5 Preview](https://platform.stepfun.ai/docs/en/guides/models/step-5-preview)\nhas a 1M context window. Step 5 and Step 3.7 expose low/medium/high reasoning;\nStep 3.5 Flash 2603 exposes low/high; base Step 3.5 uses provider-default reasoning.\n[Published API prices](https://platform.stepfun.ai/docs/en/guides/pricing/details)\napply only to verified PAYG routes. Step Plan displays subscription allowance.\nSpeech, music and image-generation models use separate interfaces and are not\npresented as coding models. Provider video capability metadata does not imply\nthat every Codewhale client can attach video.\n\n\n### OpenCode Zen protocol catalog\n\nZen Responses and Chat Completions requests authenticate with Bearer\n`Authorization`; Zen Anthropic Messages requests use `x-api-key`. None of these\nroutes add ChatGPT/Codex OAuth headers.\n\nEach Zen model's wire comes from two sources, and neither is guessed from a\nmodel-id family (`qwen3.8-flash` is Messages while `qwen3.8-max` is Chat):\n\n1. **The curated snapshot** compiled into Codewhale, verified against the\n [official endpoint table](https://opencode.ai/docs/zen/) and the `opencode`\n provider in [Models.dev](https://models.dev). It is the offline floor, and\n it wins when a catalog row names a different wire for the same id.\n2. **The Models.dev catalog.** Its `opencode` provider is Zen's published\n catalog: each model row names the AI SDK package OpenCode itself uses, which\n Codewhale maps exactly — `@ai-sdk/openai` to Responses, `@ai-sdk/anthropic`\n to Anthropic Messages, and `@ai-sdk/openai-compatible` (the provider\n default) to Chat Completions. A Zen model released after this build routes\n once the catalog lists it, without a Codewhale release. The interactive TUI\n and `codewhale exec` both load the persisted catalog; refresh it with\n `codewhale models --update`.\n\nThe curated snapshot:\n\n- Responses: `gpt-6-astra`, `gpt-6-sol`, `gpt-6-luna`, `gpt-5.6-sol`,\n `gpt-5.6-terra`, `gpt-5.6-luna`, `gpt-5.5`, `gpt-5.5-pro`, `gpt-5.4`,\n `gpt-5.4-pro`, `gpt-5.4-mini`, `gpt-5.4-nano`, `gpt-5.3-codex`,\n `gpt-5.3-codex-spark`, `gpt-5.2`, `gpt-5.2-codex`, `gpt-5.1`,\n `gpt-5.1-codex`, `gpt-5.1-codex-max`, `gpt-5.1-codex-mini`, `gpt-5`,\n `gpt-5-codex`, `gpt-5-nano`, `grok-4.7`, `grok-4.6`, `grok-4.5`,\n `grok-build-0.1`, `muse-spark-1.3`, `muse-spark-1.3-contributor-free`,\n `muse-spark-1.2`, `muse-spark-1.2-contributor`,\n `muse-spark-1.2-contributor-free`.\n- Anthropic Messages: `claude-fable-5-1`, `claude-fable-5`,\n `claude-opus-5-5`, `claude-opus-5`, `claude-opus-4-8`, `claude-opus-4-7`,\n `claude-opus-4-6`, `claude-opus-4-5`, `claude-sonnet-5-5`,\n `claude-sonnet-5`, `claude-sonnet-4-6`, `claude-sonnet-4-5`,\n `claude-sonnet-4`, `claude-haiku-4-5`, `qwen3.8-flash`, `qwen3.7-max`,\n `qwen3.7-plus`, `qwen3.6-plus`, `qwen3.5-plus`.\n- Chat Completions: `deepseek-v4.1-flash`, `deepseek-v4-pro`,\n `deepseek-v4-flash`, `deepseek-v4-flash-vision-exp`, `minimax-m3`,\n `minimax-m2.7`, `minimax-m2.5`, `glm-5.3-flash`, `glm-5.3`, `glm-5.2`,\n `glm-5.1`, `glm-5`, `kimi-k3`, `kimi-k2.7-code`, `kimi-k2.6`, `kimi-k2.5`,\n `qwen3.8-max`, `big-pickle`, `space-bunny-free`,\n `longcat-2.5-preview-free`, `mimo-v2.6-flash-free`, `mimo-v2.5-free`,\n `ling-3.0-flash-fin-free`, `north-mini-code-free`,\n `nemotron-3-ultra-free`, `nemotron-3.5-lightning-free`,\n `deepseek-v4-flash-free`.\n\nThese fail closed locally, with the reason in the error, instead of reaching\nZen: Gemini (`@ai-sdk/google`, Google's model-specific protocol, which Codewhale\ndoes not speak); a catalog row naming any other package; a catalog row Models.dev\nmarks `deprecated`; and a model neither source lists. A miss never falls back to\nanother Zen wire shape, including when a custom Zen base URL is configured.\n\n### Concentrate Notes\n\nConcentrate (`concentrate`) is an OpenAI **Responses**-compatible gateway:\n`POST https://api.concentrate.ai/v1/responses` with `Authorization: Bearer\n`. It is opt-in and **BYOK only**.\n\n- **Model ids pass through.** A plain catalog id (`gpt-5.6-sol`,\n `deepseek-v4-pro`) lets the gateway choose the upstream provider;\n `provider/model` (`openai/gpt-5.6-sol`) pins the upstream provider inside the\n gateway; `concentrate/auto` sends the gateway's own `auto` router. Codewhale's\n bare `--model auto` remains the resolver sentinel (provider default), which is\n why the gateway router has its own explicit spelling. Once streaming begins\n the gateway commits to one provider ([auto routing](https://concentrate.ai/docs/api-reference/endpoint/auto-routing)).\n- **Wire.** Fixed Responses dialect. The request carries only documented\n fields — `model`, `input`, `stream`, `max_output_tokens`, `tools`,\n `tool_choice`, `parallel_tool_calls`, `reasoning.effort` — and the system\n prompt travels as a leading `system` input item because `instructions` is\n not in the gateway's [parameter reference](https://concentrate.ai/docs/api-reference/endpoint/request-parameters).\n Streaming follows the typed `response.*` SSE events and ends on\n `response.completed` without a `[DONE]` sentinel ([streaming](https://concentrate.ai/docs/api-reference/endpoint/streaming)).\n- **Errors.** `{ \"error\", \"message\", \"model\"?, \"retry_after\"? }` with 400\n (bad request / unknown model), 401 (invalid key), 402 (insufficient\n credits), 424 (upstream provider unavailable), 429 (rate limit) —\n surfaced verbatim and classified by message ([errors](https://concentrate.ai/docs/api-reference/endpoint/errors)).\n- **Catalog.** `GET /v1/models` needs no key\n ([list models](https://concentrate.ai/docs/api-reference/endpoint/list-models)); the live rows\n are provider-scoped and unclaimed (no pricing or capability claims).\n- **Commercial boundary.** Concentrate's [Terms of Service](https://concentrate.ai/legal/terms-of-service)\n forbid reselling, white-labeling, or providing the service on a\n service-bureau basis without written consent, and its\n [Acceptable Use Policy](https://concentrate.ai/legal/acceptable-use-policy)\n forbids sharing or sublicensing keys. Codewhale therefore ships **no**\n Codewhale-owned Concentrate key, no stored customer key, no default or\n managed routing, and no markup — activation of any hosted lane is gated on\n written consent, terms, and billing approval (tracked in the Codewhale ops\n evidence checklist `concentrate-gateway-20260829/CHECKLIST.md`). Public\n pricing states \"No platform markup on tokens\".\n- **Self-test without a key.** `scripts/concentrate-selftest.sh` boots a\n local stub that speaks the documented contract and drives the real\n `codewhale exec` path through it, asserting the URL, bearer header, model\n passthrough, streaming, and the completed-turn receipt. No network call\n leaves the machine and no account is required.\n\n### Hugging Face Provider vs MCP vs Hub\n\nCodewhale's `huggingface` provider ID is only the OpenAI-compatible chat\ninference route through Hugging Face Inference Providers. It is selected with\n`/provider huggingface`, `CODEWHALE_PROVIDER=huggingface`, or\n`provider = \"huggingface\"`.\n\nHugging Face MCP is a separate external-tool route. Configure it through the\nMCP config described in `docs/MCP.md`, preferably using the settings-generated\nsnippet from . In the TUI, `/hf mcp status`\nchecks whether the Hugging Face MCP server appears in the resolved MCP config,\n`/hf mcp setup` prints the settings workflow and a placeholder-only shape, and\n`/hf concepts` explains the provider/MCP/Hub distinction.\n\nHub publishing or repository management remains explicit user action through\nHub-native tooling such as `huggingface_hub` or git. The `/hf` helper does not\nupload to Hugging Face and does not perform direct Hugging Face Hub HTTP search.\n\n### Xiaomi MiMo Notes\n\n`xiaomi-mimo` defaults to `mimo-v2.5-pro` for long-context reasoning and coding\nwork. The chat picker also exposes `mimo-v2.5-pro-ultraspeed` and the latest\nOmni model `mimo-v2.5`. Xiaomi MiMo TTS is available through\n`codewhale --provider xiaomi-mimo speech \"text\" --model tts` (or the `tts`\nalias). In Act and Operate, the provider-specific `speech` / `tts` tools are\navailable through deferred discovery when the Xiaomi MiMo route is configured.\n\n`/provider xiaomi-mimo ultraspeed` and `/provider xiaomi-mimo pro-ultraspeed`\nboth select `mimo-v2.5-pro-ultraspeed`. Speech aliases such as `tts`,\n`voice-design`, and `voice-clone` are separate from normal chat defaults.\n\nToken Plan keys default to the Singapore endpoint\n`https://token-plan-sgp.xiaomimimo.com/v1`. If your MiMo account is provisioned\nfor the China region, set `base_url = \"https://token-plan-cn.xiaomimimo.com/v1\"`\nexplicitly in `[providers.xiaomi_mimo]` or set `mode = \"token-plan-cn\"`. Europe\nToken Plan accounts can set\n`base_url = \"https://token-plan-ams.xiaomimimo.com/v1\"` or use\n`mode = \"token-plan-ams\"`; `mode = \"pay-as-you-go\"`\nselects the standard API endpoint and standard MiMo key family. Xiaomi Token\nPlan docs and console expose credit/quota semantics, but Codewhale does not\ncurrently have a documented balance endpoint to poll, so cost display remains\nunknown rather than reusing token-price estimates from another provider.\n\nVoice-design and voice-clone shorthands map to `mimo-v2.5-tts-voicedesign` and\n`mimo-v2.5-tts-voiceclone`. Xiaomi's current\n[image-understanding guide](https://platform.xiaomimimo.com/docs/en-US/usage-guide/multimodal-understanding/image-understanding)\nincludes `mimo-v2.5` for image input. Codewhale exposes image analysis through the\nseparate `[vision_model]` / `image_analyze` path; set that model to\n`mimo-v2.5` when using MiMo for vision.\n\n### OpenRouter-Compatible Base URLs\n\nOpenRouter-compatible gateways should usually stay on the `openrouter`\nprovider with a provider-scoped `base_url` override instead of moving through\nthe generic `openai` route. That keeps OpenRouter-style reasoning, streaming,\ncache usage, and namespaced wire model parsing attached to the selected route:\n\n```toml\nprovider = \"openrouter\"\n\n[providers.openrouter]\napi_key = \"sk-...\"\nbase_url = \"https://openrouter-compatible.example/v1\"\nmodel = \"deepseek/deepseek-v4-pro\"\n```\n\nCodewhale preserves the `deepseek/` wire-model prefix under the OpenRouter\nprovider scope; it does not infer a switch to the direct DeepSeek provider from\nthat model string. Cache fields such as `prompt_cache_hit_tokens`,\n`prompt_cache_miss_tokens`, and `prompt_tokens_details.cached_tokens` are\nparsed when the upstream gateway sends them. If a key/account type omits those\nfields, Codewhale treats them as absent for that response rather than as a\ndifferent provider route.\n\nOrcaRouter (`https://api.orcarouter.ai/v1`) is a dedicated named route\n([OrcaRouter](https://www.orcarouter.ai)) that speaks the same OpenAI\nChat Completions wire protocol and serves the same namespaced\n`vendor/model` catalog. It does not need an OpenRouter-compatible\n`base_url` override: select `provider = \"orcarouter\"` and its namespaced\nwire models (for example `deepseek/deepseek-v4-pro` or its own\n`orcarouter/auto` router) pass through verbatim, exactly as they do on the\nOpenRouter provider scope.\n\n#### OrcaRouter credentials: API key or OAuth 2.0 + PKCE\n\nOrcaRouter accepts two credential sources, and both write the same durable\n`sk-orca-…` key to the same `orcarouter` secret-store slot with\n`auth_mode = \"api_key\"`:\n\n- **API key** — `codewhale auth set --provider orcarouter`, `/provider`, or\n `ORCAROUTER_API_KEY`. Use this when you already have a key.\n- **Connect with OrcaRouter** — `codewhale auth orcarouter` (CLI) or\n `/auth orcarouter` (in-session). This runs an OAuth 2.0 authorization-code\n flow with PKCE (S256) on a loopback redirect. The browser is sent to\n `GET https://www.orcarouter.ai/auth` with `callback_url`, `code_challenge`,\n `code_challenge_method=S256`, `state`, `app_name`, and `scope`; the code is\n exchanged at `POST https://www.orcarouter.ai/api/v1/auth/keys` for a\n durable API key. There is no client secret and no pre-registered redirect\n URI; state is compared in constant time before the code is used.\n\nAuthentication and inference use different origins: the consent and exchange\nlive on `https://www.orcarouter.ai`; models and chat live on\n`https://api.orcarouter.ai/v1`. Neither is derived from the other, and\n`/v1/auth/keys` on the API origin is not the exchange route. Self-hosted\ndeployments can override each origin explicitly with `ORCA_AUTH_BASE_URL`\n(auth) and `ORCA_API_BASE_URL`/`ORCAROUTER_BASE_URL` (inference); the explicit\nvalue wins. Remote origins must be HTTPS; plain HTTP is accepted only on\nloopback.\n\nA PKCE-issued key is a durable API key, **not** a refresh token: Codewhale\nstores it, reuses it across restarts, and never sends a refresh grant. Revoke\nthe key on the OrcaRouter console (`/auth orcarouter-revoke` clears the local\ncopy) and sign in again to get a new one. A 401 from the relay marks that\ncredential generation as needing re-authentication rather than silently\nretrying.\n\nThe chat model list is discovered live from `GET https://api.orcarouter.ai/v1/models`\nwith the configured key. OrcaRouter publishes `supported_endpoint_types` on\nevery row, so the chat selector keeps only rows advertising `openai`,\n`anthropic`, `gemini`, or `openai-response`, and drops image-generation,\nvideo, and rerank rows instead of guessing from a model name. A row that\nstates `architecture.input_modalities` with `image` is image-input capable;\nrows that state no architecture are treated as unknown, not as text-only.\n\n### Recent OpenRouter Large Models\n\nOpenRouter completions and static registry rows include the April 2026 onward\nlarge models verified through OpenRouter's model metadata:\n`arcee-ai/trinity-large-thinking`, `qwen/qwen3.6-flash`,\n`qwen/qwen3.6-35b-a3b`, `qwen/qwen3.6-max-preview`, `qwen/qwen3.6-27b`,\n`qwen/qwen3.6-plus`, `minimax/minimax-m3`, `xiaomi/mimo-v2.5-pro`,\n`xiaomi/mimo-v2.5`, `moonshotai/kimi-k2.7-code`, `moonshotai/kimi-k2.6`,\n`z-ai/glm-5.1`, `z-ai/glm-5.2`, `z-ai/glm-5-turbo`, `tencent/hy3-preview`,\n`google/gemma-4-31b-it`, `google/gemma-4-26b-a4b-it`, and\n`nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free`.\n`minimax/minimax-m3` was added from OpenRouter's May 31, 2026 listing as a 1M\ncontext multimodal model for coding, tool use, and long-horizon agentic work.\n`GLM-5.3` is now the default direct Z.AI Coding Plan model; `GLM-5.2` /\n`z-ai/glm-5.2` remain available (explicit selections keep their own id),\n`GLM-5.1` / `z-ai/glm-5.1` remain available as the smaller model,\n`GLM-5.3-Flash` / `z-ai/glm-5.3-flash` is the faster/explore sibling of\n`GLM-5.3`, and `GLM-5-Turbo` / `z-ai/glm-5-turbo` remains the faster sibling\nof `GLM-5.2`.\n`GLM-5.3` / `z-ai/glm-5.3` and `GLM-5.3-Flash` / `z-ai/glm-5.3-flash` are\nfirst-class picker ids on the Z.ai and OpenRouter routes (`/model` after\n`/provider zai`, or `model = \"GLM-5.3-Flash\"`).\nLimits and reasoning options for 5.3 are inherited from\n`GLM-5.2` until Z.ai publishes distinct 5.3 metadata, and 5.3 carries no\nprice. Flash ships the published $0.15/$0.50 list. A live call can still\n429 with entitlement code 1311 on accounts that are not provisioned for 5.3.\n\n## Static Model Registry\n\nThis table describes the static registry, which `codewhale model resolve` (and\nthe `[model]` config surface) still use to resolve selector aliases.\n\n`codewhale model resolve` projects the reviewed `selections` in\n`crates/config/assets/catalog_corrections.json` through\n`crates/agent/src/lib.rs`. There is no independent Rust model roster. These\nordered aliases and flags are compatibility metadata, not account availability\nor executable route permission. This differs from live `/models` discovery.\nUse `/models` or `codewhale models` to fetch model IDs from the active API\nendpoint when the endpoint supports model listing.\n\n| Provider | Static registry entries | Tool calls | Registry reasoning flag |\n| --- | --- | --- | --- |\n| `deepseek` | `deepseek-v4-pro`, `deepseek-v4-flash`, `deepseek-v4-flash-vision-exp` | yes | yes |\n| `nvidia-nim` | `deepseek-ai/deepseek-v4-pro`, `deepseek-ai/deepseek-v4-flash` | yes | yes |\n| `openai` | `deepseek-v4-pro`, `deepseek-v4-flash`, `gpt-5.6`, `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna` | yes | yes |\n| `atlascloud` | `deepseek-ai/deepseek-v4-flash`, `deepseek-ai/deepseek-v4-pro` | yes | yes |\n| `wanjie-ark` | `deepseek-reasoner` | yes | yes |\n| `volcengine` | `DeepSeek-V4-Pro`, `DeepSeek-V4-Flash` | yes | yes |\n| `openrouter` | `deepseek/deepseek-v4-pro`, `deepseek/deepseek-v4-flash`, `arcee-ai/trinity-large-thinking`, `minimax/minimax-m3`, `minimax/minimax-m2.7`, `xiaomi/mimo-v2.5-pro`, `xiaomi/mimo-v2.5`, `qwen/qwen3.6-flash`, `qwen/qwen3.6-35b-a3b`, `qwen/qwen3.6-max-preview`, `qwen/qwen3.6-27b`, `qwen/qwen3.6-plus`, `qwen/qwen3.7-max`, `moonshotai/kimi-k2.7-code`, `moonshotai/kimi-k2.6`, `z-ai/glm-5.1`, `z-ai/glm-5.2`, `z-ai/glm-5.3`, `z-ai/glm-5.3-flash`, `z-ai/glm-5-turbo`, `tencent/hy3-preview`, `google/gemma-4-31b-it`, `google/gemma-4-26b-a4b-it`, `nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free`, `nvidia/nemotron-3-ultra-550b-a55b` | yes | yes |\n| `orcarouter` | `deepseek/deepseek-v4-pro`, `deepseek/deepseek-v4-flash`, `orcarouter/auto` | yes | yes |\n| `xiaomi-mimo` | `mimo-v2.5-pro`, `mimo-v2.5-pro-ultraspeed`, `mimo-v2.5`; speech/TTS IDs are selected through `codewhale speech` / `tts` | yes | yes for chat models; no for speech/TTS models |\n| `novita` | `deepseek/deepseek-v4-pro`, `deepseek/deepseek-v4-flash` | yes | yes |\n| `fireworks` | `accounts/fireworks/models/deepseek-v4-pro` | yes | yes |\n| `siliconflow` | `deepseek-ai/DeepSeek-V4-Pro`, `deepseek-ai/DeepSeek-V4-Flash` | yes | yes |\n| `arcee` | `trinity-large-thinking`, `trinity-large-preview`; provider-hinted custom model IDs pass through | yes | yes for `trinity-large-thinking`; no for `trinity-large-preview` |\n| `moonshot` | `kimi-k2.7-code`, `kimi-k2.6` | yes | yes |\n| `zai` | `GLM-5.3`, `GLM-5.3-Flash`, `GLM-5.2`, `GLM-5.1`, `GLM-5-Turbo`; provider-hinted custom model IDs pass through | yes | yes |\n| `stepfun` | `step-3.7-flash` (default), `step-5-preview`, `step-3.5-flash`, `step-3.5-flash-2603` | yes | yes |\n| `minimax` | `MiniMax-M3`, `MiniMax-M2.7`, `MiniMax-M2.7-highspeed`, `MiniMax-M2.5`, `MiniMax-M2.5-highspeed`, `MiniMax-M2.1`, `MiniMax-M2.1-highspeed`, `MiniMax-M2` | yes | yes |\n| `minimax-anthropic` | `MiniMax-M3`, `MiniMax-M2.7` | yes | yes |\n| `sglang` | `deepseek-ai/DeepSeek-V4-Pro`, `deepseek-ai/DeepSeek-V4-Flash` | yes | yes |\n| `vllm` | `deepseek-ai/DeepSeek-V4-Pro`, `deepseek-ai/DeepSeek-V4-Flash` | yes | yes |\n| `ollama` | live local tag; custom tags pass through when provider hint is `ollama` | yes | no |\n| `ollama-cloud` | `gpt-oss:120b`; arbitrary provider-owned model IDs pass through | yes | yes |\n| `huggingface` | `deepseek-ai/DeepSeek-V4-Pro`, `deepseek-ai/DeepSeek-V4-Flash` | yes | no |\n| `modelscope` | `Qwen/Qwen3.5-397B-A17B`, `Qwen/Qwen3.5-122B-A10B`, `Qwen/Qwen3.5-27B`, `Qwen/Qwen3.5-35B-A3B`, `Qwen/Qwen3.8-27B`, `Qwen/Qwen3.8-Flash-Next`, `deepseek-ai/DeepSeek-V4-Pro`, `deepseek-ai/DeepSeek-V4-Pro-0813`, `deepseek-ai/DeepSeek-V4.1-Flash`, `ZhipuAI/GLM-4.7-Flash`, `ZhipuAI/GLM-5.2` | yes | no |\n| `deepinfra` | `deepseek-ai/DeepSeek-V4-Pro`, `deepseek-ai/DeepSeek-V4-Flash` | yes | yes |\n| `together` | `deepseek-ai/DeepSeek-V4-Pro`, `deepseek-ai/DeepSeek-V4-Flash`, `thinkingmachines/inkling` | yes | yes |\n| `openai-codex` | `gpt-5.5` | yes | yes |\n| `anthropic` | `claude-opus-5`, `claude-opus-4-8`, `claude-sonnet-5`, `claude-sonnet-4-6`, `claude-fable-5`, `claude-haiku-4-5` | yes | yes except `claude-haiku-4-5` |\n| `openmodel` | `deepseek-v4-flash`; provider-scoped custom model IDs pass through | yes | model-dependent |\n| `sakana` | `fugu`, `fugu-ultra-20260615` | yes | yes for `fugu-ultra-20260615` |\n| `longcat` | `LongCat-2.0` | yes | yes |\n| `opencode-go` | `deepseek-v4-pro`, `grok-4.5`, `glm-5.2`, `glm-5.1`, `kimi-k3`, `kimi-k2.7-code`, `kimi-k2.6`, `deepseek-v4-flash`, `mimo-v2.5`, `mimo-v2.5-pro` | yes | yes |\n| `meta` | `muse-spark-1.2` | yes | yes |\n| `xai` | `grok-4.6`, `grok-4.7`, `grok-4.5`, `grok-4.3`, `grok-build`, `grok-composer-2.5-fast`, `grok-4.20-0309-reasoning`, `grok-4.20-0309-non-reasoning` | yes | yes for `grok-4.6`, `grok-4.7`, `grok-4.5`, `grok-4.3`, `grok-build`, and `grok-4.20-0309-reasoning` |\n| `google` | `gemini-3.1-pro-preview`, `gemini-3-pro-preview`, `gemini-3.7-flash`, `gemini-3.6-flash`, `gemini-3.5-flash`, `gemini-3.5-flash-lite`, `gemini-2.5-pro`, `gemini-2.5-flash` | yes | yes except `gemini-3.5-flash-lite` |\n| `mistral` | `mistral-code-latest`, `mistral-medium-latest`, `mistral-small-latest`, `mistral-large-latest` | yes | yes for Medium and Small (`reasoning_effort` `none` or `high` on exact first-party routes); deprecated native Magistral remains an always-on explicit compatibility ID; no for Code and Large |\n| `modelstudio-token-plan`, `modelstudio-coding-plan` | `qwen3.8-max`, `qwen3.8-max-preview`, `qwen3.7-plus`, `qwen3.7-max`, `qwen3.6-flash`, `deepseek-v4-pro`, `deepseek-v4-flash-0731`, `glm-5.2` | yes | yes |\n| `csdn` | `glm_for_coding`; other marketplace model IDs pass through | yes | yes |\n\nAtlasCloud keeps the same default model as the config layer and adds\nprovider-scoped aliases for the Pro and Flash rows. Other AtlasCloud model IDs\nshould still be selected through `ATLASCLOUD_MODEL`, config, or live model\nlisting when available.\n\n## Capability Metadata\n\n`codewhale doctor --json` exposes the `capability` object. It is static\nmetadata, not a live API probe. Current fields are:\n\n`resolved_provider`, `resolved_model`, `context_window`, `max_output`,\n`thinking_supported`, `cache_telemetry_supported`, and `request_payload_mode`.\n\nWhen configuration cannot be loaded or validated, `doctor --json` exits\nnonzero and prints a bounded, secret-redacted JSON error envelope with\n`status = \"error\"` and `error.kind = \"config_validation\"` instead of emitting\nmisleading route or capability metadata.\n\nMost shipped providers use the Chat Completions request payload mode. Native\nMessages routes, including `minimax-anthropic`, use `/v1/messages`, and\n`openai-codex` uses Responses.\n\nFor OpenAI-compatible gateways or self-hosted runtimes whose real window\ndiffers from the static table, set `[providers.] context_window = N`.\nThe configured value becomes the route-effective context window for prompts,\ncontext-pressure checks, compaction, and output-cap budgeting.\n\n`max_output` is optional and truthful: it is `null` (and omitted from the\ncapability struct on the wire) when the route publishes no output maximum we\ncan stand behind — the Kimi Code membership `kimi-for-coding` family is the\ncanonical example, since the membership catalog owns their limits. An unknown\noutput ceiling is never backfilled with a placeholder, and it applies **no**\ncompatibility clamp to a turn's requested `max_tokens`; only a concrete\nroute/offering maximum narrows the request. A model the catalogue simply has no\nrow for is a different fact — absence is not permission, so an uncatalogued id\nkeeps a conservative ceiling. The \"Max output metadata\" column below reads\n`unknown` wherever no documented maximum exists.\n\nThe exact Kimi Code membership roster contains `k3`, `k3-256k`,\n`kimi-for-coding`, and `kimi-for-coding-highspeed`. The two K3 ids share the\nsame reasoning and fixed-sampling contract; `k3-256k` stays at 262,144 tokens,\nwhile bare `k3` can use an entitled 1M override.\n\n| Provider/model class | Context window | Max output metadata | Thinking support | Cache telemetry | FIM endpoint |\n| --- | --- | --- | --- | --- | --- |\n| DeepSeek V4 (`deepseek-v4-pro`, `deepseek-v4-flash`) | 1,000,000 | 384,000 | yes | yes | DeepSeek beta only |\n| DeepSeek V4 Flash Vision experimental (`deepseek-v4-flash-vision-exp`) | 1,000,000 inherited from Flash | 384,000 inherited from Flash | yes, inherited | yes, inherited | not claimed; Chat Completions route only |\n| DeepSeek compatibility aliases (`deepseek-chat`, `deepseek-reasoner`) | 1,000,000 | 384,000 | yes | yes | DeepSeek beta only |\n| NVIDIA NIM V4 registry models | 1,000,000 | 384,000 | yes | yes | not documented in code |\n| Volcengine Ark V4 model IDs | 1,000,000 | 384,000 | yes | yes | not documented in code |\n| OpenRouter, Novita, Fireworks, SiliconFlow, SGLang, and vLLM V4 model IDs | 1,000,000 | 384,000 | yes | no | not documented in code |\n| Xiaomi MiMo `mimo-v2.5-pro`, `mimo-v2.5-pro-ultraspeed`, `mimo-v2.5` | 1,000,000 | 131,072 | yes | no | not documented in code |\n| OpenRouter Qwen 3.6 Flash / Plus | 1,000,000 | 65,536 | yes | no | not documented in code |\n| OpenRouter Qwen 3.6 35B / 27B | 262,144 | 262,140 | yes | no | not documented in code |\n| OpenRouter Qwen 3.6 Max Preview | 262,144 | 65,536 | yes | no | not documented in code |\n| OpenAI API `gpt-5.5` | 1,050,000 | 128,000 | yes | no | not documented in code |\n| OpenAI API `gpt-5.6`, `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna` | 1,050,000 | 128,000 | yes | no | not documented in code |\n| Anthropic API `claude-opus-5`, `claude-opus-4-8`, `claude-sonnet-5`, `claude-sonnet-4-6`, `claude-fable-5` | 1,000,000 | 128,000 | yes | yes | not documented in code |\n| Google Gemini API `gemini-3.7-flash`, `gemini-3.6-flash`, `gemini-3.5-flash`, `gemini-3.5-flash-lite`, `gemini-3.1-pro-preview`, `gemini-2.5-pro`, `gemini-2.5-flash` | 1,048,576 | 65,536 | model-dependent | no | not documented in code |\n| Meta Model API `muse-spark-1.2` | 1,000,000 | 32,000 | yes | no | not documented in code |\n| ChatGPT plan route (`openai-codex`) | conservatively budgeted; account listing does not state a window | no output cap sent in preview | model dependent | no | public `/v1/responses`; no context limit is inferred from account eligibility |\n| OpenModel default/custom model IDs | 200,000 fallback unless model metadata or config overrides it | 64,000 fallback | model-dependent | no | route uses Messages payload at `/v1/messages` |\n| Wanjie Ark `reasoner` / `r1` model IDs | 128,000 | unknown (no documented maximum) | yes | no | not documented in code |\n| Direct Arcee API `trinity-large-thinking` | 262,144 | 262,144 | yes | no | not documented in code |\n| Direct Arcee API `trinity-large-preview` | 262,144 | unknown (no documented maximum) | no in doctor capability metadata | no | not documented in code |\n| Direct Moonshot `kimi-k3` | 1,048,576 | 1,048,576 documented maximum; 131,072 provider default | yes | no | exact route uses `max_completion_tokens` and omits fixed sampling fields ([K3 quickstart](https://platform.kimi.ai/docs/guide/kimi-k3-quickstart)) |\n| Kimi Code membership `k3` | 262,144 safe baseline; 1,048,576 with an explicit entitled-plan override | 131,072 conservative default ceiling; membership maximum is not published | yes | no | exact `https://api.kimi.com/coding/v1` route |\n| Kimi Code membership `k3-256k` | 262,144 fixed | 131,072 conservative default ceiling; membership maximum is not published | yes | no | exact `https://api.kimi.com/coding/v1` route |\n| Direct Moonshot/Kimi K2.7/K2.6 (`kimi-k2.7-code`, `kimi-k2.7-code-highspeed`, `kimi-k2.6`) | 262,144 | 32,768 | yes | no | provider-reported bundled catalog |\n| Kimi Code membership `kimi-for-coding`, `kimi-for-coding-highspeed` | 262,144 | unknown — the membership catalog owns these limits and no client-side ceiling is claimed | yes | no | exact `https://api.kimi.com/coding/v1` route |\n| Direct Z.AI `GLM-5.3` (default) | 1,000,000 | 131,072 | yes | no | live on the GLM Coding Plan; limits inherited from `GLM-5.2` until Z.ai publishes distinct 5.3 numbers; no USD price |\n| Direct Z.AI `GLM-5.3-Flash` | 1,000,000 | 131,072 | yes | no | natively multimodal; $0.15/$0.50 list (2026-08-26); faster/explore sibling of `GLM-5.3` |\n| Direct Z.AI `GLM-5.2` | 1,000,000 | 131,072 | yes | no | not documented in code |\n| Direct Z.AI `GLM-5.1` | 202,752 | 131,072 | yes | no | not documented in code |\n| Direct Z.AI `GLM-5-Turbo` | 202,752 | 131,072 | yes | no | faster/explore sub-agent sibling |\n| Direct MiniMax `MiniMax-M3` | 1,000,000 | 524,288 | yes | no | not documented in code |\n| Direct MiniMax M2.x models | 204,800 | unknown until MiniMax output metadata is promoted | yes | no | not documented in code |\n| MiniMax Messages route (`MiniMax-M3`, `MiniMax-M2.7`) | model-specific values above | model-specific values above | yes | no | route uses `/anthropic/v1/messages` |\n| Generic `openai` and AtlasCloud | 128,000 | unknown (no documented maximum) | no in doctor capability metadata | no | not documented in code |\n| Ollama | 8,192 | unknown (no documented maximum) | no | no | not documented in code |\n| Hugging Face Inference Providers V4 model IDs | 131,072 | unknown (no documented maximum) | yes | no | not documented in code |\n| Other recognized DeepSeek model IDs | 128,000 unless the model name carries an explicit `Nk` hint | unknown (no documented maximum) | no unless V4/reasoner logic matches | DeepSeek/NIM only | DeepSeek beta only |\n\nMiniMax M3 uses input-length and service tiers. Codewhale omits\n`service_tier`, so requests use the standard tier and cost estimates select the\ncorrect standard rate from total input usage. Priority rates are listed to keep\nthe official tier structure visible. Prices are USD per million tokens.\n\n| Model / service tier | Input length | Input | Output | Cache read | Cache write |\n| --- | --- | ---: | ---: | ---: | ---: |\n| `MiniMax-M3` standard | up to 512,000 input tokens | $0.30 | $1.20 | $0.06 | not published |\n| `MiniMax-M3` standard | over 512,000 input tokens | $0.60 | $2.40 | $0.12 | not published |\n| `MiniMax-M3` priority | up to 512,000 input tokens | $0.45 | $1.80 | $0.09 | not published |\n| `MiniMax-M3` priority | over 512,000 input tokens | $0.90 | $3.60 | $0.18 | not published |\n| `MiniMax-M2.7` standard | all supported inputs | $0.30 | $1.20 | $0.06 | $0.375 |\n\nThese values come from the [MiniMax pay-as-you-go pricing\nguide](https://platform.minimax.io/docs/guides/pricing-paygo). M3 thinking is\nadaptive or disabled; the OpenAI-compatible API defaults to adaptive and the\nAnthropic-compatible API defaults to disabled. M2.7 thinking cannot be\ndisabled. Codewhale sends explicit controls when the user selects a reasoning\nmode.\n\nTool-call support is tracked separately by the static `ModelRegistry` and by\nthe endpoint's ability to accept OpenAI-compatible `tools` payloads. A custom\nOpenAI-compatible or local endpoint can still reject tool calls even if\nCodewhale can send the schema.\n\n### Hugging Face Inference Providers Notes\n\nThe shipped Hugging Face route targets the OpenAI-compatible Inference Providers\nrouter at `https://router.huggingface.co/v1`. Configure auth with\n`HUGGINGFACE_API_KEY` first, or `HF_TOKEN` as a fallback. Configure the endpoint\nwith `HUGGINGFACE_BASE_URL` first, or `HF_BASE_URL` as a fallback; configure the\nmodel with `HUGGINGFACE_MODEL` first, or `HF_MODEL` as a fallback.\n\nThis route does not imply Hub browsing, model-card metadata, dataset access,\nJobs, uploads, or export. Those remain explicit Model Lab work items so\nprovider auth and artifact movement stay separate.\n\n### When a Local Model Prints Tool JSON\n\nCodewhale only executes tools when the provider returns Chat Completions\n`tool_calls` or streamed `delta.tool_calls`. If a local model prints text such\nas `{\"name\":\"File\",\"arguments\":{\"action\":\"search_content\",...}}` in the\nassistant message, that is ordinary model output, not an executable tool\nrequest.\n\nFor OpenAI-compatible or local runtimes, check:\n\n- The endpoint accepts the `tools` array in `/v1/chat/completions` requests.\n- The selected model or chat template is configured for function/tool calls.\n- The server returns `tool_calls` in the response rather than plain JSON text.\n- The compatibility layer does not strip tools before forwarding the request.\n- If in doubt, test a small `File` `read` or `search_content` action against a\n known tool-calling model before debugging Codewhale's tool registry.\n\nChanging `provider`, `base_url`, or `model` can select a route that supports the\nOpenAI-compatible payload shape, but Codewhale cannot convert arbitrary JSON\ntext into a trusted tool call after the model has emitted it as prose.\n\nDeepSeek will retire `deepseek-chat` and `deepseek-reasoner` on 2026-07-24 at\n15:59 UTC. Codewhale migrates either name to `deepseek-v4-flash` before a\nrequest reaches DeepSeek's first-party OpenAI or Anthropic endpoint. If no\nreasoning tier was configured, `deepseek-chat` also migrates to `off` and\n`deepseek-reasoner` to `high`, preserving their former non-thinking / thinking\nintent; an explicit `reasoning_effort` remains authoritative. The mapping is\ndeliberately not global: Wanjie Ark, aggregators, self-hosted runtimes, and\ncustom endpoints continue to own their model ids.\n\n## Reasoning Effort\n\n`/reasoning ` (and the `reasoning_effort` config key) is translated to\neach provider's wire dialect by the client before the request is sent. `off`\ndisables thinking where the route supports it. Both exact K3 routes map `off`\nto their lowest supported tier, `low`, and the model is never switched to\nsatisfy `off` — but they do so for different reasons:\n\n- **Kimi Code membership K3** (exact `https://api.kimi.com/coding/v1` with\n `model = \"k3\"` or `model = \"k3-256k\"`) — the membership roster declares K3 always-thinking, so `off`\n cannot be honored without changing what the model is. The clamp preserves the\n fixed K3 identity.\n- **Direct Moonshot K3** (exact `https://api.moonshot.ai/v1` with\n `model = \"kimi-k3\"`) — this clamp is *defensive*, not a documented contract.\n The direct platform publishes no `off` state for K3, and Codewhale will not\n assert a fixed-thinking guarantee it cannot verify for a given key's\n entitlement, so the requested `off` is normalized to the lowest tier with the\n live entitlement left unknown.\n\nNormal dispatched\n`auto` uses Codewhale's auto-reasoning selector and sends a concrete tier;\nonly an omitted reasoning setting leaves the provider default in control.\nProviders marked \"omitted\" receive no reasoning fields at all for that tier.\n\n| Provider | `off` | `low`/`medium`/`high` | `max`/`xhigh` |\n| --- | --- | --- | --- |\n| `deepseek`, `deepseek-cn`, `siliconflow`, `siliconflow-CN`, `sglang`, `volcengine`, `atlascloud` | `thinking: {type: disabled}` | `reasoning_effort: \"high\"` + `thinking: {type: enabled}` | `reasoning_effort: \"max\"` + `thinking: {type: enabled}` |\n| `openrouter`, `novita`, other `together` models | `thinking: {type: disabled}` | `reasoning_effort` pass-through + `thinking: {type: enabled}` | `reasoning_effort: \"xhigh\"` + `thinking: {type: enabled}` |\n| `together` + `thinkingmachines/inkling` | `reasoning_effort: \"none\"` | exact `minimal`/`low`/`medium`/`high` `reasoning_effort` | `reasoning_effort: \"max\"` |\n| Direct Moonshot `kimi-k3` at exact `https://api.moonshot.ai/v1` | top-level `reasoning_effort: \"low\"` (effective normalization) | top-level `reasoning_effort: \"low\"` / `\"high\"` (`medium` becomes `high`) | top-level `reasoning_effort: \"max\"` |\n| Kimi Code membership `k3`, `k3-256k` at exact `https://api.kimi.com/coding/v1` | `thinking: {type: enabled, effort: \"low\"}` (effective normalization) | `thinking: {type: enabled, effort: \"low\" | \"high\"}` | `thinking: {type: enabled, effort: \"max\"}` |\n| Other `moonshot` routes | `thinking: {type: disabled}` | `thinking: {type: enabled}` | `thinking: {type: enabled}` |\n| `ollama` | `think: false` | `think: true` | `think: true` |\n| `ollama-cloud` | `reasoning_effort: \"none\"` | exact `low`/`medium`/`high` `reasoning_effort` | `reasoning_effort: \"max\"` |\n| `xiaomi-mimo` | `thinking: {type: disabled}` | `thinking: {type: enabled}` | `thinking: {type: enabled}` |\n| First-party `minimax` `MiniMax-M3` | `reasoning_split: true` + `thinking: {type: disabled}` | `reasoning_split: true` + `thinking: {type: adaptive}`; effective tier granularity unavailable | `reasoning_split: true` + `thinking: {type: adaptive}`; effective tier granularity unavailable |\n| First-party Z.ai `GLM-5.2` | `thinking: {type: disabled}`; no `reasoning_effort` | enabled thinking; only effective `high` adds `reasoning_effort: \"high\"` | enabled thinking + `reasoning_effort: \"max\"` |\n| First-party Z.ai `GLM-5.3` | `thinking: {type: disabled}`; no `reasoning_effort` | enabled thinking; only effective `high` adds `reasoning_effort: \"high\"` | enabled thinking + `reasoning_effort: \"max\"` |\n| First-party Z.ai `GLM-5.3-Flash` | `thinking: {type: disabled}`; no `reasoning_effort` | enabled thinking; only effective `high` adds `reasoning_effort: \"high\"` | enabled thinking + `reasoning_effort: \"max\"` |\n| First-party Z.ai `GLM-5-Turbo` | `thinking: {type: disabled}` | enabled thinking; effort granularity unavailable | enabled thinking; effort granularity unavailable |\n| Compatible gateways configured as `zai` | omitted; effective unavailable | omitted; effective unavailable | omitted; effective unavailable |\n| `nvidia-nim` | `chat_template_kwargs.thinking: false` | `chat_template_kwargs`: `thinking: true` + `reasoning_effort: \"high\"` | `chat_template_kwargs`: `thinking: true` + `reasoning_effort: \"max\"` |\n| `vllm` | `chat_template_kwargs.enable_thinking: false` | `chat_template_kwargs.enable_thinking: true` + `reasoning_effort` low/medium/high | `chat_template_kwargs.enable_thinking: true` + `reasoning_effort: \"high\"` (vLLM has no max tier) |\n| `arcee`, `huggingface` | omitted | `reasoning_effort` pass-through | `reasoning_effort: \"high\"` |\n| `fireworks` | omitted | `reasoning_effort: \"high\"` | `reasoning_effort: \"max\"` |\n| `openai`, `wanjie-ark`, `telecomjs` | omitted | omitted | omitted |\n| `openmodel` | Anthropic Messages adapter handles thinking/output configuration | Anthropic Messages adapter handles thinking/output configuration | Anthropic Messages adapter handles thinking/output configuration |\n| `openai-codex` | Responses API `reasoning` field (handled by the Responses bridge) | Responses API `reasoning` field | Responses API `reasoning` field |\n\nAtlasCloud serves DeepSeek models, so it speaks the DeepSeek reasoning dialect,\nincluding the `max` tier (#3024).\n\nOn the exact MiniMax OpenAI-compatible Chat endpoints, `MiniMax-M3` uses\n`max_completion_tokens`. Other MiniMax models and compatible gateways retain\n`max_tokens`; the MiniMax Anthropic endpoints use the separate Messages\nadapter.\n\n## Drift Check\n\nRun this before changing provider IDs, provider TOML tables, static model\nregistry rows, or provider default strings:\n\n```bash\npython3 scripts/check-provider-registry.py\n```\n\nThe check fails when:\n\n- `docs/PROVIDERS.md` omits a canonical `ProviderKind::as_str()` ID.\n- Descriptor presentation IDs or released wire tags are duplicated or drift\n from intrinsic kinds, or a second provider enum/ordinal bridge is introduced.\n- The shipped-provider table omits or adds a `[providers.*]` TOML table.\n- The static model registry table drifts from providers used by\n `crates/agent/src/lib.rs`.\n- A provider default model or base URL constant in `crates/tui/src/config.rs`\n is no longer mentioned here.\n\n## Provider Gotchas\n\nThree failures that look like something else (measured by a provider operator\non live traffic):\n\n- **A cold model looks broken.** The first call to a model the provider has not\n loaded can take 90 to 150 seconds, then drop to a second or less once warm.\n Raise `[stream].open_timeout_secs` (default 45 seconds, at most 300) before reading a timeout as \"model unavailable\".\n- **Listed is not callable.** A catalog entry can be visible and still fail\n every call. The same error text on every attempt (for example a \"resources\n busy\" 502) is not transient: a genuinely busy upstream returns successes in\n between. Probe a model before trusting it, and stop retrying one that fails\n identically.\n- **A truncated answer can report `stop`.** A reasoning model can spend the\n whole `max_tokens` allowance on reasoning. When the provider reports\n `completion_tokens` exactly equal to the `max_tokens` the request asked for\n and the finish reason is `stop`, Codewhale treats the turn as cut at the\n ceiling rather than finished (`stop_contradicts_output_ceiling` in\n `codewhale-models`); retrying the same prompt stops at the same count, so\n raise the ceiling or shorten the task instead. No inference is made when the\n provider reports no usage.\n\n## Planned, Not Shipped Yet\n\nThese items belong to the v0.8.48+ provider-abstraction milestone or related\nprovider docs work, but they are not native shipped behavior in this checkout:\n\n- A unified `Provider` trait in `codewhale-agent` that owns env precedence,\n secret resolution, base URL normalization, auth-header construction, and\n provider metadata. Those responsibilities are still split across\n `crates/config`, `crates/secrets`, and `crates/tui/src/client.rs`.\n- Hugging Face model passport metadata in the picker, including license, base\n model, context length, chat template, tool-call support, reasoning support,\n and gated/private status.\n\n## Sign in with Claude\n\nRun `codewhale auth claude` (or `/auth claude` in a running session), open the\nprinted Claude sign-in URL, and paste the complete `code#state` callback.\n`/provider setup anthropic` also offers API-key and Claude Pro / Max choices.\nThen select `anthropic` or its `claude` alias. API keys continue to use separate\nAnthropic API billing; selecting subscription sign-in never falls back to one.\n\nCodewhale stores the grant in its private credentials directory, commits the\nprovider's credential pointer atomically, and refreshes it before requests on a\nworker. Subscription tokens go only to `https://api.anthropic.com`; a custom\nendpoint is rejected. Each request keeps the existing Messages adapter, tool\nprotocol, cache prefix, and Codewhale client identity. No Claude Code credential\nfile or keychain entry is read or modified.\n\n`codewhale auth claude-revoke` (or `/auth claude-revoke`) removes the owned local\ngrant. End remote access separately in your Claude account settings. The\nsubscription route then needs another login; select API-key billing explicitly\nto use an API key. Login and inference follow Anthropic's provider-side\navailability; local checks do not\nestablish that an account is eligible or that live subscription inference works.\n\nThe callback and JSON token exchange follow the interoperable flow used by\n[pi's Anthropic OAuth adapter](https://github.com/fivewillow/badlogic-pi-mono/blob/main/packages/ai/src/utils/oauth/anthropic.ts).\n" + "sha256": "22274d4a904f4dc805b451ae8e27ae2f3d7350c596658e5267f645fdb343764f", + "content": "# Provider Registry\n\n> 阅读简体中文版:[zh_hans/PROVIDERS.md](zh_hans/PROVIDERS.md)\n\nSpeech recognition, synthesis, translation and video have separate execution\npaths. See [media models](MEDIA_MODELS.md) for current support and reviewed\nupstream candidates; a chat catalogue row alone does not add a media backend.\n\nThis registry describes provider behavior that is wired into the current\nCodewhale codebase. It is intentionally conservative: shipped entries are\nlimited to provider IDs, config keys, auth paths, base URLs, model resolution,\nand capability metadata that the code already knows about.\n\nDeepSeek remains the default provider, but every entry in `ProviderKind::ALL`\nis a first-class selectable provider route. `ALL` is the catalog/picker\nsurface — one identity per vendor. Dual-wire dialect kinds (`*Anthropic`, e.g.\n`deepseek-anthropic`) and the Model Studio plan variants stay on the enum for\nserde and `provider_for_kind` but are deliberately **not** catalog rows:\na plan is `mode`/`base_url` and a dialect is `wire = openai|anthropic` on the\nprimary provider config (`crates/config/src/provider_kind.rs:221-226`). Hosted\nroutes, generic OpenAI-compatible endpoints, the OpenAI Codex/ChatGPT route,\nnative Anthropic, and local runtimes all run the same terminal harness against\nthe selected provider/model/base URL.\n\nA host reached over plain Chat Completions is an ordinary named provider,\nnot a `ProviderKind`: enum variants are reserved for distinct *wires*\n(Anthropic Messages, Codex Responses, Google thought signatures). Any such\nhost is a `[providers.]` table with a base URL, a model, and a key env\n(`docs/CONFIGURATION.md`); `/provider` and `/setup` keep a \"paste a Base URL\nand a key\" path for exactly this. Offerings come from live `GET /v1/models`\nplus the Codewhale catalog rather than a compiled roster (#5350, #6289).\n\nKnown-good hosts. These ship as bundled descriptor rows in\n`crates/config/assets/provider_descriptors.json` (compiled in by\n`crates/config/src/descriptors.rs`): each row says how to reach the host — wire,\nbase URL, key env, aliases — while model ids stay live from `GET /v1/models`\nand the Codewhale catalog; the example model is only a bootstrap hint. Verify\nagainst the vendor's own docs before trusting any value here:\n\n| Host | Base URL | Example models | API key env |\n| --- | --- | --- | --- |\n| SenseNova | `https://token.sensenova.cn/v1` | `deepseek-v4-flash` | `SENSENOVA_API_KEY` |\n| Baseten | `https://inference.baseten.co/v1` | `deepseek-ai/DeepSeek-V4-Pro` | `BASETEN_API_KEY` |\n| Groq | `https://api.groq.com/openai/v1` | `llama-3.3-70b-versatile` | `GROQ_API_KEY` |\n| Cerebras | `https://api.cerebras.ai/v1` | `llama-3.3-70b` | `CEREBRAS_API_KEY` |\n| Command Code | `https://api.commandcode.ai/provider/v1` | `deepseek/deepseek-v4-flash` | `COMMAND_CODE_API_KEY` |\n| Alibaba Model Studio (DashScope) | `https://dashscope-intl.aliyuncs.com/compatible-mode/v1` | `qwen3.8-flash` | `DASHSCOPE_API_KEY` |\n| AICraft | `https://aicraftapi.com/v1` | `claude-4.6-sonnet`; DeepSeek / Claude / Gemini / Qwen / GLM / MiniMax / Doubao families | `AICRAFT_API_KEY` |\n| Tsubasa | `https://api.tsubasa.sh/v1` | `tsubasa-pro`, `tsubasa-fast` (32,768-token context) | `TSUBASA_API_KEY` |\n| Cheaper Inference | `https://api.cheaperinference.com/v1` | `gpt-5.4-mini`, `claude-sonnet-5`, `gemini-3.1-pro` | `CHEAPER_INFERENCE_API_KEY` |\n| Yolo-Auto | `https://yolo-auto.com/v1` | `qwen3.8-flash`; `yolo` / `yolo-small` | `YOLO_AUTO_API_KEY` |\n| Standard Compute | `https://api.stdcmpt.com/v1` | `standardcompute` (router); `deepseek/deepseek-v4-pro`, `anthropic/claude-sonnet-5.5` | `STANDARDCOMPUTE_API_KEY` |\n\nAICraft's roster spans DeepSeek, Anthropic Claude, Google Gemini, Qwen, GLM,\nMiniMax and Doubao ids on its OpenAI-compatible endpoint. The authority is\n`GET https://aicraftapi.com/v1/models` with your key — pick a model from that\nlist, not from this table.\nTsubasa implements only `GET /v1/models` and Chat Completions. Its two public\nmodel ids share a 32,768-token context, smaller than the 128,000 tokens Codewhale assumes\nfor an unknown model, so set it on the route after saving:\n`codewhale config set providers.tsubasa.context_window 32768`.\n\nCheaper Inference is an OpenAI-compatible gateway with one key for models from\nseveral labs. Model ids are bare, such as `gpt-5.4-mini` or `claude-sonnet-5`.\nPricing varies by model and route; consult the provider’s current catalog.\nThe authority is `GET https://api.cheaperinference.com/v1/models` with your key.\nDocs: .\n\nStandard Compute offers flat monthly plans with a compute budget. By default,\nrequests return HTTP 402 when it is used; eligible plans can enable Pay as you go\nto continue with additional prepaid charges. See its\n[budget policy](https://docs.standardcompute.com/budgets-and-limits).\nThe `standardcompute` model id routes each request across models and providers;\nvendor-prefixed ids such as `deepseek/deepseek-v4-pro` pin one model. The\nauthority is `GET https://api.stdcmpt.com/v1/models`.\nDocs: .\n\nOpenCode Zen and OpenCode Go are first-class provider routes, configured like\nany other provider below; they are not part of this table. In `/provider`,\ntype to filter the list (letters not bound to a row action); `Ctrl+T` probes the\nselected row's `/models` and records reachability only (a 2xx is not\nmodel-ready).\n\nSources to keep in sync:\n\n- `crates/config/assets/provider_descriptors.json` - built-in and compatible-host\n labels, defaults, aliases, key-env lists, config/secret slots, and credential\n guidance. `crates/config/build.rs` generates immutable typed views and the\n existing constant projections from this one data owner.\n- `crates/config/src/provider_kind.rs` and `src/lib.rs` - legacy identity serde,\n config schema, environment precedence and Rust route/auth behavior.\n- `crates/tui/src/config.rs` - captures and verifies exact configured provider\n identities and keeps provider-specific credential and route policy in Rust.\n- `crates/config/assets/catalog_corrections.json` `reviewed` - intrinsic facts,\n scoped selector aliases, completion references and pure transport metadata.\n The existing seed renderer embeds this reviewed supplement in Models.dev.\n- `crates/agent/src/lib.rs` - compatibility projection of those shared selector\n rows, used by `codewhale model resolve` (and the `[model]` config surface).\n `codewhale model list` reads the resolved provider lake instead, so a single\n list shows bundled, live and configured rows together.\n- `config.example.toml` and `docs/CONFIGURATION.md` - user-facing config\n examples and environment variable reference.\n- `scripts/check-provider-registry.py` - drift check for canonical provider\n IDs, live TUI provider IDs, TOML table names, static registry rows, and\n documented defaults.\n\n## Captured Provider Identity\n\nPresentation names, labels, aliases, and historical wire tags come from\n`provider_descriptors.json`. `ProviderKind` remains the Rust-owned intrinsic\ncredential, protocol, and region distinction. A configured route captures both\nits kind and exact table key; a custom table named `openai` stays custom and\ndoes not acquire OpenAI credentials or protocol rules from its name. Case is\nsignificant for custom keys.\n\nDeepSeek China has three preserved representations: `deepseek_c_n` in released\nTUI serde wrappers, `deepseek-cn` as its captured route ID, and `deepseek_cn` as\nits config leaf. Its intrinsic kind is DeepSeek, while its table and endpoint\nstay distinct.\n\nAn old custom route without an additive provider ID can resume only with a\nverified root `base_url` migration into the active `providers.custom` table.\nThat private receipt is bound to the parsed table generation. A table-only,\nprofile-only, conflicting, or later replaced table cannot establish the\nmissing identity; an explicit empty ID is refused. Writes reuse the existing\nlocked config mutation and undo comparison, obtain the fresh migration receipt\nunder that lock, and verify the captured table before changing a leaf.\n\nIn-flight requests retain their captured identity, endpoint, and credential\ngeneration. Health lookup cannot treat an opaque credential reference as ready\nmerely because an earlier request used the same authentication class.\n\n## Provider Selection\n\nWith no saved model, no `default_text_model`, and no `CODEWHALE_MODEL` or\nprovider-specific model variable, a fresh install runs `deepseek-flash` on the\nDeepSeek provider. Precedence is the active provider's configured default, then\nits catalog default — so an explicit `default_text_model` is not silently\noverridden by whichever model the shipped catalog lists first.\n\nRefresh model catalogs without installing a new Codewhale release:\n\n```sh\ncodewhale models --update\ncodewhale models --update --provider openai\ncodewhale models --provider openai --json\n```\n\n`models --update` (also `--refresh`) updates the shared Models.dev metadata\nand calls the existing `/models` endpoint for each configured provider with\nits own credentials. `--provider ID` restricts the refresh to that exact\nprovider, including named custom endpoints. It makes no inference requests\nand never changes the saved provider or model. A command-line API key is\nconfined to the active provider; other routes are reported as skipped for\nthat invocation.\n\nPlain `models` lists the active provider's saved catalog without provider requests.\nFor ChatGPT, it validates the selected registration locally before reading\nthat account's saved roster. Successful refreshes are saved under Codewhale's\ncatalog directory and used by the model/provider pickers. Cache files are\nscoped to provider identity and endpoint; a failed refresh preserves prior\nrows. Text output reports source, last successful fetch time (Unix seconds),\nand freshness. `--update --json` adds per-source receipts and aggregate counts;\npartial failures return a nonzero exit code after writing those receipts.\nOrdinary `models --json` keeps its model-array format. Bundled/configured\nfallbacks are not proof that an account can use every listed model.\n\n### Sign in with ChatGPT\n\nThe `openai-codex` provider ID now uses OpenAI's official open-source\n[Sign in with ChatGPT flow](https://developers.openai.com/siwc/token-sharing-open-source).\nSign in and refresh the selected account's catalog:\n\n```sh\ncodewhale auth chatgpt\ncodewhale models --update --provider openai-codex\ncodewhale --provider openai-codex\n```\n\nSign-in opens your system browser, uses a loopback callback and PKCE, validates\nthe returned identity, and stores the issued registration and renewable tokens\nin Codewhale's protected credential storage. Permission to use your ChatGPT\nplan is separate from identity sign-in. A declined or missing plan grant stops\ninference; choose another provider explicitly if you want another billing path.\n`codewhale auth chatgpt-revoke` signs out of the Codewhale-owned session.\nThis experimental implementation retains one active registration. A picker\nfor multiple saved ChatGPT accounts is not implemented yet.\n\nModel discovery uses your granted bearer token at\n`GET https://api.openai.com/v1/models`; inference uses the public\n`POST https://api.openai.com/v1/responses` endpoint. The model picker keeps\nOpenAI's display labels and order and lists only entries with `visibility: list`.\nThe catalog contains no credentials and is bound to the verified issuer,\nissued client ID, and account subject. Another account or workspace never\ninherits those model choices. Missing, invalid, or older-than-one-day rosters\nare reported explicitly and provide no account entitlement evidence. Run the\nrefresh command after signing in. Neither model discovery nor ordinary listing\nstarts an inference request. Imported Codex CLI tokens and legacy process-token\nvariables cannot authorize this official plan route.\n\nEligible requests consume your ChatGPT plan or credits. ChatGPT Plus's\nfive-hour allowance is shared across apps; each app receives no separate\nallowance. The documented five-hour limit does not apply to Pro. App-specific\nlimits can also apply. Review limits and access in\n[ChatGPT usage settings](https://chatgpt.com/settings/usage). Codewhale does\nnot silently switch to an API key or another provider when a limit is reached.\n\nThis is an OpenAI preview for open-source/local apps. It does not grant access\nto ChatGPT conversation history. Requests stream with `store: false` and\n`stream: true`, while Codewhale retains its own session history and tools.\nOpenAI-hosted image generation, file search, Code Interpreter, native computer\nuse, hosted MCP/connectors, and Responses `tool_search` are unavailable on this\nroute; Codewhale's own tools use supported function/custom tool calls.\nThe ChatGPT preview requests one function call at a time.\nSee [preview limitations](https://developers.openai.com/siwc/token-sharing-open-source/preview-limitations).\nPaid or remotely hosted applications require the\n[commercial partner interest process](https://openai.com/form/sign-in-with-chatgpt-interest/);\nthis local integration is not commercial approval.\n\nThe canonical provider IDs are the entries of `ProviderKind::ALL`\n(`crates/config/src/provider_kind.rs`), in that order:\n\n`deepseek`, `nvidia-nim`, `openai`, `atlascloud`, `wanjie-ark`, `volcengine`,\n`openrouter`, `orcarouter`, `xiaomi-mimo`, `novita`, `fireworks`, `siliconflow`, `arcee`,\n`siliconflow-CN`, `moonshot`, `sglang`, `vllm`, `ollama`, `ollama-cloud`, `huggingface`,\n`together`, `qianfan`, `openai-codex`, `anthropic`, `openmodel`, `zai`,\n`stepfun`, `minimax`, `deepinfra`, `sakana`, `longcat`, `opencode-go`,\n`opencode-zen`, `meta`, `xai`, `mistral`, `telecomjs`, `modelstudio-token-plan`, `modelscope`,\n`google`, `edenai`, `zenmux`, `csdn`, `concentrate`, `codewhale`, and `custom`.\n\n`deepseek-anthropic` is *not* on this list — it is a wire dialect of\n`deepseek`, reached with `wire = \"anthropic\"`, not a separate route to select.\n\nUse any of these surfaces to select a provider:\n\n- CLI: `codewhale --provider `\n- TUI: `/provider ` or the provider picker\n- Env: `CODEWHALE_PROVIDER=`; `DEEPSEEK_PROVIDER=` is the legacy alias\n- Config: `provider = \"\"`\n\n`deepseek-cn`, `deepseek_china`, `deepseekcn`, and `deepseek-china` are accepted\nas legacy aliases for `deepseek`. They do not select a different official host;\nDeepSeek uses the same official API host worldwide.\n\n`deepseek_anthropic`, `deepseek-claude`, and `deepseek_claude` select\n`deepseek-anthropic`, the opt-in DeepSeek route that speaks the Anthropic\nMessages API at `https://api.deepseek.com/anthropic`. It keeps the normal\nDeepSeek API key path but uses `x-api-key` plus `anthropic-version: 2023-06-01`\ninstead of Bearer auth. If the key already lives in official DeepSeek Harness\n(`dsh`) at `$DSH_HOME/.credentials.yaml`, grant read-only access with\n`codewhale auth external-consent --provider deepseek --mode read-only`.\nCodewhale never writes that file and only reads `DEEPSEEK_API_KEY`.\n\n`huggingface`, `hugging-face`, `hugging_face`, and `hf` all select the\nHugging Face Inference Providers route. This is the OpenAI-compatible router\npath for chat/inference, not Hub browsing, model-card inspection, uploads, or\nartifact export.\n\n`telecomjs`, `telecom-js`, `telecom_js`, `telecomjs-cn`, and `tokenhub` all\nselect the TelecomJS TokenHub route. Its authenticated `/models` catalog is\nkey-scoped and remains isolated from every other provider's live snapshot.\n\nFresh shared config writes to `~/.codewhale/config.toml`. Existing\n`~/.deepseek/config.toml` files are still read for compatibility.\n\n### Legacy Antigravity tombstone\n\nAntigravity is not a Codewhale provider and cannot be selected or run. Existing\nlegacy Antigravity provider state is recognized only as a non-runnable migration\ntombstone. Run `codewhale auth clear --provider antigravity` to forget only\nCodewhale-owned legacy configuration and consent metadata. This does not sign\nout of, revoke, read, or otherwise alter any official Google or Antigravity\nsession. For Gemini, select the supported `google` provider and supply\n`GEMINI_API_KEY`.\n\n### Wire Protocol Compatibility\n\nProvider selection is explicit. A model string prefix such as\n`deepseek-ai/...`, `deepseek/...`, `qwen/...`, or `arcee-ai/...` is a\nprovider-owned wire ID or catalog namespace hint under the selected provider.\nIt is not a provider switch and must not be treated as proof that the route is\nDeepSeek, OpenRouter, or any other provider.\n\nSet the route with `provider = \"\"`, `CODEWHALE_PROVIDER=`, or\n`codewhale --provider `. Set the request model with `CODEWHALE_MODEL`, a\nprovider-specific model env var, top-level `default_text_model`, or\n`[providers.
].model`. Set the endpoint with `CODEWHALE_BASE_URL`, a\nprovider-specific base URL env var, or `[providers.
].base_url`. Set auth\nwith `codewhale auth set --provider `, `[providers.
].api_key`, or\nthe listed provider env vars.\n\n| Provider ID | TOML table | Wire protocol | Auth env vars |\n| --- | --- | --- | --- |\n| `deepseek` | `[providers.deepseek]` | Model-aware: Responses default (`deepseek-flash`); Chat Completions (`deepseek-v4-pro`) | `DEEPSEEK_API_KEY` |\n| `deepseek-anthropic` | `[providers.deepseek_anthropic]` | Anthropic Messages | `DEEPSEEK_API_KEY` |\n| `nvidia-nim` | `[providers.nvidia_nim]` | OpenAI Chat Completions | `NVIDIA_API_KEY`, `NVIDIA_NIM_API_KEY` |\n| `openai` | `[providers.openai]` | OpenAI Chat Completions | `OPENAI_API_KEY` |\n| `atlascloud` | `[providers.atlascloud]` | OpenAI Chat Completions | `ATLASCLOUD_API_KEY` |\n| `wanjie-ark` | `[providers.wanjie_ark]` | OpenAI Chat Completions | `WANJIE_ARK_API_KEY`, `WANJIE_API_KEY`, `WANJIE_MAAS_API_KEY` |\n| `volcengine` | `[providers.volcengine]` | OpenAI Chat Completions | `VOLCENGINE_API_KEY`, `VOLCENGINE_ARK_API_KEY`, `ARK_API_KEY` |\n| `openrouter` | `[providers.openrouter]` | OpenAI Chat Completions | `OPENROUTER_API_KEY` |\n| `xiaomi-mimo` | `[providers.xiaomi_mimo]` | OpenAI Chat Completions | `XIAOMI_MIMO_TOKEN_PLAN_API_KEY`, `MIMO_TOKEN_PLAN_API_KEY`, `XIAOMI_MIMO_API_KEY`, `XIAOMI_API_KEY`, `MIMO_API_KEY` |\n| `novita` | `[providers.novita]` | OpenAI Chat Completions | `NOVITA_API_KEY` |\n| `fireworks` | `[providers.fireworks]` | OpenAI Chat Completions | `FIREWORKS_API_KEY` |\n| `siliconflow` | `[providers.siliconflow]` | OpenAI Chat Completions | `SILICONFLOW_API_KEY` |\n| `arcee` | `[providers.arcee]` | OpenAI Chat Completions | `ARCEE_API_KEY` |\n| `siliconflow-CN` | `[providers.siliconflow_cn]` | OpenAI Chat Completions | `SILICONFLOW_API_KEY` |\n| `moonshot` | `[providers.moonshot]` | OpenAI Chat Completions | `MOONSHOT_API_KEY`, `KIMI_API_KEY` |\n| `sglang` | `[providers.sglang]` | OpenAI Chat Completions | `SGLANG_API_KEY` |\n| `vllm` | `[providers.vllm]` | OpenAI Chat Completions | `VLLM_API_KEY` |\n| `ollama` | `[providers.ollama]` | Local OpenAI-compatible Chat Completions | `OLLAMA_API_KEY` (optional; only for an authenticated local route) |\n| `ollama-cloud` | `[providers.ollama_cloud]` | Hosted OpenAI-compatible Chat Completions | `OLLAMA_CLOUD_API_KEY`, `OLLAMA_API_KEY` |\n| `huggingface` | `[providers.huggingface]` | OpenAI Chat Completions | `HUGGINGFACE_API_KEY`, `HF_TOKEN` |\n| `modelscope` | `[providers.modelscope]` | OpenAI Chat Completions | `MODELSCOPE_API_KEY` |\n| `together` | `[providers.together]` | OpenAI Chat Completions | `TOGETHER_API_KEY` |\n| `qianfan` | `[providers.qianfan]` | OpenAI Chat Completions | `QIANFAN_API_KEY`, `BAIDU_QIANFAN_API_KEY` |\n| `openai-codex` | `[providers.openai_codex]` | OpenAI Responses | Official Sign in with ChatGPT (`codewhale auth chatgpt`) with a validated Codewhale-owned plan grant |\n| `anthropic` | `[providers.anthropic]` | Anthropic Messages | `ANTHROPIC_API_KEY` or `codewhale auth claude` |\n| `openmodel` | `[providers.openmodel]` | Anthropic Messages | `OPENMODEL_API_KEY` |\n| `zai` | `[providers.zai]` | OpenAI Chat Completions | `ZAI_API_KEY`, `Z_AI_API_KEY` |\n| `stepfun` | `[providers.stepfun]` | OpenAI Chat Completions | `STEPFUN_API_KEY`, `STEP_API_KEY` |\n| `minimax` | `[providers.minimax]` | OpenAI Chat Completions | `MINIMAX_API_KEY` |\n| `deepinfra` | `[providers.deepinfra]` | OpenAI Chat Completions | `DEEPINFRA_API_KEY`, `DEEPINFRA_TOKEN` |\n| `sakana` | `[providers.sakana]` | OpenAI Chat Completions | `FUGU_API_KEY`, `SAKANA_API_KEY` |\n| `longcat` | `[providers.longcat]` | OpenAI Chat Completions | `LONGCAT_API_KEY` |\n| `opencode-go` | `[providers.opencode_go]` | OpenAI Chat Completions | `OPENCODE_GO_API_KEY` |\n| `opencode-zen` | `[providers.opencode_zen]` | Model-aware: OpenAI Responses, Anthropic Messages, or OpenAI Chat Completions | `OPENCODE_ZEN_API_KEY`, `OPENCODE_API_KEY` |\n| `meta` | `[providers.meta]` | OpenAI Chat Completions | `META_MODEL_API_KEY`, `MODEL_API_KEY` |\n| `telecomjs` | `[providers.telecomjs]` | OpenAI Chat Completions | `TELECOMJS_API_KEY` |\n| `xai` | `[providers.xai]` | OpenAI Chat Completions | `XAI_API_KEY` |\n| `mistral` | `[providers.mistral]` | OpenAI Chat Completions | `MISTRAL_API_KEY` |\n| `google` | `[providers.google]` | OpenAI Chat Completions (official Gemini OpenAI-compat route; captures and replays thought signatures on tool calls) | `GOOGLE_API_KEY`, `GEMINI_API_KEY` |\n| `edenai` | `[providers.edenai]` | OpenAI Chat Completions | `EDENAI_API_KEY` |\n| `zenmux` | `[providers.zenmux]` | OpenAI Chat Completions | `ZENMUX_API_KEY` |\n| `csdn` | `[providers.csdn]` | OpenAI Chat Completions | `CSDN_API_KEY` |\n| `concentrate` | `[providers.concentrate]` | OpenAI Responses (`/v1/responses`) | `CONCENTRATE_API_KEY` |\n| `codewhale` | `[providers.codewhale]` | Model-aware: OpenAI Chat Completions (`/v1/chat/completions`) or Anthropic Messages (`/v1/messages`), chosen per model by the account catalog | `CODEWHALE_API_KEY` |\n| `modelstudio-token-plan` | `[providers.modelstudio_token_plan]` | OpenAI Chat Completions | `MODELSTUDIO_API_KEY`, `DASHSCOPE_API_KEY` |\n| `modelstudio-token-plan-anthropic` | `[providers.modelstudio_token_plan_anthropic]` | Anthropic Messages | `MODELSTUDIO_API_KEY`, `DASHSCOPE_API_KEY` |\n| `modelstudio-coding-plan` | `[providers.modelstudio_coding_plan]` | OpenAI Chat Completions | `MODELSTUDIO_API_KEY`, `DASHSCOPE_API_KEY` |\n| `modelstudio-coding-plan-anthropic` | `[providers.modelstudio_coding_plan_anthropic]` | Anthropic Messages | `MODELSTUDIO_API_KEY`, `DASHSCOPE_API_KEY` |\n\nDefault base URLs and models for each route are listed in the shipped provider\ntable below. The wire protocol values above are derived from\n`crates/config/src/provider.rs`: `ChatCompletions` is the default,\n`openai-codex` overrides to `Responses`; `deepseek-anthropic`, `anthropic`, and\n`openmodel` override to `AnthropicMessages`; `opencode-zen` resolves the\nprotocol from the selected model's curated offering; and `deepseek` is\nmodel-aware — the shipped default `deepseek-flash` (and legacy\n`deepseek-v4-flash`) rides the Responses endpoint while `deepseek-v4-pro`\nstays on Chat Completions.\n\n## Auth And Env Rules\n\nFor hosted providers, `codewhale auth set --provider ` saves an API key for\nthat provider. API-key environment variables are fallback inputs after saved\nconfig and keyring credentials; an explicit process-level `--api-key` still\nwins for that launch.\n\nFor base URL and model selection, prefer:\n\n- `CODEWHALE_BASE_URL` / `CODEWHALE_MODEL` for the active provider.\n- Provider-specific base URL/model env vars when listed below.\n- `DEEPSEEK_BASE_URL`, `DEEPSEEK_MODEL`, and `DEEPSEEK_DEFAULT_TEXT_MODEL` as\n legacy aliases.\n\nNon-local `http://` base URLs are rejected unless\n`DEEPSEEK_ALLOW_INSECURE_HTTP=1` is set. Loopback HTTP URLs are allowed for\nself-hosted runtimes.\n\n## Custom DeepSeek-Compatible Endpoints\n\nMost custom DeepSeek-compatible deployments can use an existing provider ID.\nDo not create `[providers.deepseek_custom]`; the provider table names are fixed.\nInstead, choose the closest shipped route and override its endpoint/model:\n\n- DeepSeek-compatible hosted API: keep `provider = \"deepseek\"` and set\n `[providers.deepseek].base_url` plus `[providers.deepseek].model`, or launch\n with `DEEPSEEK_BASE_URL` and `DEEPSEEK_MODEL`.\n- Generic OpenAI-compatible gateway: use `provider = \"openai\"` with\n `[providers.openai].base_url` plus `[providers.openai].model`, or launch with\n `OPENAI_BASE_URL` and `OPENAI_MODEL`.\n- Multiple named OpenAI-compatible gateways, or local routes you want to pin\n from an AgentProfile, can use a custom table such as\n `[providers.lm-studio] kind = \"openai-compatible\"` and select it with\n `provider = \"lm-studio\"` or a profile `provider = \"lm-studio\"`.\n- Local OpenAI-compatible runtimes: use `provider = \"vllm\"`, `\"sglang\"`, or\n `\"ollama\"` with the matching provider-specific base URL/model values.\n\nExample user config for a DeepSeek-compatible host:\n\n```toml\nprovider = \"deepseek\"\n\n[providers.deepseek]\napi_key = \"YOUR_API_KEY\"\nbase_url = \"https://your-provider.example/v1\"\nmodel = \"deepseek-ai/DeepSeek-V4-Pro\"\n```\n\nExample user config for a generic gateway:\n\n```toml\nprovider = \"openai\"\n\n[providers.openai]\napi_key = \"YOUR_GATEWAY_API_KEY\"\nbase_url = \"https://gateway.example/v1\"\nmodel = \"your-deepseek-compatible-model\"\n```\n\nAlibaba Cloud Model Studio (Bailian / DashScope) is a first-class provider as\nof v0.9.4 with two plan profiles: Token Plan (Personal / Team) and Coding Plan.\nBoth plans expose an OpenAI-compatible Chat Completions endpoint and an\nAnthropic-compatible Messages endpoint.\n\n**Token Plan** (Personal and Team share the same AP-Southeast endpoint):\n\n```toml\nprovider = \"modelstudio-token-plan\"\n\n[providers.modelstudio_token_plan]\napi_key = \"YOUR_MODELSTUDIO_API_KEY\"\n# base_url defaults to https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1\nmodel = \"qwen3.8-max\" # or qwen3.8-max-preview | qwen3.7-plus | qwen3.7-max |\n # qwen3.6-flash | deepseek-v4-pro | deepseek-v4-flash-0731 |\n # glm-5.2\n```\n\n**Coding Plan** (separate international endpoint):\n\n```toml\nprovider = \"modelstudio-coding-plan\"\n\n[providers.modelstudio_coding_plan]\napi_key = \"YOUR_MODELSTUDIO_API_KEY\"\n# base_url defaults to https://coding-intl.dashscope.aliyuncs.com/v1\nmodel = \"qwen3.8-max\"\n```\n\n**Anthropic-compatible dialect** — both plans also expose a native Anthropic\nMessages path. Select it with the `-anthropic` provider suffix:\n\n```toml\nprovider = \"modelstudio-token-plan-anthropic\"\n\n[providers.modelstudio_token_plan_anthropic]\napi_key = \"YOUR_MODELSTUDIO_API_KEY\"\n# base_url defaults to https://token-plan.ap-southeast-1.maas.aliyuncs.com/apps/anthropic\nmodel = \"qwen3.8-max\"\n```\n\nCreate or copy a Model Studio API key from the\n[Bailian console](https://bailian.console.aliyun.com/). The API key is shared\nacross all four provider IDs above; only the base URL and wire protocol differ.\n\n**Thinking / reasoning.** Reasoning surfaces in the TUI's Thinking view on both\ndialects, per Model Studio's\n[deep-thinking docs](https://www.alibabacloud.com/help/en/model-studio/deep-thinking).\n\nOn the OpenAI-compatible routes the top-level controls are **route- and\nmodel-specific**, and Codewhale fails closed: they are sent only when the\nconfigured `base_url` is an official Alibaba Chat Completions host\n(`*.maas.aliyuncs.com/compatible-mode/v1`, including workspace-scoped hosts, or\n`coding-intl.dashscope.aliyuncs.com/v1`). A custom `base_url` on the same\nprovider ID gets `thinking`, `enable_thinking`, `preserve_thinking`, and\n`reasoning_effort` stripped, so an arbitrary OpenAI-compatible gateway is never\nhanded Alibaba's dialect. On a verified host:\n\n- **Hybrid models** (`qwen3.7-*`, `qwen3.6-*`, `deepseek-v4*`, `glm-*`,\n `kimi-k2.6*`) get `enable_thinking`: `false` for `off`, `true` otherwise.\n- **Thinking-only models** — `qwen3.8-max` (catalogued `thinking: always_on`),\n `qwen3.8-max-preview` (effort/budget options, no toggle), and\n `kimi-k2.7-code` — get **no** enable/disable switch at all. Sending one is at\n best ignored.\n- `preserve_thinking` is sent for the models documented to accept it\n (`qwen3.7-max`/`-plus`, `qwen3.6-max-preview`/`-plus`/`-flash`, `kimi-k2.6*`,\n `kimi-k2.7-code`), so the next turn keeps the assistant's trace.\n- `reasoning_effort` is sent only for the two families with a documented ladder\n — `deepseek-v4*` and `glm-5`/`5.1`/`5.2` — mapped to `high` or `max`.\n\nReasoning streams back as `delta.reasoning_content`. It is replayed to the\nprovider on later turns only for the `preserve_thinking` models above and the\nthinking-only models; `deepseek-v3.1`, `deepseek-v3.2`, and `glm-*` history\nstays stripped pending live confirmation that DashScope accepts\n`reasoning_content` in input messages. (`deepseek-v4*` replays regardless — the\nDeepSeek thinking-mode contract requires it on every provider.)\n\nOn the Anthropic-compatible routes, thinking uses the documented\n`{\"type\":\"enabled\",\"budget_tokens\":N}` / `{\"type\":\"disabled\"}` shapes from the\n[Anthropic-compatible Messages API](https://www.alibabacloud.com/help/en/model-studio/anthropic-api-messages),\nwith `budget_tokens` derived from the effort level.\n\nDeepSeek (`deepseek-v4-pro`, `deepseek-v4-flash-0731`) and GLM (`glm-5.2`)\nmodels served by Model Studio are provider-scoped and do not collide with the\nfirst-party DeepSeek or Zhipu/Z.ai routes. Model Studio publishes no `glm-5.3`\nentry, so Codewhale does not offer one on this route.\nPay-as-you-go workspace-id templating is not yet in the built-in provider; use\na custom provider entry for that plan until a follow-up adds it.\n\nPrivate gateways with broken or intercepted certificates should use\n`SSL_CERT_FILE` with a trusted CA bundle. The legacy\n`insecure_skip_tls_verify = true` key is still parsed so `codewhale doctor` can\nreport stale configs, but provider clients reject it instead of skipping TLS\ncertificate verification.\n\nKeep `provider`, `api_key`, and `base_url` in user config or process\nenvironment. Project-local config overlays intentionally cannot set those keys,\nso a repository cannot silently redirect prompts or credentials to another\nendpoint.\n\n## Local Models (DS4, Ollama, vLLM, SGLang)\n\nSelf-hosted OpenAI-compatible runtimes are first-class routes and are keyless\nby default — set an API key only when your server requires one. Start your\nrunner, then point Codewhale at it with `--provider` / `/provider` or a config\ntable.\n\n| Runner | Default base URL | Default model | Base URL override |\n| --- | --- | --- | --- |\n| `ollama` | `http://localhost:11434/v1` | live tag from `GET /v1/models` (pre-refresh: `unknown`) | `OLLAMA_BASE_URL` |\n| `vllm` | `http://localhost:8000/v1` | `deepseek-ai/DeepSeek-V4-Pro` | `VLLM_BASE_URL` |\n| `sglang` | `http://localhost:30000/v1` | `deepseek-ai/DeepSeek-V4-Pro` | `SGLANG_BASE_URL` |\n\n### DS4 (DwarfStar)\n\n[DS4](https://github.com/antirez/ds4/tree/84cc882352757baf628a1776badf7cc54d584e28)\nserves DeepSeek V4 Flash and Pro locally\nthrough an OpenAI-compatible API. Start DS4, then open Codewhale's prefilled,\nkeyless setup form:\n\n```bash\n./ds4-server --ctx 100000 --kv-disk-dir /tmp/ds4-kv --kv-disk-space-mb 8192\ncodewhale\n# In Codewhale: /setup provider ds4\n```\n\nReview the prefilled route and press Enter to save it. The preset budgets a\n100,000-token context to match that starter command and defaults to the Flash\ncompatibility alias. Check the local route explicitly with\n`codewhale doctor --probe-local`.\n\nDS4 loads the actual GGUF when the server starts. Its `deepseek-v4-flash` and\n`deepseek-v4-pro` API ids are compatibility aliases; changing `/model` does\nnot swap the resident model. To run Pro, download the supported Pro weights\nand start `ds4-server -m ...` as described by DS4. Update\n`context_window` whenever the server's `--ctx` value changes.\n\nThe equivalent config is:\n\n```toml\nprovider = \"ds4\"\n\n[providers.ds4]\nkind = \"openai-compatible\"\nbase_url = \"http://127.0.0.1:8000/v1\"\nmodel = \"deepseek-v4-flash\"\nauth_mode = \"none\"\ncontext_window = 100000\n```\n\nCodewhale reuses its existing OpenAI-compatible transport and DeepSeek\nreasoning/tool-call shaping for DS4. It does not invent an API key, confuse an\nAPI alias with the loaded GGUF, or silently switch to a hosted DeepSeek route.\nThe pinned DS4 [agent-client contract](https://github.com/antirez/ds4/blob/84cc882352757baf628a1776badf7cc54d584e28/README.md#agent-client-usage)\ndocuments Chat Completions at `/v1`, DeepSeek thinking replay, streamed usage,\n`max_tokens`, and no strict-tool mode; Codewhale follows those exact route\nfacts instead of inheriting unsupported capabilities from a generic gateway.\nThe primary sources for model-facing behavior are DeepSeek's official\n[thinking-mode](https://api-docs.deepseek.com/guides/thinking_mode),\n[tool-call](https://api-docs.deepseek.com/guides/tool_calls), and\n[Chat Completion](https://api-docs.deepseek.com/api/create-chat-completion)\ncontracts. The pinned\n[DeepSeek Harness adapter](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/packages/llm/llm-deepseek/README.md)\nis only a secondary implementation cross-check; it is not the API contract.\n\n### Ollama\n\n```bash\nollama serve # if not already running\nollama pull # e.g. deepseek-v4-flash, or any tag you prefer\ncodewhale --provider ollama --model \n```\n\nProvider-hinted model names are sent as-is, so `--model qwen3:8b` works with\nany tag Ollama has pulled.\n\n### Ollama Cloud\n\nOllama Cloud is a separate hosted provider. It uses the authenticated\nOpenAI-compatible `/v1/chat/completions` route and defaults to `gpt-oss:120b`:\n\n```toml\nprovider = \"ollama-cloud\"\n\n[providers.ollama_cloud]\nbase_url = \"https://ollama.com/v1\"\nmodel = \"gpt-oss:120b\"\n```\n\nCreate a key in [Ollama account settings](https://ollama.com/settings/keys),\nthen run `codewhale auth set --provider ollama-cloud`. For ambient auth,\n`OLLAMA_CLOUD_API_KEY` wins over Ollama's official `OLLAMA_API_KEY`.\n`OLLAMA_CLOUD_BASE_URL` and `OLLAMA_CLOUD_MODEL` override the Cloud defaults;\narbitrary provider-owned model IDs pass through unchanged. Local `ollama`\nremains a separate, keyless-by-default provider.\n\nCompatibility is read-only and in memory: a released config that selected\n`provider = \"ollama\"` with the exact normalized\n`[providers.ollama] base_url = \"https://ollama.com/v1\"` tuple is treated as\n`ollama-cloud` at runtime. Only that exact tuple may fall back to the legacy\n`ollama` secret slot. Codewhale does not rewrite the config, copy or delete a\nsecret, migrate neighboring paths, or make an explicit `ollama-cloud` route\nconsume the legacy slot.\n\n### vLLM\n\n```bash\nvllm serve --port 8000\n# or: python -m vllm.entrypoints.openai.api_server --model --port 8000\ncodewhale --provider vllm --model \n```\n\nvLLM's OpenAI-compatible server listens on port 8000 by default, matching\nCodewhale's `VLLM_BASE_URL`.\n\n### SGLang\n\n```bash\npython -m sglang.launch_server --model-path --port 30000\ncodewhale --provider sglang --model \n```\n\nSGLang's default port 30000 matches Codewhale's `SGLANG_BASE_URL`.\n\n### Pinning a local route in config\n\n```toml\nprovider = \"ollama\" # or \"vllm\" / \"sglang\"\n\n[providers.ollama]\nmodel = \"qwen3:8b\" # default is deepseek-v4-flash\n# base_url defaults to http://localhost:11434/v1\n```\n\nLocal models that print tool-call JSON without the wire markers: see\n[When a Local Model Prints Tool JSON](#when-a-local-model-prints-tool-json).\n\n## Credential Links\n\nProvider setup surfaces use the same typed credential metadata as onboarding,\n`/provider`, `/links`, setup receipts, and doctor output. A missing URL is\nintentional: local, OAuth-only, and user-defined routes show their supported\nconfiguration path instead of guessing a vendor page.\n\n| Provider ID | Credential or console link |\n| --- | --- |\n| `deepseek`, `deepseek-anthropic` | [DeepSeek API keys](https://platform.deepseek.com/api_keys) |\n| `nvidia-nim` | [NVIDIA NIM API keys](https://build.nvidia.com/settings/api-keys) |\n| `openai` | [OpenAI API keys](https://platform.openai.com/api-keys) |\n| `atlascloud` | [Atlas Cloud API keys](https://atlascloud.ai/docs/en/api-keys) |\n| `wanjie-ark` | [Wanjie MaaS APIKEY docs](https://docs.wanjiedata.com/maas/maas-openapi-v1.html) |\n| `volcengine` | [Volcengine Ark API keys](https://console.volcengine.com/ark/apiKey) |\n| `openrouter` | [OpenRouter keys](https://openrouter.ai/settings/keys) |\n| `xiaomi-mimo` | [Xiaomi MiMo Token Plan](https://platform.xiaomimimo.com/token-plan) |\n| `novita` | [Novita key management](https://novita.ai/en/settings/key-management) |\n| `fireworks` | [Fireworks API keys](https://fireworks.ai/api-keys) |\n| `siliconflow` | [SiliconFlow global API keys](https://cloud.siliconflow.com/account/ak) |\n| `siliconflow-CN` | [SiliconFlow China API keys](https://cloud.siliconflow.cn/account/ak) |\n| `arcee` | [Arcee API key guide](https://docs.arcee.ai/other/create-your-first-api-key) |\n| `moonshot` | [Kimi API platform keys](https://platform.kimi.ai/console/api-keys) or [Kimi Code membership console](https://www.kimi.com/code/console) |\n| `zai` | [Z.ai model API](https://z.ai/model-api) |\n| `stepfun` | [StepFun Open Platform](https://platform.stepfun.ai/) |\n| `minimax`, `minimax-anthropic` | [MiniMax interface keys](https://platform.minimax.io/user-center/basic-information/interface-key) |\n| `huggingface` | [Hugging Face tokens](https://huggingface.co/settings/tokens) |\n| `modelscope` | [ModelScope API Keys](https://modelscope.cn/my/settings/token) |\n| `deepinfra` | [DeepInfra API keys](https://deepinfra.com/dash/api_keys) |\n| `together` | [Together API keys](https://api.together.ai/settings/api-keys) |\n| `qianfan` | [Baidu Cloud access keys](https://console.bce.baidu.com/iam/#/iam/accesslist) |\n| `anthropic` | [Anthropic API keys](https://console.anthropic.com/settings/keys) |\n| `openmodel` | [OpenModel console](https://console.openmodel.ai/) ([authentication guide](https://docs.openmodel.ai/en/docs/getting-started/authentication)) |\n| `openai-codex` | Official Sign in with ChatGPT via `codewhale auth chatgpt` (eligible ChatGPT plan or credits, Codewhale-owned tokens). The `openai` API-key route has separate billing. Legacy imported Codex credentials do not authorize this route. |\n| `sglang`, `vllm` | Local OpenAI-compatible endpoints are keyless by default; configure a key only when the server requires one. |\n| `ollama` | Local Ollama is keyless by default; configure a key only when the local server requires one. |\n| `ollama-cloud` | Create an [Ollama API key](https://ollama.com/settings/keys), save it with `codewhale auth set --provider ollama-cloud`, or set `OLLAMA_CLOUD_API_KEY` / `OLLAMA_API_KEY` in that precedence order. |\n| `sakana` | [Sakana AI API keys](https://console.sakana.ai/api-keys) ([get started](https://console.sakana.ai/get-started)) |\n| `longcat` | [Meituan LongCat platform](https://longcat.chat/platform) |\n| `opencode-go` | [OpenCode Go](https://opencode.ai/docs/go/) |\n| `opencode-zen` | [OpenCode Zen](https://opencode.ai/docs/zen/) |\n| `meta` | [Meta Model API](https://developer.meta.com/ai/) |\n| `telecomjs` | [TelecomJS TokenHub](https://aigw.telecomjs.com/) |\n| `xai` | [xAI Console](https://console.x.ai/) for an API key, Codewhale-owned device login, or explicitly consented read-only Grok CLI credentials. |\n| `mistral` | [Mistral Console (la Plateforme)](https://console.mistral.ai/api-keys) |\n| `google` | [Google AI Studio](https://aistudio.google.com/apikey) — Codewhale uses the official Gemini OpenAI-compatible endpoint and never reads Google OAuth files. |\n| `edenai` | [Eden AI API keys](https://app.edenai.run/settings/api-keys) |\n| `zenmux` | [ZenMux API keys](https://zenmux.ai/platform/pay-as-you-go) |\n| `csdn` | [CSDN 星图 console](https://ai.csdn.net/workbench/api-key) — choose the Coding Plan key type for the `glm_for_coding` plan route; a general key bills metered. Docs: [Coding Plan](https://ai.csdn.net/coding-plan). |\n| `concentrate` | [Concentrate dashboard](https://concentrate.ai/) → API Keys → Create API Key (a Universal API key); docs: [API introduction](https://concentrate.ai/docs/api-reference/introduction). BYOK only — the key stays in the local secret store. |\n| `modelstudio-token-plan`, `modelstudio-token-plan-anthropic`, `modelstudio-coding-plan`, `modelstudio-coding-plan-anthropic` | [Alibaba Cloud Model Studio (Bailian console)](https://bailian.console.aliyun.com/) — create or copy a Model Studio API key. |\n| `codewhale` | [Codewhale account settings](https://app.codewhale.net/settings?section=api) — create an API key with the `models:infer` scope, or run `codewhale account api-keys create --name --use`. |\n| `custom` | Set the named provider's `base_url` and `api_key_env` or `api_key`; no canonical vendor credential page exists. |\n\nFor Kimi, the official [quickstart](https://platform.kimi.ai/docs/overview)\ndirects users to sign in, open **API Keys**, create and copy a key, and keep it\nsecret. Codewhale links straight to that console and accepts the copied key.\nIt never probes or impersonates `kimi_cli`/`kimi_code_cli`; first-class Kimi\nOAuth remains blocked on a vendor-registered Codewhale identity.\n\n### Subscription sign-in accounts (ChatGPT, xAI)\n\nCodewhale keeps one sign-in of its own per subscription provider. It is\nseparate from the browser, the ChatGPT or Grok apps, and the Codex or Grok\nCLIs, so those can be signed in to a different account. A successful login\nreplaces the previous owned grant; there is no picker for multiple saved\nChatGPT accounts.\n\n- **See which account is signed in.** `codewhale auth status --provider\n openai-codex` (or `--provider xai`) and `codewhale auth list` show an account\n label when the ID token contains an email. ChatGPT plan and workspace\n details appear only when those claims are present; a workspace label uses\n the first characters of its account ID. The label is display metadata, not\n proof of plan entitlement. A valid sign-in may have no email label. Status\n reads local credential state without contacting the issuer: an expired\n access token with a stored refresh token remains structurally usable, while\n missing or invalid storage, or an expired token without a refresh token,\n is reported unusable. The provider picker shows the label of the sign-in\n the route would use (for xAI this includes a consented Grok CLI import).\n Successful login reports the account when known and whether it replaced\n an earlier sign-in, in the TUI's selected language. No token is printed.\n- **Reauthorize ChatGPT.** Run `/auth chatgpt` inside Codewhale to update the\n running session, or `codewhale auth chatgpt` from a shell and restart open\n Codewhale sessions. Ordinary login reuses the selected account/workspace's\n issued client ID and checks that the returned account is the same. The\n browser opens with `prompt=login`; `CODEWHALE_CHATGPT_OAUTH_NO_PROMPT=1`\n omits that parameter if the issuer refuses it.\n- **Replace the ChatGPT account or workspace.** From a shell, run\n `CODEWHALE_CHATGPT_NEW_ACCOUNT=1 codewhale auth chatgpt`, then refresh its\n model catalog and restart open Codewhale sessions. If the browser holds the\n wrong account, sign out there or open the printed URL in a private window.\n Only a fully validated new grant replaces the active owned sign-in.\n- **Switch xAI accounts.** Run `/auth xai-device` inside Codewhale, or\n `codewhale auth xai-device` from a shell and restart open sessions. The\n device page approves with whichever account the browser holds; sign out\n there or use a private window to approve another account. The login names\n the account it replaced, or says it is the same account as before.\n- **Usage limits.** ChatGPT plan requests can fail with\n `subscription_sharing_usage_limit_exceeded` or\n `subscription_sharing_usage_unavailable`. These errors, and subscription\n quota errors from other providers, name the account that made the request\n when its label is known and offer recovery guidance. Codewhale does not\n retry these terminal errors or silently choose another billing route. An\n xAI route set to OAuth that fell back to an API key gets no sign-in\n guidance, since no sign-in was used.\n- **ChatGPT credential authority.** The official ChatGPT plan route uses\n only its selected, verified Codewhale-owned grant.\n `OPENAI_CODEX_ACCESS_TOKEN`, `CODEX_ACCESS_TOKEN`, and consented Codex CLI\n tokens cannot override or authorize this route.\n\n### External CLI credential consent\n\nCredential files owned by another CLI are disabled by default. Without an\nexplicit grant, provider discovery, setup, routing, `auth status`, and doctor\ndo not stat, read, refresh, contact an identity provider for, or rewrite Codex,\nGrok, Kimi, or future external credential files.\n\nCodewhale currently supports exact-path, provider-scoped **read-only** grants\nfor the Codex CLI and Grok CLI. Codex grants remain available for legacy\ncredential inspection only; they cannot authorize the official ChatGPT plan\nroute. Use `codewhale auth chatgpt` for that route.\n\n```bash\n# Legacy Codex credential inspection; does not authorize ChatGPT plan requests.\ncodex login\ncodewhale auth external-consent --provider openai-codex --mode read-only\n\ngrok login\ncodewhale auth external-consent --provider xai --mode read-only\n\ncodewhale auth status --provider openai-codex\ncodewhale auth external-revoke --provider openai-codex\n```\n\nPass `--path /absolute/path/to/auth.json` when the external CLI uses a custom\nlocation. Consent persists the provider, external owner, exact absolute path,\nand consent schema version. Later environment-variable changes do not redirect\nthat authority to a different file. Read-only grants never refresh, contact an\nidentity/discovery service, or rewrite the external file. Supported routes such\nas xAI may use the external token after explicit selection. The official ChatGPT\nplan route ignores imported Codex tokens and requires its own verified grant.\nAn expired external token fails with login guidance. Doctor reports structural\nconsent/config state without\nopening credential files and is always non-mutating.\n\n`managed` is reserved for a future provider-specific preservation adapter.\nv0.9.1 rejects it before file or network I/O because no reviewed adapter can\nyet preserve every unknown external schema field safely. Codewhale-started xAI\ndevice login instead atomically activates a Codewhale-owned generation named\n`$CODEWHALE_HOME/credentials/xai-auth-.json`, stores only that\nvalidated basename in config, and revokes any Grok-file grant. Superseded\ngenerations are cleaned only after the new config pointer commits.\nKimi remains API-key-only; external consent for Kimi is rejected.\n\nThe official DeepSeek Harness (`dsh`) is a third read-only credential owner:\n`codewhale auth external-consent --provider deepseek --mode read-only` grants\nexact-path read access to `DEEPSEEK_API_KEY` in `$DSH_HOME/.credentials.yaml`\n(or `~/.dsh/.credentials.yaml`), which Codewhale never writes, refreshes, or\nloads into the process environment. This is separate from the DSH *harness*\nintegration (`codewhale integrations dsh …`, see\n[INTEGRATIONS_DSH.md](INTEGRATIONS_DSH.md)), which never touches credentials\nin either direction: it pins Codewhale's route identity into a `--patch`\noverlay and lets DSH resolve its own keys.\n\n## Shipped Providers\n\n| Provider ID | TOML table | Auth env | Base URL env and default | Default or static models | Notes |\n| --- | --- | --- | --- | --- | --- |\n| `deepseek` | `[providers.deepseek]` | `DEEPSEEK_API_KEY` | `CODEWHALE_BASE_URL` / `DEEPSEEK_BASE_URL`; default `https://api.deepseek.com/beta` | `deepseek-flash` (shipped default; V4.1 Flash, unversioned id), `deepseek-v4-pro`, `deepseek-v4-flash`, experimental `deepseek-v4-flash-vision-exp`; vision aliases `flash-vision`, `deepseek-v4flashvisionexp`; compatibility aliases `deepseek-chat`, `deepseek-reasoner` | First-class default. The live Pro backend is labeled `DeepSeek-V4-Pro-0813`; the callable API ID remains `deepseek-v4-pro`. Beta URL enables strict tool mode, chat prefix completion, and FIM completion. The documented V4 routes can use provider-native web search through a separate bounded Responses request; compatible custom endpoints do not inherit that capability. Set `https://api.deepseek.com` or `/v1` explicitly to opt out of beta-only features. The shipped default `deepseek-flash` speaks the Responses API (DeepSeek's documented path for Codex-style integration, since the 2026-07-31 Flash production update); the Chat-only controls (the `thinking` toggle and strict-tool `/beta` routing) apply to Chat Completions routes, and `deepseek-v4-pro` stays on Chat Completions until its announced Responses rollout. Reasoning effort follows DeepSeek's documented requested-to-actual mapping: `minimal`/`low` land on `low`, `medium`/`xhigh` on `high`, and `max`/`ultra` on `max`; `off` disables thinking (`thinking: {\"type\":\"disabled\"}` on Chat, `reasoning.effort: \"none\"` on Responses). The experimental vision ID was observed in the authenticated `/models` roster on 2026-08-21 and is advertised as image-input capable on the direct Chat Completions route only. Its limits, reasoning, and tool-call flags provisionally inherit Flash; pricing remains unknown, and no funded image round trip was made during this release work. |\n| `deepseek-anthropic` | `[providers.deepseek_anthropic]` | `DEEPSEEK_API_KEY` | `DEEPSEEK_ANTHROPIC_BASE_URL`; default `https://api.deepseek.com/anthropic` | `deepseek-v4-pro`, `deepseek-v4-flash`; compatibility aliases `deepseek-chat`, `deepseek-reasoner` | Opt-in DeepSeek route for the Anthropic Messages wire protocol. Uses `/v1/messages`, `x-api-key`, and `anthropic-version: 2023-06-01`. Keep `provider = \"deepseek\"` for the default Chat Completions path. |\n| `nvidia-nim` | `[providers.nvidia_nim]` | `NVIDIA_API_KEY`, `NVIDIA_NIM_API_KEY` | `NVIDIA_NIM_BASE_URL`, `NIM_BASE_URL`, `NVIDIA_BASE_URL`; default `https://integrate.api.nvidia.com/v1` | `deepseek-ai/deepseek-v4-pro`, `deepseek-ai/deepseek-v4-flash` | Hosted DeepSeek V4 through NVIDIA NIM. `NVIDIA_NIM_MODEL` is accepted by the TUI config path. |\n| `openai` | `[providers.openai]` | `OPENAI_API_KEY` | `OPENAI_BASE_URL`; default `https://api.openai.com/v1` | `gpt-5.6` (default), `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna` | Generic OpenAI-compatible route whose built-in endpoint and fallback catalog are native to OpenAI. The [GPT-5.6 family](https://developers.openai.com/api/docs/models/gpt-5.6-sol) uses OpenAI's documented 1.05M context, 128K max output, and reasoning levels. Custom gateways remain free to select an explicit gateway-owned model. `OPENAI_MODEL` is accepted. |\n| `atlascloud` | `[providers.atlascloud]` | `ATLASCLOUD_API_KEY` | `ATLASCLOUD_BASE_URL`; default `https://api.atlascloud.ai/v1` | Default `deepseek-ai/deepseek-v4-flash`; explicit `vendor/model-id` values pass through when AtlasCloud is selected | OpenAI-compatible hosted route. `ATLASCLOUD_MODEL` is accepted by the TUI config path, the static `ModelRegistry` keeps DeepSeek V4 fallback rows, and provider-hinted CLI model IDs are sent to AtlasCloud exactly as requested. Use Atlas Cloud's own catalog or Coding Plan page for the current provider-owned model list and pricing. |\n| `wanjie-ark` | `[providers.wanjie_ark]` | `WANJIE_ARK_API_KEY`, `WANJIE_API_KEY`, `WANJIE_MAAS_API_KEY` | `WANJIE_ARK_BASE_URL`, `WANJIE_BASE_URL`, `WANJIE_MAAS_BASE_URL`; default `https://maas-openapi.wanjiedata.com/api/v1` | `deepseek-reasoner` | OpenAI-compatible hosted route. `WANJIE_ARK_MODEL`, `WANJIE_MODEL`, and `WANJIE_MAAS_MODEL` are accepted. |\n| `volcengine` | `[providers.volcengine]` | `VOLCENGINE_API_KEY`, `VOLCENGINE_ARK_API_KEY`, `ARK_API_KEY` | `VOLCENGINE_BASE_URL`, `VOLCENGINE_ARK_BASE_URL`, `ARK_BASE_URL`; default `https://ark.cn-beijing.volces.com/api/coding/v3` | `DeepSeek-V4-Pro`, `DeepSeek-V4-Flash` | Volcengine/Volcano Engine Ark OpenAI-compatible coding endpoint. `VOLCENGINE_MODEL` and `VOLCENGINE_ARK_MODEL` are accepted. |\n| `openrouter` | `[providers.openrouter]` | `OPENROUTER_API_KEY` | `OPENROUTER_BASE_URL`; default `https://openrouter.ai/api/v1` | `deepseek/deepseek-v4-pro`, `deepseek/deepseek-v4-flash`; recent large IDs include `arcee-ai/trinity-large-thinking`, `minimax/minimax-m3`, `xiaomi/mimo-v2.5-pro`, `qwen/qwen3.6-flash`, `qwen/qwen3.6-35b-a3b`, `qwen/qwen3.6-max-preview`, `qwen/qwen3.6-27b`, `qwen/qwen3.6-plus`, `google/gemma-4-31b-it`, `z-ai/glm-5.1`, `z-ai/glm-5.2`, `moonshotai/kimi-k2.7-code`, `moonshotai/kimi-k2.6` | Additive open-model routing layer. It does not replace DeepSeek; it lets users route supported model IDs through OpenRouter when they choose it. |\n| `orcarouter` | `[providers.orcarouter]` | `ORCAROUTER_API_KEY` | `ORCAROUTER_BASE_URL`; default `https://api.orcarouter.ai/v1` | `deepseek/deepseek-v4-pro`, `deepseek/deepseek-v4-flash`; router alias `orcarouter/auto`; recent large IDs mirror the OpenRouter namespaced catalog | [OrcaRouter](https://www.orcarouter.ai) OpenAI-compatible aggregation gateway. Shares the namespaced `vendor/model` wire-model format and DeepSeek model set with OpenRouter, so the OpenRouter base-URL and model-normalization rules apply. `ORCAROUTER_MODEL` is accepted. Provider aliases: `orcarouter`, `orca_router`, `orca`. |\n| `xiaomi-mimo` | `[providers.xiaomi_mimo]` | `XIAOMI_MIMO_TOKEN_PLAN_API_KEY`, `MIMO_TOKEN_PLAN_API_KEY`, `XIAOMI_MIMO_API_KEY`, `XIAOMI_API_KEY`, `MIMO_API_KEY` | `XIAOMI_MIMO_BASE_URL`, `MIMO_BASE_URL`, `XIAOMI_MIMO_MODE`, `MIMO_MODE`; default `https://token-plan-sgp.xiaomimimo.com/v1` | Chat: `mimo-v2.5-pro`, `mimo-v2.5-pro-ultraspeed`, `mimo-v2.5`; speech/TTS: `mimo-v2.5-tts`, `mimo-v2.5-tts-voicedesign`, `mimo-v2.5-tts-voiceclone`, `mimo-v2-tts` | Xiaomi MiMo OpenAI-compatible chat completions route. `mimo-v2.5-pro` and `mimo-v2.5` can use the documented provider-native web-search plugin; ultraspeed, speech/TTS, and custom-compatible routes do not inherit it. Token Plan keys (`tp-...`) use `api-key` auth and the token-plan endpoint by default; pay-as-you-go mode uses standard API keys (`sk-...`) and `https://api.xiaomimimo.com/v1`. It sends `max_completion_tokens` and uses MiMo's `thinking` field for reasoning control. Token Plan cost/usage is credit/quota based; Codewhale shows it as unknown until Xiaomi exposes a reliable balance API. `codewhale speech` / `tts` uses the TTS models. |\n| `novita` | `[providers.novita]` | `NOVITA_API_KEY` | `NOVITA_BASE_URL`; default `https://api.novita.ai/openai/v1` | `deepseek/deepseek-v4-pro`, `deepseek/deepseek-v4-flash` | OpenAI-compatible hosted route for DeepSeek model IDs. Use config or `CODEWHALE_MODEL` / `DEEPSEEK_MODEL` for model overrides. |\n| `fireworks` | `[providers.fireworks]` | `FIREWORKS_API_KEY` | `FIREWORKS_BASE_URL`; default `https://api.fireworks.ai/inference/v1` | `accounts/fireworks/models/deepseek-v4-pro` | OpenAI-compatible hosted route. Use config or `CODEWHALE_MODEL` / `DEEPSEEK_MODEL` for model overrides. |\n| `siliconflow` | `[providers.siliconflow]` | `SILICONFLOW_API_KEY` | `SILICONFLOW_BASE_URL`; default `https://api.siliconflow.com/v1` | `deepseek-ai/DeepSeek-V4-Pro`, `deepseek-ai/DeepSeek-V4-Flash` | OpenAI-compatible hosted route. Official docs use the `.com` endpoint. `SILICONFLOW_MODEL` is accepted. Reasoning aliases `deepseek-reasoner` and `deepseek-r1` map to Pro; `deepseek-chat` and `deepseek-v3` map to Flash. |\n| `siliconflow-CN` | `[providers.siliconflow_cn]` | `SILICONFLOW_API_KEY` | `SILICONFLOW_BASE_URL`; default `https://api.siliconflow.cn/v1` | Uses the SiliconFlow model set | China regional SiliconFlow route. Falls back to `[providers.siliconflow]` for api_key / base_url / model when unset. Select it with `provider = \"siliconflow-CN\"` or `CODEWHALE_PROVIDER=siliconflow-CN`. |\n| `arcee` | `[providers.arcee]` | `ARCEE_API_KEY` | `ARCEE_BASE_URL`; default `https://api.arcee.ai/api/v1` | `trinity-large-thinking`, `trinity-large-preview` | Arcee AI direct OpenAI-compatible route, tracked as 256K-context BF16 serving. `ARCEE_MODEL` is accepted. OpenRouter's `arcee-ai/trinity-large-thinking` remains the OpenRouter namespaced model ID; direct Arcee uses the bare `trinity-large-thinking` ID. |\n| `moonshot` | `[providers.moonshot]` | `MOONSHOT_API_KEY`, `KIMI_API_KEY` | `MOONSHOT_BASE_URL`, `KIMI_BASE_URL`; default `https://api.moonshot.ai/v1` | Direct Moonshot: `kimi-k3`, `kimi-k2.7-code`, `kimi-k2.7-code-highspeed`, `kimi-k2.6`; Kimi Code membership: `k3`, `kimi-for-coding`, `kimi-for-coding-highspeed` at `https://api.kimi.com/coding/v1` | Moonshot/Kimi route. Exact direct `kimi-k3` routes use the documented Formula web-search tool/fiber loop; direct `kimi-k2.6` retains the built-in `$web_search` contract, and exact Kimi Code membership routes use their structured `/search` service. Adjacent paths, K2.7 direct models, and cross-product model IDs do not inherit native search. `kimi` and `kimi-k2` aliases select `kimi-k2.7-code`; `MOONSHOT_MODEL`, `KIMI_MODEL_NAME`, and `KIMI_MODEL` are accepted. Kimi thinking streams through `reasoning_content`; Codewhale keeps it in Thinking cells and replays it for thinking/tool-call continuity. For direct K3, use exact `base_url = \"https://api.moonshot.ai/v1\"` and `model = \"kimi-k3\"`; it is always-thinking and receives top-level `reasoning_effort = \"low\" | \"high\" | \"max\"` (`off` normalizes to `low`), uses only `max_completion_tokens`, and omits `temperature`/`top_p` per the [K3 quickstart](https://platform.kimi.ai/docs/guide/kimi-k3-quickstart). For Kimi Code K3, use a key from the [Kimi Code console](https://www.kimi.com/code/console), exact `base_url = \"https://api.kimi.com/coding/v1\"`, and bare `model = \"k3\"`; `off` becomes enabled `low`, while normal dispatched `auto` selects and sends a concrete Codewhale tier. Only an omitted reasoning setting leaves the provider default in control. That membership route defaults safely to 262,144 context tokens; the [Kimi Code model-tier table](https://www.kimi.com/code/docs/en/kimi-code/models.html) grants Allegretto and higher plans up to 1M, which those plans may express as `context_window = 1048576`. `k3[1m]` is Claude Code-only and Codewhale rejects it. `kimi-for-coding` remains the valid K2.7 membership route, and `kimi-for-coding-highspeed` is its own high-speed roster entry (262,144 context); membership ids are rejected on the direct platform endpoint, and `kimi-k3` stays rejected on the membership endpoint. Billing is decided by the endpoint the route resolves to, judged once against the two exact product endpoints: direct Moonshot (`https://api.moonshot.ai/v1` or the default) bills metered with dollar estimates, the exact Kimi Code membership endpoint bills as Kimi Code quota and never shows dollar estimates, and anything else — a gateway host, a neighboring Kimi-hosted path — reports `cost: unknown` rather than borrowing either product. An imported Kimi Code token with no `base_url` in its table still resolves to the membership endpoint, so it bills as Kimi Code quota and never accrues dollars. A completed turn, parent or sub-agent, is billed from the immutable endpoint receipt its own client was built with, never from a later config re-read: `MOONSHOT_BASE_URL`/`KIMI_BASE_URL` are merged into the *active* provider's table only, and an in-turn provider switch can move the ambient config off the route that actually ran. Legacy `auth_mode = \"kimi_oauth\"` fails to API-key guidance without probing Kimi CLI files. Codewhale does not impersonate `kimi_cli` or `kimi_code_cli`. **China-region keys:** contributor field evidence (@vFONGv, PR #5229, verified on Windows 10) reports that a China-region Moonshot key must be paired with `base_url = \"https://api.moonshot.cn/v1\"`; left on the default international host (`https://api.moonshot.ai/v1`) it fails authentication. We have no China-region key to verify this ourselves, so it is recorded as a user report rather than a tested route. Note also that editing `base_url` alone does not take effect until `codewhale auth set` is re-run for that provider. |\n| `google` | `[providers.google]` | `GOOGLE_API_KEY`, `GEMINI_API_KEY` | `GOOGLE_BASE_URL`, `GEMINI_BASE_URL`; default `https://generativelanguage.googleapis.com/v1beta/openai/` | `gemini-3.1-pro-preview` (default); `/model` also lists `gemini-3-pro-preview`, `gemini-3.7-flash`, `gemini-3.6-flash`, `gemini-3.5-flash`, `gemini-3.5-flash-lite`, `gemini-2.5-pro`, `gemini-2.5-flash` | Google Gemini as its own backend on the official OpenAI-compatible Chat Completions route. Thinking models capture `extra_content.google.thought_signature` on tool calls and replay it with the assistant tool-call messages; replaying a tool call whose signature was not captured fails closed with an actionable error instead of letting the tool loop break. `gemini-2.5-flash-lite` ships thinking off and degrades with a warning instead. Reasoning effort maps onto the documented `google.thinking_config.thinking_level` (`low`/`high`). The dialect binds to the exact official base URL: a `google` row pointed at another gateway gets plain OpenAI semantics and no signature requirements. Codewhale never reads Google OAuth files; only an AI Studio API key is used. Not live-tested against the real endpoint in this environment. |\n| `zai` | `[providers.zai]` | `ZAI_API_KEY`, `Z_AI_API_KEY`, `ZHIPU_API_KEY`, `GLM_API_KEY` | `ZAI_BASE_URL`, `Z_AI_BASE_URL`; default `https://api.z.ai/api/coding/paas/v4`; general APIs `https://api.z.ai/api/paas/v4` and `https://open.bigmodel.cn/api/paas/v4` | `GLM-5.3` default; `/model` also lists `GLM-5.3-Flash`, `GLM-5.2`, `GLM-5.1`, and `GLM-5-Turbo` | Z.AI GLM Coding Plan route. All three first-party Chat routes (both api.z.ai products and BigModel's general platform endpoint) share one request dialect, so reasoning controls — the GLM-5.2 thinking toggle, tiered effort, and the forced-thinking GLM-5.3 rewrite that sends `off` as `enabled` + `reasoning_effort: \"low\"` — apply on BigModel too; neighboring paths such as `/preview` stay fail-closed. The two general API products expose structured provider-native web search (`search-prime` globally, `search_std` in China); Coding Plan and compatible custom endpoints do not inherit it. `GLM-5.3` is the default and a first-class picker row (`model = \"GLM-5.3\"` or `ZAI_MODEL=GLM-5.3`); `GLM-5.3-Flash` is the 1M multimodal fast sibling (`model = \"GLM-5.3-Flash\"`). An explicit `GLM-5.2` selection keeps its own id. Limits and reasoning options for 5.3 are inherited from `GLM-5.2` until Z.ai publishes distinct 5.3 metadata; 5.3 carries no price. Flash ships the published $0.15/$0.50 list. A live call can still 429 with entitlement code 1311 on accounts that are not provisioned for 5.3. |\n| `stepfun` | `[providers.stepfun]` | `STEPFUN_API_KEY`, `STEP_API_KEY` | `STEPFUN_BASE_URL`, `STEP_BASE_URL`; default `https://api.stepfun.ai/v1`; Coding Plan endpoint `https://api.stepfun.ai/step_plan/v1` | `step-3.7-flash` | StepFun / StepFlash direct OpenAI-compatible route. `/provider` setup asks which billing route the key belongs to — pay-as-you-go or Step Plan — validates the key against the chosen endpoint, and writes the answer to `[providers.stepfun].base_url` only. A base URL that is neither recognized route is left alone and the question is skipped. You can also set `[providers.stepfun].base_url` or `STEP_BASE_URL` to the Coding Plan URL by hand. Offline accounting labels recognized routes as `stepfun-payg` or `stepfun-plan` without persisting the raw endpoint, and only the standard PAYG route receives token pricing. `STEPFUN_MODEL` and `STEP_MODEL` are accepted. |\n| `minimax` | `[providers.minimax]` | `MINIMAX_API_KEY` | `MINIMAX_BASE_URL`; default `https://api.minimax.io/v1`; China `https://api.minimaxi.com/v1` | `MiniMax-M3`, `MiniMax-M2.7`, `MiniMax-M2.7-highspeed`, `MiniMax-M2.5`, `MiniMax-M2.5-highspeed`, `MiniMax-M2.1`, `MiniMax-M2.1-highspeed`, `MiniMax-M2` | MiniMax direct OpenAI-compatible route. Codewhale sends `reasoning_split = true` so MiniMax thinking arrives separately from answer text. Both MiniMax dialects sell pay-as-you-go and Token Plan over the same endpoints and the same key, so billing is classified from the credential *product*, never from the endpoint or from a default. `mode = \"token-plan\"` in `[providers.minimax]`/`[providers.minimax_anthropic]`, or a Token Plan key shaped `sk-cp…`, bills as MiniMax Token Plan quota with no dollar estimates; an explicit pay-as-you-go mode (`pay-as-you-go`/`payg`/`metered`) wins over key shape. The key's product prefix is only visible when the key is in config, bound by `api_key_env`, or exported as `MINIMAX_API_KEY` on an official endpoint — a key saved through `codewhale auth set` (secret store / OS keyring) is deliberately not read to classify billing. With no explicit mode and no visible product marker the route reports `cost: unknown` rather than assuming pay-as-you-go, so a Token Plan account is never charged invented dollars. Custom/gateway endpoints also fail closed with `cost: unknown`. Official M3 input modalities are text, image, and video; M2.7 is text-only. |\n| `minimax-anthropic` | `[providers.minimax_anthropic]` | `MINIMAX_API_KEY` | `MINIMAX_ANTHROPIC_BASE_URL`; default `https://api.minimax.io/anthropic`; China `https://api.minimaxi.com/anthropic` | `MiniMax-M3`, `MiniMax-M2.7` | MiniMax direct Anthropic-compatible Messages route. Keep the `/anthropic` suffix because Codewhale appends `/v1/messages`; the route uses `x-api-key`. M3 supports adaptive or disabled thinking. M2.7 always keeps thinking enabled. |\n| `sglang` | `[providers.sglang]` | Optional `SGLANG_API_KEY` | `SGLANG_BASE_URL`; default `http://localhost:30000/v1` | `deepseek-ai/DeepSeek-V4-Pro`, `deepseek-ai/DeepSeek-V4-Flash` | Self-hosted OpenAI-compatible route. Localhost deployments commonly omit auth. `SGLANG_MODEL` is accepted. |\n| `vllm` | `[providers.vllm]` | Optional `VLLM_API_KEY` | `VLLM_BASE_URL`; default `http://localhost:8000/v1` | `deepseek-ai/DeepSeek-V4-Pro`, `deepseek-ai/DeepSeek-V4-Flash` | Self-hosted vLLM OpenAI-compatible route. Localhost deployments commonly omit auth. `VLLM_MODEL` is accepted. |\n| `ollama` | `[providers.ollama]` | Local optional `OLLAMA_API_KEY` | `OLLAMA_BASE_URL`; default `http://localhost:11434/v1` | live tag from the local catalog; pre-refresh placeholder `unknown`; provider-hinted custom tags pass through | Local Ollama is keyless by default. `OLLAMA_MODEL` is accepted. The header must not paint a hosted id the local daemon did not list. |\n| `ollama-cloud` | `[providers.ollama_cloud]` | `OLLAMA_CLOUD_API_KEY`, then `OLLAMA_API_KEY` | `OLLAMA_CLOUD_BASE_URL`; default `https://ollama.com/v1` | `gpt-oss:120b`; arbitrary provider-owned IDs pass through | Hosted OpenAI-compatible `/v1/chat/completions` route. Save credentials under `ollama-cloud`; the exact released `ollama` + Cloud URL tuple has bounded read-only in-memory compatibility with its legacy table and secret slot. `OLLAMA_CLOUD_MODEL` is accepted. |\n| `huggingface` | `[providers.huggingface]` | `HUGGINGFACE_API_KEY`, `HF_TOKEN` | `HUGGINGFACE_BASE_URL`, `HF_BASE_URL`; default `https://router.huggingface.co/v1` | `deepseek-ai/DeepSeek-V4-Pro`, `deepseek-ai/DeepSeek-V4-Flash` | Hugging Face Inference Providers OpenAI-compatible router route. Accepted aliases: `huggingface`, `hugging-face`, `hugging_face`, `hf`. Org-prefixed model IDs pass through. `HUGGINGFACE_MODEL` and `HF_MODEL` are accepted. Hub browsing/export are separate future features. |\n| `modelscope` | `[providers.modelscope]` | `MODELSCOPE_API_KEY` | `MODELSCOPE_BASE_URL`; default `https://api-inference.modelscope.cn/v1` | `Qwen/Qwen3.5-397B-A17B` (default), `Qwen/Qwen3.5-122B-A10B`, `Qwen/Qwen3.5-27B`, `Qwen/Qwen3.5-35B-A3B`, `Qwen/Qwen3.8-27B`, `Qwen/Qwen3.8-Flash-Next`, `deepseek-ai/DeepSeek-V4-Pro`, `deepseek-ai/DeepSeek-V4-Pro-0813`, `deepseek-ai/DeepSeek-V4.1-Flash`, `ZhipuAI/GLM-4.7-Flash`, `ZhipuAI/GLM-5.2` | ModelScope OpenAI-compatible inference route. Org-prefixed model IDs pass through. `MODELSCOPE_MODEL` is accepted. |\n| `deepinfra` | `[providers.deepinfra]` | `DEEPINFRA_API_KEY`, `DEEPINFRA_TOKEN` | `DEEPINFRA_BASE_URL`; default `https://api.deepinfra.com/v1/openai` | `deepseek-ai/DeepSeek-V4-Pro`, `deepseek-ai/DeepSeek-V4-Flash` | DeepInfra OpenAI-compatible route. Drop-in replacement for OpenAI SDK. |\n| `together` | `[providers.together]` | `TOGETHER_API_KEY` | `TOGETHER_BASE_URL`; default `https://api.together.xyz/v1` | `deepseek-ai/DeepSeek-V4-Pro`, `deepseek-ai/DeepSeek-V4-Flash`, `thinkingmachines/inkling` | Together AI OpenAI-compatible route. `TOGETHER_MODEL` is accepted. Model aliases `deepseek-v4-pro` and `deepseek-v4-flash` normalize to Together's org-prefixed IDs; `inkling` and `together-inkling` normalize to Together's published lowercase Inkling wire ID. Inkling uses the exact `none`/`minimal`/`low`/`medium`/`high`/`max` reasoning vocabulary from Thinking Machines' [official model repository](https://huggingface.co/thinkingmachines/Inkling). Together's [launch post](https://www.together.ai/blog/together-ai-brings-thinking-machines-labs-new-model-inkling-on-day-0) currently says Inkling is live with 1M context, while its [model detail page](https://www.together.ai/models/inkling) says coming soon with 256K context and publishes no price. Until Together's active `/models` endpoint and the Models.dev catalog resolve that conflict, Inkling is not seeded into Codewhale's offline picker and no route-specific context or cost is inferred. |\n| `qianfan` | `[providers.qianfan]` | `QIANFAN_API_KEY`, `BAIDU_QIANFAN_API_KEY` | `QIANFAN_BASE_URL`, `BAIDU_QIANFAN_BASE_URL`; default `https://api.baiduqianfan.ai/v1` | `ernie-4.0-turbo-8k`; provider-scoped custom Qianfan service/model IDs pass through | Baidu Qianfan OpenAI-compatible route. Requests use Bearer auth and Chat Completions payloads. `QIANFAN_MODEL` and `BAIDU_QIANFAN_MODEL` are accepted; aliases `baidu-qianfan`, `baidu_qianfan`, and `baidu` resolve to this provider. Tool/function calling is model-scoped in Qianfan docs, so Codewhale preserves the selected wire model and leaves live capability proof to follow-up route/capability work. |\n| `openai-codex` | `[providers.openai_codex]` | Official Sign in with ChatGPT (`codewhale auth chatgpt` / `/provider setup openai-codex`) | Official `https://api.openai.com/v1` | Selected account catalog; configured model IDs remain explicit selections | **Experimental.** Public Responses endpoint (`/v1/responses`) with a validated `chatgpt.tokens.use.direct` grant. Dynamic OSS registration issues a client ID for the selected account/workspace; Codewhale protects and renews its own tokens. The account catalog supplies selectable models; public model lists and legacy Codex tokens do not establish plan permission. No silent billing fallback. See [Sign in with ChatGPT](#sign-in-with-chatgpt) for setup, usage limits, and preview boundaries. |\n| `anthropic` | `[providers.anthropic]` | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL`; default `https://api.anthropic.com` | `claude-opus-4-8`, `claude-sonnet-4-6` (default), `claude-haiku-4-5` | Native Anthropic Messages API route (`/v1/messages`, `x-api-key` + `anthropic-version: 2023-06-01`) — not OpenAI-compatible. Prompt caching via `cache_control` breakpoints, adaptive thinking + `output_config.effort`, signed thinking blocks replayed verbatim, cache telemetry normalized per #2961. `ANTHROPIC_MODEL` is accepted. |\n| `openmodel` | `[providers.openmodel]` | `OPENMODEL_API_KEY` | `OPENMODEL_BASE_URL`; default `https://api.openmodel.ai` | `deepseek-v4-flash`; provider-scoped custom model IDs pass through | OpenModel Anthropic-compatible Messages route. Uses `/v1/messages`, Bearer auth, and `anthropic-version: 2023-06-01`; OpenModel selects DeepSeek, DashScope, Xiaomi, Claude, and other routes by model id. `OPENMODEL_MODEL` is accepted. |\n| `sakana` | `[providers.sakana]` | `FUGU_API_KEY`, `SAKANA_API_KEY` | `SAKANA_BASE_URL`; default `https://api.sakana.ai/v1` | `fugu` (default), `fugu-ultra-20260615` | Sakana AI Fugu OpenAI-compatible route. Standard Chat Completions wire protocol; streaming supported. `fugu-ultra-20260615` is the heavy/reasoning variant. Env var aliases: `FUGU_API_KEY` (primary), `SAKANA_API_KEY`; provider aliases: `sakana-ai`, `sakana_ai`, `fugu`. |\n| `longcat` | `[providers.longcat]` | `LONGCAT_API_KEY` | `LONGCAT_BASE_URL`; default `https://api.longcat.chat/openai/v1` | `LongCat-2.0` (default) | Meituan LongCat curated model gateway. OpenAI-compatible Chat Completions wire protocol. Sign up at https://longcat.chat/platform for an API key. Provider aliases: `long-cat`, `meituan-longcat`, `meituan`. |\n| `opencode-go` | `[providers.opencode_go]` | `OPENCODE_GO_API_KEY` | `OPENCODE_GO_BASE_URL`; default `https://opencode.ai/zen/go/v1` | `deepseek-v4-pro` (default), `grok-4.5`, `glm-5.2`, `glm-5.1`, `kimi-k3`, `kimi-k2.7-code`, `kimi-k2.6`, `deepseek-v4-flash`, `mimo-v2.5`, `mimo-v2.5-pro` | [OpenCode Go](https://opencode.ai/docs/go/) subscription route using OpenAI-compatible Chat Completions. `OPENCODE_GO_MODEL` is accepted. Codewhale uses bare wire IDs; familiar `opencode-go/` input aliases normalize to the bare ID. Go models documented only on the Anthropic `/messages` endpoint are deliberately not advertised by this route until Codewhale supports per-model wire selection. Billing surfaces show the Go allowance instead of token-price estimates. |\n| `opencode-zen` | `[providers.opencode_zen]` | `OPENCODE_ZEN_API_KEY`, fallback `OPENCODE_API_KEY` | `OPENCODE_ZEN_BASE_URL`; default `https://opencode.ai/zen/v1` | `gpt-5.6` (default); current GPT, Claude, Qwen, DeepSeek, MiniMax, GLM, Kimi, Grok, Muse Spark, and free-model IDs | [OpenCode Zen](https://opencode.ai/docs/zen/) model-aware gateway. `OPENCODE_ZEN_MODEL` is accepted, and official `opencode/` selectors normalize to bare wire IDs. Each model's wire comes from the curated snapshot, then from the AI SDK package its [Models.dev](https://models.dev) row names: GPT, Grok, and Muse Spark rows use `/responses`; Claude and most Qwen rows use `/messages`; DeepSeek, MiniMax, GLM, Kimi, `qwen3.8-max`, and the free rows use `/chat/completions`. Responses and Chat Completions authenticate with Bearer `Authorization`, while Anthropic Messages uses `x-api-key`; none of these routes use ChatGPT/Codex OAuth guidance or headers. Gemini fails closed because its model-specific Google wire protocol is not implemented; Models.dev rows marked `deprecated` and models no loaded catalog lists also fail closed. See [OpenCode Zen protocol catalog](#opencode-zen-protocol-catalog). |\n| `meta` | `[providers.meta]` | `META_MODEL_API_KEY`, `MODEL_API_KEY` | `META_MODEL_API_BASE_URL`, `MODEL_API_BASE_URL`; default `https://api.meta.ai/v1` | `muse-spark-1.2` (default) | [Meta Model API](https://developer.meta.com/ai/resources/blog/build-with-muse-spark/) public-preview route using OpenAI-compatible Chat Completions. Muse Spark 1.2 keeps its wire ID, tool support, 1M context, 32K output metadata, and `none` through `xhigh` reasoning effort. `META_MODEL_API_MODEL` and `MODEL_API_MODEL` are accepted. Provider aliases: `meta-ai`, `meta_model_api`, `muse`, `muse-spark`. |\n| `telecomjs` | `[providers.telecomjs]` | `TELECOMJS_API_KEY` | `TELECOMJS_BASE_URL`; default `https://aigw.telecomjs.com/v1` | `deepseek-v4-pro` conservative fallback; authenticated `/models` rows when a key is configured | TelecomJS TokenHub OpenAI-compatible Chat Completions route. Live catalogs are isolated by provider and key fingerprint, stale rows survive transient refresh failures, and unsupported reasoning request fields are omitted. `TELECOMJS_MODEL` is accepted. Provider aliases: `telecom-js`, `telecom_js`, `telecomjs-cn`, `tokenhub`. |\n| `mistral` | `[providers.mistral]` | `MISTRAL_API_KEY` | `MISTRAL_BASE_URL`; default `https://api.mistral.ai/v1` | `mistral-code-latest` (default; `codestral-latest` accepted as alias), `mistral-medium-latest` (aliases: `mistral-medium-3-5`), `mistral-small-latest` (aliases: `mistral-small-2603`), `mistral-large-latest` | Mistral AI (la Plateforme) OpenAI-compatible Chat route. On the documented first-party HTTPS `/v1` hosts, Medium and Small send adjustable `reasoning_effort` (`none` or `high` only), parse Mistral's polymorphic thinking/text blocks, and replay stored thinking in that same wire shape. Deprecated native Magistral IDs remain explicit-configuration compatibility routes: they are always-reasoning and never receive the adjustable effort field. Code and Large are non-reasoning. A custom `MISTRAL_BASE_URL` keeps generic Chat semantics unless it is one of the documented first-party hosts. `MISTRAL_MODEL` is accepted. Provider aliases: `mistral-ai`, `mistralai`, `la-plateforme`. |\n| `edenai` | `[providers.edenai]` | `EDENAI_API_KEY` | `EDENAI_BASE_URL`; default `https://api.edenai.run/v3`; EU `https://api.eu.edenai.run/v3` | `deepseek/deepseek-v4-pro` (default); live `/models` catalog of `provider/model` ids | Eden AI OpenAI-compatible aggregation gateway. Catalog rows remain provider-scoped; generic reasoning controls are omitted because supported fields depend on the selected upstream family. `EDENAI_MODEL` is accepted. The default `deepseek/deepseek-v4-pro` is listed on the global catalog only; on the EU endpoint set `EDENAI_MODEL` (or `model`) to a row from the EU `/models` list, for example `qwen/deepseek-v4-pro`. Provider aliases: `eden-ai`, `eden_ai`. |\n| `zenmux` | `[providers.zenmux]` | `ZENMUX_API_KEY` | `ZENMUX_BASE_URL`; default `https://zenmux.ai/api/v1` | `deepseek/deepseek-v4.1-flash` (default); live `/models` catalog of `provider/model` ids (keyless-readable) | ZenMux OpenAI-compatible aggregation gateway (~190 models). Catalog rows remain provider-scoped; generic reasoning controls are omitted because supported fields depend on the selected upstream family. `ZENMUX_MODEL` is accepted. Provider aliases: `zen-mux`, `zen_mux`. |\n| `csdn` | `[providers.csdn]` | `CSDN_API_KEY` | `CSDN_BASE_URL`; default `https://ai.csdn.net/api/model/v1` | `glm_for_coding` (default; the Coding Plan's dedicated model id); other marketplace model ids pass through | CSDN 星图 (Starmap) OpenAI-compatible hosted platform. Coding Plan keys and general marketplace keys share the one endpoint, so billing follows the credential product, never the URL alone: routing `glm_for_coding` — the shipped default — or setting `mode = \"coding_plan\"`/`\"plan\"`/`\"subscription\"` bills as CSDN Coding Plan quota with no dollar estimates; any other model, or an explicit `pay-as-you-go`/`metered` mode, bills metered; an unrecognized mode or an endpoint off `ai.csdn.net/api/model/v1` reports `cost: unknown`. `CSDN_MODEL` is accepted. Provider aliases: `csdn-ai`, `csdn_ai`, `csdn-coding-plan`, `csdn_coding_plan`, `starmap`. |\n| `concentrate` | `[providers.concentrate]` | `CONCENTRATE_API_KEY` | `CONCENTRATE_BASE_URL`; default `https://api.concentrate.ai/v1` | `deepseek-v4-pro` (default; a plain catalog id lets the gateway pick the upstream provider); `provider/model` ids such as `openai/gpt-5.6-sol` pin one upstream; `concentrate/auto` is the gateway's own router; unauthenticated live `/v1/models` catalog | Concentrate OpenAI Responses-compatible gateway (`POST /v1/responses`, bearer Universal API key). Opt-in and BYOK only: your key, your Concentrate bill, zero Codewhale fee, no managed default. Requests carry only documented fields (the system prompt rides as a `system` input item). Contract: [API introduction](https://concentrate.ai/docs/api-reference/introduction), [request parameters](https://concentrate.ai/docs/api-reference/endpoint/request-parameters), [streaming](https://concentrate.ai/docs/api-reference/endpoint/streaming), [errors](https://concentrate.ai/docs/api-reference/endpoint/errors). See [Concentrate Notes](#concentrate-notes). |\n| `codewhale` | `[providers.codewhale]` | `CODEWHALE_API_KEY` | `CODEWHALE_API_BASE`; default `https://api.codewhale.net/v1` | `deepseek/deepseek-v4-pro` (default), `anthropic/claude-sonnet-5`, `openai/gpt-5.6` are offline bootstrap rows only; the authenticated `GET /v1/models` listing of the account's connected providers is the catalog authority | Codewhale API: account-backed model access over the provider keys the customer connected to their Codewhale account. One `cwc_key_…` account API key with the `models:infer` scope authenticates every model. Model ids are `provider/model` exactly as the account catalog returns them, and each row states its protocol (`chat-completions` → `/v1/chat/completions`, `anthropic-messages` → `/v1/messages`, `responses` → `/v1/responses`); every protocol uses `Authorization: Bearer`, never `x-api-key`. `CODEWHALE_API_BASE` must be HTTPS except on loopback. Connect provider keys with `codewhale account keys set `. Provider aliases: `codewhale-api`, `cw-api`, `codewhale-cloud`. |\n| `xai` | `[providers.xai]` | `XAI_API_KEY`, Codewhale-owned device OAuth, or explicit read-only Grok CLI consent | `XAI_BASE_URL`; default `https://api.x.ai/v1` | `grok-4.6` (default), `grok-4.7`, `grok-4.5`, `grok-4.3`, `grok-build`, `grok-composer-2.5-fast`, `grok-4.20-0309-reasoning`, `grok-4.20-0309-non-reasoning` | xAI/Grok OpenAI-compatible Chat Completions route. Grok 4.6 has a 500K context window, text/image input, function calls, structured output, server-side web search, and `low`/`medium`/`high`/`xhigh` reasoning (default `high`). [Grok 4.7](https://docs.x.ai/docs/models/grok-4.7) has the same 500K window, text/image input, function calls, structured output, reasoning ladder and $2.00 / $0.50 cached / $6.00 rates; xAI documents no web-search support for it yet, so Codewhale does not claim it. Grok reasoning cannot be disabled ([reasoning guide](https://docs.x.ai/docs/guides/reasoning)). Its standard rates double when the prompt reaches 200K tokens; the same 2x long-context rule applies to `grok-4.5` (500K context, $2.00 / $0.30 cached / $6.00) and `grok-4.3` (1M context, $1.25 / $0.20 cached / $2.50) per their [model pages](https://docs.x.ai/docs/models/grok-4.5). There is no documented `latest`/`fast` alias and no published numeric output limit. **API-key** (default): Bearer token from console.x.ai via `XAI_API_KEY` / keyring / `api_key`. **OAuth**: `codewhale auth xai-device` uses SSH-friendly device login and Codewhale-owned storage, which may refresh itself. Existing Grok CLI credentials require `codewhale auth external-consent --provider xai --mode read-only`; the granted external file is never refreshed or rewritten. OAuth may return HTTP 403 on some SuperGrok tiers — keep API-key as the reliable fallback. `XAI_MODEL` is accepted. Provider aliases: `x-ai`, `x_ai`, `grok`. |\n| `modelstudio-token-plan` | `[providers.modelstudio_token_plan]` | `MODELSTUDIO_API_KEY`, `DASHSCOPE_API_KEY` | `MODELSTUDIO_TOKEN_PLAN_BASE_URL`; default `https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1` | `qwen3.8-max` (default), `qwen3.8-max-preview`, `qwen3.7-plus`, `qwen3.7-max`, `qwen3.6-flash`, `deepseek-v4-pro`, `deepseek-v4-flash-0731`, `glm-5.2` | Alibaba Cloud Model Studio Token Plan OpenAI-compatible Chat Completions route. Token Plan Personal and Team share this endpoint. `qwen3.8-max`, `qwen3.7-plus`, and `qwen3.7-max` can use provider-native web search through the Token Plan Responses Harness; the preview, Coding Plan, and Anthropic routes do not inherit that capability. All listed models are reasoning-capable text/coding models. DeepSeek and GLM entries are provider-scoped and do not collide with first-party routes. `MODELSTUDIO_TOKEN_PLAN_MODEL` is accepted. Provider aliases: `modelstudio-token-plan`, `alibaba-token-plan`, `dashscope-token-plan`. |\n| `modelstudio-token-plan-anthropic` | `[providers.modelstudio_token_plan_anthropic]` | `MODELSTUDIO_API_KEY`, `DASHSCOPE_API_KEY` | default `https://token-plan.ap-southeast-1.maas.aliyuncs.com/apps/anthropic` | Same model catalog as `modelstudio-token-plan` | Token Plan Anthropic-compatible Messages route (`/apps/anthropic`). Same API key as the OpenAI dialect. Provider aliases: `modelstudio-token-plan-anthropic`, `alibaba-token-plan-anthropic`. |\n| `modelstudio-coding-plan` | `[providers.modelstudio_coding_plan]` | `MODELSTUDIO_API_KEY`, `DASHSCOPE_API_KEY` | `MODELSTUDIO_CODING_PLAN_BASE_URL`; default `https://coding-intl.dashscope.aliyuncs.com/v1` | `qwen3.8-max` (default); same catalog as Token Plan | Alibaba Cloud Model Studio Coding Plan OpenAI-compatible Chat Completions route. `MODELSTUDIO_CODING_PLAN_MODEL` is accepted. Provider aliases: `modelstudio-coding-plan`, `alibaba-coding-plan`, `dashscope-coding-plan`. |\n| `modelstudio-coding-plan-anthropic` | `[providers.modelstudio_coding_plan_anthropic]` | `MODELSTUDIO_API_KEY`, `DASHSCOPE_API_KEY` | default `https://coding-intl.dashscope.aliyuncs.com/apps/anthropic` | Same model catalog as `modelstudio-coding-plan` | Coding Plan Anthropic-compatible Messages route (`/apps/anthropic`). Provider aliases: `modelstudio-coding-plan-anthropic`, `alibaba-coding-plan-anthropic`. |\n\nStepFun's four coding models are available through both its standard API and\n[Step Plan](https://platform.stepfun.ai/docs/en/step-plan/integrations/reasoning-api).\nChoose the billing route in `/provider`, then the model in `/model`; existing\nStep 3.7 selections remain unchanged. [Step 5 Preview](https://platform.stepfun.ai/docs/en/guides/models/step-5-preview)\nhas a 1M context window. Step 5 and Step 3.7 expose low/medium/high reasoning;\nStep 3.5 Flash 2603 exposes low/high; base Step 3.5 uses provider-default reasoning.\n[Published API prices](https://platform.stepfun.ai/docs/en/guides/pricing/details)\napply only to verified PAYG routes. Step Plan displays subscription allowance.\nSpeech, music and image-generation models use separate interfaces and are not\npresented as coding models. Provider video capability metadata does not imply\nthat every Codewhale client can attach video.\n\n\n### OpenCode Zen protocol catalog\n\nZen Responses and Chat Completions requests authenticate with Bearer\n`Authorization`; Zen Anthropic Messages requests use `x-api-key`. None of these\nroutes add ChatGPT/Codex OAuth headers.\n\nEach Zen model's wire comes from two sources, and neither is guessed from a\nmodel-id family (`qwen3.8-flash` is Messages while `qwen3.8-max` is Chat):\n\n1. **The curated snapshot** compiled into Codewhale, verified against the\n [official endpoint table](https://opencode.ai/docs/zen/) and the `opencode`\n provider in [Models.dev](https://models.dev). It is the offline floor, and\n it wins when a catalog row names a different wire for the same id.\n2. **The Models.dev catalog.** Its `opencode` provider is Zen's published\n catalog: each model row names the AI SDK package OpenCode itself uses, which\n Codewhale maps exactly — `@ai-sdk/openai` to Responses, `@ai-sdk/anthropic`\n to Anthropic Messages, and `@ai-sdk/openai-compatible` (the provider\n default) to Chat Completions. A Zen model released after this build routes\n once the catalog lists it, without a Codewhale release. The interactive TUI\n and `codewhale exec` both load the persisted catalog; refresh it with\n `codewhale models --update`.\n\nThe curated snapshot:\n\n- Responses: `gpt-6-astra`, `gpt-6-sol`, `gpt-6-luna`, `gpt-5.6-sol`,\n `gpt-5.6-terra`, `gpt-5.6-luna`, `gpt-5.5`, `gpt-5.5-pro`, `gpt-5.4`,\n `gpt-5.4-pro`, `gpt-5.4-mini`, `gpt-5.4-nano`, `gpt-5.3-codex`,\n `gpt-5.3-codex-spark`, `gpt-5.2`, `gpt-5.2-codex`, `gpt-5.1`,\n `gpt-5.1-codex`, `gpt-5.1-codex-max`, `gpt-5.1-codex-mini`, `gpt-5`,\n `gpt-5-codex`, `gpt-5-nano`, `grok-4.7`, `grok-4.6`, `grok-4.5`,\n `grok-build-0.1`, `muse-spark-1.3`, `muse-spark-1.3-contributor-free`,\n `muse-spark-1.2`, `muse-spark-1.2-contributor`,\n `muse-spark-1.2-contributor-free`.\n- Anthropic Messages: `claude-fable-5-1`, `claude-fable-5`,\n `claude-opus-5-5`, `claude-opus-5`, `claude-opus-4-8`, `claude-opus-4-7`,\n `claude-opus-4-6`, `claude-opus-4-5`, `claude-sonnet-5-5`,\n `claude-sonnet-5`, `claude-sonnet-4-6`, `claude-sonnet-4-5`,\n `claude-sonnet-4`, `claude-haiku-4-5`, `qwen3.8-flash`, `qwen3.7-max`,\n `qwen3.7-plus`, `qwen3.6-plus`, `qwen3.5-plus`.\n- Chat Completions: `deepseek-v4.1-flash`, `deepseek-v4-pro`,\n `deepseek-v4-flash`, `deepseek-v4-flash-vision-exp`, `minimax-m3`,\n `minimax-m2.7`, `minimax-m2.5`, `glm-5.3-flash`, `glm-5.3`, `glm-5.2`,\n `glm-5.1`, `glm-5`, `kimi-k3`, `kimi-k2.7-code`, `kimi-k2.6`, `kimi-k2.5`,\n `qwen3.8-max`, `big-pickle`, `space-bunny-free`,\n `longcat-2.5-preview-free`, `mimo-v2.6-flash-free`, `mimo-v2.5-free`,\n `ling-3.0-flash-fin-free`, `north-mini-code-free`,\n `nemotron-3-ultra-free`, `nemotron-3.5-lightning-free`,\n `deepseek-v4-flash-free`.\n\nThese fail closed locally, with the reason in the error, instead of reaching\nZen: Gemini (`@ai-sdk/google`, Google's model-specific protocol, which Codewhale\ndoes not speak); a catalog row naming any other package; a catalog row Models.dev\nmarks `deprecated`; and a model neither source lists. A miss never falls back to\nanother Zen wire shape, including when a custom Zen base URL is configured.\n\n### Concentrate Notes\n\nConcentrate (`concentrate`) is an OpenAI **Responses**-compatible gateway:\n`POST https://api.concentrate.ai/v1/responses` with `Authorization: Bearer\n`. It is opt-in and **BYOK only**.\n\n- **Model ids pass through.** A plain catalog id (`gpt-5.6-sol`,\n `deepseek-v4-pro`) lets the gateway choose the upstream provider;\n `provider/model` (`openai/gpt-5.6-sol`) pins the upstream provider inside the\n gateway; `concentrate/auto` sends the gateway's own `auto` router. Codewhale's\n bare `--model auto` remains the resolver sentinel (provider default), which is\n why the gateway router has its own explicit spelling. Once streaming begins\n the gateway commits to one provider ([auto routing](https://concentrate.ai/docs/api-reference/endpoint/auto-routing)).\n- **Wire.** Fixed Responses dialect. The request carries only documented\n fields — `model`, `input`, `stream`, `max_output_tokens`, `tools`,\n `tool_choice`, `parallel_tool_calls`, `reasoning.effort` — and the system\n prompt travels as a leading `system` input item because `instructions` is\n not in the gateway's [parameter reference](https://concentrate.ai/docs/api-reference/endpoint/request-parameters).\n Streaming follows the typed `response.*` SSE events and ends on\n `response.completed` without a `[DONE]` sentinel ([streaming](https://concentrate.ai/docs/api-reference/endpoint/streaming)).\n- **Errors.** `{ \"error\", \"message\", \"model\"?, \"retry_after\"? }` with 400\n (bad request / unknown model), 401 (invalid key), 402 (insufficient\n credits), 424 (upstream provider unavailable), 429 (rate limit) —\n surfaced verbatim and classified by message ([errors](https://concentrate.ai/docs/api-reference/endpoint/errors)).\n- **Catalog.** `GET /v1/models` needs no key\n ([list models](https://concentrate.ai/docs/api-reference/endpoint/list-models)); the live rows\n are provider-scoped and unclaimed (no pricing or capability claims).\n- **Commercial boundary.** Concentrate's [Terms of Service](https://concentrate.ai/legal/terms-of-service)\n forbid reselling, white-labeling, or providing the service on a\n service-bureau basis without written consent, and its\n [Acceptable Use Policy](https://concentrate.ai/legal/acceptable-use-policy)\n forbids sharing or sublicensing keys. Codewhale therefore ships **no**\n Codewhale-owned Concentrate key, no stored customer key, no default or\n managed routing, and no markup — activation of any hosted lane is gated on\n written consent, terms, and billing approval (tracked in the Codewhale ops\n evidence checklist `concentrate-gateway-20260829/CHECKLIST.md`). Public\n pricing states \"No platform markup on tokens\".\n- **Self-test without a key.** `scripts/concentrate-selftest.sh` boots a\n local stub that speaks the documented contract and drives the real\n `codewhale exec` path through it, asserting the URL, bearer header, model\n passthrough, streaming, and the completed-turn receipt. No network call\n leaves the machine and no account is required.\n\n### Hugging Face Provider vs MCP vs Hub\n\nCodewhale's `huggingface` provider ID is only the OpenAI-compatible chat\ninference route through Hugging Face Inference Providers. It is selected with\n`/provider huggingface`, `CODEWHALE_PROVIDER=huggingface`, or\n`provider = \"huggingface\"`.\n\nHugging Face MCP is a separate external-tool route. Configure it through the\nMCP config described in `docs/MCP.md`, preferably using the settings-generated\nsnippet from . In the TUI, `/hf mcp status`\nchecks whether the Hugging Face MCP server appears in the resolved MCP config,\n`/hf mcp setup` prints the settings workflow and a placeholder-only shape, and\n`/hf concepts` explains the provider/MCP/Hub distinction.\n\nHub publishing or repository management remains explicit user action through\nHub-native tooling such as `huggingface_hub` or git. The `/hf` helper does not\nupload to Hugging Face and does not perform direct Hugging Face Hub HTTP search.\n\n### Xiaomi MiMo Notes\n\n`xiaomi-mimo` defaults to `mimo-v2.5-pro` for long-context reasoning and coding\nwork. The chat picker also exposes `mimo-v2.5-pro-ultraspeed` and the latest\nOmni model `mimo-v2.5`. Xiaomi MiMo TTS is available through\n`codewhale --provider xiaomi-mimo speech \"text\" --model tts` (or the `tts`\nalias). In Act and Operate, the provider-specific `speech` / `tts` tools are\navailable through deferred discovery when the Xiaomi MiMo route is configured.\n\n`/provider xiaomi-mimo ultraspeed` and `/provider xiaomi-mimo pro-ultraspeed`\nboth select `mimo-v2.5-pro-ultraspeed`. Speech aliases such as `tts`,\n`voice-design`, and `voice-clone` are separate from normal chat defaults.\n\nToken Plan keys default to the Singapore endpoint\n`https://token-plan-sgp.xiaomimimo.com/v1`. If your MiMo account is provisioned\nfor the China region, set `base_url = \"https://token-plan-cn.xiaomimimo.com/v1\"`\nexplicitly in `[providers.xiaomi_mimo]` or set `mode = \"token-plan-cn\"`. Europe\nToken Plan accounts can set\n`base_url = \"https://token-plan-ams.xiaomimimo.com/v1\"` or use\n`mode = \"token-plan-ams\"`; `mode = \"pay-as-you-go\"`\nselects the standard API endpoint and standard MiMo key family. Xiaomi Token\nPlan docs and console expose credit/quota semantics, but Codewhale does not\ncurrently have a documented balance endpoint to poll, so cost display remains\nunknown rather than reusing token-price estimates from another provider.\n\nVoice-design and voice-clone shorthands map to `mimo-v2.5-tts-voicedesign` and\n`mimo-v2.5-tts-voiceclone`. Xiaomi's current\n[image-understanding guide](https://platform.xiaomimimo.com/docs/en-US/usage-guide/multimodal-understanding/image-understanding)\nincludes `mimo-v2.5` for image input. Codewhale exposes image analysis through the\nseparate `[vision_model]` / `image_analyze` path; set that model to\n`mimo-v2.5` when using MiMo for vision.\n\n### OpenRouter-Compatible Base URLs\n\nOpenRouter-compatible gateways should usually stay on the `openrouter`\nprovider with a provider-scoped `base_url` override instead of moving through\nthe generic `openai` route. That keeps OpenRouter-style reasoning, streaming,\ncache usage, and namespaced wire model parsing attached to the selected route:\n\n```toml\nprovider = \"openrouter\"\n\n[providers.openrouter]\napi_key = \"sk-...\"\nbase_url = \"https://openrouter-compatible.example/v1\"\nmodel = \"deepseek/deepseek-v4-pro\"\n```\n\nCodewhale preserves the `deepseek/` wire-model prefix under the OpenRouter\nprovider scope; it does not infer a switch to the direct DeepSeek provider from\nthat model string. Cache fields such as `prompt_cache_hit_tokens`,\n`prompt_cache_miss_tokens`, and `prompt_tokens_details.cached_tokens` are\nparsed when the upstream gateway sends them. If a key/account type omits those\nfields, Codewhale treats them as absent for that response rather than as a\ndifferent provider route.\n\nOrcaRouter (`https://api.orcarouter.ai/v1`) is a dedicated named route\n([OrcaRouter](https://www.orcarouter.ai)) that speaks the same OpenAI\nChat Completions wire protocol and serves the same namespaced\n`vendor/model` catalog. It does not need an OpenRouter-compatible\n`base_url` override: select `provider = \"orcarouter\"` and its namespaced\nwire models (for example `deepseek/deepseek-v4-pro` or its own\n`orcarouter/auto` router) pass through verbatim, exactly as they do on the\nOpenRouter provider scope.\n\n#### OrcaRouter credentials: API key or OAuth 2.0 + PKCE\n\nOrcaRouter accepts two credential sources, and both write the same durable\n`sk-orca-…` key to the same `orcarouter` secret-store slot with\n`auth_mode = \"api_key\"`:\n\n- **API key** — `codewhale auth set --provider orcarouter`, `/provider`, or\n `ORCAROUTER_API_KEY`. Use this when you already have a key.\n- **Connect with OrcaRouter** — `codewhale auth orcarouter` (CLI) or\n `/auth orcarouter` (in-session). This runs an OAuth 2.0 authorization-code\n flow with PKCE (S256) on a loopback redirect. The browser is sent to\n `GET https://www.orcarouter.ai/auth` with `callback_url`, `code_challenge`,\n `code_challenge_method=S256`, `state`, `app_name`, and `scope`; the code is\n exchanged at `POST https://www.orcarouter.ai/api/v1/auth/keys` for a\n durable API key. There is no client secret and no pre-registered redirect\n URI; state is compared in constant time before the code is used.\n\nAuthentication and inference use different origins: the consent and exchange\nlive on `https://www.orcarouter.ai`; models and chat live on\n`https://api.orcarouter.ai/v1`. Neither is derived from the other, and\n`/v1/auth/keys` on the API origin is not the exchange route. Self-hosted\ndeployments can override each origin explicitly with `ORCA_AUTH_BASE_URL`\n(auth) and `ORCA_API_BASE_URL`/`ORCAROUTER_BASE_URL` (inference); the explicit\nvalue wins. Remote origins must be HTTPS; plain HTTP is accepted only on\nloopback.\n\nA PKCE-issued key is a durable API key, **not** a refresh token: Codewhale\nstores it, reuses it across restarts, and never sends a refresh grant. Revoke\nthe key on the OrcaRouter console (`/auth orcarouter-revoke` clears the local\ncopy) and sign in again to get a new one. A 401 from the relay marks that\ncredential generation as needing re-authentication rather than silently\nretrying.\n\nThe chat model list is discovered live from `GET https://api.orcarouter.ai/v1/models`\nwith the configured key. OrcaRouter publishes `supported_endpoint_types` on\nevery row, so the chat selector keeps only rows advertising `openai`,\n`anthropic`, `gemini`, or `openai-response`, and drops image-generation,\nvideo, and rerank rows instead of guessing from a model name. A row that\nstates `architecture.input_modalities` with `image` is image-input capable;\nrows that state no architecture are treated as unknown, not as text-only.\n\n### Recent OpenRouter Large Models\n\nOpenRouter completions and static registry rows include the April 2026 onward\nlarge models verified through OpenRouter's model metadata:\n`arcee-ai/trinity-large-thinking`, `qwen/qwen3.6-flash`,\n`qwen/qwen3.6-35b-a3b`, `qwen/qwen3.6-max-preview`, `qwen/qwen3.6-27b`,\n`qwen/qwen3.6-plus`, `minimax/minimax-m3`, `xiaomi/mimo-v2.5-pro`,\n`xiaomi/mimo-v2.5`, `moonshotai/kimi-k2.7-code`, `moonshotai/kimi-k2.6`,\n`z-ai/glm-5.1`, `z-ai/glm-5.2`, `z-ai/glm-5-turbo`, `tencent/hy3-preview`,\n`google/gemma-4-31b-it`, `google/gemma-4-26b-a4b-it`, and\n`nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free`.\n`minimax/minimax-m3` was added from OpenRouter's May 31, 2026 listing as a 1M\ncontext multimodal model for coding, tool use, and long-horizon agentic work.\n`GLM-5.3` is now the default direct Z.AI Coding Plan model; `GLM-5.2` /\n`z-ai/glm-5.2` remain available (explicit selections keep their own id),\n`GLM-5.1` / `z-ai/glm-5.1` remain available as the smaller model,\n`GLM-5.3-Flash` / `z-ai/glm-5.3-flash` is the faster/explore sibling of\n`GLM-5.3`, and `GLM-5-Turbo` / `z-ai/glm-5-turbo` remains the faster sibling\nof `GLM-5.2`.\n`GLM-5.3` / `z-ai/glm-5.3` and `GLM-5.3-Flash` / `z-ai/glm-5.3-flash` are\nfirst-class picker ids on the Z.ai and OpenRouter routes (`/model` after\n`/provider zai`, or `model = \"GLM-5.3-Flash\"`).\nLimits and reasoning options for 5.3 are inherited from\n`GLM-5.2` until Z.ai publishes distinct 5.3 metadata, and 5.3 carries no\nprice. Flash ships the published $0.15/$0.50 list. A live call can still\n429 with entitlement code 1311 on accounts that are not provisioned for 5.3.\n\n## Static Model Registry\n\nThis table describes the static registry, which `codewhale model resolve` (and\nthe `[model]` config surface) still use to resolve selector aliases.\n\n`codewhale model resolve` projects the reviewed `selections` in\n`crates/config/assets/catalog_corrections.json` through\n`crates/agent/src/lib.rs`. There is no independent Rust model roster. These\nordered aliases and flags are compatibility metadata, not account availability\nor executable route permission. This differs from live `/models` discovery.\nUse `/models` or `codewhale models` to fetch model IDs from the active API\nendpoint when the endpoint supports model listing.\n\n| Provider | Static registry entries | Tool calls | Registry reasoning flag |\n| --- | --- | --- | --- |\n| `deepseek` | `deepseek-v4-pro`, `deepseek-v4-flash`, `deepseek-v4-flash-vision-exp` | yes | yes |\n| `nvidia-nim` | `deepseek-ai/deepseek-v4-pro`, `deepseek-ai/deepseek-v4-flash` | yes | yes |\n| `openai` | `deepseek-v4-pro`, `deepseek-v4-flash`, `gpt-5.6`, `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna` | yes | yes |\n| `atlascloud` | `deepseek-ai/deepseek-v4-flash`, `deepseek-ai/deepseek-v4-pro` | yes | yes |\n| `wanjie-ark` | `deepseek-reasoner` | yes | yes |\n| `volcengine` | `DeepSeek-V4-Pro`, `DeepSeek-V4-Flash` | yes | yes |\n| `openrouter` | `deepseek/deepseek-v4-pro`, `deepseek/deepseek-v4-flash`, `arcee-ai/trinity-large-thinking`, `minimax/minimax-m3`, `minimax/minimax-m2.7`, `xiaomi/mimo-v2.5-pro`, `xiaomi/mimo-v2.5`, `qwen/qwen3.6-flash`, `qwen/qwen3.6-35b-a3b`, `qwen/qwen3.6-max-preview`, `qwen/qwen3.6-27b`, `qwen/qwen3.6-plus`, `qwen/qwen3.7-max`, `moonshotai/kimi-k2.7-code`, `moonshotai/kimi-k2.6`, `z-ai/glm-5.1`, `z-ai/glm-5.2`, `z-ai/glm-5.3`, `z-ai/glm-5.3-flash`, `z-ai/glm-5-turbo`, `tencent/hy3-preview`, `google/gemma-4-31b-it`, `google/gemma-4-26b-a4b-it`, `nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free`, `nvidia/nemotron-3-ultra-550b-a55b` | yes | yes |\n| `orcarouter` | `deepseek/deepseek-v4-pro`, `deepseek/deepseek-v4-flash`, `orcarouter/auto` | yes | yes |\n| `xiaomi-mimo` | `mimo-v2.5-pro`, `mimo-v2.5-pro-ultraspeed`, `mimo-v2.5`; speech/TTS IDs are selected through `codewhale speech` / `tts` | yes | yes for chat models; no for speech/TTS models |\n| `novita` | `deepseek/deepseek-v4-pro`, `deepseek/deepseek-v4-flash` | yes | yes |\n| `fireworks` | `accounts/fireworks/models/deepseek-v4-pro` | yes | yes |\n| `siliconflow` | `deepseek-ai/DeepSeek-V4-Pro`, `deepseek-ai/DeepSeek-V4-Flash` | yes | yes |\n| `arcee` | `trinity-large-thinking`, `trinity-large-preview`; provider-hinted custom model IDs pass through | yes | yes for `trinity-large-thinking`; no for `trinity-large-preview` |\n| `moonshot` | `kimi-k2.7-code`, `kimi-k2.6` | yes | yes |\n| `zai` | `GLM-5.3`, `GLM-5.3-Flash`, `GLM-5.2`, `GLM-5.1`, `GLM-5-Turbo`; provider-hinted custom model IDs pass through | yes | yes |\n| `stepfun` | `step-3.7-flash` (default), `step-5-preview`, `step-3.5-flash`, `step-3.5-flash-2603` | yes | yes |\n| `minimax` | `MiniMax-M3`, `MiniMax-M2.7`, `MiniMax-M2.7-highspeed`, `MiniMax-M2.5`, `MiniMax-M2.5-highspeed`, `MiniMax-M2.1`, `MiniMax-M2.1-highspeed`, `MiniMax-M2` | yes | yes |\n| `minimax-anthropic` | `MiniMax-M3`, `MiniMax-M2.7` | yes | yes |\n| `sglang` | `deepseek-ai/DeepSeek-V4-Pro`, `deepseek-ai/DeepSeek-V4-Flash` | yes | yes |\n| `vllm` | `deepseek-ai/DeepSeek-V4-Pro`, `deepseek-ai/DeepSeek-V4-Flash` | yes | yes |\n| `ollama` | live local tag; custom tags pass through when provider hint is `ollama` | yes | no |\n| `ollama-cloud` | `gpt-oss:120b`; arbitrary provider-owned model IDs pass through | yes | yes |\n| `huggingface` | `deepseek-ai/DeepSeek-V4-Pro`, `deepseek-ai/DeepSeek-V4-Flash` | yes | no |\n| `modelscope` | `Qwen/Qwen3.5-397B-A17B`, `Qwen/Qwen3.5-122B-A10B`, `Qwen/Qwen3.5-27B`, `Qwen/Qwen3.5-35B-A3B`, `Qwen/Qwen3.8-27B`, `Qwen/Qwen3.8-Flash-Next`, `deepseek-ai/DeepSeek-V4-Pro`, `deepseek-ai/DeepSeek-V4-Pro-0813`, `deepseek-ai/DeepSeek-V4.1-Flash`, `ZhipuAI/GLM-4.7-Flash`, `ZhipuAI/GLM-5.2` | yes | no |\n| `deepinfra` | `deepseek-ai/DeepSeek-V4-Pro`, `deepseek-ai/DeepSeek-V4-Flash` | yes | yes |\n| `together` | `deepseek-ai/DeepSeek-V4-Pro`, `deepseek-ai/DeepSeek-V4-Flash`, `thinkingmachines/inkling` | yes | yes |\n| `openai-codex` | `gpt-5.5` | yes | yes |\n| `anthropic` | `claude-opus-5`, `claude-opus-4-8`, `claude-sonnet-5`, `claude-sonnet-4-6`, `claude-fable-5`, `claude-haiku-4-5` | yes | yes except `claude-haiku-4-5` |\n| `openmodel` | `deepseek-v4-flash`; provider-scoped custom model IDs pass through | yes | model-dependent |\n| `sakana` | `fugu`, `fugu-ultra-20260615` | yes | yes for `fugu-ultra-20260615` |\n| `longcat` | `LongCat-2.0` | yes | yes |\n| `opencode-go` | `deepseek-v4-pro`, `grok-4.5`, `glm-5.2`, `glm-5.1`, `kimi-k3`, `kimi-k2.7-code`, `kimi-k2.6`, `deepseek-v4-flash`, `mimo-v2.5`, `mimo-v2.5-pro` | yes | yes |\n| `meta` | `muse-spark-1.2` | yes | yes |\n| `xai` | `grok-4.6`, `grok-4.7`, `grok-4.5`, `grok-4.3`, `grok-build`, `grok-composer-2.5-fast`, `grok-4.20-0309-reasoning`, `grok-4.20-0309-non-reasoning` | yes | yes for `grok-4.6`, `grok-4.7`, `grok-4.5`, `grok-4.3`, `grok-build`, and `grok-4.20-0309-reasoning` |\n| `google` | `gemini-3.1-pro-preview`, `gemini-3-pro-preview`, `gemini-3.7-flash`, `gemini-3.6-flash`, `gemini-3.5-flash`, `gemini-3.5-flash-lite`, `gemini-2.5-pro`, `gemini-2.5-flash` | yes | yes except `gemini-3.5-flash-lite` |\n| `mistral` | `mistral-code-latest`, `mistral-medium-latest`, `mistral-small-latest`, `mistral-large-latest` | yes | yes for Medium and Small (`reasoning_effort` `none` or `high` on exact first-party routes); deprecated native Magistral remains an always-on explicit compatibility ID; no for Code and Large |\n| `modelstudio-token-plan`, `modelstudio-coding-plan` | `qwen3.8-max`, `qwen3.8-max-preview`, `qwen3.7-plus`, `qwen3.7-max`, `qwen3.6-flash`, `deepseek-v4-pro`, `deepseek-v4-flash-0731`, `glm-5.2` | yes | yes |\n| `csdn` | `glm_for_coding`; other marketplace model IDs pass through | yes | yes |\n\nAtlasCloud keeps the same default model as the config layer and adds\nprovider-scoped aliases for the Pro and Flash rows. Other AtlasCloud model IDs\nshould still be selected through `ATLASCLOUD_MODEL`, config, or live model\nlisting when available.\n\n## Capability Metadata\n\n`codewhale doctor --json` exposes the `capability` object. It is static\nmetadata, not a live API probe. Current fields are:\n\n`resolved_provider`, `resolved_model`, `context_window`, `max_output`,\n`thinking_supported`, `cache_telemetry_supported`, and `request_payload_mode`.\n\nWhen configuration cannot be loaded or validated, `doctor --json` exits\nnonzero and prints a bounded, secret-redacted JSON error envelope with\n`status = \"error\"` and `error.kind = \"config_validation\"` instead of emitting\nmisleading route or capability metadata.\n\nMost shipped providers use the Chat Completions request payload mode. Native\nMessages routes, including `minimax-anthropic`, use `/v1/messages`, and\n`openai-codex` uses Responses.\n\nFor OpenAI-compatible gateways or self-hosted runtimes whose real window\ndiffers from the static table, set `[providers.] context_window = N`.\nThe configured value becomes the route-effective context window for prompts,\ncontext-pressure checks, compaction, and output-cap budgeting.\n\n`max_output` is optional and truthful: it is `null` (and omitted from the\ncapability struct on the wire) when the route publishes no output maximum we\ncan stand behind — the Kimi Code membership `kimi-for-coding` family is the\ncanonical example, since the membership catalog owns their limits. An unknown\noutput ceiling is never backfilled with a placeholder, and it applies **no**\ncompatibility clamp to a turn's requested `max_tokens`; only a concrete\nroute/offering maximum narrows the request. A model the catalogue simply has no\nrow for is a different fact — absence is not permission, so an uncatalogued id\nkeeps a conservative ceiling. The \"Max output metadata\" column below reads\n`unknown` wherever no documented maximum exists.\n\nThe exact Kimi Code membership roster contains `k3`, `k3-256k`,\n`kimi-for-coding`, and `kimi-for-coding-highspeed`. The two K3 ids share the\nsame reasoning and fixed-sampling contract; `k3-256k` stays at 262,144 tokens,\nwhile bare `k3` can use an entitled 1M override.\n\n| Provider/model class | Context window | Max output metadata | Thinking support | Cache telemetry | FIM endpoint |\n| --- | --- | --- | --- | --- | --- |\n| DeepSeek V4 (`deepseek-v4-pro`, `deepseek-v4-flash`) | 1,000,000 | 384,000 | yes | yes | DeepSeek beta only |\n| DeepSeek V4 Flash Vision experimental (`deepseek-v4-flash-vision-exp`) | 1,000,000 inherited from Flash | 384,000 inherited from Flash | yes, inherited | yes, inherited | not claimed; Chat Completions route only |\n| DeepSeek compatibility aliases (`deepseek-chat`, `deepseek-reasoner`) | 1,000,000 | 384,000 | yes | yes | DeepSeek beta only |\n| NVIDIA NIM V4 registry models | 1,000,000 | 384,000 | yes | yes | not documented in code |\n| Volcengine Ark V4 model IDs | 1,000,000 | 384,000 | yes | yes | not documented in code |\n| OpenRouter, Novita, Fireworks, SiliconFlow, SGLang, and vLLM V4 model IDs | 1,000,000 | 384,000 | yes | no | not documented in code |\n| Xiaomi MiMo `mimo-v2.5-pro`, `mimo-v2.5-pro-ultraspeed`, `mimo-v2.5` | 1,000,000 | 131,072 | yes | no | not documented in code |\n| OpenRouter Qwen 3.6 Flash / Plus | 1,000,000 | 65,536 | yes | no | not documented in code |\n| OpenRouter Qwen 3.6 35B / 27B | 262,144 | 262,140 | yes | no | not documented in code |\n| OpenRouter Qwen 3.6 Max Preview | 262,144 | 65,536 | yes | no | not documented in code |\n| OpenAI API `gpt-5.5` | 1,050,000 | 128,000 | yes | no | not documented in code |\n| OpenAI API `gpt-5.6`, `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna` | 1,050,000 | 128,000 | yes | no | not documented in code |\n| Anthropic API `claude-opus-5`, `claude-opus-4-8`, `claude-sonnet-5`, `claude-sonnet-4-6`, `claude-fable-5` | 1,000,000 | 128,000 | yes | yes | not documented in code |\n| Google Gemini API `gemini-3.7-flash`, `gemini-3.6-flash`, `gemini-3.5-flash`, `gemini-3.5-flash-lite`, `gemini-3.1-pro-preview`, `gemini-2.5-pro`, `gemini-2.5-flash` | 1,048,576 | 65,536 | model-dependent | no | not documented in code |\n| Meta Model API `muse-spark-1.2` | 1,000,000 | 32,000 | yes | no | not documented in code |\n| ChatGPT plan route (`openai-codex`) | conservatively budgeted; account listing does not state a window | no output cap sent in preview | model dependent | no | public `/v1/responses`; no context limit is inferred from account eligibility |\n| OpenModel default/custom model IDs | 200,000 fallback unless model metadata or config overrides it | 64,000 fallback | model-dependent | no | route uses Messages payload at `/v1/messages` |\n| Wanjie Ark `reasoner` / `r1` model IDs | 128,000 | unknown (no documented maximum) | yes | no | not documented in code |\n| Direct Arcee API `trinity-large-thinking` | 262,144 | 262,144 | yes | no | not documented in code |\n| Direct Arcee API `trinity-large-preview` | 262,144 | unknown (no documented maximum) | no in doctor capability metadata | no | not documented in code |\n| Direct Moonshot `kimi-k3` | 1,048,576 | 1,048,576 documented maximum; 131,072 provider default | yes | no | exact route uses `max_completion_tokens` and omits fixed sampling fields ([K3 quickstart](https://platform.kimi.ai/docs/guide/kimi-k3-quickstart)) |\n| Kimi Code membership `k3` | 262,144 safe baseline; 1,048,576 with an explicit entitled-plan override | 131,072 conservative default ceiling; membership maximum is not published | yes | no | exact `https://api.kimi.com/coding/v1` route |\n| Kimi Code membership `k3-256k` | 262,144 fixed | 131,072 conservative default ceiling; membership maximum is not published | yes | no | exact `https://api.kimi.com/coding/v1` route |\n| Direct Moonshot/Kimi K2.7/K2.6 (`kimi-k2.7-code`, `kimi-k2.7-code-highspeed`, `kimi-k2.6`) | 262,144 | 32,768 | yes | no | provider-reported bundled catalog |\n| Kimi Code membership `kimi-for-coding`, `kimi-for-coding-highspeed` | 262,144 | unknown — the membership catalog owns these limits and no client-side ceiling is claimed | yes | no | exact `https://api.kimi.com/coding/v1` route |\n| Direct Z.AI `GLM-5.3` (default) | 1,000,000 | 131,072 | yes | no | live on the GLM Coding Plan; limits inherited from `GLM-5.2` until Z.ai publishes distinct 5.3 numbers; no USD price |\n| Direct Z.AI `GLM-5.3-Flash` | 1,000,000 | 131,072 | yes | no | natively multimodal; $0.15/$0.50 list (2026-08-26); faster/explore sibling of `GLM-5.3` |\n| Direct Z.AI `GLM-5.2` | 1,000,000 | 131,072 | yes | no | not documented in code |\n| Direct Z.AI `GLM-5.1` | 202,752 | 131,072 | yes | no | not documented in code |\n| Direct Z.AI `GLM-5-Turbo` | 202,752 | 131,072 | yes | no | faster/explore sub-agent sibling |\n| Direct MiniMax `MiniMax-M3` | 1,000,000 | 524,288 | yes | no | not documented in code |\n| Direct MiniMax M2.x models | 204,800 | unknown until MiniMax output metadata is promoted | yes | no | not documented in code |\n| MiniMax Messages route (`MiniMax-M3`, `MiniMax-M2.7`) | model-specific values above | model-specific values above | yes | no | route uses `/anthropic/v1/messages` |\n| Generic `openai` and AtlasCloud | 128,000 | unknown (no documented maximum) | no in doctor capability metadata | no | not documented in code |\n| Ollama | 8,192 | unknown (no documented maximum) | no | no | not documented in code |\n| Hugging Face Inference Providers V4 model IDs | 131,072 | unknown (no documented maximum) | yes | no | not documented in code |\n| Other recognized DeepSeek model IDs | 128,000 unless the model name carries an explicit `Nk` hint | unknown (no documented maximum) | no unless V4/reasoner logic matches | DeepSeek/NIM only | DeepSeek beta only |\n\nMiniMax M3 uses input-length and service tiers. Codewhale omits\n`service_tier`, so requests use the standard tier and cost estimates select the\ncorrect standard rate from total input usage. Priority rates are listed to keep\nthe official tier structure visible. Prices are USD per million tokens.\n\n| Model / service tier | Input length | Input | Output | Cache read | Cache write |\n| --- | --- | ---: | ---: | ---: | ---: |\n| `MiniMax-M3` standard | up to 512,000 input tokens | $0.30 | $1.20 | $0.06 | not published |\n| `MiniMax-M3` standard | over 512,000 input tokens | $0.60 | $2.40 | $0.12 | not published |\n| `MiniMax-M3` priority | up to 512,000 input tokens | $0.45 | $1.80 | $0.09 | not published |\n| `MiniMax-M3` priority | over 512,000 input tokens | $0.90 | $3.60 | $0.18 | not published |\n| `MiniMax-M2.7` standard | all supported inputs | $0.30 | $1.20 | $0.06 | $0.375 |\n\nThese values come from the [MiniMax pay-as-you-go pricing\nguide](https://platform.minimax.io/docs/guides/pricing-paygo). M3 thinking is\nadaptive or disabled; the OpenAI-compatible API defaults to adaptive and the\nAnthropic-compatible API defaults to disabled. M2.7 thinking cannot be\ndisabled. Codewhale sends explicit controls when the user selects a reasoning\nmode.\n\nTool-call support is tracked separately by the static `ModelRegistry` and by\nthe endpoint's ability to accept OpenAI-compatible `tools` payloads. A custom\nOpenAI-compatible or local endpoint can still reject tool calls even if\nCodewhale can send the schema.\n\n### Hugging Face Inference Providers Notes\n\nThe shipped Hugging Face route targets the OpenAI-compatible Inference Providers\nrouter at `https://router.huggingface.co/v1`. Configure auth with\n`HUGGINGFACE_API_KEY` first, or `HF_TOKEN` as a fallback. Configure the endpoint\nwith `HUGGINGFACE_BASE_URL` first, or `HF_BASE_URL` as a fallback; configure the\nmodel with `HUGGINGFACE_MODEL` first, or `HF_MODEL` as a fallback.\n\nThis route does not imply Hub browsing, model-card metadata, dataset access,\nJobs, uploads, or export. Those remain explicit Model Lab work items so\nprovider auth and artifact movement stay separate.\n\n### When a Local Model Prints Tool JSON\n\nCodewhale only executes tools when the provider returns Chat Completions\n`tool_calls` or streamed `delta.tool_calls`. If a local model prints text such\nas `{\"name\":\"File\",\"arguments\":{\"action\":\"search_content\",...}}` in the\nassistant message, that is ordinary model output, not an executable tool\nrequest.\n\nFor OpenAI-compatible or local runtimes, check:\n\n- The endpoint accepts the `tools` array in `/v1/chat/completions` requests.\n- The selected model or chat template is configured for function/tool calls.\n- The server returns `tool_calls` in the response rather than plain JSON text.\n- The compatibility layer does not strip tools before forwarding the request.\n- If in doubt, test a small `File` `read` or `search_content` action against a\n known tool-calling model before debugging Codewhale's tool registry.\n\nChanging `provider`, `base_url`, or `model` can select a route that supports the\nOpenAI-compatible payload shape, but Codewhale cannot convert arbitrary JSON\ntext into a trusted tool call after the model has emitted it as prose.\n\nDeepSeek will retire `deepseek-chat` and `deepseek-reasoner` on 2026-07-24 at\n15:59 UTC. Codewhale migrates either name to `deepseek-v4-flash` before a\nrequest reaches DeepSeek's first-party OpenAI or Anthropic endpoint. If no\nreasoning tier was configured, `deepseek-chat` also migrates to `off` and\n`deepseek-reasoner` to `high`, preserving their former non-thinking / thinking\nintent; an explicit `reasoning_effort` remains authoritative. The mapping is\ndeliberately not global: Wanjie Ark, aggregators, self-hosted runtimes, and\ncustom endpoints continue to own their model ids.\n\n## Reasoning Effort\n\n`/reasoning ` (and the `reasoning_effort` config key) is translated to\neach provider's wire dialect by the client before the request is sent. `off`\ndisables thinking where the route supports it. Both exact K3 routes map `off`\nto their lowest supported tier, `low`, and the model is never switched to\nsatisfy `off` — but they do so for different reasons:\n\n- **Kimi Code membership K3** (exact `https://api.kimi.com/coding/v1` with\n `model = \"k3\"` or `model = \"k3-256k\"`) — the membership roster declares K3 always-thinking, so `off`\n cannot be honored without changing what the model is. The clamp preserves the\n fixed K3 identity.\n- **Direct Moonshot K3** (exact `https://api.moonshot.ai/v1` with\n `model = \"kimi-k3\"`) — this clamp is *defensive*, not a documented contract.\n The direct platform publishes no `off` state for K3, and Codewhale will not\n assert a fixed-thinking guarantee it cannot verify for a given key's\n entitlement, so the requested `off` is normalized to the lowest tier with the\n live entitlement left unknown.\n\nNormal dispatched\n`auto` uses Codewhale's auto-reasoning selector and sends a concrete tier;\nonly an omitted reasoning setting leaves the provider default in control.\nProviders marked \"omitted\" receive no reasoning fields at all for that tier.\n\n| Provider | `off` | `low`/`medium`/`high` | `max`/`xhigh` |\n| --- | --- | --- | --- |\n| `deepseek`, `deepseek-cn`, `siliconflow`, `siliconflow-CN`, `sglang`, `volcengine`, `atlascloud` | `thinking: {type: disabled}` | `reasoning_effort: \"high\"` + `thinking: {type: enabled}` | `reasoning_effort: \"max\"` + `thinking: {type: enabled}` |\n| `openrouter`, `novita`, other `together` models | `thinking: {type: disabled}` | `reasoning_effort` pass-through + `thinking: {type: enabled}` | `reasoning_effort: \"xhigh\"` + `thinking: {type: enabled}` |\n| `together` + `thinkingmachines/inkling` | `reasoning_effort: \"none\"` | exact `minimal`/`low`/`medium`/`high` `reasoning_effort` | `reasoning_effort: \"max\"` |\n| Direct Moonshot `kimi-k3` at exact `https://api.moonshot.ai/v1` | top-level `reasoning_effort: \"low\"` (effective normalization) | top-level `reasoning_effort: \"low\"` / `\"high\"` (`medium` becomes `high`) | top-level `reasoning_effort: \"max\"` |\n| Kimi Code membership `k3`, `k3-256k` at exact `https://api.kimi.com/coding/v1` | `thinking: {type: enabled, effort: \"low\"}` (effective normalization) | `thinking: {type: enabled, effort: \"low\" | \"high\"}` | `thinking: {type: enabled, effort: \"max\"}` |\n| Other `moonshot` routes | `thinking: {type: disabled}` | `thinking: {type: enabled}` | `thinking: {type: enabled}` |\n| `ollama` | `think: false` | `think: true` | `think: true` |\n| `ollama-cloud` | `reasoning_effort: \"none\"` | exact `low`/`medium`/`high` `reasoning_effort` | `reasoning_effort: \"max\"` |\n| `xiaomi-mimo` | `thinking: {type: disabled}` | `thinking: {type: enabled}` | `thinking: {type: enabled}` |\n| First-party `minimax` `MiniMax-M3` | `reasoning_split: true` + `thinking: {type: disabled}` | `reasoning_split: true` + `thinking: {type: adaptive}`; effective tier granularity unavailable | `reasoning_split: true` + `thinking: {type: adaptive}`; effective tier granularity unavailable |\n| First-party Z.ai `GLM-5.2` | `thinking: {type: disabled}`; no `reasoning_effort` | enabled thinking; only effective `high` adds `reasoning_effort: \"high\"` | enabled thinking + `reasoning_effort: \"max\"` |\n| First-party Z.ai `GLM-5.3` | `thinking: {type: disabled}`; no `reasoning_effort` | enabled thinking; only effective `high` adds `reasoning_effort: \"high\"` | enabled thinking + `reasoning_effort: \"max\"` |\n| First-party Z.ai `GLM-5.3-Flash` | `thinking: {type: disabled}`; no `reasoning_effort` | enabled thinking; only effective `high` adds `reasoning_effort: \"high\"` | enabled thinking + `reasoning_effort: \"max\"` |\n| First-party Z.ai `GLM-5-Turbo` | `thinking: {type: disabled}` | enabled thinking; effort granularity unavailable | enabled thinking; effort granularity unavailable |\n| Compatible gateways configured as `zai` | omitted; effective unavailable | omitted; effective unavailable | omitted; effective unavailable |\n| `nvidia-nim` | `chat_template_kwargs.thinking: false` | `chat_template_kwargs`: `thinking: true` + `reasoning_effort: \"high\"` | `chat_template_kwargs`: `thinking: true` + `reasoning_effort: \"max\"` |\n| `vllm` | `chat_template_kwargs.enable_thinking: false` | `chat_template_kwargs.enable_thinking: true` + `reasoning_effort` low/medium/high | `chat_template_kwargs.enable_thinking: true` + `reasoning_effort: \"high\"` (vLLM has no max tier) |\n| `arcee`, `huggingface` | omitted | `reasoning_effort` pass-through | `reasoning_effort: \"high\"` |\n| `fireworks` | omitted | `reasoning_effort: \"high\"` | `reasoning_effort: \"max\"` |\n| `openai`, `wanjie-ark`, `telecomjs` | omitted | omitted | omitted |\n| `openmodel` | Anthropic Messages adapter handles thinking/output configuration | Anthropic Messages adapter handles thinking/output configuration | Anthropic Messages adapter handles thinking/output configuration |\n| `openai-codex` | Responses API `reasoning` field (handled by the Responses bridge) | Responses API `reasoning` field | Responses API `reasoning` field |\n\nAtlasCloud serves DeepSeek models, so it speaks the DeepSeek reasoning dialect,\nincluding the `max` tier (#3024).\n\nOn the exact MiniMax OpenAI-compatible Chat endpoints, `MiniMax-M3` uses\n`max_completion_tokens`. Other MiniMax models and compatible gateways retain\n`max_tokens`; the MiniMax Anthropic endpoints use the separate Messages\nadapter.\n\n## Drift Check\n\nRun this before changing provider IDs, provider TOML tables, static model\nregistry rows, or provider default strings:\n\n```bash\npython3 scripts/check-provider-registry.py\n```\n\nThe check fails when:\n\n- `docs/PROVIDERS.md` omits a canonical `ProviderKind::as_str()` ID.\n- Descriptor presentation IDs or released wire tags are duplicated or drift\n from intrinsic kinds, or a second provider enum/ordinal bridge is introduced.\n- The shipped-provider table omits or adds a `[providers.*]` TOML table.\n- The static model registry table drifts from providers used by\n `crates/agent/src/lib.rs`.\n- A provider default model or base URL constant in `crates/tui/src/config.rs`\n is no longer mentioned here.\n\n## Provider Gotchas\n\nThree failures that look like something else (measured by a provider operator\non live traffic):\n\n- **A cold model looks broken.** The first call to a model the provider has not\n loaded can take 90 to 150 seconds, then drop to a second or less once warm.\n Raise `[stream].open_timeout_secs` (default 45 seconds, at most 300) before reading a timeout as \"model unavailable\".\n- **Listed is not callable.** A catalog entry can be visible and still fail\n every call. The same error text on every attempt (for example a \"resources\n busy\" 502) is not transient: a genuinely busy upstream returns successes in\n between. Probe a model before trusting it, and stop retrying one that fails\n identically.\n- **A truncated answer can report `stop`.** A reasoning model can spend the\n whole `max_tokens` allowance on reasoning. When the provider reports\n `completion_tokens` exactly equal to the `max_tokens` the request asked for\n and the finish reason is `stop`, Codewhale treats the turn as cut at the\n ceiling rather than finished (`stop_contradicts_output_ceiling` in\n `codewhale-models`); retrying the same prompt stops at the same count, so\n raise the ceiling or shorten the task instead. No inference is made when the\n provider reports no usage.\n\n## Planned, Not Shipped Yet\n\nThese items belong to the v0.8.48+ provider-abstraction milestone or related\nprovider docs work, but they are not native shipped behavior in this checkout:\n\n- A unified `Provider` trait in `codewhale-agent` that owns env precedence,\n secret resolution, base URL normalization, auth-header construction, and\n provider metadata. Those responsibilities are still split across\n `crates/config`, `crates/secrets`, and `crates/tui/src/client.rs`.\n- Hugging Face model passport metadata in the picker, including license, base\n model, context length, chat template, tool-call support, reasoning support,\n and gated/private status.\n\n## Sign in with Claude\n\nRun `codewhale auth claude` (or `/auth claude` in a running session), open the\nprinted Claude sign-in URL, and paste the complete `code#state` callback.\n`/provider setup anthropic` also offers API-key and Claude Pro / Max choices.\nThen select `anthropic` or its `claude` alias. API keys continue to use separate\nAnthropic API billing; selecting subscription sign-in never falls back to one.\n\nCodewhale stores the grant in its private credentials directory, commits the\nprovider's credential pointer atomically, and refreshes it before requests on a\nworker. Subscription tokens go only to `https://api.anthropic.com`; a custom\nendpoint is rejected. Each request keeps the existing Messages adapter, tool\nprotocol, cache prefix, and Codewhale client identity. No Claude Code credential\nfile or keychain entry is read or modified.\n\n`codewhale auth claude-revoke` (or `/auth claude-revoke`) removes the owned local\ngrant. End remote access separately in your Claude account settings. The\nsubscription route then needs another login; select API-key billing explicitly\nto use an API key. Login and inference follow Anthropic's provider-side\navailability; local checks do not\nestablish that an account is eligible or that live subscription inference works.\n\nThe callback and JSON token exchange follow the interoperable flow used by\n[pi's Anthropic OAuth adapter](https://github.com/fivewillow/badlogic-pi-mono/blob/main/packages/ai/src/utils/oauth/anthropic.ts).\n" }, { "path": "docs/MODEL_LAB.md", @@ -352,8 +352,8 @@ }, { "path": "docs/CONTRIBUTORS.md", - "sha256": "4e7ff98061615c85fed9a013d93827f0e1f4d8eca09fa85c1c91e6309fa43d4a", - "content": "# Contributors\n\nCodewhale is built in the open with a growing community of contributors. Every\nissue report and pull request is real project work — welcome at any experience\nlevel. This is the full per-PR contributor record, grouped into release/time\nbands with the newest band first so it stays scannable. Expand any band to see\neveryone.\n\nFor the live list, see the\n[GitHub contributors page](https://github.com/codewhale-hq/CodeWhale/graphs/contributors),\n[`AUTHOR_MAP`](https://github.com/codewhale-hq/CodeWhale/blob/main/.github/AUTHOR_MAP),\nand [CHANGELOG.md](../CHANGELOG.md).\n\n## Organizational thanks\n\n- **[DeepSeek](https://github.com/deepseek-ai)** — the models and support that got this project started. 感谢 DeepSeek 提供模型与支持。\n- **[DataWhale](https://github.com/datawhalechina)** 🐋 — for the support and for welcoming us into the Whale Brother family. 感谢 DataWhale 的支持。\n- **[OpenWarp](https://github.com/zerx-lab/warp)** — for prioritizing Codewhale support and collaborating on a better terminal-agent experience.\n- **[Open Design](https://github.com/nexu-io/open-design)** — for support and collaboration around design-forward agent workflows.\n\nThe maintainer rule: reports and PRs are real project work, even when the final\npatch has to be narrowed, delayed, or harvested into a maintainer branch.\nAdapted contributions keep visible credit in commits and PR bodies, the\nchangelog or release notes, and this contributor record.\n\n---\n\n## Contributors by time\n\n
\nUnreleased\n\n**Merged or adapted contributions**\n\n- **[printf033](https://github.com/printf033)** — confined-file I/O on Android/Termux: SELinux-denied `open(\"/\", O_RDONLY|O_DIRECTORY)` anchor replaced with an `O_PATH` walk (Linux-cfg-gated) plus a re-materialized final parent, restoring journal, compaction and artifact writes in search-only SELinux domains ([#6983](https://github.com/codewhale-hq/Codewhale/pull/6983)), with the diagnosis and on-device reproducer in [#6980](https://github.com/codewhale-hq/Codewhale/issues/6980).\n\n
\n\n
\nv0.10.2 — terminal, recovery and reliability\n\n**Contributions**\n\n- **[Sh1Zuku / SparkofSpike](https://github.com/SparkofSpike)** — live network-policy updates and goal milestone hand-back ([#6928](https://github.com/codewhale-hq/Codewhale/pull/6928), [#6930](https://github.com/codewhale-hq/Codewhale/pull/6930)), and a Codewhale home reached through a symlink or junction ([#6947](https://github.com/codewhale-hq/Codewhale/issues/6947)).\n- **[dajiaohuang](https://github.com/dajiaohuang)** — cache-write token accounting, with missing and explicit-zero usage preserved ([#6913](https://github.com/codewhale-hq/Codewhale/pull/6913)).\n- **[gaord](https://github.com/gaord)** — embedder-declared telemetry surface support without changing collection policy ([#6916](https://github.com/codewhale-hq/Codewhale/pull/6916)).\n- **[Lstarsky0](https://github.com/Lstarsky0)** — localized `/profile` replies across all 15 complete locale packs ([#6919](https://github.com/codewhale-hq/Codewhale/pull/6919)), and workflow gates that block their own role rejected at plan admission ([#6952](https://github.com/codewhale-hq/Codewhale/pull/6952)).\n- **[LIghtJUNction](https://github.com/LIghtJUNction)** — plugin shell install and in-TUI plugin OAuth sign-in with `/connect` and `/disconnect` ([#6950](https://github.com/codewhale-hq/Codewhale/pull/6950)).\n- **[jayanthvee](https://github.com/jayanthvee)** — Windows npm launcher guidance and targeted process shutdown ([#6906](https://github.com/codewhale-hq/Codewhale/pull/6906)).\n- **[asto18089](https://github.com/asto18089)** — reference fix for longer browser sign-in callback windows ([#6865](https://github.com/codewhale-hq/Codewhale/issues/6865)).\n\n**Reports and verification**\n\n- **[BX166](https://github.com/BX166)** — reported three provider failure modes measured on AICraft's own traffic: a cold model that reads as a dead connection, a listed model that fails on every call, and a response cut at the output ceiling that reports `stop` ([#6889](https://github.com/codewhale-hq/Codewhale/issues/6889)).\n\n
\n\n
\nv0.10.1 — reliability and first-run fixes\n\n**Merged or adapted contributions**\n\n- **[gaord](https://github.com/gaord)** — exposed call-specific workspace changes to Runtime clients ([#6817](https://github.com/codewhale-hq/Codewhale/pull/6817)) and canonical skill-detail/review routes ([#6869](https://github.com/codewhale-hq/Codewhale/pull/6869)).\n- **[asto18089](https://github.com/asto18089)** — fixed preferred search-language selection ([#6860](https://github.com/codewhale-hq/Codewhale/pull/6860)), image metadata for model input ([#6858](https://github.com/codewhale-hq/Codewhale/pull/6858)), automation deletion wording and retained-run cleanup ([#6864](https://github.com/codewhale-hq/Codewhale/pull/6864)), and compaction-anchor regression coverage ([#6857](https://github.com/codewhale-hq/Codewhale/pull/6857)).\n- **[aboimpinto](https://github.com/aboimpinto)** — extracted portable config/status/permission command contracts while preserving host-owned mutation and queue-worker readiness ([#6832](https://github.com/codewhale-hq/Codewhale/pull/6832)).\n- **[hodeswildsmith455-boop](https://github.com/hodeswildsmith455-boop)** — added OrcaRouter account sign-in with PKCE and its live chat catalog ([#6867](https://github.com/codewhale-hq/Codewhale/pull/6867)).\n- **[LIghtJUNction](https://github.com/LIghtJUNction)** — added reviewed plugin-provided AI routes with host-owned OAuth PKCE credentials and request-time authority checks ([#6805](https://github.com/codewhale-hq/Codewhale/pull/6805)).\n- **[AdityaVG13](https://github.com/AdityaVG13)** — supplied the discovery-cache priority correction adapted from [#6393](https://github.com/codewhale-hq/Codewhale/pull/6393); highest-ranked tools survive cache overflow. The broader echo and fork-inheritance draft remains open.\n- **[Guan0923](https://github.com/Guan0923)** — accepted case-insensitive HTTP(S) schemes in `config doctor` without rewriting the configured URL ([#6819](https://github.com/codewhale-hq/Codewhale/pull/6819)).\n- **[harryvgiunta](https://github.com/harryvgiunta)** — added Yolo-Auto as a bundled OpenAI-compatible host descriptor, with its billing basis recorded as unreviewed rather than guessed ([#6408](https://github.com/codewhale-hq/Codewhale/pull/6408)).\n- **[asto18089](https://github.com/asto18089)** — contributed the integrated runtime liveness, context, search, JavaScript execution, stopship scout and pet repairs, preserving the original contributor commits ([#6799](https://github.com/codewhale-hq/Codewhale/pull/6799)).\n- **[qiuYliangM](https://github.com/qiuYliangM)** — made provider-bound project instruction and constitution labels stable across directory moves and kept their absolute paths in operator reports ([#6799](https://github.com/codewhale-hq/Codewhale/pull/6799)).\n- **[zhuowp](https://github.com/zhuowp)** — supplied the process-scoped PowerShell execution-policy repair adapted for Codewhale; machine and user Group Policy still take precedence ([#6745](https://github.com/codewhale-hq/Codewhale/issues/6745)).\n- **[Andrea-Bruno](https://github.com/Andrea-Bruno)** — designed the Superfast Decision Gate and contributed its off-by-default shadow classifier ([#6604](https://github.com/codewhale-hq/Codewhale/pull/6604), [#6603](https://github.com/codewhale-hq/Codewhale/issues/6603)).\n- **[aiapienthusiast](https://github.com/aiapienthusiast)** — added Cheaper Inference to the bundled provider catalog ([#6761](https://github.com/codewhale-hq/Codewhale/pull/6761)).\n- **[gaord](https://github.com/gaord)** — let a client fork a thread at a named turn ([#6580](https://github.com/codewhale-hq/Codewhale/pull/6580)), let undo roll back files for the turn it is undoing ([#6483](https://github.com/codewhale-hq/Codewhale/pull/6483)), stopped resume and fork from duplicating threads and sessions ([#6406](https://github.com/codewhale-hq/Codewhale/pull/6406)), exposed user-defined provider routes to native clients ([#6404](https://github.com/codewhale-hq/Codewhale/pull/6404)), and kept a fork going when a turn lost its tool call ([#6664](https://github.com/codewhale-hq/Codewhale/pull/6664)).\n- **[Lstarsky0](https://github.com/Lstarsky0)** — moved the docs/work, legal, digest and FAQ pages onto the dictionary spine ([#6405](https://github.com/codewhale-hq/Codewhale/pull/6405), [#6417](https://github.com/codewhale-hq/Codewhale/pull/6417), [#6499](https://github.com/codewhale-hq/Codewhale/pull/6499), [#6574](https://github.com/codewhale-hq/Codewhale/pull/6574)), tightened the Chinese-branching ceiling to 18 ([#6403](https://github.com/codewhale-hq/Codewhale/pull/6403)), and made Fleet publish without a two-link window ([#6431](https://github.com/codewhale-hq/Codewhale/pull/6431)). Also moved the constitution page onto the dictionary spine and kept its install link in the selected locale ([#6733](https://github.com/codewhale-hq/Codewhale/pull/6733)). Translated the session-only note after model switches across the complete TUI locale packs ([#6875](https://github.com/codewhale-hq/Codewhale/pull/6875)).\n- **[aboimpinto](https://github.com/aboimpinto)** — restored a green Linux full-workspace test gate without loosening any test, twice ([#6581](https://github.com/codewhale-hq/Codewhale/pull/6581), [#6666](https://github.com/codewhale-hq/Codewhale/pull/6666)), and completed the session command group's shared boundary ([#6793](https://github.com/codewhale-hq/Codewhale/pull/6793)).\n- **[dajiaohuang](https://github.com/dajiaohuang)** — validated `config set` values against the settings schema ([#6568](https://github.com/codewhale-hq/Codewhale/pull/6568)).\n- **[Water-Run](https://github.com/Water-Run)** — ingested namespaced model-only catalog entries so models present only in the canonical `models` map reach the offering list ([#6400](https://github.com/codewhale-hq/Codewhale/pull/6400)), and retired the blanket dead-code allowance and its unused feature stages, tightening the budget to match ([#6402](https://github.com/codewhale-hq/Codewhale/pull/6402)).\n- **[wuisabel-gif](https://github.com/wuisabel-gif)** — designed the `tool_call_after` execution-receipt contract and its tests on a reference branch, which landed re-implemented on the current hook seam ([#6689](https://github.com/codewhale-hq/Codewhale/issues/6689), [#6713](https://github.com/codewhale-hq/Codewhale/pull/6713)).\n- **[Sh1Zuku / SparkofSpike](https://github.com/SparkofSpike)** — let making room survive a provider request-body limit (HTTP 413) by shrinking, then replacing, inline images for that one summary pass ([#6642](https://github.com/codewhale-hq/Codewhale/pull/6642)). Also translated seventeen more guides into Simplified Chinese, among them plugins, memory, sandbox, workflow authoring, Docker, Termux and HarmonyOS, and brought the existing zh_hans docs onto one terminology standard ([#6662](https://github.com/codewhale-hq/Codewhale/pull/6662)), then translated thirteen developer and internal docs, among them the runtime API, architecture, tool surface, authorization order, operations runbook and Workroom security ([#6663](https://github.com/codewhale-hq/Codewhale/pull/6663)).\n\n**Reports and reproductions**\n\n- **[7jrxt42BxFZo4iAnN4CX](https://github.com/7jrxt42BxFZo4iAnN4CX)** — reported indefinite human questions being cancelled by the TUI hung-tool watchdog and supplied the timer evidence ([#6872](https://github.com/codewhale-hq/Codewhale/issues/6872)).\n- **[cenab](https://github.com/cenab)** — requested the Tsubasa provider row and supplied its endpoint, key and model values ([#6695](https://github.com/codewhale-hq/Codewhale/issues/6695)).\n- **[BX166](https://github.com/BX166)** — reported the AICraft provider row missing its key console, docs link and guidance, and supplied the values ([#6616](https://github.com/codewhale-hq/Codewhale/issues/6616)); the report also surfaced that no bundled descriptor's links reached the setup form.\n- **[jayanthvee](https://github.com/jayanthvee)** — reported and diagnosed that killing the npm launcher's `node.exe` ends Windows sessions without cleanup, with reproductions and fix directions ([#6827](https://github.com/codewhale-hq/Codewhale/issues/6827)).\n\n
\n\n
\nv0.10.0 — redesigned workbench, session recovery, and runtime surfaces\n\n**Merged or adapted contributions**\n\n- **[AdityaVG13](https://github.com/AdityaVG13)** — composer wrapping, pasted/editor draft history, painted-column transcript copying, tab/caret placement, explicit terminal foregrounds, and headless user-input tool availability ([#6363](https://github.com/codewhale-hq/Codewhale/pull/6363), [#6365](https://github.com/codewhale-hq/Codewhale/pull/6365)); both PRs merged with their original ancestry.\n- **[aboimpinto](https://github.com/aboimpinto)** — moved the TUI session-export slice onto shared command contracts (FEAT-025): a session-export contract facet with one shared sanitizer, `/export` routed through the facet, pinned with baseline-captured goldens and gates ([#6096](https://github.com/codewhale-hq/Codewhale/pull/6096)).\n- **[gaord](https://github.com/gaord)** — recorded the mode each turn ran in so mixed-mode sessions stay legible ([#6321](https://github.com/codewhale-hq/Codewhale/pull/6321), harvested), stated the approval posture a task thread starts on ([#6386](https://github.com/codewhale-hq/Codewhale/pull/6386)), and rebuilt the runtime-API thread summary in one store pass instead of one per row ([#6376](https://github.com/codewhale-hq/Codewhale/pull/6376)).\n- **[zhuowp](https://github.com/zhuowp)** — preserved chat roles across compaction, protected user turns on recompaction, and kept the operate contract intact through the same path ([#6286](https://github.com/codewhale-hq/Codewhale/pull/6286)).\n- **[h3c-hexin](https://github.com/h3c-hexin)** — rate-limit-adaptive subagent launch scheduling: the `DynamicGate` that replaces fixed spawn pacing when a provider throttles ([#6055](https://github.com/codewhale-hq/Codewhale/pull/6055), harvested).\n- **[asto18089](https://github.com/asto18089)** — co-authored the rate-limit-adaptive launch scheduling work ([#6055](https://github.com/codewhale-hq/Codewhale/pull/6055)).\n- **[yrk111222](https://github.com/yrk111222)** — ModelScope provider support, landed through the shared `ChildGrant` fleet authority ([#6299](https://github.com/codewhale-hq/Codewhale/pull/6299), harvested).\n- **[xiechimon](https://github.com/xiechimon)** — capped child tool results at capture time rather than at render ([#6294](https://github.com/codewhale-hq/Codewhale/pull/6294), harvested).\n- **[VincentCorleone](https://github.com/VincentCorleone)** — defined and implemented the weixin-bridge Quick Start so a first run works from the README alone ([#6170](https://github.com/codewhale-hq/Codewhale/pull/6170), harvested).\n- **[Serendo](https://github.com/Serendo)** — fixed the `/config` theme editor exiting the panel on an arrow key ([#6336](https://github.com/codewhale-hq/Codewhale/pull/6336)).\n- **[yetuge](https://github.com/yetuge)** — dropped the retired `token_budget` field from the subagent documentation ([#6335](https://github.com/codewhale-hq/Codewhale/pull/6335)).\n- **[Water-Run](https://github.com/Water-Run)** — translated the local browser client guide into Simplified Chinese ([#6401](https://github.com/codewhale-hq/Codewhale/pull/6401)). The catalog and dead-code work (#6400, #6402) landed after the v0.10.0 tag and is credited under v0.10.1.\n\n**Reports and reproductions**\n\n- **[BX166](https://github.com/BX166)** — contributed the AICraft provider template and its documentation ([#6171](https://github.com/codewhale-hq/Codewhale/pull/6171)). The PR was closed unmerged, but it is what surfaced the decision to stop special-casing named OpenAI-compatible hosts and make them ordinary providers ([#6289](https://github.com/codewhale-hq/Codewhale/issues/6289)); its base URL and key env carry into that work.\n- **[7jrxt42BxFZo4iAnN4CX](https://github.com/7jrxt42BxFZo4iAnN4CX)** — reported the session-retention defects behind archive-past-the-cap and empty-session cap occupancy ([#6136](https://github.com/codewhale-hq/Codewhale/issues/6136), [#6137](https://github.com/codewhale-hq/Codewhale/issues/6137)), the resume-failure design behind durable transcript errors ([#6138](https://github.com/codewhale-hq/Codewhale/issues/6138)), and the gaps behind the opt-in approval timeout ([#6101](https://github.com/codewhale-hq/Codewhale/issues/6101)), `codewhale exec --hooks` ([#6099](https://github.com/codewhale-hq/Codewhale/issues/6099)), Markdown drag-copy ([#6156](https://github.com/codewhale-hq/Codewhale/issues/6156)), and the browsable, current-aware session picker ([#6014](https://github.com/codewhale-hq/Codewhale/issues/6014)); the goal token-budget hard stop ([#6013](https://github.com/codewhale-hq/Codewhale/issues/6013)) and the fleet no-progress guard shared with child workers ([#6015](https://github.com/codewhale-hq/Codewhale/issues/6015)) landed as first slices of two larger proposals, and the runtime-store session refusal ([#6207](https://github.com/codewhale-hq/Codewhale/issues/6207)) stays open after the first fix was reverted on a race.\n- **[Lstarsky0](https://github.com/Lstarsky0)** — reported TUI tests reading machine state instead of hermetic fixtures; the `lock_test_env` remedy from that report shaped two more hermetic fixes for shared UI fixtures and the compaction budget test ([#5359](https://github.com/codewhale-hq/Codewhale/issues/5359)).\n- **[Lujc0523](https://github.com/Lujc0523)** — reported `/hooks edit` splitting keystrokes between the editor and the composer, fixed by pausing the TUI input pump inside the editor handoff ([#6165](https://github.com/codewhale-hq/Codewhale/issues/6165)).\n- **[Statter](https://github.com/Statter)** — reported the Gemini `/models` failure that now surfaces the provider's reason instead of an empty error ([#6173](https://github.com/codewhale-hq/Codewhale/issues/6173)).\n- **[sequico](https://github.com/sequico)** — reported the ACP `session/new` ids that `session/load` could not resolve, fixed by minting resolvable session ids ([#6174](https://github.com/codewhale-hq/Codewhale/issues/6174)).\n- **[bevis-wong](https://github.com/bevis-wong)** — reported the mid-run engine freeze behind the bounded turn-end foreground-child join, and the resume path that re-ran identical tool-call repair on every load instead of persisting it ([#6184](https://github.com/codewhale-hq/Codewhale/issues/6184), [#6185](https://github.com/codewhale-hq/Codewhale/issues/6185)).\n\n
\n\n
\nv0.9.13 — paste integrity, dispatch safety, and the Computer Use bundle\n\n**Merged or adapted contributions**\n\n- **[nightt5879](https://github.com/nightt5879)** — added bounded Gemini signature recovery guidance and streaming/non-streaming gateway transport regressions ([#6081](https://github.com/codewhale-hq/Codewhale/pull/6081)).\n- **[c020627](https://github.com/c020627)** — repaired translated contributor-guide and Windows screenshot links ([#6080](https://github.com/codewhale-hq/Codewhale/pull/6080)).\n- **[h3c-hexin](https://github.com/h3c-hexin)** — contributed full-fidelity session archives ([#6056](https://github.com/codewhale-hq/Codewhale/pull/6056)), GLM-5.3 reasoning controls and the model-facing documentation/tool-gating audit ([#6051](https://github.com/codewhale-hq/Codewhale/pull/6051), [#6052](https://github.com/codewhale-hq/Codewhale/pull/6052)).\n- **[asto18089](https://github.com/asto18089)** — co-authored full-fidelity session archives ([#6056](https://github.com/codewhale-hq/Codewhale/pull/6056)), GLM-5.3 reasoning controls and tool-gating/documentation fixes ([#6051](https://github.com/codewhale-hq/Codewhale/pull/6051), [#6052](https://github.com/codewhale-hq/Codewhale/pull/6052)).\n- **[Hmbown](https://github.com/Hmbown)** — updated JavaScript dependencies across the website, telemetry package and VS Code extension ([#6057](https://github.com/codewhale-hq/Codewhale/pull/6057)).\n- **[gaord](https://github.com/gaord)** — contributed the file-scoped restore endpoint and trust-gated whole-tree rollback ([#6111](https://github.com/codewhale-hq/Codewhale/pull/6111)), Fleet schema inspection, role precedence and worker deliverable receipts, and linked the community VS Code frontend ([#5944](https://github.com/codewhale-hq/Codewhale/pull/5944), [#5945](https://github.com/codewhale-hq/Codewhale/pull/5945), [#5946](https://github.com/codewhale-hq/Codewhale/pull/5946), [#5992](https://github.com/codewhale-hq/Codewhale/pull/5992)).\n- **[goransh-walia](https://github.com/goransh-walia)** — contributed the propose-only commit-planning rework ([#5870](https://github.com/codewhale-hq/Codewhale/pull/5870)).\n- **[7jrxt42BxFZo4iAnN4CX](https://github.com/7jrxt42BxFZo4iAnN4CX)** — documented turn budgets and goal configuration, and reported gaps in command discovery, Fleet navigation, human waits, state hooks, history and provider routing ([#5996](https://github.com/codewhale-hq/Codewhale/pull/5996), [#5952](https://github.com/codewhale-hq/Codewhale/issues/5952), [#5954](https://github.com/codewhale-hq/Codewhale/issues/5954), [#6003](https://github.com/codewhale-hq/Codewhale/issues/6003), [#6004](https://github.com/codewhale-hq/Codewhale/issues/6004), [#6006](https://github.com/codewhale-hq/Codewhale/issues/6006), [#6007](https://github.com/codewhale-hq/Codewhale/issues/6007)).\n- **[SparkofSpike](https://github.com/SparkofSpike)** — contributed two-stage consent for opting out of model-bound credential redaction and session titles derived from real user prompts instead of runtime handoffs ([#5982](https://github.com/codewhale-hq/Codewhale/pull/5982), [#6012](https://github.com/codewhale-hq/Codewhale/pull/6012)).\n- **[aboimpinto](https://github.com/aboimpinto)** — moved session lifecycle and session-control commands onto shared command contracts ([#5902](https://github.com/codewhale-hq/Codewhale/pull/5902), [#5951](https://github.com/codewhale-hq/Codewhale/pull/5951)).\n- **[EvanProgramming](https://github.com/EvanProgramming)** — reported Windows input and CRLF-write defects, and contributed CRLF preservation and an injectable Windows input runner ([#5908](https://github.com/codewhale-hq/Codewhale/issues/5908), [#5909](https://github.com/codewhale-hq/Codewhale/issues/5909), [#5910](https://github.com/codewhale-hq/Codewhale/pull/5910), [#5911](https://github.com/codewhale-hq/Codewhale/pull/5911), [#5912](https://github.com/codewhale-hq/Codewhale/pull/5912)).\n- **[wuisabel-gif](https://github.com/wuisabel-gif)** — exposed workspace file suggestions through the Runtime API ([#6120](https://github.com/codewhale-hq/Codewhale/pull/6120)) and added custom-theme discovery, preview and selection in the theme picker ([#5907](https://github.com/codewhale-hq/Codewhale/pull/5907)).\n- **[zhuowp](https://github.com/zhuowp)** — matched model-visible shell guidance to the interpreter selected for execution ([#5900](https://github.com/codewhale-hq/Codewhale/pull/5900)).\n- **[googio](https://github.com/googio)** — added the opt-in Serply web-search provider ([#6100](https://github.com/codewhale-hq/Codewhale/pull/6100)).\n\n**Reports and reproductions**\n\n- **[Hmbown](https://github.com/Hmbown)** — identified missing recovery guidance when a compatible gateway rejects Gemini tool-call replay without thought signatures ([#6048](https://github.com/codewhale-hq/Codewhale/issues/6048)).\n- **[7jrxt42BxFZo4iAnN4CX](https://github.com/7jrxt42BxFZo4iAnN4CX)** — proposed global usage and tool diagnostics and independent goal verification ([#6011](https://github.com/codewhale-hq/Codewhale/issues/6011), [#6013](https://github.com/codewhale-hq/Codewhale/issues/6013)); these broader requests remain open.\n- **[nsfoxer](https://github.com/nsfoxer)** — reported the multiline-paste regression and incomplete provider model lists ([#5981](https://github.com/codewhale-hq/Codewhale/issues/5981), [#6009](https://github.com/codewhale-hq/Codewhale/issues/6009)).\n- **[Nefelibata1024](https://github.com/Nefelibata1024)** — confirmed the multiline-paste regression's impact ([#5981](https://github.com/codewhale-hq/Codewhale/issues/5981)).\n- **[Gabriel-Degret](https://github.com/Gabriel-Degret)** — reported the loss of the allow_insecure_http provider setting and that saved agent profiles were silently ignored when spawning sub-agents ([#5991](https://github.com/codewhale-hq/Codewhale/issues/5991), [#6117](https://github.com/codewhale-hq/Codewhale/issues/6117)).\n- **[LmeSzinc](https://github.com/LmeSzinc)** — requested Runtime API access to the TUI fuzzy file search ([#6095](https://github.com/codewhale-hq/Codewhale/issues/6095)).\n- **[dmt4](https://github.com/dmt4)** — requested Linux copy-on-select and middle-click paste ([#6116](https://github.com/codewhale-hq/Codewhale/issues/6116)).\n- **[Lujc0523](https://github.com/Lujc0523)** — reported the ACP initialize schema violation affecting strict IDE clients ([#5969](https://github.com/codewhale-hq/Codewhale/issues/5969)).\n- **[mo-vic](https://github.com/mo-vic)** — proposed storing evicted context on disk so it can be retrieved later ([#6008](https://github.com/codewhale-hq/Codewhale/issues/6008)).\n- **[giancarlocp](https://github.com/giancarlocp)** — requested a plugin authoring guide and OpenCode plugin conversion ([#5827](https://github.com/codewhale-hq/Codewhale/discussions/5827)).\n- **[hxfhd](https://github.com/hxfhd)** — supplied a Windows reproduction of a turn stopping before its stated next tool action ([#6010](https://github.com/codewhale-hq/Codewhale/discussions/6010)).\n\n
\n\n
\nv0.9.12 — native search, live token truth, and runtime surfaces\n\n**Merged or adapted contributions**\n\n- **[hexin / h3c-hexin](https://github.com/h3c-hexin)** — provider-native web\n search across four routes: the DeepSeek adapter (#5683), Z.AI and BigModel\n (#5685), and Xiaomi MiMo (#5687), each fail-closed for undocumented models,\n plus the constraint enforcement that runs before any fallback (#5682); also\n authoritative edit-last-turn boundaries (#5621), Kimi Code k3-256k support\n (#5622), post-compaction input-token reporting (#5623), and preserving the\n scheduled model selection in automations (#5650)\n- **[Isabel Wu / wuisabel-gif](https://github.com/wuisabel-gif)** — live\n session token totals (#5624), persisted context-pressure warnings (#5629),\n discoverable Fleet roster editing (#5604), the capability-gated cursor\n accent (#5599), and `/copy` for the latest completed response (#5692)\n- **[Paulo Aboim Pinto / aboimpinto](https://github.com/aboimpinto)** —\n preserved Windows verbatim-path operands through POSIX word splitting\n (#5610), moved the plugins group onto the command shapes (#5657), built\n FEAT-022 skills command shapes with retained-host validation (#5825), and\n re-landed FEAT-020 plugin command shapes on main (#5865)\n- **[Alex Musichen / musichen](https://github.com/musichen)** — fixed the\n configured-view DeepSeek model picker so it shows a stable DeepSeek heading\n and keeps every official catalog model for the active provider visible\n (#5689)\n- **[gaord](https://github.com/gaord)** — added the `GET /v1/fleet/profiles`\n runtime API endpoint, reusing the FleetManager validation path (#5688)\n- **[Sh1Zuku / SparkofSpike](https://github.com/SparkofSpike)** — corrected\n English documentation inaccuracies and contributed the first zh_hans\n translations for the Tier-2 docs (#5613)\n- **[M-Maciej](https://github.com/M-Maciej)** — goal continuation cadence fix\n (#5591) and the per-session control socket (#5533, #5831)\n- **[Serephus / serephus](https://github.com/serephus)** — nixpkgs update\n (#5669)\n- **[秋月凉梦 / qiuYliangM](https://github.com/qiuYliangM)** — co-authored the\n authoritative edit-last-turn boundaries (#5621), Kimi Code k3-256k support\n (#5622), and post-compaction input-token reporting (#5623)\n- **[whp233](https://github.com/whp233)** — `wire = responses|anthropic` for\n openai-compatible custom routes and opencode-zen muse-spark (#5716, landed\n as #5719)\n- **[Gabriel Degret / Gabriel-Degret](https://github.com/Gabriel-Degret)** —\n found the reasoning-only retry gap and built the first fix; landed as the\n `[reasoning_only]` retry ceiling with a request-scoped nudge (#5867)\n- **[huangxianzhan](https://github.com/huangxianzhan)** — the\n `x-opencode-session` header for OpenCode Go and Zen gateways (#5868)\n- **[zhuowp](https://github.com/zhuowp)** — task origin preserved in job\n snapshots (#5869)\n- **[AdityaG / AdityaVG13](https://github.com/AdityaVG13)** — a ten-commit\n performance pass across the TUI and config: zero-copy LaTeX streaming,\n single-pass token accounting, memoized provider resolution, once-per-process\n models.dev catalog parsing (interactive boot -70%), adaptive shell-completion\n poll cadence, and diagnostic worker caps\n- **[Nightt / nightt5879](https://github.com/nightt5879)** — isolated remote\n recovery lease generations (#5790)\n- **[yiheng-kkk](https://github.com/yiheng-kkk)** — replaced stale todo\n transcript snapshots so a rewritten todo list renders its current tasks\n (#5871, #5873)\n- **[Lfanxing](https://github.com/Lfanxing)** — Moonshot routes degrade\n incompatible tool definitions per request instead of failing the turn\n- **[WissssleyL / Lstarsky0](https://github.com/Lstarsky0)** — moved\n `docs/subagents` and `docs/mcp` onto the dictionary spine (#5337), with the\n metaTitle probe that keeps them there\n\n**Reports and reproductions**\n\n- **[slowly247](https://github.com/slowly247)** — reported the Ollama input\n budget collapsing to 1,024 tokens on 32K local models (#5820)\n- **[ronohara](https://github.com/ronohara)** — reported the engine stopping\n after recoverable network errors and reproduced the discarded approval (#5769)\n- **[Lujc0523](https://github.com/Lujc0523)** — asked for ACP session mode and\n model configuration (#5863)\n- **[senka9h](https://github.com/senka9h)** — reported the missing ACP\n `session/list` and `session/load` methods (#5864)\n
\n\n
\nv0.9.11 — portable command surfaces and turn-loop structure\n\n**Merged or adapted contributions**\n\n- **[xyzs996 / Mark Yan](https://github.com/xyzs996)** — DeepSeek V4 billing treats whole Beijing weekends as off-peak, and the scorecard window comment now matches ([#5545](https://github.com/codewhale-hq/Codewhale/pull/5545))\n- **[Sun Zhenyuan / bistack](https://github.com/bistack)** — extracted tool-call\n planning, execution, and result processing from the turn loop while preserving\n the existing sandbox-policy, hook, budget, and batch-execution behavior\n (#5523)\n- **[Isabel Wu / wuisabel-gif](https://github.com/wuisabel-gif)** — added\n bounded, workspace-relative multi-file diagnostics to the existing model-\n visible `lsp` tool, reusing the shared transport pool without expanding the\n 75-tool catalog (#5524)\n- **[Paulo Aboim Pinto / aboimpinto](https://github.com/aboimpinto)** — added\n portable presentation, media-attachment, and operation-digest facets to the\n command contract, then moved all seven utility command handlers onto the\n contract-backed dispatch path (#5525)\n\n**Reviewed overlap**\n\n- **[Lstarsky0](https://github.com/Lstarsky0)** — reviewed #5524 and identified\n the closed-channel, severity-filtering, and truncation-receipt gaps covered by\n the maintainer hardening pass.\n- Isabel Wu's PR #5530 independently routed the legacy plural completion\n command through the public CLI generator. Equivalent behavior, including the\n published `codew` alias registration, had already landed in the integration\n lane, so the PR is recorded here as reviewed project work rather than counted\n as a second merged contribution.\n\n**Reports and reproductions**\n\n- **[RepentStar](https://github.com/RepentStar)** — reported the stale shell-\n completion generator and missing `codew` registration that led to the\n completion fixes and upgrade guidance in #5526.\n\n
\n\n
\nv0.9.10 — retention, identity, and durable approvals\n\n**Merged or adapted contributions**\n\n- **[Sh1Zuku / SparkofSpike](https://github.com/SparkofSpike)** — restored\n `/title` as an independent, persistent terminal-window title in PR #5509,\n and contributed the Tier 1 Chinese and Indonesian documentation move to\n `docs/zh_hans/` and `docs/id/` with one-release redirect stubs (#5507,\n epic #5482)\n- **[Sun Zhenyuan / bistack](https://github.com/bistack)** — extracted the\n turn-loop stream processor in PR #5514 while preserving retry,\n cancellation, usage, TTFT, steering, and partial-response behavior\n- **[OctoBored](https://github.com/OctoBored)** — supplied the working\n no-token Star History mirror used by the localized README set after the\n canonical chart endpoint began returning a restricted placeholder (#5510)\n- **[cacdcaecawae](https://github.com/cacdcaecawae)** — added provider-neutral\n typed MCP image forwarding in PR #5515; the adapted version also emits a\n visible omission receipt for malformed image fields\n- **[cyq1017](https://github.com/cyq1017)** — approval outcomes are persisted\n before execution can proceed: receipts commit to a session-owned log first,\n unpersistable evidence blocks the tool, stale decisions are rejected, and\n resume reconstructs closed and interrupted approvals (#5491, closes #5360)\n- **[aboimpinto](https://github.com/aboimpinto)** — the TUI-owned\n dependency-injection and migration infrastructure behind safe slash-command\n extraction: seven capability facets, a dual-path dispatch seam, and\n source-aware CI enforcement so a command slice cannot claim migration while\n it still accepts concrete `App` (#5506, EPIC-005/FEAT-015 under the #5316\n umbrella they filed)\n- **[wuisabel-gif](https://github.com/wuisabel-gif)** — the TUI header now\n names the active repository or linked worktree before the branch and dirty\n marker, derived from Git's common directory and capped by shell density\n tier (#5511, the repo/worktree slice of #5437)\n- **[Lstarsky0](https://github.com/Lstarsky0)** — `docs/hooks` and\n `docs/troubleshooting` move onto the dictionary spine, retiring their inline\n bilingual literals in favor of locale dictionaries with token-aware code\n spans (#5504, closes #5337 they filed)\n\n**Reports, reproductions, and verification**\n\n- **[DingYong4223](https://github.com/DingYong4223)** — reported the\n narrow-terminal completion truncation closed by the bounded hover reveal\n (#998)\n- **[AiurArtanis](https://github.com/AiurArtanis)** and\n **[formp3](https://github.com/formp3)** — identified the completion surfaces\n affected by narrow-terminal truncation (#998)\n- **[sky-sun-moon](https://github.com/sky-sun-moon)** — reported the missing\n full per-turn input, reasoning, tool, and assistant pages that shaped Turn\n Inspector navigation (#1682)\n- **[cy2311](https://github.com/cy2311)** — reported the Windows launch path\n now covered by the Windows Terminal-aware batch launcher (#1854)\n- **[demian-welt](https://github.com/demian-welt)** — provided the reproducible\n pre-header SSE transport failure behind the bounded HTTP/1.1 retry (#4683)\n- **[BrathonBai](https://github.com/BrathonBai)** — reported the Tabby/CJK IME\n candidate-window jump that led to the cursor hide-diff-position-show\n transaction (#5023)\n- **[M-Maciej](https://github.com/M-Maciej)** — provided the organization-\n coordinator use case and 5-30 minute cadence requirement behind cancellable\n cross-turn goal delays (#5508)\n- **[thejayjetson](https://github.com/thejayjetson)** — the header\n status-indicator report that pinned the regression to a specific setting,\n having already ruled out every value, both themes, `fancy_animations`, the\n terminal auto-off rules, and a clean `codewhale doctor` (#5512)\n- **[hxfhd](https://github.com/hxfhd)** — reported the deterministic\n cross-session contamination class behind this release's session-ownership\n boundary, plus route budgeting evidence (#5518)\n- **[sfdzhmr](https://github.com/sfdzhmr)** — reported the route budgeting\n root causes that exact route-limit propagation now closes (#5516)\n\n
\n\n
\nv0.9.9 — truth and resilience\n\n**Merged or adapted contributions**\n\n- **[Lstarsky0](https://github.com/Lstarsky0)** — compact rows no longer reserve a hidden session-metrics strip ([#5486](https://github.com/codewhale-hq/Codewhale/pull/5486)); docs shell and shared component pick-text onto the typed dictionary spine ([#5488](https://github.com/codewhale-hq/Codewhale/pull/5488), [#5490](https://github.com/codewhale-hq/Codewhale/pull/5490))\n- **[Sh1Zuku / SparkofSpike](https://github.com/SparkofSpike)** — topbar session title ([#5481](https://github.com/codewhale-hq/Codewhale/pull/5481))\n- **[h3c-hexin](https://github.com/h3c-hexin)** — a concrete route/offering\n output limit now outranks the conservative 8,192-token compatibility guess\n for an uncatalogued model; routes that publish no limit stay fail-closed\n (#5461, closes #5460); every web tool surface uses the noisy-result soft\n limit (#5474); lowercase saved selectors resolve against the owning\n Z.ai/DeepSeek catalog row (#5475); configured-skill prompt paths remain\n stable across ephemeral roots and operating systems (#5492, #5473)\n- **[Gabriel-Degret](https://github.com/Gabriel-Degret)** — configurable\n auto-router classifier timeout (#5494; first contribution)\n\n**Reports, reproductions, and verification**\n\n- **[asto18089](https://github.com/asto18089)** — diagnosed the Z.ai `glm-5.2`\n casing collision and wrote the first provider-scoped fix downstream\n (Pinvou/CodeWhale#14, carried upstream in #5475)\n\n- **[hardy922](https://github.com/hardy922)** — the context-window honesty\n report that became the every-surface labeling pass (#5239)\n- **[redstar](https://github.com/redstar)** — bwrap container essentials and\n configurable extra roots (#5410)\n- **[all-lopezg](https://github.com/all-lopezg)** — SSE UTF-8 garbling on\n DeepSeek Flash with screenshots, fixed fail-closed in every dialect (#5374)\n- **[alitvak69](https://github.com/alitvak69)** — the unverified-live-pricing\n report behind the bundled fallback rates and DeepSeek V4 tiers (#5241)\n- **[wuisabel-gif](https://github.com/wuisabel-gif)** — bounded reproduction\n attempts for the macOS filtered-suite hang note on #5056\n\n
\n\n
\nv0.9.8 — marketplace, Google, Ollama Cloud\n\n**Merged or adapted contributions**\n\n- **[xiaoray-blip / Arlo](https://github.com/xiaoray-blip)** — MCP list responses omit `nextCursor` when there are no further pages ([#5336](https://github.com/codewhale-hq/Codewhale/pull/5336), reported in [#5335](https://github.com/codewhale-hq/Codewhale/issues/5335))\n- **[EvanProgramming](https://github.com/EvanProgramming)** — webhook hook\n sink no longer panics when its HTTP client fails to build (#5381); session-index\n JSONL writes are serialized so concurrent stores cannot drop an append\n (#5382)\n- **[Lstarsky0](https://github.com/Lstarsky0)** — session peek hides internal\n runtime events (#5376); thinking-ladder tests re-pinned (#5378);\n provider-count follow-ups (#5383/#5384); macOS agy fixture\n canonicalization (#5392); website zh-Hans 宪章 terminology (#5397);\n regenerated website facts harvested and corrected so Google and Ollama\n Cloud are listed and Antigravity is not advertised as a route (#5398)\n- **[mvanhorn](https://github.com/mvanhorn)** — read-only, repository-fact\n driven settings preview on the website models page (#5411, fixes #5370)\n- **[buiducnhat](https://github.com/buiducnhat)** — canonical `ultra`\n reasoning effort mapped to every provider's maximum tier (#5409); session\n titles truncated by character count instead of byte offset so CJK and\n emoji names cut at the intended width (#5415)\n- **[SparkofSpike](https://github.com/SparkofSpike)** — `/title` and the\n saved session name in the terminal tab/window title, plus the fix for the\n deadlock when the title changed during an active turn; landed as a\n discoverable alias of `/rename` on the one persisted session name (#5419)\n- **[redstar](https://github.com/redstar)** — Eden AI registered as a named\n OpenAI-compatible provider with `EDENAI_API_KEY`, `eden-ai`/`eden_ai`\n aliases, and the global and EU endpoints (#5422)\n- **[wuisabel-gif](https://github.com/wuisabel-gif)** — background verifier\n test isolated from the rustup `rustc` shim and `$HOME`, one narrow\n reliability slice of #5056 (#5423)\n\n
\n\n
\nv0.9.7 — the catalog stays ordinary\n\n**Merged or adapted contributions**\n\n- **[XhesicaFrost](https://github.com/XhesicaFrost)** — copy from the message\n context menu now takes canonical content, keeping authored Unicode,\n Markdown, and hard line breaks in the clipboard while role glyphs,\n continuation rails, and visual wrapping stay out of it (PR #5319)\n- **[h3c-hexin](https://github.com/h3c-hexin)** — split durable-session\n snapshot reads from crash recovery so an embedding host inspecting a\n session while a tool is still running no longer gets a spurious crash\n repair (PR #5320)\n- **[XiaoHuo888-hue](https://github.com/XiaoHuo888-hue)** — OrcaRouter as a\n first-class named provider with `ORCAROUTER_API_KEY`, auto-routing,\n CLI `--provider` selection, and TUI picker entries (PR #5321)\n\n**Reports and verification**\n\n- **[USTHzhanglu](https://github.com/USTHzhanglu)** — reported the Auto-Review\n shell/write regression with a Windows reproduction and audit-log evidence\n (issue #5323)\n- **[Lstarsky0](https://github.com/Lstarsky0)** — traced the Auto-Review\n regression to the exact permission-posture change and documented the safe\n recovery choices (issue #5323)\n\n
\n\n
\nv0.9.6 — fewer bumpers, truthful endings\n\n**Merged or adapted contributions**\n\n- **[Xavier Pestel / xavierpestel-ai](https://github.com/xavierpestel-ai)** —\n Mistral AI (la Plateforme) as a first-class provider route, including the\n adjustable-reasoning wire contract and its multi-turn thinking replay\n (PR #5295)\n- **[Ben Younes / ousamabenyounes](https://github.com/ousamabenyounes)** —\n inherited nested-agent depth cap, keeping child agents from widening the\n budget provided by their parent (PR #5317)\n- **[Rafael Cavalheri / rafaelcavalheri](https://github.com/rafaelcavalheri)** —\n multi-round ACP file, search, Git, patch, and explicitly enabled shell tool\n execution with cancellation and fail-closed shell safety (PR #5225)\n\n
\n\n
\nv0.9.5 — one runtime, managed controls, and uninterrupted turns\n\n**Merged or adapted contributions**\n\n- **[Sh1Zuku / SparkofSpike](https://github.com/SparkofSpike)** — stale cached\n session-title recovery so `New Session` yields to the first real prompt\n- **[Paulo Aboim Pinto / aboimpinto](https://github.com/aboimpinto)** — the\n shared alias-aware command discovery contract across the palette, slash\n completion, dispatch, and acceptance harness\n- **[Sun Zhenyuan / bistack](https://github.com/bistack)** — background\n incremental MCP Registry refreshes that return the local snapshot immediately\n- **[SKY ZHAO / skyzhao1223](https://github.com/skyzhao1223)** — prompt-based\n `model = \"auto\"` tier selection in PR #5257\n\n
\n\n
\nv0.9.4 — calmer output, recovery, and release hardening\n\n**Merged or adapted contributions**\n\n- **[Sh1Zuku / SparkofSpike](https://github.com/SparkofSpike)** — LaTeX\n rendering in PR #4981, circled-digit and keycap width handling in PR #5001,\n and actionable File-edit recovery in PR #5008; sub-agent checkpoint resume\n in PR #5242, real shell wait elapsed time in PR #5240, and keeping\n alternate-scroll off while mouse capture is active in PR #5234\n- **[XhesicaFrost](https://github.com/XhesicaFrost)** — long Windows user-PATH\n preservation in PR #5006\n- **[Paulo Aboim Pinto / aboimpinto](https://github.com/aboimpinto)** — the\n user-command dispatch acceptance contract in PR #4992\n- **[shenjackyuanjie](https://github.com/shenjackyuanjie)** — Windows\n OpenHarmony linker re-quoting for spaced SDK paths in PR #5095\n- **[bistack](https://github.com/bistack)** — MCP Registry discovery with\n Registry-first tool selection in PR #5238\n- **[vFONGv](https://github.com/vFONGv)** — the zh-CN Windows beginner guide\n with screenshots in PR #5229\n- **[mky](https://github.com/mky)** — FreeBSD build fix (`rquickjs` `bindgen` on FreeBSD, PR #5254)\n- **[cacdcaecawae](https://github.com/cacdcaecawae)** — embedder-owned sub-agent state roots (PR #5252)\n\n**Reports, reproductions, and verification**\n\n- **[DracheTek](https://github.com/DracheTek)** — the multilingual, CRLF-heavy\n File-edit failure report in issue #5003\n- **[An Ziwu / MuRongMoQing](https://github.com/MuRongMoQing)** — the Windows\n PATH-overwrite defect report in issue #4685\n\n
\n\n
\nv0.9.3 — DeepSeek Responses, canonical tools, and runtime hardening\n\n- **[greyfreedom](https://github.com/greyfreedom)** (Turisla) — the documented\n and tested authorization-order contract from PR #4980\n- **[nightt5879](https://github.com/nightt5879)** (Nightt) — foreground shell\n detachment before steering from PR #4979\n- **[Watcher24](https://github.com/Watcher24)** — the macOS File Provider\n sandbox report and reproduction in #4085\n- **[Fred Leitz / fleitz](https://github.com/fleitz)** — required\n source-candidate credit for the canonical `Bash` no-`cwd` workspace fix and\n regression in PR #4673 (issue #4674)\n\n
\n\n
\nv0.9.2 — routing, workflow, localization, and inspectability\n\n- **[greyfreedom](https://github.com/greyfreedom)** — exact repository-scoped\n allow grants and the cross-platform path-semantics repairs from PR #4761\n- **[nightt5879](https://github.com/nightt5879)** — off-event-loop terminal\n clipboard writes (PR #4896), complete locale exposure in settings (PR #4856),\n CRLF-safe edits (PR #4942), and automatic-routing reasoning preservation\n (PR #4961)\n- **[XhesicaFrost](https://github.com/XhesicaFrost)** — the configurable\n session-token header from PR #4610 and context-menu hover alignment in PR #4897\n- **[cyq1017](https://github.com/cyq1017)** — the hooks configuration/executor\n split from PR #4087\n- **[snail-vs](https://github.com/snail-vs)** (snailoniu) — OpenCode Zen's\n model-aware route, authentication, documentation, and test-isolation work\n from closed PR #4467, whose contributor commits are preserved in the\n candidate\n- **[Sh1Zuku / SparkofSpike](https://github.com/SparkofSpike)** — the zh-Hans\n translation quality review harvested from PR #4908, duplicate-session fix in\n PR #4963, LaTeX implementation from PR #4973 landed through #4974, and the\n context-menu reproduction in #4803\n- **[GTC2080](https://github.com/GTC2080)** (TaoMu) — the `dryrun` concept\n behind `/preview-request`: preview the next outbound request from the real\n request-building seam rather than a hand-rolled summary (PR #1099,\n harvested)\n- **[h3c-hexin](https://github.com/h3c-hexin)** — the non-UTF-8 `fetch_url`\n report and implementation direction harvested from PR #4909\n- **[Fred Leitz / fleitz](https://github.com/fleitz)** — required\n source-candidate credit for the canonical `Bash` no-`cwd` workspace fix and\n regression in PR #4673 (issue #4674)\n- **[LmeSzinc](https://github.com/LmeSzinc)** — the Windows CRLF `edit_file`\n reproduction, root-cause analysis, and affected-code anchors in issue #4764\n- **[atmosuwiryo](https://github.com/atmosuwiryo)** — ACP numeric-id\n compatibility (PR #4929) and the Indonesian documentation and website locale\n (PRs #4962 and #4972)\n- **[M-Maciej](https://github.com/M-Maciej)** — the expanded-by-default\n reasoning setting and report (PR #4928, issue #4925)\n- **[raphamorim](https://github.com/raphamorim)** — migration of the QA PTY\n frame parser to `rio-vt` (PR #4931)\n- **[LI-Jialu](https://github.com/LI-Jialu)** — truthful finalization of stale\n restored shell cells (PR #4937)\n- **[kobihikri](https://github.com/kobihikri)** — release-container SBOM and\n explicit provenance mode (PR #4958)\n- **[EvanProgramming](https://github.com/EvanProgramming)**,\n **[adity982](https://github.com/adity982)**, and\n **[vibecoding-skills](https://github.com/vibecoding-skills)** — equivalent\n fix direction for effective-home resolution (#4760), MCP call-once behavior\n (#4756), and streaming/non-streaming timeout separation (#4743)\n- **[antarikshraya](https://github.com/antarikshraya)** — the LaTeX transcript\n rendering report in #4957\n- **[eugenicum](https://github.com/eugenicum)** — the token-header request and\n output-presentation measurements in #4520 and #4468\n- **[whp233](https://github.com/whp233)** — the StepFun/OpenCode subscription\n route request in #4526\n- **[redjade75723](https://github.com/redjade75723)** — stale resumed-workspace\n diagnosis input from #4100\n- **[hardy922](https://github.com/hardy922)** — the native DeepSeek tool-token\n visibility report in #3880\n- **[JayBeest](https://github.com/JayBeest)** — contributor-onboarding product\n direction in #4227\n- **[elijahchan2019](https://github.com/elijahchan2019)** — the optional\n reasoning-highlight request in #4089\n- **[cy2311](https://github.com/cy2311)** — sessions rail, archive, and\n auto-resume direction in #2934\n- **[wywsoor](https://github.com/wywsoor)** — export/restore correlation\n direction in #2494\n\n
\n\n
\nv0.9.1 — provider and runtime hardening\n\n- **[h3c-hexin](https://github.com/h3c-hexin)** — calendar-anchored hourly\n automation recurrence across DST and lifecycle transitions (PR #4381),\n explicit limits for unknown local models (PR #4656 / #4655), and\n idle-timeout progress telemetry (PR #4657)\n- **[gaord](https://github.com/gaord)** — Runtime API provider registry and\n atomic provider-switch endpoints (PR #4658)\n- **[SamhandsomeLee](https://github.com/SamhandsomeLee)** — the unified\n `/skills` root catalog, audit/provenance model, validated mutations, manager\n UI, and acceptance coverage (PR #4679), plus Enter-send lag diagnosis and\n fix direction for #4605 (PR #4654; landed through the release-lane\n async-dispatch split)\n- **[Paulo Aboim Pinto / aboimpinto](https://github.com/aboimpinto)** — the\n Layer 5.1 user-command registry boundary from PR #3278; the exact authored\n evidence commit from PR #4046, preserved intact in the integration graph;\n and the #2870 follow-up audit whose metadata and malformed-sibling gaps\n shaped the final corrections. Paulo also provided the structured, redacted\n Agent Details and `current_activity` design direction preserved from\n #2694/#2889 and the real-PTY lifecycle acceptance direction from #2886\n- **[baendlorel](https://github.com/baendlorel)** — TelecomJS TokenHub provider\n and key-scoped live-catalog direction, source-partitioned refresh behavior,\n and both refresh-order regressions from PR #4370, harvested into the current\n provider architecture with co-authorship preserved\n- **[zhangweiii](https://github.com/zhangweiii)** and\n **[Sterne Lee / sternelee](https://github.com/sternelee)** — the original\n first-class OpenCode Go implementations in PRs #773 and #1050, harvested\n into the current provider architecture with co-authorship preserved in the\n landing commit\n- **[Sean Tse / seanthefuturegorilla](https://github.com/seanthefuturegorilla)**\n — the canonical OpenCode Go/Zen provider request and acceptance direction in\n #1481\n- **[nightt5879](https://github.com/nightt5879)** — `/debt` compatibility\n aliases with dispatch-consistent user-command shadowing across help and\n slash discovery (PR #4680), plus the Solarized Light background preservation\n fix for the underwater shell (PR #4471)\n- **[AiurArtanis](https://github.com/AiurArtanis)** — the Solarized Light\n v0.9.0 regression report and reproduction (#4457)\n- **[shenjackyuanjie](https://github.com/shenjackyuanjie)** — the HarmonyOS\n workflow-js bindgen, portable-pty gating, and SDK environment work\n (PR #4470)\n- **[shenyongqing](https://github.com/shenyongqing)** — the original HarmonyOS\n workflow-js bindgen approach (PR #4384), carried into the landed\n implementation with credit\n- **[Luis Mateus Vargas / luismateusvargas](https://github.com/luismateusvargas)**\n — the Windows hook-process leak reproduction, process-tree analysis, and EOF\n fix direction (#4489)\n- **[redjade75723](https://github.com/redjade75723)** — the persistent Windows\n PTY failure report that exposed lossy high-bit exit-status handling (#4100)\n- **[w1w218](https://github.com/w1w218)** — the Windows ARM64 release request\n and cross-compilation report that led to native release, npm, updater, and\n archive support (#4267)\n- **[stream2stream](https://github.com/stream2stream)** — the legacy-session\n recovery report that led to the read-only doctor diagnostic (#4032, #4539)\n- **[Sh1Zuku / SparkofSpike](https://github.com/SparkofSpike)** — the Windows\n Ctrl+O reproduction that exposed pre-pager result truncation and conflicting\n composer shortcut routing (#4482)\n- **[Lu Shihan / Angel-Hair](https://github.com/Angel-Hair)** — session-owned\n read-before-edit tracking and the explicit, backwards-compatible\n `apply_patch` replacement contract (PRs #4475 and #4476)\n- **[dmitri-0](https://github.com/dmitri-0)** — configurable cache-hit\n visibility in the phase strip (PR #4474)\n- **[Fred Leitz / fleitz](https://github.com/fleitz)** — canonical `Bash`\n no-`cwd` workspace resolution and its regression test, keeping isolated\n sub-agent commands inside their selected worktree (PR #4673; issue #4674)\n- **[Sh1Zuku / SparkofSpike](https://github.com/SparkofSpike)** — exact\n Vim-space regression reproduction and verification that the v0.9.1 input\n path already contains the needed global binding (PR #4477)\n\n
\n\n
\nv0.9.0 — underwater shell, runtime persistence & release evidence\n\nThe v0.9.0 lane grew from a maintenance sweep into the underwater shell,\nmessage-first Operate, broader Fleet and Workflow behavior, runtime-thread\npersistence, terminal selection, UTF-8 handling, internationalization, and\nrelease evidence. The reports and pull requests below materially shaped it.\n\n- **[Amuthan / amuthantamil](https://github.com/amuthantamil)** — approval-time\n transcript review report that led to live Page Up/Down, modified-arrow,\n Home/End, and mouse-wheel navigation while the decision card stays active\n (#4371)\n- **[Angel-Hair](https://github.com/Angel-Hair)** — reports that restored the\n opt-in `remember` tool to the first-turn catalog, made required user\n confirmation a real goal blocker, and added a clear recovery notice for\n cached approval denials (#4373, #4374, #4375)\n- **[Bruce / bruce6135](https://github.com/bruce6135)** — Kimi Coding Plan\n reproduction that exposed the false 1K emergency-compaction budget (#4368)\n- **[Matt Van Horn / mvanhorn](https://github.com/mvanhorn)** — first-turn\n `remember` regression coverage and the Kimi output-budget correction that\n prevents false emergency compaction (#4377, #4378)\n- **[郝某人BH / hmr-BH](https://github.com/hmr-BH)** — native Simplified\n Chinese review that replaced literal legal/doctrinal metaphors with clear\n collaboration terminology across setup and `/constitution` (#4369)\n- **[WavesMan](https://github.com/WavesMan)** — large-tree `@` completion\n reproduction that led to bounded background discovery and exact-path\n resolution on send (#4365)\n- **[SamhandsomeLee](https://github.com/SamhandsomeLee)** — input-budget-aware\n compaction work harvested from PR #4293 with co-authorship preserved\n- **[idling11](https://github.com/idling11)** — keyboard-driven keyword search\n for the docs and FAQ surfaces (PR #4364)\n- **[LeoLin990405](https://github.com/LeoLin990405)** — initial bounded\n workspace-walk approach and root-cause analysis for large-tree `@` mention\n discovery (PR #4367), harvested into the final fail-soft background\n implementation for #4365\n- **[octo-patch](https://github.com/octo-patch)** — MiniMax Messages provider\n support for MiniMax-M3 and MiniMax-M2.7 across OpenAI-compatible and Messages\n routes, regional endpoints, catalog metadata, pricing, and request coverage\n (PR #4354)\n- **[Wenshan Deng / findshan](https://github.com/findshan)** — original offline\n token/cache/cost scorecard and regression gate (#3388), extended with\n provider-aware provenance in #4335\n- **[hongqitai](https://github.com/hongqitai)** — localization extraction and\n English-locale enforcement that keep UI copy on the typed translation path\n (#4225, #4194)\n- **[nsfoxer](https://github.com/nsfoxer)** — bounded, fail-soft MCP capability\n discovery with advertised/legacy `tools/list` handling and Unicode-safe\n description formatting (#4308, harvested with co-authorship)\n- **[maple / yekern](https://github.com/yekern)** — root-cause analysis and fix\n direction for age-evicting terminal worker records from long-lived\n sub-agent state ledgers (#4217)\n- **[moduvoice](https://github.com/moduvoice)** — Korean (ko) UI locale with\n full key parity and onboarding/setup wiring (PR #4347)\n- **[qinlinwang](https://github.com/qinlinwang)** — Anthropic tool-schema\n sanitization for top-level oneOf/anyOf/allOf failures (PR #4346)\n- **[knqiufan](https://github.com/knqiufan)** — Anthropic cache-write token\n pricing at published rates (PR #4348, #4318)\n- **[Chavdar Ivanov / ci4ic4](https://github.com/ci4ic4)** — NetBSD QuickJS\n bindgen support for codewhale-workflow-js (PR #4349)\n- **[eugenicum](https://github.com/eugenicum)** — copy-paste rail-pollution\n report with code-aware fix direction (#4208)\n- **[JayBeest](https://github.com/JayBeest)** — parent\n `--disallowed-tools` inheritance through sub-agents and Fleet workers,\n harvested from PR #4096 with authorship preserved (#4042)\n- **[wuisabel-gif](https://github.com/wuisabel-gif)** — move runtime-thread\n coordination onto `parking_lot::Mutex` to remove async lock contention\n (#4243, #4149)\n- **[cyq1017](https://github.com/cyq1017)** — Windows Python stdio UTF-8\n handling and richer active-tool summaries (#4281/#4202, #3818)\n\n- **[Jeffrey Luna / Mr-Moon121](https://github.com/Mr-Moon121)** — anti-polling\n constitution for sub-agent waiting (harvested into #4097 / PR #4229 from\n PR #4098)\n\n- **[MXAntian](https://github.com/MXAntian)** — persist compaction summaries\n into thread records so `/v1` engine reloads keep compacted context (#4091)\n- **[nightt5879](https://github.com/nightt5879)** — keep native terminal\n selection usable when mouse capture is disabled, and advance fuzzy edit\n matches on UTF-8 character boundaries; preserve inline skill task text in\n PR #4372 (#4088, #4045, #3915)\n- **[gaord](https://github.com/gaord)** — add the community-maintained\n Codewhale for VS Code GUI frontend to the English and Chinese READMEs (#4035)\n- **[Darrell Thomas](https://github.com/DarrellThomas)** — remove the unused\n whale route taxonomy module and its dead tests (#4041)\n- **[Taixin Guo](https://github.com/taixinguo)** — CJK fuzzy-edit panic report\n and fix direction credited in the UTF-8 boundary patch (#3971, #4045)\n- **[CCChisato](https://github.com/CCChisato)** — preserve task text when\n sending dollar, unified-slash, and explicit skill invocations (#3915,\n co-authored)\n- **[Sun Zhenyuan / bistack](https://github.com/bistack)** — dynamic MCP server\n infrastructure and approval-gated model-started MCP servers from chat\n context (#3869, #3866, harvested with authorship preserved)\n\n
\n\n
\nv0.8.66 — release readiness, provider intake & UI hardening\n\nThe v0.8.66 release prepared the 0.8.66 package lane, hardened provider/model\nrouting and modal surfaces, advanced Hotbar/sub-agent UI reliability, and pulled\nin several community provider and bridge contributions with release credit.\n\n- **[lerugray](https://github.com/lerugray)** — Sakana AI Fugu provider\n support across config, CLI, TUI provider picker, docs, and model completions\n (#3748, harvested)\n- **[greyfreedom](https://github.com/greyfreedom)** — read-only `/config\n ask-rules` view for resolved ask-rule paths, status, and configured\n tool/command/path rules (#3569, merged)\n- **[noaft](https://github.com/noaft)** — `/links` provider docs fallback\n update, including the current Codewhale docs URL and a Baidu Qianfan docs\n link (#3621, harvested)\n- **[noaft](https://github.com/noaft)** — OpenModel provider support across\n config, CLI, TUI provider picker, docs, and registry checks (#3585,\n harvested)\n- **[pkeging](https://github.com/pkeging)** — original plugin manifest,\n discovery, CLI, and MCP foundation (#3708, #3709, #3710, merged), plus WeCom\n Bridge deployment and security documentation, including the approval-timeout\n configuration surface (#3640, harvested)\n- **[codepgq](https://github.com/codepgq)** — cross-client plugin-workflow\n migration request that shaped the explicit compatibility and trust boundary\n (#1172)\n- **[Wenshan Deng / findshan](https://github.com/findshan)** — original offline\n token/cache/cost scorecard and regression gate (#3388), extended with\n provider-aware provenance in #4335\n- **[buko](https://github.com/buko)** — precise Ctrl+O external-editor freeze\n reproduction that shaped the terminal input-pump fix (#3657)\n- **[cyq1017](https://github.com/cyq1017)** — sub-agent progress-event\n headroom report that shaped the fanout reliability hardening (#3783)\n\n
\n\n
\nv0.8.63 — sub-agent budgets, command extraction & reliability\n\n\nThe v0.8.63 release hardened sub-agent fanout with token-budget governance and\nqueue-and-drain admission, split the TUI command surface into focused modules,\nand landed reliability fixes for app-server teardown, JavaScript-execution\nproxying, and DeepSeek thinking tool calls — alongside community contributions.\n\n- **[donglovejava](https://github.com/donglovejava)** — per-worker sub-agent\n token-budget enforcement, so a `token_budget`/`max_tokens` on an individual\n `agent` call bounds that worker mid-run with a clean `budget_exhausted` stop\n (#3321, harvested)\n- **[cyq1017](https://github.com/cyq1017)** — `js_execution` proxy-environment\n handling (#3331), Hugging Face API-key env in the auth probe (#3329), and Codex\n Responses request retry (#3344) — harvested into the train\n- **[aboimpinto](https://github.com/aboimpinto)** — FEAT-005 command extraction:\n core/session command groups split into focused modules via `RegisterCommand`,\n `/swarm` migration, and Gherkin acceptance coverage (#3330, merged literally\n with authorship preserved)\n- **[wuisabel-gif](https://github.com/wuisabel-gif)** — tear down the delegated\n serve/app-server child process when the dispatcher exits (#3259 / #3317)\n- **[nightt5879](https://github.com/nightt5879)** — keep the onboarding marker in\n the codewhale home view (#3302) and branch-hygiene check hardening (#3348)\n- **[gaord](https://github.com/gaord)** — preserve thinking/tool blocks when\n seeding a thread from a saved session, plus Hugging Face provider env (#3329)\n- **[greyfreedom](https://github.com/greyfreedom)** — persist ask-permission rules\n from approvals and stabilize the CI verifier/provider-registry checks\n- Reports that shaped fixes: **[lordwedggie](https://github.com/lordwedggie)**\n (#3331 proxy env), **[Final527](https://github.com/Final527)** (#3240 legacy\n state migration), **[dxfq](https://github.com/dxfq)** (#3228 sidebar default)\n\n
\n\n
\nv0.8.62 — provider/model routing, TOML comment preservation & community closeout\n\n\nThe v0.8.62 release retuned provider/model routing (GLM-5.2 as the default direct\nZ.AI model, `type: \"explore\"` sub-agents defaulting to the cheaper same-family\nsibling), added TOML comment preservation and the Codewhale-only skill discovery\ngate, and shipped the static Linux x64 musl binary — alongside a broad community\ncloseout and a retroactive credit reconciliation pass.\n\n- **[zlh124](https://github.com/zlh124)** — preserve user comments and formatting\n when rewriting `config.toml`/`settings.toml`/`tui.toml` (with a malformed-file\n fallback) and Linux build deps in the cargo install guides (#3270)\n- **[idling11](https://github.com/idling11)** — Kimi `type:object` schema root for\n all parameter shapes (#3281), `approval_mode` restore on Plan→Agent with a\n wait-for-user guard (#3279), and workroom metadata draft types\n- **[LeoLin990405](https://github.com/LeoLin990405)** — Poppler `pdftotext -v`\n detection (#1667), session persistence before stall/cancel recovery (#2739),\n and debounced thinking-stream re-renders (#1620)\n- **[nightt5879](https://github.com/nightt5879)** — Codewhale-only skill discovery\n gate (`[skills].scan_codewhale_only`) ignoring cross-tool directories (#3296) and\n app-server no-auth loopback docs\n- **[reidliu41](https://github.com/reidliu41)** — slash commands exposed as hotbar\n actions (#3269)\n- **[wavezhang](https://github.com/wavezhang)** — static Linux x64 (musl) release\n binaries\n- **[wuisabel-gif](https://github.com/wuisabel-gif)** — per-tool snapshot gate\n respecting `[snapshots].enabled` (#3292) and composer history written under\n `.codewhale`\n- **[gaord](https://github.com/gaord)** — `workspace_follow_symlinks` setting for\n symlink-aware tool operations with hardened path handling\n- **[greyfreedom](https://github.com/greyfreedom)** — ask-permission rules honored\n at runtime (#3295)\n- **[aboimpinto](https://github.com/aboimpinto)** — EPIC-001 command-boundary\n replay and user-registry review feedback\n- **[h3c-hexin](https://github.com/h3c-hexin)** — volatile workspace path moved\n out of the static system prefix (prefix-cache hygiene)\n- **[hongchen1993](https://github.com/hongchen1993)** — heuristic-only auto routing\n when the flash router is unavailable\n- **[lucaszhu-hue](https://github.com/lucaszhu-hue)** — Atlas Cloud provider setup\n docs\n- Retroactive reconciliation (shipped earlier, credited now):\n **[manaskarra](https://github.com/manaskarra)** / **[xfy6238](https://github.com/xfy6238)** (#1157),\n **[djairjr](https://github.com/djairjr)** (#1309 alongside reidliu41),\n **[Geallier](https://github.com/Geallier)** (#1470),\n **[quentin-lian](https://github.com/quentin-lian)** / **[k0tran](https://github.com/k0tran)** (#1531 / #1992),\n **[F1LT3R](https://github.com/F1LT3R)** (#1656),\n **[cmyyy](https://github.com/cmyyy)** (#1842),\n **[Final527](https://github.com/Final527)** (#3058)\n\n
\n\n
\nv0.8.61 — runtime control plane & community closeout\n\n\nThe v0.8.61 release was a community closeout: the runtime control plane, provider\npatches, and TUI fixes landed alongside first-time and returning contributor work.\n\n- **[idling11](https://github.com/idling11)** — DeepInfra provider support with\n OpenAI-compatible routing and model registry entries (#3235, closes #3231)\n- **[greyfreedom](https://github.com/greyfreedom)** — atomic ask-only\n permission-rule persistence so an execution-policy rule survives the write\n that triggered the prompt (#3233)\n- **[VincentCorleone](https://github.com/VincentCorleone)** — WeChat bridge\n (`integrations/weixin-bridge`) leveraging Feishu + Tencent OpenClaw (#3206)\n- **[nightt5879](https://github.com/nightt5879)** — whale-accent rename (#3197)\n and `$skillname` aliases for `/skill` activation (#3241)\n- **[mvanhorn](https://github.com/mvanhorn)** — non-DeepSeek model pricing\n coverage (#3201)\n- **[cyq1017](https://github.com/cyq1017)** — Telegram polling transport\n (#3195) and VS Code read-only API documentation (#3013)\n- **[RobertEmprechtinger](https://github.com/RobertEmprechtinger)** — mobile\n event history (#3220)\n- **[gaord](https://github.com/gaord)** — runtime-API session save (#3199)\n- **[hongchen1993](https://github.com/hongchen1993)** — `DEEPSEEK_BASE_URL` /\n `MODEL` honored in `exec` (#3221)\n\n
\n\n
\nForward track — recent v0.9 work (newest)\n\n\n- **[xyuai](https://github.com/xyuai)** — canonical Codewhale settings path,\n provider persistence, provider picker, logout-scope, and MiMo auth cleanup\n work (#2730, #2714, #2715, #2717, #2718)\n- **[shenjackyuanjie](https://github.com/shenjackyuanjie)** — HarmonyOS /\n OpenHarmony porting work and MatePad Edge validation trail (#2634)\n- **[ousamabenyounes](https://github.com/ousamabenyounes)** — AZERTY/AltGr\n composer shortcut fix for Windows keyboard layouts (#2863, #2867)\n- **[reidliu41](https://github.com/reidliu41)** — hotbar action-registry\n foundation and Ollama model-completion cleanup for the forward track (#2866,\n #2742)\n- **[ljm3790865](https://github.com/ljm3790865)** — multi-tab\n core/persistence foundation and broader tab collaboration direction (#2864,\n #2753)\n- **[sximelon](https://github.com/sximelon)** — saved-session resume footer\n hint work plus provider-trait metadata registry direction reviewed and\n harvested for the forward track (#2758, #2760, #2479)\n- **[aboimpinto](https://github.com/aboimpinto)** — sidebar command polish and\n pausable custom-command lifecycle direction harvested into the forward track,\n plus the directly merged command-support boundary cleanup and broader command\n layer design direction (#2788, #2732, #2871, #2851, #2791)\n- **[AdityaVG13](https://github.com/AdityaVG13)** — Workflow orchestration\n and cost-tracking drafts that shaped the maintained workflow IR and\n TraceStore foundation (#2482, #2486)\n- **[lbcheng888](https://github.com/lbcheng888)**,\n **[AiurArtanis](https://github.com/AiurArtanis)**, and\n **[nasus9527](https://github.com/nasus9527)** — VS Code extension scaffold\n direction, Agent View request, and IDE plugin request that shaped the\n official Phase 0 extension (#1022, #1584, #2580)\n- **[HUQIANTAO](https://github.com/HUQIANTAO)** — `web_run` cache-state\n lock-splitting, turn-metadata prefix-cache stability, and project-context\n cache work (#2502, #2517, #2636)\n- **[idling11](https://github.com/idling11)** — PlanArtifact continuity,\n dense tool-call transcript collapse, sidebar detail popovers, and\n HarnessPosture provider/model policy direction (#2733, #2738, #2734,\n #2741, #2692, #2694, #2693)\n- **[h3c-hexin](https://github.com/h3c-hexin)** — sub-agent model inheritance,\n configured `skills_dir` discovery, prompt-environment stability, and static\n prompt composer direction (#2736, #2737, #2786)\n- **[gaord](https://github.com/gaord)** — runtime thread workspace updates and\n completed-thread saved-session API work (#2640, #2639)\n- **[cyq1017](https://github.com/cyq1017)** — trusted workspace MCP config,\n provider auth rollback, custom search endpoint, custom completion sound,\n restore-listing, and pending-input delivery-mode label work (#2751, #2755,\n #2510, #2512, #2513, #2532, #2054)\n- **[yusufgurdogan](https://github.com/yusufgurdogan)** — Sofya search\n provider implementation harvested as a non-default search backend (#2790)\n- **[LeoAlex0](https://github.com/LeoAlex0)** — runtime prompt metadata cache\n direction harvested into the maintained prompt/cache path (#2687);\n `allow_shell` prefix-cache decoupling and `visibility=\"internal\"`\n explanation for mode-flip stability (#2949, #2951)\n- **[hongchen1993](https://github.com/hongchen1993)** — Volcengine provider\n in TUI dispatcher and dispatcher API-key preference (#2923, #2928)\n- **[NASLXTO](https://github.com/NASLXTO)** and\n **[wuxixing](https://github.com/wuxixing)** — large-workspace startup\n reports that shaped the bounded project-context fallback (#697, #1827)\n- **[shuxiangxuebiancheng](https://github.com/shuxiangxuebiancheng)**,\n **[hongqitai](https://github.com/hongqitai)**, and\n **[cyq1017](https://github.com/cyq1017)** — third-party\n OpenAI-compatible path-suffix report and follow-up review trail (#1874,\n #2508, #2506)\n\n\n
\n\n
\nRecurring & historical contributors\n\n\n- **[merchloubna70-dot](https://github.com/merchloubna70-dot)** — 28 PRs spanning features, fixes, and VS Code extension scaffolding (#645–#681)\n- **[WyxBUPT-22](https://github.com/WyxBUPT-22)** — Markdown rendering for tables, bold/italic, and horizontal rules (#579)\n- **[loongmiaow-pixel](https://github.com/loongmiaow-pixel)** — Windows + China install documentation (#578)\n- **[20bytes](https://github.com/20bytes)** — User memory docs and help polish (#569)\n- **[staryxchen](https://github.com/staryxchen)** — glibc compatibility preflight (#556)\n- **[Vishnu1837](https://github.com/Vishnu1837)** — glibc compatibility improvements and terminal restoration on SIGINT/SIGTERM (#565, #1586)\n- **[shentoumengxin](https://github.com/shentoumengxin)** — Shell `cwd` boundary validation (#524)\n- **[toi500](https://github.com/toi500)** — Windows paste fix report\n- **[xsstomy](https://github.com/xsstomy)** — Terminal startup repaint report\n- **[melody0709](https://github.com/melody0709)** — Slash-prefix Enter activation report\n- **[lloydzhou](https://github.com/lloydzhou)** and **[jeoor](https://github.com/jeoor)** — Compaction cost reports; lloydzhou also contributed deterministic environment context (#813, #922) and KV prefix-cache stabilisation (#1080)\n- **[Agent-Skill-007](https://github.com/Agent-Skill-007)** — README clarity pass (#685)\n- **[woyxiang](https://github.com/woyxiang)** — Windows install documentation (#696)\n- **[wangfeng](mailto:wangfengcsu@qq.com)** — Pricing/discount info update (#692)\n- **[zichen0116](https://github.com/zichen0116)** — CODE_OF_CONDUCT.md (#686)\n- **[dfwqdyl-ui](https://github.com/dfwqdyl-ui)** — model ID case-sensitivity compatibility report (#729)\n- **[Oliver-ZPLiu](https://github.com/Oliver-ZPLiu)** — stale `working...` state bug report, Windows clipboard fallback, MCP Streamable HTTP session fixes, and Homebrew tap automation (#738, #850, #1643, #1631)\n- **[reidliu41](https://github.com/reidliu41)** — resume hint, workspace trust persistence, Ollama provider support, thinking-block stream finalization, CI cache hardening, streaming wrap, and DeepSeek model completions (#863, #870, #921, #1078, #1603, #1628, #1601)\n- **[xieshutao](https://github.com/xieshutao)** — plain Markdown skill fallback (#869)\n- **[GK012](https://github.com/GK012)** — npm wrapper `--version` fallback (#885)\n- **[y0sif](https://github.com/y0sif)** — parent turn-loop wakeup after direct child sub-agent completion (#901)\n- **[mac119](https://github.com/mac119)** and **[leo119](https://github.com/leo119)** — `codewhale update` command documentation (#838, #917)\n- **[dumbjack](https://github.com/dumbjack)** / **浩淼的mac** — command-safety null-byte hardening (#706, #918)\n- **macworkers** — fork confirmation with the new session id (#600, #919)\n- **zero** and **[zerx-lab](https://github.com/zerx-lab)** — notification condition config and richer OSC 9 notification body (#820, #920)\n- **[chnjames](https://github.com/chnjames)** — cached @mention completions, config recovery polish, and Windows UTF-8 shell output (#849, #927, #982, #1018)\n- **[angziii](https://github.com/angziii)** — config safety, async cleanup, Docker hardening, and command-safety fixes (#822, #824, #827, #831, #833, #835, #837)\n- **[elowen53](https://github.com/elowen53)** — UTF-8 decoding and deterministic test coverage (#825, #840)\n- **[wdw8276](https://github.com/wdw8276)** — `/rename` command for custom session titles (#836)\n- **[banqii](https://github.com/banqii)** — `.cursor/skills` discovery path support (#817)\n- **[junskyeed](https://github.com/junskyeed)** — dynamic `max_tokens` calculation for API requests (#826)\n- **Hafeez Pizofreude** — SSRF protection in `fetch_url` and Star History chart\n- **Unic (YuniqueUnic)** — Schema-driven config UI (TUI + web)\n- **Jason** — SSRF security hardening\n- **[axobase001](https://github.com/axobase001)** — snapshot orphan cleanup, npm install guards, session telemetry fixes, model-scope cache clear, symlinked skill support, npm mirror-escape-hatch guidance, proxy preservation for child tasks, mobile runtime control, Docker toolbox docs, large-output receipts, and activity detail context (#975, #1032, #1047, #1049, #1052, #1019, #1051, #1056, #1608, #1968, #2296, #2297, #2298)\n- **[MengZ-super](https://github.com/MengZ-super)** — `/theme` command foundation and SSE gzip/brotli decompression (#1057, #1061)\n- **[DI-HUO-MING-YI](https://github.com/DI-HUO-MING-YI)** — Plan-mode read-only sandbox safety fix (#1077)\n- **[bevis-wong](https://github.com/bevis-wong)** — precise paste-Enter auto-submit reproducer (#1073)\n- **[Duducoco](https://github.com/Duducoco)** and **[AlphaGogoo](https://github.com/AlphaGogoo)** — skills slash-menu and `/skills` coverage fix (#1068, #1083)\n- **[ArronAI007](https://github.com/ArronAI007)** — window-resize artifact fix for macOS Terminal.app and ConHost (#993)\n- **[THINKER-ONLY](https://github.com/THINKER-ONLY)** — OpenRouter and custom-endpoint model-ID preservation (#1066)\n- **[Jefsky](https://github.com/Jefsky)** — DeepSeek endpoint correction report (#1079, #1084)\n- **[wlon](https://github.com/wlon)** — NVIDIA NIM provider API-key preference diagnosis (#1081)\n- **[Horace Liu](https://github.com/liuhq)** — Nix package support and install documentation (#1173)\n- **[jieshu666](https://github.com/jieshu666)** — terminal repaint flicker reduction (#1563)\n- **[gordonlu](https://github.com/gordonlu)** — Windows Enter / CSI-u input fix, status picker localization (7 MessageIds), approval dialog localization across 7 locales, and mode picker + composer Vim indicator localization across 7 locales (#1612, #2896, #2891, #2239)\n- **[mdrkrg](https://github.com/mdrkrg)** — first-run onboarding crash fix when the API key is missing (#1598)\n- **[Aitensa](https://github.com/Aitensa)** — CJK wrapping propagation for diff and pager output (#1622)\n- **[qiyan233](https://github.com/qiyan233)** — legacy DeepSeek CN provider alias compatibility (#1645)\n- **[zlh124](https://github.com/zlh124)** — WSL2/headless startup report, clipboard-init fix, Codewhale tab-title polish, localized context-menu labels, and approval-dialog fixes (#1772, #1773, #2319, #2320, #2325)\n- **[aboimpinto](https://github.com/aboimpinto)** — Windows alt-screen\n logging, Home/End composer, runtime log follow-ups, sidebar command polish,\n and pausable command lifecycle work (#1774, #1776, #1748, #1749, #1782,\n #1783, #2788, #2732)\n- **[LeoLin990405](https://github.com/LeoLin990405)** — provider model passthrough, reasoning replay, thinking-only turn, and Windows quoting fixes (#1740, #1743, #1742, #1744)\n- **[nightt5879](https://github.com/nightt5879)** — Ctrl+C prompt restore, provider registry drift docs, tool-search defaults, footer git branch display, and startup prompt interactivity (#1764, #2274, #2344, #2347, #2373)\n- **[donglovejava](https://github.com/donglovejava)** — paste @file consolidation, CJK panic fix, user feedback, RLM routing, edit_file retry, hidden-worktree discovery skip, IME composer routing, and eager shell companion tools (#2154-#2168, #2302, #2329, #2330, #2331)\n- **[encyc](https://github.com/encyc)** — session token breakdown in footer and `/status` (#2152)\n- **[saieswar237](https://github.com/saieswar237)** — review pipeline docs (#2178)\n- **[sximelon](https://github.com/sximelon)** — paste Enter suppression, key handler extraction (#2174, #2042)\n- **[nanookclaw](https://github.com/nanookclaw)** — search provider in doctor output (#2135)\n- **[Sskift](https://github.com/Sskift)** — CLI default env override prevention and statusline footer clearing (#2119, #2248)\n- **[xin1104](https://github.com/xin1104)** — Homebrew codewhale binary install (#2105)\n- **[mrluanma](https://github.com/mrluanma)** — Metaso search provider (#2059)\n- **[Lellansin](https://github.com/Lellansin)** — skip config merge at home dir (#2055)\n- **[zhuangbiaowei](https://github.com/zhuangbiaowei)** — update release channels and legacy MCP SSE fixes (#2145, #2301)\n- **[cy2311](https://github.com/cy2311)** — Windows `.bat` launcher for Codewhale (#1861)\n- **[LING71671](https://github.com/LING71671)** — effective cost currency context, custom provider docs, and core tool taxonomy prompt block (#1902, #2287, #2292)\n- **[dzyuan](https://github.com/dzyuan)** — Volcengine provider support with DeepSeek V4 Pro/Flash models (#1993)\n- **[mvanhorn](https://github.com/mvanhorn)** — live request-shape test factories and global `~/.agents/AGENTS.md` fallback (#2107, #2236)\n- **[malsony](https://github.com/malsony)** — Matrix-inspired theme and theme picker improvements (#2129)\n- **[gaord](https://github.com/gaord)** — external GUI runtime event bridge, session detail serialization, and skills API discovery alignment (#2133, #2265, #2285)\n- **[yuanchenglu](https://github.com/yuanchenglu)** — Feishu per-chat model switching (#2149)\n- **[HUQIANTAO](https://github.com/HUQIANTAO)** — Xiaomi balance/status work, stalled-turn recovery, approval intent summaries, mobile smoke/QR support, Claude theme, and broad docs/test/CI coverage (#2257, #2267, #2283, #2384, #2385, #2389, #2403, #2440-#2458, #2460)\n- **[h3c-hexin](https://github.com/h3c-hexin)** — web-search URL decoding, prompt/instructions override hooks, sub-agent guidance, SSRF fake-IP trust configuration, and prompt-cache-friendly environment placement (#2245, #2311, #2313, #2314, #2354, #2355, #2356)\n- **[tdccccc](https://github.com/tdccccc)** — approval prompt key-detail and shell-preview work harvested into the maintained approval path (#1991, #2269)\n- **[AresNing](https://github.com/AresNing)** — first-run guide, message-submit hook transform design, and turn-end observer hook work harvested into the maintained hooks path (#2278, #2318, #2434, #2578)\n- **[Implementist](https://github.com/Implementist)** — Volcengine Ark search provider and reliability hardening (#2426, #2429, #2439)\n- **[lihuan215](https://github.com/lihuan215)** — Unix socket hook sink design harvested into the opt-in hook event path (#2333, #2430)\n- **[AdityaVG13](https://github.com/AdityaVG13)** — Xiaomi MiMo provider support (#2246)\n- **[New2Niu](https://github.com/New2Niu)** — macOS display notifications (#2260)\n- **[AiurArtanis](https://github.com/AiurArtanis)** — Solarized Light theme and\n canonical-background regression report (#2270, #4457)\n- **[Lee-take](https://github.com/Lee-take)** — task migration and session environment isolation fixes (#2272)\n- **[LeoAlex0](https://github.com/LeoAlex0)** — session persistence fixes for message counts and tool-output cache preservation (#2388, #2395)\n- **[jimmyzhuu](https://github.com/jimmyzhuu)** — Baidu AI Search backend for `web_search` (#2371)\n- **[rockyzhang](https://github.com/rockyzhang)** — RISC-V prebuilt binary support (#2383)\n- **[mo-vic](https://github.com/mo-vic)** — `/purge` slash command for agent-driven context pruning (#2387)\n- **[hufanexplore](https://github.com/hufanexplore)** — Java and Vue language-server defaults (#2367)\n- **[hoclaptrinh33](https://github.com/hoclaptrinh33)** — Vietnamese localization support (#2358)\n- **[AccMoment](https://github.com/AccMoment)** — proxy option for the update command (#2281)\n- **[idling11](https://github.com/idling11)** — durable debt ledger and `/hunt` rename/trophy-card work (#2161, #2306)\n- **[cyq1017](https://github.com/cyq1017)** — runtime event envelope, render-diff debug logging, and deterministic composer history flushing (#2252, #2332, #2375)\n- **[hongqitai](https://github.com/hongqitai)** — state schema parent-entry support and clippy/fmt cleanup (#2308, #2432)\n- **[BryonGo](https://github.com/BryonGo)** — effective-model compaction budgeting fix (#2437)\n- **[xyuai](https://github.com/xyuai)** — provider persistence to config, /logout scope clarification, provider picker key replacement shortcut, MiMo auth state cleanup (#2714, #2715, #2717, #2718)\n- **[RefuseOdd](https://github.com/RefuseOdd)** — configurable `path_suffix` for OpenAI-compatible endpoints (#2558)\n\n\n
\n\n
\nv0.8.48 — reports, repros & verification (earliest listed)\n\nReports, repros, and verification that shaped v0.8.48 also deserve visible\ncredit: **[@buko](https://github.com/buko)**, **[@yyyCode](https://github.com/yyyCode)**,\n**[@gaslebinh-glitch](https://github.com/gaslebinh-glitch)**, **[@Dr3259](https://github.com/Dr3259)**,\n**[@lpeng1711694086-lang](https://github.com/lpeng1711694086-lang)**, **[@VerrPower](https://github.com/VerrPower)**,\n**[@yan-zay](https://github.com/yan-zay)**, **[@jretz](https://github.com/jretz)**,\n**[@Neo-millunnium](https://github.com/Neo-millunnium)**, **[@caeserchen](https://github.com/caeserchen)**,\n**[@T-Phuong-Nguyen](https://github.com/T-Phuong-Nguyen)**, **[@zhyuzhyu](https://github.com/zhyuzhyu)**,\n**[@0gl20shk0sbt36](https://github.com/0gl20shk0sbt36)**, **[@hatakes](https://github.com/hatakes)**,\n**[@goodvecn-dev](https://github.com/goodvecn-dev)**, **[@bevis-wong](https://github.com/bevis-wong)**,\n**[@PurplePulse](https://github.com/PurplePulse)**, and **[@nbiish](https://github.com/nbiish)**.\n\n---\n\n
\n\n
\nReconciled credits — earlier contributors restored to the record\n\nA credit-reconciliation pass mapped every shipped commit author to a GitHub\nhandle and found these contributors whose merged work was not yet listed here or\nin the changelog. Restoring them with thanks — every one shipped real code.\n\n- **[MoriTang](https://github.com/MoriTang)** — account balance status-bar item, with a request timeout, reused HTTP client, stale-balance-on-failure handling, and DeepSeek-gated display\n- **[mars-base](https://github.com/mars-base)** — session title shown in the composer border and `gh` discovery across common install paths (#836)\n- **[Giggitycountless](https://github.com/Giggitycountless)** — auto-add `.deepseek/` to `.gitignore`, gitignore-check robustness, and `/clear` resetting the Todos panel\n- **[Inference1](https://github.com/Inference1)** — vLLM provider support, README pricing/structure clarity, and the Model Studio reasoning route guard: a fail-closed host check so Alibaba's `enable_thinking` never reaches a custom gateway, plus catching that Codewhale was sending a disable switch to the always-thinking `qwen3.8-max` (#737, #776, #5233)\n- **[membphis](https://github.com/membphis)** — bordered Markdown table rendering and Shift+Enter newline in the composer (#801)\n- **[JasonOA888](https://github.com/JasonOA888)** — `web_run` network-policy enforcement and refusing to snapshot `$HOME` (#798, #800)\n- **[tuohai666](https://github.com/tuohai666)** — recursive skills-directory reading plus hook-dispatch and approval-branch test coverage (#811)\n- **[xuezhaoyu](https://github.com/xuezhaoyu)** — DEC 2026 synchronized-update flicker fix for GPU terminals, guaranteeing `END_SYNC_UPDATE` even when a draw fails\n- **[manaskarra](https://github.com/manaskarra)** — global `~/.deepseek/AGENTS.md` fallback loading (#1157)\n- **[gerryqi](https://github.com/gerryqi)** — wrap fire-and-forget `spawn_blocking` calls with a panic dump (#810)\n- **[ccomma](https://github.com/ccomma)** — skip snapshots for dangerous workspaces (#804)\n- **[AGSaturn](https://github.com/AGSaturn)** — preserve requested model-ID casing in registry resolution (#733)\n- **[wucm667](https://github.com/wucm667)** — accept provider-prefixed DeepSeek model IDs (#794)\n- **[quentin-lian](https://github.com/quentin-lian)** — portable-pty 0.9 upgrade for LoongArch64 support (#1992)\n- **[Beltran12138](https://github.com/Beltran12138)** — treat `deepseek-chat` / `deepseek-reasoner` aliases as reasoning models\n- **[chuntseevolving](https://github.com/chuntseevolving)** — send `TurnStarted` before snapshot to prevent WSL2 timeout\n- **[lawrencewzen](https://github.com/lawrencewzen)** — preserve UTF-8 while stripping ANSI\n- **[hhhaiai](https://github.com/hhhaiai)** — keep workspace skills visible when the prompt budget truncates\n- **[khalid-hungerstation](https://github.com/khalid-hungerstation)** — bundle the delegate skill alongside skill-creator\n- **[Anyexyz](https://github.com/Anyexyz)** — GitHub Actions workflow to sync with the CNB repo\n- **[nightfallsad](https://github.com/nightfallsad)** — clearer `/continue` hint copy\n- **[zxyasfas](https://github.com/zxyasfas)** — align Rust MSRV references with the workspace (#739)\n\n_A follow-up audit of harvested commits (work reimplemented onto a maintainer\nbranch rather than merged) surfaced contributors whose machine-readable credit\nwas dropped. Restoring them here — every one shipped real code:_\n\n- **[CrepuscularIRIS](https://github.com/CrepuscularIRIS)** — OpenHarmony→Linux npm binary mapping, O(1) job-panel refresh, file-mention UTF-8 boundary safety, Kitty keyboard protocol on Windows, and auto low-motion under Termius/SSH (#1479, #1483, #1494, #1495, #1499, #1475)\n- **[MMMarcinho](https://github.com/MMMarcinho)** — `image_analyze` vision tool (#1467)\n- **[MeAiRobot](https://github.com/MeAiRobot)** — toast-stack overlay z-order fix (#1485)\n- **[NorethSea](https://github.com/NorethSea)** — `update` refreshing the sibling TUI binary (#1492)\n- **[SamhandsomeLee](https://github.com/SamhandsomeLee)** — bundled\n v4-best-practices skill (#1448) and input-budget-aware compaction trigger\n (#4293)\n- **[YaYII](https://github.com/YaYII)** — opt-in `/translate` command (#1462)\n- **[sandofree](https://github.com/sandofree)** — Tavily and Bocha `web_search` backends (#1294)\n- **[tiger-dog](https://github.com/tiger-dog)** — approval one-line banner and Markdown underscore handling (#1455)\n- **[Jianfengwu2024](https://github.com/Jianfengwu2024)** — preserving MSVC toolchain vars in the child environment (#1487)\n- **[wplll](https://github.com/wplll)** — prompt-cache warmup keys, tool-catalog handling, a dedup test, and pack ordering (#2390, #2391, #2392, #2393)\n\nAdditional harvested PRs from the same audit, credited to contributors already\nlisted above: **[axobase001](https://github.com/axobase001)** (#2400, #2405, #2406, #2407, #2408, #2415), **[cyq1017](https://github.com/cyq1017)** (#2516, #2534, #2540), **[Oliver-ZPLiu](https://github.com/Oliver-ZPLiu)** (#1451, #1456), **[reidliu41](https://github.com/reidliu41)** (#1444, #1493), **[lucaszhu-hue](https://github.com/lucaszhu-hue)** (#1436, #2343), **[h3c-hexin](https://github.com/h3c-hexin)** (#1480), **[Duducoco](https://github.com/Duducoco)** (#1345), **[zhuangbiaowei](https://github.com/zhuangbiaowei)** (#1416), **[wdw8276](https://github.com/wdw8276)** (#1498), and **[buko](https://github.com/buko)** (#2377).\n\n_A further machine-credit pass restored these contributors, missing from both the\nlist above and the contribution graph (AUTHOR_MAP entries added; logins/IDs\nverified against the GitHub user API) — every one shipped real code:_\n\n- **[1Git2Clone](https://github.com/1Git2Clone)** — `Ctrl+P`/`Ctrl+N` slash-menu navigation\n- **[rockeverm3m](https://github.com/rockeverm3m)** — community ACP adapter reference in the docs\n- **[hxy91819](https://github.com/hxy91819)** — stable MCP tool ordering for prefix-cache stability (#1319)\n- **[heloanc](https://github.com/heloanc)** — Home/End keys moving the cursor in the input box (#1246)\n\n**Earlier reports, proposals and reviewed overlap**\n\n- **[dajiaohuang](https://github.com/dajiaohuang)** — independently diagnosed the local-model output-budget problem and submitted a reviewed patch; equivalent behavior had already shipped ([#5883](https://github.com/codewhale-hq/Codewhale/pull/5883)).\n- **[Edouard-Legoupil](https://github.com/Edouard-Legoupil)** — proposed user-controlled skill evolution from repeated work and corrections ([#5860](https://github.com/codewhale-hq/Codewhale/issues/5860)).\n- **[freedomlovesfrank](https://github.com/freedomlovesfrank)** — proposed an optional Rust allocator alongside the existing default ([#5872](https://github.com/codewhale-hq/Codewhale/issues/5872)).\n- **[zyxrealhero](https://github.com/zyxrealhero)** — reported malformed tool-call history after a Runtime restart, with a reproduction and payload analysis ([#5823](https://github.com/codewhale-hq/Codewhale/issues/5823)).\n- **[cmdcorp6534](https://github.com/cmdcorp6534)** — reported Chinese IME pre-edit and composer behavior in Windows Terminal, including input shown behind modal dialogs ([#2323](https://github.com/codewhale-hq/Codewhale/issues/2323)).\n- **[ivysrono](https://github.com/ivysrono)** — proposed switching to a configured backup profile after provider rate-limit errors ([#855](https://github.com/codewhale-hq/Codewhale/issues/855)).\n- **[JoeKerF](https://github.com/JoeKerF)** — proposed desktop project and task workflows with managed runtime startup, recovery, and updates ([#4986](https://github.com/codewhale-hq/Codewhale/issues/4986)).\n- **[ShikiSuen](https://github.com/ShikiSuen)** — provided a detailed reproduction of SwiftPM test failures inside the macOS sandbox ([#2617](https://github.com/codewhale-hq/Codewhale/issues/2617)).\n\n
\n\n---\n\nMissed someone? Open an issue or PR — credit is kept current, and names are happily added. See [CONTRIBUTING.md](../CONTRIBUTING.md) to get started.\n" + "sha256": "2c6db2195f382f94bd39a2aa2fa693e7759c7124918eb96aaf2f8bcda474c7a6", + "content": "# Contributors\n\nCodewhale is built in the open with a growing community of contributors. Every\nissue report and pull request is real project work — welcome at any experience\nlevel. This is the full per-PR contributor record, grouped into release/time\nbands with the newest band first so it stays scannable. Expand any band to see\neveryone.\n\nFor the live list, see the\n[GitHub contributors page](https://github.com/codewhale-hq/CodeWhale/graphs/contributors),\n[`AUTHOR_MAP`](https://github.com/codewhale-hq/CodeWhale/blob/main/.github/AUTHOR_MAP),\nand [CHANGELOG.md](../CHANGELOG.md).\n\n## Organizational thanks\n\n- **[DeepSeek](https://github.com/deepseek-ai)** — the models and support that got this project started. 感谢 DeepSeek 提供模型与支持。\n- **[DataWhale](https://github.com/datawhalechina)** 🐋 — for the support and for welcoming us into the Whale Brother family. 感谢 DataWhale 的支持。\n- **[OpenWarp](https://github.com/zerx-lab/warp)** — for prioritizing Codewhale support and collaborating on a better terminal-agent experience.\n- **[Open Design](https://github.com/nexu-io/open-design)** — for support and collaboration around design-forward agent workflows.\n\nThe maintainer rule: reports and PRs are real project work, even when the final\npatch has to be narrowed, delayed, or harvested into a maintainer branch.\nAdapted contributions keep visible credit in commits and PR bodies, the\nchangelog or release notes, and this contributor record.\n\n---\n\n## Contributors by time\n\n
\nUnreleased\n\n**Merged or adapted contributions**\n\n- **[printf033](https://github.com/printf033)** — confined-file I/O on Android/Termux: SELinux-denied `open(\"/\", O_RDONLY|O_DIRECTORY)` anchor replaced with an `O_PATH` walk (Linux-cfg-gated) plus a re-materialized final parent, restoring journal, compaction and artifact writes in search-only SELinux domains ([#6983](https://github.com/codewhale-hq/Codewhale/pull/6983)), with the diagnosis and on-device reproducer in [#6980](https://github.com/codewhale-hq/Codewhale/issues/6980).\n\n
\n\n
\nv0.10.2 — terminal, recovery and reliability\n\n**Contributions**\n\n- **[Henrik Bakke Dukefoss / henrikdukefoss](https://github.com/henrikdukefoss)** — added the Standard Compute compatible-host descriptor, with live model discovery and its billing basis kept Unknown ([#6985](https://github.com/codewhale-hq/Codewhale/pull/6985)).\n- **[shenjackyuanjie](https://github.com/shenjackyuanjie)** — diagnosed and fixed the Windows OpenHarmony CMake generator and CLI hashing-module build failures ([#6988](https://github.com/codewhale-hq/Codewhale/issues/6988), [#6989](https://github.com/codewhale-hq/Codewhale/pull/6989)).\n- **[Sh1Zuku / SparkofSpike](https://github.com/SparkofSpike)** — live network-policy updates and goal milestone hand-back ([#6928](https://github.com/codewhale-hq/Codewhale/pull/6928), [#6930](https://github.com/codewhale-hq/Codewhale/pull/6930)), and a Codewhale home reached through a symlink or junction ([#6947](https://github.com/codewhale-hq/Codewhale/issues/6947)).\n- **[dajiaohuang](https://github.com/dajiaohuang)** — cache-write token accounting, with missing and explicit-zero usage preserved ([#6913](https://github.com/codewhale-hq/Codewhale/pull/6913)).\n- **[gaord](https://github.com/gaord)** — embedder-declared telemetry surface support without changing collection policy ([#6916](https://github.com/codewhale-hq/Codewhale/pull/6916)).\n- **[Lstarsky0](https://github.com/Lstarsky0)** — localized `/profile` replies across all 15 complete locale packs ([#6919](https://github.com/codewhale-hq/Codewhale/pull/6919)), and workflow gates that block their own role rejected at plan admission ([#6952](https://github.com/codewhale-hq/Codewhale/pull/6952)).\n- **[LIghtJUNction](https://github.com/LIghtJUNction)** — plugin shell install and in-TUI plugin OAuth sign-in with `/connect` and `/disconnect` ([#6950](https://github.com/codewhale-hq/Codewhale/pull/6950)).\n- **[jayanthvee](https://github.com/jayanthvee)** — Windows npm launcher guidance and targeted process shutdown ([#6906](https://github.com/codewhale-hq/Codewhale/pull/6906)).\n- **[asto18089](https://github.com/asto18089)** — reference fix for longer browser sign-in callback windows ([#6865](https://github.com/codewhale-hq/Codewhale/issues/6865)).\n\n**Reports and verification**\n\n- **[BX166](https://github.com/BX166)** — reported three provider failure modes measured on AICraft's own traffic: a cold model that reads as a dead connection, a listed model that fails on every call, and a response cut at the output ceiling that reports `stop` ([#6889](https://github.com/codewhale-hq/Codewhale/issues/6889)).\n\n
\n\n
\nv0.10.1 — reliability and first-run fixes\n\n**Merged or adapted contributions**\n\n- **[gaord](https://github.com/gaord)** — exposed call-specific workspace changes to Runtime clients ([#6817](https://github.com/codewhale-hq/Codewhale/pull/6817)) and canonical skill-detail/review routes ([#6869](https://github.com/codewhale-hq/Codewhale/pull/6869)).\n- **[asto18089](https://github.com/asto18089)** — fixed preferred search-language selection ([#6860](https://github.com/codewhale-hq/Codewhale/pull/6860)), image metadata for model input ([#6858](https://github.com/codewhale-hq/Codewhale/pull/6858)), automation deletion wording and retained-run cleanup ([#6864](https://github.com/codewhale-hq/Codewhale/pull/6864)), and compaction-anchor regression coverage ([#6857](https://github.com/codewhale-hq/Codewhale/pull/6857)).\n- **[aboimpinto](https://github.com/aboimpinto)** — extracted portable config/status/permission command contracts while preserving host-owned mutation and queue-worker readiness ([#6832](https://github.com/codewhale-hq/Codewhale/pull/6832)).\n- **[hodeswildsmith455-boop](https://github.com/hodeswildsmith455-boop)** — added OrcaRouter account sign-in with PKCE and its live chat catalog ([#6867](https://github.com/codewhale-hq/Codewhale/pull/6867)).\n- **[LIghtJUNction](https://github.com/LIghtJUNction)** — added reviewed plugin-provided AI routes with host-owned OAuth PKCE credentials and request-time authority checks ([#6805](https://github.com/codewhale-hq/Codewhale/pull/6805)).\n- **[AdityaVG13](https://github.com/AdityaVG13)** — supplied the discovery-cache priority correction adapted from [#6393](https://github.com/codewhale-hq/Codewhale/pull/6393); highest-ranked tools survive cache overflow. The broader echo and fork-inheritance draft remains open.\n- **[Guan0923](https://github.com/Guan0923)** — accepted case-insensitive HTTP(S) schemes in `config doctor` without rewriting the configured URL ([#6819](https://github.com/codewhale-hq/Codewhale/pull/6819)).\n- **[harryvgiunta](https://github.com/harryvgiunta)** — added Yolo-Auto as a bundled OpenAI-compatible host descriptor, with its billing basis recorded as unreviewed rather than guessed ([#6408](https://github.com/codewhale-hq/Codewhale/pull/6408)).\n- **[asto18089](https://github.com/asto18089)** — contributed the integrated runtime liveness, context, search, JavaScript execution, stopship scout and pet repairs, preserving the original contributor commits ([#6799](https://github.com/codewhale-hq/Codewhale/pull/6799)).\n- **[qiuYliangM](https://github.com/qiuYliangM)** — made provider-bound project instruction and constitution labels stable across directory moves and kept their absolute paths in operator reports ([#6799](https://github.com/codewhale-hq/Codewhale/pull/6799)).\n- **[zhuowp](https://github.com/zhuowp)** — supplied the process-scoped PowerShell execution-policy repair adapted for Codewhale; machine and user Group Policy still take precedence ([#6745](https://github.com/codewhale-hq/Codewhale/issues/6745)).\n- **[Andrea-Bruno](https://github.com/Andrea-Bruno)** — designed the Superfast Decision Gate and contributed its off-by-default shadow classifier ([#6604](https://github.com/codewhale-hq/Codewhale/pull/6604), [#6603](https://github.com/codewhale-hq/Codewhale/issues/6603)).\n- **[aiapienthusiast](https://github.com/aiapienthusiast)** — added Cheaper Inference to the bundled provider catalog ([#6761](https://github.com/codewhale-hq/Codewhale/pull/6761)).\n- **[gaord](https://github.com/gaord)** — let a client fork a thread at a named turn ([#6580](https://github.com/codewhale-hq/Codewhale/pull/6580)), let undo roll back files for the turn it is undoing ([#6483](https://github.com/codewhale-hq/Codewhale/pull/6483)), stopped resume and fork from duplicating threads and sessions ([#6406](https://github.com/codewhale-hq/Codewhale/pull/6406)), exposed user-defined provider routes to native clients ([#6404](https://github.com/codewhale-hq/Codewhale/pull/6404)), and kept a fork going when a turn lost its tool call ([#6664](https://github.com/codewhale-hq/Codewhale/pull/6664)).\n- **[Lstarsky0](https://github.com/Lstarsky0)** — moved the docs/work, legal, digest and FAQ pages onto the dictionary spine ([#6405](https://github.com/codewhale-hq/Codewhale/pull/6405), [#6417](https://github.com/codewhale-hq/Codewhale/pull/6417), [#6499](https://github.com/codewhale-hq/Codewhale/pull/6499), [#6574](https://github.com/codewhale-hq/Codewhale/pull/6574)), tightened the Chinese-branching ceiling to 18 ([#6403](https://github.com/codewhale-hq/Codewhale/pull/6403)), and made Fleet publish without a two-link window ([#6431](https://github.com/codewhale-hq/Codewhale/pull/6431)). Also moved the constitution page onto the dictionary spine and kept its install link in the selected locale ([#6733](https://github.com/codewhale-hq/Codewhale/pull/6733)). Translated the session-only note after model switches across the complete TUI locale packs ([#6875](https://github.com/codewhale-hq/Codewhale/pull/6875)).\n- **[aboimpinto](https://github.com/aboimpinto)** — restored a green Linux full-workspace test gate without loosening any test, twice ([#6581](https://github.com/codewhale-hq/Codewhale/pull/6581), [#6666](https://github.com/codewhale-hq/Codewhale/pull/6666)), and completed the session command group's shared boundary ([#6793](https://github.com/codewhale-hq/Codewhale/pull/6793)).\n- **[dajiaohuang](https://github.com/dajiaohuang)** — validated `config set` values against the settings schema ([#6568](https://github.com/codewhale-hq/Codewhale/pull/6568)).\n- **[Water-Run](https://github.com/Water-Run)** — ingested namespaced model-only catalog entries so models present only in the canonical `models` map reach the offering list ([#6400](https://github.com/codewhale-hq/Codewhale/pull/6400)), and retired the blanket dead-code allowance and its unused feature stages, tightening the budget to match ([#6402](https://github.com/codewhale-hq/Codewhale/pull/6402)).\n- **[wuisabel-gif](https://github.com/wuisabel-gif)** — designed the `tool_call_after` execution-receipt contract and its tests on a reference branch, which landed re-implemented on the current hook seam ([#6689](https://github.com/codewhale-hq/Codewhale/issues/6689), [#6713](https://github.com/codewhale-hq/Codewhale/pull/6713)).\n- **[Sh1Zuku / SparkofSpike](https://github.com/SparkofSpike)** — let making room survive a provider request-body limit (HTTP 413) by shrinking, then replacing, inline images for that one summary pass ([#6642](https://github.com/codewhale-hq/Codewhale/pull/6642)). Also translated seventeen more guides into Simplified Chinese, among them plugins, memory, sandbox, workflow authoring, Docker, Termux and HarmonyOS, and brought the existing zh_hans docs onto one terminology standard ([#6662](https://github.com/codewhale-hq/Codewhale/pull/6662)), then translated thirteen developer and internal docs, among them the runtime API, architecture, tool surface, authorization order, operations runbook and Workroom security ([#6663](https://github.com/codewhale-hq/Codewhale/pull/6663)).\n\n**Reports and reproductions**\n\n- **[7jrxt42BxFZo4iAnN4CX](https://github.com/7jrxt42BxFZo4iAnN4CX)** — reported indefinite human questions being cancelled by the TUI hung-tool watchdog and supplied the timer evidence ([#6872](https://github.com/codewhale-hq/Codewhale/issues/6872)).\n- **[cenab](https://github.com/cenab)** — requested the Tsubasa provider row and supplied its endpoint, key and model values ([#6695](https://github.com/codewhale-hq/Codewhale/issues/6695)).\n- **[BX166](https://github.com/BX166)** — reported the AICraft provider row missing its key console, docs link and guidance, and supplied the values ([#6616](https://github.com/codewhale-hq/Codewhale/issues/6616)); the report also surfaced that no bundled descriptor's links reached the setup form.\n- **[jayanthvee](https://github.com/jayanthvee)** — reported and diagnosed that killing the npm launcher's `node.exe` ends Windows sessions without cleanup, with reproductions and fix directions ([#6827](https://github.com/codewhale-hq/Codewhale/issues/6827)).\n\n
\n\n
\nv0.10.0 — redesigned workbench, session recovery, and runtime surfaces\n\n**Merged or adapted contributions**\n\n- **[AdityaVG13](https://github.com/AdityaVG13)** — composer wrapping, pasted/editor draft history, painted-column transcript copying, tab/caret placement, explicit terminal foregrounds, and headless user-input tool availability ([#6363](https://github.com/codewhale-hq/Codewhale/pull/6363), [#6365](https://github.com/codewhale-hq/Codewhale/pull/6365)); both PRs merged with their original ancestry.\n- **[aboimpinto](https://github.com/aboimpinto)** — moved the TUI session-export slice onto shared command contracts (FEAT-025): a session-export contract facet with one shared sanitizer, `/export` routed through the facet, pinned with baseline-captured goldens and gates ([#6096](https://github.com/codewhale-hq/Codewhale/pull/6096)).\n- **[gaord](https://github.com/gaord)** — recorded the mode each turn ran in so mixed-mode sessions stay legible ([#6321](https://github.com/codewhale-hq/Codewhale/pull/6321), harvested), stated the approval posture a task thread starts on ([#6386](https://github.com/codewhale-hq/Codewhale/pull/6386)), and rebuilt the runtime-API thread summary in one store pass instead of one per row ([#6376](https://github.com/codewhale-hq/Codewhale/pull/6376)).\n- **[zhuowp](https://github.com/zhuowp)** — preserved chat roles across compaction, protected user turns on recompaction, and kept the operate contract intact through the same path ([#6286](https://github.com/codewhale-hq/Codewhale/pull/6286)).\n- **[h3c-hexin](https://github.com/h3c-hexin)** — rate-limit-adaptive subagent launch scheduling: the `DynamicGate` that replaces fixed spawn pacing when a provider throttles ([#6055](https://github.com/codewhale-hq/Codewhale/pull/6055), harvested).\n- **[asto18089](https://github.com/asto18089)** — co-authored the rate-limit-adaptive launch scheduling work ([#6055](https://github.com/codewhale-hq/Codewhale/pull/6055)).\n- **[yrk111222](https://github.com/yrk111222)** — ModelScope provider support, landed through the shared `ChildGrant` fleet authority ([#6299](https://github.com/codewhale-hq/Codewhale/pull/6299), harvested).\n- **[xiechimon](https://github.com/xiechimon)** — capped child tool results at capture time rather than at render ([#6294](https://github.com/codewhale-hq/Codewhale/pull/6294), harvested).\n- **[VincentCorleone](https://github.com/VincentCorleone)** — defined and implemented the weixin-bridge Quick Start so a first run works from the README alone ([#6170](https://github.com/codewhale-hq/Codewhale/pull/6170), harvested).\n- **[Serendo](https://github.com/Serendo)** — fixed the `/config` theme editor exiting the panel on an arrow key ([#6336](https://github.com/codewhale-hq/Codewhale/pull/6336)).\n- **[yetuge](https://github.com/yetuge)** — dropped the retired `token_budget` field from the subagent documentation ([#6335](https://github.com/codewhale-hq/Codewhale/pull/6335)).\n- **[Water-Run](https://github.com/Water-Run)** — translated the local browser client guide into Simplified Chinese ([#6401](https://github.com/codewhale-hq/Codewhale/pull/6401)). The catalog and dead-code work (#6400, #6402) landed after the v0.10.0 tag and is credited under v0.10.1.\n\n**Reports and reproductions**\n\n- **[BX166](https://github.com/BX166)** — contributed the AICraft provider template and its documentation ([#6171](https://github.com/codewhale-hq/Codewhale/pull/6171)). The PR was closed unmerged, but it is what surfaced the decision to stop special-casing named OpenAI-compatible hosts and make them ordinary providers ([#6289](https://github.com/codewhale-hq/Codewhale/issues/6289)); its base URL and key env carry into that work.\n- **[7jrxt42BxFZo4iAnN4CX](https://github.com/7jrxt42BxFZo4iAnN4CX)** — reported the session-retention defects behind archive-past-the-cap and empty-session cap occupancy ([#6136](https://github.com/codewhale-hq/Codewhale/issues/6136), [#6137](https://github.com/codewhale-hq/Codewhale/issues/6137)), the resume-failure design behind durable transcript errors ([#6138](https://github.com/codewhale-hq/Codewhale/issues/6138)), and the gaps behind the opt-in approval timeout ([#6101](https://github.com/codewhale-hq/Codewhale/issues/6101)), `codewhale exec --hooks` ([#6099](https://github.com/codewhale-hq/Codewhale/issues/6099)), Markdown drag-copy ([#6156](https://github.com/codewhale-hq/Codewhale/issues/6156)), and the browsable, current-aware session picker ([#6014](https://github.com/codewhale-hq/Codewhale/issues/6014)); the goal token-budget hard stop ([#6013](https://github.com/codewhale-hq/Codewhale/issues/6013)) and the fleet no-progress guard shared with child workers ([#6015](https://github.com/codewhale-hq/Codewhale/issues/6015)) landed as first slices of two larger proposals, and the runtime-store session refusal ([#6207](https://github.com/codewhale-hq/Codewhale/issues/6207)) stays open after the first fix was reverted on a race.\n- **[Lstarsky0](https://github.com/Lstarsky0)** — reported TUI tests reading machine state instead of hermetic fixtures; the `lock_test_env` remedy from that report shaped two more hermetic fixes for shared UI fixtures and the compaction budget test ([#5359](https://github.com/codewhale-hq/Codewhale/issues/5359)).\n- **[Lujc0523](https://github.com/Lujc0523)** — reported `/hooks edit` splitting keystrokes between the editor and the composer, fixed by pausing the TUI input pump inside the editor handoff ([#6165](https://github.com/codewhale-hq/Codewhale/issues/6165)).\n- **[Statter](https://github.com/Statter)** — reported the Gemini `/models` failure that now surfaces the provider's reason instead of an empty error ([#6173](https://github.com/codewhale-hq/Codewhale/issues/6173)).\n- **[sequico](https://github.com/sequico)** — reported the ACP `session/new` ids that `session/load` could not resolve, fixed by minting resolvable session ids ([#6174](https://github.com/codewhale-hq/Codewhale/issues/6174)).\n- **[bevis-wong](https://github.com/bevis-wong)** — reported the mid-run engine freeze behind the bounded turn-end foreground-child join, and the resume path that re-ran identical tool-call repair on every load instead of persisting it ([#6184](https://github.com/codewhale-hq/Codewhale/issues/6184), [#6185](https://github.com/codewhale-hq/Codewhale/issues/6185)).\n\n
\n\n
\nv0.9.13 — paste integrity, dispatch safety, and the Computer Use bundle\n\n**Merged or adapted contributions**\n\n- **[nightt5879](https://github.com/nightt5879)** — added bounded Gemini signature recovery guidance and streaming/non-streaming gateway transport regressions ([#6081](https://github.com/codewhale-hq/Codewhale/pull/6081)).\n- **[c020627](https://github.com/c020627)** — repaired translated contributor-guide and Windows screenshot links ([#6080](https://github.com/codewhale-hq/Codewhale/pull/6080)).\n- **[h3c-hexin](https://github.com/h3c-hexin)** — contributed full-fidelity session archives ([#6056](https://github.com/codewhale-hq/Codewhale/pull/6056)), GLM-5.3 reasoning controls and the model-facing documentation/tool-gating audit ([#6051](https://github.com/codewhale-hq/Codewhale/pull/6051), [#6052](https://github.com/codewhale-hq/Codewhale/pull/6052)).\n- **[asto18089](https://github.com/asto18089)** — co-authored full-fidelity session archives ([#6056](https://github.com/codewhale-hq/Codewhale/pull/6056)), GLM-5.3 reasoning controls and tool-gating/documentation fixes ([#6051](https://github.com/codewhale-hq/Codewhale/pull/6051), [#6052](https://github.com/codewhale-hq/Codewhale/pull/6052)).\n- **[Hmbown](https://github.com/Hmbown)** — updated JavaScript dependencies across the website, telemetry package and VS Code extension ([#6057](https://github.com/codewhale-hq/Codewhale/pull/6057)).\n- **[gaord](https://github.com/gaord)** — contributed the file-scoped restore endpoint and trust-gated whole-tree rollback ([#6111](https://github.com/codewhale-hq/Codewhale/pull/6111)), Fleet schema inspection, role precedence and worker deliverable receipts, and linked the community VS Code frontend ([#5944](https://github.com/codewhale-hq/Codewhale/pull/5944), [#5945](https://github.com/codewhale-hq/Codewhale/pull/5945), [#5946](https://github.com/codewhale-hq/Codewhale/pull/5946), [#5992](https://github.com/codewhale-hq/Codewhale/pull/5992)).\n- **[goransh-walia](https://github.com/goransh-walia)** — contributed the propose-only commit-planning rework ([#5870](https://github.com/codewhale-hq/Codewhale/pull/5870)).\n- **[7jrxt42BxFZo4iAnN4CX](https://github.com/7jrxt42BxFZo4iAnN4CX)** — documented turn budgets and goal configuration, and reported gaps in command discovery, Fleet navigation, human waits, state hooks, history and provider routing ([#5996](https://github.com/codewhale-hq/Codewhale/pull/5996), [#5952](https://github.com/codewhale-hq/Codewhale/issues/5952), [#5954](https://github.com/codewhale-hq/Codewhale/issues/5954), [#6003](https://github.com/codewhale-hq/Codewhale/issues/6003), [#6004](https://github.com/codewhale-hq/Codewhale/issues/6004), [#6006](https://github.com/codewhale-hq/Codewhale/issues/6006), [#6007](https://github.com/codewhale-hq/Codewhale/issues/6007)).\n- **[SparkofSpike](https://github.com/SparkofSpike)** — contributed two-stage consent for opting out of model-bound credential redaction and session titles derived from real user prompts instead of runtime handoffs ([#5982](https://github.com/codewhale-hq/Codewhale/pull/5982), [#6012](https://github.com/codewhale-hq/Codewhale/pull/6012)).\n- **[aboimpinto](https://github.com/aboimpinto)** — moved session lifecycle and session-control commands onto shared command contracts ([#5902](https://github.com/codewhale-hq/Codewhale/pull/5902), [#5951](https://github.com/codewhale-hq/Codewhale/pull/5951)).\n- **[EvanProgramming](https://github.com/EvanProgramming)** — reported Windows input and CRLF-write defects, and contributed CRLF preservation and an injectable Windows input runner ([#5908](https://github.com/codewhale-hq/Codewhale/issues/5908), [#5909](https://github.com/codewhale-hq/Codewhale/issues/5909), [#5910](https://github.com/codewhale-hq/Codewhale/pull/5910), [#5911](https://github.com/codewhale-hq/Codewhale/pull/5911), [#5912](https://github.com/codewhale-hq/Codewhale/pull/5912)).\n- **[wuisabel-gif](https://github.com/wuisabel-gif)** — exposed workspace file suggestions through the Runtime API ([#6120](https://github.com/codewhale-hq/Codewhale/pull/6120)) and added custom-theme discovery, preview and selection in the theme picker ([#5907](https://github.com/codewhale-hq/Codewhale/pull/5907)).\n- **[zhuowp](https://github.com/zhuowp)** — matched model-visible shell guidance to the interpreter selected for execution ([#5900](https://github.com/codewhale-hq/Codewhale/pull/5900)).\n- **[googio](https://github.com/googio)** — added the opt-in Serply web-search provider ([#6100](https://github.com/codewhale-hq/Codewhale/pull/6100)).\n\n**Reports and reproductions**\n\n- **[Hmbown](https://github.com/Hmbown)** — identified missing recovery guidance when a compatible gateway rejects Gemini tool-call replay without thought signatures ([#6048](https://github.com/codewhale-hq/Codewhale/issues/6048)).\n- **[7jrxt42BxFZo4iAnN4CX](https://github.com/7jrxt42BxFZo4iAnN4CX)** — proposed global usage and tool diagnostics and independent goal verification ([#6011](https://github.com/codewhale-hq/Codewhale/issues/6011), [#6013](https://github.com/codewhale-hq/Codewhale/issues/6013)); these broader requests remain open.\n- **[nsfoxer](https://github.com/nsfoxer)** — reported the multiline-paste regression and incomplete provider model lists ([#5981](https://github.com/codewhale-hq/Codewhale/issues/5981), [#6009](https://github.com/codewhale-hq/Codewhale/issues/6009)).\n- **[Nefelibata1024](https://github.com/Nefelibata1024)** — confirmed the multiline-paste regression's impact ([#5981](https://github.com/codewhale-hq/Codewhale/issues/5981)).\n- **[Gabriel-Degret](https://github.com/Gabriel-Degret)** — reported the loss of the allow_insecure_http provider setting and that saved agent profiles were silently ignored when spawning sub-agents ([#5991](https://github.com/codewhale-hq/Codewhale/issues/5991), [#6117](https://github.com/codewhale-hq/Codewhale/issues/6117)).\n- **[LmeSzinc](https://github.com/LmeSzinc)** — requested Runtime API access to the TUI fuzzy file search ([#6095](https://github.com/codewhale-hq/Codewhale/issues/6095)).\n- **[dmt4](https://github.com/dmt4)** — requested Linux copy-on-select and middle-click paste ([#6116](https://github.com/codewhale-hq/Codewhale/issues/6116)).\n- **[Lujc0523](https://github.com/Lujc0523)** — reported the ACP initialize schema violation affecting strict IDE clients ([#5969](https://github.com/codewhale-hq/Codewhale/issues/5969)).\n- **[mo-vic](https://github.com/mo-vic)** — proposed storing evicted context on disk so it can be retrieved later ([#6008](https://github.com/codewhale-hq/Codewhale/issues/6008)).\n- **[giancarlocp](https://github.com/giancarlocp)** — requested a plugin authoring guide and OpenCode plugin conversion ([#5827](https://github.com/codewhale-hq/Codewhale/discussions/5827)).\n- **[hxfhd](https://github.com/hxfhd)** — supplied a Windows reproduction of a turn stopping before its stated next tool action ([#6010](https://github.com/codewhale-hq/Codewhale/discussions/6010)).\n\n
\n\n
\nv0.9.12 — native search, live token truth, and runtime surfaces\n\n**Merged or adapted contributions**\n\n- **[hexin / h3c-hexin](https://github.com/h3c-hexin)** — provider-native web\n search across four routes: the DeepSeek adapter (#5683), Z.AI and BigModel\n (#5685), and Xiaomi MiMo (#5687), each fail-closed for undocumented models,\n plus the constraint enforcement that runs before any fallback (#5682); also\n authoritative edit-last-turn boundaries (#5621), Kimi Code k3-256k support\n (#5622), post-compaction input-token reporting (#5623), and preserving the\n scheduled model selection in automations (#5650)\n- **[Isabel Wu / wuisabel-gif](https://github.com/wuisabel-gif)** — live\n session token totals (#5624), persisted context-pressure warnings (#5629),\n discoverable Fleet roster editing (#5604), the capability-gated cursor\n accent (#5599), and `/copy` for the latest completed response (#5692)\n- **[Paulo Aboim Pinto / aboimpinto](https://github.com/aboimpinto)** —\n preserved Windows verbatim-path operands through POSIX word splitting\n (#5610), moved the plugins group onto the command shapes (#5657), built\n FEAT-022 skills command shapes with retained-host validation (#5825), and\n re-landed FEAT-020 plugin command shapes on main (#5865)\n- **[Alex Musichen / musichen](https://github.com/musichen)** — fixed the\n configured-view DeepSeek model picker so it shows a stable DeepSeek heading\n and keeps every official catalog model for the active provider visible\n (#5689)\n- **[gaord](https://github.com/gaord)** — added the `GET /v1/fleet/profiles`\n runtime API endpoint, reusing the FleetManager validation path (#5688)\n- **[Sh1Zuku / SparkofSpike](https://github.com/SparkofSpike)** — corrected\n English documentation inaccuracies and contributed the first zh_hans\n translations for the Tier-2 docs (#5613)\n- **[M-Maciej](https://github.com/M-Maciej)** — goal continuation cadence fix\n (#5591) and the per-session control socket (#5533, #5831)\n- **[Serephus / serephus](https://github.com/serephus)** — nixpkgs update\n (#5669)\n- **[秋月凉梦 / qiuYliangM](https://github.com/qiuYliangM)** — co-authored the\n authoritative edit-last-turn boundaries (#5621), Kimi Code k3-256k support\n (#5622), and post-compaction input-token reporting (#5623)\n- **[whp233](https://github.com/whp233)** — `wire = responses|anthropic` for\n openai-compatible custom routes and opencode-zen muse-spark (#5716, landed\n as #5719)\n- **[Gabriel Degret / Gabriel-Degret](https://github.com/Gabriel-Degret)** —\n found the reasoning-only retry gap and built the first fix; landed as the\n `[reasoning_only]` retry ceiling with a request-scoped nudge (#5867)\n- **[huangxianzhan](https://github.com/huangxianzhan)** — the\n `x-opencode-session` header for OpenCode Go and Zen gateways (#5868)\n- **[zhuowp](https://github.com/zhuowp)** — task origin preserved in job\n snapshots (#5869)\n- **[AdityaG / AdityaVG13](https://github.com/AdityaVG13)** — a ten-commit\n performance pass across the TUI and config: zero-copy LaTeX streaming,\n single-pass token accounting, memoized provider resolution, once-per-process\n models.dev catalog parsing (interactive boot -70%), adaptive shell-completion\n poll cadence, and diagnostic worker caps\n- **[Nightt / nightt5879](https://github.com/nightt5879)** — isolated remote\n recovery lease generations (#5790)\n- **[yiheng-kkk](https://github.com/yiheng-kkk)** — replaced stale todo\n transcript snapshots so a rewritten todo list renders its current tasks\n (#5871, #5873)\n- **[Lfanxing](https://github.com/Lfanxing)** — Moonshot routes degrade\n incompatible tool definitions per request instead of failing the turn\n- **[WissssleyL / Lstarsky0](https://github.com/Lstarsky0)** — moved\n `docs/subagents` and `docs/mcp` onto the dictionary spine (#5337), with the\n metaTitle probe that keeps them there\n\n**Reports and reproductions**\n\n- **[slowly247](https://github.com/slowly247)** — reported the Ollama input\n budget collapsing to 1,024 tokens on 32K local models (#5820)\n- **[ronohara](https://github.com/ronohara)** — reported the engine stopping\n after recoverable network errors and reproduced the discarded approval (#5769)\n- **[Lujc0523](https://github.com/Lujc0523)** — asked for ACP session mode and\n model configuration (#5863)\n- **[senka9h](https://github.com/senka9h)** — reported the missing ACP\n `session/list` and `session/load` methods (#5864)\n
\n\n
\nv0.9.11 — portable command surfaces and turn-loop structure\n\n**Merged or adapted contributions**\n\n- **[xyzs996 / Mark Yan](https://github.com/xyzs996)** — DeepSeek V4 billing treats whole Beijing weekends as off-peak, and the scorecard window comment now matches ([#5545](https://github.com/codewhale-hq/Codewhale/pull/5545))\n- **[Sun Zhenyuan / bistack](https://github.com/bistack)** — extracted tool-call\n planning, execution, and result processing from the turn loop while preserving\n the existing sandbox-policy, hook, budget, and batch-execution behavior\n (#5523)\n- **[Isabel Wu / wuisabel-gif](https://github.com/wuisabel-gif)** — added\n bounded, workspace-relative multi-file diagnostics to the existing model-\n visible `lsp` tool, reusing the shared transport pool without expanding the\n 75-tool catalog (#5524)\n- **[Paulo Aboim Pinto / aboimpinto](https://github.com/aboimpinto)** — added\n portable presentation, media-attachment, and operation-digest facets to the\n command contract, then moved all seven utility command handlers onto the\n contract-backed dispatch path (#5525)\n\n**Reviewed overlap**\n\n- **[Lstarsky0](https://github.com/Lstarsky0)** — reviewed #5524 and identified\n the closed-channel, severity-filtering, and truncation-receipt gaps covered by\n the maintainer hardening pass.\n- Isabel Wu's PR #5530 independently routed the legacy plural completion\n command through the public CLI generator. Equivalent behavior, including the\n published `codew` alias registration, had already landed in the integration\n lane, so the PR is recorded here as reviewed project work rather than counted\n as a second merged contribution.\n\n**Reports and reproductions**\n\n- **[RepentStar](https://github.com/RepentStar)** — reported the stale shell-\n completion generator and missing `codew` registration that led to the\n completion fixes and upgrade guidance in #5526.\n\n
\n\n
\nv0.9.10 — retention, identity, and durable approvals\n\n**Merged or adapted contributions**\n\n- **[Sh1Zuku / SparkofSpike](https://github.com/SparkofSpike)** — restored\n `/title` as an independent, persistent terminal-window title in PR #5509,\n and contributed the Tier 1 Chinese and Indonesian documentation move to\n `docs/zh_hans/` and `docs/id/` with one-release redirect stubs (#5507,\n epic #5482)\n- **[Sun Zhenyuan / bistack](https://github.com/bistack)** — extracted the\n turn-loop stream processor in PR #5514 while preserving retry,\n cancellation, usage, TTFT, steering, and partial-response behavior\n- **[OctoBored](https://github.com/OctoBored)** — supplied the working\n no-token Star History mirror used by the localized README set after the\n canonical chart endpoint began returning a restricted placeholder (#5510)\n- **[cacdcaecawae](https://github.com/cacdcaecawae)** — added provider-neutral\n typed MCP image forwarding in PR #5515; the adapted version also emits a\n visible omission receipt for malformed image fields\n- **[cyq1017](https://github.com/cyq1017)** — approval outcomes are persisted\n before execution can proceed: receipts commit to a session-owned log first,\n unpersistable evidence blocks the tool, stale decisions are rejected, and\n resume reconstructs closed and interrupted approvals (#5491, closes #5360)\n- **[aboimpinto](https://github.com/aboimpinto)** — the TUI-owned\n dependency-injection and migration infrastructure behind safe slash-command\n extraction: seven capability facets, a dual-path dispatch seam, and\n source-aware CI enforcement so a command slice cannot claim migration while\n it still accepts concrete `App` (#5506, EPIC-005/FEAT-015 under the #5316\n umbrella they filed)\n- **[wuisabel-gif](https://github.com/wuisabel-gif)** — the TUI header now\n names the active repository or linked worktree before the branch and dirty\n marker, derived from Git's common directory and capped by shell density\n tier (#5511, the repo/worktree slice of #5437)\n- **[Lstarsky0](https://github.com/Lstarsky0)** — `docs/hooks` and\n `docs/troubleshooting` move onto the dictionary spine, retiring their inline\n bilingual literals in favor of locale dictionaries with token-aware code\n spans (#5504, closes #5337 they filed)\n\n**Reports, reproductions, and verification**\n\n- **[DingYong4223](https://github.com/DingYong4223)** — reported the\n narrow-terminal completion truncation closed by the bounded hover reveal\n (#998)\n- **[AiurArtanis](https://github.com/AiurArtanis)** and\n **[formp3](https://github.com/formp3)** — identified the completion surfaces\n affected by narrow-terminal truncation (#998)\n- **[sky-sun-moon](https://github.com/sky-sun-moon)** — reported the missing\n full per-turn input, reasoning, tool, and assistant pages that shaped Turn\n Inspector navigation (#1682)\n- **[cy2311](https://github.com/cy2311)** — reported the Windows launch path\n now covered by the Windows Terminal-aware batch launcher (#1854)\n- **[demian-welt](https://github.com/demian-welt)** — provided the reproducible\n pre-header SSE transport failure behind the bounded HTTP/1.1 retry (#4683)\n- **[BrathonBai](https://github.com/BrathonBai)** — reported the Tabby/CJK IME\n candidate-window jump that led to the cursor hide-diff-position-show\n transaction (#5023)\n- **[M-Maciej](https://github.com/M-Maciej)** — provided the organization-\n coordinator use case and 5-30 minute cadence requirement behind cancellable\n cross-turn goal delays (#5508)\n- **[thejayjetson](https://github.com/thejayjetson)** — the header\n status-indicator report that pinned the regression to a specific setting,\n having already ruled out every value, both themes, `fancy_animations`, the\n terminal auto-off rules, and a clean `codewhale doctor` (#5512)\n- **[hxfhd](https://github.com/hxfhd)** — reported the deterministic\n cross-session contamination class behind this release's session-ownership\n boundary, plus route budgeting evidence (#5518)\n- **[sfdzhmr](https://github.com/sfdzhmr)** — reported the route budgeting\n root causes that exact route-limit propagation now closes (#5516)\n\n
\n\n
\nv0.9.9 — truth and resilience\n\n**Merged or adapted contributions**\n\n- **[Lstarsky0](https://github.com/Lstarsky0)** — compact rows no longer reserve a hidden session-metrics strip ([#5486](https://github.com/codewhale-hq/Codewhale/pull/5486)); docs shell and shared component pick-text onto the typed dictionary spine ([#5488](https://github.com/codewhale-hq/Codewhale/pull/5488), [#5490](https://github.com/codewhale-hq/Codewhale/pull/5490))\n- **[Sh1Zuku / SparkofSpike](https://github.com/SparkofSpike)** — topbar session title ([#5481](https://github.com/codewhale-hq/Codewhale/pull/5481))\n- **[h3c-hexin](https://github.com/h3c-hexin)** — a concrete route/offering\n output limit now outranks the conservative 8,192-token compatibility guess\n for an uncatalogued model; routes that publish no limit stay fail-closed\n (#5461, closes #5460); every web tool surface uses the noisy-result soft\n limit (#5474); lowercase saved selectors resolve against the owning\n Z.ai/DeepSeek catalog row (#5475); configured-skill prompt paths remain\n stable across ephemeral roots and operating systems (#5492, #5473)\n- **[Gabriel-Degret](https://github.com/Gabriel-Degret)** — configurable\n auto-router classifier timeout (#5494; first contribution)\n\n**Reports, reproductions, and verification**\n\n- **[asto18089](https://github.com/asto18089)** — diagnosed the Z.ai `glm-5.2`\n casing collision and wrote the first provider-scoped fix downstream\n (Pinvou/CodeWhale#14, carried upstream in #5475)\n\n- **[hardy922](https://github.com/hardy922)** — the context-window honesty\n report that became the every-surface labeling pass (#5239)\n- **[redstar](https://github.com/redstar)** — bwrap container essentials and\n configurable extra roots (#5410)\n- **[all-lopezg](https://github.com/all-lopezg)** — SSE UTF-8 garbling on\n DeepSeek Flash with screenshots, fixed fail-closed in every dialect (#5374)\n- **[alitvak69](https://github.com/alitvak69)** — the unverified-live-pricing\n report behind the bundled fallback rates and DeepSeek V4 tiers (#5241)\n- **[wuisabel-gif](https://github.com/wuisabel-gif)** — bounded reproduction\n attempts for the macOS filtered-suite hang note on #5056\n\n
\n\n
\nv0.9.8 — marketplace, Google, Ollama Cloud\n\n**Merged or adapted contributions**\n\n- **[xiaoray-blip / Arlo](https://github.com/xiaoray-blip)** — MCP list responses omit `nextCursor` when there are no further pages ([#5336](https://github.com/codewhale-hq/Codewhale/pull/5336), reported in [#5335](https://github.com/codewhale-hq/Codewhale/issues/5335))\n- **[EvanProgramming](https://github.com/EvanProgramming)** — webhook hook\n sink no longer panics when its HTTP client fails to build (#5381); session-index\n JSONL writes are serialized so concurrent stores cannot drop an append\n (#5382)\n- **[Lstarsky0](https://github.com/Lstarsky0)** — session peek hides internal\n runtime events (#5376); thinking-ladder tests re-pinned (#5378);\n provider-count follow-ups (#5383/#5384); macOS agy fixture\n canonicalization (#5392); website zh-Hans 宪章 terminology (#5397);\n regenerated website facts harvested and corrected so Google and Ollama\n Cloud are listed and Antigravity is not advertised as a route (#5398)\n- **[mvanhorn](https://github.com/mvanhorn)** — read-only, repository-fact\n driven settings preview on the website models page (#5411, fixes #5370)\n- **[buiducnhat](https://github.com/buiducnhat)** — canonical `ultra`\n reasoning effort mapped to every provider's maximum tier (#5409); session\n titles truncated by character count instead of byte offset so CJK and\n emoji names cut at the intended width (#5415)\n- **[SparkofSpike](https://github.com/SparkofSpike)** — `/title` and the\n saved session name in the terminal tab/window title, plus the fix for the\n deadlock when the title changed during an active turn; landed as a\n discoverable alias of `/rename` on the one persisted session name (#5419)\n- **[redstar](https://github.com/redstar)** — Eden AI registered as a named\n OpenAI-compatible provider with `EDENAI_API_KEY`, `eden-ai`/`eden_ai`\n aliases, and the global and EU endpoints (#5422)\n- **[wuisabel-gif](https://github.com/wuisabel-gif)** — background verifier\n test isolated from the rustup `rustc` shim and `$HOME`, one narrow\n reliability slice of #5056 (#5423)\n\n
\n\n
\nv0.9.7 — the catalog stays ordinary\n\n**Merged or adapted contributions**\n\n- **[XhesicaFrost](https://github.com/XhesicaFrost)** — copy from the message\n context menu now takes canonical content, keeping authored Unicode,\n Markdown, and hard line breaks in the clipboard while role glyphs,\n continuation rails, and visual wrapping stay out of it (PR #5319)\n- **[h3c-hexin](https://github.com/h3c-hexin)** — split durable-session\n snapshot reads from crash recovery so an embedding host inspecting a\n session while a tool is still running no longer gets a spurious crash\n repair (PR #5320)\n- **[XiaoHuo888-hue](https://github.com/XiaoHuo888-hue)** — OrcaRouter as a\n first-class named provider with `ORCAROUTER_API_KEY`, auto-routing,\n CLI `--provider` selection, and TUI picker entries (PR #5321)\n\n**Reports and verification**\n\n- **[USTHzhanglu](https://github.com/USTHzhanglu)** — reported the Auto-Review\n shell/write regression with a Windows reproduction and audit-log evidence\n (issue #5323)\n- **[Lstarsky0](https://github.com/Lstarsky0)** — traced the Auto-Review\n regression to the exact permission-posture change and documented the safe\n recovery choices (issue #5323)\n\n
\n\n
\nv0.9.6 — fewer bumpers, truthful endings\n\n**Merged or adapted contributions**\n\n- **[Xavier Pestel / xavierpestel-ai](https://github.com/xavierpestel-ai)** —\n Mistral AI (la Plateforme) as a first-class provider route, including the\n adjustable-reasoning wire contract and its multi-turn thinking replay\n (PR #5295)\n- **[Ben Younes / ousamabenyounes](https://github.com/ousamabenyounes)** —\n inherited nested-agent depth cap, keeping child agents from widening the\n budget provided by their parent (PR #5317)\n- **[Rafael Cavalheri / rafaelcavalheri](https://github.com/rafaelcavalheri)** —\n multi-round ACP file, search, Git, patch, and explicitly enabled shell tool\n execution with cancellation and fail-closed shell safety (PR #5225)\n\n
\n\n
\nv0.9.5 — one runtime, managed controls, and uninterrupted turns\n\n**Merged or adapted contributions**\n\n- **[Sh1Zuku / SparkofSpike](https://github.com/SparkofSpike)** — stale cached\n session-title recovery so `New Session` yields to the first real prompt\n- **[Paulo Aboim Pinto / aboimpinto](https://github.com/aboimpinto)** — the\n shared alias-aware command discovery contract across the palette, slash\n completion, dispatch, and acceptance harness\n- **[Sun Zhenyuan / bistack](https://github.com/bistack)** — background\n incremental MCP Registry refreshes that return the local snapshot immediately\n- **[SKY ZHAO / skyzhao1223](https://github.com/skyzhao1223)** — prompt-based\n `model = \"auto\"` tier selection in PR #5257\n\n
\n\n
\nv0.9.4 — calmer output, recovery, and release hardening\n\n**Merged or adapted contributions**\n\n- **[Sh1Zuku / SparkofSpike](https://github.com/SparkofSpike)** — LaTeX\n rendering in PR #4981, circled-digit and keycap width handling in PR #5001,\n and actionable File-edit recovery in PR #5008; sub-agent checkpoint resume\n in PR #5242, real shell wait elapsed time in PR #5240, and keeping\n alternate-scroll off while mouse capture is active in PR #5234\n- **[XhesicaFrost](https://github.com/XhesicaFrost)** — long Windows user-PATH\n preservation in PR #5006\n- **[Paulo Aboim Pinto / aboimpinto](https://github.com/aboimpinto)** — the\n user-command dispatch acceptance contract in PR #4992\n- **[shenjackyuanjie](https://github.com/shenjackyuanjie)** — Windows\n OpenHarmony linker re-quoting for spaced SDK paths in PR #5095\n- **[bistack](https://github.com/bistack)** — MCP Registry discovery with\n Registry-first tool selection in PR #5238\n- **[vFONGv](https://github.com/vFONGv)** — the zh-CN Windows beginner guide\n with screenshots in PR #5229\n- **[mky](https://github.com/mky)** — FreeBSD build fix (`rquickjs` `bindgen` on FreeBSD, PR #5254)\n- **[cacdcaecawae](https://github.com/cacdcaecawae)** — embedder-owned sub-agent state roots (PR #5252)\n\n**Reports, reproductions, and verification**\n\n- **[DracheTek](https://github.com/DracheTek)** — the multilingual, CRLF-heavy\n File-edit failure report in issue #5003\n- **[An Ziwu / MuRongMoQing](https://github.com/MuRongMoQing)** — the Windows\n PATH-overwrite defect report in issue #4685\n\n
\n\n
\nv0.9.3 — DeepSeek Responses, canonical tools, and runtime hardening\n\n- **[greyfreedom](https://github.com/greyfreedom)** (Turisla) — the documented\n and tested authorization-order contract from PR #4980\n- **[nightt5879](https://github.com/nightt5879)** (Nightt) — foreground shell\n detachment before steering from PR #4979\n- **[Watcher24](https://github.com/Watcher24)** — the macOS File Provider\n sandbox report and reproduction in #4085\n- **[Fred Leitz / fleitz](https://github.com/fleitz)** — required\n source-candidate credit for the canonical `Bash` no-`cwd` workspace fix and\n regression in PR #4673 (issue #4674)\n\n
\n\n
\nv0.9.2 — routing, workflow, localization, and inspectability\n\n- **[greyfreedom](https://github.com/greyfreedom)** — exact repository-scoped\n allow grants and the cross-platform path-semantics repairs from PR #4761\n- **[nightt5879](https://github.com/nightt5879)** — off-event-loop terminal\n clipboard writes (PR #4896), complete locale exposure in settings (PR #4856),\n CRLF-safe edits (PR #4942), and automatic-routing reasoning preservation\n (PR #4961)\n- **[XhesicaFrost](https://github.com/XhesicaFrost)** — the configurable\n session-token header from PR #4610 and context-menu hover alignment in PR #4897\n- **[cyq1017](https://github.com/cyq1017)** — the hooks configuration/executor\n split from PR #4087\n- **[snail-vs](https://github.com/snail-vs)** (snailoniu) — OpenCode Zen's\n model-aware route, authentication, documentation, and test-isolation work\n from closed PR #4467, whose contributor commits are preserved in the\n candidate\n- **[Sh1Zuku / SparkofSpike](https://github.com/SparkofSpike)** — the zh-Hans\n translation quality review harvested from PR #4908, duplicate-session fix in\n PR #4963, LaTeX implementation from PR #4973 landed through #4974, and the\n context-menu reproduction in #4803\n- **[GTC2080](https://github.com/GTC2080)** (TaoMu) — the `dryrun` concept\n behind `/preview-request`: preview the next outbound request from the real\n request-building seam rather than a hand-rolled summary (PR #1099,\n harvested)\n- **[h3c-hexin](https://github.com/h3c-hexin)** — the non-UTF-8 `fetch_url`\n report and implementation direction harvested from PR #4909\n- **[Fred Leitz / fleitz](https://github.com/fleitz)** — required\n source-candidate credit for the canonical `Bash` no-`cwd` workspace fix and\n regression in PR #4673 (issue #4674)\n- **[LmeSzinc](https://github.com/LmeSzinc)** — the Windows CRLF `edit_file`\n reproduction, root-cause analysis, and affected-code anchors in issue #4764\n- **[atmosuwiryo](https://github.com/atmosuwiryo)** — ACP numeric-id\n compatibility (PR #4929) and the Indonesian documentation and website locale\n (PRs #4962 and #4972)\n- **[M-Maciej](https://github.com/M-Maciej)** — the expanded-by-default\n reasoning setting and report (PR #4928, issue #4925)\n- **[raphamorim](https://github.com/raphamorim)** — migration of the QA PTY\n frame parser to `rio-vt` (PR #4931)\n- **[LI-Jialu](https://github.com/LI-Jialu)** — truthful finalization of stale\n restored shell cells (PR #4937)\n- **[kobihikri](https://github.com/kobihikri)** — release-container SBOM and\n explicit provenance mode (PR #4958)\n- **[EvanProgramming](https://github.com/EvanProgramming)**,\n **[adity982](https://github.com/adity982)**, and\n **[vibecoding-skills](https://github.com/vibecoding-skills)** — equivalent\n fix direction for effective-home resolution (#4760), MCP call-once behavior\n (#4756), and streaming/non-streaming timeout separation (#4743)\n- **[antarikshraya](https://github.com/antarikshraya)** — the LaTeX transcript\n rendering report in #4957\n- **[eugenicum](https://github.com/eugenicum)** — the token-header request and\n output-presentation measurements in #4520 and #4468\n- **[whp233](https://github.com/whp233)** — the StepFun/OpenCode subscription\n route request in #4526\n- **[redjade75723](https://github.com/redjade75723)** — stale resumed-workspace\n diagnosis input from #4100\n- **[hardy922](https://github.com/hardy922)** — the native DeepSeek tool-token\n visibility report in #3880\n- **[JayBeest](https://github.com/JayBeest)** — contributor-onboarding product\n direction in #4227\n- **[elijahchan2019](https://github.com/elijahchan2019)** — the optional\n reasoning-highlight request in #4089\n- **[cy2311](https://github.com/cy2311)** — sessions rail, archive, and\n auto-resume direction in #2934\n- **[wywsoor](https://github.com/wywsoor)** — export/restore correlation\n direction in #2494\n\n
\n\n
\nv0.9.1 — provider and runtime hardening\n\n- **[h3c-hexin](https://github.com/h3c-hexin)** — calendar-anchored hourly\n automation recurrence across DST and lifecycle transitions (PR #4381),\n explicit limits for unknown local models (PR #4656 / #4655), and\n idle-timeout progress telemetry (PR #4657)\n- **[gaord](https://github.com/gaord)** — Runtime API provider registry and\n atomic provider-switch endpoints (PR #4658)\n- **[SamhandsomeLee](https://github.com/SamhandsomeLee)** — the unified\n `/skills` root catalog, audit/provenance model, validated mutations, manager\n UI, and acceptance coverage (PR #4679), plus Enter-send lag diagnosis and\n fix direction for #4605 (PR #4654; landed through the release-lane\n async-dispatch split)\n- **[Paulo Aboim Pinto / aboimpinto](https://github.com/aboimpinto)** — the\n Layer 5.1 user-command registry boundary from PR #3278; the exact authored\n evidence commit from PR #4046, preserved intact in the integration graph;\n and the #2870 follow-up audit whose metadata and malformed-sibling gaps\n shaped the final corrections. Paulo also provided the structured, redacted\n Agent Details and `current_activity` design direction preserved from\n #2694/#2889 and the real-PTY lifecycle acceptance direction from #2886\n- **[baendlorel](https://github.com/baendlorel)** — TelecomJS TokenHub provider\n and key-scoped live-catalog direction, source-partitioned refresh behavior,\n and both refresh-order regressions from PR #4370, harvested into the current\n provider architecture with co-authorship preserved\n- **[zhangweiii](https://github.com/zhangweiii)** and\n **[Sterne Lee / sternelee](https://github.com/sternelee)** — the original\n first-class OpenCode Go implementations in PRs #773 and #1050, harvested\n into the current provider architecture with co-authorship preserved in the\n landing commit\n- **[Sean Tse / seanthefuturegorilla](https://github.com/seanthefuturegorilla)**\n — the canonical OpenCode Go/Zen provider request and acceptance direction in\n #1481\n- **[nightt5879](https://github.com/nightt5879)** — `/debt` compatibility\n aliases with dispatch-consistent user-command shadowing across help and\n slash discovery (PR #4680), plus the Solarized Light background preservation\n fix for the underwater shell (PR #4471)\n- **[AiurArtanis](https://github.com/AiurArtanis)** — the Solarized Light\n v0.9.0 regression report and reproduction (#4457)\n- **[shenjackyuanjie](https://github.com/shenjackyuanjie)** — the HarmonyOS\n workflow-js bindgen, portable-pty gating, and SDK environment work\n (PR #4470)\n- **[shenyongqing](https://github.com/shenyongqing)** — the original HarmonyOS\n workflow-js bindgen approach (PR #4384), carried into the landed\n implementation with credit\n- **[Luis Mateus Vargas / luismateusvargas](https://github.com/luismateusvargas)**\n — the Windows hook-process leak reproduction, process-tree analysis, and EOF\n fix direction (#4489)\n- **[redjade75723](https://github.com/redjade75723)** — the persistent Windows\n PTY failure report that exposed lossy high-bit exit-status handling (#4100)\n- **[w1w218](https://github.com/w1w218)** — the Windows ARM64 release request\n and cross-compilation report that led to native release, npm, updater, and\n archive support (#4267)\n- **[stream2stream](https://github.com/stream2stream)** — the legacy-session\n recovery report that led to the read-only doctor diagnostic (#4032, #4539)\n- **[Sh1Zuku / SparkofSpike](https://github.com/SparkofSpike)** — the Windows\n Ctrl+O reproduction that exposed pre-pager result truncation and conflicting\n composer shortcut routing (#4482)\n- **[Lu Shihan / Angel-Hair](https://github.com/Angel-Hair)** — session-owned\n read-before-edit tracking and the explicit, backwards-compatible\n `apply_patch` replacement contract (PRs #4475 and #4476)\n- **[dmitri-0](https://github.com/dmitri-0)** — configurable cache-hit\n visibility in the phase strip (PR #4474)\n- **[Fred Leitz / fleitz](https://github.com/fleitz)** — canonical `Bash`\n no-`cwd` workspace resolution and its regression test, keeping isolated\n sub-agent commands inside their selected worktree (PR #4673; issue #4674)\n- **[Sh1Zuku / SparkofSpike](https://github.com/SparkofSpike)** — exact\n Vim-space regression reproduction and verification that the v0.9.1 input\n path already contains the needed global binding (PR #4477)\n\n
\n\n
\nv0.9.0 — underwater shell, runtime persistence & release evidence\n\nThe v0.9.0 lane grew from a maintenance sweep into the underwater shell,\nmessage-first Operate, broader Fleet and Workflow behavior, runtime-thread\npersistence, terminal selection, UTF-8 handling, internationalization, and\nrelease evidence. The reports and pull requests below materially shaped it.\n\n- **[Amuthan / amuthantamil](https://github.com/amuthantamil)** — approval-time\n transcript review report that led to live Page Up/Down, modified-arrow,\n Home/End, and mouse-wheel navigation while the decision card stays active\n (#4371)\n- **[Angel-Hair](https://github.com/Angel-Hair)** — reports that restored the\n opt-in `remember` tool to the first-turn catalog, made required user\n confirmation a real goal blocker, and added a clear recovery notice for\n cached approval denials (#4373, #4374, #4375)\n- **[Bruce / bruce6135](https://github.com/bruce6135)** — Kimi Coding Plan\n reproduction that exposed the false 1K emergency-compaction budget (#4368)\n- **[Matt Van Horn / mvanhorn](https://github.com/mvanhorn)** — first-turn\n `remember` regression coverage and the Kimi output-budget correction that\n prevents false emergency compaction (#4377, #4378)\n- **[郝某人BH / hmr-BH](https://github.com/hmr-BH)** — native Simplified\n Chinese review that replaced literal legal/doctrinal metaphors with clear\n collaboration terminology across setup and `/constitution` (#4369)\n- **[WavesMan](https://github.com/WavesMan)** — large-tree `@` completion\n reproduction that led to bounded background discovery and exact-path\n resolution on send (#4365)\n- **[SamhandsomeLee](https://github.com/SamhandsomeLee)** — input-budget-aware\n compaction work harvested from PR #4293 with co-authorship preserved\n- **[idling11](https://github.com/idling11)** — keyboard-driven keyword search\n for the docs and FAQ surfaces (PR #4364)\n- **[LeoLin990405](https://github.com/LeoLin990405)** — initial bounded\n workspace-walk approach and root-cause analysis for large-tree `@` mention\n discovery (PR #4367), harvested into the final fail-soft background\n implementation for #4365\n- **[octo-patch](https://github.com/octo-patch)** — MiniMax Messages provider\n support for MiniMax-M3 and MiniMax-M2.7 across OpenAI-compatible and Messages\n routes, regional endpoints, catalog metadata, pricing, and request coverage\n (PR #4354)\n- **[Wenshan Deng / findshan](https://github.com/findshan)** — original offline\n token/cache/cost scorecard and regression gate (#3388), extended with\n provider-aware provenance in #4335\n- **[hongqitai](https://github.com/hongqitai)** — localization extraction and\n English-locale enforcement that keep UI copy on the typed translation path\n (#4225, #4194)\n- **[nsfoxer](https://github.com/nsfoxer)** — bounded, fail-soft MCP capability\n discovery with advertised/legacy `tools/list` handling and Unicode-safe\n description formatting (#4308, harvested with co-authorship)\n- **[maple / yekern](https://github.com/yekern)** — root-cause analysis and fix\n direction for age-evicting terminal worker records from long-lived\n sub-agent state ledgers (#4217)\n- **[moduvoice](https://github.com/moduvoice)** — Korean (ko) UI locale with\n full key parity and onboarding/setup wiring (PR #4347)\n- **[qinlinwang](https://github.com/qinlinwang)** — Anthropic tool-schema\n sanitization for top-level oneOf/anyOf/allOf failures (PR #4346)\n- **[knqiufan](https://github.com/knqiufan)** — Anthropic cache-write token\n pricing at published rates (PR #4348, #4318)\n- **[Chavdar Ivanov / ci4ic4](https://github.com/ci4ic4)** — NetBSD QuickJS\n bindgen support for codewhale-workflow-js (PR #4349)\n- **[eugenicum](https://github.com/eugenicum)** — copy-paste rail-pollution\n report with code-aware fix direction (#4208)\n- **[JayBeest](https://github.com/JayBeest)** — parent\n `--disallowed-tools` inheritance through sub-agents and Fleet workers,\n harvested from PR #4096 with authorship preserved (#4042)\n- **[wuisabel-gif](https://github.com/wuisabel-gif)** — move runtime-thread\n coordination onto `parking_lot::Mutex` to remove async lock contention\n (#4243, #4149)\n- **[cyq1017](https://github.com/cyq1017)** — Windows Python stdio UTF-8\n handling and richer active-tool summaries (#4281/#4202, #3818)\n\n- **[Jeffrey Luna / Mr-Moon121](https://github.com/Mr-Moon121)** — anti-polling\n constitution for sub-agent waiting (harvested into #4097 / PR #4229 from\n PR #4098)\n\n- **[MXAntian](https://github.com/MXAntian)** — persist compaction summaries\n into thread records so `/v1` engine reloads keep compacted context (#4091)\n- **[nightt5879](https://github.com/nightt5879)** — keep native terminal\n selection usable when mouse capture is disabled, and advance fuzzy edit\n matches on UTF-8 character boundaries; preserve inline skill task text in\n PR #4372 (#4088, #4045, #3915)\n- **[gaord](https://github.com/gaord)** — add the community-maintained\n Codewhale for VS Code GUI frontend to the English and Chinese READMEs (#4035)\n- **[Darrell Thomas](https://github.com/DarrellThomas)** — remove the unused\n whale route taxonomy module and its dead tests (#4041)\n- **[Taixin Guo](https://github.com/taixinguo)** — CJK fuzzy-edit panic report\n and fix direction credited in the UTF-8 boundary patch (#3971, #4045)\n- **[CCChisato](https://github.com/CCChisato)** — preserve task text when\n sending dollar, unified-slash, and explicit skill invocations (#3915,\n co-authored)\n- **[Sun Zhenyuan / bistack](https://github.com/bistack)** — dynamic MCP server\n infrastructure and approval-gated model-started MCP servers from chat\n context (#3869, #3866, harvested with authorship preserved)\n\n
\n\n
\nv0.8.66 — release readiness, provider intake & UI hardening\n\nThe v0.8.66 release prepared the 0.8.66 package lane, hardened provider/model\nrouting and modal surfaces, advanced Hotbar/sub-agent UI reliability, and pulled\nin several community provider and bridge contributions with release credit.\n\n- **[lerugray](https://github.com/lerugray)** — Sakana AI Fugu provider\n support across config, CLI, TUI provider picker, docs, and model completions\n (#3748, harvested)\n- **[greyfreedom](https://github.com/greyfreedom)** — read-only `/config\n ask-rules` view for resolved ask-rule paths, status, and configured\n tool/command/path rules (#3569, merged)\n- **[noaft](https://github.com/noaft)** — `/links` provider docs fallback\n update, including the current Codewhale docs URL and a Baidu Qianfan docs\n link (#3621, harvested)\n- **[noaft](https://github.com/noaft)** — OpenModel provider support across\n config, CLI, TUI provider picker, docs, and registry checks (#3585,\n harvested)\n- **[pkeging](https://github.com/pkeging)** — original plugin manifest,\n discovery, CLI, and MCP foundation (#3708, #3709, #3710, merged), plus WeCom\n Bridge deployment and security documentation, including the approval-timeout\n configuration surface (#3640, harvested)\n- **[codepgq](https://github.com/codepgq)** — cross-client plugin-workflow\n migration request that shaped the explicit compatibility and trust boundary\n (#1172)\n- **[Wenshan Deng / findshan](https://github.com/findshan)** — original offline\n token/cache/cost scorecard and regression gate (#3388), extended with\n provider-aware provenance in #4335\n- **[buko](https://github.com/buko)** — precise Ctrl+O external-editor freeze\n reproduction that shaped the terminal input-pump fix (#3657)\n- **[cyq1017](https://github.com/cyq1017)** — sub-agent progress-event\n headroom report that shaped the fanout reliability hardening (#3783)\n\n
\n\n
\nv0.8.63 — sub-agent budgets, command extraction & reliability\n\n\nThe v0.8.63 release hardened sub-agent fanout with token-budget governance and\nqueue-and-drain admission, split the TUI command surface into focused modules,\nand landed reliability fixes for app-server teardown, JavaScript-execution\nproxying, and DeepSeek thinking tool calls — alongside community contributions.\n\n- **[donglovejava](https://github.com/donglovejava)** — per-worker sub-agent\n token-budget enforcement, so a `token_budget`/`max_tokens` on an individual\n `agent` call bounds that worker mid-run with a clean `budget_exhausted` stop\n (#3321, harvested)\n- **[cyq1017](https://github.com/cyq1017)** — `js_execution` proxy-environment\n handling (#3331), Hugging Face API-key env in the auth probe (#3329), and Codex\n Responses request retry (#3344) — harvested into the train\n- **[aboimpinto](https://github.com/aboimpinto)** — FEAT-005 command extraction:\n core/session command groups split into focused modules via `RegisterCommand`,\n `/swarm` migration, and Gherkin acceptance coverage (#3330, merged literally\n with authorship preserved)\n- **[wuisabel-gif](https://github.com/wuisabel-gif)** — tear down the delegated\n serve/app-server child process when the dispatcher exits (#3259 / #3317)\n- **[nightt5879](https://github.com/nightt5879)** — keep the onboarding marker in\n the codewhale home view (#3302) and branch-hygiene check hardening (#3348)\n- **[gaord](https://github.com/gaord)** — preserve thinking/tool blocks when\n seeding a thread from a saved session, plus Hugging Face provider env (#3329)\n- **[greyfreedom](https://github.com/greyfreedom)** — persist ask-permission rules\n from approvals and stabilize the CI verifier/provider-registry checks\n- Reports that shaped fixes: **[lordwedggie](https://github.com/lordwedggie)**\n (#3331 proxy env), **[Final527](https://github.com/Final527)** (#3240 legacy\n state migration), **[dxfq](https://github.com/dxfq)** (#3228 sidebar default)\n\n
\n\n
\nv0.8.62 — provider/model routing, TOML comment preservation & community closeout\n\n\nThe v0.8.62 release retuned provider/model routing (GLM-5.2 as the default direct\nZ.AI model, `type: \"explore\"` sub-agents defaulting to the cheaper same-family\nsibling), added TOML comment preservation and the Codewhale-only skill discovery\ngate, and shipped the static Linux x64 musl binary — alongside a broad community\ncloseout and a retroactive credit reconciliation pass.\n\n- **[zlh124](https://github.com/zlh124)** — preserve user comments and formatting\n when rewriting `config.toml`/`settings.toml`/`tui.toml` (with a malformed-file\n fallback) and Linux build deps in the cargo install guides (#3270)\n- **[idling11](https://github.com/idling11)** — Kimi `type:object` schema root for\n all parameter shapes (#3281), `approval_mode` restore on Plan→Agent with a\n wait-for-user guard (#3279), and workroom metadata draft types\n- **[LeoLin990405](https://github.com/LeoLin990405)** — Poppler `pdftotext -v`\n detection (#1667), session persistence before stall/cancel recovery (#2739),\n and debounced thinking-stream re-renders (#1620)\n- **[nightt5879](https://github.com/nightt5879)** — Codewhale-only skill discovery\n gate (`[skills].scan_codewhale_only`) ignoring cross-tool directories (#3296) and\n app-server no-auth loopback docs\n- **[reidliu41](https://github.com/reidliu41)** — slash commands exposed as hotbar\n actions (#3269)\n- **[wavezhang](https://github.com/wavezhang)** — static Linux x64 (musl) release\n binaries\n- **[wuisabel-gif](https://github.com/wuisabel-gif)** — per-tool snapshot gate\n respecting `[snapshots].enabled` (#3292) and composer history written under\n `.codewhale`\n- **[gaord](https://github.com/gaord)** — `workspace_follow_symlinks` setting for\n symlink-aware tool operations with hardened path handling\n- **[greyfreedom](https://github.com/greyfreedom)** — ask-permission rules honored\n at runtime (#3295)\n- **[aboimpinto](https://github.com/aboimpinto)** — EPIC-001 command-boundary\n replay and user-registry review feedback\n- **[h3c-hexin](https://github.com/h3c-hexin)** — volatile workspace path moved\n out of the static system prefix (prefix-cache hygiene)\n- **[hongchen1993](https://github.com/hongchen1993)** — heuristic-only auto routing\n when the flash router is unavailable\n- **[lucaszhu-hue](https://github.com/lucaszhu-hue)** — Atlas Cloud provider setup\n docs\n- Retroactive reconciliation (shipped earlier, credited now):\n **[manaskarra](https://github.com/manaskarra)** / **[xfy6238](https://github.com/xfy6238)** (#1157),\n **[djairjr](https://github.com/djairjr)** (#1309 alongside reidliu41),\n **[Geallier](https://github.com/Geallier)** (#1470),\n **[quentin-lian](https://github.com/quentin-lian)** / **[k0tran](https://github.com/k0tran)** (#1531 / #1992),\n **[F1LT3R](https://github.com/F1LT3R)** (#1656),\n **[cmyyy](https://github.com/cmyyy)** (#1842),\n **[Final527](https://github.com/Final527)** (#3058)\n\n
\n\n
\nv0.8.61 — runtime control plane & community closeout\n\n\nThe v0.8.61 release was a community closeout: the runtime control plane, provider\npatches, and TUI fixes landed alongside first-time and returning contributor work.\n\n- **[idling11](https://github.com/idling11)** — DeepInfra provider support with\n OpenAI-compatible routing and model registry entries (#3235, closes #3231)\n- **[greyfreedom](https://github.com/greyfreedom)** — atomic ask-only\n permission-rule persistence so an execution-policy rule survives the write\n that triggered the prompt (#3233)\n- **[VincentCorleone](https://github.com/VincentCorleone)** — WeChat bridge\n (`integrations/weixin-bridge`) leveraging Feishu + Tencent OpenClaw (#3206)\n- **[nightt5879](https://github.com/nightt5879)** — whale-accent rename (#3197)\n and `$skillname` aliases for `/skill` activation (#3241)\n- **[mvanhorn](https://github.com/mvanhorn)** — non-DeepSeek model pricing\n coverage (#3201)\n- **[cyq1017](https://github.com/cyq1017)** — Telegram polling transport\n (#3195) and VS Code read-only API documentation (#3013)\n- **[RobertEmprechtinger](https://github.com/RobertEmprechtinger)** — mobile\n event history (#3220)\n- **[gaord](https://github.com/gaord)** — runtime-API session save (#3199)\n- **[hongchen1993](https://github.com/hongchen1993)** — `DEEPSEEK_BASE_URL` /\n `MODEL` honored in `exec` (#3221)\n\n
\n\n
\nForward track — recent v0.9 work (newest)\n\n\n- **[xyuai](https://github.com/xyuai)** — canonical Codewhale settings path,\n provider persistence, provider picker, logout-scope, and MiMo auth cleanup\n work (#2730, #2714, #2715, #2717, #2718)\n- **[shenjackyuanjie](https://github.com/shenjackyuanjie)** — HarmonyOS /\n OpenHarmony porting work and MatePad Edge validation trail (#2634)\n- **[ousamabenyounes](https://github.com/ousamabenyounes)** — AZERTY/AltGr\n composer shortcut fix for Windows keyboard layouts (#2863, #2867)\n- **[reidliu41](https://github.com/reidliu41)** — hotbar action-registry\n foundation and Ollama model-completion cleanup for the forward track (#2866,\n #2742)\n- **[ljm3790865](https://github.com/ljm3790865)** — multi-tab\n core/persistence foundation and broader tab collaboration direction (#2864,\n #2753)\n- **[sximelon](https://github.com/sximelon)** — saved-session resume footer\n hint work plus provider-trait metadata registry direction reviewed and\n harvested for the forward track (#2758, #2760, #2479)\n- **[aboimpinto](https://github.com/aboimpinto)** — sidebar command polish and\n pausable custom-command lifecycle direction harvested into the forward track,\n plus the directly merged command-support boundary cleanup and broader command\n layer design direction (#2788, #2732, #2871, #2851, #2791)\n- **[AdityaVG13](https://github.com/AdityaVG13)** — Workflow orchestration\n and cost-tracking drafts that shaped the maintained workflow IR and\n TraceStore foundation (#2482, #2486)\n- **[lbcheng888](https://github.com/lbcheng888)**,\n **[AiurArtanis](https://github.com/AiurArtanis)**, and\n **[nasus9527](https://github.com/nasus9527)** — VS Code extension scaffold\n direction, Agent View request, and IDE plugin request that shaped the\n official Phase 0 extension (#1022, #1584, #2580)\n- **[HUQIANTAO](https://github.com/HUQIANTAO)** — `web_run` cache-state\n lock-splitting, turn-metadata prefix-cache stability, and project-context\n cache work (#2502, #2517, #2636)\n- **[idling11](https://github.com/idling11)** — PlanArtifact continuity,\n dense tool-call transcript collapse, sidebar detail popovers, and\n HarnessPosture provider/model policy direction (#2733, #2738, #2734,\n #2741, #2692, #2694, #2693)\n- **[h3c-hexin](https://github.com/h3c-hexin)** — sub-agent model inheritance,\n configured `skills_dir` discovery, prompt-environment stability, and static\n prompt composer direction (#2736, #2737, #2786)\n- **[gaord](https://github.com/gaord)** — runtime thread workspace updates and\n completed-thread saved-session API work (#2640, #2639)\n- **[cyq1017](https://github.com/cyq1017)** — trusted workspace MCP config,\n provider auth rollback, custom search endpoint, custom completion sound,\n restore-listing, and pending-input delivery-mode label work (#2751, #2755,\n #2510, #2512, #2513, #2532, #2054)\n- **[yusufgurdogan](https://github.com/yusufgurdogan)** — Sofya search\n provider implementation harvested as a non-default search backend (#2790)\n- **[LeoAlex0](https://github.com/LeoAlex0)** — runtime prompt metadata cache\n direction harvested into the maintained prompt/cache path (#2687);\n `allow_shell` prefix-cache decoupling and `visibility=\"internal\"`\n explanation for mode-flip stability (#2949, #2951)\n- **[hongchen1993](https://github.com/hongchen1993)** — Volcengine provider\n in TUI dispatcher and dispatcher API-key preference (#2923, #2928)\n- **[NASLXTO](https://github.com/NASLXTO)** and\n **[wuxixing](https://github.com/wuxixing)** — large-workspace startup\n reports that shaped the bounded project-context fallback (#697, #1827)\n- **[shuxiangxuebiancheng](https://github.com/shuxiangxuebiancheng)**,\n **[hongqitai](https://github.com/hongqitai)**, and\n **[cyq1017](https://github.com/cyq1017)** — third-party\n OpenAI-compatible path-suffix report and follow-up review trail (#1874,\n #2508, #2506)\n\n\n
\n\n
\nRecurring & historical contributors\n\n\n- **[merchloubna70-dot](https://github.com/merchloubna70-dot)** — 28 PRs spanning features, fixes, and VS Code extension scaffolding (#645–#681)\n- **[WyxBUPT-22](https://github.com/WyxBUPT-22)** — Markdown rendering for tables, bold/italic, and horizontal rules (#579)\n- **[loongmiaow-pixel](https://github.com/loongmiaow-pixel)** — Windows + China install documentation (#578)\n- **[20bytes](https://github.com/20bytes)** — User memory docs and help polish (#569)\n- **[staryxchen](https://github.com/staryxchen)** — glibc compatibility preflight (#556)\n- **[Vishnu1837](https://github.com/Vishnu1837)** — glibc compatibility improvements and terminal restoration on SIGINT/SIGTERM (#565, #1586)\n- **[shentoumengxin](https://github.com/shentoumengxin)** — Shell `cwd` boundary validation (#524)\n- **[toi500](https://github.com/toi500)** — Windows paste fix report\n- **[xsstomy](https://github.com/xsstomy)** — Terminal startup repaint report\n- **[melody0709](https://github.com/melody0709)** — Slash-prefix Enter activation report\n- **[lloydzhou](https://github.com/lloydzhou)** and **[jeoor](https://github.com/jeoor)** — Compaction cost reports; lloydzhou also contributed deterministic environment context (#813, #922) and KV prefix-cache stabilisation (#1080)\n- **[Agent-Skill-007](https://github.com/Agent-Skill-007)** — README clarity pass (#685)\n- **[woyxiang](https://github.com/woyxiang)** — Windows install documentation (#696)\n- **[wangfeng](mailto:wangfengcsu@qq.com)** — Pricing/discount info update (#692)\n- **[zichen0116](https://github.com/zichen0116)** — CODE_OF_CONDUCT.md (#686)\n- **[dfwqdyl-ui](https://github.com/dfwqdyl-ui)** — model ID case-sensitivity compatibility report (#729)\n- **[Oliver-ZPLiu](https://github.com/Oliver-ZPLiu)** — stale `working...` state bug report, Windows clipboard fallback, MCP Streamable HTTP session fixes, and Homebrew tap automation (#738, #850, #1643, #1631)\n- **[reidliu41](https://github.com/reidliu41)** — resume hint, workspace trust persistence, Ollama provider support, thinking-block stream finalization, CI cache hardening, streaming wrap, and DeepSeek model completions (#863, #870, #921, #1078, #1603, #1628, #1601)\n- **[xieshutao](https://github.com/xieshutao)** — plain Markdown skill fallback (#869)\n- **[GK012](https://github.com/GK012)** — npm wrapper `--version` fallback (#885)\n- **[y0sif](https://github.com/y0sif)** — parent turn-loop wakeup after direct child sub-agent completion (#901)\n- **[mac119](https://github.com/mac119)** and **[leo119](https://github.com/leo119)** — `codewhale update` command documentation (#838, #917)\n- **[dumbjack](https://github.com/dumbjack)** / **浩淼的mac** — command-safety null-byte hardening (#706, #918)\n- **macworkers** — fork confirmation with the new session id (#600, #919)\n- **zero** and **[zerx-lab](https://github.com/zerx-lab)** — notification condition config and richer OSC 9 notification body (#820, #920)\n- **[chnjames](https://github.com/chnjames)** — cached @mention completions, config recovery polish, and Windows UTF-8 shell output (#849, #927, #982, #1018)\n- **[angziii](https://github.com/angziii)** — config safety, async cleanup, Docker hardening, and command-safety fixes (#822, #824, #827, #831, #833, #835, #837)\n- **[elowen53](https://github.com/elowen53)** — UTF-8 decoding and deterministic test coverage (#825, #840)\n- **[wdw8276](https://github.com/wdw8276)** — `/rename` command for custom session titles (#836)\n- **[banqii](https://github.com/banqii)** — `.cursor/skills` discovery path support (#817)\n- **[junskyeed](https://github.com/junskyeed)** — dynamic `max_tokens` calculation for API requests (#826)\n- **Hafeez Pizofreude** — SSRF protection in `fetch_url` and Star History chart\n- **Unic (YuniqueUnic)** — Schema-driven config UI (TUI + web)\n- **Jason** — SSRF security hardening\n- **[axobase001](https://github.com/axobase001)** — snapshot orphan cleanup, npm install guards, session telemetry fixes, model-scope cache clear, symlinked skill support, npm mirror-escape-hatch guidance, proxy preservation for child tasks, mobile runtime control, Docker toolbox docs, large-output receipts, and activity detail context (#975, #1032, #1047, #1049, #1052, #1019, #1051, #1056, #1608, #1968, #2296, #2297, #2298)\n- **[MengZ-super](https://github.com/MengZ-super)** — `/theme` command foundation and SSE gzip/brotli decompression (#1057, #1061)\n- **[DI-HUO-MING-YI](https://github.com/DI-HUO-MING-YI)** — Plan-mode read-only sandbox safety fix (#1077)\n- **[bevis-wong](https://github.com/bevis-wong)** — precise paste-Enter auto-submit reproducer (#1073)\n- **[Duducoco](https://github.com/Duducoco)** and **[AlphaGogoo](https://github.com/AlphaGogoo)** — skills slash-menu and `/skills` coverage fix (#1068, #1083)\n- **[ArronAI007](https://github.com/ArronAI007)** — window-resize artifact fix for macOS Terminal.app and ConHost (#993)\n- **[THINKER-ONLY](https://github.com/THINKER-ONLY)** — OpenRouter and custom-endpoint model-ID preservation (#1066)\n- **[Jefsky](https://github.com/Jefsky)** — DeepSeek endpoint correction report (#1079, #1084)\n- **[wlon](https://github.com/wlon)** — NVIDIA NIM provider API-key preference diagnosis (#1081)\n- **[Horace Liu](https://github.com/liuhq)** — Nix package support and install documentation (#1173)\n- **[jieshu666](https://github.com/jieshu666)** — terminal repaint flicker reduction (#1563)\n- **[gordonlu](https://github.com/gordonlu)** — Windows Enter / CSI-u input fix, status picker localization (7 MessageIds), approval dialog localization across 7 locales, and mode picker + composer Vim indicator localization across 7 locales (#1612, #2896, #2891, #2239)\n- **[mdrkrg](https://github.com/mdrkrg)** — first-run onboarding crash fix when the API key is missing (#1598)\n- **[Aitensa](https://github.com/Aitensa)** — CJK wrapping propagation for diff and pager output (#1622)\n- **[qiyan233](https://github.com/qiyan233)** — legacy DeepSeek CN provider alias compatibility (#1645)\n- **[zlh124](https://github.com/zlh124)** — WSL2/headless startup report, clipboard-init fix, Codewhale tab-title polish, localized context-menu labels, and approval-dialog fixes (#1772, #1773, #2319, #2320, #2325)\n- **[aboimpinto](https://github.com/aboimpinto)** — Windows alt-screen\n logging, Home/End composer, runtime log follow-ups, sidebar command polish,\n and pausable command lifecycle work (#1774, #1776, #1748, #1749, #1782,\n #1783, #2788, #2732)\n- **[LeoLin990405](https://github.com/LeoLin990405)** — provider model passthrough, reasoning replay, thinking-only turn, and Windows quoting fixes (#1740, #1743, #1742, #1744)\n- **[nightt5879](https://github.com/nightt5879)** — Ctrl+C prompt restore, provider registry drift docs, tool-search defaults, footer git branch display, and startup prompt interactivity (#1764, #2274, #2344, #2347, #2373)\n- **[donglovejava](https://github.com/donglovejava)** — paste @file consolidation, CJK panic fix, user feedback, RLM routing, edit_file retry, hidden-worktree discovery skip, IME composer routing, and eager shell companion tools (#2154-#2168, #2302, #2329, #2330, #2331)\n- **[encyc](https://github.com/encyc)** — session token breakdown in footer and `/status` (#2152)\n- **[saieswar237](https://github.com/saieswar237)** — review pipeline docs (#2178)\n- **[sximelon](https://github.com/sximelon)** — paste Enter suppression, key handler extraction (#2174, #2042)\n- **[nanookclaw](https://github.com/nanookclaw)** — search provider in doctor output (#2135)\n- **[Sskift](https://github.com/Sskift)** — CLI default env override prevention and statusline footer clearing (#2119, #2248)\n- **[xin1104](https://github.com/xin1104)** — Homebrew codewhale binary install (#2105)\n- **[mrluanma](https://github.com/mrluanma)** — Metaso search provider (#2059)\n- **[Lellansin](https://github.com/Lellansin)** — skip config merge at home dir (#2055)\n- **[zhuangbiaowei](https://github.com/zhuangbiaowei)** — update release channels and legacy MCP SSE fixes (#2145, #2301)\n- **[cy2311](https://github.com/cy2311)** — Windows `.bat` launcher for Codewhale (#1861)\n- **[LING71671](https://github.com/LING71671)** — effective cost currency context, custom provider docs, and core tool taxonomy prompt block (#1902, #2287, #2292)\n- **[dzyuan](https://github.com/dzyuan)** — Volcengine provider support with DeepSeek V4 Pro/Flash models (#1993)\n- **[mvanhorn](https://github.com/mvanhorn)** — live request-shape test factories and global `~/.agents/AGENTS.md` fallback (#2107, #2236)\n- **[malsony](https://github.com/malsony)** — Matrix-inspired theme and theme picker improvements (#2129)\n- **[gaord](https://github.com/gaord)** — external GUI runtime event bridge, session detail serialization, and skills API discovery alignment (#2133, #2265, #2285)\n- **[yuanchenglu](https://github.com/yuanchenglu)** — Feishu per-chat model switching (#2149)\n- **[HUQIANTAO](https://github.com/HUQIANTAO)** — Xiaomi balance/status work, stalled-turn recovery, approval intent summaries, mobile smoke/QR support, Claude theme, and broad docs/test/CI coverage (#2257, #2267, #2283, #2384, #2385, #2389, #2403, #2440-#2458, #2460)\n- **[h3c-hexin](https://github.com/h3c-hexin)** — web-search URL decoding, prompt/instructions override hooks, sub-agent guidance, SSRF fake-IP trust configuration, and prompt-cache-friendly environment placement (#2245, #2311, #2313, #2314, #2354, #2355, #2356)\n- **[tdccccc](https://github.com/tdccccc)** — approval prompt key-detail and shell-preview work harvested into the maintained approval path (#1991, #2269)\n- **[AresNing](https://github.com/AresNing)** — first-run guide, message-submit hook transform design, and turn-end observer hook work harvested into the maintained hooks path (#2278, #2318, #2434, #2578)\n- **[Implementist](https://github.com/Implementist)** — Volcengine Ark search provider and reliability hardening (#2426, #2429, #2439)\n- **[lihuan215](https://github.com/lihuan215)** — Unix socket hook sink design harvested into the opt-in hook event path (#2333, #2430)\n- **[AdityaVG13](https://github.com/AdityaVG13)** — Xiaomi MiMo provider support (#2246)\n- **[New2Niu](https://github.com/New2Niu)** — macOS display notifications (#2260)\n- **[AiurArtanis](https://github.com/AiurArtanis)** — Solarized Light theme and\n canonical-background regression report (#2270, #4457)\n- **[Lee-take](https://github.com/Lee-take)** — task migration and session environment isolation fixes (#2272)\n- **[LeoAlex0](https://github.com/LeoAlex0)** — session persistence fixes for message counts and tool-output cache preservation (#2388, #2395)\n- **[jimmyzhuu](https://github.com/jimmyzhuu)** — Baidu AI Search backend for `web_search` (#2371)\n- **[rockyzhang](https://github.com/rockyzhang)** — RISC-V prebuilt binary support (#2383)\n- **[mo-vic](https://github.com/mo-vic)** — `/purge` slash command for agent-driven context pruning (#2387)\n- **[hufanexplore](https://github.com/hufanexplore)** — Java and Vue language-server defaults (#2367)\n- **[hoclaptrinh33](https://github.com/hoclaptrinh33)** — Vietnamese localization support (#2358)\n- **[AccMoment](https://github.com/AccMoment)** — proxy option for the update command (#2281)\n- **[idling11](https://github.com/idling11)** — durable debt ledger and `/hunt` rename/trophy-card work (#2161, #2306)\n- **[cyq1017](https://github.com/cyq1017)** — runtime event envelope, render-diff debug logging, and deterministic composer history flushing (#2252, #2332, #2375)\n- **[hongqitai](https://github.com/hongqitai)** — state schema parent-entry support and clippy/fmt cleanup (#2308, #2432)\n- **[BryonGo](https://github.com/BryonGo)** — effective-model compaction budgeting fix (#2437)\n- **[xyuai](https://github.com/xyuai)** — provider persistence to config, /logout scope clarification, provider picker key replacement shortcut, MiMo auth state cleanup (#2714, #2715, #2717, #2718)\n- **[RefuseOdd](https://github.com/RefuseOdd)** — configurable `path_suffix` for OpenAI-compatible endpoints (#2558)\n\n\n
\n\n
\nv0.8.48 — reports, repros & verification (earliest listed)\n\nReports, repros, and verification that shaped v0.8.48 also deserve visible\ncredit: **[@buko](https://github.com/buko)**, **[@yyyCode](https://github.com/yyyCode)**,\n**[@gaslebinh-glitch](https://github.com/gaslebinh-glitch)**, **[@Dr3259](https://github.com/Dr3259)**,\n**[@lpeng1711694086-lang](https://github.com/lpeng1711694086-lang)**, **[@VerrPower](https://github.com/VerrPower)**,\n**[@yan-zay](https://github.com/yan-zay)**, **[@jretz](https://github.com/jretz)**,\n**[@Neo-millunnium](https://github.com/Neo-millunnium)**, **[@caeserchen](https://github.com/caeserchen)**,\n**[@T-Phuong-Nguyen](https://github.com/T-Phuong-Nguyen)**, **[@zhyuzhyu](https://github.com/zhyuzhyu)**,\n**[@0gl20shk0sbt36](https://github.com/0gl20shk0sbt36)**, **[@hatakes](https://github.com/hatakes)**,\n**[@goodvecn-dev](https://github.com/goodvecn-dev)**, **[@bevis-wong](https://github.com/bevis-wong)**,\n**[@PurplePulse](https://github.com/PurplePulse)**, and **[@nbiish](https://github.com/nbiish)**.\n\n---\n\n
\n\n
\nReconciled credits — earlier contributors restored to the record\n\nA credit-reconciliation pass mapped every shipped commit author to a GitHub\nhandle and found these contributors whose merged work was not yet listed here or\nin the changelog. Restoring them with thanks — every one shipped real code.\n\n- **[MoriTang](https://github.com/MoriTang)** — account balance status-bar item, with a request timeout, reused HTTP client, stale-balance-on-failure handling, and DeepSeek-gated display\n- **[mars-base](https://github.com/mars-base)** — session title shown in the composer border and `gh` discovery across common install paths (#836)\n- **[Giggitycountless](https://github.com/Giggitycountless)** — auto-add `.deepseek/` to `.gitignore`, gitignore-check robustness, and `/clear` resetting the Todos panel\n- **[Inference1](https://github.com/Inference1)** — vLLM provider support, README pricing/structure clarity, and the Model Studio reasoning route guard: a fail-closed host check so Alibaba's `enable_thinking` never reaches a custom gateway, plus catching that Codewhale was sending a disable switch to the always-thinking `qwen3.8-max` (#737, #776, #5233)\n- **[membphis](https://github.com/membphis)** — bordered Markdown table rendering and Shift+Enter newline in the composer (#801)\n- **[JasonOA888](https://github.com/JasonOA888)** — `web_run` network-policy enforcement and refusing to snapshot `$HOME` (#798, #800)\n- **[tuohai666](https://github.com/tuohai666)** — recursive skills-directory reading plus hook-dispatch and approval-branch test coverage (#811)\n- **[xuezhaoyu](https://github.com/xuezhaoyu)** — DEC 2026 synchronized-update flicker fix for GPU terminals, guaranteeing `END_SYNC_UPDATE` even when a draw fails\n- **[manaskarra](https://github.com/manaskarra)** — global `~/.deepseek/AGENTS.md` fallback loading (#1157)\n- **[gerryqi](https://github.com/gerryqi)** — wrap fire-and-forget `spawn_blocking` calls with a panic dump (#810)\n- **[ccomma](https://github.com/ccomma)** — skip snapshots for dangerous workspaces (#804)\n- **[AGSaturn](https://github.com/AGSaturn)** — preserve requested model-ID casing in registry resolution (#733)\n- **[wucm667](https://github.com/wucm667)** — accept provider-prefixed DeepSeek model IDs (#794)\n- **[quentin-lian](https://github.com/quentin-lian)** — portable-pty 0.9 upgrade for LoongArch64 support (#1992)\n- **[Beltran12138](https://github.com/Beltran12138)** — treat `deepseek-chat` / `deepseek-reasoner` aliases as reasoning models\n- **[chuntseevolving](https://github.com/chuntseevolving)** — send `TurnStarted` before snapshot to prevent WSL2 timeout\n- **[lawrencewzen](https://github.com/lawrencewzen)** — preserve UTF-8 while stripping ANSI\n- **[hhhaiai](https://github.com/hhhaiai)** — keep workspace skills visible when the prompt budget truncates\n- **[khalid-hungerstation](https://github.com/khalid-hungerstation)** — bundle the delegate skill alongside skill-creator\n- **[Anyexyz](https://github.com/Anyexyz)** — GitHub Actions workflow to sync with the CNB repo\n- **[nightfallsad](https://github.com/nightfallsad)** — clearer `/continue` hint copy\n- **[zxyasfas](https://github.com/zxyasfas)** — align Rust MSRV references with the workspace (#739)\n\n_A follow-up audit of harvested commits (work reimplemented onto a maintainer\nbranch rather than merged) surfaced contributors whose machine-readable credit\nwas dropped. Restoring them here — every one shipped real code:_\n\n- **[CrepuscularIRIS](https://github.com/CrepuscularIRIS)** — OpenHarmony→Linux npm binary mapping, O(1) job-panel refresh, file-mention UTF-8 boundary safety, Kitty keyboard protocol on Windows, and auto low-motion under Termius/SSH (#1479, #1483, #1494, #1495, #1499, #1475)\n- **[MMMarcinho](https://github.com/MMMarcinho)** — `image_analyze` vision tool (#1467)\n- **[MeAiRobot](https://github.com/MeAiRobot)** — toast-stack overlay z-order fix (#1485)\n- **[NorethSea](https://github.com/NorethSea)** — `update` refreshing the sibling TUI binary (#1492)\n- **[SamhandsomeLee](https://github.com/SamhandsomeLee)** — bundled\n v4-best-practices skill (#1448) and input-budget-aware compaction trigger\n (#4293)\n- **[YaYII](https://github.com/YaYII)** — opt-in `/translate` command (#1462)\n- **[sandofree](https://github.com/sandofree)** — Tavily and Bocha `web_search` backends (#1294)\n- **[tiger-dog](https://github.com/tiger-dog)** — approval one-line banner and Markdown underscore handling (#1455)\n- **[Jianfengwu2024](https://github.com/Jianfengwu2024)** — preserving MSVC toolchain vars in the child environment (#1487)\n- **[wplll](https://github.com/wplll)** — prompt-cache warmup keys, tool-catalog handling, a dedup test, and pack ordering (#2390, #2391, #2392, #2393)\n\nAdditional harvested PRs from the same audit, credited to contributors already\nlisted above: **[axobase001](https://github.com/axobase001)** (#2400, #2405, #2406, #2407, #2408, #2415), **[cyq1017](https://github.com/cyq1017)** (#2516, #2534, #2540), **[Oliver-ZPLiu](https://github.com/Oliver-ZPLiu)** (#1451, #1456), **[reidliu41](https://github.com/reidliu41)** (#1444, #1493), **[lucaszhu-hue](https://github.com/lucaszhu-hue)** (#1436, #2343), **[h3c-hexin](https://github.com/h3c-hexin)** (#1480), **[Duducoco](https://github.com/Duducoco)** (#1345), **[zhuangbiaowei](https://github.com/zhuangbiaowei)** (#1416), **[wdw8276](https://github.com/wdw8276)** (#1498), and **[buko](https://github.com/buko)** (#2377).\n\n_A further machine-credit pass restored these contributors, missing from both the\nlist above and the contribution graph (AUTHOR_MAP entries added; logins/IDs\nverified against the GitHub user API) — every one shipped real code:_\n\n- **[1Git2Clone](https://github.com/1Git2Clone)** — `Ctrl+P`/`Ctrl+N` slash-menu navigation\n- **[rockeverm3m](https://github.com/rockeverm3m)** — community ACP adapter reference in the docs\n- **[hxy91819](https://github.com/hxy91819)** — stable MCP tool ordering for prefix-cache stability (#1319)\n- **[heloanc](https://github.com/heloanc)** — Home/End keys moving the cursor in the input box (#1246)\n\n**Earlier reports, proposals and reviewed overlap**\n\n- **[dajiaohuang](https://github.com/dajiaohuang)** — independently diagnosed the local-model output-budget problem and submitted a reviewed patch; equivalent behavior had already shipped ([#5883](https://github.com/codewhale-hq/Codewhale/pull/5883)).\n- **[Edouard-Legoupil](https://github.com/Edouard-Legoupil)** — proposed user-controlled skill evolution from repeated work and corrections ([#5860](https://github.com/codewhale-hq/Codewhale/issues/5860)).\n- **[freedomlovesfrank](https://github.com/freedomlovesfrank)** — proposed an optional Rust allocator alongside the existing default ([#5872](https://github.com/codewhale-hq/Codewhale/issues/5872)).\n- **[zyxrealhero](https://github.com/zyxrealhero)** — reported malformed tool-call history after a Runtime restart, with a reproduction and payload analysis ([#5823](https://github.com/codewhale-hq/Codewhale/issues/5823)).\n- **[cmdcorp6534](https://github.com/cmdcorp6534)** — reported Chinese IME pre-edit and composer behavior in Windows Terminal, including input shown behind modal dialogs ([#2323](https://github.com/codewhale-hq/Codewhale/issues/2323)).\n- **[ivysrono](https://github.com/ivysrono)** — proposed switching to a configured backup profile after provider rate-limit errors ([#855](https://github.com/codewhale-hq/Codewhale/issues/855)).\n- **[JoeKerF](https://github.com/JoeKerF)** — proposed desktop project and task workflows with managed runtime startup, recovery, and updates ([#4986](https://github.com/codewhale-hq/Codewhale/issues/4986)).\n- **[ShikiSuen](https://github.com/ShikiSuen)** — provided a detailed reproduction of SwiftPM test failures inside the macOS sandbox ([#2617](https://github.com/codewhale-hq/Codewhale/issues/2617)).\n\n
\n\n---\n\nMissed someone? Open an issue or PR — credit is kept current, and names are happily added. See [CONTRIBUTING.md](../CONTRIBUTING.md) to get started.\n" }, { "path": "docs/RELEASE_CHECKLIST.md", diff --git a/web/lib/release-credits.ts b/web/lib/release-credits.ts index 06d93abca9..0393f8c300 100644 --- a/web/lib/release-credits.ts +++ b/web/lib/release-credits.ts @@ -20,6 +20,8 @@ /** Contributors whose PRs were merged or harvested into this release. */ export const RELEASE_CONTRIBUTORS: string[] = [ + "@henrikdukefoss", + "@shenjackyuanjie", "@SparkofSpike", "@dajiaohuang", "@gaord",