dsh-talk
Voice-first session loop for DeepSeek Harness: a composer microphone button with browser/local speech-to-text (Web Speech, FunASR, whisper.cpp), a speak tool for text-to-speech replies (browser, edge-tts, piper), event announcements with mute, and speak-to-interrupt.
安装
$
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:PerryLink/dsh-talk说明文档
阅读完整 README ↗Configuration
All tunables are Schemastery Config fields (changeable from cordis.yml). cordis.patch.yml documents each key inline.
| Key | Default | Meaning |
|---|---|---|
record.enabled | true | Show the composer mic button |
record.hotkey | (none) | Optional toggle hotkey, e.g. "alt+r" |
record.maxSeconds | 60 | Recording cap in seconds (1..600) |
record.autoSubmit | false | Submit the transcription as a user message (false = fill the draft) |
record.vad.enabled / silenceMs / energyThreshold | true / 1500 / 0.01 | Voice-activity detection: silence auto-ends the recording (degrades when AudioContext is absent) |
stt.engine | auto | auto / web / funasr / whisper; auto prefers a configured local engine, then Web Speech |
stt.language | auto | BCP-47 language or auto |
stt.interim | true | Show interim transcriptions (Web Speech) |
stt.silenceFinaliseMs | 4000 | Stop continuous Web Speech recognition after this many milliseconds without speech (500..15000) |
stt.funasr.url | (none) | FunASR inference endpoint; required when the engine is funasr |
stt.whisper.modelPath | (none) | whisper.cpp model; required when the engine is whisper |
tts.engine | auto | auto / browser / edge-tts / piper; auto prefers piper, then edge-tts, then the browser voice |
tts.rate | 0 | Rate offset in percent (-50..50) for edge-tts/piper |
tts.fallbackToBrowser | true | Fall back to the browser voice when a local engine fails |
tts.browser.voiceName | (none) | Preferred browser voice name; an unknown name uses the platform default |
tts.browser.rate | 1 | Browser SpeechSynthesis rate (0.1..10) |
tts.browser.pitch | 1 | Browser SpeechSynthesis pitch (0..2) |
tts.piper.modelPath | (none) | piper voice model; required when the engine is piper |
announce.enabled | true | Master switch for event announcements |
announce.onTurnEnd / onApproval / onError | true | Which events are spoken |
announce.messages.* | "Turn complete." etc. | Spoken phrases |
interrupt | true | Talking stops current playback |
maxSpeakChars | 20000 | Cap on the speak tool's text length (1..100000) |
maxAudioCacheBytes | 8388608 | In-memory synthesized-audio cache cap (1 MiB..64 MiB) |
stt.silenceFinaliseMs and record.vad.silenceMs are separate mechanisms: the first finalises the Web Speech transcript when continuous recognition hears no speech, the second is the MediaRecorder energy-based detector that ends the recording (and submits it when record.autoSubmit is on). They run in different pipelines and share no state.