916 lines · 29.6 KB · TypeScript
RawDownload
import {  ANTIGRAVITY_DEFAULT_MODEL,  ProviderDriverKind,  ProviderInstanceId,  type ServerProvider,} from "@t3tools/contracts";import { DEFAULT_UNIFIED_SETTINGS, type UnifiedSettings } from "@t3tools/contracts/settings";import { describe, expect, it } from "vite-plus/test";import { createModelSelection } from "@t3tools/shared/model";import { deriveEffectiveComposerModelState } from "./composerDraftStore";import { getComposerProviderState } from "./components/chat/composerProviderState";import { deriveProviderInstanceEntries, NO_PROVIDER_MODEL_SELECTION } from "./providerInstances";import {  getCustomModelOptionsByInstance,  getAppModelOptionsForInstance,  resolveAppModelSelectionForInstance,  resolveAppModelSelectionState,  resolvePlanAgentHealPatch,  withoutPlanAgentSelection,} from "./modelSelection"; function provider(input: {  provider?: ProviderDriverKind;  instanceId: string;  models?: ReadonlyArray<string>;}): ServerProvider {  const driver =    input.provider ??    (input.instanceId.startsWith("claude_")      ? ProviderDriverKind.make("claudeAgent")      : ProviderDriverKind.make("codex"));  return {    instanceId: ProviderInstanceId.make(input.instanceId),    driver,    enabled: true,    installed: true,    version: null,    status: "ready",    auth: { status: "authenticated" },    checkedAt: "2026-01-01T00:00:00.000Z",    models: (input.models ?? []).map((slug) => ({      slug,      name: slug,      isCustom: false,      capabilities: {},    })),    slashCommands: [],    skills: [],  };} function settingsWithProviderInstances(): UnifiedSettings {  return {    ...DEFAULT_UNIFIED_SETTINGS,    providerInstances: {      [ProviderInstanceId.make("claudeAgent")]: {        driver: ProviderDriverKind.make("claudeAgent"),        config: { customModels: [] },      },      [ProviderInstanceId.make("claude_openrouter")]: {        driver: ProviderDriverKind.make("claudeAgent"),        config: { customModels: ["openai/gpt-5.5"] },      },    },  };} describe("instance-scoped model selection", () => {  it("preserves server-provided legacy model metadata", () => {    const baseProvider = provider({      instanceId: "claudeAgent",      models: ["claude-opus-4-8"],    });    const providers = [      {        ...baseProvider,        models: [{ ...baseProvider.models[0]!, isLegacy: true }],      },    ];    const stock = deriveProviderInstanceEntries(providers)[0]!;     expect(getAppModelOptionsForInstance(settingsWithProviderInstances(), stock)[0]?.isLegacy).toBe(      true,    );  });   it("keeps custom models on the provider instance that declared them", () => {    const providers = [      provider({        instanceId: "claudeAgent",        models: ["claude-sonnet-4-6"],      }),      provider({        instanceId: "claude_openrouter",        models: ["claude-sonnet-4-6"],      }),    ];    const entries = deriveProviderInstanceEntries(providers);    const stock = entries.find((entry) => entry.instanceId === "claudeAgent")!;    const openrouter = entries.find((entry) => entry.instanceId === "claude_openrouter")!;     expect(      getAppModelOptionsForInstance(settingsWithProviderInstances(), stock).map(        (option) => option.slug,      ),    ).not.toContain("openai/gpt-5.5");    expect(      getAppModelOptionsForInstance(settingsWithProviderInstances(), openrouter).map(        (option) => option.slug,      ),    ).toContain("openai/gpt-5.5");  });   it("resolves a custom slug against the selected custom instance", () => {    const providers = [      provider({ provider: ProviderDriverKind.make("claudeAgent"), instanceId: "claudeAgent" }),      provider({        provider: ProviderDriverKind.make("claudeAgent"),        instanceId: "claude_openrouter",      }),    ];     expect(      resolveAppModelSelectionForInstance(        ProviderInstanceId.make("claude_openrouter"),        settingsWithProviderInstances(),        providers,        "openai/gpt-5.5",      ),    ).toBe("openai/gpt-5.5");  });   it("preserves a custom slug that collides with a provider alias", () => {    const providers = [      provider({        provider: ProviderDriverKind.make("claudeAgent"),        instanceId: "claude_openrouter",        models: ["claude-opus-4-8"],      }),    ];    const settings: UnifiedSettings = {      ...settingsWithProviderInstances(),      providerInstances: {        ...settingsWithProviderInstances().providerInstances,        [ProviderInstanceId.make("claude_openrouter")]: {          driver: ProviderDriverKind.make("claudeAgent"),          config: { customModels: ["opus"] },        },      },    };    const openrouter = deriveProviderInstanceEntries(providers)[0]!;     expect(      getAppModelOptionsForInstance(settings, openrouter).map((option) => option.slug),    ).toEqual(["claude-opus-4-8", "opus"]);    expect(      resolveAppModelSelectionForInstance(        ProviderInstanceId.make("claude_openrouter"),        settings,        providers,        "opus",      ),    ).toBe("opus");  });   it("includes Grok custom models from the selected provider instance", () => {    const providers = [provider({ provider: ProviderDriverKind.make("grok"), instanceId: "grok" })];    const settings: UnifiedSettings = {      ...settingsWithProviderInstances(),      providerInstances: {        ...settingsWithProviderInstances().providerInstances,        [ProviderInstanceId.make("grok")]: {          driver: ProviderDriverKind.make("grok"),          config: { customModels: ["grok-test-custom-model"] },        },      },    };    const grok = deriveProviderInstanceEntries(providers).find(      (entry) => entry.instanceId === "grok",    )!;     expect(getAppModelOptionsForInstance(settings, grok).map((option) => option.slug)).toContain(      "grok-test-custom-model",    );  });   it("does not inject an unknown selected slug into the stock instance list", () => {    const providers = [      provider({        instanceId: "claudeAgent",        models: ["claude-sonnet-4-6"],      }),      provider({        instanceId: "claude_openrouter",        models: ["claude-sonnet-4-6"],      }),    ];    const stock = deriveProviderInstanceEntries(providers).find(      (entry) => entry.instanceId === "claudeAgent",    )!;     expect(      getAppModelOptionsForInstance(settingsWithProviderInstances(), stock).map(        (option) => option.slug,      ),    ).not.toContain("openai/gpt-5.5");  });   it("hides server models from the instance option list", () => {    const providers = [      provider({        instanceId: "claudeAgent",        models: ["claude-opus-4-6", "claude-sonnet-4-6"],      }),    ];    const settings: UnifiedSettings = {      ...settingsWithProviderInstances(),      providerModelPreferences: {        [ProviderInstanceId.make("claudeAgent")]: {          hiddenModels: ["claude-opus-4-6"],          modelOrder: [],        },      },    };    const stock = deriveProviderInstanceEntries(providers).find(      (entry) => entry.instanceId === "claudeAgent",    )!;     expect(getAppModelOptionsForInstance(settings, stock).map((option) => option.slug)).toEqual([      "claude-sonnet-4-6",    ]);  });   it("drops server-reported custom rows that are no longer in settings", () => {    const baseProvider = provider({      instanceId: "claude_openrouter",      models: ["claude-sonnet-4-6"],    });    const providers = [      {        ...baseProvider,        models: [          ...baseProvider.models,          { slug: "removed/custom", name: "removed/custom", isCustom: true, capabilities: {} },        ],      },    ];    const openrouter = deriveProviderInstanceEntries(providers)[0]!;     expect(      getAppModelOptionsForInstance(settingsWithProviderInstances(), openrouter).map(        (option) => option.slug,      ),    ).toEqual(["claude-sonnet-4-6", "openai/gpt-5.5"]);  });   it("applies persisted per-instance model ordering", () => {    const providers = [      provider({        instanceId: "claudeAgent",        models: ["claude-opus-4-6", "claude-sonnet-4-6", "claude-haiku-4-5"],      }),    ];    const settings: UnifiedSettings = {      ...settingsWithProviderInstances(),      providerModelPreferences: {        [ProviderInstanceId.make("claudeAgent")]: {          hiddenModels: [],          modelOrder: ["claude-haiku-4-5", "claude-opus-4-6"],        },      },    };    const stock = deriveProviderInstanceEntries(providers).find(      (entry) => entry.instanceId === "claudeAgent",    )!;     expect(getAppModelOptionsForInstance(settings, stock).map((option) => option.slug)).toEqual([      "claude-haiku-4-5",      "claude-opus-4-6",      "claude-sonnet-4-6",    ]);  });   it("falls back when the selected model is hidden", () => {    const providers = [      provider({        instanceId: "claudeAgent",        models: ["claude-opus-4-6", "claude-sonnet-4-6"],      }),    ];    const settings: UnifiedSettings = {      ...settingsWithProviderInstances(),      providerModelPreferences: {        [ProviderInstanceId.make("claudeAgent")]: {          hiddenModels: ["claude-opus-4-6"],          modelOrder: [],        },      },    };     expect(      resolveAppModelSelectionForInstance(        ProviderInstanceId.make("claudeAgent"),        settings,        providers,        "claude-opus-4-6",      ),    ).toBe("claude-sonnet-4-6");    expect(      resolveAppModelSelectionForInstance(        ProviderInstanceId.make("claudeAgent"),        settings,        providers,        "claude-opus-4-6",        { preserveUnavailableSelection: true },      ),    ).toBe("claude-sonnet-4-6");  });   it("falls back instead of resolving a custom slug against the wrong instance", () => {    const providers = [      provider({        instanceId: "claudeAgent",        models: ["claude-sonnet-4-6"],      }),      provider({        instanceId: "claude_openrouter",        models: ["claude-sonnet-4-6"],      }),    ];     expect(      resolveAppModelSelectionForInstance(        ProviderInstanceId.make("claudeAgent"),        settingsWithProviderInstances(),        providers,        "openai/gpt-5.5",      ),    ).toBe("claude-sonnet-4-6");  });   describe.each([    {      driverName: "opencode",      availableModel: "opencode/big-pickle",      missingModel: "opencode/kimi-k3",    },    {      driverName: "antigravity",      availableModel: "gemini-3.1-pro",      missingModel: "gemini-3.1-pro-high",    },  ])("$driverName catalog gaps", ({ driverName, availableModel, missingModel }) => {    it("preserves a selected model when a catalog refresh no longer contains it", () => {      const providers = [        provider({          provider: ProviderDriverKind.make(driverName),          instanceId: driverName,          models: [availableModel],        }),      ];       expect(        resolveAppModelSelectionForInstance(          ProviderInstanceId.make(driverName),          settingsWithProviderInstances(),          providers,          missingModel,          { preserveUnavailableSelection: true },        ),      ).toBe(missingModel);      expect(        resolveAppModelSelectionForInstance(          ProviderInstanceId.make(driverName),          settingsWithProviderInstances(),          providers,          missingModel,        ),      ).toBe(availableModel);    });     it("adds the selected missing model as an unavailable option", () => {      const providers = [        provider({          provider: ProviderDriverKind.make(driverName),          instanceId: driverName,          models: [availableModel],        }),      ];      const entry = deriveProviderInstanceEntries(providers)[0]!;       expect(        getAppModelOptionsForInstance(settingsWithProviderInstances(), entry, missingModel),      ).toEqual([        expect.objectContaining({ slug: availableModel }),        expect.objectContaining({          slug: missingModel,          name: missingModel,          isUnavailable: true,        }),      ]);    });     it("keeps a missing option scoped to the selected instance", () => {      const selectedInstanceId = ProviderInstanceId.make(`${driverName}_work`);      const otherInstanceId = ProviderInstanceId.make(`${driverName}_personal`);      const driver = ProviderDriverKind.make(driverName);      const providers = [        provider({ provider: driver, instanceId: selectedInstanceId, models: [] }),        provider({ provider: driver, instanceId: otherInstanceId, models: [] }),      ];      const options = getCustomModelOptionsByInstance(        settingsWithProviderInstances(),        providers,        selectedInstanceId,        missingModel,      );       expect(options.get(selectedInstanceId)).toEqual([        expect.objectContaining({ slug: missingModel, isUnavailable: true }),      ]);      expect(options.get(otherInstanceId)).toEqual([]);    });     it("replaces the unavailable marker with catalog metadata after recovery", () => {      const instanceId = ProviderInstanceId.make(driverName);      const driver = ProviderDriverKind.make(driverName);      const selectedModel = missingModel;      const pendingProviders = [        provider({ provider: driver, instanceId, models: [availableModel] }),      ];      const recoveredProviders = [        provider({ provider: driver, instanceId, models: [availableModel, selectedModel] }),      ];       expect(        getAppModelOptionsForInstance(          settingsWithProviderInstances(),          deriveProviderInstanceEntries(pendingProviders)[0]!,          selectedModel,        ).find((option) => option.slug === selectedModel)?.isUnavailable,      ).toBe(true);      expect(        getAppModelOptionsForInstance(          settingsWithProviderInstances(),          deriveProviderInstanceEntries(recoveredProviders)[0]!,          selectedModel,        ).find((option) => option.slug === selectedModel)?.isUnavailable,      ).toBeUndefined();      expect(        resolveAppModelSelectionForInstance(          instanceId,          settingsWithProviderInstances(),          recoveredProviders,          selectedModel,          { preserveUnavailableSelection: true },        ),      ).toBe(selectedModel);    });     it("does not resurrect a hidden model when the raw catalog omits it", () => {      const instanceId = ProviderInstanceId.make(driverName);      const driver = ProviderDriverKind.make(driverName);      const settings: UnifiedSettings = {        ...settingsWithProviderInstances(),        providerModelPreferences: {          [instanceId]: {            hiddenModels: [missingModel],            modelOrder: [],          },        },      };      const providers = [provider({ provider: driver, instanceId, models: [] })];      const entry = deriveProviderInstanceEntries(providers)[0]!;       expect(getAppModelOptionsForInstance(settings, entry, missingModel)).toEqual([]);      expect(        resolveAppModelSelectionForInstance(instanceId, settings, providers, missingModel, {          preserveUnavailableSelection: true,        }),      ).toBeNull();    });  });   it("does not add unavailable options for other providers", () => {    const providers = [      provider({        provider: ProviderDriverKind.make("codex"),        instanceId: "codex",        models: ["gpt-5.6-sol"],      }),    ];    const entry = deriveProviderInstanceEntries(providers)[0]!;     expect(      getAppModelOptionsForInstance(settingsWithProviderInstances(), entry, "gpt-missing").map(        (option) => option.slug,      ),    ).toEqual(["gpt-5.6-sol"]);    expect(

Lines 1–500 of 916.