import { describe, expect, it } from 'vitest'; import { levenshtein, suggestToolName, formatUnknownToolError, } from '../inference/tool-suggestions.js'; describe('levenshtein', () => { it('returns 0 for identical strings', () => { expect(levenshtein('view_file', 'view_file')).toBe(0); }); it('returns the length when one string is empty', () => { expect(levenshtein('', 'view_file')).toBe(9); expect(levenshtein('view_file', '')).toBe(9); }); it('computes a small distance for a single-character substitution', () => { expect(levenshtein('cat', 'bat')).toBe(1); }); it('computes a known case: read_file → view_file is 4', () => { expect(levenshtein('read_file', 'view_file')).toBe(4); }); }); describe('suggestToolName (v1.13.16)', () => { const tools = [ 'view_file', 'list_dir', 'grep', 'find_files', 'view_truncated_output', 'ask_user_input', 'web_search', ]; it('suggests the closest match when distance is small', () => { expect(suggestToolName('view_files', tools)).toBe('view_file'); }); it('suggests via substring match when distance alone would miss', () => { expect(suggestToolName('file', tools)).toBe('view_file'); }); it('returns null when nothing is close', () => { expect(suggestToolName('xxxx_yyyy_zzzz', tools)).toBeNull(); }); it('is case-insensitive in the distance check', () => { expect(suggestToolName('VIEW_FILE', tools)).toBe('view_file'); }); }); describe('formatUnknownToolError (v1.13.16)', () => { const tools = ['view_file', 'list_dir', 'grep', 'find_files']; it('includes the wrong name and the available tools list', () => { const msg = formatUnknownToolError('read_file', tools); expect(msg).toContain("Tool 'read_file' not found"); expect(msg).toContain('Available tools:'); expect(msg).toContain('view_file'); expect(msg).toContain('find_files'); }); it('includes a suggestion when the drifted name is within threshold', () => { const msg = formatUnknownToolError('view_files', tools); expect(msg).toContain('Did you mean: view_file?'); }); it('omits the suggestion clause when no tool is close enough', () => { const msg = formatUnknownToolError('zzzzzzz', tools); expect(msg).toContain("Tool 'zzzzzzz' not found"); expect(msg).toContain('Available tools:'); expect(msg).not.toContain('Did you mean'); }); it('does not suggest view_file for the read_file drift case (distance is 4, over threshold)', () => { const msg = formatUnknownToolError('read_file', tools); expect(msg).not.toContain('Did you mean'); }); });