v1.54.9
[1.54.9] — 2026-05-18
fix(llm): honour the parent .env LLM keys at request time — stop mis-routing to a stale/invalid provider.
🐛 Fixes
- Live evaluation could fail with "Gemini API error: API key not valid" even when
ANTHROPIC_API_KEYwas the configured provider. Root cause:hasAnthropicKey()/hasGeminiKey()(andrunAnthropic's key/model lookup) read only the boot-timeprocess.envsnapshot. If the Anthropic key was added to the parent.envafter the server started, the running process never saw it → Anthropic detection was false, and evaluation fell through to whatever stale key was inprocess.env(often an old, invalidGEMINI_API_KEY). The Gemini exec path (a parent Node subprocess) already read the live parent.env, so the two providers resolved keys inconsistently. - New
effectiveEnv(key, envFilePath)inenv-config.mjs: a non-emptyprocess.envvalue wins (covers shell exports and the live-apply inPOST /api/config); otherwise the current parent.envfile is consulted.anthropic.mjsnow resolvesANTHROPIC_API_KEY,ANTHROPIC_MODEL, and the Gemini-key check through it, so a key set in the parent.envis honoured without a server restart and key DETECTION always matches the key the request actually SENDS. Provider order is unchanged (auto→ Anthropic-then-Gemini); this only fixes detection. Keys are never logged or returned (the REVIEW-B4 no-leak test still passes).
🧪 Tests
test: tests/anthropic.test.mjsrewritten to be CI-isolated (tempCAREER_OPS_ROOT, dynamic import) with 2 new cases reproducing the exact bug (key only in parent.env→ detected;runAnthropicsends the parent-.envkey + model whenprocess.envis unset).test: tests/env-config.test.mjs+3effectiveEnvcases (process.env precedence,.envfallback incl. empty-string-as-unset, missing-file / absent-key / no-path → undefined) — 100% of the new branch. 742 → 747.