Skip to content

Gateway auto-resume on a non-interactive platform (webhook) acknowledges restoration instead of completing the interrupted turn #57056

Description

@denysgaievskyi

Gateway auto-resume on a non-interactive platform (webhook) acknowledges restoration instead of completing the interrupted turn

Version

Hermes v2026.7.1 (0.18.0). Code path present unchanged at least since 0.13.0's session-resume feature.

Summary

When the gateway is interrupted mid-turn (SIGTERM drain / restart) and marks a session resume_pending, the next boot re-runs the session via _schedule_resume_pending_sessions(), which synthesizes an empty-text internal MessageEvent. The resume [System note] then tells the model to "report to the user that the session was restored successfully and ask what they would like to do next" and to "skip any unfinished work from the conversation history."

That guidance is correct for an interactive platform (CLI/Telegram/Slack DM), where a human is waiting and can answer "what next?". It is wrong for a non-interactive platform such as webhook, where there is no responder: the resumed turn emits a short "session restored" acknowledgement that goes nowhere, and — because it is told to skip unfinished work — it abandons the interrupted task instead of finishing it.

Where

gateway/run.py, the _is_resume_pending branch (~L17517-17549 in v2026.7.1):

if message:
    _resume_guidance = "Address the user's NEW message below FIRST ..."
else:
    _resume_guidance = (
        "Report to the user that the session was restored "
        "successfully and ask what they would like to do next."
    )
message = (
    f"[System note: The previous turn was interrupted by {_reason_phrase}; "
    f"the gateway is now back online. Any restart/shutdown command in the "
    f"history has already run — do NOT re-execute or verify it. {_resume_guidance} "
    f"Do NOT re-execute old tool calls — skip any unfinished work from the "
    f"conversation history.]"
    + (f"\n\n{message}" if message else "")
)

Reproduce

  1. Run the gateway with a webhook platform adapter connected.
  2. Send a webhook event that kicks off a long-running agent task (multiple tool turns).
  3. While it is mid-task, send SIGTERM (drain) so the session is marked resume_pending, then let the process exit and restart.
  4. On boot, _schedule_resume_pending_sessions() re-runs the session.

Observed: the resumed turn is 1 API call producing a short "session restored" text response (finish_reason=stop, no tool calls); the interrupted task is not completed and no downstream output is produced.

Expected: on a non-interactive platform, the resumed turn should continue and complete the interrupted task (re-run the remaining tool work), not emit an interactive "restored" acknowledgement.

Suggested fix

Make the empty-message resume guidance platform-aware. For interactive platforms keep the current "report restored / ask what next" behaviour. For non-interactive platforms (webhook, and any adapter without a live responder), instruct the model to continue and complete the interrupted turn, and drop the "skip any unfinished work" clause for that case (keep the "a restart/shutdown command already ran, don't re-run it" caveat). Idempotency of the completed work is the integration's responsibility (dedup on the downstream write).

Impact

Session-resume marks + re-schedules correctly, but for webhook integrations the interrupted work is silently dropped on resume — the operator must re-trigger manually. This defeats the practical value of resume_pending for automated (non-interactive) gateway workloads.

Related

Environment note

Observed on a webhook-only gateway deployment (single-pod, EKS). Session marking + boot re-scheduling work correctly (fresh Scheduled auto-resume for N session(s) on boot); only the resumed turn's behaviour is wrong for the non-interactive case.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium — degraded but workaround existscomp/gatewayGateway runner, session dispatch, deliveryplatform/webhookWebhook / API serversweeper:risk-message-deliverySweeper risk: may drop, duplicate, misroute, or suppress messagessweeper:risk-session-stateSweeper risk: may lose/corrupt/mis-associate session or context statetype/bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions