SavirD commited on
Commit
66ddc54
·
verified ·
1 Parent(s): fc6b5c1

Upload folder using huggingface_hub

Browse files
Dockerfile CHANGED
@@ -54,6 +54,10 @@ RUN --mount=type=cache,target=/root/.cache/uv \
54
  uv sync --no-editable; \
55
  fi
56
 
 
 
 
 
57
  # Final runtime stage
58
  FROM ${BASE_IMAGE}
59
 
 
54
  uv sync --no-editable; \
55
  fi
56
 
57
+ # Patch OpenEnv web UI so number inputs use step=0.01 (allows lr_scale=0.02, momentum_coef=0.9)
58
+ RUN WEBIF="$$(find /app/env/.venv -path '*openenv*env_server*web_interface.py' | head -1)" && \
59
+ /app/env/.venv/bin/python /app/env/scripts/patch_openenv_web_interface.py "$$WEBIF"
60
+
61
  # Final runtime stage
62
  FROM ${BASE_IMAGE}
63
 
scripts/patch_openenv_web_interface.py ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Apply step-attribute patch to OpenEnv web_interface.py so number inputs
4
+ use step=0.01 (not default 1), allowing float values like lr_scale=0.02 and momentum_coef=0.9.
5
+ Idempotent: safe to run multiple times.
6
+ """
7
+ import sys
8
+ from pathlib import Path
9
+
10
+
11
+ def main() -> None:
12
+ if len(sys.argv) < 2:
13
+ # Discover path from current Python's site-packages
14
+ import openenv.core.env_server.web_interface as m
15
+
16
+ path = Path(m.__file__).resolve()
17
+ else:
18
+ path = Path(sys.argv[1]).resolve()
19
+
20
+ if not path.exists():
21
+ print(f"File not found: {path}", file=sys.stderr)
22
+ sys.exit(1)
23
+
24
+ text = path.read_text()
25
+
26
+ # Already patched?
27
+ if "_get_step_for_number_field" in text and '"step": _get_step_for_number_field(field_info)' in text:
28
+ print("Already patched:", path)
29
+ return
30
+
31
+ # 1) Insert helper before _extract_action_fields
32
+ old1 = 'def _extract_action_fields(action_cls: Type[Action]) -> List[Dict[str, Any]]:'
33
+ new1 = '''def _get_step_for_number_field(field_info: Dict[str, Any]) -> float | None:
34
+ """Step for number inputs; avoids HTML5 default of 1 which restricts float ranges."""
35
+ if field_info.get("type") == "integer":
36
+ return 1
37
+ if field_info.get("type") == "number":
38
+ return field_info.get("multipleOf") if field_info.get("multipleOf") is not None else 0.01
39
+ return None
40
+
41
+
42
+ def _extract_action_fields(action_cls: Type[Action]) -> List[Dict[str, Any]]:'''
43
+ if new1 not in text and old1 in text:
44
+ text = text.replace(old1, new1, 1)
45
+
46
+ # 2) Add "step" to action_fields dict
47
+ old2 = ' "help_text": _generate_help_text(field_name, field_info),\n }\n )'
48
+ new2 = ' "help_text": _generate_help_text(field_name, field_info),\n "step": _get_step_for_number_field(field_info),\n }\n )'
49
+ if new2 not in text and old2 in text:
50
+ text = text.replace(old2, new2, 1)
51
+
52
+ # 3) Add step_value and step attribute in _generate_single_field
53
+ old3a = " max_value = field.get(\"max_value\")\n default_value = field.get(\"default_value\")"
54
+ new3a = " max_value = field.get(\"max_value\")\n step_value = field.get(\"step\")\n default_value = field.get(\"default_value\")"
55
+ if new3a not in text and old3a in text:
56
+ text = text.replace(old3a, new3a, 1)
57
+
58
+ old3b = " if default_value is not None:\n input_attrs.append(f'value=\"{default_value}\"')\n\n attrs_str = \" \".join(input_attrs)"
59
+ new3b = " if default_value is not None:\n input_attrs.append(f'value=\"{default_value}\"')\n if step_value is not None:\n input_attrs.append(f'step=\"{step_value}\"')\n\n attrs_str = \" \".join(input_attrs)"
60
+ if new3b not in text and old3b in text:
61
+ text = text.replace(old3b, new3b, 1)
62
+
63
+ path.write_text(text)
64
+ print("Patched:", path)
65
+
66
+
67
+ if __name__ == "__main__":
68
+ main()