◑docsParity

vs https://docs.cyberwave.com/overview

The docs consistently teach a `cw.twins(...)`/`cw.twin(...)` API with helpers like `cw.affect(...)`, `cw.environments`, `cw.models`, `cw.datasets`, and a rich per-twin method surface, but the actual `Cyberwave` class only exposes `mqtt()` and a single `twin(asset_key, ...)` overload set returning specific `GripperTwin` classes. Several documented methods and namespaces do not exist on the extracted surface.

4 high4 medium0 low
Open issue with all findings ↗
12
Files analyzed
8
API symbols
8
Doc pages
43.8s
Analyzed in
50%
API coverage: Partially documented
4 of 8 exported symbols mentioned in docs
12 source files inspected · deepseek-chat · Sep 24, 2026

8 mismatches found

01

Docs reference a non-existent `cw.twins(...)` plural method

cyberwave/client.pyi

high
In the code
def twin( self, asset_key: Literal["the-robot-studio/so101"], environment_id: str | None = None, twin_id: str | None = None, **kwargs, ) -> GripperTwin
In the docs
drone = cw.twins("dji/dji-mini-4-pro")
drone.takeoff()

robot_dog = cw.twins("unitree/go2")
robot_dog.move_forward()

The Quickstart docs use `cw.twins(...)` (plural) in every example, but the client only exposes a singular `twin(...)` method. A developer copying these snippets will hit `AttributeError: 'Cyberwave' object has no attribute 'twins'`.

Suggested fix
Replace all `cw.twins(...)` usages in the docs with `cw.twin(...)`, matching the actual client API.
02

`cw.affect(...)` documented as a top-level client method is not in the API surface

cyberwave/client.pyi

high
In the code
class Cyberwave:
  def __init__( self, base_url: str | None = None, api_key: str | None = None, token: str | None = None, mqtt_host: str | None = None, mqtt_port: int | None = None, mqtt_username: str | None = None, mqtt_use_tls: bool = False, mqtt_tls_ca_cert: str | None = None, **config_kwargs, ) -> None
  def mqtt(self) -> CyberwaveMQTTClient
  def twin( ... ) -> GripperTwin
In the docs
cw.affect("simulation")   # commands now run against the virtual twin
cw.affect("live")         # flip back to the physical robot

The docs teach `cw.affect("simulation")` / `cw.affect("live")` as direct calls on the `Cyberwave` client, but no `affect` method exists in the exposed surface. Developers following the docs will get an AttributeError.

Suggested fix
Either expose `affect` on the client or update the docs to use the actual mechanism for switching simulation/live (and document its real mode strings — note the docs also inconsistently use "real-world").
03

`cw.environments`, `cw.models`, and `cw.datasets` namespaces are undocumented/not present

cyberwave/client.pyi

high
In the code
class Cyberwave:
  def mqtt(self) -> CyberwaveMQTTClient
  def twin( self, asset_key: Literal[...], ... ) -> GripperTwin
In the docs
env = cw.environments.create(name="Lab Cell", description="UR7e + table + camera")
...
model = cw.models.load("yolov8n")        # straight from the catalog
...
with cw.affect("live"):
    frame = camera.capture_frame("numpy")

Docs show `cw.environments.create(...)`, `cw.models.load(...)`, and `cw.datasets.add(...)` as attributes of the `Cyberwave` client, but the exposed client exposes only `mqtt()` and `twin()`. These namespaces are absent from the extracted surface, so all examples using them will fail.

Suggested fix
Either expose `environments`, `models`, and `datasets` on the client (or via `__getattr__`) and document their real import paths/method signatures, or rewrite the docs to match the actual client surface.
04

Docs claim assets outside the enumerated `Literal` slugs are supported by `twin(...)`

cyberwave/client.pyi

high
In the code
def twin( self, asset_key: Literal["the-robot-studio/so101"], ... ) -> GripperTwin
def twin( self, asset_key: Literal["agile-x-robotics/piper"], ... ) -> GripperTwin
def twin( self, asset_key: Literal["arx-roboticsx/r5a"], ... ) -> GripperTwin
def twin( self, asset_key: Literal["kinova/jaco"], ... ) -> GripperTwin
def twin( self, asset_key: Literal["interbotix/vx300s"], ... ) -> GripperTwin
def twin( self, asset_key: Literal["poppy-project/poppy-torso"], ... ) -> GripperTwin
In the docs
drone = cw.twin("SZ-DJI-Technology/DJI-Mini-4-Pro")  # swap for any other drone
...
robot = cw.twin("unitree/go2")
...
camera = cw.twin("logitech/c275")
...
dog = cw.twin("unitree/go2")

