1) 客服 Agent 四份交付文档 + 构建脚手架:品牌由包装占位 XX科技 / 旧名 南方财富 统一为南方基金(热线 400-889-8899 / 官网 nffund.com),系统名改为「智能服务系统」; 同步追加 §0.4 修订记录行,工程记录行保留原占位字面以支撑硬编码扫描验收。 2) 开发文档:清理 28 份已作废/残留文档(14 份移出归档 + 14 份仓库副本), 新增《文档规整方案与开发前待决事项-2026-09-17》。 3) 客服agent 四份交付文档首次纳入本分支。
63 lines
2.3 KiB
Python
63 lines
2.3 KiB
Python
"""公共 Agent 注册表契约:业务组员接入时必须通过这些机器检查。"""
|
|
|
|
from collections.abc import Iterable
|
|
|
|
import pytest
|
|
from pydantic import BaseModel
|
|
|
|
from app.core.contracts import AgentDefinition, AgentRequest, CoreResult, RequestContext
|
|
from app.service.agent.base import BaseAgent
|
|
from app.service.agent.factory import AgentFactory
|
|
|
|
|
|
class ContractAgent(BaseAgent):
|
|
definition = AgentDefinition(
|
|
agent_type="contract_agent", version="1", allowed_roles=("customer",),
|
|
allowed_portals=("api",)
|
|
)
|
|
|
|
async def handle(self, request: AgentRequest, context: RequestContext) -> CoreResult:
|
|
return CoreResult(text=request.message)
|
|
|
|
|
|
def assert_registered_agents(factory: AgentFactory, context: RequestContext) -> None:
|
|
"""扫描全部注册项,保证定义、构造器和公共基类不可漂移。"""
|
|
builders: Iterable[tuple[str, object]] = factory._builders.items()
|
|
for agent_type, builder in builders:
|
|
definition = factory.definition(agent_type)
|
|
assert definition.agent_type == agent_type
|
|
agent = builder(context) # type: ignore[operator]
|
|
assert isinstance(agent, BaseAgent)
|
|
assert agent.definition == definition
|
|
|
|
|
|
def test_registration_table_is_scannable_and_builder_contract_holds() -> None:
|
|
factory = AgentFactory()
|
|
factory.register(
|
|
ContractAgent.definition,
|
|
lambda _context: ContractAgent(ContractAgent.definition),
|
|
)
|
|
context = RequestContext(
|
|
user_id="1", trace_id="contract", roles=("customer",), permissions=("agent:run",)
|
|
)
|
|
assert_registered_agents(factory, context)
|
|
assert factory.create("contract_agent", context).__class__ is ContractAgent
|
|
|
|
|
|
def test_contract_rejects_builder_that_does_not_return_base_agent() -> None:
|
|
class NotAnAgent(BaseModel):
|
|
value: str = "bad"
|
|
|
|
factory = AgentFactory()
|
|
definition = AgentDefinition(
|
|
agent_type="invalid_contract", version="1", allowed_roles=("customer",),
|
|
allowed_portals=("api",)
|
|
)
|
|
factory.register(definition, lambda _context: NotAnAgent()) # type: ignore[arg-type]
|
|
with pytest.raises(Exception, match="BaseAgent"):
|
|
factory.create(
|
|
"invalid_contract", RequestContext(
|
|
user_id="1", trace_id="bad", roles=("customer",), permissions=("agent:run",)
|
|
)
|
|
)
|