chore(plan): marca Fases H, I y J (Tasks 30-38) completadas
Notas de desviación: Task 31 añade per-file-ignore N999 para pages/* (Streamlit exige nombres con emoji); se quitan noqa BLE001 inútiles y la var muerta chosen_example; Task 37 — el build de docker falló por typer 0.12.x vs click >=8.2, se fijó click<8.2 y el smoke pasó (core healthy /health 200, dashboard /_stcore/health ok, down limpio). Streamlit verificado con ruff + py_compile. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -4920,6 +4920,12 @@ git commit -m "feat(api,test): índice de ejecuciones persistido + test resume t
|
|||||||
## Phase H — Streamlit Dashboard (Tasks 30–35)
|
## Phase H — Streamlit Dashboard (Tasks 30–35)
|
||||||
|
|
||||||
> Streamlit no se testea con unit tests en este MVP (cost/benefit malo). El smoke manual está documentado en `docs/manual_qa.md` (Task 38).
|
> Streamlit no se testea con unit tests en este MVP (cost/benefit malo). El smoke manual está documentado en `docs/manual_qa.md` (Task 38).
|
||||||
|
>
|
||||||
|
> **Nota de implementación (desviación del plan):**
|
||||||
|
> - **Task 31:** las páginas de Streamlit *deben* llamarse `<n>_<emoji>_<Label>.py` para la navegación multipágina, lo que choca con `N999` de ruff; se añadió `per-file-ignores` para `dashboard/src/agentforge_dashboard/pages/*` en `pyproject.toml` (commit junto a la página de Registro).
|
||||||
|
> - **Tasks 30-31:** se eliminó el `# noqa: BLE001` del plan (`BLE` no está en `select`, así que `RUF100` lo marcaba como noqa inútil); `diff_view.py` parte el literal HTML largo en dos por legibilidad (E501 está en `ignore`, no era necesario).
|
||||||
|
> - **Task 32:** se omite la variable muerta `chosen_example` del plan (se asigna directamente a `st.session_state["input_text"]`).
|
||||||
|
> - Verificación de cada página: `ruff check .` + `python -m py_compile` (no hay unit tests de Streamlit). Los códigos de estado y los nombres de campo se cotejaron contra los modelos del core (`AgentDefinition`, `AgentExecution`, `GuardrailViolation`, `PolicyDefinition`).
|
||||||
|
|
||||||
### Task 30: Dashboard skeleton — `app.py` y cliente HTTP
|
### Task 30: Dashboard skeleton — `app.py` y cliente HTTP
|
||||||
|
|
||||||
@@ -4927,7 +4933,7 @@ git commit -m "feat(api,test): índice de ejecuciones persistido + test resume t
|
|||||||
- Create: `dashboard/src/agentforge_dashboard/client.py`
|
- Create: `dashboard/src/agentforge_dashboard/client.py`
|
||||||
- Create: `dashboard/src/agentforge_dashboard/app.py`
|
- Create: `dashboard/src/agentforge_dashboard/app.py`
|
||||||
|
|
||||||
- [ ] **Step 1: `client.py`**
|
- [x] **Step 1: `client.py`**
|
||||||
|
|
||||||
```python
|
```python
|
||||||
"""Cliente HTTP tipado al core. Encapsula httpx y mapea respuestas a dicts."""
|
"""Cliente HTTP tipado al core. Encapsula httpx y mapea respuestas a dicts."""
|
||||||
@@ -5004,7 +5010,7 @@ class CoreClient:
|
|||||||
return r.json()
|
return r.json()
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 2: `app.py`**
|
- [x] **Step 2: `app.py`**
|
||||||
|
|
||||||
```python
|
```python
|
||||||
"""Entry point del dashboard Streamlit con sidebar de branding y health."""
|
"""Entry point del dashboard Streamlit con sidebar de branding y health."""
|
||||||
@@ -5055,7 +5061,7 @@ if __name__ == "__main__":
|
|||||||
main()
|
main()
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 3: Commit**
|
- [x] **Step 3: Commit**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git add dashboard/src/agentforge_dashboard/client.py dashboard/src/agentforge_dashboard/app.py
|
git add dashboard/src/agentforge_dashboard/client.py dashboard/src/agentforge_dashboard/app.py
|
||||||
@@ -5070,7 +5076,7 @@ git commit -m "feat(dashboard): scaffolding Streamlit con cliente HTTP y health
|
|||||||
- Create: `dashboard/src/agentforge_dashboard/pages/1_🏛️_Registro.py`
|
- Create: `dashboard/src/agentforge_dashboard/pages/1_🏛️_Registro.py`
|
||||||
- Create: `dashboard/src/agentforge_dashboard/components/diff_view.py`
|
- Create: `dashboard/src/agentforge_dashboard/components/diff_view.py`
|
||||||
|
|
||||||
- [ ] **Step 1: `components/diff_view.py`**
|
- [x] **Step 1: `components/diff_view.py`**
|
||||||
|
|
||||||
```python
|
```python
|
||||||
"""Componente para renderizar diffs unificados con coloreado básico."""
|
"""Componente para renderizar diffs unificados con coloreado básico."""
|
||||||
@@ -5097,7 +5103,7 @@ def render_unified_diff(diff_text: str) -> None:
|
|||||||
st.markdown(html, unsafe_allow_html=True)
|
st.markdown(html, unsafe_allow_html=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 2: `pages/1_🏛️_Registro.py`**
|
- [x] **Step 2: `pages/1_🏛️_Registro.py`**
|
||||||
|
|
||||||
```python
|
```python
|
||||||
"""Página de registro de agentes: lista, detalle, versiones y diff."""
|
"""Página de registro de agentes: lista, detalle, versiones y diff."""
|
||||||
@@ -5161,7 +5167,7 @@ if len(versions) >= 2:
|
|||||||
render_unified_diff(diff["unified_diff"])
|
render_unified_diff(diff["unified_diff"])
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 3: Commit**
|
- [x] **Step 3: Commit**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git add dashboard/src/agentforge_dashboard/pages/1_🏛️_Registro.py dashboard/src/agentforge_dashboard/components/diff_view.py
|
git add dashboard/src/agentforge_dashboard/pages/1_🏛️_Registro.py dashboard/src/agentforge_dashboard/components/diff_view.py
|
||||||
@@ -5177,7 +5183,7 @@ git commit -m "feat(dashboard): página de Registro con detalle, versiones y dif
|
|||||||
- Create: `dashboard/src/agentforge_dashboard/components/trace_view.py`
|
- Create: `dashboard/src/agentforge_dashboard/components/trace_view.py`
|
||||||
- Create: `dashboard/src/agentforge_dashboard/components/violation_view.py`
|
- Create: `dashboard/src/agentforge_dashboard/components/violation_view.py`
|
||||||
|
|
||||||
- [ ] **Step 1: `components/trace_view.py`**
|
- [x] **Step 1: `components/trace_view.py`**
|
||||||
|
|
||||||
```python
|
```python
|
||||||
"""Renderiza el decision_path como timeline."""
|
"""Renderiza el decision_path como timeline."""
|
||||||
@@ -5205,7 +5211,7 @@ def render_trace(decision_path: list[dict]) -> None:
|
|||||||
st.json(step["detail"])
|
st.json(step["detail"])
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 2: `components/violation_view.py`**
|
- [x] **Step 2: `components/violation_view.py`**
|
||||||
|
|
||||||
```python
|
```python
|
||||||
"""Renderiza violaciones de guardrails con badges de severidad."""
|
"""Renderiza violaciones de guardrails con badges de severidad."""
|
||||||
@@ -5236,7 +5242,7 @@ def render_violations(violations: list[dict]) -> None:
|
|||||||
st.caption(v["message"])
|
st.caption(v["message"])
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 3: `pages/2_▶️_Ejecutar.py`**
|
- [x] **Step 3: `pages/2_▶️_Ejecutar.py`**
|
||||||
|
|
||||||
```python
|
```python
|
||||||
"""Página para invocar un agente y visualizar la traza completa."""
|
"""Página para invocar un agente y visualizar la traza completa."""
|
||||||
@@ -5314,7 +5320,7 @@ elif execution and "error" in execution:
|
|||||||
st.error(f"Error de la API: {execution['error']}")
|
st.error(f"Error de la API: {execution['error']}")
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 4: Commit**
|
- [x] **Step 4: Commit**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git add dashboard/src/agentforge_dashboard/pages/2_▶️_Ejecutar.py dashboard/src/agentforge_dashboard/components/trace_view.py dashboard/src/agentforge_dashboard/components/violation_view.py
|
git add dashboard/src/agentforge_dashboard/pages/2_▶️_Ejecutar.py dashboard/src/agentforge_dashboard/components/trace_view.py dashboard/src/agentforge_dashboard/components/violation_view.py
|
||||||
@@ -5328,7 +5334,7 @@ git commit -m "feat(dashboard): página Ejecutar con trace timeline y violations
|
|||||||
**Files:**
|
**Files:**
|
||||||
- Create: `dashboard/src/agentforge_dashboard/pages/3_🤝_Aprobaciones.py`
|
- Create: `dashboard/src/agentforge_dashboard/pages/3_🤝_Aprobaciones.py`
|
||||||
|
|
||||||
- [ ] **Step 1: Implementar**
|
- [x] **Step 1: Implementar**
|
||||||
|
|
||||||
```python
|
```python
|
||||||
"""Página de aprobaciones pendientes (HITL)."""
|
"""Página de aprobaciones pendientes (HITL)."""
|
||||||
@@ -5416,7 +5422,7 @@ with col_r:
|
|||||||
st.rerun()
|
st.rerun()
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 2: Commit**
|
- [x] **Step 2: Commit**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git add dashboard/src/agentforge_dashboard/pages/3_🤝_Aprobaciones.py
|
git add dashboard/src/agentforge_dashboard/pages/3_🤝_Aprobaciones.py
|
||||||
@@ -5430,7 +5436,7 @@ git commit -m "feat(dashboard): página Aprobaciones con HITL approve/reject por
|
|||||||
**Files:**
|
**Files:**
|
||||||
- Create: `dashboard/src/agentforge_dashboard/pages/4_📜_Historial.py`
|
- Create: `dashboard/src/agentforge_dashboard/pages/4_📜_Historial.py`
|
||||||
|
|
||||||
- [ ] **Step 1: Implementar**
|
- [x] **Step 1: Implementar**
|
||||||
|
|
||||||
```python
|
```python
|
||||||
"""Página de historial de ejecuciones y log de violaciones."""
|
"""Página de historial de ejecuciones y log de violaciones."""
|
||||||
@@ -5487,7 +5493,7 @@ with tabs[1]:
|
|||||||
st.dataframe(violations, hide_index=True, use_container_width=True)
|
st.dataframe(violations, hide_index=True, use_container_width=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 2: Commit**
|
- [x] **Step 2: Commit**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git add dashboard/src/agentforge_dashboard/pages/4_📜_Historial.py
|
git add dashboard/src/agentforge_dashboard/pages/4_📜_Historial.py
|
||||||
@@ -5501,7 +5507,7 @@ git commit -m "feat(dashboard): página Historial con tabs ejecuciones y violaci
|
|||||||
**Files:**
|
**Files:**
|
||||||
- Create: `dashboard/src/agentforge_dashboard/pages/5_📐_Politicas.py`
|
- Create: `dashboard/src/agentforge_dashboard/pages/5_📐_Politicas.py`
|
||||||
|
|
||||||
- [ ] **Step 1: Implementar**
|
- [x] **Step 1: Implementar**
|
||||||
|
|
||||||
```python
|
```python
|
||||||
"""Página de políticas de guardrails y sus versiones."""
|
"""Página de políticas de guardrails y sus versiones."""
|
||||||
@@ -5552,7 +5558,7 @@ versions = client.list_policy_versions(selected)
|
|||||||
st.dataframe(versions, hide_index=True, use_container_width=True)
|
st.dataframe(versions, hide_index=True, use_container_width=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 2: Commit**
|
- [x] **Step 2: Commit**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git add dashboard/src/agentforge_dashboard/pages/5_📐_Politicas.py
|
git add dashboard/src/agentforge_dashboard/pages/5_📐_Politicas.py
|
||||||
@@ -5563,6 +5569,10 @@ git commit -m "feat(dashboard): página Politicas con detalle de validadores y v
|
|||||||
|
|
||||||
## Phase I — Dockerización (Tasks 36–37)
|
## Phase I — Dockerización (Tasks 36–37)
|
||||||
|
|
||||||
|
> **Nota de implementación (desviación del plan):**
|
||||||
|
> - **Task 36:** ambos Dockerfiles pasan `docker build --check` sin warnings (se usó como lint previo).
|
||||||
|
> - **Task 37 (smoke):** `docker compose build` falló la primera vez en `RUN python -m spacy download en_core_web_sm` del core — `guardrails-ai<0.6` arrastra `typer 0.12.x`, incompatible con el `click 8.3.x` que resolvió pip (`TypeError: Secondary flag is not valid for non-boolean flag`). Se mantuvo el `spacy download` del plan y se fijó `click>=8.1,<8.2` en `core/requirements.txt` (commit `fix(deps): fija click<8.2 …`); el rebuild funcionó. Smoke OK: `docker compose up -d` → `agentforge-core` *healthy* con `GET /health → 200 {"status":"ok"}`, `agentforge-dashboard` con `/_stcore/health → ok`, sin errores en logs; `docker compose down` limpio.
|
||||||
|
|
||||||
### Task 36: Dockerfiles para core y dashboard
|
### Task 36: Dockerfiles para core y dashboard
|
||||||
|
|
||||||
**Files:**
|
**Files:**
|
||||||
@@ -5570,7 +5580,7 @@ git commit -m "feat(dashboard): página Politicas con detalle de validadores y v
|
|||||||
- Create: `dashboard/Dockerfile`
|
- Create: `dashboard/Dockerfile`
|
||||||
- Create: `.dockerignore`
|
- Create: `.dockerignore`
|
||||||
|
|
||||||
- [ ] **Step 1: `core/Dockerfile`**
|
- [x] **Step 1: `core/Dockerfile`**
|
||||||
|
|
||||||
```dockerfile
|
```dockerfile
|
||||||
# syntax=docker/dockerfile:1.7
|
# syntax=docker/dockerfile:1.7
|
||||||
@@ -5611,7 +5621,7 @@ HEALTHCHECK --interval=10s --timeout=3s --start-period=15s --retries=3 \
|
|||||||
CMD ["uvicorn", "agentforge_core.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
CMD ["uvicorn", "agentforge_core.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 2: `dashboard/Dockerfile`**
|
- [x] **Step 2: `dashboard/Dockerfile`**
|
||||||
|
|
||||||
```dockerfile
|
```dockerfile
|
||||||
# syntax=docker/dockerfile:1.7
|
# syntax=docker/dockerfile:1.7
|
||||||
@@ -5647,7 +5657,7 @@ CMD ["streamlit", "run", "/app/src/agentforge_dashboard/app.py", \
|
|||||||
"--server.headless=true", "--browser.gatherUsageStats=false"]
|
"--server.headless=true", "--browser.gatherUsageStats=false"]
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 3: `.dockerignore`**
|
- [x] **Step 3: `.dockerignore`**
|
||||||
|
|
||||||
```
|
```
|
||||||
.git
|
.git
|
||||||
@@ -5666,7 +5676,7 @@ docs/superpowers/plans
|
|||||||
tests
|
tests
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 4: Commit**
|
- [x] **Step 4: Commit**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git add core/Dockerfile dashboard/Dockerfile .dockerignore
|
git add core/Dockerfile dashboard/Dockerfile .dockerignore
|
||||||
@@ -5680,7 +5690,7 @@ git commit -m "build: añade Dockerfiles para core y dashboard con healthchecks
|
|||||||
**Files:**
|
**Files:**
|
||||||
- Create: `docker-compose.yml`
|
- Create: `docker-compose.yml`
|
||||||
|
|
||||||
- [ ] **Step 1: `docker-compose.yml`**
|
- [x] **Step 1: `docker-compose.yml`**
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
services:
|
services:
|
||||||
@@ -5728,7 +5738,7 @@ services:
|
|||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 2: Verificar build + smoke**
|
- [x] **Step 2: Verificar build + smoke**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose build
|
docker compose build
|
||||||
@@ -5742,7 +5752,7 @@ docker compose down
|
|||||||
|
|
||||||
Si los dos healthchecks devuelven 200 y los logs no tienen errores, el smoke pasa.
|
Si los dos healthchecks devuelven 200 y los logs no tienen errores, el smoke pasa.
|
||||||
|
|
||||||
- [ ] **Step 3: Commit**
|
- [x] **Step 3: Commit**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git add docker-compose.yml
|
git add docker-compose.yml
|
||||||
@@ -5761,7 +5771,7 @@ git commit -m "build: añade docker-compose con dos servicios y healthchecks"
|
|||||||
- Create: `docs/futuro.md`
|
- Create: `docs/futuro.md`
|
||||||
- Create: `docs/manual_qa.md`
|
- Create: `docs/manual_qa.md`
|
||||||
|
|
||||||
- [ ] **Step 1: `README.md`**
|
- [x] **Step 1: `README.md`**
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
# 🛡️ AgentForge
|
# 🛡️ AgentForge
|
||||||
@@ -5867,7 +5877,7 @@ make smoke # docker-compose + curl health
|
|||||||
MIT (a confirmar).
|
MIT (a confirmar).
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 2: `ARCHITECTURE.md`**
|
- [x] **Step 2: `ARCHITECTURE.md`**
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
# AgentForge — Arquitectura técnica
|
# AgentForge — Arquitectura técnica
|
||||||
@@ -5943,7 +5953,7 @@ nodo `approve_gate`. Sólo pausa cuando hay acciones de alto riesgo
|
|||||||
Ver [`docs/futuro.md`](docs/futuro.md).
|
Ver [`docs/futuro.md`](docs/futuro.md).
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 3: `docs/futuro.md`**
|
- [x] **Step 3: `docs/futuro.md`**
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
# Roadmap (post-MVP)
|
# Roadmap (post-MVP)
|
||||||
@@ -5963,7 +5973,7 @@ Ver [`docs/futuro.md`](docs/futuro.md).
|
|||||||
- **Promoción explícita draft → active** vía PR/aprobación.
|
- **Promoción explícita draft → active** vía PR/aprobación.
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 4: `docs/manual_qa.md`**
|
- [x] **Step 4: `docs/manual_qa.md`**
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
# Smoke manual del dashboard
|
# Smoke manual del dashboard
|
||||||
@@ -6026,7 +6036,7 @@ Abrir [http://localhost:8501](http://localhost:8501).
|
|||||||
pendientes.
|
pendientes.
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 5: Commit final**
|
- [x] **Step 5: Commit final**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git add README.md ARCHITECTURE.md docs/futuro.md docs/manual_qa.md
|
git add README.md ARCHITECTURE.md docs/futuro.md docs/manual_qa.md
|
||||||
|
|||||||
Reference in New Issue
Block a user