aps-agent/tests/golden/test_tool_runtime.py

73 lines
3.4 KiB
Python
Raw Normal View History

# ============================================================
# 统一工具运行时黄金测试(plan.md §3.3 / 矩阵 111 行「LLM 只有提议权」)
# 覆盖:未登记意图拒绝(LLM 只有提议权)、已登记意图直通、TOOL 审计溯源、
# 只读白名单放行、不能通过未登记 API 绕过。
# ============================================================
from __future__ import annotations
from server.agent_core.tool_runtime import is_registered, run_tool
from server.contracts import IntentResult
from server.state.seed import ensure_flex_seed, seed_world
class _MemStore:
"""最小内存 store:满足 run_tool 对 data/next_id/save 的依赖。"""
def __init__(self, data):
self.data = data
def next_id(self, kind: str) -> int:
key = f"_c_{kind}"
self.data[key] = self.data.get(key, 0) + 1
return self.data[key]
def save(self):
pass
def test_unregistered_intent_denied_with_audit():
"""未登记意图(LLM 只有提议权):拒绝执行并写 TOOL 审计(result=DENIED)。"""
store = _MemStore(seed_world())
reply = run_tool(store, "t", IntentResult(intent="unknown", params={},
confidence=1.0, source="LLM"))
assert "未登记" in reply.text
audits = [a for a in store.data["auditEvents"] if a["category"] == "TOOL"]
assert audits and audits[0]["action"] == "tool.denied"
assert audits[0]["result"] == "DENIED"
# 未登记意图不得触发任何业务执行(无 schedule.run 等)
assert not any(a["action"] == "schedule.run" for a in store.data["auditEvents"])
def test_registered_intent_runs_and_audits():
"""已登记意图(schedule.run P1):经统一运行时执行并写 tool.run 审计。"""
world = seed_world()
ensure_flex_seed(world)
store = _MemStore(world)
reply = run_tool(store, "t", IntentResult(intent="schedule.run",
params={"engine": "RULE", "strategy": "DELIVERY_FIRST"},
confidence=1.0, source="LLM"))
assert "排产完成" in reply.text
audits = [a for a in store.data["auditEvents"] if a["category"] == "TOOL"]
assert audits and audits[0]["action"] == "tool.run"
# 业务审计同步落盘(schedule.run ALGO_RUN)
assert any(a["action"] == "schedule.run" for a in store.data["auditEvents"])
def test_registered_readonly_intent_passes():
"""只读白名单(master.query 等)放行:仍经统一运行时。"""
world = seed_world()
store = _MemStore(world)
reply = run_tool(store, "t", IntentResult(intent="master.query", params={"entity": "orders"},
confidence=1.0, source="LLM"))
assert reply.text, "只读意图应产生回复"
assert is_registered("master.query") is True
def test_is_registered_matches_power_map_and_whitelist():
"""登记判定:写入类匹配 _POWER_MAP;只读类在白名单;其余未登记。"""
assert is_registered("schedule.run") is True # P1 写入类
assert is_registered("schedule.publish") is True # P2 写入类
assert is_registered("master.query") is True # 只读白名单
assert is_registered("knowledge.query") is True # 只读白名单
assert is_registered("unknown") is False # 未登记