fix: improve migration logic and reduce code duplication

- Preserve user's configured model during config migration (issue #5)
- Simplify ExtractProtocol using strings.Cut
- Extract NormalizeToolCall to shared utility, removing ~70 lines of duplicate code
- Clean up unused fields in providerMigrationConfig struct

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
yinwm
2026-02-19 09:22:39 +08:00
parent 09a0d19119
commit ec86b21d3f
6 changed files with 600 additions and 285 deletions
+4 -6
View File
@@ -45,13 +45,11 @@ func createCodexAuthProvider() (LLMProvider, error) {
// - "gpt-4o" -> ("openai", "gpt-4o") // default protocol
func ExtractProtocol(model string) (protocol, modelID string) {
model = strings.TrimSpace(model)
for i := 0; i < len(model); i++ {
if model[i] == '/' {
return model[:i], model[i+1:]
}
protocol, modelID, found := strings.Cut(model, "/")
if !found {
return "openai", model
}
// No prefix found, default to openai
return "openai", model
return protocol, modelID
}
// CreateProviderFromConfig creates a provider based on the ModelConfig.
+54
View File
@@ -0,0 +1,54 @@
// PicoClaw - Ultra-lightweight personal AI agent
// License: MIT
//
// Copyright (c) 2026 PicoClaw contributors
package providers
import "encoding/json"
// NormalizeToolCall normalizes a ToolCall to ensure all fields are properly populated.
// It handles cases where Name/Arguments might be in different locations (top-level vs Function)
// and ensures both are populated consistently.
func NormalizeToolCall(tc ToolCall) ToolCall {
normalized := tc
// Ensure Name is populated from Function if not set
if normalized.Name == "" && normalized.Function != nil {
normalized.Name = normalized.Function.Name
}
// Ensure Arguments is not nil
if normalized.Arguments == nil {
normalized.Arguments = map[string]interface{}{}
}
// Parse Arguments from Function.Arguments if not already set
if len(normalized.Arguments) == 0 && normalized.Function != nil && normalized.Function.Arguments != "" {
var parsed map[string]interface{}
if err := json.Unmarshal([]byte(normalized.Function.Arguments), &parsed); err == nil && parsed != nil {
normalized.Arguments = parsed
}
}
// Ensure Function is populated with consistent values
argsJSON, _ := json.Marshal(normalized.Arguments)
if normalized.Function == nil {
normalized.Function = &FunctionCall{
Name: normalized.Name,
Arguments: string(argsJSON),
}
} else {
if normalized.Function.Name == "" {
normalized.Function.Name = normalized.Name
}
if normalized.Name == "" {
normalized.Name = normalized.Function.Name
}
if normalized.Function.Arguments == "" {
normalized.Function.Arguments = string(argsJSON)
}
}
return normalized
}