mirror of
https://github.com/sipeed/picoclaw.git
synced 2026-06-12 18:08:54 +00:00
refactor: parse Kimi API hostname once in constructor instead of per-call
Avoid re-parsing apiBase URL on every Chat() invocation by computing isKimiAPI once in NewProvider(). Also document why the KimiCLI/0.77 User-Agent string is required. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -33,6 +33,7 @@ type Provider struct {
|
||||
apiBase string
|
||||
maxTokensField string // Field name for max tokens (e.g., "max_completion_tokens" for o1/glm models)
|
||||
httpClient *http.Client
|
||||
isKimiAPI bool // true when apiBase points to api.kimi.com
|
||||
}
|
||||
|
||||
type Option func(*Provider)
|
||||
@@ -69,10 +70,17 @@ func NewProvider(apiKey, apiBase, proxy string, opts ...Option) *Provider {
|
||||
}
|
||||
}
|
||||
|
||||
trimmedBase := strings.TrimRight(apiBase, "/")
|
||||
var isKimi bool
|
||||
if parsed, err := url.Parse(trimmedBase); err == nil {
|
||||
isKimi = parsed.Hostname() == "api.kimi.com"
|
||||
}
|
||||
|
||||
p := &Provider{
|
||||
apiKey: apiKey,
|
||||
apiBase: strings.TrimRight(apiBase, "/"),
|
||||
apiBase: trimmedBase,
|
||||
httpClient: client,
|
||||
isKimiAPI: isKimi,
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
@@ -176,8 +184,10 @@ func (p *Provider) Chat(
|
||||
if p.apiKey != "" {
|
||||
req.Header.Set("Authorization", "Bearer "+p.apiKey)
|
||||
}
|
||||
// Kimi Code API requires a coding agent User-Agent
|
||||
if parsedURL, parseErr := url.Parse(p.apiBase); parseErr == nil && parsedURL.Hostname() == "api.kimi.com" {
|
||||
// Kimi Code API rejects requests without a recognized coding-agent
|
||||
// User-Agent. "KimiCLI/0.77" is the minimum version string accepted
|
||||
// by the api.kimi.com/coding/v1 endpoint (per Kimi's API docs).
|
||||
if p.isKimiAPI {
|
||||
req.Header.Set("User-Agent", "KimiCLI/0.77")
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user