diff --git a/dcp.schema.json b/dcp.schema.json index e25f09b1..fc2e6e78 100644 --- a/dcp.schema.json +++ b/dcp.schema.json @@ -121,6 +121,11 @@ "pattern": "^\\d+(?:\\.\\d+)?%$" } ] + }, + "contextLimitFallback": { + "description": "Fallback token limit when model context window is unknown and percentage-based contextLimit is used (defaults to 100000)", + "type": "number", + "default": 100000 } } }, diff --git a/lib/config.ts b/lib/config.ts index 1a60307f..b1a14eff 100644 --- a/lib/config.ts +++ b/lib/config.ts @@ -28,6 +28,7 @@ export interface ToolSettings { nudgeFrequency: number protectedTools: string[] contextLimit: number | `${number}%` + contextLimitFallback?: number } export interface Tools { @@ -107,6 +108,7 @@ export const VALID_CONFIG_KEYS = new Set([ "tools.settings.nudgeFrequency", "tools.settings.protectedTools", "tools.settings.contextLimit", + "tools.settings.contextLimitFallback", "tools.distill", "tools.distill.permission", "tools.distill.showDistillation", @@ -303,6 +305,15 @@ function validateConfigTypes(config: Record): ValidationError[] { }) } } + if (tools.settings.contextLimitFallback !== undefined) { + if (typeof tools.settings.contextLimitFallback !== "number") { + errors.push({ + key: "tools.settings.contextLimitFallback", + expected: "number", + actual: typeof tools.settings.contextLimitFallback, + }) + } + } } if (tools.distill) { if (tools.distill.permission !== undefined) { @@ -684,6 +695,8 @@ function mergeTools( ]), ], contextLimit: override.settings?.contextLimit ?? base.settings.contextLimit, + contextLimitFallback: + override.settings?.contextLimitFallback ?? base.settings.contextLimitFallback, }, distill: { permission: override.distill?.permission ?? base.distill.permission, diff --git a/lib/messages/inject.ts b/lib/messages/inject.ts index 3f0c60b1..92978816 100644 --- a/lib/messages/inject.ts +++ b/lib/messages/inject.ts @@ -68,11 +68,14 @@ Context management was just performed. Do NOT use the ${toolName} again. A fresh const resolveContextLimit = (config: PluginConfig, state: SessionState): number | undefined => { const configLimit = config.tools.settings.contextLimit + const contextLimitFallback = config.tools.settings.contextLimitFallback + const DEFAULT_FALLBACK = 100_000 // 100k tokens hardcoded fallback if (typeof configLimit === "string") { if (configLimit.endsWith("%")) { if (state.modelContextLimit === undefined) { - return undefined + const fallback = contextLimitFallback ?? DEFAULT_FALLBACK + return parsePercentageString(configLimit, fallback) } return parsePercentageString(configLimit, state.modelContextLimit) }