1aebf39d23
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
104 lines
3.1 KiB
TypeScript
104 lines
3.1 KiB
TypeScript
import type { OhMyOpenCodeConfig } from "../config"
|
|
import type { ContextLimitModelCacheState } from "../shared/context-limit-resolver"
|
|
|
|
import { createPostCompactionDegradationMonitor } from "./preemptive-compaction-degradation-monitor"
|
|
import { runPreemptiveCompactionIfNeeded } from "./preemptive-compaction-trigger"
|
|
import type {
|
|
CachedCompactionState,
|
|
PreemptiveCompactionContext,
|
|
TokenInfo,
|
|
} from "./preemptive-compaction-types"
|
|
|
|
export function createPreemptiveCompactionHook(
|
|
ctx: PreemptiveCompactionContext,
|
|
pluginConfig: OhMyOpenCodeConfig,
|
|
modelCacheState?: ContextLimitModelCacheState,
|
|
) {
|
|
const compactionInProgress = new Set<string>()
|
|
const compactedSessions = new Set<string>()
|
|
const lastCompactionTime = new Map<string, number>()
|
|
const tokenCache = new Map<string, CachedCompactionState>()
|
|
|
|
const postCompactionMonitor = createPostCompactionDegradationMonitor({
|
|
client: ctx.client,
|
|
directory: ctx.directory,
|
|
pluginConfig,
|
|
tokenCache,
|
|
compactionInProgress,
|
|
})
|
|
|
|
const toolExecuteAfter = async (
|
|
input: { tool: string; sessionID: string; callID: string },
|
|
_output: { title: string; output: string; metadata: unknown }
|
|
) => {
|
|
await runPreemptiveCompactionIfNeeded({
|
|
ctx,
|
|
pluginConfig,
|
|
modelCacheState,
|
|
sessionID: input.sessionID,
|
|
tokenCache,
|
|
compactionInProgress,
|
|
compactedSessions,
|
|
lastCompactionTime,
|
|
})
|
|
}
|
|
|
|
const eventHandler = async ({ event }: { event: { type: string; properties?: unknown } }) => {
|
|
const props = event.properties as Record<string, unknown> | undefined
|
|
|
|
if (event.type === "session.deleted") {
|
|
const sessionID = (props?.info as { id?: string } | undefined)?.id
|
|
if (sessionID) {
|
|
compactionInProgress.delete(sessionID)
|
|
compactedSessions.delete(sessionID)
|
|
lastCompactionTime.delete(sessionID)
|
|
tokenCache.delete(sessionID)
|
|
postCompactionMonitor.clear(sessionID)
|
|
}
|
|
return
|
|
}
|
|
|
|
if (event.type === "session.compacted") {
|
|
const sessionID = (props?.sessionID as string | undefined)
|
|
?? (props?.info as { id?: string } | undefined)?.id
|
|
if (sessionID) {
|
|
postCompactionMonitor.onSessionCompacted(sessionID)
|
|
}
|
|
return
|
|
}
|
|
|
|
if (event.type === "message.updated") {
|
|
const info = props?.info as {
|
|
id?: string
|
|
role?: string
|
|
sessionID?: string
|
|
providerID?: string
|
|
modelID?: string
|
|
finish?: boolean
|
|
tokens?: TokenInfo
|
|
} | undefined
|
|
|
|
if (!info || info.role !== "assistant" || !info.finish || !info.sessionID) return
|
|
|
|
if (info.providerID && info.tokens) {
|
|
tokenCache.set(info.sessionID, {
|
|
providerID: info.providerID,
|
|
modelID: info.modelID ?? "",
|
|
tokens: info.tokens,
|
|
})
|
|
}
|
|
compactedSessions.delete(info.sessionID)
|
|
|
|
await postCompactionMonitor.onAssistantMessageUpdated({
|
|
sessionID: info.sessionID,
|
|
id: info.id,
|
|
})
|
|
}
|
|
}
|
|
|
|
return {
|
|
"tool.execute.after": toolExecuteAfter,
|
|
event: eventHandler,
|
|
}
|
|
}
|