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:
@@ -65,7 +65,7 @@ class Pipeline:
|
||||
except Exception as exc: # a single bad frame must not kill the loop
|
||||
log.exception("vision.describe failed")
|
||||
if self.monitor is not None:
|
||||
self.monitor.log("error", f"화면 이해 실패: {exc}")
|
||||
self.monitor.log("error", f"화면 이해 실패: {exc}", cat="VISION")
|
||||
continue
|
||||
await self.context.update(obs)
|
||||
log.debug("screen: %s", obs.text[:120])
|
||||
@@ -122,7 +122,7 @@ class Pipeline:
|
||||
return
|
||||
if self.monitor is not None:
|
||||
self.monitor.set_status(listening=True)
|
||||
self.monitor.log("info", "음성 수신 시작 — 발화 대기 중")
|
||||
self.monitor.log("info", "음성 수신 시작 — 발화 대기 중", cat="PIPELINE")
|
||||
try:
|
||||
async for utt in self.stt.utterances():
|
||||
await self._handle(utt)
|
||||
@@ -157,7 +157,7 @@ class Pipeline:
|
||||
except Exception as exc: # a warm failure must not abort startup
|
||||
log.warning("prewarm %s failed: %s", name, exc)
|
||||
if self.monitor is not None:
|
||||
self.monitor.log("error", f"{name} 예열 실패: {exc}")
|
||||
self.monitor.log("error", f"{name} 예열 실패: {exc}", cat="READY")
|
||||
|
||||
async def run(self) -> None:
|
||||
# A TaskGroup (not bare gather) so that if ONE loop raises, the others
|
||||
@@ -167,7 +167,7 @@ class Pipeline:
|
||||
# still-live loop (close-during-use).
|
||||
if self.monitor is not None:
|
||||
self.monitor.set_status(running=True)
|
||||
self.monitor.log("info", "파이프라인 시작")
|
||||
self.monitor.log("info", "파이프라인 시작", cat="PIPELINE")
|
||||
await self._prewarm()
|
||||
try:
|
||||
async with asyncio.TaskGroup() as tg:
|
||||
@@ -177,12 +177,12 @@ class Pipeline:
|
||||
except* Exception as eg:
|
||||
if self.monitor is not None:
|
||||
for exc in eg.exceptions:
|
||||
self.monitor.log("error", f"루프 예외: {type(exc).__name__}: {exc}")
|
||||
self.monitor.log("error", f"루프 예외: {type(exc).__name__}: {exc}", cat="PIPELINE")
|
||||
raise
|
||||
finally:
|
||||
if self.monitor is not None:
|
||||
self.monitor.set_status(running=False, listening=False)
|
||||
self.monitor.log("info", "파이프라인 종료")
|
||||
self.monitor.log("info", "파이프라인 종료", cat="PIPELINE")
|
||||
await self.aclose()
|
||||
|
||||
async def aclose(self) -> None:
|
||||
|
||||
Reference in New Issue
Block a user