mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-09-24 16:02:55 +08:00
feat: configure auto compaction threshold
This commit is contained in:
@@ -115,6 +115,7 @@ const LogLevelRef = Schema.Literals(["DEBUG", "INFO", "WARN", "ERROR"]).annotate
|
||||
identifier: "LogLevel",
|
||||
description: "Log level",
|
||||
})
|
||||
const Percent = Schema.Number.check(Schema.isGreaterThan(0), Schema.isLessThanOrEqualTo(100)) // kilocode_change
|
||||
|
||||
// kilocode_change - KiloIndexingConfig is still a Zod schema; bridge via ZodOverride
|
||||
const IndexingRef = Schema.Any.annotate({ [ZodOverride]: KiloIndexingConfig })
|
||||
@@ -277,6 +278,12 @@ export const Info = Schema.Struct({
|
||||
auto: Schema.optional(Schema.Boolean).annotate({
|
||||
description: "Enable automatic compaction when context is full (default: true)",
|
||||
}),
|
||||
// kilocode_change start
|
||||
threshold_percent: Schema.optional(Schema.NullOr(Percent)).annotate({
|
||||
description:
|
||||
"Percentage of the model input/context window that triggers automatic compaction. The reserved safety buffer still applies if it would compact sooner.",
|
||||
}),
|
||||
// kilocode_change end
|
||||
prune: Schema.optional(Schema.Boolean).annotate({
|
||||
description: "Enable pruning of old tool outputs (default: true)",
|
||||
}),
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import type { Config } from "@/config/config"
|
||||
import type { Provider } from "@/provider/provider"
|
||||
|
||||
export namespace KiloSessionOverflow {
|
||||
export function limit(input: { cfg: Config.Info; model: Provider.Model; usable: number }) {
|
||||
const percent = input.cfg.compaction?.threshold_percent
|
||||
if (typeof percent !== "number") return input.usable
|
||||
|
||||
const context = input.model.limit.input || input.model.limit.context
|
||||
if (context === 0) return input.usable
|
||||
|
||||
const cap = Math.floor(context * (percent / 100))
|
||||
return Math.min(input.usable, cap)
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import type { Config } from "@/config/config"
|
||||
import type { Provider } from "@/provider/provider"
|
||||
import { ProviderTransform } from "@/provider/transform"
|
||||
import type { MessageV2 } from "./message-v2"
|
||||
import { KiloSessionOverflow } from "@/kilocode/session/overflow" // kilocode_change
|
||||
|
||||
const COMPACTION_BUFFER = 20_000
|
||||
|
||||
@@ -22,5 +23,8 @@ export function isOverflow(input: { cfg: Config.Info; tokens: MessageV2.Assistan
|
||||
|
||||
const count =
|
||||
input.tokens.total || input.tokens.input + input.tokens.output + input.tokens.cache.read + input.tokens.cache.write
|
||||
return count >= usable(input)
|
||||
// kilocode_change start
|
||||
const cap = KiloSessionOverflow.limit({ cfg: input.cfg, model: input.model, usable: usable(input) })
|
||||
return count >= cap
|
||||
// kilocode_change end
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
import { describe, expect, test } from "bun:test"
|
||||
import { Config } from "@/config/config"
|
||||
import type { Provider } from "@/provider/provider"
|
||||
import type { MessageV2 } from "@/session/message-v2"
|
||||
import { isOverflow } from "@/session/overflow"
|
||||
|
||||
function cfg(compaction?: Config.Info["compaction"]) {
|
||||
return Config.Info.zod.parse({ compaction })
|
||||
}
|
||||
|
||||
function model(opts: { context: number; output: number; input?: number }): Provider.Model {
|
||||
return {
|
||||
id: "test-model",
|
||||
providerID: "test",
|
||||
name: "Test",
|
||||
limit: {
|
||||
context: opts.context,
|
||||
input: opts.input,
|
||||
output: opts.output,
|
||||
},
|
||||
cost: { input: 0, output: 0, cache: { read: 0, write: 0 } },
|
||||
capabilities: {
|
||||
toolcall: true,
|
||||
attachment: false,
|
||||
reasoning: false,
|
||||
temperature: true,
|
||||
input: { text: true, image: false, audio: false, video: false },
|
||||
output: { text: true, image: false, audio: false, video: false },
|
||||
},
|
||||
api: { npm: "@ai-sdk/anthropic" },
|
||||
options: {},
|
||||
} as Provider.Model
|
||||
}
|
||||
|
||||
function tokens(count: number): MessageV2.Assistant["tokens"] {
|
||||
return { input: count, output: 0, reasoning: 0, cache: { read: 0, write: 0 } }
|
||||
}
|
||||
|
||||
describe("Kilo auto-compaction threshold", () => {
|
||||
test("triggers at the configured context percentage", () => {
|
||||
const conf = cfg({ threshold_percent: 75 })
|
||||
const mdl = model({ context: 200_000, output: 32_000 })
|
||||
|
||||
expect(isOverflow({ cfg: conf, model: mdl, tokens: tokens(149_999) })).toBe(false)
|
||||
expect(isOverflow({ cfg: conf, model: mdl, tokens: tokens(150_000) })).toBe(true)
|
||||
})
|
||||
|
||||
test("keeps the reserved safety trigger when it is lower", () => {
|
||||
const conf = cfg({ threshold_percent: 95 })
|
||||
const mdl = model({ context: 200_000, output: 32_000 })
|
||||
|
||||
expect(isOverflow({ cfg: conf, model: mdl, tokens: tokens(167_999) })).toBe(false)
|
||||
expect(isOverflow({ cfg: conf, model: mdl, tokens: tokens(168_000) })).toBe(true)
|
||||
})
|
||||
|
||||
test("uses a model input limit when present", () => {
|
||||
const conf = cfg({ threshold_percent: 75 })
|
||||
const mdl = model({ context: 400_000, input: 200_000, output: 32_000 })
|
||||
|
||||
expect(isOverflow({ cfg: conf, model: mdl, tokens: tokens(149_999) })).toBe(false)
|
||||
expect(isOverflow({ cfg: conf, model: mdl, tokens: tokens(150_000) })).toBe(true)
|
||||
})
|
||||
|
||||
test("ignores a cleared threshold", () => {
|
||||
const conf = cfg({ threshold_percent: null })
|
||||
const mdl = model({ context: 200_000, output: 32_000 })
|
||||
|
||||
expect(isOverflow({ cfg: conf, model: mdl, tokens: tokens(150_000) })).toBe(false)
|
||||
expect(isOverflow({ cfg: conf, model: mdl, tokens: tokens(168_000) })).toBe(true)
|
||||
})
|
||||
|
||||
test("still respects disabled auto-compaction", () => {
|
||||
const conf = cfg({ auto: false, threshold_percent: 75 })
|
||||
const mdl = model({ context: 200_000, output: 32_000 })
|
||||
|
||||
expect(isOverflow({ cfg: conf, model: mdl, tokens: tokens(150_000) })).toBe(false)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user