168 lines
6.4 KiB
Python
168 lines
6.4 KiB
Python
"""Shared VedAstro-first source priority helpers.
|
|
|
|
This module keeps the user-facing data order identical across the CLI engine,
|
|
API server, and MCP strict workflow:
|
|
|
|
1. VedAstro official full snapshot when it contains an official chart.
|
|
2. Local modules as supplemental evidence and cross-checks.
|
|
3. Local chart as fallback only when the official snapshot is blocked.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from copy import deepcopy
|
|
from typing import Any
|
|
|
|
|
|
SOURCE_PRIORITY = [
|
|
"vedastro_official_snapshot",
|
|
"local_supplemental_modules",
|
|
"local_engine_fallback_when_official_blocked",
|
|
]
|
|
|
|
|
|
def official_chart_available(official_snapshot: dict[str, Any] | None) -> bool:
|
|
if not isinstance(official_snapshot, dict):
|
|
return False
|
|
official_chart = official_snapshot.get("official_chart")
|
|
if not isinstance(official_chart, dict):
|
|
return False
|
|
return (
|
|
isinstance(official_chart.get("planets"), dict)
|
|
and bool(official_chart.get("planets"))
|
|
and isinstance(official_chart.get("ascendant"), dict)
|
|
and bool(official_chart.get("ascendant"))
|
|
)
|
|
|
|
|
|
def _local_chart_from(report: dict[str, Any], modules: dict[str, Any]) -> dict[str, Any]:
|
|
chart = report.get("chart")
|
|
if isinstance(chart, dict) and chart:
|
|
return chart
|
|
chart = modules.get("chart")
|
|
return chart if isinstance(chart, dict) else {}
|
|
|
|
|
|
def _blocked_reason(official_snapshot: dict[str, Any] | None) -> str:
|
|
status = "missing"
|
|
if isinstance(official_snapshot, dict):
|
|
status = str(official_snapshot.get("status") or "blocked")
|
|
return f"VedAstro official snapshot blocked: {status}"
|
|
|
|
|
|
def build_source_priority_metadata(
|
|
official_snapshot: dict[str, Any] | None,
|
|
*,
|
|
official_primary: bool,
|
|
) -> dict[str, Any]:
|
|
status = official_snapshot.get("status") if isinstance(official_snapshot, dict) else "missing"
|
|
return {
|
|
"mode": "vedastro_official_primary" if official_primary else "local_fallback_official_blocked",
|
|
"priority": list(SOURCE_PRIORITY),
|
|
"official_snapshot_first": True,
|
|
"official_snapshot_status": status or "blocked",
|
|
"local_engine_role": (
|
|
"supplemental_crosscheck_or_fallback"
|
|
if official_primary
|
|
else "fallback_only_because_official_blocked"
|
|
),
|
|
"user_visible_policy": (
|
|
"show_vedastro_verified_when_official_chart_available"
|
|
if official_primary
|
|
else "show_local_fallback_with_official_blocked_boundary"
|
|
),
|
|
}
|
|
|
|
|
|
def apply_vedastro_source_priority(
|
|
report: dict[str, Any],
|
|
*,
|
|
official_snapshot: dict[str, Any] | None,
|
|
) -> dict[str, Any]:
|
|
if not isinstance(report, dict):
|
|
return report
|
|
modules = report.setdefault("modules", {})
|
|
if not isinstance(modules, dict):
|
|
modules = {}
|
|
report["modules"] = modules
|
|
|
|
if isinstance(official_snapshot, dict):
|
|
modules["vedastro_official_full_snapshot"] = official_snapshot
|
|
|
|
local_chart = _local_chart_from(report, modules)
|
|
|
|
if official_chart_available(official_snapshot):
|
|
official_chart = official_snapshot.get("official_chart") # type: ignore[union-attr]
|
|
modules["local_engine_chart_fallback"] = deepcopy(local_chart)
|
|
public_chart = {
|
|
**deepcopy(local_chart),
|
|
"source": "vedastro_official_primary",
|
|
"primary_source": "vedastro_official",
|
|
"fallback_source": "local_engine",
|
|
"local_engine_role": "supplemental_crosscheck_or_fallback",
|
|
"local_crosscheck_status": "pending",
|
|
"source_priority": list(SOURCE_PRIORITY),
|
|
"planets": official_chart.get("planets", {}),
|
|
"ascendant": official_chart.get("ascendant", {}),
|
|
"houses": official_chart.get("houses", {}),
|
|
"birth_info": local_chart.get("birth_info", report.get("birth_info", report.get("birth", {}))),
|
|
"official_coverage": official_chart.get("coverage", {}),
|
|
}
|
|
report["chart"] = public_chart
|
|
modules["chart"] = public_chart
|
|
for key in ("source", "primary_source", "fallback_source", "planets", "ascendant", "houses"):
|
|
if key in public_chart:
|
|
report[key] = public_chart[key]
|
|
modules["source_priority"] = build_source_priority_metadata(
|
|
official_snapshot,
|
|
official_primary=True,
|
|
)
|
|
return report
|
|
|
|
if local_chart:
|
|
fallback_chart = {
|
|
**deepcopy(local_chart),
|
|
"source": "local_engine_fallback",
|
|
"primary_source": "local_engine",
|
|
"fallback_reason": _blocked_reason(official_snapshot),
|
|
"local_engine_role": "fallback_only_because_official_blocked",
|
|
"source_priority": list(SOURCE_PRIORITY),
|
|
}
|
|
report["chart"] = fallback_chart
|
|
modules["chart"] = fallback_chart
|
|
for key in ("source", "primary_source", "planets", "ascendant", "houses"):
|
|
if key in fallback_chart:
|
|
report[key] = fallback_chart[key]
|
|
|
|
modules["source_priority"] = build_source_priority_metadata(
|
|
official_snapshot,
|
|
official_primary=False,
|
|
)
|
|
return report
|
|
|
|
|
|
def official_snapshot_evidence(modules: dict[str, Any]) -> dict[str, Any]:
|
|
snapshot = modules.get("vedastro_official_full_snapshot") if isinstance(modules, dict) else {}
|
|
source_priority = modules.get("source_priority") if isinstance(modules, dict) else {}
|
|
if not isinstance(snapshot, dict) or not snapshot:
|
|
return {
|
|
"level": "blocked",
|
|
"source": "vedastro_official",
|
|
"status": "missing",
|
|
"operation": "official_full_snapshot",
|
|
"source_priority": source_priority if isinstance(source_priority, dict) else {},
|
|
"reason": "VedAstro official full snapshot is not attached.",
|
|
}
|
|
level = "primary" if official_chart_available(snapshot) else "blocked"
|
|
return {
|
|
"level": level,
|
|
"source": "vedastro_official",
|
|
"status": snapshot.get("status") or "blocked",
|
|
"available": bool(snapshot.get("available")),
|
|
"operation": snapshot.get("operation") or "official_full_snapshot",
|
|
"source_priority": source_priority if isinstance(source_priority, dict) else {},
|
|
"section_statuses": snapshot.get("section_statuses") or {},
|
|
"chart_available": official_chart_available(snapshot),
|
|
"reason": snapshot.get("reason"),
|
|
}
|