Spaces:
Running
Running
| import gradio as gr | |
| def create_input_form(agent_stream_html): | |
| """創建優化後的輸入表單 - 放棄 gr.Examples,改用純按鈕""" | |
| with gr.Group(elem_classes="glass-card") as input_area: | |
| gr.Markdown("### 📝 What's your plan today?") | |
| # 1. 主要輸入區 | |
| user_input = gr.Textbox( | |
| label="Describe your tasks", | |
| placeholder="e.g., I need to visit the dentist at 10am...", | |
| lines=3, | |
| elem_id="main-input" | |
| ) | |
| # 2. 位置設定 (保持不變) | |
| with gr.Accordion("📍 Location Settings", open=True): | |
| auto_location = gr.Checkbox(label="Auto-detect my location", value=False) | |
| with gr.Group(visible=True) as location_inputs: | |
| with gr.Row(): | |
| lat_input = gr.Number(label="Latitude", value=25.033, precision=6, scale=1) | |
| lon_input = gr.Number(label="Longitude", value=121.565, precision=6, scale=1) | |
| # 3. 快速範例 (⭐⭐ 重製版:使用 Button 取代 Examples ⭐⭐) | |
| gr.Markdown("##### ⚡ Quick Start Examples") | |
| # 定義範例文字 | |
| ex_text_1 = "Errands run: Post office, bank, and supermarket. Start at tomorrow 10 AM, finish by 1 PM." | |
| ex_text_2 = """ | |
| I need to run some errands tomorrow morning starting at 9:30 AM. | |
| 1. Go to a Bank. | |
| 2. Drop off a package at the Post Office. | |
| 3. Buy groceries. | |
| I need to be back home by 1:00 PM for a meeting. | |
| """ | |
| ex_text_3 = """ | |
| I am arriving at Cordoba Train Station next Sunday at 11:00 AM. | |
| 1. I want to visit the magnificent 'Mezquita-Catedral'. | |
| 2. Walk across the 'Roman Bridge' for photos. | |
| 3. Find a place to eat the famous 'Salmorejo' for lunch. | |
| I need to be back at the station to catch my return train by 4:30 PM. | |
| """ | |
| with gr.Column(elem_classes="example-container"): | |
| btn_ex1 = gr.Button(ex_text_1, size="sm", variant="secondary", elem_classes="example-btn") | |
| btn_ex2 = gr.Button(ex_text_2[:100]+'...' if len(ex_text_2)>100 else ex_text_2, size="sm", variant="secondary", elem_classes="example-btn") | |
| btn_ex3 = gr.Button(ex_text_3[:100]+'...' if len(ex_text_3)>100 else ex_text_3, size="sm", variant="secondary", elem_classes="example-btn") | |
| # 4. 主按鈕 | |
| analyze_btn = gr.Button("🚀 Analyze & Plan Trip", variant="primary", size="lg") | |
| # 5. Agent 狀態區 | |
| gr.Markdown("---") | |
| gr.Markdown("### 🤖 Agent Status") | |
| agent_stream_output = gr.HTML( | |
| value=agent_stream_html, | |
| elem_classes="agent-stream-box-step1", | |
| visible=True | |
| ) | |
| geo_js = """ | |
| (is_auto, curr_lat, curr_lon) => { | |
| if (!is_auto) { | |
| // 如果是「取消勾選」,保持原值不變 | |
| return [curr_lat, curr_lon]; | |
| } | |
| // 如果是「勾選」,開始定位 | |
| return new Promise((resolve) => { | |
| if (!navigator.geolocation) { | |
| alert("Geolocation is not supported by your browser."); | |
| resolve([curr_lat, curr_lon]); // 失敗回傳原值 | |
| return; | |
| } | |
| // 顯示讀取中的狀態 (可選) | |
| // document.body.style.cursor = 'wait'; | |
| navigator.geolocation.getCurrentPosition( | |
| (position) => { | |
| // document.body.style.cursor = 'default'; | |
| // 成功!回傳經緯度 | |
| resolve([position.coords.latitude, position.coords.longitude]); | |
| }, | |
| (error) => { | |
| // document.body.style.cursor = 'default'; | |
| let msg = "Unknown error"; | |
| switch(error.code) { | |
| case 1: msg = "Permission denied. Please allow location access."; break; | |
| case 2: msg = "Position unavailable."; break; | |
| case 3: msg = "Timeout."; break; | |
| } | |
| alert("📍 Location Error: " + msg); | |
| resolve([curr_lat, curr_lon]); // 失敗回傳原值 | |
| }, | |
| { enableHighAccuracy: true, timeout: 8000 } | |
| ); | |
| }); | |
| } | |
| """ | |
| # 綁定事件 1: 控制輸入框顯示/隱藏 (Python 邏輯) | |
| auto_location.change( | |
| fn=lambda x: gr.update(visible=not x), | |
| inputs=[auto_location], | |
| outputs=[location_inputs] | |
| ) | |
| # 綁定事件 2: 執行 JS 定位 (JS 邏輯) | |
| # 注意 inputs 包含了 lat/lon,這樣 JS 才能在失敗/取消時把原值傳回來 | |
| auto_location.change( | |
| fn=None, | |
| inputs=[auto_location, lat_input, lon_input], | |
| outputs=[lat_input, lon_input], | |
| js=geo_js | |
| ) | |
| # ⭐⭐ 綁定點擊事件 ⭐⭐ | |
| # 點擊按鈕 -> 把按鈕文字填入 user_input | |
| btn_ex1.click(lambda: ex_text_1, outputs=user_input) | |
| btn_ex2.click(lambda: ex_text_2, outputs=user_input) | |
| btn_ex3.click(lambda: ex_text_3, outputs=user_input) | |
| return (input_area, agent_stream_output, user_input, auto_location, | |
| location_inputs, lat_input, lon_input, analyze_btn) | |
| def toggle_location_inputs(auto_loc): | |
| return gr.update(visible=not auto_loc) |