Files
ewoooc/services/market_intel/mcp_fetch_gate.py
ogt 08d9e3fe7d
Some checks failed
CD Pipeline / deploy (push) Has been cancelled
清除市場情報 P3 相容人工語意
2026-07-01 18:24:51 +08:00

116 lines
4.8 KiB
Python
Raw 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.
"""市場情報 AI 受控 fetch 的 MCP gate preview。
這裡只計算外部 fetch 是否具備前置條件;不呼叫電商平台、不寫 DB、不掛排程。
"""
from services.market_intel.ai_controlled_service_compat import compatibility_flag
from services.market_intel.mcp_readiness import build_mcp_readiness_plan
_FETCH_PREREQUISITES_MET_KEY = compatibility_flag("fetch_prerequisites_met")
_FETCH_GATE_OPEN_KEY = compatibility_flag("fetch_gate_open")
def _status_value(runtime_status, name, default=False):
if isinstance(runtime_status, dict):
return runtime_status.get(name, default)
return getattr(runtime_status, name, default)
def build_mcp_fetch_gate_preview(
runtime_status,
*,
fetch_requested=False,
execute_readiness=False,
readiness=None,
):
"""建立 AI 受控 fetch 前的 MCP gate預設不做 health check、不連 DB。"""
fetch_requested = bool(fetch_requested)
execute_readiness = bool(execute_readiness)
readiness = readiness or build_mcp_readiness_plan(
execute_requested=execute_readiness,
)
readiness_checks = readiness.get("readiness_checks") or {}
gate_checks = {
"market_intel_enabled": bool(_status_value(runtime_status, "enabled")),
"market_intel_crawler_enabled": bool(
_status_value(runtime_status, "crawler_enabled")
),
"database_write_still_blocked": not bool(
_status_value(runtime_status, "database_write_allowed")
),
"scheduler_detached": not bool(
_status_value(runtime_status, "scheduler_attached")
),
"mcp_readiness_executed": bool(readiness.get("execute_requested")),
"mcp_router_enabled": bool(readiness.get("router_enabled")),
"external_mcp_complete": bool(readiness.get("external_mcp_complete")),
"internal_mcp_complete": bool(readiness.get("internal_mcp_complete")),
"market_intel_mcp_integrated": bool(
readiness.get("market_intel_mcp_integrated")
),
"market_intel_tool_contract_ready": bool(
readiness_checks.get("market_intel_tool_contract_ready")
),
"external_servers_all_healthy": bool(
readiness_checks.get("external_servers_all_healthy")
),
}
blocked_reasons = [
key for key, passed in gate_checks.items()
if not passed
]
if not fetch_requested:
blocked_reasons.insert(0, "fetch_false_planned_only")
prerequisites_met = not blocked_reasons
network_request_allowed = bool(fetch_requested and prerequisites_met)
return {
"mode": (
"mcp_fetch_gate_read_only"
if execute_readiness
else "mcp_fetch_gate_planned"
),
"fetch_requested": fetch_requested,
"readiness_execute_requested": bool(readiness.get("execute_requested")),
"ai_controlled_fetch_prerequisites_met": prerequisites_met,
"ai_controlled_fetch_gate_open": network_request_allowed,
_FETCH_PREREQUISITES_MET_KEY: prerequisites_met,
_FETCH_GATE_OPEN_KEY: network_request_allowed,
"network_request_allowed": network_request_allowed,
"would_use_external_network": network_request_allowed,
"gate_checks": gate_checks,
"blocked_reasons": blocked_reasons,
"operator_message": (
"AI 受控 fetch 已通過 MCP gate仍只允許公開頁面、限速、不得寫 DB。"
if network_request_allowed
else "AI 受控 fetch 仍被 MCP gate 阻擋;需 feature flags、MCP health、router 與 tool contract 全部通過。"
),
"required_sequence": [
"MARKET_INTEL_ENABLED 與 MARKET_INTEL_CRAWLER_ENABLED 需由操作員明確開啟",
"MCP deploy preflight 必須通過必要 env、compose、localhost port 與 fallback 檢查",
"外部 MCP stack 四個 health endpoint 需全部 200",
"MCP_ROUTER_ENABLED 只能在 health 全過後才打開",
"AI controlled discovery fetch 才能進入公開頁面限速探測,且仍不得寫 DB",
],
"mcp_readiness_summary": {
"mode": readiness.get("mode"),
"router_enabled": bool(readiness.get("router_enabled")),
"external_mcp_complete": bool(readiness.get("external_mcp_complete")),
"internal_mcp_complete": bool(readiness.get("internal_mcp_complete")),
"market_intel_mcp_integrated": bool(
readiness.get("market_intel_mcp_integrated")
),
"blocked_reasons": readiness.get("blocked_reasons", []),
},
"database_session_created": False,
"database_write_executed": False,
"database_commit_executed": False,
"external_network_executed": False,
"scheduler_attached": False,
"writes_executed": False,
"would_write_database": False,
}