mirror of
https://github.com/sipeed/picoclaw.git
synced 2026-06-12 18:08:54 +00:00
fix(config): support legacy config without provider field
When no provider field is set but model is specified, use the user's model as ModelName for the first provider. This maintains backward compatibility with old configs that relied on implicit provider selection and ensures GetModelConfig(model) can find the model by its configured name.
This commit is contained in:
+12
-1
@@ -32,9 +32,13 @@ func ConvertProvidersToModelList(cfg *Config) []ModelConfig {
|
||||
userProvider := strings.ToLower(cfg.Agents.Defaults.Provider)
|
||||
userModel := cfg.Agents.Defaults.Model
|
||||
|
||||
var result []ModelConfig
|
||||
p := cfg.Providers
|
||||
|
||||
var result []ModelConfig
|
||||
|
||||
// Track if we've applied the legacy model name fix (only for first provider)
|
||||
legacyModelNameApplied := false
|
||||
|
||||
// Define migration rules for each provider
|
||||
migrations := []providerMigrationConfig{
|
||||
{
|
||||
@@ -322,6 +326,13 @@ func ConvertProvidersToModelList(cfg *Config) []ModelConfig {
|
||||
if slices.Contains(m.providerNames, userProvider) && userModel != "" {
|
||||
// Use the user's configured model instead of default
|
||||
mc.Model = m.protocol + "/" + userModel
|
||||
} else if userProvider == "" && userModel != "" && !legacyModelNameApplied {
|
||||
// Legacy config: no explicit provider field but model is specified
|
||||
// Use userModel as ModelName for the FIRST provider so GetModelConfig(model) can find it
|
||||
// This maintains backward compatibility with old configs that relied on implicit provider selection
|
||||
mc.ModelName = userModel
|
||||
mc.Model = m.protocol + "/" + userModel
|
||||
legacyModelNameApplied = true
|
||||
}
|
||||
|
||||
result = append(result, mc)
|
||||
|
||||
@@ -391,3 +391,101 @@ func TestConvertProvidersToModelList_ProviderNameAliases(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Test for backward compatibility: single provider without explicit provider field
|
||||
// This matches the legacy config pattern where users only set model, not provider
|
||||
|
||||
func TestConvertProvidersToModelList_NoProviderField_SingleProvider(t *testing.T) {
|
||||
// This matches the user's actual config:
|
||||
// - No provider field set
|
||||
// - model = "glm-4.7"
|
||||
// - Only zhipu has API key configured
|
||||
cfg := &Config{
|
||||
Agents: AgentsConfig{
|
||||
Defaults: AgentDefaults{
|
||||
Provider: "", // Not set
|
||||
Model: "glm-4.7",
|
||||
},
|
||||
},
|
||||
Providers: ProvidersConfig{
|
||||
Zhipu: ProviderConfig{APIKey: "test-zhipu-key"},
|
||||
},
|
||||
}
|
||||
|
||||
result := ConvertProvidersToModelList(cfg)
|
||||
|
||||
if len(result) != 1 {
|
||||
t.Fatalf("len(result) = %d, want 1", len(result))
|
||||
}
|
||||
|
||||
// ModelName should be the user's model value for backward compatibility
|
||||
if result[0].ModelName != "glm-4.7" {
|
||||
t.Errorf("ModelName = %q, want %q (user's model for backward compatibility)", result[0].ModelName, "glm-4.7")
|
||||
}
|
||||
|
||||
// Model should use the user's model with protocol prefix
|
||||
if result[0].Model != "openai/glm-4.7" {
|
||||
t.Errorf("Model = %q, want %q", result[0].Model, "openai/glm-4.7")
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertProvidersToModelList_NoProviderField_MultipleProviders(t *testing.T) {
|
||||
// When multiple providers are configured but no provider field is set,
|
||||
// the FIRST provider (in migration order) will use userModel as ModelName
|
||||
// for backward compatibility with legacy implicit provider selection
|
||||
cfg := &Config{
|
||||
Agents: AgentsConfig{
|
||||
Defaults: AgentDefaults{
|
||||
Provider: "", // Not set
|
||||
Model: "some-model",
|
||||
},
|
||||
},
|
||||
Providers: ProvidersConfig{
|
||||
OpenAI: ProviderConfig{APIKey: "openai-key"},
|
||||
Zhipu: ProviderConfig{APIKey: "zhipu-key"},
|
||||
},
|
||||
}
|
||||
|
||||
result := ConvertProvidersToModelList(cfg)
|
||||
|
||||
if len(result) != 2 {
|
||||
t.Fatalf("len(result) = %d, want 2", len(result))
|
||||
}
|
||||
|
||||
// The first provider (OpenAI in migration order) should use userModel as ModelName
|
||||
// This ensures GetModelConfig("some-model") will find it
|
||||
if result[0].ModelName != "some-model" {
|
||||
t.Errorf("First provider ModelName = %q, want %q", result[0].ModelName, "some-model")
|
||||
}
|
||||
|
||||
// Other providers should use provider name as ModelName
|
||||
if result[1].ModelName != "zhipu" {
|
||||
t.Errorf("Second provider ModelName = %q, want %q", result[1].ModelName, "zhipu")
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertProvidersToModelList_NoProviderField_NoModel(t *testing.T) {
|
||||
// Edge case: no provider, no model
|
||||
cfg := &Config{
|
||||
Agents: AgentsConfig{
|
||||
Defaults: AgentDefaults{
|
||||
Provider: "",
|
||||
Model: "",
|
||||
},
|
||||
},
|
||||
Providers: ProvidersConfig{
|
||||
Zhipu: ProviderConfig{APIKey: "zhipu-key"},
|
||||
},
|
||||
}
|
||||
|
||||
result := ConvertProvidersToModelList(cfg)
|
||||
|
||||
if len(result) != 1 {
|
||||
t.Fatalf("len(result) = %d, want 1", len(result))
|
||||
}
|
||||
|
||||
// Should use default provider name since no model is specified
|
||||
if result[0].ModelName != "zhipu" {
|
||||
t.Errorf("ModelName = %q, want %q", result[0].ModelName, "zhipu")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user