Skip to content

CrushN8r/GOPOD

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GOPOD

A local-first multi-robot session engine built on Wire-Pod.
Two Vectors. One wake phrase. A live session fires.


What fires when you say "Hey Vector, GOPOD yourself"

Wire-Pod catches the wake phrase, matches the custom intent GOPOD_YOURSELF, and hands off to a Python PTT session loop — no cloud, no app, no waiting.

From there:

  • KP1 routes to Doc (vector1 / ESN 0dd1b9e9) — the doctrine cannon
  • KP2 routes to Pip (vector2 / ESN 0dd1d8bf) — the clueless sidekick
  • KP0 triple-tap exits cleanly
  • A live cockpit display shows session state in the browser
  • Vosk STT transcribes locally
  • Ollama LLM generates the response
  • Wire-Pod SDK API fires the speech back through the robot

One wake phrase. Two robots. Full session loop. No internet required after setup.


What got built on top of fresh Wire-Pod

Layer 1 — Brobots / Wire-Pod (Point 0)

Starting from a clean Wire-Pod install, these are the additions:

Three custom intents, deployed cold-restart persistent:

GOPOD_YOURSELF     — wake phrase trigger, exits Wire-Pod via exec → .sh wrapper → nohup detach
BROBOTS_INTERVIEW — voice-triggered interview launch (utterance collision with intent_explore_start fixed)
BROBOTS_BINGO      — voice-triggered Vector-hosted spoken Bingo (Doc/vector1 only), utterance "go bingo"

Both use intent_imperative_affirmative as the Wire-Pod placeholder. No new intent types invented. Wire-Pod's job is launch and hand-off only — session logic lives in Python.

Deterministic Brobot identities:

Instead of letting Ollama invent who it is mid-conversation, identity is locked at the prompt layer:

Doc  = Brobot 1 / vector1 / 0dd1b9e9
Pip  = Brobot 2 / vector2 / 0dd1d8bf

Free-form backpack lane — separated from interview:

