feat(config): named LLM provider list via env vars, runtime selection

- Config.llm_profiles: LLM_PROVIDERS declares names, each group defined by
  LLM_<NAME>_BASE_URL/_API_KEY/_MODEL (required) and optional _TIMEOUT_SECONDS/
  _MAX_RETRIES/_TEMPERATURE/_EXTRA_BODY; JSON-dict form of LLM_PROVIDERS also
  supported. LLM_PROVIDER selects the active group at runtime; empty/fake =
  offline scripted model
- removed fixed openai/kimi groups (AGENT_LLM_PROVIDER, KIMI_LLM_*)
- validate(): incomplete groups and unknown LLM_PROVIDER fail fast with
  the configured-name list
- OpenAILLMService: http client trust_env from LLM_HTTP_TRUST_ENV (default
  False - local gateways must bypass the Windows system proxy)
- build_llm_service(provider): explicit name or LLM_PROVIDER default
- .env/.env.example: deepseek + kimi groups side by side, switch by
  LLM_PROVIDER=kimi (thinking off via EXTRA_BODY reasoning_effort=none)
- eval probe scripts updated to the new config interface

Verified: 172 unit tests; live calls succeed on both providers
(deepseek 28s, kimi 6.6s, both emitting valid <state> prefixes)
This commit is contained in:
Eric Wang
2026-10-22 13:59:18 +08:00
parent e72d9c9bc0
commit e5d2a78886
6 changed files with 184 additions and 43 deletions
+1 -1
View File
@@ -26,7 +26,7 @@ def parsed_time(value):
async def main(output):
llm = build_llm_service('openai')
llm = build_llm_service()
cases = []
for delay in (75,135):
cases.append(dict(name=f'anchored_cross_midnight_delay_{delay}',now=ORIGIN+timedelta(minutes=delay),