Docs repeatedly pass slugs like `unitree/go2`, `dji/dji-mini-4-pro`, `logitech/c275`, and `universal_robots/UR7` to `twin(...)`, but the only overloads in the surface are the enumerated `Literal` robot-arm slugs (so101, piper, r5a, jaco, vx300s, poppy-torso). If these literals are exhaustive, the documented slugs will fail type checking and may fail at runtime.

Suggested fix
Either widen the `asset_key` parameter (e.g. to `str`) and document how arbitrary slugs resolve to twin classes, or update the docs to only use the supported asset keys and document the actual supported catalog.
05

`cw.data` DataBus API not covered by the docs

cyberwave/data/api.py

medium
In the code
class DataBus:
  def __init__( self, backend: DataBackend, twin_uuid: str, *, sensor_name: str | None = None, key_prefix: str = "cw", ) -> None
  def publish( self, channel: str, sample: Any, *, metadata: dict[str, Any] | None = None, twin_uuid: str | None = None, ) -> None
  def subscribe( self, channel: str, callback: Callable[..., None], *, policy: str = "latest", raw: bool = False, twin_uuid: str | None = None, ) -> Subscription
  def latest( self, channel: str, *, timeout_s: float = 1.0, max_age_ms: float | None = None, raw: bool = False, twin_uuid: str | None = None, ) -> Any
In the docs
(not documented)

The code exports a substantial `DataBus` (`cw.data`) with `publish`, `publish_raw`, `subscribe`, `latest`, `stats`, `stats_and_reset`, `close`, and context-manager support, but no page in the provided docs mentions it. This is a public API with no doc coverage, so developers won't know how to use it.

Suggested fix
Add a `DataBus` reference page documenting the constructor options (`sensor_name`, `key_prefix`), the `policy` values for `subscribe`, and the async/blocking semantics of `latest`.
06

Docs use `cw.affect("real-world")` — a third mode string not present in code

cyberwave/client.pyi

medium
In the code
class Cyberwave:
  def mqtt(self) -> CyberwaveMQTTClient
  def twin( ... ) -> GripperTwin
In the docs
cw.affect("real-world")  # or "simulation" for a dry run

The Drones page passes `"real-world"` to `affect(...)` while the Cameras page passes `"live"`(inside a `with cw.affect("live"):` block). The docs are internally inconsistent about the mode strings, and neither is backed by an exposed method in the code surface — following either example gives an AttributeError and/or an invalid mode.

Suggested fix
Standardise the documented mode string (pick one of `"live"` or `"real-world"`) and align the docs with the actual `affect`/mode API in the SDK.
07

`twin_id` vs positional `asset_key` usage in docs may not match the real signature

cyberwave/client.pyi

medium
In the code
def twin( self, asset_key: Literal["the-robot-studio/so101"], environment_id: str | None = None, twin_id: str | None = None, **kwargs, ) -> GripperTwin
In the docs
arm = cw.twin(twin_id="acme/twins/arm-station-1")

The docs show `cw.twin(twin_id="...")` as a way to fetch an existing twin by slug, but in the real signature `asset_key` is the first required positional argument with a `Literal` type. If `asset_key` is required, calling `twin(twin_id=...)` alone will raise a `TypeError`.

Suggested fix
Document the exact signature — if `asset_key` is required, show it in the example (`cw.twin(<asset_key>, twin_id="acme/twins/arm-station-1")`) or make `asset_key` optional in the code when `twin_id` is provided.
08

Per-twin methods shown in docs (`joints.set`, `move_forward`, `capture_frame`, `takeoff`) not evidenced in surface

cyberwave/client.pyi

medium
In the code
def twin( self, asset_key: Literal["the-robot-studio/so101"], ... ) -> GripperTwin
// GripperTwin: no methods/properties shown in the extracted surface
In the docs
arm.joints.set("shoulder_pan", 45, degrees=True)
dog.move_forward(distance=1.0)
frame = camera.capture_frame("numpy")      # latest RGB frame
drone.takeoff()
drone.gimbal_rotate(pitch=-45.0, duration=1.5)

The docs depend heavily on typed twin methods (`joints.set(...)`, `move_forward(...)`, `capture_frame(...)`, `takeoff()`, `gimbal_rotate(...)`, `pan_camera(...)`, `use_controller(...)`). None of these appear in the extracted `GripperTwin` surface, and `camera.twin(...)` is not represented by any documented `CameraTwin` overload. Developers following these snippets may use methods that no longer exist or have moved.

Suggested fix
Regenerate the SDK reference from the current `twin.py` and re-verify each named method/attribute (`joints`, `move_forward`, `capture_frame`, `takeoff`, `gimbal_rotate`, `pan_camera`, `use_controller`); fix or remove any that have been renamed or removed.