[IMPROVED] Mejorar interacción con Claude Code en claude_voice.py
- 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 <noreply@anthropic.com>
This commit is contained in:
parent
ccdfa68813
commit
c35f705537
2 changed files with 118 additions and 15 deletions
|
@ -180,6 +180,12 @@ bin/claude_voice.py --list-devices
|
||||||
# Especificar dispositivo de audio por ID
|
# Especificar dispositivo de audio por ID
|
||||||
bin/claude_voice.py --device 1
|
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)
|
# Enviar texto directamente (sin voz)
|
||||||
bin/claude_voice.py --text "Cómo puedo crear un archivo en Python"
|
bin/claude_voice.py --text "Cómo puedo crear un archivo en Python"
|
||||||
```
|
```
|
||||||
|
|
|
@ -243,7 +243,7 @@ def recognize_speech(language="es-ES"):
|
||||||
|
|
||||||
return final_result
|
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"""
|
"""Envía el texto reconocido a Claude Code"""
|
||||||
if not text:
|
if not text:
|
||||||
return False
|
return False
|
||||||
|
@ -255,25 +255,76 @@ def send_to_claude(text, silent=False):
|
||||||
# Usar la ruta de instalación de Claude Code
|
# 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"
|
claude_cmd = "claude" if os.system("which claude > /dev/null 2>&1") == 0 else "/usr/local/bin/claude"
|
||||||
|
|
||||||
|
# Mostrar que estamos esperando respuesta
|
||||||
|
print(f"{Colors.BLUE}[Claude Voice]{Colors.END} {Colors.YELLOW}Esperando respuesta de Claude Code...{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
|
# Enviar el texto como entrada a Claude
|
||||||
result = subprocess.run([claude_cmd, text],
|
result = subprocess.run([claude_cmd, text],
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.PIPE,
|
stderr=subprocess.PIPE,
|
||||||
text=True,
|
text=True,
|
||||||
|
timeout=timeout,
|
||||||
check=False)
|
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:
|
if result.returncode != 0:
|
||||||
print(f"{Colors.RED}Error al ejecutar Claude Code: {result.stderr}{Colors.END}")
|
print(f"\n{Colors.RED}Error al ejecutar Claude Code: {result.stderr}{Colors.END}")
|
||||||
return False
|
|
||||||
return True
|
|
||||||
except Exception as e:
|
|
||||||
print(f"{Colors.RED}Error al ejecutar Claude Code: {e}{Colors.END}")
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def interactive_mode(language="es-ES", continuous=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
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
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, timeout=60, device=None):
|
||||||
"""Modo interactivo que escucha continuamente comandos de voz"""
|
"""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.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 '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:
|
try:
|
||||||
while True:
|
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}")
|
print(f"{Colors.BLUE}[Claude Voice]{Colors.END} {Colors.YELLOW}Saliendo del modo de voz...{Colors.END}")
|
||||||
break
|
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
|
# 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
|
# Si no es modo continuo, salir después del primer comando exitoso
|
||||||
if not continuous and success:
|
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('-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('-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('-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-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('--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')
|
parser.add_argument('--install-deps', action='store_true', help='Instalar dependencias')
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
@ -406,13 +481,35 @@ def main():
|
||||||
list_languages()
|
list_languages()
|
||||||
return
|
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
|
# Enviar texto directo si se proporciona
|
||||||
if args.text:
|
if args.text:
|
||||||
send_to_claude(args.text, args.silent)
|
send_to_claude(args.text, args.silent, args.timeout)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Modo interactivo con reconocimiento de voz
|
# 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__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
Loading…
Reference in a new issue