Spaces:
Sleeping
Sleeping
| """ | |
| Fyltr Form Generator Service (LangGraph). | |
| POST /generate-form: full form from description. | |
| POST /refine-form: surgical diff (changes, additions, removals). | |
| """ | |
| import logging | |
| import os | |
| from fastapi import FastAPI, HTTPException | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from dotenv import load_dotenv | |
| from schema import ( | |
| GenerateFormRequest, | |
| GenerateFormResponse, | |
| RefineFormRequest, | |
| RefineFormResponse, | |
| RefineDiff, | |
| PlanFormRequest, | |
| PlanFormResponse, | |
| PlanFormQuestion, | |
| PlanFormQuestionOption, | |
| ) | |
| from src.form_generator_workflow import workflow_instance, plan_form_request | |
| load_dotenv() | |
| logging.basicConfig(level=logging.INFO) | |
| logger = logging.getLogger(__name__) | |
| app = FastAPI(title="Fyltr Form Generator Service", version="1.0.0") | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| async def root(): | |
| return {"message": "Fyltr Form Generator Service", "status": "running"} | |
| async def health(): | |
| return {"status": "healthy", "service": "form-generator"} | |
| async def plan_form_request_route(request: PlanFormRequest): | |
| """Lightweight preflight: decide if we need clarifying questions. No balance deduction.""" | |
| if not request.description or not request.description.strip(): | |
| return PlanFormResponse( | |
| should_ask_questions=False, | |
| questions=[], | |
| reasoning_summary="", | |
| ) | |
| if not os.getenv("OPENAI_API_KEY"): | |
| return PlanFormResponse( | |
| should_ask_questions=False, | |
| questions=[], | |
| reasoning_summary="Service not configured.", | |
| ) | |
| result = plan_form_request( | |
| description=request.description.strip(), | |
| current_fields=request.current_fields, | |
| current_title=request.current_title or "", | |
| ) | |
| if not result.get("success"): | |
| return PlanFormResponse( | |
| should_ask_questions=False, | |
| questions=[], | |
| reasoning_summary=result.get("error") or "Could not analyze request.", | |
| ) | |
| questions = [] | |
| for q in result.get("questions") or []: | |
| opts = None | |
| if q.get("options"): | |
| opts = [PlanFormQuestionOption(value=o.get("value", ""), label=o.get("label", "")) for o in q["options"] if isinstance(o, dict)] | |
| questions.append( | |
| PlanFormQuestion( | |
| id=q.get("id", "q"), | |
| label=q.get("label", ""), | |
| type=q.get("type", "text"), | |
| options=opts, | |
| required=bool(q.get("required", True)), | |
| ) | |
| ) | |
| return PlanFormResponse( | |
| should_ask_questions=result.get("should_ask_questions", False), | |
| questions=questions, | |
| reasoning_summary=result.get("reasoning_summary", "") or "Ready.", | |
| ) | |
| async def generate_form(request: GenerateFormRequest): | |
| if not request.description or not request.description.strip(): | |
| raise HTTPException(status_code=400, detail="description is required and must be non-empty") | |
| if not os.getenv("OPENAI_API_KEY"): | |
| raise HTTPException(status_code=500, detail="OPENAI_API_KEY not configured") | |
| result = workflow_instance.generate_form( | |
| request.description.strip(), | |
| conversation_context=request.conversation_context, | |
| user_goals=request.user_goals, | |
| preferred_field_types=request.preferred_field_types, | |
| must_have_logic=request.must_have_logic, | |
| ) | |
| if not result.get("success") or result.get("formJSON") is None: | |
| detail = result.get("error") or "Form generation failed" | |
| raise HTTPException(status_code=422, detail=detail) | |
| return GenerateFormResponse( | |
| formJSON=result["formJSON"], | |
| metadata=result.get("metadata") or {}, | |
| warnings=result.get("warnings"), | |
| ) | |
| async def refine_form(request: RefineFormRequest): | |
| if not request.user_request or not request.user_request.strip(): | |
| raise HTTPException(status_code=400, detail="user_request is required and must be non-empty") | |
| if not os.getenv("OPENAI_API_KEY"): | |
| raise HTTPException(status_code=500, detail="OPENAI_API_KEY not configured") | |
| result = workflow_instance.refine_form( | |
| user_request=request.user_request.strip(), | |
| current_fields=request.current_fields, | |
| current_title=request.current_title or "", | |
| conversation_context=request.conversation_context, | |
| ) | |
| if not result.get("success") or result.get("diff") is None: | |
| detail = result.get("error") or "Form refine failed" | |
| raise HTTPException(status_code=422, detail=detail) | |
| diff = result["diff"] | |
| return RefineFormResponse( | |
| diff=RefineDiff( | |
| changes=diff.get("changes", []), | |
| additions=diff.get("additions", []), | |
| removals=diff.get("removals", []), | |
| ) | |
| ) | |