feat: 按机器人选择 Agent Preset

在九个渠道的设置页卡片上选择 Host 已有预设;未选则跟随默认,只影响之后新建的会话。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
iamyaojie 2026-08-21 19:19:45 +08:00
parent c3b3a29f27
commit 3161816cc4
51 changed files with 2227 additions and 740 deletions

View file

@ -24,6 +24,7 @@ test('client exposes the fixed DingTalk RPC channel and endpoint names', () => {
reconnectBot: 'bot.reconnect',
deleteBot: 'bot.delete',
setWorkspace: 'bot.workspace.set',
setAgentPreset: 'bot.preset.set',
});
});

View file

@ -456,3 +456,59 @@ test('unmount does not cancel a Host provisioning task that already started', as
);
assert.equal(clock.frames.size, 0);
});
test('DingTalk settings save an Agent Preset through bot.preset.set', async (t) => {
const clock = createBrowserClock();
t.after(() => clock.restore());
const bot = {
botId: 'dt_test',
connected: true,
state: 'connected',
workspace: '/workspace/current',
bot: { name: '钉钉机器人', clientIdMasked: 'ding••••test' },
health: { status: 'healthy', summary: '连接正常', lastCheckedAt: Date.now() },
};
const catalog = {
defaultId: 'default',
items: [
{ id: 'coding', label: 'Coding' },
{ id: 'default', label: 'Default' },
],
};
const calls = [];
const rpcCall = async (endpoint, payload) => {
calls.push({ endpoint, payload });
if (endpoint === DINGTALK_ENDPOINTS.status) {
return ok(snapshot({
state: 'connected',
bots: [bot],
agentPresetCatalog: catalog,
}));
}
if (endpoint === DINGTALK_ENDPOINTS.setAgentPreset) {
return ok(snapshot({
state: 'connected',
bots: [{ ...bot, agentPreset: payload.agentPreset }],
agentPresetCatalog: catalog,
}));
}
throw new Error(`unexpected endpoint: ${endpoint}`);
};
let renderer;
await act(async () => {
renderer = create(React.createElement(DingtalkSettingsTab, { rpcCall }));
await flushMicrotasks();
});
await act(async () => {
renderer.root.findByProps({ className: 'dim-presetSelect' })
.props.onChange({ target: { value: 'coding' } });
await flushMicrotasks();
});
assert.deepEqual(
calls.find((call) => call.endpoint === DINGTALK_ENDPOINTS.setAgentPreset)?.payload,
{ botId: 'dt_test', agentPreset: 'coding' },
);
act(() => renderer.unmount());
});