fix: stabilize ai design history switching
This commit is contained in:
@@ -464,6 +464,41 @@ describe('Works Square AI design adapter', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('passes the opaque older-history cursor through and preserves server message ids', async () => {
|
||||
const pagedConversation = {
|
||||
...serverConversation,
|
||||
messages: [{
|
||||
...serverConversation.messages[0],
|
||||
message_id: 'persisted-turn-one:assistant',
|
||||
}],
|
||||
message_page: {
|
||||
has_older: true,
|
||||
next_before: 'opaque-older-page',
|
||||
},
|
||||
};
|
||||
const fetchMock = vi.fn<typeof fetch>().mockResolvedValue(jsonResponse(pagedConversation));
|
||||
const adapter = new WorksSquareDesignWorkspace({
|
||||
apiBaseUrl: 'https://square.example',
|
||||
fetchImpl: fetchMock,
|
||||
});
|
||||
|
||||
const result = await adapter.getConversation(
|
||||
'workspace-one',
|
||||
'conversation-one',
|
||||
'opaque-older-page',
|
||||
);
|
||||
|
||||
expect(fetchMock).toHaveBeenCalledWith(
|
||||
'https://square.example/api/design/workspaces/workspace-one/conversations/conversation-one?before=opaque-older-page',
|
||||
expect.objectContaining({ headers: expect.any(Object) }),
|
||||
);
|
||||
expect(result.messages[0]?.id).toBe('persisted-turn-one:assistant');
|
||||
expect(result.messagePage).toEqual({
|
||||
hasOlder: true,
|
||||
nextBefore: 'opaque-older-page',
|
||||
});
|
||||
});
|
||||
|
||||
it('normalizes a missing Brief medium to null and rejects invalid non-null values', async () => {
|
||||
const { medium: _medium, ...legacyBrief } = serverConversation.brief;
|
||||
const legacyConversation = {
|
||||
@@ -1148,6 +1183,46 @@ describe('Works Square AI design adapter', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('fails a WebSocket event stream that never opens instead of leaving it pending', async () => {
|
||||
vi.useFakeTimers();
|
||||
const { sockets, webSocketFactory } = scriptedSockets([{ open: false }]);
|
||||
const fetchMock = vi.fn<typeof fetch>(async (input) => {
|
||||
const url = String(input);
|
||||
if (url.endsWith('/conversations/conversation-one')) {
|
||||
return jsonResponse({ ...serverConversation, agent_session_id: 'session-open-timeout' });
|
||||
}
|
||||
if (url.endsWith('/stream-tickets')) {
|
||||
return jsonResponse({
|
||||
stream_url: '/api/agents/sessions/session-open-timeout/ws?ticket=ticket-open-timeout',
|
||||
});
|
||||
}
|
||||
throw new Error(`Unexpected request: ${url}`);
|
||||
});
|
||||
const adapter = new WorksSquareDesignWorkspace({
|
||||
apiBaseUrl: 'https://square.example',
|
||||
fetchImpl: fetchMock,
|
||||
webSocketFactory,
|
||||
});
|
||||
|
||||
try {
|
||||
const opening = adapter.openWorkspaceEvents({
|
||||
workspaceId: 'workspace-one',
|
||||
conversationId: 'conversation-one',
|
||||
});
|
||||
const openingAssertion = expect(opening).rejects.toMatchObject({
|
||||
status: 504,
|
||||
code: 'DESIGN_EVENT_STREAM_TIMEOUT',
|
||||
});
|
||||
await vi.advanceTimersByTimeAsync(10_000);
|
||||
|
||||
await openingAssertion;
|
||||
expect(sockets).toHaveLength(1);
|
||||
expect(sockets[0].readyState).toBe(3);
|
||||
} finally {
|
||||
vi.useRealTimers();
|
||||
}
|
||||
});
|
||||
|
||||
it('maps a failed Run received from the connected WebSocket without polling', async () => {
|
||||
const { webSocketFactory } = scriptedSockets([{
|
||||
open: true,
|
||||
|
||||
Reference in New Issue
Block a user