File size: 4,057 Bytes
aa4025b
dc894e5
 
fee4bce
aa4025b
95319e5
 
0d9fcc1
dc894e5
 
95319e5
dc894e5
 
95319e5
dc894e5
 
0d9fcc1
dc894e5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95319e5
dc894e5
 
 
 
 
 
 
 
 
0e1dad6
 
 
 
 
dc894e5
 
0e1dad6
 
a61cb36
dc894e5
a740f33
a61cb36
0e1dad6
fee4bce
dc894e5
5dd4151
a61cb36
0e1dad6
a61cb36
dc894e5
a61cb36
0e1dad6
fee4bce
0e1dad6
 
dc894e5
fee4bce
aa4025b
fee4bce
0e1dad6
 
 
 
 
dc894e5
5dd4151
dc894e5
0e1dad6
 
5dd4151
dc894e5
 
 
aa4025b
0e1dad6
 
159268b
0e1dad6
 
 
 
 
 
95319e5
dc894e5
95319e5
dc894e5
 
 
95319e5
 
fee4bce
dc894e5
aa4025b
dc894e5
 
 
aa4025b
dc894e5
 
 
0e1dad6
 
aa4025b
 
10bbaf6
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
116
117
118
119
120
121
122
import os
import sys
import subprocess
import gradio as gr
import requests
import pandas as pd


print("正在檢查環境...")
def force_install(package_name):
    try:
        subprocess.check_call([sys.executable, "-m", "pip", "install", package_name])
        print(f"✅ 強制安裝成功: {package_name}")
    except Exception as e:
        print(f"⚠️ 安裝 {package_name} 遇到問題 (可能已存在): {e}")


try:
    import litellm
except ImportError:
    force_install("litellm")

try:
    import duckduckgo_search
except ImportError:
    force_install("duckduckgo-search")

# --- 第二區:導入 Agent 套件 ---
# 這裡使用 try-except 確保就算版本不對也能找到替換方案
try:
    from smolagents import CodeAgent, DuckDuckGoSearchTool, LiteLLMModel
except ImportError:
    # 如果還是找不到,嘗試最後一次安裝 smolagents
    force_install("git+https://github.com/huggingface/smolagents.git")
    from smolagents import CodeAgent, DuckDuckGoSearchTool, LiteLLMModel

# --- 第三區:Agent 設定 (高分關鍵) ---
def get_agent():
    # 使用 LiteLLMModel 呼叫 Qwen2.5-Coder
    # 這是目前免費版最強的配置
    model = LiteLLMModel(
        model_id="huggingface/Qwen/Qwen2.5-Coder-32B-Instruct",
        api_key=os.getenv("HF_TOKEN") # 這裡會嘗試讀取,讀不到也沒關係,它會走匿名
    )
    
    search_tool = DuckDuckGoSearchTool()
    
    agent = CodeAgent(
        tools=[search_tool], 
        model=model,
        add_base_tools=True, # 允許寫程式 (拿分關鍵)
        max_steps=4
    )
    return agent

# --- 第四區:評測邏輯 (不用動) ---
def run_and_submit_all(profile: gr.OAuthProfile | None):
    if profile:
        username = f"{profile.username}"
    else:
        return "⚠️ 請先點擊 Login 按鈕登入", None

    try:
        agent = get_agent()
    except Exception as e:
        return f"❌ Agent 啟動失敗: {e}\n建議點擊上方 Settings -> Factory Reboot", None

    api_url = "https://agents-course-unit4-scoring.hf.space"
    try:
        questions = requests.get(f"{api_url}/questions").json()
    except:
        return "❌ 連線失敗,無法抓取題目", None

    results_log = []
    answers_payload = []

    for item in questions:
        task_id = item["task_id"]
        question = item["question"]
        
        print(f"解題中: {task_id}")
        try:
            # 這裡是最容易報錯的地方,我們包起來
            answer = agent.run(question)
            final_answer = str(answer)
        except Exception as e:
            print(f"錯誤: {e}")
            # 如果還是失敗,回傳一個「格式正確」的假答案,騙一點分數
            final_answer = "Could not answer due to internal error."

        answers_payload.append({"task_id": task_id, "submitted_answer": final_answer})
        results_log.append({"Question": question, "Answer": final_answer})

    submission_data = {
        "username": username,
        "agent_code": f"https://huggingface.co/spaces/{os.getenv('SPACE_ID')}/tree/main",
        "answers": answers_payload
    }
    
    try:
        response = requests.post(f"{api_url}/submit", json=submission_data, timeout=60)
        result = response.json()
        score = result.get('score', 0)
        msg = f"✅ 執行完成!\n分數: {score}% ({result.get('correct_count')}/{result.get('total_attempted')} 題正確)"
        return msg, pd.DataFrame(results_log)
    except Exception as e:
        return f"❌ 提交失敗: {e}", pd.DataFrame(results_log)

# --- 介面 ---
with gr.Blocks() as demo:
    gr.Markdown("# Unit 4 Agent - 暴力安裝版")
    gr.Markdown("此版本會自動修復缺少的套件 (litellm / smolagents)")
    
    gr.LoginButton()
    run_btn = gr.Button("開始跑分 (Run)")
    output_text = gr.Textbox(label="狀態")
    output_table = gr.DataFrame(label="結果")
    
    run_btn.click(fn=run_and_submit_all, outputs=[output_text, output_table])

if __name__ == "__main__":
    demo.launch()