diff --git a/doc/guardia-signage_개발자지침서_v1.0.pptx b/doc/guardia-signage_개발자지침서_v1.0.pptx new file mode 100644 index 0000000..8e14000 Binary files /dev/null and b/doc/guardia-signage_개발자지침서_v1.0.pptx differ diff --git a/doc/guardia-signage_사용자지침서_v1.0.pptx b/doc/guardia-signage_사용자지침서_v1.0.pptx new file mode 100644 index 0000000..dfb0377 Binary files /dev/null and b/doc/guardia-signage_사용자지침서_v1.0.pptx differ diff --git a/doc/guardia-signage_아키텍처설계서_v1.0.pptx b/doc/guardia-signage_아키텍처설계서_v1.0.pptx new file mode 100644 index 0000000..9473126 Binary files /dev/null and b/doc/guardia-signage_아키텍처설계서_v1.0.pptx differ diff --git a/doc/guardia-signage_운영자지침서_v1.0.pptx b/doc/guardia-signage_운영자지침서_v1.0.pptx new file mode 100644 index 0000000..01831d7 Binary files /dev/null and b/doc/guardia-signage_운영자지침서_v1.0.pptx differ diff --git a/frontend/src/components/Sidebar.tsx b/frontend/src/components/Sidebar.tsx index dde2587..6f8075d 100644 --- a/frontend/src/components/Sidebar.tsx +++ b/frontend/src/components/Sidebar.tsx @@ -43,7 +43,7 @@ const groups: { title: string; items: NavItem[] }[] = [ { title: 'AI · 시스템', items: [ - { to: '/ai', icon: 'ai', label: 'AI 어시스턴트' }, + { to: '/ai', icon: 'ai', label: 'WISE AI' }, { to: '/ai-platform', icon: 'cpu', label: 'AI 플랫폼 설정' }, { to: '/audit', icon: 'audit', label: '감사 로그' }, { to: '/settings', icon: 'settings', label: '시스템 설정' }, diff --git a/frontend/src/pages/AiAssistant.tsx b/frontend/src/pages/AiAssistant.tsx index 6d940ac..f149441 100644 --- a/frontend/src/pages/AiAssistant.tsx +++ b/frontend/src/pages/AiAssistant.tsx @@ -4,32 +4,83 @@ import { PageHeader, Button } from '../components/ui' import { Icon } from '../lib/icons' import { aiChat, aiAnalyzeAlarm, aiGenerateSignText, aiRecommendAd } from '../api/client' -// AI 어시스턴트 — 온프레미스/Claude(AiTextRouter) 경유. 알람 분석·간판 문구·광고 추천·챗. -type Msg = { role: 'user' | 'ai'; text: string } +// WISE AI 어시스턴트 — 온프레미스/Claude(AiTextRouter) 경유. 알람 분석·간판 문구·광고 추천·챗. +// 응답에 근거(citations/sources)·환각차단(abstained)·degraded 필드가 있으면 인용/보류 UX 로 표기. +type Meta = { citations?: any[]; sources?: any[]; abstained?: boolean; degraded?: boolean } +type Msg = { role: 'user' | 'ai'; text: string; meta?: Meta } + +// 인용 라벨 — 문서명·위치·근거지지도. citation/source 객체 형태 방어적 처리. +function sgnCite(c: any): string { + if (c == null) return '문서' + if (typeof c === 'string') return c + const src = c.source || c.document || c.doc || c.title || c.chunk_id || c.id || '문서' + const loc = c.page != null ? ` p.${c.page}` : (c.location ? ` ${c.location}` : '') + const sup = c.support != null ? ` · ${Math.round(Number(c.support) * 100)}%` : '' + return `${src}${loc}${sup}` +} + +// 근거/보류 배지 블록 — 근거·보류·degraded 정보가 있을 때만 노출(없으면 null). +function Evidence({ meta }: { meta?: Meta }) { + if (!meta) return null + const items = (meta.citations?.length ? meta.citations : meta.sources) || [] + const abstained = meta.abstained === true + const degraded = meta.degraded === true + if (!abstained && !degraded && items.length === 0) return null + return ( +