@probelabs/probe 0.6.0-rc198 → 0.6.0-rc200
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/bin/binaries/probe-v0.6.0-rc200-aarch64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc200-aarch64-unknown-linux-musl.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc200-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc200-x86_64-pc-windows-msvc.zip +0 -0
- package/bin/binaries/probe-v0.6.0-rc200-x86_64-unknown-linux-musl.tar.gz +0 -0
- package/build/agent/index.js +1588 -1530
- package/build/agent/xmlParsingUtils.js +6 -3
- package/build/delegate.js +5 -1
- package/build/tools/common.js +29 -4
- package/build/tools/index.js +3 -1
- package/build/tools/vercel.js +17 -4
- package/cjs/agent/ProbeAgent.cjs +2240 -2182
- package/cjs/index.cjs +690 -670
- package/package.json +1 -1
- package/src/agent/xmlParsingUtils.js +6 -3
- package/src/delegate.js +5 -1
- package/src/tools/common.js +29 -4
- package/src/tools/index.js +3 -1
- package/src/tools/vercel.js +17 -4
- package/bin/binaries/probe-v0.6.0-rc198-aarch64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc198-aarch64-unknown-linux-musl.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc198-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc198-x86_64-pc-windows-msvc.zip +0 -0
- package/bin/binaries/probe-v0.6.0-rc198-x86_64-unknown-linux-musl.tar.gz +0 -0
package/cjs/index.cjs
CHANGED
|
@@ -30515,261 +30515,6 @@ var init_imageConfig = __esm({
|
|
|
30515
30515
|
}
|
|
30516
30516
|
});
|
|
30517
30517
|
|
|
30518
|
-
// src/agent/xmlParsingUtils.js
|
|
30519
|
-
function removeThinkingTags(xmlString) {
|
|
30520
|
-
let result = xmlString;
|
|
30521
|
-
result = result.replace(/<thinking>[\s\S]*?<\/thinking>/g, "");
|
|
30522
|
-
const thinkingIndex = result.indexOf("<thinking>");
|
|
30523
|
-
if (thinkingIndex !== -1) {
|
|
30524
|
-
const afterThinking = result.substring(thinkingIndex + "<thinking>".length);
|
|
30525
|
-
const toolPattern = /<(search|query|extract|listFiles|searchFiles|implement|attempt_completion|attempt_complete)>/;
|
|
30526
|
-
const toolMatch = afterThinking.match(toolPattern);
|
|
30527
|
-
if (toolMatch) {
|
|
30528
|
-
const toolStart = thinkingIndex + "<thinking>".length + toolMatch.index;
|
|
30529
|
-
result = result.substring(0, thinkingIndex) + result.substring(toolStart);
|
|
30530
|
-
} else {
|
|
30531
|
-
result = result.substring(0, thinkingIndex);
|
|
30532
|
-
}
|
|
30533
|
-
}
|
|
30534
|
-
return result.trim();
|
|
30535
|
-
}
|
|
30536
|
-
function extractThinkingContent(xmlString) {
|
|
30537
|
-
const thinkingMatch = xmlString.match(/<thinking>([\s\S]*?)<\/thinking>/);
|
|
30538
|
-
return thinkingMatch ? thinkingMatch[1].trim() : null;
|
|
30539
|
-
}
|
|
30540
|
-
function checkAttemptCompleteRecovery(cleanedXmlString, validTools = []) {
|
|
30541
|
-
const openTagIndex = cleanedXmlString.indexOf("<attempt_completion>");
|
|
30542
|
-
if (openTagIndex !== -1) {
|
|
30543
|
-
const afterOpenTag = cleanedXmlString.substring(openTagIndex + "<attempt_completion>".length);
|
|
30544
|
-
const closeTagIndex = cleanedXmlString.lastIndexOf("</attempt_completion>");
|
|
30545
|
-
let content;
|
|
30546
|
-
let hasClosingTag = false;
|
|
30547
|
-
if (closeTagIndex !== -1 && closeTagIndex >= openTagIndex + "<attempt_completion>".length) {
|
|
30548
|
-
content = cleanedXmlString.substring(
|
|
30549
|
-
openTagIndex + "<attempt_completion>".length,
|
|
30550
|
-
closeTagIndex
|
|
30551
|
-
).trim();
|
|
30552
|
-
hasClosingTag = true;
|
|
30553
|
-
} else {
|
|
30554
|
-
content = afterOpenTag.trim();
|
|
30555
|
-
hasClosingTag = false;
|
|
30556
|
-
}
|
|
30557
|
-
if (content) {
|
|
30558
|
-
return {
|
|
30559
|
-
toolName: "attempt_completion",
|
|
30560
|
-
params: { result: content }
|
|
30561
|
-
};
|
|
30562
|
-
}
|
|
30563
|
-
return {
|
|
30564
|
-
toolName: "attempt_completion",
|
|
30565
|
-
params: { result: hasClosingTag ? "" : "__PREVIOUS_RESPONSE__" }
|
|
30566
|
-
};
|
|
30567
|
-
}
|
|
30568
|
-
const attemptCompletePatterns = [
|
|
30569
|
-
// Standard shorthand with optional whitespace
|
|
30570
|
-
/^<attempt_complete>\s*$/,
|
|
30571
|
-
// Empty with proper closing tag (common case from the logs)
|
|
30572
|
-
/^<attempt_complete>\s*<\/attempt_complete>\s*$/,
|
|
30573
|
-
// Self-closing variant
|
|
30574
|
-
/^<attempt_complete\s*\/>\s*$/,
|
|
30575
|
-
// Incomplete opening tag (missing closing bracket)
|
|
30576
|
-
/^<attempt_complete\s*$/,
|
|
30577
|
-
// With trailing content (extract just the tag part) - must come after empty tag pattern
|
|
30578
|
-
/^<attempt_complete>(.*)$/s,
|
|
30579
|
-
// Self-closing with trailing content
|
|
30580
|
-
/^<attempt_complete\s*\/>(.*)$/s
|
|
30581
|
-
];
|
|
30582
|
-
for (const pattern of attemptCompletePatterns) {
|
|
30583
|
-
const match2 = cleanedXmlString.match(pattern);
|
|
30584
|
-
if (match2) {
|
|
30585
|
-
return {
|
|
30586
|
-
toolName: "attempt_completion",
|
|
30587
|
-
params: { result: "__PREVIOUS_RESPONSE__" }
|
|
30588
|
-
};
|
|
30589
|
-
}
|
|
30590
|
-
}
|
|
30591
|
-
if (cleanedXmlString.includes("<attempt_complete") && !hasOtherToolTags(cleanedXmlString, validTools)) {
|
|
30592
|
-
return {
|
|
30593
|
-
toolName: "attempt_completion",
|
|
30594
|
-
params: { result: "__PREVIOUS_RESPONSE__" }
|
|
30595
|
-
};
|
|
30596
|
-
}
|
|
30597
|
-
return null;
|
|
30598
|
-
}
|
|
30599
|
-
function hasOtherToolTags(xmlString, validTools = []) {
|
|
30600
|
-
const defaultTools = ["search", "query", "extract", "listFiles", "searchFiles", "implement", "attempt_completion"];
|
|
30601
|
-
const toolsToCheck = validTools.length > 0 ? validTools : defaultTools;
|
|
30602
|
-
for (const tool4 of toolsToCheck) {
|
|
30603
|
-
if (tool4 !== "attempt_completion" && xmlString.includes(`<${tool4}`)) {
|
|
30604
|
-
return true;
|
|
30605
|
-
}
|
|
30606
|
-
}
|
|
30607
|
-
return false;
|
|
30608
|
-
}
|
|
30609
|
-
function processXmlWithThinkingAndRecovery(xmlString, validTools = []) {
|
|
30610
|
-
const thinkingContent = extractThinkingContent(xmlString);
|
|
30611
|
-
const cleanedXmlString = removeThinkingTags(xmlString);
|
|
30612
|
-
const recoveryResult = checkAttemptCompleteRecovery(cleanedXmlString, validTools);
|
|
30613
|
-
if (process.env.DEBUG === "1" && thinkingContent) {
|
|
30614
|
-
console.log(`[DEBUG] AI Thinking Process:
|
|
30615
|
-
${thinkingContent}`);
|
|
30616
|
-
}
|
|
30617
|
-
return {
|
|
30618
|
-
cleanedXmlString,
|
|
30619
|
-
thinkingContent,
|
|
30620
|
-
recoveryResult
|
|
30621
|
-
};
|
|
30622
|
-
}
|
|
30623
|
-
var init_xmlParsingUtils = __esm({
|
|
30624
|
-
"src/agent/xmlParsingUtils.js"() {
|
|
30625
|
-
"use strict";
|
|
30626
|
-
}
|
|
30627
|
-
});
|
|
30628
|
-
|
|
30629
|
-
// src/agent/tools.js
|
|
30630
|
-
function createTools(configOptions) {
|
|
30631
|
-
const tools2 = {};
|
|
30632
|
-
const isToolAllowed = configOptions.isToolAllowed || ((toolName) => {
|
|
30633
|
-
if (!configOptions.allowedTools) return true;
|
|
30634
|
-
return configOptions.allowedTools.isEnabled(toolName);
|
|
30635
|
-
});
|
|
30636
|
-
if (isToolAllowed("search")) {
|
|
30637
|
-
tools2.searchTool = searchTool(configOptions);
|
|
30638
|
-
}
|
|
30639
|
-
if (isToolAllowed("query")) {
|
|
30640
|
-
tools2.queryTool = queryTool(configOptions);
|
|
30641
|
-
}
|
|
30642
|
-
if (isToolAllowed("extract")) {
|
|
30643
|
-
tools2.extractTool = extractTool(configOptions);
|
|
30644
|
-
}
|
|
30645
|
-
if (configOptions.enableDelegate && isToolAllowed("delegate")) {
|
|
30646
|
-
tools2.delegateTool = delegateTool(configOptions);
|
|
30647
|
-
}
|
|
30648
|
-
if (configOptions.enableBash && isToolAllowed("bash")) {
|
|
30649
|
-
tools2.bashTool = bashTool(configOptions);
|
|
30650
|
-
}
|
|
30651
|
-
if (configOptions.allowEdit && isToolAllowed("edit")) {
|
|
30652
|
-
tools2.editTool = editTool(configOptions);
|
|
30653
|
-
}
|
|
30654
|
-
if (configOptions.allowEdit && isToolAllowed("create")) {
|
|
30655
|
-
tools2.createTool = createTool(configOptions);
|
|
30656
|
-
}
|
|
30657
|
-
return tools2;
|
|
30658
|
-
}
|
|
30659
|
-
function parseXmlToolCallWithThinking(xmlString, validTools) {
|
|
30660
|
-
const { cleanedXmlString, recoveryResult } = processXmlWithThinkingAndRecovery(xmlString, validTools);
|
|
30661
|
-
if (recoveryResult) {
|
|
30662
|
-
return recoveryResult;
|
|
30663
|
-
}
|
|
30664
|
-
return parseXmlToolCall(cleanedXmlString, validTools);
|
|
30665
|
-
}
|
|
30666
|
-
var import_crypto2, implementToolDefinition, listFilesToolDefinition, searchFilesToolDefinition, readImageToolDefinition;
|
|
30667
|
-
var init_tools = __esm({
|
|
30668
|
-
"src/agent/tools.js"() {
|
|
30669
|
-
"use strict";
|
|
30670
|
-
init_index();
|
|
30671
|
-
import_crypto2 = require("crypto");
|
|
30672
|
-
init_xmlParsingUtils();
|
|
30673
|
-
implementToolDefinition = `
|
|
30674
|
-
## implement
|
|
30675
|
-
Description: Implement a given task. Can modify files. Can be used ONLY if task explicitly stated that something requires modification or implementation.
|
|
30676
|
-
|
|
30677
|
-
Parameters:
|
|
30678
|
-
- task: (required) The task description. Should be as detailed as possible, ideally pointing to exact files which needs be modified or created.
|
|
30679
|
-
- autoCommits: (optional) Whether to enable auto-commits in aider. Default is false.
|
|
30680
|
-
|
|
30681
|
-
Usage Example:
|
|
30682
|
-
|
|
30683
|
-
<examples>
|
|
30684
|
-
|
|
30685
|
-
User: Can you implement a function to calculate Fibonacci numbers in main.js?
|
|
30686
|
-
<implement>
|
|
30687
|
-
<task>Implement a recursive function to calculate the nth Fibonacci number in main.js</task>
|
|
30688
|
-
</implement>
|
|
30689
|
-
|
|
30690
|
-
User: Can you implement a function to calculate Fibonacci numbers in main.js with auto-commits?
|
|
30691
|
-
<implement>
|
|
30692
|
-
<task>Implement a recursive function to calculate the nth Fibonacci number in main.js</task>
|
|
30693
|
-
<autoCommits>true</autoCommits>
|
|
30694
|
-
</implement>
|
|
30695
|
-
|
|
30696
|
-
</examples>
|
|
30697
|
-
`;
|
|
30698
|
-
listFilesToolDefinition = `
|
|
30699
|
-
## listFiles
|
|
30700
|
-
Description: List files and directories in a specified location.
|
|
30701
|
-
|
|
30702
|
-
Parameters:
|
|
30703
|
-
- directory: (optional) The directory path to list files from. Defaults to current directory if not specified.
|
|
30704
|
-
|
|
30705
|
-
Usage Example:
|
|
30706
|
-
|
|
30707
|
-
<examples>
|
|
30708
|
-
|
|
30709
|
-
User: Can you list the files in the src directory?
|
|
30710
|
-
<listFiles>
|
|
30711
|
-
<directory>src</directory>
|
|
30712
|
-
</listFiles>
|
|
30713
|
-
|
|
30714
|
-
User: What files are in the current directory?
|
|
30715
|
-
<listFiles>
|
|
30716
|
-
</listFiles>
|
|
30717
|
-
|
|
30718
|
-
</examples>
|
|
30719
|
-
`;
|
|
30720
|
-
searchFilesToolDefinition = `
|
|
30721
|
-
## searchFiles
|
|
30722
|
-
Description: Find files with name matching a glob pattern with recursive search capability.
|
|
30723
|
-
|
|
30724
|
-
Parameters:
|
|
30725
|
-
- pattern: (required) The glob pattern to search for (e.g., "**/*.js", "*.md").
|
|
30726
|
-
- directory: (optional) The directory to search in. Defaults to current directory if not specified.
|
|
30727
|
-
- recursive: (optional) Whether to search recursively. Defaults to true.
|
|
30728
|
-
|
|
30729
|
-
Usage Example:
|
|
30730
|
-
|
|
30731
|
-
<examples>
|
|
30732
|
-
|
|
30733
|
-
User: Can you find all JavaScript files in the project?
|
|
30734
|
-
<searchFiles>
|
|
30735
|
-
<pattern>**/*.js</pattern>
|
|
30736
|
-
</searchFiles>
|
|
30737
|
-
|
|
30738
|
-
User: Find all markdown files in the docs directory, but only at the top level.
|
|
30739
|
-
<searchFiles>
|
|
30740
|
-
<pattern>*.md</pattern>
|
|
30741
|
-
<directory>docs</directory>
|
|
30742
|
-
<recursive>false</recursive>
|
|
30743
|
-
</searchFiles>
|
|
30744
|
-
|
|
30745
|
-
</examples>
|
|
30746
|
-
`;
|
|
30747
|
-
readImageToolDefinition = `
|
|
30748
|
-
## readImage
|
|
30749
|
-
Description: Read and load an image file so it can be viewed by the AI. Use this when you need to analyze, describe, or work with image content. Images from user messages are automatically loaded, but use this tool to explicitly read images mentioned in tool outputs or when you need to examine specific image files.
|
|
30750
|
-
|
|
30751
|
-
Parameters:
|
|
30752
|
-
- path: (required) The path to the image file to read. Supports png, jpg, jpeg, webp, bmp, and svg formats.
|
|
30753
|
-
|
|
30754
|
-
Usage Example:
|
|
30755
|
-
|
|
30756
|
-
<examples>
|
|
30757
|
-
|
|
30758
|
-
User: Can you describe what's in screenshot.png?
|
|
30759
|
-
<readImage>
|
|
30760
|
-
<path>screenshot.png</path>
|
|
30761
|
-
</readImage>
|
|
30762
|
-
|
|
30763
|
-
User: Analyze the diagram in docs/architecture.svg
|
|
30764
|
-
<readImage>
|
|
30765
|
-
<path>docs/architecture.svg</path>
|
|
30766
|
-
</readImage>
|
|
30767
|
-
|
|
30768
|
-
</examples>
|
|
30769
|
-
`;
|
|
30770
|
-
}
|
|
30771
|
-
});
|
|
30772
|
-
|
|
30773
30518
|
// node_modules/zod/v3/helpers/util.js
|
|
30774
30519
|
var util, objectUtil, ZodParsedType, getParsedType;
|
|
30775
30520
|
var init_util2 = __esm({
|
|
@@ -34876,7 +34621,332 @@ var init_zod = __esm({
|
|
|
34876
34621
|
}
|
|
34877
34622
|
});
|
|
34878
34623
|
|
|
34624
|
+
// src/tools/edit.js
|
|
34625
|
+
function isPathAllowed(filePath, allowedFolders) {
|
|
34626
|
+
if (!allowedFolders || allowedFolders.length === 0) {
|
|
34627
|
+
const resolvedPath3 = (0, import_path5.resolve)(filePath);
|
|
34628
|
+
const cwd = (0, import_path5.resolve)(process.cwd());
|
|
34629
|
+
return resolvedPath3 === cwd || resolvedPath3.startsWith(cwd + import_path5.sep);
|
|
34630
|
+
}
|
|
34631
|
+
const resolvedPath2 = (0, import_path5.resolve)(filePath);
|
|
34632
|
+
return allowedFolders.some((folder) => {
|
|
34633
|
+
const allowedPath = (0, import_path5.resolve)(folder);
|
|
34634
|
+
return resolvedPath2 === allowedPath || resolvedPath2.startsWith(allowedPath + import_path5.sep);
|
|
34635
|
+
});
|
|
34636
|
+
}
|
|
34637
|
+
function parseFileToolOptions(options = {}) {
|
|
34638
|
+
return {
|
|
34639
|
+
debug: options.debug || false,
|
|
34640
|
+
allowedFolders: options.allowedFolders || [],
|
|
34641
|
+
cwd: options.cwd
|
|
34642
|
+
};
|
|
34643
|
+
}
|
|
34644
|
+
var import_ai, import_fs4, import_path5, import_fs5, editTool, createTool, editSchema, createSchema, editDescription, createDescription, editToolDefinition, createToolDefinition;
|
|
34645
|
+
var init_edit = __esm({
|
|
34646
|
+
"src/tools/edit.js"() {
|
|
34647
|
+
"use strict";
|
|
34648
|
+
import_ai = require("ai");
|
|
34649
|
+
import_fs4 = require("fs");
|
|
34650
|
+
import_path5 = require("path");
|
|
34651
|
+
import_fs5 = require("fs");
|
|
34652
|
+
editTool = (options = {}) => {
|
|
34653
|
+
const { debug, allowedFolders, cwd } = parseFileToolOptions(options);
|
|
34654
|
+
return (0, import_ai.tool)({
|
|
34655
|
+
name: "edit",
|
|
34656
|
+
description: `Edit files using exact string replacement (Claude Code style).
|
|
34657
|
+
|
|
34658
|
+
This tool performs exact string replacements in files. It requires the old_string to match exactly what's in the file, including all whitespace and indentation.
|
|
34659
|
+
|
|
34660
|
+
Parameters:
|
|
34661
|
+
- file_path: Path to the file to edit (absolute or relative)
|
|
34662
|
+
- old_string: Exact text to find and replace (must be unique in the file unless replace_all is true)
|
|
34663
|
+
- new_string: Text to replace with
|
|
34664
|
+
- replace_all: (optional) Replace all occurrences instead of requiring uniqueness
|
|
34665
|
+
|
|
34666
|
+
Important:
|
|
34667
|
+
- The old_string must match EXACTLY including whitespace
|
|
34668
|
+
- If old_string appears multiple times and replace_all is false, the edit will fail
|
|
34669
|
+
- Use larger context around the string to ensure uniqueness when needed`,
|
|
34670
|
+
inputSchema: {
|
|
34671
|
+
type: "object",
|
|
34672
|
+
properties: {
|
|
34673
|
+
file_path: {
|
|
34674
|
+
type: "string",
|
|
34675
|
+
description: "Path to the file to edit"
|
|
34676
|
+
},
|
|
34677
|
+
old_string: {
|
|
34678
|
+
type: "string",
|
|
34679
|
+
description: "Exact text to find and replace"
|
|
34680
|
+
},
|
|
34681
|
+
new_string: {
|
|
34682
|
+
type: "string",
|
|
34683
|
+
description: "Text to replace with"
|
|
34684
|
+
},
|
|
34685
|
+
replace_all: {
|
|
34686
|
+
type: "boolean",
|
|
34687
|
+
description: "Replace all occurrences (default: false)",
|
|
34688
|
+
default: false
|
|
34689
|
+
}
|
|
34690
|
+
},
|
|
34691
|
+
required: ["file_path", "old_string", "new_string"]
|
|
34692
|
+
},
|
|
34693
|
+
execute: async ({ file_path, old_string, new_string, replace_all = false }) => {
|
|
34694
|
+
try {
|
|
34695
|
+
if (!file_path || typeof file_path !== "string" || file_path.trim() === "") {
|
|
34696
|
+
return `Error editing file: Invalid file_path - must be a non-empty string`;
|
|
34697
|
+
}
|
|
34698
|
+
if (old_string === void 0 || old_string === null || typeof old_string !== "string") {
|
|
34699
|
+
return `Error editing file: Invalid old_string - must be a string`;
|
|
34700
|
+
}
|
|
34701
|
+
if (new_string === void 0 || new_string === null || typeof new_string !== "string") {
|
|
34702
|
+
return `Error editing file: Invalid new_string - must be a string`;
|
|
34703
|
+
}
|
|
34704
|
+
const resolvedPath2 = (0, import_path5.isAbsolute)(file_path) ? file_path : (0, import_path5.resolve)(cwd || process.cwd(), file_path);
|
|
34705
|
+
if (debug) {
|
|
34706
|
+
console.error(`[Edit] Attempting to edit file: ${resolvedPath2}`);
|
|
34707
|
+
}
|
|
34708
|
+
if (!isPathAllowed(resolvedPath2, allowedFolders)) {
|
|
34709
|
+
return `Error editing file: Permission denied - ${file_path} is outside allowed directories`;
|
|
34710
|
+
}
|
|
34711
|
+
if (!(0, import_fs5.existsSync)(resolvedPath2)) {
|
|
34712
|
+
return `Error editing file: File not found - ${file_path}`;
|
|
34713
|
+
}
|
|
34714
|
+
const content = await import_fs4.promises.readFile(resolvedPath2, "utf-8");
|
|
34715
|
+
if (!content.includes(old_string)) {
|
|
34716
|
+
return `Error editing file: String not found - the specified old_string was not found in ${file_path}`;
|
|
34717
|
+
}
|
|
34718
|
+
const occurrences = content.split(old_string).length - 1;
|
|
34719
|
+
if (!replace_all && occurrences > 1) {
|
|
34720
|
+
return `Error editing file: Multiple occurrences found - the old_string appears ${occurrences} times. Use replace_all: true to replace all occurrences, or provide more context to make the string unique.`;
|
|
34721
|
+
}
|
|
34722
|
+
let newContent;
|
|
34723
|
+
if (replace_all) {
|
|
34724
|
+
newContent = content.replaceAll(old_string, new_string);
|
|
34725
|
+
} else {
|
|
34726
|
+
newContent = content.replace(old_string, new_string);
|
|
34727
|
+
}
|
|
34728
|
+
if (newContent === content) {
|
|
34729
|
+
return `Error editing file: No changes made - old_string and new_string might be the same`;
|
|
34730
|
+
}
|
|
34731
|
+
await import_fs4.promises.writeFile(resolvedPath2, newContent, "utf-8");
|
|
34732
|
+
const replacedCount = replace_all ? occurrences : 1;
|
|
34733
|
+
if (debug) {
|
|
34734
|
+
console.error(`[Edit] Successfully edited ${resolvedPath2}, replaced ${replacedCount} occurrence(s)`);
|
|
34735
|
+
}
|
|
34736
|
+
return `Successfully edited ${file_path} (${replacedCount} replacement${replacedCount !== 1 ? "s" : ""})`;
|
|
34737
|
+
} catch (error2) {
|
|
34738
|
+
console.error("[Edit] Error:", error2);
|
|
34739
|
+
return `Error editing file: ${error2.message}`;
|
|
34740
|
+
}
|
|
34741
|
+
}
|
|
34742
|
+
});
|
|
34743
|
+
};
|
|
34744
|
+
createTool = (options = {}) => {
|
|
34745
|
+
const { debug, allowedFolders, cwd } = parseFileToolOptions(options);
|
|
34746
|
+
return (0, import_ai.tool)({
|
|
34747
|
+
name: "create",
|
|
34748
|
+
description: `Create new files with specified content.
|
|
34749
|
+
|
|
34750
|
+
This tool creates new files in the filesystem. It will create parent directories if they don't exist.
|
|
34751
|
+
|
|
34752
|
+
Parameters:
|
|
34753
|
+
- file_path: Path where the file should be created (absolute or relative)
|
|
34754
|
+
- content: Content to write to the file
|
|
34755
|
+
- overwrite: (optional) Whether to overwrite if file exists (default: false)
|
|
34756
|
+
|
|
34757
|
+
Important:
|
|
34758
|
+
- By default, will fail if the file already exists
|
|
34759
|
+
- Set overwrite: true to replace existing files
|
|
34760
|
+
- Parent directories will be created automatically if needed`,
|
|
34761
|
+
inputSchema: {
|
|
34762
|
+
type: "object",
|
|
34763
|
+
properties: {
|
|
34764
|
+
file_path: {
|
|
34765
|
+
type: "string",
|
|
34766
|
+
description: "Path where the file should be created"
|
|
34767
|
+
},
|
|
34768
|
+
content: {
|
|
34769
|
+
type: "string",
|
|
34770
|
+
description: "Content to write to the file"
|
|
34771
|
+
},
|
|
34772
|
+
overwrite: {
|
|
34773
|
+
type: "boolean",
|
|
34774
|
+
description: "Overwrite if file exists (default: false)",
|
|
34775
|
+
default: false
|
|
34776
|
+
}
|
|
34777
|
+
},
|
|
34778
|
+
required: ["file_path", "content"]
|
|
34779
|
+
},
|
|
34780
|
+
execute: async ({ file_path, content, overwrite = false }) => {
|
|
34781
|
+
try {
|
|
34782
|
+
if (!file_path || typeof file_path !== "string" || file_path.trim() === "") {
|
|
34783
|
+
return `Error creating file: Invalid file_path - must be a non-empty string`;
|
|
34784
|
+
}
|
|
34785
|
+
if (content === void 0 || content === null || typeof content !== "string") {
|
|
34786
|
+
return `Error creating file: Invalid content - must be a string`;
|
|
34787
|
+
}
|
|
34788
|
+
const resolvedPath2 = (0, import_path5.isAbsolute)(file_path) ? file_path : (0, import_path5.resolve)(cwd || process.cwd(), file_path);
|
|
34789
|
+
if (debug) {
|
|
34790
|
+
console.error(`[Create] Attempting to create file: ${resolvedPath2}`);
|
|
34791
|
+
}
|
|
34792
|
+
if (!isPathAllowed(resolvedPath2, allowedFolders)) {
|
|
34793
|
+
return `Error creating file: Permission denied - ${file_path} is outside allowed directories`;
|
|
34794
|
+
}
|
|
34795
|
+
if ((0, import_fs5.existsSync)(resolvedPath2) && !overwrite) {
|
|
34796
|
+
return `Error creating file: File already exists - ${file_path}. Use overwrite: true to replace it.`;
|
|
34797
|
+
}
|
|
34798
|
+
const dir = (0, import_path5.dirname)(resolvedPath2);
|
|
34799
|
+
await import_fs4.promises.mkdir(dir, { recursive: true });
|
|
34800
|
+
await import_fs4.promises.writeFile(resolvedPath2, content, "utf-8");
|
|
34801
|
+
const action = (0, import_fs5.existsSync)(resolvedPath2) && overwrite ? "overwrote" : "created";
|
|
34802
|
+
const bytes = Buffer.byteLength(content, "utf-8");
|
|
34803
|
+
if (debug) {
|
|
34804
|
+
console.error(`[Create] Successfully ${action} ${resolvedPath2}`);
|
|
34805
|
+
}
|
|
34806
|
+
return `Successfully ${action} ${file_path} (${bytes} bytes)`;
|
|
34807
|
+
} catch (error2) {
|
|
34808
|
+
console.error("[Create] Error:", error2);
|
|
34809
|
+
return `Error creating file: ${error2.message}`;
|
|
34810
|
+
}
|
|
34811
|
+
}
|
|
34812
|
+
});
|
|
34813
|
+
};
|
|
34814
|
+
editSchema = {
|
|
34815
|
+
type: "object",
|
|
34816
|
+
properties: {
|
|
34817
|
+
file_path: {
|
|
34818
|
+
type: "string",
|
|
34819
|
+
description: "Path to the file to edit"
|
|
34820
|
+
},
|
|
34821
|
+
old_string: {
|
|
34822
|
+
type: "string",
|
|
34823
|
+
description: "Exact text to find and replace"
|
|
34824
|
+
},
|
|
34825
|
+
new_string: {
|
|
34826
|
+
type: "string",
|
|
34827
|
+
description: "Text to replace with"
|
|
34828
|
+
},
|
|
34829
|
+
replace_all: {
|
|
34830
|
+
type: "boolean",
|
|
34831
|
+
description: "Replace all occurrences (default: false)"
|
|
34832
|
+
}
|
|
34833
|
+
},
|
|
34834
|
+
required: ["file_path", "old_string", "new_string"]
|
|
34835
|
+
};
|
|
34836
|
+
createSchema = {
|
|
34837
|
+
type: "object",
|
|
34838
|
+
properties: {
|
|
34839
|
+
file_path: {
|
|
34840
|
+
type: "string",
|
|
34841
|
+
description: "Path where the file should be created"
|
|
34842
|
+
},
|
|
34843
|
+
content: {
|
|
34844
|
+
type: "string",
|
|
34845
|
+
description: "Content to write to the file"
|
|
34846
|
+
},
|
|
34847
|
+
overwrite: {
|
|
34848
|
+
type: "boolean",
|
|
34849
|
+
description: "Overwrite if file exists (default: false)"
|
|
34850
|
+
}
|
|
34851
|
+
},
|
|
34852
|
+
required: ["file_path", "content"]
|
|
34853
|
+
};
|
|
34854
|
+
editDescription = "Edit files using exact string replacement. Requires exact match including whitespace.";
|
|
34855
|
+
createDescription = "Create new files with specified content. Will create parent directories if needed.";
|
|
34856
|
+
editToolDefinition = `
|
|
34857
|
+
## edit
|
|
34858
|
+
Description: ${editDescription}
|
|
34859
|
+
|
|
34860
|
+
When to use:
|
|
34861
|
+
- For precise, surgical edits to existing files
|
|
34862
|
+
- When you need to change specific lines or blocks of code
|
|
34863
|
+
- For renaming functions, variables, or updating configuration values
|
|
34864
|
+
- When the exact text to replace is known and unique (or use replace_all for multiple occurrences)
|
|
34865
|
+
|
|
34866
|
+
When NOT to use:
|
|
34867
|
+
- For creating new files (use 'create' tool instead)
|
|
34868
|
+
- When you cannot determine the exact text to replace
|
|
34869
|
+
- When changes span multiple locations that would be better handled together
|
|
34870
|
+
|
|
34871
|
+
Parameters:
|
|
34872
|
+
- file_path: (required) Path to the file to edit
|
|
34873
|
+
- old_string: (required) Exact text to find and replace (must match including whitespace, newlines, and indentation)
|
|
34874
|
+
- new_string: (required) Text to replace with
|
|
34875
|
+
- replace_all: (optional, default: false) Replace all occurrences if the string appears multiple times
|
|
34876
|
+
|
|
34877
|
+
Important notes:
|
|
34878
|
+
- The old_string MUST match EXACTLY, including all whitespace, indentation, and line breaks
|
|
34879
|
+
- If old_string appears multiple times and replace_all is false, the tool will fail
|
|
34880
|
+
- Always verify the exact formatting of the text you want to replace
|
|
34881
|
+
|
|
34882
|
+
Examples:
|
|
34883
|
+
<edit>
|
|
34884
|
+
<file_path>src/main.js</file_path>
|
|
34885
|
+
<old_string>function oldName() {
|
|
34886
|
+
return 42;
|
|
34887
|
+
}</old_string>
|
|
34888
|
+
<new_string>function newName() {
|
|
34889
|
+
return 42;
|
|
34890
|
+
}</new_string>
|
|
34891
|
+
</edit>
|
|
34892
|
+
|
|
34893
|
+
<edit>
|
|
34894
|
+
<file_path>config.json</file_path>
|
|
34895
|
+
<old_string>"debug": false</old_string>
|
|
34896
|
+
<new_string>"debug": true</new_string>
|
|
34897
|
+
<replace_all>true</replace_all>
|
|
34898
|
+
</edit>`;
|
|
34899
|
+
createToolDefinition = `
|
|
34900
|
+
## create
|
|
34901
|
+
Description: ${createDescription}
|
|
34902
|
+
|
|
34903
|
+
When to use:
|
|
34904
|
+
- For creating brand new files from scratch
|
|
34905
|
+
- When you need to add configuration files, documentation, or new modules
|
|
34906
|
+
- For generating boilerplate code or templates
|
|
34907
|
+
- When you have the complete content ready to write
|
|
34908
|
+
|
|
34909
|
+
When NOT to use:
|
|
34910
|
+
- For editing existing files (use 'edit' tool instead)
|
|
34911
|
+
- When a file already exists unless you explicitly want to overwrite it
|
|
34912
|
+
|
|
34913
|
+
Parameters:
|
|
34914
|
+
- file_path: (required) Path where the file should be created
|
|
34915
|
+
- content: (required) Complete content to write to the file
|
|
34916
|
+
- overwrite: (optional, default: false) Whether to overwrite if file already exists
|
|
34917
|
+
|
|
34918
|
+
Important notes:
|
|
34919
|
+
- Parent directories will be created automatically if they don't exist
|
|
34920
|
+
- The tool will fail if the file already exists and overwrite is false
|
|
34921
|
+
- Be careful with the overwrite option as it completely replaces existing files
|
|
34922
|
+
|
|
34923
|
+
Examples:
|
|
34924
|
+
<create>
|
|
34925
|
+
<file_path>src/newFile.js</file_path>
|
|
34926
|
+
<content>export function hello() {
|
|
34927
|
+
return "Hello, world!";
|
|
34928
|
+
}</content>
|
|
34929
|
+
</create>
|
|
34930
|
+
|
|
34931
|
+
<create>
|
|
34932
|
+
<file_path>README.md</file_path>
|
|
34933
|
+
<content># My Project
|
|
34934
|
+
|
|
34935
|
+
This is a new project.</content>
|
|
34936
|
+
<overwrite>true</overwrite>
|
|
34937
|
+
</create>`;
|
|
34938
|
+
}
|
|
34939
|
+
});
|
|
34940
|
+
|
|
34879
34941
|
// src/tools/common.js
|
|
34942
|
+
function buildToolTagPattern(tools2 = DEFAULT_VALID_TOOLS) {
|
|
34943
|
+
const allTools = [...tools2];
|
|
34944
|
+
if (allTools.includes("attempt_completion") && !allTools.includes("attempt_complete")) {
|
|
34945
|
+
allTools.push("attempt_complete");
|
|
34946
|
+
}
|
|
34947
|
+
const escaped = allTools.map((t4) => t4.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
|
|
34948
|
+
return new RegExp(`<(${escaped.join("|")})>`);
|
|
34949
|
+
}
|
|
34880
34950
|
function getValidParamsForTool(toolName) {
|
|
34881
34951
|
const schemaMap = {
|
|
34882
34952
|
search: searchSchema,
|
|
@@ -34884,7 +34954,9 @@ function getValidParamsForTool(toolName) {
|
|
|
34884
34954
|
extract: extractSchema,
|
|
34885
34955
|
delegate: delegateSchema,
|
|
34886
34956
|
bash: bashSchema,
|
|
34887
|
-
attempt_completion: attemptCompletionSchema
|
|
34957
|
+
attempt_completion: attemptCompletionSchema,
|
|
34958
|
+
edit: editSchema,
|
|
34959
|
+
create: createSchema
|
|
34888
34960
|
};
|
|
34889
34961
|
const schema = schemaMap[toolName];
|
|
34890
34962
|
if (!schema) {
|
|
@@ -34893,9 +34965,12 @@ function getValidParamsForTool(toolName) {
|
|
|
34893
34965
|
if (toolName === "attempt_completion") {
|
|
34894
34966
|
return ["result"];
|
|
34895
34967
|
}
|
|
34896
|
-
if (schema
|
|
34968
|
+
if (schema._def && schema._def.shape) {
|
|
34897
34969
|
return Object.keys(schema._def.shape());
|
|
34898
34970
|
}
|
|
34971
|
+
if (schema.properties) {
|
|
34972
|
+
return Object.keys(schema.properties);
|
|
34973
|
+
}
|
|
34899
34974
|
return [];
|
|
34900
34975
|
}
|
|
34901
34976
|
function parseXmlToolCall(xmlString, validTools = DEFAULT_VALID_TOOLS) {
|
|
@@ -34995,10 +35070,10 @@ function parseAndResolvePaths(pathStr, cwd) {
|
|
|
34995
35070
|
if (!pathStr) return [];
|
|
34996
35071
|
const paths = pathStr.split(",").map((p4) => p4.trim()).filter((p4) => p4.length > 0);
|
|
34997
35072
|
return paths.map((p4) => {
|
|
34998
|
-
if ((0,
|
|
35073
|
+
if ((0, import_path6.isAbsolute)(p4)) {
|
|
34999
35074
|
return p4;
|
|
35000
35075
|
}
|
|
35001
|
-
return cwd ? (0,
|
|
35076
|
+
return cwd ? (0, import_path6.resolve)(cwd, p4) : p4;
|
|
35002
35077
|
});
|
|
35003
35078
|
}
|
|
35004
35079
|
function resolveTargetPath(target, cwd) {
|
|
@@ -35016,17 +35091,18 @@ function resolveTargetPath(target, cwd) {
|
|
|
35016
35091
|
filePart = target;
|
|
35017
35092
|
suffix = "";
|
|
35018
35093
|
}
|
|
35019
|
-
if (!(0,
|
|
35020
|
-
filePart = (0,
|
|
35094
|
+
if (!(0, import_path6.isAbsolute)(filePart) && cwd) {
|
|
35095
|
+
filePart = (0, import_path6.resolve)(cwd, filePart);
|
|
35021
35096
|
}
|
|
35022
35097
|
return filePart + suffix;
|
|
35023
35098
|
}
|
|
35024
|
-
var
|
|
35099
|
+
var import_path6, searchSchema, querySchema, extractSchema, delegateSchema, bashSchema, attemptCompletionSchema, searchToolDefinition, queryToolDefinition, extractToolDefinition, delegateToolDefinition, attemptCompletionToolDefinition, bashToolDefinition, searchDescription, queryDescription, extractDescription, delegateDescription, bashDescription, DEFAULT_VALID_TOOLS;
|
|
35025
35100
|
var init_common2 = __esm({
|
|
35026
35101
|
"src/tools/common.js"() {
|
|
35027
35102
|
"use strict";
|
|
35028
35103
|
init_zod();
|
|
35029
|
-
|
|
35104
|
+
import_path6 = require("path");
|
|
35105
|
+
init_edit();
|
|
35030
35106
|
searchSchema = external_exports.object({
|
|
35031
35107
|
query: external_exports.string().describe("Search query with Elasticsearch syntax. Use quotes for exact matches, AND/OR for boolean logic, - for negation."),
|
|
35032
35108
|
path: external_exports.string().optional().default(".").describe('Path to search in. For dependencies use "go:github.com/owner/repo", "js:package_name", or "rust:cargo_name" etc.')
|
|
@@ -35328,11 +35404,267 @@ User: Check system info
|
|
|
35328
35404
|
"listFiles",
|
|
35329
35405
|
"searchFiles",
|
|
35330
35406
|
"implement",
|
|
35407
|
+
"bash",
|
|
35331
35408
|
"attempt_completion"
|
|
35332
35409
|
];
|
|
35333
35410
|
}
|
|
35334
35411
|
});
|
|
35335
35412
|
|
|
35413
|
+
// src/agent/xmlParsingUtils.js
|
|
35414
|
+
function removeThinkingTags(xmlString) {
|
|
35415
|
+
let result = xmlString;
|
|
35416
|
+
result = result.replace(/<thinking>[\s\S]*?<\/thinking>/g, "");
|
|
35417
|
+
const thinkingIndex = result.indexOf("<thinking>");
|
|
35418
|
+
if (thinkingIndex !== -1) {
|
|
35419
|
+
const afterThinking = result.substring(thinkingIndex + "<thinking>".length);
|
|
35420
|
+
const toolPattern = buildToolTagPattern(DEFAULT_VALID_TOOLS);
|
|
35421
|
+
const toolMatch = afterThinking.match(toolPattern);
|
|
35422
|
+
if (toolMatch) {
|
|
35423
|
+
const toolStart = thinkingIndex + "<thinking>".length + toolMatch.index;
|
|
35424
|
+
result = result.substring(0, thinkingIndex) + result.substring(toolStart);
|
|
35425
|
+
} else {
|
|
35426
|
+
result = result.substring(0, thinkingIndex);
|
|
35427
|
+
}
|
|
35428
|
+
}
|
|
35429
|
+
return result.trim();
|
|
35430
|
+
}
|
|
35431
|
+
function extractThinkingContent(xmlString) {
|
|
35432
|
+
const thinkingMatch = xmlString.match(/<thinking>([\s\S]*?)<\/thinking>/);
|
|
35433
|
+
return thinkingMatch ? thinkingMatch[1].trim() : null;
|
|
35434
|
+
}
|
|
35435
|
+
function checkAttemptCompleteRecovery(cleanedXmlString, validTools = []) {
|
|
35436
|
+
const openTagIndex = cleanedXmlString.indexOf("<attempt_completion>");
|
|
35437
|
+
if (openTagIndex !== -1) {
|
|
35438
|
+
const afterOpenTag = cleanedXmlString.substring(openTagIndex + "<attempt_completion>".length);
|
|
35439
|
+
const closeTagIndex = cleanedXmlString.lastIndexOf("</attempt_completion>");
|
|
35440
|
+
let content;
|
|
35441
|
+
let hasClosingTag = false;
|
|
35442
|
+
if (closeTagIndex !== -1 && closeTagIndex >= openTagIndex + "<attempt_completion>".length) {
|
|
35443
|
+
content = cleanedXmlString.substring(
|
|
35444
|
+
openTagIndex + "<attempt_completion>".length,
|
|
35445
|
+
closeTagIndex
|
|
35446
|
+
).trim();
|
|
35447
|
+
hasClosingTag = true;
|
|
35448
|
+
} else {
|
|
35449
|
+
content = afterOpenTag.trim();
|
|
35450
|
+
hasClosingTag = false;
|
|
35451
|
+
}
|
|
35452
|
+
if (content) {
|
|
35453
|
+
return {
|
|
35454
|
+
toolName: "attempt_completion",
|
|
35455
|
+
params: { result: content }
|
|
35456
|
+
};
|
|
35457
|
+
}
|
|
35458
|
+
return {
|
|
35459
|
+
toolName: "attempt_completion",
|
|
35460
|
+
params: { result: hasClosingTag ? "" : "__PREVIOUS_RESPONSE__" }
|
|
35461
|
+
};
|
|
35462
|
+
}
|
|
35463
|
+
const attemptCompletePatterns = [
|
|
35464
|
+
// Standard shorthand with optional whitespace
|
|
35465
|
+
/^<attempt_complete>\s*$/,
|
|
35466
|
+
// Empty with proper closing tag (common case from the logs)
|
|
35467
|
+
/^<attempt_complete>\s*<\/attempt_complete>\s*$/,
|
|
35468
|
+
// Self-closing variant
|
|
35469
|
+
/^<attempt_complete\s*\/>\s*$/,
|
|
35470
|
+
// Incomplete opening tag (missing closing bracket)
|
|
35471
|
+
/^<attempt_complete\s*$/,
|
|
35472
|
+
// With trailing content (extract just the tag part) - must come after empty tag pattern
|
|
35473
|
+
/^<attempt_complete>(.*)$/s,
|
|
35474
|
+
// Self-closing with trailing content
|
|
35475
|
+
/^<attempt_complete\s*\/>(.*)$/s
|
|
35476
|
+
];
|
|
35477
|
+
for (const pattern of attemptCompletePatterns) {
|
|
35478
|
+
const match2 = cleanedXmlString.match(pattern);
|
|
35479
|
+
if (match2) {
|
|
35480
|
+
return {
|
|
35481
|
+
toolName: "attempt_completion",
|
|
35482
|
+
params: { result: "__PREVIOUS_RESPONSE__" }
|
|
35483
|
+
};
|
|
35484
|
+
}
|
|
35485
|
+
}
|
|
35486
|
+
if (cleanedXmlString.includes("<attempt_complete") && !hasOtherToolTags(cleanedXmlString, validTools)) {
|
|
35487
|
+
return {
|
|
35488
|
+
toolName: "attempt_completion",
|
|
35489
|
+
params: { result: "__PREVIOUS_RESPONSE__" }
|
|
35490
|
+
};
|
|
35491
|
+
}
|
|
35492
|
+
return null;
|
|
35493
|
+
}
|
|
35494
|
+
function hasOtherToolTags(xmlString, validTools = []) {
|
|
35495
|
+
const toolsToCheck = validTools.length > 0 ? validTools : DEFAULT_VALID_TOOLS;
|
|
35496
|
+
for (const tool4 of toolsToCheck) {
|
|
35497
|
+
if (tool4 !== "attempt_completion" && xmlString.includes(`<${tool4}`)) {
|
|
35498
|
+
return true;
|
|
35499
|
+
}
|
|
35500
|
+
}
|
|
35501
|
+
return false;
|
|
35502
|
+
}
|
|
35503
|
+
function processXmlWithThinkingAndRecovery(xmlString, validTools = []) {
|
|
35504
|
+
const thinkingContent = extractThinkingContent(xmlString);
|
|
35505
|
+
const cleanedXmlString = removeThinkingTags(xmlString);
|
|
35506
|
+
const recoveryResult = checkAttemptCompleteRecovery(cleanedXmlString, validTools);
|
|
35507
|
+
if (process.env.DEBUG === "1" && thinkingContent) {
|
|
35508
|
+
console.log(`[DEBUG] AI Thinking Process:
|
|
35509
|
+
${thinkingContent}`);
|
|
35510
|
+
}
|
|
35511
|
+
return {
|
|
35512
|
+
cleanedXmlString,
|
|
35513
|
+
thinkingContent,
|
|
35514
|
+
recoveryResult
|
|
35515
|
+
};
|
|
35516
|
+
}
|
|
35517
|
+
var init_xmlParsingUtils = __esm({
|
|
35518
|
+
"src/agent/xmlParsingUtils.js"() {
|
|
35519
|
+
"use strict";
|
|
35520
|
+
init_common2();
|
|
35521
|
+
}
|
|
35522
|
+
});
|
|
35523
|
+
|
|
35524
|
+
// src/agent/tools.js
|
|
35525
|
+
function createTools(configOptions) {
|
|
35526
|
+
const tools2 = {};
|
|
35527
|
+
const isToolAllowed = configOptions.isToolAllowed || ((toolName) => {
|
|
35528
|
+
if (!configOptions.allowedTools) return true;
|
|
35529
|
+
return configOptions.allowedTools.isEnabled(toolName);
|
|
35530
|
+
});
|
|
35531
|
+
if (isToolAllowed("search")) {
|
|
35532
|
+
tools2.searchTool = searchTool(configOptions);
|
|
35533
|
+
}
|
|
35534
|
+
if (isToolAllowed("query")) {
|
|
35535
|
+
tools2.queryTool = queryTool(configOptions);
|
|
35536
|
+
}
|
|
35537
|
+
if (isToolAllowed("extract")) {
|
|
35538
|
+
tools2.extractTool = extractTool(configOptions);
|
|
35539
|
+
}
|
|
35540
|
+
if (configOptions.enableDelegate && isToolAllowed("delegate")) {
|
|
35541
|
+
tools2.delegateTool = delegateTool(configOptions);
|
|
35542
|
+
}
|
|
35543
|
+
if (configOptions.enableBash && isToolAllowed("bash")) {
|
|
35544
|
+
tools2.bashTool = bashTool(configOptions);
|
|
35545
|
+
}
|
|
35546
|
+
if (configOptions.allowEdit && isToolAllowed("edit")) {
|
|
35547
|
+
tools2.editTool = editTool(configOptions);
|
|
35548
|
+
}
|
|
35549
|
+
if (configOptions.allowEdit && isToolAllowed("create")) {
|
|
35550
|
+
tools2.createTool = createTool(configOptions);
|
|
35551
|
+
}
|
|
35552
|
+
return tools2;
|
|
35553
|
+
}
|
|
35554
|
+
function parseXmlToolCallWithThinking(xmlString, validTools) {
|
|
35555
|
+
const { cleanedXmlString, recoveryResult } = processXmlWithThinkingAndRecovery(xmlString, validTools);
|
|
35556
|
+
if (recoveryResult) {
|
|
35557
|
+
return recoveryResult;
|
|
35558
|
+
}
|
|
35559
|
+
return parseXmlToolCall(cleanedXmlString, validTools);
|
|
35560
|
+
}
|
|
35561
|
+
var import_crypto2, implementToolDefinition, listFilesToolDefinition, searchFilesToolDefinition, readImageToolDefinition;
|
|
35562
|
+
var init_tools = __esm({
|
|
35563
|
+
"src/agent/tools.js"() {
|
|
35564
|
+
"use strict";
|
|
35565
|
+
init_index();
|
|
35566
|
+
import_crypto2 = require("crypto");
|
|
35567
|
+
init_xmlParsingUtils();
|
|
35568
|
+
implementToolDefinition = `
|
|
35569
|
+
## implement
|
|
35570
|
+
Description: Implement a given task. Can modify files. Can be used ONLY if task explicitly stated that something requires modification or implementation.
|
|
35571
|
+
|
|
35572
|
+
Parameters:
|
|
35573
|
+
- task: (required) The task description. Should be as detailed as possible, ideally pointing to exact files which needs be modified or created.
|
|
35574
|
+
- autoCommits: (optional) Whether to enable auto-commits in aider. Default is false.
|
|
35575
|
+
|
|
35576
|
+
Usage Example:
|
|
35577
|
+
|
|
35578
|
+
<examples>
|
|
35579
|
+
|
|
35580
|
+
User: Can you implement a function to calculate Fibonacci numbers in main.js?
|
|
35581
|
+
<implement>
|
|
35582
|
+
<task>Implement a recursive function to calculate the nth Fibonacci number in main.js</task>
|
|
35583
|
+
</implement>
|
|
35584
|
+
|
|
35585
|
+
User: Can you implement a function to calculate Fibonacci numbers in main.js with auto-commits?
|
|
35586
|
+
<implement>
|
|
35587
|
+
<task>Implement a recursive function to calculate the nth Fibonacci number in main.js</task>
|
|
35588
|
+
<autoCommits>true</autoCommits>
|
|
35589
|
+
</implement>
|
|
35590
|
+
|
|
35591
|
+
</examples>
|
|
35592
|
+
`;
|
|
35593
|
+
listFilesToolDefinition = `
|
|
35594
|
+
## listFiles
|
|
35595
|
+
Description: List files and directories in a specified location.
|
|
35596
|
+
|
|
35597
|
+
Parameters:
|
|
35598
|
+
- directory: (optional) The directory path to list files from. Defaults to current directory if not specified.
|
|
35599
|
+
|
|
35600
|
+
Usage Example:
|
|
35601
|
+
|
|
35602
|
+
<examples>
|
|
35603
|
+
|
|
35604
|
+
User: Can you list the files in the src directory?
|
|
35605
|
+
<listFiles>
|
|
35606
|
+
<directory>src</directory>
|
|
35607
|
+
</listFiles>
|
|
35608
|
+
|
|
35609
|
+
User: What files are in the current directory?
|
|
35610
|
+
<listFiles>
|
|
35611
|
+
</listFiles>
|
|
35612
|
+
|
|
35613
|
+
</examples>
|
|
35614
|
+
`;
|
|
35615
|
+
searchFilesToolDefinition = `
|
|
35616
|
+
## searchFiles
|
|
35617
|
+
Description: Find files with name matching a glob pattern with recursive search capability.
|
|
35618
|
+
|
|
35619
|
+
Parameters:
|
|
35620
|
+
- pattern: (required) The glob pattern to search for (e.g., "**/*.js", "*.md").
|
|
35621
|
+
- directory: (optional) The directory to search in. Defaults to current directory if not specified.
|
|
35622
|
+
- recursive: (optional) Whether to search recursively. Defaults to true.
|
|
35623
|
+
|
|
35624
|
+
Usage Example:
|
|
35625
|
+
|
|
35626
|
+
<examples>
|
|
35627
|
+
|
|
35628
|
+
User: Can you find all JavaScript files in the project?
|
|
35629
|
+
<searchFiles>
|
|
35630
|
+
<pattern>**/*.js</pattern>
|
|
35631
|
+
</searchFiles>
|
|
35632
|
+
|
|
35633
|
+
User: Find all markdown files in the docs directory, but only at the top level.
|
|
35634
|
+
<searchFiles>
|
|
35635
|
+
<pattern>*.md</pattern>
|
|
35636
|
+
<directory>docs</directory>
|
|
35637
|
+
<recursive>false</recursive>
|
|
35638
|
+
</searchFiles>
|
|
35639
|
+
|
|
35640
|
+
</examples>
|
|
35641
|
+
`;
|
|
35642
|
+
readImageToolDefinition = `
|
|
35643
|
+
## readImage
|
|
35644
|
+
Description: Read and load an image file so it can be viewed by the AI. Use this when you need to analyze, describe, or work with image content. Images from user messages are automatically loaded, but use this tool to explicitly read images mentioned in tool outputs or when you need to examine specific image files.
|
|
35645
|
+
|
|
35646
|
+
Parameters:
|
|
35647
|
+
- path: (required) The path to the image file to read. Supports png, jpg, jpeg, webp, bmp, and svg formats.
|
|
35648
|
+
|
|
35649
|
+
Usage Example:
|
|
35650
|
+
|
|
35651
|
+
<examples>
|
|
35652
|
+
|
|
35653
|
+
User: Can you describe what's in screenshot.png?
|
|
35654
|
+
<readImage>
|
|
35655
|
+
<path>screenshot.png</path>
|
|
35656
|
+
</readImage>
|
|
35657
|
+
|
|
35658
|
+
User: Analyze the diagram in docs/architecture.svg
|
|
35659
|
+
<readImage>
|
|
35660
|
+
<path>docs/architecture.svg</path>
|
|
35661
|
+
</readImage>
|
|
35662
|
+
|
|
35663
|
+
</examples>
|
|
35664
|
+
`;
|
|
35665
|
+
}
|
|
35666
|
+
});
|
|
35667
|
+
|
|
35336
35668
|
// node_modules/balanced-match/index.js
|
|
35337
35669
|
var require_balanced_match = __commonJS({
|
|
35338
35670
|
"node_modules/balanced-match/index.js"(exports2, module2) {
|
|
@@ -36178,7 +36510,7 @@ var init_escape = __esm({
|
|
|
36178
36510
|
});
|
|
36179
36511
|
|
|
36180
36512
|
// node_modules/minimatch/dist/esm/index.js
|
|
36181
|
-
var import_brace_expansion, minimatch, starDotExtRE, starDotExtTest, starDotExtTestDot, starDotExtTestNocase, starDotExtTestNocaseDot, starDotStarRE, starDotStarTest, starDotStarTestDot, dotStarRE, dotStarTest, starRE, starTest, starTestDot, qmarksRE, qmarksTestNocase, qmarksTestNocaseDot, qmarksTestDot, qmarksTest, qmarksTestNoExt, qmarksTestNoExtDot, defaultPlatform, path5,
|
|
36513
|
+
var import_brace_expansion, minimatch, starDotExtRE, starDotExtTest, starDotExtTestDot, starDotExtTestNocase, starDotExtTestNocaseDot, starDotStarRE, starDotStarTest, starDotStarTestDot, dotStarRE, dotStarTest, starRE, starTest, starTestDot, qmarksRE, qmarksTestNocase, qmarksTestNocaseDot, qmarksTestDot, qmarksTest, qmarksTestNoExt, qmarksTestNoExtDot, defaultPlatform, path5, sep2, GLOBSTAR, qmark2, star2, twoStarDot, twoStarNoDot, filter, ext, defaults, braceExpand, makeRe, match, globMagic, regExpEscape2, Minimatch;
|
|
36182
36514
|
var init_esm = __esm({
|
|
36183
36515
|
"node_modules/minimatch/dist/esm/index.js"() {
|
|
36184
36516
|
import_brace_expansion = __toESM(require_brace_expansion(), 1);
|
|
@@ -36251,8 +36583,8 @@ var init_esm = __esm({
|
|
|
36251
36583
|
win32: { sep: "\\" },
|
|
36252
36584
|
posix: { sep: "/" }
|
|
36253
36585
|
};
|
|
36254
|
-
|
|
36255
|
-
minimatch.sep =
|
|
36586
|
+
sep2 = defaultPlatform === "win32" ? path5.win32.sep : path5.posix.sep;
|
|
36587
|
+
minimatch.sep = sep2;
|
|
36256
36588
|
GLOBSTAR = Symbol("globstar **");
|
|
36257
36589
|
minimatch.GLOBSTAR = GLOBSTAR;
|
|
36258
36590
|
qmark2 = "[^/]";
|
|
@@ -39166,22 +39498,22 @@ var init_esm3 = __esm({
|
|
|
39166
39498
|
});
|
|
39167
39499
|
|
|
39168
39500
|
// node_modules/path-scurry/dist/esm/index.js
|
|
39169
|
-
var import_node_path, import_node_url,
|
|
39501
|
+
var import_node_path, import_node_url, import_fs6, actualFS, import_promises, realpathSync, defaultFS, fsFromOption, uncDriveRegexp, uncToDrive, eitherSep, UNKNOWN, IFIFO, IFCHR, IFDIR, IFBLK, IFREG, IFLNK, IFSOCK, IFMT, IFMT_UNKNOWN, READDIR_CALLED, LSTAT_CALLED, ENOTDIR, ENOENT, ENOREADLINK, ENOREALPATH, ENOCHILD, TYPEMASK, entToType, normalizeCache, normalize, normalizeNocaseCache, normalizeNocase, ResolveCache, ChildrenCache, setAsCwd, PathBase, PathWin32, PathPosix, PathScurryBase, PathScurryWin32, PathScurryPosix, PathScurryDarwin, Path, PathScurry;
|
|
39170
39502
|
var init_esm4 = __esm({
|
|
39171
39503
|
"node_modules/path-scurry/dist/esm/index.js"() {
|
|
39172
39504
|
init_esm2();
|
|
39173
39505
|
import_node_path = require("node:path");
|
|
39174
39506
|
import_node_url = require("node:url");
|
|
39175
|
-
|
|
39507
|
+
import_fs6 = require("fs");
|
|
39176
39508
|
actualFS = __toESM(require("node:fs"), 1);
|
|
39177
39509
|
import_promises = require("node:fs/promises");
|
|
39178
39510
|
init_esm3();
|
|
39179
|
-
realpathSync =
|
|
39511
|
+
realpathSync = import_fs6.realpathSync.native;
|
|
39180
39512
|
defaultFS = {
|
|
39181
|
-
lstatSync:
|
|
39182
|
-
readdir:
|
|
39183
|
-
readdirSync:
|
|
39184
|
-
readlinkSync:
|
|
39513
|
+
lstatSync: import_fs6.lstatSync,
|
|
39514
|
+
readdir: import_fs6.readdir,
|
|
39515
|
+
readdirSync: import_fs6.readdirSync,
|
|
39516
|
+
readlinkSync: import_fs6.readlinkSync,
|
|
39185
39517
|
realpathSync,
|
|
39186
39518
|
promises: {
|
|
39187
39519
|
lstat: import_promises.lstat,
|
|
@@ -42090,7 +42422,7 @@ function createWrappedTools(baseTools) {
|
|
|
42090
42422
|
}
|
|
42091
42423
|
return wrappedTools;
|
|
42092
42424
|
}
|
|
42093
|
-
var import_child_process6, import_util11, import_crypto3, import_events,
|
|
42425
|
+
var import_child_process6, import_util11, import_crypto3, import_events, import_fs7, import_fs8, import_path7, toolCallEmitter, activeToolExecutions, wrapToolWithEmitter, listFilesTool, searchFilesTool, listFilesToolInstance, searchFilesToolInstance;
|
|
42094
42426
|
var init_probeTool = __esm({
|
|
42095
42427
|
"src/agent/probeTool.js"() {
|
|
42096
42428
|
"use strict";
|
|
@@ -42099,9 +42431,9 @@ var init_probeTool = __esm({
|
|
|
42099
42431
|
import_util11 = require("util");
|
|
42100
42432
|
import_crypto3 = require("crypto");
|
|
42101
42433
|
import_events = require("events");
|
|
42102
|
-
|
|
42103
|
-
|
|
42104
|
-
|
|
42434
|
+
import_fs7 = __toESM(require("fs"), 1);
|
|
42435
|
+
import_fs8 = require("fs");
|
|
42436
|
+
import_path7 = __toESM(require("path"), 1);
|
|
42105
42437
|
init_esm5();
|
|
42106
42438
|
init_symlink_utils();
|
|
42107
42439
|
toolCallEmitter = new import_events.EventEmitter();
|
|
@@ -42190,17 +42522,17 @@ var init_probeTool = __esm({
|
|
|
42190
42522
|
execute: async (params) => {
|
|
42191
42523
|
const { directory = ".", workingDirectory } = params;
|
|
42192
42524
|
const baseCwd = workingDirectory || process.cwd();
|
|
42193
|
-
const secureBaseDir =
|
|
42525
|
+
const secureBaseDir = import_path7.default.resolve(baseCwd);
|
|
42194
42526
|
const isDependencyPath = directory.startsWith("/dep/") || directory.startsWith("go:") || directory.startsWith("js:") || directory.startsWith("rust:");
|
|
42195
42527
|
let targetDir;
|
|
42196
|
-
if (
|
|
42197
|
-
targetDir =
|
|
42198
|
-
if (!isDependencyPath && !targetDir.startsWith(secureBaseDir +
|
|
42528
|
+
if (import_path7.default.isAbsolute(directory)) {
|
|
42529
|
+
targetDir = import_path7.default.resolve(directory);
|
|
42530
|
+
if (!isDependencyPath && !targetDir.startsWith(secureBaseDir + import_path7.default.sep) && targetDir !== secureBaseDir) {
|
|
42199
42531
|
throw new Error(`Path traversal attempt detected. Cannot access directory outside workspace: ${directory}`);
|
|
42200
42532
|
}
|
|
42201
42533
|
} else {
|
|
42202
|
-
targetDir =
|
|
42203
|
-
if (!isDependencyPath && !targetDir.startsWith(secureBaseDir +
|
|
42534
|
+
targetDir = import_path7.default.resolve(secureBaseDir, directory);
|
|
42535
|
+
if (!isDependencyPath && !targetDir.startsWith(secureBaseDir + import_path7.default.sep) && targetDir !== secureBaseDir) {
|
|
42204
42536
|
throw new Error(`Path traversal attempt detected. Access denied: ${directory}`);
|
|
42205
42537
|
}
|
|
42206
42538
|
}
|
|
@@ -42209,7 +42541,7 @@ var init_probeTool = __esm({
|
|
|
42209
42541
|
console.log(`[DEBUG] Listing files in directory: ${targetDir}`);
|
|
42210
42542
|
}
|
|
42211
42543
|
try {
|
|
42212
|
-
const files = await
|
|
42544
|
+
const files = await import_fs8.promises.readdir(targetDir, { withFileTypes: true });
|
|
42213
42545
|
const formatSize = (size) => {
|
|
42214
42546
|
if (size < 1024) return `${size}B`;
|
|
42215
42547
|
if (size < 1024 * 1024) return `${(size / 1024).toFixed(1)}K`;
|
|
@@ -42217,7 +42549,7 @@ var init_probeTool = __esm({
|
|
|
42217
42549
|
return `${(size / (1024 * 1024 * 1024)).toFixed(1)}G`;
|
|
42218
42550
|
};
|
|
42219
42551
|
const entries = await Promise.all(files.map(async (file) => {
|
|
42220
|
-
const fullPath =
|
|
42552
|
+
const fullPath = import_path7.default.join(targetDir, file.name);
|
|
42221
42553
|
const entryType = await getEntryType(file, fullPath);
|
|
42222
42554
|
return {
|
|
42223
42555
|
name: file.name,
|
|
@@ -42254,17 +42586,17 @@ var init_probeTool = __esm({
|
|
|
42254
42586
|
throw new Error("Pattern is required for file search");
|
|
42255
42587
|
}
|
|
42256
42588
|
const baseCwd = workingDirectory || process.cwd();
|
|
42257
|
-
const secureBaseDir =
|
|
42589
|
+
const secureBaseDir = import_path7.default.resolve(baseCwd);
|
|
42258
42590
|
const isDependencyPath = directory.startsWith("/dep/") || directory.startsWith("go:") || directory.startsWith("js:") || directory.startsWith("rust:");
|
|
42259
42591
|
let targetDir;
|
|
42260
|
-
if (
|
|
42261
|
-
targetDir =
|
|
42262
|
-
if (!isDependencyPath && !targetDir.startsWith(secureBaseDir +
|
|
42592
|
+
if (import_path7.default.isAbsolute(directory)) {
|
|
42593
|
+
targetDir = import_path7.default.resolve(directory);
|
|
42594
|
+
if (!isDependencyPath && !targetDir.startsWith(secureBaseDir + import_path7.default.sep) && targetDir !== secureBaseDir) {
|
|
42263
42595
|
throw new Error(`Path traversal attempt detected. Cannot access directory outside workspace: ${directory}`);
|
|
42264
42596
|
}
|
|
42265
42597
|
} else {
|
|
42266
|
-
targetDir =
|
|
42267
|
-
if (!isDependencyPath && !targetDir.startsWith(secureBaseDir +
|
|
42598
|
+
targetDir = import_path7.default.resolve(secureBaseDir, directory);
|
|
42599
|
+
if (!isDependencyPath && !targetDir.startsWith(secureBaseDir + import_path7.default.sep) && targetDir !== secureBaseDir) {
|
|
42268
42600
|
throw new Error(`Path traversal attempt detected. Access denied: ${directory}`);
|
|
42269
42601
|
}
|
|
42270
42602
|
}
|
|
@@ -80589,11 +80921,11 @@ function loadMCPConfigurationFromPath(configPath) {
|
|
|
80589
80921
|
if (!configPath) {
|
|
80590
80922
|
throw new Error("Config path is required");
|
|
80591
80923
|
}
|
|
80592
|
-
if (!(0,
|
|
80924
|
+
if (!(0, import_fs9.existsSync)(configPath)) {
|
|
80593
80925
|
throw new Error(`MCP configuration file not found: ${configPath}`);
|
|
80594
80926
|
}
|
|
80595
80927
|
try {
|
|
80596
|
-
const content = (0,
|
|
80928
|
+
const content = (0, import_fs9.readFileSync)(configPath, "utf8");
|
|
80597
80929
|
const config = JSON.parse(content);
|
|
80598
80930
|
if (process.env.DEBUG === "1" || process.env.DEBUG_MCP === "1") {
|
|
80599
80931
|
console.error(`[MCP DEBUG] Loaded configuration from: ${configPath}`);
|
|
@@ -80608,19 +80940,19 @@ function loadMCPConfiguration() {
|
|
|
80608
80940
|
// Environment variable path
|
|
80609
80941
|
process.env.MCP_CONFIG_PATH,
|
|
80610
80942
|
// Local project paths
|
|
80611
|
-
(0,
|
|
80612
|
-
(0,
|
|
80943
|
+
(0, import_path8.join)(process.cwd(), ".mcp", "config.json"),
|
|
80944
|
+
(0, import_path8.join)(process.cwd(), "mcp.config.json"),
|
|
80613
80945
|
// Home directory paths
|
|
80614
|
-
(0,
|
|
80615
|
-
(0,
|
|
80946
|
+
(0, import_path8.join)((0, import_os3.homedir)(), ".config", "probe", "mcp.json"),
|
|
80947
|
+
(0, import_path8.join)((0, import_os3.homedir)(), ".mcp", "config.json"),
|
|
80616
80948
|
// Claude-style config location
|
|
80617
|
-
(0,
|
|
80949
|
+
(0, import_path8.join)((0, import_os3.homedir)(), "Library", "Application Support", "Claude", "mcp_config.json")
|
|
80618
80950
|
].filter(Boolean);
|
|
80619
80951
|
let config = null;
|
|
80620
80952
|
for (const configPath of configPaths) {
|
|
80621
|
-
if ((0,
|
|
80953
|
+
if ((0, import_fs9.existsSync)(configPath)) {
|
|
80622
80954
|
try {
|
|
80623
|
-
const content = (0,
|
|
80955
|
+
const content = (0, import_fs9.readFileSync)(configPath, "utf8");
|
|
80624
80956
|
config = JSON.parse(content);
|
|
80625
80957
|
if (process.env.DEBUG === "1" || process.env.DEBUG_MCP === "1") {
|
|
80626
80958
|
console.error(`[MCP DEBUG] Loaded configuration from: ${configPath}`);
|
|
@@ -80732,16 +81064,16 @@ function parseEnabledServers(config) {
|
|
|
80732
81064
|
}
|
|
80733
81065
|
return servers;
|
|
80734
81066
|
}
|
|
80735
|
-
var
|
|
81067
|
+
var import_fs9, import_path8, import_os3, import_url4, __filename4, __dirname4, DEFAULT_TIMEOUT, MAX_TIMEOUT, DEFAULT_CONFIG;
|
|
80736
81068
|
var init_config = __esm({
|
|
80737
81069
|
"src/agent/mcp/config.js"() {
|
|
80738
81070
|
"use strict";
|
|
80739
|
-
|
|
80740
|
-
|
|
81071
|
+
import_fs9 = require("fs");
|
|
81072
|
+
import_path8 = require("path");
|
|
80741
81073
|
import_os3 = require("os");
|
|
80742
81074
|
import_url4 = require("url");
|
|
80743
81075
|
__filename4 = (0, import_url4.fileURLToPath)("file:///");
|
|
80744
|
-
__dirname4 = (0,
|
|
81076
|
+
__dirname4 = (0, import_path8.dirname)(__filename4);
|
|
80745
81077
|
DEFAULT_TIMEOUT = 3e4;
|
|
80746
81078
|
MAX_TIMEOUT = 6e5;
|
|
80747
81079
|
DEFAULT_CONFIG = {
|
|
@@ -80749,7 +81081,7 @@ var init_config = __esm({
|
|
|
80749
81081
|
// Example probe server configuration
|
|
80750
81082
|
"probe-local": {
|
|
80751
81083
|
command: "node",
|
|
80752
|
-
args: [(0,
|
|
81084
|
+
args: [(0, import_path8.join)(__dirname4, "../../../examples/chat/mcpServer.js")],
|
|
80753
81085
|
transport: "stdio",
|
|
80754
81086
|
enabled: false
|
|
80755
81087
|
},
|
|
@@ -82871,12 +83203,12 @@ async function createEnhancedClaudeCLIEngine(options = {}) {
|
|
|
82871
83203
|
console.log("[DEBUG] Built-in MCP server started");
|
|
82872
83204
|
console.log("[DEBUG] MCP URL:", `http://${host}:${port}/mcp`);
|
|
82873
83205
|
}
|
|
82874
|
-
mcpConfigPath =
|
|
83206
|
+
mcpConfigPath = import_path9.default.join(import_os4.default.tmpdir(), `probe-mcp-${session.id}.json`);
|
|
82875
83207
|
const mcpConfig = {
|
|
82876
83208
|
mcpServers: {
|
|
82877
83209
|
probe: {
|
|
82878
83210
|
command: "node",
|
|
82879
|
-
args: [
|
|
83211
|
+
args: [import_path9.default.join(process.cwd(), "mcp-probe-server.js")],
|
|
82880
83212
|
env: {
|
|
82881
83213
|
PROBE_WORKSPACE: process.cwd(),
|
|
82882
83214
|
DEBUG: debug ? "true" : "false"
|
|
@@ -83245,14 +83577,14 @@ function combinePrompts(systemPrompt, customPrompt, agent) {
|
|
|
83245
83577
|
}
|
|
83246
83578
|
return systemPrompt || "";
|
|
83247
83579
|
}
|
|
83248
|
-
var import_child_process7, import_crypto5, import_promises2,
|
|
83580
|
+
var import_child_process7, import_crypto5, import_promises2, import_path9, import_os4, import_events3;
|
|
83249
83581
|
var init_enhanced_claude_code = __esm({
|
|
83250
83582
|
"src/agent/engines/enhanced-claude-code.js"() {
|
|
83251
83583
|
"use strict";
|
|
83252
83584
|
import_child_process7 = require("child_process");
|
|
83253
83585
|
import_crypto5 = require("crypto");
|
|
83254
83586
|
import_promises2 = __toESM(require("fs/promises"), 1);
|
|
83255
|
-
|
|
83587
|
+
import_path9 = __toESM(require("path"), 1);
|
|
83256
83588
|
import_os4 = __toESM(require("os"), 1);
|
|
83257
83589
|
import_events3 = require("events");
|
|
83258
83590
|
init_built_in_server();
|
|
@@ -83596,11 +83928,11 @@ function createEnhancedVercelEngine(agent) {
|
|
|
83596
83928
|
}
|
|
83597
83929
|
};
|
|
83598
83930
|
}
|
|
83599
|
-
var
|
|
83931
|
+
var import_ai2;
|
|
83600
83932
|
var init_enhanced_vercel = __esm({
|
|
83601
83933
|
"src/agent/engines/enhanced-vercel.js"() {
|
|
83602
83934
|
"use strict";
|
|
83603
|
-
|
|
83935
|
+
import_ai2 = require("ai");
|
|
83604
83936
|
}
|
|
83605
83937
|
});
|
|
83606
83938
|
|
|
@@ -83609,7 +83941,7 @@ var ProbeAgent_exports = {};
|
|
|
83609
83941
|
__export(ProbeAgent_exports, {
|
|
83610
83942
|
ProbeAgent: () => ProbeAgent
|
|
83611
83943
|
});
|
|
83612
|
-
var import_dotenv, import_anthropic2, import_openai2, import_google2,
|
|
83944
|
+
var import_dotenv, import_anthropic2, import_openai2, import_google2, import_ai3, import_crypto7, import_events4, import_fs10, import_promises3, import_path10, MAX_TOOL_ITERATIONS, MAX_HISTORY_MESSAGES, MAX_IMAGE_FILE_SIZE, ProbeAgent;
|
|
83613
83945
|
var init_ProbeAgent = __esm({
|
|
83614
83946
|
"src/agent/ProbeAgent.js"() {
|
|
83615
83947
|
"use strict";
|
|
@@ -83618,12 +83950,12 @@ var init_ProbeAgent = __esm({
|
|
|
83618
83950
|
import_openai2 = require("@ai-sdk/openai");
|
|
83619
83951
|
import_google2 = require("@ai-sdk/google");
|
|
83620
83952
|
init_dist3();
|
|
83621
|
-
|
|
83953
|
+
import_ai3 = require("ai");
|
|
83622
83954
|
import_crypto7 = require("crypto");
|
|
83623
83955
|
import_events4 = require("events");
|
|
83624
|
-
|
|
83956
|
+
import_fs10 = require("fs");
|
|
83625
83957
|
import_promises3 = require("fs/promises");
|
|
83626
|
-
|
|
83958
|
+
import_path10 = require("path");
|
|
83627
83959
|
init_tokenCounter();
|
|
83628
83960
|
init_InMemoryStorageAdapter();
|
|
83629
83961
|
init_HookManager();
|
|
@@ -83950,7 +84282,7 @@ var init_ProbeAgent = __esm({
|
|
|
83950
84282
|
if (!imagePath) {
|
|
83951
84283
|
throw new Error("Image path is required");
|
|
83952
84284
|
}
|
|
83953
|
-
const filename = (0,
|
|
84285
|
+
const filename = (0, import_path10.basename)(imagePath);
|
|
83954
84286
|
const extension = filename.toLowerCase().split(".").pop();
|
|
83955
84287
|
if (!extension || !SUPPORTED_IMAGE_EXTENSIONS.includes(extension)) {
|
|
83956
84288
|
throw new Error(`Invalid or unsupported image extension: ${extension}. Supported formats: ${SUPPORTED_IMAGE_EXTENSIONS.join(", ")}`);
|
|
@@ -84268,7 +84600,7 @@ var init_ProbeAgent = __esm({
|
|
|
84268
84600
|
}
|
|
84269
84601
|
if (!this.fallbackManager) {
|
|
84270
84602
|
return await this.retryManager.executeWithRetry(
|
|
84271
|
-
() => (0,
|
|
84603
|
+
() => (0, import_ai3.streamText)(options),
|
|
84272
84604
|
{
|
|
84273
84605
|
provider: this.apiType,
|
|
84274
84606
|
model: this.model
|
|
@@ -84290,7 +84622,7 @@ var init_ProbeAgent = __esm({
|
|
|
84290
84622
|
debug: this.debug
|
|
84291
84623
|
});
|
|
84292
84624
|
return await providerRetryManager.executeWithRetry(
|
|
84293
|
-
() => (0,
|
|
84625
|
+
() => (0, import_ai3.streamText)(fallbackOptions),
|
|
84294
84626
|
{
|
|
84295
84627
|
provider: config.provider,
|
|
84296
84628
|
model
|
|
@@ -84505,7 +84837,7 @@ var init_ProbeAgent = __esm({
|
|
|
84505
84837
|
let resolvedPath2 = imagePath;
|
|
84506
84838
|
if (!imagePath.includes("/") && !imagePath.includes("\\")) {
|
|
84507
84839
|
for (const dir of listFilesDirectories) {
|
|
84508
|
-
const potentialPath = (0,
|
|
84840
|
+
const potentialPath = (0, import_path10.resolve)(dir, imagePath);
|
|
84509
84841
|
const loaded = await this.loadImageIfValid(potentialPath);
|
|
84510
84842
|
if (loaded) {
|
|
84511
84843
|
if (this.debug) {
|
|
@@ -84530,7 +84862,7 @@ var init_ProbeAgent = __esm({
|
|
|
84530
84862
|
let match2;
|
|
84531
84863
|
while ((match2 = fileHeaderPattern.exec(content)) !== null) {
|
|
84532
84864
|
const filePath = match2[1].trim();
|
|
84533
|
-
const dir = (0,
|
|
84865
|
+
const dir = (0, import_path10.dirname)(filePath);
|
|
84534
84866
|
if (dir && dir !== ".") {
|
|
84535
84867
|
directories.push(dir);
|
|
84536
84868
|
if (this.debug) {
|
|
@@ -84575,17 +84907,17 @@ var init_ProbeAgent = __esm({
|
|
|
84575
84907
|
const allowedDirs = this.allowedFolders && this.allowedFolders.length > 0 ? this.allowedFolders : [process.cwd()];
|
|
84576
84908
|
let absolutePath;
|
|
84577
84909
|
let isPathAllowed2 = false;
|
|
84578
|
-
if ((0,
|
|
84579
|
-
absolutePath = (0,
|
|
84910
|
+
if ((0, import_path10.isAbsolute)(imagePath)) {
|
|
84911
|
+
absolutePath = (0, import_path10.normalize)((0, import_path10.resolve)(imagePath));
|
|
84580
84912
|
isPathAllowed2 = allowedDirs.some((dir) => {
|
|
84581
|
-
const normalizedDir = (0,
|
|
84582
|
-
return absolutePath === normalizedDir || absolutePath.startsWith(normalizedDir +
|
|
84913
|
+
const normalizedDir = (0, import_path10.normalize)((0, import_path10.resolve)(dir));
|
|
84914
|
+
return absolutePath === normalizedDir || absolutePath.startsWith(normalizedDir + import_path10.sep);
|
|
84583
84915
|
});
|
|
84584
84916
|
} else {
|
|
84585
84917
|
for (const dir of allowedDirs) {
|
|
84586
|
-
const normalizedDir = (0,
|
|
84587
|
-
const resolvedPath2 = (0,
|
|
84588
|
-
if (resolvedPath2 === normalizedDir || resolvedPath2.startsWith(normalizedDir +
|
|
84918
|
+
const normalizedDir = (0, import_path10.normalize)((0, import_path10.resolve)(dir));
|
|
84919
|
+
const resolvedPath2 = (0, import_path10.normalize)((0, import_path10.resolve)(dir, imagePath));
|
|
84920
|
+
if (resolvedPath2 === normalizedDir || resolvedPath2.startsWith(normalizedDir + import_path10.sep)) {
|
|
84589
84921
|
absolutePath = resolvedPath2;
|
|
84590
84922
|
isPathAllowed2 = true;
|
|
84591
84923
|
break;
|
|
@@ -85517,10 +85849,10 @@ ${toolResultContent}
|
|
|
85517
85849
|
try {
|
|
85518
85850
|
let resolvedWorkingDirectory = this.cwd || this.allowedFolders && this.allowedFolders[0] || process.cwd();
|
|
85519
85851
|
if (params.workingDirectory) {
|
|
85520
|
-
const requestedDir = (0,
|
|
85852
|
+
const requestedDir = (0, import_path10.isAbsolute)(params.workingDirectory) ? (0, import_path10.resolve)(params.workingDirectory) : (0, import_path10.resolve)(resolvedWorkingDirectory, params.workingDirectory);
|
|
85521
85853
|
const isWithinAllowed = !this.allowedFolders || this.allowedFolders.length === 0 || this.allowedFolders.some((folder) => {
|
|
85522
|
-
const resolvedFolder = (0,
|
|
85523
|
-
return requestedDir === resolvedFolder || requestedDir.startsWith(resolvedFolder +
|
|
85854
|
+
const resolvedFolder = (0, import_path10.resolve)(folder);
|
|
85855
|
+
return requestedDir === resolvedFolder || requestedDir.startsWith(resolvedFolder + import_path10.sep);
|
|
85524
85856
|
});
|
|
85525
85857
|
if (isWithinAllowed) {
|
|
85526
85858
|
resolvedWorkingDirectory = requestedDir;
|
|
@@ -86470,7 +86802,9 @@ async function delegate({
|
|
|
86470
86802
|
debug,
|
|
86471
86803
|
tracer,
|
|
86472
86804
|
path: path9,
|
|
86473
|
-
//
|
|
86805
|
+
// Workspace root (from delegateTool)
|
|
86806
|
+
cwd: path9,
|
|
86807
|
+
// Explicitly set cwd to workspace root to prevent path doubling
|
|
86474
86808
|
provider,
|
|
86475
86809
|
// Inherit from parent
|
|
86476
86810
|
model,
|
|
@@ -86681,11 +87015,11 @@ var init_delegate = __esm({
|
|
|
86681
87015
|
});
|
|
86682
87016
|
|
|
86683
87017
|
// src/tools/vercel.js
|
|
86684
|
-
var
|
|
87018
|
+
var import_ai4, searchTool, queryTool, extractTool, delegateTool;
|
|
86685
87019
|
var init_vercel = __esm({
|
|
86686
87020
|
"src/tools/vercel.js"() {
|
|
86687
87021
|
"use strict";
|
|
86688
|
-
|
|
87022
|
+
import_ai4 = require("ai");
|
|
86689
87023
|
init_search();
|
|
86690
87024
|
init_query();
|
|
86691
87025
|
init_extract();
|
|
@@ -86693,7 +87027,7 @@ var init_vercel = __esm({
|
|
|
86693
87027
|
init_common2();
|
|
86694
87028
|
searchTool = (options = {}) => {
|
|
86695
87029
|
const { sessionId, maxTokens = 1e4, debug = false, outline = false } = options;
|
|
86696
|
-
return (0,
|
|
87030
|
+
return (0, import_ai4.tool)({
|
|
86697
87031
|
name: "search",
|
|
86698
87032
|
description: searchDescription,
|
|
86699
87033
|
inputSchema: searchSchema,
|
|
@@ -86739,7 +87073,7 @@ var init_vercel = __esm({
|
|
|
86739
87073
|
};
|
|
86740
87074
|
queryTool = (options = {}) => {
|
|
86741
87075
|
const { debug = false } = options;
|
|
86742
|
-
return (0,
|
|
87076
|
+
return (0, import_ai4.tool)({
|
|
86743
87077
|
name: "query",
|
|
86744
87078
|
description: queryDescription,
|
|
86745
87079
|
inputSchema: querySchema,
|
|
@@ -86775,7 +87109,7 @@ var init_vercel = __esm({
|
|
|
86775
87109
|
};
|
|
86776
87110
|
extractTool = (options = {}) => {
|
|
86777
87111
|
const { debug = false, outline = false } = options;
|
|
86778
|
-
return (0,
|
|
87112
|
+
return (0, import_ai4.tool)({
|
|
86779
87113
|
name: "extract",
|
|
86780
87114
|
description: extractDescription,
|
|
86781
87115
|
inputSchema: extractSchema,
|
|
@@ -86851,7 +87185,7 @@ var init_vercel = __esm({
|
|
|
86851
87185
|
};
|
|
86852
87186
|
delegateTool = (options = {}) => {
|
|
86853
87187
|
const { debug = false, timeout = 300, cwd, allowedFolders, enableBash = false, bashConfig } = options;
|
|
86854
|
-
return (0,
|
|
87188
|
+
return (0, import_ai4.tool)({
|
|
86855
87189
|
name: "delegate",
|
|
86856
87190
|
description: delegateDescription,
|
|
86857
87191
|
inputSchema: delegateSchema,
|
|
@@ -86880,14 +87214,15 @@ var init_vercel = __esm({
|
|
|
86880
87214
|
if (model !== void 0 && model !== null && typeof model !== "string") {
|
|
86881
87215
|
throw new TypeError("model must be a string, null, or undefined");
|
|
86882
87216
|
}
|
|
86883
|
-
const
|
|
87217
|
+
const workspaceRoot = allowedFolders && allowedFolders[0];
|
|
87218
|
+
const effectivePath = path9 || workspaceRoot || cwd;
|
|
86884
87219
|
if (debug) {
|
|
86885
87220
|
console.error(`Executing delegate with task: "${task.substring(0, 100)}${task.length > 100 ? "..." : ""}"`);
|
|
86886
87221
|
if (parentSessionId) {
|
|
86887
87222
|
console.error(`Parent session: ${parentSessionId}`);
|
|
86888
87223
|
}
|
|
86889
87224
|
if (effectivePath && effectivePath !== path9) {
|
|
86890
|
-
console.error(`Using
|
|
87225
|
+
console.error(`Using workspace root: ${effectivePath} (cwd was: ${cwd || "not set"})`);
|
|
86891
87226
|
}
|
|
86892
87227
|
}
|
|
86893
87228
|
const result = await delegate({
|
|
@@ -87834,8 +88169,8 @@ async function executeBashCommand(command, options = {}) {
|
|
|
87834
88169
|
} = options;
|
|
87835
88170
|
let cwd = workingDirectory;
|
|
87836
88171
|
try {
|
|
87837
|
-
cwd = (0,
|
|
87838
|
-
if (!(0,
|
|
88172
|
+
cwd = (0, import_path11.resolve)(cwd);
|
|
88173
|
+
if (!(0, import_fs11.existsSync)(cwd)) {
|
|
87839
88174
|
throw new Error(`Working directory does not exist: ${cwd}`);
|
|
87840
88175
|
}
|
|
87841
88176
|
} catch (error2) {
|
|
@@ -88059,7 +88394,7 @@ function validateExecutionOptions(options = {}) {
|
|
|
88059
88394
|
if (options.workingDirectory) {
|
|
88060
88395
|
if (typeof options.workingDirectory !== "string") {
|
|
88061
88396
|
errors.push("workingDirectory must be a string");
|
|
88062
|
-
} else if (!(0,
|
|
88397
|
+
} else if (!(0, import_fs11.existsSync)(options.workingDirectory)) {
|
|
88063
88398
|
errors.push(`workingDirectory does not exist: ${options.workingDirectory}`);
|
|
88064
88399
|
}
|
|
88065
88400
|
}
|
|
@@ -88072,24 +88407,24 @@ function validateExecutionOptions(options = {}) {
|
|
|
88072
88407
|
warnings
|
|
88073
88408
|
};
|
|
88074
88409
|
}
|
|
88075
|
-
var import_child_process9,
|
|
88410
|
+
var import_child_process9, import_path11, import_fs11;
|
|
88076
88411
|
var init_bashExecutor = __esm({
|
|
88077
88412
|
"src/agent/bashExecutor.js"() {
|
|
88078
88413
|
"use strict";
|
|
88079
88414
|
import_child_process9 = require("child_process");
|
|
88080
|
-
|
|
88081
|
-
|
|
88415
|
+
import_path11 = require("path");
|
|
88416
|
+
import_fs11 = require("fs");
|
|
88082
88417
|
init_bashCommandUtils();
|
|
88083
88418
|
}
|
|
88084
88419
|
});
|
|
88085
88420
|
|
|
88086
88421
|
// src/tools/bash.js
|
|
88087
|
-
var
|
|
88422
|
+
var import_ai5, import_path12, bashTool;
|
|
88088
88423
|
var init_bash = __esm({
|
|
88089
88424
|
"src/tools/bash.js"() {
|
|
88090
88425
|
"use strict";
|
|
88091
|
-
|
|
88092
|
-
|
|
88426
|
+
import_ai5 = require("ai");
|
|
88427
|
+
import_path12 = require("path");
|
|
88093
88428
|
init_bashPermissions();
|
|
88094
88429
|
init_bashExecutor();
|
|
88095
88430
|
bashTool = (options = {}) => {
|
|
@@ -88118,7 +88453,7 @@ var init_bash = __esm({
|
|
|
88118
88453
|
}
|
|
88119
88454
|
return process.cwd();
|
|
88120
88455
|
};
|
|
88121
|
-
return (0,
|
|
88456
|
+
return (0, import_ai5.tool)({
|
|
88122
88457
|
name: "bash",
|
|
88123
88458
|
description: `Execute bash commands for system exploration and development tasks.
|
|
88124
88459
|
|
|
@@ -88198,12 +88533,12 @@ For code exploration, try these safe alternatives:
|
|
|
88198
88533
|
- npm list, pip list for package information`;
|
|
88199
88534
|
}
|
|
88200
88535
|
const defaultDir = getDefaultWorkingDirectory();
|
|
88201
|
-
const workingDir = workingDirectory ? (0,
|
|
88536
|
+
const workingDir = workingDirectory ? (0, import_path12.isAbsolute)(workingDirectory) ? (0, import_path12.resolve)(workingDirectory) : (0, import_path12.resolve)(defaultDir, workingDirectory) : defaultDir;
|
|
88202
88537
|
if (allowedFolders && allowedFolders.length > 0) {
|
|
88203
|
-
const resolvedWorkingDir = (0,
|
|
88538
|
+
const resolvedWorkingDir = (0, import_path12.resolve)(workingDir);
|
|
88204
88539
|
const isAllowed = allowedFolders.some((folder) => {
|
|
88205
|
-
const resolvedFolder = (0,
|
|
88206
|
-
return resolvedWorkingDir === resolvedFolder || resolvedWorkingDir.startsWith(resolvedFolder +
|
|
88540
|
+
const resolvedFolder = (0, import_path12.resolve)(folder);
|
|
88541
|
+
return resolvedWorkingDir === resolvedFolder || resolvedWorkingDir.startsWith(resolvedFolder + import_path12.sep);
|
|
88207
88542
|
});
|
|
88208
88543
|
if (!isAllowed) {
|
|
88209
88544
|
return `Error: Working directory "${workingDir}" is not within allowed folders: ${allowedFolders.join(", ")}`;
|
|
@@ -88255,323 +88590,6 @@ Command failed with exit code ${result.exitCode}`;
|
|
|
88255
88590
|
}
|
|
88256
88591
|
});
|
|
88257
88592
|
|
|
88258
|
-
// src/tools/edit.js
|
|
88259
|
-
function isPathAllowed(filePath, allowedFolders) {
|
|
88260
|
-
if (!allowedFolders || allowedFolders.length === 0) {
|
|
88261
|
-
const resolvedPath3 = (0, import_path12.resolve)(filePath);
|
|
88262
|
-
const cwd = (0, import_path12.resolve)(process.cwd());
|
|
88263
|
-
return resolvedPath3 === cwd || resolvedPath3.startsWith(cwd + import_path12.sep);
|
|
88264
|
-
}
|
|
88265
|
-
const resolvedPath2 = (0, import_path12.resolve)(filePath);
|
|
88266
|
-
return allowedFolders.some((folder) => {
|
|
88267
|
-
const allowedPath = (0, import_path12.resolve)(folder);
|
|
88268
|
-
return resolvedPath2 === allowedPath || resolvedPath2.startsWith(allowedPath + import_path12.sep);
|
|
88269
|
-
});
|
|
88270
|
-
}
|
|
88271
|
-
function parseFileToolOptions(options = {}) {
|
|
88272
|
-
return {
|
|
88273
|
-
debug: options.debug || false,
|
|
88274
|
-
allowedFolders: options.allowedFolders || [],
|
|
88275
|
-
cwd: options.cwd
|
|
88276
|
-
};
|
|
88277
|
-
}
|
|
88278
|
-
var import_ai5, import_fs10, import_path12, import_fs11, editTool, createTool, editSchema, createSchema, editDescription, createDescription, editToolDefinition, createToolDefinition;
|
|
88279
|
-
var init_edit = __esm({
|
|
88280
|
-
"src/tools/edit.js"() {
|
|
88281
|
-
"use strict";
|
|
88282
|
-
import_ai5 = require("ai");
|
|
88283
|
-
import_fs10 = require("fs");
|
|
88284
|
-
import_path12 = require("path");
|
|
88285
|
-
import_fs11 = require("fs");
|
|
88286
|
-
editTool = (options = {}) => {
|
|
88287
|
-
const { debug, allowedFolders, cwd } = parseFileToolOptions(options);
|
|
88288
|
-
return (0, import_ai5.tool)({
|
|
88289
|
-
name: "edit",
|
|
88290
|
-
description: `Edit files using exact string replacement (Claude Code style).
|
|
88291
|
-
|
|
88292
|
-
This tool performs exact string replacements in files. It requires the old_string to match exactly what's in the file, including all whitespace and indentation.
|
|
88293
|
-
|
|
88294
|
-
Parameters:
|
|
88295
|
-
- file_path: Path to the file to edit (absolute or relative)
|
|
88296
|
-
- old_string: Exact text to find and replace (must be unique in the file unless replace_all is true)
|
|
88297
|
-
- new_string: Text to replace with
|
|
88298
|
-
- replace_all: (optional) Replace all occurrences instead of requiring uniqueness
|
|
88299
|
-
|
|
88300
|
-
Important:
|
|
88301
|
-
- The old_string must match EXACTLY including whitespace
|
|
88302
|
-
- If old_string appears multiple times and replace_all is false, the edit will fail
|
|
88303
|
-
- Use larger context around the string to ensure uniqueness when needed`,
|
|
88304
|
-
inputSchema: {
|
|
88305
|
-
type: "object",
|
|
88306
|
-
properties: {
|
|
88307
|
-
file_path: {
|
|
88308
|
-
type: "string",
|
|
88309
|
-
description: "Path to the file to edit"
|
|
88310
|
-
},
|
|
88311
|
-
old_string: {
|
|
88312
|
-
type: "string",
|
|
88313
|
-
description: "Exact text to find and replace"
|
|
88314
|
-
},
|
|
88315
|
-
new_string: {
|
|
88316
|
-
type: "string",
|
|
88317
|
-
description: "Text to replace with"
|
|
88318
|
-
},
|
|
88319
|
-
replace_all: {
|
|
88320
|
-
type: "boolean",
|
|
88321
|
-
description: "Replace all occurrences (default: false)",
|
|
88322
|
-
default: false
|
|
88323
|
-
}
|
|
88324
|
-
},
|
|
88325
|
-
required: ["file_path", "old_string", "new_string"]
|
|
88326
|
-
},
|
|
88327
|
-
execute: async ({ file_path, old_string, new_string, replace_all = false }) => {
|
|
88328
|
-
try {
|
|
88329
|
-
if (!file_path || typeof file_path !== "string" || file_path.trim() === "") {
|
|
88330
|
-
return `Error editing file: Invalid file_path - must be a non-empty string`;
|
|
88331
|
-
}
|
|
88332
|
-
if (old_string === void 0 || old_string === null || typeof old_string !== "string") {
|
|
88333
|
-
return `Error editing file: Invalid old_string - must be a string`;
|
|
88334
|
-
}
|
|
88335
|
-
if (new_string === void 0 || new_string === null || typeof new_string !== "string") {
|
|
88336
|
-
return `Error editing file: Invalid new_string - must be a string`;
|
|
88337
|
-
}
|
|
88338
|
-
const resolvedPath2 = (0, import_path12.isAbsolute)(file_path) ? file_path : (0, import_path12.resolve)(cwd || process.cwd(), file_path);
|
|
88339
|
-
if (debug) {
|
|
88340
|
-
console.error(`[Edit] Attempting to edit file: ${resolvedPath2}`);
|
|
88341
|
-
}
|
|
88342
|
-
if (!isPathAllowed(resolvedPath2, allowedFolders)) {
|
|
88343
|
-
return `Error editing file: Permission denied - ${file_path} is outside allowed directories`;
|
|
88344
|
-
}
|
|
88345
|
-
if (!(0, import_fs11.existsSync)(resolvedPath2)) {
|
|
88346
|
-
return `Error editing file: File not found - ${file_path}`;
|
|
88347
|
-
}
|
|
88348
|
-
const content = await import_fs10.promises.readFile(resolvedPath2, "utf-8");
|
|
88349
|
-
if (!content.includes(old_string)) {
|
|
88350
|
-
return `Error editing file: String not found - the specified old_string was not found in ${file_path}`;
|
|
88351
|
-
}
|
|
88352
|
-
const occurrences = content.split(old_string).length - 1;
|
|
88353
|
-
if (!replace_all && occurrences > 1) {
|
|
88354
|
-
return `Error editing file: Multiple occurrences found - the old_string appears ${occurrences} times. Use replace_all: true to replace all occurrences, or provide more context to make the string unique.`;
|
|
88355
|
-
}
|
|
88356
|
-
let newContent;
|
|
88357
|
-
if (replace_all) {
|
|
88358
|
-
newContent = content.replaceAll(old_string, new_string);
|
|
88359
|
-
} else {
|
|
88360
|
-
newContent = content.replace(old_string, new_string);
|
|
88361
|
-
}
|
|
88362
|
-
if (newContent === content) {
|
|
88363
|
-
return `Error editing file: No changes made - old_string and new_string might be the same`;
|
|
88364
|
-
}
|
|
88365
|
-
await import_fs10.promises.writeFile(resolvedPath2, newContent, "utf-8");
|
|
88366
|
-
const replacedCount = replace_all ? occurrences : 1;
|
|
88367
|
-
if (debug) {
|
|
88368
|
-
console.error(`[Edit] Successfully edited ${resolvedPath2}, replaced ${replacedCount} occurrence(s)`);
|
|
88369
|
-
}
|
|
88370
|
-
return `Successfully edited ${file_path} (${replacedCount} replacement${replacedCount !== 1 ? "s" : ""})`;
|
|
88371
|
-
} catch (error2) {
|
|
88372
|
-
console.error("[Edit] Error:", error2);
|
|
88373
|
-
return `Error editing file: ${error2.message}`;
|
|
88374
|
-
}
|
|
88375
|
-
}
|
|
88376
|
-
});
|
|
88377
|
-
};
|
|
88378
|
-
createTool = (options = {}) => {
|
|
88379
|
-
const { debug, allowedFolders, cwd } = parseFileToolOptions(options);
|
|
88380
|
-
return (0, import_ai5.tool)({
|
|
88381
|
-
name: "create",
|
|
88382
|
-
description: `Create new files with specified content.
|
|
88383
|
-
|
|
88384
|
-
This tool creates new files in the filesystem. It will create parent directories if they don't exist.
|
|
88385
|
-
|
|
88386
|
-
Parameters:
|
|
88387
|
-
- file_path: Path where the file should be created (absolute or relative)
|
|
88388
|
-
- content: Content to write to the file
|
|
88389
|
-
- overwrite: (optional) Whether to overwrite if file exists (default: false)
|
|
88390
|
-
|
|
88391
|
-
Important:
|
|
88392
|
-
- By default, will fail if the file already exists
|
|
88393
|
-
- Set overwrite: true to replace existing files
|
|
88394
|
-
- Parent directories will be created automatically if needed`,
|
|
88395
|
-
inputSchema: {
|
|
88396
|
-
type: "object",
|
|
88397
|
-
properties: {
|
|
88398
|
-
file_path: {
|
|
88399
|
-
type: "string",
|
|
88400
|
-
description: "Path where the file should be created"
|
|
88401
|
-
},
|
|
88402
|
-
content: {
|
|
88403
|
-
type: "string",
|
|
88404
|
-
description: "Content to write to the file"
|
|
88405
|
-
},
|
|
88406
|
-
overwrite: {
|
|
88407
|
-
type: "boolean",
|
|
88408
|
-
description: "Overwrite if file exists (default: false)",
|
|
88409
|
-
default: false
|
|
88410
|
-
}
|
|
88411
|
-
},
|
|
88412
|
-
required: ["file_path", "content"]
|
|
88413
|
-
},
|
|
88414
|
-
execute: async ({ file_path, content, overwrite = false }) => {
|
|
88415
|
-
try {
|
|
88416
|
-
if (!file_path || typeof file_path !== "string" || file_path.trim() === "") {
|
|
88417
|
-
return `Error creating file: Invalid file_path - must be a non-empty string`;
|
|
88418
|
-
}
|
|
88419
|
-
if (content === void 0 || content === null || typeof content !== "string") {
|
|
88420
|
-
return `Error creating file: Invalid content - must be a string`;
|
|
88421
|
-
}
|
|
88422
|
-
const resolvedPath2 = (0, import_path12.isAbsolute)(file_path) ? file_path : (0, import_path12.resolve)(cwd || process.cwd(), file_path);
|
|
88423
|
-
if (debug) {
|
|
88424
|
-
console.error(`[Create] Attempting to create file: ${resolvedPath2}`);
|
|
88425
|
-
}
|
|
88426
|
-
if (!isPathAllowed(resolvedPath2, allowedFolders)) {
|
|
88427
|
-
return `Error creating file: Permission denied - ${file_path} is outside allowed directories`;
|
|
88428
|
-
}
|
|
88429
|
-
if ((0, import_fs11.existsSync)(resolvedPath2) && !overwrite) {
|
|
88430
|
-
return `Error creating file: File already exists - ${file_path}. Use overwrite: true to replace it.`;
|
|
88431
|
-
}
|
|
88432
|
-
const dir = (0, import_path12.dirname)(resolvedPath2);
|
|
88433
|
-
await import_fs10.promises.mkdir(dir, { recursive: true });
|
|
88434
|
-
await import_fs10.promises.writeFile(resolvedPath2, content, "utf-8");
|
|
88435
|
-
const action = (0, import_fs11.existsSync)(resolvedPath2) && overwrite ? "overwrote" : "created";
|
|
88436
|
-
const bytes = Buffer.byteLength(content, "utf-8");
|
|
88437
|
-
if (debug) {
|
|
88438
|
-
console.error(`[Create] Successfully ${action} ${resolvedPath2}`);
|
|
88439
|
-
}
|
|
88440
|
-
return `Successfully ${action} ${file_path} (${bytes} bytes)`;
|
|
88441
|
-
} catch (error2) {
|
|
88442
|
-
console.error("[Create] Error:", error2);
|
|
88443
|
-
return `Error creating file: ${error2.message}`;
|
|
88444
|
-
}
|
|
88445
|
-
}
|
|
88446
|
-
});
|
|
88447
|
-
};
|
|
88448
|
-
editSchema = {
|
|
88449
|
-
type: "object",
|
|
88450
|
-
properties: {
|
|
88451
|
-
file_path: {
|
|
88452
|
-
type: "string",
|
|
88453
|
-
description: "Path to the file to edit"
|
|
88454
|
-
},
|
|
88455
|
-
old_string: {
|
|
88456
|
-
type: "string",
|
|
88457
|
-
description: "Exact text to find and replace"
|
|
88458
|
-
},
|
|
88459
|
-
new_string: {
|
|
88460
|
-
type: "string",
|
|
88461
|
-
description: "Text to replace with"
|
|
88462
|
-
},
|
|
88463
|
-
replace_all: {
|
|
88464
|
-
type: "boolean",
|
|
88465
|
-
description: "Replace all occurrences (default: false)"
|
|
88466
|
-
}
|
|
88467
|
-
},
|
|
88468
|
-
required: ["file_path", "old_string", "new_string"]
|
|
88469
|
-
};
|
|
88470
|
-
createSchema = {
|
|
88471
|
-
type: "object",
|
|
88472
|
-
properties: {
|
|
88473
|
-
file_path: {
|
|
88474
|
-
type: "string",
|
|
88475
|
-
description: "Path where the file should be created"
|
|
88476
|
-
},
|
|
88477
|
-
content: {
|
|
88478
|
-
type: "string",
|
|
88479
|
-
description: "Content to write to the file"
|
|
88480
|
-
},
|
|
88481
|
-
overwrite: {
|
|
88482
|
-
type: "boolean",
|
|
88483
|
-
description: "Overwrite if file exists (default: false)"
|
|
88484
|
-
}
|
|
88485
|
-
},
|
|
88486
|
-
required: ["file_path", "content"]
|
|
88487
|
-
};
|
|
88488
|
-
editDescription = "Edit files using exact string replacement. Requires exact match including whitespace.";
|
|
88489
|
-
createDescription = "Create new files with specified content. Will create parent directories if needed.";
|
|
88490
|
-
editToolDefinition = `
|
|
88491
|
-
## edit
|
|
88492
|
-
Description: ${editDescription}
|
|
88493
|
-
|
|
88494
|
-
When to use:
|
|
88495
|
-
- For precise, surgical edits to existing files
|
|
88496
|
-
- When you need to change specific lines or blocks of code
|
|
88497
|
-
- For renaming functions, variables, or updating configuration values
|
|
88498
|
-
- When the exact text to replace is known and unique (or use replace_all for multiple occurrences)
|
|
88499
|
-
|
|
88500
|
-
When NOT to use:
|
|
88501
|
-
- For creating new files (use 'create' tool instead)
|
|
88502
|
-
- When you cannot determine the exact text to replace
|
|
88503
|
-
- When changes span multiple locations that would be better handled together
|
|
88504
|
-
|
|
88505
|
-
Parameters:
|
|
88506
|
-
- file_path: (required) Path to the file to edit
|
|
88507
|
-
- old_string: (required) Exact text to find and replace (must match including whitespace, newlines, and indentation)
|
|
88508
|
-
- new_string: (required) Text to replace with
|
|
88509
|
-
- replace_all: (optional, default: false) Replace all occurrences if the string appears multiple times
|
|
88510
|
-
|
|
88511
|
-
Important notes:
|
|
88512
|
-
- The old_string MUST match EXACTLY, including all whitespace, indentation, and line breaks
|
|
88513
|
-
- If old_string appears multiple times and replace_all is false, the tool will fail
|
|
88514
|
-
- Always verify the exact formatting of the text you want to replace
|
|
88515
|
-
|
|
88516
|
-
Examples:
|
|
88517
|
-
<edit>
|
|
88518
|
-
<file_path>src/main.js</file_path>
|
|
88519
|
-
<old_string>function oldName() {
|
|
88520
|
-
return 42;
|
|
88521
|
-
}</old_string>
|
|
88522
|
-
<new_string>function newName() {
|
|
88523
|
-
return 42;
|
|
88524
|
-
}</new_string>
|
|
88525
|
-
</edit>
|
|
88526
|
-
|
|
88527
|
-
<edit>
|
|
88528
|
-
<file_path>config.json</file_path>
|
|
88529
|
-
<old_string>"debug": false</old_string>
|
|
88530
|
-
<new_string>"debug": true</new_string>
|
|
88531
|
-
<replace_all>true</replace_all>
|
|
88532
|
-
</edit>`;
|
|
88533
|
-
createToolDefinition = `
|
|
88534
|
-
## create
|
|
88535
|
-
Description: ${createDescription}
|
|
88536
|
-
|
|
88537
|
-
When to use:
|
|
88538
|
-
- For creating brand new files from scratch
|
|
88539
|
-
- When you need to add configuration files, documentation, or new modules
|
|
88540
|
-
- For generating boilerplate code or templates
|
|
88541
|
-
- When you have the complete content ready to write
|
|
88542
|
-
|
|
88543
|
-
When NOT to use:
|
|
88544
|
-
- For editing existing files (use 'edit' tool instead)
|
|
88545
|
-
- When a file already exists unless you explicitly want to overwrite it
|
|
88546
|
-
|
|
88547
|
-
Parameters:
|
|
88548
|
-
- file_path: (required) Path where the file should be created
|
|
88549
|
-
- content: (required) Complete content to write to the file
|
|
88550
|
-
- overwrite: (optional, default: false) Whether to overwrite if file already exists
|
|
88551
|
-
|
|
88552
|
-
Important notes:
|
|
88553
|
-
- Parent directories will be created automatically if they don't exist
|
|
88554
|
-
- The tool will fail if the file already exists and overwrite is false
|
|
88555
|
-
- Be careful with the overwrite option as it completely replaces existing files
|
|
88556
|
-
|
|
88557
|
-
Examples:
|
|
88558
|
-
<create>
|
|
88559
|
-
<file_path>src/newFile.js</file_path>
|
|
88560
|
-
<content>export function hello() {
|
|
88561
|
-
return "Hello, world!";
|
|
88562
|
-
}</content>
|
|
88563
|
-
</create>
|
|
88564
|
-
|
|
88565
|
-
<create>
|
|
88566
|
-
<file_path>README.md</file_path>
|
|
88567
|
-
<content># My Project
|
|
88568
|
-
|
|
88569
|
-
This is a new project.</content>
|
|
88570
|
-
<overwrite>true</overwrite>
|
|
88571
|
-
</create>`;
|
|
88572
|
-
}
|
|
88573
|
-
});
|
|
88574
|
-
|
|
88575
88593
|
// src/tools/langchain.js
|
|
88576
88594
|
function createSearchTool(options = {}) {
|
|
88577
88595
|
const { cwd } = options;
|
|
@@ -88796,12 +88814,14 @@ For GitHub-compatible mermaid diagrams, avoid single quotes and parentheses in n
|
|
|
88796
88814
|
var tools_exports = {};
|
|
88797
88815
|
__export(tools_exports, {
|
|
88798
88816
|
DEFAULT_SYSTEM_MESSAGE: () => DEFAULT_SYSTEM_MESSAGE,
|
|
88817
|
+
DEFAULT_VALID_TOOLS: () => DEFAULT_VALID_TOOLS,
|
|
88799
88818
|
attemptCompletionSchema: () => attemptCompletionSchema,
|
|
88800
88819
|
attemptCompletionToolDefinition: () => attemptCompletionToolDefinition,
|
|
88801
88820
|
bashDescription: () => bashDescription,
|
|
88802
88821
|
bashSchema: () => bashSchema,
|
|
88803
88822
|
bashTool: () => bashTool,
|
|
88804
88823
|
bashToolDefinition: () => bashToolDefinition,
|
|
88824
|
+
buildToolTagPattern: () => buildToolTagPattern,
|
|
88805
88825
|
createDescription: () => createDescription,
|
|
88806
88826
|
createExtractTool: () => createExtractTool,
|
|
88807
88827
|
createQueryTool: () => createQueryTool,
|