fix: don't filter cron payloads containing 'heartbeat'#2219
fix: don't filter cron payloads containing 'heartbeat'#2219thewilloftheshadow merged 1 commit intoopenclaw:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Refines system-event compaction so events containing the word “heartbeat” are no longer broadly filtered (preventing cron payloads from being dropped), and adds Android support for specifying a manual gateway password used when connecting to manual endpoints.
Changes:
- Narrow
compactSystemEventfiltering to match the actual heartbeat prompt / noise strings instead of any occurrence of “heartbeat”. - Add an Android “Manual Gateway Password” preference (encrypted) and UI input for it.
- Use the manual password (when set) for connections to manual gateway endpoints.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/auto-reply/reply/session-updates.ts | Makes heartbeat filtering more specific to avoid dropping cron/system events that merely mention “heartbeat”. |
| apps/android/app/src/main/java/com/clawdbot/android/ui/SettingsSheet.kt | Adds a password input field for manual gateway configuration. |
| apps/android/app/src/main/java/com/clawdbot/android/SecurePrefs.kt | Persists a manual gateway password in encrypted prefs and exposes it as a StateFlow. |
| apps/android/app/src/main/java/com/clawdbot/android/NodeRuntime.kt | Plumbs manual password into runtime and uses it when connecting to `manual |
| apps/android/app/src/main/java/com/clawdbot/android/MainViewModel.kt | Exposes manual password state and setter to the Compose UI layer. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // For manual endpoints, use the manual password if set; otherwise fall back to stored password. | ||
| val password = if (endpoint.stableId.startsWith("manual|")) { | ||
| manualPassword.value.takeIf { it.isNotEmpty() } ?: prefs.loadGatewayPassword() | ||
| } else { | ||
| prefs.loadGatewayPassword() | ||
| } |
There was a problem hiding this comment.
connect() now uses manualPassword for endpoints with stableId starting with "manual|", but refreshGatewayConnection() still always uses prefs.loadGatewayPassword(). If the app is connected to a manual endpoint that requires a different password, a refresh/reconnect path can switch back to the stored password and fail. Consider centralizing password selection (manual vs stored) and using it consistently in both connect() and refreshGatewayConnection().
| OutlinedTextField( | ||
| value = manualPassword, | ||
| onValueChange = viewModel::setManualPassword, | ||
| label = { Text("Password") }, | ||
| modifier = Modifier.fillMaxWidth(), | ||
| enabled = manualEnabled, | ||
| visualTransformation = PasswordVisualTransformation(), | ||
| singleLine = true, | ||
| ) |
There was a problem hiding this comment.
The PR title/description focuses on fixing heartbeat-related filtering in session-updates.ts, but this change set also adds a new manual gateway password preference + UI field and connection behavior on Android. If this Android work is intentional, please update the PR description to reflect it; otherwise consider splitting it into a separate PR to keep scope focused.
| // Filter out the actual heartbeat prompt, but not cron jobs that mention "heartbeat" | ||
| // The heartbeat prompt starts with "Read HEARTBEAT.md" - cron payloads won't match this | ||
| if (lower.startsWith("read heartbeat.md")) return null; | ||
| // Also filter heartbeat poll/wake noise | ||
| if (lower.includes("heartbeat poll") || lower.includes("heartbeat wake")) return null; |
There was a problem hiding this comment.
Add/adjust unit tests for the updated system-event filtering behavior. There are existing tests for prependSystemEvents, but none asserting that (1) the heartbeat prompt line is filtered and (2) system events containing the word "heartbeat" in arbitrary payload text (e.g. cron payloads) are not filtered. Covering both cases will prevent regressions back to over-broad filtering.
07bcde4 to
cf9eeb9
Compare
…hanks @dwfinkelstein) # Conflicts: # CHANGELOG.md
cf9eeb9 to
3d3d1bd
Compare
Problem
The
compactSystemEventfilter insession-updates.tswas filtering out any system event containing the word "heartbeat". This was intended to suppress the standard heartbeat prompt from being echoed, but it inadvertently blocked cron job payloads that mentioned "heartbeat" in their text.Impact: Cron jobs with payload text like "📧 EMAIL SCANNER HEARTBEAT" would silently fail - the cron would report "ok" but the message never reached the agent because it was filtered out.
Solution
Changed the filter to be more specific:
Testing
Tested locally with a cron job that has "heartbeat" in its payload - it now properly delivers the message to the agent.
Found while debugging why hourly heartbeat cron jobs were reporting success but never posting messages.