@rdmind/rdmind 0.0.21-alpha.1 → 0.0.21
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/cli.js +617 -521
- package/package.json +2 -2
package/cli.js
CHANGED
|
@@ -183747,7 +183747,7 @@ function createContentGeneratorConfig(config, authType, generationConfig) {
|
|
|
183747
183747
|
};
|
|
183748
183748
|
}
|
|
183749
183749
|
async function createContentGenerator(config, gcConfig, sessionId2) {
|
|
183750
|
-
const version2 = "0.0.21
|
|
183750
|
+
const version2 = "0.0.21";
|
|
183751
183751
|
const userAgent2 = `QwenCode/${version2} (${process.platform}; ${process.arch})`;
|
|
183752
183752
|
const baseHeaders = {
|
|
183753
183753
|
"User-Agent": userAgent2
|
|
@@ -200491,6 +200491,506 @@ ${[...this.pendingCitations].sort().join("\n")}`
|
|
|
200491
200491
|
}
|
|
200492
200492
|
});
|
|
200493
200493
|
|
|
200494
|
+
// packages/core/src/config/constants.ts
|
|
200495
|
+
var DEFAULT_MEMORY_FILE_FILTERING_OPTIONS, DEFAULT_FILE_FILTERING_OPTIONS;
|
|
200496
|
+
var init_constants3 = __esm({
|
|
200497
|
+
"packages/core/src/config/constants.ts"() {
|
|
200498
|
+
"use strict";
|
|
200499
|
+
init_esbuild_shims();
|
|
200500
|
+
DEFAULT_MEMORY_FILE_FILTERING_OPTIONS = {
|
|
200501
|
+
respectGitIgnore: false,
|
|
200502
|
+
respectQwenIgnore: true
|
|
200503
|
+
};
|
|
200504
|
+
DEFAULT_FILE_FILTERING_OPTIONS = {
|
|
200505
|
+
respectGitIgnore: true,
|
|
200506
|
+
respectQwenIgnore: true
|
|
200507
|
+
};
|
|
200508
|
+
}
|
|
200509
|
+
});
|
|
200510
|
+
|
|
200511
|
+
// packages/core/src/utils/getFolderStructure.ts
|
|
200512
|
+
import * as fs24 from "node:fs/promises";
|
|
200513
|
+
import * as path21 from "node:path";
|
|
200514
|
+
async function readFullStructure(rootPath, options2) {
|
|
200515
|
+
const rootName = path21.basename(rootPath);
|
|
200516
|
+
const rootNode = {
|
|
200517
|
+
name: rootName,
|
|
200518
|
+
path: rootPath,
|
|
200519
|
+
files: [],
|
|
200520
|
+
subFolders: [],
|
|
200521
|
+
totalChildren: 0,
|
|
200522
|
+
totalFiles: 0
|
|
200523
|
+
};
|
|
200524
|
+
const queue = [
|
|
200525
|
+
{ folderInfo: rootNode, currentPath: rootPath }
|
|
200526
|
+
];
|
|
200527
|
+
let currentItemCount = 0;
|
|
200528
|
+
const processedPaths = /* @__PURE__ */ new Set();
|
|
200529
|
+
while (queue.length > 0) {
|
|
200530
|
+
const { folderInfo, currentPath } = queue.shift();
|
|
200531
|
+
if (processedPaths.has(currentPath)) {
|
|
200532
|
+
continue;
|
|
200533
|
+
}
|
|
200534
|
+
processedPaths.add(currentPath);
|
|
200535
|
+
if (currentItemCount >= options2.maxItems) {
|
|
200536
|
+
continue;
|
|
200537
|
+
}
|
|
200538
|
+
let entries;
|
|
200539
|
+
try {
|
|
200540
|
+
const rawEntries = await fs24.readdir(currentPath, { withFileTypes: true });
|
|
200541
|
+
entries = rawEntries.sort((a, b) => a.name.localeCompare(b.name));
|
|
200542
|
+
} catch (error) {
|
|
200543
|
+
if (isNodeError(error) && (error.code === "EACCES" || error.code === "ENOENT")) {
|
|
200544
|
+
console.warn(
|
|
200545
|
+
`Warning: Could not read directory ${currentPath}: ${error.message}`
|
|
200546
|
+
);
|
|
200547
|
+
if (currentPath === rootPath && error.code === "ENOENT") {
|
|
200548
|
+
return null;
|
|
200549
|
+
}
|
|
200550
|
+
continue;
|
|
200551
|
+
}
|
|
200552
|
+
throw error;
|
|
200553
|
+
}
|
|
200554
|
+
const filesInCurrentDir = [];
|
|
200555
|
+
const subFoldersInCurrentDir = [];
|
|
200556
|
+
for (const entry of entries) {
|
|
200557
|
+
if (entry.isFile()) {
|
|
200558
|
+
if (currentItemCount >= options2.maxItems) {
|
|
200559
|
+
folderInfo.hasMoreFiles = true;
|
|
200560
|
+
break;
|
|
200561
|
+
}
|
|
200562
|
+
const fileName = entry.name;
|
|
200563
|
+
const filePath = path21.join(currentPath, fileName);
|
|
200564
|
+
if (options2.fileService) {
|
|
200565
|
+
const shouldIgnore = options2.fileFilteringOptions.respectGitIgnore && options2.fileService.shouldGitIgnoreFile(filePath) || options2.fileFilteringOptions.respectQwenIgnore && options2.fileService.shouldQwenIgnoreFile(filePath);
|
|
200566
|
+
if (shouldIgnore) {
|
|
200567
|
+
continue;
|
|
200568
|
+
}
|
|
200569
|
+
}
|
|
200570
|
+
if (!options2.fileIncludePattern || options2.fileIncludePattern.test(fileName)) {
|
|
200571
|
+
filesInCurrentDir.push(fileName);
|
|
200572
|
+
currentItemCount++;
|
|
200573
|
+
folderInfo.totalFiles++;
|
|
200574
|
+
folderInfo.totalChildren++;
|
|
200575
|
+
}
|
|
200576
|
+
}
|
|
200577
|
+
}
|
|
200578
|
+
folderInfo.files = filesInCurrentDir;
|
|
200579
|
+
for (const entry of entries) {
|
|
200580
|
+
if (entry.isDirectory()) {
|
|
200581
|
+
if (currentItemCount >= options2.maxItems) {
|
|
200582
|
+
folderInfo.hasMoreSubfolders = true;
|
|
200583
|
+
break;
|
|
200584
|
+
}
|
|
200585
|
+
const subFolderName = entry.name;
|
|
200586
|
+
const subFolderPath = path21.join(currentPath, subFolderName);
|
|
200587
|
+
let isIgnored = false;
|
|
200588
|
+
if (options2.fileService) {
|
|
200589
|
+
isIgnored = options2.fileFilteringOptions.respectGitIgnore && options2.fileService.shouldGitIgnoreFile(subFolderPath) || options2.fileFilteringOptions.respectQwenIgnore && options2.fileService.shouldQwenIgnoreFile(subFolderPath);
|
|
200590
|
+
}
|
|
200591
|
+
if (options2.ignoredFolders.has(subFolderName) || isIgnored) {
|
|
200592
|
+
const ignoredSubFolder = {
|
|
200593
|
+
name: subFolderName,
|
|
200594
|
+
path: subFolderPath,
|
|
200595
|
+
files: [],
|
|
200596
|
+
subFolders: [],
|
|
200597
|
+
totalChildren: 0,
|
|
200598
|
+
totalFiles: 0,
|
|
200599
|
+
isIgnored: true
|
|
200600
|
+
};
|
|
200601
|
+
subFoldersInCurrentDir.push(ignoredSubFolder);
|
|
200602
|
+
currentItemCount++;
|
|
200603
|
+
folderInfo.totalChildren++;
|
|
200604
|
+
continue;
|
|
200605
|
+
}
|
|
200606
|
+
const subFolderNode = {
|
|
200607
|
+
name: subFolderName,
|
|
200608
|
+
path: subFolderPath,
|
|
200609
|
+
files: [],
|
|
200610
|
+
subFolders: [],
|
|
200611
|
+
totalChildren: 0,
|
|
200612
|
+
totalFiles: 0
|
|
200613
|
+
};
|
|
200614
|
+
subFoldersInCurrentDir.push(subFolderNode);
|
|
200615
|
+
currentItemCount++;
|
|
200616
|
+
folderInfo.totalChildren++;
|
|
200617
|
+
queue.push({ folderInfo: subFolderNode, currentPath: subFolderPath });
|
|
200618
|
+
}
|
|
200619
|
+
}
|
|
200620
|
+
folderInfo.subFolders = subFoldersInCurrentDir;
|
|
200621
|
+
}
|
|
200622
|
+
return rootNode;
|
|
200623
|
+
}
|
|
200624
|
+
function formatStructure(node, currentIndent, isLastChildOfParent, isProcessingRootNode, builder) {
|
|
200625
|
+
const connector = isLastChildOfParent ? "\u2514\u2500\u2500\u2500" : "\u251C\u2500\u2500\u2500";
|
|
200626
|
+
if (!isProcessingRootNode || node.isIgnored) {
|
|
200627
|
+
builder.push(
|
|
200628
|
+
`${currentIndent}${connector}${node.name}${path21.sep}${node.isIgnored ? TRUNCATION_INDICATOR : ""}`
|
|
200629
|
+
);
|
|
200630
|
+
}
|
|
200631
|
+
const indentForChildren = isProcessingRootNode ? "" : currentIndent + (isLastChildOfParent ? " " : "\u2502 ");
|
|
200632
|
+
const fileCount = node.files.length;
|
|
200633
|
+
for (let i = 0; i < fileCount; i++) {
|
|
200634
|
+
const isLastFileAmongSiblings = i === fileCount - 1 && node.subFolders.length === 0 && !node.hasMoreSubfolders;
|
|
200635
|
+
const fileConnector = isLastFileAmongSiblings ? "\u2514\u2500\u2500\u2500" : "\u251C\u2500\u2500\u2500";
|
|
200636
|
+
builder.push(`${indentForChildren}${fileConnector}${node.files[i]}`);
|
|
200637
|
+
}
|
|
200638
|
+
if (node.hasMoreFiles) {
|
|
200639
|
+
const isLastIndicatorAmongSiblings = node.subFolders.length === 0 && !node.hasMoreSubfolders;
|
|
200640
|
+
const fileConnector = isLastIndicatorAmongSiblings ? "\u2514\u2500\u2500\u2500" : "\u251C\u2500\u2500\u2500";
|
|
200641
|
+
builder.push(`${indentForChildren}${fileConnector}${TRUNCATION_INDICATOR}`);
|
|
200642
|
+
}
|
|
200643
|
+
const subFolderCount = node.subFolders.length;
|
|
200644
|
+
for (let i = 0; i < subFolderCount; i++) {
|
|
200645
|
+
const isLastSubfolderAmongSiblings = i === subFolderCount - 1 && !node.hasMoreSubfolders;
|
|
200646
|
+
formatStructure(
|
|
200647
|
+
node.subFolders[i],
|
|
200648
|
+
indentForChildren,
|
|
200649
|
+
isLastSubfolderAmongSiblings,
|
|
200650
|
+
false,
|
|
200651
|
+
builder
|
|
200652
|
+
);
|
|
200653
|
+
}
|
|
200654
|
+
if (node.hasMoreSubfolders) {
|
|
200655
|
+
builder.push(`${indentForChildren}\u2514\u2500\u2500\u2500${TRUNCATION_INDICATOR}`);
|
|
200656
|
+
}
|
|
200657
|
+
}
|
|
200658
|
+
async function getFolderStructure(directory, options2) {
|
|
200659
|
+
const resolvedPath = path21.resolve(directory);
|
|
200660
|
+
const mergedOptions = {
|
|
200661
|
+
maxItems: options2?.maxItems ?? MAX_ITEMS,
|
|
200662
|
+
ignoredFolders: options2?.ignoredFolders ?? DEFAULT_IGNORED_FOLDERS,
|
|
200663
|
+
fileIncludePattern: options2?.fileIncludePattern,
|
|
200664
|
+
fileService: options2?.fileService,
|
|
200665
|
+
fileFilteringOptions: options2?.fileFilteringOptions ?? DEFAULT_FILE_FILTERING_OPTIONS
|
|
200666
|
+
};
|
|
200667
|
+
try {
|
|
200668
|
+
let isTruncated2 = function(node) {
|
|
200669
|
+
if (node.hasMoreFiles || node.hasMoreSubfolders || node.isIgnored) {
|
|
200670
|
+
return true;
|
|
200671
|
+
}
|
|
200672
|
+
for (const sub of node.subFolders) {
|
|
200673
|
+
if (isTruncated2(sub)) {
|
|
200674
|
+
return true;
|
|
200675
|
+
}
|
|
200676
|
+
}
|
|
200677
|
+
return false;
|
|
200678
|
+
};
|
|
200679
|
+
var isTruncated = isTruncated2;
|
|
200680
|
+
__name(isTruncated2, "isTruncated");
|
|
200681
|
+
const structureRoot = await readFullStructure(resolvedPath, mergedOptions);
|
|
200682
|
+
if (!structureRoot) {
|
|
200683
|
+
return `Error: Could not read directory "${resolvedPath}". Check path and permissions.`;
|
|
200684
|
+
}
|
|
200685
|
+
const structureLines = [];
|
|
200686
|
+
formatStructure(structureRoot, "", true, true, structureLines);
|
|
200687
|
+
let summary = `Showing up to ${mergedOptions.maxItems} items (files + folders).`;
|
|
200688
|
+
if (isTruncated2(structureRoot)) {
|
|
200689
|
+
summary += ` Folders or files indicated with ${TRUNCATION_INDICATOR} contain more items not shown, were ignored, or the display limit (${mergedOptions.maxItems} items) was reached.`;
|
|
200690
|
+
}
|
|
200691
|
+
return `${summary}
|
|
200692
|
+
|
|
200693
|
+
${resolvedPath}${path21.sep}
|
|
200694
|
+
${structureLines.join("\n")}`;
|
|
200695
|
+
} catch (error) {
|
|
200696
|
+
console.error(`Error getting folder structure for ${resolvedPath}:`, error);
|
|
200697
|
+
return `Error processing directory "${resolvedPath}": ${getErrorMessage(error)}`;
|
|
200698
|
+
}
|
|
200699
|
+
}
|
|
200700
|
+
var MAX_ITEMS, TRUNCATION_INDICATOR, DEFAULT_IGNORED_FOLDERS;
|
|
200701
|
+
var init_getFolderStructure = __esm({
|
|
200702
|
+
"packages/core/src/utils/getFolderStructure.ts"() {
|
|
200703
|
+
"use strict";
|
|
200704
|
+
init_esbuild_shims();
|
|
200705
|
+
init_errors();
|
|
200706
|
+
init_constants3();
|
|
200707
|
+
MAX_ITEMS = 20;
|
|
200708
|
+
TRUNCATION_INDICATOR = "...";
|
|
200709
|
+
DEFAULT_IGNORED_FOLDERS = /* @__PURE__ */ new Set(["node_modules", ".git", "dist"]);
|
|
200710
|
+
__name(readFullStructure, "readFullStructure");
|
|
200711
|
+
__name(formatStructure, "formatStructure");
|
|
200712
|
+
__name(getFolderStructure, "getFolderStructure");
|
|
200713
|
+
}
|
|
200714
|
+
});
|
|
200715
|
+
|
|
200716
|
+
// packages/core/src/utils/environmentContext.ts
|
|
200717
|
+
async function getDirectoryContextString(config) {
|
|
200718
|
+
const workspaceContext = config.getWorkspaceContext();
|
|
200719
|
+
const workspaceDirectories = workspaceContext.getDirectories();
|
|
200720
|
+
const folderStructures = await Promise.all(
|
|
200721
|
+
workspaceDirectories.map(
|
|
200722
|
+
(dir) => getFolderStructure(dir, {
|
|
200723
|
+
fileService: config.getFileService()
|
|
200724
|
+
})
|
|
200725
|
+
)
|
|
200726
|
+
);
|
|
200727
|
+
const folderStructure = folderStructures.join("\n");
|
|
200728
|
+
let workingDirPreamble;
|
|
200729
|
+
if (workspaceDirectories.length === 1) {
|
|
200730
|
+
workingDirPreamble = `I'm currently working in the directory: ${workspaceDirectories[0]}`;
|
|
200731
|
+
} else {
|
|
200732
|
+
const dirList = workspaceDirectories.map((dir) => ` - ${dir}`).join("\n");
|
|
200733
|
+
workingDirPreamble = `I'm currently working in the following directories:
|
|
200734
|
+
${dirList}`;
|
|
200735
|
+
}
|
|
200736
|
+
return `${workingDirPreamble}
|
|
200737
|
+
Here is the folder structure of the current working directories:
|
|
200738
|
+
|
|
200739
|
+
${folderStructure}`;
|
|
200740
|
+
}
|
|
200741
|
+
async function getEnvironmentContext(config) {
|
|
200742
|
+
const today = (/* @__PURE__ */ new Date()).toLocaleDateString(void 0, {
|
|
200743
|
+
weekday: "long",
|
|
200744
|
+
year: "numeric",
|
|
200745
|
+
month: "long",
|
|
200746
|
+
day: "numeric"
|
|
200747
|
+
});
|
|
200748
|
+
const platform14 = process.platform;
|
|
200749
|
+
const directoryContext = await getDirectoryContextString(config);
|
|
200750
|
+
const context2 = `
|
|
200751
|
+
This is the RDMind. We are setting up the context for our chat.
|
|
200752
|
+
Today's date is ${today} (formatted according to the user's locale).
|
|
200753
|
+
My operating system is: ${platform14}
|
|
200754
|
+
${directoryContext}
|
|
200755
|
+
`.trim();
|
|
200756
|
+
const initialParts = [{ text: context2 }];
|
|
200757
|
+
const toolRegistry = config.getToolRegistry();
|
|
200758
|
+
if (config.getFullContext()) {
|
|
200759
|
+
try {
|
|
200760
|
+
const readManyFilesTool = toolRegistry.getTool("read_many_files");
|
|
200761
|
+
if (readManyFilesTool) {
|
|
200762
|
+
const invocation = readManyFilesTool.build({
|
|
200763
|
+
paths: ["**/*"],
|
|
200764
|
+
// Read everything recursively
|
|
200765
|
+
useDefaultExcludes: true
|
|
200766
|
+
// Use default excludes
|
|
200767
|
+
});
|
|
200768
|
+
const result = await invocation.execute(AbortSignal.timeout(3e4));
|
|
200769
|
+
if (result.llmContent) {
|
|
200770
|
+
initialParts.push({
|
|
200771
|
+
text: `
|
|
200772
|
+
--- Full File Context ---
|
|
200773
|
+
${result.llmContent}`
|
|
200774
|
+
});
|
|
200775
|
+
} else {
|
|
200776
|
+
console.warn(
|
|
200777
|
+
"Full context requested, but read_many_files returned no content."
|
|
200778
|
+
);
|
|
200779
|
+
}
|
|
200780
|
+
} else {
|
|
200781
|
+
console.warn(
|
|
200782
|
+
"Full context requested, but read_many_files tool not found."
|
|
200783
|
+
);
|
|
200784
|
+
}
|
|
200785
|
+
} catch (error) {
|
|
200786
|
+
console.error("Error reading full file context:", error);
|
|
200787
|
+
initialParts.push({
|
|
200788
|
+
text: "\n--- Error reading full file context ---"
|
|
200789
|
+
});
|
|
200790
|
+
}
|
|
200791
|
+
}
|
|
200792
|
+
return initialParts;
|
|
200793
|
+
}
|
|
200794
|
+
async function getInitialChatHistory(config, extraHistory) {
|
|
200795
|
+
const envParts = await getEnvironmentContext(config);
|
|
200796
|
+
const envContextString = envParts.map((part) => part.text || "").join("\n\n");
|
|
200797
|
+
return [
|
|
200798
|
+
{
|
|
200799
|
+
role: "user",
|
|
200800
|
+
parts: [{ text: envContextString }]
|
|
200801
|
+
},
|
|
200802
|
+
{
|
|
200803
|
+
role: "model",
|
|
200804
|
+
parts: [{ text: "Got it. Thanks for the context!" }]
|
|
200805
|
+
},
|
|
200806
|
+
...extraHistory ?? []
|
|
200807
|
+
];
|
|
200808
|
+
}
|
|
200809
|
+
var init_environmentContext = __esm({
|
|
200810
|
+
"packages/core/src/utils/environmentContext.ts"() {
|
|
200811
|
+
"use strict";
|
|
200812
|
+
init_esbuild_shims();
|
|
200813
|
+
init_getFolderStructure();
|
|
200814
|
+
__name(getDirectoryContextString, "getDirectoryContextString");
|
|
200815
|
+
__name(getEnvironmentContext, "getEnvironmentContext");
|
|
200816
|
+
__name(getInitialChatHistory, "getInitialChatHistory");
|
|
200817
|
+
}
|
|
200818
|
+
});
|
|
200819
|
+
|
|
200820
|
+
// packages/core/src/services/chatCompressionService.ts
|
|
200821
|
+
function findCompressSplitPoint(contents, fraction) {
|
|
200822
|
+
if (fraction <= 0 || fraction >= 1) {
|
|
200823
|
+
throw new Error("Fraction must be between 0 and 1");
|
|
200824
|
+
}
|
|
200825
|
+
const charCounts = contents.map((content) => JSON.stringify(content).length);
|
|
200826
|
+
const totalCharCount = charCounts.reduce((a, b) => a + b, 0);
|
|
200827
|
+
const targetCharCount = totalCharCount * fraction;
|
|
200828
|
+
let lastSplitPoint = 0;
|
|
200829
|
+
let cumulativeCharCount = 0;
|
|
200830
|
+
for (let i = 0; i < contents.length; i++) {
|
|
200831
|
+
const content = contents[i];
|
|
200832
|
+
if (content.role === "user" && !content.parts?.some((part) => !!part.functionResponse)) {
|
|
200833
|
+
if (cumulativeCharCount >= targetCharCount) {
|
|
200834
|
+
return i;
|
|
200835
|
+
}
|
|
200836
|
+
lastSplitPoint = i;
|
|
200837
|
+
}
|
|
200838
|
+
cumulativeCharCount += charCounts[i];
|
|
200839
|
+
}
|
|
200840
|
+
const lastContent = contents[contents.length - 1];
|
|
200841
|
+
if (lastContent?.role === "model" && !lastContent?.parts?.some((part) => part.functionCall)) {
|
|
200842
|
+
return contents.length;
|
|
200843
|
+
}
|
|
200844
|
+
return lastSplitPoint;
|
|
200845
|
+
}
|
|
200846
|
+
var COMPRESSION_TOKEN_THRESHOLD, COMPRESSION_PRESERVE_THRESHOLD, ChatCompressionService;
|
|
200847
|
+
var init_chatCompressionService = __esm({
|
|
200848
|
+
"packages/core/src/services/chatCompressionService.ts"() {
|
|
200849
|
+
"use strict";
|
|
200850
|
+
init_esbuild_shims();
|
|
200851
|
+
init_turn();
|
|
200852
|
+
init_uiTelemetry();
|
|
200853
|
+
init_tokenLimits();
|
|
200854
|
+
init_prompts();
|
|
200855
|
+
init_partUtils();
|
|
200856
|
+
init_loggers();
|
|
200857
|
+
init_types3();
|
|
200858
|
+
init_environmentContext();
|
|
200859
|
+
COMPRESSION_TOKEN_THRESHOLD = 0.7;
|
|
200860
|
+
COMPRESSION_PRESERVE_THRESHOLD = 0.3;
|
|
200861
|
+
__name(findCompressSplitPoint, "findCompressSplitPoint");
|
|
200862
|
+
ChatCompressionService = class {
|
|
200863
|
+
static {
|
|
200864
|
+
__name(this, "ChatCompressionService");
|
|
200865
|
+
}
|
|
200866
|
+
async compress(chat, promptId, force, model, config, hasFailedCompressionAttempt) {
|
|
200867
|
+
const curatedHistory = chat.getHistory(true);
|
|
200868
|
+
if (curatedHistory.length === 0 || hasFailedCompressionAttempt && !force) {
|
|
200869
|
+
return {
|
|
200870
|
+
newHistory: null,
|
|
200871
|
+
info: {
|
|
200872
|
+
originalTokenCount: 0,
|
|
200873
|
+
newTokenCount: 0,
|
|
200874
|
+
compressionStatus: 5 /* NOOP */
|
|
200875
|
+
}
|
|
200876
|
+
};
|
|
200877
|
+
}
|
|
200878
|
+
const originalTokenCount = uiTelemetryService.getLastPromptTokenCount();
|
|
200879
|
+
const contextPercentageThreshold = config.getChatCompression()?.contextPercentageThreshold;
|
|
200880
|
+
if (!force) {
|
|
200881
|
+
const threshold = contextPercentageThreshold ?? COMPRESSION_TOKEN_THRESHOLD;
|
|
200882
|
+
if (originalTokenCount < threshold * tokenLimit(model)) {
|
|
200883
|
+
return {
|
|
200884
|
+
newHistory: null,
|
|
200885
|
+
info: {
|
|
200886
|
+
originalTokenCount,
|
|
200887
|
+
newTokenCount: originalTokenCount,
|
|
200888
|
+
compressionStatus: 5 /* NOOP */
|
|
200889
|
+
}
|
|
200890
|
+
};
|
|
200891
|
+
}
|
|
200892
|
+
}
|
|
200893
|
+
const splitPoint = findCompressSplitPoint(
|
|
200894
|
+
curatedHistory,
|
|
200895
|
+
1 - COMPRESSION_PRESERVE_THRESHOLD
|
|
200896
|
+
);
|
|
200897
|
+
const historyToCompress = curatedHistory.slice(0, splitPoint);
|
|
200898
|
+
const historyToKeep = curatedHistory.slice(splitPoint);
|
|
200899
|
+
if (historyToCompress.length === 0) {
|
|
200900
|
+
return {
|
|
200901
|
+
newHistory: null,
|
|
200902
|
+
info: {
|
|
200903
|
+
originalTokenCount,
|
|
200904
|
+
newTokenCount: originalTokenCount,
|
|
200905
|
+
compressionStatus: 5 /* NOOP */
|
|
200906
|
+
}
|
|
200907
|
+
};
|
|
200908
|
+
}
|
|
200909
|
+
const summaryResponse = await config.getContentGenerator().generateContent(
|
|
200910
|
+
{
|
|
200911
|
+
model,
|
|
200912
|
+
contents: [
|
|
200913
|
+
...historyToCompress,
|
|
200914
|
+
{
|
|
200915
|
+
role: "user",
|
|
200916
|
+
parts: [
|
|
200917
|
+
{
|
|
200918
|
+
text: "First, reason in your scratchpad. Then, generate the <state_snapshot>."
|
|
200919
|
+
}
|
|
200920
|
+
]
|
|
200921
|
+
}
|
|
200922
|
+
],
|
|
200923
|
+
config: {
|
|
200924
|
+
systemInstruction: getCompressionPrompt()
|
|
200925
|
+
}
|
|
200926
|
+
},
|
|
200927
|
+
promptId
|
|
200928
|
+
);
|
|
200929
|
+
const summary = getResponseText(summaryResponse) ?? "";
|
|
200930
|
+
const isSummaryEmpty = !summary || summary.trim().length === 0;
|
|
200931
|
+
let newTokenCount = originalTokenCount;
|
|
200932
|
+
let extraHistory = [];
|
|
200933
|
+
if (!isSummaryEmpty) {
|
|
200934
|
+
extraHistory = [
|
|
200935
|
+
{
|
|
200936
|
+
role: "user",
|
|
200937
|
+
parts: [{ text: summary }]
|
|
200938
|
+
},
|
|
200939
|
+
{
|
|
200940
|
+
role: "model",
|
|
200941
|
+
parts: [{ text: "Got it. Thanks for the additional context!" }]
|
|
200942
|
+
},
|
|
200943
|
+
...historyToKeep
|
|
200944
|
+
];
|
|
200945
|
+
const fullNewHistory = await getInitialChatHistory(config, extraHistory);
|
|
200946
|
+
newTokenCount = Math.floor(
|
|
200947
|
+
fullNewHistory.reduce(
|
|
200948
|
+
(total, content) => total + JSON.stringify(content).length,
|
|
200949
|
+
0
|
|
200950
|
+
) / 4
|
|
200951
|
+
);
|
|
200952
|
+
}
|
|
200953
|
+
logChatCompression(
|
|
200954
|
+
config,
|
|
200955
|
+
makeChatCompressionEvent({
|
|
200956
|
+
tokens_before: originalTokenCount,
|
|
200957
|
+
tokens_after: newTokenCount
|
|
200958
|
+
})
|
|
200959
|
+
);
|
|
200960
|
+
if (isSummaryEmpty) {
|
|
200961
|
+
return {
|
|
200962
|
+
newHistory: null,
|
|
200963
|
+
info: {
|
|
200964
|
+
originalTokenCount,
|
|
200965
|
+
newTokenCount: originalTokenCount,
|
|
200966
|
+
compressionStatus: 4 /* COMPRESSION_FAILED_EMPTY_SUMMARY */
|
|
200967
|
+
}
|
|
200968
|
+
};
|
|
200969
|
+
} else if (newTokenCount > originalTokenCount) {
|
|
200970
|
+
return {
|
|
200971
|
+
newHistory: null,
|
|
200972
|
+
info: {
|
|
200973
|
+
originalTokenCount,
|
|
200974
|
+
newTokenCount,
|
|
200975
|
+
compressionStatus: 2 /* COMPRESSION_FAILED_INFLATED_TOKEN_COUNT */
|
|
200976
|
+
}
|
|
200977
|
+
};
|
|
200978
|
+
} else {
|
|
200979
|
+
uiTelemetryService.setLastPromptTokenCount(newTokenCount);
|
|
200980
|
+
return {
|
|
200981
|
+
newHistory: extraHistory,
|
|
200982
|
+
info: {
|
|
200983
|
+
originalTokenCount,
|
|
200984
|
+
newTokenCount,
|
|
200985
|
+
compressionStatus: 1 /* COMPRESSED */
|
|
200986
|
+
}
|
|
200987
|
+
};
|
|
200988
|
+
}
|
|
200989
|
+
}
|
|
200990
|
+
};
|
|
200991
|
+
}
|
|
200992
|
+
});
|
|
200993
|
+
|
|
200494
200994
|
// packages/core/src/services/loopDetectionService.ts
|
|
200495
200995
|
import { createHash as createHash3 } from "node:crypto";
|
|
200496
200996
|
var TOOL_CALL_LOOP_THRESHOLD, CONTENT_LOOP_THRESHOLD, CONTENT_CHUNK_SIZE, MAX_HISTORY_LENGTH, LLM_LOOP_CHECK_HISTORY_COUNT, LLM_CHECK_AFTER_TURNS, DEFAULT_LLM_CHECK_INTERVAL, MIN_LLM_CHECK_INTERVAL, MAX_LLM_CHECK_INTERVAL, LOOP_DETECTION_SYSTEM_PROMPT, LoopDetectionService;
|
|
@@ -200872,316 +201372,6 @@ var init_types6 = __esm({
|
|
|
200872
201372
|
}
|
|
200873
201373
|
});
|
|
200874
201374
|
|
|
200875
|
-
// packages/core/src/config/constants.ts
|
|
200876
|
-
var DEFAULT_MEMORY_FILE_FILTERING_OPTIONS, DEFAULT_FILE_FILTERING_OPTIONS;
|
|
200877
|
-
var init_constants3 = __esm({
|
|
200878
|
-
"packages/core/src/config/constants.ts"() {
|
|
200879
|
-
"use strict";
|
|
200880
|
-
init_esbuild_shims();
|
|
200881
|
-
DEFAULT_MEMORY_FILE_FILTERING_OPTIONS = {
|
|
200882
|
-
respectGitIgnore: false,
|
|
200883
|
-
respectQwenIgnore: true
|
|
200884
|
-
};
|
|
200885
|
-
DEFAULT_FILE_FILTERING_OPTIONS = {
|
|
200886
|
-
respectGitIgnore: true,
|
|
200887
|
-
respectQwenIgnore: true
|
|
200888
|
-
};
|
|
200889
|
-
}
|
|
200890
|
-
});
|
|
200891
|
-
|
|
200892
|
-
// packages/core/src/utils/getFolderStructure.ts
|
|
200893
|
-
import * as fs24 from "node:fs/promises";
|
|
200894
|
-
import * as path21 from "node:path";
|
|
200895
|
-
async function readFullStructure(rootPath, options2) {
|
|
200896
|
-
const rootName = path21.basename(rootPath);
|
|
200897
|
-
const rootNode = {
|
|
200898
|
-
name: rootName,
|
|
200899
|
-
path: rootPath,
|
|
200900
|
-
files: [],
|
|
200901
|
-
subFolders: [],
|
|
200902
|
-
totalChildren: 0,
|
|
200903
|
-
totalFiles: 0
|
|
200904
|
-
};
|
|
200905
|
-
const queue = [
|
|
200906
|
-
{ folderInfo: rootNode, currentPath: rootPath }
|
|
200907
|
-
];
|
|
200908
|
-
let currentItemCount = 0;
|
|
200909
|
-
const processedPaths = /* @__PURE__ */ new Set();
|
|
200910
|
-
while (queue.length > 0) {
|
|
200911
|
-
const { folderInfo, currentPath } = queue.shift();
|
|
200912
|
-
if (processedPaths.has(currentPath)) {
|
|
200913
|
-
continue;
|
|
200914
|
-
}
|
|
200915
|
-
processedPaths.add(currentPath);
|
|
200916
|
-
if (currentItemCount >= options2.maxItems) {
|
|
200917
|
-
continue;
|
|
200918
|
-
}
|
|
200919
|
-
let entries;
|
|
200920
|
-
try {
|
|
200921
|
-
const rawEntries = await fs24.readdir(currentPath, { withFileTypes: true });
|
|
200922
|
-
entries = rawEntries.sort((a, b) => a.name.localeCompare(b.name));
|
|
200923
|
-
} catch (error) {
|
|
200924
|
-
if (isNodeError(error) && (error.code === "EACCES" || error.code === "ENOENT")) {
|
|
200925
|
-
console.warn(
|
|
200926
|
-
`Warning: Could not read directory ${currentPath}: ${error.message}`
|
|
200927
|
-
);
|
|
200928
|
-
if (currentPath === rootPath && error.code === "ENOENT") {
|
|
200929
|
-
return null;
|
|
200930
|
-
}
|
|
200931
|
-
continue;
|
|
200932
|
-
}
|
|
200933
|
-
throw error;
|
|
200934
|
-
}
|
|
200935
|
-
const filesInCurrentDir = [];
|
|
200936
|
-
const subFoldersInCurrentDir = [];
|
|
200937
|
-
for (const entry of entries) {
|
|
200938
|
-
if (entry.isFile()) {
|
|
200939
|
-
if (currentItemCount >= options2.maxItems) {
|
|
200940
|
-
folderInfo.hasMoreFiles = true;
|
|
200941
|
-
break;
|
|
200942
|
-
}
|
|
200943
|
-
const fileName = entry.name;
|
|
200944
|
-
const filePath = path21.join(currentPath, fileName);
|
|
200945
|
-
if (options2.fileService) {
|
|
200946
|
-
const shouldIgnore = options2.fileFilteringOptions.respectGitIgnore && options2.fileService.shouldGitIgnoreFile(filePath) || options2.fileFilteringOptions.respectQwenIgnore && options2.fileService.shouldQwenIgnoreFile(filePath);
|
|
200947
|
-
if (shouldIgnore) {
|
|
200948
|
-
continue;
|
|
200949
|
-
}
|
|
200950
|
-
}
|
|
200951
|
-
if (!options2.fileIncludePattern || options2.fileIncludePattern.test(fileName)) {
|
|
200952
|
-
filesInCurrentDir.push(fileName);
|
|
200953
|
-
currentItemCount++;
|
|
200954
|
-
folderInfo.totalFiles++;
|
|
200955
|
-
folderInfo.totalChildren++;
|
|
200956
|
-
}
|
|
200957
|
-
}
|
|
200958
|
-
}
|
|
200959
|
-
folderInfo.files = filesInCurrentDir;
|
|
200960
|
-
for (const entry of entries) {
|
|
200961
|
-
if (entry.isDirectory()) {
|
|
200962
|
-
if (currentItemCount >= options2.maxItems) {
|
|
200963
|
-
folderInfo.hasMoreSubfolders = true;
|
|
200964
|
-
break;
|
|
200965
|
-
}
|
|
200966
|
-
const subFolderName = entry.name;
|
|
200967
|
-
const subFolderPath = path21.join(currentPath, subFolderName);
|
|
200968
|
-
let isIgnored = false;
|
|
200969
|
-
if (options2.fileService) {
|
|
200970
|
-
isIgnored = options2.fileFilteringOptions.respectGitIgnore && options2.fileService.shouldGitIgnoreFile(subFolderPath) || options2.fileFilteringOptions.respectQwenIgnore && options2.fileService.shouldQwenIgnoreFile(subFolderPath);
|
|
200971
|
-
}
|
|
200972
|
-
if (options2.ignoredFolders.has(subFolderName) || isIgnored) {
|
|
200973
|
-
const ignoredSubFolder = {
|
|
200974
|
-
name: subFolderName,
|
|
200975
|
-
path: subFolderPath,
|
|
200976
|
-
files: [],
|
|
200977
|
-
subFolders: [],
|
|
200978
|
-
totalChildren: 0,
|
|
200979
|
-
totalFiles: 0,
|
|
200980
|
-
isIgnored: true
|
|
200981
|
-
};
|
|
200982
|
-
subFoldersInCurrentDir.push(ignoredSubFolder);
|
|
200983
|
-
currentItemCount++;
|
|
200984
|
-
folderInfo.totalChildren++;
|
|
200985
|
-
continue;
|
|
200986
|
-
}
|
|
200987
|
-
const subFolderNode = {
|
|
200988
|
-
name: subFolderName,
|
|
200989
|
-
path: subFolderPath,
|
|
200990
|
-
files: [],
|
|
200991
|
-
subFolders: [],
|
|
200992
|
-
totalChildren: 0,
|
|
200993
|
-
totalFiles: 0
|
|
200994
|
-
};
|
|
200995
|
-
subFoldersInCurrentDir.push(subFolderNode);
|
|
200996
|
-
currentItemCount++;
|
|
200997
|
-
folderInfo.totalChildren++;
|
|
200998
|
-
queue.push({ folderInfo: subFolderNode, currentPath: subFolderPath });
|
|
200999
|
-
}
|
|
201000
|
-
}
|
|
201001
|
-
folderInfo.subFolders = subFoldersInCurrentDir;
|
|
201002
|
-
}
|
|
201003
|
-
return rootNode;
|
|
201004
|
-
}
|
|
201005
|
-
function formatStructure(node, currentIndent, isLastChildOfParent, isProcessingRootNode, builder) {
|
|
201006
|
-
const connector = isLastChildOfParent ? "\u2514\u2500\u2500\u2500" : "\u251C\u2500\u2500\u2500";
|
|
201007
|
-
if (!isProcessingRootNode || node.isIgnored) {
|
|
201008
|
-
builder.push(
|
|
201009
|
-
`${currentIndent}${connector}${node.name}${path21.sep}${node.isIgnored ? TRUNCATION_INDICATOR : ""}`
|
|
201010
|
-
);
|
|
201011
|
-
}
|
|
201012
|
-
const indentForChildren = isProcessingRootNode ? "" : currentIndent + (isLastChildOfParent ? " " : "\u2502 ");
|
|
201013
|
-
const fileCount = node.files.length;
|
|
201014
|
-
for (let i = 0; i < fileCount; i++) {
|
|
201015
|
-
const isLastFileAmongSiblings = i === fileCount - 1 && node.subFolders.length === 0 && !node.hasMoreSubfolders;
|
|
201016
|
-
const fileConnector = isLastFileAmongSiblings ? "\u2514\u2500\u2500\u2500" : "\u251C\u2500\u2500\u2500";
|
|
201017
|
-
builder.push(`${indentForChildren}${fileConnector}${node.files[i]}`);
|
|
201018
|
-
}
|
|
201019
|
-
if (node.hasMoreFiles) {
|
|
201020
|
-
const isLastIndicatorAmongSiblings = node.subFolders.length === 0 && !node.hasMoreSubfolders;
|
|
201021
|
-
const fileConnector = isLastIndicatorAmongSiblings ? "\u2514\u2500\u2500\u2500" : "\u251C\u2500\u2500\u2500";
|
|
201022
|
-
builder.push(`${indentForChildren}${fileConnector}${TRUNCATION_INDICATOR}`);
|
|
201023
|
-
}
|
|
201024
|
-
const subFolderCount = node.subFolders.length;
|
|
201025
|
-
for (let i = 0; i < subFolderCount; i++) {
|
|
201026
|
-
const isLastSubfolderAmongSiblings = i === subFolderCount - 1 && !node.hasMoreSubfolders;
|
|
201027
|
-
formatStructure(
|
|
201028
|
-
node.subFolders[i],
|
|
201029
|
-
indentForChildren,
|
|
201030
|
-
isLastSubfolderAmongSiblings,
|
|
201031
|
-
false,
|
|
201032
|
-
builder
|
|
201033
|
-
);
|
|
201034
|
-
}
|
|
201035
|
-
if (node.hasMoreSubfolders) {
|
|
201036
|
-
builder.push(`${indentForChildren}\u2514\u2500\u2500\u2500${TRUNCATION_INDICATOR}`);
|
|
201037
|
-
}
|
|
201038
|
-
}
|
|
201039
|
-
async function getFolderStructure(directory, options2) {
|
|
201040
|
-
const resolvedPath = path21.resolve(directory);
|
|
201041
|
-
const mergedOptions = {
|
|
201042
|
-
maxItems: options2?.maxItems ?? MAX_ITEMS,
|
|
201043
|
-
ignoredFolders: options2?.ignoredFolders ?? DEFAULT_IGNORED_FOLDERS,
|
|
201044
|
-
fileIncludePattern: options2?.fileIncludePattern,
|
|
201045
|
-
fileService: options2?.fileService,
|
|
201046
|
-
fileFilteringOptions: options2?.fileFilteringOptions ?? DEFAULT_FILE_FILTERING_OPTIONS
|
|
201047
|
-
};
|
|
201048
|
-
try {
|
|
201049
|
-
let isTruncated2 = function(node) {
|
|
201050
|
-
if (node.hasMoreFiles || node.hasMoreSubfolders || node.isIgnored) {
|
|
201051
|
-
return true;
|
|
201052
|
-
}
|
|
201053
|
-
for (const sub of node.subFolders) {
|
|
201054
|
-
if (isTruncated2(sub)) {
|
|
201055
|
-
return true;
|
|
201056
|
-
}
|
|
201057
|
-
}
|
|
201058
|
-
return false;
|
|
201059
|
-
};
|
|
201060
|
-
var isTruncated = isTruncated2;
|
|
201061
|
-
__name(isTruncated2, "isTruncated");
|
|
201062
|
-
const structureRoot = await readFullStructure(resolvedPath, mergedOptions);
|
|
201063
|
-
if (!structureRoot) {
|
|
201064
|
-
return `Error: Could not read directory "${resolvedPath}". Check path and permissions.`;
|
|
201065
|
-
}
|
|
201066
|
-
const structureLines = [];
|
|
201067
|
-
formatStructure(structureRoot, "", true, true, structureLines);
|
|
201068
|
-
let summary = `Showing up to ${mergedOptions.maxItems} items (files + folders).`;
|
|
201069
|
-
if (isTruncated2(structureRoot)) {
|
|
201070
|
-
summary += ` Folders or files indicated with ${TRUNCATION_INDICATOR} contain more items not shown, were ignored, or the display limit (${mergedOptions.maxItems} items) was reached.`;
|
|
201071
|
-
}
|
|
201072
|
-
return `${summary}
|
|
201073
|
-
|
|
201074
|
-
${resolvedPath}${path21.sep}
|
|
201075
|
-
${structureLines.join("\n")}`;
|
|
201076
|
-
} catch (error) {
|
|
201077
|
-
console.error(`Error getting folder structure for ${resolvedPath}:`, error);
|
|
201078
|
-
return `Error processing directory "${resolvedPath}": ${getErrorMessage(error)}`;
|
|
201079
|
-
}
|
|
201080
|
-
}
|
|
201081
|
-
var MAX_ITEMS, TRUNCATION_INDICATOR, DEFAULT_IGNORED_FOLDERS;
|
|
201082
|
-
var init_getFolderStructure = __esm({
|
|
201083
|
-
"packages/core/src/utils/getFolderStructure.ts"() {
|
|
201084
|
-
"use strict";
|
|
201085
|
-
init_esbuild_shims();
|
|
201086
|
-
init_errors();
|
|
201087
|
-
init_constants3();
|
|
201088
|
-
MAX_ITEMS = 20;
|
|
201089
|
-
TRUNCATION_INDICATOR = "...";
|
|
201090
|
-
DEFAULT_IGNORED_FOLDERS = /* @__PURE__ */ new Set(["node_modules", ".git", "dist"]);
|
|
201091
|
-
__name(readFullStructure, "readFullStructure");
|
|
201092
|
-
__name(formatStructure, "formatStructure");
|
|
201093
|
-
__name(getFolderStructure, "getFolderStructure");
|
|
201094
|
-
}
|
|
201095
|
-
});
|
|
201096
|
-
|
|
201097
|
-
// packages/core/src/utils/environmentContext.ts
|
|
201098
|
-
async function getDirectoryContextString(config) {
|
|
201099
|
-
const workspaceContext = config.getWorkspaceContext();
|
|
201100
|
-
const workspaceDirectories = workspaceContext.getDirectories();
|
|
201101
|
-
const folderStructures = await Promise.all(
|
|
201102
|
-
workspaceDirectories.map(
|
|
201103
|
-
(dir) => getFolderStructure(dir, {
|
|
201104
|
-
fileService: config.getFileService()
|
|
201105
|
-
})
|
|
201106
|
-
)
|
|
201107
|
-
);
|
|
201108
|
-
const folderStructure = folderStructures.join("\n");
|
|
201109
|
-
let workingDirPreamble;
|
|
201110
|
-
if (workspaceDirectories.length === 1) {
|
|
201111
|
-
workingDirPreamble = `I'm currently working in the directory: ${workspaceDirectories[0]}`;
|
|
201112
|
-
} else {
|
|
201113
|
-
const dirList = workspaceDirectories.map((dir) => ` - ${dir}`).join("\n");
|
|
201114
|
-
workingDirPreamble = `I'm currently working in the following directories:
|
|
201115
|
-
${dirList}`;
|
|
201116
|
-
}
|
|
201117
|
-
return `${workingDirPreamble}
|
|
201118
|
-
Here is the folder structure of the current working directories:
|
|
201119
|
-
|
|
201120
|
-
${folderStructure}`;
|
|
201121
|
-
}
|
|
201122
|
-
async function getEnvironmentContext(config) {
|
|
201123
|
-
const today = (/* @__PURE__ */ new Date()).toLocaleDateString(void 0, {
|
|
201124
|
-
weekday: "long",
|
|
201125
|
-
year: "numeric",
|
|
201126
|
-
month: "long",
|
|
201127
|
-
day: "numeric"
|
|
201128
|
-
});
|
|
201129
|
-
const platform14 = process.platform;
|
|
201130
|
-
const directoryContext = await getDirectoryContextString(config);
|
|
201131
|
-
const context2 = `
|
|
201132
|
-
This is the RDMind. We are setting up the context for our chat.
|
|
201133
|
-
Today's date is ${today} (formatted according to the user's locale).
|
|
201134
|
-
My operating system is: ${platform14}
|
|
201135
|
-
${directoryContext}
|
|
201136
|
-
`.trim();
|
|
201137
|
-
const initialParts = [{ text: context2 }];
|
|
201138
|
-
const toolRegistry = config.getToolRegistry();
|
|
201139
|
-
if (config.getFullContext()) {
|
|
201140
|
-
try {
|
|
201141
|
-
const readManyFilesTool = toolRegistry.getTool("read_many_files");
|
|
201142
|
-
if (readManyFilesTool) {
|
|
201143
|
-
const invocation = readManyFilesTool.build({
|
|
201144
|
-
paths: ["**/*"],
|
|
201145
|
-
// Read everything recursively
|
|
201146
|
-
useDefaultExcludes: true
|
|
201147
|
-
// Use default excludes
|
|
201148
|
-
});
|
|
201149
|
-
const result = await invocation.execute(AbortSignal.timeout(3e4));
|
|
201150
|
-
if (result.llmContent) {
|
|
201151
|
-
initialParts.push({
|
|
201152
|
-
text: `
|
|
201153
|
-
--- Full File Context ---
|
|
201154
|
-
${result.llmContent}`
|
|
201155
|
-
});
|
|
201156
|
-
} else {
|
|
201157
|
-
console.warn(
|
|
201158
|
-
"Full context requested, but read_many_files returned no content."
|
|
201159
|
-
);
|
|
201160
|
-
}
|
|
201161
|
-
} else {
|
|
201162
|
-
console.warn(
|
|
201163
|
-
"Full context requested, but read_many_files tool not found."
|
|
201164
|
-
);
|
|
201165
|
-
}
|
|
201166
|
-
} catch (error) {
|
|
201167
|
-
console.error("Error reading full file context:", error);
|
|
201168
|
-
initialParts.push({
|
|
201169
|
-
text: "\n--- Error reading full file context ---"
|
|
201170
|
-
});
|
|
201171
|
-
}
|
|
201172
|
-
}
|
|
201173
|
-
return initialParts;
|
|
201174
|
-
}
|
|
201175
|
-
var init_environmentContext = __esm({
|
|
201176
|
-
"packages/core/src/utils/environmentContext.ts"() {
|
|
201177
|
-
"use strict";
|
|
201178
|
-
init_esbuild_shims();
|
|
201179
|
-
init_getFolderStructure();
|
|
201180
|
-
__name(getDirectoryContextString, "getDirectoryContextString");
|
|
201181
|
-
__name(getEnvironmentContext, "getEnvironmentContext");
|
|
201182
|
-
}
|
|
201183
|
-
});
|
|
201184
|
-
|
|
201185
201375
|
// packages/core/src/subagents/subagent-events.ts
|
|
201186
201376
|
import { EventEmitter as EventEmitter5 } from "events";
|
|
201187
201377
|
var SubAgentEventEmitter;
|
|
@@ -201785,11 +201975,7 @@ var init_subagent = __esm({
|
|
|
201785
201975
|
"PromptConfig cannot have both `systemPrompt` and `initialMessages` defined."
|
|
201786
201976
|
);
|
|
201787
201977
|
}
|
|
201788
|
-
const
|
|
201789
|
-
const envHistory = [
|
|
201790
|
-
{ role: "user", parts: envParts },
|
|
201791
|
-
{ role: "model", parts: [{ text: "Got it. Thanks for the context!" }] }
|
|
201792
|
-
];
|
|
201978
|
+
const envHistory = await getInitialChatHistory(this.runtimeContext);
|
|
201793
201979
|
const start_history = [
|
|
201794
201980
|
...envHistory,
|
|
201795
201981
|
...this.promptConfig.initialMessages ?? []
|
|
@@ -206856,32 +207042,7 @@ var init_types8 = __esm({
|
|
|
206856
207042
|
function isThinkingSupported(model) {
|
|
206857
207043
|
return model.startsWith("gemini-2.5") || model === DEFAULT_GEMINI_MODEL_AUTO;
|
|
206858
207044
|
}
|
|
206859
|
-
|
|
206860
|
-
if (fraction <= 0 || fraction >= 1) {
|
|
206861
|
-
throw new Error("Fraction must be between 0 and 1");
|
|
206862
|
-
}
|
|
206863
|
-
const charCounts = contents.map((content) => JSON.stringify(content).length);
|
|
206864
|
-
const totalCharCount = charCounts.reduce((a, b) => a + b, 0);
|
|
206865
|
-
const targetCharCount = totalCharCount * fraction;
|
|
206866
|
-
let lastSplitPoint = 0;
|
|
206867
|
-
let cumulativeCharCount = 0;
|
|
206868
|
-
for (let i = 0; i < contents.length; i++) {
|
|
206869
|
-
const content = contents[i];
|
|
206870
|
-
if (content.role === "user" && !content.parts?.some((part) => !!part.functionResponse)) {
|
|
206871
|
-
if (cumulativeCharCount >= targetCharCount) {
|
|
206872
|
-
return i;
|
|
206873
|
-
}
|
|
206874
|
-
lastSplitPoint = i;
|
|
206875
|
-
}
|
|
206876
|
-
cumulativeCharCount += charCounts[i];
|
|
206877
|
-
}
|
|
206878
|
-
const lastContent = contents[contents.length - 1];
|
|
206879
|
-
if (lastContent?.role === "model" && !lastContent?.parts?.some((part) => part.functionCall)) {
|
|
206880
|
-
return contents.length;
|
|
206881
|
-
}
|
|
206882
|
-
return lastSplitPoint;
|
|
206883
|
-
}
|
|
206884
|
-
var MAX_TURNS, COMPRESSION_TOKEN_THRESHOLD, COMPRESSION_PRESERVE_THRESHOLD, GeminiClient;
|
|
207045
|
+
var MAX_TURNS, GeminiClient;
|
|
206885
207046
|
var init_client2 = __esm({
|
|
206886
207047
|
"packages/core/src/core/client.ts"() {
|
|
206887
207048
|
"use strict";
|
|
@@ -206890,9 +207051,9 @@ var init_client2 = __esm({
|
|
|
206890
207051
|
init_models();
|
|
206891
207052
|
init_geminiChat();
|
|
206892
207053
|
init_prompts();
|
|
206893
|
-
init_tokenLimits();
|
|
206894
207054
|
init_turn();
|
|
206895
207055
|
init_chatRecordingService();
|
|
207056
|
+
init_chatCompressionService();
|
|
206896
207057
|
init_loopDetectionService();
|
|
206897
207058
|
init_task();
|
|
206898
207059
|
init_telemetry();
|
|
@@ -206906,10 +207067,7 @@ var init_client2 = __esm({
|
|
|
206906
207067
|
init_types8();
|
|
206907
207068
|
init_handler();
|
|
206908
207069
|
__name(isThinkingSupported, "isThinkingSupported");
|
|
206909
|
-
__name(findCompressSplitPoint, "findCompressSplitPoint");
|
|
206910
207070
|
MAX_TURNS = 100;
|
|
206911
|
-
COMPRESSION_TOKEN_THRESHOLD = 0.7;
|
|
206912
|
-
COMPRESSION_PRESERVE_THRESHOLD = 0.3;
|
|
206913
207071
|
GeminiClient = class {
|
|
206914
207072
|
constructor(config) {
|
|
206915
207073
|
this.config = config;
|
|
@@ -206992,21 +207150,10 @@ var init_client2 = __esm({
|
|
|
206992
207150
|
async startChat(extraHistory) {
|
|
206993
207151
|
this.forceFullIdeContext = true;
|
|
206994
207152
|
this.hasFailedCompressionAttempt = false;
|
|
206995
|
-
const envParts = await getEnvironmentContext(this.config);
|
|
206996
207153
|
const toolRegistry = this.config.getToolRegistry();
|
|
206997
207154
|
const toolDeclarations = toolRegistry.getFunctionDeclarations();
|
|
206998
207155
|
const tools = [{ functionDeclarations: toolDeclarations }];
|
|
206999
|
-
const history =
|
|
207000
|
-
{
|
|
207001
|
-
role: "user",
|
|
207002
|
-
parts: envParts
|
|
207003
|
-
},
|
|
207004
|
-
{
|
|
207005
|
-
role: "model",
|
|
207006
|
-
parts: [{ text: "Got it. Thanks for the context!" }]
|
|
207007
|
-
},
|
|
207008
|
-
...extraHistory ?? []
|
|
207009
|
-
];
|
|
207156
|
+
const history = await getInitialChatHistory(this.config, extraHistory);
|
|
207010
207157
|
try {
|
|
207011
207158
|
const userMemory = this.config.getUserMemory();
|
|
207012
207159
|
const model = this.config.getModel();
|
|
@@ -207195,12 +207342,13 @@ var init_client2 = __esm({
|
|
|
207195
207342
|
userMemory,
|
|
207196
207343
|
this.config.getModel()
|
|
207197
207344
|
);
|
|
207198
|
-
const
|
|
207345
|
+
const initialHistory = await getInitialChatHistory(this.config);
|
|
207199
207346
|
const mockRequestContent = [
|
|
207200
207347
|
{
|
|
207201
207348
|
role: "system",
|
|
207202
|
-
parts: [{ text: systemPrompt }
|
|
207349
|
+
parts: [{ text: systemPrompt }]
|
|
207203
207350
|
},
|
|
207351
|
+
...initialHistory,
|
|
207204
207352
|
...currentHistory
|
|
207205
207353
|
];
|
|
207206
207354
|
const { totalTokens: totalRequestTokens } = await this.config.getContentGenerator().countTokens({
|
|
@@ -207360,99 +207508,26 @@ var init_client2 = __esm({
|
|
|
207360
207508
|
}
|
|
207361
207509
|
}
|
|
207362
207510
|
async tryCompressChat(prompt_id, force = false) {
|
|
207363
|
-
const
|
|
207364
|
-
const
|
|
207365
|
-
|
|
207366
|
-
|
|
207367
|
-
|
|
207368
|
-
|
|
207369
|
-
compressionStatus: 4 /* NOOP */
|
|
207370
|
-
};
|
|
207371
|
-
}
|
|
207372
|
-
const originalTokenCount = uiTelemetryService.getLastPromptTokenCount();
|
|
207373
|
-
const contextPercentageThreshold = this.config.getChatCompression()?.contextPercentageThreshold;
|
|
207374
|
-
if (!force) {
|
|
207375
|
-
const threshold = contextPercentageThreshold ?? COMPRESSION_TOKEN_THRESHOLD;
|
|
207376
|
-
if (originalTokenCount < threshold * tokenLimit(model)) {
|
|
207377
|
-
return {
|
|
207378
|
-
originalTokenCount,
|
|
207379
|
-
newTokenCount: originalTokenCount,
|
|
207380
|
-
compressionStatus: 4 /* NOOP */
|
|
207381
|
-
};
|
|
207382
|
-
}
|
|
207383
|
-
}
|
|
207384
|
-
const splitPoint = findCompressSplitPoint(
|
|
207385
|
-
curatedHistory,
|
|
207386
|
-
1 - COMPRESSION_PRESERVE_THRESHOLD
|
|
207387
|
-
);
|
|
207388
|
-
const historyToCompress = curatedHistory.slice(0, splitPoint);
|
|
207389
|
-
const historyToKeep = curatedHistory.slice(splitPoint);
|
|
207390
|
-
const summaryResponse = await this.config.getContentGenerator().generateContent(
|
|
207391
|
-
{
|
|
207392
|
-
model,
|
|
207393
|
-
contents: [
|
|
207394
|
-
...historyToCompress,
|
|
207395
|
-
{
|
|
207396
|
-
role: "user",
|
|
207397
|
-
parts: [
|
|
207398
|
-
{
|
|
207399
|
-
text: "First, reason in your scratchpad. Then, generate the <state_snapshot>."
|
|
207400
|
-
}
|
|
207401
|
-
]
|
|
207402
|
-
}
|
|
207403
|
-
],
|
|
207404
|
-
config: {
|
|
207405
|
-
systemInstruction: { text: getCompressionPrompt() }
|
|
207406
|
-
}
|
|
207407
|
-
},
|
|
207408
|
-
prompt_id
|
|
207409
|
-
);
|
|
207410
|
-
const summary = getResponseText(summaryResponse) ?? "";
|
|
207411
|
-
const chat = await this.startChat([
|
|
207412
|
-
{
|
|
207413
|
-
role: "user",
|
|
207414
|
-
parts: [{ text: summary }]
|
|
207415
|
-
},
|
|
207416
|
-
{
|
|
207417
|
-
role: "model",
|
|
207418
|
-
parts: [{ text: "Got it. Thanks for the additional context!" }]
|
|
207419
|
-
},
|
|
207420
|
-
...historyToKeep
|
|
207421
|
-
]);
|
|
207422
|
-
this.forceFullIdeContext = true;
|
|
207423
|
-
const newTokenCount = Math.floor(
|
|
207424
|
-
chat.getHistory().reduce((total, content) => total + JSON.stringify(content).length, 0) / 4
|
|
207425
|
-
);
|
|
207426
|
-
logChatCompression(
|
|
207511
|
+
const compressionService = new ChatCompressionService();
|
|
207512
|
+
const { newHistory, info } = await compressionService.compress(
|
|
207513
|
+
this.getChat(),
|
|
207514
|
+
prompt_id,
|
|
207515
|
+
force,
|
|
207516
|
+
this.config.getModel(),
|
|
207427
207517
|
this.config,
|
|
207428
|
-
|
|
207429
|
-
tokens_before: originalTokenCount,
|
|
207430
|
-
tokens_after: newTokenCount
|
|
207431
|
-
})
|
|
207518
|
+
this.hasFailedCompressionAttempt
|
|
207432
207519
|
);
|
|
207433
|
-
if (
|
|
207434
|
-
|
|
207435
|
-
|
|
207436
|
-
|
|
207437
|
-
|
|
207438
|
-
|
|
207439
|
-
|
|
207440
|
-
|
|
207441
|
-
|
|
207442
|
-
uiTelemetryService.setLastPromptTokenCount(newTokenCount);
|
|
207520
|
+
if (info.compressionStatus === 1 /* COMPRESSED */) {
|
|
207521
|
+
if (newHistory) {
|
|
207522
|
+
this.chat = await this.startChat(newHistory);
|
|
207523
|
+
this.forceFullIdeContext = true;
|
|
207524
|
+
}
|
|
207525
|
+
} else if (info.compressionStatus === 2 /* COMPRESSION_FAILED_INFLATED_TOKEN_COUNT */ || info.compressionStatus === 4 /* COMPRESSION_FAILED_EMPTY_SUMMARY */) {
|
|
207526
|
+
if (!force) {
|
|
207527
|
+
this.hasFailedCompressionAttempt = true;
|
|
207528
|
+
}
|
|
207443
207529
|
}
|
|
207444
|
-
|
|
207445
|
-
this.config,
|
|
207446
|
-
makeChatCompressionEvent({
|
|
207447
|
-
tokens_before: originalTokenCount,
|
|
207448
|
-
tokens_after: newTokenCount
|
|
207449
|
-
})
|
|
207450
|
-
);
|
|
207451
|
-
return {
|
|
207452
|
-
originalTokenCount,
|
|
207453
|
-
newTokenCount,
|
|
207454
|
-
compressionStatus: 1 /* COMPRESSED */
|
|
207455
|
-
};
|
|
207530
|
+
return info;
|
|
207456
207531
|
}
|
|
207457
207532
|
};
|
|
207458
207533
|
}
|
|
@@ -235724,38 +235799,13 @@ async function listKnowledgeExt(subPath = "", debugMode = false) {
|
|
|
235724
235799
|
}
|
|
235725
235800
|
}
|
|
235726
235801
|
function findKnowledgeDirectory() {
|
|
235727
|
-
const
|
|
235728
|
-
|
|
235729
|
-
|
|
235730
|
-
|
|
235731
|
-
|
|
235732
|
-
|
|
235733
|
-
|
|
235734
|
-
path43.resolve(__dirname4, "../../../../../.knowledge"),
|
|
235735
|
-
// 从 core 包的 dist/src/tools 回退到 cli 包
|
|
235736
|
-
path43.resolve(__dirname4, "../../../../../../.knowledge"),
|
|
235737
|
-
// 兼容不同的安装结构
|
|
235738
|
-
// 3. npm 全局安装:从 core 包所在位置找到 rdmind 包
|
|
235739
|
-
// 全局: /usr/local/lib/node_modules/@rdmind/rdmind/node_modules/@rdmind/rdmind-core/dist/src/tools
|
|
235740
|
-
path43.resolve(__dirname4, "../../../../../../../@rdmind/rdmind/.knowledge"),
|
|
235741
|
-
// 4. 开发环境:相对于项目根目录
|
|
235742
|
-
path43.resolve(__dirname4, "../../../../../../../.knowledge"),
|
|
235743
|
-
// 从 packages/core/dist/src/tools 到项目根
|
|
235744
|
-
path43.resolve(__dirname4, "../../../../../../.knowledge"),
|
|
235745
|
-
path43.resolve(__dirname4, "../../../../../.knowledge"),
|
|
235746
|
-
path43.resolve(__dirname4, "../../../../.knowledge"),
|
|
235747
|
-
path43.resolve(__dirname4, "../../../.knowledge"),
|
|
235748
|
-
path43.resolve(__dirname4, "../../.knowledge"),
|
|
235749
|
-
path43.resolve(__dirname4, "../.knowledge")
|
|
235750
|
-
];
|
|
235751
|
-
for (const candidatePath of candidatePaths) {
|
|
235752
|
-
try {
|
|
235753
|
-
if (fsSync2.existsSync(candidatePath) && fsSync2.statSync(candidatePath).isDirectory()) {
|
|
235754
|
-
return candidatePath;
|
|
235755
|
-
}
|
|
235756
|
-
} catch {
|
|
235757
|
-
continue;
|
|
235758
|
-
}
|
|
235802
|
+
const userKnowledgePath = path43.resolve(process.cwd(), ".knowledge");
|
|
235803
|
+
if (fsSync2.existsSync(userKnowledgePath) && fsSync2.statSync(userKnowledgePath).isDirectory()) {
|
|
235804
|
+
return userKnowledgePath;
|
|
235805
|
+
}
|
|
235806
|
+
const packageKnowledgePath = path43.join(__dirname4, ".knowledge");
|
|
235807
|
+
if (fsSync2.existsSync(packageKnowledgePath) && fsSync2.statSync(packageKnowledgePath).isDirectory()) {
|
|
235808
|
+
return packageKnowledgePath;
|
|
235759
235809
|
}
|
|
235760
235810
|
return null;
|
|
235761
235811
|
}
|
|
@@ -245048,16 +245098,30 @@ var init_redoc_fetch = __esm({
|
|
|
245048
245098
|
if (!responseData.data) {
|
|
245049
245099
|
const errorMessage = "Redoc API response does not contain data field";
|
|
245050
245100
|
console.error(`[RedocFetchTool] ${errorMessage}`);
|
|
245051
|
-
console.error(
|
|
245101
|
+
console.error(
|
|
245102
|
+
`[RedocFetchTool] \u5B8C\u6574\u54CD\u5E94\u6570\u636E:`,
|
|
245103
|
+
JSON.stringify(responseData, null, 2)
|
|
245104
|
+
);
|
|
245052
245105
|
throw new Error(errorMessage);
|
|
245053
245106
|
}
|
|
245054
245107
|
if (!responseData.data.content) {
|
|
245055
245108
|
const errorMessage = "Redoc API response does not contain content field in data";
|
|
245056
245109
|
console.error(`[RedocFetchTool] ${errorMessage}`);
|
|
245057
|
-
console.error(
|
|
245058
|
-
|
|
245059
|
-
|
|
245060
|
-
|
|
245110
|
+
console.error(
|
|
245111
|
+
`[RedocFetchTool] \u5B8C\u6574\u54CD\u5E94\u6570\u636E:`,
|
|
245112
|
+
JSON.stringify(responseData, null, 2)
|
|
245113
|
+
);
|
|
245114
|
+
console.error(
|
|
245115
|
+
`[RedocFetchTool] data \u5B57\u6BB5\u5185\u5BB9:`,
|
|
245116
|
+
JSON.stringify(responseData.data, null, 2)
|
|
245117
|
+
);
|
|
245118
|
+
console.error(
|
|
245119
|
+
`[RedocFetchTool] data \u5B57\u6BB5\u7684\u6240\u6709\u952E:`,
|
|
245120
|
+
Object.keys(responseData.data)
|
|
245121
|
+
);
|
|
245122
|
+
throw new Error(
|
|
245123
|
+
`${errorMessage}. \u53EF\u7528\u5B57\u6BB5: ${Object.keys(responseData.data).join(", ")}`
|
|
245124
|
+
);
|
|
245061
245125
|
}
|
|
245062
245126
|
console.debug(
|
|
245063
245127
|
`[RedocFetchTool] Successfully fetched content for doc_id: ${docId}, title: ${responseData.data.title}`
|
|
@@ -319835,7 +319899,7 @@ function CompressionMessage({
|
|
|
319835
319899
|
return "Chat history compression did not reduce size. This may indicate issues with the compression prompt.";
|
|
319836
319900
|
case 3 /* COMPRESSION_FAILED_TOKEN_COUNT_ERROR */:
|
|
319837
319901
|
return "Could not compress chat history due to a token counting error.";
|
|
319838
|
-
case
|
|
319902
|
+
case 5 /* NOOP */:
|
|
319839
319903
|
return "Chat history is already compressed.";
|
|
319840
319904
|
default:
|
|
319841
319905
|
return "";
|
|
@@ -319912,7 +319976,7 @@ init_esbuild_shims();
|
|
|
319912
319976
|
|
|
319913
319977
|
// packages/cli/src/generated/git-commit.ts
|
|
319914
319978
|
init_esbuild_shims();
|
|
319915
|
-
var GIT_COMMIT_INFO2 = "
|
|
319979
|
+
var GIT_COMMIT_INFO2 = "bf55c089";
|
|
319916
319980
|
|
|
319917
319981
|
// packages/cli/src/ui/components/AboutBox.tsx
|
|
319918
319982
|
var import_jsx_runtime43 = __toESM(require_jsx_runtime(), 1);
|
|
@@ -329514,6 +329578,8 @@ var USER_SETTINGS_PATH = Storage.getGlobalSettingsPath();
|
|
|
329514
329578
|
var USER_SETTINGS_DIR2 = path72.dirname(USER_SETTINGS_PATH);
|
|
329515
329579
|
var DEFAULT_EXCLUDED_ENV_VARS = ["DEBUG", "DEBUG_MODE"];
|
|
329516
329580
|
var MIGRATE_V2_OVERWRITE = true;
|
|
329581
|
+
var SETTINGS_VERSION = 2;
|
|
329582
|
+
var SETTINGS_VERSION_KEY = "$version";
|
|
329517
329583
|
var MIGRATION_MAP = {
|
|
329518
329584
|
accessibility: "ui.accessibility",
|
|
329519
329585
|
allowedTools: "tools.allowed",
|
|
@@ -329639,6 +329705,12 @@ function setNestedProperty(obj, path109, value) {
|
|
|
329639
329705
|
}
|
|
329640
329706
|
__name(setNestedProperty, "setNestedProperty");
|
|
329641
329707
|
function needsMigration(settings) {
|
|
329708
|
+
if (SETTINGS_VERSION_KEY in settings) {
|
|
329709
|
+
const version2 = settings[SETTINGS_VERSION_KEY];
|
|
329710
|
+
if (typeof version2 === "number" && version2 >= SETTINGS_VERSION) {
|
|
329711
|
+
return false;
|
|
329712
|
+
}
|
|
329713
|
+
}
|
|
329642
329714
|
const hasV1Keys = Object.entries(MIGRATION_MAP).some(([v1Key, v2Path]) => {
|
|
329643
329715
|
if (v1Key === v2Path || !(v1Key in settings)) {
|
|
329644
329716
|
return false;
|
|
@@ -329659,6 +329731,11 @@ function migrateSettingsToV2(flatSettings) {
|
|
|
329659
329731
|
const flatKeys = new Set(Object.keys(flatSettings));
|
|
329660
329732
|
for (const [oldKey, newPath] of Object.entries(MIGRATION_MAP)) {
|
|
329661
329733
|
if (flatKeys.has(oldKey)) {
|
|
329734
|
+
if (KNOWN_V2_CONTAINERS.has(oldKey) && typeof flatSettings[oldKey] === "object" && flatSettings[oldKey] !== null && !Array.isArray(flatSettings[oldKey])) {
|
|
329735
|
+
v2Settings[oldKey] = flatSettings[oldKey];
|
|
329736
|
+
flatKeys.delete(oldKey);
|
|
329737
|
+
continue;
|
|
329738
|
+
}
|
|
329662
329739
|
setNestedProperty(v2Settings, newPath, flatSettings[oldKey]);
|
|
329663
329740
|
flatKeys.delete(oldKey);
|
|
329664
329741
|
}
|
|
@@ -329682,6 +329759,7 @@ function migrateSettingsToV2(flatSettings) {
|
|
|
329682
329759
|
v2Settings[remainingKey] = newValue;
|
|
329683
329760
|
}
|
|
329684
329761
|
}
|
|
329762
|
+
v2Settings[SETTINGS_VERSION_KEY] = SETTINGS_VERSION;
|
|
329685
329763
|
return v2Settings;
|
|
329686
329764
|
}
|
|
329687
329765
|
__name(migrateSettingsToV2, "migrateSettingsToV2");
|
|
@@ -329718,6 +329796,9 @@ function migrateSettingsToV1(v2Settings) {
|
|
|
329718
329796
|
v2Keys.delete("mcpServers");
|
|
329719
329797
|
}
|
|
329720
329798
|
for (const remainingKey of v2Keys) {
|
|
329799
|
+
if (remainingKey === SETTINGS_VERSION_KEY) {
|
|
329800
|
+
continue;
|
|
329801
|
+
}
|
|
329721
329802
|
const value = v2Settings[remainingKey];
|
|
329722
329803
|
if (value === void 0) {
|
|
329723
329804
|
continue;
|
|
@@ -329923,6 +330004,21 @@ function loadSettings(workspaceDir = process27.cwd()) {
|
|
|
329923
330004
|
}
|
|
329924
330005
|
settingsObject = migratedSettings;
|
|
329925
330006
|
}
|
|
330007
|
+
} else if (!(SETTINGS_VERSION_KEY in settingsObject)) {
|
|
330008
|
+
settingsObject[SETTINGS_VERSION_KEY] = SETTINGS_VERSION;
|
|
330009
|
+
if (MIGRATE_V2_OVERWRITE) {
|
|
330010
|
+
try {
|
|
330011
|
+
fs70.writeFileSync(
|
|
330012
|
+
filePath,
|
|
330013
|
+
JSON.stringify(settingsObject, null, 2),
|
|
330014
|
+
"utf-8"
|
|
330015
|
+
);
|
|
330016
|
+
} catch (e2) {
|
|
330017
|
+
console.error(
|
|
330018
|
+
`Error adding version to settings file: ${getErrorMessage(e2)}`
|
|
330019
|
+
);
|
|
330020
|
+
}
|
|
330021
|
+
}
|
|
329926
330022
|
}
|
|
329927
330023
|
return { settings: settingsObject, rawJson: content };
|
|
329928
330024
|
}
|
|
@@ -342023,7 +342119,7 @@ __name(getPackageJson, "getPackageJson");
|
|
|
342023
342119
|
// packages/cli/src/utils/version.ts
|
|
342024
342120
|
async function getCliVersion() {
|
|
342025
342121
|
const pkgJson = await getPackageJson();
|
|
342026
|
-
return "0.0.21
|
|
342122
|
+
return "0.0.21";
|
|
342027
342123
|
}
|
|
342028
342124
|
__name(getCliVersion, "getCliVersion");
|
|
342029
342125
|
|
|
@@ -342476,24 +342572,24 @@ async function parseArguments(settings) {
|
|
|
342476
342572
|
"\u4F7F\u7528\u65B9\u6CD5: rdmind [options] [command]\n\nRDMind - \u542F\u52A8\u4EA4\u4E92\u5F0F CLI\uFF0C\u4F7F\u7528 -p/--prompt \u8FDB\u5165\u975E\u4EA4\u4E92\u6A21\u5F0F"
|
|
342477
342573
|
).option("telemetry", {
|
|
342478
342574
|
type: "boolean",
|
|
342479
|
-
description: "
|
|
342575
|
+
description: "Enable telemetry? This flag specifically controls if telemetry is sent. Other --telemetry-* flags set specific values but do not enable telemetry on their own."
|
|
342480
342576
|
}).option("telemetry-target", {
|
|
342481
342577
|
type: "string",
|
|
342482
342578
|
choices: ["local", "gcp"],
|
|
342483
|
-
description: "
|
|
342579
|
+
description: "Set the telemetry target (local or gcp). Overrides settings files."
|
|
342484
342580
|
}).option("telemetry-otlp-endpoint", {
|
|
342485
342581
|
type: "string",
|
|
342486
|
-
description: "
|
|
342582
|
+
description: "Set the OTLP endpoint for telemetry. Overrides environment variables and settings files."
|
|
342487
342583
|
}).option("telemetry-otlp-protocol", {
|
|
342488
342584
|
type: "string",
|
|
342489
342585
|
choices: ["grpc", "http"],
|
|
342490
|
-
description: "
|
|
342586
|
+
description: "Set the OTLP protocol for telemetry (grpc or http). Overrides settings files."
|
|
342491
342587
|
}).option("telemetry-log-prompts", {
|
|
342492
342588
|
type: "boolean",
|
|
342493
|
-
description: "
|
|
342589
|
+
description: "Enable or disable logging of user prompts for telemetry. Overrides settings files."
|
|
342494
342590
|
}).option("telemetry-outfile", {
|
|
342495
342591
|
type: "string",
|
|
342496
|
-
description: "
|
|
342592
|
+
description: "Redirect all telemetry output to the specified file."
|
|
342497
342593
|
}).deprecateOption(
|
|
342498
342594
|
"telemetry",
|
|
342499
342595
|
'Use the "telemetry.enabled" setting in settings.json instead. This flag will be removed in a future version.'
|
|
@@ -342531,52 +342627,52 @@ async function parseArguments(settings) {
|
|
|
342531
342627
|
}).option("model", {
|
|
342532
342628
|
alias: "m",
|
|
342533
342629
|
type: "string",
|
|
342534
|
-
description:
|
|
342630
|
+
description: `Model`
|
|
342535
342631
|
}).option("prompt", {
|
|
342536
342632
|
alias: "p",
|
|
342537
342633
|
type: "string",
|
|
342538
|
-
description: "
|
|
342634
|
+
description: "Prompt. Appended to input on stdin (if any)."
|
|
342539
342635
|
}).option("prompt-interactive", {
|
|
342540
342636
|
alias: "i",
|
|
342541
342637
|
type: "string",
|
|
342542
|
-
description: "
|
|
342638
|
+
description: "Execute the provided prompt and continue in interactive mode"
|
|
342543
342639
|
}).option("sandbox", {
|
|
342544
342640
|
alias: "s",
|
|
342545
342641
|
type: "boolean",
|
|
342546
|
-
description: "
|
|
342642
|
+
description: "Run in sandbox?"
|
|
342547
342643
|
}).option("sandbox-image", {
|
|
342548
342644
|
type: "string",
|
|
342549
|
-
description: "
|
|
342645
|
+
description: "Sandbox image URI."
|
|
342550
342646
|
}).option("all-files", {
|
|
342551
342647
|
alias: ["a"],
|
|
342552
342648
|
type: "boolean",
|
|
342553
|
-
description: "
|
|
342649
|
+
description: "Include ALL files in context?",
|
|
342554
342650
|
default: false
|
|
342555
342651
|
}).option("show-memory-usage", {
|
|
342556
342652
|
type: "boolean",
|
|
342557
|
-
description: "
|
|
342653
|
+
description: "Show memory usage in status bar",
|
|
342558
342654
|
default: false
|
|
342559
342655
|
}).option("yolo", {
|
|
342560
342656
|
alias: "y",
|
|
342561
342657
|
type: "boolean",
|
|
342562
|
-
description: "
|
|
342658
|
+
description: "Automatically accept all actions (aka YOLO mode, see https://www.youtube.com/watch?v=xvFZjo5PgG0 for more details)?",
|
|
342563
342659
|
default: false
|
|
342564
342660
|
}).option("approval-mode", {
|
|
342565
342661
|
type: "string",
|
|
342566
342662
|
choices: ["plan", "default", "auto-edit", "yolo"],
|
|
342567
|
-
description: "
|
|
342663
|
+
description: "Set the approval mode: plan (plan only), default (prompt for approval), auto-edit (auto-approve edit tools), yolo (auto-approve all tools)"
|
|
342568
342664
|
}).option("checkpointing", {
|
|
342569
342665
|
alias: "c",
|
|
342570
342666
|
type: "boolean",
|
|
342571
|
-
description: "
|
|
342667
|
+
description: "Enables checkpointing of file edits",
|
|
342572
342668
|
default: false
|
|
342573
342669
|
}).option("experimental-acp", {
|
|
342574
342670
|
type: "boolean",
|
|
342575
|
-
description: "
|
|
342671
|
+
description: "Starts the agent in ACP mode"
|
|
342576
342672
|
}).option("allowed-mcp-server-names", {
|
|
342577
342673
|
type: "array",
|
|
342578
342674
|
string: true,
|
|
342579
|
-
description: "
|
|
342675
|
+
description: "Allowed MCP server names",
|
|
342580
342676
|
coerce: /* @__PURE__ */ __name((mcpServerNames) => (
|
|
342581
342677
|
// Handle comma-separated values
|
|
342582
342678
|
mcpServerNames.flatMap(
|
|
@@ -342586,7 +342682,7 @@ async function parseArguments(settings) {
|
|
|
342586
342682
|
}).option("allowed-tools", {
|
|
342587
342683
|
type: "array",
|
|
342588
342684
|
string: true,
|
|
342589
|
-
description: "
|
|
342685
|
+
description: "Tools that are allowed to run without confirmation",
|
|
342590
342686
|
coerce: /* @__PURE__ */ __name((tools) => (
|
|
342591
342687
|
// Handle comma-separated values
|
|
342592
342688
|
tools.flatMap((tool) => tool.split(",").map((t2) => t2.trim()))
|
|
@@ -342595,7 +342691,7 @@ async function parseArguments(settings) {
|
|
|
342595
342691
|
alias: "e",
|
|
342596
342692
|
type: "array",
|
|
342597
342693
|
string: true,
|
|
342598
|
-
description: "
|
|
342694
|
+
description: "A list of extensions to use. If not provided, all extensions are used.",
|
|
342599
342695
|
coerce: /* @__PURE__ */ __name((extensions) => (
|
|
342600
342696
|
// Handle comma-separated values
|
|
342601
342697
|
extensions.flatMap(
|
|
@@ -342605,34 +342701,34 @@ async function parseArguments(settings) {
|
|
|
342605
342701
|
}).option("list-extensions", {
|
|
342606
342702
|
alias: "l",
|
|
342607
342703
|
type: "boolean",
|
|
342608
|
-
description: "
|
|
342704
|
+
description: "List all available extensions and exit."
|
|
342609
342705
|
}).option("include-directories", {
|
|
342610
342706
|
type: "array",
|
|
342611
342707
|
string: true,
|
|
342612
|
-
description: "
|
|
342708
|
+
description: "Additional directories to include in the workspace (comma-separated or multiple --include-directories)",
|
|
342613
342709
|
coerce: /* @__PURE__ */ __name((dirs) => (
|
|
342614
342710
|
// Handle comma-separated values
|
|
342615
342711
|
dirs.flatMap((dir) => dir.split(",").map((d) => d.trim()))
|
|
342616
342712
|
), "coerce")
|
|
342617
342713
|
}).option("openai-logging", {
|
|
342618
342714
|
type: "boolean",
|
|
342619
|
-
description: "
|
|
342715
|
+
description: "Enable logging of OpenAI API calls for debugging and analysis"
|
|
342620
342716
|
}).option("openai-api-key", {
|
|
342621
342717
|
type: "string",
|
|
342622
|
-
description: "
|
|
342718
|
+
description: "OpenAI API key to use for authentication"
|
|
342623
342719
|
}).option("openai-base-url", {
|
|
342624
342720
|
type: "string",
|
|
342625
|
-
description: "OpenAI base URL"
|
|
342721
|
+
description: "OpenAI base URL (for custom endpoints)"
|
|
342626
342722
|
}).option("tavily-api-key", {
|
|
342627
342723
|
type: "string",
|
|
342628
|
-
description: "Tavily API
|
|
342724
|
+
description: "Tavily API key for web search functionality"
|
|
342629
342725
|
}).option("screen-reader", {
|
|
342630
342726
|
type: "boolean",
|
|
342631
|
-
description: "
|
|
342727
|
+
description: "Enable screen reader mode for accessibility."
|
|
342632
342728
|
}).option("vlm-switch-mode", {
|
|
342633
342729
|
type: "string",
|
|
342634
342730
|
choices: ["once", "session", "persist"],
|
|
342635
|
-
description: "
|
|
342731
|
+
description: "Default behavior when images are detected in input. Values: once (one-time switch), session (switch for entire session), persist (continue with current model). Overrides settings files.",
|
|
342636
342732
|
default: process.env["VLM_SWITCH_MODE"]
|
|
342637
342733
|
}).option("output-format", {
|
|
342638
342734
|
alias: "o",
|
|
@@ -342662,13 +342758,13 @@ async function parseArguments(settings) {
|
|
|
342662
342758
|
const query = argv["query"];
|
|
342663
342759
|
const hasPositionalQuery = Array.isArray(query) ? query.length > 0 : !!query;
|
|
342664
342760
|
if (argv["prompt"] && hasPositionalQuery) {
|
|
342665
|
-
return "
|
|
342761
|
+
return "Cannot use both a positional prompt and the --prompt (-p) flag together";
|
|
342666
342762
|
}
|
|
342667
342763
|
if (argv["prompt"] && argv["promptInteractive"]) {
|
|
342668
|
-
return "
|
|
342764
|
+
return "Cannot use both --prompt (-p) and --prompt-interactive (-i) together";
|
|
342669
342765
|
}
|
|
342670
342766
|
if (argv["yolo"] && argv["approvalMode"]) {
|
|
342671
|
-
return "
|
|
342767
|
+
return "Cannot use both --yolo (-y) and --approval-mode together. Use --approval-mode=yolo instead.";
|
|
342672
342768
|
}
|
|
342673
342769
|
return true;
|
|
342674
342770
|
})
|