Skip to content

Commit df4c8d2

Browse files
croakyoz-agent
andauthored
Skip periodic chip refresh when fingerprint matches (#10307)
The 30s timer passed `allow_fingerprint_skip = false`, so the GitHub PR chip re-ran `gh pr view` every tick. Each `gh` invocation makes a GraphQL viewer precheck; across 3+ tabs this exhausts a user's 5,000-pt/hr quota (#9830). Pass `true` so the timer uses the chip's fingerprint as a cache key. Branch, cwd, and `git`/`gh`/`gt` commands still bust it. Make the fingerprint skip status-aware so a previous `Error` or `TimedOut` is treated as a cache miss. Otherwise retryable failures would become sticky: `last_fingerprint` is recorded before the command runs and `last_failure_fingerprint` is intentionally empty for non-deterministic failures. Deterministic auth failures continue to be suppressed via `last_failure_fingerprint`. ## Description The recursive timer continuation in `fetch_chip_value_at_interval` was the only call site passing `allow_fingerprint_skip = false`. Every other entry point passes `true`. The chip's fingerprint inputs (`SessionId`, `WorkingDirectory`, `GitBranch`, `RequiredExecutablesPresence`, `InvalidatingCommandCount`) combined with `invalidate_on_commands ["git", "gh", "gt"]` already capture every input that can change the PR URL. `maybe_skip_fetch_due_to_matching_fingerprint` now filters out states whose `update_status` is `Error` or `TimedOut` before the fingerprint-equality check, so the periodic timer still retries transient failures while successful refreshes are skipped. Other periodic chips are unaffected. `Time`/`Date` have no fingerprint inputs, so the skip check is a no-op. `ShellGitBranch`/`GitDiffStats` route through the `GitRepoStatusModel` filesystem watcher on local sessions and don't reach this path. Warp version v0.2026.04.29.08.57.stable_01 ## Linked Issue Closes #9830. - [ ] The linked issue is labeled `ready-to-spec` or `ready-to-implement`. ## Testing Measured GraphQL rate-limit consumption before and after disabling the chip locally on macOS: - Before: ~0.66 calls/sec sustained. - After: ~0.012 calls/sec (1 external call in 84s; the rest were the polling query itself). `test_github_pr_chip_transient_failure_retries_with_same_fingerprint` now passes `allow_fingerprint_skip = true` to exercise the same path the periodic timer uses; without the status-aware filter it would short-circuit as `Cached` and the transient failure would become sticky. ## Agent Mode - [x] Warp Agent Mode - This PR was created via Warp's AI Agent Mode CHANGELOG-BUG-FIX: Stop the GitHub PR prompt chip from polling `gh pr view` every 30 seconds when nothing has changed, preventing it from draining the user's GitHub GraphQL rate limit. --------- Co-authored-by: Oz <oz-agent@warp.dev>
1 parent 98fa392 commit df4c8d2

2 files changed

Lines changed: 20 additions & 2 deletions

File tree

app/src/context_chips/current_prompt.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -518,9 +518,21 @@ impl CurrentPrompt {
518518
return false;
519519
};
520520

521+
// A retryable failure (`Error`, `TimedOut`) is not a usable cached
522+
// result: `last_fingerprint` is recorded before the command runs, and
523+
// such failures intentionally do not populate `last_failure_fingerprint`.
524+
// Without this guard, the next periodic tick would treat the failed
525+
// attempt as a cache hit and never retry. Deterministic failures
526+
// continue to be suppressed via `last_failure_fingerprint`.
521527
let should_skip = self
522528
.states
523529
.get(chip_kind)
530+
.filter(|state| {
531+
!matches!(
532+
state.update_status,
533+
ChipUpdateStatus::Error | ChipUpdateStatus::TimedOut
534+
)
535+
})
524536
.and_then(|state| state.last_fingerprint.as_ref())
525537
.is_some_and(|existing| existing == &new_fingerprint);
526538

@@ -982,7 +994,7 @@ impl CurrentPrompt {
982994
chip_kind_clone
983995
},
984996
|me, chip_kind, ctx| {
985-
me.fetch_chip_value_at_interval(&chip_kind, None, None, false, ctx);
997+
me.fetch_chip_value_at_interval(&chip_kind, None, None, true, ctx);
986998
},
987999
);
9881000

app/src/context_chips/current_prompt_tests.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -964,11 +964,17 @@ fn test_github_pr_chip_transient_failure_retries_with_same_fingerprint() {
964964
.to_chip()
965965
.expect("expected github pr chip");
966966
let generator = chip.generator().clone();
967+
// Pass `allow_fingerprint_skip = true` to exercise the same
968+
// path the periodic timer uses. The previous attempt left the
969+
// chip in `Error` state with the fingerprint already recorded;
970+
// without status-aware skip handling, this call would short-
971+
// circuit as `Cached` and the transient failure would become
972+
// sticky.
967973
current_prompt.fetch_chip_value_once(
968974
&ContextChipKind::GithubPullRequest,
969975
&generator,
970976
None,
971-
false,
977+
true,
972978
ctx,
973979
);
974980
current_prompt.await_generators(ctx)

0 commit comments

Comments
 (0)