From c35f705537676689e4708590fffb1eb7df0f9271 Mon Sep 17 00:00:00 2001 From: "Mauro Rosero P." Date: Sun, 30 Mar 2025 23:13:04 -0500 Subject: [PATCH] =?UTF-8?q?[IMPROVED]=20Mejorar=20interacci=C3=B3n=20con?= =?UTF-8?q?=20Claude=20Code=20en=20claude=5Fvoice.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Añadido indicador de progreso animado durante la espera de respuestas - Implementación de timeout configurable para evitar esperas indefinidas - Nuevo comando de voz 'versión' para verificar la versión de Claude Code - Nueva opción --version para consultar directamente la versión instalada - Información más clara sobre el estado de las respuestas - Sugerencias de solución para problemas comunes - Actualizado README con las nuevas características 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- README.md | 6 +++ bin/claude_voice.py | 127 ++++++++++++++++++++++++++++++++++++++------ 2 files changed, 118 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 9d84526..356664b 100644 --- a/README.md +++ b/README.md @@ -180,6 +180,12 @@ bin/claude_voice.py --list-devices # Especificar dispositivo de audio por ID bin/claude_voice.py --device 1 +# Ver la versión de Claude Code instalada +bin/claude_voice.py --version + +# Modificar tiempo máximo de espera para respuestas (en segundos) +bin/claude_voice.py --timeout 30 + # Enviar texto directamente (sin voz) bin/claude_voice.py --text "Cómo puedo crear un archivo en Python" ``` diff --git a/bin/claude_voice.py b/bin/claude_voice.py index 83dca6f..60a6801 100755 --- a/bin/claude_voice.py +++ b/bin/claude_voice.py @@ -243,7 +243,7 @@ def recognize_speech(language="es-ES"): return final_result -def send_to_claude(text, silent=False): +def send_to_claude(text, silent=False, timeout=60): """Envía el texto reconocido a Claude Code""" if not text: return False @@ -255,25 +255,76 @@ def send_to_claude(text, silent=False): # Usar la ruta de instalación de Claude Code claude_cmd = "claude" if os.system("which claude > /dev/null 2>&1") == 0 else "/usr/local/bin/claude" - # Enviar el texto como entrada a Claude - result = subprocess.run([claude_cmd, text], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - text=True, - check=False) + # Mostrar que estamos esperando respuesta + print(f"{Colors.BLUE}[Claude Voice]{Colors.END} {Colors.YELLOW}Esperando respuesta de Claude Code...{Colors.END}") - if result.returncode != 0: - print(f"{Colors.RED}Error al ejecutar Claude Code: {result.stderr}{Colors.END}") + # Usar un timer para mostrar actividad + start_time = time.time() + progress_chars = ['⣾', '⣽', '⣻', '⢿', '⡿', '⣟', '⣯', '⣷'] + progress_thread_active = True + + def show_progress(): + i = 0 + while progress_thread_active: + sys.stdout.write(f"\r{Colors.BLUE}[Claude Voice]{Colors.END} {Colors.YELLOW}Esperando {progress_chars[i]} {int(time.time() - start_time)}s{Colors.END}") + sys.stdout.flush() + i = (i + 1) % len(progress_chars) + time.sleep(0.1) + # Limpiar la línea cuando terminamos + sys.stdout.write("\r" + " " * 60 + "\r") + sys.stdout.flush() + + # Iniciar hilo de progreso + progress_thread = threading.Thread(target=show_progress) + progress_thread.daemon = True + progress_thread.start() + + try: + # Enviar el texto como entrada a Claude + result = subprocess.run([claude_cmd, text], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + timeout=timeout, + check=False) + + # Detener el hilo de progreso + progress_thread_active = False + progress_thread.join(1.0) # Esperar a que termine, pero con timeout + + # Verificar resultado + if result.returncode != 0: + print(f"\n{Colors.RED}Error al ejecutar Claude Code: {result.stderr}{Colors.END}") + return False + + # Mostrar información sobre la respuesta + print(f"\n{Colors.GREEN}Claude Code ha respondido exitosamente.{Colors.END}") + return True + + except subprocess.TimeoutExpired: + # Detener el hilo de progreso + progress_thread_active = False + progress_thread.join(1.0) + + print(f"\n{Colors.RED}Tiempo de espera agotado. Claude Code está tardando demasiado en responder.{Colors.END}") + print(f"{Colors.YELLOW}La consulta fue enviada, pero puedes verificar la terminal de Claude Code para ver la respuesta.{Colors.END}") return False - return True + except Exception as e: - print(f"{Colors.RED}Error al ejecutar Claude Code: {e}{Colors.END}") + print(f"\n{Colors.RED}Error al ejecutar Claude Code: {e}{Colors.END}") + + # Sugerir soluciones comunes + if "No such file or directory" in str(e): + print(f"{Colors.YELLOW}No se encontró el comando 'claude'. Asegúrate de tener Claude Code instalado correctamente.{Colors.END}") + print(f"{Colors.YELLOW}Prueba instalarlo con: bin/claude_install.sh{Colors.END}") + return False -def interactive_mode(language="es-ES", continuous=False): +def interactive_mode(language="es-ES", continuous=False, timeout=60, device=None): """Modo interactivo que escucha continuamente comandos de voz""" print(f"{Colors.BLUE}[Claude Voice]{Colors.END} {Colors.GREEN}Modo interactivo iniciado. Di tus instrucciones para Claude Code.{Colors.END}") print(f"{Colors.BLUE}[Claude Voice]{Colors.END} {Colors.YELLOW}Di 'salir' o 'terminar' para finalizar{Colors.END}") + print(f"{Colors.BLUE}[Claude Voice]{Colors.END} {Colors.YELLOW}Di 'versión' para conocer la versión de Claude Code{Colors.END}") try: while True: @@ -288,8 +339,30 @@ def interactive_mode(language="es-ES", continuous=False): print(f"{Colors.BLUE}[Claude Voice]{Colors.END} {Colors.YELLOW}Saliendo del modo de voz...{Colors.END}") break + # Verificar comandos especiales + if text.lower() in ["versión", "version"]: + try: + # Usar la ruta de instalación de Claude Code + claude_cmd = "claude" if os.system("which claude > /dev/null 2>&1") == 0 else "/usr/local/bin/claude" + + # Obtener versión + result = subprocess.run([claude_cmd, "--version"], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + check=False) + + if result.returncode == 0: + version = result.stdout.strip() or "Desconocida" + print(f"{Colors.BLUE}[Claude Voice]{Colors.END} {Colors.GREEN}Versión de Claude Code: {Colors.BOLD}{version}{Colors.END}") + else: + print(f"{Colors.RED}Error al obtener versión: {result.stderr}{Colors.END}") + except Exception as e: + print(f"{Colors.RED}Error al ejecutar Claude Code: {e}{Colors.END}") + continue + # Enviar a Claude Code - success = send_to_claude(text) + success = send_to_claude(text, timeout=timeout) # Si no es modo continuo, salir después del primer comando exitoso if not continuous and success: @@ -361,8 +434,10 @@ def main(): parser.add_argument('-t', '--text', help='Texto a enviar directamente (sin reconocimiento de voz)') parser.add_argument('-s', '--silent', action='store_true', help='Modo silencioso - no muestra mensajes extra') parser.add_argument('-d', '--device', type=int, help='ID del dispositivo de audio a utilizar') + parser.add_argument('--timeout', type=int, default=60, help='Tiempo máximo de espera para respuesta de Claude Code (segundos)') parser.add_argument('--list-devices', action='store_true', help='Listar dispositivos de audio disponibles') parser.add_argument('--list-languages', action='store_true', help='Listar idiomas soportados') + parser.add_argument('--version', action='store_true', help='Mostrar versión de Claude Code') parser.add_argument('--install-deps', action='store_true', help='Instalar dependencias') args = parser.parse_args() @@ -405,14 +480,36 @@ def main(): if args.list_languages: list_languages() return + + # Mostrar versión de Claude Code si se solicita + if args.version: + try: + # Usar la ruta de instalación de Claude Code + claude_cmd = "claude" if os.system("which claude > /dev/null 2>&1") == 0 else "/usr/local/bin/claude" + + # Obtener versión + result = subprocess.run([claude_cmd, "--version"], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + check=False) + + if result.returncode == 0: + version = result.stdout.strip() or "Desconocida" + print(f"{Colors.BLUE}[Claude Voice]{Colors.END} {Colors.GREEN}Versión de Claude Code: {Colors.BOLD}{version}{Colors.END}") + else: + print(f"{Colors.RED}Error al obtener versión: {result.stderr}{Colors.END}") + except Exception as e: + print(f"{Colors.RED}Error al ejecutar Claude Code: {e}{Colors.END}") + return # Enviar texto directo si se proporciona if args.text: - send_to_claude(args.text, args.silent) + send_to_claude(args.text, args.silent, args.timeout) return # Modo interactivo con reconocimiento de voz - interactive_mode(args.language, args.continuous) + interactive_mode(args.language, args.continuous, args.timeout, args.device) if __name__ == "__main__": main() \ No newline at end of file