dina1 commited on
Commit
c910e41
Β·
verified Β·
1 Parent(s): 4869492

Update agents/graph_builder_langgraph.py

Browse files
Files changed (1) hide show
  1. agents/graph_builder_langgraph.py +45 -45
agents/graph_builder_langgraph.py CHANGED
@@ -1,109 +1,109 @@
1
  import os
 
 
 
2
  from langgraph.graph import StateGraph
3
  from .document_parser import parse_documents
4
  from .requirements_extractor import extract_requirements
5
  from .ui_generator import generate_ui_html
6
 
 
7
  # ==========================================================
8
- # 🧩 Agent Node 1: Document Parser
9
  # ==========================================================
10
- async def node_parse_docs(state, config=None):
11
- """Extract text content from uploaded documents."""
12
- files = state.get("files", [])
13
- if not files:
14
- raise ValueError("No input files provided to document parser.")
 
 
15
 
 
 
 
 
16
  print("πŸ“„ [Document Parser] Extracting text...")
17
- text = await parse_documents(files)
18
 
19
- if not text or not text.strip():
 
 
 
 
20
  raise ValueError("Document parser returned empty text.")
21
 
22
- # Return as state update
23
  return {"text": text}
24
 
25
 
26
  # ==========================================================
27
- # 🧠 Agent Node 2: Requirements Extractor
28
  # ==========================================================
29
- async def node_requirements(state, config=None):
30
- """Extract structured business requirements from text."""
31
  print("🧩 [Requirements Agent] Extracting structured info...")
32
 
33
- text = state.get("text")
34
- if not text:
35
- raise ValueError("Missing input text for requirements extraction.")
36
-
37
- requirements = await extract_requirements(text)
38
 
 
39
  if not requirements:
40
- raise ValueError("Requirements extraction failed or returned empty.")
41
 
42
  return {"requirements": requirements}
43
 
44
 
45
  # ==========================================================
46
- # 🎨 Agent Node 3: UI Generator
47
  # ==========================================================
48
- async def node_ui_generator(state, config=None):
49
- """Generate HTML UI using Gemini (PowerApps-style layout)."""
50
  print("🎨 [UI Generator] Creating PowerApps-style interface...")
51
 
52
- requirements = state.get("requirements")
53
- if not requirements:
54
- raise ValueError("Missing requirements for UI generation.")
55
 
56
  # Load reference design
57
- reference_html_path = os.path.join("templates", "demo_qms_design.html")
58
- if not os.path.exists(reference_html_path):
59
- raise FileNotFoundError(f"Reference HTML not found at {reference_html_path}")
60
 
61
- with open(reference_html_path, "r", encoding="utf-8") as f:
62
  reference_html = f.read()
63
 
64
- ui = await generate_ui_html(requirements, reference_html)
65
  html = ui.get("html", "")
66
 
67
  if not html or "<html" not in html:
68
  raise ValueError("Generated HTML invalid or empty.")
69
 
70
- # Save to static/outputs
71
  os.makedirs("static/outputs", exist_ok=True)
72
- import uuid
73
  session_id = uuid.uuid4().hex
74
- html_filename = f"{session_id}.html"
75
- html_path = os.path.join("static/outputs", html_filename)
76
  with open(html_path, "w", encoding="utf-8") as f:
77
  f.write(html)
78
 
79
- # Construct public link
80
  base_url = os.environ.get("BASE_PUBLIC_URL", "").rstrip("/")
81
  if not base_url:
82
  base_url = "http://localhost:7860"
83
- public_url = f"{base_url}/static/outputs/{html_filename}"
84
 
85
- print(f"βœ… [UI Generator] HTML generated at: {public_url}")
 
 
86
 
87
- return {
88
- "html": html,
89
- "public_url": public_url
90
- }
91
 
92
 
93
  # ==========================================================
94
- # πŸ”— LangGraph Flow Definition
95
  # ==========================================================
96
- graph = StateGraph()
97
 
98
- # Add nodes (agents)
99
  graph.add_node("parse_docs", node_parse_docs)
100
  graph.add_node("requirements", node_requirements)
101
  graph.add_node("ui_generator", node_ui_generator)
102
 
103
- # Define edges (data flow)
104
  graph.set_entry_point("parse_docs")
105
  graph.add_edge("parse_docs", "requirements")
106
  graph.add_edge("requirements", "ui_generator")
107
  graph.set_finish_point("ui_generator")
108
 
109
- print("βœ… LangGraph pipeline initialized: [Document Parser β†’ Requirements β†’ UI Generator]")
 
