fix(AGC): 目录缺 unavailableModels 时不再崩溃
Project CI / Backend tests (pull_request) Failing after 1m26s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 3m5s
Project CI / Native shell tests (pull_request) Failing after 2m18s
Project CI / Frontend tests (pull_request) Failing after 1m7s
Project CI / Repository checks (pull_request) Failing after 1m15s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 5m3s
Project CI / AI game creator shell web tests (pull_request) Failing after 58s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Failing after 1m26s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 3m5s
Project CI / Native shell tests (pull_request) Failing after 2m18s
Project CI / Frontend tests (pull_request) Failing after 1m7s
Project CI / Repository checks (pull_request) Failing after 1m15s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 5m3s
Project CI / AI game creator shell web tests (pull_request) Failing after 58s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Has been cancelled
- applyCatalog 归一化 catalog.unavailableModels,修掉按 reason 取降级文案时对 undefined 解引用(此前 26 个用例挂在这) - 用例跟进新降级文案;disabled 用例补上下线桶,断言「该模型已下线」专用文案
This commit is contained in:
+5
-2
@@ -144,6 +144,9 @@ export function ConversationModelSelect({
|
||||
showBusy: boolean,
|
||||
epochAtRequest: number,
|
||||
) => {
|
||||
// 目录契约的 `unavailableModels` 是加法字段:旧缓存 / 局部数据可能缺失。
|
||||
// 统一归一化一次,避免下面 setState 与按 reason 取文案时解引用 undefined。
|
||||
const catalogUnavailableModels = catalog.unavailableModels ?? [];
|
||||
if (
|
||||
mountedRef.current &&
|
||||
(appliedRevisionRef.current !== catalog.revision ||
|
||||
@@ -151,7 +154,7 @@ export function ConversationModelSelect({
|
||||
) {
|
||||
appliedRevisionRef.current = catalog.revision;
|
||||
setModels(catalog.models);
|
||||
setUnavailableModels(catalog.unavailableModels);
|
||||
setUnavailableModels(catalogUnavailableModels);
|
||||
setDefaultModelId(catalog.defaultModelId);
|
||||
}
|
||||
const invoke = resolveTauriInvoke();
|
||||
@@ -190,7 +193,7 @@ export function ConversationModelSelect({
|
||||
if (saved) {
|
||||
// 命中不可用桶时按 reason 给具体原因;两桶都没有(后台直接删除)走泛化文案。
|
||||
nextNotice = unavailableModelFallbackNotice(
|
||||
catalog.unavailableModels.find((model) => model.id === saved)
|
||||
catalogUnavailableModels.find((model) => model.id === saved)
|
||||
?.reason,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -315,7 +315,7 @@ test('falls back to the default model when the saved selection was removed', asy
|
||||
}));
|
||||
const onReady = vi.fn();
|
||||
render(<ConversationModelSelect disabled={false} onReady={onReady} />);
|
||||
await screen.findByText('所选模型已停用,已切换为默认模型');
|
||||
await screen.findByText('所选模型已不可用,已切回默认模型');
|
||||
await waitFor(() => expect(onReady).toHaveBeenLastCalledWith(true));
|
||||
expect(screen.queryByText('private-old-model')).toBeNull();
|
||||
expect(invoke).toHaveBeenCalledWith('select_game_creator_model', {
|
||||
@@ -521,12 +521,22 @@ test('pre-send validation falls back when the selected model is disabled', async
|
||||
vi.mocked(loadClientLlmModels).mockResolvedValue({
|
||||
defaultModelId: 'quality',
|
||||
models: [{ id: 'quality', displayName: '高质量', agentMode: 'codex' }],
|
||||
// `fast` 仍在下线桶里:降级文案要按 `disabled` 取「该模型已下线」。
|
||||
unavailableModels: [
|
||||
{
|
||||
id: 'fast',
|
||||
displayName: '快速',
|
||||
agentMode: 'cc',
|
||||
protocol: 'anthropic',
|
||||
reason: 'disabled',
|
||||
},
|
||||
],
|
||||
revision: 2,
|
||||
});
|
||||
await act(async () => {
|
||||
await expect(ref.current?.ensureUsable()).resolves.toBe(true);
|
||||
});
|
||||
expect(screen.getByText('所选模型已停用,已切换为默认模型')).not.toBeNull();
|
||||
expect(screen.getByText('所选模型已下线,已切换为默认模型')).not.toBeNull();
|
||||
expect(savedModelId).toBe('quality');
|
||||
expect(invoke).toHaveBeenCalledWith('select_game_creator_model', {
|
||||
modelId: 'quality',
|
||||
|
||||
Reference in New Issue
Block a user