feat(voice): configurable user voice-recognition time (bargeInMs, default 700ms)
Expose the barge-in sustained-speech threshold as a dashboard bot setting "유저 음성 인식 시간" (ms). Server clamps 0..5000, persists via state_store, and the bot reads it each report round-trip; WSAI_BARGE_IN_MS/700 stays the fallback default. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -37,7 +37,13 @@ class BotControl:
|
||||
self._lists: dict[str, dict[str, Any]] = st.get("lists") or {}
|
||||
# Bot behaviour settings the dashboard toggles and the bot reads on each
|
||||
# report. bargeIn: stop the bot's current TTS the moment a user speaks.
|
||||
self._settings: dict[str, Any] = {"bargeIn": True, **(st.get("botSettings") or {})}
|
||||
# bargeInMs: how long (ms) a user must keep speaking before that barge-in
|
||||
# fires — the "유저 음성 인식 시간" the dashboard exposes (default 700).
|
||||
self._settings: dict[str, Any] = {
|
||||
"bargeIn": True,
|
||||
"bargeInMs": 700,
|
||||
**(st.get("botSettings") or {}),
|
||||
}
|
||||
|
||||
# -- bot behaviour settings ------------------------------------------ #
|
||||
def get_settings(self) -> dict[str, Any]:
|
||||
@@ -48,6 +54,13 @@ class BotControl:
|
||||
with self._lock:
|
||||
if "bargeIn" in data:
|
||||
self._settings["bargeIn"] = bool(data["bargeIn"])
|
||||
if "bargeInMs" in data:
|
||||
try:
|
||||
ms = int(data["bargeInMs"])
|
||||
except (TypeError, ValueError):
|
||||
ms = 700
|
||||
# Keep it sane: 0ms = instant, cap at 5s so a typo can't wedge it.
|
||||
self._settings["bargeInMs"] = max(0, min(5000, ms))
|
||||
out = dict(self._settings)
|
||||
from . import state_store
|
||||
state_store.patch("botSettings", out)
|
||||
|
||||
@@ -1162,6 +1162,10 @@ PAGE = r"""<!DOCTYPE html>
|
||||
<div id="botcfgBody" style="display:none">
|
||||
<label class="cfgrow"><input type="checkbox" id="cfgBargeIn" checked>
|
||||
<span>유저 목소리 들을 때 봇이 말하던 것 중지 <b class="cfghint">(기본: 켜짐)</b></span></label>
|
||||
<label class="cfgrow"><span>유저 음성 인식 시간
|
||||
<input type="number" id="cfgBargeInMs" min="0" max="5000" step="50" value="700"
|
||||
style="width:80px;margin:0 4px"> ms
|
||||
<b class="cfghint">(이 시간 이상 말해야 봇이 멈춤 · 기본: 700)</b></span></label>
|
||||
</div>
|
||||
</section>
|
||||
<section class="sttbox" id="logcfgbox">
|
||||
@@ -1483,8 +1487,23 @@ function wireCollapse(toggleId, bodyId, caretId){
|
||||
body:JSON.stringify({bargeIn:$('cfgBargeIn').checked})});
|
||||
toast('봇 설정 저장됨'); }catch(e){}
|
||||
};
|
||||
// 유저 음성 인식 시간(ms): 서버가 0~5000으로 클램프, 봇이 다음 report에서 읽어감.
|
||||
$('cfgBargeInMs').onchange = async ()=>{
|
||||
let ms = Math.round(Number($('cfgBargeInMs').value));
|
||||
if(!Number.isFinite(ms)) ms = 700;
|
||||
ms = Math.max(0, Math.min(5000, ms));
|
||||
$('cfgBargeInMs').value = ms;
|
||||
try{ const r=await fetch('/api/bot/settings',{method:'POST',headers:{'Content-Type':'application/json'},
|
||||
body:JSON.stringify({bargeInMs:ms})});
|
||||
const j=await r.json();
|
||||
if(j&&j.ok&&j.settings&&j.settings.bargeInMs!=null) $('cfgBargeInMs').value=j.settings.bargeInMs;
|
||||
toast('봇 설정 저장됨'); }catch(e){}
|
||||
};
|
||||
fetch('/api/bot/settings').then(r=>r.json()).then(j=>{
|
||||
if(j&&j.ok&&j.settings) $('cfgBargeIn').checked = j.settings.bargeIn !== false;
|
||||
if(j&&j.ok&&j.settings){
|
||||
$('cfgBargeIn').checked = j.settings.bargeIn !== false;
|
||||
if(j.settings.bargeInMs!=null) $('cfgBargeInMs').value = j.settings.bargeInMs;
|
||||
}
|
||||
}).catch(()=>{});
|
||||
// 로그 설정: 잡음 로그 표시 안 함 — 클라이언트 필터(로컬 저장).
|
||||
$('cfgHideNoise').checked = hideNoise;
|
||||
|
||||
Reference in New Issue
Block a user