mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-01-30 14:22:02 +00:00
Resolves merge conflicts: - apps/server/src/routes/terminal/common.ts: Keep randomBytes import, use @automaker/utils for createLogger - apps/ui/eslint.config.mjs: Use main's explicit globals list with XMLHttpRequest and MediaQueryListEvent additions - apps/ui/src/components/views/terminal-view.tsx: Keep our terminal improvements (killAllSessions, beforeunload, better error handling) - apps/ui/src/config/terminal-themes.ts: Keep our search highlight colors for all themes - apps/ui/src/store/app-store.ts: Keep our terminal settings persistence improvements (merge function) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
242 lines
8.1 KiB
TypeScript
242 lines
8.1 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import type { ConversationMessage } from '@automaker/types';
|
|
import {
|
|
extractTextFromContent,
|
|
normalizeContentBlocks,
|
|
formatHistoryAsText,
|
|
convertHistoryToMessages,
|
|
} from '../src/conversation-utils';
|
|
|
|
describe('conversation-utils.ts', () => {
|
|
describe('extractTextFromContent', () => {
|
|
it('should extract text from string content', () => {
|
|
const content = 'Hello, world!';
|
|
const result = extractTextFromContent(content);
|
|
expect(result).toBe('Hello, world!');
|
|
});
|
|
|
|
it('should extract text from array content with text blocks', () => {
|
|
const content = [
|
|
{ type: 'text', text: 'First block' },
|
|
{ type: 'text', text: 'Second block' },
|
|
];
|
|
const result = extractTextFromContent(content);
|
|
expect(result).toBe('First block\nSecond block');
|
|
});
|
|
|
|
it('should filter out non-text blocks', () => {
|
|
const content = [
|
|
{ type: 'text', text: 'Text block' },
|
|
{ type: 'image', source: { data: '...' } },
|
|
{ type: 'text', text: 'Another text' },
|
|
];
|
|
const result = extractTextFromContent(content);
|
|
expect(result).toBe('Text block\nAnother text');
|
|
});
|
|
|
|
it('should handle empty text blocks', () => {
|
|
const content = [
|
|
{ type: 'text', text: 'First' },
|
|
{ type: 'text' },
|
|
{ type: 'text', text: 'Third' },
|
|
];
|
|
const result = extractTextFromContent(content);
|
|
expect(result).toBe('First\n\nThird');
|
|
});
|
|
|
|
it('should return empty string for array with only non-text blocks', () => {
|
|
const content = [
|
|
{ type: 'image', source: {} },
|
|
{ type: 'tool_use', source: {} },
|
|
];
|
|
const result = extractTextFromContent(content);
|
|
expect(result).toBe('');
|
|
});
|
|
|
|
it('should return empty string for empty array', () => {
|
|
const content: Array<{ type: string; text?: string }> = [];
|
|
const result = extractTextFromContent(content);
|
|
expect(result).toBe('');
|
|
});
|
|
});
|
|
|
|
describe('normalizeContentBlocks', () => {
|
|
it('should convert string to array of text blocks', () => {
|
|
const content = 'Simple text';
|
|
const result = normalizeContentBlocks(content);
|
|
expect(result).toEqual([{ type: 'text', text: 'Simple text' }]);
|
|
});
|
|
|
|
it('should return array as-is', () => {
|
|
const content = [
|
|
{ type: 'text', text: 'First' },
|
|
{ type: 'image', source: {} },
|
|
];
|
|
const result = normalizeContentBlocks(content);
|
|
expect(result).toBe(content);
|
|
expect(result).toEqual(content);
|
|
});
|
|
|
|
it('should handle empty string', () => {
|
|
const content = '';
|
|
const result = normalizeContentBlocks(content);
|
|
expect(result).toEqual([{ type: 'text', text: '' }]);
|
|
});
|
|
|
|
it('should handle multiline string', () => {
|
|
const content = 'Line 1\nLine 2\nLine 3';
|
|
const result = normalizeContentBlocks(content);
|
|
expect(result).toEqual([{ type: 'text', text: 'Line 1\nLine 2\nLine 3' }]);
|
|
});
|
|
});
|
|
|
|
describe('formatHistoryAsText', () => {
|
|
it('should format empty history as empty string', () => {
|
|
const history: ConversationMessage[] = [];
|
|
const result = formatHistoryAsText(history);
|
|
expect(result).toBe('');
|
|
});
|
|
|
|
it('should format single user message', () => {
|
|
const history: ConversationMessage[] = [{ role: 'user', content: 'Hello!' }];
|
|
const result = formatHistoryAsText(history);
|
|
expect(result).toBe('Previous conversation:\n\nUser: Hello!\n\n---\n\n');
|
|
});
|
|
|
|
it('should format single assistant message', () => {
|
|
const history: ConversationMessage[] = [{ role: 'assistant', content: 'Hi there!' }];
|
|
const result = formatHistoryAsText(history);
|
|
expect(result).toBe('Previous conversation:\n\nAssistant: Hi there!\n\n---\n\n');
|
|
});
|
|
|
|
it('should format conversation with multiple messages', () => {
|
|
const history: ConversationMessage[] = [
|
|
{ role: 'user', content: "What's 2+2?" },
|
|
{ role: 'assistant', content: 'The answer is 4.' },
|
|
{ role: 'user', content: 'Thanks!' },
|
|
];
|
|
const result = formatHistoryAsText(history);
|
|
expect(result).toBe(
|
|
'Previous conversation:\n\n' +
|
|
"User: What's 2+2?\n\n" +
|
|
'Assistant: The answer is 4.\n\n' +
|
|
'User: Thanks!\n\n' +
|
|
'---\n\n'
|
|
);
|
|
});
|
|
|
|
it('should handle array content by extracting text', () => {
|
|
const history: ConversationMessage[] = [
|
|
{
|
|
role: 'user',
|
|
content: [
|
|
{ type: 'text', text: 'First part' },
|
|
{ type: 'text', text: 'Second part' },
|
|
],
|
|
},
|
|
];
|
|
const result = formatHistoryAsText(history);
|
|
expect(result).toBe('Previous conversation:\n\nUser: First part\nSecond part\n\n---\n\n');
|
|
});
|
|
|
|
it('should handle mixed string and array content', () => {
|
|
const history: ConversationMessage[] = [
|
|
{ role: 'user', content: 'String message' },
|
|
{
|
|
role: 'assistant',
|
|
content: [{ type: 'text', text: 'Array message' }],
|
|
},
|
|
];
|
|
const result = formatHistoryAsText(history);
|
|
expect(result).toContain('User: String message');
|
|
expect(result).toContain('Assistant: Array message');
|
|
});
|
|
});
|
|
|
|
describe('convertHistoryToMessages', () => {
|
|
it('should convert empty history', () => {
|
|
const history: ConversationMessage[] = [];
|
|
const result = convertHistoryToMessages(history);
|
|
expect(result).toEqual([]);
|
|
});
|
|
|
|
it('should convert single user message', () => {
|
|
const history: ConversationMessage[] = [{ role: 'user', content: 'Hello!' }];
|
|
const result = convertHistoryToMessages(history);
|
|
|
|
expect(result).toHaveLength(1);
|
|
expect(result[0]).toMatchObject({
|
|
type: 'user',
|
|
session_id: '',
|
|
message: {
|
|
role: 'user',
|
|
content: [{ type: 'text', text: 'Hello!' }],
|
|
},
|
|
parent_tool_use_id: null,
|
|
});
|
|
});
|
|
|
|
it('should convert single assistant message', () => {
|
|
const history: ConversationMessage[] = [{ role: 'assistant', content: 'Hi there!' }];
|
|
const result = convertHistoryToMessages(history);
|
|
|
|
expect(result).toHaveLength(1);
|
|
expect(result[0]).toMatchObject({
|
|
type: 'assistant',
|
|
session_id: '',
|
|
message: {
|
|
role: 'assistant',
|
|
content: [{ type: 'text', text: 'Hi there!' }],
|
|
},
|
|
parent_tool_use_id: null,
|
|
});
|
|
});
|
|
|
|
it('should preserve array content as-is', () => {
|
|
const content = [
|
|
{ type: 'text', text: 'Text' },
|
|
{ type: 'image', source: { data: '...' } },
|
|
];
|
|
const history: ConversationMessage[] = [{ role: 'user', content }];
|
|
const result = convertHistoryToMessages(history);
|
|
|
|
expect(result[0].message.content).toEqual(content);
|
|
});
|
|
|
|
it('should convert multiple messages', () => {
|
|
const history: ConversationMessage[] = [
|
|
{ role: 'user', content: 'First' },
|
|
{ role: 'assistant', content: 'Second' },
|
|
{ role: 'user', content: 'Third' },
|
|
];
|
|
const result = convertHistoryToMessages(history);
|
|
|
|
expect(result).toHaveLength(3);
|
|
expect(result[0].type).toBe('user');
|
|
expect(result[1].type).toBe('assistant');
|
|
expect(result[2].type).toBe('user');
|
|
});
|
|
|
|
it('should set session_id to empty string', () => {
|
|
const history: ConversationMessage[] = [{ role: 'user', content: 'Test' }];
|
|
const result = convertHistoryToMessages(history);
|
|
|
|
expect(result[0].session_id).toBe('');
|
|
});
|
|
|
|
it('should set parent_tool_use_id to null', () => {
|
|
const history: ConversationMessage[] = [{ role: 'user', content: 'Test' }];
|
|
const result = convertHistoryToMessages(history);
|
|
|
|
expect(result[0].parent_tool_use_id).toBeNull();
|
|
});
|
|
|
|
it('should normalize string content to blocks', () => {
|
|
const history: ConversationMessage[] = [{ role: 'user', content: 'String content' }];
|
|
const result = convertHistoryToMessages(history);
|
|
|
|
expect(result[0].message.content).toEqual([{ type: 'text', text: 'String content' }]);
|
|
});
|
|
});
|
|
});
|