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润色失败",