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
This commit is contained in:
OpenCode Agent
2026-04-12 14:02:32 -03:00
commit 5ce8187c65
118 changed files with 55075 additions and 0 deletions

View File

@@ -0,0 +1,65 @@
"""Compatibility wrapper for legacy production_workflow imports."""
from typing import Any, Dict, List, Optional
from .workflow_engine import get_workflow
class ProductionWorkflow:
"""Expose the legacy API expected by server.py."""
def __init__(self):
self._workflow = get_workflow()
def __getattr__(self, name):
return getattr(self._workflow, name)
def generate_song(self, genre: str = "reggaeton", bpm: float = 95.0, key: str = "Am",
style: str = "classic", structure: str = "standard") -> Dict[str, Any]:
return self._workflow.generate_complete_reggaeton(
bpm=bpm, key=key, style=style, structure=structure
)
def generate_from_samples(self, samples: Optional[List[Dict[str, Any]]] = None,
bpm: float = 95.0, key: str = "Am",
style: str = "matched") -> Dict[str, Any]:
result = self._workflow.generate_complete_reggaeton(
bpm=bpm, key=key, style=style, structure="standard", use_samples=bool(samples)
)
if isinstance(result, dict):
result.setdefault("input_samples", samples or [])
return result
def produce_reggaeton(self, bpm: float = 95.0, key: str = "Am",
style: str = "classic", structure: str = "verse-chorus") -> Dict[str, Any]:
return self._workflow.generate_complete_reggaeton(
bpm=bpm, key=key, style=style, structure=structure
)
def produce_from_reference(self, reference_path: str, bpm: Optional[float] = None,
key: Optional[str] = None) -> Dict[str, Any]:
result = self._workflow.generate_from_reference(reference_path)
if isinstance(result, dict):
if bpm is not None:
result.setdefault("requested_bpm", bpm)
if key is not None:
result.setdefault("requested_key", key)
return result
def produce_arrangement(self, bpm: float = 95.0, key: str = "Am",
style: str = "classic") -> Dict[str, Any]:
result = self._workflow.generate_complete_reggaeton(
bpm=bpm, key=key, style=style, structure="extended"
)
if isinstance(result, dict):
result.setdefault("view", "Arrangement")
return result
def complete_production(self, bpm: float = 95.0, key: str = "Am",
style: str = "classic") -> Dict[str, Any]:
result = self._workflow.generate_complete_reggaeton(
bpm=bpm, key=key, style=style, structure="extended"
)
if isinstance(result, dict):
result.setdefault("production_complete", True)
return result