llm: 统一源接入层修复(对照 llmsproxy)

- provider: 新增 OpenAI-compatible 响应/流兜底解析,Lua adapter 异常时也能解析
  choices/message/tool_calls/usage(含 function.arguments 缺失、对象/字符串参数)
- 过滤无效 LLM 源(<nil>/空/缺 http(s) scheme),main 与 ReloadFromConfig 均跳过,
  避免 mocktest 等坏源污染 fallback 与 healthcheck
- adapter(openai/deepseek/groq/mistral/github/kimicode): 修 tool_calls 对
  nil function 的崩溃,兼容扁平/嵌套结构;openai 流透传 reasoning/tool_calls
- config: ToConfig 探活端点过滤无效 base_url,修复 supervisor 误报 LLM unreachable
This commit is contained in:
root
2026-08-09 20:39:54 +08:00
parent a62f5ba0fa
commit 171e6f233b
10 changed files with 472 additions and 85 deletions

View File

@ -695,6 +695,14 @@ func (r *ConfigRegistry) GetBool(key string, defaultVal bool) bool {
return b
}
func validLLMEndpoint(s string) bool {
s = strings.TrimSpace(s)
if s == "" || strings.EqualFold(s, "<nil>") || strings.EqualFold(s, "nil") || strings.EqualFold(s, "null") {
return false
}
return strings.HasPrefix(s, "http://") || strings.HasPrefix(s, "https://")
}
// ToConfig 从 config 表重建 *types.Config
func (r *ConfigRegistry) ToConfig() *types.Config {
cfg := &types.Config{}
@ -817,10 +825,12 @@ func (r *ConfigRegistry) ToConfig() *types.Config {
} else {
seen := make(map[string]bool)
for _, src := range cfg.LLM.Sources {
if src.BaseURL != "" && !seen[src.BaseURL] {
seen[src.BaseURL] = true
cfg.Defaults.LLMEndpoints = append(cfg.Defaults.LLMEndpoints, src.BaseURL)
baseURL := strings.TrimSpace(src.BaseURL)
if !validLLMEndpoint(baseURL) || seen[baseURL] {
continue
}
seen[baseURL] = true
cfg.Defaults.LLMEndpoints = append(cfg.Defaults.LLMEndpoints, baseURL)
}
}