/** * B2 wiring tests — search_memory integration with CombinedRetrieval. * * Tests the search_memory tool's behavior with and without kvarkClient, * and the formatCombinedResult helper. */ import { describe, it, expect, vi } from 'vitest'; import { formatCombinedResult } from '../src/tools.js'; import type { CombinedRetrievalResult, CombinedResult } from '../src/combined-retrieval.js'; // ── Factories ────────────────────────────────────────────────────────── function makeCombinedResult(overrides: Partial = {}): CombinedResult { return { content: overrides.content ?? 'some content', source: overrides.source ?? 'workspace', attribution: overrides.attribution ?? '[workspace memory]', score: overrides.score ?? 0.8, metadata: overrides.metadata ?? {}, }; } function makeRetrievalResult(overrides: Partial = {}): CombinedRetrievalResult { return { query: overrides.query ?? 'test', workspaceResults: overrides.workspaceResults ?? [], personalResults: overrides.personalResults ?? [], kvarkResults: overrides.kvarkResults ?? [], kvarkAvailable: overrides.kvarkAvailable ?? false, kvarkSkipped: overrides.kvarkSkipped ?? false, kvarkError: overrides.kvarkError, }; } // ── formatCombinedResult tests ────────────────────────────────────────── describe('formatCombinedResult', () => { it('returns no-results message when all arrays are empty', () => { const result = formatCombinedResult(makeRetrievalResult(), true); expect(result).toBe('No relevant memories found.'); }); it('formats workspace results with section header', () => { const result = formatCombinedResult(makeRetrievalResult({ workspaceResults: [ makeCombinedResult({ content: 'project uses React', score: 0.85, metadata: { frameType: 'fact', importance: 'normal' }, }), ], }), true); expect(result).toContain('## Workspace Memory'); expect(result).toContain('score: 0.850'); expect(result).toContain('type: fact'); expect(result).toContain('importance: normal'); expect(result).toContain('[workspace memory]'); expect(result).toContain('project uses React'); }); it('formats personal results with section header when workspace is active', () => { const result = formatCombinedResult(makeRetrievalResult({ personalResults: [ makeCombinedResult({ source: 'personal', attribution: '[personal memory]', content: 'user prefers dark mode', score: 0.6, }), ], }), true); expect(result).toContain('## Personal Memory'); expect(result).toContain('[personal memory]'); expect(result).toContain('user prefers dark mode'); }); it('omits Personal Memory header when no workspace is active', () => { const result = formatCombinedResult(makeRetrievalResult({ personalResults: [ makeCombinedResult({ source: 'personal', content: 'some pref', score: 0.7 }), ], }), false); expect(result).not.toContain('## Personal Memory'); expect(result).toContain('some pref'); }); it('formats KVARK results with Enterprise Knowledge header and attribution', () => { const result = formatCombinedResult(makeRetrievalResult({ kvarkResults: [ makeCombinedResult({ source: 'kvark', attribution: '[KVARK: pdf: Q3 Report]', content: 'Revenue grew 15%', score: 0.92, metadata: { documentId: 42, documentType: 'pdf' }, }), ], kvarkAvailable: true, }), true); expect(result).toContain('## Enterprise Knowledge (KVARK)'); expect(result).toContain('[KVARK: pdf: Q3 Report]'); expect(result).toContain('Revenue grew 15%'); expect(result).toContain('score: 0.920'); }); it('appends KVARK error note while preserving local results', () => { const result = formatCombinedResult(makeRetrievalResult({ workspaceResults: [ makeCombinedResult({ content: 'local fact', score: 0.7 }), ], kvarkError: 'Connection refused', kvarkAvailable: true, }), true); expect(result).toContain('local fact'); expect(result).toContain('Enterprise search encountered an error: Connection refused'); expect(result).toContain('Results shown are from local memory only'); }); it('formats all three sources together correctly', () => { const result = formatCombinedResult(makeRetrievalResult({ workspaceResults: [makeCombinedResult({ content: 'ws data', score: 0.9 })], personalResults: [makeCombinedResult({ source: 'personal', content: 'personal data', score: 0.7 })], kvarkResults: [makeCombinedResult({ source: 'kvark', attribution: '[KVARK: doc]', content: 'enterprise data', score: 0.85 })], kvarkAvailable: true, }), true); expect(result).toContain('## Workspace Memory'); expect(result).toContain('## Personal Memory'); expect(result).toContain('## Enterprise Knowledge (KVARK)'); // Verify ordering: workspace → personal → KVARK const wsIdx = result.indexOf('## Workspace Memory'); const pIdx = result.indexOf('## Personal Memory'); const kIdx = result.indexOf('## Enterprise Knowledge'); expect(wsIdx).toBeLessThan(pIdx); expect(pIdx).toBeLessThan(kIdx); }); it('KVARK results use score-only format (no frame_type/importance)', () => { const result = formatCombinedResult(makeRetrievalResult({ kvarkResults: [ makeCombinedResult({ source: 'kvark', attribution: '[KVARK: pdf: Doc]', content: 'content', score: 0.9, }), ], kvarkAvailable: true, }), true); // KVARK results should NOT have frame_type or importance expect(result).not.toContain('type:'); expect(result).not.toContain('importance:'); expect(result).toContain('score: 0.900'); }); }); // ── MindToolDeps.kvarkClient integration (structural tests) ───────────── describe('MindToolDeps kvarkClient integration', () => { it('MindToolDeps accepts optional kvarkClient', async () => { // This is a compile-time test — if MindToolDeps didn't have kvarkClient, // TypeScript would catch it. We verify the type exists by importing it. const { type } = await import('../src/tools.js'); // If we got here, the import succeeded and the type exists expect(true).toBe(true); }); it('OrchestratorConfig accepts optional kvarkClient', async () => { const { type } = await import('../src/orchestrator.js'); expect(true).toBe(true); }); });