Spaces:
Sleeping
Sleeping
Update agents/ui_generator.py
Browse files- agents/ui_generator.py +33 -9
agents/ui_generator.py
CHANGED
|
@@ -6,13 +6,11 @@ PROMPT = """
|
|
| 6 |
You are an expert PowerApps-style UI generator and business workflow designer.
|
| 7 |
Your goal is to create a Recruitment Management Application HTML layout that follows
|
| 8 |
exactly the same layout, structure, and JavaScript logic as the reference QMS app design provided below.
|
| 9 |
-
|
| 10 |
### 🔧 INSTRUCTIONS
|
| 11 |
1️⃣ Mimic the UI structure and components of the QMS reference exactly:
|
| 12 |
- Keep the sidebar, header, and multi-screen logic identical.
|
| 13 |
- Each .menu-item must open a corresponding .screen using the same showScreen() JS pattern.
|
| 14 |
- Each workflow stage (like Draft → Manage → Review → etc.) should be clickable and update the workflow progress using the same logic from the reference.
|
| 15 |
-
|
| 16 |
2️⃣ Adapt the content to Recruitment Workflow:
|
| 17 |
Replace QMS-specific names with Recruitment equivalents while keeping UI consistency.
|
| 18 |
For example:
|
|
@@ -20,19 +18,16 @@ For example:
|
|
| 20 |
- “Draft / Review / Approval / Published” → “Requisition / Sourcing / Interview / Offer / Hired”
|
| 21 |
- “Document Type / Identifier” → “Job Role / Candidate ID”
|
| 22 |
- “Reviewer / Approver” → “Hiring Manager / HR Lead”
|
| 23 |
-
|
| 24 |
3️⃣ Keep CSS and JS identical to the reference except where labels or icons differ.
|
| 25 |
- Preserve all existing class names (e.g., .workflow-step, .screen, .menu-item, .kanban-board).
|
| 26 |
- Only modify inner HTML and labels.
|
| 27 |
- Keep inline scripts functional — do not remove event handlers.
|
| 28 |
-
|
| 29 |
4️⃣ Functional Requirements:
|
| 30 |
- Must be a single standalone HTML document (no markdown, no external JS).
|
| 31 |
- Include embedded <style> and <script> tags (like the reference).
|
| 32 |
- Maintain all transitions, dynamic toggles, and progress updates.
|
| 33 |
- All UI parts (menu, header, cards, workflow) must remain interactive.
|
| 34 |
- Icons should use Font Awesome 6 syntax.
|
| 35 |
-
|
| 36 |
5️⃣ Sidebar and Navigation Consistency (Dynamic Rule):
|
| 37 |
- Automatically detect all sidebar sections and menu items from the reference design’s <div class="sidebar"> block.
|
| 38 |
- Recreate the same sidebar structure, menu hierarchy, and icons exactly as they appear in the reference.
|
|
@@ -40,11 +35,9 @@ For example:
|
|
| 40 |
- Only replace text labels where the business context clearly requires recruitment-related equivalents.
|
| 41 |
- Maintain the same onclick="showScreen('...')" mapping and active class behavior.
|
| 42 |
- If new screens are generated from recruitment documents, append them under the most relevant section while preserving the reference menu’s ordering.
|
| 43 |
-
|
| 44 |
📘 Reference Design:
|
| 45 |
--------------------
|
| 46 |
{reference_html}
|
| 47 |
-
|
| 48 |
📄 Recruitment Document Content:
|
| 49 |
--------------------
|
| 50 |
{requirements}
|
|
@@ -58,6 +51,7 @@ async def generate_ui_html(requirements: Dict, reference_html: str) -> Dict:
|
|
| 58 |
req_json = json.dumps(requirements, ensure_ascii=False, indent=2)
|
| 59 |
prompt = PROMPT.format(reference_html=reference_html[:12000], requirements=req_json)
|
| 60 |
|
|
|
|
| 61 |
html = await call_llm(
|
| 62 |
prompt,
|
| 63 |
system="Generate a standalone interactive HTML UI following the reference structure.",
|
|
@@ -65,9 +59,39 @@ async def generate_ui_html(requirements: Dict, reference_html: str) -> Dict:
|
|
| 65 |
api_key=GEMINI_KEY_GENERATOR,
|
| 66 |
)
|
| 67 |
|
| 68 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 69 |
match = re.search(r"(<html[\s\S]*?</html>)", html, flags=re.IGNORECASE)
|
| 70 |
if match:
|
| 71 |
html = match.group(1)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 72 |
|
| 73 |
-
return {"html": html.strip()}
|
|
|
|
| 6 |
You are an expert PowerApps-style UI generator and business workflow designer.
|
| 7 |
Your goal is to create a Recruitment Management Application HTML layout that follows
|
| 8 |
exactly the same layout, structure, and JavaScript logic as the reference QMS app design provided below.
|
|
|
|
| 9 |
### 🔧 INSTRUCTIONS
|
| 10 |
1️⃣ Mimic the UI structure and components of the QMS reference exactly:
|
| 11 |
- Keep the sidebar, header, and multi-screen logic identical.
|
| 12 |
- Each .menu-item must open a corresponding .screen using the same showScreen() JS pattern.
|
| 13 |
- Each workflow stage (like Draft → Manage → Review → etc.) should be clickable and update the workflow progress using the same logic from the reference.
|
|
|
|
| 14 |
2️⃣ Adapt the content to Recruitment Workflow:
|
| 15 |
Replace QMS-specific names with Recruitment equivalents while keeping UI consistency.
|
| 16 |
For example:
|
|
|
|
| 18 |
- “Draft / Review / Approval / Published” → “Requisition / Sourcing / Interview / Offer / Hired”
|
| 19 |
- “Document Type / Identifier” → “Job Role / Candidate ID”
|
| 20 |
- “Reviewer / Approver” → “Hiring Manager / HR Lead”
|
|
|
|
| 21 |
3️⃣ Keep CSS and JS identical to the reference except where labels or icons differ.
|
| 22 |
- Preserve all existing class names (e.g., .workflow-step, .screen, .menu-item, .kanban-board).
|
| 23 |
- Only modify inner HTML and labels.
|
| 24 |
- Keep inline scripts functional — do not remove event handlers.
|
|
|
|
| 25 |
4️⃣ Functional Requirements:
|
| 26 |
- Must be a single standalone HTML document (no markdown, no external JS).
|
| 27 |
- Include embedded <style> and <script> tags (like the reference).
|
| 28 |
- Maintain all transitions, dynamic toggles, and progress updates.
|
| 29 |
- All UI parts (menu, header, cards, workflow) must remain interactive.
|
| 30 |
- Icons should use Font Awesome 6 syntax.
|
|
|
|
| 31 |
5️⃣ Sidebar and Navigation Consistency (Dynamic Rule):
|
| 32 |
- Automatically detect all sidebar sections and menu items from the reference design’s <div class="sidebar"> block.
|
| 33 |
- Recreate the same sidebar structure, menu hierarchy, and icons exactly as they appear in the reference.
|
|
|
|
| 35 |
- Only replace text labels where the business context clearly requires recruitment-related equivalents.
|
| 36 |
- Maintain the same onclick="showScreen('...')" mapping and active class behavior.
|
| 37 |
- If new screens are generated from recruitment documents, append them under the most relevant section while preserving the reference menu’s ordering.
|
|
|
|
| 38 |
📘 Reference Design:
|
| 39 |
--------------------
|
| 40 |
{reference_html}
|
|
|
|
| 41 |
📄 Recruitment Document Content:
|
| 42 |
--------------------
|
| 43 |
{requirements}
|
|
|
|
| 51 |
req_json = json.dumps(requirements, ensure_ascii=False, indent=2)
|
| 52 |
prompt = PROMPT.format(reference_html=reference_html[:12000], requirements=req_json)
|
| 53 |
|
| 54 |
+
print("🚀 [UI Generator] Sending prompt to Gemini...")
|
| 55 |
html = await call_llm(
|
| 56 |
prompt,
|
| 57 |
system="Generate a standalone interactive HTML UI following the reference structure.",
|
|
|
|
| 59 |
api_key=GEMINI_KEY_GENERATOR,
|
| 60 |
)
|
| 61 |
|
| 62 |
+
# Debug preview
|
| 63 |
+
print("🔧 Raw Gemini output (first 400 chars):\n", html[:400])
|
| 64 |
+
|
| 65 |
+
# ==========================================================
|
| 66 |
+
# 🧼 CLEANUP PHASE — remove markdown, explanations, artifacts
|
| 67 |
+
# ==========================================================
|
| 68 |
+
if not html or len(html.strip()) < 20:
|
| 69 |
+
raise ValueError("Gemini returned an empty or invalid response.")
|
| 70 |
+
|
| 71 |
+
# Remove markdown code fences (```html ... ``` or ```)
|
| 72 |
+
html = re.sub(r"^```html", "", html.strip(), flags=re.IGNORECASE | re.MULTILINE)
|
| 73 |
+
html = re.sub(r"^```", "", html.strip(), flags=re.MULTILINE)
|
| 74 |
+
html = re.sub(r"```$", "", html.strip(), flags=re.MULTILINE)
|
| 75 |
+
|
| 76 |
+
# Remove common prefix like "Here’s your HTML:" or "Sure, here is"
|
| 77 |
+
html = re.sub(r"^(Here[’']?s|Sure,|OK,|Below is|Here is).*?<html", "<html", html, flags=re.IGNORECASE | re.DOTALL)
|
| 78 |
+
|
| 79 |
+
# ==========================================================
|
| 80 |
+
# 🧩 EXTRACT OR WRAP HTML
|
| 81 |
+
# ==========================================================
|
| 82 |
match = re.search(r"(<html[\s\S]*?</html>)", html, flags=re.IGNORECASE)
|
| 83 |
if match:
|
| 84 |
html = match.group(1)
|
| 85 |
+
else:
|
| 86 |
+
print("⚠️ No <html> tag found — wrapping raw output manually.")
|
| 87 |
+
html = f"<html><body>{html}</body></html>"
|
| 88 |
+
|
| 89 |
+
# ==========================================================
|
| 90 |
+
# ✅ FINAL VALIDATION
|
| 91 |
+
# ==========================================================
|
| 92 |
+
if "<html" not in html or "</html>" not in html:
|
| 93 |
+
raise ValueError("Generated HTML missing <html> structure after cleaning.")
|
| 94 |
+
|
| 95 |
+
print(f"✅ [UI Generator] Cleaned HTML ready — length {len(html)} chars")
|
| 96 |
|
| 97 |
+
return {"html": html.strip()}
|