verbalcoding 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +5 -3
- package/app-node/install_config.mjs +1 -1
- package/app-node/install_config.test.mjs +1 -1
- package/app-node/main.mjs +4 -1
- package/docs/CONFIGURATION.md +52 -2
- package/docs/RELEASE.md +1 -1
- package/docs/USAGE.md +47 -1
- package/docs/i18n/CONFIGURATION.ko.md +52 -2
- package/docs/i18n/RELEASE.ko.md +1 -1
- package/docs/i18n/USAGE.ko.md +47 -1
- package/package.json +1 -1
- package/run.sh +1 -1
- package/scripts/docker_ubuntu_smoke.sh +1 -1
- package/scripts/doctor.mjs +1 -1
- package/scripts/install.mjs +1 -1
package/.env.example
CHANGED
|
@@ -26,6 +26,7 @@ STT_LANGUAGE="ko"
|
|
|
26
26
|
|
|
27
27
|
TTS_BACKEND="edge" # edge | openvoice | speechswift | supertonic
|
|
28
28
|
EDGE_TTS_COMMAND="edge-tts"
|
|
29
|
+
TTS_VOICE_TYPE="korean_female" # edge: korean_male | korean_female | korean_multilingual_male | english_male | english_female
|
|
29
30
|
TTS_VOICE="ko-KR-SunHiNeural"
|
|
30
31
|
TTS_RATE="+10%"
|
|
31
32
|
TTS_MAX_CHARS="495"
|
|
@@ -66,8 +67,9 @@ OPENVOICE_STYLE="default"
|
|
|
66
67
|
OPENVOICE_TIMEOUT_MS="90000"
|
|
67
68
|
OPENVOICE_PROGRESS="0" # keep progress prompts fast via Edge unless set to 1
|
|
68
69
|
REQUIRE_WAKE_WORD="0"
|
|
69
|
-
MIN_UTTERANCE_SECONDS="1.
|
|
70
|
-
|
|
70
|
+
MIN_UTTERANCE_SECONDS="1.0"
|
|
71
|
+
# Wait for natural thinking pauses before STT. Lower for faster but more fragmented turns.
|
|
72
|
+
UTTERANCE_IDLE_MS="4500"
|
|
71
73
|
MIN_MEAN_VOLUME_DB="-35"
|
|
72
74
|
MIN_MAX_VOLUME_DB="-12"
|
|
73
75
|
BARGE_IN_MIN_SECONDS="1.4"
|
|
@@ -80,4 +82,4 @@ PLAYBACK_BARGE_IN_REQUIRE_BOTH="1"
|
|
|
80
82
|
BARGE_IN_CONSERVATIVE_MIN_SECONDS="1.8"
|
|
81
83
|
BARGE_IN_CONSERVATIVE_MIN_MEAN_VOLUME_DB="-27"
|
|
82
84
|
BARGE_IN_CONSERVATIVE_MIN_MAX_VOLUME_DB="-12"
|
|
83
|
-
MAX_DEFERRED_PROCESSING_UTTERANCES="
|
|
85
|
+
MAX_DEFERRED_PROCESSING_UTTERANCES="0"
|
|
@@ -57,7 +57,7 @@ export function normalizeInstallAnswers(input = {}) {
|
|
|
57
57
|
OPENVOICE_PROGRESS: input.openvoiceProgress === true || input.OPENVOICE_PROGRESS === '1' ? '1' : '0',
|
|
58
58
|
REQUIRE_WAKE_WORD: input.requireWakeWord === true || input.REQUIRE_WAKE_WORD === '1' ? '1' : '0',
|
|
59
59
|
MIN_UTTERANCE_SECONDS: clean(input.minUtteranceSeconds || input.MIN_UTTERANCE_SECONDS, '1.0'),
|
|
60
|
-
UTTERANCE_IDLE_MS: clean(input.utteranceIdleMs || input.UTTERANCE_IDLE_MS, '
|
|
60
|
+
UTTERANCE_IDLE_MS: clean(input.utteranceIdleMs || input.UTTERANCE_IDLE_MS, '4500'),
|
|
61
61
|
HERMES_TASK_TIMEOUT_MS: clean(input.taskTimeoutMs || input.HERMES_TASK_TIMEOUT_MS, '0'),
|
|
62
62
|
HERMES_CHAT_TIMEOUT_MS: clean(input.chatTimeoutMs || input.HERMES_CHAT_TIMEOUT_MS, '45000'),
|
|
63
63
|
AGENT_VERBOSE_PROGRESS: input.verboseProgress === true || input.AGENT_VERBOSE_PROGRESS === '1' ? '1' : '0',
|
|
@@ -63,7 +63,7 @@ test('normalizeInstallAnswers maps supported harnesses to backend env', () => {
|
|
|
63
63
|
assert.equal(answers.SUPERTONIC_LANGUAGE, 'ko');
|
|
64
64
|
assert.equal(answers.OPENVOICE_LANGUAGE, 'KR');
|
|
65
65
|
assert.equal(answers.REQUIRE_WAKE_WORD, '0');
|
|
66
|
-
assert.equal(answers.UTTERANCE_IDLE_MS, '
|
|
66
|
+
assert.equal(answers.UTTERANCE_IDLE_MS, '4500');
|
|
67
67
|
});
|
|
68
68
|
|
|
69
69
|
test('buildEnvFile writes configurable CLI harness and Discord settings without comments leaking into values', () => {
|
package/app-node/main.mjs
CHANGED
|
@@ -217,7 +217,10 @@ const BARGE_IN_CONSERVATIVE_MIN_MAX_VOLUME_DB = Number(process.env.BARGE_IN_CONS
|
|
|
217
217
|
const SENSITIVITY_MODE_DEFAULT = (process.env.BARGE_IN_SENSITIVITY_MODE || 'normal').toLowerCase() === 'conservative' ? 'conservative' : 'normal';
|
|
218
218
|
const SENSITIVITY_OUTDOOR_SECONDS = Number(process.env.BARGE_IN_OUTDOOR_SECONDS || '900');
|
|
219
219
|
const SUBSCRIBE_AFTER_SILENCE_MS = Number(process.env.SUBSCRIBE_AFTER_SILENCE_MS || '2200');
|
|
220
|
-
|
|
220
|
+
// Wait long enough for natural mid-sentence pauses before sending audio to STT.
|
|
221
|
+
// If this is too short, a long thought gets split: the first fragment starts an
|
|
222
|
+
// agent turn and the rest is treated as barge-in/processing speech.
|
|
223
|
+
const UTTERANCE_IDLE_MS = Number(process.env.UTTERANCE_IDLE_MS || '4500');
|
|
221
224
|
const MIN_MEAN_VOLUME_DB = Number(process.env.MIN_MEAN_VOLUME_DB || '-35');
|
|
222
225
|
const MIN_MAX_VOLUME_DB = Number(process.env.MIN_MAX_VOLUME_DB || '-12');
|
|
223
226
|
const STT_START_VOICE_NOTICE = !['0', 'false', 'no', 'off'].includes((process.env.STT_START_VOICE_NOTICE || '1').toLowerCase());
|
package/docs/CONFIGURATION.md
CHANGED
|
@@ -37,7 +37,7 @@ AGENT_COMMAND="my-harness run --non-interactive"
|
|
|
37
37
|
AGENT_TASK_TIMEOUT_MS=0
|
|
38
38
|
AGENT_CHAT_TIMEOUT_MS=45000
|
|
39
39
|
AGENT_VERBOSE_PROGRESS=0
|
|
40
|
-
UTTERANCE_IDLE_MS=
|
|
40
|
+
UTTERANCE_IDLE_MS=4500
|
|
41
41
|
LATENCY_LOG_PATH=./.logs/latency.jsonl
|
|
42
42
|
```
|
|
43
43
|
|
|
@@ -66,6 +66,7 @@ WHISPER_CPP_BIN="whisper-cli"
|
|
|
66
66
|
WHISPER_CPP_MODEL="./models/ggml-small-q5_1.bin"
|
|
67
67
|
|
|
68
68
|
TTS_BACKEND="edge"
|
|
69
|
+
TTS_VOICE_TYPE="korean_female"
|
|
69
70
|
TTS_VOICE="ko-KR-SunHiNeural"
|
|
70
71
|
TTS_RATE="+10%"
|
|
71
72
|
TTS_MAX_CHARS="495"
|
|
@@ -73,13 +74,62 @@ TTS_VOLUME="1.0"
|
|
|
73
74
|
|
|
74
75
|
REQUIRE_WAKE_WORD="0"
|
|
75
76
|
MIN_UTTERANCE_SECONDS="1.0"
|
|
76
|
-
UTTERANCE_IDLE_MS="
|
|
77
|
+
UTTERANCE_IDLE_MS="4500"
|
|
77
78
|
HERMES_TASK_TIMEOUT_MS="0"
|
|
78
79
|
HERMES_CHAT_TIMEOUT_MS="45000"
|
|
79
80
|
AGENT_VERBOSE_PROGRESS="0"
|
|
80
81
|
LATENCY_LOG_PATH="./.logs/latency.jsonl"
|
|
81
82
|
```
|
|
82
83
|
|
|
84
|
+
## TTS Voice Selection
|
|
85
|
+
|
|
86
|
+
Language presets and voice selection are separate:
|
|
87
|
+
|
|
88
|
+
- `vc language ko|en|auto` changes STT language, progress language, and the default voice for that language.
|
|
89
|
+
- Live voice commands such as “남자 한국어 목소리로 바꿔”, “여자 한국어 목소리로 바꿔”, `change voice to Korean female`, and `switch speaker to English` change only the speaker/voice type.
|
|
90
|
+
- `!voice-test <text>` plays a quick sample with the currently selected backend and voice.
|
|
91
|
+
|
|
92
|
+
Voice selection is stored in `config/tts-voices.json` by default. Override the path with `TTS_VOICE_CONFIG`. The running bridge re-reads/applies voice selection before synthesis, so voice commands take effect without a full restart.
|
|
93
|
+
|
|
94
|
+
Default Edge catalog:
|
|
95
|
+
|
|
96
|
+
| `TTS_VOICE_TYPE` | `TTS_VOICE` | Language |
|
|
97
|
+
|---|---|---|
|
|
98
|
+
| `korean_male` | `ko-KR-InJoonNeural` | Korean |
|
|
99
|
+
| `korean_female` | `ko-KR-SunHiNeural` | Korean |
|
|
100
|
+
| `korean_multilingual_male` | `ko-KR-HyunsuMultilingualNeural` | Korean |
|
|
101
|
+
| `english_male` | `en-US-GuyNeural` | English |
|
|
102
|
+
| `english_female` | `en-US-AriaNeural` | English |
|
|
103
|
+
|
|
104
|
+
Manual persistent override:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
TTS_BACKEND="edge"
|
|
108
|
+
TTS_VOICE_TYPE="korean_male"
|
|
109
|
+
TTS_VOICE="ko-KR-InJoonNeural"
|
|
110
|
+
TTS_VOICE_CONFIG="config/tts-voices.json"
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
For OpenVoice, SpeechSwift, or Supertonic, keep the backend-specific voice/reference settings in the sections below; the same voice catalog file can still track the active voice type.
|
|
114
|
+
|
|
115
|
+
Backend-specific voice options:
|
|
116
|
+
|
|
117
|
+
| Backend | Settings | Voice choices |
|
|
118
|
+
|---|---|---|
|
|
119
|
+
| Edge | `TTS_VOICE_TYPE`, `TTS_VOICE` | Built-in types above, plus any voice returned by `edge-tts --list-voices` |
|
|
120
|
+
| Supertonic | `SUPERTONIC_VOICE`, `SUPERTONIC_LANGUAGE` | `M1`–`M5`, `F1`–`F5`; language `ko`, `en`, `es`, `pt`, `fr` |
|
|
121
|
+
| OpenVoice | `OPENVOICE_REF_AUDIO`, `OPENVOICE_STYLE`, `OPENVOICE_LANGUAGE` | User-provided permitted reference WAV; style defaults to `default` |
|
|
122
|
+
| SpeechSwift / CosyVoice | `SPEECHSWIFT_REF_AUDIO`, `SPEECHSWIFT_ENGINE`, `SPEECHSWIFT_SPEAKER`, `SPEECHSWIFT_MODEL_ID` | Reference-sample voices for CosyVoice, or backend-supported speaker/model IDs |
|
|
123
|
+
|
|
124
|
+
## Utterance Segmentation
|
|
125
|
+
|
|
126
|
+
`UTTERANCE_IDLE_MS` controls how long the bridge waits after a speech segment before it decides the user is done and starts STT. The default is `4500` ms to preserve longer spoken instructions with natural pauses. Lower values feel faster for short commands but can split long dictation; higher values are safer for thoughtful speech.
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
UTTERANCE_IDLE_MS="4500" # balanced default
|
|
130
|
+
UTTERANCE_IDLE_MS="6000" # safer for long dictation with pauses
|
|
131
|
+
```
|
|
132
|
+
|
|
83
133
|
## MCP Server
|
|
84
134
|
|
|
85
135
|
VerbalCoding ships a stdio MCP server so Hermes Agent or any MCP client can control the bridge through tools instead of relying on skills or free-form shell commands.
|
package/docs/RELEASE.md
CHANGED
|
@@ -25,7 +25,7 @@ VerbalCoding is a Discord voice bridge for controlling CLI-based coding agents b
|
|
|
25
25
|
- npm package install path: `npm install -g verbalcoding`, `vc setup --yes`, and `vc start`.
|
|
26
26
|
- Optional verbose progress mode for text-only middle-step updates during long agent work.
|
|
27
27
|
- Always-on JSONL latency metrics plus `!latency` / `!metrics` summary for pipeline optimization.
|
|
28
|
-
-
|
|
28
|
+
- More patient utterance idle wait (`UTTERANCE_IDLE_MS=4500`) so long spoken instructions with natural pauses are not split into a partial prompt plus ignored processing-time speech.
|
|
29
29
|
- Multi-instance Hermes profile isolation: `vc instance setup <name>` auto-clones a Hermes profile to `~/.hermes/profiles/<name>` with the instance workdir, seeds SOUL.md, and writes `HERMES_HOME` into the instance env so per-project memory and skills stay separate; `vc instance start` self-heals a missing profile, and `vc doctor` checks profile-dir presence and `terminal.cwd` consistency.
|
|
30
30
|
|
|
31
31
|
### Pre-release checklist
|
package/docs/USAGE.md
CHANGED
|
@@ -48,7 +48,7 @@ The bot auto-joins the first configured channel name, defaulting to `일반,Gene
|
|
|
48
48
|
| `!ping` | Basic bot check |
|
|
49
49
|
| `!join` / `!leave` | Join or leave voice |
|
|
50
50
|
| `!say <text>` | Speak text directly through TTS |
|
|
51
|
-
| `!voice-test <text>` | Test the active TTS backend |
|
|
51
|
+
| `!voice-test <text>` | Test the active TTS backend/voice |
|
|
52
52
|
| `!voice-clone capture` | Save the next valid utterance as an OpenVoice reference sample |
|
|
53
53
|
| `!voice-clone status` / `!voice-clone cancel` | Inspect or cancel capture |
|
|
54
54
|
| `!ask <prompt>` | Send text through the same selected harness adapter as voice |
|
|
@@ -63,6 +63,52 @@ The bot auto-joins the first configured channel name, defaulting to `일반,Gene
|
|
|
63
63
|
|
|
64
64
|
Voice equivalents such as “외부 모드”, “보수 모드”, “실내”, “기본 감도”, and clear stop phrases like “잠깐”, “멈춰”, “그만” are handled by the bridge. You can also say “상세 진행 켜” / “상세 진행 꺼” to toggle verbose progress by voice.
|
|
65
65
|
|
|
66
|
+
## Changing the Voice
|
|
67
|
+
|
|
68
|
+
`vc language ko|en|auto` changes STT language, progress language, and the matching default TTS voice together. If you only want to change the speaker/voice while the bridge is running, say it in Discord voice:
|
|
69
|
+
|
|
70
|
+
```text
|
|
71
|
+
남자 한국어 목소리로 바꿔
|
|
72
|
+
여자 한국어 목소리로 바꿔
|
|
73
|
+
change voice to Korean female
|
|
74
|
+
switch speaker to English
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The live bridge recognizes these as voice-control commands, updates `config/tts-voices.json`, updates the effective TTS env for the running process, and answers with a short confirmation such as “목소리를 Korean male로 바꿨어.” Use `!voice-test <text>` right after changing it to hear the current backend and voice.
|
|
78
|
+
|
|
79
|
+
Built-in Edge voice types:
|
|
80
|
+
|
|
81
|
+
| Voice type | Edge voice |
|
|
82
|
+
|---|---|
|
|
83
|
+
| `korean_male` | `ko-KR-InJoonNeural` |
|
|
84
|
+
| `korean_female` | `ko-KR-SunHiNeural` |
|
|
85
|
+
| `korean_multilingual_male` | `ko-KR-HyunsuMultilingualNeural` |
|
|
86
|
+
| `english_male` | `en-US-GuyNeural` |
|
|
87
|
+
| `english_female` | `en-US-AriaNeural` |
|
|
88
|
+
|
|
89
|
+
For persistent manual config, set `TTS_BACKEND=edge`, `TTS_VOICE_TYPE=<voice-type>`, and optionally `TTS_VOICE=<edge-voice>` in `.env`, or edit `config/tts-voices.json` for custom voice catalogs.
|
|
90
|
+
|
|
91
|
+
Backend-specific voice knobs:
|
|
92
|
+
|
|
93
|
+
| Backend | Voice setting | Common choices |
|
|
94
|
+
|---|---|---|
|
|
95
|
+
| Edge | `TTS_VOICE_TYPE`, `TTS_VOICE` | `korean_male`, `korean_female`, `korean_multilingual_male`, `english_male`, `english_female`; any Edge voice from `edge-tts --list-voices` |
|
|
96
|
+
| Supertonic | `SUPERTONIC_VOICE` | `M1`–`M5`, `F1`–`F5`; set `SUPERTONIC_LANGUAGE=ko|en|es|pt|fr` |
|
|
97
|
+
| OpenVoice | `OPENVOICE_REF_AUDIO`, `OPENVOICE_STYLE` | a permitted reference WAV plus style such as `default` |
|
|
98
|
+
| SpeechSwift / CosyVoice | `SPEECHSWIFT_REF_AUDIO`, `SPEECHSWIFT_ENGINE`, `SPEECHSWIFT_SPEAKER` | reference WAV for CosyVoice, or backend-supported speaker/model values |
|
|
99
|
+
|
|
100
|
+
For Supertonic and local clone backends, use the backend env vars above plus `!voice-test <text>` to audition changes. Voice-command switching currently maps the built-in Edge-style voice types; richer backend catalogs can be added in `config/tts-voices.json`.
|
|
101
|
+
|
|
102
|
+
## Long Dictation and Pauses
|
|
103
|
+
|
|
104
|
+
VerbalCoding waits for an idle window before sending speech to STT. The default `UTTERANCE_IDLE_MS=4500` is intentionally a bit patient so a natural pause in a long instruction does not split the sentence, start an agent turn too early, and then treat the rest as a processing-time interruption.
|
|
105
|
+
|
|
106
|
+
If you prefer faster short commands, lower it in `.env`; if long Korean dictation is still being split, raise it:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
UTTERANCE_IDLE_MS="6000"
|
|
110
|
+
```
|
|
111
|
+
|
|
66
112
|
## Verbose Progress Mode
|
|
67
113
|
|
|
68
114
|
Verbose progress is off by default unless `AGENT_VERBOSE_PROGRESS=1` is set. Enable it with `!verbose on` or a voice command like “상세 진행 켜”. It can emit short progress lines such as:
|
|
@@ -45,7 +45,7 @@ AGENT_COMMAND="my-harness run --non-interactive"
|
|
|
45
45
|
AGENT_TASK_TIMEOUT_MS=0
|
|
46
46
|
AGENT_CHAT_TIMEOUT_MS=45000
|
|
47
47
|
AGENT_VERBOSE_PROGRESS=0
|
|
48
|
-
UTTERANCE_IDLE_MS=
|
|
48
|
+
UTTERANCE_IDLE_MS=4500
|
|
49
49
|
LATENCY_LOG_PATH=./.logs/latency.jsonl
|
|
50
50
|
```
|
|
51
51
|
|
|
@@ -74,6 +74,7 @@ WHISPER_CPP_BIN="whisper-cli"
|
|
|
74
74
|
WHISPER_CPP_MODEL="./models/ggml-small-q5_1.bin"
|
|
75
75
|
|
|
76
76
|
TTS_BACKEND="edge"
|
|
77
|
+
TTS_VOICE_TYPE="korean_female"
|
|
77
78
|
TTS_VOICE="ko-KR-SunHiNeural"
|
|
78
79
|
TTS_RATE="+10%"
|
|
79
80
|
TTS_MAX_CHARS="495"
|
|
@@ -81,13 +82,62 @@ TTS_VOLUME="1.0"
|
|
|
81
82
|
|
|
82
83
|
REQUIRE_WAKE_WORD="0"
|
|
83
84
|
MIN_UTTERANCE_SECONDS="1.0"
|
|
84
|
-
UTTERANCE_IDLE_MS="
|
|
85
|
+
UTTERANCE_IDLE_MS="4500"
|
|
85
86
|
HERMES_TASK_TIMEOUT_MS="0"
|
|
86
87
|
HERMES_CHAT_TIMEOUT_MS="45000"
|
|
87
88
|
AGENT_VERBOSE_PROGRESS="0"
|
|
88
89
|
LATENCY_LOG_PATH="./.logs/latency.jsonl"
|
|
89
90
|
```
|
|
90
91
|
|
|
92
|
+
## TTS 목소리 선택
|
|
93
|
+
|
|
94
|
+
언어 프리셋과 목소리 선택은 분리되어 있습니다.
|
|
95
|
+
|
|
96
|
+
- `vc language ko|en|auto`는 STT 언어, 진행 언어, 해당 언어의 기본 목소리를 함께 바꿉니다.
|
|
97
|
+
- “남자 한국어 목소리로 바꿔”, “여자 한국어 목소리로 바꿔”, `change voice to Korean female`, `switch speaker to English` 같은 실시간 음성 명령은 말하는 사람/목소리 타입만 바꿉니다.
|
|
98
|
+
- `!voice-test <text>`는 현재 선택된 백엔드와 목소리로 짧은 샘플을 재생합니다.
|
|
99
|
+
|
|
100
|
+
목소리 선택은 기본적으로 `config/tts-voices.json`에 저장됩니다. 경로는 `TTS_VOICE_CONFIG`로 바꿀 수 있습니다. 실행 중인 브릿지는 합성 직전에 목소리 선택을 다시 적용하므로, 음성 명령으로 바꾼 목소리는 전체 재시작 없이 바로 반영됩니다.
|
|
101
|
+
|
|
102
|
+
기본 Edge 카탈로그:
|
|
103
|
+
|
|
104
|
+
| `TTS_VOICE_TYPE` | `TTS_VOICE` | 언어 |
|
|
105
|
+
|---|---|---|
|
|
106
|
+
| `korean_male` | `ko-KR-InJoonNeural` | 한국어 |
|
|
107
|
+
| `korean_female` | `ko-KR-SunHiNeural` | 한국어 |
|
|
108
|
+
| `korean_multilingual_male` | `ko-KR-HyunsuMultilingualNeural` | 한국어 |
|
|
109
|
+
| `english_male` | `en-US-GuyNeural` | 영어 |
|
|
110
|
+
| `english_female` | `en-US-AriaNeural` | 영어 |
|
|
111
|
+
|
|
112
|
+
수동 영구 override 예시:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
TTS_BACKEND="edge"
|
|
116
|
+
TTS_VOICE_TYPE="korean_male"
|
|
117
|
+
TTS_VOICE="ko-KR-InJoonNeural"
|
|
118
|
+
TTS_VOICE_CONFIG="config/tts-voices.json"
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
OpenVoice, SpeechSwift, Supertonic을 쓸 때는 아래 백엔드별 reference/voice 설정을 유지하세요. 같은 voice catalog 파일에서 현재 voice type을 추적할 수 있습니다.
|
|
122
|
+
|
|
123
|
+
백엔드별 목소리 옵션:
|
|
124
|
+
|
|
125
|
+
| 백엔드 | 설정 | 목소리 선택지 |
|
|
126
|
+
|---|---|---|
|
|
127
|
+
| Edge | `TTS_VOICE_TYPE`, `TTS_VOICE` | 위 기본 타입, 또는 `edge-tts --list-voices`가 반환하는 모든 voice |
|
|
128
|
+
| Supertonic | `SUPERTONIC_VOICE`, `SUPERTONIC_LANGUAGE` | `M1`–`M5`, `F1`–`F5`; 언어 `ko`, `en`, `es`, `pt`, `fr` |
|
|
129
|
+
| OpenVoice | `OPENVOICE_REF_AUDIO`, `OPENVOICE_STYLE`, `OPENVOICE_LANGUAGE` | 사용자가 제공한 허가된 reference WAV; style 기본값은 `default` |
|
|
130
|
+
| SpeechSwift / CosyVoice | `SPEECHSWIFT_REF_AUDIO`, `SPEECHSWIFT_ENGINE`, `SPEECHSWIFT_SPEAKER`, `SPEECHSWIFT_MODEL_ID` | CosyVoice reference sample voice 또는 백엔드가 지원하는 speaker/model ID |
|
|
131
|
+
|
|
132
|
+
## 발화 분리 설정
|
|
133
|
+
|
|
134
|
+
`UTTERANCE_IDLE_MS`는 음성 segment가 끝난 뒤 사용자의 말이 끝났다고 판단하고 STT를 시작하기 전까지 기다리는 시간입니다. 기본값은 `4500` ms입니다. 긴 지시 중 자연스러운 멈춤을 보존하기 위한 값입니다. 낮추면 짧은 명령 반응은 빨라지지만 긴 발화가 잘릴 수 있고, 높이면 생각하면서 말하는 긴 dictation에 더 안전합니다.
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
UTTERANCE_IDLE_MS="4500" # 균형 잡힌 기본값
|
|
138
|
+
UTTERANCE_IDLE_MS="6000" # 중간 멈춤이 있는 긴 발화에 더 안전
|
|
139
|
+
```
|
|
140
|
+
|
|
91
141
|
## MCP 서버
|
|
92
142
|
|
|
93
143
|
VerbalCoding은 stdio MCP 서버를 포함합니다. Hermes Agent 또는 MCP client는 자유 형식 shell 명령 대신 도구로 브릿지를 제어할 수 있습니다.
|
package/docs/i18n/RELEASE.ko.md
CHANGED
|
@@ -24,7 +24,7 @@ VerbalCoding은 음성으로 CLI 기반 코딩 에이전트를 제어하기 위
|
|
|
24
24
|
- 설정 마법사, `.env.example`, `vc doctor` prerequisite checker, OS 패키지/npm 의존성/Edge TTS helper/기본 whisper.cpp 모델을 준비하는 `./scripts/install.sh --yes` 부트스트랩.
|
|
25
25
|
- 긴 에이전트 작업 중 텍스트 전용 중간 단계 업데이트를 위한 선택적 verbose progress mode.
|
|
26
26
|
- 파이프라인 최적화를 위한 JSONL latency metrics와 `!latency` / `!metrics` 요약.
|
|
27
|
-
-
|
|
27
|
+
- 더 여유 있는 utterance idle wait (`UTTERANCE_IDLE_MS=4500`)로 자연스러운 중간 멈춤이 있는 긴 지시가 앞부분 prompt와 무시되는 processing-time speech로 쪼개지지 않도록 개선.
|
|
28
28
|
- 멀티 인스턴스 Hermes 프로필 격리: `vc instance setup <name>`이 자동으로 Hermes 프로필을 `~/.hermes/profiles/<name>`에 clone하고, instance workdir을 설정하고, SOUL.md를 초기화하고, instance env에 `HERMES_HOME`을 기록합니다. `vc instance start`는 누락된 profile을 self-heal하고, `vc doctor`는 profile-dir 존재와 `terminal.cwd` 일관성을 검사합니다.
|
|
29
29
|
- npm 공개 패키지: `npm install -g verbalcoding`, `vc setup --yes`, `vc start` 경로 지원.
|
|
30
30
|
|
package/docs/i18n/USAGE.ko.md
CHANGED
|
@@ -56,7 +56,7 @@ VERBALCODING_INSTANCE_ENV=instances/my-project.env ./run.sh
|
|
|
56
56
|
| `!ping` | 봇 연결 기본 확인 |
|
|
57
57
|
| `!join` / `!leave` | 음성 채널 입장/퇴장 |
|
|
58
58
|
| `!say <text>` | 텍스트를 바로 TTS로 읽기 |
|
|
59
|
-
| `!voice-test <text>` | 현재 TTS
|
|
59
|
+
| `!voice-test <text>` | 현재 TTS 백엔드/목소리 테스트 |
|
|
60
60
|
| `!voice-clone capture` | 다음 유효 발화를 OpenVoice 기준 샘플로 저장 |
|
|
61
61
|
| `!voice-clone status` / `!voice-clone cancel` | 샘플 캡처 상태 확인/취소 |
|
|
62
62
|
| `!ask <prompt>` | 음성과 같은 선택된 CLI 어댑터로 텍스트 요청 보내기 |
|
|
@@ -71,6 +71,52 @@ VERBALCODING_INSTANCE_ENV=instances/my-project.env ./run.sh
|
|
|
71
71
|
|
|
72
72
|
음성으로도 “외부 모드”, “보수 모드”, “실내”, “기본 감도” 같은 감도 전환과 “잠깐”, “멈춰”, “그만” 같은 명확한 중단 표현을 처리합니다. “상세 진행 켜” / “상세 진행 꺼”처럼 말해서 verbose progress도 바꿀 수 있습니다.
|
|
73
73
|
|
|
74
|
+
## 목소리 변경
|
|
75
|
+
|
|
76
|
+
`vc language ko|en|auto`는 STT 언어, 진행 언어, 기본 TTS 목소리를 함께 바꿉니다. 언어 전체가 아니라 말하는 사람/목소리만 바꾸고 싶다면 Discord 음성에서 이렇게 말하면 됩니다.
|
|
77
|
+
|
|
78
|
+
```text
|
|
79
|
+
남자 한국어 목소리로 바꿔
|
|
80
|
+
여자 한국어 목소리로 바꿔
|
|
81
|
+
change voice to Korean female
|
|
82
|
+
switch speaker to English
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
실행 중인 브릿지는 이 발화를 제어 명령으로 인식해 `config/tts-voices.json`을 갱신하고, 현재 프로세스의 TTS 설정도 바로 바꾼 뒤 “목소리를 Korean male로 바꿨어.” 같은 짧은 확인을 말합니다. 바꾼 직후에는 `!voice-test <text>`로 현재 백엔드와 목소리를 바로 들어볼 수 있습니다.
|
|
86
|
+
|
|
87
|
+
기본 Edge 목소리 타입:
|
|
88
|
+
|
|
89
|
+
| 목소리 타입 | Edge voice |
|
|
90
|
+
|---|---|
|
|
91
|
+
| `korean_male` | `ko-KR-InJoonNeural` |
|
|
92
|
+
| `korean_female` | `ko-KR-SunHiNeural` |
|
|
93
|
+
| `korean_multilingual_male` | `ko-KR-HyunsuMultilingualNeural` |
|
|
94
|
+
| `english_male` | `en-US-GuyNeural` |
|
|
95
|
+
| `english_female` | `en-US-AriaNeural` |
|
|
96
|
+
|
|
97
|
+
영구 수동 설정이 필요하면 `.env`에 `TTS_BACKEND=edge`, `TTS_VOICE_TYPE=<voice-type>`, 필요 시 `TTS_VOICE=<edge-voice>`를 설정하세요. 더 많은 커스텀 목소리 카탈로그는 `config/tts-voices.json`에서 관리할 수 있습니다.
|
|
98
|
+
|
|
99
|
+
백엔드별 목소리 설정:
|
|
100
|
+
|
|
101
|
+
| 백엔드 | 목소리 설정 | 자주 쓰는 선택지 |
|
|
102
|
+
|---|---|---|
|
|
103
|
+
| Edge | `TTS_VOICE_TYPE`, `TTS_VOICE` | `korean_male`, `korean_female`, `korean_multilingual_male`, `english_male`, `english_female`; `edge-tts --list-voices`의 모든 Edge voice |
|
|
104
|
+
| Supertonic | `SUPERTONIC_VOICE` | `M1`–`M5`, `F1`–`F5`; `SUPERTONIC_LANGUAGE=ko|en|es|pt|fr` |
|
|
105
|
+
| OpenVoice | `OPENVOICE_REF_AUDIO`, `OPENVOICE_STYLE` | 사용 허가가 있는 reference WAV와 `default` 같은 style |
|
|
106
|
+
| SpeechSwift / CosyVoice | `SPEECHSWIFT_REF_AUDIO`, `SPEECHSWIFT_ENGINE`, `SPEECHSWIFT_SPEAKER` | CosyVoice reference WAV 또는 백엔드가 지원하는 speaker/model 값 |
|
|
107
|
+
|
|
108
|
+
Supertonic과 로컬 clone 백엔드는 위 env를 바꾼 뒤 `!voice-test <text>`로 바로 들어보세요. 현재 음성 명령 기반 전환은 기본 Edge-style voice type에 매핑되어 있고, 더 풍부한 백엔드 카탈로그는 `config/tts-voices.json`에 추가할 수 있습니다.
|
|
109
|
+
|
|
110
|
+
## 긴 발화와 중간 멈춤
|
|
111
|
+
|
|
112
|
+
VerbalCoding은 말을 STT로 보내기 전에 idle window를 기다립니다. 기본값 `UTTERANCE_IDLE_MS=4500`은 일부러 조금 여유 있게 잡혀 있습니다. 긴 지시 중 자연스러운 멈춤을 문장 끝으로 오해해 앞부분만 에이전트에 보내고, 뒷부분을 processing 중 끼어들기로 처리하는 문제를 줄이기 위해서입니다.
|
|
113
|
+
|
|
114
|
+
짧은 명령 반응을 더 빠르게 하고 싶다면 `.env`에서 낮추고, 긴 한국어 dictation이 여전히 잘리면 더 올리세요.
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
UTTERANCE_IDLE_MS="6000"
|
|
118
|
+
```
|
|
119
|
+
|
|
74
120
|
## 자세한 진행 모드
|
|
75
121
|
|
|
76
122
|
자세한 진행은 기본적으로 꺼져 있습니다. `.env`에 `AGENT_VERBOSE_PROGRESS=1`을 설정하거나 Discord에서 `!verbose on`, 또는 음성으로 “상세 진행 켜”라고 말해 켤 수 있습니다.
|
package/package.json
CHANGED
package/run.sh
CHANGED
|
@@ -8,7 +8,7 @@ mkdir -p /tmp/verbalcoding-node-debug
|
|
|
8
8
|
export NODE_AUDIO_DEBUG_DIR="${NODE_AUDIO_DEBUG_DIR:-/tmp/verbalcoding-node-debug}"
|
|
9
9
|
export MIN_UTTERANCE_SECONDS="${MIN_UTTERANCE_SECONDS:-1.0}"
|
|
10
10
|
export SUBSCRIBE_AFTER_SILENCE_MS="${SUBSCRIBE_AFTER_SILENCE_MS:-2200}"
|
|
11
|
-
export UTTERANCE_IDLE_MS="${UTTERANCE_IDLE_MS:-
|
|
11
|
+
export UTTERANCE_IDLE_MS="${UTTERANCE_IDLE_MS:-4500}"
|
|
12
12
|
export MIN_MEAN_VOLUME_DB="${MIN_MEAN_VOLUME_DB:--35}"
|
|
13
13
|
export MIN_MAX_VOLUME_DB="${MIN_MAX_VOLUME_DB:--18}"
|
|
14
14
|
export TTS_RATE="${TTS_RATE:-+10%}"
|
package/scripts/doctor.mjs
CHANGED
|
@@ -66,7 +66,7 @@ note('Allowed users configured', env.DISCORD_ALLOWED_USERS ? '[REDACTED]' : 'not
|
|
|
66
66
|
note('Auto-join channels', env.AUTO_JOIN_VOICE_CHANNELS || 'default: 일반,General,general');
|
|
67
67
|
note('Verbose progress default', ['1', 'true', 'yes', 'on'].includes(String(env.AGENT_VERBOSE_PROGRESS || env.VERBALCODING_VERBOSE_PROGRESS || '0').toLowerCase()) ? 'on' : 'off');
|
|
68
68
|
note('Auto restart voice bot after commits', autoRestartVoiceBotEnabled(env) ? 'on' : 'off');
|
|
69
|
-
note('Utterance idle wait before STT', `${env.UTTERANCE_IDLE_MS || '
|
|
69
|
+
note('Utterance idle wait before STT', `${env.UTTERANCE_IDLE_MS || '4500'} ms`);
|
|
70
70
|
note('STT language', env.WHISPER_CPP_LANGUAGE || env.STT_LANGUAGE || 'ko');
|
|
71
71
|
note('Progress/voice language', env.VOICE_LANGUAGE || env.WHISPER_CPP_LANGUAGE || env.STT_LANGUAGE || 'ko');
|
|
72
72
|
note('Latency log path', env.LATENCY_LOG_PATH || './.logs/latency.jsonl');
|
package/scripts/install.mjs
CHANGED
|
@@ -58,7 +58,7 @@ async function main() {
|
|
|
58
58
|
const openvoiceRefAudio = await ask('OpenVoice reference audio path', process.env.OPENVOICE_REF_AUDIO || './voice-samples/user-reference.wav');
|
|
59
59
|
const requireWake = (await ask('Require wake word? 1/0', process.env.REQUIRE_WAKE_WORD || '0')) === '1';
|
|
60
60
|
const verboseProgress = (await ask('Verbose progress by default? 1/0', process.env.AGENT_VERBOSE_PROGRESS || process.env.VERBALCODING_VERBOSE_PROGRESS || '0')) === '1';
|
|
61
|
-
const utteranceIdleMs = await ask('Utterance idle wait before STT, ms', process.env.UTTERANCE_IDLE_MS || '
|
|
61
|
+
const utteranceIdleMs = await ask('Utterance idle wait before STT, ms', process.env.UTTERANCE_IDLE_MS || '4500');
|
|
62
62
|
const latencyLogPath = await ask('Latency JSONL log path', process.env.LATENCY_LOG_PATH || './.logs/latency.jsonl');
|
|
63
63
|
|
|
64
64
|
const values = normalizeInstallAnswers({
|