From 1bda147a6f4e1ce5eea1dda1d7cbfb10a449050f Mon Sep 17 00:00:00 2001 From: JOJO <1498581755@qq.com> Date: Fri, 10 Apr 2026 14:33:41 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=AE=8C=E5=96=84=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E7=BA=A6=E6=9D=9F=E4=B8=8E=E9=A1=B9=E7=9B=AE=E6=96=87=E6=A1=A3?= =?UTF-8?q?=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGENTS.md | 4 +-- CLAUDE.md | 6 ++-- README.md | 6 ++-- config/skill_hints.json | 2 +- core/main_terminal_parts/tools_execution.py | 31 +++++++++++++++++++-- core/main_terminal_parts/tools_policy.py | 3 ++ vite.config.ts | 10 +++++++ 7 files changed, 50 insertions(+), 12 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 8828ff1..5253f20 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,6 +1,6 @@ # Repository Guidelines (Code-Verified) -> Last verified against current codebase: 2026-04-06 +> Last verified against current codebase: 2026-04-10 > Scope: `/Users/jojo/Desktop/agents/正在修复中/agents` 这份文档基于当前仓库实际代码重写。若与未来代码冲突,以代码为准并及时更新本文档。 @@ -12,7 +12,7 @@ - `server/app.py`: 推荐的 Web 服务入口(封装并转发到 `server/app_legacy.py`) - `web_server.py`: 兼容入口,已标记 deprecated,但仍可启动 - **后端核心目录** - - `server/`: Flask + Socket.IO 业务主线(chat flow、conversation、tasks、status、api_v1 等) + - `server/`: Flask 业务主线(chat/task 以 REST 任务轮询为主,Socket.IO 主要用于兼容与实时辅助通道) - `core/`: 终端与工具编排(`main_terminal.py`、`web_terminal.py`、`main_terminal_parts/*`) - `modules/`: 可复用能力模块(terminal/file/memory/sub_agent/upload_security/user 等) - `config/`: 配置拆分(`api.py`, `limits.py`, `terminal.py`, `paths.py` ...),由 `config/__init__.py` 聚合并加载 `.env` diff --git a/CLAUDE.md b/CLAUDE.md index c551ddf..ac2788a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -10,13 +10,13 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ### Entry Points - **CLI模式**: `python main.py` - 启动命令行交互式 Agent -- **Web模式**: `python web_server.py` - 启动 Flask + Socket.IO Web 服务器 (默认端口 8091) +- **Web模式**: `python web_server.py` - 启动 Flask Web 服务器(主链路为 REST 任务轮询,默认端口 8091) ### Key Components **core/** - `MainTerminal` - CLI 主终端,处理用户输入和 AI 对话循环 -- `WebTerminal` - Web 终端,继承 MainTerminal,增加实时推送和对话持久化 +- `WebTerminal` - Web 终端,继承 MainTerminal,支持轮询任务与实时通道兼容能力 - `tool_config.py` - 定义所有工具的配置和分类 **modules/** @@ -37,7 +37,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co - `terminal_factory.py` - 终端类型工厂 **static/** -- Vue + Socket.IO 前端,包含对话流、终端输出、资源监控面板 +- Vue 前端(聊天主链路使用 REST 任务轮询,保留 Socket.IO 兼容能力),包含对话流、终端输出、资源监控面板 **docker/** - `terminal.Dockerfile` - 终端容器镜像构建配置 diff --git a/README.md b/README.md index 399f9ac..9e90af5 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ ### 🌐 双端架构 -- **Web 模式**: 基于 Flask + Socket.IO + Vue 3 的现代化 Web 界面 +- **Web 模式**: 基于 Flask + REST 任务轮询 + Vue 3 的现代化 Web 界面(保留 Socket.IO 兼容通道) - 实时消息流式传输 - 多对话管理 - 可视化文件管理器 @@ -211,7 +211,7 @@ agents/ │ ├── app.py # Flask应用 │ ├── chat_flow_*.py # 对话流程处理 │ ├── conversation.py # 对话管理 -│ ├── socket_handlers.py # WebSocket处理 +│ ├── socket_handlers.py # Socket.IO 连接与兼容事件处理(聊天主链路已迁移到 REST 任务轮询) │ └── ... ├── modules/ # 功能模块 │ ├── file_manager.py # 文件管理 @@ -261,7 +261,7 @@ static/src/ ### 数据流 -1. **用户输入** → WebSocket/CLI +1. **用户输入** → REST API(Web)/CLI 2. **消息处理** → ContextManager 构建上下文 3. **API 调用** → DeepSeekClient 发送请求 4. **流式响应** → 实时解析工具调用 diff --git a/config/skill_hints.json b/config/skill_hints.json index 9a6f987..24693fb 100644 --- a/config/skill_hints.json +++ b/config/skill_hints.json @@ -20,7 +20,7 @@ }, "run-command-guide": { "keywords": [ - "run_command", "runcommand", "后台指令", "后台命令", "命令后台运行", "后台执行", + "run_command", "runcommand", "后台指令", "后台命令", "命令后台运行", "后台执行","git","下载","仓库", "command_id", "wait_runcommand_id", "sleep wait_runcommand_id", "run_in_background", "超时", "timeout", "终端命令", "shell命令", "执行命令", "npm run build", "pip install", "brew install", "apt install", "cargo build", "mvn package", diff --git a/core/main_terminal_parts/tools_execution.py b/core/main_terminal_parts/tools_execution.py index d0ac5fd..546b291 100644 --- a/core/main_terminal_parts/tools_execution.py +++ b/core/main_terminal_parts/tools_execution.py @@ -204,6 +204,19 @@ class MainTerminalToolsExecutionMixin: return False return normalized in self._get_visited_read_files() + def _mark_file_as_read_visited(self, path: Any) -> None: + normalized = self._normalize_tool_path(path) + if not normalized: + return + visited = self._get_visited_read_files() + if normalized in visited: + return + visited.add(normalized) + self.context_manager._set_meta_flag( + self._file_read_meta_key(), + sorted(visited), + ) + def _target_file_exists(self, path: Any) -> bool: try: valid, _, full_path = self.file_manager._validate_path(str(path or "")) @@ -267,10 +280,18 @@ class MainTerminalToolsExecutionMixin: return "sub-agent-guide" if ( tool_name == "run_command" - and bool(getattr(self, "skill_strict_run_command_background_enabled", False)) - and bool((arguments or {}).get("run_in_background", False)) ): - return "run-command-guide" + run_in_background = bool((arguments or {}).get("run_in_background", False)) + if ( + run_in_background + and bool(getattr(self, "skill_strict_run_command_background_enabled", False)) + ): + return "run-command-guide" + if ( + (not run_in_background) + and bool(getattr(self, "skill_strict_run_command_foreground_enabled", False)) + ): + return "run-command-guide" return None def _check_skill_strict_prerequisite(self, tool_name: str, arguments: Optional[Dict[str, Any]] = None) -> Optional[Dict[str, Any]]: @@ -695,6 +716,10 @@ class MainTerminalToolsExecutionMixin: else: mode = "a" if append_flag else "w" result = self.file_manager.write_file(path, content, mode=mode) + if isinstance(result, dict) and result.get("success"): + # write_file 成功后,该文件视作当前会话已“接触”, + # 允许后续继续 write/edit 而不再触发先读拦截。 + self._mark_file_as_read_visited(result.get("path") or path) elif tool_name == "edit_file": read_guard_error = self._check_read_before_edit_prerequisite(tool_name, arguments) diff --git a/core/main_terminal_parts/tools_policy.py b/core/main_terminal_parts/tools_policy.py index 5019a1d..7364130 100644 --- a/core/main_terminal_parts/tools_policy.py +++ b/core/main_terminal_parts/tools_policy.py @@ -97,6 +97,9 @@ class MainTerminalToolsPolicyMixin: # Skill 强约束开关 self.skill_strict_terminal_enabled = bool(effective_config.get("skill_strict_terminal_enabled", False)) self.skill_strict_sub_agent_enabled = bool(effective_config.get("skill_strict_sub_agent_enabled", False)) + self.skill_strict_run_command_foreground_enabled = bool( + effective_config.get("skill_strict_run_command_foreground_enabled", False) + ) self.skill_strict_run_command_background_enabled = bool( effective_config.get("skill_strict_run_command_background_enabled", False) ) diff --git a/vite.config.ts b/vite.config.ts index 3761c63..cf2fd3a 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -21,6 +21,16 @@ export default defineConfig({ // 统一静态资源基路径,避免动态 import 走到 /assets/* 导致 404 base: '/static/dist/', plugins: [vue()], + css: { + preprocessorOptions: { + scss: { + silenceDeprecations: ['legacy-js-api'] + }, + sass: { + silenceDeprecations: ['legacy-js-api'] + } + } + }, build: { outDir: 'static/dist', emptyOutDir: false,