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消息内容
assistant_content_parts = []
# 添加思考内容
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 "已完成操作。"
# 1. 构建助手回复内容(思考内容通过 reasoning_content 存储)
assistant_content = final_response or "已完成操作。"
# 2. 保存assistant消息包含tool_calls但不包含结果
self.context_manager.add_conversation(
"assistant",
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消息

View File

@ -77,7 +77,7 @@
- `tool`:卡片包含工具名、图标(`TOOL_ICON_MAP`),参数快照/状态消息/结果JSON、plain text、命令输出 `pre`),流式时加 loading 条;`action.tool.awaiting_content` 控制“等待正文”占位。工具 `status` 颜色区分 `preparing/running/completed/error`
- `append_payload`/`modify_payload`:专门显示文件路径、强制标志、成功/失败行数。
- `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 行为。
#### 3.3 输入区(`.compact-input-area`

View File

@ -1387,23 +1387,7 @@ const appOptions = {
}
const content = message.content || '';
let 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();
}
const reasoningText = (message.reasoning_content || '').trim();
if (reasoningText) {
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 containsAppendMarkers = /<<<\s*(APPEND|MODIFY)/i.test(content || '') || /<<<END_\s*(APPEND|MODIFY)>>>/i.test(content || '');
let textContent = content;
if (!message.reasoning_content) {
textContent = textContent
.replace(/<think>[\s\S]*?<\/think>/g, '')
.replace(/<thinking>[\s\S]*?<\/thinking>/g, '')
.trim();
} else {
textContent = textContent.trim();
}
const textContent = content.trim();
if (appendPayloadMeta) {
currentAssistantMessage.actions.push({

View File

@ -592,25 +592,15 @@ class MainTerminal:
# ===== 统一保存到对话历史(关键修复) =====
# 1. 构建完整的assistant消息内容
assistant_content_parts = []
# 添加思考内容
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 "已完成操作。"
# 1. 构建助手回复内容(思考内容通过 reasoning_content 保存)
assistant_content = final_response or "已完成操作。"
# 2. 保存assistant消息包含tool_calls但不包含结果
self.context_manager.add_conversation(
"assistant",
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消息

View File

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

View File

@ -409,10 +409,6 @@ class DeepSeekClient:
# 构建助手消息 - 始终包含所有收集到的内容
assistant_content_parts = []
# 添加思考内容(如果有)
if current_thinking:
assistant_content_parts.append(f"<think>\n{current_thinking}\n</think>")
# 添加正式回复内容(如果有)
if 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', {})
# 增量保存相关变量
has_saved_thinking = False # 是否已保存思考内容
accumulated_response = "" # 累积的响应内容
is_first_iteration = True # 是否是第一次迭代
@ -3347,13 +3346,6 @@ async def handle_task_with_sender(terminal: WebTerminal, message, sender, client
thinking_ended = True
sender('thinking_end', {'full_content': current_thinking})
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_append = bool(pending_append) or bool(getattr(web_terminal, "pending_append_request", None))
@ -3599,13 +3591,6 @@ async def handle_task_with_sender(terminal: WebTerminal, message, sender, client
if in_thinking and not thinking_ended:
sender('thinking_end', {'full_content': current_thinking})
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事件被发送
if text_started and text_has_content and not append_result["handled"] and not modify_result["handled"]:
@ -3617,7 +3602,11 @@ async def handle_task_with_sender(terminal: WebTerminal, message, sender, client
# ===== 增量保存:保存当前轮次的文本内容 =====
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)} 字符)")
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(
"assistant",
append_content_text,
metadata=append_metadata
metadata=append_metadata,
reasoning_content=current_thinking or None
)
debug_log("💾 增量保存:追加正文快照")
@ -3703,7 +3693,8 @@ async def handle_task_with_sender(terminal: WebTerminal, message, sender, client
web_terminal.context_manager.add_conversation(
"assistant",
modify_content_text,
metadata=modify_metadata
metadata=modify_metadata,
reasoning_content=current_thinking or None
)
debug_log("💾 增量保存:修改正文快照")
@ -3809,9 +3800,6 @@ async def handle_task_with_sender(terminal: WebTerminal, message, sender, client
# 构建助手消息用于API继续对话
assistant_content_parts = []
if current_thinking:
assistant_content_parts.append(f"<think>\n{current_thinking}\n</think>")
if full_response:
assistant_content_parts.append(full_response)
elif append_result["handled"] and append_result["assistant_content"]: