feat: listen mode + volume knob in chat; briefing discuss auto-send; fix LLM proactive note search
- ChatView: listen mode toggle (auto-reads new responses via TTS), volume popup with range slider persisted per-device in localStorage via GainNode - useVoiceAudio: shared module-level _volume ref with localStorage persistence, GainNode for volume control, exported setVoiceVolume() - tts.py: pre-warm all Kokoro voices at pipeline load to eliminate HuggingFace HEAD requests at synthesis time (reduces TTS latency) - BriefingView: discuss article button now auto-sends instead of just filling input; prompt capped to 15 sentences; send() accepts optional overrideText - llm.py: instruct LLM not to proactively search notes or comment on note absence Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -507,7 +507,8 @@ async def build_context(
|
||||
"Use search_notes for conceptual/semantic queries — e.g. 'what notes do I have about X' or "
|
||||
"'find notes related to Y' — it uses semantic understanding to find thematically related content "
|
||||
"even when exact words don't match. Pass project= to scope the search to a specific project. "
|
||||
"Use delete_note / delete_task only when explicitly asked to delete — these require confirmation."
|
||||
"Use delete_note / delete_task only when explicitly asked to delete — these require confirmation. "
|
||||
"Never proactively search notes or comment on the absence of notes/context unless the user explicitly asks about their notes."
|
||||
)
|
||||
tool_guidance = "\n".join(tool_lines)
|
||||
|
||||
|
||||
@@ -46,11 +46,18 @@ async def load_tts_model() -> None:
|
||||
|
||||
logger.info("Loading Kokoro TTS pipeline...")
|
||||
loop = asyncio.get_running_loop()
|
||||
_pipeline = await loop.run_in_executor(
|
||||
None,
|
||||
lambda: KPipeline(lang_code="a"), # "a" = American English
|
||||
)
|
||||
logger.info("Kokoro TTS pipeline loaded")
|
||||
def _load_and_warm():
|
||||
p = KPipeline(lang_code="a") # "a" = American English
|
||||
# Pre-load all voice tensors so synthesis never hits HuggingFace at request time
|
||||
for v in _VOICES:
|
||||
try:
|
||||
p.load_voice(v["id"])
|
||||
except Exception:
|
||||
pass
|
||||
return p
|
||||
|
||||
_pipeline = await loop.run_in_executor(None, _load_and_warm)
|
||||
logger.info("Kokoro TTS pipeline loaded and voices pre-warmed")
|
||||
except Exception:
|
||||
_load_error = "Failed to load Kokoro TTS pipeline"
|
||||
logger.exception(_load_error)
|
||||
|
||||
Reference in New Issue
Block a user