feat: configure auto compaction threshold

This commit is contained in:
marius-kilocode
2026-05-13 18:09:54 +02:00
parent cdbae6c24c
commit 4860e654ca
30 changed files with 263 additions and 28 deletions
+7
View File
@@ -0,0 +1,7 @@
---
"@kilocode/cli": minor
"@kilocode/sdk": minor
"kilo-code": minor
---
Support setting an auto-compaction threshold percentage so long sessions can compact before the context window is full.
@@ -36,10 +36,12 @@ This summary replaces older conversation history while Kilo keeps the most recen
### Automatic trigger
Kilo tracks the total token count for the session input, output, and cached reads and writes — and compares it to the model's context window. Compaction runs when the total fills the window minus a reserved buffer of headroom kept free for the next turn.
Kilo tracks the total token count for the session: input, output, and cached reads and writes. Compaction runs when token usage reaches `compaction.threshold_percent`, or when the remaining window hits the reserved safety buffer, whichever happens first.
How the buffer is chosen depends on what the model declares. When the model advertises a separate input limit, the buffer defaults to 20,000 tokens (or the model's maximum output size, whichever is smaller). When the model only declares a single context window, Kilo instead reserves the model's full output cap — up to 32,000 tokens.
`compaction.threshold_percent` is optional. Set it from `1` to `100` to compact at that percentage of the model input or context window.
Custom models that do not declare a context window are not tracked, and auto-compaction does not run for them.
### Context Pruning
@@ -59,10 +61,11 @@ You can trigger compaction at any time:
| Setting | Default | Effect |
|---|---|---|
| `compaction.auto` | `true` | Automatically compact when the usable window is reached |
| `compaction.threshold_percent` | unset | Compact when token usage reaches this percentage of the model window |
| `compaction.prune` | `true` | Clear old tool outputs beyond the 40K recency window |
| `compaction.tail_turns` | `2` | Keep the most recent user turns and their responses verbatim when possible |
| `compaction.preserve_recent_tokens` | 25% of usable context, clamped between 2,000 and 8,000 tokens | Token budget for the verbatim recent tail |
| `compaction.reserved` | `min(20,000, model_max_output_tokens)` | Token headroom kept free for the next turn — also defines the compaction trigger point |
| `compaction.reserved` | `min(20,000, model_max_output_tokens)` | Token headroom kept free for the next turn, and a safety trigger if reached before the threshold |
## Configuration
@@ -72,6 +75,7 @@ Compaction is configured in your `kilo.jsonc` file:
{
"compaction": {
"auto": true, // Enable or disable automatic compaction
"threshold_percent": 80, // Optional trigger at 80% of the model window
"prune": true, // Enable pruning of old tool outputs beyond the recency window
"tail_turns": 2, // Recent user turns to keep verbatim during compaction
"preserve_recent_tokens": 8000, // Maximum token budget for the recent tail
@@ -83,6 +87,7 @@ Compaction is configured in your `kilo.jsonc` file:
| Option | Type | Default | Description |
|---|---|---|---|
| `compaction.auto` | boolean | `true` | Enable or disable automatic compaction when the usable window is reached |
| `compaction.threshold_percent` | number | unset | Optional percentage from 1 to 100. Auto-compaction runs when token usage reaches this share of the model input or context window, unless the reserved safety buffer triggers first. |
| `compaction.prune` | boolean | `true` | Enable pruning of old tool outputs outside the 40K token recency window |
| `compaction.tail_turns` | number | `2` | Number of recent user turns, including following assistant and tool responses, to keep verbatim during compaction |
| `compaction.preserve_recent_tokens` | number | 25% of usable context, clamped between 2,000 and 8,000 tokens | Maximum token budget for recent turns kept verbatim after compaction |
@@ -131,10 +136,12 @@ This summary replaces older conversation history while Kilo keeps the most recen
### Automatic trigger
Kilo tracks the total token count for the session input, output, and cached reads and writes — and compares it to the model's context window. Compaction runs when the total fills the window minus a reserved buffer of headroom kept free for the next turn.
Kilo tracks the total token count for the session: input, output, and cached reads and writes. Compaction runs when token usage reaches `compaction.threshold_percent`, or when the remaining window hits the reserved safety buffer, whichever happens first.
How the buffer is chosen depends on what the model declares. When the model advertises a separate input limit, the buffer defaults to 20,000 tokens (or the model's maximum output size, whichever is smaller). When the model only declares a single context window, Kilo instead reserves the model's full output cap — up to 32,000 tokens.
`compaction.threshold_percent` is optional. Set it from `1` to `100` to compact at that percentage of the model input or context window.
[Custom models](/docs/code-with-ai/agents/custom-models) that do not declare a context window are not tracked, and auto-compaction does not run for them.
### Context Pruning
@@ -153,10 +160,11 @@ You can trigger compaction at any time:
| Setting | Default | Effect |
|---|---|---|
| `compaction.auto` | `true` | Automatically compact when the usable window is reached |
| `compaction.threshold_percent` | unset | Compact when token usage reaches this percentage of the model window |
| `compaction.prune` | `true` | Clear old tool outputs beyond the 40K recency window |
| `compaction.tail_turns` | `2` | Keep the most recent user turns and their responses verbatim when possible |
| `compaction.preserve_recent_tokens` | 25% of usable context, clamped between 2,000 and 8,000 tokens | Token budget for the verbatim recent tail |
| `compaction.reserved` | `min(20,000, model_max_output_tokens)` | Token headroom kept free for the next turn — also defines the compaction trigger point |
| `compaction.reserved` | `min(20,000, model_max_output_tokens)` | Token headroom kept free for the next turn, and a safety trigger if reached before the threshold |
## Configuration
@@ -166,6 +174,7 @@ Compaction is configured in your `kilo.jsonc` file:
{
"compaction": {
"auto": true, // Enable or disable automatic compaction
"threshold_percent": 80, // Optional trigger at 80% of the model window
"prune": true, // Enable pruning of old tool outputs beyond the recency window
"tail_turns": 2, // Recent user turns to keep verbatim during compaction
"preserve_recent_tokens": 8000, // Maximum token budget for the recent tail
@@ -177,6 +186,7 @@ Compaction is configured in your `kilo.jsonc` file:
| Option | Type | Default | Description |
|---|---|---|---|
| `compaction.auto` | boolean | `true` | Enable or disable automatic compaction when the usable window is reached |
| `compaction.threshold_percent` | number | unset | Optional percentage from 1 to 100. Auto-compaction runs when token usage reaches this share of the model input or context window, unless the reserved safety buffer triggers first. |
| `compaction.prune` | boolean | `true` | Enable pruning of old tool outputs outside the 40K token recency window |
| `compaction.tail_turns` | number | `2` | Number of recent user turns, including following assistant and tool responses, to keep verbatim during compaction |
| `compaction.preserve_recent_tokens` | number | 25% of usable context, clamped between 2,000 and 8,000 tokens | Maximum token budget for recent turns kept verbatim after compaction |
@@ -284,7 +294,11 @@ If the condensed summary doesn't capture important details:
- **Before major transitions**: When switching to a different aspect of your project
- **When approaching limits**: Run `/compact` manually before hitting the automatic trigger if you want control over _when_ the summary is produced
### Tuning `compaction.reserved`
### Tuning compaction triggers
Use `compaction.threshold_percent` when you want compaction to happen at a predictable share of the model window, such as `80` for earlier summaries on long tasks.
The reserved safety buffer still applies and can trigger compaction earlier than the percentage threshold.
On models that advertise a separate input limit, the `reserved` value is a trade-off:
+1 -1
View File
@@ -886,7 +886,7 @@
"format": "prettier --write .",
"format:check": "prettier --check .",
"knip": "knip",
"check-kilocode-change": "! grep -rn 'kilocode_change' . ../kilo-ui/ --exclude='package.json' --exclude='*.md' --exclude-dir='node_modules' --exclude-dir='dist' | grep -v '`kilocode_change`'",
"check-kilocode-change": "! grep -rIn 'kilocode_change' . ../kilo-ui/ --exclude='package.json' --exclude='*.md' --exclude-dir='node_modules' --exclude-dir='dist' | grep -v '`kilocode_change`'",
"lint": "eslint src webview-ui",
"test": "vscode-test",
"test:unit": "bun test tests/unit/",
@@ -15,6 +15,23 @@ const ContextTab: Component = () => {
const [newPattern, setNewPattern] = createSignal("")
const patterns = () => config().watcher?.ignore ?? []
const limit = () => {
const value = config().compaction?.threshold_percent
return value === null || value === undefined ? "" : String(value)
}
const saveLimit = (value: string) => {
const raw = value.trim()
if (!raw) {
updateConfig({ compaction: { ...config().compaction, threshold_percent: null } })
return
}
const percent = Number(raw)
if (!Number.isFinite(percent)) return
const next = Math.min(100, Math.max(1, percent))
updateConfig({ compaction: { ...config().compaction, threshold_percent: next } })
}
const addPattern = () => {
const value = newPattern().trim()
@@ -42,20 +59,39 @@ const ContextTab: Component = () => {
description={language.t("settings.context.autoCompaction.description")}
>
<Switch
checked={config().compaction?.auto ?? false}
checked={config().compaction?.auto ?? true}
onChange={(checked) => updateConfig({ compaction: { ...config().compaction, auto: checked } })}
hideLabel
>
{language.t("settings.context.autoCompaction.title")}
</Switch>
</SettingsRow>
<SettingsRow
title={language.t("settings.context.compactionLimit.title")}
description={language.t("settings.context.compactionLimit.description")}
>
<div style={{ display: "flex", "align-items": "center", gap: "6px", width: "96px" }}>
<TextField
type="number"
min="1"
max="100"
step="1"
value={limit()}
placeholder="80"
onChange={saveLimit}
hideLabel
label={language.t("settings.context.compactionLimit.title")}
/>
<span style={{ color: "var(--text-weak-base, var(--vscode-descriptionForeground))" }}>%</span>
</div>
</SettingsRow>
<SettingsRow
title={language.t("settings.context.prune.title")}
description={language.t("settings.context.prune.description")}
last
>
<Switch
checked={config().compaction?.prune ?? false}
checked={config().compaction?.prune ?? true}
onChange={(checked) => updateConfig({ compaction: { ...config().compaction, prune: checked } })}
hideLabel
>
+4 -1
View File
@@ -1378,7 +1378,10 @@ export const dict = {
"settings.checkpoints.enable.title": "تمكين اللقطات",
"settings.checkpoints.enable.description": "إنشاء نقاط فحص قبل تحرير الملفات",
"settings.context.autoCompaction.title": "ضغط تلقائي",
"settings.context.autoCompaction.description": "ضغط السياق تلقائياً عند امتلائه",
"settings.context.autoCompaction.description": "ضغط السياق تلقائياً قبل أن يصل إلى الحد",
"settings.context.compactionLimit.title": "حد الضغط التلقائي",
"settings.context.compactionLimit.description":
"اضغط عندما يصل السياق إلى هذه النسبة المئوية من نافذة النموذج. اتركه فارغاً لاستخدام هامش الأمان فقط.",
"settings.context.prune.title": "تقليم المخرجات القديمة",
"settings.context.prune.description": "إزالة مخرجات الأدوات القديمة أثناء الضغط",
"settings.context.watcherPatterns": "أنماط تجاهل مراقب الملفات",
+4 -1
View File
@@ -1419,7 +1419,10 @@ export const dict = {
"settings.checkpoints.enable.title": "Ativar snapshots",
"settings.checkpoints.enable.description": "Criar pontos de verificação antes de editar arquivos",
"settings.context.autoCompaction.title": "Compactação automática",
"settings.context.autoCompaction.description": "Compactar automaticamente o contexto quando estiver cheio",
"settings.context.autoCompaction.description": "Compactar automaticamente o contexto antes que atinja o limite",
"settings.context.compactionLimit.title": "Limite de compactação automática",
"settings.context.compactionLimit.description":
"Compacte quando o contexto atingir esta porcentagem da janela do modelo. Deixe em branco para usar apenas a margem de segurança.",
"settings.context.prune.title": "Remover saídas antigas",
"settings.context.prune.description": "Remover saídas antigas de ferramentas durante a compactação",
"settings.context.watcherPatterns": "Padrões de ignorar do observador",
+4 -1
View File
@@ -1416,7 +1416,10 @@ export const dict = {
"settings.checkpoints.enable.title": "Omogući snimke",
"settings.checkpoints.enable.description": "Kreiraj kontrolne točke prije uređivanja datoteka",
"settings.context.autoCompaction.title": "Automatska kompresija",
"settings.context.autoCompaction.description": "Automatski komprimiraj kontekst kada je pun",
"settings.context.autoCompaction.description": "Automatski komprimiraj kontekst prije nego dostigne limit",
"settings.context.compactionLimit.title": "Limit automatske kompresije",
"settings.context.compactionLimit.description":
"Komprimiraj kada kontekst dostigne ovaj procenat prozora modela. Ostavite prazno da koristite samo sigurnosnu rezervu.",
"settings.context.prune.title": "Očisti stare izlaze",
"settings.context.prune.description": "Ukloni stare izlaze alata tokom kompresije",
"settings.context.watcherPatterns": "Uzorci ignoriranja za promatrač datoteka",
+4 -1
View File
@@ -1405,7 +1405,10 @@ export const dict = {
"settings.checkpoints.enable.title": "Aktiver snapshots",
"settings.checkpoints.enable.description": "Opret kontrolpunkter før filredigeringer",
"settings.context.autoCompaction.title": "Automatisk komprimering",
"settings.context.autoCompaction.description": "Komprimér automatisk kontekst, r den er fuld",
"settings.context.autoCompaction.description": "Komprimér automatisk kontekst, r den når grænsen",
"settings.context.compactionLimit.title": "Grænse for automatisk komprimering",
"settings.context.compactionLimit.description":
"Komprimér, når konteksten når denne procentdel af modelvinduet. Lad feltet være tomt for kun at bruge sikkerhedsbufferen.",
"settings.context.prune.title": "Fjern gamle output",
"settings.context.prune.description": "Fjern gamle værktøjsoutput under komprimering",
"settings.context.watcherPatterns": "Filvagt-ignormønstre",
+4 -1
View File
@@ -1434,7 +1434,10 @@ export const dict = {
"settings.checkpoints.enable.description":
"Prüfpunkte vor Dateibearbeitungen erstellen, um vorherige Zustände wiederherstellen zu können",
"settings.context.autoCompaction.title": "Automatische Komprimierung",
"settings.context.autoCompaction.description": "Kontext automatisch komprimieren, wenn er voll ist",
"settings.context.autoCompaction.description": "Kontext automatisch komprimieren, bevor er das Limit erreicht",
"settings.context.compactionLimit.title": "Limit für automatische Komprimierung",
"settings.context.compactionLimit.description":
"Komprimieren, wenn der Kontext diesen Prozentsatz des Modellfensters erreicht. Leer lassen, um nur den Sicherheitspuffer zu verwenden.",
"settings.context.prune.title": "Alte Ausgaben bereinigen",
"settings.context.prune.description": "Alte Werkzeugausgaben während der Komprimierung entfernen",
"settings.context.watcherPatterns": "Datei-Watcher-Ignorierungsmuster",
@@ -1396,7 +1396,10 @@ export const dict = {
"settings.checkpoints.enable.description": "Create checkpoints before file edits so you can restore previous states",
"settings.context.autoCompaction.title": "Auto Compaction",
"settings.context.autoCompaction.description": "Automatically compact context when it's full",
"settings.context.autoCompaction.description": "Automatically compact context before it reaches the limit",
"settings.context.compactionLimit.title": "Auto Compaction Limit",
"settings.context.compactionLimit.description":
"Compact when context reaches this percentage of the model window. Leave blank to use the safety buffer only.",
"settings.context.prune.title": "Prune Old Outputs",
"settings.context.prune.description": "Remove old tool outputs during compaction",
"settings.context.watcherPatterns": "File Watcher Ignore Patterns",
+4 -1
View File
@@ -1426,7 +1426,10 @@ export const dict = {
"settings.checkpoints.enable.title": "Habilitar instantáneas",
"settings.checkpoints.enable.description": "Crear puntos de control antes de editar archivos",
"settings.context.autoCompaction.title": "Compactación automática",
"settings.context.autoCompaction.description": "Compactar automáticamente el contexto cuando está lleno",
"settings.context.autoCompaction.description": "Compactar automáticamente el contexto antes de que alcance el límite",
"settings.context.compactionLimit.title": "Límite de compactación automática",
"settings.context.compactionLimit.description":
"Compactar cuando el contexto alcance este porcentaje de la ventana del modelo. Déjalo en blanco para usar solo el búfer de seguridad.",
"settings.context.prune.title": "Eliminar salidas antiguas",
"settings.context.prune.description": "Eliminar salidas de herramientas antiguas durante la compactación",
"settings.context.watcherPatterns": "Patrones de ignorar del observador",
+5 -1
View File
@@ -1441,7 +1441,11 @@ export const dict = {
"settings.checkpoints.enable.title": "Activer les instantanés",
"settings.checkpoints.enable.description": "Créer des points de contrôle avant les modifications de fichiers",
"settings.context.autoCompaction.title": "Compaction automatique",
"settings.context.autoCompaction.description": "Compacter automatiquement le contexte lorsqu'il est plein",
"settings.context.autoCompaction.description":
"Compacter automatiquement le contexte avant qu'il n'atteigne la limite",
"settings.context.compactionLimit.title": "Limite de compactage automatique",
"settings.context.compactionLimit.description":
"Compacter lorsque le contexte atteint ce pourcentage de la fenêtre du modèle. Laissez vide pour utiliser uniquement la marge de sécurité.",
"settings.context.prune.title": "Élaguer les anciennes sorties",
"settings.context.prune.description": "Supprimer les anciennes sorties d'outils pendant la compaction",
"settings.context.watcherPatterns": "Motifs d'ignorance de l'observateur",
+4 -1
View File
@@ -1401,7 +1401,10 @@ export const dict = {
"settings.checkpoints.enable.title": "スナップショットを有効にする",
"settings.checkpoints.enable.description": "ファイル編集前にチェックポイントを作成して以前の状態を復元可能にする",
"settings.context.autoCompaction.title": "自動圧縮",
"settings.context.autoCompaction.description": "コンテキストが満杯のとき自動的に圧縮",
"settings.context.autoCompaction.description": "コンテキストが上限に達する前に自動的に圧縮",
"settings.context.compactionLimit.title": "自動圧縮の上限",
"settings.context.compactionLimit.description":
"コンテキストがモデルウィンドウのこの割合に達したら圧縮します。安全バッファーのみを使用するには空欄のままにしてください。",
"settings.context.prune.title": "古い出力を削除",
"settings.context.prune.description": "圧縮時に古いツール出力を削除",
"settings.context.watcherPatterns": "ファイルウォッチャー無視パターン",
+4 -1
View File
@@ -1386,7 +1386,10 @@ export const dict = {
"settings.checkpoints.enable.title": "스냅샷 활성화",
"settings.checkpoints.enable.description": "파일 편집 전 체크포인트를 생성하여 이전 상태를 복원할 수 있습니다",
"settings.context.autoCompaction.title": "자동 압축",
"settings.context.autoCompaction.description": "컨텍스트가 가득 차면 자동으로 압축",
"settings.context.autoCompaction.description": "컨텍스트가 한도에 도달하기 전에 자동으로 압축",
"settings.context.compactionLimit.title": "자동 압축 한도",
"settings.context.compactionLimit.description":
"컨텍스트가 모델 창의 이 비율에 도달하면 압축합니다. 안전 버퍼만 사용하려면 비워 두세요.",
"settings.context.prune.title": "이전 출력 정리",
"settings.context.prune.description": "압축 중 이전 도구 출력 제거",
"settings.context.watcherPatterns": "파일 감시자 무시 패턴",
+4 -1
View File
@@ -1385,7 +1385,10 @@ export const dict = {
"Maak checkpoints aan voor het bewerken van bestanden zodat je eerdere staten kunt herstellen",
"settings.context.autoCompaction.title": "Automatische Compactie",
"settings.context.autoCompaction.description": "Context automatisch compacteren wanneer deze vol is",
"settings.context.autoCompaction.description": "Context automatisch compacteren voordat deze de limiet bereikt",
"settings.context.compactionLimit.title": "Limiet voor automatisch compacteren",
"settings.context.compactionLimit.description":
"Compacteer wanneer de context dit percentage van het modelvenster bereikt. Laat leeg om alleen de veiligheidsbuffer te gebruiken.",
"settings.context.prune.title": "Oude Uitvoer Opschonen",
"settings.context.prune.description": "Verwijder oude tool uitvoer tijdens compactie",
"settings.context.watcherPatterns": "File Watcher Negeer Patronen",
+4 -1
View File
@@ -1404,7 +1404,10 @@ export const dict = {
"settings.checkpoints.enable.title": "Aktiver øyeblikksbilder",
"settings.checkpoints.enable.description": "Opprett kontrollpunkter før filredigeringer",
"settings.context.autoCompaction.title": "Automatisk komprimering",
"settings.context.autoCompaction.description": "Komprimer automatisk kontekst r den er full",
"settings.context.autoCompaction.description": "Komprimer automatisk kontekst r den når grensen",
"settings.context.compactionLimit.title": "Grense for automatisk komprimering",
"settings.context.compactionLimit.description":
"Komprimer når konteksten når denne prosentandelen av modellvinduet. La stå tomt for å bare bruke sikkerhetsbufferen.",
"settings.context.prune.title": "Fjern gamle utdata",
"settings.context.prune.description": "Fjern gamle verktøyutdata under komprimering",
"settings.context.watcherPatterns": "Filvakt-ignormønstre",
+4 -1
View File
@@ -1411,7 +1411,10 @@ export const dict = {
"settings.checkpoints.enable.title": "Włącz migawki",
"settings.checkpoints.enable.description": "Twórz punkty kontrolne przed edycją plików",
"settings.context.autoCompaction.title": "Automatyczna kompakcja",
"settings.context.autoCompaction.description": "Automatycznie kompaktuj kontekst, gdy jest pełny",
"settings.context.autoCompaction.description": "Automatycznie kompaktuj kontekst, zanim osiągnie limit",
"settings.context.compactionLimit.title": "Limit automatycznego kompaktowania",
"settings.context.compactionLimit.description":
"Kompaktuj, gdy kontekst osiągnie ten procent okna modelu. Pozostaw puste, aby używać tylko bufora bezpieczeństwa.",
"settings.context.prune.title": "Przytnij stare wyjścia",
"settings.context.prune.description": "Usuń stare wyjścia narzędzi podczas kompakcji",
"settings.context.watcherPatterns": "Wzorce ignorowania obserwatora plików",
+4 -1
View File
@@ -1411,7 +1411,10 @@ export const dict = {
"settings.checkpoints.enable.title": "Включить снимки",
"settings.checkpoints.enable.description": "Создавать контрольные точки перед редактированием файлов",
"settings.context.autoCompaction.title": "Автоматическое сжатие",
"settings.context.autoCompaction.description": "Автоматически сжимать контекст при заполнении",
"settings.context.autoCompaction.description": "Автоматически сжимать контекст до достижения лимита",
"settings.context.compactionLimit.title": "Лимит автоматического сжатия",
"settings.context.compactionLimit.description":
"Сжимать, когда контекст достигает этого процента окна модели. Оставьте пустым, чтобы использовать только буфер безопасности.",
"settings.context.prune.title": "Очистить старые выходные данные",
"settings.context.prune.description": "Удалить старые выходные данные инструментов при сжатии",
"settings.context.watcherPatterns": "Шаблоны игнорирования наблюдателя файлов",
+4 -1
View File
@@ -1384,7 +1384,10 @@ export const dict = {
"settings.checkpoints.enable.title": "เปิดใช้งานสแนปชอต",
"settings.checkpoints.enable.description": "สร้างจุดตรวจก่อนแก้ไขไฟล์",
"settings.context.autoCompaction.title": "การบีบอัดอัตโนมัติ",
"settings.context.autoCompaction.description": "บีบอัดบริบทอัตโนมัติเมื่อเต็ม",
"settings.context.autoCompaction.description": "บีบอัดบริบทอัตโนมัติก่อนถึงขีดจำกัด",
"settings.context.compactionLimit.title": "ขีดจำกัดการบีบอัดอัตโนมัติ",
"settings.context.compactionLimit.description":
"บีบอัดเมื่อบริบทถึงเปอร์เซ็นต์นี้ของหน้าต่างโมเดล เว้นว่างไว้เพื่อใช้เฉพาะบัฟเฟอร์ความปลอดภัย",
"settings.context.prune.title": "ตัดผลลัพธ์เก่า",
"settings.context.prune.description": "ลบผลลัพธ์เครื่องมือเก่าระหว่างการบีบอัด",
"settings.context.watcherPatterns": "รูปแบบการละเว้นตัวเฝ้าดูไฟล์",
+4 -1
View File
@@ -1374,7 +1374,10 @@ export const dict = {
"Dosya düzenlemelerinden önce kontrol noktaları oluştur, böylece önceki durumları geri yükleyebilirsiniz",
"settings.context.autoCompaction.title": "Otomatik Sıkıştırma",
"settings.context.autoCompaction.description": "Bağlam dolduğunda otomatik olarak sıkıştır",
"settings.context.autoCompaction.description": "Bağlam sınıra ulaşmadan önce otomatik olarak sıkıştır",
"settings.context.compactionLimit.title": "Otomatik sıkıştırma sınırı",
"settings.context.compactionLimit.description":
"Bağlam model penceresinin bu yüzdesine ulaştığında sıkıştır. Yalnızca güvenlik tamponunu kullanmak için boş bırakın.",
"settings.context.prune.title": "Eski Çıktıları Temizle",
"settings.context.prune.description": "Sıkıştırma sırasında eski araç çıktılarını kaldır",
"settings.context.watcherPatterns": "Dosya İzleyici Yok Sayma Kalıpları",
+4 -1
View File
@@ -1373,7 +1373,10 @@ export const dict = {
"Створювати контрольні точки перед редагуванням файлів, щоб мати можливість відновити попередні стани",
"settings.context.autoCompaction.title": "Автоматичне стиснення",
"settings.context.autoCompaction.description": "Автоматично стискати при заповненні контексту",
"settings.context.autoCompaction.description": "Автоматично стискати контекст до досягнення ліміту",
"settings.context.compactionLimit.title": "Ліміт автоматичного стискання",
"settings.context.compactionLimit.description":
"Стискати, коли контекст досягає цього відсотка вікна моделі. Залиште порожнім, щоб використовувати лише буфер безпеки.",
"settings.context.prune.title": "Очищати старі виводи",
"settings.context.prune.description": "Видаляти старі виводи інструментів під час стиснення",
"settings.context.watcherPatterns": "Шаблони ігнорування спостерігача файлів",
+3 -1
View File
@@ -1352,7 +1352,9 @@ export const dict = {
"settings.checkpoints.enable.title": "启用快照",
"settings.checkpoints.enable.description": "在文件编辑前创建检查点,以便恢复之前的状态",
"settings.context.autoCompaction.title": "自动压缩",
"settings.context.autoCompaction.description": "上下文满时自动压缩",
"settings.context.autoCompaction.description": "上下文达到限制前自动压缩",
"settings.context.compactionLimit.title": "自动压缩限制",
"settings.context.compactionLimit.description": "当上下文达到模型窗口的此百分比时进行压缩。留空则仅使用安全缓冲区。",
"settings.context.prune.title": "修剪旧输出",
"settings.context.prune.description": "压缩期间移除旧的工具输出",
"settings.context.watcherPatterns": "文件监视器忽略模式",
+3 -1
View File
@@ -1323,7 +1323,9 @@ export const dict = {
"settings.checkpoints.enable.title": "啟用快照",
"settings.checkpoints.enable.description": "在檔案編輯前建立檢查點,以便恢復之前的狀態",
"settings.context.autoCompaction.title": "自動壓縮",
"settings.context.autoCompaction.description": "上下文滿時自動壓縮",
"settings.context.autoCompaction.description": "上下文達到限制前自動壓縮",
"settings.context.compactionLimit.title": "自動壓縮限制",
"settings.context.compactionLimit.description": "當上下文達到模型視窗的此百分比時進行壓縮。留空則僅使用安全緩衝區。",
"settings.context.prune.title": "修剪舊輸出",
"settings.context.prune.description": "壓縮期間移除舊的工具輸出",
"settings.context.watcherPatterns": "檔案監視器忽略模式",
@@ -29,6 +29,7 @@ export interface SkillsConfig {
export interface CompactionConfig {
auto?: boolean
threshold_percent?: number | null
prune?: boolean
}
+7
View File
@@ -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)
}
}
+5 -1
View File
@@ -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)
})
})
+4
View File
@@ -2048,6 +2048,10 @@ export type Config = {
* Enable automatic compaction when context is full (default: true)
*/
auto?: boolean
/**
* Percentage of the model input/context window that triggers automatic compaction. The reserved safety buffer still applies if it would compact sooner.
*/
threshold_percent?: number | null
/**
* Enable pruning of old tool outputs (default: true)
*/
+13
View File
@@ -16413,6 +16413,19 @@
"description": "Enable automatic compaction when context is full (default: true)",
"type": "boolean"
},
"threshold_percent": {
"description": "Percentage of the model input/context window that triggers automatic compaction. The reserved safety buffer still applies if it would compact sooner.",
"anyOf": [
{
"type": "number",
"exclusiveMinimum": 0,
"maximum": 100
},
{
"type": "null"
}
]
},
"prune": {
"description": "Enable pruning of old tool outputs (default: true)",
"type": "boolean"