Skip to content

Commit 6001ad5

Browse files
committed
feat(session): make compaction thresholds and message buffer configurable
1 parent 7c80ac0 commit 6001ad5

File tree

3 files changed

+24
-6
lines changed

3 files changed

+24
-6
lines changed

packages/opencode/src/config/config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,6 +1042,9 @@ export namespace Config {
10421042
.object({
10431043
auto: z.boolean().optional().describe("Enable automatic compaction when context is full (default: true)"),
10441044
prune: z.boolean().optional().describe("Enable pruning of old tool outputs (default: true)"),
1045+
token_threshold: z.number().int().positive().optional().describe("Trigger compaction when total token count exceeds this absolute number"),
1046+
context_threshold: z.number().gt(0).lte(1).optional().describe("Trigger compaction when token usage exceeds this fraction of the model context window (e.g. 0.8 = 80%)"),
1047+
min_messages: z.number().int().positive().optional().describe("Minimum number of messages to wait before next compaction (default: 5)"),
10451048
})
10461049
.optional(),
10471050
experimental: z

packages/opencode/src/session/compaction.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ export namespace SessionCompaction {
3333
const context = input.model.limit.context
3434
if (context === 0) return false
3535
const count = input.tokens.input + input.tokens.cache.read + input.tokens.output
36+
37+
// Absolute token threshold
38+
if (config.compaction?.token_threshold && count > config.compaction.token_threshold) return true
39+
40+
// Context percentage threshold
41+
if (config.compaction?.context_threshold && count > context * config.compaction.context_threshold) return true
42+
3643
const output = Math.min(input.model.limit.output, SessionPrompt.OUTPUT_TOKEN_MAX) || SessionPrompt.OUTPUT_TOKEN_MAX
3744
const usable = input.model.limit.input || context - output
3845
return count > usable

packages/opencode/src/session/prompt.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import z from "zod"
55
import { Identifier } from "../id/id"
66
import { MessageV2 } from "./message-v2"
77
import { Log } from "../util/log"
8+
import { Config } from "../config/config"
89
import { SessionRevert } from "./revert"
910
import { Session } from "."
1011
import { Agent } from "../agent/agent"
@@ -269,6 +270,7 @@ export namespace SessionPrompt {
269270
let step = 0
270271
const session = await Session.get(sessionID)
271272
while (true) {
273+
const config = await Config.get()
272274
SessionStatus.set(sessionID, { type: "busy" })
273275
log.info("loop", { step, sessionID })
274276
if (abort.aborted) break
@@ -496,9 +498,13 @@ export namespace SessionPrompt {
496498
}
497499

498500
// context overflow, needs compaction
501+
const lastSummaryIndex = msgs.findLastIndex((m) => m.info.role === "assistant" && m.info.summary)
502+
const messagesSinceSummary = lastSummaryIndex === -1 ? Infinity : msgs.length - 1 - lastSummaryIndex
503+
499504
if (
500505
lastFinished &&
501506
lastFinished.summary !== true &&
507+
messagesSinceSummary > (config.compaction?.min_messages ?? 5) &&
502508
(await SessionCompaction.isOverflow({ tokens: lastFinished.tokens, model }))
503509
) {
504510
await SessionCompaction.create({
@@ -615,12 +621,14 @@ export namespace SessionPrompt {
615621
})
616622
if (result === "stop") break
617623
if (result === "compact") {
618-
await SessionCompaction.create({
619-
sessionID,
620-
agent: lastUser.agent,
621-
model: lastUser.model,
622-
auto: true,
623-
})
624+
if (messagesSinceSummary > (config.compaction?.min_messages ?? 5)) {
625+
await SessionCompaction.create({
626+
sessionID,
627+
agent: lastUser.agent,
628+
model: lastUser.model,
629+
auto: true,
630+
})
631+
}
624632
}
625633
continue
626634
}

0 commit comments

Comments
 (0)