Skip to content

Add contextWindowSize Configuration Support#1539

Merged
tanzhenxin merged 19 commits intoQwenLM:mainfrom
xuewenjie123:feature/add-context-window-size-config
Jan 29, 2026
Merged

Add contextWindowSize Configuration Support#1539
tanzhenxin merged 19 commits intoQwenLM:mainfrom
xuewenjie123:feature/add-context-window-size-config

Conversation

@xuewenjie123
Copy link
Copy Markdown
Collaborator

@xuewenjie123 xuewenjie123 commented Jan 19, 2026

Add contextWindowSize Configuration Support

Overview

This PR adds support for configuring context window size (contextWindowSize) through the ContentGeneratorConfig interface. Users can now override automatic detection values to provide more granular control over the model's input token limits for different use cases.

Motivation

  • User Control: Allow users to manually set context window size when automatic detection doesn't meet their needs
  • Flexibility: Support different context window sizes for different models or scenarios
  • Provider Compatibility: Handle cases where a provider's effective context limit differs from Qwen Code's default detection
  • Model-Specific Configuration: Context window size is model-specific and naturally belongs in the generation config
  • Backward Compatible: Automatic detection remains the default behavior, not affecting existing users

Key Changes

1. Core Interface Enhancement (packages/core/src/core/contentGenerator.ts)

New Field:

  • contextWindowSize?: number - Context window size configuration (user-configurable)

Logic Improvements:

  • Added contextWindowSize field to ContentGeneratorConfig interface
  • resolveContentGeneratorConfigWithSources focuses on validation and parsing
  • Added complete source tracking for configuration sources

2. Model Configuration Enhancement (packages/core/src/models/modelsConfig.ts)

Key Changes:

  • Added contextWindowSize fallback calculation in applyResolvedModelDefaults() method
  • Implements three-tier priority: user config > model auto-detection > default value (131,072 / 128K)
  • Uses tokenLimit(model, 'input') for automatic detection when not explicitly configured
  • Ensures contextWindowSize is always calculated before validation
  • Maintains separation of concerns: default value application vs. validation

3. Token Limits Enhancement (packages/core/src/core/tokenLimits.ts)

Key Changes:

  • Exported DEFAULT_TOKEN_LIMIT constant for use in other modules
  • Provides centralized token limit calculation via tokenLimit() function
  • Supports both input and output token limit queries

4. Configuration Resolution (packages/core/src/models/constants.ts)

  • Added 'contextWindowSize' to MODEL_GENERATION_CONFIG_FIELDS constant
  • Ensures the config field is properly parsed and applied from user settings

5. Chat Compression Service (packages/core/src/services/chatCompressionService.ts)

  • Updated to use config.getContentGeneratorConfig() to get configuration
  • Properly passes config to token limit calculation functions

6. CLI Settings Schema (packages/cli/src/config/settingsSchema.ts)

New Configuration Option:

  • model.generationConfig.contextWindowSize - Context window size override

Cleanup:

  • Removed legacy childKey field (from type definition and all usages)
  • Simplified configuration structure, improved code maintainability

7. UI Component Refactoring

ContextUsageDisplay (packages/cli/src/ui/components/ContextUsageDisplay.tsx):

  • Refactored interface to directly receive contextWindowSize parameter instead of entire Config object
  • Removed unused model parameter
  • Removed dependency on Config type, reducing coupling

Footer (packages/cli/src/ui/components/Footer.tsx):

  • Used useMemo to optimize contextWindowSize calculation, avoiding unnecessary recomputation
  • Updated component calls to pass correct parameters

8. Configuration Hot-Update (packages/core/src/config/config.ts)

  • Updated hot-update logic to sync contextWindowSize when switching models
  • Ensures configuration stays consistent with the selected model

9. Documentation Enhancement (docs/users/configuration/settings.md)

New Documentation:

  • Added contextWindowSize to model.generationConfig description
  • Added detailed explanation for contextWindowSize field's purpose and behavior
  • Updated example JSON configuration to demonstrate usage
  • Maintained consistent documentation style with existing fields

