voice-mode 2.25.0__tar.gz → 2.26.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.
Files changed (107) hide show
  1. {voice_mode-2.25.0 → voice_mode-2.26.0}/.gitignore +3 -0
  2. {voice_mode-2.25.0 → voice_mode-2.26.0}/CHANGELOG.md +24 -0
  3. {voice_mode-2.25.0 → voice_mode-2.26.0}/PKG-INFO +1 -1
  4. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/__version__.py +1 -1
  5. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/cli.py +162 -0
  6. {voice_mode-2.25.0 → voice_mode-2.26.0}/README.md +0 -0
  7. {voice_mode-2.25.0 → voice_mode-2.26.0}/build_hooks.py +0 -0
  8. {voice_mode-2.25.0 → voice_mode-2.26.0}/pyproject.toml +0 -0
  9. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/__init__.py +0 -0
  10. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/__main__.py +0 -0
  11. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/cli_commands/__init__.py +0 -0
  12. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/cli_commands/exchanges.py +0 -0
  13. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/config.py +0 -0
  14. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/conversation_logger.py +0 -0
  15. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/core.py +0 -0
  16. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/data/versions.json +0 -0
  17. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/exchanges/__init__.py +0 -0
  18. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/exchanges/conversations.py +0 -0
  19. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/exchanges/filters.py +0 -0
  20. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/exchanges/formatters.py +0 -0
  21. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/exchanges/models.py +0 -0
  22. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/exchanges/reader.py +0 -0
  23. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/exchanges/stats.py +0 -0
  24. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/frontend/README.md +0 -0
  25. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/frontend/app/api/connection-details/route.ts +0 -0
  26. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/frontend/app/favicon.ico +0 -0
  27. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/frontend/app/globals.css +0 -0
  28. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/frontend/app/layout.tsx +0 -0
  29. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/frontend/app/page.tsx +0 -0
  30. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/frontend/components/CloseIcon.tsx +0 -0
  31. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/frontend/components/NoAgentNotification.tsx +0 -0
  32. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/frontend/components/TranscriptionView.tsx +0 -0
  33. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/frontend/hooks/useCombinedTranscriptions.ts +0 -0
  34. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/frontend/hooks/useLocalMicTrack.ts +0 -0
  35. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/frontend/next-env.d.ts +0 -0
  36. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/frontend/next.config.mjs +0 -0
  37. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/frontend/package-lock.json +0 -0
  38. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/frontend/package.json +0 -0
  39. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/frontend/pnpm-lock.yaml +0 -0
  40. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/frontend/postcss.config.mjs +0 -0
  41. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/frontend/tailwind.config.ts +0 -0
  42. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/frontend/tsconfig.json +0 -0
  43. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/prompts/README.md +0 -0
  44. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/prompts/__init__.py +0 -0
  45. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/prompts/converse.py +0 -0
  46. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/prompts/release_notes.py +0 -0
  47. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/prompts/services.py +0 -0
  48. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/provider_discovery.py +0 -0
  49. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/providers.py +0 -0
  50. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/resources/__init__.py +0 -0
  51. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/resources/audio_files.py +0 -0
  52. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/resources/changelog.py +0 -0
  53. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/resources/configuration.py +0 -0
  54. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/resources/statistics.py +0 -0
  55. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/resources/version.py +0 -0
  56. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/resources/whisper_models.py +0 -0
  57. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/server.py +0 -0
  58. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/shared.py +0 -0
  59. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/simple_failover.py +0 -0
  60. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/statistics.py +0 -0
  61. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/streaming.py +0 -0
  62. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/templates/launchd/com.voicemode.frontend.plist +0 -0
  63. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/templates/launchd/com.voicemode.kokoro.plist +0 -0
  64. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/templates/launchd/com.voicemode.livekit.plist +0 -0
  65. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/templates/launchd/com.voicemode.whisper.plist +0 -0
  66. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/templates/launchd/start-kokoro-with-health-check.sh +0 -0
  67. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/templates/launchd/start-whisper-with-health-check.sh +0 -0
  68. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/templates/systemd/voicemode-frontend.service +0 -0
  69. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/templates/systemd/voicemode-kokoro.service +0 -0
  70. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/templates/systemd/voicemode-livekit.service +0 -0
  71. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/templates/systemd/voicemode-whisper.service +0 -0
  72. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/tools/__init__.py +0 -0
  73. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/tools/configuration_management.py +0 -0
  74. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/tools/converse.py +0 -0
  75. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/tools/dependencies.py +0 -0
  76. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/tools/devices.py +0 -0
  77. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/tools/diagnostics.py +0 -0
  78. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/tools/providers.py +0 -0
  79. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/tools/service.py +0 -0
  80. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/tools/services/kokoro/install.py +0 -0
  81. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/tools/services/kokoro/uninstall.py +0 -0
  82. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/tools/services/list_versions.py +0 -0
  83. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/tools/services/livekit/__init__.py +0 -0
  84. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/tools/services/livekit/frontend.py +0 -0
  85. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/tools/services/livekit/install.py +0 -0
  86. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/tools/services/livekit/production_server.py +0 -0
  87. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/tools/services/livekit/uninstall.py +0 -0
  88. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/tools/services/version_info.py +0 -0
  89. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/tools/services/whisper/download_model.py +0 -0
  90. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/tools/services/whisper/install.py +0 -0
  91. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/tools/services/whisper/uninstall.py +0 -0
  92. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/tools/statistics.py +0 -0
  93. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/tools/voice_registry.py +0 -0
  94. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/utils/__init__.py +0 -0
  95. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/utils/audio_diagnostics.py +0 -0
  96. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/utils/event_logger.py +0 -0
  97. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/utils/ffmpeg_check.py +0 -0
  98. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/utils/format_migration.py +0 -0
  99. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/utils/gpu_detection.py +0 -0
  100. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/utils/migration_helpers.py +0 -0
  101. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/utils/services/common.py +0 -0
  102. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/utils/services/kokoro_helpers.py +0 -0
  103. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/utils/services/livekit_helpers.py +0 -0
  104. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/utils/services/whisper_helpers.py +0 -0
  105. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/utils/version_helpers.py +0 -0
  106. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/version.py +0 -0
  107. {voice_mode-2.25.0 → voice_mode-2.26.0}/voice_mode/voice_preferences.py +0 -0
