Skip to main content

fomo

An SO-101 leader arm that films.
six servos · a camera on a printed pan/tilt head · five tools: calibrate photo move pose motion

Site — the twin plays the nine motions · Install · Five verbs · Motions · The guard · Cockpit

ci python ≥ 3.11 MIT

Hi. I'm Fomo.

I'm the leader arm from an SO-101 kit — the one that goes back in the box after teleop. Someone took my handle off, printed a pan/tilt yoke for an Arduino Nicla Vision, and screwed it to my wrist. Now I'm a cameraman: six Feetech STS3215 servos on one bus, a camera that knows its own pose, and an agent that drives me with exactly five verbs.

from strands import Agent
from fomo.tools import calibrate, photo, move, pose, motion

fomo = Agent(tools=[calibrate, photo, move, pose, motion])
fomo("look 40 degrees left, take a photo, then show me you're happy")

Install me — five steps

pip install "fomo-the-arm[dashboard]"     # tools · CLI · MCP · agent · dash API   (+[mcp], +[rl])

pip gives you the five tools, fomo and fomo mcp, the agent and the dash API. The cockpit's SPA and the twin's models live in the repo, so for the full panel clone it:

git clone https://github.com/cagataycali/fomo-the-arm.git && cd fomo-the-arm
pip install -e ".[dashboard]"
fomo doctor                 # read-only: which port is me, six servos, calibration, camera
fomo calibrate --manual --hold 40 --i-know   # torque off, move me by hand, fold me before the timer ends
fomo dash                   # http://127.0.0.1:8091 — the cockpit: agent log, dock, twin, eyes

No arm? FOMO_SIM=1 fomo dash is six simulated servos ramping at my real speed — the site's twin is one. The long form, with what each step refuses and why, is Install.

Set FOMO_PORT when doctor finds more than one usbmodem (on the bench this was written on it found five: the servo adapter, a Nicla, a Sticky, a Flipper — two share the CH343 chip, so I refuse to guess). Nothing moves until you say --i-know (you are watching me) or write {"ok": true} to ~/.fomo/bench.json.

My five verbs

tool what it does honest limits
calibrate(mode) report reads ~/.fomo/calib.json; manual drops torque, samples every joint while you move me by hand (≥ 20 s), makes the fold my home and the extremes my window; write_eeprom burns MIN/MAX into servos 1–4; --import adopts a strands-arm calibration I don't search for my own stops — on this arm the automatic search found the fold contact 30–45° short of the metal, the hand found 185–207° spans
photo(source) one JPEG from the Nicla (LAN /stream, or USB raw-REPL), else the dashboard, else this machine's webcam; saved to ~/.fomo/photos/, the source named 320×240 from the Nicla; if every source fails I say so and name each
move(actions) several servos, several actions, one guarded ramped command: to, by, rel (from home), look {pan,tilt}, home, stop, torque, read (present degrees + what the head feels: ToF, roll/pitch, bench or head) any angle inside the measured window is one call; a stall holds, never forces
pose(action, name) list show save delete goto nudge; five built-ins (home attention look_around_left look_around_right up); stored relative to home so a re-calibration shifts poses instead of breaking them a pose is a place, not a path
motion(action, name) list show run save delete; nine built-ins timed on the metal — approve (nod) deny (shake) happy frustrated curious wave look_around up sleep; keyframes from wherever I am, ending folded unless stay every frame is checked against the hard limits before the first write

Every tool returns the same {"status", "content": [{"text"}]} shape, dash-first (when the dashboard owns the port) with a local-bus fallback. fomo mcp serves the same five over MCP. Verbs · Motions — the twin plays all nine.

The guard — hard limits only

Every servo write passes fomo.guard.Guard. It refuses on six things, each named after a night something went wrong on the real leader (2026-09-05 → 08), and executes everything inside them:

refuses on why
1 Gate. Nothing moves without i_know or ~/.fomo/bench.json {"ok": true} a tool call from a phone moved the head while the owner's hand was on it
3 Head window. Pan ±160°, tilt ±80° about home the horns spin freely; the Nicla's USB cable does not
4 Measured window. Joints 1–4 stay inside what your hand found, not the EEPROM's the base's factory window 111..251 wasted 45° on one side; the hand found 66.4
7 Upright. torque off is refused until I'm folded the elbow fell onto its stop at 04:05Z, 2026-09-07
8 Power. No lifting away from the fold while the rail reads under 5 V; folding is always allowed the 5.5 V leader supply could not lift the forearm
9 Stall. 6° behind a streamed goal and not moving → every joint is re-goaled to where it is; a hold, not a refusal the wrist was driven into the forearm for 2 s, the rail sagging to 5.0 V

