Files
aryx/tests/renderer/messagePhase.test.ts
T
David KayaandCopilot deb5c96d58 feat: render thinking process UI for intermediate agent messages
Wire message-reclassified sidecar events through the main process to
the renderer, where reclassified messages are filtered out of the main
transcript and collected into a collapsible ThinkingProcess component.

Main process changes:
- Route message-reclassified via dedicated onMessageReclassified callback
- Add applyMessageReclassified handler that sets messageKind and emits
  the session event for the renderer
- Forward assistant-intent and reasoning-delta as turn-scoped events

Renderer changes:
- Split session.messages into visibleMessages and thinkingMessages
- Render ThinkingProcess above the last assistant message
- ThinkingProcess auto-expands during active turns, collapses on finish
- Update messagePhase to skip thinking-kind messages for final detection

Tests:
- 3 new sessionWorkspace tests for reclassification apply/dedup/ignore
- 2 new messagePhase tests for thinking-kind handling
- Updated runTurnPending test fixtures for new callback

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-30 16:16:37 +01:00

144 lines
4.1 KiB
TypeScript

import { describe, expect, test } from 'bun:test';
import { getAssistantMessagePhase } from '@renderer/lib/messagePhase';
import type { SessionRecord } from '@shared/domain/session';
function createSession(
messages: SessionRecord['messages'],
status: SessionRecord['status'] = 'idle',
): SessionRecord {
return {
id: 'session-1',
projectId: 'project-1',
patternId: 'pattern-1',
title: 'Test session',
createdAt: '2026-03-23T00:00:00.000Z',
updatedAt: '2026-03-23T00:00:00.000Z',
status,
messages,
runs: [],
};
}
describe('assistant message phase', () => {
test('marks pending assistant messages as thinking', () => {
const session = createSession([
{
id: 'msg-1',
role: 'assistant',
authorName: 'Triage',
content: 'Draft',
createdAt: '2026-03-23T00:00:00.000Z',
pending: true,
},
], 'running');
expect(getAssistantMessagePhase(session, session.messages[0], 0)).toBe('thinking');
});
test('marks the last completed assistant message as final when the session is idle', () => {
const session = createSession([
{
id: 'msg-1',
role: 'assistant',
authorName: 'Triage',
content: 'Earlier',
createdAt: '2026-03-23T00:00:00.000Z',
},
{
id: 'msg-2',
role: 'assistant',
authorName: 'UX Specialist',
content: 'Final answer',
createdAt: '2026-03-23T00:00:01.000Z',
},
]);
expect(getAssistantMessagePhase(session, session.messages[0], 0)).toBe('default');
expect(getAssistantMessagePhase(session, session.messages[1], 1)).toBe('final');
});
test('does not mark completed assistant messages as final while the session is still running', () => {
const session = createSession([
{
id: 'msg-1',
role: 'assistant',
authorName: 'Triage',
content: 'In progress',
createdAt: '2026-03-23T00:00:00.000Z',
},
], 'running');
expect(getAssistantMessagePhase(session, session.messages[0], 0)).toBe('default');
});
test('ignores non-assistant messages', () => {
const session = createSession([
{
id: 'msg-1',
role: 'user',
authorName: 'You',
content: 'Hello',
createdAt: '2026-03-23T00:00:00.000Z',
},
]);
expect(getAssistantMessagePhase(session, session.messages[0], 0)).toBe('default');
});
test('returns default for thinking-kind messages regardless of other state', () => {
const session = createSession([
{
id: 'msg-1',
role: 'assistant',
authorName: 'Primary Agent',
content: 'Let me search...',
createdAt: '2026-03-23T00:00:00.000Z',
messageKind: 'thinking',
},
{
id: 'msg-2',
role: 'assistant',
authorName: 'Primary Agent',
content: 'Here is the result.',
createdAt: '2026-03-23T00:00:01.000Z',
},
]);
expect(getAssistantMessagePhase(session, session.messages[0], 0)).toBe('default');
expect(getAssistantMessagePhase(session, session.messages[1], 1)).toBe('final');
});
test('skips thinking messages when determining the last completed assistant', () => {
const session = createSession([
{
id: 'msg-1',
role: 'assistant',
authorName: 'Primary Agent',
content: 'Let me search...',
createdAt: '2026-03-23T00:00:00.000Z',
messageKind: 'thinking',
},
{
id: 'msg-2',
role: 'assistant',
authorName: 'Primary Agent',
content: 'More searching...',
createdAt: '2026-03-23T00:00:01.000Z',
messageKind: 'thinking',
},
{
id: 'msg-3',
role: 'assistant',
authorName: 'Primary Agent',
content: 'Final answer.',
createdAt: '2026-03-23T00:00:02.000Z',
},
]);
expect(getAssistantMessagePhase(session, session.messages[0], 0)).toBe('default');
expect(getAssistantMessagePhase(session, session.messages[1], 1)).toBe('default');
expect(getAssistantMessagePhase(session, session.messages[2], 2)).toBe('final');
});
});