@polka-codes/core 0.8.10 → 0.8.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_tsup-dts-rollup.d.ts +668 -423
- package/dist/index.d.ts +4 -2
- package/dist/index.js +600 -342
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7,8 +7,10 @@ var __export = (target, all) => {
|
|
|
7
7
|
// src/AiService/AiServiceBase.ts
|
|
8
8
|
var AiServiceBase = class {
|
|
9
9
|
usageMeter;
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
options;
|
|
11
|
+
constructor(options) {
|
|
12
|
+
this.options = options;
|
|
13
|
+
this.usageMeter = options.usageMeter;
|
|
12
14
|
}
|
|
13
15
|
async *send(systemPrompt, messages) {
|
|
14
16
|
this.usageMeter.checkLimit();
|
|
@@ -169,7 +171,7 @@ var AnthropicService = class extends AiServiceBase {
|
|
|
169
171
|
#client;
|
|
170
172
|
model;
|
|
171
173
|
constructor(options) {
|
|
172
|
-
super(options
|
|
174
|
+
super(options);
|
|
173
175
|
this.#options = options;
|
|
174
176
|
this.#client = new Anthropic({
|
|
175
177
|
apiKey: options.apiKey,
|
|
@@ -448,7 +450,7 @@ var DeepSeekService = class extends AiServiceBase {
|
|
|
448
450
|
#client;
|
|
449
451
|
model;
|
|
450
452
|
constructor(options) {
|
|
451
|
-
super(options
|
|
453
|
+
super(options);
|
|
452
454
|
this.#client = new OpenAI({
|
|
453
455
|
baseURL: "https://api.deepseek.com/v1",
|
|
454
456
|
apiKey: options.apiKey
|
|
@@ -511,7 +513,7 @@ var OllamaService = class extends AiServiceBase {
|
|
|
511
513
|
#client;
|
|
512
514
|
model;
|
|
513
515
|
constructor(options) {
|
|
514
|
-
super(options
|
|
516
|
+
super(options);
|
|
515
517
|
this.#client = new OpenAI2({
|
|
516
518
|
baseURL: `${options.baseUrl || "http://localhost:11434"}/v1`,
|
|
517
519
|
apiKey: "ollama"
|
|
@@ -554,7 +556,7 @@ var OpenRouterService = class extends AiServiceBase {
|
|
|
554
556
|
#modelProviderInfo;
|
|
555
557
|
model;
|
|
556
558
|
constructor(options) {
|
|
557
|
-
super(options
|
|
559
|
+
super(options);
|
|
558
560
|
if (!options.model) {
|
|
559
561
|
throw new Error("OpenRouter requires a model");
|
|
560
562
|
}
|
|
@@ -876,9 +878,6 @@ var MockProvider = class {
|
|
|
876
878
|
async searchFiles(path, regex, filePattern) {
|
|
877
879
|
return ["mock-file.txt"];
|
|
878
880
|
}
|
|
879
|
-
async listCodeDefinitionNames(path) {
|
|
880
|
-
return "mockDefinition";
|
|
881
|
-
}
|
|
882
881
|
async executeCommand(command, needApprove) {
|
|
883
882
|
return { stdout: "mock output", stderr: "", exitCode: 0 };
|
|
884
883
|
}
|
|
@@ -896,14 +895,13 @@ __export(allTools_exports, {
|
|
|
896
895
|
askFollowupQuestion: () => askFollowupQuestion_default,
|
|
897
896
|
attemptCompletion: () => attemptCompletion_default,
|
|
898
897
|
delegate: () => delegate_default,
|
|
898
|
+
editFile: () => editFile_default,
|
|
899
899
|
executeCommand: () => executeCommand_default,
|
|
900
900
|
handOver: () => handOver_default,
|
|
901
|
-
listCodeDefinitionNames: () => listCodeDefinitionNames_default,
|
|
902
901
|
listFiles: () => listFiles_default,
|
|
903
902
|
readFile: () => readFile_default,
|
|
904
903
|
removeFile: () => removeFile_default,
|
|
905
904
|
renameFile: () => renameFile_default,
|
|
906
|
-
replaceInFile: () => replaceInFile_default,
|
|
907
905
|
searchFiles: () => searchFiles_default,
|
|
908
906
|
updateKnowledge: () => updateKnowledge_default,
|
|
909
907
|
writeToFile: () => writeToFile_default
|
|
@@ -929,61 +927,85 @@ var ToolResponseType = /* @__PURE__ */ ((ToolResponseType2) => {
|
|
|
929
927
|
return ToolResponseType2;
|
|
930
928
|
})(ToolResponseType || {});
|
|
931
929
|
|
|
932
|
-
// src/tools/utils/
|
|
933
|
-
var
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
930
|
+
// src/tools/utils/editFile.ts
|
|
931
|
+
var START_OF_FILE = "<<<START_OF_FILE>>>";
|
|
932
|
+
var END_OF_FILE = "<<<END_OF_FILE>>>";
|
|
933
|
+
var editFile = async (fileContent, operations) => {
|
|
934
|
+
if (!operations || operations.length === 0) {
|
|
935
|
+
throw new Error("At least one edit operation is required");
|
|
938
936
|
}
|
|
939
|
-
|
|
940
|
-
|
|
937
|
+
const originalLines = fileContent.split("\n");
|
|
938
|
+
let updatedContent = fileContent;
|
|
939
|
+
for (const operation of operations) {
|
|
940
|
+
updatedContent = await applyEditOperation(updatedContent, operation, originalLines);
|
|
941
941
|
}
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
942
|
+
return updatedContent;
|
|
943
|
+
};
|
|
944
|
+
async function applyEditOperation(fileContent, operation, originalLines) {
|
|
945
|
+
const { before_text, after_text, new_text, before_text_line_start, after_text_line_start } = operation;
|
|
946
|
+
if (before_text === START_OF_FILE && after_text === END_OF_FILE) {
|
|
947
|
+
return new_text;
|
|
948
|
+
}
|
|
949
|
+
if (before_text === START_OF_FILE) {
|
|
950
|
+
if (!after_text) {
|
|
951
|
+
return new_text + fileContent;
|
|
946
952
|
}
|
|
947
|
-
const
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
if (
|
|
952
|
-
|
|
953
|
-
return content.slice(0, absoluteIndex) + replace + content.slice(absoluteIndex + trimmedSearch.length);
|
|
953
|
+
const afterIndex = findTextWithHint(fileContent, after_text, after_text_line_start, originalLines);
|
|
954
|
+
return new_text + fileContent.slice(afterIndex);
|
|
955
|
+
}
|
|
956
|
+
if (after_text === END_OF_FILE) {
|
|
957
|
+
if (!before_text) {
|
|
958
|
+
return fileContent + new_text;
|
|
954
959
|
}
|
|
955
|
-
const
|
|
956
|
-
const
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
960
|
+
const beforeIndex = findTextWithHint(fileContent, before_text, before_text_line_start, originalLines);
|
|
961
|
+
const beforeEndIndex = beforeIndex + before_text.length;
|
|
962
|
+
return fileContent.slice(0, beforeEndIndex) + new_text;
|
|
963
|
+
}
|
|
964
|
+
if (before_text && after_text) {
|
|
965
|
+
const beforeIndex = findTextWithHint(fileContent, before_text, before_text_line_start, originalLines);
|
|
966
|
+
const beforeEndIndex = beforeIndex + before_text.length;
|
|
967
|
+
const afterIndex = findTextWithHint(fileContent, after_text, after_text_line_start, originalLines, beforeEndIndex);
|
|
968
|
+
return fileContent.slice(0, beforeEndIndex) + new_text + fileContent.slice(afterIndex);
|
|
969
|
+
}
|
|
970
|
+
if (before_text) {
|
|
971
|
+
const beforeIndex = findTextWithHint(fileContent, before_text, before_text_line_start, originalLines);
|
|
972
|
+
const beforeEndIndex = beforeIndex + before_text.length;
|
|
973
|
+
return fileContent.slice(0, beforeEndIndex) + new_text + fileContent.slice(beforeEndIndex);
|
|
974
|
+
}
|
|
975
|
+
if (after_text) {
|
|
976
|
+
const afterIndex = findTextWithHint(fileContent, after_text, after_text_line_start, originalLines);
|
|
977
|
+
return fileContent.slice(0, afterIndex) + new_text + fileContent.slice(afterIndex);
|
|
978
|
+
}
|
|
979
|
+
throw new Error("Either before_text or after_text must be specified");
|
|
980
|
+
}
|
|
981
|
+
function findTextWithHint(content, searchText, lineHint, originalLines, startIndex = 0) {
|
|
982
|
+
if (lineHint && lineHint > 0 && lineHint <= originalLines.length) {
|
|
983
|
+
const hintIndex = getLineStartIndex(originalLines, lineHint - 1);
|
|
984
|
+
const searchRadius = 5;
|
|
985
|
+
const windowStart = Math.max(0, hintIndex - searchRadius * 50);
|
|
986
|
+
const windowEnd = Math.min(content.length, hintIndex + searchRadius * 50);
|
|
987
|
+
const windowContent = content.slice(windowStart, windowEnd);
|
|
988
|
+
const relativeIndex = windowContent.indexOf(searchText);
|
|
989
|
+
if (relativeIndex !== -1) {
|
|
990
|
+
const absoluteIndex = windowStart + relativeIndex;
|
|
991
|
+
if (absoluteIndex >= startIndex) {
|
|
992
|
+
return absoluteIndex;
|
|
972
993
|
}
|
|
973
|
-
const strippedSearch = trimmedSearch.replace(/\s+/g, "");
|
|
974
|
-
const endPos = actualPos;
|
|
975
|
-
const startPos = endPos - strippedSearch.length;
|
|
976
|
-
return content.slice(0, startPos) + replace + content.slice(endPos);
|
|
977
994
|
}
|
|
978
|
-
throw new Error(`Could not find the following text in file:
|
|
979
|
-
${search}`);
|
|
980
|
-
};
|
|
981
|
-
let updatedFile = fileContent;
|
|
982
|
-
for (const { search, replace } of blocks) {
|
|
983
|
-
updatedFile = findAndReplace(updatedFile, search, replace);
|
|
984
995
|
}
|
|
985
|
-
|
|
986
|
-
|
|
996
|
+
const index = content.indexOf(searchText, startIndex);
|
|
997
|
+
if (index === -1) {
|
|
998
|
+
throw new Error(`Could not find text: ${searchText}`);
|
|
999
|
+
}
|
|
1000
|
+
return index;
|
|
1001
|
+
}
|
|
1002
|
+
function getLineStartIndex(lines, lineIndex) {
|
|
1003
|
+
let index = 0;
|
|
1004
|
+
for (let i = 0; i < lineIndex && i < lines.length; i++) {
|
|
1005
|
+
index += lines[i].length + 1;
|
|
1006
|
+
}
|
|
1007
|
+
return index;
|
|
1008
|
+
}
|
|
987
1009
|
|
|
988
1010
|
// src/tools/utils/getArg.ts
|
|
989
1011
|
var getString = (args, name, defaultValue) => {
|
|
@@ -1077,6 +1099,62 @@ var getArray = (args, name, defaultValue) => {
|
|
|
1077
1099
|
return [ret];
|
|
1078
1100
|
};
|
|
1079
1101
|
|
|
1102
|
+
// src/tools/utils/replaceInFile.ts
|
|
1103
|
+
var replaceInFile = async (fileContent, diff) => {
|
|
1104
|
+
const blockPattern = /<<<<<+ SEARCH\s*\r?\n([\s\S]*?)\r?\n=======[ \t]*\r?\n([\s\S]*?)\r?\n?>>>>>+ REPLACE/g;
|
|
1105
|
+
const blocks = [];
|
|
1106
|
+
for (let match = blockPattern.exec(diff); match !== null; match = blockPattern.exec(diff)) {
|
|
1107
|
+
blocks.push({ search: match[1], replace: match[2] });
|
|
1108
|
+
}
|
|
1109
|
+
if (blocks.length === 0) {
|
|
1110
|
+
throw new Error("No valid diff blocks found.");
|
|
1111
|
+
}
|
|
1112
|
+
const findAndReplace = (content, search, replace) => {
|
|
1113
|
+
let index = content.indexOf(search);
|
|
1114
|
+
if (index !== -1) {
|
|
1115
|
+
return content.slice(0, index) + replace + content.slice(index + search.length);
|
|
1116
|
+
}
|
|
1117
|
+
const trimmedSearch = search.trim();
|
|
1118
|
+
const trimmedContent = content.trim();
|
|
1119
|
+
const offset = content.indexOf(trimmedContent);
|
|
1120
|
+
index = trimmedContent.indexOf(trimmedSearch);
|
|
1121
|
+
if (index !== -1) {
|
|
1122
|
+
const absoluteIndex = offset + index;
|
|
1123
|
+
return content.slice(0, absoluteIndex) + replace + content.slice(absoluteIndex + trimmedSearch.length);
|
|
1124
|
+
}
|
|
1125
|
+
const normalizedSearch = trimmedSearch.replace(/\s+/g, " ");
|
|
1126
|
+
const normalizedContent = trimmedContent.replace(/\s+/g, " ");
|
|
1127
|
+
index = normalizedContent.indexOf(normalizedSearch);
|
|
1128
|
+
if (index !== -1) {
|
|
1129
|
+
let runningIndex = 0;
|
|
1130
|
+
let actualPos = offset;
|
|
1131
|
+
for (const segment of trimmedSearch.replace(/\s+/g, " ").split(" ")) {
|
|
1132
|
+
const segIndex = content.indexOf(segment, actualPos);
|
|
1133
|
+
if (segIndex === -1) {
|
|
1134
|
+
break;
|
|
1135
|
+
}
|
|
1136
|
+
if (runningIndex === 0) {
|
|
1137
|
+
actualPos = segIndex;
|
|
1138
|
+
} else {
|
|
1139
|
+
actualPos = segIndex + segment.length;
|
|
1140
|
+
}
|
|
1141
|
+
runningIndex++;
|
|
1142
|
+
}
|
|
1143
|
+
const strippedSearch = trimmedSearch.replace(/\s+/g, "");
|
|
1144
|
+
const endPos = actualPos;
|
|
1145
|
+
const startPos = endPos - strippedSearch.length;
|
|
1146
|
+
return content.slice(0, startPos) + replace + content.slice(endPos);
|
|
1147
|
+
}
|
|
1148
|
+
throw new Error(`Could not find the following text in file:
|
|
1149
|
+
${search}`);
|
|
1150
|
+
};
|
|
1151
|
+
let updatedFile = fileContent;
|
|
1152
|
+
for (const { search, replace } of blocks) {
|
|
1153
|
+
updatedFile = findAndReplace(updatedFile, search, replace);
|
|
1154
|
+
}
|
|
1155
|
+
return updatedFile;
|
|
1156
|
+
};
|
|
1157
|
+
|
|
1080
1158
|
// src/tools/askFollowupQuestion.ts
|
|
1081
1159
|
var toolInfo = {
|
|
1082
1160
|
name: "ask_followup_question",
|
|
@@ -1387,59 +1465,8 @@ var executeCommand_default = {
|
|
|
1387
1465
|
isAvailable: isAvailable4
|
|
1388
1466
|
};
|
|
1389
1467
|
|
|
1390
|
-
// src/tools/listCodeDefinitionNames.ts
|
|
1391
|
-
var toolInfo5 = {
|
|
1392
|
-
name: "list_code_definition_names",
|
|
1393
|
-
description: "Request to list definition names (classes, functions, methods, etc.) used for all files in a directory. This tool provides insights into the codebase structure and important constructs, encapsulating high-level concepts and relationships that are crucial for understanding the overall architecture.",
|
|
1394
|
-
parameters: [
|
|
1395
|
-
{
|
|
1396
|
-
name: "path",
|
|
1397
|
-
description: "The path of a code file to list top level source code definitions for.",
|
|
1398
|
-
required: true,
|
|
1399
|
-
usageValue: "Directory path here"
|
|
1400
|
-
}
|
|
1401
|
-
],
|
|
1402
|
-
examples: [
|
|
1403
|
-
{
|
|
1404
|
-
description: "Request to list code definition names in a directory",
|
|
1405
|
-
parameters: [
|
|
1406
|
-
{
|
|
1407
|
-
name: "path",
|
|
1408
|
-
value: "src/utils"
|
|
1409
|
-
}
|
|
1410
|
-
]
|
|
1411
|
-
}
|
|
1412
|
-
],
|
|
1413
|
-
permissionLevel: 1 /* Read */
|
|
1414
|
-
};
|
|
1415
|
-
var handler5 = async (provider, args) => {
|
|
1416
|
-
if (!provider.listCodeDefinitionNames) {
|
|
1417
|
-
return {
|
|
1418
|
-
type: "Error" /* Error */,
|
|
1419
|
-
message: "Not possible to list code definition names. Abort."
|
|
1420
|
-
};
|
|
1421
|
-
}
|
|
1422
|
-
const path = getString(args, "path");
|
|
1423
|
-
const result = await provider.listCodeDefinitionNames(path);
|
|
1424
|
-
return {
|
|
1425
|
-
type: "Reply" /* Reply */,
|
|
1426
|
-
message: `<list_code_definition_names_path>${path}</list_code_definition_names_path>
|
|
1427
|
-
<list_code_definition_names_result>
|
|
1428
|
-
${result}
|
|
1429
|
-
</list_code_definition_names_result>`
|
|
1430
|
-
};
|
|
1431
|
-
};
|
|
1432
|
-
var isAvailable5 = (provider) => {
|
|
1433
|
-
return !!provider.listCodeDefinitionNames;
|
|
1434
|
-
};
|
|
1435
|
-
var listCodeDefinitionNames_default = {
|
|
1436
|
-
...toolInfo5,
|
|
1437
|
-
handler: handler5,
|
|
1438
|
-
isAvailable: isAvailable5
|
|
1439
|
-
};
|
|
1440
|
-
|
|
1441
1468
|
// src/tools/listFiles.ts
|
|
1442
|
-
var
|
|
1469
|
+
var toolInfo5 = {
|
|
1443
1470
|
name: "list_files",
|
|
1444
1471
|
description: "Request to list files and directories within the specified directory. If recursive is true, it will list all files and directories recursively. If recursive is false or not provided, it will only list the top-level contents. Do not use this tool to confirm the existence of files you may have created, as the user will let you know if the files were created successfully or not.",
|
|
1445
1472
|
parameters: [
|
|
@@ -1479,7 +1506,7 @@ var toolInfo6 = {
|
|
|
1479
1506
|
],
|
|
1480
1507
|
permissionLevel: 1 /* Read */
|
|
1481
1508
|
};
|
|
1482
|
-
var
|
|
1509
|
+
var handler5 = async (provider, args) => {
|
|
1483
1510
|
if (!provider.listFiles) {
|
|
1484
1511
|
return {
|
|
1485
1512
|
type: "Error" /* Error */,
|
|
@@ -1499,17 +1526,17 @@ ${files.join("\n")}
|
|
|
1499
1526
|
<list_files_truncated>${limitReached}</list_files_truncated>`
|
|
1500
1527
|
};
|
|
1501
1528
|
};
|
|
1502
|
-
var
|
|
1529
|
+
var isAvailable5 = (provider) => {
|
|
1503
1530
|
return !!provider.listFiles;
|
|
1504
1531
|
};
|
|
1505
1532
|
var listFiles_default = {
|
|
1506
|
-
...
|
|
1507
|
-
handler:
|
|
1508
|
-
isAvailable:
|
|
1533
|
+
...toolInfo5,
|
|
1534
|
+
handler: handler5,
|
|
1535
|
+
isAvailable: isAvailable5
|
|
1509
1536
|
};
|
|
1510
1537
|
|
|
1511
1538
|
// src/tools/readFile.ts
|
|
1512
|
-
var
|
|
1539
|
+
var toolInfo6 = {
|
|
1513
1540
|
name: "read_file",
|
|
1514
1541
|
description: "Request to read the contents of one or multiple files at the specified paths. Use comma separated paths to read multiple files. Use this when you need to examine the contents of an existing file you do not know the contents of, for example to analyze code, review text files, or extract information from configuration files. May not be suitable for other types of binary files, as it returns the raw content as a string. Try to list all the potential files are relevent to the task, and then use this tool to read all the relevant files.",
|
|
1515
1542
|
parameters: [
|
|
@@ -1542,7 +1569,7 @@ var toolInfo7 = {
|
|
|
1542
1569
|
],
|
|
1543
1570
|
permissionLevel: 1 /* Read */
|
|
1544
1571
|
};
|
|
1545
|
-
var
|
|
1572
|
+
var handler6 = async (provider, args) => {
|
|
1546
1573
|
if (!provider.readFile) {
|
|
1547
1574
|
return {
|
|
1548
1575
|
type: "Error" /* Error */,
|
|
@@ -1569,135 +1596,17 @@ var handler7 = async (provider, args) => {
|
|
|
1569
1596
|
message: resp.join("\n")
|
|
1570
1597
|
};
|
|
1571
1598
|
};
|
|
1572
|
-
var
|
|
1599
|
+
var isAvailable6 = (provider) => {
|
|
1573
1600
|
return !!provider.readFile;
|
|
1574
1601
|
};
|
|
1575
1602
|
var readFile_default = {
|
|
1576
|
-
...
|
|
1577
|
-
handler:
|
|
1578
|
-
isAvailable:
|
|
1579
|
-
};
|
|
1580
|
-
|
|
1581
|
-
// src/tools/replaceInFile.ts
|
|
1582
|
-
var toolInfo8 = {
|
|
1583
|
-
name: "replace_in_file",
|
|
1584
|
-
description: "Request to replace sections of content in an existing file using SEARCH/REPLACE blocks that define exact changes to specific parts of the file. This tool should be used when you need to make targeted changes to specific parts of a file.",
|
|
1585
|
-
parameters: [
|
|
1586
|
-
{
|
|
1587
|
-
name: "path",
|
|
1588
|
-
description: "The path of the file to modify",
|
|
1589
|
-
required: true,
|
|
1590
|
-
usageValue: "File path here"
|
|
1591
|
-
},
|
|
1592
|
-
{
|
|
1593
|
-
name: "diff",
|
|
1594
|
-
description: `One or more SEARCH/REPLACE blocks following this exact format:
|
|
1595
|
-
\`\`\`
|
|
1596
|
-
<<<<<<< SEARCH
|
|
1597
|
-
[exact content to find]
|
|
1598
|
-
=======
|
|
1599
|
-
[new content to replace with]
|
|
1600
|
-
>>>>>>> REPLACE
|
|
1601
|
-
\`\`\`
|
|
1602
|
-
Critical rules:
|
|
1603
|
-
1. SEARCH content must match the associated file section to find EXACTLY:
|
|
1604
|
-
* Match character-for-character including whitespace, indentation, line endings
|
|
1605
|
-
* Include all comments, docstrings, etc.
|
|
1606
|
-
2. SEARCH/REPLACE blocks will ONLY replace the first match occurrence.
|
|
1607
|
-
* Including multiple unique SEARCH/REPLACE blocks if you need to make multiple changes.
|
|
1608
|
-
* Include *just* enough lines in each SEARCH section to uniquely match each set of lines that need to change.
|
|
1609
|
-
* When using multiple SEARCH/REPLACE blocks, list them in the order they appear in the file.
|
|
1610
|
-
3. Keep SEARCH/REPLACE blocks concise:
|
|
1611
|
-
* Break large SEARCH/REPLACE blocks into a series of smaller blocks that each change a small portion of the file.
|
|
1612
|
-
* Include just the changing lines, and a few surrounding lines if needed for uniqueness.
|
|
1613
|
-
* Do not include long runs of unchanging lines in SEARCH/REPLACE blocks.
|
|
1614
|
-
* Each line must be complete. Never truncate lines mid-way through as this can cause matching failures.
|
|
1615
|
-
4. Special operations:
|
|
1616
|
-
* To move code: Use two SEARCH/REPLACE blocks (one to delete from original + one to insert at new location)
|
|
1617
|
-
* To delete code: Use empty REPLACE section`,
|
|
1618
|
-
required: true,
|
|
1619
|
-
usageValue: "Search and replace blocks here"
|
|
1620
|
-
}
|
|
1621
|
-
],
|
|
1622
|
-
examples: [
|
|
1623
|
-
{
|
|
1624
|
-
description: "Request to replace sections of content in a file",
|
|
1625
|
-
parameters: [
|
|
1626
|
-
{
|
|
1627
|
-
name: "path",
|
|
1628
|
-
value: "src/main.js"
|
|
1629
|
-
},
|
|
1630
|
-
{
|
|
1631
|
-
name: "diff",
|
|
1632
|
-
value: `
|
|
1633
|
-
<<<<<<< SEARCH
|
|
1634
|
-
import React from 'react';
|
|
1635
|
-
=======
|
|
1636
|
-
import React, { useState } from 'react';
|
|
1637
|
-
>>>>>>> REPLACE
|
|
1638
|
-
|
|
1639
|
-
<<<<<<< SEARCH
|
|
1640
|
-
function handleSubmit() {
|
|
1641
|
-
saveData();
|
|
1642
|
-
setLoading(false);
|
|
1643
|
-
}
|
|
1644
|
-
|
|
1645
|
-
=======
|
|
1646
|
-
>>>>>>> REPLACE
|
|
1647
|
-
|
|
1648
|
-
<<<<<<< SEARCH
|
|
1649
|
-
return (
|
|
1650
|
-
<div>
|
|
1651
|
-
=======
|
|
1652
|
-
function handleSubmit() {
|
|
1653
|
-
saveData();
|
|
1654
|
-
setLoading(false);
|
|
1655
|
-
}
|
|
1656
|
-
|
|
1657
|
-
return (
|
|
1658
|
-
<div>
|
|
1659
|
-
>>>>>>> REPLACE
|
|
1660
|
-
`
|
|
1661
|
-
}
|
|
1662
|
-
]
|
|
1663
|
-
}
|
|
1664
|
-
],
|
|
1665
|
-
permissionLevel: 2 /* Write */
|
|
1666
|
-
};
|
|
1667
|
-
var handler8 = async (provider, args) => {
|
|
1668
|
-
if (!provider.readFile || !provider.writeFile) {
|
|
1669
|
-
return {
|
|
1670
|
-
type: "Error" /* Error */,
|
|
1671
|
-
message: "Not possible to replace in file. Abort."
|
|
1672
|
-
};
|
|
1673
|
-
}
|
|
1674
|
-
const path = getString(args, "path");
|
|
1675
|
-
const diff = getString(args, "diff");
|
|
1676
|
-
const fileContent = await provider.readFile(path);
|
|
1677
|
-
if (fileContent == null) {
|
|
1678
|
-
return {
|
|
1679
|
-
type: "Error" /* Error */,
|
|
1680
|
-
message: `<error><replace_in_file_path>${path}</replace_in_file_path><error_message>File not found</error_message></error>`
|
|
1681
|
-
};
|
|
1682
|
-
}
|
|
1683
|
-
const result = await replaceInFile(fileContent, diff);
|
|
1684
|
-
await provider.writeFile(path, result);
|
|
1685
|
-
return {
|
|
1686
|
-
type: "Reply" /* Reply */,
|
|
1687
|
-
message: `<replace_in_file_path>${path}</replace_in_file_path>`
|
|
1688
|
-
};
|
|
1689
|
-
};
|
|
1690
|
-
var isAvailable8 = (provider) => {
|
|
1691
|
-
return !!provider.readFile && !!provider.writeFile;
|
|
1692
|
-
};
|
|
1693
|
-
var replaceInFile_default = {
|
|
1694
|
-
...toolInfo8,
|
|
1695
|
-
handler: handler8,
|
|
1696
|
-
isAvailable: isAvailable8
|
|
1603
|
+
...toolInfo6,
|
|
1604
|
+
handler: handler6,
|
|
1605
|
+
isAvailable: isAvailable6
|
|
1697
1606
|
};
|
|
1698
1607
|
|
|
1699
1608
|
// src/tools/searchFiles.ts
|
|
1700
|
-
var
|
|
1609
|
+
var toolInfo7 = {
|
|
1701
1610
|
name: "search_files",
|
|
1702
1611
|
description: "Request to perform a regex search across files in a specified directory, outputting context-rich results that include surrounding lines. This tool searches for patterns or specific content across multiple files, displaying each match with encapsulating context.",
|
|
1703
1612
|
parameters: [
|
|
@@ -1741,7 +1650,7 @@ var toolInfo9 = {
|
|
|
1741
1650
|
],
|
|
1742
1651
|
permissionLevel: 1 /* Read */
|
|
1743
1652
|
};
|
|
1744
|
-
var
|
|
1653
|
+
var handler7 = async (provider, args) => {
|
|
1745
1654
|
if (!provider.searchFiles) {
|
|
1746
1655
|
return {
|
|
1747
1656
|
type: "Error" /* Error */,
|
|
@@ -1763,19 +1672,19 @@ ${files.join("\n")}
|
|
|
1763
1672
|
`
|
|
1764
1673
|
};
|
|
1765
1674
|
};
|
|
1766
|
-
var
|
|
1675
|
+
var isAvailable7 = (provider) => {
|
|
1767
1676
|
return !!provider.searchFiles;
|
|
1768
1677
|
};
|
|
1769
1678
|
var searchFiles_default = {
|
|
1770
|
-
...
|
|
1771
|
-
handler:
|
|
1772
|
-
isAvailable:
|
|
1679
|
+
...toolInfo7,
|
|
1680
|
+
handler: handler7,
|
|
1681
|
+
isAvailable: isAvailable7
|
|
1773
1682
|
};
|
|
1774
1683
|
|
|
1775
1684
|
// src/tools/updateKnowledge.ts
|
|
1776
1685
|
import { join } from "node:path";
|
|
1777
1686
|
import YAML from "yaml";
|
|
1778
|
-
var
|
|
1687
|
+
var toolInfo8 = {
|
|
1779
1688
|
name: "update_knowledge",
|
|
1780
1689
|
description: "Update knowledge in a knowledge.ai.yml file with smart merging capabilities. This tool lets you add, update, or remove information using path-based updates and special directives.",
|
|
1781
1690
|
parameters: [
|
|
@@ -1949,7 +1858,7 @@ function deepMerge(target, source) {
|
|
|
1949
1858
|
}
|
|
1950
1859
|
return output;
|
|
1951
1860
|
}
|
|
1952
|
-
var
|
|
1861
|
+
var handler8 = async (provider, args) => {
|
|
1953
1862
|
if (!provider.readFile || !provider.writeFile) {
|
|
1954
1863
|
return {
|
|
1955
1864
|
type: "Error" /* Error */,
|
|
@@ -2021,17 +1930,17 @@ var handler10 = async (provider, args) => {
|
|
|
2021
1930
|
};
|
|
2022
1931
|
}
|
|
2023
1932
|
};
|
|
2024
|
-
var
|
|
1933
|
+
var isAvailable8 = (provider) => {
|
|
2025
1934
|
return !!provider.readFile && !!provider.writeFile;
|
|
2026
1935
|
};
|
|
2027
1936
|
var updateKnowledge_default = {
|
|
2028
|
-
...
|
|
2029
|
-
handler:
|
|
2030
|
-
isAvailable:
|
|
1937
|
+
...toolInfo8,
|
|
1938
|
+
handler: handler8,
|
|
1939
|
+
isAvailable: isAvailable8
|
|
2031
1940
|
};
|
|
2032
1941
|
|
|
2033
1942
|
// src/tools/writeToFile.ts
|
|
2034
|
-
var
|
|
1943
|
+
var toolInfo9 = {
|
|
2035
1944
|
name: "write_to_file",
|
|
2036
1945
|
description: "Request to write content to a file at the specified path. If the file exists, it will be overwritten with the provided content. If the file doesn't exist, it will be created. This tool will automatically create any directories needed to write the file. Ensure that the output content does not include incorrect escaped character patterns such as `<` and `>`.",
|
|
2037
1946
|
parameters: [
|
|
@@ -2076,7 +1985,7 @@ export default App;
|
|
|
2076
1985
|
],
|
|
2077
1986
|
permissionLevel: 2 /* Write */
|
|
2078
1987
|
};
|
|
2079
|
-
var
|
|
1988
|
+
var handler9 = async (provider, args) => {
|
|
2080
1989
|
if (!provider.writeFile) {
|
|
2081
1990
|
return {
|
|
2082
1991
|
type: "Error" /* Error */,
|
|
@@ -2091,17 +2000,17 @@ var handler11 = async (provider, args) => {
|
|
|
2091
2000
|
message: `<write_to_file_path>${path}</write_to_file_path><status>Success</status>`
|
|
2092
2001
|
};
|
|
2093
2002
|
};
|
|
2094
|
-
var
|
|
2003
|
+
var isAvailable9 = (provider) => {
|
|
2095
2004
|
return !!provider.writeFile;
|
|
2096
2005
|
};
|
|
2097
2006
|
var writeToFile_default = {
|
|
2098
|
-
...
|
|
2099
|
-
handler:
|
|
2100
|
-
isAvailable:
|
|
2007
|
+
...toolInfo9,
|
|
2008
|
+
handler: handler9,
|
|
2009
|
+
isAvailable: isAvailable9
|
|
2101
2010
|
};
|
|
2102
2011
|
|
|
2103
2012
|
// src/tools/handOver.ts
|
|
2104
|
-
var
|
|
2013
|
+
var toolInfo10 = {
|
|
2105
2014
|
name: "hand_over",
|
|
2106
2015
|
description: "Hand over the current task to another agent to complete. This tool MUST NOT to be used with any other tool.",
|
|
2107
2016
|
parameters: [
|
|
@@ -2124,79 +2033,274 @@ var toolInfo12 = {
|
|
|
2124
2033
|
usageValue: "Context information"
|
|
2125
2034
|
},
|
|
2126
2035
|
{
|
|
2127
|
-
name: "files",
|
|
2128
|
-
description: "The files relevant to the task. Comma separated paths",
|
|
2129
|
-
required: false,
|
|
2130
|
-
usageValue: "Relevant files"
|
|
2036
|
+
name: "files",
|
|
2037
|
+
description: "The files relevant to the task. Comma separated paths",
|
|
2038
|
+
required: false,
|
|
2039
|
+
usageValue: "Relevant files"
|
|
2040
|
+
}
|
|
2041
|
+
],
|
|
2042
|
+
examples: [
|
|
2043
|
+
{
|
|
2044
|
+
description: "Hand over a coding task to the coder agent",
|
|
2045
|
+
parameters: [
|
|
2046
|
+
{
|
|
2047
|
+
name: "agent_name",
|
|
2048
|
+
value: "coder"
|
|
2049
|
+
},
|
|
2050
|
+
{
|
|
2051
|
+
name: "task",
|
|
2052
|
+
value: "Implement the login feature"
|
|
2053
|
+
},
|
|
2054
|
+
{
|
|
2055
|
+
name: "context",
|
|
2056
|
+
value: "We need a secure login system with email and password"
|
|
2057
|
+
},
|
|
2058
|
+
{
|
|
2059
|
+
name: "files",
|
|
2060
|
+
value: "src/auth/login.ts,src/auth/types.ts"
|
|
2061
|
+
}
|
|
2062
|
+
]
|
|
2063
|
+
}
|
|
2064
|
+
],
|
|
2065
|
+
permissionLevel: 0 /* None */
|
|
2066
|
+
};
|
|
2067
|
+
var handler10 = async (_provider, args) => {
|
|
2068
|
+
const agentName = getString(args, "agent_name");
|
|
2069
|
+
const task = getString(args, "task");
|
|
2070
|
+
const context = getString(args, "context", void 0);
|
|
2071
|
+
const files = getStringArray(args, "files", []);
|
|
2072
|
+
return {
|
|
2073
|
+
type: "HandOver" /* HandOver */,
|
|
2074
|
+
agentName,
|
|
2075
|
+
task,
|
|
2076
|
+
context,
|
|
2077
|
+
files
|
|
2078
|
+
// originalTask will be set by AgentBase
|
|
2079
|
+
};
|
|
2080
|
+
};
|
|
2081
|
+
var isAvailable10 = (_provider) => {
|
|
2082
|
+
return true;
|
|
2083
|
+
};
|
|
2084
|
+
var handOver_default = {
|
|
2085
|
+
...toolInfo10,
|
|
2086
|
+
handler: handler10,
|
|
2087
|
+
isAvailable: isAvailable10
|
|
2088
|
+
};
|
|
2089
|
+
|
|
2090
|
+
// src/tools/removeFile.ts
|
|
2091
|
+
var toolInfo11 = {
|
|
2092
|
+
name: "remove_file",
|
|
2093
|
+
description: "Request to remove a file at the specified path.",
|
|
2094
|
+
parameters: [
|
|
2095
|
+
{
|
|
2096
|
+
name: "path",
|
|
2097
|
+
description: "The path of the file to remove",
|
|
2098
|
+
required: true,
|
|
2099
|
+
usageValue: "File path here"
|
|
2100
|
+
}
|
|
2101
|
+
],
|
|
2102
|
+
examples: [
|
|
2103
|
+
{
|
|
2104
|
+
description: "Request to remove a file",
|
|
2105
|
+
parameters: [
|
|
2106
|
+
{
|
|
2107
|
+
name: "path",
|
|
2108
|
+
value: "src/main.js"
|
|
2109
|
+
}
|
|
2110
|
+
]
|
|
2111
|
+
}
|
|
2112
|
+
],
|
|
2113
|
+
permissionLevel: 2 /* Write */
|
|
2114
|
+
};
|
|
2115
|
+
var handler11 = async (provider, args) => {
|
|
2116
|
+
if (!provider.removeFile) {
|
|
2117
|
+
return {
|
|
2118
|
+
type: "Error" /* Error */,
|
|
2119
|
+
message: "Not possible to remove file. Abort."
|
|
2120
|
+
};
|
|
2121
|
+
}
|
|
2122
|
+
const path = getString(args, "path");
|
|
2123
|
+
await provider.removeFile(path);
|
|
2124
|
+
return {
|
|
2125
|
+
type: "Reply" /* Reply */,
|
|
2126
|
+
message: `<remove_file_path>${path}</remove_file_path><status>Success</status>`
|
|
2127
|
+
};
|
|
2128
|
+
};
|
|
2129
|
+
var isAvailable11 = (provider) => {
|
|
2130
|
+
return !!provider.removeFile;
|
|
2131
|
+
};
|
|
2132
|
+
var removeFile_default = {
|
|
2133
|
+
...toolInfo11,
|
|
2134
|
+
handler: handler11,
|
|
2135
|
+
isAvailable: isAvailable11
|
|
2136
|
+
};
|
|
2137
|
+
|
|
2138
|
+
// src/tools/renameFile.ts
|
|
2139
|
+
var toolInfo12 = {
|
|
2140
|
+
name: "rename_file",
|
|
2141
|
+
description: "Request to rename a file from source path to target path.",
|
|
2142
|
+
parameters: [
|
|
2143
|
+
{
|
|
2144
|
+
name: "source_path",
|
|
2145
|
+
description: "The current path of the file",
|
|
2146
|
+
required: true,
|
|
2147
|
+
usageValue: "Source file path here"
|
|
2148
|
+
},
|
|
2149
|
+
{
|
|
2150
|
+
name: "target_path",
|
|
2151
|
+
description: "The new path for the file",
|
|
2152
|
+
required: true,
|
|
2153
|
+
usageValue: "Target file path here"
|
|
2131
2154
|
}
|
|
2132
2155
|
],
|
|
2133
2156
|
examples: [
|
|
2134
2157
|
{
|
|
2135
|
-
description: "
|
|
2158
|
+
description: "Request to rename a file",
|
|
2136
2159
|
parameters: [
|
|
2137
2160
|
{
|
|
2138
|
-
name: "
|
|
2139
|
-
value: "
|
|
2140
|
-
},
|
|
2141
|
-
{
|
|
2142
|
-
name: "task",
|
|
2143
|
-
value: "Implement the login feature"
|
|
2144
|
-
},
|
|
2145
|
-
{
|
|
2146
|
-
name: "context",
|
|
2147
|
-
value: "We need a secure login system with email and password"
|
|
2161
|
+
name: "source_path",
|
|
2162
|
+
value: "src/old-name.js"
|
|
2148
2163
|
},
|
|
2149
2164
|
{
|
|
2150
|
-
name: "
|
|
2151
|
-
value: "src/
|
|
2165
|
+
name: "target_path",
|
|
2166
|
+
value: "src/new-name.js"
|
|
2152
2167
|
}
|
|
2153
2168
|
]
|
|
2154
2169
|
}
|
|
2155
2170
|
],
|
|
2156
|
-
permissionLevel:
|
|
2171
|
+
permissionLevel: 2 /* Write */
|
|
2157
2172
|
};
|
|
2158
|
-
var handler12 = async (
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2173
|
+
var handler12 = async (provider, args) => {
|
|
2174
|
+
if (!provider.renameFile) {
|
|
2175
|
+
return {
|
|
2176
|
+
type: "Error" /* Error */,
|
|
2177
|
+
message: "Not possible to rename file. Abort."
|
|
2178
|
+
};
|
|
2179
|
+
}
|
|
2180
|
+
const sourcePath = getString(args, "source_path");
|
|
2181
|
+
const targetPath = getString(args, "target_path");
|
|
2182
|
+
await provider.renameFile(sourcePath, targetPath);
|
|
2163
2183
|
return {
|
|
2164
|
-
type: "
|
|
2165
|
-
|
|
2166
|
-
task,
|
|
2167
|
-
context,
|
|
2168
|
-
files
|
|
2169
|
-
// originalTask will be set by AgentBase
|
|
2184
|
+
type: "Reply" /* Reply */,
|
|
2185
|
+
message: `<rename_file_path>${targetPath}</rename_file_path><status>Success</status>`
|
|
2170
2186
|
};
|
|
2171
2187
|
};
|
|
2172
|
-
var isAvailable12 = (
|
|
2173
|
-
return
|
|
2188
|
+
var isAvailable12 = (provider) => {
|
|
2189
|
+
return !!provider.renameFile;
|
|
2174
2190
|
};
|
|
2175
|
-
var
|
|
2191
|
+
var renameFile_default = {
|
|
2176
2192
|
...toolInfo12,
|
|
2177
2193
|
handler: handler12,
|
|
2178
2194
|
isAvailable: isAvailable12
|
|
2179
2195
|
};
|
|
2180
2196
|
|
|
2181
|
-
// src/tools/
|
|
2197
|
+
// src/tools/editFile.ts
|
|
2182
2198
|
var toolInfo13 = {
|
|
2183
|
-
name: "
|
|
2184
|
-
description: "Request to
|
|
2199
|
+
name: "edit_file",
|
|
2200
|
+
description: "Request to edit file contents using before/after text anchors with flexible operations. Supports multiple edit operations in a single call.",
|
|
2185
2201
|
parameters: [
|
|
2186
2202
|
{
|
|
2187
2203
|
name: "path",
|
|
2188
|
-
description: "The path of the file to
|
|
2204
|
+
description: "The path of the file to edit",
|
|
2189
2205
|
required: true,
|
|
2190
2206
|
usageValue: "File path here"
|
|
2207
|
+
},
|
|
2208
|
+
{
|
|
2209
|
+
name: "operations",
|
|
2210
|
+
description: "Edit operation with before_text, after_text, new_text, and optional line range hints",
|
|
2211
|
+
required: true,
|
|
2212
|
+
allowMultiple: true,
|
|
2213
|
+
children: [
|
|
2214
|
+
{
|
|
2215
|
+
name: "before_text",
|
|
2216
|
+
description: `Text to find as the start anchor (use ${START_OF_FILE} for file start)`,
|
|
2217
|
+
required: false,
|
|
2218
|
+
usageValue: "Text before the edit location"
|
|
2219
|
+
},
|
|
2220
|
+
{
|
|
2221
|
+
name: "after_text",
|
|
2222
|
+
description: `Text to find as the end anchor (use ${END_OF_FILE} for file end)`,
|
|
2223
|
+
required: false,
|
|
2224
|
+
usageValue: "Text after the edit location"
|
|
2225
|
+
},
|
|
2226
|
+
{
|
|
2227
|
+
name: "new_text",
|
|
2228
|
+
description: "Text to replace the content between before_text and after_text",
|
|
2229
|
+
required: true,
|
|
2230
|
+
usageValue: "New text content"
|
|
2231
|
+
},
|
|
2232
|
+
{
|
|
2233
|
+
name: "before_text_line_start",
|
|
2234
|
+
description: "Optional line number hint for before_text location (1-based)",
|
|
2235
|
+
required: false,
|
|
2236
|
+
usageValue: "10"
|
|
2237
|
+
},
|
|
2238
|
+
{
|
|
2239
|
+
name: "after_text_line_start",
|
|
2240
|
+
description: "Optional line number hint for after_text location (1-based)",
|
|
2241
|
+
required: false,
|
|
2242
|
+
usageValue: "20"
|
|
2243
|
+
}
|
|
2244
|
+
],
|
|
2245
|
+
usageValue: "operations here"
|
|
2191
2246
|
}
|
|
2192
2247
|
],
|
|
2193
2248
|
examples: [
|
|
2194
2249
|
{
|
|
2195
|
-
description: "
|
|
2250
|
+
description: "Replace content between two text anchors",
|
|
2196
2251
|
parameters: [
|
|
2197
2252
|
{
|
|
2198
2253
|
name: "path",
|
|
2199
|
-
value: "src/main.
|
|
2254
|
+
value: "src/main.ts"
|
|
2255
|
+
},
|
|
2256
|
+
{
|
|
2257
|
+
name: "operations",
|
|
2258
|
+
value: {
|
|
2259
|
+
before_text: "function oldFunction() {",
|
|
2260
|
+
after_text: "}",
|
|
2261
|
+
new_text: '\n return "new implementation";\n'
|
|
2262
|
+
}
|
|
2263
|
+
}
|
|
2264
|
+
]
|
|
2265
|
+
},
|
|
2266
|
+
{
|
|
2267
|
+
description: "Insert at start of file",
|
|
2268
|
+
parameters: [
|
|
2269
|
+
{
|
|
2270
|
+
name: "path",
|
|
2271
|
+
value: "src/header.ts"
|
|
2272
|
+
},
|
|
2273
|
+
{
|
|
2274
|
+
name: "operations",
|
|
2275
|
+
value: {
|
|
2276
|
+
before_text: START_OF_FILE,
|
|
2277
|
+
after_text: "export",
|
|
2278
|
+
new_text: "// File header comment\n"
|
|
2279
|
+
}
|
|
2280
|
+
}
|
|
2281
|
+
]
|
|
2282
|
+
},
|
|
2283
|
+
{
|
|
2284
|
+
description: "Multiple operations in one call",
|
|
2285
|
+
parameters: [
|
|
2286
|
+
{
|
|
2287
|
+
name: "path",
|
|
2288
|
+
value: "src/utils.ts"
|
|
2289
|
+
},
|
|
2290
|
+
{
|
|
2291
|
+
name: "operations",
|
|
2292
|
+
value: [
|
|
2293
|
+
{
|
|
2294
|
+
before_text: "import React",
|
|
2295
|
+
after_text: 'from "react"',
|
|
2296
|
+
new_text: ", { useState }"
|
|
2297
|
+
},
|
|
2298
|
+
{
|
|
2299
|
+
before_text: "function Component() {",
|
|
2300
|
+
after_text: "return (",
|
|
2301
|
+
new_text: "\n const [state, setState] = useState(false);\n "
|
|
2302
|
+
}
|
|
2303
|
+
]
|
|
2200
2304
|
}
|
|
2201
2305
|
]
|
|
2202
2306
|
}
|
|
@@ -2204,57 +2308,130 @@ var toolInfo13 = {
|
|
|
2204
2308
|
permissionLevel: 2 /* Write */
|
|
2205
2309
|
};
|
|
2206
2310
|
var handler13 = async (provider, args) => {
|
|
2207
|
-
if (!provider.
|
|
2311
|
+
if (!provider.readFile || !provider.writeFile) {
|
|
2208
2312
|
return {
|
|
2209
2313
|
type: "Error" /* Error */,
|
|
2210
|
-
message: "Not possible to
|
|
2314
|
+
message: "Not possible to edit file. Abort."
|
|
2211
2315
|
};
|
|
2212
2316
|
}
|
|
2213
2317
|
const path = getString(args, "path");
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2318
|
+
const operations = getArray(args, "operations");
|
|
2319
|
+
if (!operations || operations.length === 0) {
|
|
2320
|
+
return {
|
|
2321
|
+
type: "Error" /* Error */,
|
|
2322
|
+
message: `<error><edit_file_path>${path}</edit_file_path><error_message>At least one edit operation is required</error_message></error>`
|
|
2323
|
+
};
|
|
2324
|
+
}
|
|
2325
|
+
const fileContent = await provider.readFile(path);
|
|
2326
|
+
if (fileContent == null) {
|
|
2327
|
+
return {
|
|
2328
|
+
type: "Error" /* Error */,
|
|
2329
|
+
message: `<error><edit_file_path>${path}</edit_file_path><error_message>File not found</error_message></error>`
|
|
2330
|
+
};
|
|
2331
|
+
}
|
|
2332
|
+
try {
|
|
2333
|
+
const result = await editFile(fileContent, operations);
|
|
2334
|
+
await provider.writeFile(path, result);
|
|
2335
|
+
return {
|
|
2336
|
+
type: "Reply" /* Reply */,
|
|
2337
|
+
message: `<edit_file_path>${path}</edit_file_path>`
|
|
2338
|
+
};
|
|
2339
|
+
} catch (error) {
|
|
2340
|
+
return {
|
|
2341
|
+
type: "Error" /* Error */,
|
|
2342
|
+
message: `<error><edit_file_path>${path}</edit_file_path><error_message>${error instanceof Error ? error.message : String(error)}</error_message></error>`
|
|
2343
|
+
};
|
|
2344
|
+
}
|
|
2219
2345
|
};
|
|
2220
2346
|
var isAvailable13 = (provider) => {
|
|
2221
|
-
return !!provider.
|
|
2347
|
+
return !!provider.readFile && !!provider.writeFile;
|
|
2222
2348
|
};
|
|
2223
|
-
var
|
|
2349
|
+
var editFile_default = {
|
|
2224
2350
|
...toolInfo13,
|
|
2225
2351
|
handler: handler13,
|
|
2226
2352
|
isAvailable: isAvailable13
|
|
2227
2353
|
};
|
|
2228
2354
|
|
|
2229
|
-
// src/tools/
|
|
2355
|
+
// src/tools/replaceInFile.ts
|
|
2230
2356
|
var toolInfo14 = {
|
|
2231
|
-
name: "
|
|
2232
|
-
description: "Request to
|
|
2357
|
+
name: "replace_in_file",
|
|
2358
|
+
description: "Request to replace sections of content in an existing file using SEARCH/REPLACE blocks that define exact changes to specific parts of the file. This tool should be used when you need to make targeted changes to specific parts of a file.",
|
|
2233
2359
|
parameters: [
|
|
2234
2360
|
{
|
|
2235
|
-
name: "
|
|
2236
|
-
description: "The
|
|
2361
|
+
name: "path",
|
|
2362
|
+
description: "The path of the file to modify",
|
|
2237
2363
|
required: true,
|
|
2238
|
-
usageValue: "
|
|
2364
|
+
usageValue: "File path here"
|
|
2239
2365
|
},
|
|
2240
2366
|
{
|
|
2241
|
-
name: "
|
|
2242
|
-
description:
|
|
2367
|
+
name: "diff",
|
|
2368
|
+
description: `One or more SEARCH/REPLACE blocks following this exact format:
|
|
2369
|
+
\`\`\`
|
|
2370
|
+
<<<<<<< SEARCH
|
|
2371
|
+
[exact content to find]
|
|
2372
|
+
=======
|
|
2373
|
+
[new content to replace with]
|
|
2374
|
+
>>>>>>> REPLACE
|
|
2375
|
+
\`\`\`
|
|
2376
|
+
Critical rules:
|
|
2377
|
+
1. SEARCH content must match the associated file section to find EXACTLY:
|
|
2378
|
+
* Match character-for-character including whitespace, indentation, line endings
|
|
2379
|
+
* Include all comments, docstrings, etc.
|
|
2380
|
+
2. SEARCH/REPLACE blocks will ONLY replace the first match occurrence.
|
|
2381
|
+
* Including multiple unique SEARCH/REPLACE blocks if you need to make multiple changes.
|
|
2382
|
+
* Include *just* enough lines in each SEARCH section to uniquely match each set of lines that need to change.
|
|
2383
|
+
* When using multiple SEARCH/REPLACE blocks, list them in the order they appear in the file.
|
|
2384
|
+
3. Keep SEARCH/REPLACE blocks concise:
|
|
2385
|
+
* Break large SEARCH/REPLACE blocks into a series of smaller blocks that each change a small portion of the file.
|
|
2386
|
+
* Include just the changing lines, and a few surrounding lines if needed for uniqueness.
|
|
2387
|
+
* Do not include long runs of unchanging lines in SEARCH/REPLACE blocks.
|
|
2388
|
+
* Each line must be complete. Never truncate lines mid-way through as this can cause matching failures.
|
|
2389
|
+
4. Special operations:
|
|
2390
|
+
* To move code: Use two SEARCH/REPLACE blocks (one to delete from original + one to insert at new location)
|
|
2391
|
+
* To delete code: Use empty REPLACE section`,
|
|
2243
2392
|
required: true,
|
|
2244
|
-
usageValue: "
|
|
2393
|
+
usageValue: "Search and replace blocks here"
|
|
2245
2394
|
}
|
|
2246
2395
|
],
|
|
2247
2396
|
examples: [
|
|
2248
2397
|
{
|
|
2249
|
-
description: "Request to
|
|
2398
|
+
description: "Request to replace sections of content in a file",
|
|
2250
2399
|
parameters: [
|
|
2251
2400
|
{
|
|
2252
|
-
name: "
|
|
2253
|
-
value: "src/
|
|
2401
|
+
name: "path",
|
|
2402
|
+
value: "src/main.js"
|
|
2254
2403
|
},
|
|
2255
2404
|
{
|
|
2256
|
-
name: "
|
|
2257
|
-
value:
|
|
2405
|
+
name: "diff",
|
|
2406
|
+
value: `
|
|
2407
|
+
<<<<<<< SEARCH
|
|
2408
|
+
import React from 'react';
|
|
2409
|
+
=======
|
|
2410
|
+
import React, { useState } from 'react';
|
|
2411
|
+
>>>>>>> REPLACE
|
|
2412
|
+
|
|
2413
|
+
<<<<<<< SEARCH
|
|
2414
|
+
function handleSubmit() {
|
|
2415
|
+
saveData();
|
|
2416
|
+
setLoading(false);
|
|
2417
|
+
}
|
|
2418
|
+
|
|
2419
|
+
=======
|
|
2420
|
+
>>>>>>> REPLACE
|
|
2421
|
+
|
|
2422
|
+
<<<<<<< SEARCH
|
|
2423
|
+
return (
|
|
2424
|
+
<div>
|
|
2425
|
+
=======
|
|
2426
|
+
function handleSubmit() {
|
|
2427
|
+
saveData();
|
|
2428
|
+
setLoading(false);
|
|
2429
|
+
}
|
|
2430
|
+
|
|
2431
|
+
return (
|
|
2432
|
+
<div>
|
|
2433
|
+
>>>>>>> REPLACE
|
|
2434
|
+
`
|
|
2258
2435
|
}
|
|
2259
2436
|
]
|
|
2260
2437
|
}
|
|
@@ -2262,24 +2439,32 @@ var toolInfo14 = {
|
|
|
2262
2439
|
permissionLevel: 2 /* Write */
|
|
2263
2440
|
};
|
|
2264
2441
|
var handler14 = async (provider, args) => {
|
|
2265
|
-
if (!provider.
|
|
2442
|
+
if (!provider.readFile || !provider.writeFile) {
|
|
2266
2443
|
return {
|
|
2267
2444
|
type: "Error" /* Error */,
|
|
2268
|
-
message: "Not possible to
|
|
2445
|
+
message: "Not possible to replace in file. Abort."
|
|
2269
2446
|
};
|
|
2270
2447
|
}
|
|
2271
|
-
const
|
|
2272
|
-
const
|
|
2273
|
-
await provider.
|
|
2448
|
+
const path = getString(args, "path");
|
|
2449
|
+
const diff = getString(args, "diff");
|
|
2450
|
+
const fileContent = await provider.readFile(path);
|
|
2451
|
+
if (fileContent == null) {
|
|
2452
|
+
return {
|
|
2453
|
+
type: "Error" /* Error */,
|
|
2454
|
+
message: `<error><replace_in_file_path>${path}</replace_in_file_path><error_message>File not found</error_message></error>`
|
|
2455
|
+
};
|
|
2456
|
+
}
|
|
2457
|
+
const result = await replaceInFile(fileContent, diff);
|
|
2458
|
+
await provider.writeFile(path, result);
|
|
2274
2459
|
return {
|
|
2275
2460
|
type: "Reply" /* Reply */,
|
|
2276
|
-
message: `<
|
|
2461
|
+
message: `<replace_in_file_path>${path}</replace_in_file_path>`
|
|
2277
2462
|
};
|
|
2278
2463
|
};
|
|
2279
2464
|
var isAvailable14 = (provider) => {
|
|
2280
|
-
return !!provider.
|
|
2465
|
+
return !!provider.readFile && !!provider.writeFile;
|
|
2281
2466
|
};
|
|
2282
|
-
var
|
|
2467
|
+
var replaceInFile_default = {
|
|
2283
2468
|
...toolInfo14,
|
|
2284
2469
|
handler: handler14,
|
|
2285
2470
|
isAvailable: isAvailable14
|
|
@@ -2713,6 +2898,9 @@ ${instance.prompt}`;
|
|
|
2713
2898
|
this.config = config;
|
|
2714
2899
|
this.#policies = policies;
|
|
2715
2900
|
}
|
|
2901
|
+
get parameters() {
|
|
2902
|
+
return this.ai.options.parameters;
|
|
2903
|
+
}
|
|
2716
2904
|
get messages() {
|
|
2717
2905
|
return this.#messages;
|
|
2718
2906
|
}
|
|
@@ -2764,6 +2952,11 @@ ${instance.prompt}`;
|
|
|
2764
2952
|
role: "user",
|
|
2765
2953
|
content: userMessage
|
|
2766
2954
|
});
|
|
2955
|
+
for (const instance of this.#policies) {
|
|
2956
|
+
if (instance.onBeforeRequest) {
|
|
2957
|
+
await instance.onBeforeRequest(this);
|
|
2958
|
+
}
|
|
2959
|
+
}
|
|
2767
2960
|
let currentAssistantMessage = "";
|
|
2768
2961
|
const retryCount = 5;
|
|
2769
2962
|
for (let i = 0; i < retryCount; i++) {
|
|
@@ -2862,7 +3055,7 @@ ${instance.prompt}`;
|
|
|
2862
3055
|
}
|
|
2863
3056
|
case "Delegate" /* Delegate */: {
|
|
2864
3057
|
if (toolResponses.length > 0) {
|
|
2865
|
-
|
|
3058
|
+
break outer;
|
|
2866
3059
|
}
|
|
2867
3060
|
const delegateResp = {
|
|
2868
3061
|
...toolResp,
|
|
@@ -3279,7 +3472,7 @@ var editingFilesPrompt = (toolNamePrefix) => `
|
|
|
3279
3472
|
|
|
3280
3473
|
EDITING FILES
|
|
3281
3474
|
|
|
3282
|
-
You have
|
|
3475
|
+
You have two file-manipulation tools: **${toolNamePrefix}write_to_file** (full overwrite) and **${toolNamePrefix}edit_file** (targeted anchor-based edits). Choose the smallest safe operation for every change.
|
|
3283
3476
|
|
|
3284
3477
|
# ${toolNamePrefix}write_to_file
|
|
3285
3478
|
|
|
@@ -3291,16 +3484,16 @@ You have access to two tools for working with files: **${toolNamePrefix}write_to
|
|
|
3291
3484
|
|
|
3292
3485
|
- Initial file creation, such as when scaffolding a new project.
|
|
3293
3486
|
- Overwriting large boilerplate files where you want to replace the entire content at once.
|
|
3294
|
-
- When the complexity or number of changes would make ${toolNamePrefix}
|
|
3487
|
+
- When the complexity or number of changes would make ${toolNamePrefix}edit_file unwieldy or error-prone.
|
|
3295
3488
|
- When you need to completely restructure a file's content or change its fundamental organization.
|
|
3296
3489
|
|
|
3297
3490
|
## Important Considerations
|
|
3298
3491
|
|
|
3299
3492
|
- Using ${toolNamePrefix}write_to_file requires providing the file's complete final content.
|
|
3300
|
-
- If you only need to make small changes to an existing file, consider using ${toolNamePrefix}
|
|
3493
|
+
- If you only need to make small changes to an existing file, consider using ${toolNamePrefix}edit_file instead to avoid unnecessarily rewriting the entire file.
|
|
3301
3494
|
- While ${toolNamePrefix}write_to_file should not be your default choice, don't hesitate to use it when the situation truly calls for it.
|
|
3302
3495
|
|
|
3303
|
-
# ${toolNamePrefix}
|
|
3496
|
+
# ${toolNamePrefix}edit_file
|
|
3304
3497
|
|
|
3305
3498
|
## Purpose
|
|
3306
3499
|
|
|
@@ -3319,10 +3512,10 @@ You have access to two tools for working with files: **${toolNamePrefix}write_to
|
|
|
3319
3512
|
|
|
3320
3513
|
# Choosing the Appropriate Tool
|
|
3321
3514
|
|
|
3322
|
-
- **Default to ${toolNamePrefix}
|
|
3515
|
+
- **Default to ${toolNamePrefix}edit_file** for most changes. It keeps diffs small and reduces risk.
|
|
3323
3516
|
- **Use ${toolNamePrefix}write_to_file** when:
|
|
3324
3517
|
- Creating new files
|
|
3325
|
-
- The changes are so extensive that using ${toolNamePrefix}
|
|
3518
|
+
- The changes are so extensive that using ${toolNamePrefix}edit_file would be more complex or risky
|
|
3326
3519
|
- You need to completely reorganize or restructure a file
|
|
3327
3520
|
- The file is relatively small and the changes affect most of its content
|
|
3328
3521
|
- You're generating boilerplate or template files
|
|
@@ -3330,11 +3523,12 @@ You have access to two tools for working with files: **${toolNamePrefix}write_to
|
|
|
3330
3523
|
# Workflow Tips
|
|
3331
3524
|
|
|
3332
3525
|
1. Before editing, assess the scope of your changes and decide which tool to use.
|
|
3333
|
-
2. For targeted edits, apply ${toolNamePrefix}
|
|
3526
|
+
2. For targeted edits, apply ${toolNamePrefix}edit_file with carefully crafted before/after text anchors. If you need multiple changes, you can stack multiple operations within a single ${toolNamePrefix}edit_file call.
|
|
3334
3527
|
3. For major overhauls or initial file creation, rely on ${toolNamePrefix}write_to_file.
|
|
3335
|
-
4. Once the file has been edited with either ${toolNamePrefix}write_to_file or ${toolNamePrefix}
|
|
3528
|
+
4. Once the file has been edited with either ${toolNamePrefix}write_to_file or ${toolNamePrefix}edit_file, the system will provide you with the final state of the modified file. Use this updated content as the reference point for any subsequent operations, since it reflects any auto-formatting or user-applied changes.
|
|
3336
3529
|
|
|
3337
|
-
|
|
3530
|
+
Picking the right tool keeps edits minimal, safe, and easy to review.
|
|
3531
|
+
`;
|
|
3338
3532
|
var rules = (toolNamePrefix) => `
|
|
3339
3533
|
====
|
|
3340
3534
|
|
|
@@ -3345,10 +3539,10 @@ RULES
|
|
|
3345
3539
|
For text files (e.g. README.md), append a footer with the same notice.
|
|
3346
3540
|
- Never describe what changed inside code comments; comments must focus on purpose or usage only.
|
|
3347
3541
|
- Before using ${toolNamePrefix}execute_command, consider SYSTEM INFORMATION to ensure commands suit the user's OS. If a command must run in a subdirectory, prepend a single \`cd childDir &&\` segment.
|
|
3348
|
-
- Use ${toolNamePrefix}search_files for broad analysis, then ${toolNamePrefix}read_file to inspect context, and finally ${toolNamePrefix}
|
|
3349
|
-
- Prefer ${toolNamePrefix}
|
|
3542
|
+
- Use ${toolNamePrefix}search_files for broad analysis, then ${toolNamePrefix}read_file to inspect context, and finally ${toolNamePrefix}edit_file or ${toolNamePrefix}write_to_file to modify.
|
|
3543
|
+
- Prefer ${toolNamePrefix}edit_file for focused edits; choose ${toolNamePrefix}write_to_file for new files or complete rewrites.
|
|
3350
3544
|
- When creating a new file, look for existing files with similar content or patterns; if found, read them and use their structure or conventions as a reference.
|
|
3351
|
-
-
|
|
3545
|
+
- Use before/after text anchors in ${toolNamePrefix}edit_file to target changes. If multiple operations are needed, list them in file order.
|
|
3352
3546
|
- Do not guess unseen content. Read existing files first unless creating new ones.
|
|
3353
3547
|
- Follow existing style, lint, and naming conventions. Ensure all changes compile and pass tests where applicable.
|
|
3354
3548
|
- ALWAYS wait for the user's confirmation after each tool call before starting the next step.
|
|
@@ -3614,6 +3808,7 @@ var configSchema = z.object({
|
|
|
3614
3808
|
}).strict();
|
|
3615
3809
|
var Policies = /* @__PURE__ */ ((Policies2) => {
|
|
3616
3810
|
Policies2["KnowledgeManagement"] = "knowledgemanagement";
|
|
3811
|
+
Policies2["TruncateContext"] = "truncatecontext";
|
|
3617
3812
|
return Policies2;
|
|
3618
3813
|
})(Policies || {});
|
|
3619
3814
|
|
|
@@ -3761,6 +3956,67 @@ var KnowledgeManagementPolicy = (tools) => {
|
|
|
3761
3956
|
};
|
|
3762
3957
|
};
|
|
3763
3958
|
|
|
3959
|
+
// src/Agent/policies/TruncateContext.ts
|
|
3960
|
+
var DEFAULT_MAX_TOKENS_ESTIMATE = 8e3;
|
|
3961
|
+
function getMaxTokens(agent) {
|
|
3962
|
+
const params = agent.parameters || {};
|
|
3963
|
+
if (params.maxTokens && typeof params.maxTokens === "number" && params.maxTokens > 0) {
|
|
3964
|
+
return params.maxTokens;
|
|
3965
|
+
}
|
|
3966
|
+
return DEFAULT_MAX_TOKENS_ESTIMATE;
|
|
3967
|
+
}
|
|
3968
|
+
function estimateTokens(text) {
|
|
3969
|
+
return Math.ceil(text.length / 4);
|
|
3970
|
+
}
|
|
3971
|
+
var TruncateContextPolicy = (tools) => {
|
|
3972
|
+
return {
|
|
3973
|
+
name: "truncatecontext" /* TruncateContext */,
|
|
3974
|
+
async onBeforeRequest(agent) {
|
|
3975
|
+
const messages = agent.messages;
|
|
3976
|
+
if (messages.length < 3) {
|
|
3977
|
+
return;
|
|
3978
|
+
}
|
|
3979
|
+
let totalTokens = 0;
|
|
3980
|
+
for (const msg of messages) {
|
|
3981
|
+
if (typeof msg.content === "string") {
|
|
3982
|
+
totalTokens += estimateTokens(msg.content);
|
|
3983
|
+
} else if (Array.isArray(msg.content)) {
|
|
3984
|
+
for (const block of msg.content) {
|
|
3985
|
+
if (typeof block === "object" && "text" in block && typeof block.text === "string") {
|
|
3986
|
+
totalTokens += estimateTokens(block.text);
|
|
3987
|
+
}
|
|
3988
|
+
}
|
|
3989
|
+
}
|
|
3990
|
+
}
|
|
3991
|
+
const maxTokens = getMaxTokens(agent);
|
|
3992
|
+
if (totalTokens <= maxTokens) {
|
|
3993
|
+
return;
|
|
3994
|
+
}
|
|
3995
|
+
const totalMessages = messages.length;
|
|
3996
|
+
const messagesToKeep = Math.ceil(totalMessages / 2);
|
|
3997
|
+
const minKeep = Math.max(2, messagesToKeep);
|
|
3998
|
+
if (minKeep >= totalMessages) {
|
|
3999
|
+
return;
|
|
4000
|
+
}
|
|
4001
|
+
const keepFromStart = Math.floor(minKeep / 2);
|
|
4002
|
+
const keepFromEnd = minKeep - keepFromStart;
|
|
4003
|
+
const startMessages = messages.slice(0, keepFromStart);
|
|
4004
|
+
const endMessages = messages.slice(-keepFromEnd);
|
|
4005
|
+
const truncatedCount = totalMessages - minKeep;
|
|
4006
|
+
const truncatedMessages = [
|
|
4007
|
+
...startMessages,
|
|
4008
|
+
// Add a message explaining truncation
|
|
4009
|
+
{
|
|
4010
|
+
role: "user",
|
|
4011
|
+
content: `Note: ${truncatedCount} messages were truncated from the middle to prevent context overflow.`
|
|
4012
|
+
},
|
|
4013
|
+
...endMessages
|
|
4014
|
+
];
|
|
4015
|
+
agent.setMessages(truncatedMessages);
|
|
4016
|
+
}
|
|
4017
|
+
};
|
|
4018
|
+
};
|
|
4019
|
+
|
|
3764
4020
|
// src/Agent/index.ts
|
|
3765
4021
|
var allAgents = [architectAgentInfo, coderAgentInfo, analyzerAgentInfo, codeFixerAgentInfo];
|
|
3766
4022
|
|
|
@@ -4159,6 +4415,7 @@ export {
|
|
|
4159
4415
|
Policies,
|
|
4160
4416
|
TaskEventKind,
|
|
4161
4417
|
ToolResponseType,
|
|
4418
|
+
TruncateContextPolicy,
|
|
4162
4419
|
UsageMeter,
|
|
4163
4420
|
agentsPrompt,
|
|
4164
4421
|
allAgents,
|
|
@@ -4181,6 +4438,8 @@ export {
|
|
|
4181
4438
|
deepSeekModels,
|
|
4182
4439
|
defaultModels,
|
|
4183
4440
|
delegate_default as delegate,
|
|
4441
|
+
editFile_default as editFile,
|
|
4442
|
+
editFile as editFileHelper,
|
|
4184
4443
|
executeAgentTool,
|
|
4185
4444
|
executeCommand_default as executeCommand,
|
|
4186
4445
|
executeTool,
|
|
@@ -4194,7 +4453,6 @@ export {
|
|
|
4194
4453
|
getString,
|
|
4195
4454
|
getStringArray,
|
|
4196
4455
|
handOver_default as handOver,
|
|
4197
|
-
listCodeDefinitionNames_default as listCodeDefinitionNames,
|
|
4198
4456
|
listFiles_default as listFiles,
|
|
4199
4457
|
makeAgentTool,
|
|
4200
4458
|
makeTool,
|