Skip to content

Commit 40eb3ae

Browse files
committed
Heartbeat every 30s while waiting on the approval workflow
The approval handler blocks on handle.result() for as long as the operator takes to decide. AgenticSession only heartbeats between LLM turns, so a multi-hour wait inside this handler would trigger heartbeat timeout (default 120s) and kill the activity. Spawn a ticker task that fires activity.heartbeat() every 30s for the duration of the wait, cancelled in finally when handle.result() returns. Survives realistic operator delays without churn. Existing tests still pass (the test path uses a fake deps record that doesn't go through this code path).
1 parent f8d6c8f commit 40eb3ae

1 file changed

Lines changed: 16 additions & 1 deletion

File tree

tool_registry_incident_triage/triage_activity.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,4 +367,19 @@ async def _real_request_human_approval(
367367
# operator should not get a second prompt for the same incident.
368368
id_conflict_policy=WorkflowIDConflictPolicy.USE_EXISTING,
369369
)
370-
return await handle.result()
370+
371+
# Heartbeat every 30 seconds while waiting on the approval workflow.
372+
# AgenticSession only heartbeats between LLM turns, so a multi-hour
373+
# operator wait inside this handler would otherwise trigger heartbeat
374+
# timeout in 120s and kill the activity. The ticker keeps the activity
375+
# alive until the operator decides.
376+
async def _ticker() -> None:
377+
while True:
378+
await asyncio.sleep(30)
379+
activity.heartbeat()
380+
381+
ticker_task = asyncio.create_task(_ticker())
382+
try:
383+
return await handle.result()
384+
finally:
385+
ticker_task.cancel()

0 commit comments

Comments
 (0)