@dev4s/opencode-dcp 0.1.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/LICENSE +21 -0
- package/README.md +160 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +87 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/config.d.ts +58 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +696 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/hooks.d.ts +10 -0
- package/dist/lib/hooks.d.ts.map +1 -0
- package/dist/lib/hooks.js +45 -0
- package/dist/lib/hooks.js.map +1 -0
- package/dist/lib/logger.d.ts +31 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +183 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/messages/index.d.ts +2 -0
- package/dist/lib/messages/index.d.ts.map +1 -0
- package/dist/lib/messages/index.js +2 -0
- package/dist/lib/messages/index.js.map +1 -0
- package/dist/lib/messages/prune.d.ts +6 -0
- package/dist/lib/messages/prune.d.ts.map +1 -0
- package/dist/lib/messages/prune.js +187 -0
- package/dist/lib/messages/prune.js.map +1 -0
- package/dist/lib/messages/utils.d.ts +9 -0
- package/dist/lib/messages/utils.d.ts.map +1 -0
- package/dist/lib/messages/utils.js +124 -0
- package/dist/lib/messages/utils.js.map +1 -0
- package/dist/lib/model-selector.d.ts +17 -0
- package/dist/lib/model-selector.d.ts.map +1 -0
- package/dist/lib/model-selector.js +141 -0
- package/dist/lib/model-selector.js.map +1 -0
- package/dist/lib/prompt.d.ts +3 -0
- package/dist/lib/prompt.d.ts.map +1 -0
- package/dist/lib/prompt.js +128 -0
- package/dist/lib/prompt.js.map +1 -0
- package/dist/lib/prompts/discard-tool-spec.txt +41 -0
- package/dist/lib/prompts/extract-tool-spec.txt +47 -0
- package/dist/lib/prompts/on-idle-analysis.txt +30 -0
- package/dist/lib/prompts/user/nudge/nudge-both.txt +10 -0
- package/dist/lib/prompts/user/nudge/nudge-discard.txt +9 -0
- package/dist/lib/prompts/user/nudge/nudge-extract.txt +9 -0
- package/dist/lib/prompts/user/system/system-prompt-both.txt +58 -0
- package/dist/lib/prompts/user/system/system-prompt-discard.txt +49 -0
- package/dist/lib/prompts/user/system/system-prompt-extract.txt +49 -0
- package/dist/lib/shared-utils.d.ts +4 -0
- package/dist/lib/shared-utils.d.ts.map +1 -0
- package/dist/lib/shared-utils.js +13 -0
- package/dist/lib/shared-utils.js.map +1 -0
- package/dist/lib/state/index.d.ts +4 -0
- package/dist/lib/state/index.d.ts.map +1 -0
- package/dist/lib/state/index.js +4 -0
- package/dist/lib/state/index.js.map +1 -0
- package/dist/lib/state/persistence.d.ts +16 -0
- package/dist/lib/state/persistence.d.ts.map +1 -0
- package/dist/lib/state/persistence.js +73 -0
- package/dist/lib/state/persistence.js.map +1 -0
- package/dist/lib/state/state.d.ts +8 -0
- package/dist/lib/state/state.d.ts.map +1 -0
- package/dist/lib/state/state.js +112 -0
- package/dist/lib/state/state.js.map +1 -0
- package/dist/lib/state/tool-cache.d.ts +13 -0
- package/dist/lib/state/tool-cache.d.ts.map +1 -0
- package/dist/lib/state/tool-cache.js +74 -0
- package/dist/lib/state/tool-cache.js.map +1 -0
- package/dist/lib/state/types.d.ts +32 -0
- package/dist/lib/state/types.d.ts.map +1 -0
- package/dist/lib/state/types.js +2 -0
- package/dist/lib/state/types.js.map +1 -0
- package/dist/lib/state/utils.d.ts +2 -0
- package/dist/lib/state/utils.d.ts.map +1 -0
- package/dist/lib/state/utils.js +10 -0
- package/dist/lib/state/utils.js.map +1 -0
- package/dist/lib/strategies/deduplication.d.ts +10 -0
- package/dist/lib/strategies/deduplication.d.ts.map +1 -0
- package/dist/lib/strategies/deduplication.js +89 -0
- package/dist/lib/strategies/deduplication.js.map +1 -0
- package/dist/lib/strategies/index.d.ts +6 -0
- package/dist/lib/strategies/index.d.ts.map +1 -0
- package/dist/lib/strategies/index.js +6 -0
- package/dist/lib/strategies/index.js.map +1 -0
- package/dist/lib/strategies/on-idle.d.ts +14 -0
- package/dist/lib/strategies/on-idle.d.ts.map +1 -0
- package/dist/lib/strategies/on-idle.js +220 -0
- package/dist/lib/strategies/on-idle.js.map +1 -0
- package/dist/lib/strategies/purge-errors.d.ts +13 -0
- package/dist/lib/strategies/purge-errors.d.ts.map +1 -0
- package/dist/lib/strategies/purge-errors.js +54 -0
- package/dist/lib/strategies/purge-errors.js.map +1 -0
- package/dist/lib/strategies/supersede-writes.d.ts +13 -0
- package/dist/lib/strategies/supersede-writes.d.ts.map +1 -0
- package/dist/lib/strategies/supersede-writes.js +80 -0
- package/dist/lib/strategies/supersede-writes.js.map +1 -0
- package/dist/lib/strategies/tools.d.ts +14 -0
- package/dist/lib/strategies/tools.d.ts.map +1 -0
- package/dist/lib/strategies/tools.js +137 -0
- package/dist/lib/strategies/tools.js.map +1 -0
- package/dist/lib/strategies/utils.d.ts +12 -0
- package/dist/lib/strategies/utils.d.ts.map +1 -0
- package/dist/lib/strategies/utils.js +82 -0
- package/dist/lib/strategies/utils.js.map +1 -0
- package/dist/lib/tokenizer.d.ts +24 -0
- package/dist/lib/tokenizer.d.ts.map +1 -0
- package/dist/lib/tokenizer.js +45 -0
- package/dist/lib/tokenizer.js.map +1 -0
- package/dist/lib/ui/notification.d.ts +9 -0
- package/dist/lib/ui/notification.d.ts.map +1 -0
- package/dist/lib/ui/notification.js +70 -0
- package/dist/lib/ui/notification.js.map +1 -0
- package/dist/lib/ui/utils.d.ts +15 -0
- package/dist/lib/ui/utils.d.ts.map +1 -0
- package/dist/lib/ui/utils.js +87 -0
- package/dist/lib/ui/utils.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { tool } from "@opencode-ai/plugin";
|
|
2
|
+
import { buildToolIdList } from "../messages/utils";
|
|
3
|
+
import { sendUnifiedNotification } from "../ui/notification";
|
|
4
|
+
import { formatPruningResultForTool } from "../ui/utils";
|
|
5
|
+
import { ensureSessionInitialized } from "../state";
|
|
6
|
+
import { saveSessionState } from "../state/persistence";
|
|
7
|
+
import { loadPrompt } from "../prompt";
|
|
8
|
+
import { calculateTokensSaved, getCurrentParams } from "./utils";
|
|
9
|
+
// Lazy-loaded tool descriptions (deferred to first tool creation)
|
|
10
|
+
let discardToolDescription = null;
|
|
11
|
+
let extractToolDescription = null;
|
|
12
|
+
function getDiscardToolDescription() {
|
|
13
|
+
if (!discardToolDescription) {
|
|
14
|
+
discardToolDescription = loadPrompt("discard-tool-spec");
|
|
15
|
+
}
|
|
16
|
+
return discardToolDescription;
|
|
17
|
+
}
|
|
18
|
+
function getExtractToolDescription() {
|
|
19
|
+
if (!extractToolDescription) {
|
|
20
|
+
extractToolDescription = loadPrompt("extract-tool-spec");
|
|
21
|
+
}
|
|
22
|
+
return extractToolDescription;
|
|
23
|
+
}
|
|
24
|
+
// Shared logic for executing prune operations.
|
|
25
|
+
async function executePruneOperation(ctx, toolCtx, ids, reason, toolName, distillation) {
|
|
26
|
+
const { client, state, logger, config, workingDirectory } = ctx;
|
|
27
|
+
const sessionId = toolCtx.sessionID;
|
|
28
|
+
logger.info(`${toolName} tool invoked`);
|
|
29
|
+
logger.info(JSON.stringify(reason ? { ids, reason } : { ids }));
|
|
30
|
+
if (!ids || ids.length === 0) {
|
|
31
|
+
logger.debug(`${toolName} tool called but ids is empty or undefined`);
|
|
32
|
+
return `No IDs provided. Check the <prunable-tools> list for available IDs to ${toolName.toLowerCase()}.`;
|
|
33
|
+
}
|
|
34
|
+
const numericToolIds = ids
|
|
35
|
+
.map((id) => parseInt(id, 10))
|
|
36
|
+
.filter((n) => !isNaN(n));
|
|
37
|
+
if (numericToolIds.length === 0) {
|
|
38
|
+
logger.debug(`No numeric tool IDs provided for ${toolName}: ` + JSON.stringify(ids));
|
|
39
|
+
return "No numeric IDs provided. Format: ids: [id1, id2, ...]";
|
|
40
|
+
}
|
|
41
|
+
// Fetch messages to calculate tokens and find current agent
|
|
42
|
+
const messagesResponse = await client.session.messages({
|
|
43
|
+
path: { id: sessionId },
|
|
44
|
+
});
|
|
45
|
+
const messages = messagesResponse.data || messagesResponse;
|
|
46
|
+
await ensureSessionInitialized(ctx.client, state, sessionId, logger, messages);
|
|
47
|
+
const currentParams = getCurrentParams(messages, logger);
|
|
48
|
+
const toolIdList = buildToolIdList(state, messages, logger);
|
|
49
|
+
// Validate that all numeric IDs are within bounds
|
|
50
|
+
if (numericToolIds.some((id) => id < 0 || id >= toolIdList.length)) {
|
|
51
|
+
logger.debug("Invalid tool IDs provided: " + numericToolIds.join(", "));
|
|
52
|
+
return "Invalid IDs provided. Only use numeric IDs from the <prunable-tools> list.";
|
|
53
|
+
}
|
|
54
|
+
// Validate that all IDs exist in cache and aren't protected
|
|
55
|
+
// (rejects hallucinated IDs and turn-protected tools not shown in <prunable-tools>)
|
|
56
|
+
for (const index of numericToolIds) {
|
|
57
|
+
const id = toolIdList[index];
|
|
58
|
+
const metadata = state.toolParameters.get(id);
|
|
59
|
+
if (!metadata) {
|
|
60
|
+
logger.debug("Rejecting prune request - ID not in cache (turn-protected or hallucinated)", { index, id });
|
|
61
|
+
return "Invalid IDs provided. Only use numeric IDs from the <prunable-tools> list.";
|
|
62
|
+
}
|
|
63
|
+
const allProtectedTools = config.tools.settings.protectedTools;
|
|
64
|
+
if (allProtectedTools.includes(metadata.tool)) {
|
|
65
|
+
logger.debug("Rejecting prune request - protected tool", {
|
|
66
|
+
index,
|
|
67
|
+
id,
|
|
68
|
+
tool: metadata.tool,
|
|
69
|
+
});
|
|
70
|
+
return "Invalid IDs provided. Only use numeric IDs from the <prunable-tools> list.";
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const pruneToolIds = numericToolIds.map((index) => toolIdList[index]);
|
|
74
|
+
state.prune.toolIds.push(...pruneToolIds);
|
|
75
|
+
const toolMetadata = new Map();
|
|
76
|
+
for (const id of pruneToolIds) {
|
|
77
|
+
const toolParameters = state.toolParameters.get(id);
|
|
78
|
+
if (toolParameters) {
|
|
79
|
+
toolMetadata.set(id, toolParameters);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
logger.debug("No metadata found for ID", { id });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
state.stats.pruneTokenCounter += calculateTokensSaved(state, messages, pruneToolIds);
|
|
86
|
+
await sendUnifiedNotification(client, logger, config, state, sessionId, pruneToolIds, toolMetadata, reason, currentParams, workingDirectory, distillation);
|
|
87
|
+
state.stats.totalPruneTokens += state.stats.pruneTokenCounter;
|
|
88
|
+
state.stats.pruneTokenCounter = 0;
|
|
89
|
+
state.nudgeCounter = 0;
|
|
90
|
+
saveSessionState(state, logger).catch((err) => logger.error("Failed to persist state", { error: err.message }));
|
|
91
|
+
return formatPruningResultForTool(pruneToolIds, toolMetadata, workingDirectory);
|
|
92
|
+
}
|
|
93
|
+
export function createDiscardTool(ctx) {
|
|
94
|
+
return tool({
|
|
95
|
+
description: getDiscardToolDescription(),
|
|
96
|
+
args: {
|
|
97
|
+
ids: tool.schema
|
|
98
|
+
.array(tool.schema.string())
|
|
99
|
+
.describe("First element is the reason ('completion' or 'noise'), followed by numeric IDs as strings to discard"),
|
|
100
|
+
},
|
|
101
|
+
async execute(args, toolCtx) {
|
|
102
|
+
// Parse reason from first element, numeric IDs from the rest
|
|
103
|
+
const reason = args.ids?.[0];
|
|
104
|
+
const validReasons = ["completion", "noise"];
|
|
105
|
+
if (typeof reason !== "string" || !validReasons.includes(reason)) {
|
|
106
|
+
ctx.logger.debug("Invalid discard reason provided: " + reason);
|
|
107
|
+
return "No valid reason found. Use 'completion' or 'noise' as the first element.";
|
|
108
|
+
}
|
|
109
|
+
const numericIds = args.ids.slice(1);
|
|
110
|
+
return executePruneOperation(ctx, toolCtx, numericIds, reason, "Discard");
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
export function createExtractTool(ctx) {
|
|
115
|
+
return tool({
|
|
116
|
+
description: getExtractToolDescription(),
|
|
117
|
+
args: {
|
|
118
|
+
ids: tool.schema
|
|
119
|
+
.array(tool.schema.string())
|
|
120
|
+
.describe("Numeric IDs as strings to extract from the <prunable-tools> list"),
|
|
121
|
+
distillation: tool.schema
|
|
122
|
+
.array(tool.schema.string())
|
|
123
|
+
.describe("REQUIRED. Array of strings, one per ID (positional: distillation[0] is for ids[0], etc.)"),
|
|
124
|
+
},
|
|
125
|
+
async execute(args, toolCtx) {
|
|
126
|
+
if (!args.distillation || args.distillation.length === 0) {
|
|
127
|
+
ctx.logger.debug("Extract tool called without distillation: " + JSON.stringify(args));
|
|
128
|
+
return "Missing distillation. You must provide a distillation string for each ID.";
|
|
129
|
+
}
|
|
130
|
+
// Log the distillation for debugging/analysis
|
|
131
|
+
ctx.logger.info("Distillation data received:");
|
|
132
|
+
ctx.logger.info(JSON.stringify(args.distillation, null, 2));
|
|
133
|
+
return executePruneOperation(ctx, toolCtx, args.ids, "extraction", "Extract", args.distillation);
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../lib/strategies/tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { SessionState, WithParts } from "../state";
|
|
2
|
+
import { Logger } from "../logger";
|
|
3
|
+
export declare function getCurrentParams(messages: WithParts[], logger: Logger): {
|
|
4
|
+
providerId: string | undefined;
|
|
5
|
+
modelId: string | undefined;
|
|
6
|
+
agent: string | undefined;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Calculates approximate tokens saved by pruning the given tool call IDs.
|
|
10
|
+
*/
|
|
11
|
+
export declare const calculateTokensSaved: (state: SessionState, messages: WithParts[], pruneToolIds: string[]) => number;
|
|
12
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../lib/strategies/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAElD,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAIlC,wBAAgB,gBAAgB,CAC5B,QAAQ,EAAE,SAAS,EAAE,EACrB,MAAM,EAAE,MAAM,GACf;IACC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IAC9B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;CAC5B,CAWA;AAaD;;GAEG;AACH,eAAO,MAAM,oBAAoB,GAC7B,OAAO,YAAY,EACnB,UAAU,SAAS,EAAE,EACrB,cAAc,MAAM,EAAE,KACvB,MAsDF,CAAA"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { encodeText } from "../tokenizer";
|
|
2
|
+
import { getLastUserMessage, isMessageCompacted } from "../shared-utils";
|
|
3
|
+
export function getCurrentParams(messages, logger) {
|
|
4
|
+
const userMsg = getLastUserMessage(messages);
|
|
5
|
+
if (!userMsg) {
|
|
6
|
+
logger.debug("No user message found when determining current params");
|
|
7
|
+
return { providerId: undefined, modelId: undefined, agent: undefined };
|
|
8
|
+
}
|
|
9
|
+
const agent = userMsg.info.agent;
|
|
10
|
+
const providerId = userMsg.info.model.providerID;
|
|
11
|
+
const modelId = userMsg.info.model.modelID;
|
|
12
|
+
return { providerId, modelId, agent };
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Estimates token counts for a batch of texts using the lazy tokenizer.
|
|
16
|
+
*/
|
|
17
|
+
function estimateTokensBatch(texts) {
|
|
18
|
+
try {
|
|
19
|
+
return texts.map((text) => encodeText(text).length);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return texts.map((text) => Math.round(text.length / 4));
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Calculates approximate tokens saved by pruning the given tool call IDs.
|
|
27
|
+
*/
|
|
28
|
+
export const calculateTokensSaved = (state, messages, pruneToolIds) => {
|
|
29
|
+
try {
|
|
30
|
+
const contents = [];
|
|
31
|
+
for (const msg of messages) {
|
|
32
|
+
if (isMessageCompacted(state, msg)) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
for (const part of msg.parts) {
|
|
36
|
+
if (part.type !== "tool" || !pruneToolIds.includes(part.callID)) {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
// For write and edit tools, count input content as that is all we prune for these tools
|
|
40
|
+
// (input is present in both completed and error states)
|
|
41
|
+
if (part.tool === "write") {
|
|
42
|
+
const inputContent = part.state.input?.content;
|
|
43
|
+
const content = typeof inputContent === "string"
|
|
44
|
+
? inputContent
|
|
45
|
+
: JSON.stringify(inputContent ?? "");
|
|
46
|
+
contents.push(content);
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (part.tool === "edit") {
|
|
50
|
+
const oldString = part.state.input?.oldString;
|
|
51
|
+
const newString = part.state.input?.newString;
|
|
52
|
+
if (typeof oldString === "string") {
|
|
53
|
+
contents.push(oldString);
|
|
54
|
+
}
|
|
55
|
+
if (typeof newString === "string") {
|
|
56
|
+
contents.push(newString);
|
|
57
|
+
}
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
// For other tools, count output or error based on status
|
|
61
|
+
if (part.state.status === "completed") {
|
|
62
|
+
const content = typeof part.state.output === "string"
|
|
63
|
+
? part.state.output
|
|
64
|
+
: JSON.stringify(part.state.output);
|
|
65
|
+
contents.push(content);
|
|
66
|
+
}
|
|
67
|
+
else if (part.state.status === "error") {
|
|
68
|
+
const content = typeof part.state.error === "string"
|
|
69
|
+
? part.state.error
|
|
70
|
+
: JSON.stringify(part.state.error);
|
|
71
|
+
contents.push(content);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const tokenCounts = estimateTokensBatch(contents);
|
|
76
|
+
return tokenCounts.reduce((sum, count) => sum + count, 0);
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
return 0;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../lib/strategies/utils.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAExE,MAAM,UAAU,gBAAgB,CAC5B,QAAqB,EACrB,MAAc;IAMd,MAAM,OAAO,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAA;IAC5C,IAAI,CAAC,OAAO,EAAE,CAAC;QACX,MAAM,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAA;QACrE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,CAAA;IAC1E,CAAC;IACD,MAAM,KAAK,GAAY,OAAO,CAAC,IAAoB,CAAC,KAAK,CAAA;IACzD,MAAM,UAAU,GAAwB,OAAO,CAAC,IAAoB,CAAC,KAAK,CAAC,UAAU,CAAA;IACrF,MAAM,OAAO,GAAwB,OAAO,CAAC,IAAoB,CAAC,KAAK,CAAC,OAAO,CAAA;IAE/E,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,CAAA;AACzC,CAAC;AAED;;GAEG;AACH,SAAS,mBAAmB,CAAC,KAAe;IACxC,IAAI,CAAC;QACD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAA;IACvD,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAA;IAC3D,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAChC,KAAmB,EACnB,QAAqB,EACrB,YAAsB,EAChB,EAAE;IACR,IAAI,CAAC;QACD,MAAM,QAAQ,GAAa,EAAE,CAAA;QAC7B,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YACzB,IAAI,kBAAkB,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC;gBACjC,SAAQ;YACZ,CAAC;YACD,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;gBAC3B,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC9D,SAAQ;gBACZ,CAAC;gBACD,wFAAwF;gBACxF,wDAAwD;gBACxD,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBACxB,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAA;oBAC9C,MAAM,OAAO,GACT,OAAO,YAAY,KAAK,QAAQ;wBAC5B,CAAC,CAAC,YAAY;wBACd,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,IAAI,EAAE,CAAC,CAAA;oBAC5C,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;oBACtB,SAAQ;gBACZ,CAAC;gBACD,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;oBACvB,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,CAAA;oBAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,CAAA;oBAC7C,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;wBAChC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;oBAC5B,CAAC;oBACD,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;wBAChC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;oBAC5B,CAAC;oBACD,SAAQ;gBACZ,CAAC;gBACD,yDAAyD;gBACzD,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;oBACpC,MAAM,OAAO,GACT,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,QAAQ;wBACjC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM;wBACnB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;oBAC3C,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;gBAC1B,CAAC;qBAAM,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;oBACvC,MAAM,OAAO,GACT,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,QAAQ;wBAChC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK;wBAClB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;oBAC1C,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;gBAC1B,CAAC;YACL,CAAC;QACL,CAAC;QACD,MAAM,WAAW,GAAa,mBAAmB,CAAC,QAAQ,CAAC,CAAA;QAC3D,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,KAAK,EAAE,CAAC,CAAC,CAAA;IAC7D,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QAClB,OAAO,CAAC,CAAA;IACZ,CAAC;AACL,CAAC,CAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazy tokenizer module - loads gpt-tokenizer in background to avoid blocking startup.
|
|
3
|
+
*
|
|
4
|
+
* The gpt-tokenizer package takes 5-15 seconds to initialize due to loading
|
|
5
|
+
* large vocabulary files. This module defers that load to happen asynchronously
|
|
6
|
+
* after plugin initialization, keeping startup instant.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Starts loading the tokenizer in the background.
|
|
10
|
+
* Call this at plugin startup - it returns immediately and loads async.
|
|
11
|
+
*/
|
|
12
|
+
export declare function preloadTokenizer(): void;
|
|
13
|
+
/**
|
|
14
|
+
* Encodes text to tokens. Returns immediately with either:
|
|
15
|
+
* - Accurate token array (if tokenizer loaded)
|
|
16
|
+
* - Estimated token array based on char/4 heuristic (if still loading)
|
|
17
|
+
*/
|
|
18
|
+
export declare function encodeText(text: string): number[];
|
|
19
|
+
/**
|
|
20
|
+
* Returns whether the tokenizer has finished loading.
|
|
21
|
+
* Useful for logging/debugging.
|
|
22
|
+
*/
|
|
23
|
+
export declare function isTokenizerReady(): boolean;
|
|
24
|
+
//# sourceMappingURL=tokenizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenizer.d.ts","sourceRoot":"","sources":["../../lib/tokenizer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAUvC;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAOjD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazy tokenizer module - loads gpt-tokenizer in background to avoid blocking startup.
|
|
3
|
+
*
|
|
4
|
+
* The gpt-tokenizer package takes 5-15 seconds to initialize due to loading
|
|
5
|
+
* large vocabulary files. This module defers that load to happen asynchronously
|
|
6
|
+
* after plugin initialization, keeping startup instant.
|
|
7
|
+
*/
|
|
8
|
+
let encodeFn = null;
|
|
9
|
+
let loadPromise = null;
|
|
10
|
+
/**
|
|
11
|
+
* Starts loading the tokenizer in the background.
|
|
12
|
+
* Call this at plugin startup - it returns immediately and loads async.
|
|
13
|
+
*/
|
|
14
|
+
export function preloadTokenizer() {
|
|
15
|
+
if (loadPromise)
|
|
16
|
+
return;
|
|
17
|
+
loadPromise = import("gpt-tokenizer")
|
|
18
|
+
.then(({ encode }) => {
|
|
19
|
+
encodeFn = encode;
|
|
20
|
+
})
|
|
21
|
+
.catch(() => {
|
|
22
|
+
// Silently fail - fallback estimation will be used
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Encodes text to tokens. Returns immediately with either:
|
|
27
|
+
* - Accurate token array (if tokenizer loaded)
|
|
28
|
+
* - Estimated token array based on char/4 heuristic (if still loading)
|
|
29
|
+
*/
|
|
30
|
+
export function encodeText(text) {
|
|
31
|
+
if (encodeFn) {
|
|
32
|
+
return encodeFn(text);
|
|
33
|
+
}
|
|
34
|
+
// Fallback: ~4 chars per token (reasonable estimate for English text)
|
|
35
|
+
const estimatedLength = Math.ceil(text.length / 4);
|
|
36
|
+
return new Array(estimatedLength);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Returns whether the tokenizer has finished loading.
|
|
40
|
+
* Useful for logging/debugging.
|
|
41
|
+
*/
|
|
42
|
+
export function isTokenizerReady() {
|
|
43
|
+
return encodeFn !== null;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=tokenizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenizer.js","sourceRoot":"","sources":["../../lib/tokenizer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,IAAI,QAAQ,GAAoB,IAAI,CAAA;AACpC,IAAI,WAAW,GAAyB,IAAI,CAAA;AAE5C;;;GAGG;AACH,MAAM,UAAU,gBAAgB;IAC5B,IAAI,WAAW;QAAE,OAAM;IAEvB,WAAW,GAAG,MAAM,CAAC,eAAe,CAAC;SAChC,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;QACjB,QAAQ,GAAG,MAAM,CAAA;IACrB,CAAC,CAAC;SACD,KAAK,CAAC,GAAG,EAAE;QACR,mDAAmD;IACvD,CAAC,CAAC,CAAA;AACV,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY;IACnC,IAAI,QAAQ,EAAE,CAAC;QACX,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAA;IACzB,CAAC;IACD,sEAAsE;IACtE,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IAClD,OAAO,IAAI,KAAK,CAAC,eAAe,CAAC,CAAA;AACrC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB;IAC5B,OAAO,QAAQ,KAAK,IAAI,CAAA;AAC5B,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Logger } from "../logger";
|
|
2
|
+
import type { SessionState } from "../state";
|
|
3
|
+
import { ToolParameterEntry } from "../state";
|
|
4
|
+
import { PluginConfig } from "../config";
|
|
5
|
+
export type PruneReason = "completion" | "noise" | "extraction";
|
|
6
|
+
export declare const PRUNE_REASON_LABELS: Record<PruneReason, string>;
|
|
7
|
+
export declare function sendUnifiedNotification(client: any, logger: Logger, config: PluginConfig, state: SessionState, sessionId: string, pruneToolIds: string[], toolMetadata: Map<string, ToolParameterEntry>, reason: PruneReason | undefined, params: any, workingDirectory: string, distillation?: string[]): Promise<boolean>;
|
|
8
|
+
export declare function sendIgnoredMessage(client: any, sessionID: string, text: string, params: any, logger: Logger): Promise<void>;
|
|
9
|
+
//# sourceMappingURL=notification.d.ts.map
|
|
@@ -0,0 +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,MAAM,UAAU,CAAA;AAO5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAExC,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,OAAO,GAAG,YAAY,CAAA;AAC/D,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAI3D,CAAA;AAqCD,wBAAsB,uBAAuB,CACzC,MAAM,EAAE,GAAG,EACX,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EAAE,EACtB,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,EAC7C,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,MAAM,EAAE,GAAG,EACX,gBAAgB,EAAE,MAAM,EACxB,YAAY,CAAC,EAAE,MAAM,EAAE,GACxB,OAAO,CAAC,OAAO,CAAC,CA0BlB;AAED,wBAAsB,kBAAkB,CACpC,MAAM,EAAE,GAAG,EACX,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,GAAG,EACX,MAAM,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CA+Bf"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { formatExtracted, formatPrunedItemsList, formatStatsHeader, formatTokenCount, } from "./utils";
|
|
2
|
+
export const PRUNE_REASON_LABELS = {
|
|
3
|
+
completion: "Task Complete",
|
|
4
|
+
noise: "Noise Removal",
|
|
5
|
+
extraction: "Extraction",
|
|
6
|
+
};
|
|
7
|
+
function buildMinimalMessage(state, reason, distillation) {
|
|
8
|
+
const reasonSuffix = reason ? ` — ${PRUNE_REASON_LABELS[reason]}` : "";
|
|
9
|
+
let message = formatStatsHeader(state.stats.totalPruneTokens, state.stats.pruneTokenCounter) +
|
|
10
|
+
reasonSuffix;
|
|
11
|
+
return message + formatExtracted(distillation);
|
|
12
|
+
}
|
|
13
|
+
function buildDetailedMessage(state, reason, pruneToolIds, toolMetadata, workingDirectory, distillation) {
|
|
14
|
+
let message = formatStatsHeader(state.stats.totalPruneTokens, state.stats.pruneTokenCounter);
|
|
15
|
+
if (pruneToolIds.length > 0) {
|
|
16
|
+
const pruneTokenCounterStr = `~${formatTokenCount(state.stats.pruneTokenCounter)}`;
|
|
17
|
+
const reasonLabel = reason ? ` — ${PRUNE_REASON_LABELS[reason]}` : "";
|
|
18
|
+
message += `\n\n▣ Pruning (${pruneTokenCounterStr})${reasonLabel}`;
|
|
19
|
+
const itemLines = formatPrunedItemsList(pruneToolIds, toolMetadata, workingDirectory);
|
|
20
|
+
message += "\n" + itemLines.join("\n");
|
|
21
|
+
}
|
|
22
|
+
return (message + formatExtracted(distillation)).trim();
|
|
23
|
+
}
|
|
24
|
+
export async function sendUnifiedNotification(client, logger, config, state, sessionId, pruneToolIds, toolMetadata, reason, params, workingDirectory, distillation) {
|
|
25
|
+
const hasPruned = pruneToolIds.length > 0;
|
|
26
|
+
if (!hasPruned) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
if (config.pruneNotification === "off") {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
const showExtraction = config.tools.extract.showDistillation ? distillation : undefined;
|
|
33
|
+
const message = config.pruneNotification === "minimal"
|
|
34
|
+
? buildMinimalMessage(state, reason, showExtraction)
|
|
35
|
+
: buildDetailedMessage(state, reason, pruneToolIds, toolMetadata, workingDirectory, showExtraction);
|
|
36
|
+
await sendIgnoredMessage(client, sessionId, message, params, logger);
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
export async function sendIgnoredMessage(client, sessionID, text, params, logger) {
|
|
40
|
+
const agent = params.agent || undefined;
|
|
41
|
+
const model = params.providerId && params.modelId
|
|
42
|
+
? {
|
|
43
|
+
providerID: params.providerId,
|
|
44
|
+
modelID: params.modelId,
|
|
45
|
+
}
|
|
46
|
+
: undefined;
|
|
47
|
+
try {
|
|
48
|
+
await client.session.prompt({
|
|
49
|
+
path: {
|
|
50
|
+
id: sessionID,
|
|
51
|
+
},
|
|
52
|
+
body: {
|
|
53
|
+
noReply: true,
|
|
54
|
+
agent: agent,
|
|
55
|
+
model: model,
|
|
56
|
+
parts: [
|
|
57
|
+
{
|
|
58
|
+
type: "text",
|
|
59
|
+
text: text,
|
|
60
|
+
ignored: true,
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
logger.error("Failed to send notification", { error: error.message });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=notification.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notification.js","sourceRoot":"","sources":["../../../lib/ui/notification.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ToolParameterEntry } from "../state";
|
|
2
|
+
export declare function formatExtracted(distillation?: string[]): string;
|
|
3
|
+
export declare function formatStatsHeader(totalTokensSaved: number, pruneTokenCounter: number): string;
|
|
4
|
+
export declare function formatTokenCount(tokens: number): string;
|
|
5
|
+
export declare function truncate(str: string, maxLen?: number): string;
|
|
6
|
+
export declare function shortenPath(input: string, workingDirectory?: string): string;
|
|
7
|
+
/**
|
|
8
|
+
* Formats a list of pruned items in the style: "→ tool: parameter"
|
|
9
|
+
*/
|
|
10
|
+
export declare function formatPrunedItemsList(pruneToolIds: string[], toolMetadata: Map<string, ToolParameterEntry>, workingDirectory?: string): string[];
|
|
11
|
+
/**
|
|
12
|
+
* Formats a PruningResult into a human-readable string for the prune tool output.
|
|
13
|
+
*/
|
|
14
|
+
export declare function formatPruningResultForTool(prunedIds: string[], toolMetadata: Map<string, ToolParameterEntry>, workingDirectory?: string): string;
|
|
15
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../lib/ui/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAG7C,wBAAgB,eAAe,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAS/D;AAED,wBAAgB,iBAAiB,CAAC,gBAAgB,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,GAAG,MAAM,CAG7F;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAKvD;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,YAAY,EAAE,MAAM,EAAE,EACtB,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,EAC7C,gBAAgB,CAAC,EAAE,MAAM,GAC1B,MAAM,EAAE,CA0BV;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACtC,SAAS,EAAE,MAAM,EAAE,EACnB,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,EAC7C,gBAAgB,CAAC,EAAE,MAAM,GAC1B,MAAM,CAWR"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { extractParameterKey } from "../messages/utils";
|
|
2
|
+
export function formatExtracted(distillation) {
|
|
3
|
+
if (!distillation || distillation.length === 0) {
|
|
4
|
+
return "";
|
|
5
|
+
}
|
|
6
|
+
let result = `\n\n▣ Extracted`;
|
|
7
|
+
for (const finding of distillation) {
|
|
8
|
+
result += `\n───\n${finding}`;
|
|
9
|
+
}
|
|
10
|
+
return result;
|
|
11
|
+
}
|
|
12
|
+
export function formatStatsHeader(totalTokensSaved, pruneTokenCounter) {
|
|
13
|
+
const totalTokensSavedStr = `~${formatTokenCount(totalTokensSaved + pruneTokenCounter)}`;
|
|
14
|
+
return [`▣ DCP | ${totalTokensSavedStr} saved total`].join("\n");
|
|
15
|
+
}
|
|
16
|
+
export function formatTokenCount(tokens) {
|
|
17
|
+
if (tokens >= 1000) {
|
|
18
|
+
return `${(tokens / 1000).toFixed(1)}K`.replace(".0K", "K") + " tokens";
|
|
19
|
+
}
|
|
20
|
+
return tokens.toString() + " tokens";
|
|
21
|
+
}
|
|
22
|
+
export function truncate(str, maxLen = 60) {
|
|
23
|
+
if (str.length <= maxLen)
|
|
24
|
+
return str;
|
|
25
|
+
return str.slice(0, maxLen - 3) + "...";
|
|
26
|
+
}
|
|
27
|
+
export function shortenPath(input, workingDirectory) {
|
|
28
|
+
const inPathMatch = input.match(/^(.+) in (.+)$/);
|
|
29
|
+
if (inPathMatch) {
|
|
30
|
+
const prefix = inPathMatch[1];
|
|
31
|
+
const pathPart = inPathMatch[2];
|
|
32
|
+
const shortenedPath = shortenSinglePath(pathPart, workingDirectory);
|
|
33
|
+
return `${prefix} in ${shortenedPath}`;
|
|
34
|
+
}
|
|
35
|
+
return shortenSinglePath(input, workingDirectory);
|
|
36
|
+
}
|
|
37
|
+
function shortenSinglePath(path, workingDirectory) {
|
|
38
|
+
if (workingDirectory) {
|
|
39
|
+
if (path.startsWith(workingDirectory + "/")) {
|
|
40
|
+
return path.slice(workingDirectory.length + 1);
|
|
41
|
+
}
|
|
42
|
+
if (path === workingDirectory) {
|
|
43
|
+
return ".";
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return path;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Formats a list of pruned items in the style: "→ tool: parameter"
|
|
50
|
+
*/
|
|
51
|
+
export function formatPrunedItemsList(pruneToolIds, toolMetadata, workingDirectory) {
|
|
52
|
+
const lines = [];
|
|
53
|
+
for (const id of pruneToolIds) {
|
|
54
|
+
const metadata = toolMetadata.get(id);
|
|
55
|
+
if (metadata) {
|
|
56
|
+
const paramKey = extractParameterKey(metadata.tool, metadata.parameters);
|
|
57
|
+
if (paramKey) {
|
|
58
|
+
// Use 60 char limit to match notification style
|
|
59
|
+
const displayKey = truncate(shortenPath(paramKey, workingDirectory), 60);
|
|
60
|
+
lines.push(`→ ${metadata.tool}: ${displayKey}`);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
lines.push(`→ ${metadata.tool}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const knownCount = pruneToolIds.filter((id) => toolMetadata.has(id)).length;
|
|
68
|
+
const unknownCount = pruneToolIds.length - knownCount;
|
|
69
|
+
if (unknownCount > 0) {
|
|
70
|
+
lines.push(`→ (${unknownCount} tool${unknownCount > 1 ? "s" : ""} with unknown metadata)`);
|
|
71
|
+
}
|
|
72
|
+
return lines;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Formats a PruningResult into a human-readable string for the prune tool output.
|
|
76
|
+
*/
|
|
77
|
+
export function formatPruningResultForTool(prunedIds, toolMetadata, workingDirectory) {
|
|
78
|
+
const lines = [];
|
|
79
|
+
lines.push(`Context pruning complete. Pruned ${prunedIds.length} tool outputs.`);
|
|
80
|
+
lines.push("");
|
|
81
|
+
if (prunedIds.length > 0) {
|
|
82
|
+
lines.push(`Semantically pruned (${prunedIds.length}):`);
|
|
83
|
+
lines.push(...formatPrunedItemsList(prunedIds, toolMetadata, workingDirectory));
|
|
84
|
+
}
|
|
85
|
+
return lines.join("\n").trim();
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../lib/ui/utils.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/package.json",
|
|
3
|
+
"name": "@dev4s/opencode-dcp",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"description": "OpenCode plugin that optimizes token usage by pruning obsolete tool outputs from conversation context",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"scripts": {
|
|
10
|
+
"clean": "rimraf dist",
|
|
11
|
+
"build": "npm run clean && tsc && cpy \"lib/prompts/**/*\" dist/lib/prompts",
|
|
12
|
+
"postbuild": "rimraf dist/logs",
|
|
13
|
+
"prepublishOnly": "npm run build",
|
|
14
|
+
"dev": "opencode plugin dev",
|
|
15
|
+
"typecheck": "tsc --noEmit",
|
|
16
|
+
"test": "node --import tsx --test tests/*.test.ts",
|
|
17
|
+
"format": "prettier --write .",
|
|
18
|
+
"format:check": "prettier --check ."
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"opencode",
|
|
22
|
+
"opencode-plugin",
|
|
23
|
+
"plugin",
|
|
24
|
+
"context",
|
|
25
|
+
"pruning",
|
|
26
|
+
"optimization",
|
|
27
|
+
"tokens"
|
|
28
|
+
],
|
|
29
|
+
"author": "dev4s",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"@opencode-ai/plugin": ">=0.13.7"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@ai-sdk/openai-compatible": "^1.0.28",
|
|
36
|
+
"@opencode-ai/sdk": "latest",
|
|
37
|
+
"@tarquinen/opencode-auth-provider": "^0.1.7",
|
|
38
|
+
"ai": "^5.0.106",
|
|
39
|
+
"gpt-tokenizer": "^3.4.0",
|
|
40
|
+
"jsonc-parser": "^3.3.1",
|
|
41
|
+
"zod": "^4.1.13"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@opencode-ai/plugin": "^1.0.143",
|
|
45
|
+
"@types/node": "^24.10.1",
|
|
46
|
+
"cpy-cli": "^5.0.0",
|
|
47
|
+
"prettier": "^3.4.2",
|
|
48
|
+
"rimraf": "^6.0.0",
|
|
49
|
+
"tsx": "^4.21.0",
|
|
50
|
+
"typescript": "^5.9.3"
|
|
51
|
+
},
|
|
52
|
+
"files": [
|
|
53
|
+
"dist/",
|
|
54
|
+
"README.md",
|
|
55
|
+
"LICENSE"
|
|
56
|
+
]
|
|
57
|
+
}
|