#!/usr/bin/env python3 """ 创建/更新「主控台Main Agent」:负责需求分流,不直接执行重任务。 输出协议(末行单行 JSON): { "action": "route_agent" | "clarify" | "answer_directly", "target_agent_name": "知你客服16号", "target_agent_id": "", "input": {"query": "...", "user_id": "..."}, "reason": "路由原因", "reply": "给用户看的话" } """ from __future__ import annotations import copy import json import os import sys from typing import Any, Dict, Optional import requests BASE = os.getenv("PLATFORM_BASE_URL", "http://127.0.0.1:8037").rstrip("/") USER = os.getenv("PLATFORM_USERNAME", "admin") PWD = os.getenv("PLATFORM_PASSWORD", "123456") SOURCE_NAME = os.getenv("SOURCE_AGENT_NAME", "知你客服14号") TARGET_NAME = os.getenv("TARGET_NAME", "主控台Main Agent") PROMPT_MAIN = """ 你是企业 Agent 主控台入口。你负责把用户请求路由到最合适的场景 Agent。 路由建议: - 需求分析/代码开发/多步执行:优先路由「知你客服16号」 - 普通客服问答:可路由「知你客服14号」 - 若信息不足,先澄清再路由 必须输出一行合法 JSON(无 markdown): { "action": "route_agent" | "clarify" | "answer_directly", "target_agent_name": "知你客服16号", "target_agent_id": "", "input": {"query": "{{user_input}}", "user_id": "{{user_id}}"}, "reason": "为何这样路由", "reply": "给用户看的一句话" } """.strip() def _find_agent_id_by_name(h: Dict[str, str], name: str) -> Optional[str]: r = requests.get(f"{BASE}/api/v1/agents", params={"search": name, "limit": 50}, headers=h, timeout=30) if r.status_code != 200: return None for a in r.json() or []: if a.get("name") == name: return a.get("id") return None def _patch_main_llm(wf: Dict[str, Any]) -> None: for n in wf.get("nodes") or []: if n.get("id") != "llm-unified": continue d = n.setdefault("data", {}) d["prompt"] = PROMPT_MAIN d["enable_tools"] = False d["tools"] = [] d["selected_tools"] = [] d["temperature"] = 0.2 return print("警告: 未找到节点 llm-unified", file=sys.stderr) def main() -> int: r = requests.post( f"{BASE}/api/v1/auth/login", data={"username": USER, "password": PWD}, headers={"Content-Type": "application/x-www-form-urlencoded"}, timeout=15, ) if r.status_code != 200: print("登录失败:", r.status_code, r.text[:500], file=sys.stderr) return 1 token = r.json().get("access_token") if not token: print("无 access_token", file=sys.stderr) return 1 h = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"} src_id = _find_agent_id_by_name(h, SOURCE_NAME) if not src_id: print(f"未找到源 Agent: {SOURCE_NAME}", file=sys.stderr) return 1 existing = _find_agent_id_by_name(h, TARGET_NAME) if existing: new_id = existing g = requests.get(f"{BASE}/api/v1/agents/{new_id}", headers=h, timeout=30) if g.status_code != 200: print("读取失败:", g.text[:600], file=sys.stderr) return 1 agent = g.json() print("已存在,更新:", TARGET_NAME, new_id) else: dup = requests.post( f"{BASE}/api/v1/agents/{src_id}/duplicate", headers=h, json={"name": TARGET_NAME}, timeout=60, ) if dup.status_code != 201: print("复制失败:", dup.status_code, dup.text[:800], file=sys.stderr) return 1 agent = dup.json() new_id = agent["id"] print("已创建:", TARGET_NAME, new_id) wf = copy.deepcopy(agent["workflow_config"]) _patch_main_llm(wf) desc = ( "主控台路由Agent:仅做任务理解与场景路由,输出结构化 action JSON;" "默认建议需求分析/代码开发路由到知你客服16号。" ) up = requests.put( f"{BASE}/api/v1/agents/{new_id}", headers=h, json={"description": desc, "workflow_config": wf}, timeout=120, ) if up.status_code != 200: print("更新失败:", up.status_code, up.text[:1000], file=sys.stderr) return 1 print(json.dumps({"id": new_id, "name": TARGET_NAME}, ensure_ascii=False)) return 0 if __name__ == "__main__": raise SystemExit(main())