mirror of
https://github.com/davidkaya/aryx.git
synced 2026-07-24 05:28:46 +02:00
Remove the entire patterns domain model, IPC channels, sidecar services, renderer components, and tests. Sessions now bind exclusively to workflows via workflowId. Builtin workflows replace builtin patterns. Backend: - Make AgentNodeConfig standalone (no longer extends PatternAgentDefinition) - Add WorkflowOrchestrationMode and WorkflowExecutionDefinition - Create builtin workflows (single-agent, sequential, concurrent, handoff, group-chat) - Rewrite session model config helpers for workflow-only - Remove pattern IPC channels, handlers, and preload bindings - Merge createSession/createWorkflowSession into single method - Remove sidecar PatternGraphResolver, PatternValidator, pattern DTOs - Add workspace migration for legacy sessions (patternId -> workflowId) Frontend: - Delete PatternEditor, pattern-graph components, patternGraph lib - Delete NewSessionModal (session creation uses workflows directly) - Remove PatternsSection from SettingsPanel - Update App.tsx, ChatPane, ActivityPanel, Sidebar, RunTimeline, AgentConfigFields, InlinePills, sessionActivity to use workflow types - Delete pattern.ts domain module 78 files changed across backend and frontend. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
144 lines
4.1 KiB
TypeScript
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',
|
|
workflowId: '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])).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])).toBe('default');
|
|
expect(getAssistantMessagePhase(session, session.messages[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])).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])).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])).toBe('default');
|
|
expect(getAssistantMessagePhase(session, session.messages[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])).toBe('default');
|
|
expect(getAssistantMessagePhase(session, session.messages[1])).toBe('default');
|
|
expect(getAssistantMessagePhase(session, session.messages[2])).toBe('final');
|
|
});
|
|
});
|