feat(core): 增强 Plan Agent 支持细粒度 bash 权限和模式切换
- Plan Agent 细粒度 bash 权限:允许只读命令 (ls, grep, git log 等), 禁止危险操作 (rm, mv, git commit 等) - 新增 plan_mode_respond 工具:结构化输出计划、进度和探索状态 - Agent.switchMode() 方法:支持 Build ↔ Plan 模式切换保留对话历史 - WebSocket mode_switch 消息:支持运行时动态切换模式 - 更新 Plan Agent prompt 引导使用 plan_mode_respond 工具
This commit is contained in:
@@ -59,6 +59,9 @@ import {
|
||||
undoTool,
|
||||
} from './checkpoint/index.js';
|
||||
|
||||
// Plan 工具
|
||||
import { planModeRespondTool } from './plan/index.js';
|
||||
|
||||
// 所有工具列表(用于注册)
|
||||
const allToolsWithMetadata: ToolWithMetadata[] = [
|
||||
// 核心工具 (deferLoading: false)
|
||||
@@ -112,6 +115,9 @@ const allToolsWithMetadata: ToolWithMetadata[] = [
|
||||
checkpointListTool,
|
||||
checkpointDiffTool,
|
||||
checkpointRestoreTool,
|
||||
|
||||
// Plan 工具 (deferLoading: true - 仅 Plan 模式)
|
||||
planModeRespondTool,
|
||||
];
|
||||
|
||||
// 注册所有工具到 registry
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Plan 工具模块
|
||||
*
|
||||
* Plan 模式专用工具集合
|
||||
*/
|
||||
|
||||
export { planModeRespondTool } from './plan_mode_respond.js';
|
||||
@@ -0,0 +1,144 @@
|
||||
/**
|
||||
* Plan Mode Respond Tool
|
||||
*
|
||||
* Plan 模式专用响应工具,用于结构化输出计划和进度信息。
|
||||
* 参考 OpenCode 的 plan_mode_respond 实现。
|
||||
*
|
||||
* 特性:
|
||||
* - response: 输出计划内容
|
||||
* - needs_more_exploration: 标记是否需要更多探索
|
||||
* - task_progress: 报告任务进度 (0-100)
|
||||
*/
|
||||
|
||||
import type { ToolWithMetadata } from '../types.js';
|
||||
import type { ToolResult } from '../../types/index.js';
|
||||
|
||||
/**
|
||||
* 生成进度条字符串
|
||||
*/
|
||||
function generateProgressBar(progress: number): string {
|
||||
const total = 20;
|
||||
const filled = Math.round((progress / 100) * total);
|
||||
const empty = total - filled;
|
||||
return '[' + '='.repeat(filled) + ' '.repeat(empty) + ']';
|
||||
}
|
||||
|
||||
/**
|
||||
* Plan Mode 响应工具
|
||||
*/
|
||||
export const planModeRespondTool: ToolWithMetadata = {
|
||||
name: 'plan_mode_respond',
|
||||
description: `Plan 模式专用响应工具。使用此工具输出结构化的计划和进度信息。
|
||||
|
||||
使用场景:
|
||||
- 完成探索后输出实现计划
|
||||
- 报告需要更多探索(设置 needs_more_exploration: true)
|
||||
- 更新任务进度
|
||||
|
||||
参数说明:
|
||||
- response (必需): 计划内容、分析结果或回复
|
||||
- needs_more_exploration (可选): 是否需要继续探索。设为 true 表示当前信息不足
|
||||
- task_progress (可选): 任务完成进度 (0-100)。0=刚开始,50=进行中,100=完成
|
||||
|
||||
示例:
|
||||
1. 输出初步分析:
|
||||
plan_mode_respond({
|
||||
response: "## 现状分析\\n代码结构如下...",
|
||||
needs_more_exploration: true,
|
||||
task_progress: 30
|
||||
})
|
||||
|
||||
2. 输出最终计划:
|
||||
plan_mode_respond({
|
||||
response: "## 实现方案\\n### 步骤 1: ...",
|
||||
needs_more_exploration: false,
|
||||
task_progress: 100
|
||||
})`,
|
||||
|
||||
metadata: {
|
||||
name: 'plan_mode_respond',
|
||||
category: 'agent',
|
||||
description: 'Plan 模式结构化响应工具',
|
||||
keywords: ['plan', 'respond', 'response', 'progress', '计划', '响应', '进度'],
|
||||
deferLoading: true, // 仅在 Plan 模式下加载
|
||||
},
|
||||
|
||||
parameters: {
|
||||
response: {
|
||||
type: 'string',
|
||||
description: '计划内容、分析结果或回复',
|
||||
required: true,
|
||||
},
|
||||
needs_more_exploration: {
|
||||
type: 'boolean',
|
||||
description: '是否需要更多探索。设为 true 表示当前信息不足,需要继续调研',
|
||||
required: false,
|
||||
},
|
||||
task_progress: {
|
||||
type: 'number',
|
||||
description: '任务完成进度 (0-100)。0=刚开始,50=进行中,100=完成',
|
||||
required: false,
|
||||
},
|
||||
},
|
||||
|
||||
async execute(params: Record<string, unknown>): Promise<ToolResult> {
|
||||
const {
|
||||
response,
|
||||
needs_more_exploration = false,
|
||||
task_progress,
|
||||
} = params as {
|
||||
response: string;
|
||||
needs_more_exploration?: boolean;
|
||||
task_progress?: number;
|
||||
};
|
||||
|
||||
// 验证参数
|
||||
if (!response || typeof response !== 'string') {
|
||||
return {
|
||||
success: false,
|
||||
output: '',
|
||||
error: 'response 参数是必需的,且必须是字符串',
|
||||
};
|
||||
}
|
||||
|
||||
if (task_progress !== undefined) {
|
||||
if (typeof task_progress !== 'number' || task_progress < 0 || task_progress > 100) {
|
||||
return {
|
||||
success: false,
|
||||
output: '',
|
||||
error: 'task_progress 必须是 0-100 之间的数字',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// 构建结构化输出
|
||||
const output: string[] = [];
|
||||
|
||||
// 添加进度信息
|
||||
if (task_progress !== undefined) {
|
||||
const progressBar = generateProgressBar(task_progress);
|
||||
output.push(`[进度: ${task_progress}%] ${progressBar}`);
|
||||
output.push('');
|
||||
}
|
||||
|
||||
// 添加响应内容
|
||||
output.push(response);
|
||||
|
||||
// 添加探索状态
|
||||
if (needs_more_exploration) {
|
||||
output.push('');
|
||||
output.push('---');
|
||||
output.push('[状态: 需要更多探索]');
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: output.join('\n'),
|
||||
metadata: {
|
||||
needs_more_exploration,
|
||||
task_progress,
|
||||
type: 'plan_response',
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user