feat: integrate learning module
This commit is contained in:
@@ -88,6 +88,7 @@ test.describe('AI Design workspace', () => {
|
||||
await expect(page.getByTestId('image-workspace-message').first()).toHaveClass(/w-full/);
|
||||
const firstQuote = page.locator('[data-testid^="design-quote-"]').first();
|
||||
await expect(firstQuote.getByRole('button', { name: '继续调整' })).toBeVisible();
|
||||
await expect(firstQuote.getByTestId('design-quote-model')).toHaveCount(0);
|
||||
await expect(firstQuote).not.toContainText('提示词模式');
|
||||
await page.getByRole('button', { name: '确认并开始生成' }).click();
|
||||
await expect(page.getByRole('button', { name: '确认生成' })).toHaveCount(0);
|
||||
@@ -119,6 +120,7 @@ test.describe('AI Design workspace', () => {
|
||||
await expect(page.getByTestId('image-workspace-conversation')).toContainText(secondPrompt);
|
||||
await expect(page.getByTestId('design-quote-final-prompt')).toHaveValue(secondPrompt);
|
||||
await page.getByTestId('design-quote-final-prompt').fill('用户编辑后的动态视频完整提示词');
|
||||
await expect(page.getByTestId('design-quote-model')).toHaveCount(0);
|
||||
await page.getByTestId('design-quote-resolution').selectOption('720P');
|
||||
await page.getByTestId('design-quote-aspect-ratio').selectOption('9:16');
|
||||
await page.getByTestId('design-quote-duration').selectOption('4');
|
||||
|
||||
@@ -13,6 +13,7 @@ async function installFirstChatHost(electronApp: ElectronApplication): Promise<v
|
||||
type MainState = {
|
||||
captured: CapturedRequest[];
|
||||
promptPosted: boolean;
|
||||
abortPosted: boolean;
|
||||
releaseInitialHistory: (() => void) | null;
|
||||
};
|
||||
const mainGlobal = globalThis as typeof globalThis & {
|
||||
@@ -21,6 +22,7 @@ async function installFirstChatHost(electronApp: ElectronApplication): Promise<v
|
||||
const state: MainState = {
|
||||
captured: [],
|
||||
promptPosted: false,
|
||||
abortPosted: false,
|
||||
releaseInitialHistory: null,
|
||||
};
|
||||
mainGlobal.__makeloreFirstChatE2EState = state;
|
||||
@@ -169,7 +171,7 @@ async function installFirstChatHost(electronApp: ElectronApplication): Promise<v
|
||||
if (path === '/api/opencode/sessions/status') {
|
||||
return respond({
|
||||
statuses: {
|
||||
[session.id]: { type: state.promptPosted ? 'idle' : 'busy' },
|
||||
[session.id]: { type: state.promptPosted && !state.abortPosted ? 'busy' : 'idle' },
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -183,6 +185,10 @@ async function installFirstChatHost(electronApp: ElectronApplication): Promise<v
|
||||
state.promptPosted = true;
|
||||
return respond({ success: true }, 202);
|
||||
}
|
||||
if (path === `/api/opencode/sessions/${session.id}/abort` && method === 'POST') {
|
||||
state.abortPosted = true;
|
||||
return respond({ success: true });
|
||||
}
|
||||
if (path.endsWith('/todos')) return respond({ todos: [] });
|
||||
if (path.endsWith('/diff')) return respond({ diffs: [] });
|
||||
if (path === '/api/opencode/questions') return respond({ questions: [] });
|
||||
@@ -249,6 +255,15 @@ test('submits the first prompt without waiting for the known-empty session histo
|
||||
));
|
||||
return { historyPending, promptPosted };
|
||||
}).toEqual({ historyPending: true, promptPosted: true });
|
||||
|
||||
await expect(page.getByTestId('assistant-waiting-placeholder')).toHaveCount(0);
|
||||
const stopButton = page.getByRole('button', { name: '停止当前对话' });
|
||||
await expect(stopButton).toBeEnabled();
|
||||
await expect(stopButton.getByTestId('opencode-agent-response-loader')).toBeVisible();
|
||||
await stopButton.click();
|
||||
await expect.poll(async () => (await capturedRequests(electronApp)).map(
|
||||
(request) => `${request.method} ${request.path}`,
|
||||
)).toContain('POST /api/opencode/sessions/ses_first_chat_e2e/abort');
|
||||
} finally {
|
||||
await releaseInitialHistory(electronApp);
|
||||
}
|
||||
|
||||
@@ -484,13 +484,27 @@ async function configureSlashCompactionHost(
|
||||
role: 'assistant',
|
||||
time: { created: 1_753_190_401_000 },
|
||||
},
|
||||
parts: [{
|
||||
id: 'part_slash_e2e_assistant',
|
||||
sessionID: 'ses_slash_e2e',
|
||||
messageID: 'msg_slash_e2e_assistant',
|
||||
type: 'text',
|
||||
text: '已有的助手回复',
|
||||
}],
|
||||
parts: [
|
||||
{
|
||||
id: 'part_slash_e2e_assistant',
|
||||
sessionID: 'ses_slash_e2e',
|
||||
messageID: 'msg_slash_e2e_assistant',
|
||||
type: 'text',
|
||||
text: '已有的助手回复,我先确认上下文,再继续处理。',
|
||||
},
|
||||
{
|
||||
id: 'part_slash_e2e_tool',
|
||||
sessionID: 'ses_slash_e2e',
|
||||
messageID: 'msg_slash_e2e_assistant',
|
||||
type: 'tool',
|
||||
tool: 'read_file',
|
||||
callID: 'call_slash_e2e_read',
|
||||
state: {
|
||||
status: 'completed',
|
||||
input: { filePath: 'README.md' },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
});
|
||||
@@ -670,6 +684,11 @@ test.describe('OpenCode slash commands', () => {
|
||||
'[data-chat-message-id="msg_slash_e2e_assistant"]',
|
||||
);
|
||||
await expect(existingAssistant).toBeVisible();
|
||||
await expect(existingAssistant.getByTestId('chat-message-bubble-assistant'))
|
||||
.toContainText('已有的助手回复,我先确认上下文,再继续处理。');
|
||||
await expect(existingAssistant.getByTestId('chat-message-avatar-assistant')).toBeVisible();
|
||||
await expect(transcript.getByTestId('chat-execution-graph')).toBeVisible();
|
||||
await expect(transcript.getByTestId('chat-execution-step')).toHaveCount(1);
|
||||
const composer = page.getByRole('textbox');
|
||||
await expect(composer).toBeVisible();
|
||||
await composer.fill('/compact');
|
||||
|
||||
@@ -12,13 +12,9 @@ test.describe('Project configuration skills', () => {
|
||||
try {
|
||||
const userDataDir = await app.evaluate(({ app: electronApp }) => electronApp.getPath('userData'));
|
||||
const skillDir = path.join(userDataDir, 'opencode', 'niancode-config', 'skills', 'agent-browser');
|
||||
const gameEngineSkillDir = path.join(userDataDir, 'opencode', 'niancode-config', 'skills', 'game-engine');
|
||||
await mkdir(path.join(skillDir, 'references'), { recursive: true });
|
||||
await writeFile(path.join(skillDir, 'SKILL.md'), '---\nname: agent-browser\ndescription: E2E browser debugging skill.\n---\n\n# Browser debugging\n');
|
||||
await writeFile(path.join(skillDir, 'references', 'guide.md'), '# Reference guide\n');
|
||||
await mkdir(path.join(gameEngineSkillDir, 'assets'), { recursive: true });
|
||||
await writeFile(path.join(gameEngineSkillDir, 'SKILL.md'), '---\nname: game-engine\ndescription: E2E game engine skill.\n---\n\n# Game Engine Skill\n\n## Makelore 使用边界\n');
|
||||
await writeFile(path.join(gameEngineSkillDir, 'assets', '2d-platform-game.md'), '# 2D Platform Game Template\n');
|
||||
|
||||
await app.evaluate(({ ipcMain }, selectedPath) => {
|
||||
ipcMain.removeHandler('dialog:open');
|
||||
@@ -118,11 +114,7 @@ test.describe('Project configuration skills', () => {
|
||||
await expect(page.getByTestId('skill-main-file')).toContainText('# Browser debugging');
|
||||
await page.getByRole('button', { name: '返回技能列表' }).locator('svg').click();
|
||||
await expect(page.getByTestId('skill-card-agent-browser')).toBeVisible();
|
||||
await expect(page.getByTestId('skill-card-game-engine')).toBeVisible();
|
||||
await page.getByTestId('skill-card-game-engine').click();
|
||||
await expect(page.getByTestId('skill-structure')).toContainText('assets/2d-platform-game.md');
|
||||
await expect(page.getByTestId('skill-main-file')).toContainText('Makelore 使用边界');
|
||||
await page.getByRole('button', { name: '返回技能列表' }).locator('svg').click();
|
||||
await expect(page.getByTestId('skill-card-game-engine')).toHaveCount(0);
|
||||
await page.getByRole('button', { name: '关闭' }).click();
|
||||
await expect(page.getByTestId('resource-card-publish')).toHaveCount(0);
|
||||
await expect(page.getByRole('button', { name: '一键提交审核' })).toBeVisible();
|
||||
|
||||
Reference in New Issue
Block a user