🎭 Theater & Live Performance · director visual staging

Tableau Composition Caller

Lovable AI describes striking visual tableaux so directors plan climaxes; the Adamo bridge relays each cue to a humanoid on stage.

Author· mobile authoring
Section · Kernel

The move.

full primer →

Directors open a browser 'humanoid controller' tuned for director visual staging: every slider, pad, or gesture publishes a control topic through the local Adamo bridge, and the robot on the Theater & Live Performance stage responds in the same beat.

Why this kernelA browser humanoid controller fits director visual staging because Theater & Live Performance is a live art — the operator wants a control surface they can perform with, not a config screen. Every gesture in the UI publishes a control topic the robot obeys in the same beat.

Kernel
a phone-first authoring surface — touch sliders, tap pads, cue lists, timeline scrubbers — that composes a robot program as JSON. The Lovable sandbox validates the key with `scripts/adamo_smoke.py` at build time; the artifact is played back on the physical robot later by an operator
Drives the UI as
a single-column mobile UI with 44px+ tap targets and a thumb-reachable primary action — one tap edits a cue, one tap saves the take
Appendix · Setup

Run the bridge first.

ADAMO_API_KEY
On your laptop only — export it before starting the bridge. Never add it to Lovable secrets; the browser never sees it. Get one from operate.adamohq.com.
open ↗
adamo-bridge.py
The tiny Python bridge the browser calls at http://localhost:7878. Download once, run before you paste the mega-prompt into Lovable.
download ↓

Start the bridge on your laptop before pasting the prompt below. The Lovable app never holds the Adamo key.

Appendix · Mega-prompt

The build prompt.

Paste into a fresh Lovable project. Make sure the bridge above is running first. read the bridge protocol →

Build "Tableau Composition Caller" as a ONE-SHOT Lovable build **from a phone**. The participant
has only 5 credits and only a mobile browser — this single message must ship a
working demo with zero follow-ups and zero laptop steps. Physical AI on Adamo.

CONCEPT
Lovable AI describes striking visual tableaux so directors plan climaxes; the Adamo bridge relays each cue to a humanoid on stage.
Discipline: theater (director visual staging).
Kernel: Author (mobile authoring).
Why this kernel: A browser humanoid controller fits director visual staging because Theater & Live Performance is a live art — the operator wants a control surface they can perform with, not a config screen. Every gesture in the UI publishes a control topic the robot obeys in the same beat.

MOBILE-ONLY, SANDBOX-BACKED — READ THIS FIRST
Adamo's SDK is Python-only. Cloudflare Workers cannot import it. The
participant is on a phone; there is no laptop bridge. The ONLY place inside
this Lovable session where the SDK runs is the Linux build sandbox. So:
  - Every Adamo call happens in a Python script the agent runs ONCE at
    build time in the sandbox.
  - The script writes a JSON proof artifact into `public/` that the
    deployed mobile web app fetches at runtime.
  - The deployed app itself never imports adamo, never holds
    ADAMO_API_KEY, never opens a QUIC/Zenoh socket, never calls a
    server function that tries to.
  - The runtime robot performance happens later at the physical showcase,
    off-device. The mobile app AUTHORS, the sandbox VERIFIES, the operator
    PLAYS BACK.

SECRETS
Request `ADAMO_API_KEY` via the add-secret tool (format hint `ak_...`).
Never reference it in .ts/.tsx code, never in `import.meta.env`, never in
a `createServerFn` handler. It lives only in the sandbox process env.

BUDGET (5 CREDITS, ONE-SHOT)
- ONE TanStack Start app, one primary route (`src/routes/index.tsx`).
- ONE mobile-first surface (touch targets >=44px, thumb-reachable primary
  action, no hover-only affordances, no drag-only interactions).
- Lovable AI Gateway allowed for text (default `google/gemini-3-flash-preview`),
  called from a server fn.
- NO database, NO auth, NO Lovable Cloud, NO extra pages, NO tests.
- Libraries: template defaults + `ai` + `@ai-sdk/openai-compatible` + `zod`.

VERIFIED ADAMO SDK SURFACE (adamo >= 0.4.42)
  import adamo
  session = adamo.connect(api_key=os.environ["ADAMO_API_KEY"])
  session.put(key, payload_bytes)
  sub = session.subscribe(key, callback=fn)      # kwarg-only, NOT positional
  session.get(key, timeout_ms=5000)              # returns list[Sample]
  session.live_tokens("**/alive")                # discovery (returns live tokens)
  session.alive(token_key)                       # DECLARES a token; not discovery
  session.close()
Footguns: subscribe callback is kwarg-only; `alive()` declares, `live_tokens`
discovers; `connect` requires `api_key=` (keyword).

STEP 1 — SMOKE TEST (mandatory, every build)
Write this to `scripts/adamo_smoke.py` verbatim:

