2168 unmodified lines
Expand all
describe("InteractiveMode model candidates", () => {
type ModelCandidatesHarness = {
agentConnection: { getModelCatalog: () => Promise<AgentConnectionModelCatalog> };
connectionModels: AgentConnectionModel[];
connectionModelCatalog: AgentConnectionModel[];
connectionConfiguredProviders: Set<string>;
connectionModelsFetchedAt: number;
connectionModelsRefreshVersion: number;
connectionModelsRefreshInFlight: { version: number; promise: Promise<AgentConnectionModel[]> } | undefined;
getScopedModelState(): AgentConnectionState["scopedModels"];
applyConnectionModelCatalog(catalog: AgentConnectionModelCatalog): void;
getAvailableConnectionModels(): AgentConnectionModel[];
getConnectionAvailableModels(): Promise<AgentConnectionModel[]>;
getModelCandidates(): Promise<AgentConnectionModel[]>;
getScopedModelsFromModelIds(
enabledIds: readonly string[],
const model = createModel("openai", "gpt-5.5");
const getModelCatalog = vi.fn(async () => ({ models: [model], configuredProviders: [model.provider] }));
const fakeThis: ModelCandidatesHarness = {
agentConnection: { getModelCatalog },
connectionModels: [],
connectionModelCatalog: [],
connectionConfiguredProviders: new Set(),
connectionModelsFetchedAt: 0,
connectionModelsRefreshVersion: 0,
connectionModelsRefreshInFlight: undefined,
getScopedModelState: () => [],
applyConnectionModelCatalog: prototype.applyConnectionModelCatalog,
getAvailableConnectionModels: prototype.getAvailableConnectionModels,
getConnectionAvailableModels: prototype.getConnectionAvailableModels,
getModelCandidates: prototype.getModelCandidates,
getScopedModelsFromModelIds: prototype.getScopedModelsFromModelIds,
};
const result = await prototype.getModelCandidates.call(fakeThis);
expect(result).toEqual([model]);
expect(getModelCatalog).toHaveBeenCalledTimes(1);
expect(fakeThis.connectionModels).toEqual([model]);
expect(fakeThis.getAvailableConnectionModels()).toEqual([model]);
});
test("uses connection state for scoped model candidates", async () => {
const model = createModel("anthropic", "claude-opus-4-5");
return { models: [available], configuredProviders: [available.provider] };
});
const fakeThis: ModelCandidatesHarness = {
agentConnection: { getModelCatalog },
connectionModels: [],
connectionModelCatalog: [],
connectionConfiguredProviders: new Set(),
connectionModelsFetchedAt: 0,
connectionModelsRefreshVersion: 0,
connectionModelsRefreshInFlight: undefined,
getScopedModelState: () => [{ model, thinkingLevel: "medium" }],
applyConnectionModelCatalog: prototype.applyConnectionModelCatalog,
getAvailableConnectionModels: prototype.getAvailableConnectionModels,
getConnectionAvailableModels: prototype.getConnectionAvailableModels,
getModelCandidates: prototype.getModelCandidates,
getScopedModelsFromModelIds: prototype.getScopedModelsFromModelIds,
};
agentConnection: {
getModelCatalog(): Promise<AgentConnectionModelCatalog>;
setModel(provider: string, modelId: string): Promise<void>;
};
connectionModels: AgentConnectionModel[];
connectionModelCatalog: AgentConnectionModel[];
connectionConfiguredProviders: Set<string>;
connectionModelsFetchedAt: number;
connectionModelsRefreshVersion: number;
showError(message: string): void;
getScopedModelState(): AgentConnectionState["scopedModels"];
getCurrentModel(): AgentConnectionModel | undefined;
applyConnectionModelCatalog(catalog: AgentConnectionModelCatalog): void;
getAvailableConnectionModels(): AgentConnectionModel[];
findExactModelMatch(searchTerm: string): Promise<AgentConnectionModel | undefined>;
getConnectionAvailableModels(): Promise<AgentConnectionModel[]>;
getCachedModelCandidates(): AgentConnectionModel[];
getModelSelectorRefreshPromise(options?: { force?: boolean }): Promise<AgentConnectionModel[]> | undefined;
};
}),
setModel: vi.fn(async () => {}),
};
fakeThis.connectionModels = [...options.connectionModels];
fakeThis.connectionModelCatalog = catalogModels;
fakeThis.connectionConfiguredProviders = configuredProviders;
fakeThis.connectionModelsFetchedAt = options.connectionModelsFetchedAt ?? 0;
fakeThis.connectionModelsRefreshVersion = 0;
529 unmodified lines
Expand all
getCommands: vi.fn(async () => []),
getResourceSnapshot: vi.fn(async () => ({})),
setModel: vi.fn(async () => {}),
} as never;
fakeThis.connectionModels = [];
fakeThis.connectionModelCatalog = [];
fakeThis.connectionConfiguredProviders = new Set();
fakeThis.connectionModelsFetchedAt = 0;
fakeThis.connectionModelsRefreshVersion = 0;
oldModels.resolve({ models: [oldModel], configuredProviders: [oldModel.provider] });
await expect(staleRefresh).resolves.toEqual([freshModel]);
expect(fakeThis.connectionModels).toEqual([freshModel]);
expect(fakeThis.getAvailableConnectionModels()).toEqual([freshModel]);
});
test("keeps the cached model catalog when a catalog refresh fails", async () => {
const cachedModel = createModel("openai", "cached");
}),
getResourceSnapshot: vi.fn(async () => ({})),
setModel: vi.fn(async () => {}),
} as never;
fakeThis.connectionModels = [cachedModel];
fakeThis.connectionModelCatalog = [cachedModel];
fakeThis.connectionConfiguredProviders = new Set([cachedModel.provider]);
fakeThis.connectionModelsFetchedAt = Date.now();
fakeThis.connectionModelsRefreshVersion = 0;
await expect(fakeThis.refreshConnectionCatalog()).resolves.toBeUndefined();
expect(fakeThis.connectionCommands).toEqual([]);
expect(fakeThis.connectionModels).toEqual([expect.objectContaining({ id: "fresh" })]);
expect(fakeThis.getAvailableConnectionModels()).toEqual([expect.objectContaining({ id: "fresh" })]);
expect(fakeThis.connectionModelsFetchedAt).toBeGreaterThan(0);
});
test("keeps an empty configuration menu open when the background refresh fails", async () => {
199 unmodified lines
Expand all
setupAutocompleteProvider(): void;
};
type OnboardingFake = OnboardingHarness & {
connectionState: AgentConnectionState;
connectionModels: AgentConnectionModel[];
agentConnection: {
getAvailableModels?: () => Promise<AgentConnectionModel[]>;
setModel?: (provider: string, modelId: string) => Promise<void>;
};
666 unmodified lines
Expand all
function createPrimeCliHarness(shown: boolean): OnboardingFake {
const fakeThis = Object.create(InteractiveMode.prototype) as OnboardingFake;
fakeThis.connectionState = createConnectionState({ model: primeModel });
fakeThis.connectionModels = [primeModel];
fakeThis.agentConnection = {
getAvailableModels: vi.fn(async () => [primeModel]),
};
fakeThis.uiServices = {
1594 unmodified lines
Expand all