HongzeFu commited on
Commit
d10d370
·
1 Parent(s): 8a7aab0
gradio-web/config.py CHANGED
@@ -24,6 +24,25 @@ SESSION_TIMEOUT = 300 # Session超时时间(秒),如果30秒内没有exec
24
  # 兜底执行次数配置
25
  EXECUTE_LIMIT_OFFSET = 4 # 兜底执行次数 = non_demonstration_task_length + EXECUTE_LIMIT_OFFSET
26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
28
  # 应该显示demonstration videos的环境ID列表
29
  DEMO_VIDEO_ENV_IDS = [
 
24
  # 兜底执行次数配置
25
  EXECUTE_LIMIT_OFFSET = 4 # 兜底执行次数 = non_demonstration_task_length + EXECUTE_LIMIT_OFFSET
26
 
27
+ TASK_NAME_LIST = [
28
+ "BinFill",
29
+ "StopCube",
30
+ "PickXtimes",
31
+ "SwingXtimes",
32
+ "ButtonUnmask",
33
+ "VideoUnmask",
34
+ "VideoUnmaskSwap",
35
+ "ButtonUnmaskSwap",
36
+ "PickHighlight",
37
+ "VideoRepick",
38
+ "VideoPlaceButton",
39
+ "VideoPlaceOrder",
40
+ "MoveCube",
41
+ "InsertPeg",
42
+ "PatternLock",
43
+ "RouteStick",
44
+ ]
45
+
46
 
47
  # 应该显示demonstration videos的环境ID列表
48
  DEMO_VIDEO_ENV_IDS = [
gradio-web/image_utils.py CHANGED
@@ -702,16 +702,17 @@ def draw_coordinate_axes(img, position="right", rotate_180=False, env_id=None):
702
 
703
 
704
  def draw_marker(img, x, y):
705
- """Draws a red circle and cross at (x, y)."""
706
  if isinstance(img, np.ndarray):
707
  img = Image.fromarray(img)
708
 
709
  img = img.copy()
710
  draw = ImageDraw.Draw(img)
711
  r = 5
 
712
  # Circle
713
- draw.ellipse((x-r, y-r, x+r, y+r), outline="red", width=2)
714
  # Cross
715
- draw.line((x-r, y, x+r, y), fill="red", width=2)
716
- draw.line((x, y-r, x, y+r), fill="red", width=2)
717
  return img
 
702
 
703
 
704
  def draw_marker(img, x, y):
705
+ """Draws a fluorescent yellow circle and cross at (x, y)."""
706
  if isinstance(img, np.ndarray):
707
  img = Image.fromarray(img)
708
 
709
  img = img.copy()
710
  draw = ImageDraw.Draw(img)
711
  r = 5
712
+ marker_color = (204, 255, 0)
713
  # Circle
714
+ draw.ellipse((x-r, y-r, x+r, y+r), outline=marker_color, width=2)
715
  # Cross
716
+ draw.line((x-r, y, x+r, y), fill=marker_color, width=2)
717
+ draw.line((x, y-r, x, y+r), fill=marker_color, width=2)
718
  return img
gradio-web/test/test_reference_action_callbacks.py CHANGED
@@ -25,6 +25,10 @@ class _FakeOptionSession:
25
  return Image.new("RGB", (24, 24), color=(0, 0, 0))
26
 
27
 
 
 
 
 
28
  def test_on_reference_action_success_updates_option_and_coords(monkeypatch, reload_module):
29
  config = reload_module("config")
30
  callbacks = reload_module("gradio_callbacks")
@@ -48,7 +52,7 @@ def test_on_reference_action_success_updates_option_and_coords(monkeypatch, relo
48
 
49
  assert img_update.get("__type__") == "update"
50
  assert isinstance(img_update.get("value"), Image.Image)
51
- assert img_update["value"].getpixel((5, 6)) != (0, 0, 0)
52
  assert img_update.get("elem_classes") == config.get_live_obs_elem_classes()
53
  assert option_update.get("value") == 2
54
  assert coords_text == "5, 6"
@@ -117,7 +121,7 @@ def test_on_map_click_clears_wait_state_and_restores_action_prompt(monkeypatch,
117
 
118
  assert img_update.get("__type__") == "update"
119
  assert isinstance(img_update.get("value"), Image.Image)
120
- assert img_update["value"].getpixel((5, 6)) != (0, 0, 0)
121
  assert img_update.get("elem_classes") == config.get_live_obs_elem_classes()
122
  assert coords_text == "5, 6"
123
  assert log_text == config.UI_TEXT["log"]["action_selection_prompt"]
 
25
  return Image.new("RGB", (24, 24), color=(0, 0, 0))
26
 
27
 
28
+ def _is_fluorescent_yellow(pixel):
29
+ return pixel[0] > 180 and pixel[1] > 200 and pixel[2] < 80
30
+
31
+
32
  def test_on_reference_action_success_updates_option_and_coords(monkeypatch, reload_module):
33
  config = reload_module("config")
34
  callbacks = reload_module("gradio_callbacks")
 
52
 
53
  assert img_update.get("__type__") == "update"
54
  assert isinstance(img_update.get("value"), Image.Image)
55
+ assert _is_fluorescent_yellow(img_update["value"].getpixel((5, 6)))
56
  assert img_update.get("elem_classes") == config.get_live_obs_elem_classes()
57
  assert option_update.get("value") == 2
58
  assert coords_text == "5, 6"
 
121
 
122
  assert img_update.get("__type__") == "update"
123
  assert isinstance(img_update.get("value"), Image.Image)
124
+ assert _is_fluorescent_yellow(img_update["value"].getpixel((5, 6)))
125
  assert img_update.get("elem_classes") == config.get_live_obs_elem_classes()
126
  assert coords_text == "5, 6"
127
  assert log_text == config.UI_TEXT["log"]["action_selection_prompt"]
gradio-web/test/test_ui_native_layout_contract.py CHANGED
@@ -97,6 +97,25 @@ def test_render_header_goal_capitalizes_display_value(reload_module):
97
  assert ui_layout.render_header_goal("") == "—"
98
 
99
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  def test_native_ui_config_contains_phase_machine_and_precheck_chain(reload_module):
101
  ui_layout = reload_module("ui_layout")
102
  demo = ui_layout.create_ui_blocks()
 
97
  assert ui_layout.render_header_goal("") == "—"
98
 
99
 
100
+ def test_header_task_dropdown_uses_task_name_list_order(reload_module):
101
+ config = reload_module("config")
102
+ ui_layout = reload_module("ui_layout")
103
+
104
+ ui_layout.user_manager.env_choices = list(config.TASK_NAME_LIST)
105
+ demo = ui_layout.create_ui_blocks()
106
+
107
+ try:
108
+ cfg = demo.get_config_file()
109
+ header_task_comp = next(
110
+ comp
111
+ for comp in cfg.get("components", [])
112
+ if comp.get("props", {}).get("elem_id") == "header_task"
113
+ )
114
+ assert header_task_comp.get("props", {}).get("choices") == config.TASK_NAME_LIST
115
+ finally:
116
+ demo.close()
117
+
118
+
119
  def test_native_ui_config_contains_phase_machine_and_precheck_chain(reload_module):
120
  ui_layout = reload_module("ui_layout")
121
  demo = ui_layout.create_ui_blocks()
gradio-web/test/test_user_manager_random_flow.py CHANGED
@@ -94,3 +94,22 @@ def test_init_session_fails_when_metadata_root_missing(monkeypatch, reload_modul
94
  assert success is False
95
  assert "No available environments" in msg
96
  assert status is None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  assert success is False
95
  assert "No available environments" in msg
96
  assert status is None
97
+
98
+
99
+ def test_env_choices_follow_task_name_list_order(monkeypatch, reload_module, tmp_path):
100
+ metadata_root = tmp_path / "metadata"
101
+ _write_metadata(metadata_root, "VideoPlaceButton", [0])
102
+ _write_metadata(metadata_root, "BinFill", [0])
103
+ _write_metadata(metadata_root, "PatternLock", [0])
104
+ _write_metadata(metadata_root, "StopCube", [0])
105
+ monkeypatch.setenv("ROBOMME_METADATA_ROOT", str(metadata_root))
106
+
107
+ user_manager_mod = reload_module("user_manager")
108
+ manager = user_manager_mod.UserManager()
109
+
110
+ assert manager.env_choices == [
111
+ "BinFill",
112
+ "StopCube",
113
+ "VideoPlaceButton",
114
+ "PatternLock",
115
+ ]
gradio-web/user_manager.py CHANGED
@@ -4,6 +4,7 @@ import random
4
  import threading
5
  from pathlib import Path
6
 
 
7
  from state_manager import clear_task_start_time, get_task_start_time
8
 
9
 
@@ -16,7 +17,7 @@ class UserManager:
16
  self.lock = threading.Lock()
17
 
18
  self.env_to_episodes = self._load_env_episode_pool()
19
- self.env_choices = sorted(self.env_to_episodes.keys())
20
 
21
  # Session-local progress only (no disk persistence)
22
  self.session_progress = {}
@@ -61,6 +62,12 @@ class UserManager:
61
  print(f"Loaded random env pool: {len(env_to_episodes)} envs from metadata root {metadata_root}")
62
  return env_to_episodes
63
 
 
 
 
 
 
 
64
  def _ensure_session_entry(self, uid):
65
  if uid not in self.session_progress:
66
  self.session_progress[uid] = {
 
4
  import threading
5
  from pathlib import Path
6
 
7
+ from config import TASK_NAME_LIST
8
  from state_manager import clear_task_start_time, get_task_start_time
9
 
10
 
 
17
  self.lock = threading.Lock()
18
 
19
  self.env_to_episodes = self._load_env_episode_pool()
20
+ self.env_choices = self._build_env_choices()
21
 
22
  # Session-local progress only (no disk persistence)
23
  self.session_progress = {}
 
62
  print(f"Loaded random env pool: {len(env_to_episodes)} envs from metadata root {metadata_root}")
63
  return env_to_episodes
64
 
65
+ def _build_env_choices(self):
66
+ available_envs = set(self.env_to_episodes.keys())
67
+ ordered_choices = [env_id for env_id in TASK_NAME_LIST if env_id in available_envs]
68
+ remaining_choices = sorted(available_envs - set(ordered_choices))
69
+ return ordered_choices + remaining_choices
70
+
71
  def _ensure_session_entry(self, uid):
72
  if uid not in self.session_progress:
73
  self.session_progress[uid] = {