feat(dashboard): default STT=medium, apply feedback+loading, log categories+filters
- Default STT model changed small -> medium (WhisperSTT default + service env; medium pre-cached). UI labels/hints updated. - Model 적용 buttons: if the picked model == current, flash "변경사항 없음" for 3s then show the current model again; if it actually changes, STT shows a live loading panel that polls /api/models until the worker is ready and logs completion to the event log (set_stt_model/set_llm_model now return `changed`). - Event/error log gains categories (READY, CONNECT, MODEL, TTS, VOICE, FILTER, SETTING, TURN, BRAIN, VISION, PIPELINE, …): Monitor.log takes an optional `cat`, call sites tagged, and each line shows a coloured category chip. A bot (re)connection now logs a CONNECT event. - Log search extended: filter by 레벨(type), 종류(category, auto-populated), and 시간(time range) in addition to free text. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -129,7 +129,7 @@ class Turn:
|
||||
# Guarded so the repeated _touch()/finish() calls can't double-count.
|
||||
if self.status == "error" and not self._error_logged:
|
||||
self._error_logged = True
|
||||
self._monitor.log("error", f"대화 #{self.id} 실패: {self.error}")
|
||||
self._monitor.log("error", f"대화 #{self.id} 실패: {self.error}", cat="TURN")
|
||||
self._touch()
|
||||
|
||||
# -- internal --------------------------------------------------------- #
|
||||
@@ -209,12 +209,17 @@ class Monitor:
|
||||
self._status["claude_output_tokens"] += int(output_tokens or 0)
|
||||
self._broadcast({"type": "status", "status": self.status_snapshot()})
|
||||
|
||||
def log(self, level: str, message: str) -> None:
|
||||
"""A free-form lifecycle/error line (startup, disconnect, crash…)."""
|
||||
def log(self, level: str, message: str, cat: str | None = None) -> None:
|
||||
"""A free-form lifecycle/error line (startup, disconnect, crash…).
|
||||
|
||||
``cat`` is a short category tag (READY, CONNECT, MODEL, TTS, VOICE,
|
||||
FILTER, SETTING, TURN, BRAIN, PIPELINE, …) shown as a chip and filterable
|
||||
on the dashboard. Defaults to the upper-cased level when omitted."""
|
||||
with self._lock:
|
||||
self._event_id += 1
|
||||
evt = {"type": "log", "id": self._event_id, "level": level,
|
||||
"message": message, "wall": _now_wall()}
|
||||
"cat": (cat or level.upper()), "message": message,
|
||||
"wall": _now_wall()}
|
||||
self._events.append(evt)
|
||||
if level == "error":
|
||||
self._status["errors_total"] += 1
|
||||
|
||||
Reference in New Issue
Block a user