UNPKG

@lobehub/chat

Version:

Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.

187 lines (172 loc) 5.83 kB
import { describe, expect, it } from 'vitest'; import type { PipelineContext } from '../../types'; import { ToolMessageReorder } from '../ToolMessageReorder'; const createContext = (messages: any[]): PipelineContext => ({ initialState: { messages: [] } as any, messages, metadata: { model: 'gpt-4', maxTokens: 4096 }, isAborted: false, }); describe('ToolMessageReorder', () => { it('should place tool messages right after their assistant calls and drop invalid tools', async () => { const proc = new ToolMessageReorder(); const messages = [ { id: 'u1', role: 'user', content: 'hi' }, { id: 'a1', role: 'assistant', content: 'calling', tool_calls: [ { id: 'call_1', type: 'function', function: { name: 'test', arguments: '{}' } }, ], }, { id: 't1', role: 'tool', content: '{"ok":1}', tool_call_id: 'call_1' }, { id: 't_invalid', role: 'tool', content: '{"ok":0}' }, ]; const ctx = createContext(messages); const res = await proc.process(ctx); expect(res.messages.map((m) => m.id)).toEqual(['u1', 'a1', 't1']); }); it('should reorderToolMessages', async () => { const proc = new ToolMessageReorder(); const messages = [ { content: '## Tools\n\nYou can use these tools', role: 'system', }, { content: '', role: 'assistant', tool_calls: [ { function: { arguments: '{"query":"LobeChat","searchEngines":["brave","google","duckduckgo","qwant"]}', name: 'lobe-web-browsing____searchWithSearXNG____builtin', }, id: 'call_6xCmrOtFOyBAcqpqO1TGfw2B', type: 'function', }, { function: { arguments: '{"query":"LobeChat","searchEngines":["brave","google","duckduckgo","qwant"]}', name: 'lobe-web-browsing____searchWithSearXNG____builtin', }, id: 'tool_call_nXxXHW8Z', type: 'function', }, ], }, { content: '[]', name: 'lobe-web-browsing____searchWithSearXNG____builtin', role: 'tool', tool_call_id: 'call_6xCmrOtFOyBAcqpqO1TGfw2B', }, { content: 'LobeHub 是一个专注于设计和开发现代人工智能生成内容(AIGC)工具和组件的团队。', role: 'assistant', }, { content: '[]', name: 'lobe-web-browsing____searchWithSearXNG____builtin', role: 'tool', tool_call_id: 'tool_call_nXxXHW8Z', }, { content: '[]', name: 'lobe-web-browsing____searchWithSearXNG____builtin', role: 'tool', tool_call_id: 'tool_call_2f3CEKz9', }, { content: '### LobeHub 智能AI聚合神器\n\nLobeHub 是一个强大的AI聚合平台', role: 'assistant', }, ]; const ctx = createContext(messages); const output = await proc.process(ctx); expect(output.messages).toEqual([ { content: '## Tools\n\nYou can use these tools', role: 'system', }, { content: '', role: 'assistant', tool_calls: [ { function: { arguments: '{"query":"LobeChat","searchEngines":["brave","google","duckduckgo","qwant"]}', name: 'lobe-web-browsing____searchWithSearXNG____builtin', }, id: 'call_6xCmrOtFOyBAcqpqO1TGfw2B', type: 'function', }, { function: { arguments: '{"query":"LobeChat","searchEngines":["brave","google","duckduckgo","qwant"]}', name: 'lobe-web-browsing____searchWithSearXNG____builtin', }, id: 'tool_call_nXxXHW8Z', type: 'function', }, ], }, { content: '[]', name: 'lobe-web-browsing____searchWithSearXNG____builtin', role: 'tool', tool_call_id: 'call_6xCmrOtFOyBAcqpqO1TGfw2B', }, { content: '[]', name: 'lobe-web-browsing____searchWithSearXNG____builtin', role: 'tool', tool_call_id: 'tool_call_nXxXHW8Z', }, { content: 'LobeHub 是一个专注于设计和开发现代人工智能生成内容(AIGC)工具和组件的团队。', role: 'assistant', }, { content: '### LobeHub 智能AI聚合神器\n\nLobeHub 是一个强大的AI聚合平台', role: 'assistant', }, ]); }); it('should correctly reorder when a tool message appears before the assistant message', async () => { const messages = [ { role: 'system', content: 'System message', }, { role: 'tool', tool_call_id: 'tool_call_1', name: 'test-plugin____testApi', content: 'Tool result', }, { role: 'assistant', content: '', tool_calls: [ { id: 'tool_call_1', type: 'function', function: { name: 'testApi', arguments: '{}' } }, ], }, ]; const proc = new ToolMessageReorder(); const ctx = createContext(messages); const { messages: output } = await proc.process(ctx); // Verify reordering logic works and covers line 688 hasPushed check // In this test, tool messages are duplicated but the second occurrence is skipped expect(output.length).toBe(4); // Original has 3, assistant will add corresponding tool message again expect(output[0].role).toBe('system'); expect(output[1].role).toBe('tool'); expect(output[2].role).toBe('assistant'); expect(output[3].role).toBe('tool'); // Tool message added by assistant's tool_calls }); });