Skip to content

Latest commit

 

History

14 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Hermes32

╔════════════════════════════════════════════════════╗
║  //       //       //       //       //       //   ║
║     ||       ||       ||       ||       ||       ||║
║  //       //       //       //       //       //   ║
║     ||       ||       ||       ||       ||       ||║
║  //        ╭─────────────────────────╮        //   ║
║     ||     │ ┌─────────────────────┐ │  ||       ||║
║  //        │ │                     │ │        //   ║
║     ||     │ │       HERMES32      │ │  ||       ||║
║  //        │ │                     │ │        //   ║
║     ||     │ └─────────────────────┘ │  ||       ||║
║  //        │                         ├───╮    //   ║
║     ||     │     ·  ·  ·  ·  ·       │ P │       ||║
║  //        │     ·  ·  ·  ·  ·       │ R │    //   ║
║     ||     │     ·  ·  ·  ·  ·       │ E │       ||║
║  //        │                         │ S │    //   ║
║     ||     │                         │ S │       ||║
║  //        │         ( ● )           ├───╯    //   ║
║     ||     │                         │  ||       ||║
║  //        │                         │        //   ║
║     ||     │                         │  ||       ||║
║  //        ╰─────────────────────────╯        //   ║
║     ||       ||       ||       ||       ||       ||║
║  //       //       //       //       //       //   ║
║     ||       ||       ||       ||       ||       ||║
║  //       //       //       //       //       //   ║
╚════════════════════════════════════════════════════╝

Hermes32 is a small handheld dictaphone and walkie-talkie for Hermes Agent.

The finished device will have its own microphone, speaker, screen, and talk button in a portable case. Hold the button to record a note or speak to Hermes, then see and hear the reply on the device. The ESP32 is the part inside the product, not the product itself.

Where it is today

The current version has a working voice path. It can record with a MacBook microphone, send the audio through the same bridge the ESP32 will use, ask Hermes to transcribe it, and then let Hermes process the transcript. The ESP32's BOOT button still sends a short text message until a microphone is connected to the board.

There is no microphone, speaker, or screen on the physical device yet. Those are the next hardware milestone.

What you need

  • An ESP32 DevKit with a classic ESP32/WROOM module
  • A USB data cable
  • Python 3.11 or newer and uv, on Apple Silicon macOS or Linux
  • A Wi-Fi network that can reach the Hermes bridge
  • A running Hermes Agent host that you can access over SSH. Automatic bridge installation supports Linux x86_64 or aarch64 with CPython 3.11-3.14.
  • Tailscale installed and signed in on this computer and the Hermes host

Tailscale gives the web interface a private HTTPS address, which browsers need before they will allow microphone access. The ESP32 itself connects over Wi-Fi and does not join Tailscale.

Intel macOS is intentionally unsupported for now. The current esptool release requires an older cryptography build on that platform, so installation fails instead of selecting a dependency with known vulnerabilities.

Set up a device

Install the setup tool and its Python dependencies from this checkout:

./install

Connect the ESP32 over USB, then run one command:

hermes32

That single flow finds the Hermes host through Tailscale, installs or updates the bridge and voice services when needed, prepares the ESP32, registers its unique device identity, connects it to Wi-Fi, waits for it to check in, and opens the private web app. It asks before changing the Hermes host, erasing a board, or using local Wi-Fi HTTP.

On macOS, Hermes32 asks for Location permission once so it can read the Mac's current Wi-Fi name. It does not use or store your physical location. If access is declined, setup falls back to asking for the Wi-Fi name.

The local Wi-Fi HTTP question matters because an ESP32 cannot use the host's private Tailscale HTTPS address. Its unique token limits the damage if a device credential is lost, but HTTP cannot hide that token from someone watching the network. Prefer a reachable HTTPS bridge when the network is not fully trusted.

For a different SSH destination, use:

hermes32 --hermes pi@192.168.1.20

If the bridge already has a reachable HTTPS address, supply the operator token through a mode-0600 file or HERMES32_OPERATOR_TOKEN and run:

hermes32 \
  --bridge-url https://radio.example.com \
  --operator-token-file ~/.config/hermes32/operator-token

hermes32 is the complete first-run and upgrade flow. Subcommands are optional tools for returning to one part of an existing installation.

Command Purpose Changes
hermes32 / setup Run the complete setup May update Hermes, erase the board, and register one device
reconfigure Update an existing ESP32 Rewrites its firmware and configuration
doctor Diagnose a connected board, its configuration, bridge, and Hermes None
talk Send one voice prompt Creates one message and Hermes run
app Open the private Hermes32 web app None
bridge status Inspect the bridge host, metadata, credential, and runtime None

