fix: 修复设计 Agent 慢响应超时

问题:客户端每 250ms 轮询 Run,并在 120 秒固定超时,导致服务端日志刷屏且慢响应被提前判定失败。

修复:将轮询改为 1 秒起步、最高 5 秒的指数退避,并将等待窗口调整为 10 分钟;新增 150 秒慢 Run 回归测试。
This commit is contained in:
2026-08-03 11:47:27 +08:00
parent f9b2616d14
commit 20c567fe5f
2 changed files with 59 additions and 3 deletions

View File

@@ -210,6 +210,59 @@ describe('Works Square AI design adapter', () => {
);
});
it('waits for a slow design run without flooding the run endpoint', async () => {
vi.useFakeTimers();
vi.setSystemTime(new Date('2026-08-03T02:00:00Z'));
const startedAt = Date.now();
let runPolls = 0;
const fetchMock = vi.fn<typeof fetch>(async (input, init) => {
const url = String(input);
if (url.endsWith('/api/agents/sessions')) {
return jsonResponse({ session_id: 'session-slow', status: 'active' }, 201);
}
if (url.endsWith('/api/agents/sessions/session-slow/commands')) {
return jsonResponse({ run_id: 'run-slow', status: 'queued', error: null }, 202);
}
if (url.endsWith('/api/agents/sessions/session-slow/runs/run-slow')) {
runPolls += 1;
return jsonResponse({
run_id: 'run-slow',
status: Date.now() - startedAt >= 150_000 ? 'succeeded' : 'running',
error: null,
});
}
if (url.endsWith('/api/design/workspaces/workspace-one')) {
return jsonResponse(serverWorkspace);
}
throw new Error(`Unexpected request: ${url} ${init?.method ?? 'GET'}`);
});
const adapter = new WorksSquareDesignWorkspace({
apiBaseUrl: 'https://square.example',
fetchImpl: fetchMock,
});
try {
const outcomePromise = adapter.submitMessage({
workspaceId: 'workspace-one',
clientTurnId: 'turn-slow',
expectedTurnRevision: 1,
message: '整理一个复杂的品牌设计方向',
}).then(
(value) => ({ value, error: null }),
(error: unknown) => ({ value: null, error }),
);
await vi.advanceTimersByTimeAsync(160_000);
const outcome = await outcomePromise;
expect(outcome.error).toBeNull();
expect(outcome.value).toMatchObject({ workspaceId: 'workspace-one' });
expect(runPolls).toBeLessThanOrEqual(40);
} finally {
vi.useRealTimers();
}
});
it('maps an invalid Runtime command to a user input error', async () => {
const fetchMock = vi.fn<typeof fetch>()
.mockResolvedValueOnce(jsonResponse({