feat(dankvoice): /say options menu with output-device routing (Refs #23)
Bare /say and /say menu open a ctx.ui.select settings surface: auto-speak toggle, voice from the frank-tts roster, PipeWire output device (pw-play --target / paplay --device=), player binary, spoken cap, and a test phrase. Choices persist to ~/.omp/cache/dankvoice.json (env wins over file); detectPlayer becomes availablePlayers + playerFor. Fixes the silent-route failure mode where synthesized audio played into an offline Bluetooth sink. 15/15 dankvoice bats, 51/51 suite, live pty TUI smoke armed the footer and wrote the settings file.
This commit is contained in:
1 parent
54f15e2a58
commit
dd8f3974c1
4 files changed
+328
-68
No files matched your search
@@ -11,6 +11,21 @@ timestamp: 2026-08-28
|
||||
|
||||
# Bundle Change Log
|
||||
|
||||
|
||||
## 2026-10-18 — dankvoice: `/say` options menu with output-device routing (Refs #23)
|
||||
|
||||
Added `/say menu` (bare `/say` now opens it; `help` keeps the text listing), the
|
||||
pi-peon-style settings surface: auto-speak toggle, voice picked from the frank-tts
|
||||
roster, **output device** (PipeWire sinks via `wpctl` → `pw-play --target` /
|
||||
`paplay --device=`), player binary, spoken-char cap, and a "speak a test phrase"
|
||||
utterance that proves the audio path audibly. Choices persist to
|
||||
`~/.omp/cache/dankvoice.json` (`DANKVOICE_CONFIG`); env now wins over that file,
|
||||
which wins over defaults — answering the silent-session incident where
|
||||
PipeWire's remembered Bluetooth route played synthesized answers into nowhere.
|
||||
`detectPlayer` becomes `availablePlayers` + `playerFor`. Tests gain a fixture
|
||||
`wpctl`, a scripted `select` in the driver, and three menu scenarios: 15 green
|
||||
in `tests/dankvoice.bats`, 51 green suite-wide.
|
||||
|
||||
## 2026-10-18 — dankvoice: the cloned voices finally speak in the TUI (Refs #21)
|
||||
|
||||
Nothing in the harness could pronounce them: the TUI vocalizer and `omp say` gate `--voice` against the bundled Kokoro enum (`omp say --voice narrator1 "test"` → `error: Expected --voice to be one of: af_heart, …`), so frank-tts was reachable only as a file. Added `agent/extensions/dankvoice.ts` — `/say <text>`, `/say on|off` (narrate the final answer at `agent_end`), `/say voice|voices|stop|status` — synthesizing over the OpenAI speech route and playing through `pw-play`/`paplay`/`ffplay`, with the endpoint read from the `api: openai-speech` row of `agent/models.yml` (no host, no secret in the file). Verified live in a real TUI session on the workstation: roster `GET /v1/audio/voices` → `narrator1, narrator2, narrator3`; `/say` produced 99,884 B / 2.08 s and 69,164 B / 1.44 s WAVs handed to the player, temp dirs cleaned afterwards; `/say on` armed the footer (`🔊 narrator1`) and each following finished turn spoke its answer (1.20 s WAV), an unknown voice name answered with the roster instead of speaking, and an `agent_end` carrying `willContinue` (the harness scheduled an auto-retry) is deliberately never narrated. Extension discovery itself proved with a probe file in `~/.omp/agent/extensions/` loaded by a fresh `omp -p` run. Reference page [dankvoice](core/dankvoice.md), registered in the core index; black-box seam `tests/dankvoice.bats` (12 tests).
|
||||
|
||||
Reference in new issue
Block a user