Files
connectai/tests/webFetchNotice.test.ts
T
koriweb c79eda1862 v2.2.313~319: 보고 품질·조사 신뢰성 수술 + 네이버 쇼핑인사이트/검색어트렌드 연동
- 파트별 완성, 웹 실접속 증빙, 턴 의도 브리핑, 본문 불일치 검증, 하위 질문
  체크리스트, 사이트 심층 수집 (PATCHNOTES.md v2.2.313~318 참조)
- /naver-shopping, /naver-trend: 네이버 데이터랩 API 연동. compare/discover
  자동 판별, API 배치 상한 캡슐화, 카테고리 트리 fuzzy 매칭, 자격증명은
  Astra 설정 패널 SecretStorage 로 관리
2026-08-05 18:20:32 +09:00

78 lines
4.5 KiB
TypeScript

/**
* [v2.2.315] 웹 실접속 결정론 표시 — "사이트 분석 요청에 실접속 없이 일반론 답변"
* (koritips.com 실사례) 재발 방지. 접속 실패는 답변 상단 경고, 성공은 하단 출처.
*/
import { buildWebFetchNotice, isUrlContextSuccessBlock } from '../src/lib/contextBuilders/urlContext';
import { shouldUseMultiAgentWorkflow } from '../src/lib/contextBuilders/multiAgentRouting';
describe('buildWebFetchNotice', () => {
test('전부 실패 → 상단 경고 (실측 아님 명시)', () => {
const n = buildWebFetchNotice({ urls: ['https://koritips.com'], succeeded: [], failed: [{ url: 'https://koritips.com', reason: 'HTTP 403' }] });
expect(n.top).toContain('사이트 실접속 실패');
expect(n.top).toContain('koritips.com');
expect(n.top).toContain('HTTP 403');
expect(n.bottom).toBe('');
});
test('성공 → 하단 실접속 출처', () => {
const n = buildWebFetchNotice({ urls: ['https://koritips.com'], succeeded: ['https://koritips.com'], failed: [] });
expect(n.top).toBe('');
expect(n.bottom).toContain('실접속 확인');
});
test('URL 없는 턴은 무표시', () => {
expect(buildWebFetchNotice(null)).toEqual({ top: '', bottom: '' });
expect(buildWebFetchNotice({ urls: [], succeeded: [], failed: [] })).toEqual({ top: '', bottom: '' });
});
test('성공 블록 판별', () => {
expect(isUrlContextSuccessBlock('[URL CONTENT — 실데이터 · https://x.com]\n...')).toBe(true);
expect(isUrlContextSuccessBlock('[URL CONTENT — https://x.com]\n상태: 접근 실패 — ...')).toBe(false);
});
});
describe('shouldUseMultiAgentWorkflow — URL 은 단일 턴 강제', () => {
test('URL 포함 조사 요청은 워크플로우로 빠지지 않는다 (웹 접근 경로가 없으므로)', () => {
expect(shouldUseMultiAgentWorkflow('HTTPS://KORITIPS.COM 사이트 조사해서 보고서 작성해줘', true)).toBe(false);
expect(shouldUseMultiAgentWorkflow('https://example.com 리서치해줘', false)).toBe(false);
});
});
// [v2.2.317] 본문 불일치 검증 — 접속 성공인데 실데이터 미반영 일반론 답변 감지.
import { detectWebContentMismatch, formatWebContentMismatchFooter, extractSuccessMeta } from '../src/lib/contextBuilders/urlContext';
describe('detectWebContentMismatch', () => {
const stats = {
urls: ['https://www.koritips.com'],
succeeded: ['https://www.koritips.com'],
failed: [],
succeededDetail: [{
url: 'https://www.koritips.com',
title: "Kori's Tips - Lived. Learned. Shared.",
sample: 'Blogging Tips 카테고리의 글 모음. 블로그 운영, 애드센스 수익, 워드프레스 세팅, 검색 노출 가이드를 다룹니다. blogging adsense wordpress guide',
}],
};
const hallucinated = '이 사이트는 IT 엔지니어 및 개발자를 위한 전문 지식 공유 플랫폼으로 판단됩니다. 기술 기획자와 테크프리너가 핵심 구독층이며, 아키텍처 관점의 심층 콘텐츠를 제공합니다. '.repeat(4);
test('실데이터 표현이 전혀 반영 안 된 일반론 = 불일치', () => {
const r = detectWebContentMismatch(hallucinated, stats);
expect(r.mismatch).toBe(true);
});
test('본문 표현을 인용한 답변은 통과', () => {
const grounded = `이 블로그는 Blogging Tips 카테고리 중심으로 블로그 운영과 애드센스 수익, 워드프레스 세팅을 다룹니다. ${'상세 설명. '.repeat(30)}`;
expect(detectWebContentMismatch(grounded, stats).mismatch).toBe(false);
});
test('접속 실패 턴은 판정 대상 아님 (실패는 상단 경고가 담당)', () => {
expect(detectWebContentMismatch(hallucinated, { urls: ['https://x.com'], succeeded: [], failed: [{ url: 'https://x.com', reason: 'x' }] }).mismatch).toBe(false);
});
test('footer 에 재요청 안내 포함', () => {
expect(formatWebContentMismatchFooter()).toContain('본문 불일치');
});
});
describe('extractSuccessMeta', () => {
test('성공 블록에서 제목·본문 표본 추출', () => {
const block = '[URL CONTENT — 실데이터 · https://x.com]\n제목: 테스트 제목\n아래 본문만 근거로 답하라.\n\n본문 내용입니다.';
const m = extractSuccessMeta('https://x.com', block);
expect(m.title).toBe('테스트 제목');
expect(m.sample).toContain('본문 내용');
});
});