Skip to content

docs: full MkDocs Material site grounded in current main code (39 pages, 5.2k lines)#160

Draft
cagataycali wants to merge 19 commits into
strands-labs:mainfrom
cagataycali:docs/mkdocs-site
Draft

docs: full MkDocs Material site grounded in current main code (39 pages, 5.2k lines)#160
cagataycali wants to merge 19 commits into
strands-labs:mainfrom
cagataycali:docs/mkdocs-site

Conversation

@cagataycali
Copy link
Copy Markdown
Member

Summary

A complete MkDocs Material documentation site for strands-robots, written from scratch against the current main code. 39 pages, 5245+ lines, zero build warnings under mkdocs build --strict.

The visual scaffolding (mkdocs.yml, theme, assets) was lifted from PR #40, but every .md page was rewritten because PR #40's prose referenced modules that no longer exist (Robot factory, simulation backend, mesh, LIBERO, GR00T N1.7 — all post-#40).

Live preview after merge: https://strands-labs.github.io/robots

What's included

Section Pages What
Landing index.md, learning-path.md Three-line promise, four feature cards, Recently shipped admonition; three learning tracks (try-it / ship-it / extend-it).
Tutorial tutorial/01..09 + index First robot → simulation → policies → agents → multi-robot → recording → training → real hardware → advanced. Each ~150-230 lines.
Getting started quickstart.md, installation.md, robot-factory.md 5-min install, full extras matrix + platform notes, every Robot() kwarg.
Robots index.md + 5 category pages All 68 catalog robots from registry/robots.json listed in their category page (arms, bimanual, hands, humanoids, mobile/aerial/mobile_manip), with featured renders.
Simulation overview.md, world-building.md, domain-randomization.md, gymnasium-env.md Full action vocabulary, scene composition, randomization distributions, gymnasium adapter status.
Policies overview.md, groot.md, lerobot-local.md, custom-policies.md, gear-sonic.md Policy ABC, three shipping providers, write-your-own walkthrough, GEAR-SONIC integration sketch.
Hardware robot-control.md, tools.md HardwareRobot class + 5 @tool helpers (calibrate, camera, teleop, pose, serial).
Misc recording.md, training/overview.md, examples/overview.md, architecture.md, api-reference.md, contributing.md, troubleshooting.md LeRobot v3 recording, the explicit 'no trainer in the box' policy, full API reference, error→fix tables.

How it was built

Following DOCS_PLAN.md (which is included in the PR), 20 autonomous cycles each:

  1. Opened the relevant code under strands_robots/... and the registry JSONs.
  2. Wrote the page grounded in real symbols / signatures / file paths.
  3. Ran mkdocs build --strict after every page batch.
  4. Committed with a short descriptive message.

Each commit corresponds to one cycle. The 17 docs commits make the diff easy to review chunk-by-chunk.

Source-of-truth grounding

  • Registry-driven robot pages. robots/{arms,bimanual,hands,humanoids,mobile}.md are generated from strands_robots/registry/robots.json so the catalog never drifts from the code.
  • Real symbol tables. API reference quotes the actual exported names (Policy, MockPolicy, create_policy, Simulation, SimEngine, DatasetRecorder, init_mesh, etc.), not invented ones.
  • Real file paths. Every "see also" cites strands_robots/... files that exist on main.

How to review

pip install mkdocs-material pymdown-extensions
mkdocs serve
# → http://localhost:8000

