- Split server/chat.py, server/status.py, server/tasks.py into sub-packages
- Split utils/context_manager.py, utils/conversation_manager.py into mixin packages
- Split modules/file_manager.py, persistent_terminal.py, terminal_ops.py, mcp_client_manager.py into packages
- Split core/main_terminal_parts/context.py into base + mixins
- Split static/src/app/methods/{ui,message,upload,taskPolling,conversation} into sub-modules
- Fix flattened method exports, dynamic import paths, missing cross-module imports
- Add missing permission/network/execution mode constants and _PERMISSION_MODE_LABEL
- Update AGENTS.md, CLAUDE.md and project memories to reflect new structure
129 lines
4.7 KiB
Python
129 lines
4.7 KiB
Python
import asyncio
|
|
import json
|
|
from pathlib import Path
|
|
from typing import Any, Dict, List, Optional, Set
|
|
|
|
try:
|
|
from config import (
|
|
OUTPUT_FORMATS, DATA_DIR, PROMPTS_DIR, NEED_CONFIRMATION,
|
|
MAX_TERMINALS, TERMINAL_BUFFER_SIZE, TERMINAL_DISPLAY_SIZE,
|
|
MAX_READ_FILE_CHARS, READ_TOOL_DEFAULT_MAX_CHARS,
|
|
READ_TOOL_DEFAULT_CONTEXT_BEFORE, READ_TOOL_DEFAULT_CONTEXT_AFTER,
|
|
READ_TOOL_MAX_CONTEXT_BEFORE, READ_TOOL_MAX_CONTEXT_AFTER,
|
|
READ_TOOL_DEFAULT_MAX_MATCHES, READ_TOOL_MAX_MATCHES,
|
|
READ_TOOL_MAX_FILE_SIZE,
|
|
TERMINAL_SANDBOX_MOUNT_PATH,
|
|
TERMINAL_SANDBOX_MODE,
|
|
TERMINAL_SANDBOX_CPUS,
|
|
TERMINAL_SANDBOX_MEMORY,
|
|
PROJECT_MAX_STORAGE_MB,
|
|
CUSTOM_TOOLS_ENABLED,
|
|
)
|
|
except ImportError:
|
|
import sys
|
|
project_root = Path(__file__).resolve().parents[2]
|
|
if str(project_root) not in sys.path:
|
|
sys.path.insert(0, str(project_root))
|
|
from config import (
|
|
OUTPUT_FORMATS, DATA_DIR, PROMPTS_DIR, NEED_CONFIRMATION,
|
|
MAX_TERMINALS, TERMINAL_BUFFER_SIZE, TERMINAL_DISPLAY_SIZE,
|
|
MAX_READ_FILE_CHARS, READ_TOOL_DEFAULT_MAX_CHARS,
|
|
READ_TOOL_DEFAULT_CONTEXT_BEFORE, READ_TOOL_DEFAULT_CONTEXT_AFTER,
|
|
READ_TOOL_MAX_CONTEXT_BEFORE, READ_TOOL_MAX_CONTEXT_AFTER,
|
|
READ_TOOL_DEFAULT_MAX_MATCHES, READ_TOOL_MAX_MATCHES,
|
|
READ_TOOL_MAX_FILE_SIZE,
|
|
TERMINAL_SANDBOX_MOUNT_PATH,
|
|
TERMINAL_SANDBOX_MODE,
|
|
TERMINAL_SANDBOX_CPUS,
|
|
TERMINAL_SANDBOX_MEMORY,
|
|
PROJECT_MAX_STORAGE_MB,
|
|
CUSTOM_TOOLS_ENABLED,
|
|
)
|
|
|
|
from modules.file_manager import FileManager
|
|
from modules.search_engine import SearchEngine
|
|
from modules.terminal_ops import TerminalOperator
|
|
from modules.memory_manager import MemoryManager
|
|
from modules.terminal_manager import TerminalManager
|
|
from modules.todo_manager import TodoManager
|
|
from modules.sub_agent import SubAgentManager
|
|
from modules.webpage_extractor import extract_webpage_content, tavily_extract
|
|
from modules.ocr_client import OCRClient
|
|
from modules.easter_egg_manager import EasterEggManager
|
|
from modules.personalization_manager import (
|
|
load_personalization_config,
|
|
build_personalization_prompt,
|
|
RECENT_CONVERSATIONS_PROMPT_LIMIT_MIN,
|
|
RECENT_CONVERSATIONS_PROMPT_LIMIT_MAX,
|
|
RECENT_CONVERSATIONS_PROMPT_LIMIT_DEFAULT,
|
|
)
|
|
from modules.skills_manager import (
|
|
get_skills_catalog,
|
|
build_skills_list,
|
|
merge_enabled_skills,
|
|
build_skills_prompt,
|
|
infer_private_skills_dir,
|
|
)
|
|
from modules.custom_tool_registry import CustomToolRegistry, build_default_tool_category
|
|
from modules.custom_tool_executor import CustomToolExecutor
|
|
|
|
try:
|
|
from config.limits import THINKING_FAST_INTERVAL
|
|
except ImportError:
|
|
THINKING_FAST_INTERVAL = 10
|
|
|
|
from modules.container_monitor import collect_stats, inspect_state
|
|
from core.tool_config import TOOL_CATEGORIES
|
|
from utils.api_client import DeepSeekClient
|
|
from utils.context_manager import ContextManager, AUTO_SHALLOW_PLACEHOLDER
|
|
from utils.host_workspace_debug import write_host_workspace_debug
|
|
from utils.tool_result_formatter import format_tool_result_for_context
|
|
from utils.logger import setup_logger
|
|
from config.model_profiles import (
|
|
get_model_profile,
|
|
get_model_prompt_replacements,
|
|
get_model_context_window,
|
|
model_supports_image,
|
|
model_supports_video,
|
|
)
|
|
|
|
logger = setup_logger(__name__)
|
|
DISABLE_LENGTH_CHECK = True
|
|
|
|
|
|
class PromptMixin:
|
|
"""MainTerminalContextMixin prompt 能力 mixin。"""
|
|
|
|
def _load_agents_md_content(self) -> Optional[str]:
|
|
"""加载工作区根目录的 AGENTS.md 文件内容。
|
|
|
|
如果存在多个 AGENTS.md 文件,返回最新更新的那一个。
|
|
"""
|
|
try:
|
|
project_path = Path(self.project_path)
|
|
if not project_path.exists():
|
|
return None
|
|
|
|
# 查找所有 AGENTS.md 文件
|
|
agents_md_files = list(project_path.rglob("AGENTS.md"))
|
|
if not agents_md_files:
|
|
return None
|
|
|
|
# 找到最新更新的文件
|
|
latest_file = max(agents_md_files, key=lambda p: p.stat().st_mtime)
|
|
|
|
# 读取文件内容
|
|
content = latest_file.read_text(encoding='utf-8')
|
|
return content.strip() if content else None
|
|
except Exception as exc:
|
|
logger.warning(f"[AGENTS.md] 读取失败: {exc}")
|
|
return None
|
|
|
|
def load_prompt(self, name: str) -> str:
|
|
"""加载提示模板"""
|
|
prompt_file = Path(PROMPTS_DIR) / f"{name}.txt"
|
|
if prompt_file.exists():
|
|
with open(prompt_file, 'r', encoding='utf-8') as f:
|
|
return f.read()
|
|
return "你是一个AI助手。"
|