feat: support Claude Code native context_window API#71
Merged
Haleclipse merged 2 commits intoHaleclipse:masterfrom Jan 23, 2026
Merged
feat: support Claude Code native context_window API#71Haleclipse merged 2 commits intoHaleclipse:masterfrom
Haleclipse merged 2 commits intoHaleclipse:masterfrom
Conversation
- Add ContextWindow struct to support native Claude Code v2.0.37+ context window data - Prioritize native context_window field for accurate token usage - Maintain backward compatibility with transcript parsing fallback - Add session history search as additional fallback mechanism - Improve percentage calculation and token display formatting Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
Reviewer's GuideImplements native Claude Code context_window support by introducing a ContextWindow struct, preferring native usage data when available, and adding layered fallbacks plus improved percentage and token formatting in the context window segment. Sequence diagram for context usage resolution with native context_window and fallbackssequenceDiagram
participant Caller
participant ContextWindowSegment
participant InputData
participant ContextWindow
participant ModelConfig
participant TranscriptParser
participant SessionHistory
Caller->>ContextWindowSegment: collect(input)
activate ContextWindowSegment
ContextWindowSegment->>InputData: read context_window
InputData-->>ContextWindowSegment: ContextWindow
ContextWindowSegment->>ContextWindow: context_window_size
ContextWindow-->>ContextWindowSegment: Option context_window_size
alt context_window_size is Some
ContextWindowSegment-->>ContextWindowSegment: context_limit = context_window_size
else context_window_size is None
ContextWindowSegment->>InputData: read model.id
ContextWindowSegment->>ModelConfig: get_context_limit(model_id)
ModelConfig-->>ContextWindowSegment: context_limit
end
ContextWindowSegment->>ContextWindow: get_display_percentage()
ContextWindow-->>ContextWindowSegment: Option percentage
alt percentage is Some
ContextWindowSegment->>ContextWindow: total_tokens()
ContextWindow-->>ContextWindowSegment: Option total_tokens
ContextWindowSegment-->>Caller: SegmentData with native percentage and tokens
else percentage is None
ContextWindowSegment-->>ContextWindowSegment: get_context_usage_with_fallback(input)
activate TranscriptParser
ContextWindowSegment->>ContextWindow: is_available()
ContextWindow-->>ContextWindowSegment: bool
alt ContextWindow is available
ContextWindowSegment->>ContextWindow: total_tokens()
ContextWindow-->>ContextWindowSegment: Option total_tokens
ContextWindowSegment-->>ContextWindowSegment: compute percentage from tokens and context_limit
else ContextWindow not available
ContextWindowSegment->>TranscriptParser: parse_transcript_usage(transcript_path)
TranscriptParser-->>ContextWindowSegment: Option usage
alt usage is None
deactivate TranscriptParser
activate SessionHistory
ContextWindowSegment->>SessionHistory: try_get_from_session_history(transcript_path)
SessionHistory-->>ContextWindowSegment: Option usage
deactivate SessionHistory
end
end
alt usage is Some
ContextWindowSegment-->>ContextWindowSegment: format percentage and tokens
ContextWindowSegment-->>Caller: SegmentData with fallback percentage and tokens
else usage is None
ContextWindowSegment-->>Caller: SegmentData with "-" for percentage and tokens
end
deactivate ContextWindowSegment
end
Class diagram for new ContextWindow and InputData structuresclassDiagram
class InputData {
+Model model
+String transcript_path
+Option~Cost~ cost
+Option~OutputStyle~ output_style
+ContextWindow context_window
}
class ContextWindow {
+Option~u32~ total_input_tokens
+Option~u32~ total_output_tokens
+Option~u32~ context_window_size
+Option~f64~ used_percentage
+Option~f64~ remaining_percentage
+Option~CurrentContextUsage~ current_usage
+total_tokens() Option~u32~
+is_available() bool
+get_display_percentage() Option~f64~
}
class CurrentContextUsage {
+Option~u32~ input_tokens
+Option~u32~ output_tokens
+Option~u32~ cache_creation_input_tokens
+Option~u32~ cache_read_input_tokens
}
InputData --> ContextWindow : has
ContextWindow --> CurrentContextUsage : has
Class diagram for updated ContextWindowSegment behaviorclassDiagram
class ContextWindowSegment {
+new() ContextWindowSegment
-get_context_limit_for_model(model_id: &str) u32
-get_context_usage_with_fallback(input: &InputData) Option~u32~
-try_get_from_session_history(transcript_path: &str) Option~u32~
+collect(input: &InputData) Option~SegmentData~
}
class InputData {
+Model model
+String transcript_path
+ContextWindow context_window
}
class ContextWindow {
+Option~u32~ context_window_size
+total_tokens() Option~u32~
+is_available() bool
+get_display_percentage() Option~f64~
}
class Model {
+String id
}
class SegmentData
ContextWindowSegment ..> InputData : reads
ContextWindowSegment ..> ContextWindow : reads
ContextWindowSegment ..> Model : reads
ContextWindowSegment ..> SegmentData : returns
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 3 issues, and left some high level feedback:
- The new
try_get_from_session_historylogic overlaps heavily withtry_find_usage_from_project_history; consider refactoring shared behaviors (directory scan, sort, recent-file iteration) into a common helper to avoid duplication and keep the fallback behavior consistent. - In the metadata population,
context_window.total_tokens().unwrap_or(0)will report0tokens when no token data is available, while the display shows-; consider aligning this by using"-"instead of0to avoid misleading zero-usage metadata. - The
ContextWindow::get_display_percentagefallback uses a hard-coded default limit of200000whencontext_window_sizeis missing; it may be safer to derive this from the model configuration (or avoid computing a percentage) to prevent incorrect usage ratios for models with different limits.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The new `try_get_from_session_history` logic overlaps heavily with `try_find_usage_from_project_history`; consider refactoring shared behaviors (directory scan, sort, recent-file iteration) into a common helper to avoid duplication and keep the fallback behavior consistent.
- In the metadata population, `context_window.total_tokens().unwrap_or(0)` will report `0` tokens when no token data is available, while the display shows `-`; consider aligning this by using `"-"` instead of `0` to avoid misleading zero-usage metadata.
- The `ContextWindow::get_display_percentage` fallback uses a hard-coded default limit of `200000` when `context_window_size` is missing; it may be safer to derive this from the model configuration (or avoid computing a percentage) to prevent incorrect usage ratios for models with different limits.
## Individual Comments
### Comment 1
<location> `src/config/types.rs:170-171` </location>
<code_context>
+ if let Some(percentage) = self.used_percentage {
+ Some(percentage)
+ } else if self.is_available() {
+ self.total_tokens().map(|tokens| {
+ let limit = self.context_window_size.unwrap_or(200000);
+ (tokens as f64 / limit as f64) * 100.0
+ })
</code_context>
<issue_to_address>
**issue (bug_risk):** Avoid hardcoded 200_000 and align percentage calculation with the actual context limit used elsewhere.
Here this falls back to a hardcoded `200_000` when `context_window_size` is `None`, but `ContextWindowSegment::collect` instead derives the limit from the model config. That can yield inconsistent percentages versus the metadata and `limit` field. Prefer wiring the effective limit into `get_display_percentage`, or removing the `200_000` default and reusing the segment’s limit logic so there is a single source of truth.
</issue_to_address>
### Comment 2
<location> `src/core/segments/context_window.rs:138-142` </location>
<code_context>
- metadata.insert("percentage".to_string(), "-".to_string());
- }
+
+ if let Some(percentage_val) = context_window.get_display_percentage() {
+ metadata.insert("percentage".to_string(), percentage_val.to_string());
+ metadata.insert(
+ "tokens".to_string(),
+ context_window.total_tokens().unwrap_or(0).to_string(),
+ );
+ } else if let Some(context_used_token) = Self::get_context_usage_with_fallback(input) {
</code_context>
<issue_to_address>
**issue (bug_risk):** Using `0` as a fallback token count may be misleading when the token total is unknown.
When `get_display_percentage()` is `Some` but `total_tokens()` is `None`, this stores `tokens = "0"`, which suggests zero tokens instead of “unknown”. Consider omitting `tokens`, using a placeholder like `"-"`, or matching the display fallback so metadata consumers don’t misread missing totals as zero usage.
</issue_to_address>
### Comment 3
<location> `src/config/types.rs:149-157` </location>
<code_context>
+}
+
+impl ContextWindow {
+ pub fn total_tokens(&self) -> Option<u32> {
+ match (self.total_input_tokens, self.total_output_tokens) {
+ (Some(input), Some(output)) => Some(input + output),
+ (Some(input), None) => Some(input),
+ (None, Some(output)) => Some(output),
+ (None, None) => None,
+ }
+ }
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Consider using a saturating or wider integer type when summing token counts.
`input + output` in `u32` can overflow (panic in debug, wrap in release). Even if current counts are unlikely to reach `u32::MAX`, using `u64` for the sum or `input.saturating_add(output)` would avoid hidden overflow issues if limits increase later.
```suggestion
impl ContextWindow {
pub fn total_tokens(&self) -> Option<u32> {
match (self.total_input_tokens, self.total_output_tokens) {
(Some(input), Some(output)) => Some(input.saturating_add(output)),
(Some(input), None) => Some(input),
(None, Some(output)) => Some(output),
(None, None) => None,
}
}
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
- Fix u32 overflow potential by using saturating_add in ContextWindow::total_tokens - Remove hardcoded 200000 limit, pass actual context_limit to get_display_percentage - Fix metadata consistency: use "-" instead of "0" when token count is unknown - Refactor duplicated logic: extract search_recent_session_files helper to unify session history and project history searching - Improve code maintainability with single source of truth for context limit calculation Changes: - types.rs: Add context_limit parameter to get_display_percentage, use saturating_add - context_window.rs: Refactor session search logic, fix metadata tokens display, align percentage calculation Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
Owner
|
有人提过 也早考虑过跟进 所以也许应该需要再附加一段逻辑 当模型id匹配成功被覆盖时 fallback 到 旧时的计算 |
Haleclipse
added a commit
that referenced
this pull request
Jan 25, 2026
Revert changes from bd88e9d to restore original context window logic. The native API approach needs further refinement.
Haleclipse
pushed a commit
that referenced
this pull request
Jan 25, 2026
* feat: support Claude Code native context_window API - Add ContextWindow struct to support native Claude Code v2.0.37+ context window data - Prioritize native context_window field for accurate token usage - Maintain backward compatibility with transcript parsing fallback - Add session history search as additional fallback mechanism - Improve percentage calculation and token display formatting * fix: address code review feedback - Fix u32 overflow potential by using saturating_add in ContextWindow::total_tokens - Remove hardcoded 200000 limit, pass actual context_limit to get_display_percentage - Fix metadata consistency: use "-" instead of "0" when token count is unknown - Refactor duplicated logic: extract search_recent_session_files helper to unify session history and project history searching - Improve code maintainability with single source of truth for context limit calculation Changes: - types.rs: Add context_limit parameter to get_display_percentage, use saturating_add - context_window.rs: Refactor session search logic, fix metadata tokens display, align percentage calculation ---------
Haleclipse
added a commit
that referenced
this pull request
Jan 25, 2026
Revert changes from bd88e9d to restore original context window logic. The native API approach needs further refinement.
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 by Sourcery
Support native context window metadata from Claude Code while preserving existing transcript-based fallbacks for token usage display.
New Features:
Enhancements: