Skip to content

Refactor: Remove legacy IPC and finalize FastAPI transition#104

Open
cesarszv wants to merge 1 commit intomainfrom
refactor/daemon-cleanup-sota-2026-4075794029776603254
Open

Refactor: Remove legacy IPC and finalize FastAPI transition#104
cesarszv wants to merge 1 commit intomainfrom
refactor/daemon-cleanup-sota-2026-4075794029776603254

Conversation

@cesarszv
Copy link
Collaborator

This PR completes the transition of the Voice2Machine daemon to the SOTA 2026 architecture by removing the legacy Unix Socket IPC system and associated "dead code".

Key changes:

  1. Architecture: Documentation updated to reflect the Feature-Based Modular Monolith. AGENTS.md marks infrastructure/core removal as complete.
  2. Code Cleanup:
    • v2m.main.py is now a pure FastAPI server runner. Deprecated --daemon flag and internal CLI client logic are removed.
    • send_command.py and verify_export_backend.py (legacy IPC) are deleted.
  3. Operations:
    • stop_daemon.sh no longer checks/cleans sockets.
    • health_check.py now verifies daemon health via HTTP (/health) instead of socket PING.
    • cleanup_v2m.sh removed socket/PID file cleanup logic.
    • common.sh removed get_runtime_dir.
  4. Verification:
    • verify_daemon.py is rewritten to act as an HTTP integration test for the FastAPI server.
  5. Dependencies:
    • Removed ollama from pyproject.toml to reduce footprint.

PR created automatically by Jules for task 4075794029776603254 started by @cesarszv

- Removed deprecated Unix Socket IPC implementation.
- Updated documentation (READMEs, AGENTS.md) to reflect Modular Monolith architecture.
- Cleaned up v2m.main.py (removed --daemon, internal CLI).
- Refactored operation scripts (stop_daemon, health_check, cleanup_v2m) to use HTTP/FastAPI instead of sockets.
- Deleted obsolete scripts (send_command.py, verify_export_backend.py).
- Updated verify_daemon.py to test FastAPI endpoints.
- Removed ollama dependency from pyproject.toml.

Co-authored-by: cesarszv <205967966+cesarszv@users.noreply.github.com>
@google-labs-jules
Copy link
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

Copilot AI review requested due to automatic review settings January 27, 2026 04:54
if resp.status_code == 200:
print("✅ Server is UP!")
return True
except requests.RequestException:
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR finalizes the migration of the Voice2Machine daemon from Unix-socket IPC to a FastAPI-based REST architecture, and removes most remaining legacy IPC code and references.

Changes:

  • Simplifies v2m.main into a pure FastAPI server entrypoint and updates backend documentation to describe the new feature-based, REST-first design.
  • Removes legacy Unix socket IPC utilities and scripts (send_command.py, verify_export_backend.py, socket/PID cleanup), updating operational scripts (stop_daemon.sh, cleanup_v2m.sh, health_check.py) to work via HTTP.
  • Rewrites verify_daemon.py into an HTTP-based integration smoke test and trims dependencies by removing the ollama Python package from pyproject.toml.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
apps/daemon/backend/src/v2m/main.py Converts the module into a single-purpose FastAPI server runner (no CLI client / --daemon mode), aligning the entrypoint with the HTTP-only architecture.
apps/daemon/backend/src/v2m/README.md Updates package-level docs to describe the FastAPI/REST API, feature-based layout, and troubleshooting in terms of localhost HTTP instead of Unix sockets.
apps/daemon/backend/scripts/shared/send_command.py Deletes the standalone Unix-socket IPC client script, removing dead code tied to the old transport.
apps/daemon/backend/scripts/shared/common.sh Drops the get_runtime_dir helper, reflecting that scripts no longer manage Unix socket/PID runtime directories.
apps/daemon/backend/scripts/operations/daemon/stop_daemon.sh Updates process matching to stop python -m v2m.main and removes orphan-socket cleanup, consistent with the HTTP daemon.
apps/daemon/backend/scripts/diagnostics/verify_export_backend.py Removes the IPC-based export verification script that depended on Unix sockets and TRANSCRIBE_FILE commands.
apps/daemon/backend/scripts/diagnostics/verify_daemon.py Replaces the legacy client/IPC-based integration test with an HTTP smoke test that starts v2m.main, calls /health, /start, /stop, and /llm/process.
apps/daemon/backend/scripts/diagnostics/health_check.py Switches the daemon responsiveness check from Unix-socket PING to HTTP GET /health, and simplifies zombie detection and cleanup to match the new architecture.
apps/daemon/backend/scripts/development/maintenance/cleanup_v2m.sh Simplifies cleanup to just process and VRAM checks, removing Unix-socket and PID file cleanup that are no longer used.
apps/daemon/backend/pyproject.toml Drops the ollama Python dependency, reducing the backend’s dependency footprint while keeping requests for HTTP diagnostics.
apps/daemon/backend/README.md Aligns the backend quick-start instructions with the FastAPI server entrypoint (python -m v2m.main on localhost:8765).
apps/daemon/backend/AGENTS.md Updates AI-agent instructions and architecture notes to treat FastAPI/REST as the canonical interface, marking legacy infrastructure removal as completed.

