| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- """
- Agent Presets - Agent 类型预设配置
- 定义不同类型 Agent 的工具权限和运行参数。
- 用户可通过 .agent/presets.json 覆盖或添加预设。
- """
- from dataclasses import dataclass, field
- from typing import Optional, List
- from pathlib import Path
- @dataclass
- class AgentPreset:
- """Agent 预设配置"""
- # 工具权限
- allowed_tools: Optional[List[str]] = None # None 表示允许全部
- denied_tools: Optional[List[str]] = None # 黑名单
- # 运行参数
- max_iterations: int = 30
- temperature: Optional[float] = None
- # System Prompt(完全自定义 system prompt;None = 使用默认模板 + skills)
- system_prompt: Optional[str] = None
- # Skills(注入 system prompt 的 skill 名称列表;None = 加载全部)
- skills: Optional[List[str]] = None
- # 描述
- description: Optional[str] = None
- # 内置预设
- _DEFAULT_SKILLS = ["planning", "research", "browser"]
- AGENT_PRESETS = {
- "default": AgentPreset(
- allowed_tools=None,
- max_iterations=30,
- skills=_DEFAULT_SKILLS,
- description="默认 Agent,拥有全部工具权限",
- ),
- "delegate": AgentPreset(
- allowed_tools=None,
- max_iterations=30,
- skills=_DEFAULT_SKILLS,
- description="委托子 Agent,拥有全部工具权限(由 agent 工具创建)",
- ),
- "explore": AgentPreset(
- allowed_tools=["read", "glob", "grep", "list_files"],
- denied_tools=["write", "edit", "bash", "task"],
- max_iterations=15,
- skills=["planning"],
- description="探索型 Agent,只读权限,用于代码分析",
- ),
- "evaluate": AgentPreset(
- allowed_tools=["read_file", "grep_content", "glob_files", "goal"],
- max_iterations=10,
- skills=["planning"],
- description="评估型 Agent,只读权限,用于结果评估",
- ),
- }
- def get_preset(name: str) -> AgentPreset:
- """获取预设配置"""
- if name not in AGENT_PRESETS:
- raise ValueError(f"Unknown preset: {name}. Available: {list(AGENT_PRESETS.keys())}")
- return AGENT_PRESETS[name]
- def register_preset(name: str, preset: AgentPreset) -> None:
- """注册自定义预设"""
- AGENT_PRESETS[name] = preset
- def load_system_prompt_from_file(path: str) -> str:
- """
- 从 .prompt 文件加载 system prompt
- Args:
- path: .prompt 文件路径(相对或绝对)
- Returns:
- system prompt 文本
- Raises:
- FileNotFoundError: 文件不存在
- ValueError: 文件格式错误或缺少 $system$ 分节
- """
- from agent.llm.prompts import load_prompt
- prompt_path = Path(path)
- if not prompt_path.is_absolute():
- # 相对路径:相对于当前工作目录
- prompt_path = Path.cwd() / prompt_path
- config, messages = load_prompt(prompt_path)
- if "system" not in messages:
- raise ValueError(f".prompt 文件缺少 $system$ 分节: {path}")
- return messages["system"]
- def load_presets_from_json(json_path: str) -> None:
- """
- 从 JSON 文件加载预设配置
- 支持特殊字段:
- - system_prompt_file: 从 .prompt 文件加载 system prompt(相对于 JSON 文件所在目录)
- Args:
- json_path: presets.json 文件路径
- """
- import json
- json_path = Path(json_path)
- if not json_path.exists():
- raise FileNotFoundError(f"presets.json 不存在: {json_path}")
- with open(json_path, "r", encoding="utf-8") as f:
- presets_data = json.load(f)
- base_dir = json_path.parent
- for name, cfg in presets_data.items():
- # 处理 system_prompt_file
- if "system_prompt_file" in cfg:
- prompt_file = cfg.pop("system_prompt_file")
- prompt_path = base_dir / prompt_file
- cfg["system_prompt"] = load_system_prompt_from_file(str(prompt_path))
- preset = AgentPreset(**cfg)
- register_preset(name, preset)
|