chore(plan): marca Phase F (Tasks 21-25) completada
Nota de desviación: fastapi/uvicorn instalados, routers con estilo Annotated[T, Depends], orchestrator.snapshot() en vez de _build_graph_for_snapshot, fixture default + tests extra. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -3454,6 +3454,15 @@ git commit -m "feat(runtime): añade AgentOrchestrator para invoke + resume + sn
|
||||
|
||||
## Phase F — FastAPI Core (Tasks 21–25)
|
||||
|
||||
> **Nota de implementación (desviación del plan):**
|
||||
> - `fastapi`/`uvicorn` no estaban instalados en el venv; se instalaron (`fastapi 0.119.1`, `uvicorn 0.31.1`).
|
||||
> - Los routers usan el estilo `Annotated[T, Depends(...)]` (sin `Depends()` en defaults) para pasar ruff B008; los aliases (`RegistryDep`, `PolicyStoreDep`, `OrchestratorDep`, `SettingsDep`) viven en `api/deps.py`.
|
||||
> - El orchestrator (ver Phase E) abre el checkpointer por llamada, así que el helper `_build_graph_for_snapshot` del Task 24 no aplica. En su lugar `AgentOrchestrator` expone un método público `snapshot(agent_def, policy, trace_id) -> AgentExecution | None`; el router `GET /executions/{trace_id}` y los gates de approve/reject lo usan.
|
||||
> - Tests del core usan `tests/fixtures/policies/default/` (fixture mínima sin validadores) además del agente `incident_analyzer` del Task 23.
|
||||
> - Se añadieron tests no contemplados en el plan: `test_persistence.py`, `test_api_executions.py`, `test_api_policies_violations.py`, y dos tests de `orchestrator.snapshot()`.
|
||||
> - Los bloques de código de los Tasks 21-25 son la versión original del plan; la **versión autoritativa es la committeada** (typing mypy-strict, manejo de errores, etc.).
|
||||
|
||||
|
||||
### Task 21: Persistence helpers (JSONL append-only) + DI
|
||||
|
||||
**Files:**
|
||||
@@ -3461,7 +3470,7 @@ git commit -m "feat(runtime): añade AgentOrchestrator para invoke + resume + sn
|
||||
- Create: `core/src/agentforge_core/api/persistence.py`
|
||||
- Create: `tests/unit/test_persistence.py`
|
||||
|
||||
- [ ] **Step 1: Test**
|
||||
- [x] **Step 1: Test**
|
||||
|
||||
```python
|
||||
"""Tests de los helpers de persistencia JSONL."""
|
||||
@@ -3516,7 +3525,7 @@ def test_append_execution_anade_a_existente(tmp_path: Path) -> None:
|
||||
assert len(lines) == 2
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Implementar `persistence.py`**
|
||||
- [x] **Step 2: Implementar `persistence.py`**
|
||||
|
||||
```python
|
||||
"""Helpers de persistencia append-only en JSONL para auditoría."""
|
||||
@@ -3581,7 +3590,7 @@ def read_execution_summaries(data_dir: Path) -> list[AgentExecutionSummary]:
|
||||
return out
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Implementar `deps.py` (DI singletons)**
|
||||
- [x] **Step 3: Implementar `deps.py` (DI singletons)**
|
||||
|
||||
```python
|
||||
"""Dependencias compartidas inyectadas en los routers FastAPI."""
|
||||
@@ -3635,7 +3644,7 @@ def get_orchestrator() -> AgentOrchestrator:
|
||||
)
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Verificar y commit**
|
||||
- [x] **Step 4: Verificar y commit**
|
||||
|
||||
```bash
|
||||
pytest tests/unit/test_persistence.py -v
|
||||
@@ -3652,7 +3661,7 @@ git commit -m "feat(api): añade persistencia JSONL y DI con factories cacheadas
|
||||
- Create: `core/src/agentforge_core/main.py`
|
||||
- Create: `tests/unit/test_health.py`
|
||||
|
||||
- [ ] **Step 1: Test**
|
||||
- [x] **Step 1: Test**
|
||||
|
||||
```python
|
||||
"""Test del endpoint de health."""
|
||||
@@ -3683,7 +3692,7 @@ def test_trace_id_header_se_propaga_si_viene() -> None:
|
||||
assert r.headers["x-trace-id"] == "fixed-123"
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Implementar `middlewares.py`**
|
||||
- [x] **Step 2: Implementar `middlewares.py`**
|
||||
|
||||
```python
|
||||
"""Middleware de propagación de trace_id."""
|
||||
@@ -3712,7 +3721,7 @@ class TraceIdMiddleware(BaseHTTPMiddleware):
|
||||
clear_trace_id()
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Implementar `main.py`**
|
||||
- [x] **Step 3: Implementar `main.py`**
|
||||
|
||||
```python
|
||||
"""Composición raíz de la aplicación FastAPI."""
|
||||
@@ -3752,7 +3761,7 @@ def create_app() -> FastAPI:
|
||||
app = create_app()
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Verificar y commit**
|
||||
- [x] **Step 4: Verificar y commit**
|
||||
|
||||
Nota: el test fallará temporalmente porque importa routers que aún no existen. Comentamos las líneas `include_router` si hace falta para esta task aislada, pero es preferible escribir routers en la misma tanda. Para mantener TDD honesto, dejamos los routers como stubs vacíos en el siguiente paso.
|
||||
|
||||
@@ -3781,7 +3790,7 @@ git commit -m "feat(api): scaffolding FastAPI con TraceIdMiddleware, /health y r
|
||||
- Create: `tests/fixtures/agents/incident_analyzer/index.yaml` (mínimo para test)
|
||||
- Create: `tests/fixtures/agents/incident_analyzer/versions/v1.yaml`
|
||||
|
||||
- [ ] **Step 1: Crear fixtures (mínimo viable; los completos vendrán en Phase G)**
|
||||
- [x] **Step 1: Crear fixtures (mínimo viable; los completos vendrán en Phase G)**
|
||||
|
||||
`tests/fixtures/agents/incident_analyzer/index.yaml`:
|
||||
```yaml
|
||||
@@ -3816,7 +3825,7 @@ risk_threshold_for_hitl: 4
|
||||
updated_at: 2026-04-01T00:00:00Z
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Test**
|
||||
- [x] **Step 2: Test**
|
||||
|
||||
```python
|
||||
"""Tests del router /agents."""
|
||||
@@ -3873,7 +3882,7 @@ def test_list_versions() -> None:
|
||||
assert r.json()[0]["id"] == "v1"
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Implementar router**
|
||||
- [x] **Step 3: Implementar router**
|
||||
|
||||
Modificar `core/src/agentforge_core/api/agents.py`:
|
||||
```python
|
||||
@@ -3941,7 +3950,7 @@ def diff_versions(
|
||||
return registry.diff_versions(name, v_from, v_to)
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Settings — añadir `agents_dir` y `policies_dir` envvars**
|
||||
- [x] **Step 4: Settings — añadir `agents_dir` y `policies_dir` envvars**
|
||||
|
||||
Verificar que `Settings` ya las acepta. Modificar `core/src/agentforge_core/config.py` para usar `env="AGENTS_DIR"` etc.:
|
||||
|
||||
@@ -3953,7 +3962,7 @@ Verificar que `Settings` ya las acepta. Modificar `core/src/agentforge_core/conf
|
||||
|
||||
(Pydantic Settings ya lee `AGENTS_DIR` por convención case-insensitive — no se necesita cambio.)
|
||||
|
||||
- [ ] **Step 5: Verificar y commit**
|
||||
- [x] **Step 5: Verificar y commit**
|
||||
|
||||
```bash
|
||||
pytest tests/unit/test_api_agents.py -v
|
||||
@@ -3969,7 +3978,7 @@ git commit -m "feat(api): implementa router /agents (list, get, versions, diff)"
|
||||
- Modify: `core/src/agentforge_core/api/executions.py`
|
||||
- Create: `tests/unit/test_api_executions.py`
|
||||
|
||||
- [ ] **Step 1: Test (happy path con MockProvider)**
|
||||
- [x] **Step 1: Test (happy path con MockProvider)**
|
||||
|
||||
```python
|
||||
"""Tests del router /executions."""
|
||||
@@ -4082,7 +4091,7 @@ def test_approve_sobre_estado_invalido_devuelve_409() -> None:
|
||||
assert r2.status_code == 409
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Implementar router**
|
||||
- [x] **Step 2: Implementar router**
|
||||
|
||||
Modificar `core/src/agentforge_core/api/executions.py`:
|
||||
```python
|
||||
@@ -4304,7 +4313,7 @@ async def reject_execution(
|
||||
return execution
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Añadir helper en orchestrator**
|
||||
- [x] **Step 3: Añadir helper en orchestrator**
|
||||
|
||||
Modificar `core/src/agentforge_core/runtime/orchestrator.py` añadiendo:
|
||||
|
||||
@@ -4320,7 +4329,7 @@ Modificar `core/src/agentforge_core/runtime/orchestrator.py` añadiendo:
|
||||
)
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Montar `invoke_router` en main.py**
|
||||
- [x] **Step 4: Montar `invoke_router` en main.py**
|
||||
|
||||
Modificar `core/src/agentforge_core/main.py` añadiendo:
|
||||
|
||||
@@ -4329,7 +4338,7 @@ Modificar `core/src/agentforge_core/main.py` añadiendo:
|
||||
app.include_router(invoke_router, prefix="/agents", tags=["agents"])
|
||||
```
|
||||
|
||||
- [ ] **Step 5: Verificar y commit**
|
||||
- [x] **Step 5: Verificar y commit**
|
||||
|
||||
```bash
|
||||
pytest tests/unit/test_api_executions.py -v
|
||||
@@ -4345,7 +4354,7 @@ git commit -m "feat(api): implementa /executions con invoke + HITL approve/rejec
|
||||
- Modify: `core/src/agentforge_core/api/policies.py`
|
||||
- Modify: `core/src/agentforge_core/api/violations.py`
|
||||
|
||||
- [ ] **Step 1: Implementar `policies.py`**
|
||||
- [x] **Step 1: Implementar `policies.py`**
|
||||
|
||||
```python
|
||||
"""Router /policies: list y versiones."""
|
||||
@@ -4378,7 +4387,7 @@ def list_versions(
|
||||
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Implementar `violations.py`**
|
||||
- [x] **Step 2: Implementar `violations.py`**
|
||||
|
||||
```python
|
||||
"""Router /violations: list filtrable."""
|
||||
@@ -4411,7 +4420,7 @@ def list_violations(
|
||||
return items
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
- [x] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add core/src/agentforge_core/api/policies.py core/src/agentforge_core/api/violations.py
|
||||
|
||||
Reference in New Issue
Block a user