Files
awoooi/apps/api/tests/test_ai_agent_communication_learning_contract.py
Your Name 8c11af7c19
All checks were successful
CD Pipeline / tests (push) Successful in 1m23s
Code Review / ai-code-review (push) Successful in 15s
CD Pipeline / build-and-deploy (push) Successful in 4m33s
CD Pipeline / post-deploy-checks (push) Successful in 1m32s
feat(governance): 定義 Agent 主動溝通學習契約
2026-06-11 11:53:42 +08:00

191 lines
7.9 KiB
Python

from __future__ import annotations
import json
import pytest
from src.services.ai_agent_communication_learning_contract import (
load_latest_ai_agent_communication_learning_contract,
)
def test_load_latest_ai_agent_communication_learning_contract_reads_committed_snapshot():
data = load_latest_ai_agent_communication_learning_contract()
assert data["schema_version"] == "ai_agent_communication_learning_contract_v1"
assert data["program_status"]["overall_completion_percent"] == 35
assert data["program_status"]["read_only_mode"] is True
assert data["program_status"]["runtime_authority"] == "contract_only_no_runtime_worker"
assert data["communication_plane"]["message_bus"] == "Redis Streams"
assert data["communication_plane"]["stream_key_pattern"] == "aiops:agent:{session_id}"
assert data["communication_plane"]["frontend_redaction"]["operator_conversation_display_allowed"] is False
assert data["approval_boundaries"]["runtime_worker_allowed"] is False
assert data["approval_boundaries"]["db_migration_allowed"] is False
assert data["approval_boundaries"]["telegram_direct_send_allowed"] is False
assert data["approval_boundaries"]["production_route_change_allowed"] is False
assert data["rollups"]["agent_lane_count"] == 3
assert data["rollups"]["mcp_stack_count"] == len(data["mcp_stack"]) == 9
assert data["rollups"]["rag_layer_count"] == len(data["rag_memory_stack"]) == 3
assert data["rollups"]["learning_loop_count"] == len(data["learning_loops"]) == 5
assert data["rollups"]["intelligence_service_count"] == len(data["intelligence_services"]) == 7
assert data["rollups"]["optional_service_ids"] == ["langfuse", "phoenix", "qdrant", "milvus"]
assert {lane["agent_id"] for lane in data["agent_lanes"]} == {
"openclaw",
"hermes",
"nemotron",
}
def test_load_latest_ai_agent_communication_learning_contract_rejects_runtime_worker(tmp_path):
snapshot = _snapshot()
snapshot["approval_boundaries"]["runtime_worker_allowed"] = True
(tmp_path / "ai_agent_communication_learning_contract_2026-06-11.json").write_text(
json.dumps(snapshot),
encoding="utf-8",
)
with pytest.raises(ValueError, match="approval boundaries"):
load_latest_ai_agent_communication_learning_contract(tmp_path)
def test_load_latest_ai_agent_communication_learning_contract_rejects_rollup_mismatch(tmp_path):
snapshot = _snapshot()
snapshot["rollups"]["mcp_stack_count"] = 99
(tmp_path / "ai_agent_communication_learning_contract_2026-06-11.json").write_text(
json.dumps(snapshot),
encoding="utf-8",
)
with pytest.raises(ValueError, match="rollup counts"):
load_latest_ai_agent_communication_learning_contract(tmp_path)
def test_load_latest_ai_agent_communication_learning_contract_rejects_nemotron_route_change(tmp_path):
snapshot = _snapshot()
snapshot["agent_lanes"][2]["blocked_actions"] = ["secret_plaintext_read"]
(tmp_path / "ai_agent_communication_learning_contract_2026-06-11.json").write_text(
json.dumps(snapshot),
encoding="utf-8",
)
with pytest.raises(ValueError, match="Nemotron"):
load_latest_ai_agent_communication_learning_contract(tmp_path)
def _snapshot() -> dict:
return {
"schema_version": "ai_agent_communication_learning_contract_v1",
"generated_at": "2026-06-11T20:40:00+08:00",
"program_status": {
"overall_completion_percent": 35,
"current_priority": "P2",
"current_task_id": "P2-401A",
"next_task_id": "P2-401B",
"read_only_mode": True,
"runtime_authority": "contract_only_no_runtime_worker",
},
"communication_plane": {
"message_bus": "Redis Streams",
"stream_key_pattern": "aiops:agent:{session_id}",
"session_table": "agent_sessions",
"event_tables": ["timeline_events"],
"turn_types": ["observe", "propose", "challenge", "review", "decide"],
"frontend_redaction": {
"operator_conversation_display_allowed": False,
"agent_private_reasoning_display_allowed": False,
},
},
"agent_lanes": [
{
"agent_id": "openclaw",
"display_name": "OpenClaw",
"primary_role": "生產仲裁",
"initiates": ["incident arbitration"],
"responds_to": ["Hermes evidence dossier"],
"writes_to": ["agent_sessions"],
"blocked_actions": ["secret_plaintext_read", "self_approval"],
},
{
"agent_id": "hermes",
"display_name": "Hermes",
"primary_role": "治理",
"initiates": ["knowledge review"],
"responds_to": ["OpenClaw evidence request"],
"writes_to": ["knowledge_entries"],
"blocked_actions": ["secret_plaintext_read", "production_write"],
},
{
"agent_id": "nemotron",
"display_name": "NemoTron",
"primary_role": "離線評估",
"initiates": ["replay scoring"],
"responds_to": ["OpenClaw offline evaluation request"],
"writes_to": ["agent_replay_results"],
"blocked_actions": ["secret_plaintext_read", "production_route_change"],
},
],
"mcp_stack": [_capability("mcp_gateway", "MCP Gateway", "openclaw", "existing")],
"rag_memory_stack": [
_capability("hot_session_memory", "Hot", "openclaw", "contract_defined"),
_capability("warm_rag_memory", "Warm", "hermes", "existing"),
_capability("cold_replay_archive", "Cold", "nemotron", "planned"),
],
"learning_loops": [_capability("incident_outcome_learning", "Incident", "openclaw", "planned")],
"intelligence_services": [
_capability("postgres_pgvector", "PostgreSQL + pgvector", "hermes", "preferred_default"),
_capability("langfuse", "Langfuse", "hermes", "optional_candidate"),
],
"rollout_tasks": [
{
"task_id": "P2-401A",
"priority": "P2",
"status": "ready_for_review",
"completion_percent": 100,
"owner_agent": "Hermes + OpenClaw",
"summary": "契約。",
"next_gate": "本地測試",
},
{
"task_id": "P2-401B",
"priority": "P2",
"status": "planned",
"completion_percent": 0,
"owner_agent": "OpenClaw",
"summary": "Migration。",
"next_gate": "DB migration approval gate",
},
],
"approval_boundaries": {
"runtime_worker_allowed": False,
"db_migration_allowed": False,
"telegram_direct_send_allowed": False,
"paid_external_service_allowed": False,
"secret_plaintext_allowed": False,
"autonomous_host_mutation_allowed": False,
"production_route_change_allowed": False,
"sdk_installation_allowed": False,
},
"rollups": {
"agent_lane_count": 3,
"mcp_stack_count": 1,
"rag_layer_count": 3,
"learning_loop_count": 1,
"intelligence_service_count": 2,
"rollout_task_count": 2,
"blocked_task_ids": ["P2-401B"],
"optional_service_ids": ["langfuse"],
},
}
def _capability(id_: str, display_name: str, owner: str, status: str) -> dict:
return {
"id": id_,
"display_name": display_name,
"primary_owner": owner,
"purpose": "測試用途。",
"storage_or_service": "test",
"status": status,
"approval_gate": "read_only_allowed",
}