{"version":3,"file":"context-capability.d.ts","sourceRoot":"","sources":["../../../src/core/context-runtime/context-capability.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,uBAAuB;IACvC,2EAA2E;IAC3E,kBAAkB,EAAE,MAAM,CAAC;IAC3B,4EAA4E;IAC5E,cAAc,EAAE,MAAM,CAAC;IACvB,qFAAqF;IACrF,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,0BAA0B;IAC1C;;;OAGG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,0DAA0D;IAC1D,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,sDAAsD;IACtD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,6EAA6E;IAC7E,sBAAsB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,iBAAiB;IACjC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,uBAAuB,EAAE,MAAM,CAAC;IAChC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,uEAAuE;IACvE,SAAS,EAAE,OAAO,CAAC;IACnB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,yEAAyE;IACzE,qBAAqB,EAAE,MAAM,CAAC;CAC9B;AAYD,wBAAgB,sBAAsB,CACrC,uBAAuB,EAAE,MAAM,EAC/B,oBAAoB,EAAE,MAAM,EAC5B,mBAAmB,EAAE,MAAM,EAC3B,sBAAsB,SAAoC,GACxD,MAAM,CAGR;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACvC,MAAM,EAAE,uBAAuB,EAC/B,SAAS,GAAE,0BAA+B,GACxC,iBAAiB,CAyCnB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAKlG;AAED,+EAA+E;AAC/E,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAG/F","sourcesContent":["/**\n * Context capability model (Long-Horizon Context Virtualization, 2.5.0).\n *\n * A provider-independent representation of what a model backend can actually\n * accept. It separates the *physical* context window from the *configured*\n * context window, reserves output + safety headroom, and derives the effective\n * safe input budget that a preflight governor must enforce.\n *\n * Invariant (HARD ACCEPTANCE INVARIANT):\n *\n *   inputTokens + reservedOutputTokens + safetyReserveTokens <= configuredContextWindow\n *\n * No Qwen/llama.cpp/provider values are hardcoded here. The source of truth is\n * `Model.contextWindow` / `Model.maxTokens` (which the model registry already\n * makes configurable per custom model and per model override); explicit\n * capability overrides win when the API cannot report a reliable value.\n */\n\nexport interface ContextCapabilitySource {\n\t/** Physical native window reported by the model/API (may be 0/unknown). */\n\tmodelContextWindow: number;\n\t/** Maximum output tokens the model can produce (total, incl. reasoning). */\n\tmodelMaxTokens: number;\n\t/** True when the model emits reasoning/thinking content out of the output budget. */\n\treasoning?: boolean;\n}\n\nexport interface ContextCapabilityOverrides {\n\t/**\n\t * Authoritative configured window. Wins over `modelContextWindow` when the\n\t * API cannot report it reliably (local llama.cpp, etc.).\n\t */\n\tconfiguredContextWindow?: number;\n\t/** Explicit output reservation. Default derived below. */\n\treservedOutputTokens?: number;\n\t/** Explicit safety reserve. Default derived below. */\n\tsafetyReserveTokens?: number;\n\t/** Ratio of safeInputBudget at which proactive pressure handling begins. */\n\tsoftPressureRatio?: number;\n\t/** Absolute floor for the safe input budget (prevents pathological zero). */\n\tminimumSafeInputBudget?: number;\n}\n\nexport interface ContextCapability {\n\tphysicalContextWindow: number;\n\tconfiguredContextWindow: number;\n\tmaximumOutputTokens: number;\n\t/** True when reasoning content is emitted out of the output budget. */\n\treasoning: boolean;\n\treservedOutputTokens: number;\n\tsafetyReserveTokens: number;\n\tsafeInputBudget: number;\n\t/** Input tokens at which the governor starts virtualizing/compacting. */\n\tsoftPressureThreshold: number;\n}\n\nconst DEFAULT_SOFT_PRESSURE_RATIO = 0.8;\nconst DEFAULT_MINIMUM_SAFE_INPUT_BUDGET = 512;\nconst MIN_SAFETY_RESERVE = 256;\nconst MAX_SAFETY_RESERVE = 4096;\nconst MAX_OUTPUT_SHARE = 0.5;\n\nfunction clamp(value: number, min: number, max: number): number {\n\treturn Math.min(max, Math.max(min, value));\n}\n\nexport function computeSafeInputBudget(\n\tconfiguredContextWindow: number,\n\treservedOutputTokens: number,\n\tsafetyReserveTokens: number,\n\tminimumSafeInputBudget = DEFAULT_MINIMUM_SAFE_INPUT_BUDGET,\n): number {\n\tconst raw = configuredContextWindow - reservedOutputTokens - safetyReserveTokens;\n\treturn Math.max(minimumSafeInputBudget, Math.floor(raw));\n}\n\n/**\n * Resolve the effective context capability for a model backend.\n *\n * Output reservation never exceeds half the configured window, so a backend\n * with a huge `maxTokens` cannot starve the input budget. This is what makes a\n * 32K window usable as a daily driver: at most half is reserved for output.\n */\nexport function resolveContextCapability(\n\tsource: ContextCapabilitySource,\n\toverrides: ContextCapabilityOverrides = {},\n): ContextCapability {\n\tconst physicalContextWindow = Math.max(1, Math.floor(source.modelContextWindow || 0));\n\tconst configuredContextWindow = Math.max(1, Math.floor(overrides.configuredContextWindow ?? physicalContextWindow));\n\tconst reasoning = source.reasoning ?? false;\n\n\tconst maximumOutputTokens = Math.max(1, Math.floor(source.modelMaxTokens || 8192));\n\tconst reservedOutputTokens = clamp(\n\t\tMath.floor(\n\t\t\toverrides.reservedOutputTokens ??\n\t\t\t\tMath.min(maximumOutputTokens, Math.floor(configuredContextWindow * MAX_OUTPUT_SHARE)),\n\t\t),\n\t\t1,\n\t\tMath.max(1, configuredContextWindow - 1),\n\t);\n\n\tconst safetyReserveTokens = clamp(\n\t\tMath.floor(overrides.safetyReserveTokens ?? Math.floor(configuredContextWindow * 0.05)),\n\t\tMIN_SAFETY_RESERVE,\n\t\tMAX_SAFETY_RESERVE,\n\t);\n\n\tconst safeInputBudget = computeSafeInputBudget(\n\t\tconfiguredContextWindow,\n\t\treservedOutputTokens,\n\t\tsafetyReserveTokens,\n\t\toverrides.minimumSafeInputBudget ?? DEFAULT_MINIMUM_SAFE_INPUT_BUDGET,\n\t);\n\n\tconst softPressureRatio = clamp(overrides.softPressureRatio ?? DEFAULT_SOFT_PRESSURE_RATIO, 0.1, 0.95);\n\tconst softPressureThreshold = Math.floor(safeInputBudget * softPressureRatio);\n\n\treturn {\n\t\tphysicalContextWindow,\n\t\tconfiguredContextWindow,\n\t\tmaximumOutputTokens,\n\t\treasoning,\n\t\treservedOutputTokens,\n\t\tsafetyReserveTokens,\n\t\tsafeInputBudget,\n\t\tsoftPressureThreshold,\n\t};\n}\n\n/**\n * True when a request of `inputTokens` would violate the hard invariant.\n */\nexport function exceedsSafeInputBudget(capability: ContextCapability, inputTokens: number): boolean {\n\treturn (\n\t\tinputTokens + capability.reservedOutputTokens + capability.safetyReserveTokens >\n\t\tcapability.configuredContextWindow\n\t);\n}\n\n/** Pressure ratio 0..1+ of the current input against the safe input budget. */\nexport function contextPressureRatio(capability: ContextCapability, inputTokens: number): number {\n\tif (capability.safeInputBudget <= 0) return Number.POSITIVE_INFINITY;\n\treturn inputTokens / capability.safeInputBudget;\n}\n"]}