Use hermes32 COMMAND --help for command-specific examples and options. hermes32 --install-completion installs shell completion for the current shell. Interactive setup uses color and compact progress indicators; use --no-color, --no-animation, or --verbose before the command for plain or detailed output. Hermes32 also honors the standard NO_COLOR environment variable.

Talk from the web interface

The main hermes32 flow starts a loopback-only Hermes voice service. Hermes uses the speech-to-text provider selected in its own stt settings; the bridge does not keep a second provider key or transcription setup.

Setup opens the private HTTPS web app. Open it again later without changing the bridge or device:

hermes32 app --hermes ubuntu@hermes

Click Talk, speak, then click Send. The web app uploads the recording and shows the prompt and Hermes reply in the message list. macOS may ask for microphone permission the first time. The CLI creates a random, one-use browser login that expires after 5 minutes. Only that short-lived code travels in the URL fragment; the full operator token does not appear in the browser launch command or browser address.

The command-line recorder remains useful for testing with an existing file or another recording program:

hermes32 talk --hermes ubuntu@hermes --file note.wav

You can also connect another recording program. {output} is replaced with a temporary WAV path and the command must write the recording there:

hermes32 talk --hermes ubuntu@hermes \
  --capture-command 'arecord -d 8 -f S16_LE -r 16000 {output}'

This is the hardware-neutral part of the design. A Mac, an ESP32 I2S mic, an analog mic with an ADC, or another small computer can all send the same audio request. Microphone-specific code only has to capture audio; it does not need to know how Hermes works.

The wire contract is deliberately small:

POST /api/voice?device_id=kitchen-radio
Authorization: Bearer <device-token>
Content-Type: audio/wav

<raw audio bytes>

The bridge accepts common WAV, MP3, M4A, AAC, FLAC, Ogg, MP4, and WebM audio. It keeps the audio in memory only for transcription. The saved message contains the transcript, transcription provider, Hermes reply, and status, not the raw recording.

Use it

The private bridge page opens automatically when setup finishes. Hold BOOT while the device listens, then release it to send the test message. The board's LED shows the current mode and the Hermes reply appears on the page.

Do not hold BOOT while resetting or powering the board. That starts firmware upload mode.

Device mode interface

Every device uses the same four modes:

Mode Meaning ESP32 DevKit proof
idle Ready for input Brief heartbeat every two seconds
listening Receiving input Solid light while BOOT is held
working Waiting for Hermes Slow blink
responding Presenting the reply Fast blink

The message workflow only calls DeviceMode.set(mode). A hardware adapter implements set_mode(mode) and decides what each mode looks or sounds like. The included Esp32StatusLight adapter uses the single LED on GPIO 2. A future device can replace it with an RGB light, display, speaker, or another output without changing the workflow.

The current board prints the reply over USB, shows responding for two seconds, then returns to idle.

Reconfigure or check a device

Run setup again after changing Wi-Fi or moving to another Hermes host:

hermes32 reconfigure

Check the USB connection, saved setup, bridge, and Hermes connection:

hermes32 doctor

When upgrading from the older shared-token bridge, update the bridge first and then reconfigure each connected board. The CLI verifies the saved credential; it will not silently keep the old shared token or rotate an existing device.

If a board is lost, provision its replacement with the same device ID and add --rotate-device-token. This explicit flag revokes the old board's credential.

For development, reset both sides before testing setup from scratch:

./dev prune

This removes only the Hermes32 services and state from Hermes and erases the connected ESP32. It keeps Hermes itself, hermes-gateway, and local source files. The command shows its exact targets and requires typing prune before it deletes anything. Use ./dev prune --yes in disposable test automation.

Current limits

  • The ESP32 button sends a fixed text message until its microphone adapter is added. The bridge and Hermes voice path are ready now.
  • Replies appear on the bridge page and are printed over the ESP32 USB console.
  • Automatic ESP32 setup asks before using plain HTTP on a trusted local Wi-Fi network. A custom HTTPS endpoint removes that limitation.
  • Hermes requests that need human approval cannot be completed from the device.

See SECURITY.md for credential roles, transport guidance, limits, and recovery steps.

License

MIT

About

An open-source walkie-talkie for Hermes Agent — a portable ESP32-based device with its own microphone, speaker, screen, and talk button.

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages