feat: 对接设计 Agent Gateway WebSocket
需求:服务端统一 Agent Gateway 将设计任务状态流切换为 WebSocket,客户端需要实时展示生成任务并支持断线恢复。 实现:Electron Main 管理 Session、一次性 Ticket、WebSocket 心跳与游标续传,按关闭码回收会话;Renderer 继续通过本机 Host API 的 SSE 投影接收任务事件,并保留 REST 降级同步。 验证:typecheck、变更文件 ESLint、37 个聚焦测试及 build:vite 通过。
This commit is contained in:
@@ -215,4 +215,60 @@ describe('AI design Main route boundary', () => {
|
||||
expect(response.headers.get('content-range')).toBe('bytes 0-6/100');
|
||||
expect(Buffer.concat(response.chunks).toString()).toBe('partial');
|
||||
});
|
||||
|
||||
it('relays normalized task events over local SSE and forwards the opaque resume cursor', async () => {
|
||||
const close = vi.fn();
|
||||
const openWorkspaceEvents = vi.fn().mockResolvedValue({
|
||||
events: (async function* () {
|
||||
yield {
|
||||
id: 'session-one:7',
|
||||
type: 'design.generation_task.updated' as const,
|
||||
workspaceId: 'workspace/one',
|
||||
workspaceViewRevision: 8,
|
||||
generationTask: {
|
||||
taskId: 'task-live',
|
||||
workspaceId: 'workspace/one',
|
||||
medium: 'image' as const,
|
||||
status: 'succeeded' as const,
|
||||
briefVersion: 1,
|
||||
briefSummary: '海洋公益海报',
|
||||
quoteId: 'quote-live',
|
||||
quotedDesignPoints: 1,
|
||||
failureCode: null,
|
||||
resultAssets: [],
|
||||
createdAt: '2026-08-02T10:00:00Z',
|
||||
updatedAt: '2026-08-02T10:02:00Z',
|
||||
},
|
||||
};
|
||||
})(),
|
||||
close,
|
||||
});
|
||||
const request = createRequest('GET');
|
||||
request.headers = { 'last-event-id': 'session-one:6' };
|
||||
const response = new MediaResponse();
|
||||
|
||||
const handled = await handleImageWorkspaceRoutes(
|
||||
request,
|
||||
response as unknown as ServerResponse,
|
||||
new URL(
|
||||
'http://127.0.0.1/api/works/image-workspace/workspaces/workspace%2Fone/events',
|
||||
),
|
||||
{ imageWorkspace: { openWorkspaceEvents } } as unknown as HostApiContext,
|
||||
);
|
||||
|
||||
expect(handled).toBe(true);
|
||||
expect(openWorkspaceEvents).toHaveBeenCalledWith({
|
||||
workspaceId: 'workspace/one',
|
||||
afterEventId: 'session-one:6',
|
||||
});
|
||||
expect(response.statusCode).toBe(200);
|
||||
expect(response.headers.get('content-type')).toBe('text/event-stream; charset=utf-8');
|
||||
expect(response.headers.get('x-accel-buffering')).toBe('no');
|
||||
expect(Buffer.concat(response.chunks).toString()).toContain([
|
||||
'id: session-one:7',
|
||||
'event: design.generation_task.updated',
|
||||
'data: {"id":"session-one:7"',
|
||||
].join('\n'));
|
||||
expect(close).toHaveBeenCalledOnce();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user