|
14 | 14 |
|
15 | 15 | import gradio as gr
|
16 | 16 | import inspect
|
17 |
| -from functools import wraps |
| 17 | +from functools import partial, wraps |
18 | 18 |
|
19 | 19 | from browser_use.agent.service import Agent
|
20 | 20 | from playwright.async_api import async_playwright
|
|
49 | 49 | webui_config_manager = utils.ConfigManager()
|
50 | 50 |
|
51 | 51 |
|
| 52 | +def sync_component_value_to_manager(component_registered_name, new_value): |
| 53 | + """Sync the value of a component to the config manager""" |
| 54 | + global webui_config_manager |
| 55 | + if webui_config_manager: |
| 56 | + component_object = webui_config_manager.components.get(component_registered_name) |
| 57 | + if component_object: |
| 58 | + current_manager_value = getattr(component_object, "value", None) |
| 59 | + if current_manager_value != new_value: |
| 60 | + component_object.value = new_value |
| 61 | + return None |
| 62 | + |
52 | 63 | def scan_and_register_components(blocks):
|
53 | 64 | """扫描一个 Blocks 对象并注册其中的所有交互式组件,但不包括按钮"""
|
54 | 65 | global webui_config_manager
|
| 66 | + component_map = {} |
55 | 67 |
|
56 | 68 | def traverse_blocks(block, prefix=""):
|
| 69 | + nonlocal component_map |
57 | 70 | registered = 0
|
58 |
| - |
59 | 71 | # 处理 Blocks 自身的组件
|
60 | 72 | if hasattr(block, "children"):
|
61 | 73 | for i, child in enumerate(block.children):
|
| 74 | + name = None |
| 75 | + is_eligible_for_config = False |
62 | 76 | if isinstance(child, gr.components.Component):
|
63 |
| - # 排除按钮 (Button) 组件 |
64 |
| - if getattr(child, "interactive", False) and not isinstance(child, gr.Button): |
| 77 | + # 排除按钮 (Button/File) 组件 |
| 78 | + if getattr(child, "interactive", False) and not isinstance(child, gr.Button) and not isinstance(child, gr.File): |
| 79 | + is_eligible_for_config = True |
65 | 80 | name = f"{prefix}component_{i}"
|
66 | 81 | if hasattr(child, "label") and child.label:
|
67 | 82 | # 使用标签作为名称的一部分
|
68 | 83 | label = child.label
|
69 | 84 | name = f"{prefix}{label}"
|
70 |
| - logger.debug(f"Registering component: {name}") |
71 |
| - webui_config_manager.register_component(name, child) |
72 |
| - registered += 1 |
73 | 85 | elif hasattr(child, "children"):
|
74 | 86 | # 递归处理嵌套的 Blocks
|
75 | 87 | new_prefix = f"{prefix}block_{i}_"
|
76 | 88 | registered += traverse_blocks(child, new_prefix)
|
77 | 89 |
|
| 90 | + if is_eligible_for_config and name: |
| 91 | + webui_config_manager.register_component(name, child) |
| 92 | + component_map[name] = child |
| 93 | + registered += 1 |
78 | 94 | return registered
|
79 | 95 |
|
80 | 96 | total = traverse_blocks(blocks)
|
81 | 97 | logger.info(f"Total registered components: {total}")
|
82 | 98 |
|
| 99 | + # Register the components with the config manager |
| 100 | + for name, component_obj in component_map.items(): |
| 101 | + sync_handler = partial(sync_component_value_to_manager, name) |
| 102 | + if hasattr(component_obj, 'change'): |
| 103 | + component_obj.change(fn=sync_handler, inputs=[component_obj], outputs=None) |
| 104 | + |
83 | 105 |
|
84 | 106 | def save_current_config():
|
85 | 107 | return webui_config_manager.save_current_config()
|
@@ -1158,8 +1180,8 @@ def list_recordings(save_recording_path):
|
1158 | 1180 |
|
1159 | 1181 | # Attach the callback to the LLM provider dropdown
|
1160 | 1182 | llm_provider.change(
|
1161 |
| - lambda provider, api_key, base_url: update_model_dropdown(provider, api_key, base_url), |
1162 |
| - inputs=[llm_provider, llm_api_key, llm_base_url], |
| 1183 | + fn=utils.update_model_dropdown, |
| 1184 | + inputs=[llm_provider, llm_model_name], |
1163 | 1185 | outputs=llm_model_name
|
1164 | 1186 | )
|
1165 | 1187 |
|
|
0 commit comments