Clone this repository
For self-hosted knots, clone URLs may differ based on your setup.
The voice model sometimes answered a repeated light command with "on it" without emitting a delegation, so the backend never saw it. The persona now says the voice model can do nothing itself, that every action request is delegated every time, and that it may only say it is on it together with the delegation.
The Android app holds the call itself instead of opening the page in a
Custom Tab: hold the headset's voice button (HFP AT+BVRA=1 starts
VOICE_COMMAND), talk, short press to hang up, all with the phone locked
and without looking at it.
- VoiceCall: the page's Call in Java over WebRTC (webrtc-sdk/android):
delegation to Hermes, voice approvals, end_call, idle hang-up.
- CallService: a self-managed Telecom call in the foreground, so the
audio goes to the headset and its hang-up (AT+CHUP) ends the call; a
tone says it listens.
- Screens: the current conversation with Call / Hang up, the list of
conversations, and the settings (app token, permissions).
- hermes-voice accepts the app's own token (--app-token-file, clan var
hermes-voice-app on coaxmetal); assist.lassul.us/app/ passes it
through without the web login.
- The page keeps Talk / Hang up in view: only the transcript scrolls.
assetlinks.json, the TWA and the page's ?listen go away with the
Custom Tab.
The app holds each call of the page as a self-managed Telecom call
(transactional API, foreground service), so a headset's AT+CHUP reaches
it. Page and app talk over the Custom Tabs postMessage channel: the page
reports started/ended, the app sends hangup. assetlinks.json grants the
app use_as_origin for that.
/?listen, which the Android app opens, matched no static file and got 404.