Files
aiagent/backend/scripts/create_main_agent.py
renjianbo 41ffd31923 feat: P0 commercial readiness — password security, legal, account management
Backend changes for Phase A of v1.0 commercial launch:

P0-3: Password Security
- Remove hardcoded admin/123456 defaults from 34+ bootstrap scripts
- Add PLATFORM_USERNAME/PLATFORM_PASSWORD env vars to config
- Add PUT /api/v1/auth/change-password endpoint (requires old password)

P0-1: User Agreement & Privacy Policy
- Add agreed_terms/agreed_terms_version/agreed_terms_at to User model
- New GET /api/v1/legal/privacy and GET /api/v1/legal/terms endpoints
- New POST /api/v1/legal/agree endpoint to record consent
- Register endpoint now validates agreed_terms must be True

P0-6: Account Management
- Add phone/status/is_email_verified to User model
- Add DELETE /api/v1/auth/account for account deletion (with password confirmation)
- Add PUT /api/v1/auth/phone for phone binding
- Reject authentication for deleted accounts (status=deleted)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-01 22:01:54 +08:00

142 lines
4.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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")
PWD = os.getenv("PLATFORM_PASSWORD")
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())