| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- """
- agent67v2.core.bootstrap — 统一启动引导
- 将 agent-config.yml 编译为可运行的 Lambda Term,
- 自动处理 subAgents 节的子代理注册和工具注入。
- 用法:
- # 方式 1: PaaS CLI
- python3 -m agentpaas agent create --name lambda2 --config agentexample/agent67v2/agent-config.yml
- python3 -m agentpaas chat lambda2
- # 方式 2: Python 直接调用
- from agent67v2.core.bootstrap import build_agent67v2
- agent = build_agent67v2()
- result = agent.apply("帮我看看当前目录")
- 流程:
- 1. 读取 agent-config.yml
- 2. 解析 subAgents 节,编译每个子代理
- 3. 注册子代理为 Skill 到 SkillRegistry
- 4. 创建 call_* 元工具 + ToolSearch
- 5. 通过 overrides["tools"] 注入到 from_config()
- 6. 返回完整的协调者 Term
- """
- from __future__ import annotations
- import json
- import os
- import sys
- import yaml
- from pathlib import Path
- from typing import Any, Dict, Optional
- PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent.parent
- AGENT_DIR = Path(__file__).resolve().parent.parent
- sys.path.insert(0, str(PROJECT_ROOT))
- from lambdagent.core import Term, Context
- from lambdagent.primitives import Tool
- from lambdagent.skills import Skill, SkillSignature, SkillPack, SkillRegistry
- # ════════════════════════════════════════════════════════════
- # SubAgent 编译与注册
- # ════════════════════════════════════════════════════════════
- def _compile_sub_agent(name: str, config_path: Path) -> Optional[Term]:
- """编译单个子代理 YAML 为 Term"""
- if not config_path.exists():
- print(f" ⚠️ 子代理配置不存在: {config_path}")
- return None
- try:
- from lambdagent.fromconfig.compiler import from_config
- return from_config(str(config_path))
- except Exception as e:
- print(f" ⚠️ 子代理 {name} 编译失败: {e}")
- return None
- def _register_sub_agents(config_path: Path, sub_agents_cfg: dict) -> Dict[str, Skill]:
- """
- 编译并注册所有子代理为 Skill。
- Args:
- config_path: agent-config.yml 所在目录
- sub_agents_cfg: subAgents 配置节
- Returns:
- {agent_name: Skill} 映射
- """
- skills = {}
- pack = SkillPack(
- name="agent67v2",
- description="agent67v2 多智能体协作系统",
- version="2.0.0",
- )
- for agent_name, agent_def in sub_agents_cfg.items():
- # 解析子代理配置文件路径 (相对于 agent-config.yml 所在目录)
- rel_path = agent_def.get("config", f"agents/{agent_name}.yml")
- agent_yml = config_path / rel_path
- # 编译子代理
- term = _compile_sub_agent(agent_name, agent_yml)
- if term is None:
- continue
- # 创建 Skill
- skill = Skill(
- name=agent_name,
- term=term,
- description=agent_def.get("description", ""),
- signature=SkillSignature(input_type="Str", output_type="Str"),
- tags=agent_def.get("tags", []),
- version="2.0.0",
- author="agent67v2",
- )
- pack.add(skill)
- skills[agent_name] = skill
- # 注册到全局 SkillRegistry
- registry = SkillRegistry()
- registry.register_pack(pack)
- return skills
- # ════════════════════════════════════════════════════════════
- # 元工具构建
- # ════════════════════════════════════════════════════════════
- def _make_agent_caller(skill: Skill):
- """为一个子代理 Skill 创建调用函数"""
- def call_agent(input_str: str) -> str:
- try:
- # 解析输入
- if isinstance(input_str, str):
- try:
- data = json.loads(input_str)
- task = data.get("task", input_str)
- except (json.JSONDecodeError, AttributeError):
- task = input_str
- else:
- task = str(input_str)
- ctx = Context()
- result = skill.apply(task, ctx)
- return str(result)
- except Exception as e:
- return f"[ERROR] {skill._name} 执行失败: {e}"
- return call_agent
- def _build_meta_tools(skills: Dict[str, Skill], sub_agents_cfg: dict) -> Dict[str, Any]:
- """
- 构建协调者的元工具集合。
- 根据 subAgents 配置中的 tool 字段,为每个子代理创建对应的 call_* 函数。
- """
- tools = {}
- for agent_name, agent_def in sub_agents_cfg.items():
- tool_name = agent_def.get("tool", f"call_{agent_name.replace('-agent', '')}")
- skill = skills.get(agent_name)
- if skill:
- tools[tool_name] = _make_agent_caller(skill)
- # ToolSearch 元工具
- from agent67v2.tools.tool_search import tool_search
- tools["ToolSearch"] = lambda x: tool_search.apply(x)
- return tools
- # ════════════════════════════════════════════════════════════
- # 主入口: build_agent67v2
- # ════════════════════════════════════════════════════════════
- def build_agent67v2(config_file: str = None, **overrides) -> Term:
- """
- 从 agent-config.yml 构建完整的 agent67v2 协调者。
- 流程:
- 1. 读取 agent-config.yml
- 2. 解析 subAgents,编译并注册子代理
- 3. 构建 call_* 元工具
- 4. 通过 overrides["tools"] 注入到 from_config()
- 5. 返回可执行的协调者 Term
- Args:
- config_file: agent-config.yml 路径 (默认: 自动定位)
- **overrides: 传递给 from_config 的覆盖参数
- Returns:
- Term: 可执行的协调者 Lambda Term
- """
- # 定位配置文件
- if config_file:
- config_path = Path(config_file).resolve()
- else:
- config_path = AGENT_DIR / "agent-config.yml"
- if not config_path.exists():
- raise FileNotFoundError(f"配置文件不存在: {config_path}")
- config_dir = config_path.parent
- # 读取配置
- with open(config_path, "r", encoding="utf-8") as f:
- cfg = yaml.safe_load(f)
- # 编译并注册子代理
- sub_agents_cfg = cfg.get("subAgents", {})
- if sub_agents_cfg:
- print(f" 🔄 编译 {len(sub_agents_cfg)} 个子代理...")
- skills = _register_sub_agents(config_dir, sub_agents_cfg)
- print(f" ✅ {len(skills)} 个子代理已注册为 Skill")
- # 构建元工具
- meta_tools = _build_meta_tools(skills, sub_agents_cfg)
- # 注入到 overrides
- existing_tools = overrides.get("tools", {})
- existing_tools.update(meta_tools)
- overrides["tools"] = existing_tools
- # 通过 from_config 编译协调者
- from lambdagent.fromconfig.compiler import from_config
- agent = from_config(str(config_path), **overrides)
- return agent
- def build_and_chat(config_file: str = None, **overrides):
- """
- 构建 agent67v2 并进入交互式对话。
- 用于 PaaS chat 模式的直接调用。
- """
- agent = build_agent67v2(config_file, **overrides)
- print(f"\n{'═' * 50}")
- print(f" 🐑 lambda v2 — 多智能体协作版")
- print(f" 输入 'exit' 退出")
- print(f"{'═' * 50}\n")
- while True:
- try:
- user_input = input("You: ").strip()
- except (EOFError, KeyboardInterrupt):
- print("\n👋 lambda v2 下线了!")
- break
- if not user_input:
- continue
- if user_input.lower() in ("exit", "quit", "bye"):
- print("👋 lambda v2 下线了!")
- break
- print()
- ctx = Context()
- result = agent.apply(user_input, ctx)
- print(f"🐑 lambda v2: {result}")
- print()
|