From 93754480870321facdca73231c31311dd72bef8a Mon Sep 17 00:00:00 2001 From: hobokenchicken Date: Thu, 26 Mar 2026 17:09:27 +0000 Subject: [PATCH] fix(moonshot): resolve 401 Unauthorized errors by trimming API keys and improving request compatibility --- internal/config/config.go | 2 +- internal/providers/helpers.go | 13 ++++++++++++- internal/providers/moonshot.go | 14 +++++++++++--- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/internal/config/config.go b/internal/config/config.go index 6da7f31b..42101266 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -203,5 +203,5 @@ func (c *Config) GetAPIKey(provider string) (string, error) { if val == "" { return "", fmt.Errorf("environment variable %s not set for %s", envVar, provider) } - return val, nil + return strings.TrimSpace(val), nil } diff --git a/internal/providers/helpers.go b/internal/providers/helpers.go index 60737051..656dd24c 100644 --- a/internal/providers/helpers.go +++ b/internal/providers/helpers.go @@ -58,9 +58,20 @@ func MessagesToOpenAIJSON(messages []models.UnifiedMessage) ([]interface{}, erro } } + var finalContent interface{} + if len(parts) == 1 { + if p, ok := parts[0].(map[string]interface{}); ok && p["type"] == "text" { + finalContent = p["text"] + } else { + finalContent = parts + } + } else { + finalContent = parts + } + msg := map[string]interface{}{ "role": m.Role, - "content": parts, + "content": finalContent, } if m.ReasoningContent != nil { diff --git a/internal/providers/moonshot.go b/internal/providers/moonshot.go index 3d0f2a31..a5cbd6eb 100644 --- a/internal/providers/moonshot.go +++ b/internal/providers/moonshot.go @@ -21,7 +21,7 @@ func NewMoonshotProvider(cfg config.MoonshotConfig, apiKey string) *MoonshotProv return &MoonshotProvider{ client: resty.New(), config: cfg, - apiKey: apiKey, + apiKey: strings.TrimSpace(apiKey), } } @@ -43,11 +43,15 @@ func (p *MoonshotProvider) ChatCompletion(ctx context.Context, req *models.Unifi } } + baseURL := strings.TrimRight(p.config.BaseURL, "/") + resp, err := p.client.R(). SetContext(ctx). SetHeader("Authorization", "Bearer "+p.apiKey). + SetHeader("Content-Type", "application/json"). + SetHeader("Accept", "application/json"). SetBody(body). - Post(fmt.Sprintf("%s/chat/completions", p.config.BaseURL)) + Post(fmt.Sprintf("%s/chat/completions", baseURL)) if err != nil { return nil, fmt.Errorf("request failed: %w", err) @@ -79,12 +83,16 @@ func (p *MoonshotProvider) ChatCompletionStream(ctx context.Context, req *models } } + baseURL := strings.TrimRight(p.config.BaseURL, "/") + resp, err := p.client.R(). SetContext(ctx). SetHeader("Authorization", "Bearer "+p.apiKey). + SetHeader("Content-Type", "application/json"). + SetHeader("Accept", "text/event-stream"). SetBody(body). SetDoNotParseResponse(true). - Post(fmt.Sprintf("%s/chat/completions", p.config.BaseURL)) + Post(fmt.Sprintf("%s/chat/completions", baseURL)) if err != nil { return nil, fmt.Errorf("request failed: %w", err)