feat(config): support configurable fallback base URLs - #242
Conversation
TerrysPOV
left a comment
There was a problem hiding this comment.
[COMPLEX — triage] 9 files, but mitigated: +194/-46 (well under 300 lines), substance is in two code files (config.ts, runner.ts); the rest are tests, docs, one example, and version files. Clean refactor of the existing config/runner env path — no new process model or plugin API.
Vision: ALIGNED — strictly opt-in. With baseUrl unset (every existing install), the default path is byte-identical, and the previously-implicit GLM→z.ai endpoint becomes explicit and configurable rather than hidden. Docs match the code; the buildChildEnv export the example relies on is real.
Overlapping PRs: the 1.0.41 version bump collides with #234, which merged earlier today and already put master at 1.0.41 — this branch (last updated 2026-06-30) needs a rebase onto current master + re-bump to 1.0.42, or both version guards fail. Also shares runner.ts regions with open #222 / #251 (merge-time friction only, no logical overlap).
Code review
Found 2 issues:
- Ambient
ANTHROPIC_API_KEYis forwarded to a user-specifiedbaseUrl.cleanSpawnEnvcopies the whole parent env and strips only the threeCLAUDE_CODE*keys — notANTHROPIC_API_KEY/ANTHROPIC_AUTH_TOKEN:
Lines 107 to 119 in 829e7ec
buildChildEnv sets ANTHROPIC_AUTH_TOKEN only when a config api is present and points ANTHROPIC_BASE_URL at the custom URL, but never clears an inherited Anthropic key:
Lines 334 to 354 in 829e7ec
So a user who has ANTHROPIC_API_KEY exported (a standard Claude Code auth method), points baseUrl/fallback.baseUrl at a third-party proxy, and leaves api blank ("just route through my proxy, no separate key") ships their real Anthropic key to that host. Pre-PR this couldn't happen for arbitrary hosts — only the hardcoded z.ai endpoint under model: glm. Suggest: when a custom baseUrl is set and no api is configured, drop ANTHROPIC_API_KEY/ANTHROPIC_AUTH_TOKEN from the child env (the same posture #102 established for host-managed tokens).
- The 50-minute request timeout isn't extended for custom
baseUrls.API_TIMEOUT_MS = "3000000"is still gated onmodel === "glm"only:
Lines 349 to 351 in 829e7ec
The whole point of the feature is slower Anthropic-compatible providers (OpenRouter, LiteLLM, local proxies), but those get the default client timeout where glm doesn't — so "my OpenRouter fallback times out but glm didn't." Extend the timeout when a custom baseUrl is set, not just for glm.
829e7ec to
90b4e41
Compare
Problem
ClaudeClaw currently ties the fallback provider base URL to the special
glmmodel name. This makes fallback routing provider-specific and forces users of Anthropic-compatible providers such as OpenRouter, LiteLLM, or local proxies to rely on a hardcoded GLM endpoint or misleading model names.Solution
This PR adds explicit
baseUrlsupport to the model configuration and routes the complete model config into Claude subprocess environment construction. Explicit base URLs now setANTHROPIC_BASE_URL; the existingmodel: "glm"behavior remains intact as the legacy default when no base URL is configured.Changes
baseUrl/fallback.baseUrlparsing to settings.ModelConfigobjects.baseUrlis omitted.Testing
bun test src/__tests__/config.test.ts src/__tests__/runner-env.test.ts src/__tests__/jobs.test.tsbun run examples/fallback-base-url/demo.tsANTHROPIC_AUTH_TOKENandANTHROPIC_BASE_URLare populated from fallback configbun testtests/session-files.test.tsand match the baseline observed before this change.Notes for Reviewer
baseUrltakes precedence over the GLM default endpoint.model: "glm"withoutbaseUrlstill maps tohttps://api.z.ai/api/anthropicfor backward compatibility.sameModelConfignow includesbaseUrlso a fallback can differ from the primary by provider endpoint even when model/API fields overlap.Closes #215