fix(context-window-monitor): clamp displayed context status percentages so the directive stays trustworthy (fixes #3655)#3701
Open
MoerAI wants to merge 1 commit intocode-yeongyu:devfrom
Conversation
…es so the directive stays trustworthy (fixes code-yeongyu#3655) Root cause: the context-window-monitor hook computes actualUsagePercentage = (input + cache.read) / actualLimit and renders both 'X% used' and '(1 - X) * 100% remaining' inside a [SYSTEM DIRECTIVE: OH-MY-OPENCODE - CONTEXT WINDOW MONITOR] block that is appended to bash tool output. When resolveActualContextLimit() underestimates the model's real context window (for example a 1M-context Anthropic model that falls back to the 200K default per code-yeongyu#3450), totalInputTokens > actualLimit and the rendered numbers go nonsensical (issue code-yeongyu#3655 reproduces 144.7% used / -44.7% remaining at 289,370 / 200,000 tokens). Safety-tuned models recognize the >100% / negative-remaining pattern as a tell-tale prompt injection and refuse to follow the directive. Fix: clamp actualUsagePercentage to [0, 1] before formatting. The 70% threshold check still uses the raw value so the block continues to fire above threshold, and resolveActualContextLimit() is left untouched (the deeper resolver concern is tracked separately as code-yeongyu#3450). When totalInputTokens exceeds actualLimit the displayed numbers now read '100.0% used / 0.0% remaining' instead of the impossible >100% / negative pair, and safety-tuned models stop flagging the block as an injection attempt. Verification: added a regression test (input 289,370, limit 200,000) that asserts usedPct in [0,100] and remainingPct in [0,100]. Test fails before the fix (Received: 144.7) and passes after. Full context-window-monitor.test.ts and context-window-monitor.model-context-limits.test.ts: 15 pass / 0 fail. Typecheck clean.
Contributor
Author
|
I have read the CLA Document and I hereby sign the CLA |
There was a problem hiding this comment.
No issues found across 2 files
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
Auto-approved: The PR implements simple clamping for display percentages to avoid nonsensical values. It includes a regression test and does not change core logic, posing no risk of regression.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Clamp the displayed
% usedand% remainingnumbers in the[SYSTEM DIRECTIVE: OH-MY-OPENCODE - CONTEXT WINDOW MONITOR]block to[0, 100]so the directive remains trustworthy when the resolvedactualLimitunderestimates the model's real context window. Without clamping, the block currently advertises numbers like144.7% used (289,370/200,000 tokens), -44.7% remaining, which safety-tuned models flag as a prompt injection and refuse to follow.Root Cause
src/hooks/context-window-monitor.tslines 62-74 compute and render the directive:When
resolveActualContextLimit()underestimates the real context window (the deeper concern tracked as #3450 - e.g. a 1M-context Anthropic model that falls back toDEFAULT_ANTHROPIC_ACTUAL_LIMIT = 200_000),totalInputTokens / actualLimitexceeds 1.0 and the formatting math then produces nonsensical numbers. The injected block also wraps itself in[SYSTEM DIRECTIVE: ...]framing and issues behavioral imperatives, so safety-tuned models correctly identify the >100% / negative-remaining pattern as adversarial:Changes
src/hooks/context-window-monitor.tsclampedPercentage = Math.min(Math.max(actualUsagePercentage, 0), 1)and use it for bothusedPctandremainingPct. The threshold check on line 64 still uses the raw value so the block continues to fire correctly above 70%.resolveActualContextLimit()is left untouched (deeper concern, tracked as #3450).src/hooks/context-window-monitor.test.tsinput: 289,370against a200,000resolved limit (matching the issue's reproduction numbers) and asserts bothusedPctandremainingPctstay within[0, 100].Total diff: 2 files, +65 lines.
Reproduction (before fix)
With the regression test added but the source change reverted:
The actually rendered block looks like:
Verification (after fix)
After the fix, the block now reads:
The numbers are still informative (token counts are unchanged so the user still sees they are over the resolved limit) but they no longer match the prompt-injection pattern that safety-tuned models reject.
Test
src/hooks/context-window-monitor.test.ts(new caseshould clamp displayed percentages when input exceeds actualLimit (regression #3655)).context-window-monitor.test.ts(9 tests) +context-window-monitor.model-context-limits.test.ts(6 tests) - 15 pass / 0 fail.resolveActualContextLimit()itself. Fixing the underlying root cause - so the resolver returns the model's real context window for 1M-context Anthropic models - is tracked as [Bug]: resolveActualContextLimit falls back to 200k when anthropic provider has no explicit model limits in config #3450 and will land separately. This PR is purely a defensive UX clamp on the displayed string.Fixes #3655
Need help on this PR? Tag
@codesmithwith what you need.Summary by cubic
Clamp context status percentages to 0–100% so the monitor stays accurate and doesn’t trigger safety checks. Fixes #3655 by preventing outputs like “144.7% used, -44.7% remaining” when the resolved limit is lower than the model’s real window.
used%/remaining%from a clamped usage value; threshold logic still uses the raw ratio so the block triggers as before.Written for commit 07064a9. Summary will update on new commits. Review in cubic