feat: 实现AGENTS.md自动注入功能和根目录文件创建限制功能
This commit is contained in:
parent
8b730917cf
commit
ccb7128867
@ -104,7 +104,7 @@ class MainTerminal(MainTerminalCommandMixin, MainTerminalContextMixin, MainTermi
|
|||||||
)
|
)
|
||||||
self.container_session: Optional["ContainerHandle"] = None
|
self.container_session: Optional["ContainerHandle"] = None
|
||||||
self.memory_manager = MemoryManager(data_dir=str(self.data_dir))
|
self.memory_manager = MemoryManager(data_dir=str(self.data_dir))
|
||||||
self.file_manager = FileManager(project_path, container_session=container_session)
|
self.file_manager = FileManager(project_path, container_session=container_session, data_dir=str(self.data_dir))
|
||||||
self.search_engine = SearchEngine()
|
self.search_engine = SearchEngine()
|
||||||
self.terminal_ops = TerminalOperator(project_path, container_session=container_session)
|
self.terminal_ops = TerminalOperator(project_path, container_session=container_session)
|
||||||
self.ocr_client = OCRClient(project_path, self.file_manager)
|
self.ocr_client = OCRClient(project_path, self.file_manager)
|
||||||
|
|||||||
@ -208,6 +208,18 @@ class MainTerminalContextMixin:
|
|||||||
personalization_text = personalization_block
|
personalization_text = personalization_block
|
||||||
messages.append({"role": "system", "content": personalization_text})
|
messages.append({"role": "system", "content": personalization_text})
|
||||||
|
|
||||||
|
# AGENTS.md 自动注入
|
||||||
|
agents_md_inject_enabled = bool(personalization_config.get("agents_md_auto_inject", False)) if isinstance(personalization_config, dict) else False
|
||||||
|
if agents_md_inject_enabled:
|
||||||
|
agents_md_content = self._load_agents_md_content()
|
||||||
|
if agents_md_content:
|
||||||
|
agents_md_template = self.load_prompt("agents_md_inject").strip()
|
||||||
|
if agents_md_template and "{{AGENTS_MD_CONTENT}}" in agents_md_template:
|
||||||
|
agents_md_text = agents_md_template.replace("{{AGENTS_MD_CONTENT}}", agents_md_content)
|
||||||
|
else:
|
||||||
|
agents_md_text = f"【AGENTS.md 项目规范】\n\n{agents_md_content}\n\n---\n请注意:以上规范来自工作区根目录的 AGENTS.md 文件,若有冲突请以 AGENTS.md 为准。"
|
||||||
|
messages.append({"role": "system", "content": agents_md_text})
|
||||||
|
|
||||||
# 支持按对话覆盖的自定义 system prompt(API 用途)。
|
# 支持按对话覆盖的自定义 system prompt(API 用途)。
|
||||||
# 放在最后一个 system 消息位置,确保优先级最高,便于业务场景强约束。
|
# 放在最后一个 system 消息位置,确保优先级最高,便于业务场景强约束。
|
||||||
custom_system_prompt = getattr(self.context_manager, "custom_system_prompt", None)
|
custom_system_prompt = getattr(self.context_manager, "custom_system_prompt", None)
|
||||||
@ -340,6 +352,31 @@ class MainTerminalContextMixin:
|
|||||||
print(f"[ContextCompression] build_messages 替换tool占位符: {replaced_tool_count} 条")
|
print(f"[ContextCompression] build_messages 替换tool占位符: {replaced_tool_count} 条")
|
||||||
return messages
|
return messages
|
||||||
|
|
||||||
|
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:
|
def load_prompt(self, name: str) -> str:
|
||||||
"""加载提示模板"""
|
"""加载提示模板"""
|
||||||
prompt_file = Path(PROMPTS_DIR) / f"{name}.txt"
|
prompt_file = Path(PROMPTS_DIR) / f"{name}.txt"
|
||||||
|
|||||||
@ -44,11 +44,22 @@ DISABLE_LENGTH_CHECK = True
|
|||||||
|
|
||||||
logger = setup_logger(__name__)
|
logger = setup_logger(__name__)
|
||||||
class FileManager:
|
class FileManager:
|
||||||
def __init__(self, project_path: str, container_session: Optional["ContainerHandle"] = None):
|
def __init__(self, project_path: str, container_session: Optional["ContainerHandle"] = None, data_dir: Optional[str] = None):
|
||||||
self.project_path = Path(project_path).resolve()
|
self.project_path = Path(project_path).resolve()
|
||||||
self.container_session: Optional["ContainerHandle"] = None
|
self.container_session: Optional["ContainerHandle"] = None
|
||||||
self._container_proxy: Optional[ContainerFileProxy] = None
|
self._container_proxy: Optional[ContainerFileProxy] = None
|
||||||
|
self._data_dir: Optional[str] = data_dir
|
||||||
self.set_container_session(container_session)
|
self.set_container_session(container_session)
|
||||||
|
|
||||||
|
def _load_personalization_config(self) -> Optional[Dict]:
|
||||||
|
"""加载个性化配置"""
|
||||||
|
if not self._data_dir:
|
||||||
|
return None
|
||||||
|
try:
|
||||||
|
from modules.personalization_manager import load_personalization_config
|
||||||
|
return load_personalization_config(self._data_dir)
|
||||||
|
except Exception:
|
||||||
|
return None
|
||||||
|
|
||||||
def set_container_session(self, container_session: Optional["ContainerHandle"]):
|
def set_container_session(self, container_session: Optional["ContainerHandle"]):
|
||||||
self.container_session = container_session
|
self.container_session = container_session
|
||||||
@ -191,7 +202,13 @@ class FileManager:
|
|||||||
relative_path = self._relative_path(full_path)
|
relative_path = self._relative_path(full_path)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if full_path.parent == self.project_path:
|
# 检查是否允许在根目录创建文件
|
||||||
|
personalization_config = self._load_personalization_config()
|
||||||
|
allow_root_creation = bool(
|
||||||
|
personalization_config.get("allow_root_file_creation", False)
|
||||||
|
) if isinstance(personalization_config, dict) else False
|
||||||
|
|
||||||
|
if full_path.parent == self.project_path and not allow_root_creation:
|
||||||
return {
|
return {
|
||||||
"success": False,
|
"success": False,
|
||||||
"error": "禁止在项目根目录直接创建文件,请先创建或选择合适的子目录。",
|
"error": "禁止在项目根目录直接创建文件,请先创建或选择合适的子目录。",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user