voice-mode 2.33.4__tar.gz → 2.34.0__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.
- {voice_mode-2.33.4 → voice_mode-2.34.0}/CHANGELOG.md +36 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/PKG-INFO +1 -1
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/__version__.py +1 -1
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/templates/launchd/com.voicemode.whisper.plist +4 -4
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/tools/services/kokoro/install.py +207 -2
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/tools/services/whisper/install.py +329 -189
- {voice_mode-2.33.4 → voice_mode-2.34.0}/.gitignore +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/README.md +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/build_hooks.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/pyproject.toml +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/__init__.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/__main__.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/cli.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/cli_commands/__init__.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/cli_commands/exchanges.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/config.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/conversation_logger.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/core.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/data/versions.json +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/exchanges/__init__.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/exchanges/conversations.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/exchanges/filters.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/exchanges/formatters.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/exchanges/models.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/exchanges/reader.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/exchanges/stats.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/frontend/README.md +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/frontend/app/api/connection-details/route.ts +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/frontend/app/favicon.ico +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/frontend/app/globals.css +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/frontend/app/layout.tsx +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/frontend/app/page.tsx +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/frontend/components/CloseIcon.tsx +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/frontend/components/NoAgentNotification.tsx +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/frontend/components/TranscriptionView.tsx +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/frontend/hooks/useCombinedTranscriptions.ts +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/frontend/hooks/useLocalMicTrack.ts +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/frontend/next-env.d.ts +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/frontend/next.config.mjs +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/frontend/package-lock.json +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/frontend/package.json +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/frontend/pnpm-lock.yaml +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/frontend/postcss.config.mjs +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/frontend/tailwind.config.ts +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/frontend/tsconfig.json +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/prompts/README.md +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/prompts/__init__.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/prompts/converse.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/prompts/release_notes.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/prompts/services.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/provider_discovery.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/providers.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/resources/__init__.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/resources/audio_files.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/resources/changelog.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/resources/configuration.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/resources/statistics.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/resources/version.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/resources/whisper_models.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/server.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/shared.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/simple_failover.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/statistics.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/streaming.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/templates/__init__.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/templates/launchd/com.voicemode.frontend.plist +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/templates/launchd/com.voicemode.kokoro.plist +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/templates/launchd/com.voicemode.livekit.plist +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/templates/launchd/start-kokoro-with-health-check.sh +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/templates/launchd/start-whisper-with-health-check.sh +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/templates/scripts/__init__.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/templates/scripts/start-whisper-server.sh +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/templates/systemd/voicemode-frontend.service +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/templates/systemd/voicemode-kokoro.service +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/templates/systemd/voicemode-livekit.service +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/templates/systemd/voicemode-whisper.service +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/tools/__init__.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/tools/configuration_management.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/tools/converse.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/tools/dependencies.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/tools/devices.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/tools/diagnostics.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/tools/providers.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/tools/service.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/tools/services/kokoro/uninstall.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/tools/services/list_versions.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/tools/services/livekit/__init__.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/tools/services/livekit/frontend.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/tools/services/livekit/install.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/tools/services/livekit/production_server.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/tools/services/livekit/uninstall.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/tools/services/version_info.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/tools/services/whisper/__init__.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/tools/services/whisper/list_models.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/tools/services/whisper/model_active.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/tools/services/whisper/model_benchmark.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/tools/services/whisper/model_install.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/tools/services/whisper/model_remove.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/tools/services/whisper/models.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/tools/services/whisper/uninstall.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/tools/statistics.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/tools/voice_registry.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/utils/__init__.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/utils/audio_diagnostics.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/utils/event_logger.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/utils/ffmpeg_check.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/utils/format_migration.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/utils/gpu_detection.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/utils/migration_helpers.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/utils/services/common.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/utils/services/coreml_setup.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/utils/services/kokoro_helpers.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/utils/services/livekit_helpers.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/utils/services/whisper_helpers.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/utils/services/whisper_version.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/utils/version_helpers.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/version.py +0 -0
- {voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/voice_preferences.py +0 -0
@@ -7,12 +7,48 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
7
7
|
|
8
8
|
## [Unreleased]
|
9
9
|
|
10
|
+
## [2.34.0] - 2025-08-26
|
11
|
+
|
12
|
+
## [2.24.0] - 2025-08-26
|
13
|
+
|
14
|
+
### Changed
|
15
|
+
- **Installer improvements**
|
16
|
+
- Refactored installer to use permanent `uv tool install --upgrade` instead of `uvx --refresh`
|
17
|
+
- Added `uv tool update-shell` for automatic PATH configuration
|
18
|
+
- Improved shell completion detection with smart fallbacks
|
19
|
+
- Added Homebrew zsh completion directory support on macOS
|
20
|
+
- Implemented XDG-compliant paths for bash completions
|
21
|
+
- Removed fish shell support to simplify maintenance (bash/zsh only)
|
22
|
+
- Zsh completions now correctly use underscore prefix (_voicemode)
|
23
|
+
- MCP configuration now uses plain `voice-mode` command for better performance
|
24
|
+
|
25
|
+
### Fixed
|
26
|
+
- **Service file updates on reinstall**
|
27
|
+
- Fixed whisper and kokoro installers to always update service files (plist/systemd) even when service is already installed
|
28
|
+
- Ensures paths are properly expanded (no `~` symbols) in service files
|
29
|
+
- Fixes issue where broken service files with unexpanded paths would remain broken after running install.sh
|
30
|
+
- Service files now updated to latest templates on every install, ensuring users always get working configurations
|
31
|
+
|
10
32
|
## [2.33.4] - 2025-08-26
|
11
33
|
|
34
|
+
### Fixed
|
35
|
+
- **CoreML support restoration**
|
36
|
+
- Re-enabled CoreML acceleration after fixing plist template path issues
|
37
|
+
- Improved CoreML compilation flags handling in whisper installer
|
38
|
+
|
12
39
|
## [2.33.3] - 2025-08-26
|
13
40
|
|
41
|
+
### Changed
|
42
|
+
- Version bump for testing installer fixes
|
43
|
+
|
14
44
|
## [2.33.2] - 2025-08-26
|
15
45
|
|
46
|
+
### Fixed
|
47
|
+
- **Whisper service installation**
|
48
|
+
- Corrected plist template path in whisper installer
|
49
|
+
- Fixed CoreML support compilation flags (disabled then re-enabled after testing)
|
50
|
+
- Removed duplicate inline plist fallback to prevent template divergence
|
51
|
+
|
16
52
|
## [2.33.1] - 2025-08-26
|
17
53
|
|
18
54
|
### Fixed
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: voice-mode
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.34.0
|
4
4
|
Summary: VoiceMode - Voice interaction capabilities for AI assistants (formerly voice-mcp)
|
5
5
|
Project-URL: Homepage, https://github.com/mbailey/voicemode
|
6
6
|
Project-URL: Repository, https://github.com/mbailey/voicemode
|
{voice_mode-2.33.4 → voice_mode-2.34.0}/voice_mode/templates/launchd/com.voicemode.whisper.plist
RENAMED
@@ -9,18 +9,18 @@
|
|
9
9
|
<string>com.voicemode.whisper</string>
|
10
10
|
<key>ProgramArguments</key>
|
11
11
|
<array>
|
12
|
-
<string
|
12
|
+
<string>{START_SCRIPT_PATH}</string>
|
13
13
|
</array>
|
14
14
|
<key>RunAtLoad</key>
|
15
15
|
<true/>
|
16
16
|
<key>KeepAlive</key>
|
17
17
|
<true/>
|
18
18
|
<key>StandardOutPath</key>
|
19
|
-
<string
|
19
|
+
<string>{LOG_DIR}/whisper/whisper.out.log</string>
|
20
20
|
<key>StandardErrorPath</key>
|
21
|
-
<string
|
21
|
+
<string>{LOG_DIR}/whisper/whisper.err.log</string>
|
22
22
|
<key>WorkingDirectory</key>
|
23
|
-
<string
|
23
|
+
<string>{INSTALL_DIR}</string>
|
24
24
|
<key>EnvironmentVariables</key>
|
25
25
|
<dict>
|
26
26
|
<key>PATH</key>
|
@@ -22,6 +22,152 @@ from voice_mode.utils.migration_helpers import auto_migrate_if_needed
|
|
22
22
|
logger = logging.getLogger("voice-mode")
|
23
23
|
|
24
24
|
|
25
|
+
async def update_kokoro_service_files(
|
26
|
+
install_dir: str,
|
27
|
+
voicemode_dir: str,
|
28
|
+
port: int,
|
29
|
+
start_script_path: str,
|
30
|
+
auto_enable: Optional[bool] = None
|
31
|
+
) -> Dict[str, Any]:
|
32
|
+
"""Update service files (plist/systemd) for kokoro service.
|
33
|
+
|
34
|
+
This function updates the service files without reinstalling kokoro itself.
|
35
|
+
It ensures paths are properly expanded and templates are up to date.
|
36
|
+
|
37
|
+
Returns:
|
38
|
+
Dict with success status and details about what was updated
|
39
|
+
"""
|
40
|
+
system = platform.system()
|
41
|
+
result = {"success": False, "updated": False}
|
42
|
+
|
43
|
+
# Create log directory
|
44
|
+
log_dir = os.path.join(voicemode_dir, 'logs', 'kokoro')
|
45
|
+
os.makedirs(log_dir, exist_ok=True)
|
46
|
+
|
47
|
+
if system == "Darwin":
|
48
|
+
logger.info("Updating launchagent for kokoro...")
|
49
|
+
launchagents_dir = os.path.expanduser("~/Library/LaunchAgents")
|
50
|
+
os.makedirs(launchagents_dir, exist_ok=True)
|
51
|
+
|
52
|
+
plist_name = "com.voicemode.kokoro.plist"
|
53
|
+
plist_path = os.path.join(launchagents_dir, plist_name)
|
54
|
+
|
55
|
+
plist_content = f"""<?xml version="1.0" encoding="UTF-8"?>
|
56
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
57
|
+
<plist version="1.0">
|
58
|
+
<dict>
|
59
|
+
<key>Label</key>
|
60
|
+
<string>com.voicemode.kokoro</string>
|
61
|
+
<key>ProgramArguments</key>
|
62
|
+
<array>
|
63
|
+
<string>{start_script_path}</string>
|
64
|
+
</array>
|
65
|
+
<key>WorkingDirectory</key>
|
66
|
+
<string>{install_dir}</string>
|
67
|
+
<key>RunAtLoad</key>
|
68
|
+
<true/>
|
69
|
+
<key>KeepAlive</key>
|
70
|
+
<true/>
|
71
|
+
<key>StandardOutPath</key>
|
72
|
+
<string>{os.path.join(voicemode_dir, 'logs', 'kokoro', 'kokoro.log')}</string>
|
73
|
+
<key>StandardErrorPath</key>
|
74
|
+
<string>{os.path.join(voicemode_dir, 'logs', 'kokoro', 'kokoro.error.log')}</string>
|
75
|
+
<key>EnvironmentVariables</key>
|
76
|
+
<dict>
|
77
|
+
<key>PATH</key>
|
78
|
+
<string>{os.path.expanduser("~/.local/bin")}:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/homebrew/bin</string>
|
79
|
+
</dict>
|
80
|
+
</dict>
|
81
|
+
</plist>"""
|
82
|
+
|
83
|
+
# Unload if already loaded (ignore errors)
|
84
|
+
try:
|
85
|
+
subprocess.run(["launchctl", "unload", plist_path], capture_output=True)
|
86
|
+
except:
|
87
|
+
pass
|
88
|
+
|
89
|
+
# Write updated plist
|
90
|
+
with open(plist_path, 'w') as f:
|
91
|
+
f.write(plist_content)
|
92
|
+
|
93
|
+
result["success"] = True
|
94
|
+
result["updated"] = True
|
95
|
+
result["plist_path"] = plist_path
|
96
|
+
|
97
|
+
# Handle auto_enable if specified
|
98
|
+
if auto_enable is None:
|
99
|
+
auto_enable = SERVICE_AUTO_ENABLE
|
100
|
+
|
101
|
+
if auto_enable:
|
102
|
+
logger.info("Auto-enabling kokoro service...")
|
103
|
+
from voice_mode.tools.service import enable_service
|
104
|
+
enable_result = await enable_service("kokoro")
|
105
|
+
if "✅" in enable_result:
|
106
|
+
result["enabled"] = True
|
107
|
+
else:
|
108
|
+
logger.warning(f"Auto-enable failed: {enable_result}")
|
109
|
+
result["enabled"] = False
|
110
|
+
|
111
|
+
elif system == "Linux":
|
112
|
+
logger.info("Updating systemd user service for kokoro...")
|
113
|
+
systemd_user_dir = os.path.expanduser("~/.config/systemd/user")
|
114
|
+
os.makedirs(systemd_user_dir, exist_ok=True)
|
115
|
+
|
116
|
+
service_name = "voicemode-kokoro.service"
|
117
|
+
service_path = os.path.join(systemd_user_dir, service_name)
|
118
|
+
|
119
|
+
service_content = f"""[Unit]
|
120
|
+
Description=VoiceMode Kokoro TTS Service
|
121
|
+
After=network.target
|
122
|
+
[Service]
|
123
|
+
Type=simple
|
124
|
+
ExecStart={start_script_path}
|
125
|
+
Restart=on-failure
|
126
|
+
RestartSec=10
|
127
|
+
WorkingDirectory={install_dir}
|
128
|
+
StandardOutput=append:{os.path.join(voicemode_dir, 'logs', 'kokoro', 'kokoro.log')}
|
129
|
+
StandardError=append:{os.path.join(voicemode_dir, 'logs', 'kokoro', 'kokoro.error.log')}
|
130
|
+
Environment="PATH=/usr/local/bin:/usr/bin:/bin:/home/m/.local/bin"
|
131
|
+
[Install]
|
132
|
+
WantedBy=default.target
|
133
|
+
"""
|
134
|
+
|
135
|
+
with open(service_path, 'w') as f:
|
136
|
+
f.write(service_content)
|
137
|
+
|
138
|
+
# Reload systemd
|
139
|
+
try:
|
140
|
+
subprocess.run(["systemctl", "--user", "daemon-reload"], check=True)
|
141
|
+
result["success"] = True
|
142
|
+
result["updated"] = True
|
143
|
+
result["service_path"] = service_path
|
144
|
+
except subprocess.CalledProcessError as e:
|
145
|
+
logger.warning(f"Failed to reload systemd: {e}")
|
146
|
+
result["success"] = True # Still consider it success if file was written
|
147
|
+
result["updated"] = True
|
148
|
+
result["service_path"] = service_path
|
149
|
+
|
150
|
+
# Handle auto_enable if specified
|
151
|
+
if auto_enable is None:
|
152
|
+
auto_enable = SERVICE_AUTO_ENABLE
|
153
|
+
|
154
|
+
if auto_enable:
|
155
|
+
logger.info("Auto-enabling kokoro service...")
|
156
|
+
from voice_mode.tools.service import enable_service
|
157
|
+
enable_result = await enable_service("kokoro")
|
158
|
+
if "✅" in enable_result:
|
159
|
+
result["enabled"] = True
|
160
|
+
else:
|
161
|
+
logger.warning(f"Auto-enable failed: {enable_result}")
|
162
|
+
result["enabled"] = False
|
163
|
+
|
164
|
+
else:
|
165
|
+
result["success"] = False
|
166
|
+
result["error"] = f"Unsupported platform: {system}"
|
167
|
+
|
168
|
+
return result
|
169
|
+
|
170
|
+
|
25
171
|
@mcp.tool()
|
26
172
|
async def kokoro_install(
|
27
173
|
install_dir: Optional[str] = None,
|
@@ -101,13 +247,58 @@ async def kokoro_install(
|
|
101
247
|
# Check if the requested version is already installed
|
102
248
|
if is_version_installed(Path(install_dir), version):
|
103
249
|
current_version = get_current_version(Path(install_dir))
|
250
|
+
|
251
|
+
# Determine which start script to use
|
252
|
+
system = platform.system()
|
253
|
+
if system == "Darwin":
|
254
|
+
start_script_name = "start-gpu_mac.sh"
|
255
|
+
else:
|
256
|
+
start_script_name = "start-gpu.sh" # Default to GPU version
|
257
|
+
|
258
|
+
start_script_path = os.path.join(install_dir, start_script_name)
|
259
|
+
|
260
|
+
# If a custom port is requested, create custom start script
|
261
|
+
if port != 8880 and os.path.exists(start_script_path):
|
262
|
+
logger.info(f"Creating custom start script for port {port}")
|
263
|
+
with open(start_script_path, 'r') as f:
|
264
|
+
script_content = f.read()
|
265
|
+
modified_script = script_content.replace("--port 8880", f"--port {port}")
|
266
|
+
custom_script_name = f"start-custom-{port}.sh"
|
267
|
+
custom_script_path = os.path.join(install_dir, custom_script_name)
|
268
|
+
with open(custom_script_path, 'w') as f:
|
269
|
+
f.write(modified_script)
|
270
|
+
os.chmod(custom_script_path, 0o755)
|
271
|
+
start_script_path = custom_script_path
|
272
|
+
|
273
|
+
# Always update service files even if kokoro is already installed
|
274
|
+
logger.info("Kokoro is already installed, updating service files...")
|
275
|
+
service_update_result = await update_kokoro_service_files(
|
276
|
+
install_dir=install_dir,
|
277
|
+
voicemode_dir=voicemode_dir,
|
278
|
+
port=port,
|
279
|
+
start_script_path=start_script_path,
|
280
|
+
auto_enable=auto_enable
|
281
|
+
)
|
282
|
+
|
283
|
+
# Build response message
|
284
|
+
message = f"kokoro-fastapi version {current_version} already installed."
|
285
|
+
if service_update_result.get("updated"):
|
286
|
+
message += " Service files updated."
|
287
|
+
if service_update_result.get("enabled"):
|
288
|
+
message += " Service auto-enabled."
|
289
|
+
|
104
290
|
return {
|
105
291
|
"success": True,
|
106
292
|
"install_path": install_dir,
|
107
293
|
"models_path": models_dir,
|
108
294
|
"already_installed": True,
|
295
|
+
"service_files_updated": service_update_result.get("updated", False),
|
109
296
|
"version": current_version,
|
110
|
-
"
|
297
|
+
"plist_path": service_update_result.get("plist_path"),
|
298
|
+
"service_path": service_update_result.get("service_path"),
|
299
|
+
"start_script": start_script_path,
|
300
|
+
"service_url": f"http://127.0.0.1:{port}",
|
301
|
+
"message": message
|
111
302
|
}
|
112
303
|
|
113
304
|
# Check Python version
|
@@ -215,7 +406,21 @@ async def kokoro_install(
|
|
215
406
|
"message": f"Kokoro-fastapi {current_version} installed. Run: cd {install_dir} && ./{os.path.basename(start_script_path)}{' (' + migration_msg + ')' if migration_msg else ''}"
|
216
407
|
}
|
217
408
|
|
218
|
-
# Install
|
409
|
+
# Install/update service files
|
410
|
+
service_update_result = await update_kokoro_service_files(
|
411
|
+
install_dir=install_dir,
|
412
|
+
voicemode_dir=voicemode_dir,
|
413
|
+
port=port,
|
414
|
+
start_script_path=start_script_path,
|
415
|
+
auto_enable=auto_enable
|
416
|
+
)
|
417
|
+
|
418
|
+
if not service_update_result.get("success"):
|
419
|
+
logger.error(f"Failed to update service files: {service_update_result.get('error', 'Unknown error')}")
|
420
|
+
result["error"] = f"Service file update failed: {service_update_result.get('error', 'Unknown error')}"
|
421
|
+
return result
|
422
|
+
|
423
|
+
# Update result with service file information based on platform
|
219
424
|
if system == "Darwin":
|
220
425
|
logger.info("Installing launchagent for automatic startup...")
|
221
426
|
launchagents_dir = os.path.expanduser("~/Library/LaunchAgents")
|