mirror of
https://github.com/YspCoder/clawgo.git
synced 2026-04-15 00:27:29 +08:00
159 lines
5.1 KiB
Go
159 lines
5.1 KiB
Go
package providers
|
|
|
|
import (
|
|
"net/http"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestBuildKimiChatRequestStripsPrefixAndAppliesThinking(t *testing.T) {
|
|
base := NewHTTPProvider("kimi", "token", kimiCompatBaseURL, "kimi-k2.5", false, "oauth", 5*time.Second, nil)
|
|
body := buildKimiChatRequest(base, []Message{{Role: "user", Content: "hi"}}, nil, "kimi-k2.5(high)", nil, false)
|
|
|
|
if got := body["model"]; got != "k2.5" {
|
|
t.Fatalf("model = %#v, want k2.5", got)
|
|
}
|
|
if got := body["reasoning_effort"]; got != "high" {
|
|
t.Fatalf("reasoning_effort = %#v, want high", got)
|
|
}
|
|
}
|
|
|
|
func TestBuildKimiChatRequestDisablesThinking(t *testing.T) {
|
|
base := NewHTTPProvider("kimi", "token", kimiCompatBaseURL, "kimi-k2.5", false, "oauth", 5*time.Second, nil)
|
|
body := buildKimiChatRequest(base, []Message{{Role: "user", Content: "hi"}}, nil, "kimi-k2.5(none)", nil, false)
|
|
|
|
thinking, _ := body["thinking"].(map[string]interface{})
|
|
if got := thinking["type"]; got != "disabled" {
|
|
t.Fatalf("thinking.type = %#v, want disabled", got)
|
|
}
|
|
}
|
|
|
|
func TestNormalizeKimiToolMessagesBackfillsToolCallID(t *testing.T) {
|
|
body := map[string]interface{}{
|
|
"messages": []map[string]interface{}{
|
|
{
|
|
"role": "assistant",
|
|
"tool_calls": []map[string]interface{}{
|
|
{"id": "call_1"},
|
|
},
|
|
"content": "thinking content",
|
|
},
|
|
{
|
|
"role": "tool",
|
|
"content": "tool result",
|
|
},
|
|
},
|
|
}
|
|
|
|
normalizeKimiToolMessages(body)
|
|
|
|
msgs := body["messages"].([]map[string]interface{})
|
|
if got := msgs[1]["tool_call_id"]; got != "call_1" {
|
|
t.Fatalf("tool_call_id = %#v, want call_1", got)
|
|
}
|
|
if got := msgs[0]["reasoning_content"]; got != "thinking content" {
|
|
t.Fatalf("reasoning_content = %#v, want fallback content", got)
|
|
}
|
|
}
|
|
|
|
func TestNormalizeKimiToolMessagesPromotesCallID(t *testing.T) {
|
|
body := map[string]interface{}{
|
|
"messages": []map[string]interface{}{
|
|
{
|
|
"role": "tool",
|
|
"call_id": "call_2",
|
|
},
|
|
},
|
|
}
|
|
|
|
normalizeKimiToolMessages(body)
|
|
|
|
msgs := body["messages"].([]map[string]interface{})
|
|
if got := msgs[0]["tool_call_id"]; got != "call_2" {
|
|
t.Fatalf("tool_call_id = %#v, want call_2", got)
|
|
}
|
|
}
|
|
|
|
func TestApplyAttemptProviderHeadersKimiUsesResolvedDeviceFields(t *testing.T) {
|
|
req, err := http.NewRequest(http.MethodPost, kimiCompatBaseURL+"/chat/completions", nil)
|
|
if err != nil {
|
|
t.Fatalf("new request: %v", err)
|
|
}
|
|
provider := &HTTPProvider{
|
|
oauth: &oauthManager{cfg: oauthConfig{Provider: defaultKimiOAuthProvider}},
|
|
}
|
|
attempt := authAttempt{
|
|
kind: "oauth",
|
|
token: "kimi-token",
|
|
session: &oauthSession{
|
|
DeviceID: "device-123",
|
|
},
|
|
}
|
|
|
|
applyAttemptProviderHeaders(req, attempt, provider, true)
|
|
|
|
if got := req.Header.Get("X-Msh-Device-Id"); got != "device-123" {
|
|
t.Fatalf("X-Msh-Device-Id = %q, want device-123", got)
|
|
}
|
|
if got := req.Header.Get("X-Msh-Device-Model"); got != kimiDeviceModel() {
|
|
t.Fatalf("X-Msh-Device-Model = %q, want %q", got, kimiDeviceModel())
|
|
}
|
|
if got := req.Header.Get("X-Msh-Device-Name"); got == "" {
|
|
t.Fatal("expected X-Msh-Device-Name to be set")
|
|
}
|
|
}
|
|
|
|
func TestKimiHookUsesSessionResourceURL(t *testing.T) {
|
|
hooks := kimiProviderHooks{}
|
|
base := NewHTTPProvider("kimi", "token", kimiCompatBaseURL, "kimi-k2.5", false, "oauth", 5*time.Second, nil)
|
|
got := hooks.endpoint(base, authAttempt{
|
|
kind: "oauth",
|
|
session: &oauthSession{
|
|
ResourceURL: "https://api.kimi.com/coding/v1",
|
|
},
|
|
}, "/chat/completions")
|
|
if got != "https://api.kimi.com/coding/v1/chat/completions" {
|
|
t.Fatalf("endpoint = %q", got)
|
|
}
|
|
}
|
|
|
|
func TestNormalizeKimiResourceURL(t *testing.T) {
|
|
tests := []struct {
|
|
in string
|
|
want string
|
|
}{
|
|
{in: "https://api.kimi.com/coding", want: "https://api.kimi.com/coding/v1"},
|
|
{in: "api.kimi.com/coding", want: "https://api.kimi.com/coding/v1"},
|
|
{in: "https://api.kimi.com/coding/v1", want: "https://api.kimi.com/coding/v1"},
|
|
}
|
|
for _, tt := range tests {
|
|
if got := normalizeKimiResourceURL(tt.in); got != tt.want {
|
|
t.Fatalf("normalizeKimiResourceURL(%q) = %q, want %q", tt.in, got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestKimiProviderCountTokens(t *testing.T) {
|
|
provider := NewKimiProvider("kimi", "token", kimiCompatBaseURL, "kimi-k2.5", false, "api_key", 5*time.Second, nil)
|
|
usage, err := provider.CountTokens(t.Context(), []Message{{Role: "user", Content: "hello kimi"}}, nil, "kimi-k2.5", nil)
|
|
if err != nil {
|
|
t.Fatalf("CountTokens error: %v", err)
|
|
}
|
|
if usage == nil || usage.PromptTokens <= 0 || usage.TotalTokens != usage.PromptTokens {
|
|
t.Fatalf("usage = %#v, want positive prompt-only count", usage)
|
|
}
|
|
}
|
|
|
|
func TestBuildKimiChatRequestSupportsNumericAutoAndDisable(t *testing.T) {
|
|
base := NewHTTPProvider("kimi", "token", kimiCompatBaseURL, "kimi-k2.5", false, "oauth", 5*time.Second, nil)
|
|
autoBody := buildKimiChatRequest(base, []Message{{Role: "user", Content: "hi"}}, nil, "kimi-k2.5(-1)", nil, false)
|
|
if got := autoBody["reasoning_effort"]; got != "auto" {
|
|
t.Fatalf("reasoning_effort = %#v, want auto", got)
|
|
}
|
|
disableBody := buildKimiChatRequest(base, []Message{{Role: "user", Content: "hi"}}, nil, "kimi-k2.5(0)", nil, false)
|
|
thinking, _ := disableBody["thinking"].(map[string]interface{})
|
|
if got := thinking["type"]; got != "disabled" {
|
|
t.Fatalf("thinking.type = %#v, want disabled", got)
|
|
}
|
|
}
|