feat(plugin): allow compaction hook to replace prompt entirely (#5907)

This commit is contained in:
Joel Hooks 2025-12-22 20:19:14 -08:00 committed by GitHub
parent 279dc04b3c
commit eab177f5e7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 42 additions and 9 deletions

View file

@ -130,12 +130,15 @@ export namespace SessionCompaction {
model,
abort: input.abort,
})
// Allow plugins to inject context for compaction
// Allow plugins to inject context or replace compaction prompt
const compacting = await Plugin.trigger(
"experimental.session.compacting",
{ sessionID: input.sessionID },
{ context: [] },
{ context: [], prompt: undefined },
)
const defaultPrompt =
"Provide a detailed prompt for continuing our conversation above. Focus on information that would be helpful for continuing the conversation, including what we did, what we're doing, which files we're working on, and what we're going to do next considering new session will not have access to our conversation."
const promptText = compacting.prompt ?? [defaultPrompt, ...compacting.context].join("\n\n")
const result = await processor.process({
user: userMessage,
agent,
@ -150,10 +153,7 @@ export namespace SessionCompaction {
content: [
{
type: "text",
text: [
"Provide a detailed prompt for continuing our conversation above. Focus on information that would be helpful for continuing the conversation, including what we did, what we're doing, which files we're working on, and what we're going to do next considering new session will not have access to our conversation.",
...compacting.context,
].join("\n\n"),
text: promptText,
},
],
},

View file

@ -192,10 +192,16 @@ export interface Hooks {
},
) => Promise<void>
/**
* Called before session compaction starts. Allows plugins to append
* additional context to the compaction prompt.
* Called before session compaction starts. Allows plugins to customize
* the compaction prompt.
*
* - `context`: Additional context strings appended to the default prompt
* - `prompt`: If set, replaces the default compaction prompt entirely
*/
"experimental.session.compacting"?: (input: { sessionID: string }, output: { context: string[] }) => Promise<void>
"experimental.session.compacting"?: (
input: { sessionID: string },
output: { context: string[]; prompt?: string },
) => Promise<void>
"experimental.text.complete"?: (
input: { sessionID: string; messageID: string; partID: string },
output: { text: string },

View file

@ -233,3 +233,30 @@ Include any state that should persist across compaction:
```
The `experimental.session.compacting` hook fires before the LLM generates a continuation summary. Use it to inject domain-specific context that the default compaction prompt would miss.
You can also replace the compaction prompt entirely by setting `output.prompt`:
```ts title=".opencode/plugin/custom-compaction.ts"
import type { Plugin } from "@opencode-ai/plugin"
export const CustomCompactionPlugin: Plugin = async (ctx) => {
return {
"experimental.session.compacting": async (input, output) => {
// Replace the entire compaction prompt
output.prompt = `
You are generating a continuation prompt for a multi-agent swarm session.
Summarize:
1. The current task and its status
2. Which files are being modified and by whom
3. Any blockers or dependencies between agents
4. The next steps to complete the work
Format as a structured prompt that a new agent can use to resume work.
`
},
}
}
```
When `output.prompt` is set, it completely replaces the default compaction prompt. The `output.context` array is ignored in this case.