opencode-recall 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 +161 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +123 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/config.d.ts +73 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +779 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/explore-tool.d.ts +11 -0
- package/dist/lib/explore-tool.d.ts.map +1 -0
- package/dist/lib/explore-tool.js +240 -0
- package/dist/lib/explore-tool.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 +58 -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 +3 -0
- package/dist/lib/messages/index.d.ts.map +1 -0
- package/dist/lib/messages/index.js +3 -0
- package/dist/lib/messages/index.js.map +1 -0
- package/dist/lib/messages/inject.d.ts +5 -0
- package/dist/lib/messages/inject.d.ts.map +1 -0
- package/dist/lib/messages/inject.js +114 -0
- package/dist/lib/messages/inject.js.map +1 -0
- package/dist/lib/messages/prune.d.ts +5 -0
- package/dist/lib/messages/prune.d.ts.map +1 -0
- package/dist/lib/messages/prune.js +179 -0
- package/dist/lib/messages/prune.js.map +1 -0
- package/dist/lib/messages/utils.d.ts +10 -0
- package/dist/lib/messages/utils.d.ts.map +1 -0
- package/dist/lib/messages/utils.js +193 -0
- package/dist/lib/messages/utils.js.map +1 -0
- package/dist/lib/prompts/agent/rcl-explorer.d.ts +2 -0
- package/dist/lib/prompts/agent/rcl-explorer.d.ts.map +1 -0
- package/dist/lib/prompts/agent/rcl-explorer.js +39 -0
- package/dist/lib/prompts/agent/rcl-explorer.js.map +1 -0
- package/dist/lib/prompts/discard-tool-spec.d.ts +2 -0
- package/dist/lib/prompts/discard-tool-spec.d.ts.map +1 -0
- package/dist/lib/prompts/discard-tool-spec.js +41 -0
- package/dist/lib/prompts/discard-tool-spec.js.map +1 -0
- package/dist/lib/prompts/extract-tool-spec.d.ts +2 -0
- package/dist/lib/prompts/extract-tool-spec.d.ts.map +1 -0
- package/dist/lib/prompts/extract-tool-spec.js +48 -0
- package/dist/lib/prompts/extract-tool-spec.js.map +1 -0
- package/dist/lib/prompts/index.d.ts +2 -0
- package/dist/lib/prompts/index.d.ts.map +1 -0
- package/dist/lib/prompts/index.js +41 -0
- package/dist/lib/prompts/index.js.map +1 -0
- package/dist/lib/prompts/nudge/both.d.ts +2 -0
- package/dist/lib/prompts/nudge/both.d.ts.map +1 -0
- package/dist/lib/prompts/nudge/both.js +11 -0
- package/dist/lib/prompts/nudge/both.js.map +1 -0
- package/dist/lib/prompts/nudge/discard.d.ts +2 -0
- package/dist/lib/prompts/nudge/discard.d.ts.map +1 -0
- package/dist/lib/prompts/nudge/discard.js +10 -0
- package/dist/lib/prompts/nudge/discard.js.map +1 -0
- package/dist/lib/prompts/nudge/extract.d.ts +2 -0
- package/dist/lib/prompts/nudge/extract.d.ts.map +1 -0
- package/dist/lib/prompts/nudge/extract.js +10 -0
- package/dist/lib/prompts/nudge/extract.js.map +1 -0
- package/dist/lib/prompts/restore-tool-spec.d.ts +2 -0
- package/dist/lib/prompts/restore-tool-spec.d.ts.map +1 -0
- package/dist/lib/prompts/restore-tool-spec.js +21 -0
- package/dist/lib/prompts/restore-tool-spec.js.map +1 -0
- package/dist/lib/prompts/system/both.d.ts +2 -0
- package/dist/lib/prompts/system/both.d.ts.map +1 -0
- package/dist/lib/prompts/system/both.js +72 -0
- package/dist/lib/prompts/system/both.js.map +1 -0
- package/dist/lib/prompts/system/core.d.ts +2 -0
- package/dist/lib/prompts/system/core.d.ts.map +1 -0
- package/dist/lib/prompts/system/core.js +26 -0
- package/dist/lib/prompts/system/core.js.map +1 -0
- package/dist/lib/prompts/system/discard.d.ts +2 -0
- package/dist/lib/prompts/system/discard.d.ts.map +1 -0
- package/dist/lib/prompts/system/discard.js +63 -0
- package/dist/lib/prompts/system/discard.js.map +1 -0
- package/dist/lib/prompts/system/extract.d.ts +2 -0
- package/dist/lib/prompts/system/extract.d.ts.map +1 -0
- package/dist/lib/prompts/system/extract.js +63 -0
- package/dist/lib/prompts/system/extract.js.map +1 -0
- package/dist/lib/protected-file-patterns.d.ts +12 -0
- package/dist/lib/protected-file-patterns.d.ts.map +1 -0
- package/dist/lib/protected-file-patterns.js +69 -0
- package/dist/lib/protected-file-patterns.js.map +1 -0
- package/dist/lib/pruned-blobs.d.ts +19 -0
- package/dist/lib/pruned-blobs.d.ts.map +1 -0
- package/dist/lib/pruned-blobs.js +111 -0
- package/dist/lib/pruned-blobs.js.map +1 -0
- package/dist/lib/rcl-pointer.d.ts +3 -0
- package/dist/lib/rcl-pointer.d.ts.map +1 -0
- package/dist/lib/rcl-pointer.js +63 -0
- package/dist/lib/rcl-pointer.js.map +1 -0
- package/dist/lib/restore-tool.d.ts +15 -0
- package/dist/lib/restore-tool.d.ts.map +1 -0
- package/dist/lib/restore-tool.js +142 -0
- package/dist/lib/restore-tool.js.map +1 -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 +14 -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 +114 -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 +79 -0
- package/dist/lib/state/tool-cache.js.map +1 -0
- package/dist/lib/state/types.d.ts +33 -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 +94 -0
- package/dist/lib/strategies/deduplication.js.map +1 -0
- package/dist/lib/strategies/index.d.ts +5 -0
- package/dist/lib/strategies/index.d.ts.map +1 -0
- package/dist/lib/strategies/index.js +5 -0
- package/dist/lib/strategies/index.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 +59 -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 +84 -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 +135 -0
- package/dist/lib/strategies/tools.js.map +1 -0
- package/dist/lib/strategies/utils.d.ts +13 -0
- package/dist/lib/strategies/utils.d.ts.map +1 -0
- package/dist/lib/strategies/utils.js +93 -0
- package/dist/lib/strategies/utils.js.map +1 -0
- package/dist/lib/ui/notification.d.ts +8 -0
- package/dist/lib/ui/notification.d.ts.map +1 -0
- package/dist/lib/ui/notification.js +54 -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 +63 -0
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { SessionState, WithParts } from "../state";
|
|
2
|
+
import type { Logger } from "../logger";
|
|
3
|
+
import type { PluginConfig } from "../config";
|
|
4
|
+
export declare const insertPruneToolContext: (state: SessionState, config: PluginConfig, logger: Logger, messages: WithParts[]) => void;
|
|
5
|
+
//# sourceMappingURL=inject.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inject.d.ts","sourceRoot":"","sources":["../../../lib/messages/inject.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AACvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAkG7C,eAAO,MAAM,sBAAsB,GAC/B,OAAO,YAAY,EACnB,QAAQ,YAAY,EACpB,QAAQ,MAAM,EACd,UAAU,SAAS,EAAE,KACtB,IA+CF,CAAA"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { loadPrompt } from "../prompts";
|
|
2
|
+
import { extractParameterKey, buildToolIdList, createSyntheticAssistantMessage, isIgnoredUserMessage, } from "./utils";
|
|
3
|
+
import { getFilePathFromParameters, isProtectedFilePath } from "../protected-file-patterns";
|
|
4
|
+
import { getLastUserMessage } from "../shared-utils";
|
|
5
|
+
const getNudgeString = (config) => {
|
|
6
|
+
const discardEnabled = config.tools.discard.enabled;
|
|
7
|
+
const extractEnabled = config.tools.extract.enabled;
|
|
8
|
+
if (discardEnabled && extractEnabled) {
|
|
9
|
+
return loadPrompt(`nudge/nudge-both`);
|
|
10
|
+
}
|
|
11
|
+
else if (discardEnabled) {
|
|
12
|
+
return loadPrompt(`nudge/nudge-discard`);
|
|
13
|
+
}
|
|
14
|
+
else if (extractEnabled) {
|
|
15
|
+
return loadPrompt(`nudge/nudge-extract`);
|
|
16
|
+
}
|
|
17
|
+
return "";
|
|
18
|
+
};
|
|
19
|
+
const wrapPrunableTools = (content) => `<prunable-tools>
|
|
20
|
+
The following tools have been invoked and are available for pruning. This list does not mandate immediate action. Consider your current goals and the resources you need before discarding valuable tool inputs or outputs. Consolidate your prunes for efficiency; it is rarely worth pruning a single tiny tool output. Keep the context free of noise.
|
|
21
|
+
${content}
|
|
22
|
+
</prunable-tools>`;
|
|
23
|
+
const getCooldownMessage = (config) => {
|
|
24
|
+
const discardEnabled = config.tools.discard.enabled;
|
|
25
|
+
const extractEnabled = config.tools.extract.enabled;
|
|
26
|
+
let toolName;
|
|
27
|
+
if (discardEnabled && extractEnabled) {
|
|
28
|
+
toolName = "discard or extract tools";
|
|
29
|
+
}
|
|
30
|
+
else if (discardEnabled) {
|
|
31
|
+
toolName = "discard tool";
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
toolName = "extract tool";
|
|
35
|
+
}
|
|
36
|
+
return `<prunable-tools>
|
|
37
|
+
Context management was just performed. Do not use the ${toolName} again. A fresh list will be available after your next tool use.
|
|
38
|
+
</prunable-tools>`;
|
|
39
|
+
};
|
|
40
|
+
const buildPrunableToolsList = (state, config, logger, messages) => {
|
|
41
|
+
const lines = [];
|
|
42
|
+
const toolIdList = buildToolIdList(state, messages, logger);
|
|
43
|
+
state.toolParameters.forEach((toolParameterEntry, toolCallId) => {
|
|
44
|
+
if (state.prune.toolIds.includes(toolCallId)) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const allProtectedTools = config.tools.settings.protectedTools;
|
|
48
|
+
if (allProtectedTools.includes(toolParameterEntry.tool)) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const filePath = getFilePathFromParameters(toolParameterEntry.parameters);
|
|
52
|
+
if (isProtectedFilePath(filePath, config.protectedFilePatterns)) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const numericId = toolIdList.indexOf(toolCallId);
|
|
56
|
+
if (numericId === -1) {
|
|
57
|
+
logger.warn(`Tool in cache but not in toolIdList - possible stale entry`, {
|
|
58
|
+
toolCallId,
|
|
59
|
+
tool: toolParameterEntry.tool,
|
|
60
|
+
});
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const paramKey = extractParameterKey(toolParameterEntry.tool, toolParameterEntry.parameters);
|
|
64
|
+
const description = paramKey
|
|
65
|
+
? `${toolParameterEntry.tool}, ${paramKey}`
|
|
66
|
+
: toolParameterEntry.tool;
|
|
67
|
+
lines.push(`${numericId}: ${description}`);
|
|
68
|
+
logger.debug(`Prunable tool found - ID: ${numericId}, Tool: ${toolParameterEntry.tool}, Call ID: ${toolCallId}`);
|
|
69
|
+
});
|
|
70
|
+
if (lines.length === 0) {
|
|
71
|
+
return "";
|
|
72
|
+
}
|
|
73
|
+
return wrapPrunableTools(lines.join("\n"));
|
|
74
|
+
};
|
|
75
|
+
export const insertPruneToolContext = (state, config, logger, messages) => {
|
|
76
|
+
if (!config.tools.discard.enabled && !config.tools.extract.enabled) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
let prunableToolsContent;
|
|
80
|
+
if (state.lastToolPrune) {
|
|
81
|
+
logger.debug("Last tool was prune - injecting cooldown message");
|
|
82
|
+
prunableToolsContent = getCooldownMessage(config);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
const prunableToolsList = buildPrunableToolsList(state, config, logger, messages);
|
|
86
|
+
if (!prunableToolsList) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
logger.debug("prunable-tools: \n" + prunableToolsList);
|
|
90
|
+
let nudgeString = "";
|
|
91
|
+
if (config.tools.settings.nudgeEnabled &&
|
|
92
|
+
state.nudgeCounter >= config.tools.settings.nudgeFrequency) {
|
|
93
|
+
logger.info("Inserting prune nudge message");
|
|
94
|
+
nudgeString = "\n" + getNudgeString(config);
|
|
95
|
+
}
|
|
96
|
+
prunableToolsContent = prunableToolsList + nudgeString;
|
|
97
|
+
}
|
|
98
|
+
const lastUserMessage = getLastUserMessage(messages);
|
|
99
|
+
if (!lastUserMessage) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
// Never inject immediately following a user message - wait until assistant has started its turn
|
|
103
|
+
// This avoids interfering with model reasoning/thinking phases
|
|
104
|
+
// TODO: This can be skipped if there is a good way to check if the model has reasoning,
|
|
105
|
+
// can't find a good way to do this yet
|
|
106
|
+
const lastMessage = messages[messages.length - 1];
|
|
107
|
+
if (lastMessage?.info?.role === "user" && !isIgnoredUserMessage(lastMessage)) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const userInfo = lastUserMessage.info;
|
|
111
|
+
const variant = state.variant ?? userInfo.variant;
|
|
112
|
+
messages.push(createSyntheticAssistantMessage(lastUserMessage, prunableToolsContent, variant));
|
|
113
|
+
};
|
|
114
|
+
//# sourceMappingURL=inject.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inject.js","sourceRoot":"","sources":["../../../lib/messages/inject.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { SessionState, WithParts } from "../state";
|
|
2
|
+
import type { Logger } from "../logger";
|
|
3
|
+
import type { PluginConfig } from "../config";
|
|
4
|
+
export declare const prune: (state: SessionState, logger: Logger, config: PluginConfig, messages: WithParts[], workingDirectory: string) => void;
|
|
5
|
+
//# sourceMappingURL=prune.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prune.d.ts","sourceRoot":"","sources":["../../../lib/messages/prune.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AACvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AA8I7C,eAAO,MAAM,KAAK,GACd,OAAO,YAAY,EACnB,QAAQ,MAAM,EACd,QAAQ,YAAY,EACpB,UAAU,SAAS,EAAE,EACrB,kBAAkB,MAAM,KACzB,IAIF,CAAA"}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { isMessageCompacted } from "../shared-utils";
|
|
2
|
+
import { formatBlobPointer, saveBlobIfMissing } from "../pruned-blobs";
|
|
3
|
+
import { extractToolOutputPath } from "../rcl-pointer";
|
|
4
|
+
import { statSync } from "fs";
|
|
5
|
+
import { isAbsolute, resolve } from "path";
|
|
6
|
+
const PRUNED_TOOL_OUTPUT_REPLACEMENT = "[Output removed to save context - information superseded or no longer needed]";
|
|
7
|
+
const PRUNED_TOOL_INPUT_REPLACEMENT = "[input removed to save context]";
|
|
8
|
+
const PRUNED_TOOL_ERROR_INPUT_REPLACEMENT = "[input removed due to failed tool call]";
|
|
9
|
+
const PRUNED_QUESTION_INPUT_REPLACEMENT = "[questions removed - see output for user's answers]";
|
|
10
|
+
function formatApproxCharCount(chars) {
|
|
11
|
+
if (!Number.isFinite(chars) || chars < 0)
|
|
12
|
+
return "0";
|
|
13
|
+
if (chars < 1000)
|
|
14
|
+
return Math.round(chars).toString();
|
|
15
|
+
if (chars < 1_000_000) {
|
|
16
|
+
const k = chars / 1000;
|
|
17
|
+
return `${k.toFixed(1).replace(/\.0$/, "")}K`;
|
|
18
|
+
}
|
|
19
|
+
if (chars < 1_000_000_000) {
|
|
20
|
+
const m = chars / 1_000_000;
|
|
21
|
+
return `${m.toFixed(1).replace(/\.0$/, "")}M`;
|
|
22
|
+
}
|
|
23
|
+
const b = chars / 1_000_000_000;
|
|
24
|
+
return `${b.toFixed(1).replace(/\.0$/, "")}B`;
|
|
25
|
+
}
|
|
26
|
+
function estimateRestoreChars(output, blobPath) {
|
|
27
|
+
if (typeof output === "string") {
|
|
28
|
+
return output.length;
|
|
29
|
+
}
|
|
30
|
+
// Approximation for non-string outputs: reading + stringifying again can be expensive.
|
|
31
|
+
// The blob file size (bytes) is a reasonable upper-bound proxy for "restored chars" for ASCII-heavy data.
|
|
32
|
+
return estimateRestoreCharsFromFile(blobPath);
|
|
33
|
+
}
|
|
34
|
+
function estimateRestoreCharsFromFile(filePath) {
|
|
35
|
+
try {
|
|
36
|
+
const stats = statSync(filePath);
|
|
37
|
+
return typeof stats.size === "number" ? stats.size : null;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function buildOutputReplacement(state, logger, callID, output, workingDirectory) {
|
|
44
|
+
const outputText = typeof output === "string" ? output : "";
|
|
45
|
+
const toolOutputPath = outputText ? extractToolOutputPath(outputText) : "";
|
|
46
|
+
if (toolOutputPath) {
|
|
47
|
+
const absPath = isAbsolute(toolOutputPath)
|
|
48
|
+
? resolve(toolOutputPath)
|
|
49
|
+
: resolve(workingDirectory, toolOutputPath);
|
|
50
|
+
const restoreChars = estimateRestoreCharsFromFile(absPath);
|
|
51
|
+
const note = restoreChars && restoreChars > 0
|
|
52
|
+
? `\n(restore_chars≈${formatApproxCharCount(restoreChars)})`
|
|
53
|
+
: "";
|
|
54
|
+
return `[RCL:o:${toolOutputPath}]${note}`;
|
|
55
|
+
}
|
|
56
|
+
const blobPath = saveBlobIfMissing(state.sessionId, callID, "tool-output", output, workingDirectory, logger);
|
|
57
|
+
if (!blobPath) {
|
|
58
|
+
return PRUNED_TOOL_OUTPUT_REPLACEMENT;
|
|
59
|
+
}
|
|
60
|
+
const pointer = formatBlobPointer(blobPath, workingDirectory);
|
|
61
|
+
const restoreChars = estimateRestoreChars(output, blobPath);
|
|
62
|
+
const note = restoreChars && restoreChars > 0
|
|
63
|
+
? `\n(restore_chars≈${formatApproxCharCount(restoreChars)})`
|
|
64
|
+
: "";
|
|
65
|
+
return `[RCL:o:${pointer}]${note}`;
|
|
66
|
+
}
|
|
67
|
+
function maybePruneLargeInputStrings(state, logger, callID, tool, input, workingDirectory, opts) {
|
|
68
|
+
if (!input || typeof input !== "object") {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
// Keep small, high-signal fields (esp. file pointers) so the model can still recover context.
|
|
72
|
+
const protectedKeys = new Set(["filePath", "path", "offset", "limit"]);
|
|
73
|
+
const keys = Object.keys(input);
|
|
74
|
+
// Only bother persisting if we will actually prune something.
|
|
75
|
+
const shouldPruneKey = (key, value) => {
|
|
76
|
+
if (protectedKeys.has(key))
|
|
77
|
+
return false;
|
|
78
|
+
if (typeof value !== "string")
|
|
79
|
+
return false;
|
|
80
|
+
// Heuristic: only prune "large" string inputs. This keeps short args intact.
|
|
81
|
+
// This matches the intent of purgeErrors/supersedeWrites: remove bulky inputs.
|
|
82
|
+
const MIN_LEN = 200;
|
|
83
|
+
return value.length >= MIN_LEN;
|
|
84
|
+
};
|
|
85
|
+
const prunableKeys = keys.filter((k) => shouldPruneKey(k, input[k]));
|
|
86
|
+
if (prunableKeys.length === 0) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const blobPath = saveBlobIfMissing(state.sessionId, callID, "tool-input", input, workingDirectory, logger);
|
|
90
|
+
const replacementBase = opts?.errorMode === true
|
|
91
|
+
? PRUNED_TOOL_ERROR_INPUT_REPLACEMENT
|
|
92
|
+
: PRUNED_TOOL_INPUT_REPLACEMENT;
|
|
93
|
+
for (const key of prunableKeys) {
|
|
94
|
+
;
|
|
95
|
+
input[key] = blobPath
|
|
96
|
+
? `[RCL:i:${formatBlobPointer(blobPath, workingDirectory)}]`
|
|
97
|
+
: replacementBase;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
export const prune = (state, logger, config, messages, workingDirectory) => {
|
|
101
|
+
pruneToolOutputs(state, logger, messages, workingDirectory);
|
|
102
|
+
pruneToolInputs(state, logger, messages, workingDirectory);
|
|
103
|
+
pruneToolErrors(state, logger, messages, workingDirectory);
|
|
104
|
+
};
|
|
105
|
+
const pruneToolOutputs = (state, logger, messages, workingDirectory) => {
|
|
106
|
+
for (const msg of messages) {
|
|
107
|
+
if (isMessageCompacted(state, msg)) {
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
for (const part of msg.parts) {
|
|
111
|
+
if (part.type !== "tool") {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (!state.prune.toolIds.includes(part.callID)) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if (part.state.status !== "completed") {
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (part.tool === "question") {
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
part.state.output = buildOutputReplacement(state, logger, part.callID, part.state.output, workingDirectory);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
const pruneToolInputs = (state, logger, messages, workingDirectory) => {
|
|
128
|
+
for (const msg of messages) {
|
|
129
|
+
if (isMessageCompacted(state, msg)) {
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
for (const part of msg.parts) {
|
|
133
|
+
if (part.type !== "tool") {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
if (!state.prune.toolIds.includes(part.callID)) {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
if (part.state.status !== "completed") {
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
if (part.tool !== "question") {
|
|
143
|
+
// Supersede writes: remove bulky write/edit inputs (content/patch/etc) but keep filePath.
|
|
144
|
+
// This is also safe for LLM-driven discard/extract when the user wants to offload the input.
|
|
145
|
+
if (part.tool === "write" || part.tool === "edit") {
|
|
146
|
+
maybePruneLargeInputStrings(state, logger, part.callID, part.tool, part.state.input, workingDirectory);
|
|
147
|
+
}
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
if (part.state.input?.questions !== undefined) {
|
|
151
|
+
const blobPath = saveBlobIfMissing(state.sessionId, part.callID, "tool-input", part.state.input, workingDirectory, logger);
|
|
152
|
+
part.state.input.questions = blobPath
|
|
153
|
+
? `[RCL:i:${formatBlobPointer(blobPath, workingDirectory)}]`
|
|
154
|
+
: PRUNED_QUESTION_INPUT_REPLACEMENT;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
const pruneToolErrors = (state, logger, messages, workingDirectory) => {
|
|
160
|
+
for (const msg of messages) {
|
|
161
|
+
if (isMessageCompacted(state, msg)) {
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
for (const part of msg.parts) {
|
|
165
|
+
if (part.type !== "tool") {
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
if (!state.prune.toolIds.includes(part.callID)) {
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
if (part.state.status !== "error") {
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
// Prune bulky string inputs for errored tools, but keep small/high-signal values (e.g. filePath).
|
|
175
|
+
maybePruneLargeInputStrings(state, logger, part.callID, part.tool, part.state.input, workingDirectory, { errorMode: true });
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
//# sourceMappingURL=prune.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prune.js","sourceRoot":"","sources":["../../../lib/messages/prune.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Logger } from "../logger";
|
|
2
|
+
import type { SessionState, WithParts } from "../state";
|
|
3
|
+
export declare const createSyntheticAssistantMessage: (baseMessage: WithParts, content: string, variant?: string) => WithParts;
|
|
4
|
+
/**
|
|
5
|
+
* Extracts a human-readable key from tool metadata for display purposes.
|
|
6
|
+
*/
|
|
7
|
+
export declare const extractParameterKey: (tool: string, parameters: any) => string;
|
|
8
|
+
export declare function buildToolIdList(state: SessionState, messages: WithParts[], logger: Logger): string[];
|
|
9
|
+
export declare const isIgnoredUserMessage: (message: WithParts) => boolean;
|
|
10
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../lib/messages/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAElC,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAYvD,eAAO,MAAM,+BAA+B,GACxC,aAAa,SAAS,EACtB,SAAS,MAAM,EACf,UAAU,MAAM,KACjB,SAkDF,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB,GAAI,MAAM,MAAM,EAAE,YAAY,GAAG,KAAG,MAkHnE,CAAA;AAED,wBAAgB,eAAe,CAC3B,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,SAAS,EAAE,EACrB,MAAM,EAAE,MAAM,GACf,MAAM,EAAE,CAeV;AAED,eAAO,MAAM,oBAAoB,GAAI,SAAS,SAAS,KAAG,OAYzD,CAAA"}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { isMessageCompacted } from "../shared-utils";
|
|
2
|
+
const SYNTHETIC_MESSAGE_ID = "msg_01234567890123456789012345";
|
|
3
|
+
const SYNTHETIC_PART_ID = "prt_01234567890123456789012345";
|
|
4
|
+
const SYNTHETIC_CALL_ID = "call_01234567890123456789012345";
|
|
5
|
+
const isGeminiModel = (modelID) => {
|
|
6
|
+
const lowerModelID = modelID.toLowerCase();
|
|
7
|
+
return lowerModelID.includes("gemini");
|
|
8
|
+
};
|
|
9
|
+
export const createSyntheticAssistantMessage = (baseMessage, content, variant) => {
|
|
10
|
+
const userInfo = baseMessage.info;
|
|
11
|
+
const now = Date.now();
|
|
12
|
+
const baseInfo = {
|
|
13
|
+
id: SYNTHETIC_MESSAGE_ID,
|
|
14
|
+
sessionID: userInfo.sessionID,
|
|
15
|
+
role: "assistant",
|
|
16
|
+
agent: userInfo.agent || "code",
|
|
17
|
+
parentID: userInfo.id,
|
|
18
|
+
modelID: userInfo.model.modelID,
|
|
19
|
+
providerID: userInfo.model.providerID,
|
|
20
|
+
mode: "default",
|
|
21
|
+
path: {
|
|
22
|
+
cwd: "/",
|
|
23
|
+
root: "/",
|
|
24
|
+
},
|
|
25
|
+
time: { created: now, completed: now },
|
|
26
|
+
cost: 0,
|
|
27
|
+
tokens: { input: 0, output: 0, reasoning: 0, cache: { read: 0, write: 0 } },
|
|
28
|
+
...(variant !== undefined && { variant }),
|
|
29
|
+
};
|
|
30
|
+
// For Gemini models, add thoughtSignature bypass to avoid validation errors
|
|
31
|
+
const toolPartMetadata = isGeminiModel(userInfo.model.modelID)
|
|
32
|
+
? { google: { thoughtSignature: "skip_thought_signature_validator" } }
|
|
33
|
+
: undefined;
|
|
34
|
+
return {
|
|
35
|
+
info: baseInfo,
|
|
36
|
+
parts: [
|
|
37
|
+
{
|
|
38
|
+
id: SYNTHETIC_PART_ID,
|
|
39
|
+
sessionID: userInfo.sessionID,
|
|
40
|
+
messageID: SYNTHETIC_MESSAGE_ID,
|
|
41
|
+
type: "tool",
|
|
42
|
+
callID: SYNTHETIC_CALL_ID,
|
|
43
|
+
tool: "context_info",
|
|
44
|
+
state: {
|
|
45
|
+
status: "completed",
|
|
46
|
+
input: {},
|
|
47
|
+
output: content,
|
|
48
|
+
title: "Context Info",
|
|
49
|
+
metadata: {},
|
|
50
|
+
time: { start: now, end: now },
|
|
51
|
+
},
|
|
52
|
+
...(toolPartMetadata && { metadata: toolPartMetadata }),
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Extracts a human-readable key from tool metadata for display purposes.
|
|
59
|
+
*/
|
|
60
|
+
export const extractParameterKey = (tool, parameters) => {
|
|
61
|
+
if (!parameters)
|
|
62
|
+
return "";
|
|
63
|
+
if (tool === "read" && parameters.filePath) {
|
|
64
|
+
const offset = parameters.offset;
|
|
65
|
+
const limit = parameters.limit;
|
|
66
|
+
if (offset !== undefined && limit !== undefined) {
|
|
67
|
+
return `${parameters.filePath} (lines ${offset}-${offset + limit})`;
|
|
68
|
+
}
|
|
69
|
+
if (offset !== undefined) {
|
|
70
|
+
return `${parameters.filePath} (lines ${offset}+)`;
|
|
71
|
+
}
|
|
72
|
+
if (limit !== undefined) {
|
|
73
|
+
return `${parameters.filePath} (lines 0-${limit})`;
|
|
74
|
+
}
|
|
75
|
+
return parameters.filePath;
|
|
76
|
+
}
|
|
77
|
+
if (tool === "write" && parameters.filePath) {
|
|
78
|
+
return parameters.filePath;
|
|
79
|
+
}
|
|
80
|
+
if (tool === "edit" && parameters.filePath) {
|
|
81
|
+
return parameters.filePath;
|
|
82
|
+
}
|
|
83
|
+
if (tool === "list") {
|
|
84
|
+
return parameters.path || "(current directory)";
|
|
85
|
+
}
|
|
86
|
+
if (tool === "glob") {
|
|
87
|
+
if (parameters.pattern) {
|
|
88
|
+
const pathInfo = parameters.path ? ` in ${parameters.path}` : "";
|
|
89
|
+
return `"${parameters.pattern}"${pathInfo}`;
|
|
90
|
+
}
|
|
91
|
+
return "(unknown pattern)";
|
|
92
|
+
}
|
|
93
|
+
if (tool === "grep") {
|
|
94
|
+
if (parameters.pattern) {
|
|
95
|
+
const pathInfo = parameters.path ? ` in ${parameters.path}` : "";
|
|
96
|
+
return `"${parameters.pattern}"${pathInfo}`;
|
|
97
|
+
}
|
|
98
|
+
return "(unknown pattern)";
|
|
99
|
+
}
|
|
100
|
+
if (tool === "bash") {
|
|
101
|
+
if (parameters.description)
|
|
102
|
+
return parameters.description;
|
|
103
|
+
if (parameters.command) {
|
|
104
|
+
return parameters.command.length > 50
|
|
105
|
+
? parameters.command.substring(0, 50) + "..."
|
|
106
|
+
: parameters.command;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (tool === "webfetch" && parameters.url) {
|
|
110
|
+
return parameters.url;
|
|
111
|
+
}
|
|
112
|
+
if (tool === "websearch" && parameters.query) {
|
|
113
|
+
return `"${parameters.query}"`;
|
|
114
|
+
}
|
|
115
|
+
if (tool === "codesearch" && parameters.query) {
|
|
116
|
+
return `"${parameters.query}"`;
|
|
117
|
+
}
|
|
118
|
+
if (tool === "todowrite") {
|
|
119
|
+
return `${parameters.todos?.length || 0} todos`;
|
|
120
|
+
}
|
|
121
|
+
if (tool === "todoread") {
|
|
122
|
+
return "read todo list";
|
|
123
|
+
}
|
|
124
|
+
if (tool === "task" && parameters.description) {
|
|
125
|
+
return parameters.description;
|
|
126
|
+
}
|
|
127
|
+
if (tool === "skill" && parameters.name) {
|
|
128
|
+
return parameters.name;
|
|
129
|
+
}
|
|
130
|
+
if (tool === "lsp") {
|
|
131
|
+
const op = parameters.operation || "lsp";
|
|
132
|
+
const path = parameters.filePath || "";
|
|
133
|
+
const line = parameters.line;
|
|
134
|
+
const char = parameters.character;
|
|
135
|
+
if (path && line !== undefined && char !== undefined) {
|
|
136
|
+
return `${op} ${path}:${line}:${char}`;
|
|
137
|
+
}
|
|
138
|
+
if (path) {
|
|
139
|
+
return `${op} ${path}`;
|
|
140
|
+
}
|
|
141
|
+
return op;
|
|
142
|
+
}
|
|
143
|
+
if (tool === "question") {
|
|
144
|
+
const questions = parameters.questions;
|
|
145
|
+
if (Array.isArray(questions) && questions.length > 0) {
|
|
146
|
+
const headers = questions
|
|
147
|
+
.map((q) => q.header || "")
|
|
148
|
+
.filter(Boolean)
|
|
149
|
+
.slice(0, 3);
|
|
150
|
+
const count = questions.length;
|
|
151
|
+
const plural = count > 1 ? "s" : "";
|
|
152
|
+
if (headers.length > 0) {
|
|
153
|
+
const suffix = count > 3 ? ` (+${count - 3} more)` : "";
|
|
154
|
+
return `${count} question${plural}: ${headers.join(", ")}${suffix}`;
|
|
155
|
+
}
|
|
156
|
+
return `${count} question${plural}`;
|
|
157
|
+
}
|
|
158
|
+
return "question";
|
|
159
|
+
}
|
|
160
|
+
const paramStr = JSON.stringify(parameters);
|
|
161
|
+
if (paramStr === "{}" || paramStr === "[]" || paramStr === "null") {
|
|
162
|
+
return "";
|
|
163
|
+
}
|
|
164
|
+
return paramStr.substring(0, 50);
|
|
165
|
+
};
|
|
166
|
+
export function buildToolIdList(state, messages, logger) {
|
|
167
|
+
const toolIds = [];
|
|
168
|
+
for (const msg of messages) {
|
|
169
|
+
if (isMessageCompacted(state, msg)) {
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
if (msg.parts) {
|
|
173
|
+
for (const part of msg.parts) {
|
|
174
|
+
if (part.type === "tool" && part.callID && part.tool) {
|
|
175
|
+
toolIds.push(part.callID);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return toolIds;
|
|
181
|
+
}
|
|
182
|
+
export const isIgnoredUserMessage = (message) => {
|
|
183
|
+
if (!message.parts || message.parts.length === 0) {
|
|
184
|
+
return true;
|
|
185
|
+
}
|
|
186
|
+
for (const part of message.parts) {
|
|
187
|
+
if (!part.ignored) {
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return true;
|
|
192
|
+
};
|
|
193
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../lib/messages/utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const RCL_EXPLORER_PROMPT = "You are RCL Explorer - a read-only specialist for exploring Recall (RCL) blobs.\n\n## Mission\nGiven a Recall blob pointer (a path under `.opencode/rcl/blobs/<sessionId>/...`) or an OpenCode tool-output path, and a user question, retrieve the content and answer with minimal context.\n\nThis environment uses Recall (RCL). When you see pointers like:\n- `[RCL:o:<path>]` (tool output)\n- `[RCL:i:<path>]` (tool input)\nor OpenCode truncation notices like:\n- `Full output saved to: /.../tool-output/...`\nyou MUST restore the original content instead of guessing.\n\n## Primary Tool\n- Use `rcl_restore(path=\"...\")` to restore the original content from the blob's `data` field (or the OpenCode tool-output file).\n\n## Output Constraints (CRITICAL)\n- DO NOT paste the full restored content.\n- Only quote the smallest excerpts needed to support your answer.\n- If you need to cite multiple places, prefer multiple short quotes over one long quote.\n- If the blob is huge and you cannot confidently answer, say so and suggest a narrower query.\n\n## Output Format\nReturn ONLY the following XML-ish block:\n\n<rcl_explorer_result>\n<answer>\n1-5 bullet points answering the question.\n</answer>\n<quotes>\n- Quote 1 (keep short, include enough surrounding context to be meaningful)\n- Quote 2 (optional)\n</quotes>\n<notes>\n- (optional) If relevant: what you searched for / where in the blob the quote came from (keywords, section headers).\n- (optional) If you are unsure: what to ask next to narrow the search.\n</notes>\n</rcl_explorer_result>\n";
|
|
2
|
+
//# sourceMappingURL=rcl-explorer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rcl-explorer.d.ts","sourceRoot":"","sources":["../../../../lib/prompts/agent/rcl-explorer.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,ohDAqC/B,CAAA"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export const RCL_EXPLORER_PROMPT = `You are RCL Explorer - a read-only specialist for exploring Recall (RCL) blobs.
|
|
2
|
+
|
|
3
|
+
## Mission
|
|
4
|
+
Given a Recall blob pointer (a path under \`.opencode/rcl/blobs/<sessionId>/...\`) or an OpenCode tool-output path, and a user question, retrieve the content and answer with minimal context.
|
|
5
|
+
|
|
6
|
+
This environment uses Recall (RCL). When you see pointers like:
|
|
7
|
+
- \`[RCL:o:<path>]\` (tool output)
|
|
8
|
+
- \`[RCL:i:<path>]\` (tool input)
|
|
9
|
+
or OpenCode truncation notices like:
|
|
10
|
+
- \`Full output saved to: /.../tool-output/...\`
|
|
11
|
+
you MUST restore the original content instead of guessing.
|
|
12
|
+
|
|
13
|
+
## Primary Tool
|
|
14
|
+
- Use \`rcl_restore(path="...")\` to restore the original content from the blob's \`data\` field (or the OpenCode tool-output file).
|
|
15
|
+
|
|
16
|
+
## Output Constraints (CRITICAL)
|
|
17
|
+
- DO NOT paste the full restored content.
|
|
18
|
+
- Only quote the smallest excerpts needed to support your answer.
|
|
19
|
+
- If you need to cite multiple places, prefer multiple short quotes over one long quote.
|
|
20
|
+
- If the blob is huge and you cannot confidently answer, say so and suggest a narrower query.
|
|
21
|
+
|
|
22
|
+
## Output Format
|
|
23
|
+
Return ONLY the following XML-ish block:
|
|
24
|
+
|
|
25
|
+
<rcl_explorer_result>
|
|
26
|
+
<answer>
|
|
27
|
+
1-5 bullet points answering the question.
|
|
28
|
+
</answer>
|
|
29
|
+
<quotes>
|
|
30
|
+
- Quote 1 (keep short, include enough surrounding context to be meaningful)
|
|
31
|
+
- Quote 2 (optional)
|
|
32
|
+
</quotes>
|
|
33
|
+
<notes>
|
|
34
|
+
- (optional) If relevant: what you searched for / where in the blob the quote came from (keywords, section headers).
|
|
35
|
+
- (optional) If you are unsure: what to ask next to narrow the search.
|
|
36
|
+
</notes>
|
|
37
|
+
</rcl_explorer_result>
|
|
38
|
+
`;
|
|
39
|
+
//# sourceMappingURL=rcl-explorer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rcl-explorer.js","sourceRoot":"","sources":["../../../../lib/prompts/agent/rcl-explorer.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqClC,CAAA"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const DISCARD_TOOL_SPEC = "Offloads tool outputs to disk and replaces them with pointers to manage conversation size and reduce noise.\n\n## IMPORTANT: The Prunable List\nA `<prunable-tools>` list is provided to you showing available tool outputs you can discard when there are tools available for pruning. Each line has the format `ID: tool, parameter` (e.g., `20: read, /path/to/file.ts`). You MUST only use numeric IDs that appear in this list to select which tools to discard.\n\n## When to Use This Tool\n\nUse `discard` for removing tool content that is no longer needed from the immediate context. The raw content is offloaded and remains recoverable via the pointer.\n\n- **Noise:** Irrelevant, unhelpful, or superseded outputs that provide no value.\n- **Task Completion:** Work is complete and there's no valuable information worth preserving.\n\n## When NOT to Use This Tool\n\n- **If the output contains useful information:** Use `extract` instead to preserve key findings.\n- **If you'll need the output later:** Don't discard files you plan to edit or context you'll need for implementation.\n\n## Best Practices\n- **Strategic Batching:** Don't discard single small tool outputs (like short bash commands) unless they are pure noise. Wait until you have several items to perform high-impact discards.\n- **Think ahead:** Before discarding, ask: \"Will I need this output for an upcoming task?\" If yes, keep it.\n\n## Format\n\n- `ids`: Array where the first element is the reason, followed by numeric IDs from the `<prunable-tools>` list\n\nReasons: `noise` | `completion`\n\n## Example\n\n<example_noise>\nAssistant: [Reads 'wrong_file.ts']\nThis file isn't relevant to the auth system. I'll remove it to clear the context.\n[Uses discard with ids: [\"noise\", \"5\"]]\n</example_noise>\n\n<example_completion>\nAssistant: [Runs tests, they pass]\nThe tests passed and I don't need to preserve any details. I'll clean up now.\n[Uses discard with ids: [\"completion\", \"20\", \"21\"]]\n</example_completion>";
|
|
2
|
+
//# sourceMappingURL=discard-tool-spec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discard-tool-spec.d.ts","sourceRoot":"","sources":["../../../lib/prompts/discard-tool-spec.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,k9DAuCR,CAAA"}
|