fix clawhub registry env compatibility

This commit is contained in:
lxowalle 2026-04-10 16:03:02 +08:00
parent 34eeaf5899
commit 528bb66750
2 changed files with 113 additions and 0 deletions

View file

@ -7,6 +7,7 @@ import (
"math/rand"
"os"
"path/filepath"
"strconv"
"strings"
"sync/atomic"
"time"
@ -978,6 +979,18 @@ type SkillRegistryConfig struct {
Param map[string]any `json:"-" yaml:"-" env:"-"`
}
const (
envSkillsClawHubEnabled = "PICOCLAW_SKILLS_REGISTRIES_CLAWHUB_ENABLED"
envSkillsClawHubBaseURL = "PICOCLAW_SKILLS_REGISTRIES_CLAWHUB_BASE_URL"
envSkillsClawHubAuthToken = "PICOCLAW_SKILLS_REGISTRIES_CLAWHUB_AUTH_TOKEN"
envSkillsClawHubSearchPath = "PICOCLAW_SKILLS_REGISTRIES_CLAWHUB_SEARCH_PATH"
envSkillsClawHubSkillsPath = "PICOCLAW_SKILLS_REGISTRIES_CLAWHUB_SKILLS_PATH"
envSkillsClawHubDownloadPath = "PICOCLAW_SKILLS_REGISTRIES_CLAWHUB_DOWNLOAD_PATH"
envSkillsClawHubTimeout = "PICOCLAW_SKILLS_REGISTRIES_CLAWHUB_TIMEOUT"
envSkillsClawHubMaxZipSize = "PICOCLAW_SKILLS_REGISTRIES_CLAWHUB_MAX_ZIP_SIZE"
envSkillsClawHubMaxResponseSize = "PICOCLAW_SKILLS_REGISTRIES_CLAWHUB_MAX_RESPONSE_SIZE"
)
func (c *SkillRegistryConfig) DecodeParam(target any) error {
if c == nil {
return nil
@ -1164,6 +1177,7 @@ func LoadConfig(path string) (*Config, error) {
if err = env.Parse(cfg); err != nil {
return nil, err
}
applySkillsRegistryEnvCompat(cfg)
// Expand multi-key configs into separate entries for key-level failover
cfg.ModelList = expandMultiKeyModels(cfg.ModelList)
@ -1182,6 +1196,61 @@ func LoadConfig(path string) (*Config, error) {
return cfg, nil
}
func applySkillsRegistryEnvCompat(cfg *Config) {
if cfg == nil {
return
}
registryCfg, ok := cfg.Tools.Skills.Registries.Get("clawhub")
if !ok {
registryCfg = SkillRegistryConfig{
Name: "clawhub",
Param: map[string]any{},
}
}
if registryCfg.Param == nil {
registryCfg.Param = map[string]any{}
}
if raw, ok := os.LookupEnv(envSkillsClawHubEnabled); ok {
if value, err := strconv.ParseBool(strings.TrimSpace(raw)); err == nil {
registryCfg.Enabled = value
}
}
if value, ok := os.LookupEnv(envSkillsClawHubBaseURL); ok {
registryCfg.BaseURL = value
}
if value, ok := os.LookupEnv(envSkillsClawHubAuthToken); ok {
registryCfg.AuthToken = *NewSecureString(value)
}
if value, ok := os.LookupEnv(envSkillsClawHubSearchPath); ok {
registryCfg.Param["search_path"] = value
}
if value, ok := os.LookupEnv(envSkillsClawHubSkillsPath); ok {
registryCfg.Param["skills_path"] = value
}
if value, ok := os.LookupEnv(envSkillsClawHubDownloadPath); ok {
registryCfg.Param["download_path"] = value
}
if raw, ok := os.LookupEnv(envSkillsClawHubTimeout); ok {
if value, err := strconv.Atoi(strings.TrimSpace(raw)); err == nil {
registryCfg.Param["timeout"] = value
}
}
if raw, ok := os.LookupEnv(envSkillsClawHubMaxZipSize); ok {
if value, err := strconv.Atoi(strings.TrimSpace(raw)); err == nil {
registryCfg.Param["max_zip_size"] = value
}
}
if raw, ok := os.LookupEnv(envSkillsClawHubMaxResponseSize); ok {
if value, err := strconv.Atoi(strings.TrimSpace(raw)); err == nil {
registryCfg.Param["max_response_size"] = value
}
}
cfg.Tools.Skills.Registries.Set("clawhub", registryCfg)
}
func makeBackup(path string) error {
if _, err := os.Stat(path); os.IsNotExist(err) {
return nil

View file

@ -1523,6 +1523,50 @@ func TestResolveGatewayLogLevel_UsesEnvOverrideAndNormalizesInvalid(t *testing.T
}
}
func TestLoadConfig_AppliesLegacyClawHubRegistryEnvOverrides(t *testing.T) {
dir := t.TempDir()
cfgPath := filepath.Join(dir, "config.json")
data := `{"version":2,"tools":{"skills":{"registries":{"clawhub":{"enabled":true,"base_url":"https://clawhub.ai"}}}}}`
if err := os.WriteFile(cfgPath, []byte(data), 0o600); err != nil {
t.Fatalf("setup: %v", err)
}
t.Setenv(envSkillsClawHubBaseURL, "https://clawhub.example.com")
t.Setenv(envSkillsClawHubAuthToken, "clawhub-token-from-env")
t.Setenv(envSkillsClawHubEnabled, "false")
t.Setenv(envSkillsClawHubSearchPath, "/custom/search")
t.Setenv(envSkillsClawHubDownloadPath, "/custom/download")
t.Setenv(envSkillsClawHubTimeout, "17")
cfg, err := LoadConfig(cfgPath)
if err != nil {
t.Fatalf("LoadConfig: %v", err)
}
clawhub, ok := cfg.Tools.Skills.Registries.Get("clawhub")
if !ok {
t.Fatal("clawhub registry missing")
}
if clawhub.BaseURL != "https://clawhub.example.com" {
t.Fatalf("BaseURL = %q, want %q", clawhub.BaseURL, "https://clawhub.example.com")
}
if clawhub.AuthToken.String() != "clawhub-token-from-env" {
t.Fatalf("AuthToken = %q, want %q", clawhub.AuthToken.String(), "clawhub-token-from-env")
}
if clawhub.Enabled {
t.Fatal("Enabled = true, want false")
}
if got := clawhub.Param["search_path"]; got != "/custom/search" {
t.Fatalf("search_path = %v, want %q", got, "/custom/search")
}
if got := clawhub.Param["download_path"]; got != "/custom/download" {
t.Fatalf("download_path = %v, want %q", got, "/custom/download")
}
if got := clawhub.Param["timeout"]; got != 17 {
t.Fatalf("timeout = %v, want %d", got, 17)
}
}
func TestModelConfig_ExtraBodyRoundTrip(t *testing.T) {
dir := t.TempDir()
cfgPath := filepath.Join(dir, "config.json")