@vxnus/siduri 0.1.8 → 0.1.11
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/README.md +3 -4
- package/dist/builtin-manifests.d.ts +2 -0
- package/dist/builtin-manifests.js +492 -0
- package/dist/clean-machine-e2e.test.d.ts +1 -0
- package/dist/clean-machine-e2e.test.js +236 -0
- package/dist/configurators/behavior.d.ts +2 -0
- package/dist/configurators/behavior.js +36 -0
- package/dist/configurators/body.d.ts +2 -0
- package/dist/configurators/body.js +60 -0
- package/dist/configurators/brain.d.ts +6 -0
- package/dist/configurators/brain.js +80 -0
- package/dist/configurators/ear.d.ts +2 -0
- package/dist/configurators/ear.js +28 -0
- package/dist/configurators/hands.d.ts +2 -0
- package/dist/configurators/hands.js +27 -0
- package/dist/configurators/index.d.ts +24 -0
- package/dist/configurators/index.js +78 -0
- package/dist/configurators/knowledge.d.ts +6 -0
- package/dist/configurators/knowledge.js +100 -0
- package/dist/configurators/memory.d.ts +2 -0
- package/dist/configurators/memory.js +44 -0
- package/dist/configurators/mouth.d.ts +2 -0
- package/dist/configurators/mouth.js +15 -0
- package/dist/configurators/observation.d.ts +2 -0
- package/dist/configurators/observation.js +12 -0
- package/dist/configurators/types.d.ts +12 -0
- package/dist/configurators/types.js +2 -0
- package/dist/configurators/vision.d.ts +2 -0
- package/dist/configurators/vision.js +39 -0
- package/dist/configurators/voice.d.ts +2 -0
- package/dist/configurators/voice.js +477 -0
- package/dist/configurators.test.d.ts +1 -0
- package/dist/configurators.test.js +331 -0
- package/dist/db.d.ts +25 -0
- package/dist/db.js +152 -0
- package/dist/discovery.d.ts +13 -0
- package/dist/discovery.js +87 -0
- package/dist/discovery.test.d.ts +1 -0
- package/dist/discovery.test.js +69 -0
- package/dist/doctor-db.test.d.ts +1 -0
- package/dist/doctor-db.test.js +141 -0
- package/dist/doctor.d.ts +19 -0
- package/dist/doctor.js +249 -0
- package/dist/generator.d.ts +20 -0
- package/dist/generator.js +615 -0
- package/dist/generator.test.d.ts +1 -0
- package/dist/generator.test.js +197 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +395 -0
- package/dist/manifest.d.ts +33 -0
- package/dist/manifest.js +40 -0
- package/dist/providers/knowledge-hub.d.ts +37 -0
- package/dist/providers/knowledge-hub.js +141 -0
- package/dist/providers/openrouter.d.ts +32 -0
- package/dist/providers/openrouter.js +201 -0
- package/dist/release-check.d.ts +9 -0
- package/dist/release-check.js +133 -0
- package/dist/runtime-parity.test.d.ts +1 -0
- package/dist/runtime-parity.test.js +141 -0
- package/dist/schema-validator.d.ts +9 -0
- package/dist/schema-validator.js +107 -0
- package/dist/web-dist/404/index.html +1 -0
- package/dist/web-dist/404.html +1 -0
- package/dist/web-dist/__next.__PAGE__.txt +35 -0
- package/dist/web-dist/__next._full.txt +32 -0
- package/dist/web-dist/__next._tree.txt +4 -0
- package/dist/web-dist/_next/static/chunks/09y7khbmco_v4.js +1 -0
- package/dist/web-dist/_next/static/chunks/0cz1d0mv5g_q7.js +1 -0
- package/dist/web-dist/_next/static/chunks/0uwih7sydv413.js +1 -0
- package/dist/web-dist/_next/static/chunks/0xhe1hasjan-9.css +1 -0
- package/dist/web-dist/_next/static/chunks/1_yae15ffa5f6.js +1 -0
- package/dist/web-dist/_next/static/chunks/2_duynll0m51m.js +30 -0
- package/dist/web-dist/_next/static/chunks/2kcqevsmv6kh2.js +31 -0
- package/dist/web-dist/_next/static/chunks/2s3d1bfr0l4b0.js +1 -0
- package/dist/web-dist/_next/static/chunks/32z87id9k6i2z.js +22 -0
- package/dist/web-dist/_next/static/chunks/3bx2gs3idjmo1.js +1 -0
- package/dist/web-dist/_next/static/chunks/turbopack-3eipe4c-imn5l.js +1 -0
- package/dist/web-dist/_next/static/media/apple-icon.2g7-yefdphkmy.png +0 -0
- package/dist/web-dist/_next/static/media/favicon.3rlors1ui1gw9.ico +0 -0
- package/dist/web-dist/_next/static/media/icon.0580nb9h-ugue.svg +4 -0
- package/dist/web-dist/_next/static/pWHUixFDDvANZeAf-shqT/_buildManifest.js +11 -0
- package/dist/web-dist/_next/static/pWHUixFDDvANZeAf-shqT/_clientMiddlewareManifest.js +1 -0
- package/dist/web-dist/_next/static/pWHUixFDDvANZeAf-shqT/_ssgManifest.js +1 -0
- package/dist/web-dist/_not-found/__next._full.txt +17 -0
- package/dist/web-dist/_not-found/__next._not-found.__PAGE__.txt +23 -0
- package/dist/web-dist/_not-found/__next._tree.txt +3 -0
- package/dist/web-dist/_not-found/index.html +1 -0
- package/dist/web-dist/_not-found/index.txt +17 -0
- package/dist/web-dist/apple-icon.png +0 -0
- package/dist/web-dist/apple-touch-icon.png +0 -0
- package/dist/web-dist/chat/__next._full.txt +18 -0
- package/dist/web-dist/chat/__next._tree.txt +3 -0
- package/dist/web-dist/chat/__next.chat.__PAGE__.txt +24 -0
- package/dist/web-dist/chat/index.html +1 -0
- package/dist/web-dist/chat/index.txt +18 -0
- package/dist/web-dist/favicon.ico +0 -0
- package/dist/web-dist/favicon.svg +4 -0
- package/dist/web-dist/icon.svg +4 -0
- package/dist/web-dist/index.html +1 -0
- package/dist/web-dist/index.txt +32 -0
- package/dist/web-dist/live2d/live2dcubismcore.min.js +9 -0
- package/dist/web-dist/logo-circle.png +0 -0
- package/dist/web-dist/logo-circle.svg +4 -0
- package/dist/web-dist/logo-white.svg +3 -0
- package/dist/web-dist/logo.png +0 -0
- package/dist/web-dist/logo.svg +3 -0
- package/dist/web-dist/operator/__next._full.txt +18 -0
- package/dist/web-dist/operator/__next._tree.txt +3 -0
- package/dist/web-dist/operator/__next.operator.__PAGE__.txt +24 -0
- package/dist/web-dist/operator/index.html +1 -0
- package/dist/web-dist/operator/index.txt +18 -0
- package/dist/web-template.d.ts +2 -0
- package/dist/web-template.js +557 -0
- package/package.json +1 -1
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.configureVoice = configureVoice;
|
|
7
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
8
|
+
async function configureVoice(_context) {
|
|
9
|
+
const companionSlug = _context.companionName.toLowerCase().replace(/[^a-z0-9_-]/g, '') || 'default';
|
|
10
|
+
const { provider } = await inquirer_1.default.prompt({
|
|
11
|
+
type: 'list',
|
|
12
|
+
name: 'provider',
|
|
13
|
+
message: 'Voice provider?',
|
|
14
|
+
choices: [
|
|
15
|
+
{
|
|
16
|
+
name: 'Edge-TTS (Zero-setup cloud TTS, no downloads/no Python required)',
|
|
17
|
+
value: 'edge-tts',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: 'VOICEVOX (Standard VOICEVOX stock character voice banks)',
|
|
21
|
+
value: 'voicevox',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: 'Kokoro TTS (Fast lightweight neural TTS via HTTP/CLI)',
|
|
25
|
+
value: 'kokoro',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: 'Piper TTS (Fast local neural TTS via HTTP/CLI)',
|
|
29
|
+
value: 'piper',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: 'RVC (Custom user-owned voice model via .pth / .index weights)',
|
|
33
|
+
value: 'rvc',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: 'None (Disable voice synthesis)',
|
|
37
|
+
value: 'none',
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
});
|
|
41
|
+
if (provider === 'none') {
|
|
42
|
+
return {
|
|
43
|
+
config: { provider: 'none' },
|
|
44
|
+
summary: { Provider: 'None (Voice disabled)' },
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
if (provider === 'edge-tts') {
|
|
48
|
+
const edgeAnswers = await inquirer_1.default.prompt([
|
|
49
|
+
{
|
|
50
|
+
type: 'input',
|
|
51
|
+
name: 'voice',
|
|
52
|
+
message: 'Edge-TTS Voice Identifier (e.g. ja-JP-NanamiNeural, en-US-AriaNeural):',
|
|
53
|
+
default: 'ja-JP-NanamiNeural',
|
|
54
|
+
},
|
|
55
|
+
]);
|
|
56
|
+
const voice = edgeAnswers.voice.trim() || 'ja-JP-NanamiNeural';
|
|
57
|
+
return {
|
|
58
|
+
config: {
|
|
59
|
+
provider: 'edge-tts',
|
|
60
|
+
voice,
|
|
61
|
+
maxQueueDepth: 50,
|
|
62
|
+
},
|
|
63
|
+
summary: {
|
|
64
|
+
Provider: 'Edge-TTS (Cloud Neural)',
|
|
65
|
+
Voice: voice,
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
if (provider === 'kokoro') {
|
|
70
|
+
const kokoroAnswers = await inquirer_1.default.prompt([
|
|
71
|
+
{
|
|
72
|
+
type: 'input',
|
|
73
|
+
name: 'baseUrl',
|
|
74
|
+
message: 'Kokoro HTTP Base URL (leave empty if using local kokoro-tts CLI):',
|
|
75
|
+
default: 'http://localhost:8880',
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
type: 'input',
|
|
79
|
+
name: 'voice',
|
|
80
|
+
message: 'Kokoro Voice Name (e.g. af_bella, af_heart):',
|
|
81
|
+
default: 'af_bella',
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
type: 'input',
|
|
85
|
+
name: 'speed',
|
|
86
|
+
message: 'Speech Speed multiplier (e.g. 1.0):',
|
|
87
|
+
default: '1.0',
|
|
88
|
+
},
|
|
89
|
+
]);
|
|
90
|
+
const baseUrl = kokoroAnswers.baseUrl.trim() || undefined;
|
|
91
|
+
const voice = kokoroAnswers.voice.trim() || 'af_bella';
|
|
92
|
+
const speed = parseFloat(kokoroAnswers.speed) || 1.0;
|
|
93
|
+
return {
|
|
94
|
+
config: {
|
|
95
|
+
provider: 'kokoro',
|
|
96
|
+
baseUrl,
|
|
97
|
+
voice,
|
|
98
|
+
speed,
|
|
99
|
+
maxQueueDepth: 50,
|
|
100
|
+
},
|
|
101
|
+
summary: {
|
|
102
|
+
Provider: 'Kokoro TTS (Local / Server)',
|
|
103
|
+
Mode: baseUrl ? `HTTP (${baseUrl})` : 'CLI (kokoro-tts)',
|
|
104
|
+
Voice: voice,
|
|
105
|
+
Speed: speed,
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
if (provider === 'piper') {
|
|
110
|
+
const piperAnswers = await inquirer_1.default.prompt([
|
|
111
|
+
{
|
|
112
|
+
type: 'input',
|
|
113
|
+
name: 'baseUrl',
|
|
114
|
+
message: 'Piper HTTP Base URL (leave empty if using local piper CLI):',
|
|
115
|
+
default: 'http://localhost:5000',
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
type: 'input',
|
|
119
|
+
name: 'model',
|
|
120
|
+
message: 'Piper Model Path or Name (.onnx, optional):',
|
|
121
|
+
default: '',
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
type: 'input',
|
|
125
|
+
name: 'speakerId',
|
|
126
|
+
message: 'Piper Speaker ID (optional):',
|
|
127
|
+
default: '',
|
|
128
|
+
},
|
|
129
|
+
]);
|
|
130
|
+
const baseUrl = piperAnswers.baseUrl.trim() || undefined;
|
|
131
|
+
const model = piperAnswers.model.trim() || undefined;
|
|
132
|
+
const speakerId = piperAnswers.speakerId.trim() ? parseInt(piperAnswers.speakerId.trim(), 10) : undefined;
|
|
133
|
+
return {
|
|
134
|
+
config: {
|
|
135
|
+
provider: 'piper',
|
|
136
|
+
baseUrl,
|
|
137
|
+
model,
|
|
138
|
+
speakerId,
|
|
139
|
+
maxQueueDepth: 50,
|
|
140
|
+
},
|
|
141
|
+
summary: {
|
|
142
|
+
Provider: 'Piper TTS (Local / Server)',
|
|
143
|
+
Mode: baseUrl ? `HTTP (${baseUrl})` : 'CLI (piper)',
|
|
144
|
+
Model: model || 'default',
|
|
145
|
+
'Speaker ID': speakerId !== undefined ? speakerId : 'default',
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
if (provider === 'rvc') {
|
|
150
|
+
const rvcAnswers = await inquirer_1.default.prompt([
|
|
151
|
+
{
|
|
152
|
+
type: 'input',
|
|
153
|
+
name: 'modelPath',
|
|
154
|
+
message: 'RVC Model Path (.pth weights):',
|
|
155
|
+
default: `./assets/voice/${companionSlug}/${companionSlug}.pth`,
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
type: 'input',
|
|
159
|
+
name: 'indexPath',
|
|
160
|
+
message: 'RVC Feature Index Path (.index, optional):',
|
|
161
|
+
default: `./assets/voice/${companionSlug}/${companionSlug}.index`,
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
type: 'input',
|
|
165
|
+
name: 'pitchShift',
|
|
166
|
+
message: 'Pitch Shift (semitones, e.g. 0 for neutral, 12 for male-to-female, -12 for female-to-male):',
|
|
167
|
+
default: '0',
|
|
168
|
+
validate: (v) => !isNaN(parseInt(v, 10)) || 'Pitch shift must be an integer.',
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
type: 'list',
|
|
172
|
+
name: 'f0Method',
|
|
173
|
+
message: 'Pitch Extraction Algorithm (F0 Method):',
|
|
174
|
+
choices: ['rmvpe', 'pm', 'harvest', 'crepe'],
|
|
175
|
+
default: 'rmvpe',
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
type: 'list',
|
|
179
|
+
name: 'baseTts',
|
|
180
|
+
message: 'Base TTS Engine for RVC (Generates initial audio):',
|
|
181
|
+
choices: [
|
|
182
|
+
{ name: 'Edge-TTS (Cloud API, 0MB)', value: 'edge-tts' },
|
|
183
|
+
{ name: 'Kokoro TTS (Local, ~80MB)', value: 'kokoro' },
|
|
184
|
+
{ name: 'Piper TTS (Local, ~20MB)', value: 'piper' },
|
|
185
|
+
],
|
|
186
|
+
default: 'edge-tts',
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
type: 'input',
|
|
190
|
+
name: 'serviceUrl',
|
|
191
|
+
message: 'RVC Headless Service URL:',
|
|
192
|
+
default: 'http://localhost:50055',
|
|
193
|
+
},
|
|
194
|
+
]);
|
|
195
|
+
const pitchShift = parseInt(rvcAnswers.pitchShift, 10) || 0;
|
|
196
|
+
const config = {
|
|
197
|
+
provider: rvcAnswers.baseTts,
|
|
198
|
+
maxQueueDepth: 50,
|
|
199
|
+
rvc: {
|
|
200
|
+
enabled: true,
|
|
201
|
+
serviceUrl: rvcAnswers.serviceUrl.trim(),
|
|
202
|
+
modelName: companionSlug,
|
|
203
|
+
modelPath: rvcAnswers.modelPath.trim(),
|
|
204
|
+
indexPath: rvcAnswers.indexPath.trim() || undefined,
|
|
205
|
+
pitchShift,
|
|
206
|
+
f0Method: rvcAnswers.f0Method,
|
|
207
|
+
indexRate: 0.75,
|
|
208
|
+
},
|
|
209
|
+
};
|
|
210
|
+
const summary = {
|
|
211
|
+
Provider: 'RVC (Custom Voice Model)',
|
|
212
|
+
'Base TTS': rvcAnswers.baseTts,
|
|
213
|
+
'Model Path': rvcAnswers.modelPath.trim(),
|
|
214
|
+
'Pitch Shift': pitchShift,
|
|
215
|
+
'F0 Method': rvcAnswers.f0Method,
|
|
216
|
+
'RVC Service': rvcAnswers.serviceUrl.trim(),
|
|
217
|
+
};
|
|
218
|
+
return {
|
|
219
|
+
config,
|
|
220
|
+
summary,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
const DEFAULT_VOICEVOX_SPEAKERS = [
|
|
224
|
+
{
|
|
225
|
+
name: '四国めたん (Shikoku Metan)',
|
|
226
|
+
speaker_uuid: '7ffcb7ce-00ec-4bdc-82cd-45a8889e43ff',
|
|
227
|
+
styles: [
|
|
228
|
+
{ id: 2, name: 'ノーマル (Normal)' },
|
|
229
|
+
{ id: 0, name: 'あまあま (Sweet)' },
|
|
230
|
+
{ id: 4, name: 'ツンツン (Tsundere)' },
|
|
231
|
+
{ id: 6, name: 'セクシー (Sexy)' },
|
|
232
|
+
{ id: 36, name: 'ささやき (Whisper)' },
|
|
233
|
+
{ id: 37, name: 'ヒソヒソ (Hisoniso)' },
|
|
234
|
+
],
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
name: 'ずんだもん (Zundamon)',
|
|
238
|
+
speaker_uuid: '388f24ea-105d-4354-b46e-22d7d7ff4479',
|
|
239
|
+
styles: [
|
|
240
|
+
{ id: 3, name: 'ノーマル (Normal)' },
|
|
241
|
+
{ id: 1, name: 'あまあま (Sweet)' },
|
|
242
|
+
{ id: 5, name: 'ツンツン (Tsundere)' },
|
|
243
|
+
{ id: 7, name: 'セクシー (Sexy)' },
|
|
244
|
+
{ id: 22, name: 'ささやき (Whisper)' },
|
|
245
|
+
{ id: 38, name: 'ヒソヒソ (Hisoniso)' },
|
|
246
|
+
{ id: 75, name: 'ヘロヘロ (Herohero)' },
|
|
247
|
+
{ id: 76, name: 'なみだめ (Namidame)' },
|
|
248
|
+
],
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
name: '春日部つむぎ (Kasukabe Tsumugi)',
|
|
252
|
+
speaker_uuid: '35b2c544-660e-401e-b033-0ab4756917cd',
|
|
253
|
+
styles: [{ id: 8, name: 'ノーマル (Normal)' }],
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
name: '雨晴はう (Rainy Hau)',
|
|
257
|
+
speaker_uuid: '3474ee95-c274-47f9-aa1a-8322163d77f1',
|
|
258
|
+
styles: [{ id: 10, name: 'ノーマル (Normal)' }],
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
name: '波音リツ (Namine Ritsu)',
|
|
262
|
+
speaker_uuid: 'b1a81618-b27b-40d2-b0ea-27a9ad408c4b',
|
|
263
|
+
styles: [{ id: 9, name: 'ノーマル (Normal)' }],
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
name: '玄野武宏 (Kurono Takehiro)',
|
|
267
|
+
speaker_uuid: 'c30dc15a-0992-4f8d-8bb8-ad3b76579016',
|
|
268
|
+
styles: [
|
|
269
|
+
{ id: 11, name: 'ノーマル (Normal)' },
|
|
270
|
+
{ id: 39, name: '喜び (Joy)' },
|
|
271
|
+
{ id: 40, name: 'ツンツン (Tsundere)' },
|
|
272
|
+
{ id: 41, name: '悲しみ (Sadness)' },
|
|
273
|
+
],
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
name: '白上虎太郎 (Shirakami Kotaro)',
|
|
277
|
+
speaker_uuid: 'e50289b4-43ff-49e6-9b58-d894c23fb4ac',
|
|
278
|
+
styles: [
|
|
279
|
+
{ id: 12, name: 'ふつう (Normal)' },
|
|
280
|
+
{ id: 32, name: 'わーい (Yay)' },
|
|
281
|
+
{ id: 33, name: 'びくびく (Timid)' },
|
|
282
|
+
{ id: 34, name: 'おこ (Angry)' },
|
|
283
|
+
{ id: 35, name: 'びえーん (Crying)' },
|
|
284
|
+
],
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
name: '青山龍星 (Aoyama Ryusei)',
|
|
288
|
+
speaker_uuid: '4f51116a-d9ee-4516-925d-02f183e2af8d',
|
|
289
|
+
styles: [
|
|
290
|
+
{ id: 13, name: 'ノーマル (Normal)' },
|
|
291
|
+
{ id: 81, name: '熱血 (Passionate)' },
|
|
292
|
+
{ id: 82, name: '不気味 (Eerie)' },
|
|
293
|
+
{ id: 83, name: '囁き (Whisper)' },
|
|
294
|
+
],
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
name: '冥鳴ひまり (Meimei Himari)',
|
|
298
|
+
speaker_uuid: '8ea4fcd4-a013-4095-abb3-11b5bf837d37',
|
|
299
|
+
styles: [{ id: 14, name: 'ノーマル (Normal)' }],
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
name: '九州そら (Kyushu Sora)',
|
|
303
|
+
speaker_uuid: '481fb609-6446-4870-9f46-90c4dd623403',
|
|
304
|
+
styles: [
|
|
305
|
+
{ id: 16, name: 'ノーマル (Normal)' },
|
|
306
|
+
{ id: 15, name: 'あまあま (Sweet)' },
|
|
307
|
+
{ id: 17, name: 'ツンツン (Tsundere)' },
|
|
308
|
+
{ id: 18, name: 'セクシー (Sexy)' },
|
|
309
|
+
{ id: 19, name: 'ささやき (Whisper)' },
|
|
310
|
+
],
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
name: 'モチノ・キョウコ (Mochino Kyoko)',
|
|
314
|
+
speaker_uuid: 'a402a5d2-085e-4b44-a034-7164ff24a3cf',
|
|
315
|
+
styles: [
|
|
316
|
+
{ id: 20, name: 'ノーマル (Normal)' },
|
|
317
|
+
{ id: 60, name: 'セクシー/タレント (Sexy)' },
|
|
318
|
+
{ id: 61, name: '泣き (Crying)' },
|
|
319
|
+
],
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
name: '剣崎雌雄 (Kenzaki Mesuo)',
|
|
323
|
+
speaker_uuid: '1a1756a4-263d-42ea-86a2-96f107f474e9',
|
|
324
|
+
styles: [{ id: 21, name: 'ノーマル (Normal)' }],
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
name: '後鬼 (Goki)',
|
|
328
|
+
speaker_uuid: '80991a54-61c4-4b5f-8700-11234c062085',
|
|
329
|
+
styles: [
|
|
330
|
+
{ id: 27, name: '人間ver. (Human)' },
|
|
331
|
+
{ id: 28, name: '鬼ver. (Oni)' },
|
|
332
|
+
],
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
name: 'No.7 (Seven)',
|
|
336
|
+
speaker_uuid: 'c86c757c-cb24-4ea0-b6f7-33c872ff72e2',
|
|
337
|
+
styles: [
|
|
338
|
+
{ id: 29, name: 'ノーマル (Normal)' },
|
|
339
|
+
{ id: 30, name: 'アナウンス (Announce)' },
|
|
340
|
+
{ id: 31, name: '読み聞かせ (Storytelling)' },
|
|
341
|
+
],
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
name: 'ちび式じい (Chibishiki Jii)',
|
|
345
|
+
speaker_uuid: '1e19d52b-426b-4e12-b250-bfbe55c0c9cb',
|
|
346
|
+
styles: [{ id: 42, name: 'ノーマル (Normal)' }],
|
|
347
|
+
},
|
|
348
|
+
{
|
|
349
|
+
name: '櫻歌ミコ (Ouka Miko)',
|
|
350
|
+
speaker_uuid: '06155980-bfab-443b-a9b8-3e4b786c7ccb',
|
|
351
|
+
styles: [
|
|
352
|
+
{ id: 43, name: 'ノーマル (Normal)' },
|
|
353
|
+
{ id: 44, name: '第二形態 (2nd Form)' },
|
|
354
|
+
{ id: 45, name: 'ロリ (Loli)' },
|
|
355
|
+
],
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
name: '小夜/SAYO',
|
|
359
|
+
speaker_uuid: 'a8fb71e1-8738-4e16-b541-002f23ea3e45',
|
|
360
|
+
styles: [{ id: 46, name: 'ノーマル (Normal)' }],
|
|
361
|
+
},
|
|
362
|
+
{
|
|
363
|
+
name: 'ナースロボ_タイプT (Nurse Robot Type T)',
|
|
364
|
+
speaker_uuid: '882a636f-3bac-431a-966d-c5e6bba9f949',
|
|
365
|
+
styles: [
|
|
366
|
+
{ id: 47, name: 'ノーマル (Normal)' },
|
|
367
|
+
{ id: 48, name: '楽々 (Relaxed)' },
|
|
368
|
+
{ id: 49, name: '恐怖 (Fear)' },
|
|
369
|
+
{ id: 50, name: '内緒話 (Secret Talk)' },
|
|
370
|
+
],
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
name: '猫使アル (Nekotsuka Aru)',
|
|
374
|
+
speaker_uuid: '7253579b-240e-4328-b0a6-574ab57597ea',
|
|
375
|
+
styles: [
|
|
376
|
+
{ id: 55, name: 'ノーマル (Normal)' },
|
|
377
|
+
{ id: 56, name: 'おちつき (Calm)' },
|
|
378
|
+
{ id: 57, name: 'うきうき (Excited)' },
|
|
379
|
+
],
|
|
380
|
+
},
|
|
381
|
+
{
|
|
382
|
+
name: '猫使ビィ (Nekotsuka Bi)',
|
|
383
|
+
speaker_uuid: 'cf6204c3-6316-43b9-a095-2eb49e29a914',
|
|
384
|
+
styles: [
|
|
385
|
+
{ id: 58, name: 'ノーマル (Normal)' },
|
|
386
|
+
{ id: 59, name: 'おちつき (Calm)' },
|
|
387
|
+
{ id: 62, name: '人見知り (Shy)' },
|
|
388
|
+
],
|
|
389
|
+
},
|
|
390
|
+
];
|
|
391
|
+
async function getVoicevoxSpeakers(baseUrl) {
|
|
392
|
+
try {
|
|
393
|
+
const controller = new AbortController();
|
|
394
|
+
const timeout = setTimeout(() => controller.abort(), 2000);
|
|
395
|
+
const res = await fetch(new URL('/speakers', baseUrl).toString(), {
|
|
396
|
+
signal: controller.signal,
|
|
397
|
+
});
|
|
398
|
+
clearTimeout(timeout);
|
|
399
|
+
if (res.ok) {
|
|
400
|
+
const data = (await res.json());
|
|
401
|
+
if (Array.isArray(data) && data.length > 0) {
|
|
402
|
+
return data;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
catch (_e) {
|
|
407
|
+
// If local instance is unreachable, fallback to the pre-populated list
|
|
408
|
+
}
|
|
409
|
+
return DEFAULT_VOICEVOX_SPEAKERS;
|
|
410
|
+
}
|
|
411
|
+
function buildSpeakerChoices(speakers) {
|
|
412
|
+
const choices = [];
|
|
413
|
+
for (const speaker of speakers) {
|
|
414
|
+
for (const style of speaker.styles) {
|
|
415
|
+
const label = `${speaker.name} - ${style.name} (ID: ${style.id})`;
|
|
416
|
+
choices.push({
|
|
417
|
+
name: label,
|
|
418
|
+
value: { id: style.id, label },
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
return choices;
|
|
423
|
+
}
|
|
424
|
+
// provider === 'voicevox'
|
|
425
|
+
const urlAnswer = await inquirer_1.default.prompt([
|
|
426
|
+
{
|
|
427
|
+
type: 'input',
|
|
428
|
+
name: 'baseUrl',
|
|
429
|
+
message: 'VOICEVOX Engine Base URL:',
|
|
430
|
+
default: 'http://localhost:50021',
|
|
431
|
+
},
|
|
432
|
+
]);
|
|
433
|
+
const baseUrl = urlAnswer.baseUrl.trim() || 'http://localhost:50021';
|
|
434
|
+
const speakers = await getVoicevoxSpeakers(baseUrl);
|
|
435
|
+
const speakerChoices = buildSpeakerChoices(speakers);
|
|
436
|
+
const speakerAnswer = await inquirer_1.default.prompt([
|
|
437
|
+
{
|
|
438
|
+
type: 'list',
|
|
439
|
+
name: 'speaker',
|
|
440
|
+
message: 'Select VOICEVOX Character Voice Bank & Style:',
|
|
441
|
+
choices: speakerChoices,
|
|
442
|
+
pageSize: 15,
|
|
443
|
+
},
|
|
444
|
+
]);
|
|
445
|
+
let speakerId = 1;
|
|
446
|
+
let speakerLabel = '四国めたん (Shikoku Metan) - ノーマル (Normal) (ID: 2)';
|
|
447
|
+
if (speakerAnswer && speakerAnswer.speaker) {
|
|
448
|
+
if (typeof speakerAnswer.speaker === 'object' && 'id' in speakerAnswer.speaker) {
|
|
449
|
+
speakerId = speakerAnswer.speaker.id;
|
|
450
|
+
speakerLabel = speakerAnswer.speaker.label;
|
|
451
|
+
}
|
|
452
|
+
else if (typeof speakerAnswer.speaker === 'number') {
|
|
453
|
+
speakerId = speakerAnswer.speaker;
|
|
454
|
+
speakerLabel = `Speaker ID: ${speakerId}`;
|
|
455
|
+
}
|
|
456
|
+
else if (typeof speakerAnswer.speaker === 'string') {
|
|
457
|
+
speakerId = parseInt(speakerAnswer.speaker, 10) || 1;
|
|
458
|
+
speakerLabel = `Speaker ID: ${speakerId}`;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
const config = {
|
|
462
|
+
provider: 'voicevox',
|
|
463
|
+
baseUrl,
|
|
464
|
+
speakerId,
|
|
465
|
+
maxQueueDepth: 50,
|
|
466
|
+
};
|
|
467
|
+
const summary = {
|
|
468
|
+
Provider: 'VOICEVOX (Stock Voice Bank)',
|
|
469
|
+
'Voice Bank': speakerLabel,
|
|
470
|
+
'Speaker ID': speakerId,
|
|
471
|
+
'Base URL': baseUrl,
|
|
472
|
+
};
|
|
473
|
+
return {
|
|
474
|
+
config,
|
|
475
|
+
summary,
|
|
476
|
+
};
|
|
477
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|