Files
clawgo/pkg/api/server_config_helpers.go
2026-03-15 13:41:19 +08:00

115 lines
3.4 KiB
Go

package api
import (
"sort"
"strings"
)
func mergeJSONMap(base, override map[string]interface{}) map[string]interface{} {
if base == nil {
base = map[string]interface{}{}
}
for k, v := range override {
if bv, ok := base[k]; ok {
bm, ok1 := bv.(map[string]interface{})
om, ok2 := v.(map[string]interface{})
if ok1 && ok2 {
base[k] = mergeJSONMap(bm, om)
continue
}
}
base[k] = v
}
return base
}
func getPathValue(m map[string]interface{}, path string) interface{} {
if m == nil || strings.TrimSpace(path) == "" {
return nil
}
parts := strings.Split(path, ".")
var cur interface{} = m
for _, p := range parts {
node, ok := cur.(map[string]interface{})
if !ok {
return nil
}
cur = node[p]
}
return cur
}
func collectRiskyConfigPaths(oldMap, newMap map[string]interface{}) []string {
paths := []string{
"channels.telegram.token",
"channels.telegram.allow_from",
"channels.telegram.allow_chats",
"models.providers.openai.api_base",
"models.providers.openai.api_key",
"runtime.providers.openai.api_base",
"runtime.providers.openai.api_key",
"gateway.token",
"gateway.port",
}
seen := map[string]bool{}
for _, path := range paths {
seen[path] = true
}
for _, name := range collectProviderNames(oldMap, newMap) {
for _, field := range []string{"api_base", "api_key"} {
path := "models.providers." + name + "." + field
if !seen[path] {
paths = append(paths, path)
seen[path] = true
}
normalizedPath := "runtime.providers." + name + "." + field
if !seen[normalizedPath] {
paths = append(paths, normalizedPath)
seen[normalizedPath] = true
}
}
}
return paths
}
func collectProviderNames(maps ...map[string]interface{}) []string {
seen := map[string]bool{}
names := make([]string, 0)
for _, root := range maps {
models, _ := root["models"].(map[string]interface{})
providers, _ := models["providers"].(map[string]interface{})
for name := range providers {
if strings.TrimSpace(name) == "" || seen[name] {
continue
}
seen[name] = true
names = append(names, name)
}
runtimeMap, _ := root["runtime"].(map[string]interface{})
runtimeProviders, _ := runtimeMap["providers"].(map[string]interface{})
for name := range runtimeProviders {
if strings.TrimSpace(name) == "" || seen[name] {
continue
}
seen[name] = true
names = append(names, name)
}
}
sort.Strings(names)
return names
}
func hotReloadFieldInfo() []map[string]interface{} {
return []map[string]interface{}{
{"path": "logging.*", "name": "Logging", "description": "Log level, persistence, and related settings"},
{"path": "sentinel.*", "name": "Sentinel", "description": "Health checks and auto-heal behavior"},
{"path": "agents.*", "name": "Agent", "description": "Models, policies, and default behavior"},
{"path": "models.providers.*", "name": "Providers", "description": "LLM provider registry and auth settings"},
{"path": "tools.*", "name": "Tools", "description": "Tool toggles and runtime options"},
{"path": "channels.*", "name": "Channels", "description": "Telegram and other channel settings"},
{"path": "cron.*", "name": "Cron", "description": "Global cron runtime settings"},
{"path": "agents.defaults.heartbeat.*", "name": "Heartbeat", "description": "Heartbeat interval and prompt template"},
{"path": "gateway.*", "name": "Gateway", "description": "Mostly hot-reloadable; host/port may require restart"},
}
}