mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-05-18 09:38:33 +00:00
fix: /models
This commit is contained in:
128
server/modules/providers/tests/provider-models.service.test.ts
Normal file
128
server/modules/providers/tests/provider-models.service.test.ts
Normal file
@@ -0,0 +1,128 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { mkdir, mkdtemp, rm } from 'node:fs/promises';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import test from 'node:test';
|
||||
|
||||
import {
|
||||
createProviderModelsService,
|
||||
PROVIDER_MODELS_CACHE_TTL_MS,
|
||||
} from '@/modules/providers/services/provider-models.service.js';
|
||||
import type { LLMProvider, ProviderModelsDefinition } from '@/shared/types.js';
|
||||
|
||||
const createModels = (value: string): ProviderModelsDefinition => ({
|
||||
OPTIONS: [{ value, label: value }],
|
||||
DEFAULT: value,
|
||||
});
|
||||
|
||||
test('provider models are cached for the two-day ttl', async () => {
|
||||
const tempRoot = await mkdtemp(path.join(os.tmpdir(), 'provider-model-cache-ttl-'));
|
||||
let currentTime = 1_000;
|
||||
let loadCount = 0;
|
||||
|
||||
try {
|
||||
const service = createProviderModelsService({
|
||||
cachePath: path.join(tempRoot, 'models-cache.json'),
|
||||
now: () => currentTime,
|
||||
loadModels: async (provider: LLMProvider) => {
|
||||
loadCount += 1;
|
||||
return createModels(`${provider}-${loadCount}`);
|
||||
},
|
||||
});
|
||||
|
||||
const first = await service.getProviderModels('codex');
|
||||
const cached = await service.getProviderModels('codex');
|
||||
assert.equal(loadCount, 1);
|
||||
assert.equal(cached.DEFAULT, first.DEFAULT);
|
||||
|
||||
currentTime += PROVIDER_MODELS_CACHE_TTL_MS - 1;
|
||||
await service.getProviderModels('codex');
|
||||
assert.equal(loadCount, 1);
|
||||
|
||||
currentTime += 2;
|
||||
const refreshed = await service.getProviderModels('codex');
|
||||
assert.equal(loadCount, 2);
|
||||
assert.equal(refreshed.DEFAULT, 'codex-2');
|
||||
} finally {
|
||||
await rm(tempRoot, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test('provider model cache is persisted across service instances', async () => {
|
||||
const tempRoot = await mkdtemp(path.join(os.tmpdir(), 'provider-model-cache-file-'));
|
||||
const cachePath = path.join(tempRoot, 'models-cache.json');
|
||||
|
||||
try {
|
||||
const writer = createProviderModelsService({
|
||||
cachePath,
|
||||
loadModels: async () => createModels('gemini-cached'),
|
||||
});
|
||||
await writer.getProviderModels('gemini');
|
||||
|
||||
const reader = createProviderModelsService({
|
||||
cachePath,
|
||||
loadModels: async () => {
|
||||
throw new Error('loader should not be called for persisted cache hits');
|
||||
},
|
||||
});
|
||||
const models = await reader.getProviderModels('gemini');
|
||||
assert.equal(models.DEFAULT, 'gemini-cached');
|
||||
} finally {
|
||||
await rm(tempRoot, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test('concurrent provider model requests share one load operation', async () => {
|
||||
const tempRoot = await mkdtemp(path.join(os.tmpdir(), 'provider-model-cache-pending-'));
|
||||
let loadCount = 0;
|
||||
|
||||
try {
|
||||
const service = createProviderModelsService({
|
||||
cachePath: path.join(tempRoot, 'models-cache.json'),
|
||||
loadModels: async () => {
|
||||
loadCount += 1;
|
||||
await new Promise((resolve) => setTimeout(resolve, 20));
|
||||
return createModels('claude-cached');
|
||||
},
|
||||
});
|
||||
|
||||
const [first, second] = await Promise.all([
|
||||
service.getProviderModels('claude'),
|
||||
service.getProviderModels('claude'),
|
||||
]);
|
||||
|
||||
assert.equal(loadCount, 1);
|
||||
assert.equal(first.DEFAULT, 'claude-cached');
|
||||
assert.equal(second.DEFAULT, 'claude-cached');
|
||||
} finally {
|
||||
await rm(tempRoot, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test('opencode model cache is scoped by workspace cwd', async () => {
|
||||
const tempRoot = await mkdtemp(path.join(os.tmpdir(), 'provider-model-cache-opencode-'));
|
||||
const workspaceA = path.join(tempRoot, 'workspace-a');
|
||||
const workspaceB = path.join(tempRoot, 'workspace-b');
|
||||
let loadCount = 0;
|
||||
|
||||
try {
|
||||
await mkdir(workspaceA, { recursive: true });
|
||||
await mkdir(workspaceB, { recursive: true });
|
||||
|
||||
const service = createProviderModelsService({
|
||||
cachePath: path.join(tempRoot, 'models-cache.json'),
|
||||
loadModels: async () => {
|
||||
loadCount += 1;
|
||||
return createModels(`opencode-${loadCount}`);
|
||||
},
|
||||
});
|
||||
|
||||
await service.getProviderModels('opencode', { cwd: workspaceA });
|
||||
await service.getProviderModels('opencode', { cwd: workspaceA });
|
||||
await service.getProviderModels('opencode', { cwd: workspaceB });
|
||||
|
||||
assert.equal(loadCount, 2);
|
||||
} finally {
|
||||
await rm(tempRoot, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user