refactor: remove legacy think tags

This commit is contained in:
JOJO 2025-11-30 15:15:35 +08:00
parent 02ab023ad7
commit 2fea4a7244
7 changed files with 24 additions and 94 deletions

View File

@ -696,25 +696,15 @@ class MainTerminal:
# ===== 统一保存到对话历史(关键修复) ===== # ===== 统一保存到对话历史(关键修复) =====
# 1. 构建完整的assistant消息内容 # 1. 构建助手回复内容(思考内容通过 reasoning_content 存储)
assistant_content_parts = [] assistant_content = final_response or "已完成操作。"
# 添加思考内容
if final_thinking:
assistant_content_parts.append(f"<think>\n{final_thinking}\n</think>")
# 添加回复内容
if final_response:
assistant_content_parts.append(final_response)
# 合并内容
assistant_content = "\n".join(assistant_content_parts) if assistant_content_parts else "已完成操作。"
# 2. 保存assistant消息包含tool_calls但不包含结果 # 2. 保存assistant消息包含tool_calls但不包含结果
self.context_manager.add_conversation( self.context_manager.add_conversation(
"assistant", "assistant",
assistant_content, assistant_content,
collected_tool_calls if collected_tool_calls else None collected_tool_calls if collected_tool_calls else None,
reasoning_content=final_thinking or None
) )
# 3. 保存独立的tool消息 # 3. 保存独立的tool消息

View File

@ -77,7 +77,7 @@
- `tool`:卡片包含工具名、图标(`TOOL_ICON_MAP`),参数快照/状态消息/结果JSON、plain text、命令输出 `pre`),流式时加 loading 条;`action.tool.awaiting_content` 控制“等待正文”占位。工具 `status` 颜色区分 `preparing/running/completed/error` - `tool`:卡片包含工具名、图标(`TOOL_ICON_MAP`),参数快照/状态消息/结果JSON、plain text、命令输出 `pre`),流式时加 loading 条;`action.tool.awaiting_content` 控制“等待正文”占位。工具 `status` 颜色区分 `preparing/running/completed/error`
- `append_payload`/`modify_payload`:专门显示文件路径、强制标志、成功/失败行数。 - `append_payload`/`modify_payload`:专门显示文件路径、强制标志、成功/失败行数。
- `system`:用于 `role=system` 文本,折叠块 `system-message` - `system`:用于 `role=system` 文本,折叠块 `system-message`
- **特殊处理**`renderHistoryMessages()` 会解析 `<think>` 块、自定义 metadata`append_payload`, `modify_payload`),并避免 LLm 输出的 `<<<APPEND`/`<<<MODIFY>>>` 内容直接进入 UI。 - **特殊处理**`renderHistoryMessages()` 会读取消息的 `reasoning_content`、自定义 metadata`append_payload`, `modify_payload`),并避免 LLM 输出的 `<<<APPEND`/`<<<MODIFY>>>` 内容直接进入 UI。
- **滚动策略**`messagesArea` 的 scroll 事件更新 `userScrolling/autoScrollEnabled``scroll-lock-toggle` 按钮切换锁定;思考块单独监听 `scroll` 以保持 pinned 行为。 - **滚动策略**`messagesArea` 的 scroll 事件更新 `userScrolling/autoScrollEnabled``scroll-lock-toggle` 按钮切换锁定;思考块单独监听 `scroll` 以保持 pinned 行为。
#### 3.3 输入区(`.compact-input-area` #### 3.3 输入区(`.compact-input-area`

View File

