Infraestructur ahabilitadora incluida en la propuesta tecnica

This commit is contained in:
Luis Esteban Acevedo Ladino 2026-04-22 14:40:38 -05:00
parent 68b379ca13
commit 9cfc922d09
5 changed files with 446 additions and 14 deletions

24
.atl/skill-registry.md Normal file
View File

@ -0,0 +1,24 @@
# Skill Registry
Generated by sdd-init on 2026-04-22.
## User-Level Skills
| Skill | Trigger | Location |
|-------|---------|----------|
| branch-pr | Creating a PR, opening a PR, preparing changes for review | ~/.config/opencode/skills/branch-pr |
| go-testing | Go tests, Bubbletea TUI testing, teatest | ~/.config/opencode/skills/go-testing |
| issue-creation | Creating a GitHub issue, reporting a bug, requesting a feature | ~/.config/opencode/skills/issue-creation |
| judgment-day | "judgment day", "review adversarial", "dual review" | ~/.config/opencode/skills/judgment-day |
| skill-creator | Creating new AI skills, documenting agent patterns | ~/.config/opencode/skills/skill-creator |
## Project-Level Skills
No project-level skills found.
## Project Conventions
| File | Purpose |
|------|---------|
| AGENTS.md | Architecture rules (Rust core, apps as UI shells), React component reading |
| .github/copilot-instructions.md | Extensive Biome lint rules, a11y, React/TS/Next.js best practices |

View File

