From ff7129eb228d150b3af85edd229ed5e974568962 Mon Sep 17 00:00:00 2001 From: SengokuCola <1026294844@qq.com> Date: Sat, 4 Apr 2026 13:23:46 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=8E=8B=E7=BC=A9=E6=97=A9=E6=9C=9Fassita?= =?UTF-8?q?nt=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/maisaka/chat_loop_service.py | 45 +++++++++++++++++++++++++++++- src/maisaka/prompt_cli_renderer.py | 7 +++-- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/src/maisaka/chat_loop_service.py b/src/maisaka/chat_loop_service.py index 9e5aba95..e8e0d008 100644 --- a/src/maisaka/chat_loop_service.py +++ b/src/maisaka/chat_loop_service.py @@ -880,10 +880,17 @@ class MaisakaChatLoopService: selected_indices.reverse() selected_history = [chat_history[index] for index in selected_indices] + selected_history, hidden_assistant_count = MaisakaChatLoopService._hide_early_assistant_messages(selected_history) selected_history = MaisakaChatLoopService._drop_leading_orphan_tool_results(selected_history) + selection_reason = ( + f"上下文裁剪:最近 {effective_context_size} 条 user/assistant 消息," + f"实际发送 {len(selected_history)} 条" + ) + if hidden_assistant_count > 0: + selection_reason += f",已隐藏最早 {hidden_assistant_count} 条 assistant 消息" return ( selected_history, - f"???????? {effective_context_size} ? user/assistant??????????? {len(selected_history)} ?", + selection_reason, ) @staticmethod @@ -917,6 +924,7 @@ class MaisakaChatLoopService: selected_indices.reverse() selected_history = [chat_history[index] for index in selected_indices] + selected_history, hidden_assistant_count = MaisakaChatLoopService._hide_early_assistant_messages(selected_history) selected_history = MaisakaChatLoopService._drop_leading_orphan_tool_results(selected_history) return ( selected_history, @@ -926,6 +934,41 @@ class MaisakaChatLoopService: ), ) + @staticmethod + def _hide_early_assistant_messages( + selected_history: List[LLMContextMessage], + ) -> tuple[List[LLMContextMessage], int]: + """隐藏上下文中最早 50% 的 assistant 文本消息,但保留工具调用链路。""" + + assistant_indices = [ + index + for index, message in enumerate(selected_history) + if isinstance(message, AssistantMessage) + ] + hidden_assistant_count = len(assistant_indices) // 2 + if hidden_assistant_count <= 0: + return selected_history, 0 + + removed_assistant_indices = set(assistant_indices[:hidden_assistant_count]) + + filtered_history: List[LLMContextMessage] = [] + for index, message in enumerate(selected_history): + if index in removed_assistant_indices: + if not message.tool_calls: + continue + filtered_history.append( + AssistantMessage( + content="", + timestamp=message.timestamp, + tool_calls=list(message.tool_calls), + source_kind=message.source_kind, + ) + ) + continue + filtered_history.append(message) + + return filtered_history, hidden_assistant_count + @staticmethod def _drop_leading_orphan_tool_results( selected_history: List[LLMContextMessage], diff --git a/src/maisaka/prompt_cli_renderer.py b/src/maisaka/prompt_cli_renderer.py index 7b4301c7..0897fd1b 100644 --- a/src/maisaka/prompt_cli_renderer.py +++ b/src/maisaka/prompt_cli_renderer.py @@ -170,8 +170,11 @@ class PromptCLIVisualizer: path_result = cls._build_image_file_link(image_format, image_base64) if path_result is not None: file_uri, file_path = path_result - preview_parts.append(Text.from_markup(f"\n[link={file_uri}]点击打开图片[/link]", style="cyan")) - preview_parts.append(Text(f"\n{file_path}", style="dim")) + preview_parts: List[RenderableType] = [ + Text(f"图片格式 image/{normalized_format} {size_text} 路径:{file_path}", style="magenta") + ] + + preview_parts.append(Text.from_markup(f"[link={file_uri}]点击打开图片[/link]", style="cyan")) return Panel( Group(*preview_parts),