Build from Source
Build the firmware from the esp-agents-firmware repo. Use this when you want to modify the code, add a tool, change the wake word, or point the device at a custom deployment.
Prerequisites
- A supported board and a USB cable.
- ESP-IDF v5.5.2 or later, on the
release/5.5branch. Newer major versions are not supported. - Git, Python 3.
Important. Don't use
masteror v5.6 of ESP-IDF. The firmware pins torelease/5.5for a specific feature set. Wrong versions either won't build or will misbehave at runtime.
Install ESP-IDF (one-time)
Follow Espressif's official guide: https://docs.espressif.com/projects/esp-idf/en/release-v5.5/esp32s3/get-started/index.html.
Quick version (Linux/macOS):
mkdir -p ~/esp && cd ~/esp
git clone -b release/5.5 https://github.com/espressif/esp-idf.git
cd esp-idf
./install.sh esp32s3
. ./export.sh
After this, idf.py --version should report v5.5.2 or newer.
Get the firmware
git clone https://github.com/espressif/esp-agents-firmware.git
cd esp-agents-firmware
Build, flash, and monitor
Pick the example you want — voice_chat or matter_controller:
cd examples/voice_chat # or examples/matter_controller
idf.py select-board --board echoear_core_board_v1_2 # or esp_box_3 / m5stack_cores3 / m5stack_cores3_h2_gateway
idf.py build flash monitor
select-boardis a custom extension, not stock ESP-IDF. The repo ships anidf_ext.pythat adds this command. Don't useidf.py set-target esp32s3— the target is fixed inside each board's defaults.
The first build takes 5–10 minutes. Subsequent builds are seconds. After flashing, the device reboots and starts running.
idf.py monitor shows the boot log and any subsequent output. Ctrl-] exits.
What's compiled in by default
| Setting | Default | Where to change |
|---|---|---|
| Gateway URL | wss://api.agents.espressif.com | menuconfig → ESP Agent Config → ESP Private Agents Server URL |
| Default agent ID | friend (voice_chat) / matter_controller (matter_controller) | menuconfig → ESP Agent Setup Configuration |
| Default volume | 75 | menuconfig → App Common Config → Default Playback Volume |
| Upload sample rate | 8000 Hz | menuconfig → App Common Config |
| Download sample rate | 16000 Hz | menuconfig → App Common Config |
| Wake word models | "Hi Lexin" + "Hi ESP" | menuconfig → WakeNet |
| AEC (echo cancel) | off | menuconfig → Audio Config → ENABLE_AEC |
Run idf.py menuconfig to bring up the curses UI; navigate, save (s), exit (q), then idf.py build flash monitor again.
After first boot
The device shows a QR code. Pair it via the mobile app — see Install and Pair a Device.
Iteration loop
Once it's paired and running:
# Edit code...
idf.py build
idf.py flash # device must be plugged in
idf.py monitor
Pairing state is preserved across reflashes (it's stored in NVS), so you don't have to re-pair every iteration. To wipe NVS and start fresh:
idf.py erase-flash
idf.py flash monitor
Common build errors
| Error | Likely cause |
|---|---|
idf.py: command not found | You haven't sourced export.sh in this shell. |
Could not find a version of toolchain | install.sh wasn't run for esp32s3, or your tool versions are stale. |
select-board: unknown command | You're not in an example dir, or idf_ext.py got removed. |
Build complete... Flashing... ESPSerial: no port | The board isn't connected, or another program (Arduino IDE, monitor) is holding the port. |
Where to look
components/agent/— gateway WebSocket client + auth.components/app_common/— shared platform code (audio, LVGL, network).examples/voice_chat/main/— entry point and tool registration for Voice Chat.examples/matter_controller/main/— entry point and tool registration for Matter.docs/— additional guides for customization in the repo itself.