-
-
Notifications
You must be signed in to change notification settings - Fork 209
Optional learning pass prior to compression #594
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Malkovsky
wants to merge
1
commit into
Opencode-DCP:master
Choose a base branch
from
Malkovsky:feature/compression-learning
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| import type { CompressionLearningConfig } from "../../config" | ||
|
|
||
| const DURABLE_LEARNING_CRITERIA = `Extract only new, non-obvious, durable codebase knowledge: | ||
|
|
||
| - hidden relationships between files or modules; | ||
| - execution paths that differ from how the code appears; | ||
| - non-obvious configuration, environment variables, or flags; | ||
| - debugging breakthroughs when errors were misleading; | ||
| - API or tool quirks and their workarounds; | ||
| - useful build or test commands not already documented; | ||
| - architectural decisions and constraints; | ||
| - files that must change together. | ||
|
|
||
| Do not treat obvious documented facts, standard language or framework behavior, existing repository guidance, verbose explanations, or session-specific details as durable learning.` | ||
|
|
||
| function renderNotificationInstructions(): string { | ||
| return `Before starting the learning pass, send the user this exact progress message: | ||
|
|
||
| \`Initialized pre-compression learning.\` | ||
|
|
||
| After the learning pass, send one concise progress message before invoking the compress tool: | ||
|
|
||
| - If durable learning was found, start with \`Learning is finished.\` and briefly list the insights and any files changed. | ||
| - If there was no durable learning, send exactly \`Learning is finished. Nothing to extract.\` | ||
|
|
||
| These messages must not interrupt compression or ask the user for input.` | ||
| } | ||
|
|
||
| export function appendCompressionLearning( | ||
| prompt: string, | ||
| config?: CompressionLearningConfig, | ||
| ): string { | ||
| if (!config?.enabled) { | ||
| return prompt | ||
| } | ||
|
|
||
| const sections = [ | ||
| prompt.trim(), | ||
| `LEARN BEFORE COMPRESSION | ||
|
|
||
| Before invoking the compress tool, review the selected closed context for durable codebase learning. | ||
|
|
||
| First follow any learning policy present in the system or project instructions. Read the applicable repository guidance before deciding what to extract or where to persist it. Treat the criteria below as defaults where project policy is silent; do not override more specific project learning rules. | ||
|
|
||
| ${DURABLE_LEARNING_CRITERIA} | ||
|
|
||
| When genuine new learning exists, determine its narrowest applicable directory and follow the project's persistence policy. If the project does not specify a destination, read the relevant existing AGENTS.md files and persist each insight in 1-3 concise lines in the nearest appropriate AGENTS.md before compressing. Do not create or edit guidance files when there is no durable new learning. | ||
|
|
||
| Do not manufacture learning or delay necessary compression. The compression summary must still preserve all session state needed to continue; persisted guidance complements rather than replaces that summary.`, | ||
| ] | ||
|
|
||
| if (config.notifications) { | ||
| sections.push(renderNotificationInstructions()) | ||
| } | ||
|
|
||
| return sections.join("\n\n") | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| import assert from "node:assert/strict" | ||
| import test from "node:test" | ||
| import { appendCompressionLearning } from "../lib/prompts/extensions/learning" | ||
| import type { CompressionLearningConfig } from "../lib/config" | ||
|
|
||
| const BASE_PROMPT = "Custom compression instructions." | ||
|
|
||
| function config(overrides: Partial<CompressionLearningConfig> = {}): CompressionLearningConfig { | ||
| return { | ||
| enabled: true, | ||
| notifications: true, | ||
| ...overrides, | ||
| } | ||
| } | ||
|
|
||
| test("disabled compression learning leaves the effective prompt unchanged", () => { | ||
| const result = appendCompressionLearning(BASE_PROMPT, config({ enabled: false })) | ||
|
|
||
| assert.equal(result, BASE_PROMPT) | ||
| }) | ||
|
|
||
| test("learning appends durable criteria and project-policy guidance", () => { | ||
| const result = appendCompressionLearning(BASE_PROMPT, config()) | ||
|
|
||
| assert.ok(result.startsWith(BASE_PROMPT)) | ||
| assert.match(result, /LEARN BEFORE COMPRESSION/) | ||
| assert.match(result, /hidden relationships between files or modules/) | ||
| assert.match(result, /follow any learning policy present in the system or project instructions/) | ||
| assert.match(result, /do not override more specific project learning rules/) | ||
| assert.match(result, /Initialized pre-compression learning\./) | ||
| }) | ||
|
|
||
| test("learning persists findings according to project policy", () => { | ||
| const result = appendCompressionLearning(BASE_PROMPT, config()) | ||
|
|
||
| assert.match(result, /narrowest applicable directory/) | ||
| assert.match(result, /follow the project's persistence policy/) | ||
| assert.match(result, /nearest appropriate AGENTS\.md/) | ||
| assert.match( | ||
| result, | ||
| /Do not create or edit guidance files when there is no durable new learning/, | ||
| ) | ||
| }) | ||
|
|
||
| test("notifications can be disabled independently", () => { | ||
| const result = appendCompressionLearning(BASE_PROMPT, config({ notifications: false })) | ||
|
|
||
| assert.match(result, /LEARN BEFORE COMPRESSION/) | ||
| assert.doesNotMatch(result, /Initialized pre-compression learning\./) | ||
| assert.doesNotMatch(result, /Learning is finished/) | ||
| }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| import assert from "node:assert/strict" | ||
| import test from "node:test" | ||
| import { readFileSync } from "node:fs" | ||
|
|
||
| const schema = JSON.parse(readFileSync(new URL("../dcp.schema.json", import.meta.url), "utf-8")) | ||
| const learningSchema = schema.properties.compress.properties.learning | ||
|
|
||
| test("compression learning schema is opt-in and side-effect free by default", () => { | ||
| assert.deepEqual(learningSchema.default, { | ||
| enabled: false, | ||
| notifications: true, | ||
| }) | ||
| }) | ||
|
|
||
| test("compression learning schema accepts only documented settings", () => { | ||
| assert.deepEqual(Object.keys(learningSchema.properties).sort(), ["enabled", "notifications"]) | ||
| assert.deepEqual(learningSchema.required.sort(), ["enabled", "notifications"]) | ||
| assert.equal(learningSchema.additionalProperties, false) | ||
| }) | ||
|
|
||
| test("compression defaults include learning settings", () => { | ||
| assert.deepEqual(schema.properties.compress.default.learning, learningSchema.default) | ||
| }) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When a user sets only
compress.learning.enabled, or a project layer overrides onlynotifications, this requirement makes an otherwise usable layered configuration schema-invalid;validateConfigTypeslikewise reports the omitted sibling as having typeundefined, even thoughmergeCompressexplicitly supplies both missing values from the previous/default layer. Remove the requirement and validate each property only when present so users can override these settings independently like the other nested configuration fields.Useful? React with 👍 / 👎.