@tarquinen/opencode-dcp 0.3.30 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -8
- package/dist/index.js.map +1 -1
- package/dist/lib/api-formats/prunable-list.d.ts +49 -0
- package/dist/lib/api-formats/prunable-list.d.ts.map +1 -0
- package/dist/lib/api-formats/prunable-list.js +112 -0
- package/dist/lib/api-formats/prunable-list.js.map +1 -0
- package/dist/lib/api-formats/synth-instruction.d.ts +29 -0
- package/dist/lib/api-formats/synth-instruction.d.ts.map +1 -0
- package/dist/lib/api-formats/synth-instruction.js +171 -0
- package/dist/lib/api-formats/synth-instruction.js.map +1 -0
- package/dist/lib/config.d.ts +1 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +13 -7
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/core/janitor.d.ts +60 -0
- package/dist/lib/core/janitor.d.ts.map +1 -0
- package/dist/lib/core/janitor.js +301 -0
- package/dist/lib/core/janitor.js.map +1 -0
- package/dist/lib/core/prompt.d.ts.map +1 -0
- package/dist/lib/{prompt.js → core/prompt.js} +1 -1
- package/dist/lib/core/prompt.js.map +1 -0
- package/dist/lib/core/strategies/deduplication.d.ts +7 -0
- package/dist/lib/core/strategies/deduplication.d.ts.map +1 -0
- package/dist/lib/core/strategies/deduplication.js +76 -0
- package/dist/lib/core/strategies/deduplication.js.map +1 -0
- package/dist/lib/core/strategies/index.d.ts +21 -0
- package/dist/lib/core/strategies/index.d.ts.map +1 -0
- package/dist/lib/core/strategies/index.js +48 -0
- package/dist/lib/core/strategies/index.js.map +1 -0
- package/dist/lib/core/strategies/types.d.ts +35 -0
- package/dist/lib/core/strategies/types.d.ts.map +1 -0
- package/dist/lib/core/strategies/types.js +6 -0
- package/dist/lib/core/strategies/types.js.map +1 -0
- package/dist/lib/fetch-wrapper/formats/bedrock.d.ts +14 -0
- package/dist/lib/fetch-wrapper/formats/bedrock.d.ts.map +1 -0
- package/dist/lib/fetch-wrapper/formats/bedrock.js +128 -0
- package/dist/lib/fetch-wrapper/formats/bedrock.js.map +1 -0
- package/dist/lib/fetch-wrapper/formats/gemini.d.ts +14 -0
- package/dist/lib/fetch-wrapper/formats/gemini.d.ts.map +1 -0
- package/dist/lib/fetch-wrapper/formats/gemini.js +138 -0
- package/dist/lib/fetch-wrapper/formats/gemini.js.map +1 -0
- package/dist/lib/fetch-wrapper/formats/index.d.ts +5 -0
- package/dist/lib/fetch-wrapper/formats/index.d.ts.map +1 -0
- package/dist/lib/fetch-wrapper/formats/index.js +5 -0
- package/dist/lib/fetch-wrapper/formats/index.js.map +1 -0
- package/dist/lib/fetch-wrapper/formats/openai-chat.d.ts +14 -0
- package/dist/lib/fetch-wrapper/formats/openai-chat.d.ts.map +1 -0
- package/dist/lib/fetch-wrapper/formats/openai-chat.js +106 -0
- package/dist/lib/fetch-wrapper/formats/openai-chat.js.map +1 -0
- package/dist/lib/fetch-wrapper/formats/openai-responses.d.ts +11 -0
- package/dist/lib/fetch-wrapper/formats/openai-responses.d.ts.map +1 -0
- package/dist/lib/fetch-wrapper/formats/openai-responses.js +69 -0
- package/dist/lib/fetch-wrapper/formats/openai-responses.js.map +1 -0
- package/dist/lib/fetch-wrapper/gc-tracker.d.ts +4 -0
- package/dist/lib/fetch-wrapper/gc-tracker.d.ts.map +1 -0
- package/dist/lib/fetch-wrapper/gc-tracker.js +61 -0
- package/dist/lib/fetch-wrapper/gc-tracker.js.map +1 -0
- package/dist/lib/fetch-wrapper/handler.d.ts +13 -0
- package/dist/lib/fetch-wrapper/handler.d.ts.map +1 -0
- package/dist/lib/fetch-wrapper/handler.js +85 -0
- package/dist/lib/fetch-wrapper/handler.js.map +1 -0
- package/dist/lib/fetch-wrapper/index.d.ts +3 -2
- package/dist/lib/fetch-wrapper/index.d.ts.map +1 -1
- package/dist/lib/fetch-wrapper/index.js +41 -15
- package/dist/lib/fetch-wrapper/index.js.map +1 -1
- package/dist/lib/fetch-wrapper/types.d.ts +36 -1
- package/dist/lib/fetch-wrapper/types.d.ts.map +1 -1
- package/dist/lib/fetch-wrapper/types.js +7 -1
- package/dist/lib/fetch-wrapper/types.js.map +1 -1
- package/dist/lib/hooks.d.ts +3 -3
- package/dist/lib/hooks.d.ts.map +1 -1
- package/dist/lib/hooks.js +25 -15
- package/dist/lib/hooks.js.map +1 -1
- package/dist/lib/prompts/tool.txt +18 -5
- package/dist/lib/pruning-tool.d.ts +14 -6
- package/dist/lib/pruning-tool.d.ts.map +1 -1
- package/dist/lib/pruning-tool.js +121 -19
- package/dist/lib/pruning-tool.js.map +1 -1
- package/dist/lib/state/id-mapping.d.ts +26 -0
- package/dist/lib/state/id-mapping.d.ts.map +1 -0
- package/dist/lib/state/id-mapping.js +54 -0
- package/dist/lib/state/id-mapping.js.map +1 -0
- package/dist/lib/state/index.d.ts +25 -0
- package/dist/lib/state/index.d.ts.map +1 -0
- package/dist/lib/{state.js → state/index.js} +10 -6
- package/dist/lib/state/index.js.map +1 -0
- package/dist/lib/{state-persistence.d.ts → state/persistence.d.ts} +3 -3
- package/dist/lib/state/persistence.d.ts.map +1 -0
- package/dist/lib/{state-persistence.js → state/persistence.js} +1 -1
- package/dist/lib/state/persistence.js.map +1 -0
- package/dist/lib/state/tool-cache.d.ts +22 -0
- package/dist/lib/state/tool-cache.d.ts.map +1 -0
- package/dist/lib/state/tool-cache.js +102 -0
- package/dist/lib/state/tool-cache.js.map +1 -0
- package/dist/lib/tokenizer.js +2 -2
- package/dist/lib/tokenizer.js.map +1 -1
- package/dist/lib/ui/display-utils.d.ts.map +1 -0
- package/dist/lib/{display-utils.js → ui/display-utils.js} +0 -3
- package/dist/lib/ui/display-utils.js.map +1 -0
- package/dist/lib/ui/notification.d.ts +32 -0
- package/dist/lib/ui/notification.d.ts.map +1 -0
- package/dist/lib/ui/notification.js +180 -0
- package/dist/lib/ui/notification.js.map +1 -0
- package/dist/lib/version-checker.d.ts +1 -1
- package/dist/lib/version-checker.d.ts.map +1 -1
- package/dist/lib/version-checker.js +4 -1
- package/dist/lib/version-checker.js.map +1 -1
- package/package.json +6 -6
- package/dist/lib/deduplicator.d.ts +0 -16
- package/dist/lib/deduplicator.d.ts.map +0 -1
- package/dist/lib/deduplicator.js +0 -68
- package/dist/lib/deduplicator.js.map +0 -1
- package/dist/lib/display-utils.d.ts.map +0 -1
- package/dist/lib/display-utils.js.map +0 -1
- package/dist/lib/fetch-wrapper/gemini.d.ts +0 -7
- package/dist/lib/fetch-wrapper/gemini.d.ts.map +0 -1
- package/dist/lib/fetch-wrapper/gemini.js +0 -120
- package/dist/lib/fetch-wrapper/gemini.js.map +0 -1
- package/dist/lib/fetch-wrapper/openai-chat.d.ts +0 -7
- package/dist/lib/fetch-wrapper/openai-chat.d.ts.map +0 -1
- package/dist/lib/fetch-wrapper/openai-chat.js +0 -101
- package/dist/lib/fetch-wrapper/openai-chat.js.map +0 -1
- package/dist/lib/fetch-wrapper/openai-responses.d.ts +0 -7
- package/dist/lib/fetch-wrapper/openai-responses.d.ts.map +0 -1
- package/dist/lib/fetch-wrapper/openai-responses.js +0 -74
- package/dist/lib/fetch-wrapper/openai-responses.js.map +0 -1
- package/dist/lib/janitor.d.ts +0 -57
- package/dist/lib/janitor.d.ts.map +0 -1
- package/dist/lib/janitor.js +0 -547
- package/dist/lib/janitor.js.map +0 -1
- package/dist/lib/prompt.d.ts.map +0 -1
- package/dist/lib/prompt.js.map +0 -1
- package/dist/lib/state-persistence.d.ts.map +0 -1
- package/dist/lib/state-persistence.js.map +0 -1
- package/dist/lib/state.d.ts +0 -43
- package/dist/lib/state.d.ts.map +0 -1
- package/dist/lib/state.js.map +0 -1
- package/dist/lib/synth-instruction.d.ts +0 -16
- package/dist/lib/synth-instruction.d.ts.map +0 -1
- package/dist/lib/synth-instruction.js +0 -209
- package/dist/lib/synth-instruction.js.map +0 -1
- package/dist/lib/tool-cache.d.ts +0 -12
- package/dist/lib/tool-cache.d.ts.map +0 -1
- package/dist/lib/tool-cache.js +0 -52
- package/dist/lib/tool-cache.js.map +0 -1
- /package/dist/lib/{prompt.d.ts → core/prompt.d.ts} +0 -0
- /package/dist/lib/{display-utils.d.ts → ui/display-utils.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ Add to your OpenCode config:
|
|
|
13
13
|
```jsonc
|
|
14
14
|
// opencode.jsonc
|
|
15
15
|
{
|
|
16
|
-
"plugin": ["@tarquinen/opencode-dcp@0.
|
|
16
|
+
"plugin": ["@tarquinen/opencode-dcp@0.4.0"]
|
|
17
17
|
}
|
|
18
18
|
```
|
|
19
19
|
|
|
@@ -21,13 +21,13 @@ When a new version is available, DCP will show a toast notification. Update by c
|
|
|
21
21
|
|
|
22
22
|
Restart OpenCode. The plugin will automatically start optimizing your sessions.
|
|
23
23
|
|
|
24
|
-
## Pruning
|
|
24
|
+
## How Pruning Works
|
|
25
25
|
|
|
26
|
-
DCP
|
|
26
|
+
DCP uses two complementary techniques:
|
|
27
27
|
|
|
28
|
-
**Deduplication** —
|
|
28
|
+
**Automatic Deduplication** — Silently identifies repeated tool calls (e.g., reading the same file multiple times) and keeps only the most recent output. Runs on every request with zero LLM cost.
|
|
29
29
|
|
|
30
|
-
**AI Analysis** — Uses a language model to semantically analyze conversation context and identify tool outputs that are no longer relevant to the current task. More thorough but incurs LLM cost.
|
|
30
|
+
**AI Analysis** — Uses a language model to semantically analyze conversation context and identify tool outputs that are no longer relevant to the current task. More thorough but incurs LLM cost. Configurable via `strategies`.
|
|
31
31
|
|
|
32
32
|
## Context Pruning Tool
|
|
33
33
|
|
|
@@ -61,17 +61,17 @@ DCP uses its own config file (`~/.config/opencode/dcp.jsonc` or `.opencode/dcp.j
|
|
|
61
61
|
| `pruning_summary` | `"detailed"` | `"off"`, `"minimal"`, or `"detailed"` |
|
|
62
62
|
| `nudge_freq` | `10` | How often to remind AI to prune (lower = more frequent) |
|
|
63
63
|
| `protectedTools` | `["task", "todowrite", "todoread", "prune"]` | Tools that are never pruned |
|
|
64
|
-
| `strategies.onIdle` | `["
|
|
65
|
-
| `strategies.onTool` | `["
|
|
64
|
+
| `strategies.onIdle` | `["ai-analysis"]` | Strategies for automatic pruning |
|
|
65
|
+
| `strategies.onTool` | `["ai-analysis"]` | Strategies when AI calls `prune` |
|
|
66
66
|
|
|
67
|
-
**Strategies:** `"
|
|
67
|
+
**Strategies:** `"ai-analysis"` uses LLM to identify prunable outputs. Empty array disables that trigger. Deduplication runs automatically on every request.
|
|
68
68
|
|
|
69
69
|
```jsonc
|
|
70
70
|
{
|
|
71
71
|
"enabled": true,
|
|
72
72
|
"strategies": {
|
|
73
|
-
"onIdle": ["
|
|
74
|
-
"onTool": ["
|
|
73
|
+
"onIdle": ["ai-analysis"],
|
|
74
|
+
"onTool": ["ai-analysis"]
|
|
75
75
|
},
|
|
76
76
|
"protectedTools": ["task", "todowrite", "todoread", "prune"]
|
|
77
77
|
}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAYjD,QAAA,MAAM,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAYjD,QAAA,MAAM,MAAM,EAAE,MA0FK,CAAA;AAEnB,eAAe,MAAM,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { getConfig } from "./lib/config";
|
|
2
2
|
import { Logger } from "./lib/logger";
|
|
3
|
-
import {
|
|
3
|
+
import { createJanitorContext } from "./lib/core/janitor";
|
|
4
4
|
import { checkForUpdates } from "./lib/version-checker";
|
|
5
5
|
import { createPluginState } from "./lib/state";
|
|
6
6
|
import { installFetchWrapper } from "./lib/fetch-wrapper";
|
|
7
7
|
import { createPruningTool } from "./lib/pruning-tool";
|
|
8
8
|
import { createEventHandler, createChatParamsHandler } from "./lib/hooks";
|
|
9
|
-
import { createToolTracker } from "./lib/synth-instruction";
|
|
10
|
-
import { loadPrompt } from "./lib/prompt";
|
|
9
|
+
import { createToolTracker } from "./lib/api-formats/synth-instruction";
|
|
10
|
+
import { loadPrompt } from "./lib/core/prompt";
|
|
11
11
|
const plugin = (async (ctx) => {
|
|
12
12
|
const { config, migrations } = getConfig(ctx);
|
|
13
13
|
if (!config.enabled) {
|
|
@@ -20,12 +20,19 @@ const plugin = (async (ctx) => {
|
|
|
20
20
|
// Initialize core components
|
|
21
21
|
const logger = new Logger(config.debug);
|
|
22
22
|
const state = createPluginState();
|
|
23
|
-
const
|
|
23
|
+
const janitorCtx = createJanitorContext(ctx.client, state, logger, {
|
|
24
|
+
protectedTools: config.protectedTools,
|
|
25
|
+
model: config.model,
|
|
26
|
+
showModelErrorToasts: config.showModelErrorToasts ?? true,
|
|
27
|
+
strictModelSelection: config.strictModelSelection ?? false,
|
|
28
|
+
pruningSummary: config.pruning_summary,
|
|
29
|
+
workingDirectory: ctx.directory
|
|
30
|
+
});
|
|
24
31
|
// Create tool tracker and load prompts for synthetic instruction injection
|
|
25
32
|
const toolTracker = createToolTracker();
|
|
26
33
|
// Wire up tool name lookup from the cached tool parameters
|
|
27
34
|
toolTracker.getToolName = (callId) => {
|
|
28
|
-
const entry = state.toolParameters.get(callId);
|
|
35
|
+
const entry = state.toolParameters.get(callId.toLowerCase());
|
|
29
36
|
return entry?.tool;
|
|
30
37
|
};
|
|
31
38
|
const prompts = {
|
|
@@ -41,7 +48,7 @@ const plugin = (async (ctx) => {
|
|
|
41
48
|
});
|
|
42
49
|
// Check for updates after a delay
|
|
43
50
|
setTimeout(() => {
|
|
44
|
-
checkForUpdates(ctx.client, logger).catch(() => { });
|
|
51
|
+
checkForUpdates(ctx.client, logger, config.showUpdateToasts ?? true).catch(() => { });
|
|
45
52
|
}, 5000);
|
|
46
53
|
// Show migration toast if there were config migrations
|
|
47
54
|
if (migrations.length > 0) {
|
|
@@ -62,10 +69,17 @@ const plugin = (async (ctx) => {
|
|
|
62
69
|
}, 7000);
|
|
63
70
|
}
|
|
64
71
|
return {
|
|
65
|
-
event: createEventHandler(ctx.client,
|
|
72
|
+
event: createEventHandler(ctx.client, janitorCtx, logger, config, toolTracker),
|
|
66
73
|
"chat.params": createChatParamsHandler(ctx.client, state, logger),
|
|
67
74
|
tool: config.strategies.onTool.length > 0 ? {
|
|
68
|
-
prune: createPruningTool(
|
|
75
|
+
prune: createPruningTool({
|
|
76
|
+
client: ctx.client,
|
|
77
|
+
state,
|
|
78
|
+
logger,
|
|
79
|
+
config,
|
|
80
|
+
notificationCtx: janitorCtx.notificationCtx,
|
|
81
|
+
workingDirectory: ctx.directory
|
|
82
|
+
}, toolTracker),
|
|
69
83
|
} : undefined,
|
|
70
84
|
};
|
|
71
85
|
});
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AACrC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prunable tools list and nudge injection for DCP.
|
|
3
|
+
*
|
|
4
|
+
* Builds and injects a single message at the end of the conversation containing:
|
|
5
|
+
* - Nudge instruction (when toolResultCount > nudge_freq)
|
|
6
|
+
* - Prunable tools list
|
|
7
|
+
*
|
|
8
|
+
* Note: The base synthetic instructions (signal_management, context_window_management,
|
|
9
|
+
* context_pruning) are still appended to the last user message separately via
|
|
10
|
+
* synth-instruction.ts - that behavior is unchanged.
|
|
11
|
+
*/
|
|
12
|
+
export interface ToolMetadata {
|
|
13
|
+
tool: string;
|
|
14
|
+
parameters?: any;
|
|
15
|
+
}
|
|
16
|
+
export interface PrunableListResult {
|
|
17
|
+
list: string;
|
|
18
|
+
numericIds: number[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Builds the prunable tools list section.
|
|
22
|
+
* Returns both the formatted list and the numeric IDs for logging.
|
|
23
|
+
*/
|
|
24
|
+
export declare function buildPrunableToolsList(sessionId: string, unprunedToolCallIds: string[], toolMetadata: Map<string, ToolMetadata>, protectedTools: string[]): PrunableListResult;
|
|
25
|
+
/**
|
|
26
|
+
* Builds the end-of-conversation injection message.
|
|
27
|
+
* Contains the system reminder, nudge (if active), and the prunable tools list.
|
|
28
|
+
*
|
|
29
|
+
* @param prunableList - The prunable tools list string (or empty string if none)
|
|
30
|
+
* @param includeNudge - Whether to include the nudge instruction
|
|
31
|
+
* @returns The injection string, or empty string if nothing to inject
|
|
32
|
+
*/
|
|
33
|
+
export declare function buildEndInjection(prunableList: string, includeNudge: boolean): string;
|
|
34
|
+
/**
|
|
35
|
+
* Injects the prunable list (and optionally nudge) at the end of OpenAI/Anthropic messages.
|
|
36
|
+
* Appends a new user message at the end.
|
|
37
|
+
*/
|
|
38
|
+
export declare function injectPrunableList(messages: any[], injection: string): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Injects the prunable list (and optionally nudge) at the end of Gemini contents.
|
|
41
|
+
* Appends a new user content at the end.
|
|
42
|
+
*/
|
|
43
|
+
export declare function injectPrunableListGemini(contents: any[], injection: string): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Injects the prunable list (and optionally nudge) at the end of OpenAI Responses API input.
|
|
46
|
+
* Appends a new user message at the end.
|
|
47
|
+
*/
|
|
48
|
+
export declare function injectPrunableListResponses(input: any[], injection: string): boolean;
|
|
49
|
+
//# sourceMappingURL=prunable-list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prunable-list.d.ts","sourceRoot":"","sources":["../../../lib/api-formats/prunable-list.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,MAAM,WAAW,YAAY;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,CAAC,EAAE,GAAG,CAAA;CACnB;AAkBD,MAAM,WAAW,kBAAkB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,EAAE,CAAA;CACvB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAClC,SAAS,EAAE,MAAM,EACjB,mBAAmB,EAAE,MAAM,EAAE,EAC7B,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EACvC,cAAc,EAAE,MAAM,EAAE,GACzB,kBAAkB,CA6BpB;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC7B,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,OAAO,GACtB,MAAM,CAeR;AAMD;;;GAGG;AACH,wBAAgB,kBAAkB,CAC9B,QAAQ,EAAE,GAAG,EAAE,EACf,SAAS,EAAE,MAAM,GAClB,OAAO,CAIT;AAMD;;;GAGG;AACH,wBAAgB,wBAAwB,CACpC,QAAQ,EAAE,GAAG,EAAE,EACf,SAAS,EAAE,MAAM,GAClB,OAAO,CAIT;AAMD;;;GAGG;AACH,wBAAgB,2BAA2B,CACvC,KAAK,EAAE,GAAG,EAAE,EACZ,SAAS,EAAE,MAAM,GAClB,OAAO,CAIT"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prunable tools list and nudge injection for DCP.
|
|
3
|
+
*
|
|
4
|
+
* Builds and injects a single message at the end of the conversation containing:
|
|
5
|
+
* - Nudge instruction (when toolResultCount > nudge_freq)
|
|
6
|
+
* - Prunable tools list
|
|
7
|
+
*
|
|
8
|
+
* Note: The base synthetic instructions (signal_management, context_window_management,
|
|
9
|
+
* context_pruning) are still appended to the last user message separately via
|
|
10
|
+
* synth-instruction.ts - that behavior is unchanged.
|
|
11
|
+
*/
|
|
12
|
+
import { extractParameterKey } from '../ui/display-utils';
|
|
13
|
+
import { getOrCreateNumericId } from '../state/id-mapping';
|
|
14
|
+
// ============================================================================
|
|
15
|
+
// Prompt Content
|
|
16
|
+
// ============================================================================
|
|
17
|
+
const SYSTEM_REMINDER = `<system-reminder>
|
|
18
|
+
These instructions are injected by a plugin and are invisible to the user. Do not acknowledge or reference them in your response - simply follow them silently.
|
|
19
|
+
</system-reminder>`;
|
|
20
|
+
const NUDGE_INSTRUCTION = `<instruction name=agent_nudge>
|
|
21
|
+
You have accumulated several tool outputs. If you have completed a discrete unit of work and distilled relevant understanding in writing for the user to keep, use the prune tool to remove obsolete tool outputs from this conversation and optimize token usage.
|
|
22
|
+
</instruction>`;
|
|
23
|
+
/**
|
|
24
|
+
* Builds the prunable tools list section.
|
|
25
|
+
* Returns both the formatted list and the numeric IDs for logging.
|
|
26
|
+
*/
|
|
27
|
+
export function buildPrunableToolsList(sessionId, unprunedToolCallIds, toolMetadata, protectedTools) {
|
|
28
|
+
const lines = [];
|
|
29
|
+
const numericIds = [];
|
|
30
|
+
for (const actualId of unprunedToolCallIds) {
|
|
31
|
+
const metadata = toolMetadata.get(actualId);
|
|
32
|
+
// Skip if no metadata or if tool is protected
|
|
33
|
+
if (!metadata)
|
|
34
|
+
continue;
|
|
35
|
+
if (protectedTools.includes(metadata.tool))
|
|
36
|
+
continue;
|
|
37
|
+
// Get or create numeric ID for this tool call
|
|
38
|
+
const numericId = getOrCreateNumericId(sessionId, actualId);
|
|
39
|
+
numericIds.push(numericId);
|
|
40
|
+
// Format: "1: read, src/components/Button.tsx"
|
|
41
|
+
const paramKey = extractParameterKey(metadata);
|
|
42
|
+
const description = paramKey ? `${metadata.tool}, ${paramKey}` : metadata.tool;
|
|
43
|
+
lines.push(`${numericId}: ${description}`);
|
|
44
|
+
}
|
|
45
|
+
if (lines.length === 0) {
|
|
46
|
+
return { list: '', numericIds: [] };
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
list: `<prunable-tools>\n${lines.join('\n')}\n</prunable-tools>`,
|
|
50
|
+
numericIds
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Builds the end-of-conversation injection message.
|
|
55
|
+
* Contains the system reminder, nudge (if active), and the prunable tools list.
|
|
56
|
+
*
|
|
57
|
+
* @param prunableList - The prunable tools list string (or empty string if none)
|
|
58
|
+
* @param includeNudge - Whether to include the nudge instruction
|
|
59
|
+
* @returns The injection string, or empty string if nothing to inject
|
|
60
|
+
*/
|
|
61
|
+
export function buildEndInjection(prunableList, includeNudge) {
|
|
62
|
+
// If no prunable tools, don't inject anything
|
|
63
|
+
if (!prunableList) {
|
|
64
|
+
return '';
|
|
65
|
+
}
|
|
66
|
+
const parts = [SYSTEM_REMINDER];
|
|
67
|
+
if (includeNudge) {
|
|
68
|
+
parts.push(NUDGE_INSTRUCTION);
|
|
69
|
+
}
|
|
70
|
+
parts.push(prunableList);
|
|
71
|
+
return parts.join('\n\n');
|
|
72
|
+
}
|
|
73
|
+
// ============================================================================
|
|
74
|
+
// OpenAI Chat / Anthropic Format
|
|
75
|
+
// ============================================================================
|
|
76
|
+
/**
|
|
77
|
+
* Injects the prunable list (and optionally nudge) at the end of OpenAI/Anthropic messages.
|
|
78
|
+
* Appends a new user message at the end.
|
|
79
|
+
*/
|
|
80
|
+
export function injectPrunableList(messages, injection) {
|
|
81
|
+
if (!injection)
|
|
82
|
+
return false;
|
|
83
|
+
messages.push({ role: 'user', content: injection });
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
// ============================================================================
|
|
87
|
+
// Google/Gemini Format
|
|
88
|
+
// ============================================================================
|
|
89
|
+
/**
|
|
90
|
+
* Injects the prunable list (and optionally nudge) at the end of Gemini contents.
|
|
91
|
+
* Appends a new user content at the end.
|
|
92
|
+
*/
|
|
93
|
+
export function injectPrunableListGemini(contents, injection) {
|
|
94
|
+
if (!injection)
|
|
95
|
+
return false;
|
|
96
|
+
contents.push({ role: 'user', parts: [{ text: injection }] });
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
// ============================================================================
|
|
100
|
+
// OpenAI Responses API Format
|
|
101
|
+
// ============================================================================
|
|
102
|
+
/**
|
|
103
|
+
* Injects the prunable list (and optionally nudge) at the end of OpenAI Responses API input.
|
|
104
|
+
* Appends a new user message at the end.
|
|
105
|
+
*/
|
|
106
|
+
export function injectPrunableListResponses(input, injection) {
|
|
107
|
+
if (!injection)
|
|
108
|
+
return false;
|
|
109
|
+
input.push({ type: 'message', role: 'user', content: injection });
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=prunable-list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prunable-list.js","sourceRoot":"","sources":["../../../lib/api-formats/prunable-list.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface ToolTracker {
|
|
2
|
+
seenToolResultIds: Set<string>;
|
|
3
|
+
toolResultCount: number;
|
|
4
|
+
skipNextIdle: boolean;
|
|
5
|
+
getToolName?: (callId: string) => string | undefined;
|
|
6
|
+
}
|
|
7
|
+
export declare function createToolTracker(): ToolTracker;
|
|
8
|
+
export declare function resetToolTrackerCount(tracker: ToolTracker): void;
|
|
9
|
+
/**
|
|
10
|
+
* Track new tool results in OpenAI/Anthropic messages.
|
|
11
|
+
* Increments toolResultCount only for tools not already seen and not protected.
|
|
12
|
+
* Returns the number of NEW tools found (since last call).
|
|
13
|
+
*/
|
|
14
|
+
export declare function trackNewToolResults(messages: any[], tracker: ToolTracker, protectedTools: Set<string>): number;
|
|
15
|
+
/**
|
|
16
|
+
* Track new tool results in Gemini contents.
|
|
17
|
+
* Uses position-based tracking since Gemini doesn't have tool call IDs.
|
|
18
|
+
* Returns the number of NEW tools found (since last call).
|
|
19
|
+
*/
|
|
20
|
+
export declare function trackNewToolResultsGemini(contents: any[], tracker: ToolTracker, protectedTools: Set<string>): number;
|
|
21
|
+
/**
|
|
22
|
+
* Track new tool results in OpenAI Responses API input.
|
|
23
|
+
* Returns the number of NEW tools found (since last call).
|
|
24
|
+
*/
|
|
25
|
+
export declare function trackNewToolResultsResponses(input: any[], tracker: ToolTracker, protectedTools: Set<string>): number;
|
|
26
|
+
export declare function injectSynth(messages: any[], instruction: string, nudgeText: string): boolean;
|
|
27
|
+
export declare function injectSynthGemini(contents: any[], instruction: string, nudgeText: string): boolean;
|
|
28
|
+
export declare function injectSynthResponses(input: any[], instruction: string, nudgeText: string): boolean;
|
|
29
|
+
//# sourceMappingURL=synth-instruction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"synth-instruction.d.ts","sourceRoot":"","sources":["../../../lib/api-formats/synth-instruction.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IACxB,iBAAiB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC9B,eAAe,EAAE,MAAM,CAAA;IACvB,YAAY,EAAE,OAAO,CAAA;IACrB,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAA;CACvD;AAED,wBAAgB,iBAAiB,IAAI,WAAW,CAE/C;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAEhE;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,CA4B9G;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,CAqBpH;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,CAepH;AASD,wBAAgB,WAAW,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAqB5F;AAUD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAgBlG;AASD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAqBlG"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
export function createToolTracker() {
|
|
2
|
+
return { seenToolResultIds: new Set(), toolResultCount: 0, skipNextIdle: false };
|
|
3
|
+
}
|
|
4
|
+
export function resetToolTrackerCount(tracker) {
|
|
5
|
+
tracker.toolResultCount = 0;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Track new tool results in OpenAI/Anthropic messages.
|
|
9
|
+
* Increments toolResultCount only for tools not already seen and not protected.
|
|
10
|
+
* Returns the number of NEW tools found (since last call).
|
|
11
|
+
*/
|
|
12
|
+
export function trackNewToolResults(messages, tracker, protectedTools) {
|
|
13
|
+
let newCount = 0;
|
|
14
|
+
for (const m of messages) {
|
|
15
|
+
if (m.role === 'tool' && m.tool_call_id) {
|
|
16
|
+
if (!tracker.seenToolResultIds.has(m.tool_call_id)) {
|
|
17
|
+
tracker.seenToolResultIds.add(m.tool_call_id);
|
|
18
|
+
const toolName = tracker.getToolName?.(m.tool_call_id);
|
|
19
|
+
if (!toolName || !protectedTools.has(toolName)) {
|
|
20
|
+
tracker.toolResultCount++;
|
|
21
|
+
newCount++;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
else if (m.role === 'user' && Array.isArray(m.content)) {
|
|
26
|
+
for (const part of m.content) {
|
|
27
|
+
if (part.type === 'tool_result' && part.tool_use_id) {
|
|
28
|
+
if (!tracker.seenToolResultIds.has(part.tool_use_id)) {
|
|
29
|
+
tracker.seenToolResultIds.add(part.tool_use_id);
|
|
30
|
+
const toolName = tracker.getToolName?.(part.tool_use_id);
|
|
31
|
+
if (!toolName || !protectedTools.has(toolName)) {
|
|
32
|
+
tracker.toolResultCount++;
|
|
33
|
+
newCount++;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return newCount;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Track new tool results in Gemini contents.
|
|
44
|
+
* Uses position-based tracking since Gemini doesn't have tool call IDs.
|
|
45
|
+
* Returns the number of NEW tools found (since last call).
|
|
46
|
+
*/
|
|
47
|
+
export function trackNewToolResultsGemini(contents, tracker, protectedTools) {
|
|
48
|
+
let newCount = 0;
|
|
49
|
+
let positionCounter = 0;
|
|
50
|
+
for (const content of contents) {
|
|
51
|
+
if (!Array.isArray(content.parts))
|
|
52
|
+
continue;
|
|
53
|
+
for (const part of content.parts) {
|
|
54
|
+
if (part.functionResponse) {
|
|
55
|
+
const positionId = `gemini_pos_${positionCounter}`;
|
|
56
|
+
positionCounter++;
|
|
57
|
+
if (!tracker.seenToolResultIds.has(positionId)) {
|
|
58
|
+
tracker.seenToolResultIds.add(positionId);
|
|
59
|
+
const toolName = part.functionResponse.name;
|
|
60
|
+
if (!toolName || !protectedTools.has(toolName)) {
|
|
61
|
+
tracker.toolResultCount++;
|
|
62
|
+
newCount++;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return newCount;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Track new tool results in OpenAI Responses API input.
|
|
72
|
+
* Returns the number of NEW tools found (since last call).
|
|
73
|
+
*/
|
|
74
|
+
export function trackNewToolResultsResponses(input, tracker, protectedTools) {
|
|
75
|
+
let newCount = 0;
|
|
76
|
+
for (const item of input) {
|
|
77
|
+
if (item.type === 'function_call_output' && item.call_id) {
|
|
78
|
+
if (!tracker.seenToolResultIds.has(item.call_id)) {
|
|
79
|
+
tracker.seenToolResultIds.add(item.call_id);
|
|
80
|
+
const toolName = tracker.getToolName?.(item.call_id);
|
|
81
|
+
if (!toolName || !protectedTools.has(toolName)) {
|
|
82
|
+
tracker.toolResultCount++;
|
|
83
|
+
newCount++;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return newCount;
|
|
89
|
+
}
|
|
90
|
+
function isNudgeMessage(msg, nudgeText) {
|
|
91
|
+
if (typeof msg.content === 'string') {
|
|
92
|
+
return msg.content === nudgeText;
|
|
93
|
+
}
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
export function injectSynth(messages, instruction, nudgeText) {
|
|
97
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
98
|
+
const msg = messages[i];
|
|
99
|
+
if (msg.role === 'user') {
|
|
100
|
+
// Skip nudge messages - find real user message
|
|
101
|
+
if (isNudgeMessage(msg, nudgeText))
|
|
102
|
+
continue;
|
|
103
|
+
if (typeof msg.content === 'string') {
|
|
104
|
+
if (msg.content.includes(instruction))
|
|
105
|
+
return false;
|
|
106
|
+
msg.content = msg.content + '\n\n' + instruction;
|
|
107
|
+
}
|
|
108
|
+
else if (Array.isArray(msg.content)) {
|
|
109
|
+
const alreadyInjected = msg.content.some((part) => part?.type === 'text' && typeof part.text === 'string' && part.text.includes(instruction));
|
|
110
|
+
if (alreadyInjected)
|
|
111
|
+
return false;
|
|
112
|
+
msg.content.push({ type: 'text', text: instruction });
|
|
113
|
+
}
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
function isNudgeContentGemini(content, nudgeText) {
|
|
120
|
+
if (Array.isArray(content.parts) && content.parts.length === 1) {
|
|
121
|
+
const part = content.parts[0];
|
|
122
|
+
return part?.text === nudgeText;
|
|
123
|
+
}
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
export function injectSynthGemini(contents, instruction, nudgeText) {
|
|
127
|
+
for (let i = contents.length - 1; i >= 0; i--) {
|
|
128
|
+
const content = contents[i];
|
|
129
|
+
if (content.role === 'user' && Array.isArray(content.parts)) {
|
|
130
|
+
// Skip nudge messages - find real user message
|
|
131
|
+
if (isNudgeContentGemini(content, nudgeText))
|
|
132
|
+
continue;
|
|
133
|
+
const alreadyInjected = content.parts.some((part) => part?.text && typeof part.text === 'string' && part.text.includes(instruction));
|
|
134
|
+
if (alreadyInjected)
|
|
135
|
+
return false;
|
|
136
|
+
content.parts.push({ text: instruction });
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
function isNudgeItemResponses(item, nudgeText) {
|
|
143
|
+
if (typeof item.content === 'string') {
|
|
144
|
+
return item.content === nudgeText;
|
|
145
|
+
}
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
export function injectSynthResponses(input, instruction, nudgeText) {
|
|
149
|
+
for (let i = input.length - 1; i >= 0; i--) {
|
|
150
|
+
const item = input[i];
|
|
151
|
+
if (item.type === 'message' && item.role === 'user') {
|
|
152
|
+
// Skip nudge messages - find real user message
|
|
153
|
+
if (isNudgeItemResponses(item, nudgeText))
|
|
154
|
+
continue;
|
|
155
|
+
if (typeof item.content === 'string') {
|
|
156
|
+
if (item.content.includes(instruction))
|
|
157
|
+
return false;
|
|
158
|
+
item.content = item.content + '\n\n' + instruction;
|
|
159
|
+
}
|
|
160
|
+
else if (Array.isArray(item.content)) {
|
|
161
|
+
const alreadyInjected = item.content.some((part) => part?.type === 'input_text' && typeof part.text === 'string' && part.text.includes(instruction));
|
|
162
|
+
if (alreadyInjected)
|
|
163
|
+
return false;
|
|
164
|
+
item.content.push({ type: 'input_text', text: instruction });
|
|
165
|
+
}
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=synth-instruction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"synth-instruction.js","sourceRoot":"","sources":["../../../lib/api-formats/synth-instruction.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/config.d.ts
CHANGED
package/dist/lib/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../lib/config.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAEtD,MAAM,MAAM,eAAe,GAAG,eAAe,GAAG,aAAa,CAAA;AAE7D,MAAM,WAAW,YAAY;IACzB,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE,OAAO,CAAA;IACd,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,eAAe,EAAE,KAAK,GAAG,SAAS,GAAG,UAAU,CAAA;IAC/C,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE;QACR,MAAM,EAAE,eAAe,EAAE,CAAA;QACzB,MAAM,EAAE,eAAe,EAAE,CAAA;KAC5B,CAAA;CACJ;AAED,MAAM,WAAW,YAAY;IACzB,MAAM,EAAE,YAAY,CAAA;IACpB,UAAU,EAAE,MAAM,EAAE,CAAA;CACvB;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../lib/config.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAEtD,MAAM,MAAM,eAAe,GAAG,eAAe,GAAG,aAAa,CAAA;AAE7D,MAAM,WAAW,YAAY;IACzB,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE,OAAO,CAAA;IACd,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,eAAe,EAAE,KAAK,GAAG,SAAS,GAAG,UAAU,CAAA;IAC/C,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE;QACR,MAAM,EAAE,eAAe,EAAE,CAAA;QACzB,MAAM,EAAE,eAAe,EAAE,CAAA;KAC5B,CAAA;CACJ;AAED,MAAM,WAAW,YAAY;IACzB,MAAM,EAAE,YAAY,CAAA;IACpB,UAAU,EAAE,MAAM,EAAE,CAAA;CACvB;AA0JD,wBAAgB,SAAS,CAAC,GAAG,CAAC,EAAE,WAAW,GAAG,YAAY,CAsEzD"}
|
package/dist/lib/config.js
CHANGED
|
@@ -6,14 +6,15 @@ import { Logger } from './logger';
|
|
|
6
6
|
const defaultConfig = {
|
|
7
7
|
enabled: true,
|
|
8
8
|
debug: false,
|
|
9
|
-
protectedTools: ['task', 'todowrite', 'todoread', 'prune'],
|
|
9
|
+
protectedTools: ['task', 'todowrite', 'todoread', 'prune', 'batch'],
|
|
10
10
|
showModelErrorToasts: true,
|
|
11
|
+
showUpdateToasts: true,
|
|
11
12
|
strictModelSelection: false,
|
|
12
13
|
pruning_summary: 'detailed',
|
|
13
14
|
nudge_freq: 10,
|
|
14
15
|
strategies: {
|
|
15
|
-
onIdle: ['
|
|
16
|
-
onTool: ['
|
|
16
|
+
onIdle: ['ai-analysis'],
|
|
17
|
+
onTool: ['ai-analysis']
|
|
17
18
|
}
|
|
18
19
|
};
|
|
19
20
|
const VALID_CONFIG_KEYS = new Set([
|
|
@@ -22,6 +23,7 @@ const VALID_CONFIG_KEYS = new Set([
|
|
|
22
23
|
'protectedTools',
|
|
23
24
|
'model',
|
|
24
25
|
'showModelErrorToasts',
|
|
26
|
+
'showUpdateToasts',
|
|
25
27
|
'strictModelSelection',
|
|
26
28
|
'pruning_summary',
|
|
27
29
|
'nudge_freq',
|
|
@@ -81,20 +83,22 @@ function createDefaultConfig() {
|
|
|
81
83
|
// "model": "anthropic/claude-haiku-4-5",
|
|
82
84
|
// Show toast notifications when model selection fails
|
|
83
85
|
"showModelErrorToasts": true,
|
|
86
|
+
// Show toast notifications when a new version is available
|
|
87
|
+
"showUpdateToasts": true,
|
|
84
88
|
// Only run AI analysis with session model or configured model (disables fallback models)
|
|
85
89
|
"strictModelSelection": false,
|
|
86
|
-
//
|
|
90
|
+
// AI analysis strategies (deduplication runs automatically on every request)
|
|
87
91
|
"strategies": {
|
|
88
92
|
// Strategies to run when session goes idle
|
|
89
|
-
"onIdle": ["
|
|
93
|
+
"onIdle": ["ai-analysis"],
|
|
90
94
|
// Strategies to run when AI calls prune tool
|
|
91
|
-
"onTool": ["
|
|
95
|
+
"onTool": ["ai-analysis"]
|
|
92
96
|
},
|
|
93
97
|
// Summary display: "off", "minimal", or "detailed"
|
|
94
98
|
"pruning_summary": "detailed",
|
|
95
99
|
// How often to nudge the AI to prune (every N tool results, 0 = disabled)
|
|
96
100
|
"nudge_freq": 10
|
|
97
|
-
// Additional tools to protect from pruning (merged with built-in: task, todowrite, todoread, prune)
|
|
101
|
+
// Additional tools to protect from pruning (merged with built-in: task, todowrite, todoread, prune, batch)
|
|
98
102
|
// "protectedTools": ["bash"]
|
|
99
103
|
}
|
|
100
104
|
`;
|
|
@@ -163,6 +167,7 @@ export function getConfig(ctx) {
|
|
|
163
167
|
protectedTools: [...new Set([...config.protectedTools, ...(globalConfig.protectedTools ?? [])])],
|
|
164
168
|
model: globalConfig.model ?? config.model,
|
|
165
169
|
showModelErrorToasts: globalConfig.showModelErrorToasts ?? config.showModelErrorToasts,
|
|
170
|
+
showUpdateToasts: globalConfig.showUpdateToasts ?? config.showUpdateToasts,
|
|
166
171
|
strictModelSelection: globalConfig.strictModelSelection ?? config.strictModelSelection,
|
|
167
172
|
strategies: mergeStrategies(config.strategies, globalConfig.strategies),
|
|
168
173
|
pruning_summary: globalConfig.pruning_summary ?? config.pruning_summary,
|
|
@@ -194,6 +199,7 @@ export function getConfig(ctx) {
|
|
|
194
199
|
protectedTools: [...new Set([...config.protectedTools, ...(projectConfig.protectedTools ?? [])])],
|
|
195
200
|
model: projectConfig.model ?? config.model,
|
|
196
201
|
showModelErrorToasts: projectConfig.showModelErrorToasts ?? config.showModelErrorToasts,
|
|
202
|
+
showUpdateToasts: projectConfig.showUpdateToasts ?? config.showUpdateToasts,
|
|
197
203
|
strictModelSelection: projectConfig.strictModelSelection ?? config.strictModelSelection,
|
|
198
204
|
strategies: mergeStrategies(config.strategies, projectConfig.strategies),
|
|
199
205
|
pruning_summary: projectConfig.pruning_summary ?? config.pruning_summary,
|