[1.55.0] — 2026-05-18
feat(llm): headless live-eval runs via "OR" — Anthropic | Gemini | OpenAI | Qwen, auto-selected by whichever key is set.
✨ Features
- Per user request, the web-ui ⚡ live eval now works with whichever API key is set, not just Anthropic/Gemini.
LLM_PROVIDERgainsopenaiandqwen;auto(default) uses the first provider whose key is present, preferring Anthropic → Gemini → OpenAI → Qwen. An explicit value pins one; a forced provider with no key still falls through to the manual-prompt path. - New
server/lib/openai.mjs— a zero-dependency OpenAI-compatible Chat Completions client (same secure direct-HTTPS pattern asanthropic.mjs:AbortControllertimeout, key never logged,effectiveEnv()key resolution so a parent-.envkey works without a restart). One core (runOpenAICompatible) backsrunOpenAI(api.openai.com) andrunQwen(Alibaba DashScope OpenAI-compatible mode; override the endpoint withQWEN_BASE_URLin the raw.envfor the mainland-CN host). No SDKs, no arbitrary CLI execution — the parent project stays CLI-agnostic (Claude Code · Codex · Gemini · OpenCode · Qwen · Copilot · Kimi); this only extends the headless API-key path. - The OpenAI/Qwen tail is wired into all eval surfaces:
/api/evaluate,/api/deep,/api/mode/:slug, and the/api/auto-pipelineSSE — consulted after the existing Anthropic (inline) + Gemini (subprocess) branches so the auto preference is preserved, with the same bundled-context inlining Anthropic uses. env-config.mjs:QWEN_API_KEY(secret) +QWEN_MODEL(not secret) added toKNOWN_KEYS/KEY_GROUPS.core;LLM_PROVIDERSandproviderOrder()extended;OPENAI_API_KEYis now a first-class headless provider key (was stored-only).#/configAPI-keys tab:LLM_PROVIDERselect gainsopenai/qwen; newQWEN_API_KEY+QWEN_MODELfields (curatedqwen-max/qwen-plus/qwen-turbo/qwen2.5-*list); a new top-of-tab note explains the CLI-agnostic parent vs the headless web-ui eval and the OR order. Updated OpenAI/provider hint copy. New i18n keys (config.providerModelNote,config.qwen*) + 3 updated hints, across all 8 locales.
🧪 Tests
test: tests/openai.test.mjs(new, 9 cases, CI-isolated): OpenAI/Qwen success + block-array content, Bearer auth, default +QWEN_BASE_URL-overridden endpoints, 4xx/5xx/malformed,max_tokensclamp, timeout,effectiveEnvkey detection, no-key-leak canary.tests/provider-selector.test.mjsupdated for the v1.55.0providerOrder/LLM_PROVIDERS/SECRET surface + the OpenAI/Qwen tail wiring. 748 → 757.