inspect-robots-xpolicylab 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,221 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[codz]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py.cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ # Pipfile.lock
96
+
97
+ # UV
98
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ # uv.lock
102
+
103
+ # poetry
104
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
106
+ # commonly ignored for libraries.
107
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
+ # poetry.lock
109
+ # poetry.toml
110
+
111
+ # pdm
112
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
113
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
114
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
115
+ # pdm.lock
116
+ # pdm.toml
117
+ .pdm-python
118
+ .pdm-build/
119
+
120
+ # pixi
121
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
122
+ # pixi.lock
123
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
124
+ # in the .venv directory. It is recommended not to include this directory in version control.
125
+ .pixi
126
+
127
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
128
+ __pypackages__/
129
+
130
+ # Celery stuff
131
+ celerybeat-schedule
132
+ celerybeat.pid
133
+
134
+ # Redis
135
+ *.rdb
136
+ *.aof
137
+ *.pid
138
+
139
+ # RabbitMQ
140
+ mnesia/
141
+ rabbitmq/
142
+ rabbitmq-data/
143
+
144
+ # ActiveMQ
145
+ activemq-data/
146
+
147
+ # SageMath parsed files
148
+ *.sage.py
149
+
150
+ # Environments
151
+ .env
152
+ .envrc
153
+ .venv
154
+ env/
155
+ venv/
156
+ ENV/
157
+ env.bak/
158
+ venv.bak/
159
+
160
+ # Spyder project settings
161
+ .spyderproject
162
+ .spyproject
163
+
164
+ # Rope project settings
165
+ .ropeproject
166
+
167
+ # mkdocs documentation
168
+ /site
169
+
170
+ # mypy
171
+ .mypy_cache/
172
+ .dmypy.json
173
+ dmypy.json
174
+
175
+ # Pyre type checker
176
+ .pyre/
177
+
178
+ # pytype static type analyzer
179
+ .pytype/
180
+
181
+ # Cython debug symbols
182
+ cython_debug/
183
+
184
+ # PyCharm
185
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
186
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
187
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
188
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
189
+ # .idea/
190
+
191
+ # Abstra
192
+ # Abstra is an AI-powered process automation framework.
193
+ # Ignore directories containing user credentials, local state, and settings.
194
+ # Learn more at https://abstra.io/docs
195
+ .abstra/
196
+
197
+ # Visual Studio Code
198
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
199
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
200
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
201
+ # you could uncomment the following to ignore the entire vscode folder
202
+ # .vscode/
203
+ # Temporary file for partial code execution
204
+ tempCodeRunnerFile.py
205
+
206
+ # Ruff stuff:
207
+ .ruff_cache/
208
+
209
+ # PyPI configuration file
210
+ .pypirc
211
+
212
+ # Marimo
213
+ marimo/_static/
214
+ marimo/_lsp/
215
+ __marimo__/
216
+
217
+ # Streamlit
218
+ .streamlit/secrets.toml
219
+
220
+ # uv.lock is committed: CI installs with `uv sync --locked` for reproducible
221
+ # builds. Run `uv lock` after changing dependencies in pyproject.toml.
@@ -0,0 +1,141 @@
1
+ Metadata-Version: 2.4
2
+ Name: inspect-robots-xpolicylab
3
+ Version: 0.1.0
4
+ Summary: XPolicyLab policy adapter for Inspect Robots — evaluate any XPolicyLab-served VLA policy (π0, GR00T, OpenVLA-OFT, RDT, ACT, ...) with Inspect Robots.
5
+ Project-URL: Homepage, https://github.com/robocurve/inspect-robots/tree/main/plugins/inspect-robots-xpolicylab
6
+ Project-URL: Repository, https://github.com/robocurve/inspect-robots
7
+ Author: Inspect Robots contributors
8
+ License-Expression: MIT
9
+ Keywords: evaluation,inspect_robots,policy-server,robotics,vla,xpolicylab
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Science/Research
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
15
+ Classifier: Typing :: Typed
16
+ Requires-Python: >=3.10
17
+ Requires-Dist: inspect-robots>=0.2
18
+ Requires-Dist: msgpack-numpy>=0.4.8
19
+ Requires-Dist: msgpack>=1.0
20
+ Requires-Dist: numpy>=1.24
21
+ Requires-Dist: websockets>=12
22
+ Provides-Extra: dev
23
+ Requires-Dist: mypy>=1.11; extra == 'dev'
24
+ Requires-Dist: pytest-cov>=5.0; extra == 'dev'
25
+ Requires-Dist: pytest>=8.0; extra == 'dev'
26
+ Requires-Dist: ruff>=0.6; extra == 'dev'
27
+ Description-Content-Type: text/markdown
28
+
29
+ # inspect-robots-xpolicylab
30
+
31
+ Drive any [XPolicyLab](https://github.com/XPolicyLab/XPolicyLab)-served policy
32
+ from [Inspect Robots](https://github.com/robocurve/inspect-robots).
33
+
34
+ XPolicyLab unifies **40+ VLA and imitation-learning policies** (π0 / π0.5,
35
+ GR00T N1.7, OpenVLA-OFT, RDT-1B, SmolVLA, ACT, Diffusion Policy, …) behind one
36
+ policy-server contract: each policy runs in its own conda/uv environment and
37
+ serves inference over a websocket protocol. This plugin is the Inspect Robots
38
+ side of that wire: a `Policy` adapter that connects to a running XPolicyLab
39
+ policy server, so the whole policy zoo becomes evaluable with any Inspect
40
+ Robots embodiment and task.
41
+
42
+ The adapter speaks XPolicyLab's msgpack-over-websocket protocol directly — it
43
+ does **not** depend on the `xpolicylab` package (which is not on PyPI). Only
44
+ the policy *server* needs an XPolicyLab checkout.
45
+
46
+ ## Install
47
+
48
+ ```bash
49
+ pip install inspect-robots-xpolicylab
50
+ ```
51
+
52
+ The `xpolicylab` policy then appears in `inspect-robots list policies`.
53
+
54
+ ## Quickstart
55
+
56
+ **Terminal 1 — serve a policy from your XPolicyLab checkout** (its own
57
+ environment, possibly another machine; see the
58
+ [XPolicyLab README](https://github.com/XPolicyLab/XPolicyLab#readme) for
59
+ per-policy install/checkpoint details):
60
+
61
+ ```bash
62
+ cd XPolicyLab/policy/Pi_0
63
+ bash setup_eval_policy_server.sh <bench_name> <task_name> <ckpt_name> \
64
+ <env_cfg_type> <action_type> <seed> <policy_gpu_id> <policy_env> 19000 0.0.0.0
65
+ ```
66
+
67
+ **Terminal 2 — evaluate it with Inspect Robots:**
68
+
69
+ ```bash
70
+ inspect-robots run --task my-task --policy xpolicylab --embodiment isaacsim \
71
+ -P url=ws://gpu-box:19000 -P cameras=cam_head:base_rgb
72
+ ```
73
+
74
+ or programmatically:
75
+
76
+ ```python
77
+ from inspect_robots import eval
78
+ from inspect_robots_xpolicylab import XPolicyLabPolicy
79
+
80
+ with XPolicyLabPolicy(url="ws://gpu-box:19000", cameras="cam_head:base_rgb") as policy:
81
+ log = eval("my-task", policy, "isaacsim")
82
+ ```
83
+
84
+ Constructing the policy and reading `.info` never touch the network — the
85
+ websocket connects on first `reset()`/`act()`, with retries while the policy
86
+ server cold-starts (loading VLA weights can take minutes).
87
+
88
+ ## Configuration
89
+
90
+ | Arg | Default | Meaning |
91
+ | --- | --- | --- |
92
+ | `url` | `ws://localhost:19000` | policy server websocket URL |
93
+ | `action_type` | `joint` | `joint` → `*arm_joint_state` actions; `ee` → `*ee_pose` |
94
+ | `arms` | `1` | `1` or `2` (dual-arm uses `left_*`/`right_*` keys) |
95
+ | `arm_dim` / `ee_dim` | `7` / `1` | per-arm joint dims / gripper dims |
96
+ | `cameras` | `cam_head:cam_head` | XPolicyLab camera slot → Inspect Robots camera name |
97
+ | `state_map` | see below | XPolicyLab state key → Inspect Robots state key |
98
+ | `required_state_keys` | joint: `joint_pos,gripper`; ee: none | state keys enforced by compatibility checking |
99
+ | `action_keys` + `action_dim` | derived | explicit ordered action-dict keys for exotic setups |
100
+ | `camera_height` / `camera_width` | unset | declare camera resolution for compatibility checks |
101
+ | `control_hz` | unset | chunk playback rate; also sent as `additional_info.frequency` |
102
+ | `name` | `xpolicylab` | policy name in logs (tag runs e.g. `xpolicylab:pi0`) |
103
+ | `connect_timeout_s` / `request_timeout_s` | `30` / `120` | client timeouts |
104
+ | `connect_attempts` / `connect_retry_delay_s` | `10` / `5` | cold-start retry budget |
105
+
106
+ Mapping-valued args accept a compact string form for the CLI:
107
+ `-P cameras=cam_head:base_rgb,cam_wrist:wrist_rgb`.
108
+
109
+ Default `state_map` (all XPolicyLab state fields are optional; mapped keys
110
+ missing from an observation are simply not sent):
111
+
112
+ | XPolicyLab key | Inspect Robots key |
113
+ | --- | --- |
114
+ | `arm_joint_state` | `joint_pos` |
115
+ | `ee_joint_state` | `gripper` |
116
+ | `ee_pose` | `eef_pose` |
117
+
118
+ ## Action mapping
119
+
120
+ Each `infer` reply is an action chunk — one dict per future control step.
121
+ Dicts flatten to vectors in a fixed order: for each arm (left then right), the
122
+ arm key then the end-effector key. The default single-arm joint profile is
123
+ `concat(arm_joint_state, ee_joint_state)` → dim 8, matching the
124
+ `inspect-robots-isaacsim` default Franka profile.
125
+
126
+ ## Lifecycle notes
127
+
128
+ - `reset(scene)` ends the previous trial server-side (`trial_end`) and starts
129
+ a fresh `trial_id`; `close()` ends any open trial and says goodbye.
130
+ - `eval()` closes embodiments it resolves, **not** policies — use `with`
131
+ / `close()` in programmatic runs. A best-effort `atexit` hook covers
132
+ registry-resolved CLI runs.
133
+ - If the socket drops mid-eval, the trial in flight errors and the next
134
+ `reset()`/`act()` reconnects (replaying the `hello` handshake).
135
+
136
+ ## Protocol compatibility
137
+
138
+ Validated against XPolicyLab commit
139
+ `fe71eb54675cef495fea817a637386a4f4529153`. The protocol carries no version
140
+ field; if upstream changes the wire format, `_protocol.py` is the single small
141
+ module to diff and update.
@@ -0,0 +1,113 @@
1
+ # inspect-robots-xpolicylab
2
+
3
+ Drive any [XPolicyLab](https://github.com/XPolicyLab/XPolicyLab)-served policy
4
+ from [Inspect Robots](https://github.com/robocurve/inspect-robots).
5
+
6
+ XPolicyLab unifies **40+ VLA and imitation-learning policies** (π0 / π0.5,
7
+ GR00T N1.7, OpenVLA-OFT, RDT-1B, SmolVLA, ACT, Diffusion Policy, …) behind one
8
+ policy-server contract: each policy runs in its own conda/uv environment and
9
+ serves inference over a websocket protocol. This plugin is the Inspect Robots
10
+ side of that wire: a `Policy` adapter that connects to a running XPolicyLab
11
+ policy server, so the whole policy zoo becomes evaluable with any Inspect
12
+ Robots embodiment and task.
13
+
14
+ The adapter speaks XPolicyLab's msgpack-over-websocket protocol directly — it
15
+ does **not** depend on the `xpolicylab` package (which is not on PyPI). Only
16
+ the policy *server* needs an XPolicyLab checkout.
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ pip install inspect-robots-xpolicylab
22
+ ```
23
+
24
+ The `xpolicylab` policy then appears in `inspect-robots list policies`.
25
+
26
+ ## Quickstart
27
+
28
+ **Terminal 1 — serve a policy from your XPolicyLab checkout** (its own
29
+ environment, possibly another machine; see the
30
+ [XPolicyLab README](https://github.com/XPolicyLab/XPolicyLab#readme) for
31
+ per-policy install/checkpoint details):
32
+
33
+ ```bash
34
+ cd XPolicyLab/policy/Pi_0
35
+ bash setup_eval_policy_server.sh <bench_name> <task_name> <ckpt_name> \
36
+ <env_cfg_type> <action_type> <seed> <policy_gpu_id> <policy_env> 19000 0.0.0.0
37
+ ```
38
+
39
+ **Terminal 2 — evaluate it with Inspect Robots:**
40
+
41
+ ```bash
42
+ inspect-robots run --task my-task --policy xpolicylab --embodiment isaacsim \
43
+ -P url=ws://gpu-box:19000 -P cameras=cam_head:base_rgb
44
+ ```
45
+
46
+ or programmatically:
47
+
48
+ ```python
49
+ from inspect_robots import eval
50
+ from inspect_robots_xpolicylab import XPolicyLabPolicy
51
+
52
+ with XPolicyLabPolicy(url="ws://gpu-box:19000", cameras="cam_head:base_rgb") as policy:
53
+ log = eval("my-task", policy, "isaacsim")
54
+ ```
55
+
56
+ Constructing the policy and reading `.info` never touch the network — the
57
+ websocket connects on first `reset()`/`act()`, with retries while the policy
58
+ server cold-starts (loading VLA weights can take minutes).
59
+
60
+ ## Configuration
61
+
62
+ | Arg | Default | Meaning |
63
+ | --- | --- | --- |
64
+ | `url` | `ws://localhost:19000` | policy server websocket URL |
65
+ | `action_type` | `joint` | `joint` → `*arm_joint_state` actions; `ee` → `*ee_pose` |
66
+ | `arms` | `1` | `1` or `2` (dual-arm uses `left_*`/`right_*` keys) |
67
+ | `arm_dim` / `ee_dim` | `7` / `1` | per-arm joint dims / gripper dims |
68
+ | `cameras` | `cam_head:cam_head` | XPolicyLab camera slot → Inspect Robots camera name |
69
+ | `state_map` | see below | XPolicyLab state key → Inspect Robots state key |
70
+ | `required_state_keys` | joint: `joint_pos,gripper`; ee: none | state keys enforced by compatibility checking |
71
+ | `action_keys` + `action_dim` | derived | explicit ordered action-dict keys for exotic setups |
72
+ | `camera_height` / `camera_width` | unset | declare camera resolution for compatibility checks |
73
+ | `control_hz` | unset | chunk playback rate; also sent as `additional_info.frequency` |
74
+ | `name` | `xpolicylab` | policy name in logs (tag runs e.g. `xpolicylab:pi0`) |
75
+ | `connect_timeout_s` / `request_timeout_s` | `30` / `120` | client timeouts |
76
+ | `connect_attempts` / `connect_retry_delay_s` | `10` / `5` | cold-start retry budget |
77
+
78
+ Mapping-valued args accept a compact string form for the CLI:
79
+ `-P cameras=cam_head:base_rgb,cam_wrist:wrist_rgb`.
80
+
81
+ Default `state_map` (all XPolicyLab state fields are optional; mapped keys
82
+ missing from an observation are simply not sent):
83
+
84
+ | XPolicyLab key | Inspect Robots key |
85
+ | --- | --- |
86
+ | `arm_joint_state` | `joint_pos` |
87
+ | `ee_joint_state` | `gripper` |
88
+ | `ee_pose` | `eef_pose` |
89
+
90
+ ## Action mapping
91
+
92
+ Each `infer` reply is an action chunk — one dict per future control step.
93
+ Dicts flatten to vectors in a fixed order: for each arm (left then right), the
94
+ arm key then the end-effector key. The default single-arm joint profile is
95
+ `concat(arm_joint_state, ee_joint_state)` → dim 8, matching the
96
+ `inspect-robots-isaacsim` default Franka profile.
97
+
98
+ ## Lifecycle notes
99
+
100
+ - `reset(scene)` ends the previous trial server-side (`trial_end`) and starts
101
+ a fresh `trial_id`; `close()` ends any open trial and says goodbye.
102
+ - `eval()` closes embodiments it resolves, **not** policies — use `with`
103
+ / `close()` in programmatic runs. A best-effort `atexit` hook covers
104
+ registry-resolved CLI runs.
105
+ - If the socket drops mid-eval, the trial in flight errors and the next
106
+ `reset()`/`act()` reconnects (replaying the `hello` handshake).
107
+
108
+ ## Protocol compatibility
109
+
110
+ Validated against XPolicyLab commit
111
+ `fe71eb54675cef495fea817a637386a4f4529153`. The protocol carries no version
112
+ field; if upstream changes the wire format, `_protocol.py` is the single small
113
+ module to diff and update.
@@ -0,0 +1,100 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.18", "hatch-fancy-pypi-readme>=24.1"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "inspect-robots-xpolicylab"
7
+ version = "0.1.0"
8
+ description = "XPolicyLab policy adapter for Inspect Robots — evaluate any XPolicyLab-served VLA policy (π0, GR00T, OpenVLA-OFT, RDT, ACT, ...) with Inspect Robots."
9
+ dynamic = ["readme"]
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ authors = [{ name = "Inspect Robots contributors" }]
13
+ keywords = ["robotics", "xpolicylab", "vla", "policy-server", "inspect_robots", "evaluation"]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Intended Audience :: Science/Research",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Programming Language :: Python :: 3",
19
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
20
+ "Typing :: Typed",
21
+ ]
22
+ # NOTE: `xpolicylab` itself is intentionally NOT a dependency. It is not published
23
+ # on PyPI (git-install only) and ships collision-prone top-level packages
24
+ # (`client_server`, `utils`). This adapter speaks XPolicyLab's small websocket
25
+ # protocol directly; the policy server always runs from the user's XPolicyLab
26
+ # checkout in its own environment — that separation is XPolicyLab's core design.
27
+ #
28
+ # websockets floor: the sync client this adapter uses exists since v11; Isaac Sim
29
+ # environments (which the flagship isaacsim pairing shares a venv with) ship v12.
30
+ dependencies = [
31
+ "inspect-robots>=0.2",
32
+ "numpy>=1.24",
33
+ "websockets>=12",
34
+ "msgpack>=1.0",
35
+ "msgpack-numpy>=0.4.8",
36
+ ]
37
+
38
+ [project.optional-dependencies]
39
+ dev = ["pytest>=8.0", "pytest-cov>=5.0", "mypy>=1.11", "ruff>=0.6"]
40
+
41
+ # Entry-point discovery: an installed inspect-robots-xpolicylab appears in
42
+ # `inspect-robots list policies` without being imported first. The registry calls
43
+ # this factory by the name `xpolicylab`.
44
+ [project.entry-points."inspect_robots.policies"]
45
+ xpolicylab = "inspect_robots_xpolicylab:xpolicylab_policy"
46
+
47
+ [project.urls]
48
+ Homepage = "https://github.com/robocurve/inspect-robots/tree/main/plugins/inspect-robots-xpolicylab"
49
+ Repository = "https://github.com/robocurve/inspect-robots"
50
+
51
+ # In the Inspect Robots monorepo this resolves the `inspect_robots` dependency to the
52
+ # in-repo core package instead of PyPI. Harmless in a standalone checkout (uv
53
+ # ignores a workspace source when there is no workspace root).
54
+ [tool.uv.sources]
55
+ inspect-robots = { workspace = true }
56
+
57
+ [tool.hatch.build.targets.wheel]
58
+ packages = ["src/inspect_robots_xpolicylab"]
59
+
60
+ [tool.hatch.build.targets.sdist]
61
+ include = ["src/inspect_robots_xpolicylab", "tests", "README.md"]
62
+
63
+ [tool.ruff]
64
+ line-length = 100
65
+
66
+ [tool.mypy]
67
+ strict = true
68
+
69
+ # msgpack / msgpack-numpy ship no type stubs; the codec wraps them in one module.
70
+ [[tool.mypy.overrides]]
71
+ module = ["msgpack.*", "msgpack_numpy.*"]
72
+ ignore_missing_imports = true
73
+
74
+ # PyPI readme: identical to README.md except GitHub-only alert syntax
75
+ # (e.g. `> [!NOTE]`) is rewritten to bold blockquotes, which PyPI renders.
76
+ [tool.hatch.metadata.hooks.fancy-pypi-readme]
77
+ content-type = "text/markdown"
78
+
79
+ [[tool.hatch.metadata.hooks.fancy-pypi-readme.fragments]]
80
+ path = "README.md"
81
+
82
+ [[tool.hatch.metadata.hooks.fancy-pypi-readme.substitutions]]
83
+ pattern = '(?m)^> \[!NOTE\][ \t]*$'
84
+ replacement = '> **Note:**'
85
+
86
+ [[tool.hatch.metadata.hooks.fancy-pypi-readme.substitutions]]
87
+ pattern = '(?m)^> \[!TIP\][ \t]*$'
88
+ replacement = '> **Tip:**'
89
+
90
+ [[tool.hatch.metadata.hooks.fancy-pypi-readme.substitutions]]
91
+ pattern = '(?m)^> \[!IMPORTANT\][ \t]*$'
92
+ replacement = '> **Important:**'
93
+
94
+ [[tool.hatch.metadata.hooks.fancy-pypi-readme.substitutions]]
95
+ pattern = '(?m)^> \[!WARNING\][ \t]*$'
96
+ replacement = '> **Warning:**'
97
+
98
+ [[tool.hatch.metadata.hooks.fancy-pypi-readme.substitutions]]
99
+ pattern = '(?m)^> \[!CAUTION\][ \t]*$'
100
+ replacement = '> **Caution:**'
@@ -0,0 +1,42 @@
1
+ """inspect-robots-xpolicylab — drive XPolicyLab-served policies from Inspect Robots.
2
+
3
+ `XPolicyLab <https://github.com/XPolicyLab/XPolicyLab>`_ unifies 40+ VLA and
4
+ imitation-learning policies behind one websocket policy-server contract. Start
5
+ any of its policy servers, then evaluate it like any other Inspect Robots
6
+ policy::
7
+
8
+ inspect-robots list policies # -> includes "xpolicylab"
9
+ inspect-robots run --task my-task --policy xpolicylab --embodiment isaacsim \
10
+ -P url=ws://gpu-box:19000 -P cameras=cam_head:base_rgb
11
+
12
+ or programmatically::
13
+
14
+ from inspect_robots import eval
15
+ from inspect_robots_xpolicylab import XPolicyLabPolicy
16
+
17
+ with XPolicyLabPolicy(url="ws://gpu-box:19000") as policy:
18
+ eval("my-task", policy, "isaacsim")
19
+
20
+ The policy is discovered via the ``inspect_robots.policies`` entry point, so it
21
+ shows up without being imported first.
22
+ """
23
+
24
+ from __future__ import annotations
25
+
26
+ from typing import Any
27
+
28
+ from inspect_robots_xpolicylab.policy import XPolicyLabPolicy
29
+
30
+ __all__ = ["XPolicyLabPolicy", "xpolicylab_policy"]
31
+
32
+ __version__ = "0.1.0"
33
+
34
+
35
+ def xpolicylab_policy(**kwargs: Any) -> XPolicyLabPolicy:
36
+ """Factory the Inspect Robots registry calls (entry point ``xpolicylab``).
37
+
38
+ Accepts the same keyword arguments as :class:`XPolicyLabPolicy`; the CLI
39
+ forwards ``-P key=value`` pairs here (mapping-valued args accept the
40
+ compact ``"key:value,key:value"`` string form).
41
+ """
42
+ return XPolicyLabPolicy(**kwargs)