@tarquinen/opencode-dcp 0.4.1 → 0.4.12
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 +13 -20
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -15
- package/dist/index.js.map +1 -1
- package/dist/lib/config.js +2 -2
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/core/janitor.d.ts +3 -25
- package/dist/lib/core/janitor.d.ts.map +1 -1
- package/dist/lib/core/janitor.js +2 -11
- package/dist/lib/core/janitor.js.map +1 -1
- package/dist/lib/core/strategies/deduplication.d.ts +1 -1
- package/dist/lib/core/strategies/index.d.ts +32 -2
- package/dist/lib/core/strategies/index.d.ts.map +1 -1
- package/dist/lib/core/strategies/index.js.map +1 -1
- package/dist/lib/fetch-wrapper/formats/anthropic.d.ts +8 -0
- package/dist/lib/fetch-wrapper/formats/anthropic.d.ts.map +1 -0
- package/dist/lib/fetch-wrapper/formats/anthropic.js +122 -0
- package/dist/lib/fetch-wrapper/formats/anthropic.js.map +1 -0
- package/dist/lib/fetch-wrapper/formats/bedrock.d.ts +3 -9
- package/dist/lib/fetch-wrapper/formats/bedrock.d.ts.map +1 -1
- package/dist/lib/fetch-wrapper/formats/bedrock.js +25 -45
- package/dist/lib/fetch-wrapper/formats/bedrock.js.map +1 -1
- package/dist/lib/fetch-wrapper/formats/gemini.d.ts +1 -7
- package/dist/lib/fetch-wrapper/formats/gemini.d.ts.map +1 -1
- package/dist/lib/fetch-wrapper/formats/gemini.js +30 -23
- package/dist/lib/fetch-wrapper/formats/gemini.js.map +1 -1
- package/dist/lib/fetch-wrapper/formats/index.d.ts +1 -0
- package/dist/lib/fetch-wrapper/formats/index.d.ts.map +1 -1
- package/dist/lib/fetch-wrapper/formats/index.js +1 -0
- package/dist/lib/fetch-wrapper/formats/index.js.map +1 -1
- package/dist/lib/fetch-wrapper/formats/openai-chat.d.ts +0 -11
- package/dist/lib/fetch-wrapper/formats/openai-chat.d.ts.map +1 -1
- package/dist/lib/fetch-wrapper/formats/openai-chat.js +33 -25
- package/dist/lib/fetch-wrapper/formats/openai-chat.js.map +1 -1
- package/dist/lib/fetch-wrapper/formats/openai-responses.d.ts +0 -8
- package/dist/lib/fetch-wrapper/formats/openai-responses.d.ts.map +1 -1
- package/dist/lib/fetch-wrapper/formats/openai-responses.js +29 -21
- package/dist/lib/fetch-wrapper/formats/openai-responses.js.map +1 -1
- package/dist/lib/fetch-wrapper/handler.d.ts +0 -10
- package/dist/lib/fetch-wrapper/handler.d.ts.map +1 -1
- package/dist/lib/fetch-wrapper/handler.js +74 -41
- package/dist/lib/fetch-wrapper/handler.js.map +1 -1
- package/dist/lib/fetch-wrapper/index.d.ts +4 -5
- package/dist/lib/fetch-wrapper/index.d.ts.map +1 -1
- package/dist/lib/fetch-wrapper/index.js +16 -7
- package/dist/lib/fetch-wrapper/index.js.map +1 -1
- package/dist/lib/fetch-wrapper/prunable-list.d.ts +8 -0
- package/dist/lib/fetch-wrapper/prunable-list.d.ts.map +1 -0
- package/dist/lib/fetch-wrapper/prunable-list.js +38 -0
- package/dist/lib/fetch-wrapper/prunable-list.js.map +1 -0
- package/dist/lib/fetch-wrapper/tool-tracker.d.ts +8 -0
- package/dist/lib/fetch-wrapper/tool-tracker.d.ts.map +1 -0
- package/dist/lib/fetch-wrapper/tool-tracker.js +7 -0
- package/dist/lib/fetch-wrapper/tool-tracker.js.map +1 -0
- package/dist/lib/fetch-wrapper/types.d.ts +31 -46
- package/dist/lib/fetch-wrapper/types.d.ts.map +1 -1
- package/dist/lib/fetch-wrapper/types.js +6 -44
- package/dist/lib/fetch-wrapper/types.js.map +1 -1
- package/dist/lib/hooks.d.ts +6 -2
- package/dist/lib/hooks.d.ts.map +1 -1
- package/dist/lib/hooks.js +21 -11
- package/dist/lib/hooks.js.map +1 -1
- package/dist/lib/prompts/nudge.txt +8 -5
- package/dist/lib/prompts/synthetic.txt +18 -30
- package/dist/lib/prompts/tool.txt +46 -63
- package/dist/lib/pruning-tool.d.ts +1 -1
- package/dist/lib/pruning-tool.d.ts.map +1 -1
- package/dist/lib/pruning-tool.js +41 -18
- package/dist/lib/pruning-tool.js.map +1 -1
- package/dist/lib/state/id-mapping.d.ts +0 -1
- package/dist/lib/state/id-mapping.d.ts.map +1 -1
- package/dist/lib/state/id-mapping.js +0 -3
- package/dist/lib/state/id-mapping.js.map +1 -1
- package/dist/lib/state/index.d.ts +3 -0
- package/dist/lib/state/index.d.ts.map +1 -1
- package/dist/lib/state/index.js.map +1 -1
- package/dist/lib/state/tool-cache.d.ts +5 -12
- package/dist/lib/state/tool-cache.d.ts.map +1 -1
- package/dist/lib/state/tool-cache.js +47 -72
- package/dist/lib/state/tool-cache.js.map +1 -1
- package/dist/lib/ui/display-utils.d.ts +12 -0
- package/dist/lib/ui/display-utils.d.ts.map +1 -1
- package/dist/lib/ui/display-utils.js +66 -0
- package/dist/lib/ui/display-utils.js.map +1 -1
- package/dist/lib/ui/notification.d.ts +5 -12
- package/dist/lib/ui/notification.d.ts.map +1 -1
- package/dist/lib/ui/notification.js +32 -141
- package/dist/lib/ui/notification.js.map +1 -1
- package/package.json +1 -1
- package/dist/lib/api-formats/prunable-list.d.ts +0 -49
- package/dist/lib/api-formats/prunable-list.d.ts.map +0 -1
- package/dist/lib/api-formats/prunable-list.js +0 -112
- package/dist/lib/api-formats/prunable-list.js.map +0 -1
- package/dist/lib/api-formats/synth-instruction.d.ts +0 -29
- package/dist/lib/api-formats/synth-instruction.d.ts.map +0 -1
- package/dist/lib/api-formats/synth-instruction.js +0 -171
- package/dist/lib/api-formats/synth-instruction.js.map +0 -1
- package/dist/lib/core/strategies/types.d.ts +0 -35
- package/dist/lib/core/strategies/types.d.ts.map +0 -1
- package/dist/lib/core/strategies/types.js +0 -6
- package/dist/lib/core/strategies/types.js.map +0 -1
|
@@ -1,90 +1,65 @@
|
|
|
1
|
+
/** Maximum number of entries to keep in the tool parameters cache */
|
|
2
|
+
const MAX_TOOL_CACHE_SIZE = 500;
|
|
1
3
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* Supports:
|
|
6
|
-
* - OpenAI format: message.tool_calls[] with id, function.name, function.arguments
|
|
7
|
-
* - Anthropic format: message.content[] with type='tool_use', id, name, input
|
|
4
|
+
* Sync tool parameters from OpenCode's session.messages() API.
|
|
5
|
+
* This is the single source of truth for tool parameters, replacing
|
|
6
|
+
* format-specific parsing from LLM API requests.
|
|
8
7
|
*/
|
|
9
|
-
export function
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
export async function syncToolCache(client, sessionId, state, tracker, protectedTools, logger) {
|
|
9
|
+
try {
|
|
10
|
+
const messagesResponse = await client.session.messages({
|
|
11
|
+
path: { id: sessionId },
|
|
12
|
+
query: { limit: 500 }
|
|
13
|
+
});
|
|
14
|
+
const messages = messagesResponse.data || messagesResponse;
|
|
15
|
+
if (!Array.isArray(messages)) {
|
|
16
|
+
return;
|
|
15
17
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
let synced = 0;
|
|
19
|
+
for (const msg of messages) {
|
|
20
|
+
if (!msg.parts)
|
|
21
|
+
continue;
|
|
22
|
+
for (const part of msg.parts) {
|
|
23
|
+
if (part.type !== "tool" || !part.callID)
|
|
19
24
|
continue;
|
|
25
|
+
const id = part.callID.toLowerCase();
|
|
26
|
+
// Track tool results for nudge injection
|
|
27
|
+
if (tracker && !tracker.seenToolResultIds.has(id)) {
|
|
28
|
+
tracker.seenToolResultIds.add(id);
|
|
29
|
+
// Only count non-protected tools toward nudge threshold
|
|
30
|
+
if (!part.tool || !protectedTools?.has(part.tool)) {
|
|
31
|
+
tracker.toolResultCount++;
|
|
32
|
+
}
|
|
20
33
|
}
|
|
21
|
-
|
|
22
|
-
const params = typeof toolCall.function.arguments === 'string'
|
|
23
|
-
? JSON.parse(toolCall.function.arguments)
|
|
24
|
-
: toolCall.function.arguments;
|
|
25
|
-
state.toolParameters.set(toolCall.id.toLowerCase(), {
|
|
26
|
-
tool: toolCall.function.name,
|
|
27
|
-
parameters: params
|
|
28
|
-
});
|
|
29
|
-
openaiCached++;
|
|
30
|
-
}
|
|
31
|
-
catch (error) {
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
if (Array.isArray(message.content)) {
|
|
36
|
-
for (const part of message.content) {
|
|
37
|
-
if (part.type !== 'tool_use' || !part.id || !part.name) {
|
|
34
|
+
if (state.toolParameters.has(id))
|
|
38
35
|
continue;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
36
|
+
if (part.tool && protectedTools?.has(part.tool))
|
|
37
|
+
continue;
|
|
38
|
+
const status = part.state?.status;
|
|
39
|
+
state.toolParameters.set(id, {
|
|
40
|
+
tool: part.tool,
|
|
41
|
+
parameters: part.state?.input ?? {},
|
|
42
|
+
status,
|
|
43
|
+
error: status === "error" ? part.state?.error : undefined,
|
|
43
44
|
});
|
|
44
|
-
|
|
45
|
+
synced++;
|
|
45
46
|
}
|
|
46
47
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
totalCached: state.toolParameters.size
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Cache tool parameters from OpenAI Responses API format.
|
|
58
|
-
* Extracts from input array items with type='function_call'.
|
|
59
|
-
*/
|
|
60
|
-
export function cacheToolParametersFromInput(input, state, logger) {
|
|
61
|
-
let cached = 0;
|
|
62
|
-
for (const item of input) {
|
|
63
|
-
if (item.type !== 'function_call' || !item.call_id || !item.name) {
|
|
64
|
-
continue;
|
|
65
|
-
}
|
|
66
|
-
try {
|
|
67
|
-
const params = typeof item.arguments === 'string'
|
|
68
|
-
? JSON.parse(item.arguments)
|
|
69
|
-
: item.arguments;
|
|
70
|
-
state.toolParameters.set(item.call_id.toLowerCase(), {
|
|
71
|
-
tool: item.name,
|
|
72
|
-
parameters: params
|
|
48
|
+
trimToolParametersCache(state);
|
|
49
|
+
if (logger && synced > 0) {
|
|
50
|
+
logger.debug("tool-cache", "Synced tool parameters from OpenCode", {
|
|
51
|
+
sessionId: sessionId.slice(0, 8),
|
|
52
|
+
synced
|
|
73
53
|
});
|
|
74
|
-
cached++;
|
|
75
|
-
}
|
|
76
|
-
catch (error) {
|
|
77
54
|
}
|
|
78
55
|
}
|
|
79
|
-
|
|
80
|
-
logger
|
|
81
|
-
|
|
82
|
-
|
|
56
|
+
catch (error) {
|
|
57
|
+
logger?.warn("tool-cache", "Failed to sync tool parameters from OpenCode", {
|
|
58
|
+
sessionId: sessionId.slice(0, 8),
|
|
59
|
+
error: error instanceof Error ? error.message : String(error)
|
|
83
60
|
});
|
|
84
61
|
}
|
|
85
62
|
}
|
|
86
|
-
/** Maximum number of entries to keep in the tool parameters cache */
|
|
87
|
-
const MAX_TOOL_CACHE_SIZE = 500;
|
|
88
63
|
/**
|
|
89
64
|
* Trim the tool parameters cache to prevent unbounded memory growth.
|
|
90
65
|
* Uses FIFO eviction - removes oldest entries first.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-cache.js","sourceRoot":"","sources":["../../../lib/state/tool-cache.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tool-cache.js","sourceRoot":"","sources":["../../../lib/state/tool-cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { ToolMetadata } from "../fetch-wrapper/types";
|
|
2
|
+
import type { PruningResult } from "../core/janitor";
|
|
1
3
|
/**
|
|
2
4
|
* Extracts a human-readable key from tool metadata for display purposes.
|
|
3
5
|
* Used by both deduplication and AI analysis to show what was pruned.
|
|
@@ -6,4 +8,14 @@ export declare function extractParameterKey(metadata: {
|
|
|
6
8
|
tool: string;
|
|
7
9
|
parameters?: any;
|
|
8
10
|
}): string;
|
|
11
|
+
export declare function truncate(str: string, maxLen?: number): string;
|
|
12
|
+
export declare function shortenPath(input: string, workingDirectory?: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Formats a list of pruned items in the style: "→ tool: parameter"
|
|
15
|
+
*/
|
|
16
|
+
export declare function formatPrunedItemsList(prunedIds: string[], toolMetadata: Map<string, ToolMetadata>, workingDirectory?: string): string[];
|
|
17
|
+
/**
|
|
18
|
+
* Formats a PruningResult into a human-readable string for the prune tool output.
|
|
19
|
+
*/
|
|
20
|
+
export declare function formatPruningResultForTool(result: PruningResult, workingDirectory?: string): string;
|
|
9
21
|
//# sourceMappingURL=display-utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"display-utils.d.ts","sourceRoot":"","sources":["../../../lib/ui/display-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,GAAG,CAAA;CAAE,GAAG,MAAM,CAoExF"}
|
|
1
|
+
{"version":3,"file":"display-utils.d.ts","sourceRoot":"","sources":["../../../lib/ui/display-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAEpD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,GAAG,CAAA;CAAE,GAAG,MAAM,CAoExF;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,MAAW,GAAG,MAAM,CAGjE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,CAU5E;AAeD;;GAEG;AACH,wBAAgB,qBAAqB,CACjC,SAAS,EAAE,MAAM,EAAE,EACnB,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EACvC,gBAAgB,CAAC,EAAE,MAAM,GAC1B,MAAM,EAAE,CA6BV;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACtC,MAAM,EAAE,aAAa,EACrB,gBAAgB,CAAC,EAAE,MAAM,GAC1B,MAAM,CAWR"}
|
|
@@ -65,4 +65,70 @@ export function extractParameterKey(metadata) {
|
|
|
65
65
|
}
|
|
66
66
|
return paramStr.substring(0, 50);
|
|
67
67
|
}
|
|
68
|
+
export function truncate(str, maxLen = 60) {
|
|
69
|
+
if (str.length <= maxLen)
|
|
70
|
+
return str;
|
|
71
|
+
return str.slice(0, maxLen - 3) + '...';
|
|
72
|
+
}
|
|
73
|
+
export function shortenPath(input, workingDirectory) {
|
|
74
|
+
const inPathMatch = input.match(/^(.+) in (.+)$/);
|
|
75
|
+
if (inPathMatch) {
|
|
76
|
+
const prefix = inPathMatch[1];
|
|
77
|
+
const pathPart = inPathMatch[2];
|
|
78
|
+
const shortenedPath = shortenSinglePath(pathPart, workingDirectory);
|
|
79
|
+
return `${prefix} in ${shortenedPath}`;
|
|
80
|
+
}
|
|
81
|
+
return shortenSinglePath(input, workingDirectory);
|
|
82
|
+
}
|
|
83
|
+
function shortenSinglePath(path, workingDirectory) {
|
|
84
|
+
if (workingDirectory) {
|
|
85
|
+
if (path.startsWith(workingDirectory + '/')) {
|
|
86
|
+
return path.slice(workingDirectory.length + 1);
|
|
87
|
+
}
|
|
88
|
+
if (path === workingDirectory) {
|
|
89
|
+
return '.';
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return path;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Formats a list of pruned items in the style: "→ tool: parameter"
|
|
96
|
+
*/
|
|
97
|
+
export function formatPrunedItemsList(prunedIds, toolMetadata, workingDirectory) {
|
|
98
|
+
const lines = [];
|
|
99
|
+
for (const prunedId of prunedIds) {
|
|
100
|
+
const normalizedId = prunedId.toLowerCase();
|
|
101
|
+
const metadata = toolMetadata.get(normalizedId);
|
|
102
|
+
if (metadata) {
|
|
103
|
+
const paramKey = extractParameterKey(metadata);
|
|
104
|
+
if (paramKey) {
|
|
105
|
+
// Use 60 char limit to match notification style
|
|
106
|
+
const displayKey = truncate(shortenPath(paramKey, workingDirectory), 60);
|
|
107
|
+
lines.push(`→ ${metadata.tool}: ${displayKey}`);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
lines.push(`→ ${metadata.tool}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const knownCount = prunedIds.filter(id => toolMetadata.has(id.toLowerCase())).length;
|
|
115
|
+
const unknownCount = prunedIds.length - knownCount;
|
|
116
|
+
if (unknownCount > 0) {
|
|
117
|
+
lines.push(`→ (${unknownCount} tool${unknownCount > 1 ? 's' : ''} with unknown metadata)`);
|
|
118
|
+
}
|
|
119
|
+
return lines;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Formats a PruningResult into a human-readable string for the prune tool output.
|
|
123
|
+
*/
|
|
124
|
+
export function formatPruningResultForTool(result, workingDirectory) {
|
|
125
|
+
const lines = [];
|
|
126
|
+
lines.push(`Context pruning complete. Pruned ${result.prunedCount} tool outputs.`);
|
|
127
|
+
lines.push('');
|
|
128
|
+
if (result.llmPrunedIds.length > 0) {
|
|
129
|
+
lines.push(`Semantically pruned (${result.llmPrunedIds.length}):`);
|
|
130
|
+
lines.push(...formatPrunedItemsList(result.llmPrunedIds, result.toolMetadata, workingDirectory));
|
|
131
|
+
}
|
|
132
|
+
return lines.join('\n').trim();
|
|
133
|
+
}
|
|
68
134
|
//# sourceMappingURL=display-utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"display-utils.js","sourceRoot":"","sources":["../../../lib/ui/display-utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"display-utils.js","sourceRoot":"","sources":["../../../lib/ui/display-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Logger } from "../logger";
|
|
2
|
-
import type { SessionStats, GCStats
|
|
2
|
+
import type { SessionStats, GCStats } from "../core/janitor";
|
|
3
|
+
import type { ToolMetadata, PruneReason } from "../fetch-wrapper/types";
|
|
3
4
|
export type PruningSummaryLevel = "off" | "minimal" | "detailed";
|
|
4
5
|
export interface NotificationConfig {
|
|
5
6
|
pruningSummary: PruningSummaryLevel;
|
|
@@ -14,19 +15,11 @@ export interface NotificationData {
|
|
|
14
15
|
aiPrunedCount: number;
|
|
15
16
|
aiTokensSaved: number;
|
|
16
17
|
aiPrunedIds: string[];
|
|
17
|
-
toolMetadata: Map<string,
|
|
18
|
-
tool: string;
|
|
19
|
-
parameters?: any;
|
|
20
|
-
}>;
|
|
18
|
+
toolMetadata: Map<string, ToolMetadata>;
|
|
21
19
|
gcPending: GCStats | null;
|
|
22
20
|
sessionStats: SessionStats | null;
|
|
21
|
+
reason?: PruneReason;
|
|
23
22
|
}
|
|
24
|
-
export declare function sendIgnoredMessage(ctx: NotificationContext, sessionID: string, text: string, agent?: string): Promise<void>;
|
|
25
23
|
export declare function sendUnifiedNotification(ctx: NotificationContext, sessionID: string, data: NotificationData, agent?: string): Promise<boolean>;
|
|
26
|
-
export declare function
|
|
27
|
-
export declare function buildToolsSummary(prunedIds: string[], toolMetadata: Map<string, {
|
|
28
|
-
tool: string;
|
|
29
|
-
parameters?: any;
|
|
30
|
-
}>, workingDirectory?: string): Map<string, string[]>;
|
|
31
|
-
export declare function formatToolSummaryLines(toolsSummary: Map<string, string[]>, indent?: string): string[];
|
|
24
|
+
export declare function sendIgnoredMessage(ctx: NotificationContext, sessionID: string, text: string, agent?: string): Promise<void>;
|
|
32
25
|
//# sourceMappingURL=notification.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notification.d.ts","sourceRoot":"","sources":["../../../lib/ui/notification.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"notification.d.ts","sourceRoot":"","sources":["../../../lib/ui/notification.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAKvE,MAAM,MAAM,mBAAmB,GAAG,KAAK,GAAG,SAAS,GAAG,UAAU,CAAA;AAEhE,MAAM,WAAW,kBAAkB;IAC/B,cAAc,EAAE,mBAAmB,CAAA;IACnC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,WAAW,mBAAmB;IAChC,MAAM,EAAE,GAAG,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,kBAAkB,CAAA;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC7B,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IACvC,SAAS,EAAE,OAAO,GAAG,IAAI,CAAA;IACzB,YAAY,EAAE,YAAY,GAAG,IAAI,CAAA;IACjC,MAAM,CAAC,EAAE,WAAW,CAAA;CACvB;AAED,wBAAsB,uBAAuB,CACzC,GAAG,EAAE,mBAAmB,EACxB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,gBAAgB,EACtB,KAAK,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,OAAO,CAAC,CAkBlB;AAED,wBAAsB,kBAAkB,CACpC,GAAG,EAAE,mBAAmB,EACxB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAiBf"}
|
|
@@ -1,5 +1,21 @@
|
|
|
1
|
+
import { PRUNE_REASON_LABELS } from "../fetch-wrapper/types";
|
|
1
2
|
import { formatTokenCount } from "../tokenizer";
|
|
2
|
-
import {
|
|
3
|
+
import { formatPrunedItemsList } from "./display-utils";
|
|
4
|
+
export async function sendUnifiedNotification(ctx, sessionID, data, agent) {
|
|
5
|
+
const hasAiPruning = data.aiPrunedCount > 0;
|
|
6
|
+
const hasGcActivity = data.gcPending && data.gcPending.toolsDeduped > 0;
|
|
7
|
+
if (!hasAiPruning && !hasGcActivity) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
if (ctx.config.pruningSummary === 'off') {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
const message = ctx.config.pruningSummary === 'minimal'
|
|
14
|
+
? buildMinimalMessage(data)
|
|
15
|
+
: buildDetailedMessage(data, ctx.config.workingDirectory);
|
|
16
|
+
await sendIgnoredMessage(ctx, sessionID, message, agent);
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
3
19
|
export async function sendIgnoredMessage(ctx, sessionID, text, agent) {
|
|
4
20
|
try {
|
|
5
21
|
await ctx.client.session.prompt({
|
|
@@ -19,24 +35,22 @@ export async function sendIgnoredMessage(ctx, sessionID, text, agent) {
|
|
|
19
35
|
ctx.logger.error("notification", "Failed to send notification", { error: error.message });
|
|
20
36
|
}
|
|
21
37
|
}
|
|
22
|
-
export async function sendUnifiedNotification(ctx, sessionID, data, agent) {
|
|
23
|
-
const hasAiPruning = data.aiPrunedCount > 0;
|
|
24
|
-
const hasGcActivity = data.gcPending && data.gcPending.toolsDeduped > 0;
|
|
25
|
-
if (!hasAiPruning && !hasGcActivity) {
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
28
|
-
if (ctx.config.pruningSummary === 'off') {
|
|
29
|
-
return false;
|
|
30
|
-
}
|
|
31
|
-
const message = ctx.config.pruningSummary === 'minimal'
|
|
32
|
-
? buildMinimalMessage(data)
|
|
33
|
-
: buildDetailedMessage(data, ctx.config.workingDirectory);
|
|
34
|
-
await sendIgnoredMessage(ctx, sessionID, message, agent);
|
|
35
|
-
return true;
|
|
36
|
-
}
|
|
37
38
|
function buildMinimalMessage(data) {
|
|
38
39
|
const { justNowTokens, totalTokens } = calculateStats(data);
|
|
39
|
-
|
|
40
|
+
const reasonSuffix = data.reason ? ` [${PRUNE_REASON_LABELS[data.reason]}]` : '';
|
|
41
|
+
return formatStatsHeader(totalTokens, justNowTokens) + reasonSuffix;
|
|
42
|
+
}
|
|
43
|
+
function buildDetailedMessage(data, workingDirectory) {
|
|
44
|
+
const { justNowTokens, totalTokens } = calculateStats(data);
|
|
45
|
+
let message = formatStatsHeader(totalTokens, justNowTokens);
|
|
46
|
+
if (data.aiPrunedCount > 0) {
|
|
47
|
+
const justNowTokensStr = `~${formatTokenCount(justNowTokens)}`;
|
|
48
|
+
const reasonLabel = data.reason ? ` — ${PRUNE_REASON_LABELS[data.reason]}` : '';
|
|
49
|
+
message += `\n\n▣ Pruned tools (${justNowTokensStr})${reasonLabel}`;
|
|
50
|
+
const itemLines = formatPrunedItemsList(data.aiPrunedIds, data.toolMetadata, workingDirectory);
|
|
51
|
+
message += '\n' + itemLines.join('\n');
|
|
52
|
+
}
|
|
53
|
+
return message.trim();
|
|
40
54
|
}
|
|
41
55
|
function calculateStats(data) {
|
|
42
56
|
const justNowTokens = data.aiTokensSaved + (data.gcPending?.tokensCollected ?? 0);
|
|
@@ -50,131 +64,8 @@ function formatStatsHeader(totalTokens, justNowTokens) {
|
|
|
50
64
|
const justNowTokensStr = `~${formatTokenCount(justNowTokens)}`;
|
|
51
65
|
const maxTokenLen = Math.max(totalTokensStr.length, justNowTokensStr.length);
|
|
52
66
|
const totalTokensPadded = totalTokensStr.padStart(maxTokenLen);
|
|
53
|
-
const justNowTokensPadded = justNowTokensStr.padStart(maxTokenLen);
|
|
54
67
|
return [
|
|
55
|
-
`▣ DCP
|
|
56
|
-
` Total saved │ ${totalTokensPadded}`,
|
|
57
|
-
` Just now │ ${justNowTokensPadded}`,
|
|
68
|
+
`▣ DCP | ${totalTokensPadded} saved total`,
|
|
58
69
|
].join('\n');
|
|
59
70
|
}
|
|
60
|
-
function buildDetailedMessage(data, workingDirectory) {
|
|
61
|
-
const { justNowTokens, totalTokens } = calculateStats(data);
|
|
62
|
-
let message = formatStatsHeader(totalTokens, justNowTokens);
|
|
63
|
-
if (data.aiPrunedCount > 0) {
|
|
64
|
-
message += '\n\n▣ Pruned tools:';
|
|
65
|
-
for (const prunedId of data.aiPrunedIds) {
|
|
66
|
-
const normalizedId = prunedId.toLowerCase();
|
|
67
|
-
const metadata = data.toolMetadata.get(normalizedId);
|
|
68
|
-
if (metadata) {
|
|
69
|
-
const paramKey = extractParameterKey(metadata);
|
|
70
|
-
if (paramKey) {
|
|
71
|
-
const displayKey = truncate(shortenPath(paramKey, workingDirectory), 60);
|
|
72
|
-
message += `\n→ ${metadata.tool}: ${displayKey}`;
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
message += `\n→ ${metadata.tool}`;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
const knownCount = data.aiPrunedIds.filter(id => data.toolMetadata.has(id.toLowerCase())).length;
|
|
80
|
-
const unknownCount = data.aiPrunedIds.length - knownCount;
|
|
81
|
-
if (unknownCount > 0) {
|
|
82
|
-
message += `\n→ (${unknownCount} tool${unknownCount > 1 ? 's' : ''} with unknown metadata)`;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
return message.trim();
|
|
86
|
-
}
|
|
87
|
-
export function formatPruningResultForTool(result, workingDirectory) {
|
|
88
|
-
const lines = [];
|
|
89
|
-
lines.push(`Context pruning complete. Pruned ${result.prunedCount} tool outputs.`);
|
|
90
|
-
lines.push('');
|
|
91
|
-
if (result.llmPrunedIds.length > 0) {
|
|
92
|
-
lines.push(`Semantically pruned (${result.llmPrunedIds.length}):`);
|
|
93
|
-
const toolsSummary = buildToolsSummary(result.llmPrunedIds, result.toolMetadata, workingDirectory);
|
|
94
|
-
lines.push(...formatToolSummaryLines(toolsSummary));
|
|
95
|
-
}
|
|
96
|
-
return lines.join('\n').trim();
|
|
97
|
-
}
|
|
98
|
-
export function buildToolsSummary(prunedIds, toolMetadata, workingDirectory) {
|
|
99
|
-
const toolsSummary = new Map();
|
|
100
|
-
for (const prunedId of prunedIds) {
|
|
101
|
-
const normalizedId = prunedId.toLowerCase();
|
|
102
|
-
const metadata = toolMetadata.get(normalizedId);
|
|
103
|
-
if (metadata) {
|
|
104
|
-
const toolName = metadata.tool;
|
|
105
|
-
if (!toolsSummary.has(toolName)) {
|
|
106
|
-
toolsSummary.set(toolName, []);
|
|
107
|
-
}
|
|
108
|
-
const paramKey = extractParameterKey(metadata);
|
|
109
|
-
if (paramKey) {
|
|
110
|
-
const displayKey = truncate(shortenPath(paramKey, workingDirectory), 80);
|
|
111
|
-
toolsSummary.get(toolName).push(displayKey);
|
|
112
|
-
}
|
|
113
|
-
else {
|
|
114
|
-
toolsSummary.get(toolName).push('(default)');
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
return toolsSummary;
|
|
119
|
-
}
|
|
120
|
-
export function formatToolSummaryLines(toolsSummary, indent = ' ') {
|
|
121
|
-
const lines = [];
|
|
122
|
-
for (const [toolName, params] of toolsSummary.entries()) {
|
|
123
|
-
if (params.length === 1) {
|
|
124
|
-
lines.push(`${indent}${toolName}: ${params[0]}`);
|
|
125
|
-
}
|
|
126
|
-
else if (params.length > 1) {
|
|
127
|
-
lines.push(`${indent}${toolName} (${params.length}):`);
|
|
128
|
-
for (const param of params) {
|
|
129
|
-
lines.push(`${indent} ${param}`);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
return lines;
|
|
134
|
-
}
|
|
135
|
-
function truncate(str, maxLen = 60) {
|
|
136
|
-
if (str.length <= maxLen)
|
|
137
|
-
return str;
|
|
138
|
-
return str.slice(0, maxLen - 3) + '...';
|
|
139
|
-
}
|
|
140
|
-
function shortenPath(input, workingDirectory) {
|
|
141
|
-
const inPathMatch = input.match(/^(.+) in (.+)$/);
|
|
142
|
-
if (inPathMatch) {
|
|
143
|
-
const prefix = inPathMatch[1];
|
|
144
|
-
const pathPart = inPathMatch[2];
|
|
145
|
-
const shortenedPath = shortenSinglePath(pathPart, workingDirectory);
|
|
146
|
-
return `${prefix} in ${shortenedPath}`;
|
|
147
|
-
}
|
|
148
|
-
return shortenSinglePath(input, workingDirectory);
|
|
149
|
-
}
|
|
150
|
-
function shortenSinglePath(path, workingDirectory) {
|
|
151
|
-
const homeDir = require('os').homedir();
|
|
152
|
-
if (workingDirectory) {
|
|
153
|
-
if (path.startsWith(workingDirectory + '/')) {
|
|
154
|
-
return path.slice(workingDirectory.length + 1);
|
|
155
|
-
}
|
|
156
|
-
if (path === workingDirectory) {
|
|
157
|
-
return '.';
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
if (path.startsWith(homeDir)) {
|
|
161
|
-
path = '~' + path.slice(homeDir.length);
|
|
162
|
-
}
|
|
163
|
-
const nodeModulesMatch = path.match(/node_modules\/(@[^\/]+\/[^\/]+|[^\/]+)\/(.*)/);
|
|
164
|
-
if (nodeModulesMatch) {
|
|
165
|
-
return `${nodeModulesMatch[1]}/${nodeModulesMatch[2]}`;
|
|
166
|
-
}
|
|
167
|
-
if (workingDirectory) {
|
|
168
|
-
const workingDirWithTilde = workingDirectory.startsWith(homeDir)
|
|
169
|
-
? '~' + workingDirectory.slice(homeDir.length)
|
|
170
|
-
: null;
|
|
171
|
-
if (workingDirWithTilde && path.startsWith(workingDirWithTilde + '/')) {
|
|
172
|
-
return path.slice(workingDirWithTilde.length + 1);
|
|
173
|
-
}
|
|
174
|
-
if (workingDirWithTilde && path === workingDirWithTilde) {
|
|
175
|
-
return '.';
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
return path;
|
|
179
|
-
}
|
|
180
71
|
//# sourceMappingURL=notification.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notification.js","sourceRoot":"","sources":["../../../lib/ui/notification.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"notification.js","sourceRoot":"","sources":["../../../lib/ui/notification.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "@tarquinen/opencode-dcp",
|
|
4
|
-
"version": "0.4.
|
|
4
|
+
"version": "0.4.12",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "OpenCode plugin that optimizes token usage by pruning obsolete tool outputs from conversation context",
|
|
7
7
|
"main": "./dist/index.js",
|
|
@@ -1,49 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|