Spaces:
Paused
Paused
Upload folder using huggingface_hub
Browse files- app.py +38 -25
- verify_final.py +25 -0
app.py
CHANGED
|
@@ -272,7 +272,7 @@ def get_example_personas():
|
|
| 272 |
if not os.path.exists(example_path):
|
| 273 |
return []
|
| 274 |
try:
|
| 275 |
-
files = [f for f in os.listdir(example_path) if f.endswith(".json")]
|
| 276 |
return sorted(files)
|
| 277 |
except Exception as e:
|
| 278 |
print(f"Error listing example personas: {e}")
|
|
@@ -302,14 +302,25 @@ def select_or_create_personas(theme, customer_profile, num_personas, force_metho
|
|
| 302 |
if force_method == "Example Persona" and example_file:
|
| 303 |
add_log(f"Loading example persona from {example_file}...")
|
| 304 |
try:
|
| 305 |
-
|
| 306 |
-
|
| 307 |
-
|
| 308 |
-
|
| 309 |
-
|
| 310 |
-
|
| 311 |
-
|
| 312 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 313 |
return [persona] * int(num_personas)
|
| 314 |
except Exception as e:
|
| 315 |
add_log(f"Failed to load example persona: {e}")
|
|
@@ -562,14 +573,15 @@ def generate_personas(theme, customer_profile, num_personas):
|
|
| 562 |
})
|
| 563 |
return personas_data
|
| 564 |
|
| 565 |
-
def generate_tasks(theme, customer_profile):
|
| 566 |
client = get_blablador_client()
|
| 567 |
if not client:
|
| 568 |
return [f"Task {i+1} for {theme} (BLABLADOR_API_KEY not set)" for i in range(10)]
|
| 569 |
|
| 570 |
prompt = f"""
|
| 571 |
-
Generate 10 sequential tasks for a user to perform on
|
| 572 |
-
The
|
|
|
|
| 573 |
|
| 574 |
The tasks should cover:
|
| 575 |
1. Communication
|
|
@@ -577,10 +589,10 @@ def generate_tasks(theme, customer_profile):
|
|
| 577 |
3. Custom Search / Information gathering
|
| 578 |
4. Emotional connection to the persona and content/styling
|
| 579 |
|
| 580 |
-
The tasks must be in sequential order.
|
| 581 |
|
| 582 |
-
CRITICAL: You MUST return a JSON object with a "tasks" key containing a list of strings.
|
| 583 |
-
Example: {
|
| 584 |
Do not include any other text in your response.
|
| 585 |
"""
|
| 586 |
|
|
@@ -625,10 +637,10 @@ def generate_tasks(theme, customer_profile):
|
|
| 625 |
|
| 626 |
return [f"Task {i+1} for {theme} (Manual fallback)" for i in range(10)]
|
| 627 |
|
| 628 |
-
def handle_generate(theme, customer_profile, num_personas, method, example_file):
|
| 629 |
try:
|
| 630 |
yield "Generating tasks...", None, None
|
| 631 |
-
tasks = generate_tasks(theme, customer_profile)
|
| 632 |
|
| 633 |
yield "Selecting or creating personas...", tasks, None
|
| 634 |
personas = select_or_create_personas(theme, customer_profile, num_personas, force_method=method, example_file=example_file)
|
|
@@ -1006,7 +1018,7 @@ You are an expert Frontend Developer. Your task is to implement the following "L
|
|
| 1006 |
"""
|
| 1007 |
return prompt
|
| 1008 |
|
| 1009 |
-
def generate_full_ui_call(repo, branch, session_id, selected_solutions_json):
|
| 1010 |
if not ANALYSIS_API_KEY or not session_id:
|
| 1011 |
return "Error: API Key or Session ID missing. Start a session first."
|
| 1012 |
|
|
@@ -1019,7 +1031,7 @@ def generate_full_ui_call(repo, branch, session_id, selected_solutions_json):
|
|
| 1019 |
return f"Error reading template: {e}"
|
| 1020 |
|
| 1021 |
prompt = template.replace("{{selected_solutions}}", selected_solutions_json)
|
| 1022 |
-
prompt = prompt.replace("{{url}}", "the analyzed website")
|
| 1023 |
prompt = prompt.replace("{{analysis_report}}", "See previous activities in this session")
|
| 1024 |
prompt = prompt.replace("{{report_id}}", session_id[:8])
|
| 1025 |
prompt = prompt.replace("{{screenshots_dir}}", f"user_experience_reports/screenshots/{session_id[:8]}")
|
|
@@ -1051,7 +1063,8 @@ def poll_for_generated_ui(repo_full_name, branch_name, session_id):
|
|
| 1051 |
except:
|
| 1052 |
return "UI not generated yet. Please wait..."
|
| 1053 |
|
| 1054 |
-
def blablador_chat_adaptation(message, history, session_id):
|
|
|
|
| 1055 |
if not BLABLADOR_API_KEY or not session_id:
|
| 1056 |
return history + [("System", "Error: BLABLADOR_API_KEY or Session ID missing.")], ""
|
| 1057 |
|
|
@@ -1151,7 +1164,7 @@ with gr.Blocks(title="UX Analysis Orchestrator") as demo:
|
|
| 1151 |
with gr.Tab("Presentation Carousel"):
|
| 1152 |
gr.Markdown("### View Presentation Slides")
|
| 1153 |
with gr.Row():
|
| 1154 |
-
sl_repo_select = gr.Dropdown(label="Repository", choices=
|
| 1155 |
sl_branch_select = gr.Dropdown(label="Branch", choices=get_repo_branches(REPO_NAME))
|
| 1156 |
sl_refresh_branches_btn = gr.Button("Refresh Branches")
|
| 1157 |
|
|
@@ -1236,7 +1249,7 @@ with gr.Blocks(title="UX Analysis Orchestrator") as demo:
|
|
| 1236 |
with gr.Tab("Report Viewer"):
|
| 1237 |
gr.Markdown("### View UX Reports & Solutions")
|
| 1238 |
with gr.Row():
|
| 1239 |
-
rv_repo_select = gr.Dropdown(label="Repository", choices=
|
| 1240 |
rv_branch_select = gr.Dropdown(label="Branch", choices=get_repo_branches(REPO_NAME))
|
| 1241 |
rv_refresh_branches_btn = gr.Button("Refresh Branches")
|
| 1242 |
|
|
@@ -1313,7 +1326,7 @@ with gr.Blocks(title="UX Analysis Orchestrator") as demo:
|
|
| 1313 |
ui_chat_msg = gr.Textbox(label="Request Modification", placeholder="e.g. Change primary color to emerald...")
|
| 1314 |
ui_chat_send = gr.Button("Send Request")
|
| 1315 |
|
| 1316 |
-
generate_full_ui_btn.click(fn=generate_full_ui_call, inputs=[rv_repo_select, rv_branch_select, active_session_state, selected_solutions_json_state], outputs=[full_ui_iframe])
|
| 1317 |
refresh_ui_btn.click(fn=poll_for_generated_ui, inputs=[rv_repo_select, rv_branch_select, active_session_state], outputs=[full_ui_iframe])
|
| 1318 |
ui_chat_send.click(fn=blablador_chat_adaptation, inputs=[ui_chat_msg, ui_chatbot, active_session_state], outputs=[ui_chatbot, ui_chat_msg])
|
| 1319 |
|
|
@@ -1322,7 +1335,7 @@ with gr.Blocks(title="UX Analysis Orchestrator") as demo:
|
|
| 1322 |
gr.Markdown("### System Diagnostics & Manual Connection")
|
| 1323 |
with gr.Row():
|
| 1324 |
sys_token_input = gr.Textbox(label="GitHub Token (Leave blank for default)", type="password")
|
| 1325 |
-
sys_repo_input = gr.Textbox(label="Repository (e.g., JsonLord/tiny_web)", value=REPO_NAME)
|
| 1326 |
sys_test_btn = gr.Button("Test Connection & Fetch Branches")
|
| 1327 |
|
| 1328 |
sys_status = gr.Textbox(label="Connection Status", interactive=False)
|
|
@@ -1385,7 +1398,7 @@ with gr.Blocks(title="UX Analysis Orchestrator") as demo:
|
|
| 1385 |
# Event handlers
|
| 1386 |
generate_btn.click(
|
| 1387 |
fn=handle_generate,
|
| 1388 |
-
inputs=[theme_input, profile_input, num_personas_input, persona_method, example_persona_select],
|
| 1389 |
outputs=[status_output, task_list_display, persona_display]
|
| 1390 |
)
|
| 1391 |
|
|
|
|
| 272 |
if not os.path.exists(example_path):
|
| 273 |
return []
|
| 274 |
try:
|
| 275 |
+
files = [f for f in os.listdir(example_path) if f.endswith(".json") or f.endswith(".md")]
|
| 276 |
return sorted(files)
|
| 277 |
except Exception as e:
|
| 278 |
print(f"Error listing example personas: {e}")
|
|
|
|
| 302 |
if force_method == "Example Persona" and example_file:
|
| 303 |
add_log(f"Loading example persona from {example_file}...")
|
| 304 |
try:
|
| 305 |
+
path = os.path.join("external/TinyTroupe/examples/agents/", example_file)
|
| 306 |
+
if example_file.endswith(".json"):
|
| 307 |
+
with open(path, "r") as f:
|
| 308 |
+
data = json.load(f)
|
| 309 |
+
# Adapt TinyTroupe format to our internal format
|
| 310 |
+
persona = {
|
| 311 |
+
"name": data.get("name", "Unknown"),
|
| 312 |
+
"minibio": data.get("mental_faculties", [{}])[0].get("context", "An example persona.") if "mental_faculties" in data else "An example persona.",
|
| 313 |
+
"persona": data
|
| 314 |
+
}
|
| 315 |
+
else: # .md
|
| 316 |
+
with open(path, "r") as f:
|
| 317 |
+
content = f.read()
|
| 318 |
+
name = example_file.replace(".md", "").replace("_", " ")
|
| 319 |
+
persona = {
|
| 320 |
+
"name": name,
|
| 321 |
+
"minibio": content,
|
| 322 |
+
"persona": {"name": name, "background": content}
|
| 323 |
+
}
|
| 324 |
return [persona] * int(num_personas)
|
| 325 |
except Exception as e:
|
| 326 |
add_log(f"Failed to load example persona: {e}")
|
|
|
|
| 573 |
})
|
| 574 |
return personas_data
|
| 575 |
|
| 576 |
+
def generate_tasks(theme, customer_profile, url):
|
| 577 |
client = get_blablador_client()
|
| 578 |
if not client:
|
| 579 |
return [f"Task {i+1} for {theme} (BLABLADOR_API_KEY not set)" for i in range(10)]
|
| 580 |
|
| 581 |
prompt = f"""
|
| 582 |
+
Generate EXACTLY 10 sequential tasks for a user to perform on the website: {url}
|
| 583 |
+
The theme of the analysis is: {theme}.
|
| 584 |
+
The user persona profile is: {customer_profile}.
|
| 585 |
|
| 586 |
The tasks should cover:
|
| 587 |
1. Communication
|
|
|
|
| 589 |
3. Custom Search / Information gathering
|
| 590 |
4. Emotional connection to the persona and content/styling
|
| 591 |
|
| 592 |
+
The tasks must be in sequential order and specific to the website {url}.
|
| 593 |
|
| 594 |
+
CRITICAL: You MUST return a JSON object with a "tasks" key containing a list of exactly 10 strings.
|
| 595 |
+
Example: {"tasks": ["task 1", "task 2", ..., "task 10"]}
|
| 596 |
Do not include any other text in your response.
|
| 597 |
"""
|
| 598 |
|
|
|
|
| 637 |
|
| 638 |
return [f"Task {i+1} for {theme} (Manual fallback)" for i in range(10)]
|
| 639 |
|
| 640 |
+
def handle_generate(theme, customer_profile, num_personas, method, example_file, url):
|
| 641 |
try:
|
| 642 |
yield "Generating tasks...", None, None
|
| 643 |
+
tasks = generate_tasks(theme, customer_profile, url)
|
| 644 |
|
| 645 |
yield "Selecting or creating personas...", tasks, None
|
| 646 |
personas = select_or_create_personas(theme, customer_profile, num_personas, force_method=method, example_file=example_file)
|
|
|
|
| 1018 |
"""
|
| 1019 |
return prompt
|
| 1020 |
|
| 1021 |
+
def generate_full_ui_call(repo, branch, session_id, selected_solutions_json, url):
|
| 1022 |
if not ANALYSIS_API_KEY or not session_id:
|
| 1023 |
return "Error: API Key or Session ID missing. Start a session first."
|
| 1024 |
|
|
|
|
| 1031 |
return f"Error reading template: {e}"
|
| 1032 |
|
| 1033 |
prompt = template.replace("{{selected_solutions}}", selected_solutions_json)
|
| 1034 |
+
prompt = prompt.replace("{{url}}", url if url else "the analyzed website")
|
| 1035 |
prompt = prompt.replace("{{analysis_report}}", "See previous activities in this session")
|
| 1036 |
prompt = prompt.replace("{{report_id}}", session_id[:8])
|
| 1037 |
prompt = prompt.replace("{{screenshots_dir}}", f"user_experience_reports/screenshots/{session_id[:8]}")
|
|
|
|
| 1063 |
except:
|
| 1064 |
return "UI not generated yet. Please wait..."
|
| 1065 |
|
| 1066 |
+
def blablador_chat_adaptation(message="", history=[], session_id=""):
|
| 1067 |
+
print(f"DEBUG: blablador_chat_adaptation called with message='{message}', history='{history}', session_id='{session_id}'")
|
| 1068 |
if not BLABLADOR_API_KEY or not session_id:
|
| 1069 |
return history + [("System", "Error: BLABLADOR_API_KEY or Session ID missing.")], ""
|
| 1070 |
|
|
|
|
| 1164 |
with gr.Tab("Presentation Carousel"):
|
| 1165 |
gr.Markdown("### View Presentation Slides")
|
| 1166 |
with gr.Row():
|
| 1167 |
+
sl_repo_select = gr.Dropdown(label="Repository", choices=[REPO_NAME], value=REPO_NAME, interactive=False)
|
| 1168 |
sl_branch_select = gr.Dropdown(label="Branch", choices=get_repo_branches(REPO_NAME))
|
| 1169 |
sl_refresh_branches_btn = gr.Button("Refresh Branches")
|
| 1170 |
|
|
|
|
| 1249 |
with gr.Tab("Report Viewer"):
|
| 1250 |
gr.Markdown("### View UX Reports & Solutions")
|
| 1251 |
with gr.Row():
|
| 1252 |
+
rv_repo_select = gr.Dropdown(label="Repository", choices=[REPO_NAME], value=REPO_NAME, interactive=False)
|
| 1253 |
rv_branch_select = gr.Dropdown(label="Branch", choices=get_repo_branches(REPO_NAME))
|
| 1254 |
rv_refresh_branches_btn = gr.Button("Refresh Branches")
|
| 1255 |
|
|
|
|
| 1326 |
ui_chat_msg = gr.Textbox(label="Request Modification", placeholder="e.g. Change primary color to emerald...")
|
| 1327 |
ui_chat_send = gr.Button("Send Request")
|
| 1328 |
|
| 1329 |
+
generate_full_ui_btn.click(fn=generate_full_ui_call, inputs=[rv_repo_select, rv_branch_select, active_session_state, selected_solutions_json_state, url_input], outputs=[full_ui_iframe])
|
| 1330 |
refresh_ui_btn.click(fn=poll_for_generated_ui, inputs=[rv_repo_select, rv_branch_select, active_session_state], outputs=[full_ui_iframe])
|
| 1331 |
ui_chat_send.click(fn=blablador_chat_adaptation, inputs=[ui_chat_msg, ui_chatbot, active_session_state], outputs=[ui_chatbot, ui_chat_msg])
|
| 1332 |
|
|
|
|
| 1335 |
gr.Markdown("### System Diagnostics & Manual Connection")
|
| 1336 |
with gr.Row():
|
| 1337 |
sys_token_input = gr.Textbox(label="GitHub Token (Leave blank for default)", type="password")
|
| 1338 |
+
sys_repo_input = gr.Textbox(label="Repository (e.g., JsonLord/tiny_web)", value=REPO_NAME, interactive=False)
|
| 1339 |
sys_test_btn = gr.Button("Test Connection & Fetch Branches")
|
| 1340 |
|
| 1341 |
sys_status = gr.Textbox(label="Connection Status", interactive=False)
|
|
|
|
| 1398 |
# Event handlers
|
| 1399 |
generate_btn.click(
|
| 1400 |
fn=handle_generate,
|
| 1401 |
+
inputs=[theme_input, profile_input, num_personas_input, persona_method, example_persona_select, url_input],
|
| 1402 |
outputs=[status_output, task_list_display, persona_display]
|
| 1403 |
)
|
| 1404 |
|
verify_final.py
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import asyncio
|
| 2 |
+
from playwright.async_api import async_playwright
|
| 3 |
+
|
| 4 |
+
async def run():
|
| 5 |
+
async with async_playwright() as p:
|
| 6 |
+
browser = await p.chromium.launch()
|
| 7 |
+
page = await browser.new_page()
|
| 8 |
+
await page.goto("http://localhost:7860")
|
| 9 |
+
|
| 10 |
+
# Wait for Gradio to load
|
| 11 |
+
await page.wait_for_selector("button:has-text('Report Viewer')", state='visible')
|
| 12 |
+
|
| 13 |
+
# Click Report Viewer
|
| 14 |
+
btns = await page.query_selector_all("button")
|
| 15 |
+
for btn in btns:
|
| 16 |
+
text = await btn.text_content()
|
| 17 |
+
if text == "Report Viewer":
|
| 18 |
+
await btn.click(force=True)
|
| 19 |
+
break
|
| 20 |
+
|
| 21 |
+
await asyncio.sleep(2)
|
| 22 |
+
await page.screenshot(path="/home/jules/verification/report_viewer_final.png")
|
| 23 |
+
await browser.close()
|
| 24 |
+
|
| 25 |
+
asyncio.run(run())
|