feat(dashboard): 4-way roster (user/bot/voice/role), persistence, TTS all-emotions, layout

- 유저 등록/관리 search now has 4 types: 유저(non-bot members), 봇(bot members),
  통화방(current voice-channel members, bot flag enriched), 역할(roles — expandable
  to the members under each role; register the role OR a member under it).
- Persist settings to a JSON state store (WSAI_STATE_FILE, default
  ~/.config/wsai/state.json) so they survive a service/container restart:
  per-guild listen lists + bargeIn (BotControl), TTS base/overrides and the
  chosen STT/LLM models (Dashboard). Applied on voice-server startup before warm.
- TTS 감정 선택에 최상단 "전체변경 (모든 감정)" 추가: 적용하면 base를 그 값으로 세팅하고
  모든 per-emotion override를 지워 전 감정이 한 번에 그 값으로 말합니다.
- Move the component status bar (눈/시각/귀/LLM/입) above the bot bar.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
EJClaw
2026-08-27 00:14:24 +09:00
parent 0588ee21ac
commit c39b47cfd3
5 changed files with 189 additions and 27 deletions

View File

@@ -37,7 +37,7 @@ def test_monitor_records_turn_with_timed_steps():
assert turn["total_ms"] >= 0
# step-by-step: every stage is named and timed
names = [s["name"] for s in turn["steps"]]
assert names == ["화면 맥락", "두뇌(생각)", "응답(TTS/전송)"]
assert names == ["화면 맥락", "LLM(생각)", "응답(TTS/전송)"]
assert all(s["ok"] is True for s in turn["steps"])
assert all(s["ms"] >= 0 for s in turn["steps"])
@@ -66,7 +66,7 @@ def test_monitor_marks_errors():
turn = snap["turns"][0]
assert turn["status"] == "error"
brain_step = next(s for s in turn["steps"] if s["name"] == "두뇌(생각)")
brain_step = next(s for s in turn["steps"] if s["name"] == "LLM(생각)")
assert brain_step["ok"] is False
assert "boom" in brain_step["error"]
assert snap["status"]["errors_total"] >= 1