Skip to content

Carve positronic-client: light workspace package for the inference wire - #500

Closed
vertix wants to merge 5 commits into
molmo-spaces-adapterfrom
positronic-client
Closed

Carve positronic-client: light workspace package for the inference wire#500
vertix wants to merge 5 commits into
molmo-spaces-adapterfrom
positronic-client

Conversation

@vertix

@vertix vertix commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Stacked on #495 (base: molmo-spaces-adapter) — retarget to main after #495 merges. (Opened outside publish_pr deliberately: it only targets the default base, and this PR must diff against #495's branch.)

Implements Positronic-Robotics/internal#91, agreed in the founders' Slack discussion of #495's constants/dependency duplication.

Why

A real (non-fake) MolmoSpaces eval needed positronic.policy.remote.RemotePolicy importable inside molmo's venv — installing all of positronic into a foreign dependency world (the dependency/version-clash concern). And the wire's vocabulary ('robot_state.q', 'grip', 'image.wrist', …) had no importable home, so every adapter mirrored it as literals.

What

packages/positronic-client — a uv-workspace member (the openpi-client pattern; deps only numpy/msgpack/websockets/httpx/pillow):

  • positronic_client.keys — the canonical raw observation keys, defined once. openpi codecs and the molmo adapter now import them; the literal mirrors are gone.
  • positronic_client.serialization — the base wire with extension hooks (make_wire). positronic's dialect (positronic/utils/serialization.py) layers the roboarm-command/RobotStatus envelopes on top — the registry refactor the module's own TODO called for. A bare client receives unknown envelopes as plain wire dicts.
  • positronic_client.clientInferenceClient/InferenceSession moved from offboard/client.py. The negotiated image downsizing (server-advertised image_sizes) moves from RemoteSession into InferenceSession, so every wire consumer gets it by default, not just positronic's own RemotePolicy (which stays as the Policy-interface veneer, wiring in the command-aware dialect).
  • The molmo adapter talks to InferenceClient directly and drops its lazy positronic import — molmo's venv installs positronic-client only.

robolab/libero adapters are deliberately untouched: they speak the env-server vocabulary ('robot_state' state object + 'grip'), not the inference-wire keys — their literals are internal#74/internal#90 territory.

Testing

187 tests green across the client package, offboard, policy, and molmo adapter suites (client tests moved into packages/positronic-client/positronic_client/tests/); serialization-adjacent suites (dataset remote, lerobot servers, cfg) green; ruff + format clean.

🤖 Generated with Claude Code

@vertix

vertix commented Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@vertix
vertix force-pushed the positronic-client branch from 1498110 to a629c82 Compare July 23, 2026 10:20

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 149811070d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/positronic-client/pyproject.toml Outdated
Comment thread positronic/offboard/__init__.py
vertix added a commit that referenced this pull request Jul 23, 2026
The sync client API the package imports needs a modern websockets; a
standalone install (the package's stated use case) must not resolve an
older release that lacks it. Mirrors the floor the main package carries.

Ticket: none (Codex review finding on PR #500)
@vertix

vertix commented Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

vertix added a commit that referenced this pull request Jul 23, 2026
The package is pure Python and exists to be installed into foreign venvs
whose ML stacks pin their own numpy; a version constraint here only
manufactures resolver conflicts.

Requested-by: Vladimir Yakunin
Ticket: none (dependency-policy comment, PR #500 review discussion)
vertix added 4 commits July 23, 2026 10:30
…wire

A real MolmoSpaces eval needed `RemotePolicy` importable inside molmo's venv
— i.e. installing all of positronic into a foreign dependency world. The
wire-facing client now lives in `packages/positronic-client` (deps: numpy,
msgpack, websockets, httpx, pillow — the openpi-client pattern), so adapters
and customers install the light client only:

- `positronic_client.keys` — the canonical raw observation keys, defined
  once; openpi codecs and the molmo adapter import them instead of mirroring
  string literals.
- `positronic_client.serialization` — the base wire (numpy/scalars/JPEG)
  with extension hooks; positronic's dialect (`utils/serialization.py`)
  layers the roboarm-command/RobotStatus envelopes on top via `make_wire`.
- `positronic_client.client` — `InferenceClient`/`InferenceSession` moved
  from `offboard/client.py`; the negotiated image downsizing moves from
  `RemoteSession` into `InferenceSession`, so every wire consumer gets it
  by default. `RemotePolicy` stays in positronic as the Policy veneer,
  wiring in the command-aware dialect.
- The molmo adapter talks to `InferenceClient` directly (commands read via
  their wire envelopes), dropping its lazy positronic import — molmo's venv
  needs only `positronic-client`.

robolab/libero adapters are untouched: they speak the env-server vocabulary
('robot_state' object + 'grip'), not the inference-wire keys.

Requested-by: Vladimir Yakunin
Ticket: Positronic-Robotics/internal#91 #refs
Ticket: Positronic-Robotics/internal#90 #refs
The sync client API the package imports needs a modern websockets; a
standalone install (the package's stated use case) must not resolve an
older release that lacks it. Mirrors the floor the main package carries.

Ticket: none (Codex review finding on PR #500)
The package is pure Python and exists to be installed into foreign venvs
whose ML stacks pin their own numpy; a version constraint here only
manufactures resolver conflicts.

Requested-by: Vladimir Yakunin
Ticket: none (dependency-policy comment, PR #500 review discussion)
Same gap as the adapter suite: the workflow's hard-coded testpaths
override omitted the new package's tests.

Ticket: none (completes the carve's CI wiring, PR #500)
@vertix
vertix force-pushed the positronic-client branch from 0373d00 to b7c4ba2 Compare July 23, 2026 10:30
It applies to every session including localhost (smaller payloads, codec
output unchanged — the codec resizes to the same advertised target either
way); in-process inference never constructs a session, so nothing local
to the process is touched.

Requested-by: Vladimir Yakunin
Ticket: none (PR #500 review discussion)
@vertix

vertix commented Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

Closing unmerged — the observation-key dedup is recut in #505 as a canonical positronic.keys module inside positronic (no packages/positronic-client split), with this PR's relevant Codex outcome preserved (the websockets floor was specific to the standalone client package; the offboard-shim finding was declined here per the no-shims rule and is moot without the split).

The positronic-client / serialization carve has no consumer in the end state — molmo's venv installs zero positronic packages, and eval customers run servers, not clients — so it's parked per internal#91 until a real out-of-repo consumer appears. The client/serialization work stays on this branch for that day.

@vertix vertix closed this Jul 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant