Files
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

120 lines
4.2 KiB
Go

package runtimeprep
import (
"strings"
"testing"
)
func TestCodexConfigWithModelPlanEndpointRewritesProvider(t *testing.T) {
t.Parallel()
endpoint := &ModelEndpointConfig{
PlanID: "mp-1",
PlanName: "Volc Coding Plan",
Protocol: "openai",
BaseURL: "https://relay.example/v1",
APIKey: "sk-secret",
WireAPI: "responses",
Model: "seed-code",
}
content := "model = \"gpt-5\"\nmodel_provider = \"openai\"\n\n[tutti]\nconversationDetailMode = \"standard\"\n"
next, changed := codexConfigWithModelPlanEndpoint(content, endpoint)
if !changed {
t.Fatalf("codexConfigWithModelPlanEndpoint() changed = false")
}
if !strings.Contains(next, "model_provider = \"tutti-model-plan\"") {
t.Fatalf("model_provider not pinned:\n%s", next)
}
if strings.Contains(next, "model_provider = \"openai\"") {
t.Fatalf("stale model_provider remains:\n%s", next)
}
if !strings.Contains(next, "model = \"seed-code\"") || strings.Contains(next, "model = \"gpt-5\"") {
t.Fatalf("model not replaced:\n%s", next)
}
if !strings.Contains(next, "[model_providers.tutti-model-plan]") {
t.Fatalf("provider table missing:\n%s", next)
}
if !strings.Contains(next, "env_key = \"TUTTI_MODEL_PLAN_API_KEY\"") {
t.Fatalf("env_key missing:\n%s", next)
}
if !strings.Contains(next, "wire_api = \"responses\"") {
t.Fatalf("responses wire_api missing:\n%s", next)
}
if strings.Contains(next, "sk-secret") {
t.Fatalf("credential leaked into config:\n%s", next)
}
// Anthropic-protocol plans must not rewrite Codex config.
if _, changed := codexConfigWithModelPlanEndpoint(content, &ModelEndpointConfig{Protocol: "anthropic", BaseURL: "https://x", APIKey: "k"}); changed {
t.Fatalf("anthropic endpoint should not change codex config")
}
}
func TestCodexConfigWithModelPlanEndpointPreservesWebSearch(t *testing.T) {
t.Parallel()
content := "web_search = \"live\"\n"
next, changed := codexConfigWithModelPlanEndpoint(content, &ModelEndpointConfig{
Protocol: "openai",
BaseURL: "https://relay.example/v1",
APIKey: "sk-secret",
Model: "seed-code",
})
if !changed {
t.Fatalf("codexConfigWithModelPlanEndpoint() changed = false")
}
if !strings.Contains(next, "web_search = \"live\"") {
t.Fatalf("web_search should be preserved:\n%s", next)
}
}
func TestModelEndpointClaudeEnvSelectsAuthShape(t *testing.T) {
t.Parallel()
relay := modelEndpointClaudeEnv(&ModelEndpointConfig{
Protocol: "anthropic",
BaseURL: "https://relay.example/api/anthropic",
APIKey: "sk-relay",
})
joined := strings.Join(relay, "\n")
if !strings.Contains(joined, "ANTHROPIC_BASE_URL=https://relay.example/api/anthropic") {
t.Fatalf("relay env = %v", relay)
}
if !strings.Contains(joined, "ANTHROPIC_AUTH_TOKEN=sk-relay") || !strings.HasSuffix(joined, "ANTHROPIC_API_KEY=") {
t.Fatalf("relay should use bearer auth token: %v", relay)
}
official := modelEndpointClaudeEnv(&ModelEndpointConfig{
Protocol: "anthropic",
BaseURL: "https://api.anthropic.com/v1",
APIKey: "sk-ant",
})
joined = strings.Join(official, "\n")
if !strings.Contains(joined, "ANTHROPIC_API_KEY=sk-ant") || !strings.HasSuffix(joined, "ANTHROPIC_AUTH_TOKEN=") {
t.Fatalf("official endpoint should use api key: %v", official)
}
if !strings.Contains(joined, "ANTHROPIC_BASE_URL=https://api.anthropic.com") {
t.Fatalf("official base url should drop /v1 suffix: %v", official)
}
kimiCoding := modelEndpointClaudeEnv(&ModelEndpointConfig{
Protocol: "anthropic",
BaseURL: "https://api.kimi.com/coding/",
APIKey: "sk-kimi",
})
joined = strings.Join(kimiCoding, "\n")
if !strings.Contains(joined, "ANTHROPIC_API_KEY=sk-kimi") || !strings.HasSuffix(joined, "ANTHROPIC_AUTH_TOKEN=") {
t.Fatalf("Kimi Coding should use api key auth: %v", kimiCoding)
}
if !strings.Contains(joined, "ANTHROPIC_BASE_URL=https://api.kimi.com/coding/") {
t.Fatalf("Kimi Coding base url should be preserved: %v", kimiCoding)
}
if env := modelEndpointClaudeEnv(&ModelEndpointConfig{Protocol: "openai", BaseURL: "https://x", APIKey: "k"}); env != nil {
t.Fatalf("openai endpoint should not produce claude env: %v", env)
}
if env := modelEndpointClaudeEnv(nil); env != nil {
t.Fatalf("nil endpoint should not produce claude env: %v", env)
}
}