fix: 完善工具约束与项目文档说明
This commit is contained in:
parent
90233690ad
commit
1bda147a6f
@ -1,6 +1,6 @@
|
|||||||
# Repository Guidelines (Code-Verified)
|
# 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`
|
> Scope: `/Users/jojo/Desktop/agents/正在修复中/agents`
|
||||||
|
|
||||||
这份文档基于当前仓库实际代码重写。若与未来代码冲突,以代码为准并及时更新本文档。
|
这份文档基于当前仓库实际代码重写。若与未来代码冲突,以代码为准并及时更新本文档。
|
||||||
@ -12,7 +12,7 @@
|
|||||||
- `server/app.py`: 推荐的 Web 服务入口(封装并转发到 `server/app_legacy.py`)
|
- `server/app.py`: 推荐的 Web 服务入口(封装并转发到 `server/app_legacy.py`)
|
||||||
- `web_server.py`: 兼容入口,已标记 deprecated,但仍可启动
|
- `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/*`)
|
- `core/`: 终端与工具编排(`main_terminal.py`、`web_terminal.py`、`main_terminal_parts/*`)
|
||||||
- `modules/`: 可复用能力模块(terminal/file/memory/sub_agent/upload_security/user 等)
|
- `modules/`: 可复用能力模块(terminal/file/memory/sub_agent/upload_security/user 等)
|
||||||
- `config/`: 配置拆分(`api.py`, `limits.py`, `terminal.py`, `paths.py` ...),由 `config/__init__.py` 聚合并加载 `.env`
|
- `config/`: 配置拆分(`api.py`, `limits.py`, `terminal.py`, `paths.py` ...),由 `config/__init__.py` 聚合并加载 `.env`
|
||||||
|
|||||||
@ -10,13 +10,13 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|||||||
|
|
||||||
### Entry Points
|
### Entry Points
|
||||||
- **CLI模式**: `python main.py` - 启动命令行交互式 Agent
|
- **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
|
### Key Components
|
||||||
|
|
||||||
**core/**
|
**core/**
|
||||||
- `MainTerminal` - CLI 主终端,处理用户输入和 AI 对话循环
|
- `MainTerminal` - CLI 主终端,处理用户输入和 AI 对话循环
|
||||||
- `WebTerminal` - Web 终端,继承 MainTerminal,增加实时推送和对话持久化
|
- `WebTerminal` - Web 终端,继承 MainTerminal,支持轮询任务与实时通道兼容能力
|
||||||
- `tool_config.py` - 定义所有工具的配置和分类
|
- `tool_config.py` - 定义所有工具的配置和分类
|
||||||
|
|
||||||
**modules/**
|
**modules/**
|
||||||
@ -37,7 +37,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|||||||
- `terminal_factory.py` - 终端类型工厂
|
- `terminal_factory.py` - 终端类型工厂
|
||||||
|
|
||||||
**static/**
|
**static/**
|
||||||
- Vue + Socket.IO 前端,包含对话流、终端输出、资源监控面板
|
- Vue 前端(聊天主链路使用 REST 任务轮询,保留 Socket.IO 兼容能力),包含对话流、终端输出、资源监控面板
|
||||||
|
|
||||||
**docker/**
|
**docker/**
|
||||||
- `terminal.Dockerfile` - 终端容器镜像构建配置
|
- `terminal.Dockerfile` - 终端容器镜像构建配置
|
||||||
|
|||||||
@ -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应用
|
│ ├── app.py # Flask应用
|
||||||
│ ├── chat_flow_*.py # 对话流程处理
|
│ ├── chat_flow_*.py # 对话流程处理
|
||||||
│ ├── conversation.py # 对话管理
|
│ ├── conversation.py # 对话管理
|
||||||
│ ├── socket_handlers.py # WebSocket处理
|
│ ├── socket_handlers.py # Socket.IO 连接与兼容事件处理(聊天主链路已迁移到 REST 任务轮询)
|
||||||
│ └── ...
|
│ └── ...
|
||||||
├── modules/ # 功能模块
|
├── modules/ # 功能模块
|
||||||
│ ├── file_manager.py # 文件管理
|
│ ├── file_manager.py # 文件管理
|
||||||
@ -261,7 +261,7 @@ static/src/
|
|||||||
|
|
||||||
### 数据流
|
### 数据流
|
||||||
|
|
||||||
1. **用户输入** → WebSocket/CLI
|
1. **用户输入** → REST API(Web)/CLI
|
||||||
2. **消息处理** → ContextManager 构建上下文
|
2. **消息处理** → ContextManager 构建上下文
|
||||||
3. **API 调用** → DeepSeekClient 发送请求
|
3. **API 调用** → DeepSeekClient 发送请求
|
||||||
4. **流式响应** → 实时解析工具调用
|
4. **流式响应** → 实时解析工具调用
|
||||||
|
|||||||
@ -20,7 +20,7 @@
|
|||||||
},
|
},
|
||||||
"run-command-guide": {
|
"run-command-guide": {
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"run_command", "runcommand", "后台指令", "后台命令", "命令后台运行", "后台执行",
|
"run_command", "runcommand", "后台指令", "后台命令", "命令后台运行", "后台执行","git","下载","仓库",
|
||||||
"command_id", "wait_runcommand_id", "sleep wait_runcommand_id", "run_in_background",
|
"command_id", "wait_runcommand_id", "sleep wait_runcommand_id", "run_in_background",
|
||||||
"超时", "timeout", "终端命令", "shell命令", "执行命令",
|
"超时", "timeout", "终端命令", "shell命令", "执行命令",
|
||||||
"npm run build", "pip install", "brew install", "apt install", "cargo build", "mvn package",
|
"npm run build", "pip install", "brew install", "apt install", "cargo build", "mvn package",
|
||||||
|
|||||||
@ -204,6 +204,19 @@ class MainTerminalToolsExecutionMixin:
|
|||||||
return False
|
return False
|
||||||
return normalized in self._get_visited_read_files()
|
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:
|
def _target_file_exists(self, path: Any) -> bool:
|
||||||
try:
|
try:
|
||||||
valid, _, full_path = self.file_manager._validate_path(str(path or ""))
|
valid, _, full_path = self.file_manager._validate_path(str(path or ""))
|
||||||
@ -267,10 +280,18 @@ class MainTerminalToolsExecutionMixin:
|
|||||||
return "sub-agent-guide"
|
return "sub-agent-guide"
|
||||||
if (
|
if (
|
||||||
tool_name == "run_command"
|
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
|
return None
|
||||||
|
|
||||||
def _check_skill_strict_prerequisite(self, tool_name: str, arguments: Optional[Dict[str, Any]] = None) -> Optional[Dict[str, Any]]:
|
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:
|
else:
|
||||||
mode = "a" if append_flag else "w"
|
mode = "a" if append_flag else "w"
|
||||||
result = self.file_manager.write_file(path, content, mode=mode)
|
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":
|
elif tool_name == "edit_file":
|
||||||
read_guard_error = self._check_read_before_edit_prerequisite(tool_name, arguments)
|
read_guard_error = self._check_read_before_edit_prerequisite(tool_name, arguments)
|
||||||
|
|||||||
@ -97,6 +97,9 @@ class MainTerminalToolsPolicyMixin:
|
|||||||
# Skill 强约束开关
|
# Skill 强约束开关
|
||||||
self.skill_strict_terminal_enabled = bool(effective_config.get("skill_strict_terminal_enabled", False))
|
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_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(
|
self.skill_strict_run_command_background_enabled = bool(
|
||||||
effective_config.get("skill_strict_run_command_background_enabled", False)
|
effective_config.get("skill_strict_run_command_background_enabled", False)
|
||||||
)
|
)
|
||||||
|
|||||||
@ -21,6 +21,16 @@ export default defineConfig({
|
|||||||
// 统一静态资源基路径,避免动态 import 走到 /assets/* 导致 404
|
// 统一静态资源基路径,避免动态 import 走到 /assets/* 导致 404
|
||||||
base: '/static/dist/',
|
base: '/static/dist/',
|
||||||
plugins: [vue()],
|
plugins: [vue()],
|
||||||
|
css: {
|
||||||
|
preprocessorOptions: {
|
||||||
|
scss: {
|
||||||
|
silenceDeprecations: ['legacy-js-api']
|
||||||
|
},
|
||||||
|
sass: {
|
||||||
|
silenceDeprecations: ['legacy-js-api']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
build: {
|
build: {
|
||||||
outDir: 'static/dist',
|
outDir: 'static/dist',
|
||||||
emptyOutDir: false,
|
emptyOutDir: false,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user