Spaces:
Sleeping
Sleeping
File size: 3,959 Bytes
b4c62e2 c910e41 4869492 d780ea2 cd40088 d780ea2 e933edd c910e41 4869492 c910e41 4869492 c910e41 4869492 c910e41 47e1153 6d2002f 4869492 2d596fc c910e41 47e1153 4869492 6d2002f 1fb4ee6 4869492 c910e41 4869492 c910e41 d780ea2 4869492 c910e41 4869492 c910e41 4869492 c910e41 4869492 d780ea2 1fb4ee6 4869492 c910e41 4869492 c910e41 6d2002f 4869492 c910e41 4869492 c910e41 4869492 c910e41 d780ea2 6d2002f c910e41 4869492 c910e41 4869492 c910e41 4869492 c910e41 4869492 c910e41 4869492 c910e41 4869492 c910e41 4869492 6d2002f 4869492 1ef5210 c910e41 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | import os
import uuid
from typing import List, Dict, Optional
from pydantic import BaseModel
from langgraph.graph import StateGraph
from .document_parser import parse_documents
from .requirements_extractor import extract_requirements
from .ui_generator import generate_ui_html
# ==========================================================
# π§± Define the State Schema (Pydantic model)
# ==========================================================
class PipelineState(BaseModel):
files: Optional[List[str]] = None
text: Optional[str] = None
requirements: Optional[Dict] = None
html: Optional[str] = None
public_url: Optional[str] = None
# ==========================================================
# π Node 1 β Document Parser
# ==========================================================
async def node_parse_docs(state: PipelineState):
print("π [Document Parser] Extracting text...")
result = await parse_documents(state.files)
# handle both string or dict outputs
if isinstance(result, dict):
text = result.get("text", "").strip()
else:
text = str(result).strip()
if not text:
raise ValueError("No text extracted from documents.")
return {"text": text}
# ==========================================================
# π§ Node 2 β Requirements Extractor
# ==========================================================
async def node_requirements(state: PipelineState, config=None) -> Dict:
print("π§© [Requirements Agent] Extracting structured info...")
if not state.text:
raise ValueError("Missing 'text' field in state for requirement extraction.")
requirements = await extract_requirements(state.text)
if not requirements:
raise ValueError("Requirements extraction returned empty.")
return {"requirements": requirements}
# ==========================================================
# π¨ Node 3 β UI Generator
# ==========================================================
async def node_ui_generator(state: PipelineState, config=None) -> Dict:
print("π¨ [UI Generator] Creating PowerApps-style interface...")
if not state.requirements:
raise ValueError("Missing 'requirements' in state for UI generation.")
# Load reference design
ref_path = os.path.join("templates", "demo_qms_design.html")
if not os.path.exists(ref_path):
raise FileNotFoundError(f"Reference HTML not found at {ref_path}")
with open(ref_path, "r", encoding="utf-8") as f:
reference_html = f.read()
ui = await generate_ui_html(state.requirements, reference_html)
html = ui.get("html", "")
if not html or "<html" not in html:
raise ValueError("Generated HTML invalid or empty.")
# Save to static/outputs/
os.makedirs("static/outputs", exist_ok=True)
session_id = uuid.uuid4().hex
html_path = os.path.join("static/outputs", f"{session_id}.html")
with open(html_path, "w", encoding="utf-8") as f:
f.write(html)
base_url = os.environ.get("BASE_PUBLIC_URL", "").rstrip("/")
if not base_url:
base_url = "http://localhost:7860"
public_url = f"{base_url}/static/outputs/{session_id}.html"
print(f"β
[UI Generator] Generated UI available at: {public_url}")
return {"html": html, "public_url": public_url}
# ==========================================================
# π Build the LangGraph
# ==========================================================
graph = StateGraph(PipelineState)
graph.add_node("parse_docs", node_parse_docs)
graph.add_node("requirements", node_requirements)
graph.add_node("ui_generator", node_ui_generator)
graph.set_entry_point("parse_docs")
graph.add_edge("parse_docs", "requirements")
graph.add_edge("requirements", "ui_generator")
graph.set_finish_point("ui_generator")
graph = graph.compile()
print("β
LangGraph pipeline loaded successfully: Document β Requirements β UI Generator") |