Build lightweight AI agent admin
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
"""
|
||||
Built-in agent Chinese display normalization.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from copy import deepcopy
|
||||
from typing import Any, Dict, Iterable, Optional
|
||||
|
||||
|
||||
class BuiltinAgentText:
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
name: str,
|
||||
code_label: str,
|
||||
description: str,
|
||||
role: str = "",
|
||||
skills: Optional[list[str]] = None,
|
||||
constraints: Optional[list[str]] = None,
|
||||
background: str = "",
|
||||
keys: Iterable[str],
|
||||
description_keywords: Iterable[str] = (),
|
||||
persona_keywords: Iterable[str] = (),
|
||||
):
|
||||
self.name = name
|
||||
self.code_label = code_label
|
||||
self.description = description
|
||||
self.role = role
|
||||
self.skills = skills or []
|
||||
self.constraints = constraints or []
|
||||
self.background = background
|
||||
self.keys = list(keys)
|
||||
self.description_keywords = list(description_keywords)
|
||||
self.persona_keywords = list(persona_keywords)
|
||||
|
||||
|
||||
BUILTIN_AGENT_TEXTS = [
|
||||
BuiltinAgentText(
|
||||
name="项目经理",
|
||||
code_label="项目管理",
|
||||
description="协调交付状态、进度风险和跨角色协作,确保项目按计划推进。",
|
||||
keys=("project manager", "project_manager", "project-manager", "projectmanager"),
|
||||
description_keywords=("coordinates delivery status",),
|
||||
),
|
||||
BuiltinAgentText(
|
||||
name="Multica 产品经理",
|
||||
code_label="产品管理",
|
||||
description="负责产品需求分诊、优先级判断和方案澄清,推动产品决策落地。",
|
||||
role="负责 Multica 协作工作的产品需求分诊、范围澄清、验收标准和质量推进决策。",
|
||||
skills=["范围澄清", "验收标准设计", "优先级取舍分析", "干系人沟通"],
|
||||
constraints=[
|
||||
"需求必须能追溯到具体 issue 或用户请求。",
|
||||
"没有明确验收标准时,不推进下游工作。",
|
||||
"遇到未决产品决策时要明确指出,不能擅自假设。",
|
||||
],
|
||||
background="擅长把模糊的平台需求转化为责任清晰、可评审、可交付的 Multica issue。",
|
||||
keys=(
|
||||
"multica product manager",
|
||||
"multica_product_manager",
|
||||
"multica-product-manager",
|
||||
"product manager",
|
||||
"product_manager",
|
||||
"product-manager",
|
||||
),
|
||||
description_keywords=("owns product triage",),
|
||||
persona_keywords=(
|
||||
"product manager for multica",
|
||||
"scope clarification",
|
||||
"acceptance criteria design",
|
||||
"priority tradeoff analysis",
|
||||
"stakeholder communication",
|
||||
"keep requirements traceable",
|
||||
),
|
||||
),
|
||||
BuiltinAgentText(
|
||||
name="业务需求分析师",
|
||||
code_label="需求分析",
|
||||
description="将业务诉求转化为清晰需求、验收标准和可执行的交付范围。",
|
||||
keys=(
|
||||
"business requirements analyst",
|
||||
"business_requirements_analyst",
|
||||
"business-requirements-analyst",
|
||||
"business analyst",
|
||||
"business_analyst",
|
||||
"business-analyst",
|
||||
),
|
||||
description_keywords=("translates business needs",),
|
||||
),
|
||||
BuiltinAgentText(
|
||||
name="系统架构师",
|
||||
code_label="系统架构",
|
||||
description="设计系统边界、模块职责和技术方案,保障架构一致性与可演进性。",
|
||||
keys=("system architect", "system_architect", "system-architect"),
|
||||
),
|
||||
BuiltinAgentText(
|
||||
name="前端工程师",
|
||||
code_label="前端开发",
|
||||
description="负责前端页面、组件交互、路由状态和浏览器端体验实现。",
|
||||
keys=("frontend engineer", "frontend_engineer", "frontend-engineer"),
|
||||
),
|
||||
BuiltinAgentText(
|
||||
name="后端工程师",
|
||||
code_label="后端开发",
|
||||
description="负责后端接口、业务服务、数据模型和系统集成能力建设。",
|
||||
keys=("backend engineer", "backend_engineer", "backend-engineer"),
|
||||
),
|
||||
BuiltinAgentText(
|
||||
name="测试工程师",
|
||||
code_label="质量保障",
|
||||
description="负责测试策略、用例设计、缺陷验证和发布质量把关。",
|
||||
keys=("qa engineer", "qa_engineer", "qa-engineer"),
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
def _normalize_text(value: Any) -> str:
|
||||
return " ".join(str(value or "").strip().lower().replace("-", " ").replace("_", " ").split())
|
||||
|
||||
|
||||
def _iter_persona_values(persona: Any) -> Iterable[str]:
|
||||
if not isinstance(persona, dict):
|
||||
return []
|
||||
|
||||
values: list[str] = []
|
||||
for key in ("role", "background"):
|
||||
value = persona.get(key)
|
||||
if isinstance(value, str):
|
||||
values.append(value)
|
||||
for key in ("personality", "skills", "constraints"):
|
||||
values.extend(item for item in persona.get(key) or [] if isinstance(item, str))
|
||||
return values
|
||||
|
||||
|
||||
def find_builtin_agent_text(data: Dict[str, Any]) -> Optional[BuiltinAgentText]:
|
||||
name = _normalize_text(data.get("name"))
|
||||
code = _normalize_text(data.get("code"))
|
||||
description = _normalize_text(data.get("description"))
|
||||
persona_text = _normalize_text(" ".join(_iter_persona_values(data.get("persona"))))
|
||||
|
||||
for display in BUILTIN_AGENT_TEXTS:
|
||||
keys = {_normalize_text(key) for key in display.keys}
|
||||
if name in keys or code in keys:
|
||||
return display
|
||||
if any(keyword in description for keyword in display.description_keywords):
|
||||
return display
|
||||
if any(keyword in persona_text for keyword in display.persona_keywords):
|
||||
return display
|
||||
return None
|
||||
|
||||
|
||||
def normalize_builtin_agent_payload(data: Dict[str, Any], *, include_code_label: bool = False) -> Dict[str, Any]:
|
||||
display = find_builtin_agent_text(data)
|
||||
if not display:
|
||||
return data
|
||||
|
||||
normalized = deepcopy(data)
|
||||
normalized["name"] = display.name
|
||||
normalized["description"] = display.description
|
||||
if include_code_label:
|
||||
normalized["code_label"] = display.code_label
|
||||
|
||||
persona = deepcopy(normalized.get("persona") or {})
|
||||
if display.role:
|
||||
persona["role"] = display.role
|
||||
if display.skills:
|
||||
persona["skills"] = list(display.skills)
|
||||
if display.constraints:
|
||||
persona["constraints"] = list(display.constraints)
|
||||
if display.background:
|
||||
persona["background"] = display.background
|
||||
normalized["persona"] = persona
|
||||
return normalized
|
||||
Reference in New Issue
Block a user