10. Test Updates

Updated Test Files:

  • packages/core/src/config/config.test.ts - Added comprehensive tests for contextWindowSize configuration
  • packages/core/src/services/chatCompressionService.test.ts - Updated to use new config API
  • packages/cli/src/ui/components/Footer.test.tsx - Updated component tests
  • packages/core/src/core/client.test.ts - Updated client tests
  • packages/core/src/core/openaiContentGenerator/provider/dashscope.test.ts - Updated provider tests

All tests have been updated to adapt to the new API and configuration structure.

Configuration Behavior

contextWindowSize Priority System

  1. User Explicit Configuration (positive number): Overrides all automatic detection
  2. Model Auto-Detection (not configured or undefined): Based on model name matching via tokenLimit(model, 'input')
  3. Default Value: 131,072 (128K) when model information is unavailable

Use Cases:

  • Override when provider's effective context limit differs from Qwen Code's default
  • Adjust for specific deployment scenarios or custom model configurations
  • Fine-tune for optimal performance in different environments

Configuration Example

{
  "model": {
    "generationConfig": {
      "contextWindowSize": 128000,
      "customHeaders": {
        "X-Request-ID": "req-123"
      },
      "samplingParams": {
        "temperature": 0.2,
        "top_p": 0.8,
        "max_tokens": 1024
      }
    }
  }
}

Testing

✅ All existing tests pass (3452 tests)

  • Core tests: 3450 passed | 2 skipped
  • Test files: 162 passed

✅ Pre-commit hooks (prettier, eslint) pass
✅ Configuration correctly applied and resolved
✅ 5 test files updated to adapt to new API
✅ No new lint errors

Code Quality

Separation of Concerns:

  • resolveContentGeneratorConfigWithSources focuses on validation and parsing
  • ModelsConfig.applyResolvedModelDefaults handles default value application
  • Clear responsibility boundaries improve maintainability

Code Statistics:

  • 2 files modified in refactoring commit
  • 14 lines added, 26 lines removed
  • Net reduction of 12 lines of code

Impact Statistics

  • Files Changed: 17 files
  • Lines Added: 376
  • Lines Removed: 73
  • Test Files Modified: 5

Migration Notes

No Breaking Changes

  • ✅ Existing code continues to work normally
  • ✅ Backward compatible: Automatic detection remains the default behavior
  • contextWindowSize is optional: Users can explicitly set values when needed
  • maxOutputTokens removal is transparent: Always calculated automatically

API Changes

Removed Fields:

  • childKey - Legacy field, completely removed from settings schema

New Fields:

  • ContentGeneratorConfig.contextWindowSize - Context window size (user-configurable)

Component Interface Changes:

  • ContextUsageDisplay now receives contextWindowSize instead of config object
  • Reduced component coupling and improved reusability

Related Issues

#1400

Checklist

  • Code follows project coding standards
  • Added/updated relevant documentation
  • All tests pass (3452 tests)
  • No new lint errors
  • Backward compatible
  • Updated relevant test files
  • Added user configuration for contextWindowSize with automatic fallback
  • Improved configuration flexibility and provider compatibility
  • Refactored to improve separation of concerns (validation vs. default value application)
  • Addressed PR review feedback about appropriate placement of fallback calculation logic

- Add contextWindowSize field to ContentGeneratorConfig interface
- Update tokenLimit function to accept contentGeneratorConfig parameter
- Implement priority logic: user config > auto-detection
- Update chatCompressionService to use new API via getContentGeneratorConfig()
- Add contextWindowSize to MODEL_GENERATION_CONFIG_FIELDS for config resolution
- Add contextWindowSize to CLI settings schema (model.generationConfig)
- Update UI components (Footer, ContextUsageDisplay) to use new config API
- Fix test mocks to include getContentGeneratorConfig method

This refactor avoids modifying 71+ test files by moving the config
to the generator level instead of the Config class level.

