refactor(vscode): harden context-usage display with trusted token limits#2875
Conversation
The webview context-usage bar did not clear when the user started a new session because the old code always fell back to DEFAULT_TOKEN_LIMIT, producing a stale percentage even after usageStats and modelInfo were both cleared. Key changes: - Extract `knownTokenLimit()` in core/tokenLimits.ts that returns `undefined` for unrecognized models instead of a default, keeping `tokenLimit()` behavior unchanged. - In acpModelInfo.ts, derive `_meta.contextLimit` from the known-model table when the ACP payload omits a numeric limit. - Extract `computeContextUsage()` into its own module, which returns `null` when no trusted numeric limit is available — the UI then correctly hides the context bar. - Remove the `@qwen-code/qwen-code-core` runtime import from App.tsx so the webview bundle stays free of Node-only dependencies. Closes #2847
📋 Review SummaryThis PR adds defensive hardening for the context-usage display in the VS Code extension, ensuring correct behavior when the ACP server omits 🔍 General Feedback
🎯 Specific Feedback🔵 Low
✅ Highlights
|
tanzhenxin
left a comment
There was a problem hiding this comment.
Review: refactor(vscode): harden context-usage display with null guards and session reset
Overview
Three interrelated improvements: extracting computeContextUsage() into a standalone tested utility (removing the last core runtime import from the webview bundle), adding knownTokenLimit() to core, and passing { forceNew: true } for explicit new-session actions.
Issues
1. forceNew session without resetting currentConversationId causes data mixing (High)
SessionMessageHandler.ts creates a fresh ACP session with forceNew: true, but neither that path nor WebViewProvider.ts resets currentConversationId. When the user sends the first prompt, SessionMessageHandler skips createConversation() because the old id is still present, and appends the new chat to the previous conversation record. This is a real data-mixing bug introduced by this change.
2. Context-usage reset incomplete — stale token usage after "New Session" (Medium)
The new-session flows only emit conversationCleared, but useWebViewMessages.ts does not clear usageStats. Since App.tsx derives the footer from retained usageStats, an empty fresh chat can still display the old session's context consumption until a new request produces updated metadata.
3. Silent behavioral change in token field priority (Medium)
Old code: usageStats?.usage?.promptTokens ?? 0
New code: usageStats?.usage?.inputTokens ?? usageStats?.usage?.promptTokens ?? 0
The new priority preferring inputTokens over promptTokens is arguably more correct (SDK primary vs legacy compat), but it's a silent behavioral change not called out in the PR description. If both fields are present with different values, displayed usage will change. Worth documenting as intentional.
Positives
- Clean extraction of
computeContextUsageas a pure, testable function. - Bundle test (
imageSupport.bundle.test.ts) is a clever integration safeguard. - Well-documented priority chain in
acpModelInfo.ts. knownTokenLimit/findTokenLimitextraction is well-structured.- Solid test coverage for new paths.
Verdict
REQUEST_CHANGES — The currentConversationId not being reset on forceNew (#1) is a data-mixing bug that needs fixing before merge. The stale usage display (#2) should also be addressed.
|
Addressed the review feedback in follow-up commits:
Verification run locally:
|
wenshao
left a comment
There was a problem hiding this comment.
No issues found. LGTM! ✅
Reviewed by glm-5.1 via Qwen Code /review
|
@codex review it |
…de-new-session-reset-context
c2f3c96
into
fix/2847-vscode-new-session-minimal
Summary
Follow-up to #2874. Adds defensive hardening so the context-usage bar behaves correctly even when the ACP server omits
tokenLimitfrom its responses.knownTokenLimit()incore/tokenLimits.ts: a new export that returnsundefinedfor unrecognized models (unliketokenLimit()which always falls back to a default). This lets callers distinguish "known limit" from "guessed default".acpModelInfo.ts: derives_meta.contextLimitfrom the known-model table when the ACP payload omits a numeric limit, with a clear priority chain (legacy numeric > meta numeric > derived > explicit null > undefined).computeContextUsage(): extracted from the 45-line inline block inApp.tsxinto a standalone tested module. Returnsnullwhen no trusted numeric limit is available — the UI hides the context bar instead of showing a misleading default.@qwen-code/qwen-code-coreruntime import fromApp.tsx, keeping the webview bundle free of Node-only dependencies.Files changed
core/tokenLimits.tsfindTokenLimit()+knownTokenLimit()export, refactortokenLimit()to reuseacpModelInfo.tscontextLimitfrom known model table when ACP omits itcontextUsage.ts(new)App.tsx, no default fallbackApp.tsxcomputeContextUsage()callTest plan
tokenLimits.test.ts—knownTokenLimitreturns values for known models,undefinedfor unknownacpModelInfo.test.ts— derives contextLimit when payload omits it, preserves explicit nullcontextUsage.test.ts— null without trusted limit, prefers usageStats over meta, inputTokens/promptTokens compatimageSupport.bundle.test.ts— App webview bundle has no core runtime importsDepends on #2874