Files
connectai/tests/domainRouter.test.ts
T
koriweb 47b3b9f93a v2.2.299~307: 아키텍처 수렴 + 채팅 정리 + 벤치마킹 강화 + Claude 구독 엔진
- v2.2.299 아키텍처 수렴: coreChat 통일(엔진 휴리스틱 3벌 제거), 기업 모드
  검색 오케스트레이터 승격, lib/execUtil(실행 래퍼 6곳·Python 탐지 3벌 단일화),
  lib/kstSchedule(워처 4개 nowInKst 통합), estimateTokens 통합, 설정 접근 규칙 명문화
- v2.2.300 채팅 화면 정리: LiveReasoningFilter(스트리밍 중 <think>/Harmony 추론
  토큰 단위 차단), 확신도·검토요청 footer 기본 숨김(계산·Reflection 은 유지)
- v2.2.301 문맥·의도 이해: [답변 전 이해 원칙] 상시 주입, 워크플로우 의도 브리핑,
  Report QA 루프(규칙 레지스트리+실측치+회귀 게이트, 블로그_v3 개념 이식)
- v2.2.302 /benchmark 비즈니스 렌즈(가격·수익·운영)+빌드 프롬프트 모드+QA 연계
- v2.2.303 handoff 모드(측정치 무손실 인수인계 문서)+/claude(Claude Code 터미널 위임)
- v2.2.304 이식성: 지식 경로 두뇌-상대 규약(pickWikiDir 상대 해석), 이사 체크리스트
- v2.2.305 Claude 구독 엔진: claude: 프로바이더(CLI 위임, 모델 드롭다운 자동 노출,
  coreChat 지원 — 워크플로우·QA도 구독 모델 가능)
- v2.2.306 Tone Guard: AI 상투어 금지 레지스트리(상담사 화법 실사례 8종+대조 예시)
- v2.2.307 /benchmark 레이아웃 골격(sectionRoles 결정론 분석, 롤링 배너 즉답),
  파트별 실패 격리, 합성 타임아웃 120→300초

검증: tsc 무오류 + jest 888 통과 + esbuild 정상

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 21:02:15 +09:00

82 lines
4.1 KiB
TypeScript

/**
* 단계별 지식 스코프 라우터 — 도메인 분류(휴리스틱)와 폴더 조합 규칙 검증.
* 소형 모델 정밀 검색의 핵심 계약: 확신 없으면 'general'(전체 두뇌)로 보수적 폴백.
*/
import { classifyKnowledgeDomain, combineDomainFolders, buildDomainRoutingHint } from '../src/retrieval/domainRouter';
// vscode 는 jest.config.js 의 moduleNameMapper(tests/mocks/vscode.js)가 전역 mock 으로 처리한다.
describe('classifyKnowledgeDomain', () => {
it('코드 펜스가 있으면 coding 확정', () => {
expect(classifyKnowledgeDomain('이 코드 왜 안 돼?\n```js\nconsole.log(x)\n```')).toBe('coding');
});
it('코딩 신호: 에러/파일 확장자/언어명', () => {
expect(classifyKnowledgeDomain('TypeError: cannot read properties of undefined 에러가 나요')).toBe('coding');
expect(classifyKnowledgeDomain('sidebarProvider.ts 파일의 함수를 리팩토링해줘')).toBe('coding');
expect(classifyKnowledgeDomain('python으로 API endpoint 구현해줘')).toBe('coding');
});
it('수학 신호: 연산식/백분율/수학 용어', () => {
expect(classifyKnowledgeDomain('1234 * 5678 계산해줘')).toBe('math');
expect(classifyKnowledgeDomain('원금 500만원에 연 3.5% 복리 이자면 10년 뒤 얼마야?')).toBe('math');
expect(classifyKnowledgeDomain('주사위 두 개 던져서 합이 7일 확률은?')).toBe('math');
});
it('팩트 신호: 질문사/정의 요청 (다른 도메인 신호가 없을 때만)', () => {
expect(classifyKnowledgeDomain('세종대왕이 누구야?')).toBe('facts');
expect(classifyKnowledgeDomain('OLED와 QLED의 차이가 뭐야?')).toBe('facts');
});
it('신호가 없거나 애매하면 general (전체 두뇌 폴백)', () => {
expect(classifyKnowledgeDomain('오늘 하루 어땠어?')).toBe('general');
expect(classifyKnowledgeDomain('')).toBe('general');
expect(classifyKnowledgeDomain('고마워!')).toBe('general');
});
it('코딩+팩트 혼합 신호는 전문 도메인(coding)이 이긴다', () => {
expect(classifyKnowledgeDomain('git rebase가 뭐야? 설명해줘')).toBe('coding');
});
});
describe('combineDomainFolders — General+Specialty 조합 규칙', () => {
const cfg = { general: 'General', math: 'Specialty_Math', coding: '10_Wiki/Topic_Programming', facts: '' };
it('도메인 분류 성공 + Specialty 설정됨 → [General, Specialty]', () => {
expect(combineDomainFolders('coding', cfg)).toEqual(['General', '10_Wiki/Topic_Programming']);
expect(combineDomainFolders('math', cfg)).toEqual(['General', 'Specialty_Math']);
});
it('Specialty 미설정 도메인은 스코프 미적용 (General만으로 좁히지 않음)', () => {
expect(combineDomainFolders('facts', cfg)).toEqual([]);
});
it('general 도메인은 항상 스코프 미적용 (레거시 전체 검색)', () => {
expect(combineDomainFolders('general', cfg)).toEqual([]);
});
it('General 미설정이면 Specialty 단독으로 스코프', () => {
expect(combineDomainFolders('math', { ...cfg, general: '' })).toEqual(['Specialty_Math']);
});
});
describe('buildDomainRoutingHint — 분류 1회로 도구 유도까지', () => {
it('math → calculate 위임 지시', () => {
expect(buildDomainRoutingHint('math')).toContain('<calculate>');
expect(buildDomainRoutingHint('math')).toContain('암산');
});
it('coding → run_code 실행 확인 + edit_file 수정 루프 지시', () => {
const hint = buildDomainRoutingHint('coding');
expect(hint).toContain('<run_code');
expect(hint).toContain('<edit_file>');
});
it('facts → 근거 없으면 확인 불가 / fetch_url', () => {
const hint = buildDomainRoutingHint('facts');
expect(hint).toContain('확인 불가');
expect(hint).toContain('<fetch_url>');
});
it('general → 힌트 없음 (기존 동작 무간섭)', () => {
expect(buildDomainRoutingHint('general')).toBe('');
});
});