Modified files:
- packages/core/src/core/contentGenerator.ts
- packages/core/src/core/tokenLimits.ts
- packages/core/src/services/chatCompressionService.ts
- packages/core/src/services/chatCompressionService.test.ts
- packages/core/src/models/constants.ts
- packages/cli/src/config/settingsSchema.ts
- packages/cli/src/ui/components/ContextUsageDisplay.tsx
- packages/cli/src/ui/components/Footer.tsx
@github-actions
Copy link
Copy Markdown
Contributor

📋 Review Summary

This PR introduces a new configuration option for context window size in the ContentGeneratorConfig, allowing users to override automatic detection. The changes are well-structured and maintain backward compatibility while providing more control over token limits for different use cases.

🔍 General Feedback

  • The implementation follows a clear priority system: user config > auto-detection > default value
  • Good backward compatibility - automatic detection remains the default behavior
  • The changes are consistently applied across all affected components
  • Clear documentation in the PR description about the configuration behavior and usage examples

🎯 Specific Feedback

🟡 High

  • File: packages/core/src/core/tokenLimits.ts:33 - The condition configuredLimit > 0 means that only positive values override the automatic detection. While this is documented, consider if zero should also be a valid override value for certain edge cases where users want to enforce a strict limit.

🟢 Medium

  • File: packages/cli/src/config/settingsSchema.ts:693 - The description mentions "Set to -1 to use automatic detection based on the model", which is clear. However, consider adding a note about the range of valid positive values or typical values for common models to guide users.
  • File: packages/core/src/core/tokenLimits.ts:29 - The JSDoc could be enhanced to mention that the third parameter is optional and what happens when it's not provided (falls back to automatic detection).

🔵 Low

  • File: packages/core/src/services/chatCompressionService.test.ts:121 - The mock returns an empty object {}. Consider returning a more complete mock with default values to make the test more robust against future changes to the ContentGeneratorConfig interface.
  • File: packages/cli/src/ui/components/ContextUsageDisplay.tsx:21 - The variable name contextLimit is clear, but consider renaming to contextWindowLimit for more specificity since it's specifically about the context window size.

✅ Highlights

  • Excellent backward compatibility approach - existing code continues to work without changes
  • Well-thought-out priority system for configuration values
  • Comprehensive updates across all affected components
  • Clear documentation and examples in the PR description
  • Proper test updates to accommodate the new API

@xuewenjie123 xuewenjie123 changed the title refactor: move contextWindowSize to ContentGeneratorConfig Add contextWindowSize Configuration Support Jan 21, 2026
@007gzs
Copy link
Copy Markdown

007gzs commented Jan 22, 2026

模型tokenLimit 和模型强相关,建议和 OPENAI_API_KEY OPENAI_BASE_URL OPENAI_MODEL 一样也增加个环境变量来配置

