select coord
Browse files
gradio-web/config.py
CHANGED
|
@@ -65,6 +65,7 @@ UI_TEXT = {
|
|
| 65 |
"log": {
|
| 66 |
"action_selection_prompt": "Please select the action.\nActions with 🎯 need to select a point on the image as input",
|
| 67 |
"point_selection_prompt": "Current action needs location input, please click on the image to select key pixel",
|
|
|
|
| 68 |
"execute_action_prompt": "Executing Action {label}",
|
| 69 |
"demo_video_prompt": 'Press "Watch Video Input 🎬" to watch a video\nNote: you can only watch the video once',
|
| 70 |
"session_error": "Session expired. Please refresh the page and try again.",
|
|
|
|
| 65 |
"log": {
|
| 66 |
"action_selection_prompt": "Please select the action.\nActions with 🎯 need to select a point on the image as input",
|
| 67 |
"point_selection_prompt": "Current action needs location input, please click on the image to select key pixel",
|
| 68 |
+
"point_selected_message": "Select: {label} | point <{x}, {y}>",
|
| 69 |
"execute_action_prompt": "Executing Action {label}",
|
| 70 |
"demo_video_prompt": 'Press "Watch Video Input 🎬" to watch a video\nNote: you can only watch the video once',
|
| 71 |
"session_error": "Session expired. Please refresh the page and try again.",
|
gradio-web/gradio_callbacks.py
CHANGED
|
@@ -100,6 +100,17 @@ def _default_post_execute_log_state():
|
|
| 100 |
}
|
| 101 |
|
| 102 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 103 |
def _normalize_post_execute_log_state(state):
|
| 104 |
"""Normalize terminal-log preservation payloads across callback boundaries."""
|
| 105 |
if isinstance(state, dict):
|
|
@@ -912,7 +923,11 @@ def on_map_click(uid, option_value, evt: gr.SelectData):
|
|
| 912 |
|
| 913 |
coords_str = f"{x}, {y}"
|
| 914 |
|
| 915 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
| 916 |
|
| 917 |
|
| 918 |
def _is_valid_coords_text(coords_text: str) -> bool:
|
|
|
|
| 100 |
}
|
| 101 |
|
| 102 |
|
| 103 |
+
def _point_selected_log(session, option_value, x, y):
|
| 104 |
+
label = _get_raw_option_label(session, option_value)
|
| 105 |
+
if label:
|
| 106 |
+
display_label = _format_choice_prefix(label)
|
| 107 |
+
else:
|
| 108 |
+
display_label = str(option_value).strip() if option_value is not None else "?"
|
| 109 |
+
return format_log_markdown(
|
| 110 |
+
_ui_text("log", "point_selected_message", label=display_label, x=int(x), y=int(y))
|
| 111 |
+
)
|
| 112 |
+
|
| 113 |
+
|
| 114 |
def _normalize_post_execute_log_state(state):
|
| 115 |
"""Normalize terminal-log preservation payloads across callback boundaries."""
|
| 116 |
if isinstance(state, dict):
|
|
|
|
| 923 |
|
| 924 |
coords_str = f"{x}, {y}"
|
| 925 |
|
| 926 |
+
return (
|
| 927 |
+
_live_obs_update(value=marked_img, interactive=True),
|
| 928 |
+
coords_str,
|
| 929 |
+
_point_selected_log(session, option_value, x, y),
|
| 930 |
+
)
|
| 931 |
|
| 932 |
|
| 933 |
def _is_valid_coords_text(coords_text: str) -> bool:
|
gradio-web/test/test_reference_action_callbacks.py
CHANGED
|
@@ -17,7 +17,7 @@ class _FakeSession:
|
|
| 17 |
|
| 18 |
class _FakeOptionSession:
|
| 19 |
def __init__(self):
|
| 20 |
-
self.raw_solve_options = [{"available": [object()]}]
|
| 21 |
self.available_options = [("pick", 0)]
|
| 22 |
|
| 23 |
def get_pil_image(self, use_segmented=True):
|
|
@@ -144,7 +144,7 @@ def test_on_option_select_suppresses_programmatic_reference_change(reload_module
|
|
| 144 |
assert log_state == callbacks._default_post_execute_log_state()
|
| 145 |
|
| 146 |
|
| 147 |
-
def
|
| 148 |
config = reload_module("config")
|
| 149 |
callbacks = reload_module("gradio_callbacks")
|
| 150 |
|
|
@@ -159,7 +159,11 @@ def test_on_map_click_clears_wait_state_and_restores_action_prompt(monkeypatch,
|
|
| 159 |
assert _is_fluorescent_yellow(img_update["value"].getpixel((5, 6)))
|
| 160 |
assert img_update.get("elem_classes") == config.get_live_obs_elem_classes()
|
| 161 |
assert coords_text == "5, 6"
|
| 162 |
-
assert log_text == config.UI_TEXT["log"]["
|
|
|
|
|
|
|
|
|
|
|
|
|
| 163 |
|
| 164 |
|
| 165 |
def test_on_reference_action_uses_configured_action_text_override(monkeypatch, reload_module):
|
|
|
|
| 17 |
|
| 18 |
class _FakeOptionSession:
|
| 19 |
def __init__(self):
|
| 20 |
+
self.raw_solve_options = [{"label": "a", "available": [object()]}]
|
| 21 |
self.available_options = [("pick", 0)]
|
| 22 |
|
| 23 |
def get_pil_image(self, use_segmented=True):
|
|
|
|
| 144 |
assert log_state == callbacks._default_post_execute_log_state()
|
| 145 |
|
| 146 |
|
| 147 |
+
def test_on_map_click_updates_log_with_selected_option_and_coords(monkeypatch, reload_module):
|
| 148 |
config = reload_module("config")
|
| 149 |
callbacks = reload_module("gradio_callbacks")
|
| 150 |
|
|
|
|
| 159 |
assert _is_fluorescent_yellow(img_update["value"].getpixel((5, 6)))
|
| 160 |
assert img_update.get("elem_classes") == config.get_live_obs_elem_classes()
|
| 161 |
assert coords_text == "5, 6"
|
| 162 |
+
assert log_text == config.UI_TEXT["log"]["point_selected_message"].format(
|
| 163 |
+
label="A",
|
| 164 |
+
x=5,
|
| 165 |
+
y=6,
|
| 166 |
+
)
|
| 167 |
|
| 168 |
|
| 169 |
def test_on_reference_action_uses_configured_action_text_override(monkeypatch, reload_module):
|
gradio-web/test/test_ui_phase_machine_runtime_e2e.py
CHANGED
|
@@ -1559,7 +1559,10 @@ def test_point_wait_state_pulses_live_obs_and_updates_system_log(monkeypatch):
|
|
| 1559 |
fake_obs_img = Image.fromarray(fake_obs)
|
| 1560 |
|
| 1561 |
class FakeSession:
|
| 1562 |
-
raw_solve_options = [
|
|
|
|
|
|
|
|
|
|
| 1563 |
|
| 1564 |
def get_pil_image(self, use_segmented=False):
|
| 1565 |
_ = use_segmented
|
|
@@ -1714,12 +1717,12 @@ def test_point_wait_state_pulses_live_obs_and_updates_system_log(monkeypatch):
|
|
| 1714 |
!!liveObs &&
|
| 1715 |
!liveObs.classList.contains(state.waitClass) &&
|
| 1716 |
/^\\d+\\s*,\\s*\\d+$/.test(coordsValue) &&
|
| 1717 |
-
logValue === state.
|
| 1718 |
);
|
| 1719 |
}""",
|
| 1720 |
arg={
|
| 1721 |
"waitClass": config_module.LIVE_OBS_POINT_WAIT_CLASS,
|
| 1722 |
-
"
|
| 1723 |
},
|
| 1724 |
timeout=5000,
|
| 1725 |
)
|
|
@@ -1733,7 +1736,11 @@ def test_point_wait_state_pulses_live_obs_and_updates_system_log(monkeypatch):
|
|
| 1733 |
assert final_classes is not None
|
| 1734 |
assert config_module.LIVE_OBS_POINT_WAIT_CLASS not in final_classes
|
| 1735 |
assert config_module.LIVE_OBS_BASE_CLASS in final_classes
|
| 1736 |
-
assert _read_log_output_value(page) == config_module.UI_TEXT["log"]["
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1737 |
final_card_wait = _read_media_card_wait_snapshot(page)
|
| 1738 |
final_transforms = _read_live_obs_transform_snapshot(page)
|
| 1739 |
assert final_card_wait["opacity"] == 0
|
|
@@ -2805,9 +2812,9 @@ def _run_local_execute_video_transition_test(
|
|
| 2805 |
const logField = logRoot?.querySelector('textarea, input');
|
| 2806 |
const coordsValue = coordsField ? coordsField.value.trim() : '';
|
| 2807 |
const logValue = logField ? logField.value.trim() : (logRoot?.textContent || '').trim();
|
| 2808 |
-
return /^\\d+\\s*,\\s*\\d+$/.test(coordsValue) && logValue === state.
|
| 2809 |
}""",
|
| 2810 |
-
arg={"
|
| 2811 |
timeout=5000,
|
| 2812 |
)
|
| 2813 |
page.locator("#exec_btn button, button#exec_btn").first.click()
|
|
|
|
| 1559 |
fake_obs_img = Image.fromarray(fake_obs)
|
| 1560 |
|
| 1561 |
class FakeSession:
|
| 1562 |
+
raw_solve_options = [
|
| 1563 |
+
{"label": "a", "available": [object()]},
|
| 1564 |
+
{"label": "b", "available": False},
|
| 1565 |
+
]
|
| 1566 |
|
| 1567 |
def get_pil_image(self, use_segmented=False):
|
| 1568 |
_ = use_segmented
|
|
|
|
| 1717 |
!!liveObs &&
|
| 1718 |
!liveObs.classList.contains(state.waitClass) &&
|
| 1719 |
/^\\d+\\s*,\\s*\\d+$/.test(coordsValue) &&
|
| 1720 |
+
logValue === `Select: ${state.label} | point <${coordsValue}>`
|
| 1721 |
);
|
| 1722 |
}""",
|
| 1723 |
arg={
|
| 1724 |
"waitClass": config_module.LIVE_OBS_POINT_WAIT_CLASS,
|
| 1725 |
+
"label": "A",
|
| 1726 |
},
|
| 1727 |
timeout=5000,
|
| 1728 |
)
|
|
|
|
| 1736 |
assert final_classes is not None
|
| 1737 |
assert config_module.LIVE_OBS_POINT_WAIT_CLASS not in final_classes
|
| 1738 |
assert config_module.LIVE_OBS_BASE_CLASS in final_classes
|
| 1739 |
+
assert _read_log_output_value(page) == config_module.UI_TEXT["log"]["point_selected_message"].format(
|
| 1740 |
+
label="A",
|
| 1741 |
+
x=coord_x,
|
| 1742 |
+
y=coord_y,
|
| 1743 |
+
)
|
| 1744 |
final_card_wait = _read_media_card_wait_snapshot(page)
|
| 1745 |
final_transforms = _read_live_obs_transform_snapshot(page)
|
| 1746 |
assert final_card_wait["opacity"] == 0
|
|
|
|
| 2812 |
const logField = logRoot?.querySelector('textarea, input');
|
| 2813 |
const coordsValue = coordsField ? coordsField.value.trim() : '';
|
| 2814 |
const logValue = logField ? logField.value.trim() : (logRoot?.textContent || '').trim();
|
| 2815 |
+
return /^\\d+\\s*,\\s*\\d+$/.test(coordsValue) && logValue === `Select: ${state.label} | point <${coordsValue}>`;
|
| 2816 |
}""",
|
| 2817 |
+
arg={"label": "B"},
|
| 2818 |
timeout=5000,
|
| 2819 |
)
|
| 2820 |
page.locator("#exec_btn button, button#exec_btn").first.click()
|
gradio-web/test/test_ui_text_config.py
CHANGED
|
@@ -7,7 +7,7 @@ from PIL import Image
|
|
| 7 |
class _FakeOptionSession:
|
| 8 |
def __init__(self, env_id="BinFill", raw_solve_options=None):
|
| 9 |
self.env_id = env_id
|
| 10 |
-
self.raw_solve_options = raw_solve_options or [{"available": True}]
|
| 11 |
|
| 12 |
def get_pil_image(self, use_segmented=False):
|
| 13 |
_ = use_segmented
|
|
@@ -52,6 +52,24 @@ def test_on_option_select_uses_configured_select_point_and_log_messages(monkeypa
|
|
| 52 |
assert log_state == callbacks._default_post_execute_log_state()
|
| 53 |
|
| 54 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 55 |
def test_precheck_execute_inputs_uses_configured_before_execute_message(monkeypatch, reload_module):
|
| 56 |
reload_module("config")
|
| 57 |
callbacks = reload_module("gradio_callbacks")
|
|
|
|
| 7 |
class _FakeOptionSession:
|
| 8 |
def __init__(self, env_id="BinFill", raw_solve_options=None):
|
| 9 |
self.env_id = env_id
|
| 10 |
+
self.raw_solve_options = raw_solve_options or [{"label": "a", "available": True}]
|
| 11 |
|
| 12 |
def get_pil_image(self, use_segmented=False):
|
| 13 |
_ = use_segmented
|
|
|
|
| 52 |
assert log_state == callbacks._default_post_execute_log_state()
|
| 53 |
|
| 54 |
|
| 55 |
+
def test_on_map_click_uses_configured_selected_point_log(monkeypatch, reload_module):
|
| 56 |
+
reload_module("config")
|
| 57 |
+
callbacks = reload_module("gradio_callbacks")
|
| 58 |
+
|
| 59 |
+
monkeypatch.setitem(
|
| 60 |
+
callbacks.UI_TEXT["log"],
|
| 61 |
+
"point_selected_message",
|
| 62 |
+
"picked {label} @ <{x}, {y}>",
|
| 63 |
+
)
|
| 64 |
+
monkeypatch.setattr(callbacks, "get_session", lambda uid: _FakeOptionSession())
|
| 65 |
+
|
| 66 |
+
event = type("Evt", (), {"index": (7, 9)})()
|
| 67 |
+
_img, coords_text, log_text = callbacks.on_map_click("uid-1", 0, event)
|
| 68 |
+
|
| 69 |
+
assert coords_text == "7, 9"
|
| 70 |
+
assert log_text == "picked A @ <7, 9>"
|
| 71 |
+
|
| 72 |
+
|
| 73 |
def test_precheck_execute_inputs_uses_configured_before_execute_message(monkeypatch, reload_module):
|
| 74 |
reload_module("config")
|
| 75 |
callbacks = reload_module("gradio_callbacks")
|