109 lines
4.5 KiB
Python
109 lines
4.5 KiB
Python
"""市場情報人工 fetch 的 MCP gate preview。
|
||
|
||
這裡只計算外部 fetch 是否具備前置條件;不呼叫電商平台、不寫 DB、不掛排程。
|
||
"""
|
||
|
||
from services.market_intel.mcp_readiness import build_mcp_readiness_plan
|
||
|
||
|
||
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,
|
||
):
|
||
"""建立人工 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")),
|
||
"manual_fetch_prerequisites_met": prerequisites_met,
|
||
"manual_fetch_gate_open": 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": (
|
||
"人工 fetch 已通過 MCP gate;仍只允許公開頁面、限速、不得寫 DB。"
|
||
if network_request_allowed
|
||
else "人工 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 全過後才打開",
|
||
"manual 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,
|
||
}
|