How far a command reaches is never a refusal: inside the limits a target is cut into ≤ 10° legs, goals streamed from the host at 30 °/s (ceiling 90) so stop lands mid-leg, torque drops 2 s after the last command — only when folded. The guard: every number on that page is read from fomo/guard.py and ~/.fomo/calib.json at build time, never typed.

Cockpit — fomo.cagatay.my

One screen; the agent is the spine. The log is the narrative — your prompts, my streamed answers, every tool call as a row in words (read · joints 0.1 s, motion · happy), a photo inline — and the eyes (live MJPEG) and the twin (following the servos at 5 Hz) are my face. STOP is always in the bar. Captured 2026-09-09 on the live arm:

the cockpit: live eyes and twin on the left, the log with a read · joints tool row and the answer on the right

Press d for the dock — one slider per joint on its measured window, look pad, every pose, every motion, torque, a speed slider capped at the guard's 90 °/s. Nothing in it bypasses the guard, and manual moves land in the same log so the agent's next turn sees them.

the dock: sliders on the measured windows, poses, motions, STOP

Voice in and out are browser-native; a think toggle lets me look and say one line every so often (off by default, never moving joints 1–4). Control routes need FOMO_TOKEN (or, with FOMO_OWNER set, the owner's tiny.technology session); state, /ws, eyes and senses are read-only public. dashboard/deploy/install.sh makes it a launchd agent and carries your model credentials (AWS_BEARER_TOKEN_BEDROCK or AWS_PROFILE) into it; cloudflared-fomo.yml puts it on a name. Cockpit · Reference — every route.

Where I come from

I'm the fresh codebase of strands-arm — the idea kept, the 14k lines cut to what a cameraman needs. Everything I learnt there — the measured servo ranges, every incident behind the guard, the nights in archive/lanes/ — is written down where it was learnt: the guard page carries the incidents, the install page the hand-measured windows.

What I won't pretend to do

  • Drive a base. That's strands-arm's three-wheel body; I'm the arm on the bench.
  • Run an RL policy live — not yet. Two ONNX policies ship and run in shadow (fomo rl shadow); stage 1 (head only) is built and stays behind a phrase the owner writes by hand in the journal.
  • Lift on 5 V. The leader kit's supply reads 5.6 V on my bus; the elbow does not lift the forearm from the fold on it (rule 9 holds it). The 7.4 V supply does.
  • See obstacles. Rule 1 exists because a human must.
  • Take a photo I didn't take. If every camera source fails, photo says so and names each.

License

MIT, Cagatay Cali. Built by cagatay and his agents at strands robots.

Metadata

Release files for fomo-the-arm 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fomo-the-arm 0.1.0
File Size Uploaded Provenance
fomo_the_arm-0.1.0.tar.gz 750.5 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for fomo-the-arm 0.1.0
File Interpreter ABI Platform
fomo_the_arm-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 946.9 kB

Release files / fomo_the_arm-0.1.0.tar.gz

Download URL fomo_the_arm-0.1.0.tar.gz
Size 750.5 kB
Tags Source
SHA-256 checksum
How to use checksums
003eca142095b13aa95ca27b82cc31d52df347a7f8e1e13ee48ae23a12874e96
BLAKE2b-256 checksum
How to use checksums
2d8f78650c5a075d21277a1678804c01d95d3da25835c95687d965d7989c0855
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release files / fomo_the_arm-0.1.0-py3-none-any.whl

Download URL fomo_the_arm-0.1.0-py3-none-any.whl
Size 196.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
22784a53789ab854e7eb255775ab3f1e5d21c5f5f3fb64bbcbbdd44e5aff8db5
BLAKE2b-256 checksum
How to use checksums
c7753d132dd936f39d9bb21d0ca025474f8d4de836ce1deecac7b919159e9617
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Security for fomo-the-arm 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page