@ -1387,23 +1387,7 @@ const appOptions = {
} }
const content = message.content || ''; const content = message.content || '';
let reasoningText = (message.reasoning_content || '').trim(); const reasoningText = (message.reasoning_content || '').trim();
if (!reasoningText) {
const thinkPatterns = [
/<think>([\s\S]*?)<\/think>/g,
/<thinking>([\s\S]*?)<\/thinking>/g
];
let extracted = '';
for (const pattern of thinkPatterns) {
let match;
while ((match = pattern.exec(content)) !== null) {
extracted += (match[1] || '').trim() + '\n';
}
}
reasoningText = extracted.trim();
}
if (reasoningText) { if (reasoningText) {
const blockId = `history-thinking-${Date.now()}-${Math.random().toString(36).slice(2)}`; const blockId = `history-thinking-${Date.now()}-${Math.random().toString(36).slice(2)}`;
@ -1426,15 +1410,7 @@ const appOptions = {
const isModifyMessage = message.name === 'modify_file'; const isModifyMessage = message.name === 'modify_file';
const containsAppendMarkers = /<<<\s*(APPEND|MODIFY)/i.test(content || '') || /<<<END_\s*(APPEND|MODIFY)>>>/i.test(content || ''); const containsAppendMarkers = /<<<\s*(APPEND|MODIFY)/i.test(content || '') || /<<<END_\s*(APPEND|MODIFY)>>>/i.test(content || '');
let textContent = content; const textContent = content.trim();
if (!message.reasoning_content) {
textContent = textContent
.replace(/<think>[\s\S]*?<\/think>/g, '')
.replace(/<thinking>[\s\S]*?<\/thinking>/g, '')
.trim();
} else {
textContent = textContent.trim();
}
if (appendPayloadMeta) { if (appendPayloadMeta) {
currentAssistantMessage.actions.push({ currentAssistantMessage.actions.push({

View File

@ -592,25 +592,15 @@ class MainTerminal:
# ===== 统一保存到对话历史(关键修复) ===== # ===== 统一保存到对话历史(关键修复) =====
# 1. 构建完整的assistant消息内容 # 1. 构建助手回复内容(思考内容通过 reasoning_content 保存)
assistant_content_parts = [] assistant_content = final_response or "已完成操作。"
# 添加思考内容
if final_thinking:
assistant_content_parts.append(f"<think>\n{final_thinking}\n</think>")
# 添加回复内容
if final_response:
assistant_content_parts.append(final_response)
# 合并内容
assistant_content = "\n".join(assistant_content_parts) if assistant_content_parts else "已完成操作。"
# 2. 保存assistant消息包含tool_calls但不包含结果 # 2. 保存assistant消息包含tool_calls但不包含结果
self.context_manager.add_conversation( self.context_manager.add_conversation(
"assistant", "assistant",
assistant_content, assistant_content,
collected_tool_calls if collected_tool_calls else None collected_tool_calls if collected_tool_calls else None,
reasoning_content=final_thinking or None
) )
# 3. 保存独立的tool消息 # 3. 保存独立的tool消息

View File

@ -1984,28 +1984,18 @@ async function bootstrapApp() {
const appendPayloadMeta = metadata.append_payload; const appendPayloadMeta = metadata.append_payload;
const modifyPayloadMeta = metadata.modify_payload; const modifyPayloadMeta = metadata.modify_payload;
const thinkPatterns = [/<think>([\s\S]*?)<\/think>/g, /<thinking>([\s\S]*?)<\/thinking>/g]; const reasoningText = (message.reasoning_content || '').trim();
let allThinkingContent = ''; if (reasoningText) {
for (const pattern of thinkPatterns) {
let match;
while ((match = pattern.exec(content)) !== null) {
allThinkingContent += match[1].trim() + '\n';
}
}
if (allThinkingContent.trim()) {
assistant.actions.push({ assistant.actions.push({
id: `history-think-${Date.now()}-${Math.random()}`, id: `history-think-${Date.now()}-${Math.random()}`,
type: 'thinking', type: 'thinking',
content: allThinkingContent.trim(), content: reasoningText,
streaming: false, streaming: false,
timestamp: Date.now() timestamp: Date.now()
}); });
} }
let textContent = content const textContent = content.trim();
.replace(/<think>[\s\S]*?<\/think>/g, '')
.replace(/<thinking>[\s\S]*?<\/thinking>/g, '')
.trim();
if (appendPayloadMeta) { if (appendPayloadMeta) {
assistant.actions.push({ assistant.actions.push({

View File

@ -409,10 +409,6 @@ class DeepSeekClient:
# 构建助手消息 - 始终包含所有收集到的内容 # 构建助手消息 - 始终包含所有收集到的内容
assistant_content_parts = [] assistant_content_parts = []
# 添加思考内容(如果有)
if current_thinking:
assistant_content_parts.append(f"<think>\n{current_thinking}\n</think>")
# 添加正式回复内容(如果有) # 添加正式回复内容(如果有)
if full_response: if full_response:
assistant_content_parts.append(full_response) assistant_content_parts.append(full_response)

View File

@ -2543,7 +2543,6 @@ async def handle_task_with_sender(terminal: WebTerminal, message, sender, client
sender('ai_message_start', {}) sender('ai_message_start', {})
# 增量保存相关变量 # 增量保存相关变量
has_saved_thinking = False # 是否已保存思考内容
accumulated_response = "" # 累积的响应内容 accumulated_response = "" # 累积的响应内容
is_first_iteration = True # 是否是第一次迭代 is_first_iteration = True # 是否是第一次迭代
@ -3348,13 +3347,6 @@ async def handle_task_with_sender(terminal: WebTerminal, message, sender, client
sender('thinking_end', {'full_content': current_thinking}) sender('thinking_end', {'full_content': current_thinking})
await asyncio.sleep(0.1) await asyncio.sleep(0.1)
# ===== 增量保存:保存思考内容 =====
if current_thinking and not has_saved_thinking and is_first_iteration:
thinking_content = f"<think>\n{current_thinking}\n</think>"
web_terminal.context_manager.add_conversation("assistant", thinking_content)
has_saved_thinking = True
debug_log(f"💾 增量保存:思考内容 ({len(current_thinking)} 字符)")
expecting_modify = bool(pending_modify) or bool(getattr(web_terminal, "pending_modify_request", None)) expecting_modify = bool(pending_modify) or bool(getattr(web_terminal, "pending_modify_request", None))
expecting_append = bool(pending_append) or bool(getattr(web_terminal, "pending_append_request", None)) expecting_append = bool(pending_append) or bool(getattr(web_terminal, "pending_append_request", None))
@ -3600,13 +3592,6 @@ async def handle_task_with_sender(terminal: WebTerminal, message, sender, client
sender('thinking_end', {'full_content': current_thinking}) sender('thinking_end', {'full_content': current_thinking})
await asyncio.sleep(0.1) await asyncio.sleep(0.1)
# 保存思考内容
if current_thinking and not has_saved_thinking and is_first_iteration:
thinking_content = f"<think>\n{current_thinking}\n</think>"
web_terminal.context_manager.add_conversation("assistant", thinking_content)
has_saved_thinking = True
debug_log(f"💾 增量保存:延迟思考内容 ({len(current_thinking)} 字符)")
# 确保text_end事件被发送 # 确保text_end事件被发送
if text_started and text_has_content and not append_result["handled"] and not modify_result["handled"]: if text_started and text_has_content and not append_result["handled"] and not modify_result["handled"]:
await flush_text_buffer(force=True) await flush_text_buffer(force=True)
@ -3617,7 +3602,11 @@ async def handle_task_with_sender(terminal: WebTerminal, message, sender, client
# ===== 增量保存:保存当前轮次的文本内容 ===== # ===== 增量保存:保存当前轮次的文本内容 =====
if full_response.strip(): if full_response.strip():
web_terminal.context_manager.add_conversation("assistant", full_response) web_terminal.context_manager.add_conversation(
"assistant",
full_response,
reasoning_content=current_thinking or None
)
debug_log(f"💾 增量保存:文本内容 ({len(full_response)} 字符)") debug_log(f"💾 增量保存:文本内容 ({len(full_response)} 字符)")
if append_result["handled"]: if append_result["handled"]:
@ -3627,7 +3616,8 @@ async def handle_task_with_sender(terminal: WebTerminal, message, sender, client
web_terminal.context_manager.add_conversation( web_terminal.context_manager.add_conversation(
"assistant", "assistant",
append_content_text, append_content_text,
metadata=append_metadata metadata=append_metadata,
reasoning_content=current_thinking or None
) )
debug_log("💾 增量保存:追加正文快照") debug_log("💾 增量保存:追加正文快照")
@ -3703,7 +3693,8 @@ async def handle_task_with_sender(terminal: WebTerminal, message, sender, client
web_terminal.context_manager.add_conversation( web_terminal.context_manager.add_conversation(
"assistant", "assistant",
modify_content_text, modify_content_text,
metadata=modify_metadata metadata=modify_metadata,
reasoning_content=current_thinking or None
) )
debug_log("💾 增量保存:修改正文快照") debug_log("💾 增量保存:修改正文快照")
@ -3809,9 +3800,6 @@ async def handle_task_with_sender(terminal: WebTerminal, message, sender, client
# 构建助手消息用于API继续对话 # 构建助手消息用于API继续对话
assistant_content_parts = [] assistant_content_parts = []
if current_thinking:
assistant_content_parts.append(f"<think>\n{current_thinking}\n</think>")
if full_response: if full_response:
assistant_content_parts.append(full_response) assistant_content_parts.append(full_response)
elif append_result["handled"] and append_result["assistant_content"]: elif append_result["handled"] and append_result["assistant_content"]: