feat(inspector): coverage inside the request, fix Context hide bugs - #383
Merged
Merged
Conversation
Prompt Inspector — Requests tab: - Drop the Coverage sub-tab and its strip. Coverage of a past request is now a collapsed block at the top of the opened request (RequestCoverageBlock), carrying the turn's memory selection and its stored lorebook manifest, so reading it no longer means a second list and a second navigation. - Keep the one coverage no captured request owns — the next request's live dry-run — as a row under the preview row in the timeline. The context card's `coverage` deep link opens straight on it. - RequestTimelineView absorbs the sub-tab shell's top inset and is what the inspector mounts directly; requests_tab.dart, coverage_sub_tab.dart and past_turn_coverage_view.dart are gone, along with the per-turn coverage rows. Context screen (tokenizer) — hide: - Fix the crash: `hideCount` clamped to an empty range (`clamp(1, 0)`) in a chat with one visible message, which threw ArgumentError and took the whole tab down. The hide tile now renders in its disabled state instead. - Stop over-promising freed tokens: messages the history budget already cut are not in the prompt, so hiding them frees nothing. The estimate now spreads `historyTokens` over the in-prompt messages and counts only the ones past the cutoff; the near-limit banner is suppressed when there is nothing to hide. - Invalidate the token-breakdown caches when hidden-ness changes (toggle, hide top N, unhide all), the way the edit path already does. Without it the Context screen served the last generation's breakdown — its hash cache misses but the Riverpod copy was returned unchecked — and counted hidden messages. - Read the hide percent and history-fill threshold from settings on every build, with the sliders as local overrides. Reading them once in initState froze the defaults when the sheet opened before settings loaded, and the next save wrote those defaults back over the stored values. - Count visible messages with HistoryAssembler's predicate (skip isTyping), and guard `_calculate` with a mounted check — its callers await a write first. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Szte1QvDC7vC2ZJyHaCtPC
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.
Prompt Inspector — coverage moves into the request
requests_tab.dart,coverage_sub_tab.dart,past_turn_coverage_view.dartand the per-turn rows incoverage_rows.dartare gone). Reading a turn's coverage no longer means a second list and a second navigation.RequestCoverageBlock, a collapsed block at the top of the opened request, carrying the memory selection stored on the turn's message and the lorebook entries from its manifest (turnCoverageProvider). Nothing is recomputed — a re-scan would answer what would fire now, which is the next request's question.requests_coverage_none, instead of inventing coverage for it.coveragedeep link opens straight on it (RequestTimelineView.initialCoverage).RequestTimelineViewabsorbs the sub-tab shell's top inset and is whatPromptInspectorSheetmounts directly.requests_coverage_title/requests_coverage_nonein both locales;requests_sub_*andcoverage_past_turns/coverage_no_past_turnsremoved.Context screen — hide
hideCountwas clamped to an empty range (clamp(1, 0)) whenever a chat had one visible message or none, which throwsArgumentErrorinsidebuildand took the whole Context tab down. The hide tile now renders in the disabled state the code already had but could never reach.historyTokensover every visible message and multiplied byhideCount, ignoringTokenBreakdown.cutoffIndex— messages the history budget already dropped are not in the prompt, so hiding them frees nothing. It now divides by the in-prompt messages and counts only the ones past the cutoff. The near-limit banner is suppressed when there is nothing to hide (it would otherwise read "hide 0 messages").toggleMessageHidden,hideTopMessages,unhideAllMessagesinChatMessageOpsController), the way the edit path already does. Without it the Context screen served the last generation's breakdown — its own hash cache misses, but the Riverpod copy incachedTokenBreakdownProviderwas returned unchecked — and kept counting messages the user had just hidden.initStatefroze the defaults when the sheet opened beforeappSettingsProviderhad loaded, and the next save wrote those defaults back over the stored values.HistoryAssembler's predicate (skipisTyping), so the count matches what the prompt carries, and guard_calculatewith amountedcheck — its callers await a write first, so the sheet can be gone by then.Docs
docs/ARCHITECTURE.md: the lorebook-coverage and Requests-tab sections now describe the block inside the request and the two next-request rows.Verification
flutter analyzeandflutter testwere not run: the agent environment has no Flutter SDK, andflutter runis unavailable to it. CI is the gate for both..tr()key used underlib/resolves inen.json; EN and RU key sets are identical (therequests_/coverage_prefixes are also covered bytest/agent_ops_localization_contract_test.dart); the deleted keys had no other call sites.🤖 Generated with Claude Code
https://claude.ai/code/session_01Szte1QvDC7vC2ZJyHaCtPC
Generated by Claude Code