diff --git a/docs/memory/feature-flows.md b/docs/memory/feature-flows.md index a3f8f6caa..7b00ded58 100644 --- a/docs/memory/feature-flows.md +++ b/docs/memory/feature-flows.md @@ -12,6 +12,7 @@ | Date | ID | Feature | Flow | |------|-----|---------|------| | 2026-04-24 | WEBHOOK-001 (#291) | Webhook triggers — token-authenticated public URL fires schedule executions | [webhook-triggers.md](feature-flows/webhook-triggers.md) | +| 2026-04-25 | #496 | Backlog drain spawn fix — repair `_spawn_drain` lazy import after #95 renamed `_execute_task_background` → `_run_async_task_with_persistence`; AST-based regression tests pin the contract | [persistent-task-backlog.md](feature-flows/persistent-task-backlog.md) | | 2026-04-25 | #487 | Telegram file upload Phase 2 — workspace delivery hardening: NFKC sanitizer with collision dedup, spec injection format `[File uploaded by {uploader}]: {name} ({size}) saved to {path}`, all-writes-failed channel error + abort. Same code path benefits Slack inbound. | [telegram-integration.md](feature-flows/telegram-integration.md), [slack-file-sharing.md](feature-flows/slack-file-sharing.md) | | 2026-04-23 | #476 | SQLite lexicographic cutoff bug fix — new `iso_cutoff(hours)` helper replaces `datetime('now', ...)` in 15 sites across rate-limit / dashboard / schedules; `max_retries` default flipped `1 → 0`; `cleanup_old_rate_limit_events` wired into `CleanupService` (phase 6, hourly) | [subscription-auto-switch.md](feature-flows/subscription-auto-switch.md), [cleanup-service.md](feature-flows/cleanup-service.md), [scheduler-service.md](feature-flows/scheduler-service.md) | | 2026-04-22 | #458 | `.gitignore` init fix — `initialize_git_in_container` now appends missing patterns instead of truncate-and-write; adds `.env`, `.env.*`, `.mcp.json` to the default list and runs for both `/home/developer` and legacy `/home/developer/workspace` (stops credential leak on first GitHub sync) | [github-repo-initialization.md](feature-flows/github-repo-initialization.md) | diff --git a/docs/memory/feature-flows/parallel-capacity.md b/docs/memory/feature-flows/parallel-capacity.md index 5f6d6aa8e..3abdd730e 100644 --- a/docs/memory/feature-flows/parallel-capacity.md +++ b/docs/memory/feature-flows/parallel-capacity.md @@ -61,8 +61,8 @@ The frontend displays slot usage as a vertical capacity meter bar on the Agents │ │ 1. Create execution record in database (chat.py:602-613) │ │ │ │ 2. Router acquires slot directly (chat.py:644-651) │ │ │ │ 3. If full → 429 response (chat.py:653-663) │ │ -│ │ 4. Spawn _run_async_task_with_persistence() with release_slot=True │ │ -│ │ 5. Background task releases slot in finally (chat.py:554-557) │ │ +│ │ 4. Spawn _run_async_task_with_persistence() (router pre-acquired)│ │ +│ │ 5. TaskExecutionService releases slot in finally (slot_already_held=True)│ │ │ │ │ │ │ PUBLIC path (public.py:315-322 → task_execution_service.py): │ │ │ │ 1. Delegate to TaskExecutionService.execute_task() │ │ @@ -137,7 +137,7 @@ POST /api/agents/{name}/task (async) │ 1. db.get_max_parallel_tasks(name) │ │ 2. slot_service.acquire_slot(...) │ │ 3. If not acquired → 429 Too Many Requests │ - │ 4. Spawn background task with release_slot=True │ + │ 4. Spawn `_run_async_task_with_persistence()` │ └─────────────────────────────────────────────────┘ ``` diff --git a/docs/memory/feature-flows/task-execution-service.md b/docs/memory/feature-flows/task-execution-service.md index 418302c77..fd596ec22 100644 --- a/docs/memory/feature-flows/task-execution-service.md +++ b/docs/memory/feature-flows/task-execution-service.md @@ -58,7 +58,7 @@ Callers inspect `result.status` to decide HTTP response. Status values come from Moved from `routers/chat.py`. Module-level async function. Used by: - `TaskExecutionService.execute_task()` internally (line 249) -- `routers/chat.py` for `/chat` endpoint (line 248) and `_execute_task_background` (line 477) +- `routers/chat.py` for `/chat` endpoint and `_run_async_task_with_persistence` (the async-mode wrapper introduced by #95; previously named `_execute_task_background`) ```python async def agent_post_with_retry( @@ -163,7 +163,7 @@ The endpoint handles: 2. Determine `triggered_by` from headers (lines 686-691) 3. Create execution record early (lines 694-705) -- passed to service as `execution_id` 4. Collaboration tracking for agent-to-agent (lines 710-732) -- stays in router -5. **Async mode branch** (lines 735-808) -- spawns `_execute_task_background()`, does NOT use service +5. **Async mode branch** -- pre-acquires capacity slot, then spawns `_run_async_task_with_persistence()` which delegates to `task_execution_service.execute_task(slot_already_held=True)` (post-#95) 6. **Sync mode branch** (lines 810-827) -- delegates to `task_execution_service.execute_task()` 7. Collaboration activity completion (lines 830-839) 8. Error translation to HTTP exceptions (lines 842-857)