@polka-codes/core 0.8.11 → 0.8.13
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 +616 -304
- package/dist/index.d.ts +4 -1
- package/dist/index.js +542 -235
- 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
|
}
|
|
@@ -893,13 +895,13 @@ __export(allTools_exports, {
|
|
|
893
895
|
askFollowupQuestion: () => askFollowupQuestion_default,
|
|
894
896
|
attemptCompletion: () => attemptCompletion_default,
|
|
895
897
|
delegate: () => delegate_default,
|
|
898
|
+
editFile: () => editFile_default,
|
|
896
899
|
executeCommand: () => executeCommand_default,
|
|
897
900
|
handOver: () => handOver_default,
|
|
898
901
|
listFiles: () => listFiles_default,
|
|
899
902
|
readFile: () => readFile_default,
|
|
900
903
|
removeFile: () => removeFile_default,
|
|
901
904
|
renameFile: () => renameFile_default,
|
|
902
|
-
replaceInFile: () => replaceInFile_default,
|
|
903
905
|
searchFiles: () => searchFiles_default,
|
|
904
906
|
updateKnowledge: () => updateKnowledge_default,
|
|
905
907
|
writeToFile: () => writeToFile_default
|
|
@@ -925,61 +927,85 @@ var ToolResponseType = /* @__PURE__ */ ((ToolResponseType2) => {
|
|
|
925
927
|
return ToolResponseType2;
|
|
926
928
|
})(ToolResponseType || {});
|
|
927
929
|
|
|
928
|
-
// src/tools/utils/
|
|
929
|
-
var
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
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");
|
|
934
936
|
}
|
|
935
|
-
|
|
936
|
-
|
|
937
|
+
const originalLines = fileContent.split("\n");
|
|
938
|
+
let updatedContent = fileContent;
|
|
939
|
+
for (const operation of operations) {
|
|
940
|
+
updatedContent = await applyEditOperation(updatedContent, operation, originalLines);
|
|
937
941
|
}
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
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;
|
|
942
952
|
}
|
|
943
|
-
const
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
if (
|
|
948
|
-
|
|
949
|
-
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;
|
|
950
959
|
}
|
|
951
|
-
const
|
|
952
|
-
const
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
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;
|
|
968
993
|
}
|
|
969
|
-
const strippedSearch = trimmedSearch.replace(/\s+/g, "");
|
|
970
|
-
const endPos = actualPos;
|
|
971
|
-
const startPos = endPos - strippedSearch.length;
|
|
972
|
-
return content.slice(0, startPos) + replace + content.slice(endPos);
|
|
973
994
|
}
|
|
974
|
-
throw new Error(`Could not find the following text in file:
|
|
975
|
-
${search}`);
|
|
976
|
-
};
|
|
977
|
-
let updatedFile = fileContent;
|
|
978
|
-
for (const { search, replace } of blocks) {
|
|
979
|
-
updatedFile = findAndReplace(updatedFile, search, replace);
|
|
980
995
|
}
|
|
981
|
-
|
|
982
|
-
|
|
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
|
+
}
|
|
983
1009
|
|
|
984
1010
|
// src/tools/utils/getArg.ts
|
|
985
1011
|
var getString = (args, name, defaultValue) => {
|
|
@@ -1073,6 +1099,62 @@ var getArray = (args, name, defaultValue) => {
|
|
|
1073
1099
|
return [ret];
|
|
1074
1100
|
};
|
|
1075
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
|
+
|
|
1076
1158
|
// src/tools/askFollowupQuestion.ts
|
|
1077
1159
|
var toolInfo = {
|
|
1078
1160
|
name: "ask_followup_question",
|
|
@@ -1319,11 +1401,11 @@ var delegate_default = {
|
|
|
1319
1401
|
// src/tools/executeCommand.ts
|
|
1320
1402
|
var toolInfo4 = {
|
|
1321
1403
|
name: "execute_command",
|
|
1322
|
-
description: "Run a single CLI command. The command is always executed in the project-root working directory (regardless of earlier commands). Prefer one-off shell commands over wrapper scripts for flexibility. After an `execute_command` call,
|
|
1404
|
+
description: "Run a single CLI command. The command is always executed in the project-root working directory (regardless of earlier commands). Prefer one-off shell commands over wrapper scripts for flexibility. **IMPORTANT**: After an `execute_command` call, you MUST stop and NOT allowed to make further tool calls in the same message.",
|
|
1323
1405
|
parameters: [
|
|
1324
1406
|
{
|
|
1325
1407
|
name: "command",
|
|
1326
|
-
description: "The exact command to run
|
|
1408
|
+
description: "The exact command to run (valid for the current OS). It must be correctly formatted and free of harmful instructions.",
|
|
1327
1409
|
required: true,
|
|
1328
1410
|
usageValue: "your-command-here"
|
|
1329
1411
|
},
|
|
@@ -1523,126 +1605,8 @@ var readFile_default = {
|
|
|
1523
1605
|
isAvailable: isAvailable6
|
|
1524
1606
|
};
|
|
1525
1607
|
|
|
1526
|
-
// src/tools/replaceInFile.ts
|
|
1527
|
-
var toolInfo7 = {
|
|
1528
|
-
name: "replace_in_file",
|
|
1529
|
-
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.",
|
|
1530
|
-
parameters: [
|
|
1531
|
-
{
|
|
1532
|
-
name: "path",
|
|
1533
|
-
description: "The path of the file to modify",
|
|
1534
|
-
required: true,
|
|
1535
|
-
usageValue: "File path here"
|
|
1536
|
-
},
|
|
1537
|
-
{
|
|
1538
|
-
name: "diff",
|
|
1539
|
-
description: `One or more SEARCH/REPLACE blocks following this exact format:
|
|
1540
|
-
\`\`\`
|
|
1541
|
-
<<<<<<< SEARCH
|
|
1542
|
-
[exact content to find]
|
|
1543
|
-
=======
|
|
1544
|
-
[new content to replace with]
|
|
1545
|
-
>>>>>>> REPLACE
|
|
1546
|
-
\`\`\`
|
|
1547
|
-
Critical rules:
|
|
1548
|
-
1. SEARCH content must match the associated file section to find EXACTLY:
|
|
1549
|
-
* Match character-for-character including whitespace, indentation, line endings
|
|
1550
|
-
* Include all comments, docstrings, etc.
|
|
1551
|
-
2. SEARCH/REPLACE blocks will ONLY replace the first match occurrence.
|
|
1552
|
-
* Including multiple unique SEARCH/REPLACE blocks if you need to make multiple changes.
|
|
1553
|
-
* Include *just* enough lines in each SEARCH section to uniquely match each set of lines that need to change.
|
|
1554
|
-
* When using multiple SEARCH/REPLACE blocks, list them in the order they appear in the file.
|
|
1555
|
-
3. Keep SEARCH/REPLACE blocks concise:
|
|
1556
|
-
* Break large SEARCH/REPLACE blocks into a series of smaller blocks that each change a small portion of the file.
|
|
1557
|
-
* Include just the changing lines, and a few surrounding lines if needed for uniqueness.
|
|
1558
|
-
* Do not include long runs of unchanging lines in SEARCH/REPLACE blocks.
|
|
1559
|
-
* Each line must be complete. Never truncate lines mid-way through as this can cause matching failures.
|
|
1560
|
-
4. Special operations:
|
|
1561
|
-
* To move code: Use two SEARCH/REPLACE blocks (one to delete from original + one to insert at new location)
|
|
1562
|
-
* To delete code: Use empty REPLACE section`,
|
|
1563
|
-
required: true,
|
|
1564
|
-
usageValue: "Search and replace blocks here"
|
|
1565
|
-
}
|
|
1566
|
-
],
|
|
1567
|
-
examples: [
|
|
1568
|
-
{
|
|
1569
|
-
description: "Request to replace sections of content in a file",
|
|
1570
|
-
parameters: [
|
|
1571
|
-
{
|
|
1572
|
-
name: "path",
|
|
1573
|
-
value: "src/main.js"
|
|
1574
|
-
},
|
|
1575
|
-
{
|
|
1576
|
-
name: "diff",
|
|
1577
|
-
value: `
|
|
1578
|
-
<<<<<<< SEARCH
|
|
1579
|
-
import React from 'react';
|
|
1580
|
-
=======
|
|
1581
|
-
import React, { useState } from 'react';
|
|
1582
|
-
>>>>>>> REPLACE
|
|
1583
|
-
|
|
1584
|
-
<<<<<<< SEARCH
|
|
1585
|
-
function handleSubmit() {
|
|
1586
|
-
saveData();
|
|
1587
|
-
setLoading(false);
|
|
1588
|
-
}
|
|
1589
|
-
|
|
1590
|
-
=======
|
|
1591
|
-
>>>>>>> REPLACE
|
|
1592
|
-
|
|
1593
|
-
<<<<<<< SEARCH
|
|
1594
|
-
return (
|
|
1595
|
-
<div>
|
|
1596
|
-
=======
|
|
1597
|
-
function handleSubmit() {
|
|
1598
|
-
saveData();
|
|
1599
|
-
setLoading(false);
|
|
1600
|
-
}
|
|
1601
|
-
|
|
1602
|
-
return (
|
|
1603
|
-
<div>
|
|
1604
|
-
>>>>>>> REPLACE
|
|
1605
|
-
`
|
|
1606
|
-
}
|
|
1607
|
-
]
|
|
1608
|
-
}
|
|
1609
|
-
],
|
|
1610
|
-
permissionLevel: 2 /* Write */
|
|
1611
|
-
};
|
|
1612
|
-
var handler7 = async (provider, args) => {
|
|
1613
|
-
if (!provider.readFile || !provider.writeFile) {
|
|
1614
|
-
return {
|
|
1615
|
-
type: "Error" /* Error */,
|
|
1616
|
-
message: "Not possible to replace in file. Abort."
|
|
1617
|
-
};
|
|
1618
|
-
}
|
|
1619
|
-
const path = getString(args, "path");
|
|
1620
|
-
const diff = getString(args, "diff");
|
|
1621
|
-
const fileContent = await provider.readFile(path);
|
|
1622
|
-
if (fileContent == null) {
|
|
1623
|
-
return {
|
|
1624
|
-
type: "Error" /* Error */,
|
|
1625
|
-
message: `<error><replace_in_file_path>${path}</replace_in_file_path><error_message>File not found</error_message></error>`
|
|
1626
|
-
};
|
|
1627
|
-
}
|
|
1628
|
-
const result = await replaceInFile(fileContent, diff);
|
|
1629
|
-
await provider.writeFile(path, result);
|
|
1630
|
-
return {
|
|
1631
|
-
type: "Reply" /* Reply */,
|
|
1632
|
-
message: `<replace_in_file_path>${path}</replace_in_file_path>`
|
|
1633
|
-
};
|
|
1634
|
-
};
|
|
1635
|
-
var isAvailable7 = (provider) => {
|
|
1636
|
-
return !!provider.readFile && !!provider.writeFile;
|
|
1637
|
-
};
|
|
1638
|
-
var replaceInFile_default = {
|
|
1639
|
-
...toolInfo7,
|
|
1640
|
-
handler: handler7,
|
|
1641
|
-
isAvailable: isAvailable7
|
|
1642
|
-
};
|
|
1643
|
-
|
|
1644
1608
|
// src/tools/searchFiles.ts
|
|
1645
|
-
var
|
|
1609
|
+
var toolInfo7 = {
|
|
1646
1610
|
name: "search_files",
|
|
1647
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.",
|
|
1648
1612
|
parameters: [
|
|
@@ -1686,7 +1650,7 @@ var toolInfo8 = {
|
|
|
1686
1650
|
],
|
|
1687
1651
|
permissionLevel: 1 /* Read */
|
|
1688
1652
|
};
|
|
1689
|
-
var
|
|
1653
|
+
var handler7 = async (provider, args) => {
|
|
1690
1654
|
if (!provider.searchFiles) {
|
|
1691
1655
|
return {
|
|
1692
1656
|
type: "Error" /* Error */,
|
|
@@ -1708,19 +1672,19 @@ ${files.join("\n")}
|
|
|
1708
1672
|
`
|
|
1709
1673
|
};
|
|
1710
1674
|
};
|
|
1711
|
-
var
|
|
1675
|
+
var isAvailable7 = (provider) => {
|
|
1712
1676
|
return !!provider.searchFiles;
|
|
1713
1677
|
};
|
|
1714
1678
|
var searchFiles_default = {
|
|
1715
|
-
...
|
|
1716
|
-
handler:
|
|
1717
|
-
isAvailable:
|
|
1679
|
+
...toolInfo7,
|
|
1680
|
+
handler: handler7,
|
|
1681
|
+
isAvailable: isAvailable7
|
|
1718
1682
|
};
|
|
1719
1683
|
|
|
1720
1684
|
// src/tools/updateKnowledge.ts
|
|
1721
1685
|
import { join } from "node:path";
|
|
1722
1686
|
import YAML from "yaml";
|
|
1723
|
-
var
|
|
1687
|
+
var toolInfo8 = {
|
|
1724
1688
|
name: "update_knowledge",
|
|
1725
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.",
|
|
1726
1690
|
parameters: [
|
|
@@ -1894,7 +1858,7 @@ function deepMerge(target, source) {
|
|
|
1894
1858
|
}
|
|
1895
1859
|
return output;
|
|
1896
1860
|
}
|
|
1897
|
-
var
|
|
1861
|
+
var handler8 = async (provider, args) => {
|
|
1898
1862
|
if (!provider.readFile || !provider.writeFile) {
|
|
1899
1863
|
return {
|
|
1900
1864
|
type: "Error" /* Error */,
|
|
@@ -1966,17 +1930,17 @@ var handler9 = async (provider, args) => {
|
|
|
1966
1930
|
};
|
|
1967
1931
|
}
|
|
1968
1932
|
};
|
|
1969
|
-
var
|
|
1933
|
+
var isAvailable8 = (provider) => {
|
|
1970
1934
|
return !!provider.readFile && !!provider.writeFile;
|
|
1971
1935
|
};
|
|
1972
1936
|
var updateKnowledge_default = {
|
|
1973
|
-
...
|
|
1974
|
-
handler:
|
|
1975
|
-
isAvailable:
|
|
1937
|
+
...toolInfo8,
|
|
1938
|
+
handler: handler8,
|
|
1939
|
+
isAvailable: isAvailable8
|
|
1976
1940
|
};
|
|
1977
1941
|
|
|
1978
1942
|
// src/tools/writeToFile.ts
|
|
1979
|
-
var
|
|
1943
|
+
var toolInfo9 = {
|
|
1980
1944
|
name: "write_to_file",
|
|
1981
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 `>`.",
|
|
1982
1946
|
parameters: [
|
|
@@ -2021,7 +1985,7 @@ export default App;
|
|
|
2021
1985
|
],
|
|
2022
1986
|
permissionLevel: 2 /* Write */
|
|
2023
1987
|
};
|
|
2024
|
-
var
|
|
1988
|
+
var handler9 = async (provider, args) => {
|
|
2025
1989
|
if (!provider.writeFile) {
|
|
2026
1990
|
return {
|
|
2027
1991
|
type: "Error" /* Error */,
|
|
@@ -2036,17 +2000,17 @@ var handler10 = async (provider, args) => {
|
|
|
2036
2000
|
message: `<write_to_file_path>${path}</write_to_file_path><status>Success</status>`
|
|
2037
2001
|
};
|
|
2038
2002
|
};
|
|
2039
|
-
var
|
|
2003
|
+
var isAvailable9 = (provider) => {
|
|
2040
2004
|
return !!provider.writeFile;
|
|
2041
2005
|
};
|
|
2042
2006
|
var writeToFile_default = {
|
|
2043
|
-
...
|
|
2044
|
-
handler:
|
|
2045
|
-
isAvailable:
|
|
2007
|
+
...toolInfo9,
|
|
2008
|
+
handler: handler9,
|
|
2009
|
+
isAvailable: isAvailable9
|
|
2046
2010
|
};
|
|
2047
2011
|
|
|
2048
2012
|
// src/tools/handOver.ts
|
|
2049
|
-
var
|
|
2013
|
+
var toolInfo10 = {
|
|
2050
2014
|
name: "hand_over",
|
|
2051
2015
|
description: "Hand over the current task to another agent to complete. This tool MUST NOT to be used with any other tool.",
|
|
2052
2016
|
parameters: [
|
|
@@ -2100,7 +2064,7 @@ var toolInfo11 = {
|
|
|
2100
2064
|
],
|
|
2101
2065
|
permissionLevel: 0 /* None */
|
|
2102
2066
|
};
|
|
2103
|
-
var
|
|
2067
|
+
var handler10 = async (_provider, args) => {
|
|
2104
2068
|
const agentName = getString(args, "agent_name");
|
|
2105
2069
|
const task = getString(args, "task");
|
|
2106
2070
|
const context = getString(args, "context", void 0);
|
|
@@ -2114,17 +2078,17 @@ var handler11 = async (_provider, args) => {
|
|
|
2114
2078
|
// originalTask will be set by AgentBase
|
|
2115
2079
|
};
|
|
2116
2080
|
};
|
|
2117
|
-
var
|
|
2081
|
+
var isAvailable10 = (_provider) => {
|
|
2118
2082
|
return true;
|
|
2119
2083
|
};
|
|
2120
2084
|
var handOver_default = {
|
|
2121
|
-
...
|
|
2122
|
-
handler:
|
|
2123
|
-
isAvailable:
|
|
2085
|
+
...toolInfo10,
|
|
2086
|
+
handler: handler10,
|
|
2087
|
+
isAvailable: isAvailable10
|
|
2124
2088
|
};
|
|
2125
2089
|
|
|
2126
2090
|
// src/tools/removeFile.ts
|
|
2127
|
-
var
|
|
2091
|
+
var toolInfo11 = {
|
|
2128
2092
|
name: "remove_file",
|
|
2129
2093
|
description: "Request to remove a file at the specified path.",
|
|
2130
2094
|
parameters: [
|
|
@@ -2148,7 +2112,7 @@ var toolInfo12 = {
|
|
|
2148
2112
|
],
|
|
2149
2113
|
permissionLevel: 2 /* Write */
|
|
2150
2114
|
};
|
|
2151
|
-
var
|
|
2115
|
+
var handler11 = async (provider, args) => {
|
|
2152
2116
|
if (!provider.removeFile) {
|
|
2153
2117
|
return {
|
|
2154
2118
|
type: "Error" /* Error */,
|
|
@@ -2162,28 +2126,28 @@ var handler12 = async (provider, args) => {
|
|
|
2162
2126
|
message: `<remove_file_path>${path}</remove_file_path><status>Success</status>`
|
|
2163
2127
|
};
|
|
2164
2128
|
};
|
|
2165
|
-
var
|
|
2129
|
+
var isAvailable11 = (provider) => {
|
|
2166
2130
|
return !!provider.removeFile;
|
|
2167
2131
|
};
|
|
2168
2132
|
var removeFile_default = {
|
|
2169
|
-
...
|
|
2170
|
-
handler:
|
|
2171
|
-
isAvailable:
|
|
2133
|
+
...toolInfo11,
|
|
2134
|
+
handler: handler11,
|
|
2135
|
+
isAvailable: isAvailable11
|
|
2172
2136
|
};
|
|
2173
2137
|
|
|
2174
2138
|
// src/tools/renameFile.ts
|
|
2175
|
-
var
|
|
2139
|
+
var toolInfo12 = {
|
|
2176
2140
|
name: "rename_file",
|
|
2177
2141
|
description: "Request to rename a file from source path to target path.",
|
|
2178
2142
|
parameters: [
|
|
2179
2143
|
{
|
|
2180
|
-
name: "
|
|
2144
|
+
name: "source_path",
|
|
2181
2145
|
description: "The current path of the file",
|
|
2182
2146
|
required: true,
|
|
2183
2147
|
usageValue: "Source file path here"
|
|
2184
2148
|
},
|
|
2185
2149
|
{
|
|
2186
|
-
name: "
|
|
2150
|
+
name: "target_path",
|
|
2187
2151
|
description: "The new path for the file",
|
|
2188
2152
|
required: true,
|
|
2189
2153
|
usageValue: "Target file path here"
|
|
@@ -2194,11 +2158,11 @@ var toolInfo13 = {
|
|
|
2194
2158
|
description: "Request to rename a file",
|
|
2195
2159
|
parameters: [
|
|
2196
2160
|
{
|
|
2197
|
-
name: "
|
|
2161
|
+
name: "source_path",
|
|
2198
2162
|
value: "src/old-name.js"
|
|
2199
2163
|
},
|
|
2200
2164
|
{
|
|
2201
|
-
name: "
|
|
2165
|
+
name: "target_path",
|
|
2202
2166
|
value: "src/new-name.js"
|
|
2203
2167
|
}
|
|
2204
2168
|
]
|
|
@@ -2206,30 +2170,306 @@ var toolInfo13 = {
|
|
|
2206
2170
|
],
|
|
2207
2171
|
permissionLevel: 2 /* Write */
|
|
2208
2172
|
};
|
|
2209
|
-
var
|
|
2173
|
+
var handler12 = async (provider, args) => {
|
|
2210
2174
|
if (!provider.renameFile) {
|
|
2211
2175
|
return {
|
|
2212
2176
|
type: "Error" /* Error */,
|
|
2213
2177
|
message: "Not possible to rename file. Abort."
|
|
2214
2178
|
};
|
|
2215
2179
|
}
|
|
2216
|
-
const sourcePath = getString(args, "
|
|
2217
|
-
const targetPath = getString(args, "
|
|
2180
|
+
const sourcePath = getString(args, "source_path");
|
|
2181
|
+
const targetPath = getString(args, "target_path");
|
|
2218
2182
|
await provider.renameFile(sourcePath, targetPath);
|
|
2219
2183
|
return {
|
|
2220
2184
|
type: "Reply" /* Reply */,
|
|
2221
2185
|
message: `<rename_file_path>${targetPath}</rename_file_path><status>Success</status>`
|
|
2222
2186
|
};
|
|
2223
2187
|
};
|
|
2224
|
-
var
|
|
2188
|
+
var isAvailable12 = (provider) => {
|
|
2225
2189
|
return !!provider.renameFile;
|
|
2226
2190
|
};
|
|
2227
2191
|
var renameFile_default = {
|
|
2192
|
+
...toolInfo12,
|
|
2193
|
+
handler: handler12,
|
|
2194
|
+
isAvailable: isAvailable12
|
|
2195
|
+
};
|
|
2196
|
+
|
|
2197
|
+
// src/tools/editFile.ts
|
|
2198
|
+
var toolInfo13 = {
|
|
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.",
|
|
2201
|
+
parameters: [
|
|
2202
|
+
{
|
|
2203
|
+
name: "path",
|
|
2204
|
+
description: "The path of the file to edit",
|
|
2205
|
+
required: true,
|
|
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"
|
|
2246
|
+
}
|
|
2247
|
+
],
|
|
2248
|
+
examples: [
|
|
2249
|
+
{
|
|
2250
|
+
description: "Replace content between two text anchors",
|
|
2251
|
+
parameters: [
|
|
2252
|
+
{
|
|
2253
|
+
name: "path",
|
|
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
|
+
]
|
|
2304
|
+
}
|
|
2305
|
+
]
|
|
2306
|
+
}
|
|
2307
|
+
],
|
|
2308
|
+
permissionLevel: 2 /* Write */
|
|
2309
|
+
};
|
|
2310
|
+
var handler13 = async (provider, args) => {
|
|
2311
|
+
if (!provider.readFile || !provider.writeFile) {
|
|
2312
|
+
return {
|
|
2313
|
+
type: "Error" /* Error */,
|
|
2314
|
+
message: "Not possible to edit file. Abort."
|
|
2315
|
+
};
|
|
2316
|
+
}
|
|
2317
|
+
const path = getString(args, "path");
|
|
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
|
+
}
|
|
2345
|
+
};
|
|
2346
|
+
var isAvailable13 = (provider) => {
|
|
2347
|
+
return !!provider.readFile && !!provider.writeFile;
|
|
2348
|
+
};
|
|
2349
|
+
var editFile_default = {
|
|
2228
2350
|
...toolInfo13,
|
|
2229
2351
|
handler: handler13,
|
|
2230
2352
|
isAvailable: isAvailable13
|
|
2231
2353
|
};
|
|
2232
2354
|
|
|
2355
|
+
// src/tools/replaceInFile.ts
|
|
2356
|
+
var toolInfo14 = {
|
|
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.",
|
|
2359
|
+
parameters: [
|
|
2360
|
+
{
|
|
2361
|
+
name: "path",
|
|
2362
|
+
description: "The path of the file to modify",
|
|
2363
|
+
required: true,
|
|
2364
|
+
usageValue: "File path here"
|
|
2365
|
+
},
|
|
2366
|
+
{
|
|
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`,
|
|
2392
|
+
required: true,
|
|
2393
|
+
usageValue: "Search and replace blocks here"
|
|
2394
|
+
}
|
|
2395
|
+
],
|
|
2396
|
+
examples: [
|
|
2397
|
+
{
|
|
2398
|
+
description: "Request to replace sections of content in a file",
|
|
2399
|
+
parameters: [
|
|
2400
|
+
{
|
|
2401
|
+
name: "path",
|
|
2402
|
+
value: "src/main.js"
|
|
2403
|
+
},
|
|
2404
|
+
{
|
|
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
|
+
`
|
|
2435
|
+
}
|
|
2436
|
+
]
|
|
2437
|
+
}
|
|
2438
|
+
],
|
|
2439
|
+
permissionLevel: 2 /* Write */
|
|
2440
|
+
};
|
|
2441
|
+
var handler14 = async (provider, args) => {
|
|
2442
|
+
if (!provider.readFile || !provider.writeFile) {
|
|
2443
|
+
return {
|
|
2444
|
+
type: "Error" /* Error */,
|
|
2445
|
+
message: "Not possible to replace in file. Abort."
|
|
2446
|
+
};
|
|
2447
|
+
}
|
|
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);
|
|
2459
|
+
return {
|
|
2460
|
+
type: "Reply" /* Reply */,
|
|
2461
|
+
message: `<replace_in_file_path>${path}</replace_in_file_path>`
|
|
2462
|
+
};
|
|
2463
|
+
};
|
|
2464
|
+
var isAvailable14 = (provider) => {
|
|
2465
|
+
return !!provider.readFile && !!provider.writeFile;
|
|
2466
|
+
};
|
|
2467
|
+
var replaceInFile_default = {
|
|
2468
|
+
...toolInfo14,
|
|
2469
|
+
handler: handler14,
|
|
2470
|
+
isAvailable: isAvailable14
|
|
2471
|
+
};
|
|
2472
|
+
|
|
2233
2473
|
// src/getAvailableTools.ts
|
|
2234
2474
|
var getAvailableTools = ({
|
|
2235
2475
|
provider,
|
|
@@ -2438,7 +2678,7 @@ var toolUsePrompt = (tools, toolNamePrefix) => {
|
|
|
2438
2678
|
|
|
2439
2679
|
TOOL USE
|
|
2440
2680
|
|
|
2441
|
-
You have access to a set of tools that are executed upon the user's approval. You can use
|
|
2681
|
+
You have access to a set of tools that are executed upon the user's approval. You can use up to 5 tool calls per message, and will receive the results of those tool uses in the user's response. You use tools step-by-step to accomplish a given task, with each tool use informed by the result of the previous tool use.
|
|
2442
2682
|
|
|
2443
2683
|
# Tool Use Formatting
|
|
2444
2684
|
|
|
@@ -2503,18 +2743,16 @@ ${tools.map((tool) => {
|
|
|
2503
2743
|
|
|
2504
2744
|
1. **Outline Your Thought Process**
|
|
2505
2745
|
- Before using a tool, wrap your reasoning inside \`<thinking>\` tags. Be concise\u2014just enough to clarify your plan and the rationale behind selecting a specific tool.
|
|
2506
|
-
|
|
2507
2746
|
2. **Wait for Feedback**
|
|
2508
2747
|
- After using a tool, wait for the user's response indicating success/failure or any output logs. Do not assume the result of a tool without explicit confirmation.
|
|
2509
|
-
|
|
2510
2748
|
3. **Error Handling**
|
|
2511
2749
|
- If a tool fails or produces an unexpected result, analyze the error, decide on an alternative approach or tool, and proceed carefully.
|
|
2512
|
-
|
|
2513
2750
|
4. **Avoid Repetition**
|
|
2514
2751
|
- Do not quote or repeat previous commands or prompts verbatim. Move the conversation forward by focusing on the latest required action.
|
|
2515
|
-
|
|
2516
2752
|
5. **No Unnecessary Re-invocations**
|
|
2517
|
-
- Only invoke the same tool again if a genuine need arises (e.g., different parameters or updated context)
|
|
2753
|
+
- Only invoke the same tool again if a genuine need arises (e.g., different parameters or updated context).
|
|
2754
|
+
6. **Tool Call Limit**
|
|
2755
|
+
- Do not make more than 5 tool calls in a single message.`;
|
|
2518
2756
|
};
|
|
2519
2757
|
var agentsPrompt = (agents, name) => `
|
|
2520
2758
|
====
|
|
@@ -2658,6 +2896,9 @@ ${instance.prompt}`;
|
|
|
2658
2896
|
this.config = config;
|
|
2659
2897
|
this.#policies = policies;
|
|
2660
2898
|
}
|
|
2899
|
+
get parameters() {
|
|
2900
|
+
return this.ai.options.parameters;
|
|
2901
|
+
}
|
|
2661
2902
|
get messages() {
|
|
2662
2903
|
return this.#messages;
|
|
2663
2904
|
}
|
|
@@ -2851,8 +3092,8 @@ ${instance.prompt}`;
|
|
|
2851
3092
|
}
|
|
2852
3093
|
async #invokeTool(name, args) {
|
|
2853
3094
|
try {
|
|
2854
|
-
const
|
|
2855
|
-
if (!
|
|
3095
|
+
const handler15 = this.handlers[name]?.handler;
|
|
3096
|
+
if (!handler15) {
|
|
2856
3097
|
return {
|
|
2857
3098
|
type: "Error" /* Error */,
|
|
2858
3099
|
message: responsePrompts.errorInvokeTool(name, "Tool not found"),
|
|
@@ -2871,7 +3112,7 @@ ${instance.prompt}`;
|
|
|
2871
3112
|
if (resp) {
|
|
2872
3113
|
return resp;
|
|
2873
3114
|
}
|
|
2874
|
-
return await
|
|
3115
|
+
return await handler15(this.config.provider, args);
|
|
2875
3116
|
} catch (error) {
|
|
2876
3117
|
return {
|
|
2877
3118
|
type: "Error" /* Error */,
|
|
@@ -3229,7 +3470,7 @@ var editingFilesPrompt = (toolNamePrefix) => `
|
|
|
3229
3470
|
|
|
3230
3471
|
EDITING FILES
|
|
3231
3472
|
|
|
3232
|
-
You have
|
|
3473
|
+
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.
|
|
3233
3474
|
|
|
3234
3475
|
# ${toolNamePrefix}write_to_file
|
|
3235
3476
|
|
|
@@ -3241,16 +3482,16 @@ You have access to two tools for working with files: **${toolNamePrefix}write_to
|
|
|
3241
3482
|
|
|
3242
3483
|
- Initial file creation, such as when scaffolding a new project.
|
|
3243
3484
|
- Overwriting large boilerplate files where you want to replace the entire content at once.
|
|
3244
|
-
- When the complexity or number of changes would make ${toolNamePrefix}
|
|
3485
|
+
- When the complexity or number of changes would make ${toolNamePrefix}edit_file unwieldy or error-prone.
|
|
3245
3486
|
- When you need to completely restructure a file's content or change its fundamental organization.
|
|
3246
3487
|
|
|
3247
3488
|
## Important Considerations
|
|
3248
3489
|
|
|
3249
3490
|
- Using ${toolNamePrefix}write_to_file requires providing the file's complete final content.
|
|
3250
|
-
- If you only need to make small changes to an existing file, consider using ${toolNamePrefix}
|
|
3491
|
+
- 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.
|
|
3251
3492
|
- While ${toolNamePrefix}write_to_file should not be your default choice, don't hesitate to use it when the situation truly calls for it.
|
|
3252
3493
|
|
|
3253
|
-
# ${toolNamePrefix}
|
|
3494
|
+
# ${toolNamePrefix}edit_file
|
|
3254
3495
|
|
|
3255
3496
|
## Purpose
|
|
3256
3497
|
|
|
@@ -3269,10 +3510,10 @@ You have access to two tools for working with files: **${toolNamePrefix}write_to
|
|
|
3269
3510
|
|
|
3270
3511
|
# Choosing the Appropriate Tool
|
|
3271
3512
|
|
|
3272
|
-
- **Default to ${toolNamePrefix}
|
|
3513
|
+
- **Default to ${toolNamePrefix}edit_file** for most changes. It keeps diffs small and reduces risk.
|
|
3273
3514
|
- **Use ${toolNamePrefix}write_to_file** when:
|
|
3274
3515
|
- Creating new files
|
|
3275
|
-
- The changes are so extensive that using ${toolNamePrefix}
|
|
3516
|
+
- The changes are so extensive that using ${toolNamePrefix}edit_file would be more complex or risky
|
|
3276
3517
|
- You need to completely reorganize or restructure a file
|
|
3277
3518
|
- The file is relatively small and the changes affect most of its content
|
|
3278
3519
|
- You're generating boilerplate or template files
|
|
@@ -3280,11 +3521,12 @@ You have access to two tools for working with files: **${toolNamePrefix}write_to
|
|
|
3280
3521
|
# Workflow Tips
|
|
3281
3522
|
|
|
3282
3523
|
1. Before editing, assess the scope of your changes and decide which tool to use.
|
|
3283
|
-
2. For targeted edits, apply ${toolNamePrefix}
|
|
3524
|
+
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.
|
|
3284
3525
|
3. For major overhauls or initial file creation, rely on ${toolNamePrefix}write_to_file.
|
|
3285
|
-
4. Once the file has been edited with either ${toolNamePrefix}write_to_file or ${toolNamePrefix}
|
|
3526
|
+
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.
|
|
3286
3527
|
|
|
3287
|
-
|
|
3528
|
+
Picking the right tool keeps edits minimal, safe, and easy to review.
|
|
3529
|
+
`;
|
|
3288
3530
|
var rules = (toolNamePrefix) => `
|
|
3289
3531
|
====
|
|
3290
3532
|
|
|
@@ -3295,10 +3537,10 @@ RULES
|
|
|
3295
3537
|
For text files (e.g. README.md), append a footer with the same notice.
|
|
3296
3538
|
- Never describe what changed inside code comments; comments must focus on purpose or usage only.
|
|
3297
3539
|
- 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.
|
|
3298
|
-
- Use ${toolNamePrefix}search_files for broad analysis, then ${toolNamePrefix}read_file to inspect context, and finally ${toolNamePrefix}
|
|
3299
|
-
- Prefer ${toolNamePrefix}
|
|
3540
|
+
- 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.
|
|
3541
|
+
- Prefer ${toolNamePrefix}edit_file for focused edits; choose ${toolNamePrefix}write_to_file for new files or complete rewrites.
|
|
3300
3542
|
- 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.
|
|
3301
|
-
-
|
|
3543
|
+
- Use before/after text anchors in ${toolNamePrefix}edit_file to target changes. If multiple operations are needed, list them in file order.
|
|
3302
3544
|
- Do not guess unseen content. Read existing files first unless creating new ones.
|
|
3303
3545
|
- Follow existing style, lint, and naming conventions. Ensure all changes compile and pass tests where applicable.
|
|
3304
3546
|
- ALWAYS wait for the user's confirmation after each tool call before starting the next step.
|
|
@@ -3564,6 +3806,7 @@ var configSchema = z.object({
|
|
|
3564
3806
|
}).strict();
|
|
3565
3807
|
var Policies = /* @__PURE__ */ ((Policies2) => {
|
|
3566
3808
|
Policies2["KnowledgeManagement"] = "knowledgemanagement";
|
|
3809
|
+
Policies2["TruncateContext"] = "truncatecontext";
|
|
3567
3810
|
return Policies2;
|
|
3568
3811
|
})(Policies || {});
|
|
3569
3812
|
|
|
@@ -3711,6 +3954,67 @@ var KnowledgeManagementPolicy = (tools) => {
|
|
|
3711
3954
|
};
|
|
3712
3955
|
};
|
|
3713
3956
|
|
|
3957
|
+
// src/Agent/policies/TruncateContext.ts
|
|
3958
|
+
var DEFAULT_MAX_TOKENS_ESTIMATE = 8e3;
|
|
3959
|
+
function getMaxTokens(agent) {
|
|
3960
|
+
const params = agent.parameters || {};
|
|
3961
|
+
if (params.maxTokens && typeof params.maxTokens === "number" && params.maxTokens > 0) {
|
|
3962
|
+
return params.maxTokens;
|
|
3963
|
+
}
|
|
3964
|
+
return DEFAULT_MAX_TOKENS_ESTIMATE;
|
|
3965
|
+
}
|
|
3966
|
+
function estimateTokens(text) {
|
|
3967
|
+
return Math.ceil(text.length / 4);
|
|
3968
|
+
}
|
|
3969
|
+
var TruncateContextPolicy = (tools) => {
|
|
3970
|
+
return {
|
|
3971
|
+
name: "truncatecontext" /* TruncateContext */,
|
|
3972
|
+
async onBeforeRequest(agent) {
|
|
3973
|
+
const messages = agent.messages;
|
|
3974
|
+
if (messages.length < 3) {
|
|
3975
|
+
return;
|
|
3976
|
+
}
|
|
3977
|
+
let totalTokens = 0;
|
|
3978
|
+
for (const msg of messages) {
|
|
3979
|
+
if (typeof msg.content === "string") {
|
|
3980
|
+
totalTokens += estimateTokens(msg.content);
|
|
3981
|
+
} else if (Array.isArray(msg.content)) {
|
|
3982
|
+
for (const block of msg.content) {
|
|
3983
|
+
if (typeof block === "object" && "text" in block && typeof block.text === "string") {
|
|
3984
|
+
totalTokens += estimateTokens(block.text);
|
|
3985
|
+
}
|
|
3986
|
+
}
|
|
3987
|
+
}
|
|
3988
|
+
}
|
|
3989
|
+
const maxTokens = getMaxTokens(agent);
|
|
3990
|
+
if (totalTokens <= maxTokens) {
|
|
3991
|
+
return;
|
|
3992
|
+
}
|
|
3993
|
+
const totalMessages = messages.length;
|
|
3994
|
+
const messagesToKeep = Math.ceil(totalMessages / 2);
|
|
3995
|
+
const minKeep = Math.max(2, messagesToKeep);
|
|
3996
|
+
if (minKeep >= totalMessages) {
|
|
3997
|
+
return;
|
|
3998
|
+
}
|
|
3999
|
+
const keepFromStart = Math.floor(minKeep / 2);
|
|
4000
|
+
const keepFromEnd = minKeep - keepFromStart;
|
|
4001
|
+
const startMessages = messages.slice(0, keepFromStart);
|
|
4002
|
+
const endMessages = messages.slice(-keepFromEnd);
|
|
4003
|
+
const truncatedCount = totalMessages - minKeep;
|
|
4004
|
+
const truncatedMessages = [
|
|
4005
|
+
...startMessages,
|
|
4006
|
+
// Add a message explaining truncation
|
|
4007
|
+
{
|
|
4008
|
+
role: "user",
|
|
4009
|
+
content: `Note: ${truncatedCount} messages were truncated from the middle to prevent context overflow.`
|
|
4010
|
+
},
|
|
4011
|
+
...endMessages
|
|
4012
|
+
];
|
|
4013
|
+
agent.setMessages(truncatedMessages);
|
|
4014
|
+
}
|
|
4015
|
+
};
|
|
4016
|
+
};
|
|
4017
|
+
|
|
3714
4018
|
// src/Agent/index.ts
|
|
3715
4019
|
var allAgents = [architectAgentInfo, coderAgentInfo, analyzerAgentInfo, codeFixerAgentInfo];
|
|
3716
4020
|
|
|
@@ -4109,6 +4413,7 @@ export {
|
|
|
4109
4413
|
Policies,
|
|
4110
4414
|
TaskEventKind,
|
|
4111
4415
|
ToolResponseType,
|
|
4416
|
+
TruncateContextPolicy,
|
|
4112
4417
|
UsageMeter,
|
|
4113
4418
|
agentsPrompt,
|
|
4114
4419
|
allAgents,
|
|
@@ -4131,6 +4436,8 @@ export {
|
|
|
4131
4436
|
deepSeekModels,
|
|
4132
4437
|
defaultModels,
|
|
4133
4438
|
delegate_default as delegate,
|
|
4439
|
+
editFile_default as editFile,
|
|
4440
|
+
editFile as editFileHelper,
|
|
4134
4441
|
executeAgentTool,
|
|
4135
4442
|
executeCommand_default as executeCommand,
|
|
4136
4443
|
executeTool,
|