from fastapi import APIRouter from pydantic import BaseModel from typing import Optional, List, Any from reasoning.reasoning import reason_check from reasoning.reflection import reflect_notes from reasoning.refine import refine_answer from persona.speak import apply_persona from ingest.intake_client import IntakeClient router = APIRouter() # ------------------------------------------------------ # Request schema # ------------------------------------------------------ class ReasonRequest(BaseModel): session_id: Optional[str] user_prompt: str temperature: float = 0.7 # ------------------------------------------------------ # /reason endpoint # ------------------------------------------------------ @router.post("/reason") async def run_reason(req: ReasonRequest): # 1. Summaries from Intake (context memory) intake = IntakeClient() intake_summary = await intake.get_context(req.session_id) # 2. Internal reflection notes reflection = await reflect_notes(intake_summary, identity_block=None) reflection_notes: List[str] = reflection.get("notes", []) # 3. Draft answer (weak, unfiltered) draft = await reason_check( user_prompt=req.user_prompt, identity_block=None, rag_block=None, reflection_notes=reflection_notes, ) # 4. Refine the answer (structured self-correction) refined_packet: dict[str, Any] = refine_answer( draft_output=draft, reflection_notes=reflection_notes, identity_block=None, rag_block=None, ) refined_text = refined_packet.get("final_output", draft) # 5. Persona styling (Lyra voice) final_output = apply_persona(refined_text) return { "draft": draft, "refined": refined_text, "final": final_output, "reflection_notes": reflection_notes, "session_id": req.session_id, }