Skip to content

Commit 0a64fce

Browse files
authored
Merge pull request SeemSeam#112 from daniellee2015/clean/upstream-cancel-completion-v2
fix(adapters): emit completion on cancellation to avoid stuck processing
2 parents 1e58557 + 7d1ef88 commit 0a64fce

5 files changed

Lines changed: 69 additions & 63 deletions

File tree

lib/askd/adapters/claude.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -552,18 +552,21 @@ def handle_task(self, task: QueuedTask) -> ProviderResult:
552552
def _finalize_result(self, result: ProviderResult, req: ProviderRequest, task: QueuedTask) -> None:
553553
_write_log(f"[INFO] done provider=claude req_id={result.req_id} exit={result.exit_code}")
554554

555-
# Skip completion hook for cancelled tasks
555+
reply_for_hook = result.reply
556+
notify_done_seen = result.done_seen
556557
if task.cancelled:
557-
_write_log(f"[INFO] Task cancelled, skipping completion hook: req_id={task.req_id}")
558-
return
558+
_write_log(f"[WARN] Task cancelled, sending failure completion hook: req_id={task.req_id}")
559+
notify_done_seen = False
560+
if not (reply_for_hook or "").strip():
561+
reply_for_hook = "Task cancelled or timed out before completion."
559562

560-
_write_log(f"[INFO] notify_completion caller={req.caller} done_seen={result.done_seen} email_req_id={req.email_req_id}")
563+
_write_log(f"[INFO] notify_completion caller={req.caller} done_seen={notify_done_seen} email_req_id={req.email_req_id}")
561564
notify_completion(
562565
provider="claude",
563566
output_file=req.output_path,
564-
reply=result.reply,
567+
reply=reply_for_hook,
565568
req_id=result.req_id,
566-
done_seen=result.done_seen,
569+
done_seen=notify_done_seen,
567570
caller=req.caller,
568571
email_req_id=req.email_req_id,
569572
email_msg_id=req.email_msg_id,

lib/askd/adapters/codex.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -279,20 +279,20 @@ def handle_task(self, task: QueuedTask) -> ProviderResult:
279279
f"anchor={result.anchor_seen} done={result.done_seen}"
280280
)
281281