@@ -108,3 +108,6 @@ docs/README_PROCESSED.md
108
108
  # Test files
109
109
  test_preferences.py
110
110
  testdir/
111
+
112
+ # Profiling output
113
+ *.prof
@@ -7,6 +7,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.26.0] - 2025-08-18
11
+
12
+ ### Added
13
+ - **CLI converse command** - Direct voice conversations from the command line
14
+ - New `voice-mode converse` command for testing voice interactions
15
+ - Supports all MCP tool options (voice, speed, audio format, etc.)
16
+ - Continuous conversation mode with `--continuous` flag
17
+ - Useful for testing TTS/STT services without MCP client
18
+ - Full control over voice parameters and silence detection
19
+
20
+ ### Changed
21
+ - **Gitignore update** - Added `*.prof` files to gitignore for profiling output
22
+
23
+ ## [2.25.1] - 2025-08-18
24
+
25
+ ### Fixed
26
+ - **WSL2 detection display** - Fixed incorrect WSL2 label on non-WSL systems
27
+ - Parameter expansion bug was showing "(WSL2)" on all Linux systems
28
+ - Now properly checks if IS_WSL equals "true" before adding WSL2 label
29
+ - Fixes false positive on Fedora and other Linux distributions
30
+ - Complements previous detection fix from 2025-08-17
31
+
32
+ ## [git push origin -v2.25.0] - 2025-08-18
33
+
10
34
  ## [2.25.0] - 2025-08-18
11
35
 
12
36
  ### Fixed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: voice-mode
3
- Version: 2.25.0
3
+ Version: 2.26.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
@@ -1,3 +1,3 @@
1
1
  # This file is automatically updated by 'make release'
