mirror of
https://github.com/anomalyco/opencode.git
synced 2026-11-13 11:39:41 +03:00
fix(core): honor compaction agent model for summaries (#53276)
Co-authored-by: Padure Sergio <70955746+sergiopadure@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
Unverified
parent
30f4119459
commit
cb389aa679
@@ -19,9 +19,11 @@ import type { SessionCompactionResult } from "@opencode/plugin/effect/session"
|
||||
import type { SessionError } from "@opencode/schema/session-error"
|
||||
import { makeLocationNode } from "@opencode/util/effect/app-node"
|
||||
import { Context, Effect, Layer, Result, Stream } from "effect"
|
||||
import { Agent } from "../agent.js"
|
||||
import { Bus } from "../bus.js"
|
||||
import { Database } from "../database/database.js"
|
||||
import { llmClient } from "../effect/app-node-platform.js"
|
||||
import { Model } from "../model.js"
|
||||
import { State } from "../state.js"
|
||||
import { Token } from "../util/token.js"
|
||||
import type { SessionContext } from "./context.js"
|
||||
@@ -30,6 +32,7 @@ import { SessionHistory } from "./history.js"
|
||||
import type { SessionMessage } from "./message.js"
|
||||
import { SessionModelRequest } from "./model-request.js"
|
||||
import { SessionProviderContext } from "./provider-context.js"
|
||||
import { SessionRunnerModel } from "./runner/model.js"
|
||||
import { SessionRunnerRetry } from "./runner/retry.js"
|
||||
import { toLLMMessages } from "./runner/to-llm-message.js"
|
||||
import { contentFilterError, toSessionError } from "./to-session-error.js"
|
||||
@@ -181,8 +184,11 @@ const LEGACY_HEADING = "## Additional Context"
|
||||
export const layer = Layer.effect(
|
||||
Service,
|
||||
Effect.gen(function* () {
|
||||
const agents = yield* Agent.Service
|
||||
const bus = yield* Bus.Service
|
||||
const llm = yield* LLMClient.Service
|
||||
const catalog = yield* Model.Service
|
||||
const models = yield* SessionRunnerModel.Service
|
||||
const db = (yield* Database.Service).db
|
||||
const requests = yield* SessionModelRequest.Service
|
||||
|
||||
@@ -202,24 +208,33 @@ export const layer = Layer.effect(
|
||||
|
||||
// Only the user compacts when automatic compaction is off, overflow included.
|
||||
if (trigger.reason !== "manual" && !settings.auto) return { status: "skipped" }
|
||||
const ceiling = calculateCeiling(context.model.limit, settings.buffer)
|
||||
if (trigger.reason === "auto" && !due(context, ceiling)) return { status: "skipped" }
|
||||
if (trigger.reason === "auto" && !due(context, calculateCeiling(context.model.limit, settings.buffer)))
|
||||
return { status: "skipped" }
|
||||
const native = context.model.compaction?.type === "native"
|
||||
const agent = native ? undefined : yield* agents.get(Agent.ID.make("compaction"))
|
||||
const model =
|
||||
(agent?.model &&
|
||||
(yield* models
|
||||
.resolve({ ...context.session, model: agent.model }, catalog.available)
|
||||
.pipe(Effect.orElseSucceed(() => undefined)))) ??
|
||||
context.model
|
||||
const ceiling = calculateCeiling(model.limit, settings.buffer)
|
||||
// An unknown window never triggers auto compaction, but the compaction request still needs a size to aim for.
|
||||
const cap = Number.isFinite(ceiling)
|
||||
? ceiling
|
||||
: calculateCeiling({ ...context.model.limit, context: UNKNOWN_WINDOW }, settings.buffer)
|
||||
: calculateCeiling({ ...model.limit, context: UNKNOWN_WINDOW }, settings.buffer)
|
||||
// The provider just rejected this context, so the estimate ran low; the first attempt already aims below it.
|
||||
const budget =
|
||||
trigger.reason === "overflow" ? Math.min(cap, Math.floor(estimateContext(context) * SHRINK_STEPS[0])) : cap
|
||||
|
||||
const compaction =
|
||||
context.model.compaction?.type === "native"
|
||||
? compactNatively(trigger, budget, settings.keep)
|
||||
: summarize(trigger, budget, settings.keep)
|
||||
const selected = model === context.model ? trigger : { ...trigger, context: { ...context, model } }
|
||||
const compaction = native
|
||||
? compactNatively(selected, budget, settings.keep)
|
||||
: summarize(selected, budget, settings.keep)
|
||||
return yield* compaction.pipe(
|
||||
Effect.matchEffect({
|
||||
onSuccess: (result) => publish(trigger, result),
|
||||
onFailure: (failure) => publish(trigger, failure),
|
||||
onSuccess: (result) => publish(selected, result),
|
||||
onFailure: (failure) => publish(selected, failure),
|
||||
}),
|
||||
)
|
||||
})
|
||||
@@ -662,7 +677,7 @@ export const layer = Layer.effect(
|
||||
export const node = makeLocationNode({
|
||||
service: Service,
|
||||
layer,
|
||||
deps: [Bus.node, Database.node, llmClient, SessionModelRequest.node],
|
||||
deps: [Agent.node, Bus.node, Database.node, llmClient, Model.node, SessionModelRequest.node, SessionRunnerModel.node],
|
||||
})
|
||||
|
||||
/** History loads from the latest completed compaction, so a previous one is always the first message. */
|
||||
|
||||
@@ -46,6 +46,7 @@ const it = testEffect(
|
||||
}),
|
||||
),
|
||||
Config.node.replace(config),
|
||||
Location.node.replace(Location.boundNode({ directory: AbsolutePath.make("/tmp") })),
|
||||
]),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -18,6 +18,7 @@ import { SessionRunnerModel } from "@opencode/core/session/runner/model"
|
||||
import { SessionTable } from "@opencode/core/session/sql"
|
||||
import { SessionStore } from "@opencode/core/session/store"
|
||||
import { Session } from "@opencode/core/session"
|
||||
import { Location } from "@opencode/core/location"
|
||||
import { Project } from "@opencode/core/project"
|
||||
import { ProjectTable } from "@opencode/core/project/sql"
|
||||
import { App } from "@opencode/core/app"
|
||||
@@ -87,7 +88,11 @@ const it = testEffect(
|
||||
SessionModelRequest.node,
|
||||
PluginHooks.node,
|
||||
]),
|
||||
[Bus.node.replace(Bus.configured({ persist: true })), llmClient.replace(client)],
|
||||
[
|
||||
Bus.node.replace(Bus.configured({ persist: true })),
|
||||
llmClient.replace(client),
|
||||
Location.node.replace(Location.boundNode({ directory: AbsolutePath.make("/project") })),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import { AppNodeBuilder } from "@opencode/core/effect/app-node-builder"
|
||||
import { llmClient } from "@opencode/core/effect/app-node-platform"
|
||||
import { Instructions } from "@opencode/core/instructions/index"
|
||||
import { PluginHooks } from "@opencode/core/plugin/hooks"
|
||||
import { Location } from "@opencode/core/location"
|
||||
import { Project } from "@opencode/core/project"
|
||||
import { ProjectTable } from "@opencode/core/project/sql"
|
||||
import { AbsolutePath } from "@opencode/core/schema"
|
||||
@@ -40,7 +41,10 @@ const it = testEffect(
|
||||
PluginHooks.node,
|
||||
llmClient,
|
||||
]),
|
||||
[Bus.node.replace(Bus.configured({ persist: true }))],
|
||||
[
|
||||
Bus.node.replace(Bus.configured({ persist: true })),
|
||||
Location.node.replace(Location.boundNode({ directory: AbsolutePath.make("/project") })),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user