Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions backend/engines/compute.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
"""
Headless Compute Engine — All deterministic math in one function call.

compute_all() runs every deterministic agent in sequence and returns the
complete bundled result. This is the function behind the /api/v1/calculate
endpoint — designed for sub-50ms execution with zero LLM involvement.

Use cases:
- Frontend real-time sliders that update as the user drags
- Comparison tools that need fast recalculation
- Batch processing without burning API quota
- Unit testing the math pipeline in isolation
"""
import sys
import os
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from schemas.schemas import UserInput, ComputeAllOutput
from engines.india_defaults import calculate_true_total_cost
from agents.deterministic.financial_reality import calculate_affordability
from agents.deterministic.scenario_simulation import run_all_scenarios
from agents.deterministic.risk_scorer import calculate_risk_score


def compute_all(user_input: UserInput) -> ComputeAllOutput:
"""
Run every deterministic calculation and return the bundled result.

Execution order (respects dependencies):
1. india_defaults — hidden cost breakdown (independent)
2. affordability — EMI, ratios, cash flow (independent)
3. scenarios — stress tests (depends on #2)
4. risk_score — composite score (depends on #2 and #3)

Total execution time target: < 50ms on a single CPU core.
All functions are pure Python arithmetic with no I/O.
"""
loan_amount = user_input.property_price - user_input.down_payment
if loan_amount < 0:
loan_amount = 0.0

india_costs = calculate_true_total_cost(
base_price=user_input.property_price,
state=user_input.state,
property_type=user_input.property_type.value,
loan_amount=loan_amount,
area_sqft=user_input.area_sqft if user_input.area_sqft else 1000,
)

financial_reality = calculate_affordability(user_input)
all_scenarios = run_all_scenarios(user_input, financial_reality)
risk_score = calculate_risk_score(
financial_reality=financial_reality,
all_scenarios=all_scenarios,
age=user_input.age,
tenure_years=user_input.tenure_years,
)

return ComputeAllOutput(
india_cost_breakdown=india_costs,
financial_reality=financial_reality,
all_scenarios=all_scenarios,
risk_score=risk_score,
)
25 changes: 25 additions & 0 deletions backend/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
from agents.deterministic.risk_scorer import calculate_risk_score
from engines.pdf_generator import generate_pdf
from storage.gcs_client import upload_pdf
# Headless compute engine (PR: headless-calculate-endpoint)
from engines.compute import compute_all


# ---------------------------------------------------------------------------
Expand Down Expand Up @@ -102,6 +104,29 @@ async def health_check():
return {"status": "healthy", "service": "niv-ai-home-buying-advisor", "version": "1.0.0"}


# ---------------------------------------------------------------------------
# Headless calculate — pure math, no LLM, no auth required
# ---------------------------------------------------------------------------

@app.post("/api/v1/calculate", response_model=APIResponse)
async def calculate_route(user_input: UserInput):
"""
Headless deterministic calculation endpoint.
Runs all math agents and returns the bundled result.
No auth required — pure math, zero API budget cost.
Designed for frontend real-time sliders. Target: < 50ms.
"""
try:
result = compute_all(user_input)
return APIResponse(
success=True,
message="Calculation complete",
data=result.model_dump(),
)
except Exception as e:
raise HTTPException(status_code=500, detail=f"Calculation failed: {str(e)}")


# ---------------------------------------------------------------------------
# Session management
# ---------------------------------------------------------------------------
Expand Down
14 changes: 13 additions & 1 deletion backend/schemas/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -576,4 +576,16 @@ class SessionStartResponse(BaseModel):
class ConversationResponse(BaseModel):
session_id: str
conversation_output: ConversationOutput
updated_analysis: Optional[AnalysisResponse] = None
updated_analysis: Optional[AnalysisResponse] = None


# -----------------------------------------------------------------------------
# Headless compute engine output (PR: headless-calculate-endpoint)
# -----------------------------------------------------------------------------

class ComputeAllOutput(BaseModel):
"""Bundled output of all deterministic calculations — no LLM involved."""
india_cost_breakdown: IndiaCostBreakdown
financial_reality: FinancialRealityOutput
all_scenarios: AllScenariosOutput
risk_score: RiskScoreOutput