Skip to content

Reconnect pull-wake stream after sleep#4634

Open
KyleAMathews wants to merge 3 commits into
fix-child-wake-deliveryfrom
fix-wake-resume-after-sleep
Open

Reconnect pull-wake stream after sleep#4634
KyleAMathews wants to merge 3 commits into
fix-child-wake-deliveryfrom
fix-wake-resume-after-sleep

Conversation

@KyleAMathews

Copy link
Copy Markdown
Contributor

Detect long heartbeat timer gaps in the pull-wake runner and reconnect the wake stream after a computer resumes from sleep or a long event-loop stall. This keeps desktop agents listening for wake notifications instead of staying attached to a stale long-lived stream.

Root Cause

The pull-wake runner already reconnects its wake stream after repeated heartbeat failures. After a laptop sleep/resume, though, the long-lived wake stream can become stale while new heartbeat requests succeed again. In that state the runner can continue reporting a connected stream but stop receiving wake notifications.

This PR is stacked on #4632, which preserves deferred same-stream wake delivery and fixes stale in-flight heartbeat ownership across runner restarts. This change handles a separate failure mode: the process was suspended long enough that the existing wake stream should be considered suspect even if the next heartbeat succeeds.

Approach

Track wall-clock time between heartbeat timer ticks:

const elapsedMs = now - lastHeartbeatTickAt

If the elapsed gap is larger than resumeGapResetMs, the runner sends STREAM_RESET to the pull-wake lifecycle machine. The default threshold is the runner lease duration, so normal short event-loop delays do not reconnect the stream, while sleep/resume-sized gaps do.

The test simulates sleep by advancing wall-clock time before the heartbeat timer gets CPU again, then verifies that the current stream is cancelled and a new stream connection is opened.

Key Invariants

  • Heartbeat requests still run on their normal cadence.
  • Normal short timer drift does not reset the stream.
  • Sleep/resume or long event-loop stalls force a wake-stream reconnect.
  • The existing Refactor wake registry sync and fix child wake delivery #4632 guarantees around deferred same-stream wakes and heartbeat ownership remain intact.

Non-goals

  • This does not change durable-stream client retry behavior.
  • This does not change server-side runner leases or wake claim semantics.
  • This does not replace heartbeat-failure-based reconnects; it adds a separate resume-gap signal.

Trade-offs

The runner may reconnect after any event-loop stall longer than the lease, not only literal OS sleep. That is intentional: after a lease-sized gap, the long-lived stream is cheap to re-establish and safer than assuming it is still delivering wake events.

Verification

cd packages/agents-runtime
pnpm exec vitest run test/pull-wake-runner.test.ts --reporter=dot
pnpm run typecheck

Also run from the repository root for changeset coverage:

GITHUB_BASE_REF=main node scripts/check-changeset.mjs

Verified locally:

  • pull-wake-runner.test.ts: 65 passed
  • @electric-ax/agents-runtime typecheck: passed after building the fresh worktree dependency @electric-ax/agents-mcp
  • Changeset check: passed

Files changed

  • packages/agents-runtime/src/pull-wake-runner.ts
    • Adds resumeGapResetMs configuration.
    • Tracks heartbeat timer wall-clock gaps.
    • Forces STREAM_RESET when the gap exceeds the configured threshold.
  • packages/agents-runtime/test/pull-wake-runner.test.ts
    • Adds regression coverage for reconnecting after a simulated sleep/resume gap.
  • .changeset/reconnect-wake-stream-after-sleep.md
    • Adds a patch changeset for @electric-ax/agents-runtime.

Stacking

Stacked on #4632.

@github-actions

github-actions Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Electric Agents Desktop Builds

Build artifacts for commit ae585ea.

Platform Status Artifact
macOS Apple Silicon Passed DMG
macOS Intel Passed DMG
Windows x64 Passed Installer
Linux x64 Passed AppImage / deb

Workflow run

@codecov

codecov Bot commented Jun 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 58.00%. Comparing base (2cc6c26) to head (ae585ea).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@                     Coverage Diff                     @@
##           fix-child-wake-delivery    #4634      +/-   ##
===========================================================
- Coverage                    58.01%   58.00%   -0.02%     
===========================================================
  Files                          342      342              
  Lines                        40345    40364      +19     
  Branches                     11778    11779       +1     
===========================================================
+ Hits                         23407    23413       +6     
- Misses                       16900    16913      +13     
  Partials                        38       38              
Flag Coverage Δ
packages/agents 72.64% <ø> (ø)
packages/agents-mobile 80.67% <ø> (ø)
packages/agents-runtime 83.49% <100.00%> (-0.05%) ⬇️
packages/agents-server 75.48% <ø> (-0.03%) ⬇️
packages/agents-server-ui 7.51% <ø> (ø)
packages/electric-ax 51.06% <ø> (ø)
typescript 58.00% <100.00%> (-0.02%) ⬇️
unit-tests 58.00% <100.00%> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Electric Agents Mobile Build

Local mobile checks ran for commit ae585ea.

The EAS Android preview build was skipped because the mobile-eas-build label is not present.
Add the mobile-eas-build label to this PR to produce an installable preview build.

Workflow run

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.

1 participant