Files
ableton-mcp-ai/docs/sprint_4_bloque_A.md
OpenCode Agent 5ce8187c65 feat: Implement senior audio injection with 5 fallback methods
- Add _cmd_create_arrangement_audio_pattern with 5-method fallback chain
- Method 1: track.insert_arrangement_clip() [Live 12+]
- Method 2: track.create_audio_clip() [Live 11+]
- Method 3: arrangement_clips.add_new_clip() [Live 12+]
- Method 4: Session->duplicate_clip_to_arrangement [Legacy]
- Method 5: Session->Recording [Universal]

- Add _cmd_duplicate_clip_to_arrangement for session-to-arrangement workflow
- Update skills documentation
- Verified: 3 clips created at positions [0, 4, 8] in Arrangement View

Closes: Audio injection in Arrangement View
2026-04-12 14:02:32 -03:00

13 KiB

SPRINT 4 — BLOQUE A: CARGA REAL, DIAGNÓSTICO Y ESTABILIZACIÓN (T001-T050)

Fecha: 2026-04-11 Estado Sprint 3: COMPLETO — 119 tools MCP, 64 handlers, 3 engines nuevos Objetivo Sprint 4-A: Que TODO lo que "dice" que hace, LO HAGA REALMENTE en Ableton Revisión: Qwen


CONTEXTO

Sprint 3 entregó código que compila 100%. El problema: muchas acciones retornan "loaded": True sin verificar que Ableton realmente las ejecutó. Este bloque se enfoca en tres pilares:

  1. Verificación real — cada handler confirma el estado POST-ejecución en Live
  2. Integración completa — browser API ya implementada, ahora se usa en TODO el sistema
  3. Diagnóstico — herramientas para que el usuario sepa exactamente qué funciona

FASE A1: VERIFICACIÓN POST-EJECUCIÓN (T001-T010)

T001_cmd_load_sample_to_clip: Agregar _verify_clip_has_audio(slot) que inspecciona slot.has_clip y clip.length > 0 DESPUÉS de la carga. Retorna verified: true/false con duration_beats real si el clip existe.

T002_cmd_insert_device: Agregar _verify_device_on_track(track, device_name) que compara lista de devices ANTES y DESPUÉS. Retorna verified: true + device_index real si el device apareció en track.devices.

T003_cmd_create_arrangement_midi_clip: Verificar si arrangement_clips API funcionó chequeando el clip existe en el track. Si Session fallback, marcar view: "session_fallback" y retornar clip_index + URL del slot real.

T004_cmd_load_sample_to_drum_rack_pad: Verificar que el pad tiene cadena después del intento. Acceder a pad.chains[0].devices[0].sample.file_path y comparar con el fname buscado. Retornar verified_path.

T005_cmd_generate_dembow_clip: Verificar que las notas se escribieron exactamente. Leer el clip con clip.get_notes() y comparar count. Retornar notes_written: N, notes_verified: M.

T006_cmd_generate_midi_clip: Agregar verificación de notas post-escritura. Si clip.get_notes() retorna vacío cuando se enviaron notas, loguear el error y reintentar con replace_selected_notes si disponible.

T007_cmd_create_drum_kit: Después de crear el Drum Rack, verificar que track.devices contiene el device. Acceder a device.drum_pads y contar pads activos. Retornar pads_active, drum_rack_index.

T008_cmd_configure_eq: Verificar que el EQ Eight está en la cadena. Leer device.parameters y confirmar que se aplicaron los valores. Retornar parameters_verified: {band: value}.

T009_cmd_setup_sidechain: Verificar que el Compressor tiene sidechain_active. Acceder a device.sidechain si existe. Retornar sidechain_confirmed: true/false.

T010 — Crear handler _cmd_verify_track_setup(track_index):

  • Lista todos los devices del track
  • Lista clips activos en Session View
  • Informa volumen, pan actual
  • Retorna snapshot completo del track para debugging

FASE A2: BROWSER API — USAR EN TODO EL SISTEMA (T011-T020)

T011_cmd_load_samples_for_genre (T008): Actualmente usa solo sample_selector.select_for_genre() para paths. Integrar _browser_load_audio() para cada sample, con fallback a create_audio_clip. Retornar qué método funcionó por cada sample.

T012_cmd_create_drum_kit (T009): Actualmente crea Drum Rack via create_midi_track() pero no carga el Drum Rack device. Integrar _browser_load_device(t, "Drum Rack", "instruments") antes de cargar samples. Verificar que el Drum Rack apareció antes de intentar cargar pads.

T013_cmd_build_track_from_samples (T010): Usar _browser_load_audio() en lugar de confiar en create_audio_clip. Agregar lógica de fallback: si browser falla, crear MIDI track con nota de instrucción.

