diff --git a/.github/scripts/check_sdist.py b/.github/scripts/check_sdist.py old mode 100644 new mode 100755 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 19defb0fd47..aaf719e94ca 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -274,6 +274,35 @@ jobs: path: .cachix-marker key: cachix-published-${{ runner.os }}-${{ runner.arch }}-${{ needs.cachix-build-check.outputs.inputs-hash }} + message-alignment: + name: Built-in message alignment + env: + DIMOS_MESSAGE_ALIGNMENT_REQUIRED: "1" + timeout-minutes: 10 + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: actions/checkout@v7 + - uses: astral-sh/setup-uv@v10.0.1 + with: + python-version: '3.12' + - uses: dtolnay/rust-toolchain@stable + with: + toolchain: '1.92.0' + components: rustfmt + - name: Install locked generation/check dependencies only + run: | + uv run --no-project --with "dimos-cdrgen[prepare]==0.1.0" python -m scripts.prepare_builtin_sources + uv sync --only-group message-codegen --frozen + - name: Reject built-in Python/C++/Rust/schema drift + run: | + .venv/bin/python -m scripts.generate_builtin_messages + .venv/bin/python -m scripts.generate_builtin_messages --check + - name: Verify drift rejection for changed inputs and output inventories + run: .venv/bin/python -m pytest -c /dev/null --rootdir . --noconftest -q dimos/message_codegen/test_builtin_alignment.py + + lint: timeout-minutes: 10 runs-on: ubuntu-latest @@ -309,7 +338,9 @@ jobs: enable-cache: true prune-cache: true - name: Install lint dependencies - run: uv sync --only-group lint --frozen + run: | + uv run --no-project --with "dimos-cdrgen[prepare]==0.1.0" python -m scripts.prepare_builtin_sources + uv sync --only-group lint --frozen - name: Check declared dependencies run: uv run --no-sync deptry dimos --config pyproject.toml --github-output - name: Mypy @@ -379,7 +410,9 @@ jobs: sudo apt-get update sudo apt-get install -y portaudio19-dev - name: Install dependencies - run: uv sync --group tests --frozen + run: | + uv run --no-project --with "dimos-cdrgen[prepare]==0.1.0" python -m scripts.prepare_builtin_sources + uv sync --group tests --frozen # Needs Python and Rust: `dimos bake` is Python that writes a Rust program and compiles it, and the tests jobs have no Rust. - name: Bake e2e tests run: uv run pytest -m bake_e2e dimos/cli/bake/test_bake_e2e.py --no-cov @@ -434,7 +467,9 @@ jobs: if: runner.os == 'macOS' run: brew install portaudio - name: Install dependencies - run: uv sync --group tests --frozen + run: | + uv run --no-project --with "dimos-cdrgen[prepare]==0.1.0" python -m scripts.prepare_builtin_sources + uv sync --group tests --frozen - name: Build the extensions run: uv run python bin/pyo3-extensions --build # Tested here, not in the tests jobs, so those start without waiting for this build. @@ -465,7 +500,9 @@ jobs: with: node-version: 'lts/*' - name: Install Python dependencies - run: uv sync --group tests --frozen + run: | + uv run --no-project --with "dimos-cdrgen[prepare]==0.1.0" python -m scripts.prepare_builtin_sources + uv sync --group tests --frozen - name: Restore Hugging Face model cache id: hf-cache uses: actions/cache/restore@v6 @@ -589,7 +626,9 @@ jobs: - name: Fetch the go2_short replay dataset run: git lfs pull --include="data/.lfs/go2_short.db.tar.gz" --exclude="" - name: Install dependencies - run: uv sync --group tests --group browser-tests --frozen + run: | + uv run --no-project --with "dimos-cdrgen[prepare]==0.1.0" python -m scripts.prepare_builtin_sources + uv sync --group tests --group browser-tests --frozen - name: Install Playwright browsers # the e2e runs in both engines run: uv run playwright install --with-deps chromium firefox - name: Cockpit + SDK browser e2e @@ -706,7 +745,9 @@ jobs: if: steps.native-marker.outputs.cache-hit == 'true' run: python3 bin/native-modules --link-results .cachix-marker/links.txt - name: Install dependencies - run: uv sync --group tests --frozen + run: | + uv run --no-project --with "dimos-cdrgen[prepare]==0.1.0" python -m scripts.prepare_builtin_sources + uv sync --group tests --frozen - name: Run tests run: uv run pytest --numprocesses=logical --cov=dimos/ --junitxml=junit.xml -m 'not (self_hosted or self_hosted_large or web_browser or bake_e2e or native_e2e)' # Serial and after the parallel run: it binds the livox SDK's fixed ports. @@ -845,11 +886,14 @@ jobs: uv venv .codecov-venv uv pip install --python .codecov-venv/bin/python codecov-cli==11.2.8 - name: Install dependencies - run: uv sync --group tests-self-hosted --frozen + run: | + uv run --no-project --with "dimos-cdrgen[prepare]==0.1.0" python -m scripts.prepare_builtin_sources + uv sync --group tests-self-hosted --frozen - name: Install web_browser e2e dependencies (macOS) if: matrix.os == 'macOS' run: | brew install ffmpeg + uv run --no-project --with "dimos-cdrgen[prepare]==0.1.0" python -m scripts.prepare_builtin_sources uv sync --group tests-self-hosted --group browser-tests --frozen uv run playwright install chromium firefox - name: Install Node 24 for the Pi and dimcode CLIs @@ -1113,7 +1157,9 @@ jobs: `# Rerun viewer pulls in X11 keyboard bindings when DISPLAY is set.` \ libxkbcommon-x11-0 - name: Install dependencies - run: uv sync --group tests-self-hosted --frozen + run: | + uv run --no-project --with "dimos-cdrgen[prepare]==0.1.0" python -m scripts.prepare_builtin_sources + uv sync --group tests-self-hosted --frozen - name: Build C++ extensions in-place run: uv run python setup.py build_ext --inplace - name: Build DimSim and install its headless Chromium @@ -1226,7 +1272,9 @@ jobs: with: enable-cache: true - name: Install dependencies - run: uv sync --group tests --frozen + run: | + uv run --no-project --with "dimos-cdrgen[prepare]==0.1.0" python -m scripts.prepare_builtin_sources + uv sync --group tests --frozen env: # Compile bytecode at install rather than at first import. UV_COMPILE_BYTECODE: "1" @@ -1341,7 +1389,9 @@ jobs: # Nothing worth caching: Otava's dependencies are all prebuilt wheels. enable-cache: false - name: Install Otava - run: uv sync --project .github/benchmark-analysis --frozen + run: | + uv run --no-project --with "dimos-cdrgen[prepare]==0.1.0" python -m scripts.prepare_builtin_sources + uv sync --project .github/benchmark-analysis --frozen - name: Analyse the series and file regressions env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/message-codegen.yml b/.github/workflows/message-codegen.yml new file mode 100644 index 00000000000..7ec219a8f1a --- /dev/null +++ b/.github/workflows/message-codegen.yml @@ -0,0 +1,32 @@ +name: message-codegen + +on: + pull_request: + paths: + - dimos/message_codegen/** + - native/cpp/include/dimos/native/cdr_codec.hpp + - docs/development/message-source-packages.md + - pyproject.toml + - uv.lock + - .github/workflows/message-codegen.yml + workflow_dispatch: + +permissions: + contents: read + +jobs: + integration: + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-14] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v7 + - uses: astral-sh/setup-uv@v10.0.1 + - name: Install published generator and consumer test tools + run: | + uv venv .venv --python 3.12 --seed + uv pip install --python .venv/bin/python 'dimos-cdrgen[native]==0.1.0' numpy build pytest pytest-asyncio pytest-env + - name: Verify DimOS SDK, installed Python consumer and C++ consumer + run: .venv/bin/python -m pytest --noconftest -o addopts='' -q dimos/message_codegen/test_integration.py diff --git a/.github/workflows/release-build-check.yml b/.github/workflows/release-build-check.yml index 7d317cd6c3a..ceada5c73b6 100644 --- a/.github/workflows/release-build-check.yml +++ b/.github/workflows/release-build-check.yml @@ -31,12 +31,18 @@ jobs: env: # Keep in sync with the build-wheels env in release.yml CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_34 + CIBW_BEFORE_TEST: "pip install {project}/wheelhouse/dimos_generated-*.whl" CIBW_TEST_COMMAND: "python {project}/.github/scripts/wheel_smoke.py" steps: - name: Checkout uses: actions/checkout@v7 - name: Build cockpit dist uses: ./.github/actions/build-cockpit + - name: Prepare the curated message wheel + run: | + python -m pip install uv + uv run --no-project --with "dimos-cdrgen[prepare]==0.1.0" python -m scripts.prepare_builtin_sources + uv build --wheel --out-dir wheelhouse packages/dimos-generated - name: Build one wheel uses: pypa/cibuildwheel@v4.2.1 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 540f1faddb6..2744727a550 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -122,6 +122,7 @@ jobs: CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_34 # open3d>=0.19 requires glibc 2.31+ CIBW_MANYLINUX_AARCH64_IMAGE: manylinux_2_34 # open3d>=0.19 requires glibc 2.31+ # Asserts the packaged relay + Cockpit and serves them from the installed wheel. + CIBW_BEFORE_TEST: "pip install {project}/wheelhouse/dimos_generated-*.whl" CIBW_TEST_COMMAND: "python {project}/.github/scripts/wheel_smoke.py" MACOSX_DEPLOYMENT_TARGET: "11.0" steps: @@ -129,6 +130,11 @@ jobs: uses: actions/checkout@v7 - name: Build cockpit dist # setup.py copies it into the wheel's _relay_dist uses: ./.github/actions/build-cockpit + - name: Prepare the curated message wheel + run: | + python -m pip install uv + uv run --no-project --with "dimos-cdrgen[prepare]==0.1.0" python -m scripts.prepare_builtin_sources + uv build --wheel --out-dir wheelhouse packages/dimos-generated - name: Build wheels uses: pypa/cibuildwheel@v4.2.1 - name: Attestation diff --git a/.gitignore b/.gitignore index 181e3ae4bbc..2644e75f80b 100644 --- a/.gitignore +++ b/.gitignore @@ -106,3 +106,6 @@ optuna.db # policy blobs are loaded from outside the repository *.bin + +# Prepared from schema-sources.json; keep downloaded schemas out of Git. +/packages/dimos-generated/interfaces/ diff --git a/dimos/hardware/sensors/lidar/fastlio2/cpp/flake.lock b/dimos/hardware/sensors/lidar/fastlio2/cpp/flake.lock index c22b1b2c472..11dd4fa4afb 100644 --- a/dimos/hardware/sensors/lidar/fastlio2/cpp/flake.lock +++ b/dimos/hardware/sensors/lidar/fastlio2/cpp/flake.lock @@ -28,11 +28,11 @@ }, "locked": { "dir": "native/cpp", - "lastModified": 1791386052, - "narHash": "sha256-MeVxI5e13wh7jQ0g2tnaLpiyDaQQMfqEAC7qrXopHY4=", + "lastModified": 1792431336, + "narHash": "sha256-W0biIt+6oH7bBHt44kV4J411Y3AUsuMkQ7OsS45BxDE=", "owner": "dimensionalOS", "repo": "dimos", - "rev": "87c0c26b40e8a5aeb9d9d346104b49d5fb02696a", + "rev": "fbccb5c45eb84a7f65413a37cba7afe3fe2d8008", "type": "github" }, "original": { diff --git a/dimos/message_codegen/native_build.py b/dimos/message_codegen/native_build.py new file mode 100644 index 00000000000..71044c0636e --- /dev/null +++ b/dimos/message_codegen/native_build.py @@ -0,0 +1,35 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Add DimOS SDK discovery to the published CDR generator toolchain.""" + +from importlib.util import find_spec +import json +from pathlib import Path + +from dimos_cdrgen.native_build import write_cmake_toolchain as library_toolchain + + +def write_cmake_toolchain(prefix: Path, destination: Path) -> Path: + """Export the library toolchain and retain optional DimOS SDK discovery.""" + result = library_toolchain(prefix, destination) + spec = find_spec("dimos") + if spec is not None and spec.submodule_search_locations: + package = Path(next(iter(spec.submodule_search_locations))) + for sdk in [package / "_native/cpp", package.parent / "native/cpp"]: + if (sdk / "dimos_nativeConfig.cmake").is_file(): + with result.open("a") as output: + output.write("list(APPEND CMAKE_PREFIX_PATH " + json.dumps(str(sdk)) + ")\n") + break + return result diff --git a/dimos/message_codegen/test_builtin_alignment.py b/dimos/message_codegen/test_builtin_alignment.py new file mode 100644 index 00000000000..f62abef6bbd --- /dev/null +++ b/dimos/message_codegen/test_builtin_alignment.py @@ -0,0 +1,197 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import ast +import json +import os +from pathlib import Path +import shutil +import subprocess +import sys + +from dimos_cdrgen.source_package import prepare +import pytest + + +@pytest.fixture(scope="module") +def aligned_checkout(tmp_path_factory): + root = Path(__file__).resolve().parents[2] + checkout = tmp_path_factory.mktemp("aligned-source") + ignore = shutil.ignore_patterns("build", "dist", "*.egg-info", "__pycache__", "target") + for name in ["dimos/message_codegen", "packages/dimos-generated"]: + shutil.copytree(root / name, checkout / name, ignore=ignore) + (checkout / "dimos/__init__.py").write_text("") + (checkout / "scripts").mkdir() + shutil.copyfile( + root / "scripts/generate_builtin_messages.py", + checkout / "scripts/generate_builtin_messages.py", + ) + shutil.copyfile(root / "pyproject.toml", checkout / "pyproject.toml") + result = run_generation(checkout, check=False) + assert result.returncode == 0, result.stderr + result = run_generation(checkout, check=True) + assert result.returncode == 0, result.stderr + return checkout + + +def run_generation(checkout, *, check): + environment = {key: value for key, value in os.environ.items() if key != "PYTHONPATH"} + return subprocess.run( + [ + sys.executable, + "-m", + "scripts.generate_builtin_messages", + *(["--check"] if check else []), + ], + cwd=checkout, + env=environment, + text=True, + capture_output=True, + ) + + +@pytest.mark.parametrize( + "change", + [ + "field", + "schema", + "new_type", + "deleted_type", + "renamed_type", + "version", + "extra_output", + "missing_python", + "missing_cpp", + "missing_rust", + "missing_rust_generator", + "missing_rust_definition", + "missing_schema", + ], +) +def test_independent_regeneration_rejects_and_repairs_drift(aligned_checkout, tmp_path, change): + checkout = tmp_path / "checkout" + shutil.copytree(aligned_checkout, checkout) + definitions = checkout / "packages/dimos-generated/interfaces" + output = checkout / "packages/dimos-generated/build/message-source/python" + point = definitions / "geometry_msgs/msg/Point.msg" + if change == "field": + point.write_text(point.read_text().replace("float64 x", "float32 x")) + elif change == "schema": + point.write_text(point.read_text() + "\n# Changed source schema comment\n") + elif change == "new_type": + (definitions / "alignment_msgs/msg").mkdir(parents=True) + (definitions / "alignment_msgs/msg/AlignmentProbe.msg").write_text( + "std_msgs/Header header\nfloat64 value\n" + ) + catalog = checkout / "packages/dimos-generated/catalog.json" + data = json.loads(catalog.read_text()) + data["roots"]["alignment_msgs/msg/AlignmentProbe"] = "Explicit test contract" + catalog.write_text(json.dumps(data)) + elif change == "deleted_type": + (definitions / "std_msgs/msg/Empty.msg").unlink() + catalog = checkout / "packages/dimos-generated/catalog.json" + data = json.loads(catalog.read_text()) + del data["roots"]["std_msgs/msg/Empty"] + catalog.write_text(json.dumps(data)) + elif change == "renamed_type": + previous = definitions / "dimos_msgs/msg/VideoStats.msg" + previous.rename(previous.with_name("RenamedStats.msg")) + catalog = checkout / "packages/dimos-generated/catalog.json" + data = json.loads(catalog.read_text()) + data["roots"]["dimos_msgs/msg/RenamedStats"] = data["roots"].pop( + "dimos_msgs/msg/VideoStats" + ) + catalog.write_text(json.dumps(data)) + elif change == "version": + metadata = checkout / "packages/dimos-generated/pyproject.toml" + metadata.write_text(metadata.read_text().replace('version = "0.1.0"', 'version = "0.1.1"')) + elif change == "extra_output": + # This file was never tracked by Git. The gate compares inventories, + # rather than relying on git diff (which would omit it). + (output / "dimos_generated/unexpected.py").write_text("STALE = True\n") + else: + paths = { + "missing_python": "dimos_generated/_types.py", + "missing_cpp": "dimos_generated_schemas/package/cpp/CMakeLists.txt", + "missing_rust": "dimos_generated_schemas/package/rust/src/lib.rs", + "missing_schema": "dimos_generated_schemas/schemas/geometry_msgs/msg/Point.msg", + "missing_rust_generator": "dimos_generated_schemas/package/rust/build.rs", + "missing_rust_definition": "dimos_generated_schemas/package/rust/interfaces/geometry_msgs/msg/Point.msg", + } + (output / paths[change]).unlink() + before_check = { + str(path.relative_to(output)): path.read_bytes() + for path in output.rglob("*") + if path.is_file() + } + failed = run_generation(checkout, check=True) + after_check = { + str(path.relative_to(output)): path.read_bytes() + for path in output.rglob("*") + if path.is_file() + } + assert after_check == before_check, "--check must not repair or rewrite build output" + assert failed.returncode != 0 + assert "Generated source drift" in failed.stderr, failed.stderr + if change == "field": + for language_output in [ + "_types.pyi", + "cpp/geometry_msgs/msg/Point.msg", + "rust/interfaces/geometry_msgs/msg/Point.msg", + ]: + assert language_output in failed.stderr + repaired = run_generation(checkout, check=False) + assert repaired.returncode == 0, repaired.stderr + aligned = run_generation(checkout, check=True) + assert aligned.returncode == 0, aligned.stderr + if change == "new_type": + assert (output / "dimos_generated/alignment_msgs/msg/__init__.py").read_text().find( + "AlignmentProbe" + ) >= 0 + elif change == "deleted_type": + assert not (output / "dimos_generated_schemas/schemas/std_msgs/msg/Empty.msg").exists() + elif change == "renamed_type": + text = (output / "dimos_generated/dimos_msgs/msg/__init__.py").read_text() + assert "RenamedStats" in text + assert "VideoStats" not in text + elif change == "version": + statements = ast.parse((output / "dimos_generated/__init__.py").read_text()).body + version = next( + ast.literal_eval(statement.value) + for statement in statements + if isinstance(statement, ast.Assign) + and isinstance(statement.targets[0], ast.Name) + and statement.targets[0].id == "__dimos_version__" + ) + assert version == "0.1.1" + manifest_path = output / "dimos_generated_schemas/package/message-package.json" + if manifest_path.exists(): + manifest = json.loads(manifest_path.read_text()) + assert manifest["version"] == "0.1.1" + assert ( + 'version = "0.1.1"' + in (output / "dimos_generated_schemas/package/rust/Cargo.toml").read_text() + ) + assert ( + "VERSION 0.1.1" + in (output / "dimos_generated_schemas/package/cpp/CMakeLists.txt").read_text() + ) + + +def test_source_package_preparation_keeps_alignment_check_valid(aligned_checkout): + project = aligned_checkout / "packages/dimos-generated" + prepare(project) + assert (project / "build/message-source/python/setup.py").is_file() + result = run_generation(aligned_checkout, check=True) + assert result.returncode == 0, result.stderr diff --git a/dimos/message_codegen/test_builtin_catalog.py b/dimos/message_codegen/test_builtin_catalog.py new file mode 100644 index 00000000000..682ec1babfb --- /dev/null +++ b/dimos/message_codegen/test_builtin_catalog.py @@ -0,0 +1,63 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Explicit product inputs do not expand when unrelated schemas appear.""" + +import json +from pathlib import Path +import shutil + +from dimos_cdrgen.source_package import prepare +import pytest + + +def test_unlisted_sources_do_not_expand_the_public_catalog(tmp_path): + project = tmp_path / "project" + shutil.copytree( + Path(__file__).resolve().parents[2] / "packages/dimos-generated", + project, + ignore=shutil.ignore_patterns("build", "dist", "*.egg-info", "__pycache__"), + ) + extra = project / "interfaces/extra_msgs/msg/NotExported.msg" + extra.parent.mkdir(parents=True) + extra.write_text("std_msgs/Header header\n") + source = prepare(project) + manifest = json.loads( + (source / "dimos_generated_schemas/package/message-package.json").read_text() + ) + assert len(manifest["owned"]) == 73 + assert "extra_msgs/msg/NotExported" not in manifest["owned"] + assert "builtin_interfaces/msg/Time" in manifest["owned"] + + +def test_declared_root_requires_a_reason_and_a_resolvable_closure(tmp_path): + project = tmp_path / "project" + shutil.copytree( + Path(__file__).resolve().parents[2] / "packages/dimos-generated", + project, + ignore=shutil.ignore_patterns("build", "dist", "*.egg-info", "__pycache__"), + ) + catalog = project / "catalog.json" + catalog.write_text(json.dumps({"format": 1, "roots": {"std_msgs/msg/Header": ""}})) + with pytest.raises(ValueError, match="requires a reason"): + prepare(project) + catalog.write_text(json.dumps({"format": 1, "roots": {"std_msgs/msg/Header": "Public API"}})) + source = prepare(project) + manifest = json.loads( + (source / "dimos_generated_schemas/package/message-package.json").read_text() + ) + assert set(manifest["owned"]) == {"std_msgs/msg/Header", "builtin_interfaces/msg/Time"} + (project / "interfaces/builtin_interfaces/msg/Time.msg").unlink() + with pytest.raises(ValueError, match="unresolved message dependency"): + prepare(project) diff --git a/dimos/message_codegen/test_builtin_codec.py b/dimos/message_codegen/test_builtin_codec.py new file mode 100644 index 00000000000..c1101b71ee5 --- /dev/null +++ b/dimos/message_codegen/test_builtin_codec.py @@ -0,0 +1,119 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Installed native value/catalog acceptance, without a generated demo extension.""" + +import gc +import pickle + +from dimos_cdrgen.registry import decode, encode, initialize +from dimos_generated.builtin_interfaces.msg import Time +from dimos_generated.sensor_msgs.msg import Image +from dimos_generated.std_msgs.msg import Header +from dimos_generated_schemas.provider import message_types +import numpy as np +import pytest + +STORE = initialize() +CLASSES = message_types() + + +def field_value(field): + kind, spec = field + if kind.name == "NAME": + return value_for(spec) + if kind.name == "BASE": + name, _ = spec + if name == "string": + return "map" + if name == "bool": + return True + return 1.25 if name.startswith("float") else 1 + item, count = spec + values = [field_value(item) for _ in range(count if kind.name == "ARRAY" else 1)] + if item[0].name == "BASE" and item[1][0] != "string": + dtype = {"byte": "uint8", "char": "uint8"}.get(item[1][0], item[1][0]) + return np.array(values, dtype=dtype) + return values + + +def value_for(name): + fields = STORE.fielddefs[name][1] + return ( + CLASSES[name](**{key: field_value(field) for key, field in fields}) + if fields + else CLASSES[name](0) + ) + + +@pytest.mark.parametrize("little_endian", [False, True]) +@pytest.mark.parametrize( + "name", + [ + pytest.param( + name, + marks=pytest.mark.xfail( + strict=True, + raises=NotImplementedError, + reason="Published CDR generator rejects unsupported bounded-string semantics", + ), + ) + if name == "shape_msgs/msg/SolidPrimitive" + else name + for name in sorted(CLASSES) + ], +) +def test_catalog_native_values_roundtrip_in_both_byte_orders(name, little_endian): + value = value_for(name) + wire = encode(value, little_endian=little_endian) + restored = decode(wire, CLASSES[name]) + assert type(restored) is CLASSES[name] + assert encode(restored, little_endian=little_endian) == wire + + +def test_large_image_preserves_header_type_data_and_worker_pickle(): + image = Image( + header=Header(stamp=Time(sec=17, nanosec=123), frame_id="camera"), + height=480, + width=640, + encoding="rgb8", + is_bigendian=0, + step=1920, + data=np.arange(921600, dtype=np.uint8), + ) + restored = decode(encode(image), Image) + assert type(restored.header) is Header + assert restored.header == image.header + np.testing.assert_array_equal(restored.data, image.data) + assert encode(pickle.loads(pickle.dumps(image))) == encode(image) + + +def test_native_array_copy_is_independent_and_view_survives_message_release(): + image = Image( + header=Header(stamp=Time(sec=0, nanosec=0), frame_id=""), + height=1, + width=3, + encoding="mono8", + is_bigendian=0, + step=3, + data=np.array([1, 2, 3], dtype=np.uint8), + ) + view = image.data.view() + copied = image.data.copy() + copied[0] = 9 + np.testing.assert_array_equal(image.data, [1, 2, 3]) + assert not np.shares_memory(view, copied) + del image + gc.collect() + np.testing.assert_array_equal(view, [1, 2, 3]) diff --git a/dimos/message_codegen/test_builtin_install.py b/dimos/message_codegen/test_builtin_install.py new file mode 100644 index 00000000000..20ca8b1adce --- /dev/null +++ b/dimos/message_codegen/test_builtin_install.py @@ -0,0 +1,143 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Cold offline source, wheel, sdist and editable installs need no native tools.""" + +import json +import os +from pathlib import Path +import shutil +import subprocess +import sys +import tarfile + +import pytest + +CHECK = """ +import pickle +from dimos_generated.builtin_interfaces.msg import Time +from dimos_generated.std_msgs.msg import Header +from dimos_generated.geometry_msgs.msg import Point, Pose, PoseStamped, Quaternion +from dimos_cdrgen.registry import encode, decode, schema +from dimos_generated_schemas.provider import message_types, package_root +from pathlib import Path +h = Header(Time(17, 23), 'map') +m = PoseStamped(h, Pose(Point(1., 2., 3.), Quaternion(0., 0., 0., 1.))) +r = decode(encode(m), PoseStamped) +assert type(r.header) is Header and r == m +assert type(pickle.loads(pickle.dumps(m)).header) is Header +assert 'MSG: std_msgs/Header' in schema(m.__msgtype__) +assert len(message_types()) == 73 +assert 'visualization_msgs/msg/Marker' not in message_types() +root = Path(package_root()) +assert (root / 'schema-sources.json').is_file() +assert (root / 'rust/Cargo.toml').is_file() +assert (root / 'cpp/CMakeLists.txt').is_file() +""" + + +def test_cold_offline_source_sdist_wheel_and_editable(tmp_path): + dependency_wheels = os.environ.get("DIMOS_MESSAGE_WHEELHOUSE") + if not dependency_wheels: + if os.environ.get("DIMOS_MESSAGE_INSTALL_REQUIRED") == "1": + pytest.fail("DIMOS_MESSAGE_WHEELHOUSE must contain the offline build dependencies") + pytest.skip("Prepare an offline message dependency wheelhouse for installation acceptance") + root = Path(__file__).resolve().parents[2] + wheels = tmp_path / "wheels" + shutil.copytree(dependency_wheels, wheels) + environment = {key: value for key, value in os.environ.items() if key != "PYTHONPATH"} + environment.update( + PIP_NO_INDEX="1", PIP_FIND_LINKS=str(wheels), PIP_DISABLE_PIP_VERSION_CHECK="1" + ) + + def run(command, cwd=tmp_path): + result = subprocess.run(command, cwd=cwd, env=environment, capture_output=True, text=True) + assert result.returncode == 0, result.stdout + result.stderr + + checkout = tmp_path / "checkout" + project = checkout / "packages/dimos-generated" + shutil.copytree( + root / "packages/dimos-generated", + project, + ignore=shutil.ignore_patterns("build", "dist", "*.egg-info", "canonical", "__pycache__"), + ) + blocked = tmp_path / "blocked" + blocked.mkdir() + for tool in ["cc", "c++", "gcc", "g++", "cmake", "cargo", "rustc", "rustup"]: + path = blocked / tool + path.write_text("#!/bin/sh\necho 'unexpected native tool' >&2\nexit 97\n") + path.chmod(0o755) + environment.update( + PATH=str(blocked) + os.pathsep + environment["PATH"], + CC=str(blocked / "cc"), + CXX=str(blocked / "c++"), + ) + venv = tmp_path / "venv" + run([sys.executable, "-m", "venv", str(venv)]) + python = str(venv / "bin/python") + run([python, "-m", "pip", "install", str(project)]) + run([python, "-I", "-c", CHECK]) + run([python, "setup.py", "sdist", "--dist-dir", str(tmp_path / "sdists")], cwd=project) + archive = next((tmp_path / "sdists").glob("*.tar.gz")) + with tarfile.open(archive) as bundle: + names = bundle.getnames() + assert any(name.endswith("catalog.json") for name in names) + assert not any("/build/" in name or "/src/" in name for name in names) + run([python, "-m", "pip", "install", "--force-reinstall", str(archive)]) + run([python, "-I", "-c", CHECK]) + run( + [ + python, + "-m", + "pip", + "wheel", + "--no-deps", + "--wheel-dir", + str(tmp_path / "output"), + str(archive), + ] + ) + wheel = next((tmp_path / "output").glob("dimos_generated-*.whl")) + run([python, "-m", "pip", "install", "--force-reinstall", str(wheel)]) + run([python, "-I", "-c", CHECK]) + run([python, "-m", "pip", "install", "-e", str(project)]) + run([python, "-I", "-c", CHECK]) + stats = project / "interfaces/dimos_msgs/msg/VideoStats.msg" + stats.write_text(stats.read_text().replace("float64 e2e_latency_ms", "float32 e2e_latency_ms")) + run([python, "-m", "pip", "install", "-e", str(project)]) + run( + [ + python, + "-I", + "-c", + CHECK + "\nassert 'float32 e2e_latency_ms' in schema('dimos_msgs/msg/VideoStats')\n", + ] + ) + + stats = project / "interfaces/dimos_msgs/msg/VideoStats.msg" + stats.rename(stats.with_name("RenamedStats.msg")) + catalog = project / "catalog.json" + data = json.loads(catalog.read_text()) + data["roots"]["dimos_msgs/msg/RenamedStats"] = data["roots"].pop("dimos_msgs/msg/VideoStats") + catalog.write_text(json.dumps(data)) + run([python, "-m", "pip", "install", "-e", str(project)]) + run( + [ + python, + "-I", + "-c", + CHECK + + "\nfrom dimos_generated.dimos_msgs import msg\nassert hasattr(msg, 'RenamedStats') and not hasattr(msg, 'VideoStats')\n", + ] + ) diff --git a/dimos/message_codegen/test_builtin_preparation.py b/dimos/message_codegen/test_builtin_preparation.py new file mode 100644 index 00000000000..3cc53553c76 --- /dev/null +++ b/dimos/message_codegen/test_builtin_preparation.py @@ -0,0 +1,60 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Product preparation uses pinned caches, never a source-build network hook.""" + +import json +import os +from pathlib import Path +import shutil + +from dimos_cdrgen.source_package import configuration, prepare as generate +import pytest + +from scripts.prepare_builtin_sources import prepare + + +def test_unprepared_product_fails_and_cached_preparation_is_complete(tmp_path, monkeypatch): + available = os.environ.get("DIMOS_BUILTIN_SOURCE_CACHE") + if not available: + if os.environ.get("DIMOS_MESSAGE_INSTALL_REQUIRED") == "1": + pytest.fail("Explicit schema preparation cache is required") + pytest.skip("Prepare the pinned builtin source cache for offline acceptance") + project = tmp_path / "product" + source = Path(__file__).resolve().parents[2] / "packages/dimos-generated" + shutil.copytree( + source, + project, + ignore=shutil.ignore_patterns("interfaces", "build", "dist", "*.egg-info", "__pycache__"), + ) + with pytest.raises(ValueError, match="not prepared"): + configuration(project) + cache = tmp_path / "cache" + shutil.copytree(Path(available) / "archives", cache / "archives") + + def no_network(*args, **kwargs): + raise AssertionError("Offline builtin preparation attempted a download") + + monkeypatch.setattr("dimos_cdrgen.source_inputs.requests.get", no_network) + inputs = prepare(cache, offline=True, project=project) + assert len(list(inputs.rglob("*.msg"))) == 73 + output = generate(project) + resources = output / "dimos_generated_schemas/package" + manifest = json.loads((resources / "message-package.json").read_text()) + assert len(manifest["owned"]) == 73 + assert len(list(project.glob("custom/dimos_msgs/msg/*.msg"))) == 14 + lock = json.loads((project / "schema-sources.json").read_text()) + assert all(len(item["sha256"]) == 64 for item in lock["sources"]) + assert (resources / "dimos_msgs-LICENSE").is_file() + assert all((resources / path.name).is_file() for path in (inputs / "licenses").iterdir()) diff --git a/dimos/message_codegen/test_integration.py b/dimos/message_codegen/test_integration.py new file mode 100644 index 00000000000..b0b14deea3c --- /dev/null +++ b/dimos/message_codegen/test_integration.py @@ -0,0 +1,163 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Verify the DimOS adapter and one installed consumer of published cdrgen.""" + +import json +import os +from pathlib import Path +import subprocess +import sys +from types import SimpleNamespace + +from dimos_cdrgen.generate import generate +from dimos_cdrgen.native_build import prepare_cpp +import pytest + +from dimos.message_codegen import native_build + + +def run(*command: str, cwd: Path) -> None: + subprocess.run(command, cwd=cwd, check=True, capture_output=True, text=True) + + +@pytest.mark.parametrize("layout", ["installed", "checkout", "absent"]) +def test_sdk_discovery(tmp_path: Path, monkeypatch: pytest.MonkeyPatch, layout: str) -> None: + prefix = tmp_path / "prefix" + prefix.mkdir() + (prefix / "native-prefixes.json").write_text(json.dumps([str(prefix)])) + (prefix / "native-target.json").write_text('{"values": {}, "toolchain_sha256": null}') + package = tmp_path / "dimos" + sdk = package / "_native/cpp" if layout == "installed" else tmp_path / "native/cpp" + if layout != "absent": + sdk.mkdir(parents=True) + (sdk / "dimos_nativeConfig.cmake").write_text("") + monkeypatch.setattr( + native_build, + "find_spec", + lambda _: SimpleNamespace(submodule_search_locations=[str(package)]), + ) + toolchain = native_build.write_cmake_toolchain(prefix, tmp_path / "toolchain.cmake") + text = toolchain.read_text() + assert str(prefix) in text + sdk_lines = [ + line for line in text.splitlines() if line.startswith("list(APPEND CMAKE_PREFIX_PATH") + ] + assert sdk_lines == ([] if layout == "absent" else [f'list(APPEND CMAKE_PREFIX_PATH "{sdk}")']) + + +def test_installed_message_consumer(tmp_path: Path) -> None: + project = tmp_path / "consumer" + source = project / "interfaces/consumer_msgs/msg/Tick.msg" + source.parent.mkdir(parents=True) + source.write_text("int32 value\n") + (project / "pyproject.toml").write_text("""[build-system] +requires = ["setuptools>=77", "wheel", "dimos-cdrgen==0.1.0"] +build-backend = "setuptools.build_meta" +[project] +name = "dimos-cdr-consumer" +version = "0.1.0" +dependencies = ["dimos-cdrgen==0.1.0"] +[tool.dimos.messages] +source = "interfaces" +""") + (project / "setup.py").write_text( + "from pathlib import Path\nfrom setuptools import setup\n" + "from dimos_cdrgen.source_package import setup_arguments\n" + "setup(**setup_arguments(Path(__file__).resolve().parent))\n" + ) + run(sys.executable, "-m", "build", "--no-isolation", cwd=project) + wheel = next((project / "dist").glob("*.whl")) + installed = tmp_path / "installed" + run( + sys.executable, + "-m", + "pip", + "install", + "--no-deps", + "--target", + str(installed), + str(wheel), + cwd=tmp_path, + ) + run( + sys.executable, + "-I", + "-c", + f"""import sys +sys.path.insert(0, {str(installed)!r}) +import pickle +from dimos_cdr_consumer.consumer_msgs.msg import Tick +from dimos_cdrgen.registry import decode, encode +value = Tick(value=17) +assert encode(value) == bytes.fromhex("0001000011000000") +assert type(decode(encode(value), Tick)) is Tick +assert type(pickle.loads(pickle.dumps(value))) is Tick +assert decode(encode(value), Tick).value == 17 +""", + cwd=tmp_path, + ) + + +@pytest.mark.native_e2e +def test_cpp_consumer_uses_dimos_header(tmp_path: Path) -> None: + source = tmp_path / "interfaces/consumer_msgs/msg/Tick.msg" + source.parent.mkdir(parents=True) + source.write_text("int32 value\n") + generated = tmp_path / "generated" + generate( + [source.parents[2]], generated, ["consumer_msgs/msg/Tick"], "dimos_consumer", shared=True + ) + sources = { + name: Path(path) + for name, path in json.loads(os.environ.get("DIMOS_NATIVE_SOURCE_DIRS", "{}")).items() + } + prefix = prepare_cpp( + generated, + cache=Path(os.environ["DIMOS_NATIVE_TEST_CACHE"]) + if "DIMOS_NATIVE_TEST_CACHE" in os.environ + else tmp_path / "native-cache", + offline=os.environ.get("DIMOS_OFFLINE") == "1", + source_dirs=sources or None, + ) + toolchain = native_build.write_cmake_toolchain(prefix, tmp_path / "toolchain.cmake") + include = Path(__file__).resolve().parents[2] / "native/cpp/include" + (tmp_path / "CMakeLists.txt").write_text(f'''cmake_minimum_required(VERSION 3.20) +project(dimos_cdr_consumer LANGUAGES CXX) +find_package(dimos_consumer CONFIG REQUIRED) +add_executable(consumer main.cpp) +target_compile_features(consumer PRIVATE cxx_std_17) +target_include_directories(consumer PRIVATE "{include}") +target_link_libraries(consumer PRIVATE dimos_consumer::messages) +''') + (tmp_path / "main.cpp").write_text("""#include +#include +#include +int main() { + const std::vector expected{0, 1, 0, 0, 17, 0, 0, 0}; + auto value = dimos::native::cdr_decode(expected); + return value.value == 17 && dimos::native::cdr_encode(value) == expected ? 0 : 1; +} +""") + run( + "cmake", + "-S", + str(tmp_path), + "-B", + str(tmp_path / "build"), + f"-DCMAKE_TOOLCHAIN_FILE={toolchain}", + cwd=tmp_path, + ) + run("cmake", "--build", str(tmp_path / "build"), "--parallel", "2", cwd=tmp_path) + run(str(tmp_path / "build/consumer"), cwd=tmp_path) diff --git a/dimos/protocol/cdr_mcap.py b/dimos/protocol/cdr_mcap.py new file mode 100644 index 00000000000..5719ceaff0e --- /dev/null +++ b/dimos/protocol/cdr_mcap.py @@ -0,0 +1,111 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Self-describing CDR recording, independent of transport and generated classes.""" + +from __future__ import annotations + +from pathlib import Path +from types import TracebackType + +from mcap.writer import CompressionType, Writer +from typing_extensions import Self + + +class CdrMcapWriter: + """Write raw generated CDR with embedded ROS2 definitions and chunk compression. + + Callers supply source and reception timestamps explicitly. No message package + is imported, so a recorder can accept schemas from external stream providers. + """ + + def __init__(self, path: str | Path) -> None: + self._stream = Path(path).open("wb") + try: + self._writer = Writer(self._stream, compression=CompressionType.ZSTD) + self._writer.start(profile="ros2", library="dimos") + except BaseException: + self._stream.close() + raise + self._schemas: dict[tuple[str, str], int] = {} + self._channels: dict[tuple[str, int], int] = {} + self._closed = False + + def write( + self, + topic: str, + payload: bytes, + *, + schema_name: str, + schema: str, + log_time_ns: int, + publish_time_ns: int | None = None, + sequence: int = 0, + ) -> None: + if self._closed: + raise ValueError("MCAP writer is closed") + channel_id = self.register_stream(topic, schema_name=schema_name, schema=schema) + self._writer.add_message( + channel_id=channel_id, + data=payload, + log_time=log_time_ns, + publish_time=log_time_ns if publish_time_ns is None else publish_time_ns, + sequence=sequence, + ) + + def register_stream( + self, + topic: str, + *, + schema_name: str, + schema: str, + metadata: dict[str, str] | None = None, + ) -> int: + """Declare a CDR stream even when it has no messages.""" + if self._closed: + raise ValueError("MCAP writer is closed") + schema_key = (schema_name, schema) + if schema_key not in self._schemas: + self._schemas[schema_key] = self._writer.register_schema( + name=schema_name, encoding="ros2msg", data=schema.encode("utf-8") + ) + schema_id = self._schemas[schema_key] + channel_key = (topic, schema_id) + if channel_key not in self._channels: + self._channels[channel_key] = self._writer.register_channel( + topic=topic, + message_encoding="cdr", + schema_id=schema_id, + metadata={"offered_qos_profiles": "[]", **(metadata or {})}, + ) + return self._channels[channel_key] + + def close(self) -> None: + if not self._closed: + self._closed = True + try: + self._writer.finish() # type: ignore[no-untyped-call] # mcap lacks an annotation. + finally: + self._stream.close() + + def __enter__(self) -> Self: + return self + + def __exit__( + self, + exc_type: type[BaseException] | None, + exc: BaseException | None, + traceback: TracebackType | None, + ) -> None: + self.close() diff --git a/dimos/protocol/test_cdr_mcap.py b/dimos/protocol/test_cdr_mcap.py new file mode 100644 index 00000000000..0f5607ecdbc --- /dev/null +++ b/dimos/protocol/test_cdr_mcap.py @@ -0,0 +1,126 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys + +from dimos_cdrgen.definitions import Definitions +from mcap.reader import make_reader +from mcap.records import Chunk +from mcap.stream_reader import StreamReader +import pytest +from rosbags.typesys import Stores, get_types_from_msg, get_typestore + +from dimos.protocol.cdr_mcap import CdrMcapWriter + + +@pytest.fixture(autouse=True) +def restore_reference_types_module(): + # Independent oracle stores own a process-global module. Restore it so they + # do not invalidate the canonical registry's native class pickle identities. + previous = sys.modules.get("rosbags.usertypes") + try: + yield + finally: + if previous is None: + sys.modules.pop("rosbags.usertypes", None) + else: + sys.modules["rosbags.usertypes"] = previous + + +@pytest.fixture +def point_message(): + name = "geometry_msgs/msg/Point" + schema = Definitions([], installed=True).schema(name) + reference = get_typestore(Stores.ROS2_JAZZY) + value = reference.types[name](x=1.25, y=-2.5, z=3.0) + return name, schema, bytes(reference.serialize_cdr(value, name)) + + +def test_embeds_schemas_and_preserves_cdr_timestamps_and_sequence(tmp_path, point_message): + name, schema, payload = point_message + path = tmp_path / "capture.mcap" + with CdrMcapWriter(path) as writer: + for topic, timestamp in (("/first", 100), ("/second", 200)): + writer.write( + topic, + payload, + schema_name=name, + schema=schema, + log_time_ns=timestamp, + publish_time_ns=0, + sequence=7, + ) + with path.open("rb") as stream: + reader = make_reader(stream, validate_crcs=True) + assert reader.get_header().profile == "ros2" + summary = reader.get_summary() + assert len(summary.schemas) == 1 + assert len(summary.channels) == 2 + messages = list(reader.iter_messages()) + assert [message.log_time for _, _, message in messages] == [100, 200] + reference = get_typestore(Stores.EMPTY) + for stored_schema, channel, message in messages: + assert stored_schema.encoding == "ros2msg" + assert stored_schema.name == name + assert stored_schema.data.decode() == schema + assert channel.message_encoding == "cdr" + assert channel.metadata["offered_qos_profiles"] == "[]" + assert message.data == payload + assert message.publish_time == 0 + assert message.sequence == 7 + reference.register(get_types_from_msg(stored_schema.data.decode(), stored_schema.name)) + decoded = reference.deserialize_cdr(message.data, name) + assert (decoded.x, decoded.y, decoded.z) == (1.25, -2.5, 3.0) + + +def test_unstamped_messages_use_reception_time_and_chunks_are_compressed(tmp_path, point_message): + name, schema, payload = point_message + path = tmp_path / "capture.mcap" + with CdrMcapWriter(path) as writer: + writer.write("/point", payload, schema_name=name, schema=schema, log_time_ns=123) + with path.open("rb") as stream: + messages = list(make_reader(stream).iter_messages()) + assert messages[0][2].publish_time == 123 + with path.open("rb") as stream: + chunks = [ + record + for record in StreamReader(stream, emit_chunks=True).records + if isinstance(record, Chunk) + ] + assert chunks + assert all(chunk.compression == "zstd" for chunk in chunks) + + +def test_context_finalizes_recording_when_producer_raises(tmp_path, point_message): + name, schema, payload = point_message + path = tmp_path / "capture.mcap" + with pytest.raises(RuntimeError, match="producer"), CdrMcapWriter(path) as writer: + writer.write("/point", payload, schema_name=name, schema=schema, log_time_ns=123) + raise RuntimeError("producer failed") + with path.open("rb") as stream: + assert make_reader(stream).get_summary().statistics.message_count == 1 + with pytest.raises(ValueError, match="closed"): + writer.write("/point", payload, schema_name=name, schema=schema, log_time_ns=124) + + +def test_nested_schema_uses_resolvable_resource_names(): + schema = Definitions([], installed=True).schema("sensor_msgs/msg/Image") + + assert "MSG: std_msgs/Header\n" in schema + assert "MSG: builtin_interfaces/Time\n" in schema + assert set(get_types_from_msg(schema, "sensor_msgs/msg/Image")) == { + "sensor_msgs/msg/Image", + "std_msgs/msg/Header", + "builtin_interfaces/msg/Time", + } diff --git a/dimos/simulation/habitat/nix/flake.lock b/dimos/simulation/habitat/nix/flake.lock index c13ac1a8111..b85bc9a050a 100644 --- a/dimos/simulation/habitat/nix/flake.lock +++ b/dimos/simulation/habitat/nix/flake.lock @@ -11,11 +11,11 @@ }, "locked": { "dir": "native/cpp", - "lastModified": 1791386052, - "narHash": "sha256-MeVxI5e13wh7jQ0g2tnaLpiyDaQQMfqEAC7qrXopHY4=", + "lastModified": 1792431336, + "narHash": "sha256-W0biIt+6oH7bBHt44kV4J411Y3AUsuMkQ7OsS45BxDE=", "owner": "dimensionalOS", "repo": "dimos", - "rev": "87c0c26b40e8a5aeb9d9d346104b49d5fb02696a", + "rev": "fbccb5c45eb84a7f65413a37cba7afe3fe2d8008", "type": "github" }, "original": { diff --git a/docs/development/message-alignment.md b/docs/development/message-alignment.md new file mode 100644 index 00000000000..442582ddad1 --- /dev/null +++ b/docs/development/message-alignment.md @@ -0,0 +1,33 @@ +# Verify prepared built-in inputs and artifacts + +PR1 owns the generic source-package hooks, dependency ownership and pinned source +preparation. PR2 owns `packages/dimos-generated/custom`, `catalog.json`, +`schema-sources.json`, package metadata and thin preparation/release entrypoints. +There is no committed generated snapshot or bulk upstream catalog. + +```sh skip +python scripts/prepare_message_parser.py +python -m scripts.prepare_builtin_sources +python -m scripts.generate_builtin_messages +python -m scripts.generate_builtin_messages --check +``` + +Source preparation checks archive and selected-file hashes. Use `--offline` with +cached archives. It is an explicit developer/release step, never a pip hook. +Only the selected message closure plus licenses is materialized into ignored +`packages/dimos-generated/interfaces`. The release sdist includes those inputs. + +The artifact check regenerates into temporary storage and compares file names and +bytes with `packages/dimos-generated/build/message-source/python`. It does not +repair changed, missing or stale artifacts. CI prepares inputs first, then runs +both regeneration and mutation checks. Python dependencies and native tools are +prepared separately; these checks do not install system tools or change hosts. + +Regression tests cover fields, schemas, package version, explicit root addition, +deletion/rename, extra files and missing Python/C++/Rust/schema outputs. Cold offline +source/wheel/sdist/editable tests block native tools and verify type identity, +complete dependency schemas, field edits and renames. Codec assertions and precise +strict expected failures remain separate from artifact alignment. + +The checks retain read-only repository permissions. They do not commit outputs, +query CI status or prove complete native/runtime/hardware acceptance. diff --git a/docs/development/message-source-packages.md b/docs/development/message-source-packages.md new file mode 100644 index 00000000000..7b26bd085fd --- /dev/null +++ b/docs/development/message-source-packages.md @@ -0,0 +1,47 @@ +# CDR generation in DimOS + +DimOS uses the published `dimos-cdrgen==0.1.0` package directly. Its parser, +generators, ownership checks, codecs and native build recipes live in the +[independent library](https://github.com/TomCC7/dimos-cdrgen). +See its [Python, C++ and Rust guides](https://tomcc7.github.io/dimos-cdrgen/) +for message package configuration and supported schema features. + +Install `dimos-cdrgen==0.1.0` in both the build and runtime dependencies of +message packages. Import its APIs directly: + +```python +from dimos_cdrgen.registry import decode, encode +from dimos_cdrgen.source_package import setup_arguments +``` + +There is no DimOS compatibility distribution. Existing consumers of +`dimos_message_build` or generic `dimos.message_codegen` APIs must change their +imports and dependency declarations to `dimos_cdrgen` and `dimos-cdrgen`. + +DimOS retains two adapters: + +- `dimos.message_codegen.native_build.write_cmake_toolchain` adds SDK discovery + for installed `dimos/_native/cpp` and source-checkout `native/cpp` layouts. + Import other build functions directly from `dimos_cdrgen.native_build`. +- `dimos/native/cdr_codec.hpp` exposes the library codec under `dimos::native` + for DimOS C++ consumers. + +This first stack layer does not switch runtime transports or supply built-in +message catalogs. Those remain separate PRs. + +## Verify the integration + +Use a Python environment with the published generator and test tools: + +```sh +uv pip install 'dimos-cdrgen[native]==0.1.0' numpy build pytest pytest-asyncio pytest-env +python -m pytest --noconftest -o addopts='' -q dimos/message_codegen/test_integration.py +``` + +The tests check SDK discovery, an installed message wheel built from a source +distribution, Python type identity and the DimOS C++ header against literal CDR +bytes. Native verification needs CMake and a C++17 compiler. It prepares pinned +native dependencies in a temporary cache; use `DIMOS_NATIVE_TEST_CACHE` to reuse +a writable cache, or `DIMOS_NATIVE_SOURCE_DIRS` with `DIMOS_OFFLINE=1` for +pre-fetched source directories. Generic generator regression tests stay in the +library repository. diff --git a/docs/web/development.md b/docs/web/development.md index f09ef74aea7..e83cdcf3585 100644 --- a/docs/web/development.md +++ b/docs/web/development.md @@ -56,7 +56,7 @@ After changing cockpit or SDK dependencies, run `deno install` in `web/` and com Without vite, `--local-relay` serves the built `cockpit/dist` at `/` and `sdk/dist/sdk.js` at `/sdk.js`. In a checkout, `ensure_web_dist` in [`relay_process.py`](/dimos/web/relay_bridge/relay_process.py#L76) builds both first when either is missing or older than the sources. It stamps the shared, SDK and cockpit sources, the workspace config and the lockfile, builds under a cross-process lock into temporary directories, and swaps both products in together. -Release wheels ship both bundles prebuilt inside `dimos/web/relay_bridge/_relay_dist` (built by the release workflow, see [`setup.py`](/setup.py#L116)), so a pip-installed dimos never builds or downloads npm packages. +Release wheels ship both bundles prebuilt inside `dimos/web/relay_bridge/_relay_dist` (built by the release workflow, see [root packaging script](/setup.py#L116)), so a pip-installed dimos never builds or downloads npm packages. Two overrides: `--no-web-build` skips the staleness check and the build, and `DIMOS_WEB_DIR` points the bridge at another web tree. diff --git a/examples/message-codegen/check_rerun_mcap.py b/examples/message-codegen/check_rerun_mcap.py new file mode 100644 index 00000000000..6ca53404360 --- /dev/null +++ b/examples/message-codegen/check_rerun_mcap.py @@ -0,0 +1,52 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Check native Rerun's semantic and reflection imports, without message packages.""" + +from collections import Counter +from pathlib import Path +import re +import sys + + +def main() -> None: + evidence = Path(sys.argv[1]) + summary = (evidence / "rerun-summary.txt").read_text() + expected = { + "/camera/image": "Image:buffer", + "/camera/compressed": "EncodedImage:blob", + "/robot/pose": "InstancePoses3D:translations", + "/tf": "Transform3D:translation", + "/telemetry": "story_msgs.msg.DeviceReading:message", + } + counts: Counter[str] = Counter() + for line in summary.splitlines(): + match = re.search(r"with (\d+) rows .* - (/[\w/]+) - data columns: (.*)", line) + if match: + rows, topic, columns = match.groups() + assert topic in expected, topic + assert expected[topic] in columns, (topic, columns) + counts[topic] += int(rows) + assert counts == dict.fromkeys(expected, 30), counts + telemetry = (evidence / "rerun-telemetry.txt").read_text() + # This must be an Arrow struct with nested fields, not an opaque byte blob. + for field in ('"value": Float64', '"sequence": UInt32', '"header": Struct'): + assert field in telemetry, field + for topic, count in counts.items(): + print(f"Rerun imported {count} {topic} rows as {expected[topic]}.") + print("Custom telemetry is a structured Arrow value with nested fields.") + + +if __name__ == "__main__": + main() diff --git a/examples/message-codegen/demo_mcap.py b/examples/message-codegen/demo_mcap.py new file mode 100644 index 00000000000..8bf70985c32 --- /dev/null +++ b/examples/message-codegen/demo_mcap.py @@ -0,0 +1,141 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Record synthetic images, poses, transforms, and custom fields for both viewers.""" + +import argparse +from io import BytesIO +import math +from pathlib import Path + +from dimos_cdrgen.registry import encode, schema +from dimos_generated.builtin_interfaces.msg import Time +from dimos_generated.geometry_msgs.msg import ( + Point, + Pose, + PoseStamped, + Quaternion, + Transform, + TransformStamped, + Vector3, +) +from dimos_generated.sensor_msgs.msg import CompressedImage, Image +from dimos_generated.std_msgs.msg import Header +from dimos_generated.tf2_msgs.msg import TFMessage +import numpy as np +from PIL import Image as PillowImage +from story_messages.story_msgs.msg import DeviceReading + +from dimos.protocol.cdr_mcap import CdrMcapWriter + +START_NS = 1_700_000_000_000_000_000 + + +def write_demo(path: Path, frames: int = 30) -> None: + path.parent.mkdir(parents=True, exist_ok=True) + with CdrMcapWriter(path) as writer: + for index in range(frames): + stamp_ns = START_NS + index * 100_000_000 + rows, columns = np.indices((192, 256), dtype=np.uint16) + pixels = np.stack( + ( + (columns + index * 8) % 256, + (rows + index * 5) % 256, + np.full_like(rows, (index * 17) % 256), + ), + axis=-1, + ).astype(np.uint8) + image = Image( + height=192, + width=256, + step=256 * 3, + encoding="rgb8", + data=np.asarray(pixels.reshape(-1), dtype=np.uint8), + header=Header(stamp=Time(sec=0, nanosec=0), frame_id=""), + is_bigendian=0, + ) + pose = PoseStamped( + header=Header(stamp=Time(sec=0, nanosec=0), frame_id=""), + pose=Pose( + position=Point(x=0.0, y=0.0, z=0.0), + orientation=Quaternion(x=0.0, y=0.0, z=0.0, w=1.0), + ), + ) + pose.pose.position.x = math.cos(index / 5) + pose.pose.position.y = math.sin(index / 5) + pose.pose.orientation.w = 1.0 + pose.header.frame_id = "map" + image.header.frame_id = "camera" + for value in (image, pose): + value.header.stamp.sec, value.header.stamp.nanosec = divmod(stamp_ns, 1_000_000_000) + compressed_bytes = BytesIO() + PillowImage.fromarray(pixels).save(compressed_bytes, format="PNG") + compressed = CompressedImage( + header=image.header, + format="png", + data=np.frombuffer(compressed_bytes.getvalue(), dtype=np.uint8), + ) + telemetry = DeviceReading( + header=pose.header, + sequence=index, + label="synthetic", + value=20.0 + index / 10, + ) + transform = TransformStamped( + header=pose.header, + child_frame_id="camera", + transform=Transform( + translation=Vector3(x=0.0, y=0.0, z=0.0), + rotation=Quaternion(x=0.0, y=0.0, z=0.0, w=1.0), + ), + ) + transform.transform.translation.x = pose.pose.position.x + transform.transform.translation.y = pose.pose.position.y + transform.transform.rotation.w = 1.0 + transforms = TFMessage(transforms=[transform]) + for topic, value in ( + ("/camera/image", image), + ("/camera/compressed", compressed), + ("/robot/pose", pose), + ("/telemetry", telemetry), + ("/tf", transforms), + ): + writer.write( + topic, + encode(value), + schema_name=value.__msgtype__, + schema=schema(value.__msgtype__), + log_time_ns=stamp_ns + 1_000_000, + publish_time_ns=stamp_ns, + sequence=index, + ) + print(f"Wrote {frames * 5} messages to {path} ({path.stat().st_size:,} bytes)") + print("Five CDR channels; ROS2 schemas and all dependencies are embedded.") + print( + "Image: 256x192 RGB gradient; pose: circular path; telemetry: sequence 0..29 and value 20.0..22.9." + ) + print("Open this same file in Foxglove and Rerun without installing story_messages.") + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + "--output", type=Path, default=Path("build/message-codegen/viewers/demo.mcap") + ) + args = parser.parse_args() + write_demo(args.output) + + +if __name__ == "__main__": + main() diff --git a/examples/message-codegen/external-app/CMakeLists.txt b/examples/message-codegen/external-app/CMakeLists.txt new file mode 100644 index 00000000000..d5c0813fe28 --- /dev/null +++ b/examples/message-codegen/external-app/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.20) +project(external_message_demo LANGUAGES CXX) +find_package(external_telemetry CONFIG REQUIRED) +find_package(dimos_generated CONFIG REQUIRED) +add_executable(relay relay.cpp) +target_link_libraries(relay PRIVATE external_telemetry::messages dimos_generated::messages) diff --git a/examples/message-codegen/external-app/demo_installed.py b/examples/message-codegen/external-app/demo_installed.py new file mode 100644 index 00000000000..cd0e9d5f069 --- /dev/null +++ b/examples/message-codegen/external-app/demo_installed.py @@ -0,0 +1,55 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Run from a fresh environment containing only the external message wheel.""" + +import argparse +from importlib.metadata import entry_points +from pathlib import Path +import subprocess + +from external_telemetry.demo_msgs.msg import Telemetry + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--build", type=Path, required=True) + args = parser.parse_args() + build = args.build.resolve() + provider = next( + entry.load() + for entry in entry_points(group="dimos.messages") + if entry.name == "external_telemetry" + ) + assert provider.message_types()[Telemetry.msg_name] is Telemetry + assert (provider.schema_root() / "demo_msgs/msg/Telemetry.msg").is_file() + value = Telemetry(application_note="added-locally") + print(f"Installed Python package sends new field: {value.application_note}", flush=True) + first, second, third = [build / name for name in ("python.cdr", "cpp.cdr", "rust.cdr")] + first.write_bytes(value.encode()) + subprocess.run([str(build / "cpp-consumer/relay"), str(first), str(second)], check=True) + subprocess.run( + [str(build / "rust-consumer/target/debug/external-consumer"), str(second), str(third)], + check=True, + ) + decoded = Telemetry.decode(third.read_bytes()) + assert decoded.application_note == "added-locally/cpp/rust" + print(f"Installed Python package receives: {decoded.application_note}") + print( + "A locally added field crossed three installed native packages; no DimOS source change or upstream PR." + ) + + +if __name__ == "__main__": + main() diff --git a/examples/message-codegen/external-app/relay.cpp b/examples/message-codegen/external-app/relay.cpp new file mode 100644 index 00000000000..9eced06291f --- /dev/null +++ b/examples/message-codegen/external-app/relay.cpp @@ -0,0 +1,18 @@ +#include +#include +#include +#include +#include + +int main(int argc, char** argv) { + if (argc != 3) return 2; + std::ifstream input(argv[1], std::ios::binary); + std::vector bytes{std::istreambuf_iterator(input), {}}; + auto value = dimos::cdr::decode(bytes); + std::cout << "Installed C++ package received: " << value.application_note << '\n'; + value.application_note += "/cpp"; + auto encoded = dimos::cdr::encode(value); + std::ofstream output(argv[2], std::ios::binary); + output.write(reinterpret_cast(encoded.data()), encoded.size()); + return output ? 0 : 1; +} diff --git a/examples/message-codegen/external-app/relay.rs b/examples/message-codegen/external-app/relay.rs new file mode 100644 index 00000000000..3b41d4d89b2 --- /dev/null +++ b/examples/message-codegen/external-app/relay.rs @@ -0,0 +1,25 @@ +// Copyright 2026 Dimensional Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use external_telemetry_messages::{codec::Message, demo_msgs::msg::Telemetry}; +use std::{env, fs}; + +fn main() -> Result<(), Box> { + let args: Vec<_> = env::args().collect(); + let mut value = Telemetry::decode(&fs::read(&args[1])?)?; + println!("Packaged Rust crate received: {}", value.application_note); + value.application_note.push_str("/rust"); + fs::write(&args[2], value.encode()?)?; + Ok(()) +} diff --git a/examples/message-codegen/user-story/story_msgs/msg/DeviceReading.msg b/examples/message-codegen/user-story/story_msgs/msg/DeviceReading.msg new file mode 100644 index 00000000000..cbb5e8ebcd5 --- /dev/null +++ b/examples/message-codegen/user-story/story_msgs/msg/DeviceReading.msg @@ -0,0 +1,4 @@ +std_msgs/Header header +uint32 sequence +float64 value +string label "new-local-type" diff --git a/examples/message-codegen/viewer-checker/check.mjs b/examples/message-codegen/viewer-checker/check.mjs new file mode 100644 index 00000000000..3856e175725 --- /dev/null +++ b/examples/message-codegen/viewer-checker/check.mjs @@ -0,0 +1,58 @@ +import assert from 'node:assert/strict'; +import { readFile } from 'node:fs/promises'; +import { McapIndexedReader } from '@mcap/core'; +import { parse, fixupTypes } from '@foxglove/rosmsg'; +import { MessageReader } from '@foxglove/rosmsg2-serialization'; +import zstd from '@foxglove/wasm-zstd'; + +await zstd.isLoaded; +const bytes = await readFile(process.argv[2]); +const reader = await McapIndexedReader.Initialize({ + readable: { + size: async () => BigInt(bytes.length), + read: async (offset, size) => bytes.subarray(Number(offset), Number(offset + size)), + }, + decompressHandlers: { zstd: (data, size) => zstd.decompress(data, Number(size)) }, +}); +assert.equal(reader.header.profile, 'ros2'); +const decoders = new Map(); +for (const schema of reader.schemasById.values()) { + assert.equal(schema.encoding, 'ros2msg'); + const definitions = parse(new TextDecoder().decode(schema.data), { ros2: true, skipTypeFixup: true }); + definitions[0].name = schema.name.replace('/msg/', '/'); + fixupTypes(definitions); + decoders.set(schema.id, new MessageReader(definitions)); +} +const counts = new Map(); +for await (const message of reader.readMessages({ validateCrcs: true })) { + const channel = reader.channelsById.get(message.channelId); + assert.equal(channel.messageEncoding, 'cdr'); + const value = decoders.get(channel.schemaId).readMessage(message.data); + const index = message.sequence; + assert.equal(message.logTime - message.publishTime, 1000000n); + if (channel.topic === '/telemetry') { + assert.equal(value.sequence, index); + assert.equal(value.value, 20 + index / 10); + assert.equal(value.label, 'synthetic'); + assert.equal(value.header.frame_id, 'map'); + } else if (channel.topic === '/camera/image') { + assert.equal(value.width, 256); + assert.equal(value.height, 192); + assert.equal(value.data.length, 256 * 192 * 3); + assert.equal(value.data[0], index * 8 % 256); + } else if (channel.topic === '/camera/compressed') { + assert.equal(value.format, 'png'); + assert.deepEqual(Array.from(value.data.slice(0, 8)), [137,80,78,71,13,10,26,10]); + } else if (channel.topic === '/robot/pose') { + assert.equal(value.pose.position.x, Math.cos(index / 5)); + assert.equal(value.pose.orientation.w, 1); + } else if (channel.topic === '/tf') { + assert.equal(value.transforms[0].child_frame_id, 'camera'); + } + counts.set(channel.topic, (counts.get(channel.topic) ?? 0) + 1); +} +assert.equal(counts.size, 5); +for (const [topic, count] of counts) { + assert.equal(count, 30); + console.log(`Foxglove libraries decoded ${count} ${topic} messages from embedded definitions.`); +} diff --git a/examples/message-codegen/viewer-checker/package-lock.json b/examples/message-codegen/viewer-checker/package-lock.json new file mode 100644 index 00000000000..b4ee01c90a6 --- /dev/null +++ b/examples/message-codegen/viewer-checker/package-lock.json @@ -0,0 +1,110 @@ +{ + "name": "viewer-checker", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "@foxglove/rosmsg": "5.0.5", + "@foxglove/rosmsg2-serialization": "3.1.2", + "@foxglove/wasm-zstd": "1.0.1", + "@mcap/core": "2.2.2" + } + }, + "node_modules/@foxglove/cdr": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@foxglove/cdr/-/cdr-3.5.1.tgz", + "integrity": "sha512-Fubm04/xC1SkeNaviwUhbFk8nAiiNvIqlmP5MW7r6IVGFa35rsA0E3/Rg/pGdE77ZXf4XNwShZcQoEmje62ddQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/@foxglove/crc": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@foxglove/crc/-/crc-0.0.3.tgz", + "integrity": "sha512-DjIZsnL3CyP/yQ/vUYA9cjrD0a/8YXejI5ZmsaOiT16cLfZcTwaCxIN01/ys4jsy+dZCQ/9DnWFn7AEFbiMDaA==", + "license": "MIT" + }, + "node_modules/@foxglove/message-definition": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@foxglove/message-definition/-/message-definition-0.5.0.tgz", + "integrity": "sha512-B/2GvWn4wRSsPDywcmy6uNXgAfZRhiOAnmy3qAaS6MHVqiHQqs/RoDsoW6Gw9sXSweJpeH5qAqAihvm1pR9Thg==", + "license": "MIT" + }, + "node_modules/@foxglove/rosmsg": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@foxglove/rosmsg/-/rosmsg-5.0.5.tgz", + "integrity": "sha512-+qY6xW+4HdbPI3ItAlFFMjXgAiplXyRsv+kqdBk8OcWGH38BmEd7s6v/VnCkbYovAoB5rfR5giuKfmPRNzwbrA==", + "license": "MIT", + "dependencies": { + "@foxglove/message-definition": "0.5.0", + "md5-typescript": "^1.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@foxglove/rosmsg2-serialization": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@foxglove/rosmsg2-serialization/-/rosmsg2-serialization-3.1.2.tgz", + "integrity": "sha512-KKtmHuuIQy6I0JLUi01LFhV7hrZb5xd+LegtuGz2+9L9pftBxtVVKhoxO6B/kQREGocIUOLP8494kxLF58LMWw==", + "license": "MIT", + "dependencies": { + "@foxglove/cdr": "^3.5.1", + "@foxglove/message-definition": "0.5.0", + "@foxglove/rostime": "^1.1.3" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@foxglove/rostime": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@foxglove/rostime/-/rostime-1.1.3.tgz", + "integrity": "sha512-Gr3Xy4sNbo2NcXg0tBHb/jVUqIcDyZ1kgHj9dB7K+Y1A7AQ0oSCmSXIuf8oqeteSIs0pl8BJOWEwAtLNC99Izg==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/@foxglove/wasm-zstd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@foxglove/wasm-zstd/-/wasm-zstd-1.0.1.tgz", + "integrity": "sha512-hqKTO45Sl+kSq9SDqM9xi5L+GncjFEZIJgYEkGTlpJXTfhy1Gf+a+3epWMcE0tLUKmzM77dtu8snape/J+7ueQ==", + "license": "MIT" + }, + "node_modules/@mcap/core": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@mcap/core/-/core-2.2.2.tgz", + "integrity": "sha512-W4NFiyqQlJsNjw8JxAAQ872u0xLWJy0GFC3YFm8bTLbNs+HdDWe8DwBqznr0MGYpWtw+AX8XzHWB5Y9rLEGJJg==", + "license": "MIT", + "dependencies": { + "@foxglove/crc": "^0.0.3", + "heap-js": "^2.7.1", + "tslib": "^2.8.1" + } + }, + "node_modules/heap-js": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/heap-js/-/heap-js-2.7.1.tgz", + "integrity": "sha512-EQfezRg0NCZGNlhlDR3Evrw1FVL2G3LhU7EgPoxufQKruNBSYA8MiRPHeWbU+36o+Fhel0wMwM+sLEiBAlNLJA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/md5-typescript": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/md5-typescript/-/md5-typescript-1.0.5.tgz", + "integrity": "sha512-ovAc4EtiNt2dY8JPhPr/wkC9h4U5k/nuClNVcG0Ga3V1rMlYpAY24ZaaymFXJlz+ccJ6UMPo3FSaVKe7czBsXw==", + "license": "ISC" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + } + } +} diff --git a/examples/message-codegen/viewer-checker/package.json b/examples/message-codegen/viewer-checker/package.json new file mode 100644 index 00000000000..9d02547d3bc --- /dev/null +++ b/examples/message-codegen/viewer-checker/package.json @@ -0,0 +1,10 @@ +{ + "private": true, + "type": "module", + "dependencies": { + "@foxglove/rosmsg": "5.0.5", + "@foxglove/rosmsg2-serialization": "3.1.2", + "@mcap/core": "2.2.2", + "@foxglove/wasm-zstd": "1.0.1" + } +} diff --git a/examples/message-package/README.md b/examples/message-package/README.md new file mode 100644 index 00000000000..d0d96682d82 --- /dev/null +++ b/examples/message-package/README.md @@ -0,0 +1,66 @@ +# Verify the installed message wheel + +Build the layer-2 message package, install its wheel into a clean environment, +then run outside the checkout. This example constructs an upstream `Image` and +the existing custom `LineSegments3D`, checks their CDR roundtrips, and inspects +the packaged definitions and native build inputs. + +Use Python 3.12 and uv on Linux or macOS. No ROS installation, CMake, Rust +toolchain, DimOS runtime, or MCAP package is needed. Initial preparation, +building, and dependency installation need network access unless their inputs +are cached. + +From the repository root on this example branch: + +```sh +message_demo_dir="$(mktemp -d)" +uv run --no-project --with 'dimos-cdrgen[prepare]==0.1.0' python -m scripts.prepare_builtin_sources +uv build --wheel --out-dir "$message_demo_dir/wheels" packages/dimos-generated +uv venv --python 3.12 "$message_demo_dir/venv" +uv pip install --python "$message_demo_dir/venv/bin/python" "$message_demo_dir"/wheels/dimos_generated-*.whl +cp examples/message-package/demo_installed_wheel.py "$message_demo_dir/" +cd "$message_demo_dir" +"$message_demo_dir/venv/bin/python" -I demo_installed_wheel.py +``` + +Expected output, with your temporary directory in the first line: + +```text +Installed package: /venv/lib/python3.12/site-packages/dimos_generated/__init__.py +Catalog: 73 types +PASS: sensor_msgs/msg/Image pixels, encoding and source stamp +PASS: dimos_msgs/msg/LineSegments3D geometry, weight and nested type identity +PASS: packaged definitions and C++/Rust build inputs; no compiled message libraries +``` + +`-I` ignores `PYTHONPATH` and the script directory during imports. The script +also verifies that the imported package lives inside the clean environment +and that the DimOS runtime is absent. It uses the installed wheel rather than +an editable checkout. + +## What the package contains + +Git stores 14 custom definitions, `catalog.json`, upstream pins, hashes, and +thin build entry points. Preparation copies the selected upstream definitions +and custom inputs into ignored `packages/dimos-generated/interfaces/`. +`setup.py` calls `dimos_cdrgen.source_package.setup_arguments` to generate and +package Python imports and stubs, complete schemas, C++ CMake projects, and +Rust Cargo inputs. Those generated files are shipped in the wheel, not checked +into Git. A source distribution also carries the prepared `.msg` inputs. + +At this layer's head, 69 catalog roots resolve to 73 types: 59 upstream and +14 custom. This is an explicit supported selection, not proof that every +message used elsewhere in the repository is covered. Later stack layers add +further types. + +The installed wheel needs `dimos-cdrgen`, rosbags, and NumPy as Python runtime +dependencies. Running this example does not fetch `.msg` files or compile +native bindings. For offline installation, make those dependency wheels +available locally and pass `--no-index --find-links ` to +`uv pip install`. Offline source preparation separately requires cached +archives and `scripts.prepare_builtin_sources --offline`. + +MCAP recording is a separate layer. The existing +[layer-3 example](https://github.com/dimensionalOS/dimos/blob/3cb96b780433dcdac605f69453721aac2df1d800/examples/message-codegen/demo_mcap.py) +writes messages and their schemas into a file for external readers. It is not +required for this wheel check. diff --git a/examples/message-package/demo_installed_wheel.py b/examples/message-package/demo_installed_wheel.py new file mode 100644 index 00000000000..9937cf7c59b --- /dev/null +++ b/examples/message-package/demo_installed_wheel.py @@ -0,0 +1,87 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Verify an installed message wheel from a clean environment outside the checkout.""" + +from importlib.util import find_spec +from pathlib import Path +import sys + +from dimos_cdrgen.registry import decode, encode +import dimos_generated +from dimos_generated.builtin_interfaces.msg import Time +from dimos_generated.dimos_msgs.msg import LineSegment3D, LineSegments3D +from dimos_generated.geometry_msgs.msg import Point +from dimos_generated.sensor_msgs.msg import Image +from dimos_generated.std_msgs.msg import Header +from dimos_generated_schemas.provider import message_types, package_root +import numpy as np + + +def main() -> None: + assert sys.prefix != sys.base_prefix, "Run in the clean verification environment" + assert dimos_generated.__file__ is not None + installed = Path(dimos_generated.__file__).resolve() + assert installed.is_relative_to(Path(sys.prefix).resolve()), installed + assert find_spec("dimos") is None, "This example does not need the DimOS runtime" + print(f"Installed package: {installed}") + print(f"Catalog: {len(message_types())} types") + + image = Image( + header=Header(stamp=Time(sec=17, nanosec=23), frame_id="camera"), + height=2, + width=3, + encoding="rgb8", + is_bigendian=0, + step=9, + data=np.arange(18, dtype=np.uint8), + ) + restored_image = decode(encode(image), Image) + assert type(restored_image) is Image and type(restored_image.header) is Header + assert restored_image.header == Header(Time(17, 23), "camera") + assert (restored_image.height, restored_image.width, restored_image.step) == (2, 3, 9) + assert restored_image.encoding == "rgb8" and restored_image.is_bigendian == 0 + np.testing.assert_array_equal(restored_image.data, np.arange(18, dtype=np.uint8)) + print("PASS: sensor_msgs/msg/Image pixels, encoding and source stamp") + + segments = LineSegments3D( + header=Header(stamp=Time(sec=17, nanosec=23), frame_id="map"), + segments=[LineSegment3D(start=Point(1.0, 2.0, 3.0), end=Point(4.0, 5.0, 6.0), weight=0.75)], + ) + restored_segments = decode(encode(segments), LineSegments3D) + assert restored_segments == segments + assert type(restored_segments.header) is Header + assert type(restored_segments.segments[0].start) is Point + print("PASS: dimos_msgs/msg/LineSegments3D geometry, weight and nested type identity") + + resources = package_root() + for relative in ( + "schemas/sensor_msgs/msg/Image.msg", + "schemas/dimos_msgs/msg/LineSegments3D.msg", + "cpp/CMakeLists.txt", + "cpp/sensor_msgs/msg/Image.msg", + "rust/Cargo.toml", + "rust/build.rs", + "rust/interfaces/dimos_msgs/msg/LineSegments3D.msg", + ): + assert (resources / relative).is_file(), relative + assert not any( + path.suffix in {".so", ".a", ".dylib", ".dll", ".rlib", ".pyd"} + for path in resources.rglob("*") + ) + print("PASS: packaged definitions and C++/Rust build inputs; no compiled message libraries") + + +if __name__ == "__main__": + main() diff --git a/examples/native-modules/cpp/flake.lock b/examples/native-modules/cpp/flake.lock index 9a9ad728e16..0ff3a2e449c 100644 --- a/examples/native-modules/cpp/flake.lock +++ b/examples/native-modules/cpp/flake.lock @@ -28,11 +28,11 @@ }, "locked": { "dir": "native/cpp", - "lastModified": 1791386052, - "narHash": "sha256-MeVxI5e13wh7jQ0g2tnaLpiyDaQQMfqEAC7qrXopHY4=", + "lastModified": 1792431336, + "narHash": "sha256-W0biIt+6oH7bBHt44kV4J411Y3AUsuMkQ7OsS45BxDE=", "owner": "dimensionalOS", "repo": "dimos", - "rev": "87c0c26b40e8a5aeb9d9d346104b49d5fb02696a", + "rev": "fbccb5c45eb84a7f65413a37cba7afe3fe2d8008", "type": "github" }, "original": { diff --git a/native/cpp/include/dimos/native/cdr_codec.hpp b/native/cpp/include/dimos/native/cdr_codec.hpp new file mode 100644 index 00000000000..373034d9327 --- /dev/null +++ b/native/cpp/include/dimos/native/cdr_codec.hpp @@ -0,0 +1,11 @@ +// Copyright 2026 Dimensional Inc. +// SPDX-License-Identifier: Apache-2.0 +#pragma once + +#include + +namespace dimos::native { +using dimos::cdr::cdr_callbacks; +using dimos::cdr::cdr_encode; +using dimos::cdr::cdr_decode; +} // namespace dimos::native diff --git a/packages/dimos-generated/MANIFEST.in b/packages/dimos-generated/MANIFEST.in new file mode 100644 index 00000000000..15f65a41dc1 --- /dev/null +++ b/packages/dimos-generated/MANIFEST.in @@ -0,0 +1,3 @@ +include pyproject.toml setup.py catalog.json schema-sources.json +prune build +global-exclude __pycache__ *.pyc diff --git a/packages/dimos-generated/README.md b/packages/dimos-generated/README.md new file mode 100644 index 00000000000..768d388acdd --- /dev/null +++ b/packages/dimos-generated/README.md @@ -0,0 +1,115 @@ +# Built-in message packages + +Git keeps the 14 DimOS definitions under `custom/dimos_msgs`, the supported +`catalog.json`, and `schema-sources.json` with pinned revisions, archive hashes, +selected-file hashes and license paths. Bulk upstream `.msg` files are not Git +inputs. Explicit preparation puts their selected closure in ignored `interfaces/`. +Python aliases/stubs and native source projects are also ignored build outputs. + +## Supported types + +`catalog.json` lists explicit roots and a reason for every root. Builds +resolve their complete dependency closure. Adding another upstream `.msg` to the +source tree does not silently add an installed type. + +The default package exports 73 types. The starting set is the 63 static consumer +types audited at published runtime commit +`59ce3b8ddb2aedcecd8ca0c592b64e2824899874`. The additional roots preserve: + +- The two remaining project-owned bounding-box array messages. This layout + change does not retire DimOS's own message contracts. +- `Empty` and `Int64` used by the dynamic topic/CDR fixtures. +- `UInt32MultiArray` and its layout dependencies used by strict array/truncation + acceptance. +- `SolidPrimitive`, `Polygon` and `Point32` used by the existing strict bounds + acceptance. Python construction remains available, but encoding/decoding this + bounded type remains unsupported. CDR-L07/L08 assertions remain strict xfails. + +All 14 project-owned types remain exported. The pinned source lock selects the upstream definitions needed by this package. +Other upstream types are not part of the default installed API. This is a deliberate proposal API reduction from +153 exports, not a claim that static imports prove every other type unused. +Dynamic topic lookup and typed replay accept installed, supported type names. +External packages can reuse the exported dependency-owned types, including the +same Header identity. We do not promise an arbitrary omitted standard type or +split ROS-package ownership across Rust crates. There is no core/extras scheme. + +## Install matching review artifacts + +The proposal packages are not assumed to exist on PyPI. Put matching backend and +built-in wheels plus their Python dependencies in a wheelhouse: + +```sh +pip install --no-index --find-links review/wheels dimos-generated==0.1.0 +``` + +Wheel installation needs no ROS, CMake, Cargo or C/C++ compiler. Import performs +no download or native compilation. Python uses rosbags classes and CDR codecs: + +```python +from dimos_generated.builtin_interfaces.msg import Time +from dimos_generated.std_msgs.msg import Header +from dimos_cdrgen.registry import encode, decode + +header = Header(Time(17, 23), "map") +assert decode(encode(header), Header) == header +``` + +## Explicit source preparation + +Prepare the backend parser first, then prepare builtin inputs as a separate action: + +```sh +python -m scripts.prepare_builtin_sources +# Reuse cached, hash-checked archives without network: +python -m scripts.prepare_builtin_sources --offline +``` + +The preparation script delegates archive/file validation to PR1's generic +`source_inputs.prepare_sources`. It adds the local custom inputs and licenses. +It never runs inside pip hooks or runtime imports. An unprepared checkout fails +with the missing-input path instead of fetching data. Offline development needs +these archives and Python dependency wheels cached beforehand. Release preparation +performs the same checks before producing self-contained source/wheel artifacts. +The generic backend retains only the first layer's small conformance fixtures, +not the full builtin catalog. Product data do not select backend behavior. + +## Source and editable builds + +PEP 517/660 calls the same `generate_builtin()` implementation used by native +source packaging. It emits Python files and native source projects, but never +invokes a native compiler. A source build needs the matching +`dimos-cdrgen` wheel, setuptools/wheel and their dependencies. An offline +build needs these in its wheelhouse: + +```sh +pip install --no-index --find-links review/wheels ./packages/dimos-generated +pip install --no-index --find-links review/wheels -e ./packages/dimos-generated +``` + +After editing a custom message or catalog, repeat source preparation and the editable install. Restart +Python processes. There is no import-time source build. A clean checkout requires explicit source preparation before a pip build. A +release sdist carries its own `interfaces/` inputs, catalog, pins and licenses. It can rebuild a wheel outside the +checkout without GitHub access. The checkout-only uv dependency path is removed +from release sdists. + +The generator backend itself retains the explicit upstream parser preparation +contract from layer 1. Preparing that backend is a developer/release step, not +an implicit download inside this package's pip hook. + +## Maintainer artifacts and checks + +```sh +python -m scripts.generate_builtin_messages +python -m scripts.generate_builtin_messages --check +``` + +Outputs live in `packages/dimos-generated/build/message-source/python`. The check +compares independent regeneration with those build artifacts and does not repair +them. CI mutation tests retain field/schema/version/deletion/rename and missing +resource checks. Undeclared source additions require a catalog decision. + +`bash scripts/package_messages.sh` creates the explicit C++ source archive and +Cargo crate using the same roots/closure. It invokes Cargo as a native packaging +step. Consumers still supply their native toolchains and prepared dependencies. +MCAP writers can embed the complete schema closure of a supported type even when +its nested values come from another package. diff --git a/packages/dimos-generated/catalog.json b/packages/dimos-generated/catalog.json new file mode 100644 index 00000000000..1b39ac7c34f --- /dev/null +++ b/packages/dimos-generated/catalog.json @@ -0,0 +1,74 @@ +{ + "format": 1, + "roots": { + "builtin_interfaces/msg/Duration": "Published runtime consumer: dimos/control/tasks/trajectory_task/trajectory_task.py", + "builtin_interfaces/msg/Time": "Published runtime consumer: dimos/cli/hardware/g1.py", + "dimos_msgs/msg/BoundingBox2DArray": "Retain the project-owned message contract; do not retire custom messages in this package-layout change.", + "dimos_msgs/msg/BoundingBox3DArray": "Retain the project-owned message contract; do not retire custom messages in this package-layout change.", + "dimos_msgs/msg/EntityMarker": "Published runtime consumer: dimos/perception/experimental/temporal_memory/temporal_memory.py", + "dimos_msgs/msg/EntityMarkers": "Published runtime consumer: dimos/perception/experimental/temporal_memory/temporal_memory.py", + "dimos_msgs/msg/GraspCandidate": "Published runtime consumer: dimos/manipulation/grasping/heuristic_grasp.py", + "dimos_msgs/msg/GraspCandidateArray": "Published runtime consumer: dimos/manipulation/grasping/grasp_gen_spec.py", + "dimos_msgs/msg/ImuInfo": "Published runtime consumer: dimos/hardware/sensors/camera/realsense/camera.py", + "dimos_msgs/msg/JointCommand": "Published runtime consumer: dimos/manipulation/control/servo_control/cartesian_motion_controller.py", + "dimos_msgs/msg/LineSegment3D": "Published runtime consumer: dimos/navigation/global_planner/mls_planner/viz.py", + "dimos_msgs/msg/LineSegments3D": "Published runtime consumer: dimos/navigation/global_planner/mls_planner/viz.py", + "dimos_msgs/msg/MotorCommandArray": "Published runtime consumer: dimos/hardware/whole_body/transport/adapter.py", + "dimos_msgs/msg/RobotState": "Published runtime consumer: dimos/manipulation/control/servo_control/cartesian_motion_controller.py", + "dimos_msgs/msg/TrajectoryStatus": "Published runtime consumer: dimos/control/tasks/planar_base_trajectory_task/planar_base_trajectory_task.py", + "dimos_msgs/msg/VideoStats": "Published runtime consumer: dimos/teleop/hosted/hosted_stats.py", + "foxglove_msgs/msg/CompressedVideo": "Published runtime consumer: dimos/robot/deeprobotics/m20/blueprints/m20_kronknav.py", + "geometry_msgs/msg/Point": "Published runtime consumer: dimos/agents/skills/navigation.py", + "geometry_msgs/msg/PointStamped": "Published runtime consumer: dimos/agents/skills/point_nav.py", + "geometry_msgs/msg/Pose": "Published runtime consumer: dimos/agents/skills/navigation.py", + "geometry_msgs/msg/PoseArray": "Published runtime consumer: dimos/manipulation/grasping/grasp_gen_spec.py", + "geometry_msgs/msg/PoseStamped": "Published runtime consumer: dimos/agents/skills/navigation.py", + "geometry_msgs/msg/PoseWithCovariance": "Published runtime consumer: dimos/experimental/robot/bosdyn/spot/effectors/high_level.py", + "geometry_msgs/msg/Quaternion": "Published runtime consumer: dimos/agents/skills/visual_servoing/bbox_navigation.py", + "geometry_msgs/msg/Transform": "Published runtime consumer: dimos/control/tick_loop.py", + "geometry_msgs/msg/TransformStamped": "Published runtime consumer: dimos/agents/skills/visual_servoing/detection_navigation.py", + "geometry_msgs/msg/Twist": "Published runtime consumer: dimos/agents/skills/person_follow.py", + "geometry_msgs/msg/TwistStamped": "Published runtime consumer: dimos/control/task.py", + "geometry_msgs/msg/TwistWithCovariance": "Published runtime consumer: dimos/experimental/robot/bosdyn/spot/effectors/high_level.py", + "geometry_msgs/msg/Vector3": "Published runtime consumer: dimos/agents/skills/person_follow.py", + "geometry_msgs/msg/Wrench": "Published runtime consumer: dimos/msgs/geometry.py", + "nav_msgs/msg/MapMetaData": "Published runtime consumer: dimos/mapping/pointclouds/occupancy.py", + "nav_msgs/msg/OccupancyGrid": "Published runtime consumer: dimos/experimental/security_demo/security_module.py", + "nav_msgs/msg/Odometry": "Published runtime consumer: dimos/experimental/robot/bosdyn/spot/effectors/high_level.py", + "nav_msgs/msg/Path": "Published runtime consumer: dimos/control/benchmarking/benchmark.py", + "sensor_msgs/msg/BatteryState": "Published runtime consumer: dimos/robot/unitree/go2/dds/module.py", + "sensor_msgs/msg/CameraInfo": "Published runtime consumer: dimos/agents/skills/person_follow.py", + "sensor_msgs/msg/CompressedImage": "Published runtime consumer: dimos/core/transport.py", + "sensor_msgs/msg/Image": "Published runtime consumer: dimos/agents/mcp/mcp_server.py", + "sensor_msgs/msg/Imu": "Published runtime consumer: dimos/hardware/sensors/camera/realsense/camera.py", + "sensor_msgs/msg/JointState": "Published runtime consumer: dimos/cli/hardware/g1.py", + "sensor_msgs/msg/Joy": "Published runtime consumer: dimos/robot/unitree/go2/dds/module.py", + "sensor_msgs/msg/PointCloud2": "Published runtime consumer: dimos/agents/skills/person_follow.py", + "sensor_msgs/msg/PointField": "Published runtime consumer: dimos/msgs/pointcloud.py", + "sensor_msgs/msg/RegionOfInterest": "Published runtime consumer: dimos/hardware/sensors/camera/webcam.py", + "shape_msgs/msg/SolidPrimitive": "Retain CDR-L07/L08 strict bounded-schema assertions; construction is exported but codec is unsupported.", + "std_msgs/msg/Bool": "Published runtime consumer: dimos/agents/skills/point_nav.py", + "std_msgs/msg/Empty": "Dynamic topic/CDR fixture contract in dimos/web/relay_bridge/gen_cdr_fixtures.py.", + "std_msgs/msg/Float32": "Published runtime consumer: dimos/control/benchmarking/benchmark.py", + "std_msgs/msg/Header": "Published runtime consumer: dimos/cli/hardware/g1.py", + "std_msgs/msg/Int32": "Published runtime consumer: dimos/experimental/isolated_python/example/contract.py", + "std_msgs/msg/Int64": "Dynamic topic/CDR fixture contract in dimos/web/relay_bridge/gen_cdr_fixtures.py.", + "std_msgs/msg/Int8": "Published runtime consumer: dimos/control/benchmarking/benchmark.py", + "std_msgs/msg/String": "Published runtime consumer: dimos/experimental/memory/rust_recorder.py", + "std_msgs/msg/UInt32": "Published runtime consumer: dimos/control/tasks/teleop_ik_task/teleop_ik_task.py", + "std_msgs/msg/UInt32MultiArray": "Existing strict array/truncation decoder acceptance in test_python_source.py.", + "tf2_msgs/msg/TFMessage": "Published runtime consumer: dimos/agents/skills/person_follow.py", + "trajectory_msgs/msg/JointTrajectory": "Published runtime consumer: dimos/control/coordinator.py", + "trajectory_msgs/msg/JointTrajectoryPoint": "Published runtime consumer: dimos/control/tasks/trajectory_task/trajectory_task.py", + "vision_msgs/msg/BoundingBox2D": "Published runtime consumer: dimos/perception/detection/type/detection2d/bbox.py", + "vision_msgs/msg/BoundingBox3D": "Published runtime consumer: dimos/perception/detection/type/detection3d/bbox.py", + "vision_msgs/msg/Detection2D": "Published runtime consumer: dimos/perception/detection/type/detection2d/base.py", + "vision_msgs/msg/Detection2DArray": "Published runtime consumer: dimos/agents/skills/visual_servoing/bbox_navigation.py", + "vision_msgs/msg/Detection3D": "Published runtime consumer: dimos/manipulation/planning/monitor/world_monitor.py", + "vision_msgs/msg/Detection3DArray": "Published runtime consumer: dimos/experimental/world_belief/worldbelief_module.py", + "vision_msgs/msg/ObjectHypothesis": "Published runtime consumer: dimos/perception/detection/type/detection2d/bbox.py", + "vision_msgs/msg/ObjectHypothesisWithPose": "Published runtime consumer: dimos/perception/detection/type/detection2d/bbox.py", + "vision_msgs/msg/Point2D": "Published runtime consumer: dimos/perception/detection/type/detection2d/bbox.py", + "vision_msgs/msg/Pose2D": "Published runtime consumer: dimos/perception/detection/type/detection2d/bbox.py" + } +} diff --git a/packages/dimos-generated/custom/dimos_msgs/LICENSE b/packages/dimos-generated/custom/dimos_msgs/LICENSE new file mode 100644 index 00000000000..5e2927e3adb --- /dev/null +++ b/packages/dimos-generated/custom/dimos_msgs/LICENSE @@ -0,0 +1,17 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + Copyright 2025 Dimensional Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/dimos-generated/custom/dimos_msgs/msg/BoundingBox2DArray.msg b/packages/dimos-generated/custom/dimos_msgs/msg/BoundingBox2DArray.msg new file mode 100644 index 00000000000..7360bdbaec4 --- /dev/null +++ b/packages/dimos-generated/custom/dimos_msgs/msg/BoundingBox2DArray.msg @@ -0,0 +1,5 @@ +# Copyright 2026 Dimensional Inc. +# SPDX-License-Identifier: Apache-2.0 + +std_msgs/Header header +vision_msgs/BoundingBox2D[] boxes diff --git a/packages/dimos-generated/custom/dimos_msgs/msg/BoundingBox3DArray.msg b/packages/dimos-generated/custom/dimos_msgs/msg/BoundingBox3DArray.msg new file mode 100644 index 00000000000..3bb3649298e --- /dev/null +++ b/packages/dimos-generated/custom/dimos_msgs/msg/BoundingBox3DArray.msg @@ -0,0 +1,5 @@ +# Copyright 2026 Dimensional Inc. +# SPDX-License-Identifier: Apache-2.0 + +std_msgs/Header header +vision_msgs/BoundingBox3D[] boxes diff --git a/packages/dimos-generated/custom/dimos_msgs/msg/EntityMarker.msg b/packages/dimos-generated/custom/dimos_msgs/msg/EntityMarker.msg new file mode 100644 index 00000000000..c4eb6dc7625 --- /dev/null +++ b/packages/dimos-generated/custom/dimos_msgs/msg/EntityMarker.msg @@ -0,0 +1,8 @@ +# Copyright 2026 Dimensional Inc. +# SPDX-License-Identifier: Apache-2.0 + +# A labeled world-space entity; rendering belongs to viewer adapters. +string entity_id +string label +string entity_type +geometry_msgs/Point position diff --git a/packages/dimos-generated/custom/dimos_msgs/msg/EntityMarkers.msg b/packages/dimos-generated/custom/dimos_msgs/msg/EntityMarkers.msg new file mode 100644 index 00000000000..a4ebd89ced5 --- /dev/null +++ b/packages/dimos-generated/custom/dimos_msgs/msg/EntityMarkers.msg @@ -0,0 +1,5 @@ +# Copyright 2026 Dimensional Inc. +# SPDX-License-Identifier: Apache-2.0 + +std_msgs/Header header +dimos_msgs/EntityMarker[] markers diff --git a/packages/dimos-generated/custom/dimos_msgs/msg/GraspCandidate.msg b/packages/dimos-generated/custom/dimos_msgs/msg/GraspCandidate.msg new file mode 100644 index 00000000000..480cb94c313 --- /dev/null +++ b/packages/dimos-generated/custom/dimos_msgs/msg/GraspCandidate.msg @@ -0,0 +1,6 @@ +# Copyright 2026 Dimensional Inc. +# SPDX-License-Identifier: Apache-2.0 + +# Target TCP pose and generator-local ranking score. +geometry_msgs/Pose pose +float64 score diff --git a/packages/dimos-generated/custom/dimos_msgs/msg/GraspCandidateArray.msg b/packages/dimos-generated/custom/dimos_msgs/msg/GraspCandidateArray.msg new file mode 100644 index 00000000000..5d0beb21198 --- /dev/null +++ b/packages/dimos-generated/custom/dimos_msgs/msg/GraspCandidateArray.msg @@ -0,0 +1,6 @@ +# Copyright 2026 Dimensional Inc. +# SPDX-License-Identifier: Apache-2.0 + +# Candidates share the input cloud's frame and timestamp. +std_msgs/Header header +GraspCandidate[] candidates diff --git a/packages/dimos-generated/custom/dimos_msgs/msg/ImuInfo.msg b/packages/dimos-generated/custom/dimos_msgs/msg/ImuInfo.msg new file mode 100644 index 00000000000..8a2ed049200 --- /dev/null +++ b/packages/dimos-generated/custom/dimos_msgs/msg/ImuInfo.msg @@ -0,0 +1,15 @@ +# Copyright 2026 Dimensional Inc. +# SPDX-License-Identifier: Apache-2.0 + +# Continuous-time IMU noise model. Extrinsics are supplied separately through TF. +std_msgs/Header header +# rad/s/sqrt(Hz) +float64 gyro_noise_density +# rad/s^2/sqrt(Hz) +float64 gyro_random_walk +# m/s^2/sqrt(Hz) +float64 accel_noise_density +# m/s^3/sqrt(Hz) +float64 accel_random_walk +# Delivered sample rate in Hz. +float64 frequency diff --git a/packages/dimos-generated/custom/dimos_msgs/msg/JointCommand.msg b/packages/dimos-generated/custom/dimos_msgs/msg/JointCommand.msg new file mode 100644 index 00000000000..8f5d1b68447 --- /dev/null +++ b/packages/dimos-generated/custom/dimos_msgs/msg/JointCommand.msg @@ -0,0 +1,6 @@ +# Copyright 2026 Dimensional Inc. +# SPDX-License-Identifier: Apache-2.0 + +# Joint position targets in radians, ordered by the controller's joint list. +std_msgs/Header header +float64[] positions diff --git a/packages/dimos-generated/custom/dimos_msgs/msg/LineSegment3D.msg b/packages/dimos-generated/custom/dimos_msgs/msg/LineSegment3D.msg new file mode 100644 index 00000000000..f026c5eef45 --- /dev/null +++ b/packages/dimos-generated/custom/dimos_msgs/msg/LineSegment3D.msg @@ -0,0 +1,6 @@ +# Copyright 2026 Dimensional Inc. +# SPDX-License-Identifier: Apache-2.0 + +geometry_msgs/Point start +geometry_msgs/Point end +float64 weight 1.0 diff --git a/packages/dimos-generated/custom/dimos_msgs/msg/LineSegments3D.msg b/packages/dimos-generated/custom/dimos_msgs/msg/LineSegments3D.msg new file mode 100644 index 00000000000..92947baed42 --- /dev/null +++ b/packages/dimos-generated/custom/dimos_msgs/msg/LineSegments3D.msg @@ -0,0 +1,6 @@ +# Copyright 2026 Dimensional Inc. +# SPDX-License-Identifier: Apache-2.0 + +# Weighted segments in a common coordinate frame. +std_msgs/Header header +LineSegment3D[] segments diff --git a/packages/dimos-generated/custom/dimos_msgs/msg/MotorCommandArray.msg b/packages/dimos-generated/custom/dimos_msgs/msg/MotorCommandArray.msg new file mode 100644 index 00000000000..e98e7ae9e8c --- /dev/null +++ b/packages/dimos-generated/custom/dimos_msgs/msg/MotorCommandArray.msg @@ -0,0 +1,11 @@ +# Copyright 2026 Dimensional Inc. +# SPDX-License-Identifier: Apache-2.0 + +# Per-joint hybrid commands. All arrays must have the same length. +# q: rad; dq: rad/s; tau: N*m. Gains follow the actuator controller's units. +std_msgs/Header header +float64[] q +float64[] dq +float64[] kp +float64[] kd +float64[] tau diff --git a/packages/dimos-generated/custom/dimos_msgs/msg/RobotState.msg b/packages/dimos-generated/custom/dimos_msgs/msg/RobotState.msg new file mode 100644 index 00000000000..36b399f85c8 --- /dev/null +++ b/packages/dimos-generated/custom/dimos_msgs/msg/RobotState.msg @@ -0,0 +1,15 @@ +# Copyright 2026 Dimensional Inc. +# SPDX-License-Identifier: Apache-2.0 + +# Controller feedback. TCP values retain the driver's x/y/z/roll/pitch/yaw convention. +std_msgs/Header header +int32 state +int32 mode +int32 error_code +int32 warn_code +int32 cmdnum +int32 mt_brake +int32 mt_able +float64[] tcp_pose +float64[] tcp_offset +float64[] joints diff --git a/packages/dimos-generated/custom/dimos_msgs/msg/TrajectoryStatus.msg b/packages/dimos-generated/custom/dimos_msgs/msg/TrajectoryStatus.msg new file mode 100644 index 00000000000..4baa51c0431 --- /dev/null +++ b/packages/dimos-generated/custom/dimos_msgs/msg/TrajectoryStatus.msg @@ -0,0 +1,15 @@ +# Copyright 2026 Dimensional Inc. +# SPDX-License-Identifier: Apache-2.0 + +std_msgs/Header header +uint8 IDLE=0 +uint8 EXECUTING=1 +uint8 COMPLETED=2 +uint8 ABORTED=3 +uint8 FAULT=4 +uint8 state +# Fraction completed, in [0, 1]. +float64 progress +builtin_interfaces/Duration time_elapsed +builtin_interfaces/Duration time_remaining +string error diff --git a/packages/dimos-generated/custom/dimos_msgs/msg/VideoStats.msg b/packages/dimos-generated/custom/dimos_msgs/msg/VideoStats.msg new file mode 100644 index 00000000000..3472623a7a7 --- /dev/null +++ b/packages/dimos-generated/custom/dimos_msgs/msg/VideoStats.msg @@ -0,0 +1,11 @@ +std_msgs/Header header +float64 fps +float64 kbps +uint32 width +uint32 height +float64 loss_pct +float64 jitter_buffer_ms +float64 decode_ms +uint64 frames_dropped +uint64 freezes +float64 e2e_latency_ms diff --git a/packages/dimos-generated/pyproject.toml b/packages/dimos-generated/pyproject.toml new file mode 100644 index 00000000000..1f0d06d4dbb --- /dev/null +++ b/packages/dimos-generated/pyproject.toml @@ -0,0 +1,23 @@ +[build-system] +requires = ["setuptools>=70", "wheel", "dimos-cdrgen==0.1.0"] +build-backend = "setuptools.build_meta" + +[project] +name = "dimos-generated" +version = "0.1.0" +description = "Generated Python message source and complete CDR schemas" +requires-python = ">=3.10" +dependencies = ["numpy>=1.26.4", "rosbags==0.11.0", "dimos-cdrgen==0.1.0"] + +[project.entry-points."dimos.messages"] +dimos_generated = "dimos_generated_schemas.provider" + +[tool.setuptools.package-data] +dimos_generated = ["py.typed", "*.pyi", "**/*.pyi"] +dimos_generated_schemas = ["schemas.json", "schemas/**/*", "package/**/*"] + +[tool.dimos.messages] +source = "interfaces" +module = "dimos_generated" +catalog = "catalog.json" +resources = ["schema-sources.json", "interfaces/licenses/dimos_msgs-LICENSE", "interfaces/licenses/ros2_common_interfaces_geometry_msgs_LICENSE", "interfaces/licenses/ros2_common_interfaces_nav_msgs_LICENSE", "interfaces/licenses/ros2_common_interfaces_sensor_msgs_LICENSE", "interfaces/licenses/ros2_common_interfaces_shape_msgs_LICENSE", "interfaces/licenses/ros2_common_interfaces_std_msgs_LICENSE", "interfaces/licenses/ros2_common_interfaces_trajectory_msgs_LICENSE", "interfaces/licenses/ros2_common_interfaces_visualization_msgs_LICENSE", "interfaces/licenses/ros2_rcl_interfaces_licenses_ros2_rcl_interfaces_LICENSE", "interfaces/licenses/ros2_geometry2_licenses_ros2_geometry2_LICENSE", "interfaces/licenses/ros-perception_vision_msgs_licenses_ros-perception_vision_msgs_LICENSE", "interfaces/licenses/ros2_rosidl_licenses_ros2_rosidl_LICENSE", "interfaces/licenses/foxglove_schemas_licenses_foxglove_schemas_LICENSE"] diff --git a/packages/dimos-generated/schema-sources.json b/packages/dimos-generated/schema-sources.json new file mode 100644 index 00000000000..65e2d266b09 --- /dev/null +++ b/packages/dimos-generated/schema-sources.json @@ -0,0 +1,343 @@ +{ + "format": 1, + "sources": [ + { + "repository": "ros2/common_interfaces", + "revision": "a941f14bb318d8d904505ed935ccbb97f24a70a4", + "url": "https://codeload.github.com/ros2/common_interfaces/tar.gz/a941f14bb318d8d904505ed935ccbb97f24a70a4", + "sha256": "4140cc780aec296bcd88c3049ba541783d40fbb7dd0e5919e621a85e314416ba", + "prefix": "common_interfaces-a941f14bb318d8d904505ed935ccbb97f24a70a4/", + "files": { + "licenses/ros2_common_interfaces_geometry_msgs_LICENSE": { + "path": "geometry_msgs/LICENSE", + "sha256": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30" + }, + "geometry_msgs/msg/Point.msg": { + "path": "geometry_msgs/msg/Point.msg", + "sha256": "eb4c07e591cf0269ccb17245dcd4f998162feb09cc8add85fa082c8a30bfc91d" + }, + "geometry_msgs/msg/Point32.msg": { + "path": "geometry_msgs/msg/Point32.msg", + "sha256": "acade2dacb4f1f7988f34e8221079eb1c757f51e8ef48adb5651f7dc478fed59" + }, + "geometry_msgs/msg/PointStamped.msg": { + "path": "geometry_msgs/msg/PointStamped.msg", + "sha256": "c58b03c27604f45e9b0fd2f1b327dcbada7d6a389beb8c060d448abc25e76bfc" + }, + "geometry_msgs/msg/Polygon.msg": { + "path": "geometry_msgs/msg/Polygon.msg", + "sha256": "43679118501e3b294349c9ad73af9f03b476ef77c7096cd79b4ce46646823056" + }, + "geometry_msgs/msg/Pose.msg": { + "path": "geometry_msgs/msg/Pose.msg", + "sha256": "3eceb77c63ebbb544c11d7f991e475e9819e0cf534deb1a879392c1b3dc997de" + }, + "geometry_msgs/msg/PoseArray.msg": { + "path": "geometry_msgs/msg/PoseArray.msg", + "sha256": "3f58a91730c78dbc5ec5092131945ccdfeeb775aa0f02df7ff09f6c979b1d398" + }, + "geometry_msgs/msg/PoseStamped.msg": { + "path": "geometry_msgs/msg/PoseStamped.msg", + "sha256": "31898ab0eb64a6c44c27ab4959819a32ec3bc3ee847c8fe1b01c897d48e311e5" + }, + "geometry_msgs/msg/PoseWithCovariance.msg": { + "path": "geometry_msgs/msg/PoseWithCovariance.msg", + "sha256": "a22f234e91b9fcd4ba0c5b533496b43c62d7f6ade39082212ac9835679d29f94" + }, + "geometry_msgs/msg/Quaternion.msg": { + "path": "geometry_msgs/msg/Quaternion.msg", + "sha256": "298495eb67a139642ffd37cc9029eae085e6c39a8789828b7517868a487939ed" + }, + "geometry_msgs/msg/Transform.msg": { + "path": "geometry_msgs/msg/Transform.msg", + "sha256": "c8916279f0a429dd9561158bd2133bc4e2d780277c3c594116b240a27e7a2993" + }, + "geometry_msgs/msg/TransformStamped.msg": { + "path": "geometry_msgs/msg/TransformStamped.msg", + "sha256": "f6e137c205e9187ac1dafdfbace7435de58bb3779a55e9c6b52c2cb513785c42" + }, + "geometry_msgs/msg/Twist.msg": { + "path": "geometry_msgs/msg/Twist.msg", + "sha256": "ed471ef861f65af991b1f64d66ef941dd41dd4c0702f6222512b1a16c62d58b0" + }, + "geometry_msgs/msg/TwistStamped.msg": { + "path": "geometry_msgs/msg/TwistStamped.msg", + "sha256": "ffc9d5925412410b28d601c55cf386a0b3e4d5dba00920fbafb98d7201f582ca" + }, + "geometry_msgs/msg/TwistWithCovariance.msg": { + "path": "geometry_msgs/msg/TwistWithCovariance.msg", + "sha256": "5690a1f109d4962c73b5ca7f3673c48052d02f37b6a38fe2fb37c899cf555c45" + }, + "geometry_msgs/msg/Vector3.msg": { + "path": "geometry_msgs/msg/Vector3.msg", + "sha256": "d8b9ea9aad1f424faf4d2b94dae1e1368af1e5d59de11aeed019399cff7f9e1d" + }, + "geometry_msgs/msg/Wrench.msg": { + "path": "geometry_msgs/msg/Wrench.msg", + "sha256": "d9667abd3d2a67d5624113fa07a647b0d4806bf89d21c8a5cf914905a036bf25" + }, + "licenses/ros2_common_interfaces_nav_msgs_LICENSE": { + "path": "nav_msgs/LICENSE", + "sha256": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30" + }, + "nav_msgs/msg/MapMetaData.msg": { + "path": "nav_msgs/msg/MapMetaData.msg", + "sha256": "6868a7d604c6cc033dd0adfac8a0adb0a6dedae1b7b140dbb47c83f3bcc6f140" + }, + "nav_msgs/msg/OccupancyGrid.msg": { + "path": "nav_msgs/msg/OccupancyGrid.msg", + "sha256": "3e54ec7e662bdd6d5528efab99c6e34ce3eed27ce628721fcdb4e5e1bbf8188b" + }, + "nav_msgs/msg/Odometry.msg": { + "path": "nav_msgs/msg/Odometry.msg", + "sha256": "bb00547ddf498cdbae46fd991d9d85a59f507e12e7cf01fb18a86f1111524f4f" + }, + "nav_msgs/msg/Path.msg": { + "path": "nav_msgs/msg/Path.msg", + "sha256": "fc1e2eff6c2bd63fb92b6cf29bad29873b026d7abe00d3a68965b40668bfdd5b" + }, + "licenses/ros2_common_interfaces_sensor_msgs_LICENSE": { + "path": "sensor_msgs/LICENSE", + "sha256": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30" + }, + "sensor_msgs/msg/BatteryState.msg": { + "path": "sensor_msgs/msg/BatteryState.msg", + "sha256": "ce13430f3c107274fb7123a6d1e79a9f83974d78cb0be1721695129e49240b25" + }, + "sensor_msgs/msg/CameraInfo.msg": { + "path": "sensor_msgs/msg/CameraInfo.msg", + "sha256": "1fced83678f5f2708aff8540987594692452de9f0b43905ce3bfba689226f3aa" + }, + "sensor_msgs/msg/CompressedImage.msg": { + "path": "sensor_msgs/msg/CompressedImage.msg", + "sha256": "75ca1003981c407148ff94a3470760985dd69233b8287a5d52848d45a312f144" + }, + "sensor_msgs/msg/Image.msg": { + "path": "sensor_msgs/msg/Image.msg", + "sha256": "575cd3434771916c2b551db8ac484522ecef1d6105196e043a305887d2730704" + }, + "sensor_msgs/msg/Imu.msg": { + "path": "sensor_msgs/msg/Imu.msg", + "sha256": "5800b7c2e6d3afed966ae229b1559f6e762c792ad34a88e55ad4288d8bbbd34b" + }, + "sensor_msgs/msg/JointState.msg": { + "path": "sensor_msgs/msg/JointState.msg", + "sha256": "711d1771a002c7190e5bbe746a163a67477c1e2a45482a64f1fe339815ca6f5d" + }, + "sensor_msgs/msg/Joy.msg": { + "path": "sensor_msgs/msg/Joy.msg", + "sha256": "5a7d133e7dc82f531e03bd4ff92c9240a828bb6ceb6f19d5cd767d5372adb757" + }, + "sensor_msgs/msg/PointCloud2.msg": { + "path": "sensor_msgs/msg/PointCloud2.msg", + "sha256": "22699bfd6c68be148363a2e889408833a5a37d3464ea20032d1c757336b80f2a" + }, + "sensor_msgs/msg/PointField.msg": { + "path": "sensor_msgs/msg/PointField.msg", + "sha256": "6e6d5d51d2e464d3074b44b112f219e67fcdc0b280260d93f8cefd9710ec972e" + }, + "sensor_msgs/msg/RegionOfInterest.msg": { + "path": "sensor_msgs/msg/RegionOfInterest.msg", + "sha256": "9c07010ab5ffddd1202876a778b44c99cafa780bc0503041c3fd935870a14c6a" + }, + "licenses/ros2_common_interfaces_shape_msgs_LICENSE": { + "path": "shape_msgs/LICENSE", + "sha256": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30" + }, + "shape_msgs/msg/SolidPrimitive.msg": { + "path": "shape_msgs/msg/SolidPrimitive.msg", + "sha256": "b3ec61569b2b4e2c37428e0625d4a360c00c95fc9ad4c94f9c8399225b98b2d8" + }, + "licenses/ros2_common_interfaces_std_msgs_LICENSE": { + "path": "std_msgs/LICENSE", + "sha256": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30" + }, + "std_msgs/msg/Bool.msg": { + "path": "std_msgs/msg/Bool.msg", + "sha256": "d989b95f2ba14d15eff5b274b5d1f379b938aaea2157d8bd707f942457ae18bf" + }, + "std_msgs/msg/Empty.msg": { + "path": "std_msgs/msg/Empty.msg", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "std_msgs/msg/Float32.msg": { + "path": "std_msgs/msg/Float32.msg", + "sha256": "fb905efdb5c7902255cad5a6e4953158384238d4652d9e7ed68d134da052f3af" + }, + "std_msgs/msg/Header.msg": { + "path": "std_msgs/msg/Header.msg", + "sha256": "d2cea14630e39ed0fa5b432ba9160a7c38855b9427d3344f99e83e83facb53c2" + }, + "std_msgs/msg/Int32.msg": { + "path": "std_msgs/msg/Int32.msg", + "sha256": "4614a6d0154436fb9ff12b0b7637816f42a550e4f5e0c4705bedf11293b4f7a7" + }, + "std_msgs/msg/Int64.msg": { + "path": "std_msgs/msg/Int64.msg", + "sha256": "117752e7d1f0e4709749c04a9251dcece8545c0dac7bbb6fb8f31262d6ace238" + }, + "std_msgs/msg/Int8.msg": { + "path": "std_msgs/msg/Int8.msg", + "sha256": "2ad86a195e6c5d3415b5b48f4c248c45bfe05d636735f88d821c44ab660c7f6f" + }, + "std_msgs/msg/MultiArrayDimension.msg": { + "path": "std_msgs/msg/MultiArrayDimension.msg", + "sha256": "94927d0ee40f1a1d9bf7bdddbca803e8b6e6d315d70c7295a9b0d2d6c380abed" + }, + "std_msgs/msg/MultiArrayLayout.msg": { + "path": "std_msgs/msg/MultiArrayLayout.msg", + "sha256": "8f059b66610c5fe0532e3f12ff1022a10671caebf773f00816fd4c9303626914" + }, + "std_msgs/msg/String.msg": { + "path": "std_msgs/msg/String.msg", + "sha256": "2022b3f1c32b578ff8d54a9948a51a10778761e0ad4ba60e50ae51292ca16884" + }, + "std_msgs/msg/UInt32.msg": { + "path": "std_msgs/msg/UInt32.msg", + "sha256": "4db7deaede98bebcc6ddfa951cf4d55aaad57909f38a8c346a12ae25df2e58ae" + }, + "std_msgs/msg/UInt32MultiArray.msg": { + "path": "std_msgs/msg/UInt32MultiArray.msg", + "sha256": "3a25d8463602c0f3eff61a14c3c17c10ef819aadf7ef19179e95cfdaea07b3ce" + }, + "licenses/ros2_common_interfaces_trajectory_msgs_LICENSE": { + "path": "trajectory_msgs/LICENSE", + "sha256": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30" + }, + "trajectory_msgs/msg/JointTrajectory.msg": { + "path": "trajectory_msgs/msg/JointTrajectory.msg", + "sha256": "d63cda4a5ec81824ed4acd737e6b5903449fb1a7e2f5cdcdcc4c49285f01117c" + }, + "trajectory_msgs/msg/JointTrajectoryPoint.msg": { + "path": "trajectory_msgs/msg/JointTrajectoryPoint.msg", + "sha256": "2358055d26d27c0c302e921f90d5aa59cb5feb3e22937f8ac98314b0c52ba8f4" + }, + "licenses/ros2_common_interfaces_visualization_msgs_LICENSE": { + "path": "visualization_msgs/LICENSE", + "sha256": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30" + } + } + }, + { + "repository": "ros2/rcl_interfaces", + "revision": "7aa3caf43377ea6ad615bc1040832e2c7566bfbe", + "url": "https://codeload.github.com/ros2/rcl_interfaces/tar.gz/7aa3caf43377ea6ad615bc1040832e2c7566bfbe", + "sha256": "d984942035cd4df4f60c92d6038cecbfc3f5a01a1977c1b3199cee45cd67281c", + "prefix": "rcl_interfaces-7aa3caf43377ea6ad615bc1040832e2c7566bfbe/", + "files": { + "builtin_interfaces/msg/Duration.msg": { + "path": "builtin_interfaces/msg/Duration.msg", + "sha256": "57da13a4201e7d258a2931323145b953e47e46967494e62ba66c2faca4fbade2" + }, + "builtin_interfaces/msg/Time.msg": { + "path": "builtin_interfaces/msg/Time.msg", + "sha256": "dc5a01ddde3aecffee21eb24974fe77cc969f873218a2b1811aa0ac8a456b8bd" + }, + "licenses/ros2_rcl_interfaces_licenses_ros2_rcl_interfaces_LICENSE": { + "path": "LICENSE", + "sha256": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30" + } + } + }, + { + "repository": "ros2/geometry2", + "revision": "f702874b1c8535d6a038230ab2cda0ba5d521ebd", + "url": "https://codeload.github.com/ros2/geometry2/tar.gz/f702874b1c8535d6a038230ab2cda0ba5d521ebd", + "sha256": "d24c3fb17cc0087b2fc7f0afac28ad74eee20c988aca4247c201f76a7031f621", + "prefix": "geometry2-f702874b1c8535d6a038230ab2cda0ba5d521ebd/", + "files": { + "licenses/ros2_geometry2_licenses_ros2_geometry2_LICENSE": { + "path": "LICENSE", + "sha256": "1b1e5ebcad699924203feced7205a4bbdf4f153d34065a19a8a4e107cf1e154b" + }, + "tf2_msgs/msg/TFMessage.msg": { + "path": "tf2_msgs/msg/TFMessage.msg", + "sha256": "f3fca610a59b31ee4c7b740522ecdd0fd8c76002170088111409e4df513f1dfc" + } + } + }, + { + "repository": "ros-perception/vision_msgs", + "revision": "adbf56af9f77e3c8ab2552e25dc99e4a8a77fb27", + "url": "https://codeload.github.com/ros-perception/vision_msgs/tar.gz/adbf56af9f77e3c8ab2552e25dc99e4a8a77fb27", + "sha256": "a2bd8a8a5b09eb2ed1c94f3bd163aafabced23df107a414414dfcb1f57358971", + "prefix": "vision_msgs-adbf56af9f77e3c8ab2552e25dc99e4a8a77fb27/", + "files": { + "licenses/ros-perception_vision_msgs_licenses_ros-perception_vision_msgs_LICENSE": { + "path": "LICENSE", + "sha256": "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4" + }, + "vision_msgs/msg/BoundingBox2D.msg": { + "path": "vision_msgs/msg/BoundingBox2D.msg", + "sha256": "74ed6347e3c8f74b884a81c5a36925c0e320836c1a5ea55df2b8d03574cc25b1" + }, + "vision_msgs/msg/BoundingBox3D.msg": { + "path": "vision_msgs/msg/BoundingBox3D.msg", + "sha256": "30502a6e247a84d87b4c2c0262fd07ce6ba3fa8d6d24e6e39c1522d7e469c450" + }, + "vision_msgs/msg/Detection2D.msg": { + "path": "vision_msgs/msg/Detection2D.msg", + "sha256": "868ffec733235c01bb5bfba3f3c528f193ea0fb3069650aaf95383a7fa9a8200" + }, + "vision_msgs/msg/Detection2DArray.msg": { + "path": "vision_msgs/msg/Detection2DArray.msg", + "sha256": "bb2eeef88b466103b89a7ae9f927164d2064e9d94e8455bb98ad2b69130331ae" + }, + "vision_msgs/msg/Detection3D.msg": { + "path": "vision_msgs/msg/Detection3D.msg", + "sha256": "68885eeededfc57231f171f2b3eb97f0d0a18580ca08307bc60b9b87216df985" + }, + "vision_msgs/msg/Detection3DArray.msg": { + "path": "vision_msgs/msg/Detection3DArray.msg", + "sha256": "077f34a634e6de6654265af5b26508eea1105bef72395cffae50fde61b713c41" + }, + "vision_msgs/msg/ObjectHypothesis.msg": { + "path": "vision_msgs/msg/ObjectHypothesis.msg", + "sha256": "6224cb18c032fe062d18859089444f4e1f311ab478e45d937fdfac18a980695b" + }, + "vision_msgs/msg/ObjectHypothesisWithPose.msg": { + "path": "vision_msgs/msg/ObjectHypothesisWithPose.msg", + "sha256": "162639c82b24a8fc4f3e93a4dc91704928d5cff9d39d169515bb748eccf4d573" + }, + "vision_msgs/msg/Point2D.msg": { + "path": "vision_msgs/msg/Point2D.msg", + "sha256": "6b99220dccc3193a603fb40d6a2880b4de67fb2175121c5683d0bde9f71e3733" + }, + "vision_msgs/msg/Pose2D.msg": { + "path": "vision_msgs/msg/Pose2D.msg", + "sha256": "0cdb3bc9872a5c3379a5122c14d03ec13d59b92752d3b444cc41592492258ab2" + } + } + }, + { + "repository": "ros2/rosidl", + "revision": "85fa592b698b0f665e3120f48fac0d35e2f7d8a4", + "url": "https://codeload.github.com/ros2/rosidl/tar.gz/85fa592b698b0f665e3120f48fac0d35e2f7d8a4", + "sha256": "ba5369bca27297f606bf3396a9e066140d07ce754d8659159148102b089e9510", + "prefix": "rosidl-85fa592b698b0f665e3120f48fac0d35e2f7d8a4/", + "files": { + "licenses/ros2_rosidl_licenses_ros2_rosidl_LICENSE": { + "path": "LICENSE", + "sha256": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30" + } + } + }, + { + "repository": "foxglove/schemas", + "revision": "e86a94e9d4d259cdde71872f18336a7a055bf9ba", + "url": "https://codeload.github.com/foxglove/schemas/tar.gz/e86a94e9d4d259cdde71872f18336a7a055bf9ba", + "sha256": "dcfa8049d34214bd26d7a13f6a7da214e08228a65a0135bac52077c1ca12cf47", + "prefix": "foxglove-sdk-e86a94e9d4d259cdde71872f18336a7a055bf9ba/", + "files": { + "foxglove_msgs/msg/CompressedVideo.msg": { + "path": "schemas/ros2/CompressedVideo.msg", + "sha256": "83d044efaefc90291cdd56cd36b2ef6b190748c1df860d1eca7df77328174324" + }, + "licenses/foxglove_schemas_licenses_foxglove_schemas_LICENSE": { + "path": "LICENSE", + "sha256": "da11235665c17d4c1634072dae92b8ba1b38d6fdde2ccf19a6bbede33253f58d" + } + } + } + ] +} diff --git a/packages/dimos-generated/setup.py b/packages/dimos-generated/setup.py new file mode 100644 index 00000000000..c820ad85a65 --- /dev/null +++ b/packages/dimos-generated/setup.py @@ -0,0 +1,22 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Build the curated DimOS catalog with the published generator.""" + +from pathlib import Path + +from dimos_cdrgen.source_package import setup_arguments +from setuptools import setup + +setup(**setup_arguments(Path(__file__).resolve().parent)) diff --git a/pyproject.toml b/pyproject.toml index 51bec617ddd..86c60a00ef1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -100,6 +100,8 @@ classifiers = [ ] dependencies = [ + "dimos-generated==0.1.0", + "dimos-cdrgen==0.1.0", "matplotlib>=3.7.1", # Rerun initializes point-cloud colormaps for all streams. # Transport Protocols "dimos-lcm>=0.1.4", @@ -393,6 +395,9 @@ all = [ ] [dependency-groups] +# Lightweight, locked environment for deterministic built-in source alignment. +message-codegen = ["dimos-cdrgen[prepare]==0.1.0", "ruff==0.14.3", "pytest==8.3.5", "rosbags==0.11.0", "tomli>=2; python_version < '3.11'"] + # For autofix.yml autofix = ["ruff==0.14.3"] @@ -426,6 +431,8 @@ project-deps = [ ] tests = [ + "dimos-cdrgen==0.1.0", + "build>=1.2.2", # Test runner "pytest==8.3.5", "pytest-asyncio==1.4.0", @@ -483,6 +490,7 @@ browser-tests = [ # Lint / format / type-check tooling for the dedicated `lint` CI job. lint = [ + "dimos-cdrgen==0.1.0", # Lint / format / type-check "ruff==0.14.3", "mypy==1.19.0", @@ -537,7 +545,7 @@ dev = [ required-version = ">=0.9.25" default-groups = ["tests"] exclude-newer = "7 days" -exclude-newer-package = { dimos-viewer = false, dimos-lcm = false, lcm-dimos-fork = false, roboplan = false, md-babel-py = false, can-motor-control = false, edgetam-dimos = false, dim-odom = false, eclipse-zenoh = false } +exclude-newer-package = { dimos-cdrgen = false, dimos-viewer = false, dimos-lcm = false, lcm-dimos-fork = false, roboplan = false, md-babel-py = false, can-motor-control = false, edgetam-dimos = false, dim-odom = false, eclipse-zenoh = false } constraint-dependencies = [ # TODO(PY311): drop this fork. onnxruntime(-gpu) 1.24 dropped cp310 # wheels, so 3.10 environments resolve 1.23.x (matching what a 3.10 @@ -569,6 +577,7 @@ override-dependencies = [ ] [tool.uv.sources] +dimos-generated = { path = "packages/dimos-generated", editable = true } # CUDA builds are not published for macOS or non-x86_64 Linux. Those platforms # fall back to PyPI. torch = [ @@ -832,6 +841,7 @@ follow_imports = "skip" [tool.pytest.ini_options] testpaths = ["dimos"] +markers = ["native_e2e: compiled native consumer acceptance in the dedicated workflow"] env = [ "GOOGLE_MAPS_API_KEY=AIzafake_google_key", "PYTHONWARNINGS=ignore:cupyx.jit.rawkernel is experimental:FutureWarning", diff --git a/scripts/generate_builtin_messages.py b/scripts/generate_builtin_messages.py new file mode 100644 index 00000000000..f9390edcfc9 --- /dev/null +++ b/scripts/generate_builtin_messages.py @@ -0,0 +1,76 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Regenerate build artifacts; --check rejects drift without rewriting them.""" + +import argparse +from pathlib import Path +import shutil +import tempfile + +from dimos_cdrgen.source_package import prepare + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--check", action="store_true") + args = parser.parse_args() + root = Path(__file__).resolve().parents[1] + target = root / "packages/dimos-generated/build/message-source/python" + with tempfile.TemporaryDirectory(prefix="dimos-source-") as temporary: + output = Path(temporary) + prepare(root / "packages/dimos-generated", output) + source = output / "python" + packages = [source / "dimos_generated", source / "dimos_generated_schemas"] + expected = { + str(path.relative_to(source)): path.read_bytes() + for package in packages + for path in package.rglob("*") + if path.is_file() + } + actual = { + str(path.relative_to(target)): path.read_bytes() + for path in target.rglob("*") + if path.is_file() + and path.relative_to(target).parts[0] + not in {"MANIFEST.in", "message-package.json", "pyproject.toml", "setup.py"} + and "__pycache__" not in path.parts + and path.suffix != ".pyc" + and not any(part.endswith(".egg-info") for part in path.parts) + } + if args.check: + if actual != expected: + missing = sorted(expected.keys() - actual.keys()) + stale = sorted(actual.keys() - expected.keys()) + changed = sorted( + name + for name in actual.keys() & expected.keys() + if actual[name] != expected[name] + ) + parser.error( + f"Generated source drift: missing={missing}, stale={stale}, changed={changed}. Run python -m scripts.generate_builtin_messages" + ) + print("Built-in generated Python/C++/Rust sources match canonical definitions") + return + target.mkdir(parents=True, exist_ok=True) + for package in packages: + destination = target / package.name + if destination.exists(): + shutil.rmtree(destination) + shutil.copytree(package, destination) + print(f"Generated built-in source in {target}") + + +if __name__ == "__main__": + main() diff --git a/scripts/install.sh b/scripts/install.sh index 5edaa4fae06..58fe38d2456 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -803,6 +803,7 @@ do_install_dev() { info "Developer installs use locked PyTorch builds; Linux x86_64 includes CUDA libraries even for CPU use." dim "will run: uv sync ${sync_args[*]}" if ! prompt_confirm "Install dependencies now?" yes; then INSTALL_DEPS=0; return; fi + project_cmd uv run --no-project --with "dimos-cdrgen[prepare]==0.1.0" python -m scripts.prepare_builtin_sources project_cmd uv sync "${sync_args[@]}" ok "developer environment ready in $dir" } diff --git a/scripts/package_messages.sh b/scripts/package_messages.sh new file mode 100644 index 00000000000..7691bfdb2fa --- /dev/null +++ b/scripts/package_messages.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +set -euo pipefail +cd "$(dirname "$0")/.." +if [[ $# -ne 0 ]]; then + echo "Message version comes from packages/dimos-generated/pyproject.toml; no version argument is accepted" >&2 + exit 2 +fi +"${DIMOS_CODEGEN_PYTHON:-$PWD/.venv/bin/python}" - <<'PY' +import os +from pathlib import Path +import shutil +import subprocess +import tarfile +import tomllib +from dimos_cdrgen.source_package import prepare +output = Path("build/message-codegen/release") +version = tomllib.loads(Path("packages/dimos-generated/pyproject.toml").read_text())["project"]["version"] +prepare(Path("packages/dimos-generated").resolve(), output) +resources = output / "python/dimos_generated_schemas/package" +metadata = output / "metadata" +metadata.mkdir(exist_ok=True) +for file in resources.iterdir(): + if file.is_file() and file.name not in {"message-package.json", "schemas.json"}: + shutil.copy2(file, metadata / file.name) +shutil.copytree(metadata, output / "rust/source-metadata", dirs_exist_ok=True) +subprocess.run(["cargo", "package", "--manifest-path", str(output / "rust/Cargo.toml"), "--allow-dirty", *(["--offline"] if os.environ.get("DIMOS_OFFLINE") == "1" else [])], check=True) +dist = output / "dist" +dist.mkdir(exist_ok=True) +# Native ROSIDL requires generated typesupport/support libraries, not just headers. +# Ship relocatable source inputs; the shared native preparation core builds them. +archive = dist / f"dimos-messages-sources-{version}.tar.gz" +with tarfile.open(archive, "w:gz") as bundle: + for name in ["cpp", "schemas", "schemas.json", "message-package.json", "metadata"]: + bundle.add(output / name, arcname=name) +shutil.copy2(output / f"rust/target/package/dimos-generated-messages-{version}.crate", dist) +print(archive.resolve()) +PY diff --git a/scripts/prepare_builtin_sources.py b/scripts/prepare_builtin_sources.py new file mode 100644 index 00000000000..d2dff83e23c --- /dev/null +++ b/scripts/prepare_builtin_sources.py @@ -0,0 +1,48 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Explicitly prepare pinned upstream data and local DimOS message inputs.""" + +import argparse +from pathlib import Path +import shutil + +from dimos_cdrgen.source_inputs import prepare_sources + +ROOT = Path(__file__).resolve().parents[1] +PROJECT = ROOT / "packages/dimos-generated" + + +def prepare(cache: Path, *, offline: bool = False, project: Path = PROJECT) -> Path: + upstream = cache / "upstream" + prepare_sources(project / "schema-sources.json", upstream, cache / "archives", offline=offline) + target = project / "interfaces" + if target.exists(): + shutil.rmtree(target) + shutil.copytree(upstream, target) + shutil.copytree(project / "custom/dimos_msgs/msg", target / "dimos_msgs/msg") + shutil.copyfile(project / "custom/dimos_msgs/LICENSE", target / "licenses/dimos_msgs-LICENSE") + return target + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--cache", type=Path, default=ROOT / "build/builtin-source-cache") + parser.add_argument("--offline", action="store_true") + args = parser.parse_args() + print(prepare(args.cache, offline=args.offline)) + + +if __name__ == "__main__": + main() diff --git a/scripts/test_builtin_message_source.sh b/scripts/test_builtin_message_source.sh new file mode 100644 index 00000000000..800c31aa087 --- /dev/null +++ b/scripts/test_builtin_message_source.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +set -euo pipefail +cd "$(dirname "$0")/.." +uv build --wheel --out-dir build/message-codegen/dist packages/dimos-generated +bash scripts/test_message_packages.sh diff --git a/scripts/test_message_mcap.sh b/scripts/test_message_mcap.sh new file mode 100644 index 00000000000..f43414b015a --- /dev/null +++ b/scripts/test_message_mcap.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Supported custom DeviceReading, separately from the unchanged bounded Telemetry fixture. +cd "$(dirname "$0")/.." +output="$PWD/build/message-codegen/viewers" +mkdir -p "$output/evidence" +python="${DIMOS_RUNTIME_PYTHON:-${DIMOS_CODEGEN_PYTHON:-$PWD/.venv/bin/python}}" +"$python" - <<'PYTHON' +from importlib.util import find_spec +from pathlib import Path +from dimos_cdrgen.generate import generate +from dimos_cdrgen.ownership import Dependency +spec = find_spec("dimos_generated_schemas") +assert spec is not None and spec.origin is not None +builtin = Dependency.load(Path(spec.origin).parent / "package") +generate([Path("examples/message-codegen/user-story")], Path("build/message-codegen/viewer-message"), + ["story_msgs/msg/DeviceReading"], "story_messages", dependencies=(builtin,), languages=("python",)) +PYTHON +"$python" -m pip install --no-deps --no-build-isolation --target "$output/site" --upgrade \ + build/message-codegen/viewer-message/python +export PYTHONPATH="$output/site:$PWD${PYTHONPATH:+:$PYTHONPATH}" +"$python" -m pytest dimos/protocol/test_cdr_mcap.py --noconftest -o addopts='' -q \ + | tee "$output/evidence/pytest.txt" +"$python" examples/message-codegen/demo_mcap.py --output "$output/demo.mcap" \ + | tee "$output/evidence/producer.txt" +if [[ ! -d examples/message-codegen/viewer-checker/node_modules ]]; then + npm ci --ignore-scripts --prefix examples/message-codegen/viewer-checker +fi +npm ls --prefix examples/message-codegen/viewer-checker --depth=0 +node examples/message-codegen/viewer-checker/check.mjs "$output/demo.mcap" \ + | tee "$output/evidence/foxglove.txt" +# The native Rerun executable has no Python message-provider imports. +unset PYTHONPATH +export RERUN_ANALYTICS_ENABLED=false +"${DIMOS_RERUN_BIN:-$(dirname "$python")/rerun}" mcap convert "$output/demo.mcap" \ + -d ros2msg -d ros2_reflection --disable-raw-fallback -o "$output/demo.rrd" +"${DIMOS_RERUN_BIN:-$(dirname "$python")/rerun}" rrd print "$output/demo.rrd" -v > "$output/evidence/rerun-summary.txt" +"${DIMOS_RERUN_BIN:-$(dirname "$python")/rerun}" rrd print "$output/demo.rrd" --entity /telemetry -vvv \ + > "$output/evidence/rerun-telemetry.txt" +"$python" examples/message-codegen/check_rerun_mcap.py "$output/evidence" diff --git a/scripts/test_message_packages.sh b/scripts/test_message_packages.sh new file mode 100644 index 00000000000..4454eaeb21b --- /dev/null +++ b/scripts/test_message_packages.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +set -euo pipefail +cd "$(dirname "$0")/.." +"${DIMOS_CODEGEN_PYTHON:-$PWD/.venv/bin/python}" -m pytest --noconftest -o addopts='' -q \ + dimos/message_codegen/test_builtin_codec.py dimos/message_codegen/test_builtin_catalog.py dimos/message_codegen/test_builtin_alignment.py \ + dimos/message_codegen/test_builtin_install.py dimos/message_codegen/test_builtin_preparation.py diff --git a/uv.lock b/uv.lock index 5451ba6099c..3d9e8085c79 100644 --- a/uv.lock +++ b/uv.lock @@ -36,14 +36,15 @@ exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for exclude-newer-span = "P7D" [options.exclude-newer-package] -dimos-viewer = false +can-motor-control = false +dim-odom = false +dimos-cdrgen = false dimos-lcm = false +dimos-viewer = false eclipse-zenoh = false edgetam-dimos = false -can-motor-control = false lcm-dimos-fork = false md-babel-py = false -dim-odom = false roboplan = false [manifest] @@ -881,12 +882,12 @@ resolution-markers = [ "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "absl-py", marker = "python_full_version < '3.11'" }, - { name = "jax", version = "0.6.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "jaxlib", version = "0.6.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "toolz", marker = "python_full_version < '3.11'" }, - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, + { name = "absl-py" }, + { name = "jax", version = "0.6.2", source = { registry = "https://pypi.org/simple" } }, + { name = "jaxlib", version = "0.6.2", source = { registry = "https://pypi.org/simple" } }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" } }, + { name = "toolz" }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/77/70/53c7d404ce9e2a94009aea7f77ef6e392f6740e071c62683a506647c520f/chex-0.1.90.tar.gz", hash = "sha256:d3c375aeb6154b08f1cccd2bee4ed83659ee2198a6acf1160d2fe2e4a6c87b5c", size = 92363, upload-time = "2025-07-23T19:50:47.945Z" } wheels = [ @@ -916,12 +917,12 @@ resolution-markers = [ "python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "absl-py", marker = "python_full_version >= '3.11'" }, - { name = "jax", version = "0.9.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "jaxlib", version = "0.9.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "toolz", marker = "python_full_version >= '3.11'" }, - { name = "typing-extensions", marker = "python_full_version >= '3.11'" }, + { name = "absl-py" }, + { name = "jax", version = "0.9.0.1", source = { registry = "https://pypi.org/simple" } }, + { name = "jaxlib", version = "0.9.0.1", source = { registry = "https://pypi.org/simple" } }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" } }, + { name = "toolz" }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/5b/7d/812f01e7b2ddf28a0caa8dde56bd951a2c8f691c9bbfce38d469458d1502/chex-0.1.91.tar.gz", hash = "sha256:65367a521415ada905b8c0222b0a41a68337fcadf79a1fb6fc992dbd95dd9f76", size = 90302, upload-time = "2025-09-01T21:49:32.834Z" } wheels = [ @@ -1237,7 +1238,7 @@ name = "cmeel-yaml-cpp" version = "0.8.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "cmeel", marker = "sys_platform != 'win32'" }, + { name = "cmeel" }, ] sdist = { url = "https://files.pythonhosted.org/packages/51/51/d67d8dd9de647666c6e8a018821f7f11313551c14d58aa052092df4ec116/cmeel_yaml_cpp-0.8.0.tar.gz", hash = "sha256:ac4d6f6fda2cda2c44bc3394fba84ca2f2e372808bd1ee4dc859dd8eaeeeba0d", size = 1027162, upload-time = "2023-11-16T22:51:05.955Z" } wheels = [ @@ -1323,7 +1324,7 @@ name = "coloredlogs" version = "15.0.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "humanfriendly", marker = "python_full_version < '3.11'" }, + { name = "humanfriendly" }, ] sdist = { url = "https://files.pythonhosted.org/packages/cc/c7/eed8f27100517e8c0e6b923d5f0845d0cb99763da6fdee00478f91db7325/coloredlogs-15.0.1.tar.gz", hash = "sha256:7c991aa71a4577af2f82600d8f8f3a89f936baeaf9b50a9c197da014e5bf16b0", size = 278520, upload-time = "2021-06-11T10:22:45.202Z" } wheels = [ @@ -1378,7 +1379,7 @@ resolution-markers = [ "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/66/54/eb9bfc647b19f2009dd5c7f5ec51c4e6ca831725f1aea7a993034f483147/contourpy-1.3.2.tar.gz", hash = "sha256:b6945942715a034c671b7fc54f9588126b0b8bf23db2696e3ca8328f3ff0ab54", size = 13466130, upload-time = "2025-04-15T17:47:53.79Z" } wheels = [ @@ -1443,7 +1444,7 @@ resolution-markers = [ "python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/58/01/1253e6698a07380cd31a736d248a3f2a50a7c88779a1813da27503cadc2a/contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880", size = 13466174, upload-time = "2025-07-26T12:03:12.549Z" } wheels = [ @@ -1619,9 +1620,9 @@ name = "cupy-cuda12x" version = "13.6.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "fastrlock", marker = "(python_full_version >= '3.11' and platform_machine != 'aarch64') or platform_machine == 'x86_64'" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' and platform_machine == 'x86_64'" }, - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' and platform_machine != 'aarch64'" }, + { name = "fastrlock" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/53/2b/8064d94a6ab6b5c4e643d8535ab6af6cabe5455765540931f0ef60a0bc3b/cupy_cuda12x-13.6.0-cp310-cp310-manylinux2014_x86_64.whl", hash = "sha256:e78409ea72f5ac7d6b6f3d33d99426a94005254fa57e10617f430f9fd7c3a0a1", size = 112238589, upload-time = "2025-08-18T08:24:15.541Z" }, @@ -1707,8 +1708,8 @@ name = "dataclasses-json" version = "0.6.7" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "marshmallow", marker = "python_full_version >= '3.11'" }, - { name = "typing-inspect", marker = "python_full_version >= '3.11'" }, + { name = "marshmallow" }, + { name = "typing-inspect" }, ] sdist = { url = "https://files.pythonhosted.org/packages/64/a4/f71d9cf3a5ac257c993b5ca3f93df5f7fb395c725e7f1e6479d2514173c3/dataclasses_json-0.6.7.tar.gz", hash = "sha256:b6b3e528266ea45b9535223bc53ca645f5208833c29229e847b3f26a1cc55fc0", size = 32227, upload-time = "2024-06-09T16:20:19.103Z" } wheels = [ @@ -1843,6 +1844,8 @@ dependencies = [ { name = "bleak" }, { name = "cmeel-tinyxml2" }, { name = "cryptography" }, + { name = "dimos-cdrgen" }, + { name = "dimos-generated" }, { name = "dimos-lcm" }, { name = "dimos-viewer" }, { name = "eclipse-zenoh" }, @@ -2326,6 +2329,7 @@ lint = [ { name = "chromadb" }, { name = "deptry" }, { name = "dimos", extra = ["visualization", "web", "webrtc"] }, + { name = "dimos-cdrgen" }, { name = "einops" }, { name = "gdown" }, { name = "googlemaps" }, @@ -2366,6 +2370,13 @@ lint = [ { name = "watchdog" }, { name = "xacro" }, ] +message-codegen = [ + { name = "dimos-cdrgen", extra = ["prepare"] }, + { name = "pytest" }, + { name = "rosbags" }, + { name = "ruff" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] project-deps = [ { name = "can-motor-control" }, { name = "chromadb" }, @@ -2394,12 +2405,14 @@ project-deps = [ { name = "xacro" }, ] tests = [ + { name = "build" }, { name = "can-motor-control" }, { name = "chromadb" }, { name = "click" }, { name = "coacd" }, { name = "coverage" }, { name = "dimos", extra = ["apriltag", "cpu", "drone", "learning", "mapping", "visualization", "web", "webrtc"] }, + { name = "dimos-cdrgen" }, { name = "einops" }, { name = "gdown" }, { name = "googlemaps" }, @@ -2450,6 +2463,7 @@ tests = [ { name = "xacro" }, ] tests-self-hosted = [ + { name = "build" }, { name = "can-motor-control" }, { name = "chromadb" }, { name = "click" }, @@ -2457,6 +2471,7 @@ tests-self-hosted = [ { name = "coverage" }, { name = "dim-odom" }, { name = "dimos", extra = ["apriltag", "cpu", "drone", "learning", "manipulation", "mapping", "misc", "unitree", "visualization", "web", "webrtc"] }, + { name = "dimos-cdrgen" }, { name = "einops" }, { name = "gdown" }, { name = "googlemaps" }, @@ -2535,6 +2550,8 @@ requires-dist = [ { name = "dimos", extras = ["control"], marker = "extra == 'planning'" }, { name = "dimos", extras = ["planning", "base", "sim", "cpu"], marker = "extra == 'manipulation'" }, { name = "dimos", extras = ["unitree"], marker = "extra == 'unitree-dds'" }, + { name = "dimos-cdrgen", specifier = "==0.1.0" }, + { name = "dimos-generated", editable = "packages/dimos-generated" }, { name = "dimos-lcm", specifier = ">=0.1.4" }, { name = "dimos-viewer", specifier = "==0.32.0a2" }, { name = "dimos-viewer", marker = "extra == 'visualization'", specifier = "==0.32.0a2" }, @@ -2681,6 +2698,7 @@ lint = [ { name = "chromadb", specifier = ">=1.0.0" }, { name = "deptry", specifier = "==0.25.1" }, { name = "dimos", extras = ["web", "visualization", "webrtc"] }, + { name = "dimos-cdrgen", specifier = "==0.1.0" }, { name = "einops", specifier = ">=0.8.1" }, { name = "gdown", specifier = "==6.0.0" }, { name = "googlemaps", specifier = ">=4.10.0" }, @@ -2720,6 +2738,13 @@ lint = [ { name = "watchdog", specifier = ">=3.0.0" }, { name = "xacro" }, ] +message-codegen = [ + { name = "dimos-cdrgen", extras = ["prepare"], specifier = "==0.1.0" }, + { name = "pytest", specifier = "==8.3.5" }, + { name = "rosbags", specifier = "==0.11.0" }, + { name = "ruff", specifier = "==0.14.3" }, + { name = "tomli", marker = "python_full_version < '3.11'", specifier = ">=2" }, +] project-deps = [ { name = "can-motor-control", specifier = ">=0.0.8" }, { name = "chromadb", specifier = ">=1.0.0" }, @@ -2748,6 +2773,7 @@ project-deps = [ { name = "xacro" }, ] tests = [ + { name = "build", specifier = ">=1.2.2" }, { name = "can-motor-control", specifier = ">=0.0.8" }, { name = "chromadb", specifier = ">=1.0.0" }, { name = "click", specifier = ">=8.3" }, @@ -2755,6 +2781,7 @@ tests = [ { name = "coverage", specifier = ">=7.0" }, { name = "dimos", extras = ["apriltag", "mapping", "drone", "cpu", "learning"] }, { name = "dimos", extras = ["web", "visualization", "webrtc"] }, + { name = "dimos-cdrgen", specifier = "==0.1.0" }, { name = "einops", specifier = ">=0.8.1" }, { name = "gdown", specifier = "==6.0.0" }, { name = "googlemaps", specifier = ">=4.10.0" }, @@ -2805,6 +2832,7 @@ tests = [ { name = "xacro" }, ] tests-self-hosted = [ + { name = "build", specifier = ">=1.2.2" }, { name = "can-motor-control", specifier = ">=0.0.8" }, { name = "chromadb", specifier = ">=1.0.0" }, { name = "click", specifier = ">=8.3" }, @@ -2814,6 +2842,7 @@ tests-self-hosted = [ { name = "dimos", extras = ["apriltag", "mapping", "drone", "cpu", "learning"] }, { name = "dimos", extras = ["manipulation", "misc", "unitree"] }, { name = "dimos", extras = ["web", "visualization", "webrtc"] }, + { name = "dimos-cdrgen", specifier = "==0.1.0" }, { name = "einops", specifier = ">=0.8.1" }, { name = "gdown", specifier = "==6.0.0" }, { name = "googlemaps", specifier = ">=4.10.0" }, @@ -2866,6 +2895,46 @@ tests-self-hosted = [ { name = "xacro" }, ] +[[package]] +name = "dimos-cdrgen" +version = "0.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "empy" }, + { name = "lark" }, + { name = "rosbags" }, + { name = "setuptools" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "wheel" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3d/1a/31327fa4bb2a240783d0b41e315be2a4485eabf07ab032f49c6328f5f51b/dimos_cdrgen-0.1.0.tar.gz", hash = "sha256:69ea4955e64a769d56d4bd5e0fff44c98f96c29c5608125cd011cef2740624f0", size = 75010, upload-time = "2026-10-15T05:00:09.663Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a3/9c/086701c3249ed2caabe83cea008c3e08bd6063c48a1df852fbca6aadff50/dimos_cdrgen-0.1.0-py3-none-any.whl", hash = "sha256:6731e8900f7e61af419b8c77599587f32677c9d64f27ac15f5e78be4b76bc011", size = 70183, upload-time = "2026-10-15T05:00:08.098Z" }, +] + +[package.optional-dependencies] +prepare = [ + { name = "requests" }, +] + +[[package]] +name = "dimos-generated" +version = "0.1.0" +source = { editable = "packages/dimos-generated" } +dependencies = [ + { name = "dimos-cdrgen" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "rosbags" }, +] + +[package.metadata] +requires-dist = [ + { name = "dimos-cdrgen", specifier = "==0.1.0" }, + { name = "numpy", specifier = ">=1.26.4" }, + { name = "rosbags", specifier = "==0.11.0" }, +] + [[package]] name = "dimos-lcm" version = "0.1.4" @@ -2948,12 +3017,12 @@ resolution-markers = [ "python_full_version < '3.11' and platform_machine != 'aarch64' and platform_machine != 'x86_64' and sys_platform == 'darwin'", ] dependencies = [ - { name = "matplotlib", marker = "platform_machine != 'aarch64' and sys_platform == 'darwin'" }, - { name = "mosek", version = "11.0.24", source = { registry = "https://pypi.org/simple" }, marker = "platform_machine != 'aarch64' and sys_platform == 'darwin'" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'darwin'" }, - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' and platform_machine != 'aarch64' and sys_platform == 'darwin'" }, - { name = "pydot", marker = "platform_machine != 'aarch64' and sys_platform == 'darwin'" }, - { name = "pyyaml", marker = "platform_machine != 'aarch64' and sys_platform == 'darwin'" }, + { name = "matplotlib" }, + { name = "mosek", version = "11.0.24", source = { registry = "https://pypi.org/simple" } }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "pydot" }, + { name = "pyyaml" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/a0/31/aa4f1f5523381539e1028354cc535d5a3307d28fd33872f2b403454d8391/drake-1.45.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:b0d9bd6196dc6d3b0e660fc6351fcf236727a45ef6a7123f8dc96f85b8662ac3", size = 57314509, upload-time = "2025-09-16T19:02:10.195Z" }, @@ -2977,12 +3046,12 @@ resolution-markers = [ "python_full_version < '3.11' and platform_machine != 'aarch64' and platform_machine != 'x86_64' and sys_platform != 'darwin' and sys_platform != 'win32'", ] dependencies = [ - { name = "matplotlib", marker = "platform_machine != 'aarch64' and sys_platform != 'darwin'" }, - { name = "mosek", version = "11.1.2", source = { registry = "https://pypi.org/simple" }, marker = "platform_machine != 'aarch64' and sys_platform != 'darwin'" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform != 'darwin'" }, - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' and platform_machine != 'aarch64' and sys_platform != 'darwin'" }, - { name = "pydot", marker = "platform_machine != 'aarch64' and sys_platform != 'darwin'" }, - { name = "pyyaml", marker = "platform_machine != 'aarch64' and sys_platform != 'darwin'" }, + { name = "matplotlib" }, + { name = "mosek", version = "11.1.2", source = { registry = "https://pypi.org/simple" } }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "pydot" }, + { name = "pyyaml" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/fb/26/2ce3a9caf431f24e39f8b1fc7b3ebba4faafef1d61c849db3194e8d2e21d/drake-1.49.0-cp310-cp310-manylinux_2_34_x86_64.whl", hash = "sha256:6c73dbd061fcb442e82b7b5a94dadcfbf4c44949035d03394df29412114647b2", size = 41482505, upload-time = "2026-01-15T19:44:08.313Z" }, @@ -3074,8 +3143,8 @@ name = "embreex" version = "4.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine != 'aarch64') or (python_full_version < '3.11' and sys_platform != 'linux')" }, - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'aarch64') or (python_full_version >= '3.11' and sys_platform != 'linux')" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/29/89/692237d6a60f58f87f7bffdfe8c30008efd8811411e692f96d2cb1df0818/embreex-4.4.0-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:b685ed766ef86dbd302ae9e92ab20156007c31cbd2ea5465542b50eea99c6da5", size = 5098460, upload-time = "2026-04-22T19:46:30.276Z" }, @@ -3092,6 +3161,12 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b5/96/625e035f3433071c91de07e66265a261be7bb708367f785000f93d7a992a/embreex-4.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:6c092ee1adf5c48b7430c7ae3902943863745e54b4aef4327ecb3473e0a299d7", size = 13119305, upload-time = "2026-04-22T19:46:59.329Z" }, ] +[[package]] +name = "empy" +version = "4.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c1/0a/c500fc4c8f48cac08b76b8987070b178f0549534584ac1f414066700a3f9/empy-4.2.tar.gz", hash = "sha256:86f15e1da9743e79a2e9b2cbacf1a13d0b7fb1835b6254eb253c978b72287f4f", size = 166069, upload-time = "2024-08-25T23:32:09.946Z" } + [[package]] name = "etils" version = "1.13.0" @@ -3117,7 +3192,7 @@ name = "exceptiongroup" version = "1.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } wheels = [ @@ -3379,15 +3454,15 @@ resolution-markers = [ "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "jax", version = "0.6.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "msgpack", marker = "python_full_version < '3.11'" }, - { name = "optax", marker = "python_full_version < '3.11'" }, - { name = "orbax-checkpoint", marker = "python_full_version < '3.11'" }, - { name = "pyyaml", marker = "python_full_version < '3.11'" }, - { name = "rich", marker = "python_full_version < '3.11'" }, - { name = "tensorstore", version = "0.1.78", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "treescope", marker = "python_full_version < '3.11'" }, - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, + { name = "jax", version = "0.6.2", source = { registry = "https://pypi.org/simple" } }, + { name = "msgpack" }, + { name = "optax" }, + { name = "orbax-checkpoint" }, + { name = "pyyaml" }, + { name = "rich" }, + { name = "tensorstore", version = "0.1.78", source = { registry = "https://pypi.org/simple" } }, + { name = "treescope" }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e6/76/4ea55a60a47e98fcff591238ee26ed4624cb4fdc4893aa3ebf78d0d021f4/flax-0.10.7.tar.gz", hash = "sha256:2930d6671e23076f6db3b96afacf45c5060898f5c189ecab6dda7e05d26c2085", size = 5136099, upload-time = "2025-07-02T06:10:07.819Z" } wheels = [ @@ -3417,17 +3492,17 @@ resolution-markers = [ "python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "jax", version = "0.9.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "msgpack", marker = "python_full_version >= '3.11'" }, - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "optax", marker = "python_full_version >= '3.11'" }, - { name = "orbax-checkpoint", marker = "python_full_version >= '3.11'" }, - { name = "orbax-export", marker = "python_full_version >= '3.11'" }, - { name = "pyyaml", marker = "python_full_version >= '3.11'" }, - { name = "rich", marker = "python_full_version >= '3.11'" }, - { name = "tensorstore", version = "0.1.81", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "treescope", marker = "python_full_version >= '3.11'" }, - { name = "typing-extensions", marker = "python_full_version >= '3.11'" }, + { name = "jax", version = "0.9.0.1", source = { registry = "https://pypi.org/simple" } }, + { name = "msgpack" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" } }, + { name = "optax" }, + { name = "orbax-checkpoint" }, + { name = "orbax-export" }, + { name = "pyyaml" }, + { name = "rich" }, + { name = "tensorstore", version = "0.1.81", source = { registry = "https://pypi.org/simple" } }, + { name = "treescope" }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/48/81/802fd686d3f47d7560a83f73b23efff03de7e3a0342e4f0fc41680136709/flax-0.12.4.tar.gz", hash = "sha256:5e924734a0595ddfa06a824568617e5440c7948e744772cbe6101b7ae06d66a9", size = 5070824, upload-time = "2026-02-12T19:10:17.048Z" } wheels = [ @@ -3767,9 +3842,9 @@ name = "gtsam-extended" version = "4.3a1.post1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' and platform_machine != 'aarch64' and platform_machine != 'x86_64' and sys_platform == 'darwin'" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' and platform_machine == 'arm64' and sys_platform == 'darwin'" }, { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "pytest", marker = "(python_full_version >= '3.11' and platform_machine == 'aarch64') or (python_full_version >= '3.11' and platform_machine == 'x86_64') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (platform_machine != 'aarch64' and platform_machine != 'x86_64' and sys_platform == 'darwin')" }, + { name = "pytest" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/7f/a3/f815f6768994d1cd11f76cfa094be1d50c84edf1d85908fa93b461bb2eaf/gtsam_extended-4.3a1.post1-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:20291cdf65ae8b97abd0dc3f9d62cbeec6a76144f9f796044cccc3ffacbaae13", size = 26677717, upload-time = "2026-04-02T22:29:33.557Z" }, @@ -3930,7 +4005,7 @@ name = "humanfriendly" version = "10.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyreadline3", marker = "python_full_version < '3.11' and sys_platform == 'win32'" }, + { name = "pyreadline3", marker = "sys_platform == 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/cc/3f/2c29224acb2e2df4d2046e4c73ee2662023c58ff5b113c4c1adac0886c43/humanfriendly-10.0.tar.gz", hash = "sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc", size = 360702, upload-time = "2021-09-17T21:40:43.31Z" } wheels = [ @@ -4005,7 +4080,7 @@ resolution-markers = [ "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/de/bf/81c848ffe2b42fc141b6db3e4e8e650183b7aab8c4535498ebff25740a3b/imagecodecs-2025.3.30.tar.gz", hash = "sha256:29256f44a7fcfb8f235a3e9b3bae72b06ea2112e63bcc892267a8c01b7097f90", size = 9506573, upload-time = "2025-03-30T04:44:50.368Z" } wheels = [ @@ -4044,7 +4119,7 @@ resolution-markers = [ "python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/3b/8d/dc18623e5e926ad53c626e128c8baaf4ec42e41029cf0a07381cfef79289/imagecodecs-2026.3.6.tar.gz", hash = "sha256:471b8a4d1b3843cbf7179b45f7d7261f0c0b28809efc1ca6c47822477b143b85", size = 9565259, upload-time = "2026-03-07T01:26:41.183Z" } wheels = [ @@ -4072,7 +4147,7 @@ resolution-markers = [ "python_full_version >= '3.12' and platform_machine == 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/98/9f/b436418349779e1c18cc27575360cad03dd492bc574ae9e297832bc48cab/imagecodecs-2026.6.26.tar.gz", hash = "sha256:da95b145f6b4f746acc9e0b8707b164eefc6a36ade3b6e70f74d102e9affad8c", size = 9669990, upload-time = "2026-06-28T18:27:01.957Z" } wheels = [ @@ -4183,17 +4258,17 @@ resolution-markers = [ "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "colorama", marker = "python_full_version < '3.11' and sys_platform == 'win32'" }, - { name = "decorator", marker = "python_full_version < '3.11'" }, - { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, - { name = "jedi", marker = "python_full_version < '3.11'" }, - { name = "matplotlib-inline", marker = "python_full_version < '3.11'" }, - { name = "pexpect", marker = "python_full_version < '3.11' and sys_platform != 'emscripten' and sys_platform != 'win32'" }, - { name = "prompt-toolkit", marker = "python_full_version < '3.11'" }, - { name = "pygments", marker = "python_full_version < '3.11'" }, - { name = "stack-data", marker = "python_full_version < '3.11'" }, - { name = "traitlets", marker = "python_full_version < '3.11'" }, - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "decorator" }, + { name = "exceptiongroup" }, + { name = "jedi" }, + { name = "matplotlib-inline" }, + { name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, + { name = "prompt-toolkit" }, + { name = "pygments" }, + { name = "stack-data" }, + { name = "traitlets" }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e5/61/1810830e8b93c72dcd3c0f150c80a00c3deb229562d9423807ec92c3a539/ipython-8.38.0.tar.gz", hash = "sha256:9cfea8c903ce0867cc2f23199ed8545eb741f3a69420bfcf3743ad1cec856d39", size = 5513996, upload-time = "2026-01-05T10:59:06.901Z" } wheels = [ @@ -4223,17 +4298,17 @@ resolution-markers = [ "python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "colorama", marker = "python_full_version >= '3.11' and sys_platform == 'win32'" }, - { name = "decorator", marker = "python_full_version >= '3.11'" }, - { name = "ipython-pygments-lexers", marker = "python_full_version >= '3.11'" }, - { name = "jedi", marker = "python_full_version >= '3.11'" }, - { name = "matplotlib-inline", marker = "python_full_version >= '3.11'" }, - { name = "pexpect", marker = "python_full_version >= '3.11' and sys_platform != 'emscripten' and sys_platform != 'win32'" }, - { name = "prompt-toolkit", marker = "python_full_version >= '3.11'" }, - { name = "pygments", marker = "python_full_version >= '3.11'" }, - { name = "stack-data", marker = "python_full_version >= '3.11'" }, - { name = "traitlets", marker = "python_full_version >= '3.11'" }, - { name = "typing-extensions", marker = "python_full_version == '3.11.*'" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "decorator" }, + { name = "ipython-pygments-lexers" }, + { name = "jedi" }, + { name = "matplotlib-inline" }, + { name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, + { name = "prompt-toolkit" }, + { name = "pygments" }, + { name = "stack-data" }, + { name = "traitlets" }, + { name = "typing-extensions", marker = "python_full_version < '3.12'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/a6/60/2111715ea11f39b1535bed6024b7dec7918b71e5e5d30855a5b503056b50/ipython-9.10.0.tar.gz", hash = "sha256:cd9e656be97618a0676d058134cd44e6dc7012c0e5cb36a9ce96a8c904adaf77", size = 4426526, upload-time = "2026-02-02T10:00:33.594Z" } wheels = [ @@ -4245,7 +4320,7 @@ name = "ipython-pygments-lexers" version = "1.1.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pygments", marker = "python_full_version >= '3.11'" }, + { name = "pygments" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ef/4c/5dd1d8af08107f88c7f741ead7a40854b8ac24ddf9ae850afbcf698aa552/ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81", size = 8393, upload-time = "2025-01-17T11:24:34.505Z" } wheels = [ @@ -4324,11 +4399,11 @@ resolution-markers = [ "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "jaxlib", version = "0.6.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "ml-dtypes", marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "opt-einsum", marker = "python_full_version < '3.11'" }, - { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "jaxlib", version = "0.6.2", source = { registry = "https://pypi.org/simple" } }, + { name = "ml-dtypes" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" } }, + { name = "opt-einsum" }, + { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/cf/1e/267f59c8fb7f143c3f778c76cb7ef1389db3fd7e4540f04b9f42ca90764d/jax-0.6.2.tar.gz", hash = "sha256:a437d29038cbc8300334119692744704ca7941490867b9665406b7f90665cd96", size = 2334091, upload-time = "2025-06-17T23:10:27.186Z" } wheels = [ @@ -4358,11 +4433,11 @@ resolution-markers = [ "python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "jaxlib", version = "0.9.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "ml-dtypes", marker = "python_full_version >= '3.11'" }, - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "opt-einsum", marker = "python_full_version >= '3.11'" }, - { name = "scipy", version = "1.17.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "jaxlib", version = "0.9.0.1", source = { registry = "https://pypi.org/simple" } }, + { name = "ml-dtypes" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" } }, + { name = "opt-einsum" }, + { name = "scipy", version = "1.17.0", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/52/40/f85d1feadd8f793fc1bfab726272523ef34b27302b55861ea872ec774019/jax-0.9.0.1.tar.gz", hash = "sha256:e395253449d74354fa813ff9e245acb6e42287431d8a01ff33d92e9ee57d36bd", size = 2534795, upload-time = "2026-02-05T18:47:33.088Z" } wheels = [ @@ -4387,9 +4462,9 @@ resolution-markers = [ "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "ml-dtypes", marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "ml-dtypes" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" } }, + { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" } }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/15/c5/41598634c99cbebba46e6777286fb76abc449d33d50aeae5d36128ca8803/jaxlib-0.6.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:da4601b2b5dc8c23d6afb293eacfb9aec4e1d1871cb2f29c5a151d103e73b0f8", size = 54298019, upload-time = "2025-06-17T23:10:36.916Z" }, @@ -4429,9 +4504,9 @@ resolution-markers = [ "python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "ml-dtypes", marker = "python_full_version >= '3.11'" }, - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "scipy", version = "1.17.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "ml-dtypes" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" } }, + { name = "scipy", version = "1.17.0", source = { registry = "https://pypi.org/simple" } }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/b0/fd/040321b0f4303ec7b558d69488c6130b1697c33d88dab0a0d2ccd2e0817c/jaxlib-0.9.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ff2c550dab210278ed3a3b96454b19108a02e0795625be56dca5a181c9833c9", size = 56092920, upload-time = "2026-02-05T18:46:20.873Z" }, @@ -4468,7 +4543,7 @@ name = "jaxtyping" version = "0.3.7" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "wadler-lindig", marker = "python_full_version >= '3.11'" }, + { name = "wadler-lindig" }, ] sdist = { url = "https://files.pythonhosted.org/packages/38/40/a2ea3ce0e3e5f540eb970de7792c90fa58fef1b27d34c83f9fa94fea4729/jaxtyping-0.3.7.tar.gz", hash = "sha256:3bd7d9beb7d3cb01a89f93f90581c6f4fff3e5c5dc3c9307e8f8687a040d10c4", size = 45721, upload-time = "2026-01-30T14:18:47.409Z" } wheels = [ @@ -4961,6 +5036,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d9/8d/00df0c44b728119fe770e0526f850b0a9201f23bf4276568aef5b372982e/lap-0.5.12-cp312-cp312-win_arm64.whl", hash = "sha256:83e507f6def40244da3e03c71f1b1f54ceab3978cde72a84b84caadd8728977e", size = 1466243, upload-time = "2024-11-30T01:26:43.202Z" }, ] +[[package]] +name = "lark" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/af/60/bc7622aefb2aee1c0b4ba23c1446d3e30225c8770b38d7aedbfb65ca9d5a/lark-1.2.2.tar.gz", hash = "sha256:ca807d0162cd16cef15a8feecb862d7319e7a09bdb13aef927968e45040fed80", size = 252132, upload-time = "2024-08-13T19:49:00.652Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2d/00/d90b10b962b4277f5e64a78b6609968859ff86889f5b898c1a778c06ec00/lark-1.2.2-py3-none-any.whl", hash = "sha256:c2276486b02f0f1b90be155f2c8ba4a8e194d42775786db622faccd652d8e80c", size = 111036, upload-time = "2024-08-13T19:48:58.603Z" }, +] + [[package]] name = "lazy-loader" version = "0.5" @@ -5384,7 +5468,7 @@ name = "marshmallow" version = "3.26.2" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "packaging", marker = "python_full_version >= '3.11'" }, + { name = "packaging" }, ] sdist = { url = "https://files.pythonhosted.org/packages/55/79/de6c16cc902f4fc372236926b0ce2ab7845268dcc30fb2fbb7f71b418631/marshmallow-3.26.2.tar.gz", hash = "sha256:bbe2adb5a03e6e3571b573f42527c6fe926e17467833660bebd11593ab8dfd57", size = 222095, upload-time = "2025-12-22T06:53:53.309Z" } wheels = [ @@ -5805,8 +5889,8 @@ resolution-markers = [ "python_full_version < '3.11' and platform_machine != 'aarch64' and platform_machine != 'x86_64' and sys_platform == 'darwin'", ] dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'darwin'" }, - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' and platform_machine != 'aarch64' and sys_platform == 'darwin'" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/37/e7/d04ea5c587fd8b491fbe9377fafa5feb063bb28a3a6949fb393a62230d9d/mosek-11.0.24-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:7f2ab70ad3357f9187c96237d0c49187f82f5885250a5e211b6aa20cb0a7207f", size = 8345311, upload-time = "2025-06-25T10:51:51.777Z" }, @@ -5830,8 +5914,8 @@ resolution-markers = [ "python_full_version < '3.11' and platform_machine != 'aarch64' and platform_machine != 'x86_64' and sys_platform != 'darwin' and sys_platform != 'win32'", ] dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform != 'darwin'" }, - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' and platform_machine != 'aarch64' and sys_platform != 'darwin'" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/c3/e9/253e759e6e00b9cfbb4e95e7fe079b0e971b3c81c75f059bf2c2be3216e9/mosek-11.1.2-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:5c3566d2a603d94a1773bcd27097c8390dba1d9a1543534f3527deb56f1d0a55", size = 15359313, upload-time = "2026-01-07T08:22:00.805Z" }, @@ -6315,7 +6399,7 @@ name = "nvidia-cublas" version = "13.6.1.10" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-cuda-nvrtc", marker = "(python_full_version >= '3.11' and platform_machine == 'x86_64' and sys_platform != 'darwin' and sys_platform != 'win32') or (platform_machine != 'aarch64' and platform_machine != 'x86_64' and sys_platform != 'darwin' and sys_platform != 'win32') or sys_platform == 'linux'" }, + { name = "nvidia-cuda-nvrtc" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/42/51/a174a0e79793e528ef4645a9d554e3aa48fd8da3f9c9cf523c0176bb121b/nvidia_cublas-13.6.1.10-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:e05a431062a17cb9b02e2f37e67817b637051ce8fad57b388482c594396ddbb4", size = 518610411, upload-time = "2026-07-30T18:18:32.969Z" }, @@ -6377,7 +6461,7 @@ name = "nvidia-cudnn-cu12" version = "9.7.1.26" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-cublas-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cublas-cu12" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/25/dc/dc825c4b1c83b538e207e34f48f86063c88deaa35d46c651c7c181364ba2/nvidia_cudnn_cu12-9.7.1.26-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:6d011159a158f3cfc47bf851aea79e31bcff60d530b70ef70474c84cac484d07", size = 726851421, upload-time = "2025-02-06T22:18:29.812Z" }, @@ -6388,7 +6472,7 @@ name = "nvidia-cufft-cu12" version = "11.3.3.41" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-nvjitlink-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-nvjitlink-cu12" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/ac/26/b53c493c38dccb1f1a42e1a21dc12cba2a77fbe36c652f7726d9ec4aba28/nvidia_cufft_cu12-11.3.3.41-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:da650080ab79fcdf7a4b06aa1b460e99860646b176a43f6208099bdc17836b6a", size = 193118795, upload-time = "2025-01-23T17:56:30.536Z" }, @@ -6415,9 +6499,9 @@ name = "nvidia-cusolver" version = "12.2.6.9" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-cublas", marker = "(python_full_version >= '3.11' and platform_machine == 'x86_64' and sys_platform != 'darwin' and sys_platform != 'win32') or (platform_machine != 'aarch64' and platform_machine != 'x86_64' and sys_platform != 'darwin' and sys_platform != 'win32') or sys_platform == 'linux'" }, - { name = "nvidia-cusparse", marker = "(python_full_version >= '3.11' and platform_machine == 'x86_64' and sys_platform != 'darwin' and sys_platform != 'win32') or (platform_machine != 'aarch64' and platform_machine != 'x86_64' and sys_platform != 'darwin' and sys_platform != 'win32') or sys_platform == 'linux'" }, - { name = "nvidia-nvjitlink", marker = "(python_full_version >= '3.11' and platform_machine == 'x86_64' and sys_platform != 'darwin' and sys_platform != 'win32') or (platform_machine != 'aarch64' and platform_machine != 'x86_64' and sys_platform != 'darwin' and sys_platform != 'win32') or sys_platform == 'linux'" }, + { name = "nvidia-cublas" }, + { name = "nvidia-cusparse" }, + { name = "nvidia-nvjitlink" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/13/bd/61dcd7917f64c9e81a35f939f1bf4ab6535adf712192e915fb472e5bbf6c/nvidia_cusolver-12.2.6.9-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:658ce9e6ed8a321033419fe6e55faf0f245a15aa23669eda03d7f2dcce436d73", size = 267275679, upload-time = "2026-06-29T16:59:54.924Z" }, @@ -6429,9 +6513,9 @@ name = "nvidia-cusolver-cu12" version = "11.7.2.55" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-cublas-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, - { name = "nvidia-cusparse-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, - { name = "nvidia-nvjitlink-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cublas-cu12" }, + { name = "nvidia-cusparse-cu12" }, + { name = "nvidia-nvjitlink-cu12" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/c2/08/953675873a136d96bb12f93b49ba045d1107bc94d2551c52b12fa6c7dec3/nvidia_cusolver_cu12-11.7.2.55-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:4d1354102f1e922cee9db51920dba9e2559877cf6ff5ad03a00d853adafb191b", size = 260373342, upload-time = "2025-01-23T17:58:56.406Z" }, @@ -6442,7 +6526,7 @@ name = "nvidia-cusparse" version = "12.8.2.51" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-nvjitlink", marker = "(python_full_version >= '3.11' and platform_machine == 'x86_64' and sys_platform != 'darwin' and sys_platform != 'win32') or (platform_machine != 'aarch64' and platform_machine != 'x86_64' and sys_platform != 'darwin' and sys_platform != 'win32') or sys_platform == 'linux'" }, + { name = "nvidia-nvjitlink" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/ac/bc/925058f9343d93426864cbb113a3f5cf6db97a7d11642aaf4159b6f0c57a/nvidia_cusparse-12.8.2.51-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:00469fcf62c4d464a1225abd9b20864ecff35e3fbc9fb992572e83d358927755", size = 172868683, upload-time = "2026-06-29T17:01:23.244Z" }, @@ -6454,7 +6538,7 @@ name = "nvidia-cusparse-cu12" version = "12.5.7.53" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-nvjitlink-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-nvjitlink-cu12" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/c2/ab/31e8149c66213b846c082a3b41b1365b831f41191f9f40c6ddbc8a7d550e/nvidia_cusparse_cu12-12.5.7.53-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3c1b61eb8c85257ea07e9354606b26397612627fdcd327bfd91ccf6155e7c86d", size = 292064180, upload-time = "2025-01-23T18:00:23.233Z" }, @@ -6554,13 +6638,13 @@ resolution-markers = [ "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "coloredlogs", marker = "python_full_version < '3.11'" }, - { name = "flatbuffers", marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "packaging", marker = "python_full_version < '3.11'" }, - { name = "protobuf", marker = "python_full_version < '3.11'" }, - { name = "sympy", version = "1.13.1", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine != 'x86_64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "sympy", version = "1.14.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine == 'x86_64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, + { name = "coloredlogs" }, + { name = "flatbuffers" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" } }, + { name = "packaging" }, + { name = "protobuf" }, + { name = "sympy", version = "1.13.1", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "sympy", version = "1.14.0", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine == 'x86_64' and sys_platform == 'linux') or sys_platform == 'win32'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/35/d6/311b1afea060015b56c742f3531168c1644650767f27ef40062569960587/onnxruntime-1.23.2-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:a7730122afe186a784660f6ec5807138bf9d792fa1df76556b27307ea9ebcbe3", size = 17195934, upload-time = "2025-10-27T23:06:14.143Z" }, @@ -6603,12 +6687,12 @@ resolution-markers = [ "python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "flatbuffers", marker = "python_full_version >= '3.11'" }, - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "packaging", marker = "python_full_version >= '3.11'" }, - { name = "protobuf", marker = "python_full_version >= '3.11'" }, - { name = "sympy", version = "1.13.1", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "sympy", version = "1.14.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine == 'x86_64' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, + { name = "flatbuffers" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" } }, + { name = "packaging" }, + { name = "protobuf" }, + { name = "sympy", version = "1.13.1", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "sympy", version = "1.14.0", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine == 'x86_64' and sys_platform == 'linux') or sys_platform == 'win32'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/d2/88/d9757c62a0f96b5193f8d447a141eefd14498c404cc5caf1a6f3233cf102/onnxruntime-1.24.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:79b3119ab9f4f3817062e6dbe7f4a44937de93905e3a31ba34313d18cb49e7be", size = 17212018, upload-time = "2026-02-05T17:32:13.986Z" }, @@ -6632,13 +6716,13 @@ resolution-markers = [ "python_full_version < '3.11' and platform_machine == 'x86_64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "coloredlogs", marker = "python_full_version < '3.11' and platform_machine == 'x86_64'" }, - { name = "flatbuffers", marker = "python_full_version < '3.11' and platform_machine == 'x86_64'" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' and platform_machine == 'x86_64'" }, - { name = "packaging", marker = "python_full_version < '3.11' and platform_machine == 'x86_64'" }, - { name = "protobuf", marker = "python_full_version < '3.11' and platform_machine == 'x86_64'" }, - { name = "sympy", version = "1.13.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' and platform_machine == 'x86_64' and sys_platform != 'linux' and sys_platform != 'win32'" }, - { name = "sympy", version = "1.14.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine == 'x86_64' and sys_platform == 'linux') or (python_full_version < '3.11' and platform_machine == 'x86_64' and sys_platform == 'win32')" }, + { name = "coloredlogs" }, + { name = "flatbuffers" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" } }, + { name = "packaging" }, + { name = "protobuf" }, + { name = "sympy", version = "1.13.1", source = { registry = "https://pypi.org/simple" }, marker = "sys_platform != 'linux' and sys_platform != 'win32'" }, + { name = "sympy", version = "1.14.0", source = { registry = "https://pypi.org/simple" }, marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/cb/ae/39283748c68a96be4f5f8a9561e0e3ca92af1eae6c2b1c07fb1da5f65cd1/onnxruntime_gpu-1.23.2-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18de50c6c8eea50acc405ea13d299aec593e46478d7a22cd32cdbbdf7c42899d", size = 300525411, upload-time = "2025-10-22T16:56:08.415Z" }, @@ -6664,12 +6748,12 @@ resolution-markers = [ "(python_full_version == '3.11.*' and platform_machine != 'aarch64' and platform_machine != 'x86_64' and sys_platform == 'linux') or (python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32')", ] dependencies = [ - { name = "flatbuffers", marker = "python_full_version >= '3.11' and platform_machine != 'aarch64'" }, - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' and platform_machine != 'aarch64'" }, - { name = "packaging", marker = "python_full_version >= '3.11' and platform_machine != 'aarch64'" }, - { name = "protobuf", marker = "python_full_version >= '3.11' and platform_machine != 'aarch64'" }, - { name = "sympy", version = "1.13.1", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'aarch64' and platform_machine != 'x86_64' and sys_platform == 'linux') or (python_full_version >= '3.11' and platform_machine != 'aarch64' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "sympy", version = "1.14.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine == 'x86_64' and sys_platform == 'linux') or (python_full_version >= '3.11' and platform_machine != 'aarch64' and sys_platform == 'win32')" }, + { name = "flatbuffers" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" } }, + { name = "packaging" }, + { name = "protobuf" }, + { name = "sympy", version = "1.13.1", source = { registry = "https://pypi.org/simple" }, marker = "sys_platform != 'linux' and sys_platform != 'win32'" }, + { name = "sympy", version = "1.14.0", source = { registry = "https://pypi.org/simple" }, marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/ca/c7/07d06175f1124fc89e8b7da30d70eb8e0e1400d90961ae1cbea9da69e69b/onnxruntime_gpu-1.24.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ac4bfc90c376516b13d709764ab257e4e3d78639bf6a2ccfc826e9db4a5c7ddf", size = 252616647, upload-time = "2026-02-05T17:24:02.993Z" }, @@ -6683,23 +6767,23 @@ name = "open3d" version = "0.19.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "addict", marker = "platform_machine != 'aarch64' or sys_platform != 'linux'" }, - { name = "configargparse", marker = "platform_machine != 'aarch64' or sys_platform != 'linux'" }, - { name = "dash", marker = "platform_machine != 'aarch64' or sys_platform != 'linux'" }, - { name = "flask", marker = "platform_machine != 'aarch64' or sys_platform != 'linux'" }, - { name = "matplotlib", marker = "platform_machine != 'aarch64' or sys_platform != 'linux'" }, - { name = "nbformat", marker = "platform_machine != 'aarch64' or sys_platform != 'linux'" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine != 'aarch64') or (python_full_version < '3.11' and sys_platform != 'linux')" }, - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'aarch64') or (python_full_version >= '3.11' and sys_platform != 'linux')" }, - { name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine != 'aarch64') or (python_full_version < '3.11' and sys_platform != 'linux')" }, - { name = "pandas", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'aarch64') or (python_full_version >= '3.11' and sys_platform != 'linux')" }, - { name = "pillow", marker = "platform_machine != 'aarch64' or sys_platform != 'linux'" }, - { name = "pyquaternion", marker = "platform_machine != 'aarch64' or sys_platform != 'linux'" }, - { name = "pyyaml", marker = "platform_machine != 'aarch64' or sys_platform != 'linux'" }, - { name = "scikit-learn", version = "1.7.2", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine != 'aarch64') or (python_full_version < '3.11' and sys_platform != 'linux')" }, - { name = "scikit-learn", version = "1.8.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'aarch64') or (python_full_version >= '3.11' and sys_platform != 'linux')" }, - { name = "tqdm", marker = "platform_machine != 'aarch64' or sys_platform != 'linux'" }, - { name = "werkzeug", marker = "platform_machine != 'aarch64' or sys_platform != 'linux'" }, + { name = "addict" }, + { name = "configargparse" }, + { name = "dash" }, + { name = "flask" }, + { name = "matplotlib" }, + { name = "nbformat" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "pandas", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "pillow" }, + { name = "pyquaternion" }, + { name = "pyyaml" }, + { name = "scikit-learn", version = "1.7.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "scikit-learn", version = "1.8.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "tqdm" }, + { name = "werkzeug" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/5c/4b/91e8a4100adf0ccd2f7ad21dd24c2e3d8f12925396528d0462cfb1735e5a/open3d-0.19.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:f7128ded206e07987cc29d0917195fb64033dea31e0d60dead3629b33d3c175f", size = 103086005, upload-time = "2025-01-08T07:25:56.755Z" }, @@ -6718,13 +6802,13 @@ name = "open3d-unofficial-arm" version = "0.19.0.post9" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "configargparse", marker = "platform_machine == 'aarch64' and sys_platform == 'linux'" }, - { name = "dash", marker = "platform_machine == 'aarch64' and sys_platform == 'linux'" }, - { name = "flask", marker = "platform_machine == 'aarch64' and sys_platform == 'linux'" }, - { name = "nbformat", marker = "platform_machine == 'aarch64' and sys_platform == 'linux'" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux'" }, - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux'" }, - { name = "werkzeug", marker = "platform_machine == 'aarch64' and sys_platform == 'linux'" }, + { name = "configargparse" }, + { name = "dash" }, + { name = "flask" }, + { name = "nbformat" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "werkzeug" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ec/f9/edcfaa213800ea278804402baa65693840bc7a323b3de8a31c54ce4e42c8/open3d_unofficial_arm-0.19.0.post9.tar.gz", hash = "sha256:ee300bd557f04750db6e47ccb6c6867c6dd6cfc04169dddeb92505da9ea739ef", size = 5327, upload-time = "2026-04-16T21:21:11.152Z" } wheels = [ @@ -6797,8 +6881,8 @@ name = "opencv-python" version = "4.13.0.92" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine != 'aarch64' and platform_machine != 'x86_64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'aarch64' and platform_machine != 'x86_64' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] [[package]] @@ -6978,15 +7062,15 @@ name = "orbax-export" version = "0.0.8" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "absl-py", marker = "python_full_version >= '3.11'" }, - { name = "dataclasses-json", marker = "python_full_version >= '3.11'" }, - { name = "etils", marker = "python_full_version >= '3.11'" }, - { name = "jax", version = "0.9.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "jaxlib", version = "0.9.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "jaxtyping", marker = "python_full_version >= '3.11'" }, - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "orbax-checkpoint", marker = "python_full_version >= '3.11'" }, - { name = "protobuf", marker = "python_full_version >= '3.11'" }, + { name = "absl-py" }, + { name = "dataclasses-json" }, + { name = "etils" }, + { name = "jax", version = "0.9.0.1", source = { registry = "https://pypi.org/simple" } }, + { name = "jaxlib", version = "0.9.0.1", source = { registry = "https://pypi.org/simple" } }, + { name = "jaxtyping" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" } }, + { name = "orbax-checkpoint" }, + { name = "protobuf" }, ] sdist = { url = "https://files.pythonhosted.org/packages/1c/c8/ed7ac3c3c687bf129d7469b016c2b3d8777379f4ea453474e50ee41ce5cb/orbax_export-0.0.8.tar.gz", hash = "sha256:544eef564e2a6f17cd11b1167febe348b7b7cf56d9575de994a33d5613dd568a", size = 124980, upload-time = "2025-09-17T15:41:14.264Z" } wheels = [ @@ -7123,10 +7207,10 @@ resolution-markers = [ "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "python-dateutil", marker = "python_full_version < '3.11'" }, - { name = "pytz", marker = "python_full_version < '3.11'" }, - { name = "tzdata", marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" } }, + { name = "python-dateutil" }, + { name = "pytz" }, + { name = "tzdata" }, ] sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223, upload-time = "2025-09-29T23:34:51.853Z" } wheels = [ @@ -7176,9 +7260,9 @@ resolution-markers = [ "python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "python-dateutil", marker = "python_full_version >= '3.11'" }, - { name = "tzdata", marker = "(python_full_version >= '3.11' and sys_platform == 'emscripten') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" } }, + { name = "python-dateutil" }, + { name = "tzdata", marker = "sys_platform == 'emscripten' or sys_platform == 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/de/da/b1dc0481ab8d55d0f46e343cfe67d4551a0e14fcee52bd38ca1bd73258d8/pandas-3.0.0.tar.gz", hash = "sha256:0facf7e87d38f721f0af46fe70d97373a37701b1c09f7ed7aeeb292ade5c050f", size = 4633005, upload-time = "2026-01-21T15:52:04.726Z" } wheels = [ @@ -7237,7 +7321,7 @@ name = "pexpect" version = "4.9.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "ptyprocess", marker = "sys_platform != 'win32'" }, + { name = "ptyprocess" }, ] sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450, upload-time = "2023-11-25T09:07:26.339Z" } wheels = [ @@ -7859,11 +7943,11 @@ wheels = [ [[package]] name = "pybind11" -version = "3.0.4" +version = "3.0.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cc/f0/35145a3c3baffeef55d4b8324caa33abaa8fa56ab345ecd4b2211d09163e/pybind11-3.0.4.tar.gz", hash = "sha256:3286b59c8a774b9ee650169302dd5a4eedc30a8617905a0560dd8ee44775130c", size = 589533, upload-time = "2026-04-19T03:08:15.925Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2f/7b/a6d8dcb83c457e24a9df1e4d8fd5fb8034d4bbc62f3c324681e8a9ba57c2/pybind11-3.0.1.tar.gz", hash = "sha256:9c0f40056a016da59bab516efb523089139fcc6f2ba7e4930854c61efb932051", size = 546914, upload-time = "2025-08-22T20:09:27.265Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/06/c3a23c9a0263b136c519f033a58d4641e73065fefc7754e9667ec206d992/pybind11-3.0.4-py3-none-any.whl", hash = "sha256:961720ee652da51d531b7b2451a6bd2bc042b0106e6d9baa48ecb7d58034ce63", size = 314166, upload-time = "2026-04-19T03:08:14.091Z" }, + { url = "https://files.pythonhosted.org/packages/cd/8a/37362fc2b949d5f733a8b0f2ff51ba423914cabefe69f1d1b6aab710f5fe/pybind11-3.0.1-py3-none-any.whl", hash = "sha256:aa8f0aa6e0a94d3b64adfc38f560f33f15e589be2175e103c0a33c6bce55ee89", size = 293611, upload-time = "2025-08-22T20:09:25.235Z" }, ] [[package]] @@ -8045,7 +8129,7 @@ name = "pydot" version = "4.0.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyparsing", marker = "platform_machine != 'aarch64'" }, + { name = "pyparsing" }, ] sdist = { url = "https://files.pythonhosted.org/packages/50/35/b17cb89ff865484c6a20ef46bf9d95a5f07328292578de0b295f4a6beec2/pydot-4.0.1.tar.gz", hash = "sha256:c2148f681c4a33e08bf0e26a9e5f8e4099a82e0e2a068098f32ce86577364ad5", size = 162594, upload-time = "2025-06-17T20:09:56.454Z" } wheels = [ @@ -8278,7 +8362,7 @@ name = "pyobjc-framework-cocoa" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "sys_platform == 'darwin'" }, + { name = "pyobjc-core" }, ] sdist = { url = "https://files.pythonhosted.org/packages/02/a3/16ca9a15e77c061a9250afbae2eae26f2e1579eb8ca9462ae2d2c71e1169/pyobjc_framework_cocoa-12.1.tar.gz", hash = "sha256:5556c87db95711b985d5efdaaf01c917ddd41d148b1e52a0c66b1a2e2c5c1640", size = 2772191, upload-time = "2025-11-14T10:13:02.069Z" } wheels = [ @@ -8292,8 +8376,8 @@ name = "pyobjc-framework-corebluetooth" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "sys_platform == 'darwin'" }, - { name = "pyobjc-framework-cocoa", marker = "sys_platform == 'darwin'" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/4b/25/d21d6cb3fd249c2c2aa96ee54279f40876a0c93e7161b3304bf21cbd0bfe/pyobjc_framework_corebluetooth-12.1.tar.gz", hash = "sha256:8060c1466d90bbb9100741a1091bb79975d9ba43911c9841599879fc45c2bbe0", size = 33157, upload-time = "2025-11-14T10:13:28.064Z" } wheels = [ @@ -8307,8 +8391,8 @@ name = "pyobjc-framework-libdispatch" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "sys_platform == 'darwin'" }, - { name = "pyobjc-framework-cocoa", marker = "sys_platform == 'darwin'" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/26/e8/75b6b9b3c88b37723c237e5a7600384ea2d84874548671139db02e76652b/pyobjc_framework_libdispatch-12.1.tar.gz", hash = "sha256:4035535b4fae1b5e976f3e0e38b6e3442ffea1b8aa178d0ca89faa9b8ecdea41", size = 38277, upload-time = "2025-11-14T10:16:46.235Z" } wheels = [ @@ -8374,8 +8458,8 @@ name = "pyquaternion" version = "0.9.9" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine != 'aarch64') or (python_full_version < '3.11' and sys_platform != 'linux')" }, - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'aarch64') or (python_full_version >= '3.11' and sys_platform != 'linux')" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/7d/0d/3d092aa20efaedacb89c3221a92c6491be5b28f618a2c36b52b53e7446c2/pyquaternion-0.9.9.tar.gz", hash = "sha256:b1f61af219cb2fe966b5fb79a192124f2e63a3f7a777ac3cadf2957b1a81bea8", size = 15530, upload-time = "2020-10-05T01:31:30.327Z" } wheels = [ @@ -9283,6 +9367,23 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/75/35/130469d1901da2b3a5a377539b4ffcd8a5c983f1c9e3ba5ffdd8d71ae314/rope-1.14.0-py3-none-any.whl", hash = "sha256:00a7ea8c0c376fc0b053b2f2f8ef3bfb8b50fecf1ebf3eb80e4f8bd7f1941918", size = 207143, upload-time = "2025-07-12T17:46:05.928Z" }, ] +[[package]] +name = "rosbags" +version = "0.11.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "lz4" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "ruamel-yaml" }, + { name = "typing-extensions" }, + { name = "zstandard" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f3/2f/b6d11cc9fac4003b284e2c152b5c34ca5b6d26caf5f6979118e2d588a0d7/rosbags-0.11.0.tar.gz", hash = "sha256:e73bbe79a15d7f539653375278ffca6c48e56b5c2ada4a4531de0b17737cbc46", size = 254438, upload-time = "2025-10-15T09:49:54.453Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/13/75/b66d992a87539cd9e0070bca6ba49694b9258a4f9bc905d0576354d7864a/rosbags-0.11.0-py3-none-any.whl", hash = "sha256:2ce27d8dc37f554f10bf5962f665331ce16f43aba304c6c233eb15fab05b61ab", size = 137920, upload-time = "2025-10-15T09:49:50.329Z" }, +] + [[package]] name = "rpds-py" version = "0.30.0" @@ -9363,6 +9464,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3f/50/0a9e7e7afe7339bd5e36911f0ceb15fed51945836ed803ae5afd661057fd/rtree-1.4.1-py3-none-win_arm64.whl", hash = "sha256:3d46f55729b28138e897ffef32f7ce93ac335cb67f9120125ad3742a220800f0", size = 355253, upload-time = "2025-08-13T19:32:00.296Z" }, ] +[[package]] +name = "ruamel-yaml" +version = "0.19.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/3b/ebda527b56beb90cb7652cb1c7e4f91f48649fbcd8d2eb2fb6e77cd3329b/ruamel_yaml-0.19.1.tar.gz", hash = "sha256:53eb66cd27849eff968ebf8f0bf61f46cdac2da1d1f3576dd4ccee9b25c31993", size = 142709, upload-time = "2026-01-02T16:50:31.84Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b8/0c/51f6841f1d84f404f92463fc2b1ba0da357ca1e3db6b7fbda26956c3b82a/ruamel_yaml-0.19.1-py3-none-any.whl", hash = "sha256:27592957fedf6e0b62f281e96effd28043345e0e66001f97683aa9a40c667c93", size = 118102, upload-time = "2026-01-02T16:50:29.201Z" }, +] + [[package]] name = "ruff" version = "0.14.3" @@ -9430,10 +9540,10 @@ resolution-markers = [ "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "joblib", marker = "(python_full_version < '3.11' and platform_machine != 'aarch64') or (python_full_version < '3.11' and sys_platform != 'linux')" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine != 'aarch64') or (python_full_version < '3.11' and sys_platform != 'linux')" }, - { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine != 'aarch64') or (python_full_version < '3.11' and sys_platform != 'linux')" }, - { name = "threadpoolctl", marker = "(python_full_version < '3.11' and platform_machine != 'aarch64') or (python_full_version < '3.11' and sys_platform != 'linux')" }, + { name = "joblib" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" } }, + { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" } }, + { name = "threadpoolctl" }, ] sdist = { url = "https://files.pythonhosted.org/packages/98/c2/a7855e41c9d285dfe86dc50b250978105dce513d6e459ea66a6aeb0e1e0c/scikit_learn-1.7.2.tar.gz", hash = "sha256:20e9e49ecd130598f1ca38a1d85090e1a600147b9c02fa6f15d69cb53d968fda", size = 7193136, upload-time = "2025-09-09T08:21:29.075Z" } wheels = [ @@ -9475,10 +9585,10 @@ resolution-markers = [ "python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "joblib", marker = "(python_full_version >= '3.11' and platform_machine != 'aarch64') or (python_full_version >= '3.11' and sys_platform != 'linux')" }, - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'aarch64') or (python_full_version >= '3.11' and sys_platform != 'linux')" }, - { name = "scipy", version = "1.17.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'aarch64') or (python_full_version >= '3.11' and sys_platform != 'linux')" }, - { name = "threadpoolctl", marker = "(python_full_version >= '3.11' and platform_machine != 'aarch64') or (python_full_version >= '3.11' and sys_platform != 'linux')" }, + { name = "joblib" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" } }, + { name = "scipy", version = "1.17.0", source = { registry = "https://pypi.org/simple" } }, + { name = "threadpoolctl" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0e/d4/40988bf3b8e34feec1d0e6a051446b1f66225f8529b9309becaeef62b6c4/scikit_learn-1.8.0.tar.gz", hash = "sha256:9bccbb3b40e3de10351f8f5068e105d0f4083b1a65fa07b6634fbc401a6287fd", size = 7335585, upload-time = "2025-12-10T07:08:53.618Z" } wheels = [ @@ -9514,7 +9624,7 @@ resolution-markers = [ "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/0f/37/6964b830433e654ec7485e45a00fc9a27cf868d622838f6b6d9c5ec0d532/scipy-1.15.3.tar.gz", hash = "sha256:eae3cf522bc7df64b42cad3925c876e1b0b6c35c1337c93e12c0f366f55b0eaf", size = 59419214, upload-time = "2025-05-08T16:13:05.955Z" } wheels = [ @@ -9570,7 +9680,7 @@ resolution-markers = [ "python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/56/3e/9cca699f3486ce6bc12ff46dc2031f1ec8eb9ccc9a320fdaf925f1417426/scipy-1.17.0.tar.gz", hash = "sha256:2591060c8e648d8b96439e111ac41fd8342fdeff1876be2e19dea3fe8930454e", size = 30396830, upload-time = "2026-01-10T21:34:23.009Z" } wheels = [ @@ -9601,8 +9711,8 @@ name = "secretstorage" version = "3.5.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "cryptography", marker = "(python_full_version >= '3.11' and platform_machine == 'x86_64' and sys_platform != 'darwin' and sys_platform != 'win32') or (platform_machine != 'aarch64' and platform_machine != 'x86_64' and sys_platform != 'darwin' and sys_platform != 'win32') or sys_platform == 'linux'" }, - { name = "jeepney", marker = "(python_full_version >= '3.11' and platform_machine == 'x86_64' and sys_platform != 'darwin' and sys_platform != 'win32') or (platform_machine != 'aarch64' and platform_machine != 'x86_64' and sys_platform != 'darwin' and sys_platform != 'win32') or sys_platform == 'linux'" }, + { name = "cryptography" }, + { name = "jeepney" }, ] sdist = { url = "https://files.pythonhosted.org/packages/1c/03/e834bcd866f2f8a49a85eaff47340affa3bfa391ee9912a952a1faa68c7b/secretstorage-3.5.0.tar.gz", hash = "sha256:f04b8e4689cbce351744d5537bf6b1329c6fc68f91fa666f60a380edddcd11be", size = 19884, upload-time = "2025-11-23T19:02:53.191Z" } wheels = [ @@ -10024,7 +10134,7 @@ resolution-markers = [ "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "mpmath", marker = "(platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "mpmath" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ca/99/5a5b6f19ff9f083671ddf7b9632028436167cd3d33e11015754e41b249a4/sympy-1.13.1.tar.gz", hash = "sha256:9cebf7e04ff162015ce31c9c6c9144daa34a93bd082f54fd8f12deca4f47515f", size = 7533040, upload-time = "2024-07-19T09:26:51.238Z" } wheels = [ @@ -10048,7 +10158,7 @@ resolution-markers = [ "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'win32'", ] dependencies = [ - { name = "mpmath", marker = "(platform_machine == 'x86_64' and sys_platform == 'linux') or sys_platform == 'win32'" }, + { name = "mpmath" }, ] sdist = { url = "https://files.pythonhosted.org/packages/83/d3/803453b36afefb7c2bb238361cd4ae6125a569b4db67cd9e79846ba2d68c/sympy-1.14.0.tar.gz", hash = "sha256:d3d3fe8df1e5a0b42f0e7bdf50541697dbe7d23746e894990c030e2b05e72517", size = 7793921, upload-time = "2025-04-27T18:05:01.611Z" } wheels = [ @@ -10128,8 +10238,8 @@ resolution-markers = [ "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "ml-dtypes", marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "ml-dtypes" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/9f/ee/05eb424437f4db63331c90e4605025eedc0f71da3faff97161d5d7b405af/tensorstore-0.1.78.tar.gz", hash = "sha256:e26074ffe462394cf54197eb76d6569b500f347573cd74da3f4dd5f510a4ad7c", size = 6913502, upload-time = "2025-10-06T17:44:29.649Z" } wheels = [ @@ -10173,8 +10283,8 @@ resolution-markers = [ "python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "ml-dtypes", marker = "python_full_version >= '3.11'" }, - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "ml-dtypes" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/43/f6/e2403fc05b97ba74ad408a98a42c288e6e1b8eacc23780c153b0e5166179/tensorstore-0.1.81.tar.gz", hash = "sha256:687546192ea6f6c8ae28d18f13103336f68017d928b9f5a00325e9b0548d9c25", size = 7120819, upload-time = "2026-02-06T18:56:12.535Z" } wheels = [ @@ -10384,14 +10494,14 @@ resolution-markers = [ "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "filelock", marker = "(platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "fsspec", marker = "(platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "jinja2", marker = "(platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "networkx", version = "3.4.2", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine != 'x86_64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "networkx", version = "3.6.1", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "setuptools", marker = "(python_full_version >= '3.12' and platform_machine != 'x86_64' and sys_platform == 'linux') or (python_full_version >= '3.12' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "sympy", version = "1.13.1", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "typing-extensions", marker = "(platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "filelock" }, + { name = "fsspec" }, + { name = "jinja2" }, + { name = "networkx", version = "3.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "networkx", version = "3.6.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "setuptools", marker = "python_full_version >= '3.12'" }, + { name = "sympy", version = "1.13.1", source = { registry = "https://pypi.org/simple" } }, + { name = "typing-extensions" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/37/81/aa9ab58ec10264c1abe62c8b73f5086c3c558885d6beecebf699f0dbeaeb/torch-2.6.0-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:6860df13d9911ac158f4c44031609700e1eba07916fff62e21e6ffa0a9e01961", size = 766685561, upload-time = "2025-01-29T16:19:12.12Z" }, @@ -10422,29 +10532,29 @@ resolution-markers = [ "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'win32'", ] dependencies = [ - { name = "filelock", marker = "(platform_machine == 'x86_64' and sys_platform == 'linux') or sys_platform == 'win32'" }, - { name = "fsspec", marker = "(platform_machine == 'x86_64' and sys_platform == 'linux') or sys_platform == 'win32'" }, - { name = "jinja2", marker = "(platform_machine == 'x86_64' and sys_platform == 'linux') or sys_platform == 'win32'" }, - { name = "networkx", version = "3.4.2", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine == 'x86_64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "networkx", version = "3.6.1", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine == 'x86_64' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "nvidia-cublas-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, - { name = "nvidia-cuda-cupti-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, - { name = "nvidia-cuda-nvrtc-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, - { name = "nvidia-cuda-runtime-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, - { name = "nvidia-cudnn-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, - { name = "nvidia-cufft-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, - { name = "nvidia-cufile-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, - { name = "nvidia-curand-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, - { name = "nvidia-cusolver-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, - { name = "nvidia-cusparse-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, - { name = "nvidia-cusparselt-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, - { name = "nvidia-nccl-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, - { name = "nvidia-nvjitlink-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, - { name = "nvidia-nvtx-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, - { name = "setuptools", marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'linux') or (python_full_version >= '3.12' and sys_platform == 'win32')" }, - { name = "sympy", version = "1.14.0", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine == 'x86_64' and sys_platform == 'linux') or sys_platform == 'win32'" }, - { name = "triton", version = "3.3.1", source = { registry = "https://pypi.org/simple" }, marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, - { name = "typing-extensions", marker = "(platform_machine == 'x86_64' and sys_platform == 'linux') or sys_platform == 'win32'" }, + { name = "filelock" }, + { name = "fsspec" }, + { name = "jinja2" }, + { name = "networkx", version = "3.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "networkx", version = "3.6.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "nvidia-cublas-cu12", marker = "sys_platform != 'win32'" }, + { name = "nvidia-cuda-cupti-cu12", marker = "sys_platform != 'win32'" }, + { name = "nvidia-cuda-nvrtc-cu12", marker = "sys_platform != 'win32'" }, + { name = "nvidia-cuda-runtime-cu12", marker = "sys_platform != 'win32'" }, + { name = "nvidia-cudnn-cu12", marker = "sys_platform != 'win32'" }, + { name = "nvidia-cufft-cu12", marker = "sys_platform != 'win32'" }, + { name = "nvidia-cufile-cu12", marker = "sys_platform != 'win32'" }, + { name = "nvidia-curand-cu12", marker = "sys_platform != 'win32'" }, + { name = "nvidia-cusolver-cu12", marker = "sys_platform != 'win32'" }, + { name = "nvidia-cusparse-cu12", marker = "sys_platform != 'win32'" }, + { name = "nvidia-cusparselt-cu12", marker = "sys_platform != 'win32'" }, + { name = "nvidia-nccl-cu12", marker = "sys_platform != 'win32'" }, + { name = "nvidia-nvjitlink-cu12", marker = "sys_platform != 'win32'" }, + { name = "nvidia-nvtx-cu12", marker = "sys_platform != 'win32'" }, + { name = "setuptools", marker = "python_full_version >= '3.12'" }, + { name = "sympy", version = "1.14.0", source = { registry = "https://pypi.org/simple" } }, + { name = "triton", version = "3.3.1", source = { registry = "https://pypi.org/simple" }, marker = "sys_platform != 'win32'" }, + { name = "typing-extensions" }, ] wheels = [ { url = "https://download-r2.pytorch.org/whl/cu128/torch-2.7.1%2Bcu128-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:d6c3cba198dc93f93422a8545f48a6697890366e4b9701f54351fc27e2304bd3", upload-time = "2025-06-03T18:30:47Z" }, @@ -10485,10 +10595,10 @@ resolution-markers = [ "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine != 'x86_64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pillow", marker = "(platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "torch", version = "2.6.0", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "pillow" }, + { name = "torch", version = "2.6.0", source = { registry = "https://pypi.org/simple" } }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/a9/20/72eb0b5b08fa293f20fc41c374e37cf899f0033076f0144d2cdc48f9faee/torchvision-0.21.0-1-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:5568c5a1ff1b2ec33127b629403adb530fab81378d9018ca4ed6508293f76e2b", size = 2327643, upload-time = "2025-03-18T17:25:51.165Z" }, @@ -10522,10 +10632,10 @@ resolution-markers = [ "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'win32'", ] dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine == 'x86_64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine == 'x86_64' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "pillow", marker = "(platform_machine == 'x86_64' and sys_platform == 'linux') or sys_platform == 'win32'" }, - { name = "torch", version = "2.7.1+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "(platform_machine == 'x86_64' and sys_platform == 'linux') or sys_platform == 'win32'" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "pillow" }, + { name = "torch", version = "2.7.1+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" } }, ] wheels = [ { url = "https://download-r2.pytorch.org/whl/cu128/torchvision-0.22.1%2Bcu128-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:538f4db667286d939b4eee0a66d31ed21b51186668006b0e0ffe20338ecc7e00", upload-time = "2025-06-03T18:37:28Z" }, @@ -10674,7 +10784,7 @@ resolution-markers = [ "python_full_version < '3.11' and platform_machine == 'x86_64' and sys_platform == 'linux'", ] dependencies = [ - { name = "setuptools", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "setuptools" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/8d/a9/549e51e9b1b2c9b854fd761a1d23df0ba2fbc60bd0c13b489ffa518cfcb7/triton-3.3.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b74db445b1c562844d3cfad6e9679c72e93fdfb1a90a24052b03bb5c49d1242e", size = 155600257, upload-time = "2025-05-29T23:39:36.085Z" }, @@ -10692,7 +10802,7 @@ resolution-markers = [ "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "importlib-metadata", marker = "platform_machine == 'aarch64' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'" }, + { name = "importlib-metadata" }, ] [[package]] @@ -10772,8 +10882,8 @@ name = "typing-inspect" version = "0.9.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "mypy-extensions", marker = "python_full_version >= '3.11'" }, - { name = "typing-extensions", marker = "python_full_version >= '3.11'" }, + { name = "mypy-extensions" }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/dc/74/1789779d91f1961fa9438e9a8710cdae6bd138c80d7303996933d117264a/typing_inspect-0.9.0.tar.gz", hash = "sha256:b23fc42ff6f6ef6954e4852c1fb512cdd18dbea03134f91f856a95ccc9461f78", size = 13825, upload-time = "2023-05-24T20:25:47.612Z" } wheels = [ @@ -11340,12 +11450,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8e/93/af1d6ccb69ab6b5a00e03fa0cefa563f9862412667776ea15dd4eece3a90/whatthepatch-1.0.7-py3-none-any.whl", hash = "sha256:1b6f655fd31091c001c209529dfaabbabdbad438f5de14e3951266ea0fc6e7ed", size = 11964, upload-time = "2024-11-16T17:21:20.761Z" }, ] +[[package]] +name = "wheel" +version = "0.48.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "packaging" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d0/20/50ed6bdf27dec98b568a8ae25dc599f35baa3d9709f9e83fd1edb56b9a90/wheel-0.48.0.tar.gz", hash = "sha256:94800765601e9171bf5d58d066e640662842bcedcbab982b2c90787a2c987322", size = 66471, upload-time = "2026-08-11T22:02:27.327Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2e/29/69cfbb602cd91690c55d38ba9fe53e6a7e76a6fa647bf38f19c138d25449/wheel-0.48.0-py3-none-any.whl", hash = "sha256:3217dcc807155e45db462d7ef2431f5ddda0d7273b700d05a67b271ceb1287ab", size = 33320, upload-time = "2026-08-11T22:02:26.1Z" }, +] + [[package]] name = "winrt-runtime" version = "3.2.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions", marker = "sys_platform == 'win32'" }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/16/dd/acdd527c1d890c8f852cc2af644aa6c160974e66631289420aa871b05e65/winrt_runtime-3.2.1.tar.gz", hash = "sha256:c8dca19e12b234ae6c3dadf1a4d0761b51e708457492c13beb666556958801ea", size = 21721, upload-time = "2025-06-06T14:40:27.593Z" } wheels = [ @@ -11365,7 +11487,7 @@ name = "winrt-windows-devices-bluetooth" version = "3.2.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "winrt-runtime", marker = "sys_platform == 'win32'" }, + { name = "winrt-runtime" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b2/a0/1c8a0c469abba7112265c6cb52f0090d08a67c103639aee71fc690e614b8/winrt_windows_devices_bluetooth-3.2.1.tar.gz", hash = "sha256:db496d2d92742006d5a052468fc355bf7bb49e795341d695c374746113d74505", size = 23732, upload-time = "2025-06-06T14:41:20.489Z" } wheels = [ @@ -11385,7 +11507,7 @@ name = "winrt-windows-devices-bluetooth-advertisement" version = "3.2.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "winrt-runtime", marker = "sys_platform == 'win32'" }, + { name = "winrt-runtime" }, ] sdist = { url = "https://files.pythonhosted.org/packages/06/fc/7ffe66ca4109b9e994b27c00f3d2d506e6e549e268791f755287ad9106d8/winrt_windows_devices_bluetooth_advertisement-3.2.1.tar.gz", hash = "sha256:0223852a7b7fa5c8dea3c6a93473bd783df4439b1ed938d9871f947933e574cc", size = 16906, upload-time = "2025-06-06T14:41:21.448Z" } wheels = [ @@ -11405,7 +11527,7 @@ name = "winrt-windows-devices-bluetooth-genericattributeprofile" version = "3.2.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "winrt-runtime", marker = "sys_platform == 'win32'" }, + { name = "winrt-runtime" }, ] sdist = { url = "https://files.pythonhosted.org/packages/44/21/aeeddc0eccdfbd25e543360b5cc093233e2eab3cdfb53ad3cabae1b5d04d/winrt_windows_devices_bluetooth_genericattributeprofile-3.2.1.tar.gz", hash = "sha256:cdf6ddc375e9150d040aca67f5a17c41ceaf13a63f3668f96608bc1d045dde71", size = 38896, upload-time = "2025-06-06T14:41:22.687Z" } wheels = [ @@ -11425,7 +11547,7 @@ name = "winrt-windows-devices-enumeration" version = "3.2.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "winrt-runtime", marker = "sys_platform == 'win32'" }, + { name = "winrt-runtime" }, ] sdist = { url = "https://files.pythonhosted.org/packages/9e/dd/75835bfbd063dffa152109727dedbd80f6e92ea284855f7855d48cdf31c9/winrt_windows_devices_enumeration-3.2.1.tar.gz", hash = "sha256:df316899e39bfc0ffc1f3cb0f5ee54d04e1d167fbbcc1484d2d5121449a935cf", size = 23538, upload-time = "2025-06-06T14:41:26.787Z" } wheels = [ @@ -11445,7 +11567,7 @@ name = "winrt-windows-devices-radios" version = "3.2.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "winrt-runtime", marker = "sys_platform == 'win32'" }, + { name = "winrt-runtime" }, ] sdist = { url = "https://files.pythonhosted.org/packages/5e/02/9704ea359ad8b0d6faa1011f98fb477e8fb6eac5201f39d19e73c2407e7b/winrt_windows_devices_radios-3.2.1.tar.gz", hash = "sha256:4dc9b9d1501846049eb79428d64ec698d6476c27a357999b78a8331072e18a0b", size = 5908, upload-time = "2025-06-06T14:41:44.868Z" } wheels = [ @@ -11465,7 +11587,7 @@ name = "winrt-windows-foundation" version = "3.2.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "winrt-runtime", marker = "sys_platform == 'win32'" }, + { name = "winrt-runtime" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0c/55/098ce7ea0679efcc1298b269c48768f010b6c68f90c588f654ec874c8a74/winrt_windows_foundation-3.2.1.tar.gz", hash = "sha256:ad2f1fcaa6c34672df45527d7c533731fdf65b67c4638c2b4aca949f6eec0656", size = 30485, upload-time = "2025-06-06T14:41:53.344Z" } wheels = [ @@ -11485,7 +11607,7 @@ name = "winrt-windows-foundation-collections" version = "3.2.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "winrt-runtime", marker = "sys_platform == 'win32'" }, + { name = "winrt-runtime" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ef/62/d21e3f1eeb8d47077887bbf0c3882c49277a84d8f98f7c12bda64d498a07/winrt_windows_foundation_collections-3.2.1.tar.gz", hash = "sha256:0eff1ad0d8d763ad17e9e7bbd0c26a62b27215016393c05b09b046d6503ae6d5", size = 16043, upload-time = "2025-06-06T14:41:53.983Z" } wheels = [ @@ -11505,7 +11627,7 @@ name = "winrt-windows-storage-streams" version = "3.2.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "winrt-runtime", marker = "sys_platform == 'win32'" }, + { name = "winrt-runtime" }, ] sdist = { url = "https://files.pythonhosted.org/packages/00/50/f4488b07281566e3850fcae1021f0285c9653992f60a915e15567047db63/winrt_windows_storage_streams-3.2.1.tar.gz", hash = "sha256:476f522722751eb0b571bc7802d85a82a3cae8b1cce66061e6e758f525e7b80f", size = 34335, upload-time = "2025-06-06T14:43:23.905Z" } wheels = [