"` and all-zero usage, so they should be
/// excluded from conversation turns and stats.
+const CONTEXT_CONTINUATION_PREFIX: &str =
+ "This session is being continued from a previous conversation";
+
+/// Detect Claude Code context continuation summary messages.
+/// These are injected as "user" type but are actually system context.
+fn is_context_continuation(content: &[ContentBlock]) -> bool {
+ content.iter().any(|block| {
+ if let ContentBlock::Text { text } = block {
+ text.starts_with(CONTEXT_CONTINUATION_PREFIX)
+ } else {
+ false
+ }
+ })
+}
+
fn is_synthetic_assistant(value: &serde_json::Value) -> bool {
value
.get("message")
@@ -486,18 +503,24 @@ impl ClaudeParser {
.unwrap_or("")
.to_string();
- if title.is_none() {
- if let Some(first_text) = content.iter().find_map(|c| match c {
- ContentBlock::Text { text } => Some(text.clone()),
- _ => None,
- }) {
- title = Some(truncate_str(&first_text, 100));
+ // Detect context continuation summary and treat as system message
+ let role = if is_context_continuation(&content) {
+ MessageRole::System
+ } else {
+ if title.is_none() {
+ if let Some(first_text) = content.iter().find_map(|c| match c {
+ ContentBlock::Text { text } => Some(text.clone()),
+ _ => None,
+ }) {
+ title = Some(truncate_str(&first_text, 100));
+ }
}
- }
+ MessageRole::User
+ };
messages.push(UnifiedMessage {
id: uuid,
- role: MessageRole::User,
+ role,
content,
timestamp,
usage: None,
diff --git a/src/components/message/message-list-view.tsx b/src/components/message/message-list-view.tsx
index 727b85d..72375f9 100644
--- a/src/components/message/message-list-view.tsx
+++ b/src/components/message/message-list-view.tsx
@@ -1,6 +1,6 @@
"use client"
-import { memo, useCallback, useEffect, useMemo, useRef } from "react"
+import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react"
import { useConversationRuntime } from "@/contexts/conversation-runtime-context"
import { ContentPartsRenderer } from "./content-parts-renderer"
import {
@@ -20,7 +20,7 @@ import {
MessageThreadScrollButton,
} from "@/components/ai-elements/message-thread"
import { Message, MessageContent } from "@/components/ai-elements/message"
-import { Loader2 } from "lucide-react"
+import { ChevronDown, ChevronRight, Info, Loader2 } from "lucide-react"
import { useTranslations } from "next-intl"
import {
buildPlanKey,
@@ -68,6 +68,41 @@ type ThreadRenderItem =
kind: "typing"
}
+const CollapsibleSystemMessage = memo(function CollapsibleSystemMessage({
+ group,
+}: {
+ group: ResolvedMessageGroup
+}) {
+ const [expanded, setExpanded] = useState(false)
+ const t = useTranslations("Folder.chat.messageList")
+
+ return (
+
+
+ {expanded && (
+
+ )}
+
+ )
+})
+
const HistoricalMessageGroup = memo(function HistoricalMessageGroup({
group,
dimmed = false,
@@ -77,6 +112,10 @@ const HistoricalMessageGroup = memo(function HistoricalMessageGroup({
dimmed?: boolean
showStats?: boolean
}) {
+ if (group.role === "system") {
+ return
+ }
+
return (
diff --git a/src/i18n/messages/ar.json b/src/i18n/messages/ar.json
index 34d5b14..46684e8 100644
--- a/src/i18n/messages/ar.json
+++ b/src/i18n/messages/ar.json
@@ -1445,7 +1445,8 @@
"attachedResources": "الموارد المرفقة",
"loading": "جارٍ التحميل...",
"error": "خطأ: {message}",
- "emptyConversation": "لا توجد رسائل في هذه المحادثة."
+ "emptyConversation": "لا توجد رسائل في هذه المحادثة.",
+ "systemMessage": "رسالة النظام"
},
"liveTurnStats": {
"thinking": "جارٍ التفكير...",
diff --git a/src/i18n/messages/de.json b/src/i18n/messages/de.json
index 547eba8..dc5f956 100644
--- a/src/i18n/messages/de.json
+++ b/src/i18n/messages/de.json
@@ -1445,7 +1445,8 @@
"attachedResources": "Angehängte Ressourcen",
"loading": "Lädt...",
"error": "Fehler: {message}",
- "emptyConversation": "Keine Nachrichten in dieser Unterhaltung."
+ "emptyConversation": "Keine Nachrichten in dieser Unterhaltung.",
+ "systemMessage": "Systemnachricht"
},
"liveTurnStats": {
"thinking": "Denkt nach...",
diff --git a/src/i18n/messages/en.json b/src/i18n/messages/en.json
index 1642387..7addaa5 100644
--- a/src/i18n/messages/en.json
+++ b/src/i18n/messages/en.json
@@ -1445,7 +1445,8 @@
"attachedResources": "Attached resources",
"loading": "Loading...",
"error": "Error: {message}",
- "emptyConversation": "No messages in this conversation."
+ "emptyConversation": "No messages in this conversation.",
+ "systemMessage": "System message"
},
"liveTurnStats": {
"thinking": "Thinking...",
diff --git a/src/i18n/messages/es.json b/src/i18n/messages/es.json
index 0ae228c..bf20e5f 100644
--- a/src/i18n/messages/es.json
+++ b/src/i18n/messages/es.json
@@ -1445,7 +1445,8 @@
"attachedResources": "Recursos adjuntos",
"loading": "Cargando...",
"error": "Error del chat: {message}",
- "emptyConversation": "No hay mensajes en esta conversación."
+ "emptyConversation": "No hay mensajes en esta conversación.",
+ "systemMessage": "Mensaje del sistema"
},
"liveTurnStats": {
"thinking": "Pensando...",
diff --git a/src/i18n/messages/fr.json b/src/i18n/messages/fr.json
index 359d7da..a02261d 100644
--- a/src/i18n/messages/fr.json
+++ b/src/i18n/messages/fr.json
@@ -1445,7 +1445,8 @@
"attachedResources": "Ressources jointes",
"loading": "Chargement...",
"error": "Erreur : {message}",
- "emptyConversation": "Aucun message dans cette conversation."
+ "emptyConversation": "Aucun message dans cette conversation.",
+ "systemMessage": "Message système"
},
"liveTurnStats": {
"thinking": "Réflexion...",
diff --git a/src/i18n/messages/ja.json b/src/i18n/messages/ja.json
index 419d9a3..6379498 100644
--- a/src/i18n/messages/ja.json
+++ b/src/i18n/messages/ja.json
@@ -1445,7 +1445,8 @@
"attachedResources": "添付リソース",
"loading": "読み込み中...",
"error": "エラー: {message}",
- "emptyConversation": "この会話にはメッセージがありません。"
+ "emptyConversation": "この会話にはメッセージがありません。",
+ "systemMessage": "システムメッセージ"
},
"liveTurnStats": {
"thinking": "考え中...",
diff --git a/src/i18n/messages/ko.json b/src/i18n/messages/ko.json
index 1759be9..08a4ad5 100644
--- a/src/i18n/messages/ko.json
+++ b/src/i18n/messages/ko.json
@@ -1445,7 +1445,8 @@
"attachedResources": "첨부된 리소스",
"loading": "불러오는 중...",
"error": "오류: {message}",
- "emptyConversation": "이 대화에는 메시지가 없습니다."
+ "emptyConversation": "이 대화에는 메시지가 없습니다.",
+ "systemMessage": "시스템 메시지"
},
"liveTurnStats": {
"thinking": "생각 중...",
diff --git a/src/i18n/messages/pt.json b/src/i18n/messages/pt.json
index 3426b27..a7a6a9f 100644
--- a/src/i18n/messages/pt.json
+++ b/src/i18n/messages/pt.json
@@ -1445,7 +1445,8 @@
"attachedResources": "Recursos anexados",
"loading": "Carregando...",
"error": "Erro: {message}",
- "emptyConversation": "Nenhuma mensagem nesta conversa."
+ "emptyConversation": "Nenhuma mensagem nesta conversa.",
+ "systemMessage": "Mensagem do sistema"
},
"liveTurnStats": {
"thinking": "Pensando...",
diff --git a/src/i18n/messages/zh-CN.json b/src/i18n/messages/zh-CN.json
index 3a2ff75..3cb4f23 100644
--- a/src/i18n/messages/zh-CN.json
+++ b/src/i18n/messages/zh-CN.json
@@ -1445,7 +1445,8 @@
"attachedResources": "附加资源",
"loading": "加载中...",
"error": "错误:{message}",
- "emptyConversation": "当前会话暂无消息。"
+ "emptyConversation": "当前会话暂无消息。",
+ "systemMessage": "系统消息"
},
"liveTurnStats": {
"thinking": "思考中...",
diff --git a/src/i18n/messages/zh-TW.json b/src/i18n/messages/zh-TW.json
index e2620f4..af8514b 100644
--- a/src/i18n/messages/zh-TW.json
+++ b/src/i18n/messages/zh-TW.json
@@ -1445,7 +1445,8 @@
"attachedResources": "附加資源",
"loading": "載入中...",
"error": "錯誤:{message}",
- "emptyConversation": "目前會話暫無訊息。"
+ "emptyConversation": "目前會話暫無訊息。",
+ "systemMessage": "系統訊息"
},
"liveTurnStats": {
"thinking": "思考中...",