Isolate providers per client: add provider targets and a Codex-side form

This commit is contained in:
kate522 committed 2026-10-18 19:22:38 +08:00
1 parent adc8234cc9
commit d759fe5e5d
13 files changed
+595 -309

No files matched your search

+74 -15
View File
@@ -58,7 +58,7 @@ func TestStoreRoundTrip(t *testing.T) {
t.Fatalf("default language = %q", store.Config().Language)
}
p, err := store.AddProvider("DeepSeek", "deepseek", "https://api.deepseek.com/v1", "sk-test",
Models{Default: "deepseek-chat", Sonnet: "deepseek-chat", Haiku: "deepseek-chat", Opus: "deepseek-chat"})
Models{Default: "deepseek-chat", Sonnet: "deepseek-chat", Haiku: "deepseek-chat", Opus: "deepseek-chat"}, TargetClaude)
if err != nil {
t.Fatalf("AddProvider: %v", err)
}
@@ -90,7 +90,7 @@ func TestAddProviderValidation(t *testing.T) {
{"p", "https://x.com/v1", ""},
}
for _, tc := range cases {
if _, err := store.AddProvider(tc.name, "", tc.baseURL, tc.apiKey, Models{}); err == nil {
if _, err := store.AddProvider(tc.name, "", tc.baseURL, tc.apiKey, Models{}, TargetClaude); err == nil {
t.Errorf("AddProvider(%q, %q, %q) succeeded, want error", tc.name, tc.baseURL, tc.apiKey)
}
}
@@ -99,8 +99,8 @@ func TestAddProviderValidation(t *testing.T) {
func TestUpdateProviderKeepsKeyWhenEmpty(t *testing.T) {
t.Setenv("CROSSRELAY_HOME", t.TempDir())
store, _ := Load()
p, _ := store.AddProvider("p", "", "https://x.com/v1", "sk-secret", Models{Default: "m1"})
updated, err := store.UpdateProvider(p.ID, "p2", "", "https://x.com/v1/", "", Models{Default: "m2"})
p, _ := store.AddProvider("p", "", "https://x.com/v1", "sk-secret", Models{Default: "m1"}, TargetClaude)
updated, err := store.UpdateProvider(p.ID, "p2", "", "https://x.com/v1/", "", Models{Default: "m2"}, TargetClaude)
if err != nil {
t.Fatalf("UpdateProvider: %v", err)
}
@@ -118,7 +118,7 @@ func TestUpdateProviderKeepsKeyWhenEmpty(t *testing.T) {
func TestDeleteProviderClearsActive(t *testing.T) {
t.Setenv("CROSSRELAY_HOME", t.TempDir())
store, _ := Load()
p, _ := store.AddProvider("p", "", "https://x.com/v1", "sk", Models{})
p, _ := store.AddProvider("p", "", "https://x.com/v1", "sk", Models{}, TargetClaude)
store.ActivateClaude(p.ID)
if err := store.DeleteProvider(p.ID); err != nil {
t.Fatalf("DeleteProvider: %v", err)
@@ -135,7 +135,7 @@ func TestActivateCodexRoundTrip(t *testing.T) {
t.Fatalf("Load: %v", err)
}
p, err := store.AddProvider("DeepSeek", "deepseek", "https://api.deepseek.com/v1", "sk-test",
Models{Default: "deepseek-chat"})
Models{Default: "deepseek-chat"}, TargetCodex)
if err != nil {
t.Fatalf("AddProvider: %v", err)
}
@@ -178,28 +178,87 @@ func TestUpdateProviderKeepsEnabledFlags(t *testing.T) {
if err != nil {
t.Fatalf("Load: %v", err)
}
p, err := store.AddProvider("DeepSeek", "deepseek", "https://api.deepseek.com/v1", "sk-test",
Models{Default: "deepseek-chat"})
claude, err := store.AddProvider("DeepSeek", "deepseek", "https://api.deepseek.com/v1", "sk-test",
Models{Default: "deepseek-chat"}, TargetClaude)
if err != nil {
t.Fatalf("AddProvider: %v", err)
}
if _, err := store.ActivateClaude(p.ID); err != nil {
codex, err := store.AddProvider("Kimi", "moonshot", "https://api.moonshot.cn/v1", "sk-kimi",
Models{Default: "kimi-k2-0905-preview"}, TargetCodex)
if err != nil {
t.Fatalf("AddProvider: %v", err)
}
if _, err := store.ActivateClaude(claude.ID); err != nil {
t.Fatalf("ActivateClaude: %v", err)
}
if _, err := store.ActivateCodex(p.ID); err != nil {
if _, err := store.ActivateCodex(codex.ID); err != nil {
t.Fatalf("ActivateCodex: %v", err)
}
updated, err := store.UpdateProvider(p.ID, "DeepSeek 2", "deepseek", "https://api.deepseek.com/v1", "",
Models{Default: "deepseek-reasoner"})
updated, err := store.UpdateProvider(claude.ID, "DeepSeek 2", "deepseek", "https://api.deepseek.com/v1", "",
Models{Default: "deepseek-reasoner"}, "")
if err != nil {
t.Fatalf("UpdateProvider: %v", err)
}
if !updated.EnabledForClaude || !updated.EnabledForCodex {
t.Errorf("enabled flags lost: claude=%v codex=%v", updated.EnabledForClaude, updated.EnabledForCodex)
if !updated.EnabledForClaude {
t.Error("enabled_for_claude lost across update")
}
if updated.EnabledForCodex {
t.Error("a Claude provider must not carry the Codex flag")
}
if updated.Target != TargetClaude {
t.Errorf("target = %q after an update without target, want claude", updated.Target)
}
if updated.APIKey != "sk-test" {
t.Errorf("api key = %q, want the stored key kept", updated.APIKey)
}
updatedCodex, err := store.UpdateProvider(codex.ID, "Kimi 2", "moonshot", "https://api.moonshot.cn/v1", "",
Models{Default: "kimi-k2-0905-preview"}, "")
if err != nil {
t.Fatalf("UpdateProvider codex: %v", err)
}
if !updatedCodex.EnabledForCodex || updatedCodex.Target != TargetCodex {
t.Errorf("codex provider after update = %+v", updatedCodex)
}
}
func TestProviderTargetDefaultsAndValidation(t *testing.T) {
t.Setenv("CROSSRELAY_HOME", t.TempDir())
store, err := Load()
if err != nil {
t.Fatalf("Load: %v", err)
}
p, err := store.AddProvider("p", "", "https://x.com/v1", "sk", Models{}, "")
if err != nil {
t.Fatalf("AddProvider: %v", err)
}
if p.Target != TargetClaude {
t.Errorf("default target = %q, want claude", p.Target)
}
if _, err := store.AddProvider("p", "", "https://x.com/v1", "sk", Models{}, "bogus"); err == nil {
t.Error("AddProvider accepted an unknown target")
}
}
func TestActivateRejectsWrongTarget(t *testing.T) {
t.Setenv("CROSSRELAY_HOME", t.TempDir())
store, err := Load()
if err != nil {
t.Fatalf("Load: %v", err)
}
claude, _ := store.AddProvider("c", "", "https://x.com/v1", "sk", Models{}, TargetClaude)
codex, _ := store.AddProvider("x", "", "https://x.com/v1", "sk", Models{}, TargetCodex)
if _, err := store.ActivateClaude(codex.ID); err == nil {
t.Error("ActivateClaude accepted a Codex provider")
}
if _, err := store.ActivateCodex(claude.ID); err == nil {
t.Error("ActivateCodex accepted a Claude provider")
}
if _, err := store.ActivateClaude(claude.ID); err != nil {
t.Errorf("ActivateClaude on a Claude provider: %v", err)
}
if _, err := store.ActivateCodex(codex.ID); err != nil {
t.Errorf("ActivateCodex on a Codex provider: %v", err)
}
}
func TestDeleteProviderClearsCodexActive(t *testing.T) {
@@ -209,7 +268,7 @@ func TestDeleteProviderClearsCodexActive(t *testing.T) {
t.Fatalf("Load: %v", err)
}
p, err := store.AddProvider("DeepSeek", "deepseek", "https://api.deepseek.com/v1", "sk-test",
Models{Default: "deepseek-chat"})
Models{Default: "deepseek-chat"}, TargetCodex)
if err != nil {
t.Fatalf("AddProvider: %v", err)
}