Check:

  • All 39 pages render.
  • Dark/light theme toggle works.
  • Robot render images load (robots/*.md pages).
  • Mermaid diagrams render (index.md, architecture.md, learning-path.md).
  • Internal links resolve (mkdocs build --strict catches broken ones).
  • Code blocks read as runnable Python.

Checklist

  • mkdocs build --strict exits 0 with zero warnings
  • All 39 nav entries point at real files
  • Every robot in registry/robots.json appears on its category page
  • No host paths anywhere in the docs
  • No emojis in code blocks
  • Cross-links: every page has a 'See also' footer with 2-3 sibling links
  • index.md has a 'Recently shipped' admonition pointing at recent PRs

This PR is companion documentation for the current main codebase. It's intentionally written against main rather than any feature branch so it ships in lockstep with the API as it stands today.

cagataycali added a commit to cagataycali/robots that referenced this pull request May 16, 2026
All 20 cycles ticked. The docs site is live as PR
strands-labs#160.
Copy link
Copy Markdown
Contributor

@yinsong1986 yinsong1986 left a comment

Choose a reason for hiding this comment

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

Summary

This is a 39-page MkDocs site rewritten against current main. The structural work — nav, theme, registry-driven robot pages, lazy-import discipline diagram, env-var inventory — is solid and the site does build under mkdocs build --strict. Big credit for grounding the registry pages in registry/robots.json and the api-reference page in actual exported names.

The blocker is that the runnable code blocks — which the PR description explicitly promises are runnable Python — frequently aren't. They use kwarg names and return-dict keys that don't match the implementation on this branch. A reader who copy-pastes the quickstart will get a KeyError on render, a TypeError on add_object, and a TypeError: missing 1 required positional argument: 'robot_name' on run_policy. The architecture page also misrepresents the Policy ABC in a way that contradicts api-reference.md three pages over.

None of these are theme/lint issues — they're factual code-vs-docs drift. Inline comments call out the most representative occurrences; the same patterns repeat across other tutorial chapters and should be swept together.

What's good

  • Registry-driven robot category pages — they will not drift from the catalog.
  • api-reference.md exports list matches the actual __all__ / public symbols I spot-checked.
  • Env-var table in installation.md matches the four canonical env vars in AGENTS.md (STRANDS_ROBOT_MODE, STRANDS_TRUST_REMOTE_CODE, MUJOCO_GL, plus the asset/audit ones).
  • Lazy-import contract is correctly described in architecture.md and contributing.md.
  • Per-page "See also" footers are consistently present.

Concerns (summary-level)

  • Code blocks aren't smoke-tested. DOCS_PLAN.md > Hard rules #2 says "Every code block must work" and lists python3 -c as the smoke check. The repeated render()["frame"], add_object(type=..., pos=..., rgba=...), and run_policy(instruction=..., policy_provider=...) (no robot_name) patterns suggest this gate was not actually run. A pre-merge sweep with a small extractor that runs each fenced ```python block against the installed library would catch all of these.
  • Internal inconsistency between architecture.md and api-reference.md on the Policy ABC surface. Pick one and propagate.
  • docs/examples/overview.md describes an examples/ directory that doesn't exist on this branch. git ls-tree pr-head -- examples/ returns empty. Either the example scripts ship in this PR (they don't) or the page should link to a future PR / be marked as a roadmap stub like policies/gear-sonic.md is.
  • DOCS_PLAN.md is on main already and the PR edits it (14 lines). The plan is fine to land alongside the docs, but if the docs site itself is the deliverable, the meta-plan probably belongs in docs/internal/ or the PR description, not the repo root. Not blocking — flagging since the file is normally an authoring scratch-pad.
  • Asset binaries (~30 PNGs/GIFs/MP4s) added without a note on size or whether they're tracked via git-lfs. Worth confirming the repo's clone size impact before merge.

Verification suggestions

# 1. Smoke-test every fenced python block in docs/
python3 - <<'PY'
import pathlib, re, ast
for p in pathlib.Path("docs").rglob("*.md"):
    for i, m in enumerate(re.finditer(r"```python\n(.*?)```", p.read_text(), re.S)):
        try:
            ast.parse(m.group(1))
        except SyntaxError as e:
            print(f"{p}:{i}: {e}")
PY
# (catches syntax errors, not runtime — but a meaningful first cut)

# 2. Diff the api-reference symbol list against actual __all__:
python3 -c "import strands_robots, strands_robots.policies, strands_robots.tools, strands_robots.simulation, strands_robots.mesh; \
  [print(m, getattr(__import__(m, fromlist=['x']), '__all__', '<no __all__>')) for m in \
    ('strands_robots','strands_robots.policies','strands_robots.tools','strands_robots.simulation','strands_robots.mesh')]"

# 3. Verify the 35+ action vocabulary count claim against AgentTool dispatch:
grep -E '^\s+(elif|if) action ==' strands_robots/simulation/mujoco/simulation.py | wc -l

Comment thread docs/architecture.md
# strands_robots/policies/base.py
class Policy(ABC):
@abstractmethod
def get_action(self, observation: dict) -> dict: ...
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

These signatures don't match strands_robots/policies/base.py on this branch. The actual ABC declares:

class Policy(ABC):
    @abstractmethod
    async def get_actions(
        self, observation_dict: dict[str, Any], instruction: str, **kwargs: Any
    ) -> list[dict[str, Any]]: ...

    @abstractmethod
    def set_robot_state_keys(self, robot_state_keys: list[str]) -> None: ...

    @property
    @abstractmethod
    def provider_name(self) -> str: ...

    @property
    def requires_images(self) -> bool: ...   # default True

No get_action (singular, sync), no reset(). Note api-reference.md line 115 already lists the correct triplet (get_actions, set_robot_state_keys, requires_images) — so the two pages disagree with each other. Custom-policies.md will need a re-read against the same source.

```python
import imageio.v3 as iio

frame = sim.render(width=640, height=480)["frame"]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Three problems in this snippet and the next, all from the implementation having drifted from what the page assumes:

  1. render() doesn't return {"frame": ndarray}. Per simulation/mujoco/rendering.py:448-455, the return shape is {"status": "success", "content": [{"text": ...}, {"image": {"format": "png", "source": {"bytes": <png bytes>}}}, {"json": ...}]}. result["frame"] will KeyError. Either decode the PNG bytes from content[1]["image"]["source"]["bytes"] or use a different code sample.
  2. add_object (next block) uses wrong kwargs. Real signature in simulation/mujoco/simulation.py:996 is add_object(name, shape="box", position=None, orientation=None, size=None, color=None, mass=0.1, ...). The page passes type=, pos=, rgba= — none of which match. They get swallowed by **kwargs silently or TypeError depending on dispatch path.
  3. run_policy (next block) is missing the required robot_name arg. simulation/mujoco/simulation.py:1858 declares def run_policy(self, robot_name: str, ...) — no default. The example raises TypeError: missing 1 required positional argument: 'robot_name'.

Same three issues recur in tutorial/01-your-first-robot.md, tutorial/02-simulation.md, and tutorial/03-policies.md. Worth one sweep across all the runnable blocks.

sim.add_camera(name="wrist", attach_to="so100", pos=[0.05, 0, 0.1], fovy=60)

# Add a red cube on the table
sim.add_object(name="cube", type="box", size=[0.025, 0.025, 0.025],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Same add_object kwargs drift as in the quickstart — type=, pos=, rgba=, plus render(camera="wrist") on line 25 (the real kwarg is camera_name=, see simulation/base.py:230 and the strict camera-name validation in mujoco/rendering.py:417-424). Line 90 has the same pattern with type="sphere". Recommending a single sweep: add_object(name=..., shape=..., position=..., color=...) and render(camera_name=..., width=..., height=...).

pretrained_name_or_path="lerobot/pi0_so100") # local checkpoint

# Plug any of them into the sim
sim.run_policy(instruction="pick up the cube", policy_provider="mock", duration=10.0)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

sim.run_policy(instruction="pick up the cube", policy_provider="mock", duration=10.0) is missing the required robot_name argument (see simulation/mujoco/simulation.py:1858robot_name: str has no default). Line 144 (sim.run_policy(...) with policy=...) and line 153 (sim.run_policy(instruction=..., policy=policy, ...)) hit the same issue. Also: there is no policy= kwarg — the actual name is policy_object= (line 1869). Once you have robot_name plumbed in, double-check by walking the call against the keyword list in the source.

Comment thread docs/examples/overview.md
## In the repo

Browse them on GitHub:
[`strands-labs/robots/tree/main/examples`](https://github.com/strands-labs/robots/tree/main/examples)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

git ls-tree pr-head -- examples/ returns empty — there is no examples/ directory on this branch and the linked GitHub URL will 404 once published. The eight scripts in the table below (01_sim_quickstart.py through physics_agent.py) don't exist in the repo.

This page should either (a) be removed from the nav until a sibling PR adds the actual examples/ directory, or (b) be reframed as a roadmap stub the way policies/gear-sonic.md and simulation/gymnasium-env.md are (NOT YET IMPLEMENTED, point to roadmap per DOCS_PLAN.md cycle 11). Shipping a docs page that confidently describes nonexistent files is worse than not shipping the page.

@cagataycali cagataycali added the documentation Improvements or additions to documentation label May 23, 2026
@cagataycali cagataycali moved this to In review in Strands Labs - Robots May 23, 2026
@cagataycali cagataycali marked this pull request as draft May 23, 2026 06:31
@cagataycali cagataycali added this to the v0.4.0 milestone May 23, 2026
Initial scaffolding for the strands-robots documentation site.

- mkdocs.yml: lifted from PR40, Material theme + glassmorphic palette,
  full nav tree (39 pages across 11 sections).
- docs/assets/: 30+ robot render PNGs, demo MP4s/GIFs, logos.
- docs/stylesheets/extra.css: theme overrides.
- DOCS_PLAN.md: 20-cycle autonomous build plan grounding every page in
  the current main code (registry, robot factory, simulation, policies,
  tools, dataset recorder).

Subsequent commits will fill the docs/ tree page by page following
DOCS_PLAN.md.
…ning-path

- index.md: landing page with three-line promise, four feature cards
  (68 robots, MuJoCo simulation, pluggable policies, LeRobot v3 recording),
  mermaid pipeline diagram, install matrix, navigation map.
- learning-path.md: three tracks (try-it / ship-it / extend-it) each with
  a mermaid flow + 5-step table linking the right pages in order.
- All 37 other pages exist as placeholders so mkdocs build resolves nav
  links cleanly. Subsequent cycles fill them in.
- mkdocs build --site-dir /tmp passes with zero warnings against the
  current site map.
The diagram every other page references. Covers:

- Module map: factory → backends → policies → cross-cutting (recorder,
  tools, benchmarks)
- The three ABCs that every extension point implements:
  Policy (policies/base.py), SimEngine (simulation/base.py), Strands
  AgentTool (Simulation + HardwareRobot)
- Module-by-module table mapping each strands_robots/* file to its key
  types and responsibilities
- Optional dependency extras matrix ([sim-mujoco], [lerobot],
  [groot-service], [mesh], [benchmark-libero], [all], [dev])
- The 'one rule': lazy imports everywhere — enforced by tests/test_init.py
- Design principles: factory not class hierarchy, composition for
  cross-cutting, JSON registries, mirrored test layout

mkdocs build passes.
…imulation)

- tutorial/index.md: 9-chapter roadmap with category breakdown, time
  estimates, hardware/GPU markers, setup commands.
- 01-your-first-robot.md: install → list_robots() → Robot('so100') →
  step → render → cleanup. Smallest possible program. Explains the
  registry resolution, asset cache path, and the 35-action contract.
- 02-simulation.md: the Simulation AgentTool action vocabulary
  (10 categories), cameras, objects, render/render_depth, randomize,
  load_scene, set_gravity/set_timestep, run_policy preview.

Both pages cross-link forward to chapters 3-4 and sideways to
robot-factory + simulation/overview.
- 03-policies.md: the Policy ABC (3 abstract methods + requires_images),
  the three shipping providers (MockPolicy / Gr00tPolicy /
  LerobotLocalPolicy), the factory (create_policy + register_policy),
  the trust_remote_code gate (STRANDS_TRUST_REMOTE_CODE for
  lerobot_local), how Simulation.run_policy / start_policy / eval_policy
  consume them.
- 04-agents.md: Agent(tools=[Robot()]) — the headline integration. Walks
  through instantiation, multi-turn scene building, mixing tools/*.py
  helpers, and the sim→real transition with mode='real'. Includes a
  patterns table mapping common English to action chains.
- 05-multi-robot.md: two Robot() peers on Zenoh, peer discovery,
  point-to-point send, broadcast, emergency_stop with audit log,
  full topic schema (presence/state/cmd/response/stream/pose/imu/health/
  lidar/hand/broadcast), robot_mesh Strands tool integration,
  cross-machine teleoperation via InputPublisher/InputReceiver, disable
  switches.
- 06-recording.md: start_recording → run_policy → stop_recording, LeRobot
  v3 on-disk layout (meta/info.json, tasks.parquet, data/chunk-000/,
  videos/chunk-000/), multi-episode recording, push_to_hub, replay_episode.
  Schema auto-derived from observation/action features.
- 07-training.md: explicit 'no trainer in the box' policy. Three paths
  (LeRobot upstream, Isaac-GR00T fine-tune, Cosmos/custom). Sim-to-real
  considerations table. Reasoning for the split.
- 08-real-hardware.md: full bring-up checklist for an SO-100 (or any real
  arm). serial detection → calibration via lerobot_calibrate → camera
  config (opencv/realsense backends) → Robot(mode='real') → first motion
  → run_policy → teleoperate (local + mesh). Safety defaults section
  covers opt-in, velocity limits, watchdog, emergency_stop, and the
  trust_remote_code gate. Common-gotchas table.
Walks the internals every contributor needs:

- Robot() factory call sequence (normalize mode → resolve name →
  validate → auto-detect → branch sim/real → init_mesh)
- SimEngine ABC for custom backends (Isaac/Newton roadmap)
- Adding a robot via registry/robots.json — three asset fetch strategies
  (robot_descriptions_module, github source, manual urdf_path)
- Adding a policy via Policy subclass + register_policy or JSON entry
- Custom GR00T data_configs (25+ shipped, JSON-edited)
- Lazy import discipline enforced by tests/test_init.py
- Authoring new @tool helpers
…ory)

- quickstart.md: 5-minute walkthrough — install [sim-mujoco], spawn,
  render, add cube, run mock policy, optional Strands Agent layer.
- installation.md: extras matrix, common flavour recipes, platform notes
  (macOS, Linux, WSL, Jetson + numpy/pandas pinning), headless rendering
  via MUJOCO_GL, install verification snippet, cache directory layout
  with full env-var override table.
- robot-factory.md: full Robot() signature, every kwarg explained, mode
  semantics (sim/real/auto + STRANDS_ROBOT_MODE override), name
  resolution via alias map, validation rules, kwarg forwarding to
  backend ctors, mesh attachment + per-robot/process disable.
- robots/index.md: 8 category cards (arm, bimanual, humanoid, hand,
  mobile, mobile_manip, aerial, expressive), counts table summing to 68.
  Generated from strands_robots/registry/robots.json so it stays in
  sync.
- robots/arms.md: full table of 22 arms with descriptions, joint counts,
  aliases. Featured renders for 8 arms (panda, so100, ur5e, fr3,
  kinova_gen3, koch, kuka_iiwa, openarm, etc.). Compatibility notes
  flagging which arms have real-hardware support today vs sim-only.
All four pages generated from strands_robots/registry/robots.json so the
catalog never drifts from the code. Each page has:

- A 4-line TL;DR with concrete Robot('name') calls.
- Full registry-backed catalog table (description, joints, top-3 aliases).
- 6 featured sim_render images.
- Cross-links to neighbouring categories + relevant tutorial chapters.

Coverage: 3 bimanual, 8 hands, 19 humanoids+expressive, 16 mobile+
mobile_manip+aerial. Adds up to all 46 non-arm robots in the registry.
…tion,gymnasium-env}.md

- overview.md: comprehensive Simulation action reference grouped by
  category (world / robots / objects / cameras / rendering / physics /
  policies / recording / randomization / assets), 10 tables, return
  shape contract.
- world-building.md: composing scenes — add_robot/add_object/add_camera
  patterns, procedural composition example, load_scene for hand-authored
  MJCF, attached vs free cameras, tear-down semantics.
- domain-randomization.md: distribution per category (colors/lighting/
  physics/cameras/textures), use cases (recording, eval, sim-to-real),
  reset semantics, what's out of scope.
- gymnasium-env.md: explicit not-yet-implemented status with proposed
  API and the LIBERO benchmark workaround.
…es,gear-sonic}.md

- overview.md: Policy ABC, the three providers, MockPolicy inline,
  factory (create_policy / list_providers / register_policy), how
  Simulation.run_policy/start_policy/eval_policy consume them,
  trust_remote_code gate.
- groot.md: NVIDIA GR00T (N1.5/N1.6/N1.7), ZMQ vs HTTP transport, 25
  embodiment data_configs, container lifecycle via gr00t_inference tool,
  RTC, N1.7 wire-format specifics (B,T,...) shape + float32 state.
- lerobot-local.md: HF LeRobot direct inference, supported policies (ACT/
  Pi0/SmolVLA/Diffusion/VQ-BeT), trust_remote_code, processor bridge for
  0.4 vs 0.5 compatibility, RTC, local checkpoint loading.
- custom-policies.md: 3-step walkthrough (subclass Policy, register,
  use), runtime vs JSON registration, what the sim does for you,
  PyTorch wrapping pattern.
- gear-sonic.md: explicit 'not bundled' status with sketched custom-policy
  integration.
- robot-control.md: HardwareRobot class layout, kwargs (tool_name,
  robot, cameras, action_horizon, data_config, control_frequency),
  TaskStatus enum + lifecycle (run_policy / start_task / stop_task /
  get_task_status), camera ingestion, cleanup, mesh attachment, and a
  diff table with Simulation.
- tools.md: lerobot_calibrate, lerobot_camera, lerobot_teleoperate,
  pose_tool (FK/IK/gripper), serial_tool, plus pointers to the
  cross-cutting gr00t_inference and robot_mesh tools.
- recording.md: DatasetRecorder direct API for non-sim use cases, on-disk
  layout (meta/info.json, tasks.parquet, episodes.parquet, stats.parquet,
  data/chunk-000/, videos/chunk-000/{cam}/), graceful behaviour when
  lerobot is missing, multi-camera recording, reading the dataset back,
  push_to_hub.
- training/overview.md: explicit 'no trainer in the box' policy with a
  table of where to train each model family, the round-trip example,
  reasoning for the split.
- examples/overview.md: pointer to the repo's examples/ directory with a
  table of scripts → tutorial-chapter alignment.
Comprehensive public-symbol reference grouped by module:

- strands_robots top-level (Robot factory, registry, policy ABCs)
- strands_robots.registry (list_robots, resolve_name, has_sim, etc.)
- strands_robots.simulation (Simulation, SimWorld/Robot/Object/Camera,
  create_simulation, register_backend, SimEngine ABC)
- strands_robots.hardware_robot (Robot class, TaskStatus, RobotTaskState)
- strands_robots.policies (Policy ABC, MockPolicy, create_policy,
  register_policy, list_providers, UntrustedRemoteCodeError, plus the
  shipping providers)
- strands_robots.tools (all @tool helpers)
- strands_robots.dataset_recorder (DatasetRecorder, has_lerobot_dataset)
- strands_robots.mesh (init_mesh, Mesh, InputPublisher, InputReceiver)
- strands_robots.benchmarks.libero
- Full environment variable reference table
- contributing.md: full PR workflow (setup with hatch + uv, common
  commands, module conventions including the lazy-imports rule, JSON
  registries as source of truth, tool-error contract). Code of conduct,
  where to ask, release process.
- troubleshooting.md: comprehensive error→fix tables across 7 categories
  (install, simulation, hardware, policies, recording, mesh, agent
  integration), bug-report checklist, escalation paths to upstream
  docs and discussion forums.
- index.md: 'Recently shipped' admonition pinning the latest landed PRs
  (Robot factory, MuJoCo backend, mesh, LIBERO, GR00T N1.7) so first-
  time visitors see what's current.
- All 68 robots from registry/robots.json appear on their category page
  (verified by the JSON-driven generation in cycles 9-10).
- mkdocs build --strict --site-dir /tmp/site_test exits 0 with zero
  warnings against the full 39-page site map.

Total: 39 pages, 5245+ lines of documentation, all grounded in the
current main code.
All 20 cycles ticked. The docs site is live as PR
strands-labs#160.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

Status: In review

Development

Successfully merging this pull request may close these issues.

2 participants