T014_cmd_insert_device → extender lookup: Actualmente busca solo en una sección. Agregar búsqueda secundaria en TODAS las secciones si la primera falla. Orden: instruments → audio_effects → midi_effects → packs.

T015 — Nuevo handler _cmd_scan_browser_section(section_name, depth=2):

  • Escanea una sección del browser Live y retorna árbol de items
  • Sections: "instruments", "audio_effects", "sounds", "user_folders", "packs"
  • Útil para debug: saber exactamente qué ve el sistema en el browser
  • Retorna lista de items con name, is_loadable, is_folder

T016 — Nuevo tool MCP scan_browser_section(section, depth) en server.py:

  • Llama a _cmd_scan_browser_section
  • Permite al usuario descubrir qué devices/samples tiene disponibles
  • Retorna JSON con árbol navegable

T017_cmd_configure_eq: Si el device no existe en el track, PRIMERO insertar EQ Eight via _browser_load_device, LUEGO configurar parámetros. Secuencia: insert → verify → configure.

T018_cmd_configure_compressor: Si no hay Compressor, insertar via browser antes de configurar. Verificar la inserción. Mismo patrón que T017.

T019_cmd_setup_sidechain: Insertar Compressor si no existe, configurar la fuente de sidechain. Usar device.sidechain_enabled = True si disponible. Retornar los parámetros realmente configurados.

T020 — Nuevo handler _cmd_add_libreria_to_browser():

  • Lee path de libreria/reggaeton desde constante
  • Intenta agregar el folder a Live's user library via application().browser
  • Retorna added: true/false con instrucción manual si falla

FASE A3: ARRANGEMENT VIEW — IMPLEMENTACIÓN COMPLETA (T021-T030)

T021_cmd_create_arrangement_midi_clip: Agregar soporte para song.record_mode. Si song.record_mode está disponible, configurar overdub antes de fire. Retornar arrangement_mode_set: true/false.

T022 — Nuevo handler _cmd_set_arrangement_position(bar):

  • song.current_song_time = bar * beats_per_bar
  • app.view.show_view("Arranger")
  • Retorna posición actual del playhead

T023 — Nuevo handler _cmd_fire_clip_to_arrangement(track_index, clip_index, target_bar):

  • Pos playhead en target_bar
  • Activa song.arrangement_overdub = True
  • Dispara el clip: track.clip_slots[clip_index].fire()
  • Espera clip.length beats en la queue de _pending_tasks
  • Desactiva overdub: song.arrangement_overdub = False
  • Retorna recorded_to_bar: target_bar

T024_cmd_duplicate_session_to_arrangement (T014): Reescribir usando _cmd_fire_clip_to_arrangement para cada clip+escena. Calcular posición en bars basada en scene_index * section_length. Retorna clips colocados + posición.

T025 — Nuevo handler _cmd_get_arrangement_clips(track_index):

  • Lee todos los clips de arrangement via track.arrangement_clips si disponible
  • Retorna lista con name, start_time, length, has_notes
  • Si no disponible, retorna vacío con method: "not_available"

T026 — Nuevo handler _cmd_show_arrangement_view():

  • app.view.show_view("Arranger")
  • app.view.show_view("Detail/Clip") para mostrar detalle
  • Retorna view: "arranger"

T027 — Nuevo handler _cmd_show_session_view():

  • app.view.show_view("Session")
  • Retorna view: "session"

T028_cmd_build_arrangement_structure: Usa _cmd_fire_clip_to_arrangement para colocar clips reales en posiciones de la estructura (Intro, Verse, Drop, etc.) en lugar de solo crear escenas en session view.

T029 — Nuevo handler _cmd_loop_arrangement_region(start_bar, end_bar):

  • song.loop_start = start_bar * beats_per_bar
  • song.loop_length = (end_bar - start_bar) * beats_per_bar
  • song.loop_on = True
  • Retorna loop_set: true

T030 — Nuevo handler _cmd_capture_to_arrangement():

  • Equivalente a "Capture" de Live: app.get_document().capture_midi() si disponible
  • Fallback: instrucción de cómo usar Capture manualmente
  • Retorna captured: true/false

FASE A4: DIAGNÓSTICO Y MONITOREO (T031-T040)

T031 — Nuevo handler _cmd_get_live_version():

  • Live.Application.get_application().get_major_version()
  • Live.Application.get_application().get_minor_version()
  • Retorna version: "12.x.x", build: N

T032 — Nuevo handler _cmd_get_track_details(track_index):

  • Snapshot completo de un track: devices, clips, volumes, routing
  • Para debugging: has_input, has_output, arm, mute, solo
  • Lista cada device con parámetros accesibles

