fix: preserve staged Agent configuration update

This commit is contained in:
鲨鱼辣椒 committed 2026-10-13 17:32:31 +08:00
1 parent 5a8b8d75e5
commit 2b2f7b96b0
6 files changed
+67 -6

No files matched your search

+4 -2
View File
@@ -30,7 +30,7 @@ test('personal cloud Agent identity, configuration and separate published chat i
const knowledgeFile = { file_id: 'document', name: '本体(Ontology)学习路线图.pdf', size: 34000, error: null };
let limits: { request_limit_points: string | null; daily_limit_points: string | null } = { request_limit_points: null, daily_limit_points: null };
const jobs: Record<string, unknown>[] = [];
const configuration = { model: '', tools: [], knowledges: [], mcps: [], skills: [], preload_skills: [], subagents: [], tool_approval_mode: 'default', max_execution_steps: 40, max_output_tokens: 4096, max_run_seconds: 600 };
const configuration = { model: '', tools: [], knowledges: [], mcps: [], skills: [], preload_skills: [], subagents: ['historical-child'], tool_approval_mode: 'default', max_execution_steps: 40, max_output_tokens: 4096, max_run_seconds: 600 };
const result = (json: unknown) => ({ ok: true, data: { status: 200, ok: true, json } });
ipcMain.removeHandler('hostapi:fetch');
ipcMain.handle('hostapi:fetch', async (_event, request: { path?: string; method?: string; body?: string }) => {
@@ -244,6 +244,8 @@ test('personal cloud Agent identity, configuration and separate published chat i
await expect(page.getByText('给它一本手册,照着方法做。', { exact: true })).toHaveCount(0);
await expect(page.getByText('管理我的云端能力', { exact: true })).toHaveCount(0);
await expect(page.getByText('未选择的资源不会开放给此智能体。通过微信或 API 使用时也遵循本配置。', { exact: true })).toHaveCount(0);
await expect(page.getByRole('group', { name: '子智能体', exact: true })).toHaveCount(0);
await expect(page.getByRole('button', { name: '选择子智能体', exact: true })).toHaveCount(0);
await expect(page.getByRole('group', { name: /^知识库/ })).toBeVisible();
await expect(page.getByRole('heading', { name: '费用上限', exact: true })).toHaveCount(0);
await expect(page.getByRole('heading', { name: '运行限制', exact: true })).toHaveCount(0);
@@ -263,7 +265,7 @@ test('personal cloud Agent identity, configuration and separate published chat i
await expect(prompt).toHaveValue(initialPrompt);
await page.getByRole('button', { name: '保存草稿', exact: true }).click();
await expect(page.getByRole('button', { name: '已保存', exact: true })).toBeDisabled();
expect((await fixtureState()).draft).toMatchObject({ purpose: '一起梳理故事和文章', system_prompt: initialPrompt, configuration: { model: 'reasoning-model', tools: ['fixture-tool'] } });
expect((await fixtureState()).draft).toMatchObject({ purpose: '一起梳理故事和文章', system_prompt: initialPrompt, configuration: { model: 'reasoning-model', tools: ['fixture-tool'], subagents: ['historical-child'] } });
await editor.getByRole('button', { name: '我的智能体', exact: true }).click();
const card = page.getByRole('article', { name: '我的写作搭档', exact: true });
await expect(card.getByText('一起梳理故事和文章', { exact: true })).toBeVisible();
@@ -0,0 +1,52 @@
import { useState } from 'react';
import { cleanup, fireEvent, render, screen, within } from '@testing-library/react';
import { afterEach, expect, it, vi } from 'vitest';
import { ConfigurationFields } from '@/pages/CloudAgents/ConfigurationFields';
import { EMPTY_CLOUD_CONFIGURATION, type CloudAgentConfiguration } from '../../shared/cloud-agents';
const api = vi.hoisted(() => ({ call: vi.fn() }));
vi.mock('@/lib/cloud-agents-api', () => ({ cloudAgentsApi: api }));
afterEach(() => { cleanup(); vi.resetAllMocks(); });
it('removes subagent selection while other capability edits preserve historical bindings', async () => {
api.call.mockImplementation(async operation => {
if (operation === 'catalog') return {
models: [{ id: 'old-model', name: '原模型' }, { id: 'new-model', name: '新模型' }],
resources: {
tools: [{ key: 'tool', name: '查询工具' }], skills: [{ key: 'skill', name: '研究手册' }],
mcps: [{ key: 'mcp', name: '资料连接' }], knowledges: [{ key: 'kb', name: '已有资料' }],
subagents: [{ key: 'historical-child', name: '调研探索员' }],
},
};
if (operation === 'knowledge') return { databases: [], models: [] };
throw new Error('Unexpected operation ' + operation);
});
const initial: CloudAgentConfiguration = {
...EMPTY_CLOUD_CONFIGURATION, model: 'old-model', subagents: ['historical-child', 'missing-child'],
max_execution_steps: 30, max_output_tokens: 2048, max_run_seconds: 300,
};
const changed = vi.fn();
function Harness() {
const [value, setValue] = useState(initial);
return <ConfigurationFields slug={'ml-' + 'a'.repeat(32)} value={value} disabled={false}
onChange={next => { changed(next); setValue(next); }} />;
}
render(<Harness />);
await screen.findByRole('option', { name: '新模型' });
expect(screen.queryByRole('group', { name: '子智能体', exact: true })).not.toBeInTheDocument();
expect(screen.queryByRole('button', { name: '选择子智能体', exact: true })).not.toBeInTheDocument();
expect(screen.queryByText('调研探索员')).not.toBeInTheDocument();
expect(screen.queryByText(/missing-child/)).not.toBeInTheDocument();
expect(changed).not.toHaveBeenCalled();
fireEvent.change(screen.getByRole('combobox', { name: '模型' }), { target: { value: 'new-model' } });
for (const [button, checkbox] of [['选择工具箱', '查询工具'], ['选择做事手册', '研究手册'], ['选择MCP 服务', '资料连接']]) {
fireEvent.click(screen.getByRole('button', { name: button, exact: true }));
fireEvent.click(screen.getByRole('checkbox', { name: checkbox, exact: true }));
}
await within(screen.getByRole('combobox', { name: '选择知识库' })).findByRole('option', { name: '已有资料' });
fireEvent.change(screen.getByRole('combobox', { name: '选择知识库' }), { target: { value: 'kb' } });
expect(changed).toHaveBeenLastCalledWith({
...initial, model: 'new-model', tools: ['tool'], skills: ['skill'], mcps: ['mcp'], knowledges: ['kb'],
});
expect(api.call.mock.calls.every(([operation]) => ['catalog', 'knowledge'].includes(operation))).toBe(true);
});