fix(consult): put locally computed techniques in the model packet
Web consult already computed Yoga, Arudha, KP, and related layers, then stripped them before the spoken model. Keep those executed structures in toModelOutput so answers cannot invent degrees from parametric knowledge. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -613,6 +613,92 @@ def _consultation_layer_present(value) -> bool:
|
||||
return status not in {'blocked', 'unavailable', 'missing'}
|
||||
|
||||
|
||||
def _consultation_audit_status(value) -> str:
|
||||
if isinstance(value, dict):
|
||||
raw = str(value.get('status') or '').lower()
|
||||
if raw == 'not_applicable':
|
||||
return 'not_applicable'
|
||||
if raw in {'blocked', 'unavailable', 'missing'}:
|
||||
return 'blocked'
|
||||
if _consultation_layer_present(value):
|
||||
return 'executed'
|
||||
if isinstance(value, list) and value:
|
||||
return 'executed'
|
||||
return 'blocked'
|
||||
|
||||
|
||||
_CHARA_DASHA_ROUTES = frozenset({'career', 'timing', 'annual', 'marriage'})
|
||||
|
||||
|
||||
def _consultation_declared_routes(body: dict) -> set[str]:
|
||||
values: list[str] = []
|
||||
for key in ('strict_workflow_route', 'theme'):
|
||||
raw = body.get(key)
|
||||
if isinstance(raw, str) and raw.strip():
|
||||
values.append(raw.strip().lower())
|
||||
elif isinstance(raw, list):
|
||||
values.extend(str(item).strip().lower() for item in raw if item)
|
||||
themes = body.get('themes')
|
||||
if isinstance(themes, list):
|
||||
values.extend(str(item).strip().lower() for item in themes if item)
|
||||
return {item for item in values if item}
|
||||
|
||||
|
||||
def _compact_yoga_entry(value) -> dict | None:
|
||||
if isinstance(value, str) and value.strip():
|
||||
return {'name': value.strip()[:80]}
|
||||
if not isinstance(value, dict):
|
||||
return None
|
||||
name = str(value.get('name') or value.get('yoga') or '').strip()
|
||||
if not name:
|
||||
return None
|
||||
compact: dict = {'name': name[:80]}
|
||||
planets = value.get('planets')
|
||||
if isinstance(planets, list):
|
||||
names = [str(item) for item in planets[:6] if item]
|
||||
if names:
|
||||
compact['planets'] = names
|
||||
elif isinstance(planets, str) and planets.strip():
|
||||
compact['planets'] = [planets.strip()]
|
||||
category = value.get('category') or value.get('cat')
|
||||
if category:
|
||||
compact['category'] = str(category)[:40]
|
||||
return compact
|
||||
|
||||
|
||||
def _compact_chara_dasha(raw: dict, age_years: float) -> dict:
|
||||
sequence = raw.get('dasha_sequence') if isinstance(raw.get('dasha_sequence'), list) else []
|
||||
cursor = 0.0
|
||||
current = None
|
||||
compact_sequence = []
|
||||
for period in sequence:
|
||||
if not isinstance(period, dict):
|
||||
continue
|
||||
try:
|
||||
duration = float(period.get('duration_years') or 0)
|
||||
except (TypeError, ValueError):
|
||||
duration = 0.0
|
||||
start = cursor
|
||||
end = cursor + duration
|
||||
row = {
|
||||
'sign': period.get('sign'),
|
||||
'lord': period.get('lord'),
|
||||
'duration_years': duration,
|
||||
}
|
||||
if current is None and (start <= age_years < end or (age_years >= end and period is sequence[-1])):
|
||||
current = {**row, 'from_age': round(start, 2), 'to_age': round(end, 2)}
|
||||
if len(compact_sequence) < 6:
|
||||
compact_sequence.append(row)
|
||||
cursor = end
|
||||
return {
|
||||
'status': 'executed',
|
||||
'method': 'kn_rao',
|
||||
'current': current,
|
||||
'sequence': compact_sequence,
|
||||
'boundary': 'commercial claims stay non-deterministic; not a majority-vote truth',
|
||||
}
|
||||
|
||||
|
||||
def _planet_longitudes(planets: dict) -> dict[str, float]:
|
||||
longitudes = {}
|
||||
for name, data in planets.items():
|
||||
@@ -855,12 +941,17 @@ def _consultation_technique_audit_table(
|
||||
for raw in quality_gate.get('technique_audit_table') or []:
|
||||
if not isinstance(raw, dict):
|
||||
continue
|
||||
rows.append(_audit_row(
|
||||
row = _audit_row(
|
||||
str(raw.get('technique') or raw.get('name') or 'Technique'),
|
||||
raw.get('status'),
|
||||
system=str(raw.get('system') or 'cross_system'),
|
||||
boundary=str(raw.get('effect_on_confidence') or raw.get('boundary') or ''),
|
||||
))
|
||||
)
|
||||
for key in ('key_functional_benefics', 'key_functional_malefics'):
|
||||
names = raw.get(key)
|
||||
if isinstance(names, list) and names:
|
||||
row[key] = [str(item) for item in names[:9] if item]
|
||||
rows.append(row)
|
||||
modules = chart.get('modules') if isinstance(chart.get('modules'), dict) else {}
|
||||
spectrum = modules.get('varga_spectrum') if isinstance(modules.get('varga_spectrum'), dict) else {}
|
||||
counts = spectrum.get('counts') if isinstance(spectrum.get('counts'), dict) else {}
|
||||
@@ -885,12 +976,13 @@ def _consultation_technique_audit_table(
|
||||
('narayana_dasha', 'Narayana Dasha', None),
|
||||
('dasha_sub_periods', 'Vimshottari sub-periods', None),
|
||||
('ashtakavarga', 'Ashtakavarga', 'component parity remains partial'),
|
||||
('yogas', 'Yogas', None),
|
||||
('chara_dasha', 'Chara Dasha', 'commercial claims stay non-deterministic; not a majority-vote truth'),
|
||||
('transits', 'Transits / Sade Sati', 'observation windows, not guaranteed events'),
|
||||
('kp_cusps', 'KP cusps', 'KP remains non-deterministic in this product'),
|
||||
('gulika', 'Gulika / Mandi', 'observation_only'),
|
||||
):
|
||||
value = modules.get(name)
|
||||
status = 'executed' if _consultation_layer_present(value) else 'blocked'
|
||||
rows.append(_audit_row(label, status, boundary=boundary))
|
||||
rows.append(_audit_row(label, _consultation_audit_status(modules.get(name)), boundary=boundary))
|
||||
shadbala = modules.get('shadbala') or chart.get('shadbala')
|
||||
rows.append(_audit_row(
|
||||
'Shadbala components',
|
||||
@@ -905,11 +997,17 @@ def _consultation_technique_audit_table(
|
||||
))
|
||||
if not any(row.get('technique') == 'Functional Benefic/Malefic' for row in rows):
|
||||
functional = modules.get('functional_benefic_malefic')
|
||||
rows.append(_audit_row(
|
||||
functional_row = _audit_row(
|
||||
'Functional Benefic/Malefic',
|
||||
'executed' if _consultation_layer_present(functional) and str(functional.get('status') or '') != 'blocked' else 'blocked',
|
||||
boundary=str((functional or {}).get('effect_on_confidence') or '') if isinstance(functional, dict) else '',
|
||||
))
|
||||
)
|
||||
if isinstance(functional, dict):
|
||||
for key in ('functional_benefics', 'functional_malefics'):
|
||||
names = functional.get(key)
|
||||
if isinstance(names, list) and names:
|
||||
functional_row[f'key_{key}'] = [str(item) for item in names[:9] if item]
|
||||
rows.append(functional_row)
|
||||
western = _compact_western_spectrum(western_evidence_packet)
|
||||
rows.append(_audit_row(
|
||||
'Western natal (tropical)',
|
||||
@@ -1163,6 +1261,122 @@ def _attach_local_consultation_layers(handler, chart: dict, birth_payload: dict,
|
||||
except Exception as exc:
|
||||
diagnostics.append({'layer': 'kakshya', 'status': 'unavailable', 'reason': exc.__class__.__name__})
|
||||
|
||||
for planet in planets.values():
|
||||
if isinstance(planet, dict) and not planet.get('sign') and planet.get('sign_idx') is not None:
|
||||
try:
|
||||
planet['sign'] = SIGNS[int(planet['sign_idx']) % 12]
|
||||
except (TypeError, ValueError, IndexError):
|
||||
pass
|
||||
|
||||
if not _consultation_layer_present(modules.get('yogas')):
|
||||
try:
|
||||
raw_yogas = chart.get('yogas') if isinstance(chart.get('yogas'), list) else []
|
||||
compact = [entry for entry in (_compact_yoga_entry(item) for item in raw_yogas) if entry]
|
||||
if not compact:
|
||||
api = handler._compute_yogas_api({
|
||||
**birth_payload,
|
||||
'planets': planets,
|
||||
'ascendant': ascendant,
|
||||
})
|
||||
result = api.get('result') if isinstance(api, dict) else {}
|
||||
extended = result.get('extended_yogas') if isinstance(result, dict) else []
|
||||
engine = result.get('rule_engine_yogas') if isinstance(result, dict) else []
|
||||
compact = [
|
||||
entry for entry in (
|
||||
_compact_yoga_entry(item)
|
||||
for item in (extended or []) + (engine or [])
|
||||
)
|
||||
if entry
|
||||
][:12]
|
||||
modules['yogas'] = {
|
||||
'status': 'executed' if compact else 'blocked',
|
||||
'count': len(compact),
|
||||
'yogas': compact[:12],
|
||||
}
|
||||
if compact and not isinstance(chart.get('yogas'), list):
|
||||
chart['yogas'] = compact[:12]
|
||||
except Exception as exc:
|
||||
modules['yogas'] = {'status': 'blocked', 'reason': exc.__class__.__name__, 'yogas': []}
|
||||
diagnostics.append({'layer': 'yogas', 'status': 'unavailable', 'reason': exc.__class__.__name__})
|
||||
|
||||
if not isinstance(modules.get('chara_dasha'), dict):
|
||||
if _consultation_declared_routes(body) & _CHARA_DASHA_ROUTES:
|
||||
try:
|
||||
jaimini = _load_local_module('jaimini')
|
||||
planet_lons = _planet_longitudes(planets)
|
||||
asc_sign_idx = int(ascendant.get('sign_idx', int(float(ascendant.get('lon', 0))) // 30)) % 12
|
||||
raw = jaimini.calc_chara_dasha(
|
||||
asc_sign_idx,
|
||||
planet_lons,
|
||||
int(birth_payload.get('year', 0) or 0),
|
||||
int(birth_payload.get('month', 1) or 1),
|
||||
int(birth_payload.get('day', 1) or 1),
|
||||
)
|
||||
modules['chara_dasha'] = _compact_chara_dasha(raw, _consultation_current_age(birth_payload, body))
|
||||
except Exception as exc:
|
||||
modules['chara_dasha'] = {
|
||||
'status': 'blocked',
|
||||
'reason': exc.__class__.__name__,
|
||||
'boundary': 'commercial claims stay non-deterministic; not a majority-vote truth',
|
||||
}
|
||||
diagnostics.append({'layer': 'chara_dasha', 'status': 'unavailable', 'reason': exc.__class__.__name__})
|
||||
else:
|
||||
modules['chara_dasha'] = {
|
||||
'status': 'not_applicable',
|
||||
'boundary': 'Chara Dasha is attached for career, timing, annual, and marriage routes',
|
||||
}
|
||||
|
||||
if not isinstance(modules.get('transits'), dict):
|
||||
try:
|
||||
sade_sati = chart.get('sade_sati') if isinstance(chart.get('sade_sati'), dict) else None
|
||||
if not sade_sati:
|
||||
moon = planets.get('Moon') if isinstance(planets.get('Moon'), dict) else {}
|
||||
calculation_service = _load_local_module('domain_calculation_service')
|
||||
sade_sati = calculation_service.compute_sade_sati(
|
||||
moon_degree=float(moon.get('lon') or 0),
|
||||
asc_degree=float(ascendant.get('lon') or 0),
|
||||
reference_date=_consultation_reference_date(body).strftime('%Y-%m-%d'),
|
||||
tz=float(birth_payload.get('tz') or birth_payload.get('timezone') or 0),
|
||||
ayanamsa=str(body.get('ayanamsa') or birth_payload.get('ayanamsa') or 'lahiri'),
|
||||
)
|
||||
compact_sade = None
|
||||
if isinstance(sade_sati, dict):
|
||||
inner = sade_sati.get('sade_sati') if isinstance(sade_sati.get('sade_sati'), dict) else sade_sati
|
||||
compact_sade = {
|
||||
key: inner[key]
|
||||
for key in ('active', 'phase', 'phase_name', 'moon_sign', 'saturn_sign', 'intensity')
|
||||
if isinstance(inner, dict) and key in inner
|
||||
}
|
||||
for key in ('moon_sign', 'saturn_sign'):
|
||||
if key in sade_sati and key not in compact_sade:
|
||||
compact_sade[key] = sade_sati[key]
|
||||
if not compact_sade:
|
||||
compact_sade = None
|
||||
triggers = []
|
||||
raw_triggers = chart.get('transit_triggers') or (modules.get('transit_triggers') if isinstance(modules.get('transit_triggers'), list) else [])
|
||||
if isinstance(raw_triggers, list):
|
||||
for item in raw_triggers[:6]:
|
||||
if not isinstance(item, dict):
|
||||
continue
|
||||
triggers.append({
|
||||
key: item[key]
|
||||
for key in ('date', 'planet', 'target', 'kind', 'orb')
|
||||
if key in item and item[key] is not None
|
||||
})
|
||||
modules['transits'] = {
|
||||
'status': 'executed' if compact_sade or triggers else 'blocked',
|
||||
'sade_sati': compact_sade,
|
||||
'triggers': triggers,
|
||||
'boundary': 'observation windows, not guaranteed events',
|
||||
}
|
||||
except Exception as exc:
|
||||
modules['transits'] = {
|
||||
'status': 'blocked',
|
||||
'reason': exc.__class__.__name__,
|
||||
'boundary': 'observation windows, not guaranteed events',
|
||||
}
|
||||
diagnostics.append({'layer': 'transits', 'status': 'unavailable', 'reason': exc.__class__.__name__})
|
||||
|
||||
chart['local_consultation_layers'] = {
|
||||
'status': 'ready' if not diagnostics else 'partial',
|
||||
'source': 'repository_local_engines',
|
||||
@@ -1172,8 +1386,9 @@ def _attach_local_consultation_layers(handler, chart: dict, birth_payload: dict,
|
||||
'varga_full', 'varga_spectrum', 'arudha_padas', 'narayana_dasha',
|
||||
'dasha_sub_periods', 'ashtakavarga', 'kp_cusps', 'gulika',
|
||||
'functional_benefic_malefic', 'shadbala', 'kakshya',
|
||||
'yogas', 'chara_dasha', 'transits',
|
||||
)
|
||||
if _consultation_layer_present(modules.get(name))
|
||||
if _consultation_audit_status(modules.get(name)) == 'executed'
|
||||
],
|
||||
'diagnostics': diagnostics,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user