282-
# Skip completion hook for cancelled tasks
282+
reply_for_hook = reply
283+
notify_done_seen = done_seen
283284
if task.cancelled:
284-
_write_log(f"[INFO] Task cancelled, skipping completion hook: req_id={task.req_id}")
285-
return result
286-
287-
# Log caller info before notify_completion
288-
_write_log(f"[INFO] notify_completion caller={req.caller} done_seen={done_seen}")
289-
285+
_write_log(f"[WARN] Task cancelled, sending failure completion hook: req_id={task.req_id}")
286+
notify_done_seen = False
287+
if not reply_for_hook.strip():
288+
reply_for_hook = "Task cancelled or timed out before completion."
289+
_write_log(f"[INFO] notify_completion caller={req.caller} done_seen={notify_done_seen}")
290290
notify_completion(
291291
provider="codex",
292292
output_file=req.output_path,
293-
reply=reply,
293+
reply=reply_for_hook,
294294
req_id=task.req_id,
295-
done_seen=done_seen,
295+
done_seen=notify_done_seen,
296296
caller=req.caller,
297297
email_req_id=req.email_req_id,
298298
email_msg_id=req.email_msg_id,

lib/askd/adapters/droid.py

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -195,22 +195,23 @@ def handle_task(self, task: QueuedTask) -> ProviderResult:
195195
combined = "\n".join(chunks)
196196
final_reply = extract_reply_for_req(combined, task.req_id)
197197

198-
# Skip completion hook for cancelled tasks
199-
if not task.cancelled:
200-
notify_completion(
201-
provider="droid",
202-
output_file=req.output_path,
203-
reply=final_reply,
204-
req_id=task.req_id,
205-
done_seen=done_seen,
206-
caller=req.caller,
207-
email_req_id=req.email_req_id,
208-
email_msg_id=req.email_msg_id,
209-
email_from=req.email_from,
210-
work_dir=req.work_dir,
211-
)
212-
else:
213-
_write_log(f"[INFO] Task cancelled, skipping completion hook: req_id={task.req_id}")
198+
reply_for_hook = final_reply
199+
if task.cancelled:
200+
_write_log(f"[WARN] Task cancelled, sending failure completion hook: req_id={task.req_id}")
201+
if not reply_for_hook.strip():
202+
reply_for_hook = "Task cancelled or timed out before completion."
203+
notify_completion(
204+
provider="droid",
205+
output_file=req.output_path,
206+
reply=reply_for_hook,
207+
req_id=task.req_id,
208+
done_seen=done_seen and (not task.cancelled),
209+
caller=req.caller,
210+
email_req_id=req.email_req_id,
211+
email_msg_id=req.email_msg_id,
212+
email_from=req.email_from,
213+
work_dir=req.work_dir,
214+
)
214215

215216
result = ProviderResult(
216217
exit_code=0 if done_seen else 2,

lib/askd/adapters/gemini.py

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -274,22 +274,23 @@ def handle_task(self, task: QueuedTask) -> ProviderResult:
274274
else:
275275
_write_log(f"[WARN] Degraded completion rejected: empty reply for req_id={task.req_id}")
276276

277-
# Skip completion hook for cancelled tasks
278-
if not task.cancelled:
279-
notify_completion(
280-
provider="gemini",
281-
output_file=req.output_path,
282-
reply=final_reply,
283-
req_id=task.req_id,
284-
done_seen=done_seen,
285-
caller=req.caller,
286-
email_req_id=req.email_req_id,
287-
email_msg_id=req.email_msg_id,
288-
email_from=req.email_from,
289-
work_dir=req.work_dir,
290-
)
291-
else:
292-
_write_log(f"[INFO] Task cancelled, skipping completion hook: req_id={task.req_id}")
277+
reply_for_hook = final_reply
278+
if task.cancelled:
279+
_write_log(f"[WARN] Task cancelled, sending failure completion hook: req_id={task.req_id}")
280+
if not reply_for_hook.strip():
281+
reply_for_hook = "Task cancelled or timed out before completion."
282+
notify_completion(
283+
provider="gemini",
284+
output_file=req.output_path,
285+
reply=reply_for_hook,
286+
req_id=task.req_id,
287+
done_seen=done_seen and (not task.cancelled),
288+
caller=req.caller,
289+
email_req_id=req.email_req_id,
290+
email_msg_id=req.email_msg_id,
291+
email_from=req.email_from,
292+
work_dir=req.work_dir,
293+
)
293294

294295
result = ProviderResult(
295296
exit_code=0 if done_seen else 2,

lib/askd/adapters/opencode.py

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -222,22 +222,23 @@ def _handle_task_locked(self, task: QueuedTask, session: Any, session_key: str,
222222
else:
223223
_write_log(f"[WARN] Degraded completion rejected: empty reply for req_id={task.req_id}")
224224

225-
# Skip completion hook for cancelled tasks
226-
if not task.cancelled:
227-
notify_completion(
228-
provider="opencode",
229-
output_file=req.output_path,
230-
reply=final_reply,
231-
req_id=task.req_id,
232-
done_seen=done_seen,
233-
caller=req.caller,
234-
email_req_id=req.email_req_id,
235-
email_msg_id=req.email_msg_id,
236-
email_from=req.email_from,
237-
work_dir=req.work_dir,
238-
)
239-
else:
240-
_write_log(f"[INFO] Task cancelled, skipping completion hook: req_id={task.req_id}")
225+
reply_for_hook = final_reply
226+
if task.cancelled:
227+
_write_log(f"[WARN] Task cancelled, sending failure completion hook: req_id={task.req_id}")
228+
if not reply_for_hook.strip():
229+
reply_for_hook = "Task cancelled or timed out before completion."
230+
notify_completion(
231+
provider="opencode",
232+
output_file=req.output_path,
233+
reply=reply_for_hook,
234+
req_id=task.req_id,
235+
done_seen=done_seen and (not task.cancelled),
236+
caller=req.caller,
237+
email_req_id=req.email_req_id,
238+
email_msg_id=req.email_msg_id,
239+
email_from=req.email_from,
240+
work_dir=req.work_dir,
241+
)
241242

242243
result = ProviderResult(
243244
exit_code=0 if done_seen else 2,

0 commit comments

Comments
 (0)