@@ -93,6 +93,8 @@ const RECENT_CONFIGS_FILE = path.join(CONFIG_DIR, 'recent-configs.json');
9393const WORKFLOW_DEFINITIONS_FILE = path . join ( CONFIG_DIR , 'codexmate-workflows.json' ) ;
9494const WORKFLOW_RUNS_FILE = path . join ( CONFIG_DIR , 'codexmate-workflow-runs.jsonl' ) ;
9595const DEFAULT_CLAUDE_MODEL = 'glm-4.7' ;
96+ const DEFAULT_MODEL_CONTEXT_WINDOW = 190000 ;
97+ const DEFAULT_MODEL_AUTO_COMPACT_TOKEN_LIMIT = 185000 ;
9698const CODEX_BACKUP_NAME = 'codex-config' ;
9799
98100const DEFAULT_MODELS = [ 'gpt-5.3-codex' , 'gpt-5.1-codex-max' , 'gpt-4-turbo' , 'gpt-4' ] ;
@@ -226,6 +228,8 @@ function resolveWebHost(options = {}) {
226228
227229const EMPTY_CONFIG_FALLBACK_TEMPLATE = `model = "gpt-5.3-codex"
228230model_reasoning_effort = "high"
231+ model_context_window = ${ DEFAULT_MODEL_CONTEXT_WINDOW }
232+ model_auto_compact_token_limit = ${ DEFAULT_MODEL_AUTO_COMPACT_TOKEN_LIMIT }
229233disable_response_storage = true
230234approval_policy = "never"
231235sandbox_mode = "danger-full-access"
@@ -3168,6 +3172,8 @@ function buildDefaultConfigContent(initializedAt) {
31683172
31693173model_provider = "openai"
31703174model = "${ defaultModel } "
3175+ model_context_window = ${ DEFAULT_MODEL_CONTEXT_WINDOW }
3176+ model_auto_compact_token_limit = ${ DEFAULT_MODEL_AUTO_COMPACT_TOKEN_LIMIT }
31713177
31723178[model_providers.openai]
31733179name = "openai"
@@ -3333,6 +3339,40 @@ function applyReasoningEffortToTemplate(template, reasoningEffort) {
33333339 return content ;
33343340}
33353341
3342+ function normalizePositiveIntegerParam ( value ) {
3343+ if ( value === undefined || value === null ) {
3344+ return null ;
3345+ }
3346+ const text = typeof value === 'number'
3347+ ? String ( value )
3348+ : ( typeof value === 'string' ? value . trim ( ) : String ( value ) . trim ( ) ) ;
3349+ if ( ! text ) {
3350+ return null ;
3351+ }
3352+ if ( ! / ^ \d + $ / . test ( text ) ) {
3353+ return null ;
3354+ }
3355+ const parsed = Number . parseInt ( text , 10 ) ;
3356+ if ( ! Number . isSafeInteger ( parsed ) || parsed <= 0 ) {
3357+ return null ;
3358+ }
3359+ return parsed ;
3360+ }
3361+
3362+ function applyPositiveIntegerConfigToTemplate ( template , key , value ) {
3363+ let content = typeof template === 'string' ? template : '' ;
3364+ const normalized = normalizePositiveIntegerParam ( value ) ;
3365+ if ( ! key || normalized === null ) {
3366+ return content ;
3367+ }
3368+
3369+ const escapedKey = key . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, '\\$&' ) ;
3370+ const pattern = new RegExp ( `^\\s*${ escapedKey } \\s*=\\s*[^\\n]*\\n?` , 'gmi' ) ;
3371+ content = content . replace ( pattern , '' ) ;
3372+ content = content . replace ( / ^ \s * \n * / , '' ) ;
3373+ return `${ key } = ${ normalized } \n${ content } ` ;
3374+ }
3375+
33363376function getConfigTemplate ( params = { } ) {
33373377 let content = EMPTY_CONFIG_FALLBACK_TEMPLATE ;
33383378 if ( fs . existsSync ( CONFIG_FILE ) ) {
@@ -3352,11 +3392,34 @@ function getConfigTemplate(params = {}) {
33523392 if ( typeof params . reasoningEffort === 'string' ) {
33533393 template = applyReasoningEffortToTemplate ( template , params . reasoningEffort ) ;
33543394 }
3395+ if ( params . modelAutoCompactTokenLimit !== undefined ) {
3396+ template = applyPositiveIntegerConfigToTemplate (
3397+ template ,
3398+ 'model_auto_compact_token_limit' ,
3399+ params . modelAutoCompactTokenLimit
3400+ ) ;
3401+ }
3402+ if ( params . modelContextWindow !== undefined ) {
3403+ template = applyPositiveIntegerConfigToTemplate (
3404+ template ,
3405+ 'model_context_window' ,
3406+ params . modelContextWindow
3407+ ) ;
3408+ }
33553409 return {
33563410 template
33573411 } ;
33583412}
33593413
3414+ function readPositiveIntegerConfigValue ( config , key ) {
3415+ if ( ! config || typeof config !== 'object' || ! key ) {
3416+ return '' ;
3417+ }
3418+ const raw = config [ key ] ;
3419+ const normalized = normalizePositiveIntegerParam ( raw ) ;
3420+ return normalized === null ? '' : normalized ;
3421+ }
3422+
33603423function applyConfigTemplate ( params = { } ) {
33613424 const template = typeof params . template === 'string' ? params . template : '' ;
33623425 if ( ! template . trim ( ) ) {
@@ -9981,11 +10044,15 @@ function createWebServer({ htmlPath, assetsDir, webDir, host, port, openBrowser
998110044 const config = statusConfigResult . config ;
998210045 const serviceTier = typeof config . service_tier === 'string' ? config . service_tier . trim ( ) : '' ;
998310046 const modelReasoningEffort = typeof config . model_reasoning_effort === 'string' ? config . model_reasoning_effort . trim ( ) : '' ;
10047+ const modelContextWindow = readPositiveIntegerConfigValue ( config , 'model_context_window' ) ;
10048+ const modelAutoCompactTokenLimit = readPositiveIntegerConfigValue ( config , 'model_auto_compact_token_limit' ) ;
998410049 result = {
998510050 provider : config . model_provider || '未设置' ,
998610051 model : config . model || '未设置' ,
998710052 serviceTier,
998810053 modelReasoningEffort,
10054+ modelContextWindow,
10055+ modelAutoCompactTokenLimit,
998910056 configReady : ! statusConfigResult . isVirtual ,
999010057 configErrorType : statusConfigResult . errorType || '' ,
999110058 configNotice : statusConfigResult . reason || '' ,
@@ -11464,11 +11531,15 @@ function buildMcpStatusPayload() {
1146411531 const config = statusConfigResult . config ;
1146511532 const serviceTier = typeof config . service_tier === 'string' ? config . service_tier . trim ( ) : '' ;
1146611533 const modelReasoningEffort = typeof config . model_reasoning_effort === 'string' ? config . model_reasoning_effort . trim ( ) : '' ;
11534+ const modelContextWindow = readPositiveIntegerConfigValue ( config , 'model_context_window' ) ;
11535+ const modelAutoCompactTokenLimit = readPositiveIntegerConfigValue ( config , 'model_auto_compact_token_limit' ) ;
1146711536 return {
1146811537 provider : config . model_provider || '未设置' ,
1146911538 model : config . model || '未设置' ,
1147011539 serviceTier,
1147111540 modelReasoningEffort,
11541+ modelContextWindow,
11542+ modelAutoCompactTokenLimit,
1147211543 configReady : ! statusConfigResult . isVirtual ,
1147311544 configErrorType : statusConfigResult . errorType || '' ,
1147411545 configNotice : statusConfigResult . reason || '' ,
@@ -11566,6 +11637,8 @@ const BUILTIN_WORKFLOW_DEFINITIONS = Object.freeze({
1156611637 model : { type : 'string' } ,
1156711638 serviceTier : { type : 'string' } ,
1156811639 reasoningEffort : { type : 'string' } ,
11640+ modelContextWindow : { type : [ 'string' , 'number' ] } ,
11641+ modelAutoCompactTokenLimit : { type : [ 'string' , 'number' ] } ,
1156911642 apply : { type : 'boolean' }
1157011643 } ,
1157111644 required : [ 'provider' ] ,
@@ -11580,7 +11653,9 @@ const BUILTIN_WORKFLOW_DEFINITIONS = Object.freeze({
1158011653 provider : '{{input.provider}}' ,
1158111654 model : '{{input.model}}' ,
1158211655 serviceTier : '{{input.serviceTier}}' ,
11583- reasoningEffort : '{{input.reasoningEffort}}'
11656+ reasoningEffort : '{{input.reasoningEffort}}' ,
11657+ modelContextWindow : '{{input.modelContextWindow}}' ,
11658+ modelAutoCompactTokenLimit : '{{input.modelAutoCompactTokenLimit}}'
1158411659 }
1158511660 } ,
1158611661 {
@@ -12149,15 +12224,17 @@ function createMcpTools(options = {}) {
1214912224
1215012225 pushTool ( {
1215112226 name : 'codexmate.config.template.get' ,
12152- description : 'Get Codex config template with optional provider/model/service tier/reasoning effort.' ,
12227+ description : 'Get Codex config template with optional provider/model/service tier/reasoning effort/context budget .' ,
1215312228 readOnly : true ,
1215412229 inputSchema : {
1215512230 type : 'object' ,
1215612231 properties : {
1215712232 provider : { type : 'string' } ,
1215812233 model : { type : 'string' } ,
1215912234 serviceTier : { type : 'string' } ,
12160- reasoningEffort : { type : 'string' }
12235+ reasoningEffort : { type : 'string' } ,
12236+ modelContextWindow : { type : [ 'string' , 'number' ] } ,
12237+ modelAutoCompactTokenLimit : { type : [ 'string' , 'number' ] }
1216112238 } ,
1216212239 additionalProperties : false
1216312240 } ,
0 commit comments