feat: invoke VedAstro for chart and rectification
This commit is contained in:
@@ -88,6 +88,7 @@ export function toAgentConsultationContext(data: JsonRecord) {
|
||||
lagna_boundary: rectification.lagna_boundary,
|
||||
},
|
||||
thematic_evidence: selectedTheme,
|
||||
vedastro_gateway: record(data.vedastro_gateway),
|
||||
reference_transparency: record(data.reference_transparency),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ test("passes transparent public-case references into the agent context", () => {
|
||||
const source = readFileSync(new URL("../src/mastra/index.ts", import.meta.url), "utf8");
|
||||
|
||||
assert.match(source, /reference_transparency:\s*record\(data\.reference_transparency\)/);
|
||||
assert.match(source, /vedastro_gateway:\s*record\(data\.vedastro_gateway\)/);
|
||||
assert.match(source, /high_similarity_public_references_available/);
|
||||
assert.match(source, /requested_uncovered_domains/);
|
||||
assert.match(source, /public_context_only/);
|
||||
|
||||
@@ -25,7 +25,7 @@ def _bool_env(name: str) -> bool:
|
||||
def _timeout_seconds() -> float:
|
||||
raw = os.environ.get("VEDASTRO_TIMEOUT_SECONDS", "").strip()
|
||||
if not raw:
|
||||
return 4.0
|
||||
return 20.0
|
||||
try:
|
||||
return float(raw)
|
||||
except ValueError:
|
||||
@@ -34,8 +34,8 @@ def _timeout_seconds() -> float:
|
||||
|
||||
def build_report() -> dict:
|
||||
load_local_env(ROOT)
|
||||
endpoint = os.environ.get("VEDASTRO_API_ENDPOINT", "").strip()
|
||||
network_enabled = _bool_env("VEDASTRO_ENABLE_NETWORK")
|
||||
endpoint = os.environ.get("VEDASTRO_API_ENDPOINT", "https://api.vedastro.org/api").strip()
|
||||
network_enabled = os.environ.get("VEDASTRO_ENABLE_NETWORK", "1").strip().lower() in {"1", "true", "yes", "on"}
|
||||
timeout_seconds = _timeout_seconds()
|
||||
has_api_key = bool(os.environ.get("VEDASTRO_API_KEY", "").strip())
|
||||
free_tier_queue_enabled = _bool_env("VEDASTRO_FREE_TIER_QUEUE") or _bool_env("VEDASTRO_FREE_TIER_QUEUE_ENABLED") or _bool_env("VEDASTRO_ENABLE_FREE_TIER_QUEUE")
|
||||
|
||||
@@ -648,6 +648,18 @@ def execute_consultation_workflow(
|
||||
blind=bool(body.get('blind') or body.get('blind_technical_mode')),
|
||||
)
|
||||
|
||||
vedastro_gateway = rectification.get('vedastro_gateway') if isinstance(rectification, dict) else None
|
||||
if not isinstance(vedastro_gateway, dict):
|
||||
try:
|
||||
vedastro_gateway = handler._compute_vedastro_gateway_run(body)
|
||||
except Exception as exc: # Gateway evidence must not block the local chart result.
|
||||
vedastro_gateway = {
|
||||
'scope': 'vedastro_gateway_run',
|
||||
'status': 'official_blocked',
|
||||
'official_closure_reason': 'gateway_invocation_error',
|
||||
'error_type': type(exc).__name__,
|
||||
}
|
||||
|
||||
result = {
|
||||
'success': True,
|
||||
'endpoint': 'consultation_workflow',
|
||||
@@ -688,6 +700,7 @@ def execute_consultation_workflow(
|
||||
'muhurta_panchanga': muhurta_panchanga,
|
||||
'audited_remedies': audited_remedies,
|
||||
'vedastro_official': vedastro_official,
|
||||
'vedastro_gateway': vedastro_gateway,
|
||||
'runtime_truth': runtime_truth,
|
||||
'external_parity_gate': external_parity_gate,
|
||||
'interpretation_source_runtime_coverage': interpretation_source_runtime_coverage,
|
||||
@@ -6707,9 +6720,19 @@ class JyotishAPIHandler(BaseHTTPRequestHandler):
|
||||
headline = '出生时间风险较低,可进入完整解盘'
|
||||
next_action = '保留原始出生记录来源;重要预测仍建议用 Dasha/Transit/案例验证交叉确认。'
|
||||
|
||||
try:
|
||||
vedastro_gateway = self._compute_vedastro_gateway_run(body)
|
||||
except Exception as exc: # Keep rectification available when the external observation is down.
|
||||
vedastro_gateway = {
|
||||
'scope': 'vedastro_gateway_run',
|
||||
'status': 'official_blocked',
|
||||
'official_closure_reason': 'gateway_invocation_error',
|
||||
'error_type': type(exc).__name__,
|
||||
}
|
||||
return {
|
||||
'success': True,
|
||||
'endpoint': 'rectification_gate',
|
||||
'vedastro_gateway': vedastro_gateway,
|
||||
'ascendant': {
|
||||
'lon': asc_lon,
|
||||
'sign': SIGNS[int(asc_lon / 30) % 12],
|
||||
|
||||
@@ -15,12 +15,17 @@ from typing import Any
|
||||
BACKEND_PRIORITY = ["self_host", "official", "cache", "queue", "local_fallback"]
|
||||
BOUNDARY_TEXT = "Users never call VedAstro directly; backend gateway owns cache, queue, and fallback."
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
OFFICIAL_ENDPOINT = "https://api.vedastro.org/api"
|
||||
|
||||
|
||||
def _bool_env(name: str) -> bool:
|
||||
return os.environ.get(name, "").strip().lower() in {"1", "true", "yes", "on"}
|
||||
|
||||
|
||||
def _official_network_enabled() -> bool:
|
||||
return os.environ.get("VEDASTRO_ENABLE_NETWORK", "1").strip().lower() in {"1", "true", "yes", "on"}
|
||||
|
||||
|
||||
def _int_env(name: str, default: int = 0) -> int:
|
||||
raw = os.environ.get(name, "").strip()
|
||||
if not raw:
|
||||
@@ -32,9 +37,9 @@ def _int_env(name: str, default: int = 0) -> int:
|
||||
|
||||
|
||||
def build_gateway_config() -> dict[str, Any]:
|
||||
mode = os.environ.get("VEDASTRO_GATEWAY_MODE", "local_first").strip() or "local_first"
|
||||
mode = os.environ.get("VEDASTRO_GATEWAY_MODE", "official_first").strip() or "official_first"
|
||||
self_host = os.environ.get("VEDASTRO_SELF_HOST_ENDPOINT", "").strip()
|
||||
official = os.environ.get("VEDASTRO_API_ENDPOINT", "").strip()
|
||||
official = os.environ.get("VEDASTRO_API_ENDPOINT", OFFICIAL_ENDPOINT).strip()
|
||||
return {
|
||||
"mode": mode,
|
||||
"self_host_endpoint_configured": bool(self_host),
|
||||
@@ -49,7 +54,7 @@ def build_gateway_config() -> dict[str, Any]:
|
||||
def _active_backend(config: dict[str, Any]) -> str:
|
||||
if config["self_host_endpoint_configured"]:
|
||||
return "self_host"
|
||||
if config["official_endpoint_configured"] and _bool_env("VEDASTRO_ENABLE_NETWORK"):
|
||||
if config["official_endpoint_configured"] and _official_network_enabled():
|
||||
return "official"
|
||||
if config["cache_ttl_seconds"] > 0:
|
||||
return "cache"
|
||||
|
||||
@@ -109,7 +109,7 @@ def _run_capability_catalog(case: dict[str, Any]) -> dict[str, Any]:
|
||||
cwd=ROOT,
|
||||
text=True,
|
||||
capture_output=True,
|
||||
timeout=max(5.0, float(os.environ.get("VEDASTRO_TIMEOUT_SECONDS", "5") or 5)),
|
||||
timeout=max(5.0, float(os.environ.get("VEDASTRO_TIMEOUT_SECONDS", "20") or 20)),
|
||||
check=False,
|
||||
env=os.environ.copy(),
|
||||
)
|
||||
|
||||
@@ -2033,6 +2033,10 @@ def test_panchanga_range_rejects_large_ranges() -> None:
|
||||
|
||||
def test_rectification_gate_returns_varga_risk_summary() -> None:
|
||||
handler = _handler()
|
||||
handler._compute_vedastro_gateway_run = lambda body: { # type: ignore[method-assign]
|
||||
'status': 'official_verified',
|
||||
'official_raw_response': {'request_id': 'rectification-live-call'},
|
||||
}
|
||||
result = handler._compute_rectification_gate({
|
||||
'planets': _sample_planets(),
|
||||
'ascendant': {'lon': 92.0},
|
||||
@@ -2042,6 +2046,7 @@ def test_rectification_gate_returns_varga_risk_summary() -> None:
|
||||
|
||||
assert result['success'] is True
|
||||
assert result['endpoint'] == 'rectification_gate'
|
||||
assert result['vedastro_gateway']['official_raw_response']['request_id'] == 'rectification-live-call'
|
||||
assert result['effective_accuracy'] == '15min'
|
||||
assert 'headline' in result['summary']
|
||||
assert result['summary']['recommended_events']
|
||||
@@ -2261,6 +2266,11 @@ def test_consultation_workflow_uses_unified_orchestrator_contract(monkeypatch) -
|
||||
'endpoint': 'rectification_gate',
|
||||
'summary': {'recommended_events': ['career_change']},
|
||||
})
|
||||
monkeypatch.setattr(handler, '_compute_vedastro_gateway_run', lambda body: {
|
||||
'scope': 'vedastro_gateway_run',
|
||||
'status': 'official_verified',
|
||||
'official_raw_response': {'request_id': 'test-live-call'},
|
||||
})
|
||||
monkeypatch.setattr(handler, '_compute_thematic_report', lambda body: {
|
||||
'success': True,
|
||||
'endpoint': 'thematic_report',
|
||||
@@ -2324,6 +2334,8 @@ def test_consultation_workflow_uses_unified_orchestrator_contract(monkeypatch) -
|
||||
'official_blocked',
|
||||
'local_fallback',
|
||||
}
|
||||
assert result['vedastro_gateway']['status'] == 'official_verified'
|
||||
assert result['vedastro_gateway']['official_raw_response']['request_id'] == 'test-live-call'
|
||||
assert result['runtime_evidence_log']['quality_gate']['technique_audit_table_required'] is True
|
||||
assert result['runtime_evidence_log']['quality_gate']['technique_audit_table'][0]['technique'] == 'VedAstro Cloud State'
|
||||
assert result['machine_evidence_packet']['status'] == 'partial'
|
||||
|
||||
@@ -3,7 +3,7 @@ from __future__ import annotations
|
||||
import json
|
||||
|
||||
|
||||
def test_gateway_status_defaults_to_local_first_cn_safe(monkeypatch):
|
||||
def test_gateway_status_defaults_to_official_first_cn_safe(monkeypatch):
|
||||
from scripts import vedastro_gateway
|
||||
|
||||
monkeypatch.delenv("VEDASTRO_GATEWAY_MODE", raising=False)
|
||||
@@ -17,13 +17,12 @@ def test_gateway_status_defaults_to_local_first_cn_safe(monkeypatch):
|
||||
status = vedastro_gateway.gateway_status()
|
||||
|
||||
assert status["scope"] == "vedastro_gateway"
|
||||
assert status["mode"] == "local_first"
|
||||
assert status["mode"] == "official_first"
|
||||
assert status["direct_browser_access_allowed"] is False
|
||||
assert status["frontend_secret_safe"] is True
|
||||
assert status["backend_priority"] == ["self_host", "official", "cache", "queue", "local_fallback"]
|
||||
assert status["active_backend"] == "local_fallback"
|
||||
assert status["official_readiness"]["official_ready"] is False
|
||||
assert "missing_endpoint" in status["official_readiness"]["readiness_blockers"]
|
||||
assert status["active_backend"] == "official"
|
||||
assert status["official_readiness"]["official_ready"] is True
|
||||
assert status["boundary"] == "Users never call VedAstro directly; backend gateway owns cache, queue, and fallback."
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user