Skip to content

refactor: Route async task mode through TaskExecutionService (#95)#162

Open
AndriiPasternak31 wants to merge 4 commits intoAbilityai:mainfrom
AndriiPasternak31:AndriiPasternak31/95-async-task-service
Open

refactor: Route async task mode through TaskExecutionService (#95)#162
AndriiPasternak31 wants to merge 4 commits intoAbilityai:mainfrom
AndriiPasternak31:AndriiPasternak31/95-async-task-service

Conversation

@AndriiPasternak31
Copy link
Copy Markdown
Contributor

Summary

  • Replaced inline slot/activity/sanitization/error logic in _execute_task_background() with delegation to TaskExecutionService, matching the pattern used by internal.py and public.py
  • Extracted _save_to_chat_session() helper to eliminate DRY violation between async and sync session persistence paths
  • Net reduction of ~124 lines in chat.py

Changes

  • src/backend/routers/chat.py — Rewrote _execute_task_background() as thin wrapper, simplified async branch, extracted shared helper
  • tests/test_parallel_task.py — Added 5 new tests (session persistence, collaboration activity, safety net)
  • docs/memory/changelog.md — Added changelog entry
  • docs/memory/feature-flows/task-execution-service.md — Updated flow documentation

Test Plan

  • Existing tests pass: pytest tests/test_parallel_task.py -v
  • New tests pass: TestAsyncSessionPersistence, TestAsyncCollaborationActivity, TestAsyncSafetyNet
  • Manual: async task returns immediately and completes via polling
  • Manual: sync task with save_to_session still persists to chat session
  • Manual: agent-to-agent async task completes collaboration activity

Closes #95

Generated with Claude Code

AndriiPasternak31 and others added 4 commits March 25, 2026 01:28
…ai#95)

The async mode path in chat.py duplicated slot management, activity
tracking, credential sanitization, and error handling instead of
delegating to TaskExecutionService. Any fix to the service didn't
apply to async mode, creating two maintenance surfaces.

- Replace _execute_task_background() with thin wrapper delegating to
  TaskExecutionService (matches internal.py pattern)
- Simplify async branch: remove inline slot/activity/status management
- Extract _save_to_chat_session() helper to eliminate DRY violation
  between async and sync session persistence paths
- Add 5 new tests for session persistence, collaboration activity,
  and safety net error handling
- Net reduction of ~124 lines in chat.py

Closes Abilityai#95

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix stringly-typed status comparison: "failed" → TaskExecutionStatus.FAILED
- Remove unused `source` variable (ExecutionSource computed but never used)
- Add try/except to sync path collaboration activity completion (matches async path)
- Extract poll_execution_until_done() test helper, eliminating 5 duplicate polling loops

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Both branches added entries at the top of changelog.md. Kept both
entries in chronological order (newest first): our Abilityai#95 refactor entry
above upstream's Abilityai#74 and Abilityai#100 entries.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@vybe vybe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the clean refactor! The delegation pattern is solid and the 5 new tests are a great addition. A few items before merge:

Required

  • execution_time_ms regression in _save_to_chat_session() — The old _execute_task_background() passed execution_time_ms to db.add_chat_message(). The new helper omits it because TaskExecutionResult has no such field. Async chat sessions will now always store NULL for execution time. Either add execution_time_ms: Optional[int] to TaskExecutionResult and populate it in the service, or explicitly accept this loss and document it.

  • context_used guard dropped — Old: context_used if context_used > 0 else None. New: stores result.context_used directly (could persist 0 instead of NULL). Small behavior change worth preserving for consistency.

  • Please rebase onto main before merge — the branch has a merge commit (merge: resolve changelog conflict with upstream/main) that should be cleaned up.

Minor

  • Issue #95 is missing the type-refactor label.
  • Confirm public.py's _execute_public_chat_background() (line 775) is considered resolved — it appears to already delegate to TaskExecutionService, but the issue's "Files to Change" section lists it. Either close the loop in the PR description or follow up in a separate issue.
  • Add ## Security Considerations section to task-execution-service.md (even a brief "N/A — service layer, no direct auth or user input" is sufficient to satisfy the flow format spec).

Please address the required items and request re-review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Route async task mode through TaskExecutionService

2 participants