Skip to main content
Glama
integration.test.ts7.78 kB
/** * Integration tests for Chat Context Optimization * * Tests the full flow from request to optimized context */ import { describe, it, expect, beforeAll, afterAll } from 'vitest'; import { db } from '../../../db/postgres'; import { buildContextForRequest } from '../integration'; import type { OpenAIMessage } from '../integration'; describe('Chat Context Optimization Integration', () => { const testConversationId = `test-conv-${Date.now()}`; beforeAll(async () => { // Ensure DB is ready if (!db.isReady()) { await new Promise(resolve => setTimeout(resolve, 1000)); } // Create test conversation await db.insert('conversations', { id: testConversationId, project_id: 'test-project', }); }); afterAll(async () => { // Cleanup test data try { await db.query('DELETE FROM messages WHERE conversation_id = $1', [testConversationId]); await db.query('DELETE FROM conversations WHERE id = $1', [testConversationId]); } catch (error) { console.error('Cleanup failed:', error); } }); describe('buildContextForRequest', () => { it('should handle stateless mode (no conversation ID)', async () => { const messages: OpenAIMessage[] = [ { role: 'system', content: 'You are a helpful assistant.' }, { role: 'user', content: 'Hello!' }, ]; const result = await buildContextForRequest({ messages, model: 'gpt-4o-mini', }); expect(result.messages).toHaveLength(2); expect(result.strategy).toBe('stateless'); expect(result.tokenStats.saved).toBe(0); }); it('should build context for new conversation', async () => { const messages: OpenAIMessage[] = [ { role: 'system', content: 'You are a helpful assistant.' }, { role: 'user', content: 'What is TypeScript?' }, ]; const result = await buildContextForRequest({ conversationId: testConversationId, messages, model: 'gpt-4o-mini', contextStrategy: 'summary+recent', }); expect(result.messages.length).toBeGreaterThan(0); expect(result.strategy).toBe('summary+recent'); expect(result.tokenStats.total).toBeGreaterThan(0); }); it('should optimize long conversation with summary+recent', async () => { // Create a long message history const messages: OpenAIMessage[] = [ { role: 'system', content: 'You are a helpful assistant.' }, ]; // Add 30 message pairs for (let i = 0; i < 30; i++) { messages.push( { role: 'user', content: `Question ${i}: Tell me about topic ${i}` }, { role: 'assistant', content: `Answer ${i}: Here's information about topic ${i}. This is a long response with detailed information...`.repeat(3) } ); } // Add current question messages.push({ role: 'user', content: 'Summarize what we discussed' }); const result = await buildContextForRequest({ conversationId: testConversationId, messages, model: 'gpt-4o-mini', contextStrategy: 'summary+recent', maxContextTokens: 4096, }); // Should have optimized the context expect(result.messages.length).toBeLessThan(messages.length); expect(result.tokenStats.saved).toBeGreaterThan(0); expect(result.metadata.recentMessagesIncluded).toBeGreaterThan(0); // Final message should be included const lastMessage = result.messages[result.messages.length - 1]; expect(lastMessage.content).toContain('Summarize'); }); it('should use span-retrieval for semantic search', async () => { const messages: OpenAIMessage[] = [ { role: 'system', content: 'You are a helpful assistant.' }, { role: 'user', content: 'Explain TypeScript interfaces' }, { role: 'assistant', content: 'TypeScript interfaces define object shapes...' }, { role: 'user', content: 'What about classes?' }, { role: 'assistant', content: 'Classes in TypeScript...' }, { role: 'user', content: 'Tell me about generics' }, { role: 'assistant', content: 'Generics provide type safety...' }, { role: 'user', content: 'How do interfaces work again?' }, // Should retrieve earlier interface discussion ]; const result = await buildContextForRequest({ conversationId: testConversationId, messages, model: 'gpt-4o-mini', contextStrategy: 'span-retrieval', }); expect(result.strategy).toBe('span-retrieval'); // Should have retrieved relevant spans expect(result.metadata.spansRetrieved).toBeGreaterThanOrEqual(0); }); it('should respect token budget', async () => { const longMessages: OpenAIMessage[] = [ { role: 'system', content: 'You are a helpful assistant.' }, ]; // Create messages that would exceed budget for (let i = 0; i < 50; i++) { longMessages.push( { role: 'user', content: `Question ${i}: ${'word '.repeat(100)}` }, { role: 'assistant', content: `Answer ${i}: ${'word '.repeat(200)}` } ); } const maxTokens = 2000; const result = await buildContextForRequest({ conversationId: testConversationId, messages: longMessages, model: 'gpt-4o-mini', maxContextTokens: maxTokens, }); // Should fit within budget expect(result.tokenStats.total).toBeLessThanOrEqual(maxTokens); expect(result.messages.length).toBeLessThan(longMessages.length); }); it('should handle fallback gracefully', async () => { const messages: OpenAIMessage[] = [ { role: 'user', content: 'Test message' }, ]; // Even with invalid config, should not throw const result = await buildContextForRequest({ conversationId: 'invalid-conv-id', messages, model: 'gpt-4o-mini', }); expect(result).toBeDefined(); expect(result.messages.length).toBeGreaterThan(0); }); }); describe('Performance', () => { it('should build context in reasonable time', async () => { const messages: OpenAIMessage[] = [ { role: 'system', content: 'System prompt' }, ]; for (let i = 0; i < 20; i++) { messages.push( { role: 'user', content: `Message ${i}` }, { role: 'assistant', content: `Response ${i}` } ); } const start = Date.now(); await buildContextForRequest({ conversationId: testConversationId, messages, model: 'gpt-4o-mini', }); const duration = Date.now() - start; // Should complete in under 2 seconds for 20 messages expect(duration).toBeLessThan(2000); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/babasida246/ai-mcp-gateway'

If you have feedback or need assistance with the MCP directory API, please join our Discord server