feat: use managed model capabilities for reasoning and image input
This commit is contained in:
@@ -81,9 +81,10 @@ async function installCodingFirstChatHost(
|
||||
electronApp: ElectronApplication,
|
||||
hostConnection: HostConnection,
|
||||
featureComplete = false,
|
||||
managedCapabilities = false,
|
||||
): Promise<void> {
|
||||
await electronApp.evaluate(async (_, payload) => {
|
||||
const { connection, featureComplete } = payload;
|
||||
const { connection, featureComplete, managedCapabilities } = payload;
|
||||
const { ipcMain } = process.mainModule!.require('electron') as typeof import('electron');
|
||||
type MainState = {
|
||||
captured: CapturedRequest[];
|
||||
@@ -116,7 +117,7 @@ async function installCodingFirstChatHost(
|
||||
lastOpenedAt: now,
|
||||
};
|
||||
const configuredModel = {
|
||||
accountId: 'account-e2e',
|
||||
accountId: managedCapabilities ? 'niancode-user-models' : 'account-e2e',
|
||||
modelId: 'model-a',
|
||||
thinkingLevel: 'off',
|
||||
};
|
||||
@@ -516,12 +517,20 @@ async function installCodingFirstChatHost(
|
||||
}
|
||||
if (path === '/api/provider-accounts') {
|
||||
return respond([{
|
||||
id: 'account-e2e',
|
||||
id: managedCapabilities ? 'niancode-user-models' : 'account-e2e',
|
||||
vendorId: 'custom',
|
||||
label: 'E2E account',
|
||||
authMode: 'api_key',
|
||||
model: 'model-a',
|
||||
fallbackModels: ['model-b'],
|
||||
...(managedCapabilities ? { metadata: { worksSquareModelCapabilitiesV2: {
|
||||
schemaVersion: 2, fetchedAt: now, refreshStatus: 'fresh', models: {
|
||||
'model-a': { inputModalities: ['text'], outputModalities: ['text'],
|
||||
reasoning: { supported: true, canDisable: true, defaultEnabled: true,
|
||||
effortValues: ['xhigh', 'medium', 'low'], defaultEffort: 'xhigh', controlFormat: 'qwen', budget: null },
|
||||
limits: null, resolutionStatus: 'ready', issues: [], updatedAt: now },
|
||||
},
|
||||
} } } : {}),
|
||||
enabled: true,
|
||||
isDefault: true,
|
||||
createdAt: now,
|
||||
@@ -703,7 +712,7 @@ async function installCodingFirstChatHost(
|
||||
if (path === '/api/coding/runtime/diagnostics') return respond({ runtime: { revision: { provider: 1, resources: 1 }, workers: [{ conversationId: conversation.id, generation: 1, state: 'running', stage: 'running' }] } });
|
||||
return respond({ success: false, error: `Unhandled E2E route: ${method} ${path}` }, 404);
|
||||
});
|
||||
}, { connection: hostConnection, featureComplete });
|
||||
}, { connection: hostConnection, featureComplete, managedCapabilities });
|
||||
}
|
||||
|
||||
async function readState(electronApp: ElectronApplication): Promise<{
|
||||
@@ -744,6 +753,36 @@ async function settleSnapshot(electronApp: ElectronApplication): Promise<void> {
|
||||
});
|
||||
}
|
||||
|
||||
test('managed capabilities expose native xhigh and block unsupported image input', async ({ launchElectronApp }) => {
|
||||
const electronApp = await launchElectronApp({ skipSetup: true });
|
||||
let page = await getStableWindow(electronApp);
|
||||
const connection = await page.evaluate(async () => ({
|
||||
token: await window.electron.ipcRenderer.invoke('hostapi:token') as string,
|
||||
baseUrl: await window.electron.ipcRenderer.invoke('hostapi:base-url') as string,
|
||||
}));
|
||||
await installCodingFirstChatHost(electronApp, connection, true, true);
|
||||
await settleSnapshot(electronApp);
|
||||
await disableCodingEventSource(page);
|
||||
try {
|
||||
await page.reload();
|
||||
page = await getStableWindow(electronApp);
|
||||
await page.getByTestId('ai-module-option-programming').click();
|
||||
await expect(page.getByTestId('main-layout')).toBeVisible();
|
||||
await page.evaluate(() => { window.location.hash = '/chat'; });
|
||||
await expect(page.getByRole('button', { name: '添加图片', exact: true })).toBeDisabled();
|
||||
const controls = page.getByTestId('coding-composer-runtime-controls');
|
||||
await expect(controls).toContainText('模型默认');
|
||||
await controls.getByRole('button').click();
|
||||
await page.getByRole('menuitem', { name: /推理强度/ }).click();
|
||||
await expect(page.getByRole('menuitemradio', { name: '模型默认', exact: true })).toBeVisible();
|
||||
await expect(page.getByRole('menuitemradio', { name: '关闭思考', exact: true })).toBeVisible();
|
||||
await page.getByRole('menuitemradio', { name: 'xhigh', exact: true }).click();
|
||||
await expect.poll(async () => (await readState(electronApp)).captured.find(
|
||||
request => request.path.endsWith('/thinking') && request.method === 'POST')?.body?.reasoningChoice,
|
||||
).toEqual({ mode: 'enabled', effort: 'xhigh' });
|
||||
} finally { await releaseSnapshot(electronApp); }
|
||||
});
|
||||
|
||||
test('first PI Conversation is editable under 500 ms and submits before runtime Snapshot', async ({
|
||||
launchElectronApp,
|
||||
}) => {
|
||||
|
||||
Reference in New Issue
Block a user