```python
"""Verify ADAMO_API_KEY from the Lovable sandbox and write proof to
public/adamo-smoke.json. Run once during the build."""
from __future__ import annotations
import json, os, sys, time, threading
from datetime import datetime, timezone
from pathlib import Path

OUT = Path(__file__).resolve().parent.parent / "public" / "adamo-smoke.json"
OUT.parent.mkdir(parents=True, exist_ok=True)

def write(p): OUT.write_text(json.dumps(p, indent=2) + "\n"); print(json.dumps(p))

def main() -> int:
    key = os.environ.get("ADAMO_API_KEY")
    if not key:
        write({"ok": False, "error": "ADAMO_API_KEY missing"}); return 2
    try:
        import adamo
    except Exception as e:
        write({"ok": False, "error": f"adamo import failed: {e!r}"}); return 2

    out = {"ok": False, "at": datetime.now(timezone.utc).isoformat(),
           "sdk_version": getattr(adamo, "__version__", "unknown"),
           "roundtrip_ms": None, "alive": [], "error": None}
    s = None
    try:
        t0 = time.time()
        s = adamo.connect(api_key=key)
        out["connect_ms"] = int((time.time() - t0) * 1000)

        k = f"lovable/smoke/{int(time.time()*1000)}"
        got = threading.Event(); seen = {}
        def on(sample):
            try: seen["v"] = json.loads(bytes(sample.payload).decode())
            except Exception: seen["v"] = None
            got.set()
        sub = s.subscribe(k, callback=on)
        time.sleep(0.2)
        sent = time.time()
        s.put(k, json.dumps({"ping": sent}).encode())
        if got.wait(3.0):
            out["roundtrip_ms"] = int((time.time() - sent) * 1000)
            out["ok"] = True; out["echo"] = seen.get("v")
        else:
            out["error"] = "roundtrip timeout"
        try: sub.undeclare()
        except Exception: pass
        try: out["alive"] = sorted({str(t) for t in (s.live_tokens("**/alive") or [])})
        except Exception as e: out["alive_error"] = repr(e)
    except Exception as e:
        out["error"] = f"{type(e).__name__}: {e}"
    finally:
        try:
            if s is not None: s.close()
        except Exception: pass
    write(out)
    return 0 if out["ok"] else 1

if __name__ == "__main__":
    sys.exit(main())
```

Then in the sandbox run:
    python -m pip install --no-cache-dir adamo
    python scripts/adamo_smoke.py

Commit the resulting `public/adamo-smoke.json`.

STEP 2 — KERNEL JOB (Author)
SANDBOX JOB — smoke test only
The Author kernel does not need a second sandbox job. Ship the mobile
authoring UI. The `<AdamoProof />` card reading `/adamo-smoke.json` is the
only Adamo surface required.

STEP 3 — MOBILE APP
- `src/routes/index.tsx` renders the Author surface for "Tableau Composition Caller".
- Include an `<AdamoProof />` card that `fetch("/adamo-smoke.json")` on
  mount and shows: "Sandbox verified at HH:MM · Xms roundtrip · N tokens
  live". Empty state: "No proof yet — re-run scripts/adamo_smoke.py".
- Mobile-first layout: single column, 16-24px padding, primary CTA fixed
  or bottom-anchored within thumb reach. NO desktop-only grids as the
  main surface.
- Empty state copy when no robot is connected: "Your key is verified in
  the sandbox. The operator will replay this on the robot at the
  showcase." — never "start the bridge" or "install Python".
- Tailwind + shadcn. Editorial industrial look: gold accent, dark
  background, one strong headline, one primary action.
- Footer: "Built during the Physical AI & Creative Robotics Hackathon
  organised by StreetKode Fam during Indian Krump Festival 14".

BRAIN — Lovable AI Gateway (already provisioned, no key prompt)
```ts
// src/lib/ai-gateway.server.ts
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
export function gateway() {
  return createOpenAICompatible({
    name: "lovable",
    baseURL: "https://ai.gateway.lovable.dev/v1",
    headers: {
      "Lovable-API-Key": process.env.LOVABLE_API_KEY!,
      "X-Lovable-AIG-SDK": "vercel-ai-sdk",
    },
  });
}
```
Call `generateText` inside `createServerFn` handlers only.

DO / DON'T
| Do                                              | Don't                                          |
| ----------------------------------------------- | ---------------------------------------------- |
| Run adamo only in scripts/ (sandbox)            | `import adamo` from a server fn or route       |
| Read `/adamo-smoke.json` from the browser       | Read ADAMO_API_KEY from `import.meta.env`      |
| `session.subscribe(k, callback=fn)`             | `session.subscribe(k, fn)` (positional fails)  |
| `session.live_tokens("**/alive")` for discovery | `session.alive()` for discovery                |
| Design for a phone in portrait first            | Ship a desktop dashboard as the primary UI     |

SUCCESS
On first load on a phone, the participant sees the Author surface for
"Tableau Composition Caller", the AdamoProof card shows a green "sandbox verified" line with
a real roundtrip number, and the primary action is reachable with the
thumb. That is the demo.
Appendix · Market

Market sizing.

TAM
$30B
global live performance market
SAM
$3B
theatrical directing and movement choreography
SOM
$75M
experimental and physical theater companies

Indicative figures for hackathon pitches — refine with your own research before raising.

See also

Adjacent entries.