export function tokenLimit(
model: Model,
type: TokenLimitType = 'input',
contentGeneratorConfig?: { contextWindowSize?: number },
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are still multiple call sites that compute context limits via tokenLimit(model) without the config. It is not correct.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest setup contextWindowSize in contentGeneratorConfig in the right timing (by calling old tokenLimit if the value is not set by user), and replace all occurrences of tokenLimit to contentGeneratorConfig?.contextWindowSize. Because it is a property tightly connected to model.

xwj02155382 added 4 commits January 23, 2026 14:41
Resolved conflicts in:
- packages/cli/src/ui/components/ContextUsageDisplay.tsx
- packages/cli/src/ui/components/Footer.tsx
- packages/cli/src/ui/components/Footer.test.tsx
- docs/users/configuration/settings.md

Changes:
- Merged main branch UI improvements with rightItems architecture
- Updated contextWindowSize documentation to be more concise
- Preserved all main branch features and functionality
- Initialize contextWindowSize and maxOutputTokens in contentGeneratorConfig during config resolution
- Remove third parameter from tokenLimit() function for cleaner API
- Replace all tokenLimit() calls with direct config property access for better performance
- Add maxOutputTokens field to ContentGeneratorConfig type
- Update dashscope provider to use config.maxOutputTokens
- Auto-detect token limits from model during initialization if not user-configured
- Update settingsSchema: set contextWindowSize default to undefined and showInDialog to false

Benefits:
- Token limits calculated once during initialization instead of repeatedly
- Cleaner API with fewer parameters
- Better performance by caching computed values
- User configuration takes precedence over auto-detection
- All 72 unit tests passing
- Update client.test.ts to mock config.getContentGeneratorConfig() instead of tokenLimit()
- Remove unused tokenLimit import
- Fix compression tests by adding contextWindowSize mock to ensure compression is triggered
- Update config.test.ts to match new getTruncateToolOutputThreshold() calculation logic
- Update dashscope.test.ts to adapt to maxOutputTokens configuration
- Remove obsolete buildRuntimeFetchOptions mock
- All 3438 tests now pass (100% pass rate)
description:
"Overrides the default context window size for the selected model. Use this setting when a provider's effective context limit differs from Qwen Code's default. This value defines the model's assumed maximum context capacity, not a per-request token limit.",
parentKey: 'generationConfig',
childKey: 'contextWindowSize',
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The childKey is a history mistake I suppose, pls remove all of them.

export const ContextUsageDisplay = ({
promptTokenCount,
model,
model: _model,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove model from props, and pass contextWindowSize instead of Config object

_meta: {
contextLimit: tokenLimit(model.id),
// Use the contextWindowSize from config, which is always set during initialization
contextLimit: contentGeneratorConfig?.contextWindowSize,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This place should not use contentGeneratorConfig?.contextWindowSize. The context window size of each model might differs, need a better solution.

private applyOutputTokenLimit<T extends { max_tokens?: number | null }>(
request: T,
model: string,
_model: string,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not write this code like this easily.

contextWindowSize?: number;
// Maximum output tokens override. If set to a positive number, it will override
// the automatic detection. Leave undefined to use automatic detection.
maxOutputTokens?: number;
Copy link
Copy Markdown
Collaborator

@tanzhenxin tanzhenxin Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like this maxOutputTokens. It is not in the initial PR, it is not in the review comments, anyhow it comes up without proper reason.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am ok with it if the logic is solid with pr description and docs updated.

xwj02155382 added 7 commits January 26, 2026 10:26
- Remove legacy childKey field from settingsSchema

- Add contextWindowSize and maxOutputTokens to documentation

- Refactor ContextUsageDisplay to accept contextWindowSize directly instead of Config object

- Add useMemo optimization for contextWindowSize in Footer component

- Fix logic gaps in contentGenerator for contextWindowSize and maxOutputTokens initialization

- Increase DEFAULT_OUTPUT_TOKEN_LIMIT from 4K to 8K for better usability

- Add fallback to default values when model is not available
- Fix handleModelChange to update contextWindowSize and maxOutputTokens during hot-update
- Fix dashscope.ts to use contentGeneratorConfig.maxOutputTokens instead of tokenLimit()
- Fix acpAgent.ts to use model-specific contextLimit for each model
- Add comprehensive tests for model switching scenarios
- Fix all TypeScript type errors (index signature and ConfigSource types)
- Fix all ESLint errors (remove 'any' types)
The tokenLimit function has a default parameter value of 'input' for the type parameter, so explicitly passing 'input' is redundant.
Clarify that when modelLimit is undefined, it could be either:
- No limit configured
- Config not initialized yet
In both cases, we don't modify max_tokens and let the API handle it.
- Remove maxOutputTokens field from ContentGeneratorConfig
- Remove maxOutputTokens auto-calculation logic in contentGenerator.ts
- Remove maxOutputTokens sync logic in config.ts hot-update
- Update dashscope.ts to use tokenLimit() function for dynamic calculation
- Remove maxOutputTokens from documentation (settings.md)
- Update all test cases to use correct model output limits
- All 143 tests passing (config.test.ts: 105, dashscope.test.ts: 38)

Changes:
- Users can no longer configure maxOutputTokens via settings
- Output token limits are now always dynamically calculated based on model
- contextWindowSize (input) remains user-configurable
- Prevents long text output truncation caused by default value settings
// User explicitly set contextWindowSize
setSource(sources, 'contextWindowSize', seedOrUnknown('contextWindowSize'));
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not appropriate to place these fallback values calculation here because this is method is like a validation not calculation.
ModelsConfig.applyResolvedModelDefaults is more appropriate.

…Defaults

- Move contextWindowSize auto-detection from resolveContentGeneratorConfigWithSources to ModelsConfig.applyResolvedModelDefaults

- Improves separation of concerns: validation vs. default value application

- resolveContentGeneratorConfigWithSources now focuses on validation and parsing

- applyResolvedModelDefaults handles all model-specific default configurations

- Add tokenLimit import to modelsConfig.ts

- All 105 tests passing

Addresses PR review comment about appropriate placement of fallback calculation logic.
const modelLimit = tokenLimit(model, 'output');
// Dynamically calculate output token limit using tokenLimit function
// This ensures we always use the latest model-specific limits without relying on user configuration
const modelLimit = tokenLimit(request.model, 'output');
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why ensures we always use the latest model-specific limits without relying on user configuration?
This tokenLimit does not cover all dashscope models' context window size.
Addition: if we decide to respect user config context window size instead of using tokenLimit, which is very reasonable, then we should take either actions below:

  1. add these config in packages/cli/src/ui/models/availableModels.ts to ensure our hard-coded qwen-oauth models have correct limits set.
  2. route coder-model and vision-model to use our hard-coded params here.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've refactored the code to move the contextWindowSize fallback calculation from resolveContentGeneratorConfigWithSources to ModelsConfig.applyResolvedModelDefaults. This improves the separation of concerns:

  • resolveContentGeneratorConfigWithSources now focuses purely on validation and parsing
  • applyResolvedModelDefaults handles all model-specific default value applications, including contextWindowSize

This refactoring ensures that:

  1. Default value calculation is placed in the appropriate location alongside other generation config defaults (timeout, maxRetries, samplingParams, etc.)
  2. The validation method remains focused on its core responsibility
  3. All call paths (refreshAuth and switchModel) correctly apply the fallback values before validation

Copy link
Copy Markdown
Collaborator

@tanzhenxin tanzhenxin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue 1: Context Window Size Doesn't Update on Model Switch

When ModelsConfig.setModel() is called programmatically, the contextWindowSize in contentGeneratorConfig is not being refreshed. This causes the context usage display in the footer to show stale/incorrect values from the previous model rather than the newly selected model's configuration.


Issue 2: ACP Agent Ignores Provider-Configured contextWindowSize

The ACP agent calculates contextLimit using tokenLimit() directly, which only performs auto-detection based on model name patterns. This means any contextWindowSize explicitly configured in modelProviders[].generationConfig is not being respected.

tanzhenxin and others added 2 commits January 29, 2026 20:51
…h and ACP agent config priority

- Fix contextWindowSize not updating when switching models via setModel()
- Fix ACP agent to respect provider-configured contextWindowSize before auto-detection
- Simplify getTruncateToolOutputThreshold to use static threshold
- Add support for GLM-4.7, Kimi-2.5, and MiniMax-M2.1 models
- Update context usage display to require explicit contextWindowSize

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
- Footer.test.tsx: provide contextWindowSize in mock config to match
  Footer component's new requirement for displaying context usage
- tokenLimits.test.ts: consolidate Kimi K2 tests and update expectations
  to 256K for all variants to match the implementation
@tanzhenxin tanzhenxin dismissed stale reviews from Mingholy and themself January 29, 2026 13:14

FIxed.

@tanzhenxin tanzhenxin merged commit 0eb94a2 into QwenLM:main Jan 29, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] /auth OpenAI mode , no adaptable 'sessionTokenLimit' and cli display ( XX % context left) Idealab provider support

4 participants