@ -0,0 +1,206 @@
# Exploration: Infraestructura Habilitadora — Fase 1 del Agente Conversacional
## Current State
### Editor Architecture
NeuralCut's editor is built around a **singleton `EditorCore`** (`apps/web/src/core/index.ts`) that owns 12 managers accessed via `EditorCore.getInstance()`:
- `project` — active project (`TProject`), CRUD, load/save, export
- `media` — loaded media assets (`MediaAsset[]`), add/remove
- `scenes` — scene list (`TScene[]`), active scene, bookmarks
- `timeline` — track mutations (add/remove/move elements)
- `playback` — playhead, play/pause, seek
- `command` — undo/redo with `BaseCommand` pattern
- `selection` — selected elements on canvas
- `renderer` — GPU/canvas rendering
- `save` — auto-save to IndexedDB
- `audio` — audio analysis
- `clipboard` — copy/paste
- `diagnostics` — runtime diagnostics
React components subscribe via `useEditor(selector)` which uses `useSyncExternalStore` over all manager subscriptions.
### How the Active Video Is Identified
1. `EditorCore.project.getActive()` returns `TProject` with `metadata.id` (the `project_id` from the URL)
2. `EditorCore.media.getAssets()` returns all `MediaAsset[]` loaded for that project
3. Each `MediaAsset` has: `id`, `name`, `type` ("image"|"video"|"audio"), `file`, `url`, `duration`, `width`, `height`, `fps`
4. The active scene's main video track: `scenes.getActiveSceneOrNull()?.tracks.main.elements[0]` references a `VideoElement` with `mediaAssetId`
5. **For the agent**: the simplest context is the project's loaded video assets. The agent can query by `mediaAssetId`.
### Panel Layout
The editor layout (`apps/web/src/app/editor/[project_id]/page.tsx`) uses `ResizablePanelGroup` (shadcn/ui) in a 4-panel arrangement:
```
┌──────────┬──────────────────────┬──────────────┐
│ Assets │ Preview │ Properties │
│ Panel │ │ Panel │
│ (25%) │ (50%) │ (25%) │
├──────────┴──────────────────────┴──────────────┤
│ Timeline (50%) │
└─────────────────────────────────────────────────┘
```
`PanelSizes` currently defines: `tools`, `preview`, `properties`, `mainContent`, `timeline`.
**ChatPanel integration**: The most natural placement is replacing/augmenting the **Properties panel** slot — properties is context-dependent and the chat panel could share that space with a tab toggle. Alternatively, it could be a **new 5th panel** that slides in from the right.
### Existing Stores
All Zustand stores at `apps/web/src/stores/`:
- `editor-store.ts` — init/ready state
- `panel-store.ts` — resizable panel sizes (persisted)
- `timeline-store.ts` — snap/ripple toggles (persisted)
- `assets-panel-store.tsx` — active tab in assets panel (persisted)
- `preview-store.ts` — guides, overlays (persisted)
- `properties-store.ts` — properties panel state
- Plus keybindings, sounds, stickers
**Pattern**: `create<State>()(persist((set) => ({...}), { name: "...", partialize: ... }))` with explicit `set` calls.
### Existing Transcription
`apps/web/src/services/transcription/service.ts` — Web Worker-based Whisper transcription. Types in `apps/web/src/lib/transcription/types.ts`:
- `TranscriptionSegment { text, start, end }`
- `TranscriptionResult { text, segments, language }`
- `TranscriptionStatus`, `TranscriptionProgress`, `TranscriptionModelId`
**This is a direct integration point** for the agent's `transcribe_video` tool — the agent can reuse the existing service.
### Existing API Routes
Only 4 simple routes exist at `apps/web/src/app/api/`:
- `auth/` — authentication
- `feedback/route.ts` — simple POST
- `health/route.ts``export async function GET()`
- `sounds/` — sound search
No agent/chat routes exist yet. Pattern is standard Next.js App Router route handlers.
### Registry Pattern
`apps/web/src/lib/registry.ts` has a generic `DefinitionRegistry<TKey, TDefinition>` with `register()`, `get()`, `getAll()`. Used for effects and masks. **This is the exact pattern to reuse for the tool registry.**
### Command System
`apps/web/src/lib/commands/` has a command pattern (`BaseCommand` with `execute`/`undo`). Used for timeline mutations, scene changes, project settings, media operations. **Agent tools that modify the timeline should go through `CommandManager`** to preserve undo/redo.
---
## Affected Areas
- `apps/web/src/stores/` — new `chatStore.ts` and `agentStore.ts`
- `apps/web/src/app/api/agent/chat/route.ts` — new API route (to create)
- `apps/web/src/components/editor/panels/chat/` — new `ChatPanel`, `MessageList`, `InputArea`
- `apps/web/src/app/editor/[project_id]/page.tsx` — layout modification to include ChatPanel
- `apps/web/src/stores/panel-store.ts` — new `chat` panel size entry
- `apps/web/src/lib/panels/layout.ts` — default config for chat panel
- `apps/web/src/agent/` — new directory for orchestrator, tools, types, prompts
- `apps/web/src/lib/registry.ts` — reuse for tool registry
- `apps/web/src/services/transcription/service.ts` — integration point for `transcribe_video` tool
- `apps/web/src/core/managers/` — agent may need to read from `media`, `scenes`, `project` managers
---
## Approaches
### 1. Thin Vertical Slice — Mock Everything, Wire End-to-End
Build the minimal pipeline: UI → API → Orchestrator → MockTool → Response → UI. No real LLM, no streaming, one mock tool.
- **Pros**: Fastest to demo, validates the full pipeline before adding complexity, team learns the architecture by doing
- **Cons**: Doesn't test real LLM integration, mock may give false confidence
- **Effort**: Low (3-5 dev-days)
### 2. Thin Slice + Real LLM (Ollama Local)
Same as #1 but the orchestrator calls a real local LLM (Ollama Qwen3-8B) for responses. Tool calling mocked.
- **Pros**: Tests the provider abstraction from day one, validates streaming
- **Cons**: Requires Ollama setup, LLM latency in dev loop, provider bugs can distract
- **Effort**: Medium (5-7 dev-days)
### 3. Full Infrastructure First
Build all abstractions (providers, tool registry, orchestrator, streaming, error recovery) before any UI.
- **Pros**: Clean architecture, no rework
- **Cons**: Slow to demo, no user feedback until everything is wired, risk of overengineering
- **Effort**: High (10-14 dev-days)
---
## Recommendation
**Approach 1 — Thin Vertical Slice with Mocks**. The propuesta_técnica explicitly says Sprint 3 should deliver the infraestructura habilitadora in 1 week. A thin slice that wires the full pipeline with one mock tool is the fastest way to:
1. Validate the architecture (stores, API route, orchestrator, tool registry)
2. Give the team a working demo to iterate on
3. Establish contracts (types) that all future tools implement
4. Let UI and backend devs work in parallel afterward
**The real LLM (Approach 2) comes in Sprint 4** when `transcribe_video` is connected to the existing Whisper service.
### Recommended Thin Scope (what goes in the first slice)
| Component | Location | Real or Mock |
|-----------|----------|-------------|
| Types: `ChatMessage`, `ToolCall`, `ToolResult`, `ExecutionStatus` | `apps/web/src/agent/types.ts` | **Real** — these are contracts |
| `chatStore` | `apps/web/src/stores/chatStore.ts` | **Real** — messages, loading, error |
| `agentStore` | `apps/web/src/stores/agentStore.ts` | **Real** — execution status, active tool, context |
| Tool registry + `ToolDefinition` interface | `apps/web/src/agent/tools/` | **Real** — registry pattern, one mock tool |
| Orchestrator (minimal) | `apps/web/src/agent/orchestrator.ts` | **Mock** — echo response + tool resolution |
| `/api/agent/chat` route | `apps/web/src/app/api/agent/chat/route.ts` | **Real** — POST handler, context extraction |
| `ChatPanel`, `MessageList`, `InputArea` | `apps/web/src/components/editor/panels/chat/` | **Real** — functional UI |
| Panel layout integration | `apps/web/src/app/editor/[project_id]/page.tsx` | **Real** — toggleable chat panel |
| Provider abstraction | `apps/web/src/agent/providers/` | **Stub** — interfaces only, mock implementation |
| System prompt template | `apps/web/src/agent/prompts/system.ts` | **Real** — basic template with context injection |
### Architecture Decision: Where Does the Agent Live?
Per the propuesta_técnica Section 5.1.1, the agent orchestration is **I/O-bound TypeScript** in `apps/web/src/agent/`. This does NOT violate the AGENTS.md rule ("business logic in rust/") because:
- The agent is an **integration layer** — it orchestrates external API calls and coordinates existing tools
- It does NOT contain algorithms or data transformations
- Heavy processing (video analysis, detection) that the agent triggers still runs through Rust/WASM
- The Zustand store manipulations it performs (cut, concat) go through the existing `CommandManager`
If in the future parts of the orchestrator become complex enough to warrant Rust (e.g., planning algorithms), they can migrate then. YAGNI for now.
### Chat Panel Placement Recommendation
**Tabbed panel alongside Properties** (sharing the right panel slot). Rationale:
- Doesn't change the 4-panel layout that users already know
- Properties panel is context-dependent and often underused
- A tab toggle ("Properties" | "Chat") at the top of the right panel is simple
- The `PanelSizes` type stays the same; we add a UI-level toggle in the right panel
---
## Risks
1. **Architecture tension with AGENTS.md** — The agent code lives in `apps/web/src/agent/` which is technically "the UI shell". The team must maintain the discipline that `agent/` contains only orchestration/I/O, never algorithms. If logic drifts into `agent/tools/`, it should move to `rust/`. This needs a clear convention documented.
2. **EditorCore singleton coupling** — The agent needs to read from `EditorCore.media` and `EditorCore.scenes` to know the active video. This creates coupling between the agent layer and the editor internals. Mitigate with a thin `EditorContext` adapter that extracts only what the agent needs.
3. **No streaming in v1** — A non-streaming response will feel sluggish. Users expect chat to stream. Mitigate by designing the types to support streaming from day one, even if v1 uses a simple JSON response.
4. **State synchronization** — When the agent modifies the timeline (via `CommandManager`), the chat store needs to reflect the result. Two separate Zustand stores + EditorCore managers = three sources of truth. Mitigate with clear ownership: `chatStore` owns messages, `agentStore` owns execution status, `EditorCore` owns project data.
5. **Tool execution in API route vs client** — Tools that modify the timeline (cut, concat) need access to `EditorCore` which runs client-side. The API route can't access it. Solution: the orchestrator runs **client-side**, and the API route is only for LLM calls. The client-side orchestrator receives the LLM response, resolves tool calls, and executes them locally. This is the correct architecture — the server is just an LLM proxy.
6. **`propuesta_tecnica.md` scope creep** — The proposal lists 15 tools across 4 tiers. The team must resist building tool scaffolding beyond what the mock requires. The registry should support 1 tool in v1, not pre-scaffold 15.
---
## Ready for Proposal
**Yes.** The exploration has identified:
- Clear placement for every component
- The exact integration points with existing code
- The tension between AGENTS.md and propuesta_técnica.md (resolved: agent is I/O orchestration, not business logic)
- A thin scope that can be delivered in Sprint 3 (1 week)
**Next**: The orchestrator should run `sdd-propose` with the recommended thin scope to create a formal proposal for this change.

