feat(awooop): route post verify mcp through gateway
All checks were successful
Code Review / ai-code-review (push) Successful in 10s
CD Pipeline / tests (push) Successful in 1m7s
CD Pipeline / build-and-deploy (push) Successful in 10m15s
CD Pipeline / post-deploy-checks (push) Successful in 1m54s

This commit is contained in:
Your Name
2026-05-13 10:30:03 +08:00
parent 15873b9e0c
commit 1a03bceb5c
2 changed files with 89 additions and 2 deletions

View File

@@ -38,9 +38,12 @@ from typing import TYPE_CHECKING, Any
import structlog
from src.db.base import get_db_context
from src.plugins.mcp.gateway import GatewayContext, McpGateway
from src.plugins.mcp.registry import AuditedMCPToolProvider
from src.services.evidence_snapshot import EvidenceSnapshot
from src.services.mcp_audit_context import with_mcp_audit_context
from src.services.mcp_tool_registry import SensorDimension, get_mcp_tool_registry
from src.services.mcp_tool_registry import RegisteredTool, SensorDimension, get_mcp_tool_registry
from src.services.sanitization_service import sanitize, sanitize_dict_values
# W2 PR-V1: 頂層 import 讓測試 patch 路徑固定(延遲 import 無法被 patch
# ENABLE_SELF_HEALING_VALIDATOR=False 時此 import 不影響效能(純 python 模組)
@@ -224,7 +227,12 @@ class PostExecutionVerifier:
agent_role="post_execution_verifier",
)
result = await asyncio.wait_for(
reg.provider.execute(reg.tool.name, audited_params),
self._execute_tool(
reg=reg,
tool_name=reg.tool.name,
audited_params=audited_params,
incident_id=_get_incident_id(incident),
),
timeout=TOOL_TIMEOUT_SEC,
)
if result.success and result.output:
@@ -243,6 +251,35 @@ class PostExecutionVerifier:
return state
async def _execute_tool(
self,
reg: RegisteredTool,
tool_name: str,
audited_params: dict[str, Any],
incident_id: str,
):
"""Route production post-execution sensors through AwoooP MCP Gateway.
Raw providers are still used by unit tests and manual injections. In
production the registry wraps providers in `AuditedMCPToolProvider`, and
those calls must leave first-class gateway audit rows just like the
pre-decision sense path.
"""
if not isinstance(reg.provider, AuditedMCPToolProvider):
return await reg.provider.execute(tool_name, audited_params)
async with get_db_context("awoooi") as db:
ctx = GatewayContext(
project_id="awoooi",
agent_id="post_execution_verifier",
tool_name=tool_name,
trace_id=incident_id,
is_shadow=True,
environment={"env": "prod"},
required_scope="read",
)
return await McpGateway(db).call(ctx, audited_params)
# ─────────────────────────────────────────────────────────────────────────────
# W2 PR-V1: SelfHealingValidator 串接