Problem
The /sessions/{session_id}/cancel endpoint has a TODO that was never implemented:
@app.post("/sessions/{session_id}/cancel")
async def cancel_session(
session_id: str,
user_id: str = Header(alias="X-User-ID", default=None),
):
...
# TODO: Cancel session worker workflow <-- NOT IMPLEMENTED
return {"status": "cancelled"}
This means cancelled sessions continue running in the DBOS workflow loop until they timeout (24 hours).
Location
backend/src/mainloop/api.py:1122-1144
Fix
Add the workflow cancellation call:
@app.post("/sessions/{session_id}/cancel")
async def cancel_session(session_id: str, ...):
...
DBOS.cancel_workflow(session_id) # Add this
await db.update_session(session_id, status=SessionStatus.CANCELLED)
return {"status": "cancelled"}
Context
- Worker tasks (
/tasks/{task_id}/cancel) already do this correctly
- Sessions don't have K8s namespaces to clean up (they run in-process via Agent SDK)
- Just need the DBOS workflow cancellation to stop the message-waiting loop
Future consideration
Investigate merging Session and WorkerTask models - they have significant overlap:
- Both have statuses, GitHub integration fields, questions, plan_text
Session already has has_repo property to distinguish code work
- Could simplify to one unified model with one workflow that branches based on
repo_url
Problem
The
/sessions/{session_id}/cancelendpoint has a TODO that was never implemented:This means cancelled sessions continue running in the DBOS workflow loop until they timeout (24 hours).
Location
backend/src/mainloop/api.py:1122-1144Fix
Add the workflow cancellation call:
Context
/tasks/{task_id}/cancel) already do this correctlyFuture consideration
Investigate merging
SessionandWorkerTaskmodels - they have significant overlap:Sessionalready hashas_repoproperty to distinguish code workrepo_url