import subprocess
import urllib.request
import json
from pathlib import Path
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

El import de Path ya no se utiliza tras eliminar la lógica basada en sockets y ficheros de runtime, por lo que queda como import muerto. Para mantener el script limpio y evitar advertencias de linting, sería mejor eliminar este import si ya no es necesario.

Suggested change
from pathlib import Path

Copilot uses AI. Check for mistakes.
python -m v2m.main PING
python -m v2m.main START_RECORDING
python -m v2m.main STOP_RECORDING
curl -X POST http://localhost:8765/health
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

El ejemplo de quick start usa curl -X POST http://localhost:8765/health, pero el endpoint /health está implementado solo como GET (ver v2m/api/routes/status.py). Esto puede confundir a quien copie el comando tal cual; conviene actualizar el ejemplo para usar una petición GET coherente con la API real.

Suggested change
curl -X POST http://localhost:8765/health
curl http://localhost:8765/health

Copilot uses AI. Check for mistakes.
Comment on lines 71 to 75
daemon_process = subprocess.Popen(
[PYTHON, DAEMON_SCRIPT],
DAEMON_CMD,
env=env,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aquí se lanza el daemon con stdout=subprocess.PIPE y stderr=subprocess.PIPE, pero la salida solo se consume al final en el bloque finally, después de terminar el proceso. Si el servidor escribe suficiente log durante las pruebas, los pipes pueden llenarse y bloquear al proceso hijo, provocando timeouts difíciles de diagnosticar; sería más seguro redirigir la salida a heredar del padre o a un fichero en disco en lugar de usar PIPE sin un lector concurrente.

Copilot uses AI. Check for mistakes.
Comment on lines +139 to +144
print("\nShutting down Daemon...")
daemon_process.terminate()
daemon_process.wait()
try:
daemon_process.wait(timeout=5)
except subprocess.TimeoutExpired:
daemon_process.kill()
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

En el bloque finally se llama incondicionalmente a daemon_process.terminate() y luego a wait(timeout=5), incluso si el proceso ya finalizó por su cuenta. En esa situación terminate() puede lanzar ProcessLookupError y abortar el cleanup, evitando que se impriman los logs; sería más robusto comprobar daemon_process.poll() o capturar específicamente ese error antes de continuar.

Copilot uses AI. Check for mistakes.
Comment on lines +67 to +69
# Set PYTHONPATH to include src
env = os.environ.copy()
env["PYTHONPATH"] = str(BACKEND_DIR / "src")
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Al sobrescribir env["PYTHONPATH"] se descarta cualquier valor previo definido por el usuario o el entorno de CI, lo que puede romper configuraciones existentes. Es más seguro extender el PYTHONPATH actual (por ejemplo, anteponiendo BACKEND_DIR / "src") en lugar de reemplazarlo por completo.

Suggested change
# Set PYTHONPATH to include src
env = os.environ.copy()
env["PYTHONPATH"] = str(BACKEND_DIR / "src")
# Set PYTHONPATH to include src, preserving any existing value
env = os.environ.copy()
existing_pythonpath = env.get("PYTHONPATH")
src_path = str(BACKEND_DIR / "src")
if existing_pythonpath:
env["PYTHONPATH"] = src_path + os.pathsep + existing_pythonpath
else:
env["PYTHONPATH"] = src_path

Copilot uses AI. Check for mistakes.
Comment on lines +126 to +129
if daemon_running:
print(f"{Colors.RED}❌ Proceso corriendo pero API NO responde (posible bloqueo){Colors.NC}")
else:
print(f"{Colors.RED}❌ PID file apunta a proceso muerto: {pid_from_file}{Colors.NC}")
else:
print(f"{Colors.YELLOW}⚠️ PID file no encontrado{Colors.NC}")
print(f"{Colors.YELLOW}⚠️ API no disponible (daemon detenido){Colors.NC}")
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Estas dos líneas tienen un espacio extra de indentación respecto al bloque if daemon_running/else, lo que rompe la alineación visual e incumple el estilo de indentación uniforme de 4 espacios. Conviene ajustar la indentación para que los print queden al mismo nivel dentro de cada rama del condicional.

Copilot uses AI. Check for mistakes.
Comment on lines +59 to +60
except requests.RequestException:
pass
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'except' clause does nothing but pass and there is no explanatory comment.

Suggested change
except requests.RequestException:
pass
except requests.RequestException as exc:
print(f"Health check request failed on attempt {i+1}: {exc}")

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants