File size: 3,798 Bytes
0d276c6
 
 
 
 
a884a74
 
0d276c6
a92112f
3db6293
0d276c6
 
a92112f
0d276c6
a884a74
0d276c6
a884a74
0d276c6
a884a74
31243f4
0d276c6
 
31243f4
a884a74
 
0d276c6
a884a74
 
0d276c6
 
 
 
3c4371f
0d276c6
a884a74
 
 
 
 
0d276c6
eccf8e4
0d276c6
7d65c66
a92112f
e80aab9
0d276c6
a884a74
0d276c6
 
 
 
 
 
 
 
 
 
3c9938b
 
 
a884a74
0d276c6
 
a884a74
0d276c6
 
a884a74
0d276c6
a884a74
 
 
 
 
a92112f
e80aab9
a884a74
0d276c6
 
7d65c66
a884a74
e80aab9
0d276c6
e80aab9
0d276c6
a884a74
0d276c6
7e4a06b
a884a74
0d276c6
a884a74
 
e80aab9
 
3c4371f
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
# ------------------------------------------------------------
# fast async app.py  (korrekte Zuordnung + Gemini-Throttle)
# ------------------------------------------------------------
import os, asyncio, concurrent.futures, functools, json
from pathlib import Path
import gradio as gr, requests, pandas as pd
from langchain_core.messages import HumanMessage
from agent import agent_executor

DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
MAX_PAR_LLM     = 3                      # 3 gleichz. Requests stay < 15/min
SEMAPHORE       = asyncio.Semaphore(MAX_PAR_LLM)

# ---------- synchroner Agent-Aufruf ---------------------------------
def run_agent_sync(task_id: str, question: str) -> str:
    payload = {
        "messages": [HumanMessage(content=question)],
        "task_id": task_id,
    }
    try:
        res = agent_executor.invoke(payload)
        return res["messages"][-1].content.strip()
    except Exception as e:
        return f"AGENT ERROR: {e}"

# ---------- async Wrapper + Throttle --------------------------------
async def run_agent_async(executor, task_id: str, question: str) -> str:
    loop = asyncio.get_event_loop()
    async with SEMAPHORE:                       # Gemini-Quota Guard
        return await loop.run_in_executor(
            executor, functools.partial(run_agent_sync, task_id, question)
        )

# ---------- Main Gradio Callback ------------------------------------
async def run_and_submit_all(profile: gr.OAuthProfile | None, progress=gr.Progress()):
    if not profile:
        return "Please login with your HF account.", None
    username = profile.username

    # 1) Fragen laden
    try:
        questions = requests.get(f"{DEFAULT_API_URL}/questions", timeout=15).json()
    except Exception as e:
        return f"Error fetching questions: {e}", None

    progress(0, desc=f"Fetched {len(questions)} questions – processing …")

    answers, logs = [], []
    work = [(q["task_id"], q["question"]) for q in questions]

    # 2) Parallel-Ausführung mit korrekt gemappten Tasks
    with concurrent.futures.ThreadPoolExecutor(max_workers=MAX_PAR_LLM) as ex:
        task_map = {
            asyncio.create_task(run_agent_async(ex, tid, qst)): (tid, qst)
            for tid, qst in work
        }
        done_total = 0
        for done in asyncio.as_completed(list(task_map.keys())):  # fix
            tid, qst = task_map[done]      # garantiert vorhanden
            answer   = await done

            answers.append({"task_id": tid, "submitted_answer": answer})
            logs.append({"Task ID": tid, "Question": qst, "Answer": answer})

            done_total += 1
            progress(done_total / len(work), desc=f"{done_total}/{len(work)} done")

    # 3) Submit
    submit_url = f"{DEFAULT_API_URL}/submit"
    payload = {
        "username": username,
        "agent_code": f"https://huggingface.co/spaces/{os.getenv('SPACE_ID')}/tree/main",
        "answers": answers,
    }
    try:
        res = requests.post(submit_url, json=payload, timeout=60).json()
        status = (f"Submission OK – Score {res.get('score','?')} % "
                  f"({res.get('correct_count','?')}/{res.get('total_attempted','?')})")
    except Exception as e:
        status = f"Submission failed: {e}"

    return status, pd.DataFrame(logs)

# ---------- Gradio UI -----------------------------------------------
with gr.Blocks() as demo:
    gr.Markdown("# Fast GAIA Agent Runner  (async × progress)")
    gr.LoginButton()
    run_btn = gr.Button("Run & Submit")
    out_status = gr.Textbox(label="Status / Score", lines=3)
    out_table  = gr.DataFrame(label="Answers", wrap=True)
    run_btn.click(run_and_submit_all, outputs=[out_status, out_table])

if __name__ == "__main__":
    demo.launch(debug=True, share=False)