1
  import os
2
+ import uuid
3
+ from typing import List, Dict, Optional
4
+ from pydantic import BaseModel
5
  from langgraph.graph import StateGraph
6
  from .document_parser import parse_documents
7
  from .requirements_extractor import extract_requirements
8
  from .ui_generator import generate_ui_html
9
 
10
+
11
  # ==========================================================
12
+ # 🧱 Define the State Schema (Pydantic model)
13
  # ==========================================================
14
+ class PipelineState(BaseModel):
15
+ files: Optional[List[str]] = None
16
+ text: Optional[str] = None
17
+ requirements: Optional[Dict] = None
18
+ html: Optional[str] = None
19
+ public_url: Optional[str] = None
20
+
21
 
22
+ # ==========================================================
23
+ # πŸ“„ Node 1 β€” Document Parser
24
+ # ==========================================================
25
+ async def node_parse_docs(state: PipelineState, config=None) -> Dict:
26
  print("πŸ“„ [Document Parser] Extracting text...")
 
27
 
28
+ if not state.files:
29
+ raise ValueError("No input files provided to document parser.")
30
+
31
+ text = await parse_documents(state.files)
32
+ if not text.strip():
33
  raise ValueError("Document parser returned empty text.")
34
 
 
35
  return {"text": text}
36
 
37
 
38
  # ==========================================================
39
+ # 🧠 Node 2 β€” Requirements Extractor
40
  # ==========================================================
41
+ async def node_requirements(state: PipelineState, config=None) -> Dict:
 
42
  print("🧩 [Requirements Agent] Extracting structured info...")
43
 
44
+ if not state.text:
45
+ raise ValueError("Missing 'text' field in state for requirement extraction.")
 
 
 
46
 
47
+ requirements = await extract_requirements(state.text)
48
  if not requirements:
49
+ raise ValueError("Requirements extraction returned empty.")
50
 
51
  return {"requirements": requirements}
52
 
53
 
54
  # ==========================================================
55
+ # 🎨 Node 3 β€” UI Generator
56
  # ==========================================================
57
+ async def node_ui_generator(state: PipelineState, config=None) -> Dict:
 
58
  print("🎨 [UI Generator] Creating PowerApps-style interface...")
59
 
60
+ if not state.requirements:
61
+ raise ValueError("Missing 'requirements' in state for UI generation.")
 
62
 
63
  # Load reference design
64
+ ref_path = os.path.join("templates", "demo_qms_design.html")
65
+ if not os.path.exists(ref_path):
66
+ raise FileNotFoundError(f"Reference HTML not found at {ref_path}")
67
 
68
+ with open(ref_path, "r", encoding="utf-8") as f:
69
  reference_html = f.read()
70
 
71
+ ui = await generate_ui_html(state.requirements, reference_html)
72
  html = ui.get("html", "")
73
 
74
  if not html or "<html" not in html:
75
  raise ValueError("Generated HTML invalid or empty.")
76
 
77
+ # Save to static/outputs/
78
  os.makedirs("static/outputs", exist_ok=True)
 
79
  session_id = uuid.uuid4().hex
80
+ html_path = os.path.join("static/outputs", f"{session_id}.html")
 
81
  with open(html_path, "w", encoding="utf-8") as f:
82
  f.write(html)
83
 
 
84
  base_url = os.environ.get("BASE_PUBLIC_URL", "").rstrip("/")
85
  if not base_url:
86
  base_url = "http://localhost:7860"
 
87
 
88
+ public_url = f"{base_url}/static/outputs/{session_id}.html"
89
+
90
+ print(f"βœ… [UI Generator] Generated UI available at: {public_url}")
91
 
92
+ return {"html": html, "public_url": public_url}
 
 
 
93
 
94
 
95
  # ==========================================================
96
+ # πŸ”— Build the LangGraph
97
  # ==========================================================
98
+ graph = StateGraph(PipelineState)
99
 
 
100
  graph.add_node("parse_docs", node_parse_docs)
101
  graph.add_node("requirements", node_requirements)
102
  graph.add_node("ui_generator", node_ui_generator)
103
 
 
104
  graph.set_entry_point("parse_docs")
105
  graph.add_edge("parse_docs", "requirements")
106
  graph.add_edge("requirements", "ui_generator")
107
  graph.set_finish_point("ui_generator")
108
 
109
+ print("βœ… LangGraph pipeline loaded successfully: Document β†’ Requirements β†’ UI Generator")