View File

@ -0,0 +1,66 @@
# Proposal: Infra Habilitadora — Fase 1
## Intent
Habilitar el primer slice implementable del agente conversacional dentro del editor, validando la frontera UI → proxy API → orquestador cliente → herramienta mock sin introducir todavía lógica pesada ni suite real de tools.
## Scope
### In Scope
- Integrar un chat panel mínimo en el slot derecho del editor, compartido con Properties.
- Crear el entrypoint del agente, el proxy `/api/agent/chat`, stores de chat/agente y contratos base.
- Montar un orquestador cliente shell, tool registry shell y wiring de contexto activo de video/media.
- Entregar un único flujo end-to-end mock con una sola tool mock.
### Out of Scope
- LLM real, streaming, múltiples tools, ejecución real de edición, backend complejo.
- Mover lógica de negocio a Rust o resolver arquitectura final de herramientas futuras.
## Capabilities
### New Capabilities
- `editor-chat-panel`: panel de chat embebido en el editor con envío, historial y estados básicos.
- `agent-session-shell`: frontera mínima entre UI, proxy API, stores y orquestador cliente.
- `agent-context-bridge`: contratos y adapter para exponer media/video activo al agente.
### Modified Capabilities
- None.
## Approach
Seguir un thin vertical slice: UI funcional, proxy API sin lógica de negocio, orquestador ejecutado en cliente y una tool mock registrada con `DefinitionRegistry`. El agente en `apps/web/src/agent/` queda limitado a I/O y coordinación; cualquier lógica pesada futura sigue en `rust/`.
## Affected Areas
| Area | Impact | Description |
|------|--------|-------------|
| `apps/web/src/app/editor/[project_id]/page.tsx` | Modified | Integra tab Chat/Properties |
| `apps/web/src/components/editor/panels/chat/` | New | UI mínima del chat |
| `apps/web/src/stores/chatStore.ts` | New | Mensajes, loading, error |
| `apps/web/src/stores/agentStore.ts` | New | Estado de ejecución y contexto |
| `apps/web/src/app/api/agent/chat/route.ts` | New | Proxy boundary |
| `apps/web/src/agent/` | New | Tipos, orquestador, prompts, tool registry |
## Risks
| Risk | Likelihood | Mitigation |
|------|------------|------------|
| Deriva de lógica fuera de `rust/` | Med | Limitar `agent/` a orquestación y contratos |
| Acoplamiento con `EditorCore` | Med | Usar adapter de contexto mínimo |
| Scope creep | High | Mantener una sola tool mock |
## Rollback Plan
Revertir la integración del tab Chat, eliminar `apps/web/src/agent/`, stores y ruta API nueva, dejando intacto el panel derecho actual y sin tocar flujos de edición existentes.
## Dependencies
- `EditorCore` (`project`, `media`, `scenes`) como fuente de contexto.
- `DefinitionRegistry` existente para el registro de tools.
- Rutas App Router de Next.js para el proxy.
## Success Criteria
- [ ] El editor muestra un panel Chat funcional sin romper el layout actual.
- [ ] Un mensaje del usuario recorre UI → API proxy → orquestador cliente → tool mock → respuesta visible.
- [ ] Los contratos base permiten agregar tools reales sin rediseñar stores ni frontera API.

