This release is a pre-release and may not be stable for production use.
Dropbear
Cloud robot policy inference — one function call.
0.1.0a7is the current pre-alpha release line.
Install
Add Dropbear to a Python 3.11–3.14 project:
uv add "dropbear==0.1.0a7"
Install the CLI as a standalone tool:
uv tool install "dropbear==0.1.0a7"
dropbear login
The base package contains cloud inference, transport, model contracts, and robot-neutral observation helpers. Install a hardware or simulator stack only when you need it:
uv add "dropbear[so101]==0.1.0a7"
uv add "dropbear[sim]==0.1.0a7"
uv add "dropbear[dreamzero]==0.1.0a7"
The dreamzero extra installs the pinned H.264 codec used automatically by
DreamZero-YAM's three persistent camera streams. DreamZero-DROID and all other
models keep their existing JPEG transport and do not require this extra.
The base SDK supports Python 3.11 through 3.14. The so101 extra currently
supports Python 3.12 and 3.13 because its pinned LeRobot dependency requires
Python 3.12 and does not yet provide a wheel-compatible Python 3.14 dependency
stack.
The sim extra is currently Linux/WSL2 only because of upstream
LIBERO/robosuite limitations.
Cloud policy inference
import dropbear
with dropbear.connect(model="molmoact2-so101") as policy:
result = policy.predict(
observation,
instruction="pick up the cube",
)
print(len(result.actions), len(result.actions[0]))
predict() returns one action chunk and does not actuate a robot. Build
observation with the model-specific helper and validate every action locally
before adding a motion path.
dropbear.connect() is the canonical SDK entrypoint.
connect_so101() is a deprecated compatibility path for the legacy physical
SO-101 safety loop and will be removed after that behavior is folded into the
generic policy surface. New cloud-policy work should use dropbear.connect().
There is no first-class public connect_libero() or connect_franka()
entrypoint; use dropbear.connect(model="molmoact2-libero") or select another
checkpoint with model=.
Startup waits default to 900 seconds. For an intentionally longer cold start,
pass a finite positive budget such as startup_timeout=1800 to
dropbear.connect() or await dropbear.aconnect().
Use a context manager so every cloud session closes deterministically:
import dropbear
with dropbear.connect(model="molmoact2-libero") as policy:
result = policy.run(
instruction="put the mug on the plate",
observe=observe,
act=act,
max_actions=220,
strategy=dropbear.RunStrategy.libero_default(),
)
DreamZero sampling
DreamZero uses one existing RunStrategy field; the server owns temporal
admission and the SDK continues uploading observations while asynchronous
inference is outstanding.
| Mode | Behavior | YAM | DROID |
|---|---|---|---|
upstream_eval |
Synchronous reference/open-loop cadence | Explicit | Explicit |
async_8 |
Single-flight async admission after a newer eight-tick epoch | Compatibility and rollback | Default |
async_latest |
Single-flight, latest-only admission on the newest strictly newer tick | Accepted default | Rejected |
An omitted value means “use the qualified default for this model”; it does not
disable sampling. YAM resolves omission to async_latest; DROID remains
async_8. Explicit compatibility and reference selections remain available:
# YAM accepted default
strategy = dropbear.RunStrategy()
# Explicit compatibility mode
strategy = dropbear.RunStrategy(dreamzero_sampling="async_8")
# Synchronous reference/evaluation
strategy = dropbear.RunStrategy(dreamzero_sampling="upstream_eval")
async_latest does not create a client request queue. The SDK retains one
latest unsent observation, while the YAM server admits at most one inference
and collapses observations received while busy to the newest eligible control
tick. Returned PolicyStepResult values expose source_control_tick and
source_capture_to_execution_ms; hold actions without a source chunk report
None for both.
The server returns absolute 24x14 YAM targets. For async_latest, the SDK
keeps the existing two committed steps and motion-smooths only the remaining
temporally aligned suffix: it blends adjacent absolute-target motion using 85%
new and 15% old motion, then corrects toward the new absolute target over five
steps. It never shifts or rebases a chunk. YAM grippers remain continuous
absolute targets and are handled with the other 12 joints. async_8,
upstream_eval, and DROID retain direct commit-prefix replacement.
DreamZero keeps its smoothing choice internal to this qualified mode; explicit
DreamZero smoothing weights or modes remain unsupported. A managed run()
callback may return ActResult(accepted_action=...) so the next merge anchors
to the target accepted by the actuator. Externally clocked step() callers
without actuator feedback anchor to the requested target.
Action smoothing
policy.run() smooths overlapping chunks automatically from the model's action
space without changing the selected control mode or its inference cadence:
strategy = dropbear.RunStrategy() # action_smoothing="auto"
auto resolves to output for delta-action models such as LIBERO and to
motion for absolute-joint models such as SO101. The raw-absolute YAM contract
is also an absolute target space, although DreamZero owns the narrower mode
selection described above. output averages old and new
action values at each overlapping logical timestep, using 70% new by default.
motion blends consecutive target increments, using 85% new motion by default,
then corrects gradually toward the new absolute targets. Absolute-position
models still receive absolute-position targets; motion changes only how
overlapping client trajectories are combined.
For controlled comparisons, set action_smoothing="output" or
action_smoothing="motion". motion requires an
absolute_joint_position or raw_absolute_joint contract. Its default correction horizon is
max(3, ceil(chunk_size / 5)) action steps, so a 30-action SO101 chunk resolves
to six steps. Optional expert overrides are smoothing_new_weight and
smoothing_correction_steps; the latter applies only to motion. These values
resolve once from the static runtime contract and do not adapt to latency.
Returned actions remain aligned to their original logical timesteps. Expired prefix steps are skipped, and a chunk that is entirely stale is discarded; it is never shifted forward and replayed. With eager inference, a predicted action can therefore be superseded or expire without ever being dispatched. This is intentional: inference stays reactive while the action loop executes only the currently resolved timestep.
For physical arms that clamp a requested target, return the accepted target so the next smoothing pass starts from what the robot was actually asked to execute:
def act(action, context):
accepted = robot.send_and_return_accepted_target(action)
return dropbear.ActResult(accepted_action=accepted)
accepted_action must be finite and have the same dimension as the requested
action. Existing callbacks returning None, bool, or ActResult(done=...)
remain supported.
policy.run() returns one RunResult and prints the same run-scoped summary
immediately. Its counters and stop condition are deliberately narrow:
result.donemeans theact()callback requested a stop; it does not assert task success or completion.result.actionscounts control callback steps, not confirmed physical robot execution.result.policy_callscounts completed policy responses accepted by that run.result.timing.policy_response_msmeasures SDK observation submission through action-chunk receipt. It excludes observation construction and physical actuation.result.timing.data_plane_rtt_msis an authenticated application-path round trip measured with a clock probe. It includes transport framing and any accelerator or relay hops; it is not a one-way network-latency estimate.- Worker queue, preprocessing, inference, and postprocessing summaries are derived from per-response worker timestamps. Missing samples remain missing rather than being inferred from client-side residual time.
region="nearest" is the default and pins the lowest measured HTTPS-latency
region, even when another region is already warm. region="available" reuses
compatible warm compute in any measured candidate region before starting cold
compute. Passing an AWS region is an exact constraint with no regional fallback.
The latency check uses five serial samples per region and reports when partial
or failed evidence required a deterministic fallback.
transport="auto" tries QUIC first and can use the hosted relay;
transport="quic" requires QUIC, and transport="relay" uses the relay
directly.
MolmoAct2-DROID on Franka
MolmoAct2-DROID consumes an exterior RGB view and wrist RGB view. A second exterior view is optional; when omitted, Dropbear reuses the first exterior frame for the checkpoint's second exterior slot.
Robot state is seven Franka joint positions in radians followed by a gripper
value in [0, 1].
import numpy as np
import dropbear
exterior_rgb = np.zeros((480, 640, 3), dtype=np.uint8)
wrist_rgb = np.zeros((480, 640, 3), dtype=np.uint8)
observation = dropbear.franka.observe(
exterior_frame=exterior_rgb,
wrist_frame=wrist_rgb,
joint_positions=[0.0] * 7,
gripper=0.5, # 0=open, 1=closed
)
with dropbear.connect(model="molmoact2-droid") as policy:
result = policy.predict(
observation,
instruction="pick up the green block",
)
assert len(result.actions) == 15
assert all(len(action) == 8 for action in result.actions)
The checkpoint returns a 15-step chunk at 15 Hz. Each action is an absolute
target [joint_0, ..., joint_6, gripper]; joints are radians and the gripper is
in [0, 1].
predict() does not actuate hardware or provide a Franka safety controller.
Validate joint, velocity, acceleration, workspace, collision, and gripper
limits before sending any target to a robot.
Manual action loop
For a caller-owned control loop, pass the task instruction to
policy.next_action(...). Dropbear owns inference, refill, action buffering,
calibration, and RTC prefix context; the caller owns sensing, actuation, and
loop cadence.
import time
dt = 1.0 / policy.action_hz
while running:
tick = time.perf_counter()
action = policy.next_action(
observe(),
instruction="put the mug on the plate",
)
robot.execute(action)
time.sleep(max(0.0, dt - (time.perf_counter() - tick)))
CLI
Sign in once. Credentials are stored in ~/.dropbear/config.toml.
dropbear login
dropbear status
For headless setup, use bare --api-key to paste a key into a hidden prompt:
dropbear login --api-key
Run robot-neutral setup checks:
dropbear doctor
SO-101 and simulation checks are explicit:
dropbear doctor so101
dropbear doctor sim
Install shell completion with:
dropbear --install-completion
Useful session commands:
dropbear sessions list
dropbear sessions stop <session-id>
dropbear sessions stop --all
Documentation: https://docs.dropbear.dreamscalelabs.com
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dropbear-0.1.0a7.tar.gz.
File metadata
- Download URL: dropbear-0.1.0a7.tar.gz
- Upload date:
- Size: 153.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
19938bf594e6a03d72e0fb56a8013ccc90460179e7452d76d11098c35eced899
|
|
| MD5 |
2cbbcae07eb1e93f8621365025b057fb
|
|
| BLAKE2b-256 |
50af4475c3a588115882f7e910b3121fb921f4f78cd0f9a6d74046e43a84b41f
|
File details
Details for the file dropbear-0.1.0a7-py3-none-any.whl.
File metadata
- Download URL: dropbear-0.1.0a7-py3-none-any.whl
- Upload date:
- Size: 177.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c5c12639676d501c3731ad7f11ae73246e525db20d65897ca713d22819a9cbd9
|
|
| MD5 |
755c6a0380e6350fd1aea2a15118f0f5
|
|
| BLAKE2b-256 |
8cf8c8727287bf6b5e25e09a889f609415949e171981567239bb33ba1ff1fe3d
|