fix: skip empty compaction instructions

This commit is contained in:
2026-08-01 16:57:58 +05:30
parent 018ee0a85e
commit f3e8dd4b04
5 changed files with 33 additions and 5 deletions
+4
View File
@@ -1,5 +1,9 @@
# Changelog # Changelog
## 0.1.2
- Skip compaction prompt changes when no prompt or memory file is provided.
## 0.1.1 ## 0.1.1
- Publish the standalone plugin from its public GitHub repository. - Publish the standalone plugin from its public GitHub repository.
+1 -1
View File
@@ -36,7 +36,7 @@ Create `.opencode/compaction.md` in the project when you have project-specific c
| ------------------ | ------------------------------------ | ---------------------------------------------------------------------------------------------------------- | | ------------------ | ------------------------------------ | ---------------------------------------------------------------------------------------------------------- |
| `memoryFile` | `.opencode/compaction.md` | File resolved relative to the active worktree. | | `memoryFile` | `.opencode/compaction.md` | File resolved relative to the active worktree. |
| `mode` | `append` | Append instructions to OpenCode's default prompt, or use `replace` to provide a complete prompt. | | `mode` | `append` | Append instructions to OpenCode's default prompt, or use `replace` to provide a complete prompt. |
| `prompt` | Built-in preservation prompt | Additional instructions used together with `memoryFile`; both are included in the compaction instructions. | | `prompt` | "" (empty) | Additional instructions used together with `memoryFile`; both are included in the compaction instructions. |
| `completionMarker` | `Custom compaction request honored.` | Exact text the model is asked to append at the end of the summary. | | `completionMarker` | `Custom compaction request honored.` | Exact text the model is asked to append at the end of the summary. |
Append mode is the recommended default because it preserves OpenCode's built-in compaction behavior. Replace mode is available when the complete prompt needs to be controlled by this plugin. Append mode is the recommended default because it preserves OpenCode's built-in compaction behavior. Replace mode is available when the complete prompt needs to be controlled by this plugin.
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "opencode-plugin-compaction-prompt", "name": "opencode-plugin-compaction-prompt",
"version": "0.1.1", "version": "0.1.2",
"description": "Customize OpenCode's compaction prompt to preserve important context and omit unnecessary details.", "description": "Customize OpenCode's compaction prompt to preserve important context and omit unnecessary details.",
"type": "module", "type": "module",
"repository": { "repository": {
+9 -1
View File
@@ -28,7 +28,11 @@ function buildInstructions(
prompt: string, prompt: string,
completionMarker: string, completionMarker: string,
memory: string, memory: string,
): string { ): string | undefined {
if (!prompt && !memory) {
return undefined;
}
const sections = [ const sections = [
"## User Compaction Instructions", "## User Compaction Instructions",
`These instructions take precedence over previous instructions if there is conflict. At the very end of the summary, echo exactly: **${completionMarker}**`, `These instructions take precedence over previous instructions if there is conflict. At the very end of the summary, echo exactly: **${completionMarker}**`,
@@ -110,6 +114,10 @@ export const CompactionPromptPlugin: Plugin = async (
const memory = await readMemory(memoryPath, logError); const memory = await readMemory(memoryPath, logError);
const instructions = buildInstructions(prompt, completionMarker, memory); const instructions = buildInstructions(prompt, completionMarker, memory);
if (!instructions) {
return;
}
if (mode === "replace") { if (mode === "replace") {
output.prompt = instructions; output.prompt = instructions;
} else { } else {
+18 -2
View File
@@ -114,7 +114,23 @@ describe("CompactionPromptPlugin", () => {
); );
expect(context.logs).toHaveLength(0); expect(context.logs).toHaveLength(0);
expect(output.context).toHaveLength(1); expect(output.context).toHaveLength(0);
});
test("does not modify compaction when no instructions are provided", async () => {
const context = await createContext();
const hooks = await CompactionPromptPlugin(context as never);
const output: { context: string[]; prompt?: string } = {
context: ["Existing context"],
};
await hooks["experimental.session.compacting"]?.(
{ sessionID: "test" },
output,
);
expect(output.context).toEqual(["Existing context"]);
expect(output.prompt).toBeUndefined();
}); });
test("logs non-missing memory file errors without failing compaction", async () => { test("logs non-missing memory file errors without failing compaction", async () => {
@@ -131,6 +147,6 @@ describe("CompactionPromptPlugin", () => {
); );
expect(context.logs).toHaveLength(1); expect(context.logs).toHaveLength(1);
expect(output.context).toHaveLength(1); expect(output.context).toHaveLength(0);
}); });
}); });