T033 — Nuevo handler _cmd_get_device_parameters(track_index, device_index):

  • Lista todos los parámetros de un device
  • device.parameters{name, value, min, max, is_quantized}
  • Útil para saber cómo configurar el device vía API

T034 — Nuevo handler _cmd_set_device_parameter(track_index, device_index, param_name, value):

  • Busca parámetro por nombre en device.parameters
  • Setea param.value = value
  • Verifica que el cambio se aplicó
  • Retorna parameter, old_value, new_value

T035 — Nuevo handler _cmd_get_clip_notes(track_index, clip_index):

  • Lee las notas de un MIDI clip via clip.get_notes()
  • Retorna lista de {pitch, start, duration, velocity, mute}
  • Con estadísticas: note_count, min_pitch, max_pitch, duration_bars

T036 — Nuevo handler _cmd_test_browser_connection():

  • Verifica que application().browser es accesible
  • Lista las secciones disponibles: sounds, instruments, audio_effects, etc.
  • Retorna browser_ok: true/false, sections: [...]

T037 — Nuevo handler _cmd_test_sample_loading(sample_path):

  • Tests: os.path.isfile() → path OK
  • Tests: _browser_load_audio() → browser OK
  • Tests: create_audio_clip() si disponible
  • Retorna path_ok, browser_ok, direct_ok, recommended_method

T038 — Nuevo handler _cmd_get_session_state():

  • song.current_song_time → posición actual
  • song.is_playing, song.tempo, song.signature_numerator
  • Lista clips activos por track
  • Retorna snapshot completo del estado de Session

T039 — Nuevo tool MCP get_system_diagnostics() en server.py:

  • Combina: get_live_version + test_browser_connection + get_session_state
  • Retorna JSON con estado completo del sistema
  • Primer tool que ejecutar para diagnosticar problemas

T040 — Nuevo tool MCP test_real_loading(sample_path) en server.py:

  • Llama a _cmd_test_sample_loading
  • Retorna qué métodos de carga funcionan en el Live actual
  • Guía al usuario sobre qué esperar

FASE A5: ROBUSTEZ Y ESTABILIDAD (T041-T050)

T041 — Agregar timeout global a _cmd_* handlers: Si un handler tarda más de 3s (detectado via time.time()), retornar timeout: true y limpiar _pending_tasks parcialmente. Previene bloqueos de Ableton.

T042_dispatch(): Agregar manejo de JSONDecodeError y KeyError explícitos. Retornar error descriptivo con el comando que falló. Loguear en Ableton con self.log_message.

T043 — Proteger update_display(): Atrapar excepciones dentro del loop de _pending_tasks. Si una task lanza excepción, remover y continuar con la siguiente. Nunca dejar que una task rota bloquee el drain.

T044_tcp_server_thread: Si la conexión se cierra abruptamente, cerrar el socket limpiamente. Agregar socket.SO_REUSEADDR si no está presente. Reiniciar listener automáticamente tras error de conexión.

T045 — Agregar límite a _pending_tasks: Si la queue supera 100 items, droppear las tareas más viejas y loguear warning. Previene acumulación sin límite cuando Ableton está bajo carga y update_display() no puede drenar rápido.

T046_cmd_get_tracks(): Si un track da error al leer un atributo (e.g., track sin nombre), continuar con el siguiente en lugar de fallar todo. Agregar try/except granular por atributo.

T047_cmd_generate_full_song(): Si un sub-handler falla durante el pipeline, continuar con los siguientes tracks. Retornar lista de errores al final pero no abortar. Comportamiento "best effort" para producción completa.

T048 — Todos los handlers que crean tracks: Verificar que el índice solicitado no excede len(song.tracks). Si se intenta acceder a track[N] y N>=len, retornar error claro en lugar de IndexError sin contexto.

T049_browser_search: Agregar límite de tiempo: si la recursión supera 5 segundos (verificar con time.time()), abortar y retornar None en lugar de bloquear el thread de Ableton indefinidamente.

T050 — Crear _cmd_health_check():

  • Ejecuta 5 checks: TCP OK, song accesible, tracks accesibles, browser accesible, update_display activo
  • Retorna score 0-5 y descripción de cada check
  • Tool MCP health_check() que llama a este handler
  • Primero que ejecutar tras abrir Ableton

ARCHIVOS A MODIFICAR (Bloque A)

Archivo Cambios
__init__.py +25 handlers nuevos, robustez en handlers existentes
mcp_server/server.py +10 tools MCP: scan_browser, health_check, get_system_diagnostics, test_real_loading, etc.

RESTRICCIONES

  1. Compilar tras cada archivo: python -m py_compile "<path>"
  2. libreria/ → solo lectura
  3. NO modificar engines del Sprint 1/2/3
  4. Handlers de verificación son SOLO-LECTURA: no mutan estado
  5. Retornar siempre JSON con status + result o error