bub-xiaoai is a Bub channel plugin for Xiaomi XiaoAi speakers.
It is based on the Xiaomi device integration approach from yihong0618/xiaogpt, but the scope here is narrower:
- listen for messages from a XiaoAi speaker
- forward them into Bub as a channel
- expose
xiaoai.speakso the assistant can speak replies back through the speaker - keep the interaction in continuous conversation mode by default
This project does not provide a standalone CLI runner for XiaoAi. It is meant to be loaded by Bub as a plugin.
- Message polling from XiaoAi via Xiaomi Mina APIs
- TTS playback through the XiaoAi speaker
- Automatic wake-up after a reply to keep conversation going
- Temporary static file HTTP server started with the listener lifecycle
- Bub tool
xiaoai.speak - Bundled skill
xiaoaiundersrc/skills/xiaoaito instruct the LLM to callxiaoai.speak
At runtime the plugin creates a single XiaoAiMessageListener, registers a Bub channel named xiaoai, and exposes a tool:
- Channel:
xiaoai - Tool:
xiaoai.speak(text: str)
Incoming XiaoAi queries are turned into Bub ChannelMessage objects. The assistant should answer by calling xiaoai.speak, which performs TTS on the device.
When the listener starts, it also creates a temporary directory and serves it through a local HTTP server for the same lifecycle window. The directory is available through listener.static_server.temp_dir, and the base URL is available through listener.static_server.origin.
The channel currently runs in continuous conversation mode by default:
- ordinary spoken queries are forwarded without a keyword prefix
- the raw wake word
小爱同学is ignored and not sent to the LLM - after a reply finishes, the plugin attempts to wake XiaoAi again so the next utterance can be captured
- Python
>=3.13
uv pip install git+https://github.com/bubbuild/bub-xiaoai.gitSettings are loaded from environment variables through XiaoAiSettings with prefix BUB_MI_.
Supported variables:
BUB_MI_HARDWAREBUB_MI_ACCOUNTBUB_MI_PASSWORDBUB_MI_MI_DIDBUB_MI_COOKIEBUB_MI_TOKEN_HOMEBUB_MI_POLL_INTERVALBUB_MI_REQUEST_TIMEOUTBUB_MI_CHAT_ID
Defaults are defined in src/bub_xiaoai/mi.py.
Two login modes are supported:
- Xiaomi account + password
- Xiaomi cookie
If BUB_MI_COOKIE is set, the plugin skips account login and uses the cookie directly.
If you use account login, the plugin also expects a token file. In Bub runtime the default token path is:
<bub-home>/mi_token.json
This is wired in src/bub_xiaoai/plugin.py.
export BUB_MI_HARDWARE=LX06
export BUB_MI_ACCOUNT='your-xiaomi-account'
export BUB_MI_PASSWORD='your-xiaomi-password'
export BUB_MI_MI_DID='your-device-did'Or with cookie login:
export BUB_MI_HARDWARE=LX06
export BUB_MI_COOKIE='deviceId=...; serviceToken=...; userId=...'
export BUB_MI_MI_DID='your-device-did'Once the plugin is loaded by Bub:
- speech coming from XiaoAi arrives on channel
xiaoai - the LLM can answer by calling
xiaoai.speak
The provided skill at src/skills/xiaoai/SKILL.md tells the model to use xiaoai.speak for user-facing spoken replies.
- User talks to XiaoAi.
XiaoAiChannelpolls Xiaomi conversation records.- A new record is converted into a Bub message.
- The assistant handles the message.
- The assistant calls
xiaoai.speak. - The plugin speaks the response on the speaker.
- After TTS finishes, the plugin tries to wake XiaoAi again.
Relevant implementation files:
- The Xiaomi integration logic is adapted from
xiaogpt, especially device discovery, conversation polling, and MiIO wake-up commands. - The code is intentionally scoped to Bub integration instead of reproducing all of
xiaogpt. - There is no prompt management, model orchestration, or standalone command runner here.
- Xiaomi login can fail due to Xiaomi risk control. Cookie login is often more reliable.
- Automatic wake-up depends on MiIO commands and a usable
mi_did. - The channel currently ignores the isolated wake word
小爱同学. - Only the latest XiaoAi conversation records are polled; this is not a full history sync.
Run a quick syntax check:
python3 -m compileall srcRun a minimal import check in the project environment:
uv run python - <<'PY'
from bub_xiaoai import XiaoAiMessageListener, XiaoAiSettings
print(XiaoAiMessageListener, XiaoAiSettings)
PY- Core Xiaomi speaker integration ideas in this project come from
yihong0618/xiaogptby @yihong0618, including device discovery, conversation polling, MiIO wake-up control, and the overall continuous-conversation interaction model. - Built for the Bub plugin/runtime model