v0.16.11: Plan Mode 最小必要性清理 — 删除进度注入和死代码链
删除项: - Plan Mode 每轮进度注入代码(formatPlanStatus() 主动注入到 user 消息) AI 改为从 plan_track mark_done/status 工具返回值自行推断进度 - _lastPlanStatus 死代码链(agent-engine.ts 2 处保存 + input-area.ts 2 处清空) 保存后从未被读取使用,纯死代码 - formatPlanStatus import(已无调用点) - _lastPlanStatus 和 _planLastInjectedDone StateKey 声明 简化项: - "计划已批准"消息移除 (web_search、write_file 等) 工具名列举,让 AI 自行判断 修正项: - L2431 注释从"AI 可通过 formatPlanStatus() 看到剩余步骤" 改为"AI 通过 plan_track mark_done/status 的工具返回值获知进度" 总计 8 文件变更
This commit is contained in:
@@ -14,7 +14,7 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="https://img.shields.io/badge/version-v0.16.10-E8734A?style=flat-square" alt="version">
|
<img src="https://img.shields.io/badge/version-v0.16.11-E8734A?style=flat-square" alt="version">
|
||||||
<img src="https://img.shields.io/badge/electron-33+-47848F?style=flat-square&logo=electron" alt="electron">
|
<img src="https://img.shields.io/badge/electron-33+-47848F?style=flat-square&logo=electron" alt="electron">
|
||||||
<img src="https://img.shields.io/badge/typescript-5.7+-3178C6?style=flat-square&logo=typescript" alt="typescript">
|
<img src="https://img.shields.io/badge/typescript-5.7+-3178C6?style=flat-square&logo=typescript" alt="typescript">
|
||||||
<img src="https://img.shields.io/badge/license-MIT-green?style=flat-square" alt="license">
|
<img src="https://img.shields.io/badge/license-MIT-green?style=flat-square" alt="license">
|
||||||
@@ -253,7 +253,7 @@ npm start
|
|||||||
ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ npm run dist
|
ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ npm run dist
|
||||||
```
|
```
|
||||||
|
|
||||||
产出:`release/Metona Ollama Setup v0.16.10.exe`
|
产出:`release/Metona Ollama Setup v0.16.11.exe`
|
||||||
|
|
||||||
## 🛠️ 常用命令
|
## 🛠️ 常用命令
|
||||||
|
|
||||||
@@ -501,7 +501,7 @@ npm start
|
|||||||
ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ npm run dist
|
ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ npm run dist
|
||||||
```
|
```
|
||||||
|
|
||||||
Output: `release/Metona Ollama Setup v0.16.10.exe`
|
Output: `release/Metona Ollama Setup v0.16.11.exe`
|
||||||
|
|
||||||
## 🛠️ Common Commands
|
## 🛠️ Common Commands
|
||||||
|
|
||||||
|
|||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "metona-ollama-desktop",
|
"name": "metona-ollama-desktop",
|
||||||
"version": "0.16.10",
|
"version": "0.16.11",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "metona-ollama-desktop",
|
"name": "metona-ollama-desktop",
|
||||||
"version": "0.16.10",
|
"version": "0.16.11",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ffmpeg-static": "^5.2.0",
|
"ffmpeg-static": "^5.2.0",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "metona-ollama-desktop",
|
"name": "metona-ollama-desktop",
|
||||||
"version": "0.16.10",
|
"version": "0.16.11",
|
||||||
"description": "Metona Ollama - TypeScript + Electron 桌面 AI 聊天客户端",
|
"description": "Metona Ollama - TypeScript + Electron 桌面 AI 聊天客户端",
|
||||||
"main": "dist/main/main.js",
|
"main": "dist/main/main.js",
|
||||||
"author": "thzxx",
|
"author": "thzxx",
|
||||||
|
|||||||
+1
-1
@@ -101,7 +101,7 @@ export function createMenu(): void {
|
|||||||
dialog.showMessageBox(mainWindow!, {
|
dialog.showMessageBox(mainWindow!, {
|
||||||
type: 'info',
|
type: 'info',
|
||||||
title: '关于 Metona Ollama',
|
title: '关于 Metona Ollama',
|
||||||
message: 'Metona Ollama Desktop v0.16.10',
|
message: 'Metona Ollama Desktop v0.16.11',
|
||||||
detail: 'TypeScript + Electron Ollama AI 聊天客户端\n\nhttps://gitee.com/thzxx/metona-ollama',
|
detail: 'TypeScript + Electron Ollama AI 聊天客户端\n\nhttps://gitee.com/thzxx/metona-ollama',
|
||||||
icon: getIconPath()
|
icon: getIconPath()
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -669,8 +669,6 @@ async function handleRetry(): Promise<void> {
|
|||||||
// renderMessages 统一渲染 session 数据,先清掉流式 placeholder 避免 DOM 重复
|
// renderMessages 统一渲染 session 数据,先清掉流式 placeholder 避免 DOM 重复
|
||||||
clearMessagesDOM();
|
clearMessagesDOM();
|
||||||
renderMessages();
|
renderMessages();
|
||||||
// ── 消费 _lastPlanStatus(不再保存为 session 消息,避免 system 消息渲染到聊天界面)──
|
|
||||||
state.set('_lastPlanStatus', '');
|
|
||||||
await saveCurrentSession();
|
await saveCurrentSession();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -1372,9 +1370,6 @@ async function sendMessageWithAgentLoop(text: string, currentSession: ChatSessio
|
|||||||
// 先移除流式 placeholder 再 renderMessages,避免未渲染(纯文本)和已渲染(markdown)两个卡片同时存在
|
// 先移除流式 placeholder 再 renderMessages,避免未渲染(纯文本)和已渲染(markdown)两个卡片同时存在
|
||||||
removeCurrentPlaceholder();
|
removeCurrentPlaceholder();
|
||||||
renderMessages();
|
renderMessages();
|
||||||
|
|
||||||
// ── 消费 _lastPlanStatus(不再保存为 session 消息,避免 system 消息渲染到聊天界面)──
|
|
||||||
state.set('_lastPlanStatus', '');
|
|
||||||
await saveCurrentSession();
|
await saveCurrentSession();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
<div class="header-left">
|
<div class="header-left">
|
||||||
<img class="logo" src="./assets/icons/llama.png" alt="logo" />
|
<img class="logo" src="./assets/icons/llama.png" alt="logo" />
|
||||||
<span class="app-title">Metona Ollama</span>
|
<span class="app-title">Metona Ollama</span>
|
||||||
<span class="app-version">v0.16.10</span>
|
<span class="app-version">v0.16.11</span>
|
||||||
<button class="icon-btn help-btn" id="btnHelp" title="使用帮助">
|
<button class="icon-btn help-btn" id="btnHelp" title="使用帮助">
|
||||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
<circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/>
|
<circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/>
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import {
|
|||||||
needsConfirmation,
|
needsConfirmation,
|
||||||
initPlanTracker,
|
initPlanTracker,
|
||||||
getPlanTracker,
|
getPlanTracker,
|
||||||
formatPlanStatus,
|
|
||||||
clearPlanTracker,
|
clearPlanTracker,
|
||||||
} from './tool-registry.js';
|
} from './tool-registry.js';
|
||||||
import {
|
import {
|
||||||
@@ -1484,20 +1483,8 @@ async function handleThinking(
|
|||||||
ctx.thinking = '';
|
ctx.thinking = '';
|
||||||
ctx.toolCalls.length = 0;
|
ctx.toolCalls.length = 0;
|
||||||
|
|
||||||
// ── Plan Mode 执行进度注入 — 仅在进度变化时注入,避免每轮重复 ──
|
// Plan Mode 进度注入已删除 — AI 调用 plan_track mark_done 后工具返回值已含进度,
|
||||||
if (ctx.mode === 'plan' && ctx.loopCount >= 1) {
|
// AI 应从上下文自行推断或主动调用 plan_track status 查询
|
||||||
const tracker = getPlanTracker();
|
|
||||||
if (tracker.active && tracker.steps.length > 0) {
|
|
||||||
const lastDone = state.get<number>('_planLastInjectedDone', -1);
|
|
||||||
if (tracker.done !== lastDone) {
|
|
||||||
const status = formatPlanStatus();
|
|
||||||
if (status) {
|
|
||||||
ctx.messages.push({ role: 'user', content: status, ephemeral: true });
|
|
||||||
state.set('_planLastInjectedDone', tracker.done);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const abortController = registerAbortController();
|
const abortController = registerAbortController();
|
||||||
|
|
||||||
@@ -2371,7 +2358,7 @@ async function handleReflecting(
|
|||||||
}
|
}
|
||||||
ctx.messages.push({
|
ctx.messages.push({
|
||||||
role: 'user',
|
role: 'user',
|
||||||
content: '计划已批准。现在开始执行——请直接调用工具(web_search、write_file 等)来完成每一步。不要描述计划,直接行动。',
|
content: '计划已批准。现在开始执行——请直接调用工具来完成每一步。不要描述计划,直接行动。',
|
||||||
ephemeral: true,
|
ephemeral: true,
|
||||||
});
|
});
|
||||||
transition(ctx, S.THINKING);
|
transition(ctx, S.THINKING);
|
||||||
@@ -2440,17 +2427,10 @@ async function handleReflecting(
|
|||||||
|
|
||||||
// Completion Gate 已删除 — 所有检查项(notThinking/toolResultReview/contextEfficiency/planModeCompletion)均已删除
|
// Completion Gate 已删除 — 所有检查项(notThinking/toolResultReview/contextEfficiency/planModeCompletion)均已删除
|
||||||
// AI 应基于工具结果和上下文自行判断是否需要继续或完成
|
// AI 应基于工具结果和上下文自行判断是否需要继续或完成
|
||||||
// Plan Mode 下 AI 可通过 formatPlanStatus() 看到剩余步骤,应自行决定是否继续
|
// Plan Mode 下 AI 通过 plan_track mark_done/status 的工具返回值获知进度,应自行决定是否继续
|
||||||
|
|
||||||
logInfo('模型停止工具调用 → ReAct Agent Loop 结束');
|
logInfo('模型停止工具调用 → ReAct Agent Loop 结束');
|
||||||
// ── 保存 Plan Mode 最终进度到状态,供下一轮 Loop 注入历史 ──
|
|
||||||
// 注意:不在此处 clearPlanTracker,由 finally 块统一处理(保存 resumeData 后清理)
|
// 注意:不在此处 clearPlanTracker,由 finally 块统一处理(保存 resumeData 后清理)
|
||||||
if (ctx.mode === 'plan') {
|
|
||||||
const tracker = getPlanTracker();
|
|
||||||
if (tracker.active && tracker.steps.length > 0) {
|
|
||||||
state.set('_lastPlanStatus', formatPlanStatus());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── 自动记忆提取(异步,不阻塞用户看到回复)──
|
// ── 自动记忆提取(异步,不阻塞用户看到回复)──
|
||||||
// P3 #12 修复:在 cleanupAbortController 之前捕获 signal 引用,避免竞态
|
// P3 #12 修复:在 cleanupAbortController 之前捕获 signal 引用,避免竞态
|
||||||
@@ -2730,7 +2710,6 @@ default:
|
|||||||
savedAt: Date.now(),
|
savedAt: Date.now(),
|
||||||
};
|
};
|
||||||
state.set('_planResumeData', resumeData);
|
state.set('_planResumeData', resumeData);
|
||||||
state.set('_lastPlanStatus', formatPlanStatus());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clearPlanTracker();
|
clearPlanTracker();
|
||||||
|
|||||||
Vendored
-2
@@ -288,8 +288,6 @@ export type StateKey =
|
|||||||
| 'loopWatchdogMs'
|
| 'loopWatchdogMs'
|
||||||
| '_planTracker'
|
| '_planTracker'
|
||||||
| '_planResumeData'
|
| '_planResumeData'
|
||||||
| '_lastPlanStatus'
|
|
||||||
| '_planLastInjectedDone'
|
|
||||||
| 'globalToolMode'
|
| 'globalToolMode'
|
||||||
| 'planAutoConfirm';
|
| 'planAutoConfirm';
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user