fix(opencode): switch session models without restart

This commit is contained in:
2026-08-20 22:38:18 +08:00
parent 1c6b004436
commit c0163bc507
18 changed files with 718 additions and 92 deletions

View File

@@ -105,8 +105,20 @@ async function installMultichatHost(electronApp: ElectronApplication): Promise<v
updatedAt: now,
};
const sessions = [
{ id: sessionAId, title: 'Session A', agent: agent.id, time: { updated: 2 } },
{ id: sessionBId, title: 'Session B', agent: agent.id, time: { updated: 1 } },
{
id: sessionAId,
title: 'Session A',
agent: agent.id,
model: { providerID: 'niancode-user-models', id: 'qwen3.7-plus' },
time: { updated: 2 },
},
{
id: sessionBId,
title: 'Session B',
agent: agent.id,
model: { providerID: 'niancode-user-models', id: 'qwen3.7-plus' },
time: { updated: 1 },
},
];
const conversationState = {
schemaVersion: 1,
@@ -194,6 +206,7 @@ async function installMultichatHost(electronApp: ElectronApplication): Promise<v
label: 'Makelore Models',
authMode: 'api_key',
model: 'qwen3.7-plus',
fallbackModels: ['deepseek-chat'],
enabled: true,
isDefault: true,
createdAt: now,
@@ -227,6 +240,13 @@ async function installMultichatHost(electronApp: ElectronApplication): Promise<v
state.sessionABusy = true;
return respond({ success: true }, 202);
}
if (
(path === `/api/opencode/sessions/${sessionAId}/model`
|| path === `/api/opencode/sessions/${sessionBId}/model`)
&& method === 'POST'
) {
return respond({ success: true, model: body?.model });
}
if (path === `/api/opencode/sessions/${sessionBId}/messages` && method === 'POST') {
return respond({
success: false,
@@ -297,6 +317,13 @@ test('keeps Session A running when Session B is terminally rejected by Agent pre
await sessionA.click();
await expect(sessionA).toHaveAttribute('aria-current', 'page');
const modelSelector = page.getByTestId('opencode-model-selector-trigger');
await expect(modelSelector).toHaveValue('niancode-user-models/qwen3.7-plus');
await modelSelector.selectOption('niancode-user-models/deepseek-chat');
await expect(modelSelector).toHaveValue('niancode-user-models/deepseek-chat');
await expect.poll(async () => (await capturedRequests(electronApp)).map(
(request) => `${request.method} ${request.path}`,
)).toContain(`POST /api/opencode/sessions/${SESSION_A_ID}/model`);
await submitComposer(page, 'Keep Session A running');
await expect.poll(async () => [...new Set((await capturedRequests(electronApp))
.filter((request) => request.path.includes('/messages'))
@@ -336,4 +363,6 @@ test('keeps Session A running when Session B is terminally rejected by Agent pre
));
expect(promptPosts.filter((request) => request.path.includes(SESSION_A_ID))).toHaveLength(1);
expect(promptPosts.filter((request) => request.path.includes(SESSION_B_ID))).toHaveLength(1);
expect(promptPosts.find((request) => request.path.includes(SESSION_A_ID))?.body)
.not.toHaveProperty('model');
});