v6.1.10: Wire DK and RTN into theme reports

This commit is contained in:
732642856
2026-06-08 14:06:13 +08:00
parent 5d74d9544d
commit 068a8e2818
7 changed files with 164 additions and 26 deletions
+33
View File
@@ -3600,6 +3600,39 @@ def cmd_full_reading(args):
ak_d9 = calc_varga(ak_lon, 9)
jaimini_result['karakamsha'] = calc_karakamsha(
ak_d9.get('sign', 'Aries'), ak_d9.get('degree_in_sign', 0))
# Darakaraka 深度解读(v6.1.10
# Registry 已将 modules.jaimini.darakaraka 标为 covered;这里把独立 DK
# reader 接入 full-reading,使婚姻主题报告可消费真实 DK 画像、D9 状态、
# 合相影响和质量评分,而不是只停留在 chara_karaka 表格层。
try:
from darakaraka_reader import analyze_darakaraka
d9_planets_for_dk = {}
varga_data = report['modules'].get('varga_full', {})
d9_data = varga_data.get('D9_Navamsa', {}) if isinstance(varga_data, dict) else {}
d9_asc = d9_data.get('Ascendant', {}) if isinstance(d9_data, dict) else {}
d9_asc_idx = SIGNS.index(d9_asc.get('sign', 'Aries')) if isinstance(d9_asc, dict) and d9_asc.get('sign') in SIGNS else 0
if isinstance(d9_data, dict):
for d9_pn, d9_pd in d9_data.items():
if d9_pn == '_meta' or d9_pn == 'Ascendant' or not isinstance(d9_pd, dict) or 'sign' not in d9_pd:
continue
d9_sign = d9_pd.get('sign')
d9_deg = d9_pd.get('degree_in_sign', d9_pd.get('degree', 0) % 30)
d9_sign_idx = SIGNS.index(d9_sign) if d9_sign in SIGNS else 0
d9_planets_for_dk[d9_pn] = {
'sign': d9_sign,
'house': ((d9_sign_idx - d9_asc_idx) % 12) + 1,
'degree_in_sign': d9_deg,
'dignity': _get_dignity_level(d9_pn, d9_sign, d9_deg),
}
jaimini_result['darakaraka'] = analyze_darakaraka({
'ascendant': chart.get('ascendant', {}),
'planets': planets,
'context': {'navamsa_planets': d9_planets_for_dk},
}, use_8_karaka=True)
except Exception as dk_e:
jaimini_result['darakaraka'] = {'error': str(dk_e)}
report['modules']['jaimini'] = jaimini_result
except Exception as e:
report['errors'].append(f"jaimini: {e}")
+78 -2
View File
@@ -401,6 +401,7 @@ class OrchestratorBridge:
self._inject_yoga_module(modules, add)
self._inject_varga_modules(modules, add)
self._inject_strength_modules(modules, add)
self._inject_jaimini_relationship_modules(modules, add)
self._inject_special_points(modules, add)
self._inject_dasa_convergence_module(modules, add)
self._inject_transit_module(modules, add)
@@ -411,7 +412,8 @@ class OrchestratorBridge:
"counts": counts,
"source_modules": sorted(k for k in modules.keys() if k in {
"yoga", "varga_full", "d9_navamsa_expanded", "ashtakavarga", "shadbala",
"special_lagnas", "vivah_saham", "dasa_convergence", "transit_multi_reference",
"jaimini", "rashi_tulya_navamsa", "special_lagnas", "vivah_saham",
"dasa_convergence", "transit_multi_reference",
"dasha", "yogini_dasha", "ashtottari_dasha", "kalachakra_dasha",
}),
}
@@ -543,6 +545,79 @@ class OrchestratorBridge:
details={"source_module": "ashtakavarga", "scores": houses},
))
def _inject_jaimini_relationship_modules(self, modules: Dict[str, Any], add) -> None:
"""Inject relationship evidence from Jaimini DK and RTN modules.
v6.1.10 connects two previously underused P0 relationship layers:
`modules.jaimini.darakaraka` and `modules.rashi_tulya_navamsa`.
Both are deterministic full-reading outputs; the bridge translates them into
marriage/health/spirituality evidence so thematic reports can narrate them.
"""
jaimini = modules.get("jaimini") or {}
darakaraka = jaimini.get("darakaraka") if isinstance(jaimini, dict) else None
if isinstance(darakaraka, dict) and darakaraka and not darakaraka.get("error"):
score = darakaraka.get("marriage_quality_score")
score_text = f",质量评分约{score:.0%}" if isinstance(score, (int, float)) else ""
conclusion = (
f"Darakaraka{darakaraka.get('dk_planet', '未知')}{darakaraka.get('dk_sign', '未知')}"
f"{darakaraka.get('dk_house', '?')}宫,伴侣原型={darakaraka.get('core_profile', '未标注')}{score_text}"
)
if darakaraka.get("d9_sign"):
conclusion += f" D9中落{darakaraka.get('d9_sign')},尊严={darakaraka.get('d9_dignity', '未知')}"
add(ThemeName.MARRIAGE, ReportTechniqueResult(
technique="jaimini:darakaraka_deep_reader",
chart="D1/D9",
conclusion=conclusion,
sentiment="positive" if isinstance(score, (int, float)) and score >= 0.6 else ("negative" if isinstance(score, (int, float)) and score < 0.4 else "neutral"),
strength=StrengthLevel.STRONG,
details={"source_module": "jaimini.darakaraka", "raw": darakaraka},
))
rtn_module = modules.get("rashi_tulya_navamsa") or {}
rtn = rtn_module.get("analysis") if isinstance(rtn_module, dict) and isinstance(rtn_module.get("analysis"), dict) else rtn_module
if isinstance(rtn, dict) and rtn and not rtn.get("error"):
house_mapping = rtn.get("house_mapping") or {}
curse_yogas = rtn.get("curse_yogas") or []
strength_score = rtn.get("strength_score")
weakness_score = rtn.get("weakness_score")
marriage_planets = house_mapping.get(7) or house_mapping.get("7") or []
summary_parts = []
if marriage_planets:
summary_parts.append(f"RTN第7宫映射行星={marriage_planets}")
if curse_yogas:
summary_parts.append(f"检测到{len(curse_yogas)}个凶星合相命名")
if isinstance(strength_score, (int, float)) and isinstance(weakness_score, (int, float)):
summary_parts.append(f"隐藏力量={strength_score:.0%},弱点={weakness_score:.0%}")
conclusion = "".join(summary_parts) or "Rashi Tulya Navamsa 已完成 D1/D9 映射分析。"
sentiment = "negative" if curse_yogas or (isinstance(weakness_score, (int, float)) and weakness_score > strength_score) else "positive"
add(ThemeName.MARRIAGE, ReportTechniqueResult(
technique="rashi_tulya_navamsa:relationship_mapping",
chart="D1/D9",
conclusion=conclusion,
sentiment=sentiment,
strength=StrengthLevel.MODERATE,
details={"source_module": "rashi_tulya_navamsa", "raw": rtn},
))
if curse_yogas:
add(ThemeName.HEALTH, ReportTechniqueResult(
technique="rashi_tulya_navamsa:curse_yogas",
chart="D1/D9",
conclusion=f"RTN凶星合相提示健康/危机压力:{[c.get('name') for c in curse_yogas[:3]]}",
sentiment="negative",
strength=StrengthLevel.MODERATE,
details={"source_module": "rashi_tulya_navamsa", "curse_yogas": curse_yogas},
))
guna = rtn.get("guna_narrative")
if guna:
add(ThemeName.SPIRITUALITY, ReportTechniqueResult(
technique="rashi_tulya_navamsa:guna_balance",
chart="D1/D9",
conclusion=f"RTN Gunas{guna}",
sentiment="neutral",
strength=StrengthLevel.MODERATE,
details={"source_module": "rashi_tulya_navamsa", "guna_balance": rtn.get("guna_balance")},
))
def _inject_special_points(self, modules: Dict[str, Any], add) -> None:
special = modules.get("special_lagnas") or {}
if isinstance(special, dict):
@@ -791,7 +866,8 @@ def _extract_modules(chart_data: Any) -> Dict[str, Any]:
# Allow passing modules directly in tests.
known = {
"yoga", "varga_full", "d9_navamsa_expanded", "ashtakavarga", "shadbala",
"special_lagnas", "vivah_saham", "dasa_convergence", "transit_multi_reference",
"jaimini", "rashi_tulya_navamsa", "special_lagnas", "vivah_saham",
"dasa_convergence", "transit_multi_reference",
"dasha", "yogini_dasha", "ashtottari_dasha", "kalachakra_dasha",
}
if any(k in chart_data for k in known):