mirror of https://github.com/buster-so/buster.git
173 lines
4.5 KiB
TypeScript
173 lines
4.5 KiB
TypeScript
import type { CoreMessage } from 'ai';
|
|
import { describe, expect, test } from 'vitest';
|
|
import {
|
|
extractResponseMessages,
|
|
formatLlmMessagesAsReasoning,
|
|
} from '../../../src/utils/database/format-llm-messages-as-reasoning';
|
|
|
|
describe('message extraction integration', () => {
|
|
test('extracts reasoning messages from sequential thinking', () => {
|
|
const messages: CoreMessage[] = [
|
|
{
|
|
role: 'assistant',
|
|
content: [
|
|
{
|
|
type: 'tool-call',
|
|
toolCallId: 'call-123',
|
|
toolName: 'sequentialThinking',
|
|
args: {
|
|
thought: 'I need to analyze the customer data',
|
|
thoughtNumber: 1,
|
|
totalThoughts: 3,
|
|
nextThoughtNeeded: true,
|
|
},
|
|
},
|
|
],
|
|
},
|
|
];
|
|
|
|
const reasoning = formatLlmMessagesAsReasoning(messages);
|
|
|
|
expect(reasoning).toHaveLength(1);
|
|
expect(reasoning[0]).toMatchObject({
|
|
id: 'call-123',
|
|
type: 'text',
|
|
title: 'Thought 1 of 3',
|
|
message: 'I need to analyze the customer data',
|
|
secondary_title: 'TODO',
|
|
status: 'completed',
|
|
finished_reasoning: false,
|
|
});
|
|
});
|
|
|
|
test('extracts response messages from doneTool', () => {
|
|
const messages: CoreMessage[] = [
|
|
{
|
|
role: 'assistant',
|
|
content: [
|
|
{
|
|
type: 'tool-call',
|
|
toolCallId: 'call-456',
|
|
toolName: 'doneTool',
|
|
args: {
|
|
message: 'Here are the top 5 customers by revenue',
|
|
},
|
|
},
|
|
],
|
|
},
|
|
];
|
|
|
|
const responses = extractResponseMessages(messages);
|
|
|
|
expect(responses).toHaveLength(1);
|
|
expect(responses[0]).toMatchObject({
|
|
id: 'call-456',
|
|
type: 'text',
|
|
message: 'Here are the top 5 customers by revenue',
|
|
is_final_message: true,
|
|
});
|
|
});
|
|
|
|
test('separates reasoning and response messages correctly', () => {
|
|
const messages: CoreMessage[] = [
|
|
{
|
|
role: 'assistant',
|
|
content: [
|
|
{
|
|
type: 'tool-call',
|
|
toolCallId: 'call-1',
|
|
toolName: 'sequentialThinking',
|
|
args: {
|
|
thought: 'Analyzing the request',
|
|
thoughtNumber: 1,
|
|
totalThoughts: 2,
|
|
nextThoughtNeeded: true,
|
|
},
|
|
},
|
|
],
|
|
},
|
|
{
|
|
role: 'assistant',
|
|
content: [
|
|
{
|
|
type: 'tool-call',
|
|
toolCallId: 'call-2',
|
|
toolName: 'executeSql',
|
|
args: {
|
|
sql: 'SELECT * FROM customers ORDER BY revenue DESC LIMIT 5',
|
|
},
|
|
},
|
|
],
|
|
},
|
|
{
|
|
role: 'assistant',
|
|
content: [
|
|
{
|
|
type: 'tool-call',
|
|
toolCallId: 'call-3',
|
|
toolName: 'doneTool',
|
|
args: {
|
|
message: 'Analysis complete',
|
|
},
|
|
},
|
|
],
|
|
},
|
|
];
|
|
|
|
const reasoning = formatLlmMessagesAsReasoning(messages);
|
|
const responses = extractResponseMessages(messages);
|
|
|
|
// Should have 2 reasoning messages (sequentialThinking and executeSql)
|
|
expect(reasoning).toHaveLength(2);
|
|
expect(reasoning[0].title).toBe('Thought 1 of 2');
|
|
expect(reasoning[1].title).toBe('Executing SQL');
|
|
|
|
// Should have 1 response message (doneTool)
|
|
expect(responses).toHaveLength(1);
|
|
expect(responses[0].message).toBe('Analysis complete');
|
|
});
|
|
|
|
test('handles create metrics file correctly', () => {
|
|
const messages: CoreMessage[] = [
|
|
{
|
|
role: 'assistant',
|
|
content: [
|
|
{
|
|
type: 'tool-call',
|
|
toolCallId: 'call-metrics',
|
|
toolName: 'createMetrics',
|
|
args: {
|
|
files: [
|
|
{
|
|
name: 'revenue_by_customer.yml',
|
|
yml_content: 'metrics:\n - name: revenue\n type: sum',
|
|
},
|
|
],
|
|
},
|
|
},
|
|
],
|
|
},
|
|
];
|
|
|
|
const reasoning = formatLlmMessagesAsReasoning(messages);
|
|
|
|
expect(reasoning).toHaveLength(1);
|
|
expect(reasoning[0]).toMatchObject({
|
|
type: 'files',
|
|
title: 'Creating 1 metric',
|
|
secondary_title: 'TODO',
|
|
file_ids: expect.any(Array),
|
|
files: expect.any(Object),
|
|
});
|
|
|
|
const fileId = reasoning[0].file_ids[0];
|
|
expect(reasoning[0].files[fileId]).toMatchObject({
|
|
file_type: 'metric',
|
|
file_name: 'revenue_by_customer.yml',
|
|
file: {
|
|
text: 'metrics:\n - name: revenue\n type: sum',
|
|
},
|
|
});
|
|
});
|
|
});
|