Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,19 +111,22 @@ DCP uses its own config file:
> },
> // Distills key findings into preserved knowledge before removing raw content
> "distill": {
> "enabled": true,
> // Permission mode: "allow" (no prompt), "ask" (prompt), "deny" (tool not registered)
> "permission": "allow",
> // Show distillation content as an ignored message notification
> "showDistillation": false,
> },
> // Collapses a range of conversation content into a single summary
> "compress": {
> "enabled": true,
> // Permission mode: "ask" (prompt), "allow" (no prompt), "deny" (tool not registered)
> "permission": "ask",
> // Show summary content as an ignored message notification
> "showCompression": false,
> },
> // Removes tool content from context without preservation (for completed tasks or noise)
> "prune": {
> "enabled": true,
> // Permission mode: "allow" (no prompt), "ask" (prompt), "deny" (tool not registered)
> "permission": "allow",
> },
> },
> // Automatic pruning strategies
Expand Down
27 changes: 15 additions & 12 deletions dcp.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,11 @@
"description": "Configuration for the distill tool",
"additionalProperties": false,
"properties": {
"enabled": {
"type": "boolean",
"default": true,
"description": "Enable the distill tool"
"permission": {
"type": "string",
"enum": ["ask", "allow", "deny"],
"default": "allow",
"description": "Permission mode (deny disables the tool)"
},
"showDistillation": {
"type": "boolean",
Expand All @@ -146,10 +147,11 @@
"description": "Configuration for the compress tool",
"additionalProperties": false,
"properties": {
"enabled": {
"type": "boolean",
"default": true,
"description": "Enable the compress tool"
"permission": {
"type": "string",
"enum": ["ask", "allow", "deny"],
"default": "ask",
"description": "Permission mode (deny disables the tool)"
},
"showCompression": {
"type": "boolean",
Expand All @@ -163,10 +165,11 @@
"description": "Configuration for the prune tool",
"additionalProperties": false,
"properties": {
"enabled": {
"type": "boolean",
"default": true,
"description": "Enable the prune tool"
"permission": {
"type": "string",
"enum": ["ask", "allow", "deny"],
"default": "allow",
"description": "Permission mode (deny disables the tool)"
}
}
}
Expand Down
32 changes: 15 additions & 17 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const plugin: Plugin = (async (ctx) => {
ctx.directory,
),
tool: {
...(config.tools.distill.enabled && {
...(config.tools.distill.permission !== "deny" && {
distill: createDistillTool({
client: ctx.client,
state,
Expand All @@ -70,7 +70,7 @@ const plugin: Plugin = (async (ctx) => {
workingDirectory: ctx.directory,
}),
}),
...(config.tools.compress.enabled && {
...(config.tools.compress.permission !== "deny" && {
compress: createCompressTool({
client: ctx.client,
state,
Expand All @@ -79,7 +79,7 @@ const plugin: Plugin = (async (ctx) => {
workingDirectory: ctx.directory,
}),
}),
...(config.tools.prune.enabled && {
...(config.tools.prune.permission !== "deny" && {
prune: createPruneTool({
client: ctx.client,
state,
Expand All @@ -99,9 +99,9 @@ const plugin: Plugin = (async (ctx) => {
}

const toolsToAdd: string[] = []
if (config.tools.distill.enabled) toolsToAdd.push("distill")
if (config.tools.compress.enabled) toolsToAdd.push("compress")
if (config.tools.prune.enabled) toolsToAdd.push("prune")
if (config.tools.distill.permission !== "deny") toolsToAdd.push("distill")
if (config.tools.compress.permission !== "deny") toolsToAdd.push("compress")
if (config.tools.prune.permission !== "deny") toolsToAdd.push("prune")

if (toolsToAdd.length > 0) {
const existingPrimaryTools = opencodeConfig.experimental?.primary_tools ?? []
Expand All @@ -112,18 +112,16 @@ const plugin: Plugin = (async (ctx) => {
logger.info(
`Added ${toolsToAdd.map((t) => `'${t}'`).join(" and ")} to experimental.primary_tools via config mutation`,
)

// Set compress permission to ask (only if not already configured)
if (config.tools.compress.enabled) {
const permission = opencodeConfig.permission ?? {}
if (!("compress" in permission)) {
opencodeConfig.permission = {
...permission,
compress: "ask",
} as typeof permission
}
}
}

// Set tool permissions from DCP config
const permission = opencodeConfig.permission ?? {}
opencodeConfig.permission = {
...permission,
distill: config.tools.distill.permission,
compress: config.tools.compress.permission,
prune: config.tools.prune.permission,
} as typeof permission
},
}
}) satisfies Plugin
Expand Down
72 changes: 39 additions & 33 deletions lib/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ export interface Deduplication {
}

export interface PruneTool {
enabled: boolean
permission: "ask" | "allow" | "deny"
}

export interface DistillTool {
enabled: boolean
permission: "ask" | "allow" | "deny"
showDistillation: boolean
}

export interface CompressTool {
enabled: boolean
permission: "ask" | "allow" | "deny"
showCompression: boolean
}

Expand Down Expand Up @@ -108,13 +108,13 @@ export const VALID_CONFIG_KEYS = new Set([
"tools.settings.protectedTools",
"tools.settings.contextLimit",
"tools.distill",
"tools.distill.enabled",
"tools.distill.permission",
"tools.distill.showDistillation",
"tools.compress",
"tools.compress.enabled",
"tools.compress.permission",
"tools.compress.showCompression",
"tools.prune",
"tools.prune.enabled",
"tools.prune.permission",
"strategies",
// strategies.deduplication
"strategies.deduplication",
Expand Down Expand Up @@ -303,12 +303,15 @@ function validateConfigTypes(config: Record<string, any>): ValidationError[] {
}
}
if (tools.distill) {
if (tools.distill.enabled !== undefined && typeof tools.distill.enabled !== "boolean") {
errors.push({
key: "tools.distill.enabled",
expected: "boolean",
actual: typeof tools.distill.enabled,
})
if (tools.distill.permission !== undefined) {
const validValues = ["ask", "allow", "deny"]
if (!validValues.includes(tools.distill.permission)) {
errors.push({
key: "tools.distill.permission",
expected: '"ask" | "allow" | "deny"',
actual: JSON.stringify(tools.distill.permission),
})
}
}
if (
tools.distill.showDistillation !== undefined &&
Expand All @@ -322,15 +325,15 @@ function validateConfigTypes(config: Record<string, any>): ValidationError[] {
}
}
if (tools.compress) {
if (
tools.compress.enabled !== undefined &&
typeof tools.compress.enabled !== "boolean"
) {
errors.push({
key: "tools.compress.enabled",
expected: "boolean",
actual: typeof tools.compress.enabled,
})
if (tools.compress.permission !== undefined) {
const validValues = ["ask", "allow", "deny"]
if (!validValues.includes(tools.compress.permission)) {
errors.push({
key: "tools.compress.permission",
expected: '"ask" | "allow" | "deny"',
actual: JSON.stringify(tools.compress.permission),
})
}
}
if (
tools.compress.showCompression !== undefined &&
Expand All @@ -344,12 +347,15 @@ function validateConfigTypes(config: Record<string, any>): ValidationError[] {
}
}
if (tools.prune) {
if (tools.prune.enabled !== undefined && typeof tools.prune.enabled !== "boolean") {
errors.push({
key: "tools.prune.enabled",
expected: "boolean",
actual: typeof tools.prune.enabled,
})
if (tools.prune.permission !== undefined) {
const validValues = ["ask", "allow", "deny"]
if (!validValues.includes(tools.prune.permission)) {
errors.push({
key: "tools.prune.permission",
expected: '"ask" | "allow" | "deny"',
actual: JSON.stringify(tools.prune.permission),
})
}
}
}
}
Expand Down Expand Up @@ -499,15 +505,15 @@ const defaultConfig: PluginConfig = {
contextLimit: 100000,
},
distill: {
enabled: true,
permission: "allow",
showDistillation: false,
},
compress: {
enabled: true,
permission: "ask",
showCompression: false,
},
prune: {
enabled: true,
permission: "allow",
},
},
strategies: {
Expand Down Expand Up @@ -678,15 +684,15 @@ function mergeTools(
contextLimit: override.settings?.contextLimit ?? base.settings.contextLimit,
},
distill: {
enabled: override.distill?.enabled ?? base.distill.enabled,
permission: override.distill?.permission ?? base.distill.permission,
showDistillation: override.distill?.showDistillation ?? base.distill.showDistillation,
},
compress: {
enabled: override.compress?.enabled ?? base.compress.enabled,
permission: override.compress?.permission ?? base.compress.permission,
showCompression: override.compress?.showCompression ?? base.compress.showCompression,
},
prune: {
enabled: override.prune?.enabled ?? base.prune.enabled,
permission: override.prune?.permission ?? base.prune.permission,
},
}
}
Expand Down
6 changes: 3 additions & 3 deletions lib/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ export function createSystemPromptHandler(
}

const flags = {
prune: config.tools.prune.enabled,
distill: config.tools.distill.enabled,
compress: config.tools.compress.enabled,
prune: config.tools.prune.permission !== "deny",
distill: config.tools.distill.permission !== "deny",
compress: config.tools.compress.permission !== "deny",
}

if (!flags.prune && !flags.distill && !flags.compress) {
Expand Down
18 changes: 9 additions & 9 deletions lib/messages/inject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ Context management was just performed. Do NOT use the ${toolName} again. A fresh

const getNudgeString = (config: PluginConfig): string => {
const flags = {
prune: config.tools.prune.enabled,
distill: config.tools.distill.enabled,
compress: config.tools.compress.enabled,
prune: config.tools.prune.permission !== "deny",
distill: config.tools.distill.permission !== "deny",
compress: config.tools.compress.permission !== "deny",
}

if (!flags.prune && !flags.distill && !flags.compress) {
Expand All @@ -71,9 +71,9 @@ const getNudgeString = (config: PluginConfig): string => {

const getCooldownMessage = (config: PluginConfig): string => {
return wrapCooldownMessage({
prune: config.tools.prune.enabled,
distill: config.tools.distill.enabled,
compress: config.tools.compress.enabled,
prune: config.tools.prune.permission !== "deny",
distill: config.tools.distill.permission !== "deny",
compress: config.tools.compress.permission !== "deny",
})
}

Expand Down Expand Up @@ -157,9 +157,9 @@ export const insertPruneToolContext = (
logger: Logger,
messages: WithParts[],
): void => {
const pruneEnabled = config.tools.prune.enabled
const distillEnabled = config.tools.distill.enabled
const compressEnabled = config.tools.compress.enabled
const pruneEnabled = config.tools.prune.permission !== "deny"
const distillEnabled = config.tools.distill.permission !== "deny"
const compressEnabled = config.tools.compress.permission !== "deny"

if (!pruneEnabled && !distillEnabled && !compressEnabled) {
return
Expand Down