abstractvoice 0.3.1__tar.gz → 0.4.1__tar.gz
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.
- {abstractvoice-0.3.1 → abstractvoice-0.4.1}/PKG-INFO +117 -19
- {abstractvoice-0.3.1 → abstractvoice-0.4.1}/README.md +116 -18
- {abstractvoice-0.3.1 → abstractvoice-0.4.1}/abstractvoice/__init__.py +5 -2
- {abstractvoice-0.3.1 → abstractvoice-0.4.1}/abstractvoice/examples/cli_repl.py +81 -44
- {abstractvoice-0.3.1 → abstractvoice-0.4.1}/abstractvoice/examples/voice_cli.py +56 -20
- abstractvoice-0.4.1/abstractvoice/model_manager.py +384 -0
- abstractvoice-0.4.1/abstractvoice/simple_model_manager.py +398 -0
- {abstractvoice-0.3.1 → abstractvoice-0.4.1}/abstractvoice/tts/tts_engine.py +139 -22
- {abstractvoice-0.3.1 → abstractvoice-0.4.1}/abstractvoice/voice_manager.py +83 -2
- {abstractvoice-0.3.1 → abstractvoice-0.4.1}/abstractvoice.egg-info/PKG-INFO +117 -19
- {abstractvoice-0.3.1 → abstractvoice-0.4.1}/abstractvoice.egg-info/SOURCES.txt +2 -0
- {abstractvoice-0.3.1 → abstractvoice-0.4.1}/LICENSE +0 -0
- {abstractvoice-0.3.1 → abstractvoice-0.4.1}/abstractvoice/__main__.py +0 -0
- {abstractvoice-0.3.1 → abstractvoice-0.4.1}/abstractvoice/dependency_check.py +0 -0
- {abstractvoice-0.3.1 → abstractvoice-0.4.1}/abstractvoice/examples/__init__.py +0 -0
- {abstractvoice-0.3.1 → abstractvoice-0.4.1}/abstractvoice/examples/web_api.py +0 -0
- {abstractvoice-0.3.1 → abstractvoice-0.4.1}/abstractvoice/recognition.py +0 -0
- {abstractvoice-0.3.1 → abstractvoice-0.4.1}/abstractvoice/stt/__init__.py +0 -0
- {abstractvoice-0.3.1 → abstractvoice-0.4.1}/abstractvoice/stt/transcriber.py +0 -0
- {abstractvoice-0.3.1 → abstractvoice-0.4.1}/abstractvoice/tts/__init__.py +0 -0
- {abstractvoice-0.3.1 → abstractvoice-0.4.1}/abstractvoice/vad/__init__.py +0 -0
- {abstractvoice-0.3.1 → abstractvoice-0.4.1}/abstractvoice/vad/voice_detector.py +0 -0
- {abstractvoice-0.3.1 → abstractvoice-0.4.1}/abstractvoice.egg-info/dependency_links.txt +0 -0
- {abstractvoice-0.3.1 → abstractvoice-0.4.1}/abstractvoice.egg-info/entry_points.txt +0 -0
- {abstractvoice-0.3.1 → abstractvoice-0.4.1}/abstractvoice.egg-info/requires.txt +0 -0
- {abstractvoice-0.3.1 → abstractvoice-0.4.1}/abstractvoice.egg-info/top_level.txt +0 -0
- {abstractvoice-0.3.1 → abstractvoice-0.4.1}/pyproject.toml +0 -0
- {abstractvoice-0.3.1 → abstractvoice-0.4.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: abstractvoice
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: A modular Python library for voice interactions with AI systems
|
|
5
5
|
Author-email: Laurent-Philippe Albou <contact@abstractcore.ai>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -164,34 +164,58 @@ AbstractVoice automatically detects espeak-ng and upgrades to premium quality vo
|
|
|
164
164
|
|
|
165
165
|
## Quick Start
|
|
166
166
|
|
|
167
|
-
###
|
|
167
|
+
### ⚡ Instant TTS (v0.4.0+)
|
|
168
168
|
|
|
169
169
|
```python
|
|
170
|
-
# First install with minimal dependencies
|
|
171
|
-
# pip install abstractvoice
|
|
172
|
-
|
|
173
170
|
from abstractvoice import VoiceManager
|
|
174
171
|
|
|
175
|
-
#
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
# Follow the instructions to install: pip install abstractvoice[all]
|
|
172
|
+
# Initialize voice manager - automatically downloads essential model if needed
|
|
173
|
+
vm = VoiceManager()
|
|
174
|
+
|
|
175
|
+
# Text-to-speech works immediately!
|
|
176
|
+
vm.speak("Hello! TTS works out of the box!")
|
|
181
177
|
```
|
|
182
178
|
|
|
183
|
-
|
|
179
|
+
**That's it!** AbstractVoice v0.4.0+ automatically:
|
|
180
|
+
- ✅ Downloads essential English model (107MB) on first use
|
|
181
|
+
- ✅ Caches models permanently for offline use
|
|
182
|
+
- ✅ Works immediately after first setup
|
|
183
|
+
- ✅ No complex configuration needed
|
|
184
184
|
|
|
185
|
-
|
|
186
|
-
# After installing with: pip install abstractvoice[all]
|
|
185
|
+
### 🌍 Multi-Language Support
|
|
187
186
|
|
|
188
|
-
|
|
187
|
+
```python
|
|
188
|
+
# Download and use French voice
|
|
189
|
+
vm.download_model('fr.css10_vits') # Downloads automatically
|
|
190
|
+
vm.set_language('fr')
|
|
191
|
+
vm.speak("Bonjour! Je parle français maintenant.")
|
|
192
|
+
|
|
193
|
+
# Download and use German voice
|
|
194
|
+
vm.download_model('de.thorsten_vits')
|
|
195
|
+
vm.set_language('de')
|
|
196
|
+
vm.speak("Hallo! Ich spreche jetzt Deutsch.")
|
|
197
|
+
```
|
|
189
198
|
|
|
190
|
-
|
|
191
|
-
vm = VoiceManager(language='en', debug_mode=True)
|
|
199
|
+
### 🔧 Check System Status
|
|
192
200
|
|
|
193
|
-
|
|
194
|
-
|
|
201
|
+
```python
|
|
202
|
+
from abstractvoice import is_ready, get_status, list_models
|
|
203
|
+
import json
|
|
204
|
+
|
|
205
|
+
# Quick readiness check
|
|
206
|
+
ready = is_ready()
|
|
207
|
+
print(f"TTS ready: {ready}")
|
|
208
|
+
|
|
209
|
+
# Get detailed status
|
|
210
|
+
status = json.loads(get_status())
|
|
211
|
+
print(f"Models cached: {status['total_cached']}")
|
|
212
|
+
print(f"Offline ready: {status['ready_for_offline']}")
|
|
213
|
+
|
|
214
|
+
# List all available models
|
|
215
|
+
models = json.loads(list_models())
|
|
216
|
+
for lang, voices in models.items():
|
|
217
|
+
print(f"{lang}: {len(voices)} voices available")
|
|
218
|
+
```
|
|
195
219
|
|
|
196
220
|
# Speech-to-text with callbacks
|
|
197
221
|
def on_transcription(text):
|
|
@@ -1289,6 +1313,80 @@ voice_manager.listen(
|
|
|
1289
1313
|
)
|
|
1290
1314
|
```
|
|
1291
1315
|
|
|
1316
|
+
## 💻 CLI Commands (v0.4.0+)
|
|
1317
|
+
|
|
1318
|
+
AbstractVoice provides powerful CLI commands for model management and voice interactions.
|
|
1319
|
+
|
|
1320
|
+
### Model Management
|
|
1321
|
+
|
|
1322
|
+
```bash
|
|
1323
|
+
# Download essential model for offline use (recommended first step)
|
|
1324
|
+
abstractvoice download-models
|
|
1325
|
+
|
|
1326
|
+
# Download models for specific languages
|
|
1327
|
+
abstractvoice download-models --language fr # French
|
|
1328
|
+
abstractvoice download-models --language de # German
|
|
1329
|
+
abstractvoice download-models --language it # Italian
|
|
1330
|
+
abstractvoice download-models --language es # Spanish
|
|
1331
|
+
|
|
1332
|
+
# Download specific model by name
|
|
1333
|
+
abstractvoice download-models --model tts_models/fr/css10/vits
|
|
1334
|
+
|
|
1335
|
+
# Download all available models (large download!)
|
|
1336
|
+
abstractvoice download-models --all
|
|
1337
|
+
|
|
1338
|
+
# Check current cache status
|
|
1339
|
+
abstractvoice download-models --status
|
|
1340
|
+
|
|
1341
|
+
# Clear model cache
|
|
1342
|
+
abstractvoice download-models --clear
|
|
1343
|
+
```
|
|
1344
|
+
|
|
1345
|
+
### Voice Interface
|
|
1346
|
+
|
|
1347
|
+
```bash
|
|
1348
|
+
# Start voice interface (default)
|
|
1349
|
+
abstractvoice
|
|
1350
|
+
|
|
1351
|
+
# Start CLI REPL with specific language
|
|
1352
|
+
abstractvoice cli --language fr
|
|
1353
|
+
|
|
1354
|
+
# Start with specific model
|
|
1355
|
+
abstractvoice --model granite3.3:2b --language de
|
|
1356
|
+
|
|
1357
|
+
# Run simple example
|
|
1358
|
+
abstractvoice simple
|
|
1359
|
+
|
|
1360
|
+
# Check dependencies
|
|
1361
|
+
abstractvoice check-deps
|
|
1362
|
+
```
|
|
1363
|
+
|
|
1364
|
+
### CLI Voice Commands
|
|
1365
|
+
|
|
1366
|
+
In the CLI REPL, use these commands:
|
|
1367
|
+
|
|
1368
|
+
```bash
|
|
1369
|
+
# List all available voices with download status
|
|
1370
|
+
/setvoice
|
|
1371
|
+
|
|
1372
|
+
# Download and set specific voice
|
|
1373
|
+
/setvoice fr.css10_vits # French CSS10 VITS
|
|
1374
|
+
/setvoice de.thorsten_vits # German Thorsten
|
|
1375
|
+
/setvoice it.mai_male_vits # Italian Male
|
|
1376
|
+
|
|
1377
|
+
# Change language
|
|
1378
|
+
/language fr
|
|
1379
|
+
/language de
|
|
1380
|
+
|
|
1381
|
+
# Voice controls
|
|
1382
|
+
/pause # Pause current speech
|
|
1383
|
+
/resume # Resume speech
|
|
1384
|
+
/stop # Stop speech
|
|
1385
|
+
|
|
1386
|
+
# Exit
|
|
1387
|
+
/exit
|
|
1388
|
+
```
|
|
1389
|
+
|
|
1292
1390
|
## Perspectives
|
|
1293
1391
|
|
|
1294
1392
|
This is a test project that I designed with examples to work with Ollama, but I will adapt the examples and abstractvoice to work with any LLM provider (anthropic, openai, etc).
|
|
@@ -82,34 +82,58 @@ AbstractVoice automatically detects espeak-ng and upgrades to premium quality vo
|
|
|
82
82
|
|
|
83
83
|
## Quick Start
|
|
84
84
|
|
|
85
|
-
###
|
|
85
|
+
### ⚡ Instant TTS (v0.4.0+)
|
|
86
86
|
|
|
87
87
|
```python
|
|
88
|
-
# First install with minimal dependencies
|
|
89
|
-
# pip install abstractvoice
|
|
90
|
-
|
|
91
88
|
from abstractvoice import VoiceManager
|
|
92
89
|
|
|
93
|
-
#
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
# Follow the instructions to install: pip install abstractvoice[all]
|
|
90
|
+
# Initialize voice manager - automatically downloads essential model if needed
|
|
91
|
+
vm = VoiceManager()
|
|
92
|
+
|
|
93
|
+
# Text-to-speech works immediately!
|
|
94
|
+
vm.speak("Hello! TTS works out of the box!")
|
|
99
95
|
```
|
|
100
96
|
|
|
101
|
-
|
|
97
|
+
**That's it!** AbstractVoice v0.4.0+ automatically:
|
|
98
|
+
- ✅ Downloads essential English model (107MB) on first use
|
|
99
|
+
- ✅ Caches models permanently for offline use
|
|
100
|
+
- ✅ Works immediately after first setup
|
|
101
|
+
- ✅ No complex configuration needed
|
|
102
102
|
|
|
103
|
-
|
|
104
|
-
# After installing with: pip install abstractvoice[all]
|
|
103
|
+
### 🌍 Multi-Language Support
|
|
105
104
|
|
|
106
|
-
|
|
105
|
+
```python
|
|
106
|
+
# Download and use French voice
|
|
107
|
+
vm.download_model('fr.css10_vits') # Downloads automatically
|
|
108
|
+
vm.set_language('fr')
|
|
109
|
+
vm.speak("Bonjour! Je parle français maintenant.")
|
|
110
|
+
|
|
111
|
+
# Download and use German voice
|
|
112
|
+
vm.download_model('de.thorsten_vits')
|
|
113
|
+
vm.set_language('de')
|
|
114
|
+
vm.speak("Hallo! Ich spreche jetzt Deutsch.")
|
|
115
|
+
```
|
|
107
116
|
|
|
108
|
-
|
|
109
|
-
vm = VoiceManager(language='en', debug_mode=True)
|
|
117
|
+
### 🔧 Check System Status
|
|
110
118
|
|
|
111
|
-
|
|
112
|
-
|
|
119
|
+
```python
|
|
120
|
+
from abstractvoice import is_ready, get_status, list_models
|
|
121
|
+
import json
|
|
122
|
+
|
|
123
|
+
# Quick readiness check
|
|
124
|
+
ready = is_ready()
|
|
125
|
+
print(f"TTS ready: {ready}")
|
|
126
|
+
|
|
127
|
+
# Get detailed status
|
|
128
|
+
status = json.loads(get_status())
|
|
129
|
+
print(f"Models cached: {status['total_cached']}")
|
|
130
|
+
print(f"Offline ready: {status['ready_for_offline']}")
|
|
131
|
+
|
|
132
|
+
# List all available models
|
|
133
|
+
models = json.loads(list_models())
|
|
134
|
+
for lang, voices in models.items():
|
|
135
|
+
print(f"{lang}: {len(voices)} voices available")
|
|
136
|
+
```
|
|
113
137
|
|
|
114
138
|
# Speech-to-text with callbacks
|
|
115
139
|
def on_transcription(text):
|
|
@@ -1207,6 +1231,80 @@ voice_manager.listen(
|
|
|
1207
1231
|
)
|
|
1208
1232
|
```
|
|
1209
1233
|
|
|
1234
|
+
## 💻 CLI Commands (v0.4.0+)
|
|
1235
|
+
|
|
1236
|
+
AbstractVoice provides powerful CLI commands for model management and voice interactions.
|
|
1237
|
+
|
|
1238
|
+
### Model Management
|
|
1239
|
+
|
|
1240
|
+
```bash
|
|
1241
|
+
# Download essential model for offline use (recommended first step)
|
|
1242
|
+
abstractvoice download-models
|
|
1243
|
+
|
|
1244
|
+
# Download models for specific languages
|
|
1245
|
+
abstractvoice download-models --language fr # French
|
|
1246
|
+
abstractvoice download-models --language de # German
|
|
1247
|
+
abstractvoice download-models --language it # Italian
|
|
1248
|
+
abstractvoice download-models --language es # Spanish
|
|
1249
|
+
|
|
1250
|
+
# Download specific model by name
|
|
1251
|
+
abstractvoice download-models --model tts_models/fr/css10/vits
|
|
1252
|
+
|
|
1253
|
+
# Download all available models (large download!)
|
|
1254
|
+
abstractvoice download-models --all
|
|
1255
|
+
|
|
1256
|
+
# Check current cache status
|
|
1257
|
+
abstractvoice download-models --status
|
|
1258
|
+
|
|
1259
|
+
# Clear model cache
|
|
1260
|
+
abstractvoice download-models --clear
|
|
1261
|
+
```
|
|
1262
|
+
|
|
1263
|
+
### Voice Interface
|
|
1264
|
+
|
|
1265
|
+
```bash
|
|
1266
|
+
# Start voice interface (default)
|
|
1267
|
+
abstractvoice
|
|
1268
|
+
|
|
1269
|
+
# Start CLI REPL with specific language
|
|
1270
|
+
abstractvoice cli --language fr
|
|
1271
|
+
|
|
1272
|
+
# Start with specific model
|
|
1273
|
+
abstractvoice --model granite3.3:2b --language de
|
|
1274
|
+
|
|
1275
|
+
# Run simple example
|
|
1276
|
+
abstractvoice simple
|
|
1277
|
+
|
|
1278
|
+
# Check dependencies
|
|
1279
|
+
abstractvoice check-deps
|
|
1280
|
+
```
|
|
1281
|
+
|
|
1282
|
+
### CLI Voice Commands
|
|
1283
|
+
|
|
1284
|
+
In the CLI REPL, use these commands:
|
|
1285
|
+
|
|
1286
|
+
```bash
|
|
1287
|
+
# List all available voices with download status
|
|
1288
|
+
/setvoice
|
|
1289
|
+
|
|
1290
|
+
# Download and set specific voice
|
|
1291
|
+
/setvoice fr.css10_vits # French CSS10 VITS
|
|
1292
|
+
/setvoice de.thorsten_vits # German Thorsten
|
|
1293
|
+
/setvoice it.mai_male_vits # Italian Male
|
|
1294
|
+
|
|
1295
|
+
# Change language
|
|
1296
|
+
/language fr
|
|
1297
|
+
/language de
|
|
1298
|
+
|
|
1299
|
+
# Voice controls
|
|
1300
|
+
/pause # Pause current speech
|
|
1301
|
+
/resume # Resume speech
|
|
1302
|
+
/stop # Stop speech
|
|
1303
|
+
|
|
1304
|
+
# Exit
|
|
1305
|
+
/exit
|
|
1306
|
+
```
|
|
1307
|
+
|
|
1210
1308
|
## Perspectives
|
|
1211
1309
|
|
|
1212
1310
|
This is a test project that I designed with examples to work with Ollama, but I will adapt the examples and abstractvoice to work with any LLM provider (anthropic, openai, etc).
|
|
@@ -29,5 +29,8 @@ warnings.filterwarnings(
|
|
|
29
29
|
# Import the main class for public API
|
|
30
30
|
from .voice_manager import VoiceManager
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
# Import simple APIs for third-party applications
|
|
33
|
+
from .simple_model_manager import list_models, download_model, get_status, is_ready
|
|
34
|
+
|
|
35
|
+
__version__ = "0.4.1"
|
|
36
|
+
__all__ = ['VoiceManager', 'list_models', 'download_model', 'get_status', 'is_ready']
|
|
@@ -38,7 +38,7 @@ class VoiceREPL(cmd.Cmd):
|
|
|
38
38
|
use_rawinput = True
|
|
39
39
|
|
|
40
40
|
def __init__(self, api_url="http://localhost:11434/api/chat",
|
|
41
|
-
model="granite3.3:2b", debug_mode=False, language="en", tts_model=None):
|
|
41
|
+
model="granite3.3:2b", debug_mode=False, language="en", tts_model=None, disable_tts=False):
|
|
42
42
|
super().__init__()
|
|
43
43
|
|
|
44
44
|
# Debug mode
|
|
@@ -54,11 +54,15 @@ class VoiceREPL(cmd.Cmd):
|
|
|
54
54
|
self.current_language = language
|
|
55
55
|
|
|
56
56
|
# Initialize voice manager with language support
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
if disable_tts:
|
|
58
|
+
self.voice_manager = None
|
|
59
|
+
print("🔇 TTS disabled - text-only mode")
|
|
60
|
+
else:
|
|
61
|
+
self.voice_manager = VoiceManager(
|
|
62
|
+
language=language,
|
|
63
|
+
tts_model=tts_model,
|
|
64
|
+
debug_mode=debug_mode
|
|
65
|
+
)
|
|
62
66
|
|
|
63
67
|
# Settings
|
|
64
68
|
self.use_tts = True
|
|
@@ -90,8 +94,11 @@ class VoiceREPL(cmd.Cmd):
|
|
|
90
94
|
def _get_intro(self):
|
|
91
95
|
"""Generate intro message with help."""
|
|
92
96
|
intro = f"\n{Colors.BOLD}Welcome to AbstractVoice CLI REPL{Colors.END}\n"
|
|
93
|
-
|
|
94
|
-
|
|
97
|
+
if self.voice_manager:
|
|
98
|
+
lang_name = self.voice_manager.get_language_name()
|
|
99
|
+
intro += f"API: {self.api_url} | Model: {self.model} | Voice: {lang_name}\n"
|
|
100
|
+
else:
|
|
101
|
+
intro += f"API: {self.api_url} | Model: {self.model} | Voice: Disabled\n"
|
|
95
102
|
intro += f"\n{Colors.CYAN}Quick Start:{Colors.END}\n"
|
|
96
103
|
intro += " • Type messages to chat with the LLM\n"
|
|
97
104
|
intro += " • Use /voice <mode> to enable voice input\n"
|
|
@@ -232,7 +239,7 @@ class VoiceREPL(cmd.Cmd):
|
|
|
232
239
|
print(f"{Colors.CYAN}{response_text}{Colors.END}")
|
|
233
240
|
|
|
234
241
|
# Speak the response if voice manager is available
|
|
235
|
-
if self.voice_manager:
|
|
242
|
+
if self.voice_manager and self.use_tts:
|
|
236
243
|
self.voice_manager.speak(response_text)
|
|
237
244
|
|
|
238
245
|
except requests.exceptions.ConnectionError as e:
|
|
@@ -376,18 +383,47 @@ class VoiceREPL(cmd.Cmd):
|
|
|
376
383
|
/setvoice <voice_id> # Set voice (format: language.voice_id)
|
|
377
384
|
|
|
378
385
|
Examples:
|
|
379
|
-
/setvoice # List all voices
|
|
386
|
+
/setvoice # List all voices with JSON-like info
|
|
380
387
|
/setvoice fr.css10_vits # Set French CSS10 VITS voice
|
|
381
388
|
/setvoice it.mai_male_vits # Set Italian male VITS voice
|
|
382
389
|
"""
|
|
383
390
|
if not args:
|
|
384
|
-
# Show all available voices
|
|
391
|
+
# Show all available voices with metadata
|
|
385
392
|
print(f"\n{Colors.CYAN}Available Voice Models:{Colors.END}")
|
|
386
|
-
self.voice_manager.list_voices()
|
|
387
393
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
394
|
+
try:
|
|
395
|
+
models = self.voice_manager.list_available_models()
|
|
396
|
+
|
|
397
|
+
for language, voices in models.items():
|
|
398
|
+
# Get language name
|
|
399
|
+
lang_names = {
|
|
400
|
+
'en': 'English', 'fr': 'French', 'es': 'Spanish',
|
|
401
|
+
'de': 'German', 'it': 'Italian'
|
|
402
|
+
}
|
|
403
|
+
lang_name = lang_names.get(language, language.upper())
|
|
404
|
+
|
|
405
|
+
print(f"\n🌍 {lang_name} ({language}):")
|
|
406
|
+
|
|
407
|
+
for voice_id, voice_info in voices.items():
|
|
408
|
+
cached_icon = "✅" if voice_info.get('cached', False) else "📥"
|
|
409
|
+
quality_icon = "✨" if voice_info['quality'] == 'excellent' else "🔧"
|
|
410
|
+
size_text = f"{voice_info['size_mb']}MB"
|
|
411
|
+
|
|
412
|
+
print(f" {cached_icon} {quality_icon} {language}.{voice_id}")
|
|
413
|
+
print(f" {voice_info['name']} ({size_text})")
|
|
414
|
+
print(f" {voice_info['description']}")
|
|
415
|
+
if voice_info.get('requires_espeak', False):
|
|
416
|
+
print(f" ⚠️ Requires espeak-ng")
|
|
417
|
+
|
|
418
|
+
print(f"\n{Colors.YELLOW}Usage:{Colors.END}")
|
|
419
|
+
print(" /setvoice <language>.<voice_id>")
|
|
420
|
+
print(" Example: /setvoice fr.css10_vits")
|
|
421
|
+
print("\n📥 = Download needed ✅ = Ready ✨ = High quality 🔧 = Good quality")
|
|
422
|
+
|
|
423
|
+
except Exception as e:
|
|
424
|
+
print(f"❌ Error listing models: {e}")
|
|
425
|
+
# Fallback to old method
|
|
426
|
+
self.voice_manager.list_voices()
|
|
391
427
|
return
|
|
392
428
|
|
|
393
429
|
voice_spec = args.strip()
|
|
@@ -412,45 +448,46 @@ class VoiceREPL(cmd.Cmd):
|
|
|
412
448
|
else:
|
|
413
449
|
was_active = False
|
|
414
450
|
|
|
415
|
-
#
|
|
451
|
+
# Download and set the specific voice using programmatic API
|
|
416
452
|
try:
|
|
417
|
-
|
|
453
|
+
print(f"🔄 Setting voice {voice_spec}...")
|
|
454
|
+
|
|
455
|
+
# Use the programmatic download API
|
|
456
|
+
success = self.voice_manager.download_model(voice_spec)
|
|
457
|
+
|
|
418
458
|
if success:
|
|
419
|
-
#
|
|
420
|
-
|
|
459
|
+
# Now set the language to match
|
|
460
|
+
success = self.voice_manager.set_language(language)
|
|
421
461
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
462
|
+
if success:
|
|
463
|
+
# Update current language
|
|
464
|
+
self.current_language = language
|
|
425
465
|
|
|
426
|
-
|
|
427
|
-
print(f" Language: {lang_name} ({language})")
|
|
428
|
-
print(f" Voice: {voice_id}")
|
|
429
|
-
if voice_info:
|
|
430
|
-
quality_icon = "✨" if voice_info.get('quality') == 'premium' else "🔧"
|
|
431
|
-
gender_icon = {"male": "👨", "female": "👩", "multiple": "👥"}.get(voice_info.get('gender'), "🗣️")
|
|
432
|
-
print(f" Details: {quality_icon} {gender_icon} {voice_info.get('accent', 'Unknown accent')}")
|
|
466
|
+
print(f"✅ Voice set to {voice_spec}")
|
|
433
467
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
468
|
+
# Test the voice
|
|
469
|
+
test_messages = {
|
|
470
|
+
'en': 'Voice changed to English.',
|
|
471
|
+
'fr': 'Voix changée en français.',
|
|
472
|
+
'es': 'Voz cambiada al español.',
|
|
473
|
+
'de': 'Stimme auf Deutsch geändert.',
|
|
474
|
+
'it': 'Voce cambiata in italiano.'
|
|
475
|
+
}
|
|
476
|
+
test_msg = test_messages.get(language, f'Voice changed to {language}.')
|
|
477
|
+
self.voice_manager.speak(test_msg)
|
|
444
478
|
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
479
|
+
# Restart voice mode if it was active
|
|
480
|
+
if was_active:
|
|
481
|
+
self.do_voice(self.voice_mode)
|
|
482
|
+
else:
|
|
483
|
+
print(f"❌ Failed to set language: {language}")
|
|
448
484
|
else:
|
|
449
|
-
print(f"❌ Failed to
|
|
450
|
-
print(
|
|
485
|
+
print(f"❌ Failed to download voice: {voice_spec}")
|
|
486
|
+
print(" Check your internet connection or try a different voice")
|
|
451
487
|
|
|
452
488
|
except Exception as e:
|
|
453
489
|
print(f"❌ Error setting voice: {e}")
|
|
490
|
+
print(f" Run '/setvoice' to see available voices")
|
|
454
491
|
if self.debug_mode:
|
|
455
492
|
import traceback
|
|
456
493
|
traceback.print_exc()
|
|
@@ -11,18 +11,20 @@ from abstractvoice.examples.cli_repl import VoiceREPL
|
|
|
11
11
|
|
|
12
12
|
def print_examples():
|
|
13
13
|
"""Print available examples."""
|
|
14
|
-
print("Available
|
|
15
|
-
print(" cli
|
|
16
|
-
print(" web
|
|
17
|
-
print(" simple
|
|
18
|
-
print(" check-deps
|
|
19
|
-
print("
|
|
14
|
+
print("Available commands:")
|
|
15
|
+
print(" cli - Command-line REPL example")
|
|
16
|
+
print(" web - Web API example")
|
|
17
|
+
print(" simple - Simple usage example")
|
|
18
|
+
print(" check-deps - Check dependency compatibility")
|
|
19
|
+
print(" download-models - Download TTS models for offline use")
|
|
20
|
+
print("\nUsage: abstractvoice <command> [--language <lang>] [args...]")
|
|
20
21
|
print("\nSupported languages: en, fr, es, de, it, ru, multilingual")
|
|
21
22
|
print("\nExamples:")
|
|
22
|
-
print(" abstractvoice cli --language fr
|
|
23
|
-
print(" abstractvoice simple --language ru
|
|
24
|
-
print(" abstractvoice check-deps
|
|
25
|
-
print(" abstractvoice
|
|
23
|
+
print(" abstractvoice cli --language fr # French CLI")
|
|
24
|
+
print(" abstractvoice simple --language ru # Russian simple example")
|
|
25
|
+
print(" abstractvoice check-deps # Check dependencies")
|
|
26
|
+
print(" abstractvoice download-models # Download models for offline use")
|
|
27
|
+
print(" abstractvoice # Direct voice mode (default)")
|
|
26
28
|
|
|
27
29
|
def simple_example():
|
|
28
30
|
"""Run a simple example demonstrating basic usage."""
|
|
@@ -95,10 +97,22 @@ def simple_example():
|
|
|
95
97
|
|
|
96
98
|
def parse_args():
|
|
97
99
|
"""Parse command line arguments."""
|
|
100
|
+
import sys
|
|
101
|
+
|
|
102
|
+
# Check if it's a download-models command and handle separately
|
|
103
|
+
if len(sys.argv) > 1 and sys.argv[1] == "download-models":
|
|
104
|
+
# Return early with just the command to handle in main()
|
|
105
|
+
class DownloadModelsArgs:
|
|
106
|
+
command = "download-models"
|
|
107
|
+
# Add dummy attributes to prevent AttributeError
|
|
108
|
+
model = "granite3.3:2b"
|
|
109
|
+
debug = False
|
|
110
|
+
return DownloadModelsArgs()
|
|
111
|
+
|
|
98
112
|
parser = argparse.ArgumentParser(description="AbstractVoice - Voice interactions with AI")
|
|
99
113
|
|
|
100
114
|
# Examples and special commands
|
|
101
|
-
parser.add_argument("command", nargs="?", help="Command to run: cli, web, simple, check-deps (default: voice mode)")
|
|
115
|
+
parser.add_argument("command", nargs="?", help="Command to run: cli, web, simple, check-deps, download-models (default: voice mode)")
|
|
102
116
|
|
|
103
117
|
# Voice mode arguments
|
|
104
118
|
parser.add_argument("--debug", action="store_true", help="Enable debug mode")
|
|
@@ -110,6 +124,8 @@ def parse_args():
|
|
|
110
124
|
help="Whisper model to use (tiny, base, small, medium, large)")
|
|
111
125
|
parser.add_argument("--no-listening", action="store_true",
|
|
112
126
|
help="Disable speech-to-text (listening), TTS still works")
|
|
127
|
+
parser.add_argument("--no-tts", action="store_true",
|
|
128
|
+
help="Disable text-to-speech (TTS), text-only mode")
|
|
113
129
|
parser.add_argument("--system",
|
|
114
130
|
help="Custom system prompt")
|
|
115
131
|
parser.add_argument("--temperature", type=float, default=0.4,
|
|
@@ -141,6 +157,17 @@ def main():
|
|
|
141
157
|
import traceback
|
|
142
158
|
traceback.print_exc()
|
|
143
159
|
return
|
|
160
|
+
elif args.command == "download-models":
|
|
161
|
+
from abstractvoice.model_manager import download_models_cli
|
|
162
|
+
# Pass remaining arguments to download_models_cli
|
|
163
|
+
import sys
|
|
164
|
+
original_argv = sys.argv
|
|
165
|
+
sys.argv = ["download-models"] + sys.argv[2:] # Remove script name and "download-models"
|
|
166
|
+
try:
|
|
167
|
+
download_models_cli()
|
|
168
|
+
finally:
|
|
169
|
+
sys.argv = original_argv
|
|
170
|
+
return
|
|
144
171
|
elif args.command == "cli":
|
|
145
172
|
# Import and run CLI REPL example
|
|
146
173
|
repl = VoiceREPL(
|
|
@@ -188,7 +215,8 @@ def main():
|
|
|
188
215
|
model=args.model,
|
|
189
216
|
debug_mode=args.debug,
|
|
190
217
|
language=args.language,
|
|
191
|
-
tts_model=args.tts_model
|
|
218
|
+
tts_model=args.tts_model,
|
|
219
|
+
disable_tts=args.no_tts
|
|
192
220
|
)
|
|
193
221
|
|
|
194
222
|
# Set custom system prompt if provided
|
|
@@ -224,22 +252,30 @@ def main():
|
|
|
224
252
|
print("\nExiting AbstractVoice...")
|
|
225
253
|
except Exception as e:
|
|
226
254
|
error_msg = str(e).lower()
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
print(f"
|
|
231
|
-
print(f"
|
|
232
|
-
|
|
233
|
-
print(f"
|
|
255
|
+
|
|
256
|
+
# Check if it's a TTS-related error (not Ollama model error)
|
|
257
|
+
if "model file not found in the output path" in error_msg:
|
|
258
|
+
print(f"❌ TTS model download failed")
|
|
259
|
+
print(f" This is a TTS voice model issue, not your Ollama model")
|
|
260
|
+
print(f" Your Ollama model '{args.model}' is fine")
|
|
261
|
+
print(f" Try: rm -rf ~/.cache/tts && pip install --force-reinstall coqui-tts")
|
|
262
|
+
print(f" Or check network connectivity for model downloads")
|
|
263
|
+
elif "ollama" in error_msg or "11434" in error_msg:
|
|
264
|
+
print(f"❌ Cannot connect to Ollama at {args.api}")
|
|
234
265
|
print(f" Make sure Ollama is running: ollama serve")
|
|
235
|
-
print(f"
|
|
266
|
+
print(f" Your model '{args.model}' exists but Ollama server isn't responding")
|
|
236
267
|
elif "importerror" in error_msg or "no module" in error_msg:
|
|
237
268
|
print(f"❌ Missing dependencies")
|
|
238
269
|
print(f" Try running: abstractvoice check-deps")
|
|
239
270
|
print(f" Or install dependencies: pip install abstractvoice[voice-full]")
|
|
271
|
+
elif "espeak" in error_msg or "phoneme" in error_msg:
|
|
272
|
+
print(f"❌ Voice synthesis setup issue")
|
|
273
|
+
print(f" Install espeak-ng for better voice quality: brew install espeak-ng")
|
|
274
|
+
print(f" Or this might be a TTS model download issue")
|
|
240
275
|
else:
|
|
241
276
|
print(f"❌ Application error: {e}")
|
|
242
277
|
print(f" Try running with --debug for more details")
|
|
278
|
+
print(f" Note: Your Ollama model '{args.model}' appears to be available")
|
|
243
279
|
|
|
244
280
|
if args.debug:
|
|
245
281
|
import traceback
|