You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug]: Per-message nudge triggers every turn after restart — lastPerMessageNudgeTokens not persisted when nudge fires without anchor changes #60
The per-message context nudge fires on every single turn after restarting OpenCode, regardless of actual token growth since the last nudge. The nudge message shows a large growth (e.g. +69.8K since last nudge), but this is actually the total session usage, not real growth since the last nudge.
Root cause
In dist/index.js, when a per-message nudge triggers, the in-memory state is updated:
Thanks for the precise report — your root-cause analysis was spot-on. This is fixed and shipped in opencode-acp@1.9.2 (now latest on npm).
What was happening
lastPerMessageNudgeTokens was updated in memory when a growth nudge fired, but saveSessionState() only ran when anchorsChanged === true. A growth nudge doesn't always change anchors (turn/iteration anchor sets saturate once seeded, or the last message is an assistant turn with no user turn to anchor), so the new baseline was never flushed to disk. On restart, the stale baseline was reloaded → growth = currentTokens − staleBaseline exceeded the threshold → the nudge refired every turn. Exactly your reproduction.
- if (anchorsChanged) {+ if (anchorsChanged || decision.shouldNudge) {
saveSessionState(state, logger).catch(() => {})
}
i.e. whenever a nudge actually fires, the new baseline is persisted — same fix you proposed. A regression test was added in tests/inject.test.ts (seeds a stale baseline to disk, fires a growth nudge with anchorsChanged=false, reloads, asserts the persisted baseline advanced).
Please upgrade
opencode-acp@1.9.2
After upgrading, the every-turn nudge loop stops: the first nudge after restart will flush the correct baseline, and subsequent nudges only fire on real new growth beyond nudgeGrowthTokens.
If the issue persists after upgrading, please reopen with the new debug logs. Thanks again for the detailed report — it made this a straightforward fix.
Activity
fix: persist nudge baseline when a growth nudge fires without anchor …
fix: persist nudge baseline when a growth nudge fires without anchor …
chore: bump version to 1.9.2 + changelog (#60 fix) (#62)
ranxianglei commentedon Jul 6, 2026
Thanks for the precise report — your root-cause analysis was spot-on. This is fixed and shipped in
opencode-acp@1.9.2(nowlateston npm).What was happening
lastPerMessageNudgeTokenswas updated in memory when a growth nudge fired, butsaveSessionState()only ran whenanchorsChanged === true. A growth nudge doesn't always change anchors (turn/iteration anchor sets saturate once seeded, or the last message is an assistant turn with no user turn to anchor), so the new baseline was never flushed to disk. On restart, the stale baseline was reloaded →growth = currentTokens − staleBaselineexceeded the threshold → the nudge refired every turn. Exactly your reproduction.The fix (PR #61, shipped in 1.9.2)
i.e. whenever a nudge actually fires, the new baseline is persisted — same fix you proposed. A regression test was added in
tests/inject.test.ts(seeds a stale baseline to disk, fires a growth nudge withanchorsChanged=false, reloads, asserts the persisted baseline advanced).Please upgrade
After upgrading, the every-turn nudge loop stops: the first nudge after restart will flush the correct baseline, and subsequent nudges only fire on real new growth beyond
nudgeGrowthTokens.If the issue persists after upgrading, please reopen with the new debug logs. Thanks again for the detailed report — it made this a straightforward fix.
修复已发布到
opencode-acp@1.9.2(npm latest),请升级验证。你的根因分析完全正确,正是saveSessionState的保存守卫漏了shouldNudge这一路。升级后重启,第一轮 nudge 即会落盘正确基线,不再每轮重复触发。