mirror of
https://github.com/cline/cline.git
synced 2026-09-13 09:50:12 +08:00
fix(core): restore compaction input budget contract
This commit is contained in:
@@ -90,7 +90,6 @@ function runForcedBasicCompaction(
|
||||
info: { id: "mock-model", maxInputTokens: targetTokens },
|
||||
},
|
||||
maxInputTokens: targetTokens,
|
||||
usableBudgetTokens: targetTokens,
|
||||
triggerTokens: targetTokens,
|
||||
thresholdRatio: 1,
|
||||
utilizationRatio: 2,
|
||||
@@ -266,7 +265,6 @@ describe("createContextCompactionPrepareTurn", () => {
|
||||
info: { id: "mock-model", maxInputTokens: 100_000 },
|
||||
},
|
||||
maxInputTokens: 100_000,
|
||||
usableBudgetTokens: 100_000,
|
||||
triggerTokens: 100_000,
|
||||
thresholdRatio: 1,
|
||||
utilizationRatio: 0.1,
|
||||
@@ -490,7 +488,6 @@ describe("createContextCompactionPrepareTurn", () => {
|
||||
info: { id: "mock-model", maxInputTokens: 1_000 },
|
||||
},
|
||||
maxInputTokens: 1_000,
|
||||
usableBudgetTokens: 1_000,
|
||||
triggerTokens: 900,
|
||||
targetTokens: 100,
|
||||
thresholdRatio: 0.9,
|
||||
@@ -1416,9 +1413,9 @@ describe("createContextCompactionPrepareTurn", () => {
|
||||
|
||||
expect(compact).toHaveBeenCalledTimes(1);
|
||||
const context = compact.mock.calls[0]?.[0];
|
||||
expect(context?.maxInputTokens).toBe(400_000);
|
||||
expect(context?.maxInputTokens).toBe(272_000);
|
||||
expect(context?.triggerTokens).toBe(244_800);
|
||||
expect(context?.thresholdRatio).toBe(244_800 / 400_000);
|
||||
expect(context?.thresholdRatio).toBe(0.9);
|
||||
expect(result?.messages).toEqual([
|
||||
{ role: "user", content: "Compacted by derived input budget" },
|
||||
]);
|
||||
@@ -1466,10 +1463,9 @@ describe("createContextCompactionPrepareTurn", () => {
|
||||
|
||||
expect(compact).toHaveBeenCalledTimes(1);
|
||||
const context = compact.mock.calls[0]?.[0];
|
||||
expect(context?.maxInputTokens).toBe(40_960);
|
||||
expect(context?.usableBudgetTokens).toBe(24_576);
|
||||
expect(context?.maxInputTokens).toBe(24_576);
|
||||
expect(context?.triggerTokens).toBe(22_118);
|
||||
expect(context?.thresholdRatio).toBe(22_118 / 40_960);
|
||||
expect(context?.thresholdRatio).toBe(22_118 / 24_576);
|
||||
});
|
||||
|
||||
it("caps shared-context output reserve at half the context window", async () => {
|
||||
@@ -1514,7 +1510,7 @@ describe("createContextCompactionPrepareTurn", () => {
|
||||
|
||||
expect(compact).toHaveBeenCalledTimes(1);
|
||||
const context = compact.mock.calls[0]?.[0];
|
||||
expect(context?.maxInputTokens).toBe(40_960);
|
||||
expect(context?.maxInputTokens).toBe(20_480);
|
||||
expect(context?.triggerTokens).toBe(18_432);
|
||||
});
|
||||
|
||||
@@ -1561,7 +1557,7 @@ describe("createContextCompactionPrepareTurn", () => {
|
||||
expect(compact).toHaveBeenCalledTimes(1);
|
||||
const context = compact.mock.calls[0]?.[0];
|
||||
expect(context?.triggerTokens).toBe(19_660);
|
||||
expect(context?.thresholdRatio).toBe(19_660 / 40_960);
|
||||
expect(context?.thresholdRatio).toBe(19_660 / 24_576);
|
||||
});
|
||||
|
||||
it("applies explicit reserve tokens to the usable budget", async () => {
|
||||
@@ -1607,7 +1603,7 @@ describe("createContextCompactionPrepareTurn", () => {
|
||||
expect(compact).toHaveBeenCalledTimes(1);
|
||||
const context = compact.mock.calls[0]?.[0];
|
||||
expect(context?.triggerTokens).toBe(20_480);
|
||||
expect(context?.thresholdRatio).toBe(0.5);
|
||||
expect(context?.thresholdRatio).toBe(20_480 / 24_576);
|
||||
});
|
||||
|
||||
it("uses the lower split input budget when it is below context-derived input budget", async () => {
|
||||
@@ -2013,7 +2009,6 @@ describe("createContextCompactionPrepareTurn", () => {
|
||||
info: { id: "mock-model", maxInputTokens: 100 },
|
||||
},
|
||||
maxInputTokens: 100,
|
||||
usableBudgetTokens: 100,
|
||||
triggerTokens: 100,
|
||||
thresholdRatio: 1,
|
||||
utilizationRatio: 0.1,
|
||||
|
||||
@@ -100,7 +100,6 @@ interface CompactionBudget {
|
||||
outputReserveTokens: number;
|
||||
triggerTokens: number;
|
||||
thresholdRatio: number;
|
||||
usableThresholdRatio: number;
|
||||
ceilingSource: CompactionBudgetSource;
|
||||
reserveCapped: boolean;
|
||||
}
|
||||
@@ -166,8 +165,6 @@ function resolveCompactionBudget(input: {
|
||||
outputReserveTokens,
|
||||
triggerTokens,
|
||||
thresholdRatio:
|
||||
ceilingTokens > 0 ? triggerTokens / ceilingTokens : 0,
|
||||
usableThresholdRatio:
|
||||
usableBudgetTokens > 0 ? triggerTokens / usableBudgetTokens : 0,
|
||||
ceilingSource,
|
||||
reserveCapped:
|
||||
@@ -371,7 +368,7 @@ export function createContextCompactionPrepareTurn(
|
||||
contextWindow: context.model.info?.contextWindow,
|
||||
modelMaxTokens: context.model.info?.maxTokens,
|
||||
});
|
||||
const maxInputTokens = compactionBudget.ceilingTokens;
|
||||
const maxInputTokens = compactionBudget.usableBudgetTokens;
|
||||
const shouldCompact = inputTokens > compactionBudget.triggerTokens;
|
||||
config.logger?.debug("Context compaction diagnostics", {
|
||||
mode,
|
||||
@@ -381,13 +378,12 @@ export function createContextCompactionPrepareTurn(
|
||||
modelId: config.modelId,
|
||||
inputTokens,
|
||||
maxInputTokens,
|
||||
usableBudgetTokens: compactionBudget.usableBudgetTokens,
|
||||
ceilingTokens: compactionBudget.ceilingTokens,
|
||||
outputReserveTokens: compactionBudget.outputReserveTokens,
|
||||
ceilingSource: compactionBudget.ceilingSource,
|
||||
reserveCapped: compactionBudget.reserveCapped,
|
||||
triggerTokens: compactionBudget.triggerTokens,
|
||||
thresholdRatio: compactionBudget.thresholdRatio,
|
||||
usableThresholdRatio: compactionBudget.usableThresholdRatio,
|
||||
shouldCompact,
|
||||
messageCount: context.messages.length,
|
||||
apiMessageCount: context.apiMessages.length,
|
||||
@@ -425,7 +421,6 @@ export function createContextCompactionPrepareTurn(
|
||||
messages: context.messages,
|
||||
model: context.model,
|
||||
maxInputTokens,
|
||||
usableBudgetTokens: compactionBudget.usableBudgetTokens,
|
||||
triggerTokens: targetState.triggerTokens,
|
||||
targetTokens,
|
||||
thresholdRatio: targetState.thresholdRatio,
|
||||
@@ -442,7 +437,7 @@ export function createContextCompactionPrepareTurn(
|
||||
iteration: context.iteration,
|
||||
triggerTokens: targetState.triggerTokens,
|
||||
maxInputTokens,
|
||||
usableBudgetTokens: compactionBudget.usableBudgetTokens,
|
||||
ceilingTokens: compactionBudget.ceilingTokens,
|
||||
outputReserveTokens: compactionBudget.outputReserveTokens,
|
||||
ceilingSource: compactionBudget.ceilingSource,
|
||||
},
|
||||
@@ -486,7 +481,7 @@ export function createContextCompactionPrepareTurn(
|
||||
severity: "info",
|
||||
strategy: strategy,
|
||||
maxInputTokens,
|
||||
usableBudgetTokens: compactionBudget.usableBudgetTokens,
|
||||
ceilingTokens: compactionBudget.ceilingTokens,
|
||||
outputReserveTokens: compactionBudget.outputReserveTokens,
|
||||
ceilingSource: compactionBudget.ceilingSource,
|
||||
reserveCapped: compactionBudget.reserveCapped,
|
||||
|
||||
@@ -67,20 +67,15 @@ export interface CoreCompactionContext {
|
||||
info?: ModelInfo;
|
||||
};
|
||||
/**
|
||||
* Full input ceiling for the model (context window or explicit override),
|
||||
* before any output-token reserve is subtracted.
|
||||
* Usable input budget after reserving any shared context window space needed
|
||||
* for model output.
|
||||
*/
|
||||
maxInputTokens: number;
|
||||
/**
|
||||
* Tokens the input may actually occupy: `maxInputTokens` minus the output
|
||||
* reserve held back on shared-context models. Compact below this value.
|
||||
*/
|
||||
usableBudgetTokens: number;
|
||||
triggerTokens: number;
|
||||
targetTokens?: number;
|
||||
/**
|
||||
* Effective trigger point as a fraction of `maxInputTokens`
|
||||
* (`triggerTokens / maxInputTokens`), not the raw configured ratio.
|
||||
* Effective trigger point as a fraction of the usable input budget
|
||||
* (`triggerTokens / maxInputTokens`).
|
||||
*/
|
||||
thresholdRatio: number;
|
||||
utilizationRatio: number;
|
||||
|
||||
Reference in New Issue
Block a user