58
openspec/config.yaml Normal file
View File

@ -0,0 +1,58 @@
schema: spec-driven
context: |
Tech stack: Rust (core logic, WASM) + TypeScript/Next.js 16 (web UI) + GPUI (desktop UI)
Architecture: Migrating to Rust core — apps/ are UI shells only, rust/ owns all logic
Monorepo: Bun workspaces + Turborepo + Cargo workspace
Testing: bun test (web), cargo test (rust)
Style: Biome (linter+formatter), tab indent, double quotes, strict TS, no console/debugger
strict_tdd: true
rules:
proposal:
- Include rollback plan for risky changes
- Identify affected modules/packages
specs:
- Use Given/When/Then format for scenarios
- Use RFC 2119 keywords (MUST, SHALL, SHOULD, MAY)
design:
- Include sequence diagrams for complex flows
- Document architecture decisions with rationale
tasks:
- Group tasks by phase (infrastructure, implementation, testing)
- Use hierarchical numbering (1.1, 1.2, etc.)
- Keep tasks small enough to complete in one session
apply:
- Follow existing code patterns and conventions
- Load relevant coding skills for the project stack
- Logic goes in rust/, UI only in apps/
verify:
- Run tests if test infrastructure exists
- Compare implementation against every spec scenario
archive:
- Warn before merging destructive deltas (large removals)
testing:
strict_tdd: true
detected: "2026-04-22"
test_runner:
web:
command: "bun test"
framework: "bun test (built-in)"
rust:
command: "cargo test"
framework: "cargo test (built-in)"
test_layers:
unit: { available: true, tool: "bun test / cargo test" }
integration: { available: false, tool: null }
e2e: { available: false, tool: null }
coverage:
available: false
command: null
quality_tools:
linter: { available: true, command: "biome check" }
type_checker: { available: true, command: "tsc --noEmit" }
formatter: { available: true, command: "biome format" }
rust_linter: { available: false, command: null }
rust_formatter: { available: true, command: "rustfmt" }