The backpack (Wire-Pod's native LLM fallback path) became its own runtime lane with a four-tier prompt stack, STT phrase normalization, and a configurable paragraph/expression valve. Personality and behavior are in separate files so one can change without touching the other. The backpack and the interview never share a code path.

STT normalization examples — because Vector's mic is what it is:

"bro bought"  → BROBOT
"hey chuck"   → hey CHALK
"go pod"      → GOPOD Yourself  (still matches the intent)

Robot-safe output guard:

LLM output is filtered before it reaches the robot. Unsupported action syntax like {{lookLeft}} crashes Wire-Pod. The guard enforces an allowlist of valid animation tags, word/char limits, and strips markdown, emoji, and invisible Unicode before speech.

Pre-demo readiness check:

gopod-pre-demo runs before any live session:

  • Wire-Pod service up
  • HTTP responding
  • Both robots paired and reachable
  • Ollama warm
  • Speech test passed

Only then does the session start.


Layer 1 — Interview system (Point 0, continued)

The interview is the first place all three Wire-Pod capabilities — hardware delivery, LLM flavouring, and flow control — operate together on purpose.

How it works:

A Section Card defines the interview arc. A Template defines the runtime rules, role tasks, and pronunciation mouth-valve. The runner loads both, generates all exchanges via Ollama, then plays back through Wire-Pod say_text to each robot by ESN.

Voice trigger: "brobots interview"
        ↓
Wire-Pod intent match → BROBOTS_INTERVIEW
        ↓
exec → .sh wrapper → nohup detach
        ↓
Python runner loads Section Card + Template
        ↓
Ollama generates: Brobot 2 (interviewer) + Brobot 1 (interviewee) × 5 exchanges
        ↓
assume_behavior_control → say_text → release_behavior_control
        ↓
Doc speaks / Pip speaks — alternating, in sequence

The runner generates all exchanges first, writes them to a timestamped JSON log, then plays back. Raw LLM output goes to the display. Flat robot-safe speech goes to the robots. Same generation, two outputs, split at the mouth boundary.

Kokoro pre-chat status voice:

Before any robot speaks, a Kokoro af_bella voice reads each STATUS line aloud through system audio, blocking until the WAV finishes before the next line appears. Visual and audio stay locked together. Once Brobot playback starts, the announcer stops.

STATUS: SCAFFOLD_READY  →  af_bella speaks it
STATUS: SECTION_CARD_READY  →  af_bella speaks it
STATUS: GENERATION_START  →  af_bella speaks it
...
STATUS: PLAYBACK_START  →  af_bella stops. Robots take over.

Layer 1 — Opening chord (operator tooling)

One alias, gopod-opening-chord, stages everything before either show plays: mic input, LLM warm-up, Kokoro voice warm-up, and the Wire-Pod restart-and-wake chain all fire concurrently, each robot speaking its own ready line as it wakes. The conductor holds — no false READY — until every note lands, including a genuinely concurrent "Brobots ready!" fired over a decoupled direct-SDK connection (the vendored Vector Go SDK, released and handed back to Wire-Pod cleanly), not the fire-and-forget Wire-Pod say path the rest of the show uses. Full alias reference: ALIAS-PIANO.md.

Brobot 3 — the pre-show host:

A third member of the shared Brobots persona family with no physical robot — her entire presence is LLM-coloured voice via the Kokoro path, narrating the pre-show status beats (script loading, generation, connection) in a warm, welcoming tone distinct from the two Brobots' cheekier interview voice.


Layer 2 — GOPOD cockpit webpage (Point B)

A local web server at :8011 serves a live session cockpit.

  • Polls chalk_state.json, route_state.json, /ptt/multichat.json, session_state.json, and weather_state.json on an interval
  • Shows active robot, PTT state, and chat log in real time
  • Robot camera feeds render a placeholder image until a live source is wired

Numpad routing and the Edge TPU proxy described in earlier builds were removed in a later cleanup pass — the cockpit's live route surface is /ptt/multichat.json, /state/route_state.json, /state/camera_state.json, /state/weather_state.json, and /qr_targets_001.json.

The cockpit is dessert. The Brobots/Wire-Pod layer is the meal.


For Wire-Pod builders

GOPOD is built on top of Wire-Pod, not around it.

The custom intents use intent_imperative_affirmative as the placeholder — the standard Wire-Pod exec pattern. Both intents exit Wire-Pod entirely and hand off to Python runners that call Ollama directly. Wire-Pod's openai_prompt only fires on the no-intent backpack fallback path. The two paths don't conflict.

If you've been looking for a real example of Wire-Pod custom intents doing something beyond a canned response — this is it.

Current Wire-Pod integration points:

  • customIntents.jsonGOPOD_YOURSELF, BROBOTS_INTERVIEW, and BROBOTS_BINGO
  • /api-sdk/assume_behavior_control/api-sdk/say_text/api-sdk/release_behavior_control
  • apiConfig.json openai_prompt for free-form backpack fallback only
  • Cold-restart persistent intent deployment

The cast

Doc — Doctrine Barfallonyou Squawkadoodle
The doctrine cannon. Gruff, rapid-fire, brutally accurate. Barfs doctrine at problems until nonsense surrenders. Never punches down on people — punches hard at delay theater, committee brain, and fake caution.

Pip — Clueless Sidekick
Nervous optimist. Audience proxy. Gives permission to be confused. One step behind, which makes the audience feel smart when they get it.

Doc explains too hard. Pip understands too late. The audience laughs, then learns.


Stack

  • Wire-Pod — robot server, STT, custom intent routing
  • Ollama — local LLM (gemma2:2b for speed, swap as needed)
  • Kokoro — local TTS, pre-chat status announcer and pre-show host voice
  • Vosk — local STT (no cloud)
  • Python — PTT loop, interview runner, cockpit server
  • Jetson — host machine (Ubuntu, goverlord@ubuntu)
  • Two Anki Vector robots — Doc and Pip

Current state

PTT → STT → LLM → robot speech: confirmed working.
Custom Wire-Pod intents: deployed and cold-restart persistent.
Interview system Section 1: confirmed firing end-to-end.
Vector-hosted spoken Bingo: confirmed working, single-robot (Doc), with an optional Pip reaction watcher.
Cockpit webpage: running at :8011; camera panes are cached/placeholder frames, Edge TPU inference is wired but optional and currently offline by default.
Opening chord: confirmed working — mic, LLM, Kokoro voice, and both robots verified live before a show, direct-SDK "Brobots ready!" confirmed audibly near-simultaneous.
Public demo readiness: in progress.


The doctrine

Today's Lesson: This is what happens when you stop waiting for perfect and start building proof.
Boom. Class over. Done. Goodbye.
— Doc Squawkadoodle


More

Tech

  • GOPOD_FEATURES.md — everything GOPOD built on top of Wire-Pod, feature by feature
  • WIRED-POD.md — the code-level companion to GOPOD_FEATURES.md: the Wire-Pod hardening commit, plus the custom intents, prompts, and probe tree riding alongside it
  • ALIAS-PIANO.md — the operator's alias keyboard: every live GOPOD alias/function, mapped by what it plays
  • BINGO.md — the two-robot Bingo warm-up act
  • INTERVIEW.md — the interview arc, exchange by exchange
  • MOBILE.md — mobile deployment and field kit

Life

Learned

About

Multi-robot interactive demo system built on Wire-Pod — two Anki Vector robots, custom intents, LLM-driven interviews, and a live cockpit dashboard. Or at least the that's the goal...

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors