From f3d5e56810774e101b06bbbf8e5c8a1134b37d3d Mon Sep 17 00:00:00 2001 From: Maciej Majek Date: Wed, 1 Jul 2026 18:30:46 +0200 Subject: [PATCH 01/11] chore: rename docker images mobile-manipulator-demo -> agentic-mobile-manipulator MMD was the old project name. Renames the published image names in docker/compose.yaml and the quickstart doc reference. --- docker/compose.yaml | 8 ++++---- docs/quickstart.md | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docker/compose.yaml b/docker/compose.yaml index 8e9c3fc..95fa16a 100644 --- a/docker/compose.yaml +++ b/docker/compose.yaml @@ -10,7 +10,7 @@ # # Build everything: docker compose -f docker/compose.yaml build # Run the demo: xhost +local:root && docker compose -f docker/compose.yaml up demo -# Attach to a session: docker exec -it $(docker ps -qf ancestor=robotecai/mobile-manipulator-demo:latest) tmux attach -t agentic-mobile-manipulator-sim +# Attach to a session: docker exec -it $(docker ps -qf ancestor=robotecai/agentic-mobile-manipulator:latest) tmux attach -t agentic-mobile-manipulator-sim # (sessions: -sim -stack -llm-servers -agents -hmi) # # Target is single-pc-gpu-and-npu (the default). For a GPU-only image — llama.cpp @@ -28,14 +28,14 @@ services: # ── Base: RoboStack ROS 2 + built workspace ──────────────────────────────── ros2: - image: robotecai/mobile-manipulator-demo-ros2:latest + image: robotecai/agentic-mobile-manipulator-ros2:latest build: context: .. dockerfile: docker/Dockerfile.ros2 # ── Base: + O3DE SDK and built simulation ────────────────────────────────── o3de: - image: robotecai/mobile-manipulator-demo-o3de:latest + image: robotecai/agentic-mobile-manipulator-o3de:latest build: context: .. dockerfile: docker/Dockerfile.o3de @@ -44,7 +44,7 @@ services: # ── The demo: + agents, local inference engines; runs the whole stack ─────── demo: - image: robotecai/mobile-manipulator-demo:latest + image: robotecai/agentic-mobile-manipulator:latest build: context: .. dockerfile: docker/Dockerfile.demo diff --git a/docs/quickstart.md b/docs/quickstart.md index 9a91f77..d85c2bc 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -60,7 +60,7 @@ docker compose -f docker/compose.yaml up demo Each component runs in its own tmux session inside the container. Attach to one (e.g. the simulation) from the host: ```bash -docker exec -it $(docker ps -qf ancestor=robotecai/mobile-manipulator-demo:latest) \ +docker exec -it $(docker ps -qf ancestor=robotecai/agentic-mobile-manipulator:latest) \ tmux attach -t agentic-mobile-manipulator-sim ``` From dbf7828c21542cedaaaf5df490b1813a2d129f91 Mon Sep 17 00:00:00 2001 From: Maciej Majek Date: Wed, 1 Jul 2026 18:31:10 +0200 Subject: [PATCH 02/11] ci: build via docker compose + headless sim smoke test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Build job was broken (referenced deleted docker/Dockerfile.agents and fed Dockerfile.o3de an ignored ROS2_IMAGE build-arg). Replace the hand-maintained build-push-action chain with 'docker compose build/push ros2 o3de' — the same ros2->o3de graph devs build locally, so it can't drift. Per-branch tags via AMM_IMG_SUFFIX (empty locally). Add a second job (needs: build-and-push) that boots the freshly-built o3de image headless with O3DE's null renderer (--rhi=null, no GPU/display) and passes iff /clock ticks — proving the image boots, loads the level, steps physics, and publishes over ROS 2. Camera/rendered sensors need a DRI3 display and are out of scope. Logic lives in scripts/sim_smoke.sh (pixi task: sim-smoke). --- .github/workflows/build_and_push_docker.yaml | 60 +++++++++---------- docker/compose.yaml | 7 ++- pixi.toml | 4 ++ scripts/sim_smoke.sh | 61 ++++++++++++++++++++ 4 files changed, 99 insertions(+), 33 deletions(-) create mode 100644 scripts/sim_smoke.sh diff --git a/.github/workflows/build_and_push_docker.yaml b/.github/workflows/build_and_push_docker.yaml index 442dc07..a7559a0 100644 --- a/.github/workflows/build_and_push_docker.yaml +++ b/.github/workflows/build_and_push_docker.yaml @@ -7,6 +7,11 @@ on: - development workflow_dispatch: +# Development builds get a -development image suffix so they never clobber main's +# :latest. Empty on every other branch. Consumed by docker/compose.yaml image names. +env: + SUFFIX: ${{ github.ref_name == 'development' && '-development' || '' }} + jobs: build-and-push: runs-on: self-hosted @@ -20,36 +25,31 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Build and push ROS 2 image - uses: docker/build-push-action@v6 - with: - context: . - file: docker/Dockerfile.ros2 - push: true - tags: | - robotecai/mobile-manipulator-demo-ros2${{ github.ref_name == 'development' && '-development' || '' }}:latest + # Build the ros2 -> o3de chain straight from docker/compose.yaml (the same + # graph devs build locally, via additional_contexts). Scoped to these two: + # `demo` is the heavy GPU+NPU single-PC image, not published here. + - name: Build and push base images (ros2, o3de) + env: + AMM_IMG_SUFFIX: ${{ env.SUFFIX }} + run: | + docker compose -f docker/compose.yaml build ros2 o3de + docker compose -f docker/compose.yaml push ros2 o3de - - name: Build and push Agents image - uses: docker/build-push-action@v6 + # Headless sim liveness gate. Boots O3DE with the null renderer (no GPU/display) + # and passes iff /clock ticks — proves the image actually boots, loads the level, + # steps physics, and publishes over ROS 2. See scripts/sim_smoke.sh. + smoke-test: + needs: build-and-push + runs-on: self-hosted + steps: + - name: Log in to Docker Hub + uses: docker/login-action@v3 with: - context: . - file: docker/Dockerfile.agents - push: true - build-args: | - ROS2_IMAGE=robotecai/mobile-manipulator-demo-ros2${{ github.ref_name == 'development' && '-development' || '' }}:latest - tags: | - robotecai/mobile-manipulator-demo-agents${{ github.ref_name == 'development' && '-development' || '' }}:latest + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Build and push O3DE image - uses: docker/build-push-action@v6 - with: - context: . - file: docker/Dockerfile.o3de - push: true - build-args: | - ROS2_IMAGE=robotecai/mobile-manipulator-demo-ros2${{ github.ref_name == 'development' && '-development' || '' }}:latest - tags: | - robotecai/mobile-manipulator-demo-o3de${{ github.ref_name == 'development' && '-development' || '' }}:latest + - name: Headless sim smoke test (/clock) + run: | + IMAGE="robotecai/agentic-mobile-manipulator-o3de${SUFFIX}:latest" + docker pull "$IMAGE" + docker run --rm --entrypoint pixi "$IMAGE" run sim-smoke diff --git a/docker/compose.yaml b/docker/compose.yaml index 95fa16a..4b58243 100644 --- a/docker/compose.yaml +++ b/docker/compose.yaml @@ -28,14 +28,15 @@ services: # ── Base: RoboStack ROS 2 + built workspace ──────────────────────────────── ros2: - image: robotecai/agentic-mobile-manipulator-ros2:latest + # AMM_IMG_SUFFIX lets CI publish per-branch tags (e.g. -development); empty locally. + image: robotecai/agentic-mobile-manipulator-ros2${AMM_IMG_SUFFIX:-}:latest build: context: .. dockerfile: docker/Dockerfile.ros2 # ── Base: + O3DE SDK and built simulation ────────────────────────────────── o3de: - image: robotecai/agentic-mobile-manipulator-o3de:latest + image: robotecai/agentic-mobile-manipulator-o3de${AMM_IMG_SUFFIX:-}:latest build: context: .. dockerfile: docker/Dockerfile.o3de @@ -44,7 +45,7 @@ services: # ── The demo: + agents, local inference engines; runs the whole stack ─────── demo: - image: robotecai/agentic-mobile-manipulator:latest + image: robotecai/agentic-mobile-manipulator${AMM_IMG_SUFFIX:-}:latest build: context: .. dockerfile: docker/Dockerfile.demo diff --git a/pixi.toml b/pixi.toml index c21de34..e667135 100644 --- a/pixi.toml +++ b/pixi.toml @@ -162,6 +162,10 @@ description = "Launch O3DE simulation in its own tmux session" cmd = "$DEMO_ROOT/sim/build/linux/bin/profile/MobileManipulatorDemo.GameLauncher -bg_ConnectToAssetProcessor=0" description = "Launch O3DE simulation in the foreground (no tmux)" +[feature.sim.tasks.sim-smoke] +cmd = "bash scripts/sim_smoke.sh" +description = "Headless sim smoke test: boot with --rhi=null, pass if /clock ticks (no GPU/display)" + [feature.sim.tasks.editor] cmd = "$O3DE_ENGINE_PATH/bin/Linux/profile/Default/Editor --project-path $DEMO_ROOT/sim" description = "Launch O3DE Editor from SDK (project must be built first)" diff --git a/scripts/sim_smoke.sh b/scripts/sim_smoke.sh new file mode 100644 index 0000000..5c626a8 --- /dev/null +++ b/scripts/sim_smoke.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +# Headless smoke test for the O3DE sim. +# +# Boots the GameLauncher with the null renderer (--rhi=null) — no GPU, no X +# display needed — and passes if the simulation is actually *ticking*, proven by +# catching a message on /clock within a timeout. That single check exercises the +# whole cold path: binary runs, assets + level load, PhysX ticks, and the ROS 2 +# bridge publishes. +# +# NOT checked: camera / rendered sensors. Those need the Atom (Vulkan) renderer, +# which headless needs a DRI3-capable display for — Xvfb doesn't provide DRI3, so +# the GPU+Vulkan path wedges on swapchain creation. rhi=null has no renderer at +# all, so camera topics are advertised but never publish. Verifying rendered +# output headless is a separate, unsolved problem; keep it out of the fast gate. +# +# Run: pixi run sim-smoke +# In Docker: docker run --rm --entrypoint pixi run sim-smoke +# Tune: SIM_SMOKE_TIMEOUT=120 pixi run sim-smoke +# SIM_SMOKE_TOPIC=/joint_states SIM_SMOKE_TYPE=sensor_msgs/msg/JointState pixi run sim-smoke +set -uo pipefail + +# Hermetic: only ever see our own sim on loopback, so a neighbouring sim on a +# shared CI runner can't cause a false pass. +export ROS_LOCALHOST_ONLY=1 + +LAUNCHER="${DEMO_ROOT:-$PWD}/sim/build/linux/bin/profile/MobileManipulatorDemo.GameLauncher" +TIMEOUT="${SIM_SMOKE_TIMEOUT:-90}" # boot + first message; rhi=null is faster than Vulkan +TOPIC="${SIM_SMOKE_TOPIC:-/clock}" +# Type must be explicit: with no publisher up yet, `ros2 topic echo` can't infer +# the type from the graph and bails instantly instead of waiting. +TYPE="${SIM_SMOKE_TYPE:-rosgraph_msgs/msg/Clock}" +LOG="$(mktemp)" + +[ -x "$LAUNCHER" ] || { echo "[FAIL] launcher not built: $LAUNCHER"; exit 1; } + +# GameLauncher ignores SIGINT (won't stop on Ctrl+C), so hard-kill on exit. +# Kill the captured PID, plus a pkill by full command line as a fallback (the +# comm name isn't reliably set during early boot). pkill -f is safe: this shell's +# own argv is just "bash scripts/sim_smoke.sh", so it can't match itself. +LAUNCHER_PID="" +cleanup() { + [ -n "$LAUNCHER_PID" ] && kill -9 "$LAUNCHER_PID" 2>/dev/null + pkill -9 -f 'MobileManipulatorDemo.GameLauncher' 2>/dev/null +} +trap cleanup EXIT + +echo "[smoke] launching sim headless (--rhi=null)" +env -u DISPLAY "$LAUNCHER" -bg_ConnectToAssetProcessor=0 --rhi=null >"$LOG" 2>&1 & +LAUNCHER_PID=$! + +# /clock is published BEST_EFFORT; a default (reliable) subscriber gets nothing. +echo "[smoke] waiting up to ${TIMEOUT}s for a message on ${TOPIC} (${TYPE})" +if timeout "$TIMEOUT" ros2 topic echo --once --qos-reliability best_effort "$TOPIC" "$TYPE" >/dev/null 2>&1; then + echo "[PASS] ${TOPIC} is publishing — sim ticks headless" + exit 0 +fi + +echo "[FAIL] no message on ${TOPIC} within ${TIMEOUT}s" +echo "----- last 30 log lines -----" +tail -30 "$LOG" +exit 1 From f256204a895dd63b56b05f94863df40de29554e0 Mon Sep 17 00:00:00 2001 From: Maciej Majek Date: Wed, 1 Jul 2026 18:35:34 +0200 Subject: [PATCH 03/11] ci: run docker build/smoke on tagged self-hosted runner (cpu, heavy, gpu) --- .github/workflows/build_and_push_docker.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_and_push_docker.yaml b/.github/workflows/build_and_push_docker.yaml index a7559a0..ae52554 100644 --- a/.github/workflows/build_and_push_docker.yaml +++ b/.github/workflows/build_and_push_docker.yaml @@ -14,7 +14,7 @@ env: jobs: build-and-push: - runs-on: self-hosted + runs-on: [self-hosted, cpu, heavy, gpu] steps: - name: Checkout code uses: actions/checkout@v4 @@ -40,7 +40,7 @@ jobs: # steps physics, and publishes over ROS 2. See scripts/sim_smoke.sh. smoke-test: needs: build-and-push - runs-on: self-hosted + runs-on: [self-hosted, cpu, heavy, gpu] steps: - name: Log in to Docker Hub uses: docker/login-action@v3 From db03fb2d11d29a10269b78d369ae883dae4159bb Mon Sep 17 00:00:00 2001 From: Maciej Majek Date: Wed, 1 Jul 2026 18:37:04 +0200 Subject: [PATCH 04/11] ci: TEMP run on every PR commit for testing --- .github/workflows/build_and_push_docker.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build_and_push_docker.yaml b/.github/workflows/build_and_push_docker.yaml index ae52554..ac2a65d 100644 --- a/.github/workflows/build_and_push_docker.yaml +++ b/.github/workflows/build_and_push_docker.yaml @@ -5,6 +5,8 @@ on: branches: - main - development + # TEMP (testing): run on every PR commit. Remove before merge. + pull_request: workflow_dispatch: # Development builds get a -development image suffix so they never clobber main's From c05d11fa86ddb292764f5e921a9604889e8de7c8 Mon Sep 17 00:00:00 2001 From: Maciej Majek Date: Wed, 1 Jul 2026 19:58:55 +0200 Subject: [PATCH 05/11] chore: update docker comments --- .github/workflows/build_and_push_docker.yaml | 14 +------------- docker/compose.yaml | 13 +++---------- 2 files changed, 4 insertions(+), 23 deletions(-) diff --git a/.github/workflows/build_and_push_docker.yaml b/.github/workflows/build_and_push_docker.yaml index ac2a65d..da3dee5 100644 --- a/.github/workflows/build_and_push_docker.yaml +++ b/.github/workflows/build_and_push_docker.yaml @@ -5,15 +5,9 @@ on: branches: - main - development - # TEMP (testing): run on every PR commit. Remove before merge. pull_request: workflow_dispatch: -# Development builds get a -development image suffix so they never clobber main's -# :latest. Empty on every other branch. Consumed by docker/compose.yaml image names. -env: - SUFFIX: ${{ github.ref_name == 'development' && '-development' || '' }} - jobs: build-and-push: runs-on: [self-hosted, cpu, heavy, gpu] @@ -27,9 +21,6 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - # Build the ros2 -> o3de chain straight from docker/compose.yaml (the same - # graph devs build locally, via additional_contexts). Scoped to these two: - # `demo` is the heavy GPU+NPU single-PC image, not published here. - name: Build and push base images (ros2, o3de) env: AMM_IMG_SUFFIX: ${{ env.SUFFIX }} @@ -37,9 +28,6 @@ jobs: docker compose -f docker/compose.yaml build ros2 o3de docker compose -f docker/compose.yaml push ros2 o3de - # Headless sim liveness gate. Boots O3DE with the null renderer (no GPU/display) - # and passes iff /clock ticks — proves the image actually boots, loads the level, - # steps physics, and publishes over ROS 2. See scripts/sim_smoke.sh. smoke-test: needs: build-and-push runs-on: [self-hosted, cpu, heavy, gpu] @@ -52,6 +40,6 @@ jobs: - name: Headless sim smoke test (/clock) run: | - IMAGE="robotecai/agentic-mobile-manipulator-o3de${SUFFIX}:latest" + IMAGE="robotecai/agentic-mobile-manipulator-o3de:latest" docker pull "$IMAGE" docker run --rm --entrypoint pixi "$IMAGE" run sim-smoke diff --git a/docker/compose.yaml b/docker/compose.yaml index 4b58243..d39b6e2 100644 --- a/docker/compose.yaml +++ b/docker/compose.yaml @@ -28,15 +28,14 @@ services: # ── Base: RoboStack ROS 2 + built workspace ──────────────────────────────── ros2: - # AMM_IMG_SUFFIX lets CI publish per-branch tags (e.g. -development); empty locally. - image: robotecai/agentic-mobile-manipulator-ros2${AMM_IMG_SUFFIX:-}:latest + image: robotecai/agentic-mobile-manipulator-ros2:latest build: context: .. dockerfile: docker/Dockerfile.ros2 # ── Base: + O3DE SDK and built simulation ────────────────────────────────── o3de: - image: robotecai/agentic-mobile-manipulator-o3de${AMM_IMG_SUFFIX:-}:latest + image: robotecai/agentic-mobile-manipulator-o3de:latest build: context: .. dockerfile: docker/Dockerfile.o3de @@ -45,7 +44,7 @@ services: # ── The demo: + agents, local inference engines; runs the whole stack ─────── demo: - image: robotecai/agentic-mobile-manipulator${AMM_IMG_SUFFIX:-}:latest + image: robotecai/agentic-mobile-manipulator:latest build: context: .. dockerfile: docker/Dockerfile.demo @@ -69,7 +68,6 @@ services: - /dev/kfd:/dev/kfd # AMD GPU compute (ROCm) - /dev/dri:/dev/dri # AMD GPU render (Vulkan) - /dev/accel/accel0:/dev/accel/accel0 # Ryzen AI NPU (amdxdna) - # The NPU pins memory; without unlimited memlock FastFlowLM fails to allocate. ulimits: memlock: soft: -1 @@ -78,10 +76,5 @@ services: - /tmp/.X11-unix:/tmp/.X11-unix - ${XAUTHORITY:-$HOME/.Xauthority}:/root/.Xauthority - ../config.toml:/root/MobileManipulatorDemo/config.toml - # All weights live under the repo's models/: llama ggufs in models/, NPU - # models in models/flm (FLM_MODEL_PATH below). `pixi run download-models` - # fetches both. No host-home (~/.config/flm) coupling. - ../models:/root/MobileManipulatorDemo/models - # Single host: ROS 2 DDS + every inference endpoint talk over localhost, and - # host networking lets RViz/ros2 on the host introspect the running demo. network_mode: host From 9949e006bffdf4aeb50ac72d318633fca9f3cb62 Mon Sep 17 00:00:00 2001 From: Maciej Majek Date: Wed, 1 Jul 2026 19:59:43 +0200 Subject: [PATCH 06/11] feat(ci): cancel concurrent jobs --- .github/workflows/build_and_push_docker.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/build_and_push_docker.yaml b/.github/workflows/build_and_push_docker.yaml index da3dee5..512cb9d 100644 --- a/.github/workflows/build_and_push_docker.yaml +++ b/.github/workflows/build_and_push_docker.yaml @@ -8,6 +8,10 @@ on: pull_request: workflow_dispatch: +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: build-and-push: runs-on: [self-hosted, cpu, heavy, gpu] @@ -43,3 +47,4 @@ jobs: IMAGE="robotecai/agentic-mobile-manipulator-o3de:latest" docker pull "$IMAGE" docker run --rm --entrypoint pixi "$IMAGE" run sim-smoke + \ No newline at end of file From ad59026c735de1a077c38ac549f1438c2b4848b6 Mon Sep 17 00:00:00 2001 From: Maciej Majek Date: Wed, 1 Jul 2026 20:29:03 +0200 Subject: [PATCH 07/11] ci: build and push all compose services (adds demo image) --- .github/workflows/build_and_push_docker.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build_and_push_docker.yaml b/.github/workflows/build_and_push_docker.yaml index 512cb9d..6df5333 100644 --- a/.github/workflows/build_and_push_docker.yaml +++ b/.github/workflows/build_and_push_docker.yaml @@ -25,12 +25,12 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Build and push base images (ros2, o3de) + - name: Build and push all images env: AMM_IMG_SUFFIX: ${{ env.SUFFIX }} run: | - docker compose -f docker/compose.yaml build ros2 o3de - docker compose -f docker/compose.yaml push ros2 o3de + docker compose -f docker/compose.yaml build + docker compose -f docker/compose.yaml push smoke-test: needs: build-and-push From 99c156740d1cd431bee5363322dcedf0b1d5b0f7 Mon Sep 17 00:00:00 2001 From: Maciej Majek Date: Thu, 2 Jul 2026 12:05:15 +0200 Subject: [PATCH 08/11] fix: checkout with lfs --- .github/workflows/build_and_push_docker.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_and_push_docker.yaml b/.github/workflows/build_and_push_docker.yaml index 6df5333..188d535 100644 --- a/.github/workflows/build_and_push_docker.yaml +++ b/.github/workflows/build_and_push_docker.yaml @@ -18,6 +18,8 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 + with: + lfs: true - name: Log in to Docker Hub uses: docker/login-action@v3 @@ -47,4 +49,4 @@ jobs: IMAGE="robotecai/agentic-mobile-manipulator-o3de:latest" docker pull "$IMAGE" docker run --rm --entrypoint pixi "$IMAGE" run sim-smoke - \ No newline at end of file + From c4b8a757dcb96850a20ed968a7ad875134bfad77 Mon Sep 17 00:00:00 2001 From: Maciej Majek Date: Thu, 2 Jul 2026 12:12:53 +0200 Subject: [PATCH 09/11] chore: bump checkout version --- .github/workflows/build_and_push_docker.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_and_push_docker.yaml b/.github/workflows/build_and_push_docker.yaml index 188d535..31a9d43 100644 --- a/.github/workflows/build_and_push_docker.yaml +++ b/.github/workflows/build_and_push_docker.yaml @@ -17,7 +17,7 @@ jobs: runs-on: [self-hosted, cpu, heavy, gpu] steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: lfs: true From e6ead49293ec388861acbfd4b02dec09f8ef1cc2 Mon Sep 17 00:00:00 2001 From: Maciej Majek Date: Thu, 2 Jul 2026 13:59:23 +0200 Subject: [PATCH 10/11] docs: update --- docs/quickstart.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/docs/quickstart.md b/docs/quickstart.md index d85c2bc..4f92772 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -17,7 +17,9 @@ git clone https://github.com/RobotecAI/agentic-mobile-manipulator.git cd agentic-mobile-manipulator ``` -## 2. Build the image +## 2. Get the image: build _or_ pull + +**Build locally:** ```bash docker compose -f docker/compose.yaml build @@ -25,6 +27,14 @@ docker compose -f docker/compose.yaml build This builds three cacheable layers — `…-ros2` (RoboStack ROS 2 + workspace) → `…-o3de` (O3DE SDK + simulation) → `…demo` (Python agents + llama.cpp + FastFlowLM). The O3DE layer is large, so the first build takes a while; later rebuilds reuse the cached bases. +**Or pull the prebuilt images:** + +```bash +docker compose -f docker/compose.yaml pull +``` + +If you pull, remember to pass `--no-build` when starting the demo (see step 4). + ## 3. Download the model weights Weights are **not** baked into the image. They are downloaded into the repo's `models/` directory, bind-mounted at run time. `config.toml` is the single source of truth for which models are fetched. Pull them once into `models/` by running: @@ -44,9 +54,12 @@ Allow local connections to your X server, then start the `demo` service: ```bash xhost +local:root -docker compose -f docker/compose.yaml up demo +docker compose -f docker/compose.yaml up demo # if you built (step 2) +docker compose -f docker/compose.yaml up --no-build demo # if you pulled (step 2) ``` +> [!IMPORTANT] > `docker compose up` rebuilds any service that has a `build:` section — even when the image is already present locally. So after `pull`, a bare `up demo` ignores the pulled image and rebuilds `ros2 → o3de → demo`. Pass `--no-build` to run the pulled image as-is. + ## What to expect ![Demo Windows](demo_windows.jpg) From e3c62e43dce21cac8308f8db5899915a0f44d67a Mon Sep 17 00:00:00 2001 From: Maciej Majek Date: Thu, 2 Jul 2026 14:00:01 +0200 Subject: [PATCH 11/11] chore: remove on commit job hook --- .github/workflows/build_and_push_docker.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build_and_push_docker.yaml b/.github/workflows/build_and_push_docker.yaml index 31a9d43..1b35e23 100644 --- a/.github/workflows/build_and_push_docker.yaml +++ b/.github/workflows/build_and_push_docker.yaml @@ -5,7 +5,6 @@ on: branches: - main - development - pull_request: workflow_dispatch: concurrency: