feat: plan_track工具卡片增加自动确认下拉框,支持跳过手动确认步骤

This commit is contained in:
thzxx
2026-07-11 16:48:32 +08:00
parent a406216e5e
commit cf96afad1e
5 changed files with 64 additions and 2 deletions
+12
View File
@@ -585,6 +585,12 @@ async function handleRetry(): Promise<void> {
}, },
onConfirmTool: async (call) => showToolConfirm(call), onConfirmTool: async (call) => showToolConfirm(call),
onPlanReady: async (plan: string, steps: string[]) => { onPlanReady: async (plan: string, steps: string[]) => {
// 检查是否启用了自动确认计划
const autoConfirm = state.get<boolean>('planAutoConfirm', false);
if (autoConfirm) {
logInfo('Plan Mode: 自动确认计划(用户已启用自动确认)');
return true;
}
try { try {
const { showHtmlConfirm } = await import('./prompt-modal.js'); const { showHtmlConfirm } = await import('./prompt-modal.js');
const html = buildPlanConfirmHtml(plan, steps); const html = buildPlanConfirmHtml(plan, steps);
@@ -1305,6 +1311,12 @@ async function sendMessageWithAgentLoop(text: string, currentSession: ChatSessio
}, },
/** Plan Mode — 计划生成后等待用户确认(Markdown 渲染) */ /** Plan Mode — 计划生成后等待用户确认(Markdown 渲染) */
onPlanReady: async (plan: string, steps: string[]) => { onPlanReady: async (plan: string, steps: string[]) => {
// 检查是否启用了自动确认计划
const autoConfirm = state.get<boolean>('planAutoConfirm', false);
if (autoConfirm) {
logInfo('Plan Mode: 自动确认计划(用户已启用自动确认)');
return true;
}
try { try {
const { showHtmlConfirm } = await import('./prompt-modal.js'); const { showHtmlConfirm } = await import('./prompt-modal.js');
const html = buildPlanConfirmHtml(plan, steps); const html = buildPlanConfirmHtml(plan, steps);
+36
View File
@@ -32,6 +32,18 @@ function updateToolBadge(toolName: string, mode: ToolMode): void {
badge.className = `tool-card-badge ${info.cls}`; badge.className = `tool-card-badge ${info.cls}`;
} }
function updatePlanBadge(autoConfirm: boolean): void {
const badge = modalEl.querySelector('#badge_plan_track') as HTMLElement;
if (!badge) return;
if (autoConfirm) {
badge.textContent = '自动确认';
badge.className = 'tool-card-badge auto';
} else {
badge.textContent = '需确认';
badge.className = 'tool-card-badge confirm';
}
}
export function initToolsModal(): void { export function initToolsModal(): void {
modalEl = document.querySelector('#toolsModal')!; modalEl = document.querySelector('#toolsModal')!;
@@ -65,6 +77,22 @@ export function initToolsModal(): void {
logInfo(`工具模式切换: ${toolName}${mode}`); logInfo(`工具模式切换: ${toolName}${mode}`);
}); });
}); });
// Plan 确认模式下拉框
const planSelect = modalEl.querySelector<HTMLSelectElement>('#select_plan_confirm');
if (planSelect) {
planSelect.addEventListener('change', async () => {
const autoConfirm = planSelect.value === 'auto';
const db = state.get<ChatDB | null>(KEYS.DB);
state.set('planAutoConfirm', autoConfirm);
if (db) await db.saveSetting('planAutoConfirm', autoConfirm);
updatePlanBadge(autoConfirm);
showToast(`计划确认:${autoConfirm ? '自动确认' : '需确认'}`, 'info');
logInfo(`计划确认模式切换: → ${autoConfirm ? 'auto' : 'confirm'}`);
});
}
} }
export function openToolsModal(): void { export function openToolsModal(): void {
@@ -79,6 +107,14 @@ export function openToolsModal(): void {
updateToolBadge(toolName, mode); updateToolBadge(toolName, mode);
}); });
// 同步 Plan 确认模式下拉框
const planSelect = modalEl.querySelector<HTMLSelectElement>('#select_plan_confirm');
if (planSelect) {
const autoConfirm = state.get<boolean>('planAutoConfirm', false);
planSelect.value = autoConfirm ? 'auto' : 'confirm';
updatePlanBadge(autoConfirm);
}
modalEl.style.display = ''; modalEl.style.display = '';
} }
+8 -1
View File
@@ -705,8 +705,15 @@
<div class="tool-card-desc">哈希计算(MD5/SHA1/SHA256/SHA384/SHA512</div> <div class="tool-card-desc">哈希计算(MD5/SHA1/SHA256/SHA384/SHA512</div>
</div> </div>
<div class="tool-card"> <div class="tool-card">
<div class="tool-card-header"><span class="tool-card-icon">📋</span><span class="tool-card-name">plan_track</span><span class="tool-card-badge plan-mode">Plan</span></div> <div class="tool-card-header"><span class="tool-card-icon">📋</span><span class="tool-card-name">plan_track</span><span class="tool-card-badge confirm" id="badge_plan_track">需确认</span></div>
<div class="tool-card-desc">Plan 模式专属:追踪执行进度,标记/查看步骤完成状态</div> <div class="tool-card-desc">Plan 模式专属:追踪执行进度,标记/查看步骤完成状态</div>
<div style="margin-top:6px;display:flex;align-items:center;gap:8px;">
<label style="margin:0;font-size:11px;color:var(--text-secondary);">计划确认:</label>
<select id="select_plan_confirm" style="font-size:11px;padding:2px 6px;background:var(--bg-card);color:var(--text-primary);border:1px solid var(--border-default);border-radius:4px;">
<option value="confirm">需确认</option>
<option value="auto">自动确认</option>
</select>
</div>
</div> </div>
</div> </div>
</div> </div>
+6
View File
@@ -460,6 +460,12 @@ async function init(): Promise<void> {
} }
} }
// ── Plan 自动确认设置 ──
{
const planAutoConfirm = await db.getSetting<boolean>('planAutoConfirm', false);
state.set('planAutoConfirm', planAutoConfirm);
}
// ── MCP 工具注册 ── // ── MCP 工具注册 ──
await startAllMCPServers(); await startAllMCPServers();
await refreshMCPTools(); await refreshMCPTools();
+2 -1
View File
@@ -289,7 +289,8 @@ export type StateKey =
| '_planResumeData' | '_planResumeData'
| '_lastPlanStatus' | '_lastPlanStatus'
| '_planLastInjectedDone' | '_planLastInjectedDone'
| 'toolModes'; | 'toolModes'
| 'planAutoConfirm';
// ═══════════════════════════════════════════════════════════ // ═══════════════════════════════════════════════════════════
// Tool Calling 类型 // Tool Calling 类型