feat(preemptive-compaction): add onBeforeSummarize callback and context injection
- Added BeforeSummarizeCallback type to allow injecting context before session summarization - Added onBeforeSummarize option to PreemptiveCompactionOptions - Created compaction-context-injector module that injects summarization instructions with sections: - User Requests (As-Is) - Final Goal - Work Completed - Remaining Tasks - MUST NOT Do (Critical Constraints) - Wired up callback invocation in preemptive-compaction before calling summarize API - Exported new hook from src/hooks/index.ts 🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
This commit is contained in:
53
src/hooks/compaction-context-injector/index.ts
Normal file
53
src/hooks/compaction-context-injector/index.ts
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import type { SummarizeContext } from "../preemptive-compaction"
|
||||||
|
import { injectHookMessage } from "../../features/hook-message-injector"
|
||||||
|
import { log } from "../../shared/logger"
|
||||||
|
|
||||||
|
const SUMMARIZE_CONTEXT_PROMPT = `[COMPACTION CONTEXT INJECTION]
|
||||||
|
|
||||||
|
When summarizing this session, you MUST include the following sections in your summary:
|
||||||
|
|
||||||
|
## 1. User Requests (As-Is)
|
||||||
|
- List all original user requests exactly as they were stated
|
||||||
|
- Preserve the user's exact wording and intent
|
||||||
|
|
||||||
|
## 2. Final Goal
|
||||||
|
- What the user ultimately wanted to achieve
|
||||||
|
- The end result or deliverable expected
|
||||||
|
|
||||||
|
## 3. Work Completed
|
||||||
|
- What has been done so far
|
||||||
|
- Files created/modified
|
||||||
|
- Features implemented
|
||||||
|
- Problems solved
|
||||||
|
|
||||||
|
## 4. Remaining Tasks
|
||||||
|
- What still needs to be done
|
||||||
|
- Pending items from the original request
|
||||||
|
- Follow-up tasks identified during the work
|
||||||
|
|
||||||
|
## 5. MUST NOT Do (Critical Constraints)
|
||||||
|
- Things that were explicitly forbidden
|
||||||
|
- Approaches that failed and should not be retried
|
||||||
|
- User's explicit restrictions or preferences
|
||||||
|
- Anti-patterns identified during the session
|
||||||
|
|
||||||
|
This context is critical for maintaining continuity after compaction.
|
||||||
|
`
|
||||||
|
|
||||||
|
export function createCompactionContextInjector() {
|
||||||
|
return async (ctx: SummarizeContext): Promise<void> => {
|
||||||
|
log("[compaction-context-injector] injecting context", { sessionID: ctx.sessionID })
|
||||||
|
|
||||||
|
const success = injectHookMessage(ctx.sessionID, SUMMARIZE_CONTEXT_PROMPT, {
|
||||||
|
agent: "general",
|
||||||
|
model: { providerID: ctx.providerID, modelID: ctx.modelID },
|
||||||
|
path: { cwd: ctx.directory },
|
||||||
|
})
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
log("[compaction-context-injector] context injected", { sessionID: ctx.sessionID })
|
||||||
|
} else {
|
||||||
|
log("[compaction-context-injector] injection failed", { sessionID: ctx.sessionID })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,7 +8,8 @@ export { createDirectoryAgentsInjectorHook } from "./directory-agents-injector";
|
|||||||
export { createDirectoryReadmeInjectorHook } from "./directory-readme-injector";
|
export { createDirectoryReadmeInjectorHook } from "./directory-readme-injector";
|
||||||
export { createEmptyTaskResponseDetectorHook } from "./empty-task-response-detector";
|
export { createEmptyTaskResponseDetectorHook } from "./empty-task-response-detector";
|
||||||
export { createAnthropicAutoCompactHook, type AnthropicAutoCompactOptions } from "./anthropic-auto-compact";
|
export { createAnthropicAutoCompactHook, type AnthropicAutoCompactOptions } from "./anthropic-auto-compact";
|
||||||
export { createPreemptiveCompactionHook, type PreemptiveCompactionOptions } from "./preemptive-compaction";
|
export { createPreemptiveCompactionHook, type PreemptiveCompactionOptions, type SummarizeContext, type BeforeSummarizeCallback } from "./preemptive-compaction";
|
||||||
|
export { createCompactionContextInjector } from "./compaction-context-injector";
|
||||||
export { createThinkModeHook } from "./think-mode";
|
export { createThinkModeHook } from "./think-mode";
|
||||||
export { createClaudeCodeHooksHook } from "./claude-code-hooks";
|
export { createClaudeCodeHooksHook } from "./claude-code-hooks";
|
||||||
export { createRulesInjectorHook } from "./rules-injector";
|
export { createRulesInjectorHook } from "./rules-injector";
|
||||||
|
|||||||
@@ -8,8 +8,19 @@ import {
|
|||||||
} from "./constants"
|
} from "./constants"
|
||||||
import { log } from "../../shared/logger"
|
import { log } from "../../shared/logger"
|
||||||
|
|
||||||
|
export interface SummarizeContext {
|
||||||
|
sessionID: string
|
||||||
|
providerID: string
|
||||||
|
modelID: string
|
||||||
|
usageRatio: number
|
||||||
|
directory: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type BeforeSummarizeCallback = (ctx: SummarizeContext) => Promise<void> | void
|
||||||
|
|
||||||
export interface PreemptiveCompactionOptions {
|
export interface PreemptiveCompactionOptions {
|
||||||
experimental?: ExperimentalConfig
|
experimental?: ExperimentalConfig
|
||||||
|
onBeforeSummarize?: BeforeSummarizeCallback
|
||||||
}
|
}
|
||||||
|
|
||||||
interface MessageInfo {
|
interface MessageInfo {
|
||||||
@@ -68,6 +79,7 @@ export function createPreemptiveCompactionHook(
|
|||||||
options?: PreemptiveCompactionOptions
|
options?: PreemptiveCompactionOptions
|
||||||
) {
|
) {
|
||||||
const experimental = options?.experimental
|
const experimental = options?.experimental
|
||||||
|
const onBeforeSummarize = options?.onBeforeSummarize
|
||||||
const enabled = experimental?.preemptive_compaction !== false
|
const enabled = experimental?.preemptive_compaction !== false
|
||||||
const threshold = experimental?.preemptive_compaction_threshold ?? DEFAULT_THRESHOLD
|
const threshold = experimental?.preemptive_compaction_threshold ?? DEFAULT_THRESHOLD
|
||||||
|
|
||||||
@@ -132,6 +144,16 @@ export function createPreemptiveCompactionHook(
|
|||||||
log("[preemptive-compaction] triggering compaction", { sessionID, usageRatio })
|
log("[preemptive-compaction] triggering compaction", { sessionID, usageRatio })
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
if (onBeforeSummarize) {
|
||||||
|
await onBeforeSummarize({
|
||||||
|
sessionID,
|
||||||
|
providerID,
|
||||||
|
modelID,
|
||||||
|
usageRatio,
|
||||||
|
directory: ctx.directory,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
await ctx.client.session.summarize({
|
await ctx.client.session.summarize({
|
||||||
path: { id: sessionID },
|
path: { id: sessionID },
|
||||||
body: { providerID, modelID },
|
body: { providerID, modelID },
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
createClaudeCodeHooksHook,
|
createClaudeCodeHooksHook,
|
||||||
createAnthropicAutoCompactHook,
|
createAnthropicAutoCompactHook,
|
||||||
createPreemptiveCompactionHook,
|
createPreemptiveCompactionHook,
|
||||||
|
createCompactionContextInjector,
|
||||||
createRulesInjectorHook,
|
createRulesInjectorHook,
|
||||||
createBackgroundNotificationHook,
|
createBackgroundNotificationHook,
|
||||||
createAutoUpdateCheckerHook,
|
createAutoUpdateCheckerHook,
|
||||||
@@ -256,7 +257,11 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => {
|
|||||||
const anthropicAutoCompact = isHookEnabled("anthropic-auto-compact")
|
const anthropicAutoCompact = isHookEnabled("anthropic-auto-compact")
|
||||||
? createAnthropicAutoCompactHook(ctx, { experimental: pluginConfig.experimental })
|
? createAnthropicAutoCompactHook(ctx, { experimental: pluginConfig.experimental })
|
||||||
: null;
|
: null;
|
||||||
const preemptiveCompaction = createPreemptiveCompactionHook(ctx, { experimental: pluginConfig.experimental });
|
const compactionContextInjector = createCompactionContextInjector();
|
||||||
|
const preemptiveCompaction = createPreemptiveCompactionHook(ctx, {
|
||||||
|
experimental: pluginConfig.experimental,
|
||||||
|
onBeforeSummarize: compactionContextInjector,
|
||||||
|
});
|
||||||
const rulesInjector = isHookEnabled("rules-injector")
|
const rulesInjector = isHookEnabled("rules-injector")
|
||||||
? createRulesInjectorHook(ctx)
|
? createRulesInjectorHook(ctx)
|
||||||
: null;
|
: null;
|
||||||
|
|||||||
Reference in New Issue
Block a user