feat(agents): 展示云端通俗技能与工具文案
This commit is contained in:
1 parent
23aa927441
commit
821fd6ffbe
16 files changed
+118
-23
No files matched your search
@@ -52,7 +52,10 @@ test('personal cloud Agent creation, draft save and leave protection in Electron
|
||||
if (path.endsWith('/recovery/recent')) { recent = body; return result({ saved: true }); }
|
||||
if (path.endsWith('/actions')) {
|
||||
const input = body.input ?? {};
|
||||
if (body.operation === 'catalog') return result({ models: [{ id: 'test-model', name: '创作模型' }], resources: {}, pricing: null });
|
||||
if (body.operation === 'catalog') return result({ models: [{ id: 'test-model', name: '创作模型' }], resources: {
|
||||
tools: [{ key: 'web_search', name: '上网查资料', description: '在网上查找相关信息。' }],
|
||||
skills: [{ key: 'deep-research', name: '查资料,做研究', description: '比较不同说法,再整理出结论和出处。' }],
|
||||
}, pricing: null });
|
||||
if (body.operation === 'knowledge') return result({ databases: knowledgeCreated ? [{ kb_id: 'kb', name: '我的创作资料' }] : [], models: ++knowledgeCatalogLoads === 1 ? [] : [{ id: 'fixture:test-embedding', name: '资料向量模型', dimension: 1024 }] });
|
||||
if (body.operation === 'createKnowledge') { knowledgeCreated = true; return result({ kb_id: 'kb', name: '我的创作资料' }); }
|
||||
if (body.operation === 'processKnowledge') { knowledgeStage = 0; return result({ task_id: 'process-document' }); }
|
||||
@@ -145,6 +148,11 @@ test('personal cloud Agent creation, draft save and leave protection in Electron
|
||||
await expect(page.getByRole('tabpanel', { name: '高级设置' })).toBeVisible();
|
||||
await expect(page.getByLabel('特别要求')).toBeHidden();
|
||||
await expect(page.getByRole('button', { name: '能力', exact: true })).toHaveAttribute('aria-current', 'page');
|
||||
await page.getByRole('button', { name: '选择工具', exact: true }).click();
|
||||
await expect(page.getByRole('checkbox', { name: /上网查资料.*在网上查找相关信息/ })).toBeVisible();
|
||||
await page.getByRole('button', { name: '选择技能', exact: true }).click();
|
||||
await page.getByLabel('搜索技能', { exact: true }).fill('出处');
|
||||
await expect(page.getByRole('checkbox', { name: /查资料,做研究.*出处/ })).toBeVisible();
|
||||
await advancedTab.click();
|
||||
await expect(advancedTab).toHaveAttribute('aria-selected', 'true');
|
||||
await page.screenshot({ path: testInfo.outputPath('cloud-agent-advanced-tab.png') });
|
||||
|
||||
@@ -35,7 +35,7 @@ test('personal chat displays thinking, tools and Markdown, then restores them af
|
||||
id: 1, message_id: 'answer', role: 'assistant', run_id: run.agent_run_id, request_id: run.request_id, created_at: '',
|
||||
content: '## 整理结果\n\n| 项目 | 状态 |\n| --- | --- |\n| 资料 | 已核对 |\n\n**可以使用**',
|
||||
reasoning_content: '先核对来源,再整理结果。',
|
||||
tool_calls: [{ id: 'lookup', name: '资料检索', args: { query: '实际检索资料' }, status: 'success', tool_call_result: { content: '找到两条资料' } }],
|
||||
tool_calls: [{ id: 'lookup', name: 'web_search', display_name: '上网查资料', display_description: '在网上查找相关信息。', args: { query: '实际检索资料' }, status: 'success', tool_call_result: { content: '找到两条资料' } }],
|
||||
}] : [] });
|
||||
if (body.operation === 'run') return result({ ...run, status: complete ? 'completed' : 'running' });
|
||||
if (body.operation === 'viewed') return result({});
|
||||
@@ -71,7 +71,7 @@ test('personal chat displays thinking, tools and Markdown, then restores them af
|
||||
const process = page.getByTestId('cloud-message-process');
|
||||
await expect(page.getByLabel('智能体思考过程')).toBeVisible();
|
||||
await emit([
|
||||
{ stream_event: { type: 'tool_call', message_id: 'answer', tool_call_id: 'lookup', name: '资料检索', args: { query: '测试资料' } } },
|
||||
{ stream_event: { type: 'tool_call', message_id: 'answer', tool_call_id: 'lookup', name: 'web_search', display_name: '上网查资料', display_description: '在网上查找相关信息。', args: { query: '测试资料' } } },
|
||||
{ event: { method: 'tools', data: { event: 'tool-started', tool_call_id: 'lookup', input: { query: '实际检索资料' } } } },
|
||||
{ event: { method: 'tools', data: { event: 'tool-finished', tool_call_id: 'lookup', output: { content: '找到两条资料' } } } },
|
||||
{ stream_event: { type: 'message_delta', message_id: 'answer', content: '## 整理结果\n\n| 项目 | 状态 |\n| --- | --- |\n| 资料 | 已核对 |\n\n**可以使用**' } },
|
||||
@@ -79,8 +79,10 @@ test('personal chat displays thinking, tools and Markdown, then restores them af
|
||||
await expect(page.getByRole('heading', { name: '整理结果' })).toBeVisible();
|
||||
await expect(page.getByRole('table')).toBeVisible();
|
||||
await process.locator(':scope > summary').click();
|
||||
await process.getByText('资料检索 · 已完成', { exact: true }).click();
|
||||
await process.getByText('上网查资料 · 已完成', { exact: true }).click();
|
||||
await expect(process.getByText('找到两条资料', { exact: true })).toBeVisible();
|
||||
await expect(process.getByText('在网上查找相关信息。', { exact: true })).toBeVisible();
|
||||
await expect(process.getByText('工具标识:web_search', { exact: true })).toBeVisible();
|
||||
await expect(process.getByText('"实际检索资料"', { exact: false })).toBeVisible();
|
||||
await page.screenshot({ path: testInfo.outputPath('personal-chat-process.png') });
|
||||
await app.evaluate(() => (globalThis as unknown as { finishRenderRun: () => void }).finishRenderRun());
|
||||
@@ -91,7 +93,9 @@ test('personal chat displays thinking, tools and Markdown, then restores them af
|
||||
await expect(page.getByRole('heading', { name: '整理结果' })).toBeVisible();
|
||||
await page.getByTestId('cloud-message-process').locator(':scope > summary').click();
|
||||
await expect(page.getByLabel('智能体思考过程')).toHaveText('先核对来源,再整理结果。');
|
||||
await expect(page.getByText('资料检索 · 已完成', { exact: true })).toBeVisible();
|
||||
await page.getByText('上网查资料 · 已完成', { exact: true }).click();
|
||||
await expect(page.getByText('在网上查找相关信息。', { exact: true })).toBeVisible();
|
||||
await expect(page.getByText('工具标识:web_search', { exact: true })).toBeVisible();
|
||||
await page.screenshot({ path: testInfo.outputPath('personal-chat-reopened.png') });
|
||||
} finally { await closeElectronApp(app); }
|
||||
});
|
||||
@@ -48,9 +48,11 @@ describe('Main cloud Agents boundary', () => {
|
||||
it('projects saved reasoning and tool results for both personal and channel history without raw metadata', () => {
|
||||
const message = { id: 1, role: 'assistant', content: 'answer', reasoning_content: 'thought', message_id: 'model-1',
|
||||
extra_metadata: { internal: true }, tool_calls: [{ id: 'call-1', name: 'search', args: { query: 'topic' },
|
||||
display_name: '上网查资料', display_description: '在网上查找相关信息。',
|
||||
status: 'success', internal: 'hidden', tool_call_result: { content: 'result', secret: 'hidden' } }] };
|
||||
const expected = { id: 1, role: 'assistant', content: 'answer', reasoning_content: 'thought', message_id: 'model-1',
|
||||
tool_calls: [{ id: 'call-1', name: 'search', args: { query: 'topic' }, status: 'success', tool_call_result: { content: 'result' } }] };
|
||||
tool_calls: [{ id: 'call-1', name: 'search', display_name: '上网查资料', display_description: '在网上查找相关信息。',
|
||||
args: { query: 'topic' }, status: 'success', tool_call_result: { content: 'result' } }] };
|
||||
for (const input of [
|
||||
{ operation: 'history', input: { thread_id: 'thread-1' } },
|
||||
{ operation: 'channelConversation', input: { session_id: 'session-1' } },
|
||||
|
||||
@@ -52,7 +52,7 @@ it('keeps one child creation intent after a lost response and waits for Skill in
|
||||
await waitFor(() => expect(screen.queryByLabelText('子智能体名称')).not.toBeInTheDocument());
|
||||
const calls = api.call.mock.calls.filter(call => call[0] === 'createChild');
|
||||
expect(calls).toHaveLength(2); expect(calls[0][1]).toEqual(calls[1][1]);
|
||||
fireEvent.click(screen.getByRole('button', { name: '上传 Skill' }));
|
||||
fireEvent.click(screen.getByRole('button', { name: '上传技能' }));
|
||||
const confirm = await screen.findByRole('button', { name: '确认安装到个人能力' });
|
||||
expect(api.call.mock.calls.some(call => call[0] === 'confirmSkill')).toBe(false);
|
||||
fireEvent.click(confirm);
|
||||
|
||||
@@ -547,7 +547,10 @@ it('searches capabilities while retaining existing selections outside the result
|
||||
api.list.mockResolvedValue({ agents: [configured], next_cursor: null });
|
||||
const base = api.call.getMockImplementation()!;
|
||||
api.call.mockImplementation(async (operation, input) => operation === 'catalog' ? {
|
||||
models: [{ id: 'test-model', name: '写作模型' }], resources: { tools: [{ key: 'search', name: '资料搜索', description: '搜索素材' }, { key: 'clock', name: '当前时间' }] }, pricing: null,
|
||||
models: [{ id: 'test-model', name: '写作模型' }], resources: {
|
||||
tools: [{ key: 'web_search', name: '上网查资料', description: '在网上查找相关信息。' }, { key: 'clock', name: '当前时间' }],
|
||||
skills: [{ key: 'deep-research', name: '查资料,做研究', description: '比较不同说法,再整理出结论和出处。' }],
|
||||
}, pricing: null,
|
||||
} : base(operation, input));
|
||||
api.save.mockImplementation(async (_slug, input) => ({ ...configured, ...input, draft_revision: 2 }));
|
||||
open();
|
||||
@@ -561,9 +564,15 @@ it('searches capabilities while retaining existing selections outside the result
|
||||
fireEvent.mouseDown(screen.getByRole('tab', { name: '高级设置' }), { button: 0, ctrlKey: false });
|
||||
expect(screen.getByLabelText('搜索工具')).toHaveValue('资料');
|
||||
expect(screen.queryByRole('checkbox', { name: '当前时间' })).not.toBeInTheDocument();
|
||||
fireEvent.click(screen.getByRole('checkbox', { name: /资料搜索/ }));
|
||||
fireEvent.click(screen.getByRole('checkbox', { name: /上网查资料/ }));
|
||||
fireEvent.click(screen.getByRole('button', { name: '完成选择' }));
|
||||
expect(screen.getByRole('checkbox', { name: /missing-tool/ })).toBeChecked();
|
||||
fireEvent.click(screen.getByRole('button', { name: '选择技能', exact: true }));
|
||||
fireEvent.change(screen.getByLabelText('搜索技能'), { target: { value: '出处' } });
|
||||
fireEvent.click(screen.getByRole('checkbox', { name: /查资料,做研究/ }));
|
||||
fireEvent.click(screen.getByRole('checkbox', { name: '开始对话前,先读好已选技能的使用方法' }));
|
||||
fireEvent.click(screen.getByRole('button', { name: '保存草稿' }));
|
||||
await waitFor(() => expect(api.save).toHaveBeenCalledWith(draft.slug, expect.objectContaining({ configuration: expect.objectContaining({ tools: ['missing-tool', 'search'] }) })));
|
||||
await waitFor(() => expect(api.save).toHaveBeenCalledWith(draft.slug, expect.objectContaining({
|
||||
configuration: expect.objectContaining({ tools: ['missing-tool', 'web_search'], skills: ['deep-research'], preload_skills: ['deep-research'] }),
|
||||
})));
|
||||
});
|
||||
@@ -74,14 +74,17 @@ it('associates tool arguments and results by call identity, keeps failures visib
|
||||
render(<CloudChat slug="agent" />);
|
||||
await waitFor(() => expect(api.events).toHaveBeenCalled());
|
||||
await emit([
|
||||
{ stream_event: { type: 'tool_call_delta', message_id: 'm', tool_call_id: 'search', name: '查资料', args_delta: '{"query":', index: 0 } },
|
||||
{ stream_event: { type: 'tool_call_delta', message_id: 'm', tool_call_id: 'search', name: 'web_search',
|
||||
display_name: '上网查资料', display_description: '在网上查找相关信息。', args_delta: '{"query":', index: 0 } },
|
||||
{ stream_event: { type: 'tool_call_delta', message_id: 'm', args_delta: '"天气"}', index: 0 } },
|
||||
{ stream_event: { type: 'tool_call', message_id: 'm', tool_call_id: 'write', name: '写文件', args: { path: '/a' }, index: 1 } },
|
||||
{ event: { method: 'tools', data: { event: 'tool-finished', tool_call_id: 'write', output: { content: '磁盘不足', status: 'error' } } } },
|
||||
{ event: { method: 'tools', data: { event: 'tool-finished', tool_call_id: 'search', output: { content: '晴天', status: 'success' } } } },
|
||||
], '101-0');
|
||||
const process = screen.getByTestId('cloud-message-process');
|
||||
expect(process).toHaveTextContent('查资料 · 已完成');
|
||||
expect(process).toHaveTextContent('上网查资料 · 已完成');
|
||||
expect(process).toHaveTextContent('在网上查找相关信息。');
|
||||
expect(process).toHaveTextContent('工具标识:web_search');
|
||||
expect(process).toHaveTextContent('写文件 · 失败');
|
||||
expect(within(process).getByText('{"query":"天气"}')).toBeInTheDocument();
|
||||
expect(within(process).getByText('晴天')).toBeInTheDocument();
|
||||
|
||||
Reference in new issue
Block a user