2
2
  # Do not edit manually
3
- __version__ = "2.25.0"
3
+ __version__ = "2.26.0"
@@ -994,3 +994,165 @@ cli.add_command(exchanges_cmd.exchanges)
994
994
  voice_mode_main_cli.add_command(exchanges_cmd.exchanges)
995
995
 
996
996
 
997
+ # Converse command - direct voice conversation from CLI
998
+ @voice_mode_main_cli.command()
999
+ @click.option('--message', '-m', default="Hello! How can I help you today?", help='Initial message to speak')
1000
+ @click.option('--wait/--no-wait', default=True, help='Wait for response after speaking')
1001
+ @click.option('--duration', '-d', type=float, default=30.0, help='Listen duration in seconds')
1002
+ @click.option('--min-duration', type=float, default=2.0, help='Minimum listen duration before silence detection')
1003
+ @click.option('--transport', type=click.Choice(['auto', 'local', 'livekit']), default='auto', help='Transport method')
1004
+ @click.option('--room-name', default='', help='LiveKit room name (for livekit transport)')
1005
+ @click.option('--voice', help='TTS voice to use (e.g., nova, shimmer, af_sky)')
1006
+ @click.option('--tts-provider', type=click.Choice(['openai', 'kokoro']), help='TTS provider')
1007
+ @click.option('--tts-model', help='TTS model (e.g., tts-1, tts-1-hd)')
1008
+ @click.option('--tts-instructions', help='Tone/style instructions for gpt-4o-mini-tts')
1009
+ @click.option('--audio-feedback/--no-audio-feedback', default=None, help='Enable/disable audio feedback')
1010
+ @click.option('--audio-format', help='Audio format (pcm, mp3, wav, flac, aac, opus)')
1011
+ @click.option('--disable-silence-detection', is_flag=True, help='Disable silence detection')
1012
+ @click.option('--speed', type=float, help='Speech rate (0.25 to 4.0)')
1013
+ @click.option('--vad-aggressiveness', type=int, help='VAD aggressiveness (0-3)')
1014
+ @click.option('--skip-tts/--no-skip-tts', default=None, help='Skip TTS and only show text')
1015
+ @click.option('--continuous', '-c', is_flag=True, help='Continuous conversation mode')
1016
+ def converse(message, wait, duration, min_duration, transport, room_name, voice, tts_provider,
1017
+ tts_model, tts_instructions, audio_feedback, audio_format, disable_silence_detection,
1018
+ speed, vad_aggressiveness, skip_tts, continuous):
1019
+ """Have a voice conversation directly from the command line.
1020
+
1021
+ Examples:
1022
+
1023
+ # Simple conversation
1024
+ voice-mode converse
1025
+
1026
+ # Speak a message without waiting
1027
+ voice-mode converse -m "Hello there!" --no-wait
1028
+
1029
+ # Continuous conversation mode
1030
+ voice-mode converse --continuous
1031
+
1032
+ # Use specific voice
1033
+ voice-mode converse --voice nova
1034
+ """
1035
+ from voice_mode.tools.converse import converse as converse_fn
1036
+
1037
+ async def run_conversation():
1038
+ """Run the conversation asynchronously."""
1039
+ try:
1040
+ if continuous:
1041
+ # Continuous conversation mode
1042
+ click.echo("🎤 Starting continuous conversation mode...")
1043
+ click.echo(" Press Ctrl+C to exit\n")
1044
+
1045
+ # First message
1046
+ result = await converse_fn.fn(
1047
+ message=message,
1048
+ wait_for_response=True,
1049
+ listen_duration=duration,
1050
+ min_listen_duration=min_duration,
1051
+ transport=transport,
1052
+ room_name=room_name,
1053
+ voice=voice,
1054
+ tts_provider=tts_provider,
1055
+ tts_model=tts_model,
1056
+ tts_instructions=tts_instructions,
1057
+ audio_feedback=audio_feedback,
1058
+ audio_feedback_style=None,
1059
+ audio_format=audio_format,
1060
+ disable_silence_detection=disable_silence_detection,
1061
+ speed=speed,
1062
+ vad_aggressiveness=vad_aggressiveness,
1063
+ skip_tts=skip_tts
1064
+ )
1065
+
1066
+ if result and "Voice response:" in result:
1067
+ click.echo(f"You: {result.split('Voice response:')[1].split('|')[0].strip()}")
1068
+
1069
+ # Continue conversation
1070
+ while True:
1071
+ # Wait for user's next input
1072
+ result = await converse_fn.fn(
1073
+ message="", # Empty message for listening only
1074
+ wait_for_response=True,
1075
+ listen_duration=duration,
1076
+ min_listen_duration=min_duration,
1077
+ transport=transport,
1078
+ room_name=room_name,
1079
+ voice=voice,
1080
+ tts_provider=tts_provider,
1081
+ tts_model=tts_model,
1082
+ tts_instructions=tts_instructions,
1083
+ audio_feedback=audio_feedback,
1084
+ audio_feedback_style=None,
1085
+ audio_format=audio_format,
1086
+ disable_silence_detection=disable_silence_detection,
1087
+ speed=speed,
1088
+ vad_aggressiveness=vad_aggressiveness,
1089
+ skip_tts=skip_tts
1090
+ )
1091
+
1092
+ if result and "Voice response:" in result:
1093
+ user_text = result.split('Voice response:')[1].split('|')[0].strip()
1094
+ click.echo(f"You: {user_text}")
1095
+
1096
+ # Check for exit commands
1097
+ if user_text.lower() in ['exit', 'quit', 'goodbye', 'bye']:
1098
+ await converse_fn.fn(
1099
+ message="Goodbye!",
1100
+ wait_for_response=False,
1101
+ voice=voice,
1102
+ tts_provider=tts_provider,
1103
+ tts_model=tts_model,
1104
+ audio_format=audio_format,
1105
+ speed=speed,
1106
+ skip_tts=skip_tts
1107
+ )
1108
+ break
1109
+ else:
1110
+ # Single conversation
1111
+ result = await converse_fn.fn(
1112
+ message=message,
1113
+ wait_for_response=wait,
1114
+ listen_duration=duration,
1115
+ min_listen_duration=min_duration,
1116
+ transport=transport,
1117
+ room_name=room_name,
1118
+ voice=voice,
1119
+ tts_provider=tts_provider,
1120
+ tts_model=tts_model,
1121
+ tts_instructions=tts_instructions,
1122
+ audio_feedback=audio_feedback,
1123
+ audio_feedback_style=None,
1124
+ audio_format=audio_format,
1125
+ disable_silence_detection=disable_silence_detection,
1126
+ speed=speed,
1127
+ vad_aggressiveness=vad_aggressiveness,
1128
+ skip_tts=skip_tts
1129
+ )
1130
+
1131
+ # Display result
1132
+ if result:
1133
+ if "Voice response:" in result:
1134
+ # Extract the response text and timing info
1135
+ parts = result.split('|')
1136
+ response_text = result.split('Voice response:')[1].split('|')[0].strip()
1137
+ timing_info = parts[1].strip() if len(parts) > 1 else ""
1138
+
1139
+ click.echo(f"\n📢 Spoke: {message}")
1140
+ if wait:
1141
+ click.echo(f"🎤 Heard: {response_text}")
1142
+ if timing_info:
1143
+ click.echo(f"⏱️ {timing_info}")
1144
+ else:
1145
+ click.echo(result)
1146
+
1147
+ except KeyboardInterrupt:
1148
+ click.echo("\n\n👋 Conversation ended")
1149
+ except Exception as e:
1150
+ click.echo(f"❌ Error: {e}", err=True)
1151
+ import traceback
1152
+ if os.environ.get('VOICEMODE_DEBUG'):
1153
+ traceback.print_exc()
1154
+
1155
+ # Run the async function
1156
+ asyncio.run(run_conversation())
1157
+
1158
+
File without changes
File without changes
File without changes