aps-agent/tests/golden/test_tool_runtime.py

73 lines
3.4 KiB
Python
Raw Permalink 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.

# ============================================================
# 统一工具运行时黄金测试(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 # 未登记