feat: 升级至 v0.2.1 — 流式渲染修复、安全增强、工具自动执行

流式渲染修复:
- runId 机制防止 abort 后旧流事件污染新 run
- run lock 防止并发 run 污染引擎状态
- abort race 提前退出工具执行等待
- TERMINATED 状态通过 stateChange 发射
- tool_call_delta 流式参数拼接 + pending 占位替换
- 首轮卡片创建路径统一,traceStep 按 ID 精确匹配
- compressed 事件转发为 toast 通知

安全增强:
- ConfirmationHook 支持持久化自动执行(跨会话)
- 设置面板新增自动执行工具管理 UI
- SandboxManager 双重安全校验 fail-closed
- 审计日志链式哈希防篡改
- PromptInjectionDefender 中文注入标记清理
- scanCode 28 模式 + base64/$() 检测
- validatePath realpathSync 防符号链接逃逸
- code-search 使用 execFile 防命令注入

新增工具:
- file_editor、code_search、task_manager、diff_viewer

其他:
- Agent Loop 加 PARSING/REFLECTING 状态 + 指数退避重试
- MemoryManager TF-IDF 语义检索
- run_command Windows 中文编码修复(chcp 65001)
- 版本号 0.2.0 → 0.2.1
This commit is contained in:
thzxx
2026-07-12 12:54:52 +08:00
parent 469f53b623
commit 3c5aea8fb7
41 changed files with 4972 additions and 423 deletions
+6 -9
View File
@@ -17,7 +17,6 @@ const MAX_RESULT_CHARS = 50_000;
export class ToolRegistry {
private tools = new Map<string, ToolRegistryEntry>();
private disabledTools = new Set<string>();
/** 注册内置工具 */
registerBuiltin(tool: IMetonaTool): void {
@@ -51,14 +50,13 @@ export class ToolRegistry {
get(name: string): IMetonaTool | undefined {
const entry = this.tools.get(name);
if (!entry?.enabled) return undefined;
if (this.disabledTools.has(name)) return undefined;
return entry.tool;
}
/** 列出所有已启用工具的定义 */
listTools(): MetonaToolDef[] {
return Array.from(this.tools.values())
.filter((e) => e.enabled && !this.disabledTools.has(e.tool.definition.name))
.filter((e) => e.enabled)
.map((e) => e.tool.definition);
}
@@ -66,16 +64,15 @@ export class ToolRegistry {
listAllTools(): Array<MetonaToolDef & { enabled: boolean }> {
return Array.from(this.tools.values()).map((e) => ({
...e.tool.definition,
enabled: e.enabled && !this.disabledTools.has(e.tool.definition.name),
enabled: e.enabled,
}));
}
/** 设置工具启用/禁用状态(供 IPC tools:toggle 调用) */
setToolEnabled(name: string, enabled: boolean): void {
if (enabled) {
this.disabledTools.delete(name);
} else {
this.disabledTools.add(name);
const entry = this.tools.get(name);
if (entry) {
entry.enabled = enabled;
}
}
@@ -151,6 +148,6 @@ export class ToolRegistry {
/** 获取工具数量 */
get size(): number {
return Array.from(this.tools.values()).filter((e) => e.enabled && !this.disabledTools.has(e.tool.definition.name)).length;
return Array.from(this.tools.values()).filter((e) => e.enabled).length;
}
}