From feb82abbf728a3a4405c6f4fa75cfac41b06f199 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9C=A4=EC=B0=AC?= Date: Mon, 13 Apr 2026 14:53:17 +0900 Subject: [PATCH] =?UTF-8?q?=EB=B2=88=EC=97=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .claude/scheduled_tasks.lock | 1 + .../components/meeting/MeetingChatPanel.tsx | 145 +++++++++++++----- packages/i18n/src/locales/de.json | 1 + packages/i18n/src/locales/en.json | 1 + packages/i18n/src/locales/es.json | 1 + packages/i18n/src/locales/fr.json | 1 + packages/i18n/src/locales/ja.json | 1 + packages/i18n/src/locales/ko.json | 1 + packages/i18n/src/locales/pt.json | 1 + packages/i18n/src/locales/ru.json | 1 + packages/i18n/src/locales/th.json | 1 + packages/i18n/src/locales/vi.json | 1 + packages/i18n/src/locales/zh-TW.json | 1 + packages/i18n/src/locales/zh.json | 1 + 14 files changed, 117 insertions(+), 41 deletions(-) create mode 100644 .claude/scheduled_tasks.lock diff --git a/.claude/scheduled_tasks.lock b/.claude/scheduled_tasks.lock new file mode 100644 index 0000000..1bb6927 --- /dev/null +++ b/.claude/scheduled_tasks.lock @@ -0,0 +1 @@ +{"sessionId":"2ac1c12e-84cc-457a-867a-5483881cd12c","pid":79317,"acquiredAt":1775918535843} \ No newline at end of file diff --git a/apps/desktop/src/renderer/components/meeting/MeetingChatPanel.tsx b/apps/desktop/src/renderer/components/meeting/MeetingChatPanel.tsx index de2f485..fb6ccb6 100644 --- a/apps/desktop/src/renderer/components/meeting/MeetingChatPanel.tsx +++ b/apps/desktop/src/renderer/components/meeting/MeetingChatPanel.tsx @@ -1,8 +1,8 @@ // src/renderer/components/meeting/MeetingChatPanel.tsx // Phase 15: 회의 상세 페이지 하단 AI 채팅 패널 -import { useState, useCallback, useEffect, useRef } from 'react' -import { Box, TextField, IconButton, LinearProgress, Tooltip } from '@mui/material' +import { useState, useCallback, useEffect, useRef, useMemo } from 'react' +import { Box, TextField, IconButton, Tooltip } from '@mui/material' import SendIcon from '@mui/icons-material/Send' import DeleteSweepIcon from '@mui/icons-material/DeleteSweep' import ExpandLessIcon from '@mui/icons-material/ExpandLess' @@ -21,16 +21,25 @@ interface MeetingChatPanelProps { const COLLAPSED_HEIGHT = 40 const EXPANDED_HEIGHT = 240 +/** LLM 리즈닝 블록 제거 (스트리밍 중 열린 태그 포함) */ +function stripThinkTags(text: string): string { + // 완성된 블록 제거 + let result = text.replace(/[\s\S]*?<\/think>/gi, '') + // 스트리밍 중 아직 닫히지 않은 … 제거 + result = result.replace(/[\s\S]*$/gi, '') + return result.trim() +} + // 타이핑 인디케이터 점 3개 애니메이션 function TypingIndicator(): React.ReactElement { return ( - + {[0, 1, 2].map((i) => ( !prev) }, []) + // 스트리밍 콘텐츠에서 think 태그 제거한 표시용 텍스트 + const visibleStreamingContent = useMemo( + () => stripThinkTags(streamingContent), + [streamingContent], + ) + // think 블록 안에 있는 동안(표시할 텍스트 없음) → 리즈닝 중 표시 + const isReasoning = streaming && streamingContent.length > 0 && visibleStreamingContent.length === 0 + return ( - {messages.map((msg) => ( - + {messages.map((msg) => { + const displayContent = msg.role === 'assistant' + ? stripThinkTags(msg.content) + : msg.content + if (!displayContent) return null + return ( - {msg.content} + + {displayContent} + - - ))} + ) + })} {/* 에러 메시지 */} {error && ( @@ -280,24 +304,63 @@ export function MeetingChatPanel({ sessionId }: MeetingChatPanelProps): React.Re border: `1px solid ${d3roPalette.border.subtle}`, wordBreak: 'break-word', whiteSpace: 'pre-wrap', + overflow: 'hidden', }} > - {streamingContent || } + {visibleStreamingContent || ( + + + {isReasoning && ( + + {t('meeting.chatReasoning')} + + )} + + )} )} - {/* 스트리밍 진행 표시 */} + {/* 스트리밍 진행 표시 — 얇은 accent 라인 */} {streaming && ( - + > + + )} {/* 입력 영역 */} diff --git a/packages/i18n/src/locales/de.json b/packages/i18n/src/locales/de.json index 6b3687b..da670a6 100644 --- a/packages/i18n/src/locales/de.json +++ b/packages/i18n/src/locales/de.json @@ -285,6 +285,7 @@ "meeting.copied": "Kopiert", "meeting.chatCollapse": "Chat einklappen", "meeting.chatExpand": "Chat ausklappen", + "meeting.chatReasoning": "Denkt nach…", "meeting.exportMd": "Markdown (.md)", "meeting.exportPdfFmt": "PDF (.pdf)", "meeting.polishFailed": "KI-Polierung fehlgeschlagen", diff --git a/packages/i18n/src/locales/en.json b/packages/i18n/src/locales/en.json index e60e727..376295f 100644 --- a/packages/i18n/src/locales/en.json +++ b/packages/i18n/src/locales/en.json @@ -510,6 +510,7 @@ "meeting.copied": "Copied", "meeting.chatCollapse": "Collapse Chat", "meeting.chatExpand": "Expand Chat", + "meeting.chatReasoning": "Reasoning…", "meeting.exportMd": "Markdown (.md)", "meeting.exportPdfFmt": "PDF (.pdf)", "meeting.polishFailed": "AI polishing failed", diff --git a/packages/i18n/src/locales/es.json b/packages/i18n/src/locales/es.json index 4db9598..2fd16d8 100644 --- a/packages/i18n/src/locales/es.json +++ b/packages/i18n/src/locales/es.json @@ -285,6 +285,7 @@ "meeting.copied": "Copiado", "meeting.chatCollapse": "Contraer chat", "meeting.chatExpand": "Expandir chat", + "meeting.chatReasoning": "Razonando…", "meeting.exportMd": "Markdown (.md)", "meeting.exportPdfFmt": "PDF (.pdf)", "meeting.polishFailed": "Error al pulir con IA", diff --git a/packages/i18n/src/locales/fr.json b/packages/i18n/src/locales/fr.json index 7d2b719..1552da8 100644 --- a/packages/i18n/src/locales/fr.json +++ b/packages/i18n/src/locales/fr.json @@ -285,6 +285,7 @@ "meeting.copied": "Copié", "meeting.chatCollapse": "Réduire le chat", "meeting.chatExpand": "Agrandir le chat", + "meeting.chatReasoning": "Raisonnement…", "meeting.exportMd": "Markdown (.md)", "meeting.exportPdfFmt": "PDF (.pdf)", "meeting.polishFailed": "Echec du polish IA", diff --git a/packages/i18n/src/locales/ja.json b/packages/i18n/src/locales/ja.json index 17f7c0b..25d3ee9 100644 --- a/packages/i18n/src/locales/ja.json +++ b/packages/i18n/src/locales/ja.json @@ -285,6 +285,7 @@ "meeting.copied": "コピーしました", "meeting.chatCollapse": "チャットを折り畳む", "meeting.chatExpand": "チャットを展開", + "meeting.chatReasoning": "推論中…", "meeting.exportMd": "Markdown (.md)", "meeting.exportPdfFmt": "PDF (.pdf)", "meeting.polishFailed": "AI磨き上げに失敗しました", diff --git a/packages/i18n/src/locales/ko.json b/packages/i18n/src/locales/ko.json index cde26fe..8bb58eb 100644 --- a/packages/i18n/src/locales/ko.json +++ b/packages/i18n/src/locales/ko.json @@ -510,6 +510,7 @@ "meeting.copied": "복사됨", "meeting.chatCollapse": "채팅 접기", "meeting.chatExpand": "채팅 펼치기", + "meeting.chatReasoning": "추론 중…", "meeting.exportMd": "Markdown (.md)", "meeting.exportPdfFmt": "PDF (.pdf)", "meeting.polishFailed": "AI 다듬기에 실패했습니다", diff --git a/packages/i18n/src/locales/pt.json b/packages/i18n/src/locales/pt.json index 2bf7342..5717aa8 100644 --- a/packages/i18n/src/locales/pt.json +++ b/packages/i18n/src/locales/pt.json @@ -285,6 +285,7 @@ "meeting.copied": "Copiado", "meeting.chatCollapse": "Recolher chat", "meeting.chatExpand": "Expandir chat", + "meeting.chatReasoning": "Raciocinando…", "meeting.exportMd": "Markdown (.md)", "meeting.exportPdfFmt": "PDF (.pdf)", "meeting.polishFailed": "Falha no polimento de IA", diff --git a/packages/i18n/src/locales/ru.json b/packages/i18n/src/locales/ru.json index e484af1..eebbfcb 100644 --- a/packages/i18n/src/locales/ru.json +++ b/packages/i18n/src/locales/ru.json @@ -285,6 +285,7 @@ "meeting.copied": "Скопировано", "meeting.chatCollapse": "Свернуть чат", "meeting.chatExpand": "Развернуть чат", + "meeting.chatReasoning": "Размышляет…", "meeting.exportMd": "Markdown (.md)", "meeting.exportPdfFmt": "PDF (.pdf)", "meeting.polishFailed": "Ошибка ИИ-полировки", diff --git a/packages/i18n/src/locales/th.json b/packages/i18n/src/locales/th.json index 85f4ed6..a4e9c00 100644 --- a/packages/i18n/src/locales/th.json +++ b/packages/i18n/src/locales/th.json @@ -285,6 +285,7 @@ "meeting.copied": "คัดลอกแล้ว", "meeting.chatCollapse": "ยุบแชท", "meeting.chatExpand": "ขยายแชท", + "meeting.chatReasoning": "กำลังคิด…", "meeting.exportMd": "Markdown (.md)", "meeting.exportPdfFmt": "PDF (.pdf)", "meeting.polishFailed": "AI ปรับแต่งล้มเหลว", diff --git a/packages/i18n/src/locales/vi.json b/packages/i18n/src/locales/vi.json index 2baa5dc..6f53fdd 100644 --- a/packages/i18n/src/locales/vi.json +++ b/packages/i18n/src/locales/vi.json @@ -285,6 +285,7 @@ "meeting.copied": "Đã sao chép", "meeting.chatCollapse": "Thu gọn chat", "meeting.chatExpand": "Mở rộng chat", + "meeting.chatReasoning": "Đang suy luận…", "meeting.exportMd": "Markdown (.md)", "meeting.exportPdfFmt": "PDF (.pdf)", "meeting.polishFailed": "AI đánh bóng thất bại", diff --git a/packages/i18n/src/locales/zh-TW.json b/packages/i18n/src/locales/zh-TW.json index eca869d..806be39 100644 --- a/packages/i18n/src/locales/zh-TW.json +++ b/packages/i18n/src/locales/zh-TW.json @@ -285,6 +285,7 @@ "meeting.copied": "已複製", "meeting.chatCollapse": "收起聊天", "meeting.chatExpand": "展開聊天", + "meeting.chatReasoning": "推理中…", "meeting.exportMd": "Markdown (.md)", "meeting.exportPdfFmt": "PDF (.pdf)", "meeting.polishFailed": "AI潤色失敗", diff --git a/packages/i18n/src/locales/zh.json b/packages/i18n/src/locales/zh.json index b81616b..a7e1933 100644 --- a/packages/i18n/src/locales/zh.json +++ b/packages/i18n/src/locales/zh.json @@ -285,6 +285,7 @@ "meeting.copied": "已复制", "meeting.chatCollapse": "收起聊天", "meeting.chatExpand": "展开聊天", + "meeting.chatReasoning": "推理中…", "meeting.exportMd": "Markdown (.md)", "meeting.exportPdfFmt": "PDF (.pdf)", "meeting.polishFailed": "AI润色失败",