Commit cf2f238
committed
feat(voice): ground STT analyzer prompt on the live VC roster + emit addressed_seat_no
The roster grounding fixes two compounding failure modes that surfaced
when sakura said "ラキオが怪しい" in voicetest and the analyzer
returned ``addressed_name=null, stance={}, vote_target_seat=null`` —
i.e. nothing routable to seat 1 — even though the speaker's intent
was unambiguous.
1) Whisper renders less-common Japanese names with phonetic drift
("ラキオ" → "ラッキーオ"). The static analyzer prompt only saw the
mistranscription, had no anchor to the actual participant list,
and could not resolve the name back to a seat. Now the STT call
threads a ``roster: Sequence[(seat_no, display_name)]`` derived
from the *live* VC member list (via ``bot.get_guild().get_member().display_name``,
cross-referenced with NpcRegistry for NPC-bot user IDs since their
seats carry ``discord_user_id=NULL``). The analyzer prompt
instructs the LLM to collapse phonetic / orthographic / honorific
variants onto a roster entry and to also resolve ``vote_target_seat``
against the same list. xAI Grok dry-run on the canonical failure
case confirms the fix:
INPUT : "ラッキーオさんが怪しいと思います"
BEFORE : addressed_name=null, stance={}, vote_target_seat=null
AFTER : addressed_name="🦋ラキオ", stance={"1":"negative"},
summary normalised to canonical name
2) The legacy resolver only matched against ``Seat.display_name``
(set once at backfill = the persona's canonical handle, e.g.
"🦋ラキオ"). When an operator renamed an NPC bot in the guild
("Lucky"), the live VC nickname diverged from the persona handle
and downstream ``resolve_seat_by_name("Lucky", seats)`` returned
None — so even with a roster grounding, the analyzer's literal
string answer would not survive Master-side resolution. Add an
``addressed_seat_no`` field analogous to ``vote_target_seat`` that
the analyzer pre-resolves from the roster directly. Plumb it
through ``SttResult`` → ``SpeechEventPayload`` and have
``MasterIngestService.ingest_voice`` prefer it when it points at
an alive seat, falling back to the name path on miss / hallucinated
value. Verified against Grok with a renamed-bot roster:
INPUT : "Luckyさん何か言いたそうですね" (seat 1 = "Lucky")
OUTPUT : addressed_name="Lucky", addressed_seat_no=1
INPUT : "ラッキーオさんに投票します"
OUTPUT : vote_target_seat=1, addressed_seat_no=1
Voicetest mirrors the production resolver — the roster lookup pulls
from ``vc_channel.members`` so an operator can A/B with the same
nicknames the speaker actually sees on their VC overlay. A startup
log line dumps the resolved roster snapshot so the prompt grounding
is auditable without crawling the JSONL trace.1 parent 70e6061 commit cf2f238
9 files changed
Lines changed: 521 additions & 19 deletions
File tree
- src/wolfbot
- domain
- master
- voicetest
- tests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
538 | 538 | | |
539 | 539 | | |
540 | 540 | | |
| 541 | + | |
| 542 | + | |
| 543 | + | |
| 544 | + | |
| 545 | + | |
| 546 | + | |
| 547 | + | |
| 548 | + | |
| 549 | + | |
| 550 | + | |
| 551 | + | |
| 552 | + | |
541 | 553 | | |
542 | 554 | | |
543 | 555 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
103 | 103 | | |
104 | 104 | | |
105 | 105 | | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
106 | 109 | | |
107 | 110 | | |
108 | | - | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
109 | 123 | | |
110 | 124 | | |
111 | 125 | | |
| |||
115 | 129 | | |
116 | 130 | | |
117 | 131 | | |
| 132 | + | |
118 | 133 | | |
119 | 134 | | |
120 | | - | |
| 135 | + | |
121 | 136 | | |
122 | 137 | | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
123 | 168 | | |
124 | 169 | | |
125 | 170 | | |
| |||
1103 | 1148 | | |
1104 | 1149 | | |
1105 | 1150 | | |
| 1151 | + | |
| 1152 | + | |
| 1153 | + | |
| 1154 | + | |
| 1155 | + | |
| 1156 | + | |
| 1157 | + | |
| 1158 | + | |
| 1159 | + | |
1106 | 1160 | | |
1107 | 1161 | | |
1108 | 1162 | | |
| |||
1113 | 1167 | | |
1114 | 1168 | | |
1115 | 1169 | | |
| 1170 | + | |
1116 | 1171 | | |
1117 | 1172 | | |
1118 | 1173 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
232 | 232 | | |
233 | 233 | | |
234 | 234 | | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
235 | 244 | | |
236 | | - | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
237 | 252 | | |
238 | 253 | | |
239 | 254 | | |
| |||
245 | 260 | | |
246 | 261 | | |
247 | 262 | | |
248 | | - | |
249 | | - | |
250 | | - | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
251 | 266 | | |
252 | 267 | | |
253 | 268 | | |
| |||
0 commit comments