
























@@ -11,7 +11,6 @@ import {
1111} from "./chat-model.test-helpers.ts";
12121313type ChatModelStateInput = Parameters<typeof resolveChatModelSelectState>[0];
14-type ResolvedChatModelState = ReturnType<typeof resolveChatModelSelectState>;
15141615function createChatModelState(
1716params: Partial<Omit<ChatModelStateInput, "sessionKey">> = {},
@@ -25,19 +24,6 @@ function createChatModelState(
2524};
2625}
272628-function expectOptionValues(
29-resolved: ResolvedChatModelState,
30-params: { include?: string[]; exclude?: string[] },
31-) {
32-const values = resolved.options.map((option) => option.value);
33-for (const value of params.include ?? []) {
34-expect(values).toContain(value);
35-}
36-for (const value of params.exclude ?? []) {
37-expect(values).not.toContain(value);
38-}
39-}
40-4127describe("chat-model-select-state", () => {
4228it("uses the server-qualified value when the active session provider is present", () => {
4329const state = createChatModelState({
@@ -70,7 +56,10 @@ describe("chat-model-select-state", () => {
70567157const resolved = resolveChatModelSelectState(state);
7258expect(resolved.currentOverride).toBe("openai/gpt-5-mini");
73-expectOptionValues(resolved, { include: ["openai/gpt-5-mini"], exclude: ["gpt-5-mini"] });
59+expect(resolved.options).toEqual([
60+{ value: "openai/gpt-5", label: "GPT-5" },
61+{ value: "openai/gpt-5-mini", label: "GPT-5 Mini" },
62+]);
7463});
75647665it("prefers catalog provider matches over stale session providers", () => {
@@ -95,10 +84,10 @@ describe("chat-model-select-state", () => {
95849685const resolved = resolveChatModelSelectState(state);
9786expect(resolved.currentOverride).toBe("openai/gpt-5-mini");
98-expectOptionValues(resolved, {
99-include: ["openai/gpt-5-mini"],
100-exclude: ["zai/openai/gpt-5-mini"],
101-});
87+expect(resolved.options).toEqual([
88+{ value: "openai/gpt-5-mini", label: "gpt-5-mini · openai" },
89+{ value: "openai/gpt-5", label: "gpt-5 · openai" },
90+]);
10291});
1039210493it("builds picker options without introducing a bare duplicate", () => {
@@ -112,7 +101,10 @@ describe("chat-model-select-state", () => {
112101113102const resolved = resolveChatModelSelectState(state);
114103expect(resolved.currentOverride).toBe("openai/gpt-5-mini");
115-expectOptionValues(resolved, { include: ["openai/gpt-5-mini"], exclude: ["gpt-5-mini"] });
104+expect(resolved.options).toEqual([
105+{ value: "openai/gpt-5", label: "GPT-5" },
106+{ value: "openai/gpt-5-mini", label: "GPT-5 Mini" },
107+]);
116108});
117109118110it("uses catalog names for the default label and matching picker options", () => {
@@ -134,10 +126,12 @@ describe("chat-model-select-state", () => {
134126const resolved = resolveChatModelSelectState(state);
135127expect(resolved.currentOverride).toBe("nvidia/moonshotai/kimi-k2.5");
136128expect(resolved.defaultLabel).toBe("Default (Kimi K2.5 (NVIDIA))");
137-expect(resolved.options).toContainEqual({
138-value: "nvidia/moonshotai/kimi-k2.5",
139-label: "Kimi K2.5 (NVIDIA)",
140-});
129+expect(resolved.options).toEqual([
130+{
131+value: "nvidia/moonshotai/kimi-k2.5",
132+label: "Kimi K2.5 (NVIDIA)",
133+},
134+]);
141135});
142136143137it("disambiguates duplicate friendly names in picker options and default labels", () => {
@@ -165,14 +159,16 @@ describe("chat-model-select-state", () => {
165159const resolved = resolveChatModelSelectState(state);
166160expect(resolved.currentOverride).toBe("anthropic/claude-3-7-sonnet");
167161expect(resolved.defaultLabel).toBe("Default (Claude Sonnet · openrouter)");
168-expect(resolved.options).toContainEqual({
169-value: "anthropic/claude-3-7-sonnet",
170-label: "Claude Sonnet · anthropic",
171-});
172-expect(resolved.options).toContainEqual({
173-value: "openrouter/claude-3-7-sonnet",
174-label: "Claude Sonnet · openrouter",
175-});
162+expect(resolved.options).toEqual([
163+{
164+value: "anthropic/claude-3-7-sonnet",
165+label: "Claude Sonnet · anthropic",
166+},
167+{
168+value: "openrouter/claude-3-7-sonnet",
169+label: "Claude Sonnet · openrouter",
170+},
171+]);
176172});
177173178174it("falls back to id and provider when duplicate names share the same provider", () => {
@@ -202,13 +198,15 @@ describe("chat-model-select-state", () => {
202198expect(resolved.defaultLabel).toBe(
203199"Default (Claude Sonnet · claude-3-7-sonnet-thinking · anthropic)",
204200);
205-expect(resolved.options).toContainEqual({
206-value: "anthropic/claude-3-7-sonnet",
207-label: "Claude Sonnet · claude-3-7-sonnet · anthropic",
208-});
209-expect(resolved.options).toContainEqual({
210-value: "anthropic/claude-3-7-sonnet-thinking",
211-label: "Claude Sonnet · claude-3-7-sonnet-thinking · anthropic",
212-});
201+expect(resolved.options).toEqual([
202+{
203+value: "anthropic/claude-3-7-sonnet",
204+label: "Claude Sonnet · claude-3-7-sonnet · anthropic",
205+},
206+{
207+value: "anthropic/claude-3-7-sonnet-thinking",
208+label: "Claude Sonnet · claude-3-7-sonnet-thinking · anthropic",
209+},
210+]);
213211});
214212});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。