fix(云智能体): 修复微信失败运行状态投影并提高默认执行步数
This commit is contained in:
@@ -155,6 +155,16 @@ describe('Main cloud Agents boundary', () => {
|
||||
expect(JSON.parse(fetchImpl.mock.calls[1][1].body)).toEqual({ request_id: 'request', thread_id: 'thread', query: 'hello' });
|
||||
});
|
||||
|
||||
it('defaults omitted execution steps to 300 while preserving an explicit saved limit', async () => {
|
||||
const { max_execution_steps: _omitted, ...configurationWithoutSteps } = EMPTY_CLOUD_CONFIGURATION;
|
||||
const fetchImpl = vi.fn().mockResolvedValueOnce(session())
|
||||
.mockResolvedValueOnce(json({ ...draft, configuration: { ...configurationWithoutSteps, max_execution_steps: 40 } }))
|
||||
.mockResolvedValueOnce(json({ ...draft, configuration: configurationWithoutSteps }));
|
||||
const module = moduleFor(fetchImpl);
|
||||
expect((await module.get(draft.slug)).configuration.max_execution_steps).toBe(40);
|
||||
expect((await module.get(draft.slug)).configuration.max_execution_steps).toBe(300);
|
||||
});
|
||||
|
||||
it('uses the WS credential directly for the creator ledger and never exchanges it into Renderer data', async () => {
|
||||
const fetchImpl = vi.fn().mockResolvedValueOnce(json({ unit: '词元点数', items: [], access_token: 'private' }));
|
||||
const result = await moduleFor(fetchImpl).execute({ operation: 'costs', input: { slug: draft.slug } });
|
||||
@@ -222,6 +232,21 @@ describe('Main cloud Agents boundary', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('preserves a failed channel run status, partial output, and authoritative error', () => {
|
||||
const plan = operationPlan({ operation: 'channelConversation', input: { session_id: 'session-1' } });
|
||||
expect(plan.project({
|
||||
session_id: 'session-1', thread_id: 'thread-1', messages: [], queued_requests: [], next_offset: null,
|
||||
run: { agent_run_id: 'run-1', request_id: 'request-1', thread_id: 'thread-1', agent_slug: draft.slug,
|
||||
status: 'failed', output: 'PPT 只写入了一部分。', version: '1',
|
||||
error: { type: 'execution_step_limit', message: '本次运行已达到执行步数上限,尚未完成。可在智能体设置中提高上限后重试。' } },
|
||||
})).toEqual({
|
||||
session_id: 'session-1', thread_id: 'thread-1', messages: [], queued_requests: [], next_offset: null,
|
||||
run: { agent_run_id: 'run-1', request_id: 'request-1', thread_id: 'thread-1', agent_slug: draft.slug,
|
||||
status: 'failed', output: 'PPT 只写入了一部分。', version: '1',
|
||||
error: { type: 'execution_step_limit', message: '本次运行已达到执行步数上限,尚未完成。可在智能体设置中提高上限后重试。' } },
|
||||
});
|
||||
});
|
||||
|
||||
it('routes user-level channel accounts without requiring an Agent slug', () => {
|
||||
const list = operationPlan({ operation: 'channelAccounts', input: {} });
|
||||
expect(list.path).toBe('/api/makelore/channel-accounts');
|
||||
|
||||
@@ -43,6 +43,40 @@ it('approves the actual action batch through the self-session endpoint and autom
|
||||
expect(api.call.mock.calls.some(call => ['resume', 'run', 'files', 'submit'].includes(call[0]))).toBe(false);
|
||||
});
|
||||
|
||||
it.each([
|
||||
['running', '运行中'],
|
||||
['completed', '已完成'],
|
||||
['cancelled', '已停止'],
|
||||
['interrupted', '等待你的确认'],
|
||||
] as const)('renders the authoritative %s WeChat run status', async (status, label) => {
|
||||
const base = api.call.getMockImplementation()!;
|
||||
api.call.mockImplementation(async (operation, input) => operation === 'channelConversation'
|
||||
? { ...history, run: { ...run, status } } : base(operation, input));
|
||||
render(<CloudChannelConversations slug={session.agent_slug} />);
|
||||
expect(await screen.findByTestId('wechat-run-status')).toHaveTextContent('任务状态:' + label);
|
||||
});
|
||||
|
||||
it('keeps partial assistant output visible while surfacing a closed run failure and its authoritative error', async () => {
|
||||
const base = api.call.getMockImplementation()!;
|
||||
api.call.mockImplementation(async (operation, input) => operation === 'channelConversation'
|
||||
? { ...history, session_state: 'closed', grant_state: 'revoked', run: { ...run, status: 'failed', error: {
|
||||
type: 'unexpected_error', message: 'Recursion limit of 40 reached',
|
||||
} }, messages: [{ id: 1, role: 'assistant', content: 'PPT 只写入了一部分。' }] } : base(operation, input));
|
||||
render(<CloudChannelConversations slug={session.agent_slug} />);
|
||||
const status = await screen.findByTestId('wechat-run-status');
|
||||
expect(status).toHaveTextContent('任务状态:失败');
|
||||
expect(screen.getByRole('alert', { name: '微信任务错误' })).toHaveTextContent('unexpected_error · Recursion limit of 40 reached');
|
||||
expect(screen.getByText('PPT 只写入了一部分。')).toBeVisible();
|
||||
});
|
||||
|
||||
it('shows a queued request status before the authoritative run is exposed', async () => {
|
||||
const base = api.call.getMockImplementation()!;
|
||||
api.call.mockImplementation(async (operation, input) => operation === 'channelConversation'
|
||||
? { ...history, run: null, queued_requests: [{ request_id: 'queued-request', thread_id: session.thread_id, run_id: null, status: 'running', version: '1' }] } : base(operation, input));
|
||||
render(<CloudChannelConversations slug={session.agent_slug} />);
|
||||
expect(await screen.findByTestId('wechat-run-status')).toHaveTextContent('任务状态:运行中');
|
||||
});
|
||||
|
||||
it('retries an uncertain stop with the identical operation ID and keeps other controls disabled', async () => {
|
||||
const base = api.call.getMockImplementation()!;
|
||||
let original: unknown;
|
||||
|
||||
Reference in New Issue
Block a user