refactor(tui_gateway): W4 wave2 pass 8 — split prompt/personality/skin setters, nest single-use voice helpers

This commit is contained in:
Teknium
2026-09-03 02:49:40 -07:00
parent dfd0a56ee9
commit 8d1714018a
2 changed files with 39 additions and 42 deletions

View File

@@ -419,32 +419,34 @@ def _set_cwd(rid, params, key, value, session):
@_cfgset_guarded
def _set_prompt_like(rid, params, key, value, session):
cfg = _load_cfg_raw() # write-back round-trip ("prompt" saves cfg)
resp = {"key": key, "value": value}
if key == "prompt":
if value == "clear":
cfg.pop("custom_prompt", None)
resp["value"] = ""
else:
cfg["custom_prompt"] = value
_save_cfg(cfg)
elif key == "personality":
pname, new_prompt = _validate_personality(str(value or ""), cfg)
# Persists via hermes_cli.personality (single owner), never the user-owned system prompt.
from hermes_cli.personality import persist_personality
persist_personality(pname)
resp["value"] = str(value or "none")
history_reset, info = _apply_personality_to_session(params.get("session_id", ""), session, new_prompt, pname)
resp["history_reset"] = history_reset
if info is not None:
resp["info"] = info
def _set_prompt(rid, params, key, value, session):
cfg = _load_cfg_raw() # write-back round-trip
if value == "clear":
cfg.pop("custom_prompt", None)
else:
_write_config_key(f"display.{key}", value)
if key == "skin": # every surface repaints; sync the watcher baseline (no re-broadcast)
_broadcast_global_event("skin.changed", resolve_skin())
_note_skin_broadcast()
return _ok(rid, resp)
cfg["custom_prompt"] = value
_save_cfg(cfg)
return _kv(rid, key, "" if value == "clear" else value)
@_cfgset_guarded
def _set_personality(rid, params, key, value, session):
pname, new_prompt = _validate_personality(str(value or ""), _load_cfg_raw())
# Persists via hermes_cli.personality (single owner), never the user-owned system prompt.
from hermes_cli.personality import persist_personality
persist_personality(pname)
history_reset, info = _apply_personality_to_session(params.get("session_id", ""), session, new_prompt, pname)
return _kv(rid, key, str(value or "none"), history_reset=history_reset,
**({"info": info} if info is not None else {}))
@_cfgset_guarded
def _set_skin(rid, params, key, value, session):
_write_config_key("display.skin", value)
# Every surface repaints; sync the watcher baseline so the poll loop doesn't re-broadcast.
_broadcast_global_event("skin.changed", resolve_skin())
_note_skin_broadcast()
return _kv(rid, key, value)
def _set_display_toggle(rid, params, key, value, session):
@@ -464,7 +466,7 @@ _CONFIG_SETTERS = {
"density": _set_display_bool, "battery": _set_display_bool, "theme": _set_theme,
"statusbar": _set_statusbar, "mouse": _set_mouse, "indicator": _set_indicator,
"cwd": _set_cwd, "terminal.cwd": _set_cwd, "workdir": _set_cwd,
"prompt": _set_prompt_like, "personality": _set_prompt_like, "skin": _set_prompt_like}
"prompt": _set_prompt, "personality": _set_personality, "skin": _set_skin}
@method("config.set")

View File

@@ -217,28 +217,24 @@ def _fd_barge_params(cfg: dict) -> tuple[float, int]:
return mult, max(0, num(lambda v: int(float(v) * 1000), "barge_in_grace_seconds", 0.5))
def _cut_all_tts() -> None:
"""Cut streaming TTS, every fallback speak pipeline, and the file player."""
from tools.voice_mode import stop_playback
_tts_stream_stop(user_barge=True)
with _fd_listener_lock:
for _stop, _done in _fd_speak_pipelines:
_stop.set()
stop_playback()
def _fd_trip(phase: str) -> None:
"""Listener tripped: latch the interruption, cut TTS FIRST (so a stale reply can never
speak), and during generation also interrupt every running turn (the ``agent.interrupt()``
seam ``session.interrupt`` uses)."""
from tools.tts_streaming import mark_speech_interrupted
from tools.voice_mode import stop_playback
mark_speech_interrupted()
if phase == "playback":
logger.debug("TTS CUT: full-duplex listener tripped during playback")
else:
logger.debug("full-duplex listener tripped during generation — "
"interrupting running turn(s)")
_cut_all_tts()
# Cut streaming TTS, every fallback speak pipeline, and the file player.
_tts_stream_stop(user_barge=True)
with _fd_listener_lock:
for _stop, _done in _fd_speak_pipelines:
_stop.set()
stop_playback()
if phase != "playback":
try:
for s in _running_sessions():
@@ -300,9 +296,8 @@ def _voice_status_payload(**extra) -> dict:
"""``{enabled, record_key, tts, **extra}``: record_key (default ``ctrl+b``) rides every voice.toggle
branch so a tts toggle never resets a custom binding."""
record_key = _voice_cfg_dict().get("record_key")
record_key = str(record_key) if isinstance(record_key, str) and record_key else "ctrl+b"
return {"enabled": _voice_mode_enabled(), "record_key": record_key, "tts": _voice_tts_enabled(),
**extra}
record_key = record_key if isinstance(record_key, str) and record_key else "ctrl+b"
return {"enabled": _voice_mode_enabled(), "record_key": record_key, "tts": _voice_tts_enabled(), **extra}
# ── Wake word ("Hey Hermes"): process-global detector (one mic). The first eligible transport
@@ -678,8 +673,8 @@ def _(rid, params: dict) -> dict:
return handler(rid, params)
# voice.record callbacks (module-level: they touch only process-global state). Each terminal
# capture event resumes the wake detector so wake-triggered and manual captures coexist.
# voice.record callbacks: each terminal capture event resumes the wake detector so wake-triggered
# and manual captures coexist.
def _vr_transcript(payload: dict) -> None:
_voice_emit("voice.transcript", payload)
_resume_voice_wake()