View File

@ -663,33 +663,111 @@ Agente: watch_video("where does the person mess up?")
## 9. Plan de desarrollo (Scrum)
### Equipo y roles
### 9.1. Infraestructura habilitadora inicial (antes de la primera feature)
Antes de implementar la primera feature de producto visible (`transcribe_video`), el equipo necesita montar una **infraestructura mínima habilitadora**. Esta capa no entrega todavía el valor completo al usuario, pero crea el canal por el cual el agente puede operar dentro del editor. Sin esto, cualquier tool real quedaría acoplada, improvisada o desconectada de la UI.
#### Objetivo
Tener un **vertical slice técnico mínimo** donde:
- el usuario puede escribir en un panel de chat,
- el frontend puede enviar ese mensaje al backend,
- existe un orquestador básico que recibe la intención,
- existe un registro de tools desacoplado,
- el agente conoce cuál es el video activo del editor,
- y una tool mock o real puede devolver un resultado visible en la interfaz.
#### Componentes de esta infraestructura
**1. Superficie de interacción (UI mínima de chat)**
- `ChatPanel`
- `MessageList`
- `InputArea`
- estado de loading, error y mensajes
**2. Canal cliente-servidor**
- `app/api/agent/chat/route.ts`
- contrato claro de request/response
- streaming opcional al inicio, respuesta simple como mínimo
**3. Orquestador básico del agente**
- `agent/orchestrator.ts`
- recibe mensajes + contexto actual
- decide entre respuesta directa o ejecución de una tool
- puede arrancar con lógica simple antes del tool calling completo por LLM
**4. Registro y contrato de tools**
- `agent/tools/index.ts`
- interfaz común para tools
- schema de input/output
- executor desacoplado por tool
**5. Capa de providers**
- interfaces abstractas (`TranscriptionProvider`, `VisionProvider`, `LLMProvider`)
- factories por ambiente
- posibilidad de usar mock/local/cloud sin cambiar el resto del código
**6. Estado agéntico y conversacional**
- `chatStore`
- `agentStore`
- mensajes, estado de ejecución, resultados y errores
**7. Integración con el editor actual**
- lectura del video seleccionado o activo
- validación de que exista media cargada
- paso de `video_id` o referencia equivalente a las tools
**8. Tipos y contratos compartidos**
- mensajes de chat
- tool calls
- tool results
- transcript segments
- estado de ejecución del agente
#### Entregable esperado de esta fase
Al final de esta fase, el equipo debe poder demostrar:
> “Escribo en el panel de chat, el mensaje viaja al endpoint del agente, el orquestador procesa la intención y devuelve una respuesta visible en la UI usando una tool mock o una tool real simple.”
Esto no reemplaza la primera feature de producto; la **habilita**.
### 9.2. Equipo y roles
- **Scrum Master:** coordina reuniones, remueve bloqueos
- **Product Owner:** prioriza backlog, dueño de la visión
- **Dev Frontend (2):** UI, NeuralCut, panel de chat
- **Dev Backend/IA (1-2):** agente (TS), tools, capa de proveedores
### Sprints propuestos (asumiendo ~14 semanas)
### 9.3. Sprints propuestos (asumiendo ~14 semanas)
| Sprint | Duración | Objetivo | Entregable |
|---|---|---|---|
| **0** | 1 semana | Setup + aprendizaje | NeuralCut corriendo local. Ollama + Qwen funcionando. Cada dev hizo "hola mundo" con APIs. |
| **1** | 1 semana | Empatizar | 8-10 entrevistas a creadores de contenido. Mapa de empatía. Declaración del problema validada. |
| **2** | 1 semana | Ideación + diseño | Wireframes del panel de chat. Diseño de la capa de abstracción. Decisión de scope de tools. |
| **3** | 1 semana | Infraestructura | Capa de abstracción implementada. Panel de chat UI (sin lógica). 1 tool conectada end-to-end (transcribe). |
| **4** | 1 semana | Tier 1 tools | transcribe, detect_silences, detect_scenes, cut_segment, concat_segments. |
| **5** | 1 semana | Video understanding | watch_video + take_screenshot + describe_scene. Primera demo "wow". |
| **6** | 1 semana | Creative tools | generate_subtitles, apply_lut, detect_faces. |
| **7** | 1 semana | Reframe + beats | auto_reframe (MediaPipe), detect_beats (Essentia). |
| **8** | 1 semana | Pipeline inteligente | suggest_highlights + remove_filler_words. |
| **9** | 1 semana | Refinamiento UX | Streaming de respuestas, aprobaciones inline, undo/redo agéntico. |
| **10** | 1 semana | Testing con usuarios | 5-10 sesiones de usability testing. Ajustes. |
| **11** | 1 semana | Performance + deploy | Optimización, caching, deploy a Vercel. |
| **12** | 1 semana | Preparación feria | Videos de ejemplo pre-procesados, afiche, guión de demo. |
| **13** | 1 semana | Buffer + Post Mortem | Buffer para imprevistos. Reunión Post Mortem. |
| **3** | 1 semana | Infraestructura habilitadora | ChatPanel mínimo funcional, `chatStore`/`agentStore`, endpoint `/api/agent/chat`, orquestador básico, registro de tools, tipos compartidos, integración con video activo. |
| **4** | 1 semana | Primer vertical slice real | `transcribe_video` conectada end-to-end con provider real o local, respuesta visible en chat y timestamps persistidos en estado. |
| **5** | 1 semana | Tier 1 tools | detect_silences, detect_scenes, cut_segment, concat_segments sobre la base ya creada. |
| **6** | 1 semana | Video understanding | watch_video + take_screenshot + describe_scene. Primera demo "wow". |
| **7** | 1 semana | Creative tools | generate_subtitles, apply_lut, detect_faces. |
| **8** | 1 semana | Reframe + beats | auto_reframe (MediaPipe), detect_beats (Essentia). |
| **9** | 1 semana | Pipeline inteligente | suggest_highlights + remove_filler_words. |
| **10** | 1 semana | Refinamiento UX | Streaming de respuestas, aprobaciones inline, undo/redo agéntico. |
| **11** | 1 semana | Testing con usuarios | 5-10 sesiones de usability testing. Ajustes. |
| **12** | 1 semana | Performance + deploy | Optimización, caching, deploy a Vercel. |
| **13** | 1 semana | Preparación feria | Videos de ejemplo pre-procesados, afiche, guión de demo. |
| **14** | 1 semana | Buffer + Post Mortem | Buffer para imprevistos. Reunión Post Mortem. |
### Backlog priorizado (primeras historias)
### 9.4. Backlog priorizado (primeras historias)
**Infraestructura habilitadora (antes de Sprint 4):**
- Como usuario, veo un panel de chat integrado dentro del editor
- Como usuario, puedo enviar un mensaje y recibir una respuesta visible del agente
- Como sistema, el agente conoce cuál es el video activo del proyecto
- Como sistema, las tools comparten un contrato estable de entrada y salida
- Como equipo, podemos alternar entre providers mock, locales y cloud sin cambiar la lógica de negocio
**Must-have (Sprint 3-5):**
- Como usuario, subo un video y el agente me lo transcribe