@polka-codes/core 0.4.7 → 0.4.9
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/README.md +5 -1
- package/dist/index.js +1271 -1051
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2865,10 +2865,78 @@ Anthropic.Models = Models2;
|
|
|
2865
2865
|
Anthropic.ModelInfosPage = ModelInfosPage;
|
|
2866
2866
|
Anthropic.Beta = Beta;
|
|
2867
2867
|
|
|
2868
|
+
// src/AiService/UsageMeter.ts
|
|
2869
|
+
class UsageMeter {
|
|
2870
|
+
#usage = {
|
|
2871
|
+
inputTokens: 0,
|
|
2872
|
+
outputTokens: 0,
|
|
2873
|
+
cacheWriteTokens: 0,
|
|
2874
|
+
cacheReadTokens: 0,
|
|
2875
|
+
totalCost: 0
|
|
2876
|
+
};
|
|
2877
|
+
#messageCount = 0;
|
|
2878
|
+
maxCost;
|
|
2879
|
+
maxMessageCount;
|
|
2880
|
+
constructor(options = {}) {
|
|
2881
|
+
this.maxCost = options.maxCost || 1000;
|
|
2882
|
+
this.maxMessageCount = options.maxMessageCount || 1000;
|
|
2883
|
+
}
|
|
2884
|
+
addUsage(usage, model) {
|
|
2885
|
+
this.#usage.inputTokens += usage.inputTokens ?? 0;
|
|
2886
|
+
this.#usage.outputTokens += usage.outputTokens ?? 0;
|
|
2887
|
+
this.#usage.cacheWriteTokens += usage.cacheWriteTokens ?? 0;
|
|
2888
|
+
this.#usage.cacheReadTokens += usage.cacheReadTokens ?? 0;
|
|
2889
|
+
if (!usage.totalCost && model) {
|
|
2890
|
+
usage.totalCost = ((model.inputPrice ?? 0) * (usage.inputTokens ?? 0) + (model.outputPrice ?? 0) * (usage.outputTokens ?? 0) + (model.cacheWritesPrice ?? 0) * (usage.cacheWriteTokens ?? 0) + (model.cacheReadsPrice ?? 0) * (usage.cacheReadTokens ?? 0)) / 1e6;
|
|
2891
|
+
}
|
|
2892
|
+
this.#usage.totalCost += usage.totalCost ?? 0;
|
|
2893
|
+
}
|
|
2894
|
+
incrementMessageCount(count = 1) {
|
|
2895
|
+
this.#messageCount += count;
|
|
2896
|
+
}
|
|
2897
|
+
isLimitExceeded() {
|
|
2898
|
+
const messageCount = this.#messageCount >= this.maxMessageCount;
|
|
2899
|
+
const cost = this.#usage.totalCost >= this.maxCost;
|
|
2900
|
+
return {
|
|
2901
|
+
messageCount,
|
|
2902
|
+
cost,
|
|
2903
|
+
result: messageCount || cost
|
|
2904
|
+
};
|
|
2905
|
+
}
|
|
2906
|
+
get usage() {
|
|
2907
|
+
return { ...this.#usage };
|
|
2908
|
+
}
|
|
2909
|
+
printUsage() {
|
|
2910
|
+
console.log("Usages:");
|
|
2911
|
+
console.log(`Input tokens: ${this.#usage.inputTokens}`);
|
|
2912
|
+
console.log(`Output tokens: ${this.#usage.outputTokens}`);
|
|
2913
|
+
console.log(`Cache read tokens: ${this.#usage.cacheReadTokens}`);
|
|
2914
|
+
console.log(`Cache write tokens: ${this.#usage.cacheWriteTokens}`);
|
|
2915
|
+
console.log(`Total cost: ${this.#usage.totalCost}`);
|
|
2916
|
+
}
|
|
2917
|
+
}
|
|
2918
|
+
|
|
2868
2919
|
// src/AiService/AiServiceBase.ts
|
|
2869
2920
|
class AiServiceBase {
|
|
2921
|
+
usageMeter;
|
|
2922
|
+
constructor(usageMeter) {
|
|
2923
|
+
this.usageMeter = usageMeter ?? new UsageMeter;
|
|
2924
|
+
}
|
|
2925
|
+
async* send(systemPrompt, messages) {
|
|
2926
|
+
this.usageMeter.incrementMessageCount();
|
|
2927
|
+
const stream = this.sendImpl(systemPrompt, messages);
|
|
2928
|
+
for await (const chunk of stream) {
|
|
2929
|
+
switch (chunk.type) {
|
|
2930
|
+
case "usage":
|
|
2931
|
+
this.usageMeter.addUsage(chunk, this.model.info);
|
|
2932
|
+
break;
|
|
2933
|
+
}
|
|
2934
|
+
yield chunk;
|
|
2935
|
+
}
|
|
2936
|
+
}
|
|
2870
2937
|
async request(systemPrompt, messages) {
|
|
2871
|
-
|
|
2938
|
+
this.usageMeter.incrementMessageCount();
|
|
2939
|
+
const stream = this.sendImpl(systemPrompt, messages);
|
|
2872
2940
|
const usage = {
|
|
2873
2941
|
inputTokens: 0,
|
|
2874
2942
|
outputTokens: 0,
|
|
@@ -2894,6 +2962,7 @@ class AiServiceBase {
|
|
|
2894
2962
|
reasoning += chunk.text;
|
|
2895
2963
|
}
|
|
2896
2964
|
}
|
|
2965
|
+
this.usageMeter.addUsage(usage, this.model.info);
|
|
2897
2966
|
return {
|
|
2898
2967
|
response: resp,
|
|
2899
2968
|
reasoning,
|
|
@@ -2985,7 +3054,7 @@ class AnthropicService extends AiServiceBase {
|
|
|
2985
3054
|
#client;
|
|
2986
3055
|
model;
|
|
2987
3056
|
constructor(options) {
|
|
2988
|
-
super();
|
|
3057
|
+
super(options.usageMeter);
|
|
2989
3058
|
this.#options = options;
|
|
2990
3059
|
this.#client = new Anthropic({
|
|
2991
3060
|
apiKey: options.apiKey,
|
|
@@ -2997,7 +3066,7 @@ class AnthropicService extends AiServiceBase {
|
|
|
2997
3066
|
info: anthropicModels[id] ?? anthropicModels[anthropicDefaultModelId]
|
|
2998
3067
|
};
|
|
2999
3068
|
}
|
|
3000
|
-
async*
|
|
3069
|
+
async* sendImpl(systemPrompt, messages) {
|
|
3001
3070
|
let stream;
|
|
3002
3071
|
const modelId = this.model.id;
|
|
3003
3072
|
switch (modelId) {
|
|
@@ -7862,7 +7931,7 @@ class DeepSeekService extends AiServiceBase {
|
|
|
7862
7931
|
#client;
|
|
7863
7932
|
model;
|
|
7864
7933
|
constructor(options) {
|
|
7865
|
-
super();
|
|
7934
|
+
super(options.usageMeter);
|
|
7866
7935
|
this.#client = new openai_default({
|
|
7867
7936
|
baseURL: "https://api.deepseek.com/v1",
|
|
7868
7937
|
apiKey: options.apiKey
|
|
@@ -7873,7 +7942,7 @@ class DeepSeekService extends AiServiceBase {
|
|
|
7873
7942
|
info: deepSeekModels[id] ?? deepSeekModels[deepSeekDefaultModelId]
|
|
7874
7943
|
};
|
|
7875
7944
|
}
|
|
7876
|
-
async*
|
|
7945
|
+
async* sendImpl(systemPrompt, messages) {
|
|
7877
7946
|
const openAiMessages = [
|
|
7878
7947
|
{ role: "system", content: systemPrompt },
|
|
7879
7948
|
...convertToOpenAiMessages(messages)
|
|
@@ -7918,7 +7987,7 @@ class OllamaService extends AiServiceBase {
|
|
|
7918
7987
|
#client;
|
|
7919
7988
|
model;
|
|
7920
7989
|
constructor(options) {
|
|
7921
|
-
super();
|
|
7990
|
+
super(options.usageMeter);
|
|
7922
7991
|
this.#client = new openai_default({
|
|
7923
7992
|
baseURL: `${options.baseUrl || "http://localhost:11434"}/v1`,
|
|
7924
7993
|
apiKey: "ollama"
|
|
@@ -7928,7 +7997,7 @@ class OllamaService extends AiServiceBase {
|
|
|
7928
7997
|
info: openAiModelInfoSaneDefaults
|
|
7929
7998
|
};
|
|
7930
7999
|
}
|
|
7931
|
-
async*
|
|
8000
|
+
async* sendImpl(systemPrompt, messages) {
|
|
7932
8001
|
const openAiMessages = [
|
|
7933
8002
|
{ role: "system", content: systemPrompt },
|
|
7934
8003
|
...convertToOpenAiMessages(messages)
|
|
@@ -7957,7 +8026,7 @@ class OpenRouterService extends AiServiceBase {
|
|
|
7957
8026
|
#apiKey;
|
|
7958
8027
|
model;
|
|
7959
8028
|
constructor(options) {
|
|
7960
|
-
super();
|
|
8029
|
+
super(options.usageMeter);
|
|
7961
8030
|
if (!options.model) {
|
|
7962
8031
|
throw new Error("OpenRouter requires a model");
|
|
7963
8032
|
}
|
|
@@ -7978,7 +8047,7 @@ class OpenRouterService extends AiServiceBase {
|
|
|
7978
8047
|
info: {}
|
|
7979
8048
|
};
|
|
7980
8049
|
}
|
|
7981
|
-
async*
|
|
8050
|
+
async* sendImpl(systemPrompt, messages) {
|
|
7982
8051
|
const openAiMessages = [
|
|
7983
8052
|
{ role: "system", content: systemPrompt },
|
|
7984
8053
|
...convertToOpenAiMessages(messages)
|
|
@@ -8141,656 +8210,211 @@ var getAvailableTools = (provider, allTools) => {
|
|
|
8141
8210
|
return allTools.filter((tool) => tool.isAvailable(provider));
|
|
8142
8211
|
};
|
|
8143
8212
|
|
|
8144
|
-
// src/
|
|
8145
|
-
|
|
8146
|
-
|
|
8147
|
-
|
|
8148
|
-
|
|
8149
|
-
|
|
8150
|
-
|
|
8151
|
-
|
|
8152
|
-
|
|
8153
|
-
|
|
8154
|
-
|
|
8155
|
-
|
|
8156
|
-
|
|
8157
|
-
|
|
8158
|
-
|
|
8159
|
-
|
|
8160
|
-
|
|
8161
|
-
|
|
8162
|
-
|
|
8213
|
+
// src/tools/provider.ts
|
|
8214
|
+
class MockProvider {
|
|
8215
|
+
async readFile(path) {
|
|
8216
|
+
return "mock content";
|
|
8217
|
+
}
|
|
8218
|
+
async writeFile(path, content) {
|
|
8219
|
+
return;
|
|
8220
|
+
}
|
|
8221
|
+
async removeFile(path) {
|
|
8222
|
+
return;
|
|
8223
|
+
}
|
|
8224
|
+
async renameFile(sourcePath, targetPath) {
|
|
8225
|
+
return;
|
|
8226
|
+
}
|
|
8227
|
+
async listFiles(path, recursive, maxCount) {
|
|
8228
|
+
return [["mock-file.txt"], false];
|
|
8229
|
+
}
|
|
8230
|
+
async searchFiles(path, regex, filePattern) {
|
|
8231
|
+
return ["mock-file.txt"];
|
|
8232
|
+
}
|
|
8233
|
+
async listCodeDefinitionNames(path) {
|
|
8234
|
+
return ["mockDefinition"];
|
|
8235
|
+
}
|
|
8236
|
+
async executeCommand(command, needApprove) {
|
|
8237
|
+
return { stdout: "mock output", stderr: "", exitCode: 0 };
|
|
8238
|
+
}
|
|
8239
|
+
async askFollowupQuestion(question, options) {
|
|
8240
|
+
return "mock answer";
|
|
8241
|
+
}
|
|
8242
|
+
async attemptCompletion(result) {
|
|
8243
|
+
return "mock completion";
|
|
8244
|
+
}
|
|
8245
|
+
}
|
|
8246
|
+
// src/tools/allTools.ts
|
|
8247
|
+
var exports_allTools = {};
|
|
8248
|
+
__export(exports_allTools, {
|
|
8249
|
+
writeToFile: () => writeToFile_default,
|
|
8250
|
+
searchFiles: () => searchFiles_default,
|
|
8251
|
+
replaceInFile: () => replaceInFile_default,
|
|
8252
|
+
renameFile: () => renameFile_default,
|
|
8253
|
+
removeFile: () => removeFile_default,
|
|
8254
|
+
readFile: () => readFile_default,
|
|
8255
|
+
listFiles: () => listFiles_default,
|
|
8256
|
+
listCodeDefinitionNames: () => listCodeDefinitionNames_default,
|
|
8257
|
+
handOver: () => handOver_default,
|
|
8258
|
+
executeCommand: () => executeCommand_default,
|
|
8259
|
+
attemptCompletion: () => attemptCompletion_default,
|
|
8260
|
+
askFollowupQuestion: () => askFollowupQuestion_default
|
|
8261
|
+
});
|
|
8262
|
+
|
|
8263
|
+
// src/tools/utils/replaceInFile.ts
|
|
8264
|
+
var replaceInFile = async (fileContent, diff) => {
|
|
8265
|
+
const blockPattern = /<<<<<+ SEARCH\s*\r?\n([\s\S]*?)\r?\n=======[ \t]*\r?\n([\s\S]*?)\r?\n?>>>>>+ REPLACE/g;
|
|
8266
|
+
const blocks = [];
|
|
8267
|
+
for (let match = blockPattern.exec(diff);match !== null; match = blockPattern.exec(diff)) {
|
|
8268
|
+
blocks.push({ search: match[1], replace: match[2] });
|
|
8269
|
+
}
|
|
8270
|
+
if (blocks.length === 0) {
|
|
8271
|
+
throw new Error("No valid diff blocks found.");
|
|
8272
|
+
}
|
|
8273
|
+
const findAndReplace = (content, search, replace) => {
|
|
8274
|
+
let index = content.indexOf(search);
|
|
8275
|
+
if (index !== -1) {
|
|
8276
|
+
return content.slice(0, index) + replace + content.slice(index + search.length);
|
|
8163
8277
|
}
|
|
8164
|
-
const
|
|
8165
|
-
const
|
|
8166
|
-
const
|
|
8167
|
-
|
|
8168
|
-
if (
|
|
8169
|
-
const
|
|
8170
|
-
|
|
8171
|
-
|
|
8172
|
-
|
|
8173
|
-
|
|
8174
|
-
|
|
8175
|
-
|
|
8176
|
-
|
|
8278
|
+
const trimmedSearch = search.trim();
|
|
8279
|
+
const trimmedContent = content.trim();
|
|
8280
|
+
const offset = content.indexOf(trimmedContent);
|
|
8281
|
+
index = trimmedContent.indexOf(trimmedSearch);
|
|
8282
|
+
if (index !== -1) {
|
|
8283
|
+
const absoluteIndex = offset + index;
|
|
8284
|
+
return content.slice(0, absoluteIndex) + replace + content.slice(absoluteIndex + trimmedSearch.length);
|
|
8285
|
+
}
|
|
8286
|
+
const normalizedSearch = trimmedSearch.replace(/\s+/g, " ");
|
|
8287
|
+
const normalizedContent = trimmedContent.replace(/\s+/g, " ");
|
|
8288
|
+
index = normalizedContent.indexOf(normalizedSearch);
|
|
8289
|
+
if (index !== -1) {
|
|
8290
|
+
let runningIndex = 0;
|
|
8291
|
+
let actualPos = offset;
|
|
8292
|
+
for (const segment of trimmedSearch.replace(/\s+/g, " ").split(" ")) {
|
|
8293
|
+
const segIndex = content.indexOf(segment, actualPos);
|
|
8294
|
+
if (segIndex === -1) {
|
|
8295
|
+
break;
|
|
8296
|
+
}
|
|
8297
|
+
if (runningIndex === 0) {
|
|
8298
|
+
actualPos = segIndex;
|
|
8299
|
+
} else {
|
|
8300
|
+
actualPos = segIndex + segment.length;
|
|
8177
8301
|
}
|
|
8302
|
+
runningIndex++;
|
|
8178
8303
|
}
|
|
8179
|
-
|
|
8180
|
-
|
|
8181
|
-
|
|
8182
|
-
|
|
8183
|
-
});
|
|
8184
|
-
} else {
|
|
8185
|
-
results.push({
|
|
8186
|
-
type: "text",
|
|
8187
|
-
content: fullTagContent
|
|
8188
|
-
});
|
|
8304
|
+
const strippedSearch = trimmedSearch.replace(/\s+/g, "");
|
|
8305
|
+
const endPos = actualPos;
|
|
8306
|
+
const startPos = endPos - strippedSearch.length;
|
|
8307
|
+
return content.slice(0, startPos) + replace + content.slice(endPos);
|
|
8189
8308
|
}
|
|
8190
|
-
|
|
8309
|
+
throw new Error(`Could not find the following text in file:
|
|
8310
|
+
${search}`);
|
|
8311
|
+
};
|
|
8312
|
+
let updatedFile = fileContent;
|
|
8313
|
+
for (const { search, replace } of blocks) {
|
|
8314
|
+
updatedFile = findAndReplace(updatedFile, search, replace);
|
|
8191
8315
|
}
|
|
8192
|
-
|
|
8193
|
-
|
|
8194
|
-
|
|
8195
|
-
|
|
8196
|
-
|
|
8316
|
+
return updatedFile;
|
|
8317
|
+
};
|
|
8318
|
+
// src/tools/utils/getArg.ts
|
|
8319
|
+
var getString = (args, name, defaultValue) => {
|
|
8320
|
+
const ret = args[name] ?? defaultValue;
|
|
8321
|
+
if (ret === undefined) {
|
|
8322
|
+
throw new Error(`Missing required argument: ${name}`);
|
|
8197
8323
|
}
|
|
8198
|
-
|
|
8199
|
-
|
|
8200
|
-
|
|
8201
|
-
|
|
8202
|
-
|
|
8324
|
+
return ret;
|
|
8325
|
+
};
|
|
8326
|
+
var getStringArray = (args, name, defaultValue) => {
|
|
8327
|
+
const ret = args[name];
|
|
8328
|
+
if (ret === undefined) {
|
|
8329
|
+
if (defaultValue === undefined) {
|
|
8330
|
+
throw new Error(`Missing required argument: ${name}`);
|
|
8331
|
+
}
|
|
8332
|
+
return defaultValue;
|
|
8203
8333
|
}
|
|
8204
|
-
|
|
8205
|
-
|
|
8206
|
-
|
|
8207
|
-
// src/Agent/prompts.ts
|
|
8208
|
-
var toolInfoPrompt = (tool, toolNamePrefix, parameterPrefix) => `
|
|
8209
|
-
## ${toolNamePrefix}${tool.name}
|
|
8210
|
-
|
|
8211
|
-
Description: ${tool.description}
|
|
8212
|
-
|
|
8213
|
-
Parameters:
|
|
8214
|
-
${tool.parameters.map((param) => `- ${parameterPrefix}${param.name}: (${param.required ? "required" : "optional"}) ${param.description}`).join(`
|
|
8215
|
-
`)}
|
|
8216
|
-
|
|
8217
|
-
Usage:
|
|
8218
|
-
<${toolNamePrefix}${tool.name}>
|
|
8219
|
-
${tool.parameters.map((param) => `<${parameterPrefix}${param.name}>${param.usageValue}</${parameterPrefix}${param.name}>`).join(`
|
|
8220
|
-
`)}
|
|
8221
|
-
</${toolNamePrefix}${tool.name}>`;
|
|
8222
|
-
var toolInfoExamplesPrompt = (idx, tool, example, toolNamePrefix, parameterPrefix) => `
|
|
8223
|
-
## Example ${idx + 1}: ${example.description}
|
|
8224
|
-
|
|
8225
|
-
<${toolNamePrefix}${tool.name}>
|
|
8226
|
-
${example.parameters.map((param) => `<${parameterPrefix}${param.name}>${param.value}</${parameterPrefix}${param.name}>`).join(`
|
|
8227
|
-
`)}
|
|
8228
|
-
</${toolNamePrefix}${tool.name}>
|
|
8229
|
-
`;
|
|
8230
|
-
var toolUsePrompt = (tools, toolNamePrefix) => {
|
|
8231
|
-
if (tools.length === 0) {
|
|
8232
|
-
return "";
|
|
8334
|
+
if (ret === "") {
|
|
8335
|
+
return [];
|
|
8233
8336
|
}
|
|
8234
|
-
|
|
8235
|
-
let exampleIndex = 0;
|
|
8236
|
-
return `
|
|
8237
|
-
====
|
|
8238
|
-
|
|
8239
|
-
TOOL USE
|
|
8240
|
-
|
|
8241
|
-
You have access to a set of tools that are executed upon the user's approval. You can use one tool per message, and will receive the result of that tool use 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.
|
|
8242
|
-
|
|
8243
|
-
# Tool Use Formatting
|
|
8244
|
-
|
|
8245
|
-
Tool use is formatted using XML-style tags. The tool name is enclosed in opening and closing tags, and each parameter is similarly enclosed within its own set of tags. Here's the structure:
|
|
8246
|
-
|
|
8247
|
-
<${toolNamePrefix}tool_name>
|
|
8248
|
-
<${parameterPrefix}name1>value1</${parameterPrefix}name1>
|
|
8249
|
-
<${parameterPrefix}name2>value2</${parameterPrefix}name2>
|
|
8250
|
-
...
|
|
8251
|
-
</${toolNamePrefix}tool_name>
|
|
8252
|
-
|
|
8253
|
-
For example:
|
|
8254
|
-
|
|
8255
|
-
<${toolNamePrefix}read_file>
|
|
8256
|
-
<${parameterPrefix}path>src/main.js</${parameterPrefix}path>
|
|
8257
|
-
</${toolNamePrefix}read_file>
|
|
8258
|
-
|
|
8259
|
-
Always adhere to this format for the tool use to ensure proper parsing and execution.
|
|
8260
|
-
|
|
8261
|
-
# Tools
|
|
8262
|
-
${tools.map((tool) => toolInfoPrompt(tool, toolNamePrefix, parameterPrefix)).join(`
|
|
8263
|
-
`)}
|
|
8264
|
-
|
|
8265
|
-
# Tool Use Examples
|
|
8266
|
-
${tools.map((tool) => {
|
|
8267
|
-
let promp = "";
|
|
8268
|
-
for (const example of tool.examples ?? []) {
|
|
8269
|
-
promp += toolInfoExamplesPrompt(exampleIndex++, tool, example, toolNamePrefix, parameterPrefix);
|
|
8270
|
-
}
|
|
8271
|
-
return promp;
|
|
8272
|
-
}).join("")}
|
|
8273
|
-
# Tool Use Guidelines
|
|
8274
|
-
|
|
8275
|
-
1. **In \`<thinking>\` tags**, assess what information you have and what you need to proceed.
|
|
8276
|
-
2. **Choose one tool at a time per message** based on the task and its description. Do not assume a tool’s outcome without explicit confirmation.
|
|
8277
|
-
3. **Formulate tool use only in the specified XML format** for each tool.
|
|
8278
|
-
4. **Wait for the user’s response** after each tool use. Do not proceed until you have their confirmation.
|
|
8279
|
-
5. The user’s response may include:
|
|
8280
|
-
- Tool success or failure details
|
|
8281
|
-
- Linter errors
|
|
8282
|
-
- Terminal output or other relevant feedback
|
|
8283
|
-
6. **Never repeat or quote the entire tool command** in your final user-facing message. Summarize outcomes clearly and avoid echoing commands verbatim.
|
|
8284
|
-
7. **Respond concisely** and move the conversation forward. Do not re-issue the same command or re-trigger tool use without necessity.
|
|
8285
|
-
8. Follow these steps **iteratively**, confirming success and addressing issues as you go.
|
|
8286
|
-
|
|
8287
|
-
By adhering to these guidelines:
|
|
8288
|
-
- You maintain clarity without accidentally re-invoking tools.
|
|
8289
|
-
- You confirm each step’s results before proceeding.
|
|
8290
|
-
- You provide only the necessary information in user-facing replies to prevent re-interpretation as new commands.`;
|
|
8337
|
+
return ret.split(",").map((s) => s.trim());
|
|
8291
8338
|
};
|
|
8292
|
-
var
|
|
8293
|
-
|
|
8294
|
-
|
|
8295
|
-
|
|
8296
|
-
|
|
8297
|
-
|
|
8298
|
-
|
|
8299
|
-
- **${agent.name}**
|
|
8300
|
-
- Responsibilities:
|
|
8301
|
-
${agent.responsibilities.map((resp) => ` - ${resp}`).join(`
|
|
8302
|
-
`)}`).join(`
|
|
8303
|
-
`)}
|
|
8304
|
-
|
|
8305
|
-
- **Current Agent Role**
|
|
8306
|
-
You are currently acting as **${name}**. If you identify the task is beyond your current scope, use the handover tool to transition to the other agent. Include sufficient context so the new agent can seamlessly continue the work.
|
|
8307
|
-
`;
|
|
8308
|
-
var capabilities = (toolNamePrefix) => `
|
|
8309
|
-
====
|
|
8310
|
-
|
|
8311
|
-
CAPABILITIES
|
|
8312
|
-
|
|
8313
|
-
- You have access to a range of tools to aid you in your work. These tools help you effectively accomplish a wide range of tasks.
|
|
8314
|
-
- When the user initially gives you a task, a recursive list of all filepaths in the current working directory will be included in context. This provides an overview of the project's file structure, offering key insights into the project from directory/file names (how developers conceptualize and organize their code) and file extensions (the language used). This can also guide decision-making on which files to explore further.`;
|
|
8315
|
-
var systemInformation = (info) => `
|
|
8316
|
-
====
|
|
8317
|
-
|
|
8318
|
-
SYSTEM INFORMATION
|
|
8319
|
-
|
|
8320
|
-
Operating System: ${info.os}`;
|
|
8321
|
-
var interactiveMode = (interactive) => {
|
|
8322
|
-
if (interactive) {
|
|
8323
|
-
return `
|
|
8324
|
-
====
|
|
8325
|
-
|
|
8326
|
-
INTERACTIVE MODE
|
|
8327
|
-
|
|
8328
|
-
You are in interactive mode. This means you may ask user questions to gather additional information to complete the task.
|
|
8329
|
-
`;
|
|
8339
|
+
var getBoolean = (args, name, defaultValue) => {
|
|
8340
|
+
const ret = args[name];
|
|
8341
|
+
if (ret === undefined) {
|
|
8342
|
+
if (defaultValue === undefined) {
|
|
8343
|
+
throw new Error(`Missing required argument: ${name}`);
|
|
8344
|
+
}
|
|
8345
|
+
return defaultValue;
|
|
8330
8346
|
}
|
|
8331
|
-
|
|
8332
|
-
|
|
8333
|
-
|
|
8334
|
-
|
|
8335
|
-
|
|
8336
|
-
|
|
8337
|
-
|
|
8338
|
-
};
|
|
8339
|
-
var customInstructions = (customInstructions2) => {
|
|
8340
|
-
const joined = customInstructions2.join(`
|
|
8341
|
-
`);
|
|
8342
|
-
if (joined.trim() === "") {
|
|
8343
|
-
return "";
|
|
8347
|
+
switch (ret.toLowerCase()) {
|
|
8348
|
+
case "true":
|
|
8349
|
+
return true;
|
|
8350
|
+
case "false":
|
|
8351
|
+
return false;
|
|
8352
|
+
default:
|
|
8353
|
+
throw new Error(`Invalid argument value: ${name}`);
|
|
8344
8354
|
}
|
|
8345
|
-
return `
|
|
8346
|
-
====
|
|
8347
|
-
|
|
8348
|
-
USER'S CUSTOM INSTRUCTIONS
|
|
8349
|
-
|
|
8350
|
-
The following additional instructions are provided by the user, and should be followed to the best of your ability without interfering with the TOOL USE guidelines.
|
|
8351
|
-
|
|
8352
|
-
${joined}`;
|
|
8353
8355
|
};
|
|
8354
|
-
var
|
|
8355
|
-
const
|
|
8356
|
-
|
|
8357
|
-
|
|
8358
|
-
|
|
8356
|
+
var getInt = (args, name, defaultValue) => {
|
|
8357
|
+
const ret = args[name];
|
|
8358
|
+
if (ret === undefined) {
|
|
8359
|
+
if (defaultValue === undefined) {
|
|
8360
|
+
throw new Error(`Missing required argument: ${name}`);
|
|
8359
8361
|
}
|
|
8360
|
-
return
|
|
8361
|
-
- Command: \`${command.command}\`
|
|
8362
|
-
- Description: ${command.description}`;
|
|
8363
|
-
}).join(`
|
|
8364
|
-
`);
|
|
8365
|
-
if (joined.trim() === "") {
|
|
8366
|
-
return "";
|
|
8362
|
+
return defaultValue;
|
|
8367
8363
|
}
|
|
8368
|
-
|
|
8369
|
-
|
|
8370
|
-
|
|
8371
|
-
USER'S CUSTOM COMMANDS
|
|
8372
|
-
|
|
8373
|
-
The following additional commands are provided by the user, and should be followed to the best of your ability without interfering with the TOOL USE guidelines.
|
|
8374
|
-
|
|
8375
|
-
${joined}`;
|
|
8376
|
-
};
|
|
8377
|
-
var responsePrompts = {
|
|
8378
|
-
errorInvokeTool: (tool, error) => `An error occurred while invoking the tool "${tool}": ${error}`,
|
|
8379
|
-
requireUseTool: "Error: You must use a tool before proceeding. Making sure the tool is invoked using xml tags.",
|
|
8380
|
-
toolResults: (tool, result) => `<tool_response>
|
|
8381
|
-
<tool_name>${tool}</tool_name>
|
|
8382
|
-
<tool_result>
|
|
8383
|
-
${result}
|
|
8384
|
-
</tool_result>
|
|
8385
|
-
</tool_response>`
|
|
8386
|
-
};
|
|
8387
|
-
|
|
8388
|
-
// src/Agent/AgentBase.ts
|
|
8389
|
-
var TaskEventKind;
|
|
8390
|
-
((TaskEventKind2) => {
|
|
8391
|
-
TaskEventKind2["StartTask"] = "StartTask";
|
|
8392
|
-
TaskEventKind2["StartRequest"] = "StartRequest";
|
|
8393
|
-
TaskEventKind2["EndRequest"] = "EndRequest";
|
|
8394
|
-
TaskEventKind2["Usage"] = "Usage";
|
|
8395
|
-
TaskEventKind2["Text"] = "Text";
|
|
8396
|
-
TaskEventKind2["Reasoning"] = "Reasoning";
|
|
8397
|
-
TaskEventKind2["ToolUse"] = "ToolUse";
|
|
8398
|
-
TaskEventKind2["ToolReply"] = "ToolReply";
|
|
8399
|
-
TaskEventKind2["ToolInvalid"] = "ToolInvalid";
|
|
8400
|
-
TaskEventKind2["ToolError"] = "ToolError";
|
|
8401
|
-
TaskEventKind2["ToolInterrupted"] = "ToolInterrupted";
|
|
8402
|
-
TaskEventKind2["ToolHandOver"] = "ToolHandOver";
|
|
8403
|
-
TaskEventKind2["MaxIterationsReached"] = "MaxIterationsReached";
|
|
8404
|
-
TaskEventKind2["EndTask"] = "EndTask";
|
|
8405
|
-
})(TaskEventKind ||= {});
|
|
8406
|
-
|
|
8407
|
-
class AgentBase {
|
|
8408
|
-
ai;
|
|
8409
|
-
config;
|
|
8410
|
-
handlers;
|
|
8411
|
-
constructor(name, ai, config) {
|
|
8412
|
-
this.ai = ai;
|
|
8413
|
-
if (config.agents && Object.keys(config.agents).length > 0) {
|
|
8414
|
-
const agents = agentsPrompt(config.agents, name);
|
|
8415
|
-
config.systemPrompt += `
|
|
8416
|
-
${agents}`;
|
|
8417
|
-
}
|
|
8418
|
-
this.config = config;
|
|
8419
|
-
const handlers = {};
|
|
8420
|
-
for (const tool of config.tools) {
|
|
8421
|
-
handlers[tool.name] = tool;
|
|
8422
|
-
}
|
|
8423
|
-
this.handlers = handlers;
|
|
8364
|
+
const parsed = Number.parseInt(ret);
|
|
8365
|
+
if (Number.isNaN(parsed)) {
|
|
8366
|
+
throw new Error(`Invalid argument value: ${name}`);
|
|
8424
8367
|
}
|
|
8425
|
-
|
|
8426
|
-
|
|
8427
|
-
|
|
8428
|
-
|
|
8429
|
-
|
|
8368
|
+
return parsed;
|
|
8369
|
+
};
|
|
8370
|
+
// src/tools/askFollowupQuestion.ts
|
|
8371
|
+
var toolInfo = {
|
|
8372
|
+
name: "ask_followup_question",
|
|
8373
|
+
description: "Whenever you need extra details or clarification to complete the task, pose a direct question to the user. Use this tool sparingly to avoid excessive back-and-forth. If helpful, offer multiple-choice options or examples to guide the user’s response.",
|
|
8374
|
+
parameters: [
|
|
8375
|
+
{
|
|
8376
|
+
name: "question",
|
|
8377
|
+
description: "The question to ask the user. This should be a clear, specific question that addresses the information you need.",
|
|
8378
|
+
required: true,
|
|
8379
|
+
usageValue: "Your question here"
|
|
8380
|
+
},
|
|
8381
|
+
{
|
|
8382
|
+
name: "options",
|
|
8383
|
+
description: "A comma separated list of possible answers to the question. If not provided, the user will be prompted to provide an answer.",
|
|
8384
|
+
required: false,
|
|
8385
|
+
usageValue: "A comma separated list of possible answers (optional)"
|
|
8430
8386
|
}
|
|
8431
|
-
|
|
8432
|
-
|
|
8433
|
-
|
|
8387
|
+
],
|
|
8388
|
+
examples: [
|
|
8389
|
+
{
|
|
8390
|
+
description: "Request to ask a question",
|
|
8391
|
+
parameters: [
|
|
8392
|
+
{
|
|
8393
|
+
name: "question",
|
|
8394
|
+
value: "What is the name of the project?"
|
|
8395
|
+
}
|
|
8396
|
+
]
|
|
8397
|
+
},
|
|
8398
|
+
{
|
|
8399
|
+
description: "Request to ask a question with options",
|
|
8400
|
+
parameters: [
|
|
8401
|
+
{
|
|
8402
|
+
name: "question",
|
|
8403
|
+
value: "What framework do you use?"
|
|
8404
|
+
},
|
|
8405
|
+
{
|
|
8406
|
+
name: "options",
|
|
8407
|
+
value: "React,Angular,Vue,Svelte"
|
|
8408
|
+
}
|
|
8409
|
+
]
|
|
8434
8410
|
}
|
|
8435
|
-
|
|
8436
|
-
|
|
8437
|
-
|
|
8438
|
-
|
|
8439
|
-
|
|
8440
|
-
|
|
8441
|
-
|
|
8442
|
-
cacheWriteTokens: 0,
|
|
8443
|
-
cacheReadTokens: 0,
|
|
8444
|
-
totalCost: 0
|
|
8445
|
-
};
|
|
8446
|
-
let text = `<task>${task}</task>`;
|
|
8447
|
-
if (context) {
|
|
8448
|
-
text += `
|
|
8449
|
-
<context>${context}</context>`;
|
|
8450
|
-
}
|
|
8451
|
-
callback({ kind: "StartTask" /* StartTask */, info: taskInfo, systemPrompt: this.config.systemPrompt });
|
|
8452
|
-
return await this.#processLoop(text, taskInfo, callback);
|
|
8453
|
-
}
|
|
8454
|
-
async#processLoop(userMessage, taskInfo, callback) {
|
|
8455
|
-
let nextRequest = userMessage;
|
|
8456
|
-
while (nextRequest) {
|
|
8457
|
-
if (taskInfo.messages.length > taskInfo.options.maxIterations * 2) {
|
|
8458
|
-
callback({ kind: "MaxIterationsReached" /* MaxIterationsReached */, info: taskInfo });
|
|
8459
|
-
return ["MaxIterations", taskInfo];
|
|
8460
|
-
}
|
|
8461
|
-
const response = await this.#request(taskInfo, nextRequest, callback);
|
|
8462
|
-
const [newMessage, exitReason] = await this.#handleResponse(taskInfo, response, callback);
|
|
8463
|
-
if (exitReason) {
|
|
8464
|
-
callback({ kind: "EndTask" /* EndTask */, info: taskInfo });
|
|
8465
|
-
return [exitReason, taskInfo];
|
|
8466
|
-
}
|
|
8467
|
-
nextRequest = newMessage;
|
|
8468
|
-
}
|
|
8469
|
-
callback({ kind: "EndTask" /* EndTask */, info: taskInfo });
|
|
8470
|
-
return [{ type: "Exit" /* Exit */, message: "Task completed successfully" }, taskInfo];
|
|
8471
|
-
}
|
|
8472
|
-
async continueTask(userMessage, taskInfo, callback = () => {
|
|
8473
|
-
}) {
|
|
8474
|
-
return await this.#processLoop(userMessage, taskInfo, callback);
|
|
8475
|
-
}
|
|
8476
|
-
async#request(info, userMessage, callback) {
|
|
8477
|
-
await callback({ kind: "StartRequest" /* StartRequest */, info, userMessage });
|
|
8478
|
-
info.messages.push({
|
|
8479
|
-
role: "user",
|
|
8480
|
-
content: userMessage
|
|
8481
|
-
});
|
|
8482
|
-
const stream = this.ai.send(this.config.systemPrompt, info.messages);
|
|
8483
|
-
let currentAssistantMessage = "";
|
|
8484
|
-
for await (const chunk of stream) {
|
|
8485
|
-
switch (chunk.type) {
|
|
8486
|
-
case "usage":
|
|
8487
|
-
info.inputTokens = chunk.inputTokens ?? 0;
|
|
8488
|
-
info.outputTokens = chunk.outputTokens ?? 0;
|
|
8489
|
-
info.cacheWriteTokens = chunk.cacheWriteTokens ?? 0;
|
|
8490
|
-
info.cacheReadTokens = chunk.cacheReadTokens ?? 0;
|
|
8491
|
-
info.totalCost = chunk.totalCost;
|
|
8492
|
-
await callback({ kind: "Usage" /* Usage */, info });
|
|
8493
|
-
break;
|
|
8494
|
-
case "text":
|
|
8495
|
-
currentAssistantMessage += chunk.text;
|
|
8496
|
-
await callback({ kind: "Text" /* Text */, info, newText: chunk.text });
|
|
8497
|
-
break;
|
|
8498
|
-
case "reasoning":
|
|
8499
|
-
await callback({ kind: "Reasoning" /* Reasoning */, info, newText: chunk.text });
|
|
8500
|
-
break;
|
|
8501
|
-
}
|
|
8502
|
-
}
|
|
8503
|
-
if (!currentAssistantMessage) {
|
|
8504
|
-
throw new Error("No assistant message received");
|
|
8505
|
-
}
|
|
8506
|
-
info.messages.push({
|
|
8507
|
-
role: "assistant",
|
|
8508
|
-
content: currentAssistantMessage
|
|
8509
|
-
});
|
|
8510
|
-
const ret = parseAssistantMessage(currentAssistantMessage, this.config.tools, this.config.toolNamePrefix);
|
|
8511
|
-
await callback({ kind: "EndRequest" /* EndRequest */, info });
|
|
8512
|
-
return ret;
|
|
8513
|
-
}
|
|
8514
|
-
async#handleResponse(info, response, callback) {
|
|
8515
|
-
const toolReponses = [];
|
|
8516
|
-
outer:
|
|
8517
|
-
for (const content of response) {
|
|
8518
|
-
switch (content.type) {
|
|
8519
|
-
case "text":
|
|
8520
|
-
break;
|
|
8521
|
-
case "tool_use": {
|
|
8522
|
-
await callback({ kind: "ToolUse" /* ToolUse */, info, tool: content.name });
|
|
8523
|
-
const toolResp = await this.#invokeTool(content.name, content.params);
|
|
8524
|
-
switch (toolResp.type) {
|
|
8525
|
-
case "Reply" /* Reply */:
|
|
8526
|
-
await callback({ kind: "ToolReply" /* ToolReply */, info, tool: content.name });
|
|
8527
|
-
toolReponses.push({ tool: content.name, response: toolResp.message });
|
|
8528
|
-
break;
|
|
8529
|
-
case "Exit" /* Exit */:
|
|
8530
|
-
return [undefined, toolResp];
|
|
8531
|
-
case "Invalid" /* Invalid */:
|
|
8532
|
-
await callback({ kind: "ToolInvalid" /* ToolInvalid */, info, tool: content.name });
|
|
8533
|
-
toolReponses.push({ tool: content.name, response: toolResp.message });
|
|
8534
|
-
break outer;
|
|
8535
|
-
case "Error" /* Error */:
|
|
8536
|
-
await callback({ kind: "ToolError" /* ToolError */, info, tool: content.name });
|
|
8537
|
-
toolReponses.push({ tool: content.name, response: toolResp.message });
|
|
8538
|
-
break outer;
|
|
8539
|
-
case "Interrupted" /* Interrupted */:
|
|
8540
|
-
await callback({ kind: "ToolInterrupted" /* ToolInterrupted */, info, tool: content.name });
|
|
8541
|
-
return [undefined, toolResp];
|
|
8542
|
-
case "HandOver" /* HandOver */:
|
|
8543
|
-
await callback({
|
|
8544
|
-
kind: "ToolHandOver" /* ToolHandOver */,
|
|
8545
|
-
info,
|
|
8546
|
-
tool: content.name,
|
|
8547
|
-
agentName: toolResp.agentName,
|
|
8548
|
-
task: toolResp.task,
|
|
8549
|
-
context: toolResp.context,
|
|
8550
|
-
files: toolResp.files
|
|
8551
|
-
});
|
|
8552
|
-
return [undefined, toolResp];
|
|
8553
|
-
}
|
|
8554
|
-
break;
|
|
8555
|
-
}
|
|
8556
|
-
}
|
|
8557
|
-
}
|
|
8558
|
-
if (toolReponses.length === 0 && !this.config.interactive) {
|
|
8559
|
-
return [responsePrompts.requireUseTool, undefined];
|
|
8560
|
-
}
|
|
8561
|
-
const finalResp = toolReponses.map(({ tool, response: response2 }) => responsePrompts.toolResults(tool, response2)).join(`
|
|
8562
|
-
|
|
8563
|
-
`);
|
|
8564
|
-
return [finalResp, undefined];
|
|
8565
|
-
}
|
|
8566
|
-
async#invokeTool(name, args) {
|
|
8567
|
-
try {
|
|
8568
|
-
const handler = this.handlers[name]?.handler;
|
|
8569
|
-
if (!handler) {
|
|
8570
|
-
return {
|
|
8571
|
-
type: "Error" /* Error */,
|
|
8572
|
-
message: responsePrompts.errorInvokeTool(name, "Tool not found"),
|
|
8573
|
-
canRetry: false
|
|
8574
|
-
};
|
|
8575
|
-
}
|
|
8576
|
-
return await handler(this.config.provider, args);
|
|
8577
|
-
} catch (error) {
|
|
8578
|
-
return {
|
|
8579
|
-
type: "Error" /* Error */,
|
|
8580
|
-
message: responsePrompts.errorInvokeTool(name, error),
|
|
8581
|
-
canRetry: false
|
|
8582
|
-
};
|
|
8583
|
-
}
|
|
8584
|
-
}
|
|
8585
|
-
get model() {
|
|
8586
|
-
return this.ai.model;
|
|
8587
|
-
}
|
|
8588
|
-
}
|
|
8589
|
-
// src/tools/provider.ts
|
|
8590
|
-
class MockProvider {
|
|
8591
|
-
async readFile(path) {
|
|
8592
|
-
return "mock content";
|
|
8593
|
-
}
|
|
8594
|
-
async writeFile(path, content) {
|
|
8595
|
-
return;
|
|
8596
|
-
}
|
|
8597
|
-
async removeFile(path) {
|
|
8598
|
-
return;
|
|
8599
|
-
}
|
|
8600
|
-
async renameFile(sourcePath, targetPath) {
|
|
8601
|
-
return;
|
|
8602
|
-
}
|
|
8603
|
-
async listFiles(path, recursive, maxCount) {
|
|
8604
|
-
return [["mock-file.txt"], false];
|
|
8605
|
-
}
|
|
8606
|
-
async searchFiles(path, regex, filePattern) {
|
|
8607
|
-
return ["mock-file.txt"];
|
|
8608
|
-
}
|
|
8609
|
-
async listCodeDefinitionNames(path) {
|
|
8610
|
-
return ["mockDefinition"];
|
|
8611
|
-
}
|
|
8612
|
-
async executeCommand(command, needApprove) {
|
|
8613
|
-
return { stdout: "mock output", stderr: "", exitCode: 0 };
|
|
8614
|
-
}
|
|
8615
|
-
async askFollowupQuestion(question, options) {
|
|
8616
|
-
return "mock answer";
|
|
8617
|
-
}
|
|
8618
|
-
async attemptCompletion(result) {
|
|
8619
|
-
return "mock completion";
|
|
8620
|
-
}
|
|
8621
|
-
}
|
|
8622
|
-
// src/tools/allTools.ts
|
|
8623
|
-
var exports_allTools = {};
|
|
8624
|
-
__export(exports_allTools, {
|
|
8625
|
-
writeToFile: () => writeToFile_default,
|
|
8626
|
-
searchFiles: () => searchFiles_default,
|
|
8627
|
-
replaceInFile: () => replaceInFile_default,
|
|
8628
|
-
renameFile: () => renameFile_default,
|
|
8629
|
-
removeFile: () => removeFile_default,
|
|
8630
|
-
readFile: () => readFile_default,
|
|
8631
|
-
listFiles: () => listFiles_default,
|
|
8632
|
-
listCodeDefinitionNames: () => listCodeDefinitionNames_default,
|
|
8633
|
-
handOver: () => handOver_default,
|
|
8634
|
-
executeCommand: () => executeCommand_default,
|
|
8635
|
-
attemptCompletion: () => attemptCompletion_default,
|
|
8636
|
-
askFollowupQuestion: () => askFollowupQuestion_default
|
|
8637
|
-
});
|
|
8638
|
-
|
|
8639
|
-
// src/tools/utils/replaceInFile.ts
|
|
8640
|
-
var replaceInFile = async (fileContent, diff) => {
|
|
8641
|
-
const blockPattern = /<<<<<+ SEARCH\s*\r?\n([\s\S]*?)\r?\n=======[ \t]*\r?\n([\s\S]*?)\r?\n?>>>>>+ REPLACE/g;
|
|
8642
|
-
const blocks = [];
|
|
8643
|
-
for (let match = blockPattern.exec(diff);match !== null; match = blockPattern.exec(diff)) {
|
|
8644
|
-
blocks.push({ search: match[1], replace: match[2] });
|
|
8645
|
-
}
|
|
8646
|
-
if (blocks.length === 0) {
|
|
8647
|
-
throw new Error("No valid diff blocks found.");
|
|
8648
|
-
}
|
|
8649
|
-
const findAndReplace = (content, search, replace) => {
|
|
8650
|
-
let index = content.indexOf(search);
|
|
8651
|
-
if (index !== -1) {
|
|
8652
|
-
return content.slice(0, index) + replace + content.slice(index + search.length);
|
|
8653
|
-
}
|
|
8654
|
-
const trimmedSearch = search.trim();
|
|
8655
|
-
const trimmedContent = content.trim();
|
|
8656
|
-
const offset = content.indexOf(trimmedContent);
|
|
8657
|
-
index = trimmedContent.indexOf(trimmedSearch);
|
|
8658
|
-
if (index !== -1) {
|
|
8659
|
-
const absoluteIndex = offset + index;
|
|
8660
|
-
return content.slice(0, absoluteIndex) + replace + content.slice(absoluteIndex + trimmedSearch.length);
|
|
8661
|
-
}
|
|
8662
|
-
const normalizedSearch = trimmedSearch.replace(/\s+/g, " ");
|
|
8663
|
-
const normalizedContent = trimmedContent.replace(/\s+/g, " ");
|
|
8664
|
-
index = normalizedContent.indexOf(normalizedSearch);
|
|
8665
|
-
if (index !== -1) {
|
|
8666
|
-
let runningIndex = 0;
|
|
8667
|
-
let actualPos = offset;
|
|
8668
|
-
for (const segment of trimmedSearch.replace(/\s+/g, " ").split(" ")) {
|
|
8669
|
-
const segIndex = content.indexOf(segment, actualPos);
|
|
8670
|
-
if (segIndex === -1) {
|
|
8671
|
-
break;
|
|
8672
|
-
}
|
|
8673
|
-
if (runningIndex === 0) {
|
|
8674
|
-
actualPos = segIndex;
|
|
8675
|
-
} else {
|
|
8676
|
-
actualPos = segIndex + segment.length;
|
|
8677
|
-
}
|
|
8678
|
-
runningIndex++;
|
|
8679
|
-
}
|
|
8680
|
-
const strippedSearch = trimmedSearch.replace(/\s+/g, "");
|
|
8681
|
-
const endPos = actualPos;
|
|
8682
|
-
const startPos = endPos - strippedSearch.length;
|
|
8683
|
-
return content.slice(0, startPos) + replace + content.slice(endPos);
|
|
8684
|
-
}
|
|
8685
|
-
throw new Error(`Could not find the following text in file:
|
|
8686
|
-
${search}`);
|
|
8687
|
-
};
|
|
8688
|
-
let updatedFile = fileContent;
|
|
8689
|
-
for (const { search, replace } of blocks) {
|
|
8690
|
-
updatedFile = findAndReplace(updatedFile, search, replace);
|
|
8691
|
-
}
|
|
8692
|
-
return updatedFile;
|
|
8693
|
-
};
|
|
8694
|
-
// src/tools/utils/getArg.ts
|
|
8695
|
-
var getString = (args, name, defaultValue) => {
|
|
8696
|
-
const ret = args[name] ?? defaultValue;
|
|
8697
|
-
if (ret === undefined) {
|
|
8698
|
-
throw new Error(`Missing required argument: ${name}`);
|
|
8699
|
-
}
|
|
8700
|
-
return ret;
|
|
8701
|
-
};
|
|
8702
|
-
var getStringArray = (args, name, defaultValue) => {
|
|
8703
|
-
const ret = args[name];
|
|
8704
|
-
if (ret === undefined) {
|
|
8705
|
-
if (defaultValue === undefined) {
|
|
8706
|
-
throw new Error(`Missing required argument: ${name}`);
|
|
8707
|
-
}
|
|
8708
|
-
return defaultValue;
|
|
8709
|
-
}
|
|
8710
|
-
if (ret === "") {
|
|
8711
|
-
return [];
|
|
8712
|
-
}
|
|
8713
|
-
return ret.split(",").map((s) => s.trim());
|
|
8714
|
-
};
|
|
8715
|
-
var getBoolean = (args, name, defaultValue) => {
|
|
8716
|
-
const ret = args[name];
|
|
8717
|
-
if (ret === undefined) {
|
|
8718
|
-
if (defaultValue === undefined) {
|
|
8719
|
-
throw new Error(`Missing required argument: ${name}`);
|
|
8720
|
-
}
|
|
8721
|
-
return defaultValue;
|
|
8722
|
-
}
|
|
8723
|
-
switch (ret.toLowerCase()) {
|
|
8724
|
-
case "true":
|
|
8725
|
-
return true;
|
|
8726
|
-
case "false":
|
|
8727
|
-
return false;
|
|
8728
|
-
default:
|
|
8729
|
-
throw new Error(`Invalid argument value: ${name}`);
|
|
8730
|
-
}
|
|
8731
|
-
};
|
|
8732
|
-
var getInt = (args, name, defaultValue) => {
|
|
8733
|
-
const ret = args[name];
|
|
8734
|
-
if (ret === undefined) {
|
|
8735
|
-
if (defaultValue === undefined) {
|
|
8736
|
-
throw new Error(`Missing required argument: ${name}`);
|
|
8737
|
-
}
|
|
8738
|
-
return defaultValue;
|
|
8739
|
-
}
|
|
8740
|
-
const parsed = Number.parseInt(ret);
|
|
8741
|
-
if (Number.isNaN(parsed)) {
|
|
8742
|
-
throw new Error(`Invalid argument value: ${name}`);
|
|
8743
|
-
}
|
|
8744
|
-
return parsed;
|
|
8745
|
-
};
|
|
8746
|
-
// src/tools/askFollowupQuestion.ts
|
|
8747
|
-
var toolInfo = {
|
|
8748
|
-
name: "ask_followup_question",
|
|
8749
|
-
description: "Whenever you need extra details or clarification to complete the task, pose a direct question to the user. Use this tool sparingly to avoid excessive back-and-forth. If helpful, offer multiple-choice options or examples to guide the user’s response.",
|
|
8750
|
-
parameters: [
|
|
8751
|
-
{
|
|
8752
|
-
name: "question",
|
|
8753
|
-
description: "The question to ask the user. This should be a clear, specific question that addresses the information you need.",
|
|
8754
|
-
required: true,
|
|
8755
|
-
usageValue: "Your question here"
|
|
8756
|
-
},
|
|
8757
|
-
{
|
|
8758
|
-
name: "options",
|
|
8759
|
-
description: "A comma separated list of possible answers to the question. If not provided, the user will be prompted to provide an answer.",
|
|
8760
|
-
required: false,
|
|
8761
|
-
usageValue: "A comma separated list of possible answers (optional)"
|
|
8762
|
-
}
|
|
8763
|
-
],
|
|
8764
|
-
examples: [
|
|
8765
|
-
{
|
|
8766
|
-
description: "Request to ask a question",
|
|
8767
|
-
parameters: [
|
|
8768
|
-
{
|
|
8769
|
-
name: "question",
|
|
8770
|
-
value: "What is the name of the project?"
|
|
8771
|
-
}
|
|
8772
|
-
]
|
|
8773
|
-
},
|
|
8774
|
-
{
|
|
8775
|
-
description: "Request to ask a question with options",
|
|
8776
|
-
parameters: [
|
|
8777
|
-
{
|
|
8778
|
-
name: "question",
|
|
8779
|
-
value: "What framework do you use?"
|
|
8780
|
-
},
|
|
8781
|
-
{
|
|
8782
|
-
name: "options",
|
|
8783
|
-
value: "React,Angular,Vue,Svelte"
|
|
8784
|
-
}
|
|
8785
|
-
]
|
|
8786
|
-
}
|
|
8787
|
-
]
|
|
8788
|
-
};
|
|
8789
|
-
var handler = async (provider, args) => {
|
|
8790
|
-
if (!provider.askFollowupQuestion) {
|
|
8791
|
-
return {
|
|
8792
|
-
type: "Error" /* Error */,
|
|
8793
|
-
message: "Not possible to ask followup question. Abort."
|
|
8411
|
+
]
|
|
8412
|
+
};
|
|
8413
|
+
var handler = async (provider, args) => {
|
|
8414
|
+
if (!provider.askFollowupQuestion) {
|
|
8415
|
+
return {
|
|
8416
|
+
type: "Error" /* Error */,
|
|
8417
|
+
message: "Not possible to ask followup question. Abort."
|
|
8794
8418
|
};
|
|
8795
8419
|
}
|
|
8796
8420
|
const question = getString(args, "question");
|
|
@@ -8840,7 +8464,7 @@ var handler2 = async (provider, args) => {
|
|
|
8840
8464
|
if (!moreMessage) {
|
|
8841
8465
|
return {
|
|
8842
8466
|
type: "Exit" /* Exit */,
|
|
8843
|
-
message:
|
|
8467
|
+
message: result
|
|
8844
8468
|
};
|
|
8845
8469
|
}
|
|
8846
8470
|
return {
|
|
@@ -9185,352 +8809,956 @@ return (
|
|
|
9185
8809
|
}
|
|
9186
8810
|
]
|
|
9187
8811
|
};
|
|
9188
|
-
var handler7 = async (provider, args) => {
|
|
9189
|
-
if (!provider.readFile || !provider.writeFile) {
|
|
8812
|
+
var handler7 = async (provider, args) => {
|
|
8813
|
+
if (!provider.readFile || !provider.writeFile) {
|
|
8814
|
+
return {
|
|
8815
|
+
type: "Error" /* Error */,
|
|
8816
|
+
message: "Not possible to replace in file. Abort."
|
|
8817
|
+
};
|
|
8818
|
+
}
|
|
8819
|
+
const path = getString(args, "path");
|
|
8820
|
+
const diff = getString(args, "diff");
|
|
8821
|
+
const fileContent = await provider.readFile(path);
|
|
8822
|
+
const result = await replaceInFile(fileContent, diff);
|
|
8823
|
+
await provider.writeFile(path, result);
|
|
8824
|
+
return {
|
|
8825
|
+
type: "Reply" /* Reply */,
|
|
8826
|
+
message: `<replace_in_file_path>${path}</replace_in_file_path>`
|
|
8827
|
+
};
|
|
8828
|
+
};
|
|
8829
|
+
var isAvailable7 = (provider) => {
|
|
8830
|
+
return !!provider.readFile && !!provider.writeFile;
|
|
8831
|
+
};
|
|
8832
|
+
var replaceInFile_default = {
|
|
8833
|
+
...toolInfo7,
|
|
8834
|
+
handler: handler7,
|
|
8835
|
+
isAvailable: isAvailable7
|
|
8836
|
+
};
|
|
8837
|
+
// src/tools/searchFiles.ts
|
|
8838
|
+
var toolInfo8 = {
|
|
8839
|
+
name: "search_files",
|
|
8840
|
+
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.",
|
|
8841
|
+
parameters: [
|
|
8842
|
+
{
|
|
8843
|
+
name: "path",
|
|
8844
|
+
description: "The path of the directory to search in (relative to the current working directory). This directory will be recursively searched.",
|
|
8845
|
+
required: true,
|
|
8846
|
+
usageValue: "Directory path here"
|
|
8847
|
+
},
|
|
8848
|
+
{
|
|
8849
|
+
name: "regex",
|
|
8850
|
+
description: "The regular expression pattern to search for. Uses Rust regex syntax.",
|
|
8851
|
+
required: true,
|
|
8852
|
+
usageValue: "Your regex pattern here"
|
|
8853
|
+
},
|
|
8854
|
+
{
|
|
8855
|
+
name: "file_pattern",
|
|
8856
|
+
description: 'Glob pattern to filter files (e.g., "*.ts" for TypeScript files). If not provided, it will search all files (*).',
|
|
8857
|
+
required: false,
|
|
8858
|
+
usageValue: "file pattern here (optional)"
|
|
8859
|
+
}
|
|
8860
|
+
],
|
|
8861
|
+
examples: [
|
|
8862
|
+
{
|
|
8863
|
+
description: "Request to perform a regex search across files",
|
|
8864
|
+
parameters: [
|
|
8865
|
+
{
|
|
8866
|
+
name: "path",
|
|
8867
|
+
value: "src"
|
|
8868
|
+
},
|
|
8869
|
+
{
|
|
8870
|
+
name: "regex",
|
|
8871
|
+
value: "^components/"
|
|
8872
|
+
},
|
|
8873
|
+
{
|
|
8874
|
+
name: "file_pattern",
|
|
8875
|
+
value: "*.ts"
|
|
8876
|
+
}
|
|
8877
|
+
]
|
|
8878
|
+
}
|
|
8879
|
+
]
|
|
8880
|
+
};
|
|
8881
|
+
var handler8 = async (provider, args) => {
|
|
8882
|
+
if (!provider.searchFiles) {
|
|
8883
|
+
return {
|
|
8884
|
+
type: "Error" /* Error */,
|
|
8885
|
+
message: "Not possible to search files. Abort."
|
|
8886
|
+
};
|
|
8887
|
+
}
|
|
8888
|
+
const path = getString(args, "path");
|
|
8889
|
+
const regex = getString(args, "regex");
|
|
8890
|
+
const filePattern = getString(args, "file_pattern", "*");
|
|
8891
|
+
const files = await provider.searchFiles(path, regex, filePattern);
|
|
8892
|
+
return {
|
|
8893
|
+
type: "Reply" /* Reply */,
|
|
8894
|
+
message: `<search_files_path>${path}</search_files_path>
|
|
8895
|
+
<search_files_regex>${regex}</search_files_regex>
|
|
8896
|
+
<search_files_file_pattern>${filePattern}</search_files_file_pattern>
|
|
8897
|
+
<search_files_files>
|
|
8898
|
+
${files.join(`
|
|
8899
|
+
`)}
|
|
8900
|
+
</search_files_files>
|
|
8901
|
+
`
|
|
8902
|
+
};
|
|
8903
|
+
};
|
|
8904
|
+
var isAvailable8 = (provider) => {
|
|
8905
|
+
return !!provider.searchFiles;
|
|
8906
|
+
};
|
|
8907
|
+
var searchFiles_default = {
|
|
8908
|
+
...toolInfo8,
|
|
8909
|
+
handler: handler8,
|
|
8910
|
+
isAvailable: isAvailable8
|
|
8911
|
+
};
|
|
8912
|
+
// src/tools/writeToFile.ts
|
|
8913
|
+
var toolInfo9 = {
|
|
8914
|
+
name: "write_to_file",
|
|
8915
|
+
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.",
|
|
8916
|
+
parameters: [
|
|
8917
|
+
{
|
|
8918
|
+
name: "path",
|
|
8919
|
+
description: "The path of the file to write to",
|
|
8920
|
+
required: true,
|
|
8921
|
+
usageValue: "File path here"
|
|
8922
|
+
},
|
|
8923
|
+
{
|
|
8924
|
+
name: "content",
|
|
8925
|
+
description: "The content to write to the file. ALWAYS provide the COMPLETE intended content of the file, without any truncation or omissions. You MUST include ALL parts of the file, even if they haven't been modified.",
|
|
8926
|
+
required: true,
|
|
8927
|
+
usageValue: "Your file content here"
|
|
8928
|
+
}
|
|
8929
|
+
],
|
|
8930
|
+
examples: [
|
|
8931
|
+
{
|
|
8932
|
+
description: "Request to write content to a file",
|
|
8933
|
+
parameters: [
|
|
8934
|
+
{
|
|
8935
|
+
name: "path",
|
|
8936
|
+
value: "src/main.js"
|
|
8937
|
+
},
|
|
8938
|
+
{
|
|
8939
|
+
name: "content",
|
|
8940
|
+
value: `import React from 'react';
|
|
8941
|
+
|
|
8942
|
+
function App() {
|
|
8943
|
+
return (
|
|
8944
|
+
<div>
|
|
8945
|
+
<h1>Hello, World!</h1>
|
|
8946
|
+
</div>
|
|
8947
|
+
);
|
|
8948
|
+
}
|
|
8949
|
+
|
|
8950
|
+
export default App;
|
|
8951
|
+
`
|
|
8952
|
+
}
|
|
8953
|
+
]
|
|
8954
|
+
}
|
|
8955
|
+
]
|
|
8956
|
+
};
|
|
8957
|
+
var handler9 = async (provider, args) => {
|
|
8958
|
+
if (!provider.writeFile) {
|
|
8959
|
+
return {
|
|
8960
|
+
type: "Error" /* Error */,
|
|
8961
|
+
message: "Not possible to write file. Abort."
|
|
8962
|
+
};
|
|
8963
|
+
}
|
|
8964
|
+
const path = getString(args, "path");
|
|
8965
|
+
const content = getString(args, "content");
|
|
8966
|
+
await provider.writeFile(path, content);
|
|
8967
|
+
return {
|
|
8968
|
+
type: "Reply" /* Reply */,
|
|
8969
|
+
message: `<write_to_file_path>${path}</write_to_file_path><status>Success</status>`
|
|
8970
|
+
};
|
|
8971
|
+
};
|
|
8972
|
+
var isAvailable9 = (provider) => {
|
|
8973
|
+
return !!provider.writeFile;
|
|
8974
|
+
};
|
|
8975
|
+
var writeToFile_default = {
|
|
8976
|
+
...toolInfo9,
|
|
8977
|
+
handler: handler9,
|
|
8978
|
+
isAvailable: isAvailable9
|
|
8979
|
+
};
|
|
8980
|
+
// src/tools/handOver.ts
|
|
8981
|
+
var toolInfo10 = {
|
|
8982
|
+
name: "hand_over",
|
|
8983
|
+
description: "Hand over the current task to another agent to complete",
|
|
8984
|
+
parameters: [
|
|
8985
|
+
{
|
|
8986
|
+
name: "agent_name",
|
|
8987
|
+
description: "The name of the agent to hand over the task to",
|
|
8988
|
+
required: true,
|
|
8989
|
+
usageValue: "Name of the target agent"
|
|
8990
|
+
},
|
|
8991
|
+
{
|
|
8992
|
+
name: "task",
|
|
8993
|
+
description: "The task to be completed by the target agent",
|
|
8994
|
+
required: true,
|
|
8995
|
+
usageValue: "Task description"
|
|
8996
|
+
},
|
|
8997
|
+
{
|
|
8998
|
+
name: "context",
|
|
8999
|
+
description: "The context information for the task",
|
|
9000
|
+
required: true,
|
|
9001
|
+
usageValue: "Context information"
|
|
9002
|
+
},
|
|
9003
|
+
{
|
|
9004
|
+
name: "files",
|
|
9005
|
+
description: "The files relevant to the task",
|
|
9006
|
+
required: false,
|
|
9007
|
+
usageValue: "Relevant files"
|
|
9008
|
+
}
|
|
9009
|
+
],
|
|
9010
|
+
examples: [
|
|
9011
|
+
{
|
|
9012
|
+
description: "Hand over a coding task to the coder agent",
|
|
9013
|
+
parameters: [
|
|
9014
|
+
{
|
|
9015
|
+
name: "agent_name",
|
|
9016
|
+
value: "coder"
|
|
9017
|
+
},
|
|
9018
|
+
{
|
|
9019
|
+
name: "task",
|
|
9020
|
+
value: "Implement the login feature"
|
|
9021
|
+
},
|
|
9022
|
+
{
|
|
9023
|
+
name: "context",
|
|
9024
|
+
value: "We need a secure login system with email and password"
|
|
9025
|
+
},
|
|
9026
|
+
{
|
|
9027
|
+
name: "files",
|
|
9028
|
+
value: "src/auth/login.ts,src/auth/types.ts"
|
|
9029
|
+
}
|
|
9030
|
+
]
|
|
9031
|
+
}
|
|
9032
|
+
]
|
|
9033
|
+
};
|
|
9034
|
+
var handler10 = async (_provider, args) => {
|
|
9035
|
+
const agentName = getString(args, "agent_name");
|
|
9036
|
+
const task = getString(args, "task");
|
|
9037
|
+
const context = getString(args, "context", undefined);
|
|
9038
|
+
const files = getStringArray(args, "files", []);
|
|
9039
|
+
return {
|
|
9040
|
+
type: "HandOver" /* HandOver */,
|
|
9041
|
+
agentName,
|
|
9042
|
+
task,
|
|
9043
|
+
context,
|
|
9044
|
+
files
|
|
9045
|
+
};
|
|
9046
|
+
};
|
|
9047
|
+
var isAvailable10 = (_provider) => {
|
|
9048
|
+
return true;
|
|
9049
|
+
};
|
|
9050
|
+
var handOver_default = {
|
|
9051
|
+
...toolInfo10,
|
|
9052
|
+
handler: handler10,
|
|
9053
|
+
isAvailable: isAvailable10
|
|
9054
|
+
};
|
|
9055
|
+
// src/tools/removeFile.ts
|
|
9056
|
+
var toolInfo11 = {
|
|
9057
|
+
name: "remove_file",
|
|
9058
|
+
description: "Request to remove a file at the specified path.",
|
|
9059
|
+
parameters: [
|
|
9060
|
+
{
|
|
9061
|
+
name: "path",
|
|
9062
|
+
description: "The path of the file to remove",
|
|
9063
|
+
required: true,
|
|
9064
|
+
usageValue: "File path here"
|
|
9065
|
+
}
|
|
9066
|
+
],
|
|
9067
|
+
examples: [
|
|
9068
|
+
{
|
|
9069
|
+
description: "Request to remove a file",
|
|
9070
|
+
parameters: [
|
|
9071
|
+
{
|
|
9072
|
+
name: "path",
|
|
9073
|
+
value: "src/main.js"
|
|
9074
|
+
}
|
|
9075
|
+
]
|
|
9076
|
+
}
|
|
9077
|
+
]
|
|
9078
|
+
};
|
|
9079
|
+
var handler11 = async (provider, args) => {
|
|
9080
|
+
if (!provider.removeFile) {
|
|
9190
9081
|
return {
|
|
9191
9082
|
type: "Error" /* Error */,
|
|
9192
|
-
message: "Not possible to
|
|
9083
|
+
message: "Not possible to remove file. Abort."
|
|
9193
9084
|
};
|
|
9194
9085
|
}
|
|
9195
9086
|
const path = getString(args, "path");
|
|
9196
|
-
|
|
9197
|
-
const fileContent = await provider.readFile(path);
|
|
9198
|
-
const result = await replaceInFile(fileContent, diff);
|
|
9199
|
-
await provider.writeFile(path, result);
|
|
9087
|
+
await provider.removeFile(path);
|
|
9200
9088
|
return {
|
|
9201
9089
|
type: "Reply" /* Reply */,
|
|
9202
|
-
message: `<
|
|
9090
|
+
message: `<remove_file_path>${path}</remove_file_path><status>Success</status>`
|
|
9203
9091
|
};
|
|
9204
9092
|
};
|
|
9205
|
-
var
|
|
9206
|
-
return !!provider.
|
|
9093
|
+
var isAvailable11 = (provider) => {
|
|
9094
|
+
return !!provider.removeFile;
|
|
9207
9095
|
};
|
|
9208
|
-
var
|
|
9209
|
-
...
|
|
9210
|
-
handler:
|
|
9211
|
-
isAvailable:
|
|
9096
|
+
var removeFile_default = {
|
|
9097
|
+
...toolInfo11,
|
|
9098
|
+
handler: handler11,
|
|
9099
|
+
isAvailable: isAvailable11
|
|
9212
9100
|
};
|
|
9213
|
-
// src/tools/
|
|
9214
|
-
var
|
|
9215
|
-
name: "
|
|
9216
|
-
description: "Request to
|
|
9101
|
+
// src/tools/renameFile.ts
|
|
9102
|
+
var toolInfo12 = {
|
|
9103
|
+
name: "rename_file",
|
|
9104
|
+
description: "Request to rename a file from source path to target path.",
|
|
9217
9105
|
parameters: [
|
|
9218
9106
|
{
|
|
9219
|
-
name: "
|
|
9220
|
-
description: "The path of the
|
|
9107
|
+
name: "sourcePath",
|
|
9108
|
+
description: "The current path of the file",
|
|
9221
9109
|
required: true,
|
|
9222
|
-
usageValue: "
|
|
9110
|
+
usageValue: "Source file path here"
|
|
9223
9111
|
},
|
|
9224
9112
|
{
|
|
9225
|
-
name: "
|
|
9226
|
-
description: "The
|
|
9113
|
+
name: "targetPath",
|
|
9114
|
+
description: "The new path for the file",
|
|
9227
9115
|
required: true,
|
|
9228
|
-
usageValue: "
|
|
9229
|
-
},
|
|
9230
|
-
{
|
|
9231
|
-
name: "file_pattern",
|
|
9232
|
-
description: 'Glob pattern to filter files (e.g., "*.ts" for TypeScript files). If not provided, it will search all files (*).',
|
|
9233
|
-
required: false,
|
|
9234
|
-
usageValue: "file pattern here (optional)"
|
|
9116
|
+
usageValue: "Target file path here"
|
|
9235
9117
|
}
|
|
9236
9118
|
],
|
|
9237
9119
|
examples: [
|
|
9238
9120
|
{
|
|
9239
|
-
description: "Request to
|
|
9121
|
+
description: "Request to rename a file",
|
|
9240
9122
|
parameters: [
|
|
9241
9123
|
{
|
|
9242
|
-
name: "
|
|
9243
|
-
value: "src"
|
|
9244
|
-
},
|
|
9245
|
-
{
|
|
9246
|
-
name: "regex",
|
|
9247
|
-
value: "^components/"
|
|
9124
|
+
name: "sourcePath",
|
|
9125
|
+
value: "src/old-name.js"
|
|
9248
9126
|
},
|
|
9249
9127
|
{
|
|
9250
|
-
name: "
|
|
9251
|
-
value: "
|
|
9128
|
+
name: "targetPath",
|
|
9129
|
+
value: "src/new-name.js"
|
|
9252
9130
|
}
|
|
9253
9131
|
]
|
|
9254
9132
|
}
|
|
9255
9133
|
]
|
|
9256
9134
|
};
|
|
9257
|
-
var
|
|
9258
|
-
if (!provider.
|
|
9259
|
-
return {
|
|
9260
|
-
type: "Error" /* Error */,
|
|
9261
|
-
message: "Not possible to
|
|
9262
|
-
};
|
|
9263
|
-
}
|
|
9264
|
-
const
|
|
9265
|
-
const
|
|
9266
|
-
|
|
9267
|
-
|
|
9268
|
-
|
|
9269
|
-
|
|
9270
|
-
|
|
9271
|
-
|
|
9272
|
-
|
|
9273
|
-
|
|
9274
|
-
|
|
9135
|
+
var handler12 = async (provider, args) => {
|
|
9136
|
+
if (!provider.renameFile) {
|
|
9137
|
+
return {
|
|
9138
|
+
type: "Error" /* Error */,
|
|
9139
|
+
message: "Not possible to rename file. Abort."
|
|
9140
|
+
};
|
|
9141
|
+
}
|
|
9142
|
+
const sourcePath = getString(args, "sourcePath");
|
|
9143
|
+
const targetPath = getString(args, "targetPath");
|
|
9144
|
+
await provider.renameFile(sourcePath, targetPath);
|
|
9145
|
+
return {
|
|
9146
|
+
type: "Reply" /* Reply */,
|
|
9147
|
+
message: `<rename_file_path>${targetPath}</rename_file_path><status>Success</status>`
|
|
9148
|
+
};
|
|
9149
|
+
};
|
|
9150
|
+
var isAvailable12 = (provider) => {
|
|
9151
|
+
return !!provider.renameFile;
|
|
9152
|
+
};
|
|
9153
|
+
var renameFile_default = {
|
|
9154
|
+
...toolInfo12,
|
|
9155
|
+
handler: handler12,
|
|
9156
|
+
isAvailable: isAvailable12
|
|
9157
|
+
};
|
|
9158
|
+
// src/Agent/parseAssistantMessage.ts
|
|
9159
|
+
function parseAssistantMessage(assistantMessage, tools, toolNamePrefix) {
|
|
9160
|
+
const parameterPrefix = `${toolNamePrefix}parameter_`;
|
|
9161
|
+
const results = [];
|
|
9162
|
+
const toolTags = tools.map((tool) => `${toolNamePrefix}${tool.name}`);
|
|
9163
|
+
const toolPattern = toolTags.join("|");
|
|
9164
|
+
let remainingMessage = assistantMessage;
|
|
9165
|
+
let match;
|
|
9166
|
+
const tagRegex = new RegExp(`<(${toolPattern})>([\\s\\S]*?)<\\/\\1>`, "s");
|
|
9167
|
+
while (true) {
|
|
9168
|
+
match = tagRegex.exec(remainingMessage);
|
|
9169
|
+
if (match === null)
|
|
9170
|
+
break;
|
|
9171
|
+
const beforeTag = remainingMessage.slice(0, match.index).trim();
|
|
9172
|
+
if (beforeTag) {
|
|
9173
|
+
results.push({
|
|
9174
|
+
type: "text",
|
|
9175
|
+
content: beforeTag
|
|
9176
|
+
});
|
|
9177
|
+
}
|
|
9178
|
+
const tagName = match[1];
|
|
9179
|
+
const toolName = tagName.replace(toolNamePrefix, "");
|
|
9180
|
+
const tool = tools.find((t) => t.name === toolName);
|
|
9181
|
+
const fullTagContent = match[0];
|
|
9182
|
+
if (tool) {
|
|
9183
|
+
const params = {};
|
|
9184
|
+
for (const param of tool.parameters) {
|
|
9185
|
+
const paramName = `${parameterPrefix}${param.name}`;
|
|
9186
|
+
const escapedParamName = paramName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
9187
|
+
const paramPattern = `<${escapedParamName}>([\\s\\S]*?)<\\/${escapedParamName}>`;
|
|
9188
|
+
const paramMatch = fullTagContent.match(new RegExp(paramPattern, "s"));
|
|
9189
|
+
if (paramMatch) {
|
|
9190
|
+
params[param.name] = paramMatch[1].trim();
|
|
9191
|
+
}
|
|
9192
|
+
}
|
|
9193
|
+
results.push({
|
|
9194
|
+
type: "tool_use",
|
|
9195
|
+
name: toolName,
|
|
9196
|
+
params
|
|
9197
|
+
});
|
|
9198
|
+
} else {
|
|
9199
|
+
results.push({
|
|
9200
|
+
type: "text",
|
|
9201
|
+
content: fullTagContent
|
|
9202
|
+
});
|
|
9203
|
+
}
|
|
9204
|
+
remainingMessage = remainingMessage.slice(match.index + fullTagContent.length);
|
|
9205
|
+
}
|
|
9206
|
+
if (remainingMessage.trim()) {
|
|
9207
|
+
results.push({
|
|
9208
|
+
type: "text",
|
|
9209
|
+
content: remainingMessage.trim()
|
|
9210
|
+
});
|
|
9211
|
+
}
|
|
9212
|
+
if (results.length === 0) {
|
|
9213
|
+
results.push({
|
|
9214
|
+
type: "text",
|
|
9215
|
+
content: assistantMessage
|
|
9216
|
+
});
|
|
9217
|
+
}
|
|
9218
|
+
return results;
|
|
9219
|
+
}
|
|
9220
|
+
|
|
9221
|
+
// src/Agent/prompts.ts
|
|
9222
|
+
var toolInfoPrompt = (tool, toolNamePrefix, parameterPrefix) => `
|
|
9223
|
+
## ${toolNamePrefix}${tool.name}
|
|
9224
|
+
|
|
9225
|
+
Description: ${tool.description}
|
|
9226
|
+
|
|
9227
|
+
Parameters:
|
|
9228
|
+
${tool.parameters.map((param) => `- ${parameterPrefix}${param.name}: (${param.required ? "required" : "optional"}) ${param.description}`).join(`
|
|
9229
|
+
`)}
|
|
9230
|
+
|
|
9231
|
+
Usage:
|
|
9232
|
+
<${toolNamePrefix}${tool.name}>
|
|
9233
|
+
${tool.parameters.map((param) => `<${parameterPrefix}${param.name}>${param.usageValue}</${parameterPrefix}${param.name}>`).join(`
|
|
9234
|
+
`)}
|
|
9235
|
+
</${toolNamePrefix}${tool.name}>`;
|
|
9236
|
+
var toolInfoExamplesPrompt = (idx, tool, example, toolNamePrefix, parameterPrefix) => `
|
|
9237
|
+
## Example ${idx + 1}: ${example.description}
|
|
9238
|
+
|
|
9239
|
+
<${toolNamePrefix}${tool.name}>
|
|
9240
|
+
${example.parameters.map((param) => `<${parameterPrefix}${param.name}>${param.value}</${parameterPrefix}${param.name}>`).join(`
|
|
9241
|
+
`)}
|
|
9242
|
+
</${toolNamePrefix}${tool.name}>
|
|
9243
|
+
`;
|
|
9244
|
+
var toolUsePrompt = (tools, toolNamePrefix) => {
|
|
9245
|
+
if (tools.length === 0) {
|
|
9246
|
+
return "";
|
|
9247
|
+
}
|
|
9248
|
+
const parameterPrefix = `${toolNamePrefix}parameter_`;
|
|
9249
|
+
let exampleIndex = 0;
|
|
9250
|
+
return `
|
|
9251
|
+
====
|
|
9252
|
+
|
|
9253
|
+
TOOL USE
|
|
9254
|
+
|
|
9255
|
+
You have access to a set of tools that are executed upon the user's approval. You can use one tool per message, and will receive the result of that tool use 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.
|
|
9256
|
+
|
|
9257
|
+
# Tool Use Formatting
|
|
9258
|
+
|
|
9259
|
+
Tool use is formatted using XML-style tags. The tool name is enclosed in opening and closing tags, and each parameter is similarly enclosed within its own set of tags. Here's the structure:
|
|
9260
|
+
|
|
9261
|
+
<${toolNamePrefix}tool_name>
|
|
9262
|
+
<${parameterPrefix}name1>value1</${parameterPrefix}name1>
|
|
9263
|
+
<${parameterPrefix}name2>value2</${parameterPrefix}name2>
|
|
9264
|
+
...
|
|
9265
|
+
</${toolNamePrefix}tool_name>
|
|
9266
|
+
|
|
9267
|
+
For example:
|
|
9268
|
+
|
|
9269
|
+
<${toolNamePrefix}read_file>
|
|
9270
|
+
<${parameterPrefix}path>src/main.js</${parameterPrefix}path>
|
|
9271
|
+
</${toolNamePrefix}read_file>
|
|
9272
|
+
|
|
9273
|
+
Always adhere to this format for the tool use to ensure proper parsing and execution.
|
|
9274
|
+
|
|
9275
|
+
# Tools
|
|
9276
|
+
${tools.map((tool) => toolInfoPrompt(tool, toolNamePrefix, parameterPrefix)).join(`
|
|
9277
|
+
`)}
|
|
9278
|
+
|
|
9279
|
+
# Tool Use Examples
|
|
9280
|
+
${tools.map((tool) => {
|
|
9281
|
+
let promp = "";
|
|
9282
|
+
for (const example of tool.examples ?? []) {
|
|
9283
|
+
promp += toolInfoExamplesPrompt(exampleIndex++, tool, example, toolNamePrefix, parameterPrefix);
|
|
9284
|
+
}
|
|
9285
|
+
return promp;
|
|
9286
|
+
}).join("")}
|
|
9287
|
+
# Tool Use Guidelines
|
|
9288
|
+
|
|
9289
|
+
1. **In \`<thinking>\` tags**, assess what information you have and what you need to proceed.
|
|
9290
|
+
2. **Choose one tool at a time per message** based on the task and its description. Do not assume a tool’s outcome without explicit confirmation.
|
|
9291
|
+
3. **Formulate tool use only in the specified XML format** for each tool.
|
|
9292
|
+
4. **Wait for the user’s response** after each tool use. Do not proceed until you have their confirmation.
|
|
9293
|
+
5. The user’s response may include:
|
|
9294
|
+
- Tool success or failure details
|
|
9295
|
+
- Linter errors
|
|
9296
|
+
- Terminal output or other relevant feedback
|
|
9297
|
+
6. **Never repeat or quote the entire tool command** in your final user-facing message. Summarize outcomes clearly and avoid echoing commands verbatim.
|
|
9298
|
+
7. **Respond concisely** and move the conversation forward. Do not re-issue the same command or re-trigger tool use without necessity.
|
|
9299
|
+
8. Follow these steps **iteratively**, confirming success and addressing issues as you go.
|
|
9300
|
+
|
|
9301
|
+
By adhering to these guidelines:
|
|
9302
|
+
- You maintain clarity without accidentally re-invoking tools.
|
|
9303
|
+
- You confirm each step’s results before proceeding.
|
|
9304
|
+
- You provide only the necessary information in user-facing replies to prevent re-interpretation as new commands.`;
|
|
9305
|
+
};
|
|
9306
|
+
var agentsPrompt = (agents, name) => `
|
|
9307
|
+
====
|
|
9308
|
+
|
|
9309
|
+
AVAILABLE AGENTS
|
|
9310
|
+
|
|
9311
|
+
The following agents are available for task handover:
|
|
9312
|
+
${agents.map((agent) => `
|
|
9313
|
+
- **${agent.name}**
|
|
9314
|
+
- Responsibilities:
|
|
9315
|
+
${agent.responsibilities.map((resp) => ` - ${resp}`).join(`
|
|
9316
|
+
`)}`).join(`
|
|
9275
9317
|
`)}
|
|
9276
|
-
</search_files_files>
|
|
9277
|
-
`
|
|
9278
|
-
};
|
|
9279
|
-
};
|
|
9280
|
-
var isAvailable8 = (provider) => {
|
|
9281
|
-
return !!provider.searchFiles;
|
|
9282
|
-
};
|
|
9283
|
-
var searchFiles_default = {
|
|
9284
|
-
...toolInfo8,
|
|
9285
|
-
handler: handler8,
|
|
9286
|
-
isAvailable: isAvailable8
|
|
9287
|
-
};
|
|
9288
|
-
// src/tools/writeToFile.ts
|
|
9289
|
-
var toolInfo9 = {
|
|
9290
|
-
name: "write_to_file",
|
|
9291
|
-
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.",
|
|
9292
|
-
parameters: [
|
|
9293
|
-
{
|
|
9294
|
-
name: "path",
|
|
9295
|
-
description: "The path of the file to write to",
|
|
9296
|
-
required: true,
|
|
9297
|
-
usageValue: "File path here"
|
|
9298
|
-
},
|
|
9299
|
-
{
|
|
9300
|
-
name: "content",
|
|
9301
|
-
description: "The content to write to the file. ALWAYS provide the COMPLETE intended content of the file, without any truncation or omissions. You MUST include ALL parts of the file, even if they haven't been modified.",
|
|
9302
|
-
required: true,
|
|
9303
|
-
usageValue: "Your file content here"
|
|
9304
|
-
}
|
|
9305
|
-
],
|
|
9306
|
-
examples: [
|
|
9307
|
-
{
|
|
9308
|
-
description: "Request to write content to a file",
|
|
9309
|
-
parameters: [
|
|
9310
|
-
{
|
|
9311
|
-
name: "path",
|
|
9312
|
-
value: "src/main.js"
|
|
9313
|
-
},
|
|
9314
|
-
{
|
|
9315
|
-
name: "content",
|
|
9316
|
-
value: `import React from 'react';
|
|
9317
9318
|
|
|
9318
|
-
|
|
9319
|
-
|
|
9320
|
-
|
|
9321
|
-
|
|
9322
|
-
|
|
9323
|
-
);
|
|
9324
|
-
}
|
|
9319
|
+
- **Current Agent Role**
|
|
9320
|
+
You are currently acting as **${name}**. If you identify the task is beyond your current scope, use the handover tool to transition to the other agent. Include sufficient context so the new agent can seamlessly continue the work.
|
|
9321
|
+
`;
|
|
9322
|
+
var capabilities = (toolNamePrefix) => `
|
|
9323
|
+
====
|
|
9325
9324
|
|
|
9326
|
-
|
|
9327
|
-
|
|
9328
|
-
|
|
9329
|
-
|
|
9330
|
-
|
|
9331
|
-
|
|
9325
|
+
CAPABILITIES
|
|
9326
|
+
|
|
9327
|
+
- You have access to a range of tools to aid you in your work. These tools help you effectively accomplish a wide range of tasks.
|
|
9328
|
+
- When the user initially gives you a task, a recursive list of all filepaths in the current working directory will be included in context. This provides an overview of the project's file structure, offering key insights into the project from directory/file names (how developers conceptualize and organize their code) and file extensions (the language used). This can also guide decision-making on which files to explore further.`;
|
|
9329
|
+
var systemInformation = (info) => `
|
|
9330
|
+
====
|
|
9331
|
+
|
|
9332
|
+
SYSTEM INFORMATION
|
|
9333
|
+
|
|
9334
|
+
Operating System: ${info.os}`;
|
|
9335
|
+
var interactiveMode = (interactive) => {
|
|
9336
|
+
if (interactive) {
|
|
9337
|
+
return `
|
|
9338
|
+
====
|
|
9339
|
+
|
|
9340
|
+
INTERACTIVE MODE
|
|
9341
|
+
|
|
9342
|
+
You are in interactive mode. This means you may ask user questions to gather additional information to complete the task.
|
|
9343
|
+
`;
|
|
9344
|
+
}
|
|
9345
|
+
return `
|
|
9346
|
+
====
|
|
9347
|
+
|
|
9348
|
+
NON-INTERACTIVE MODE
|
|
9349
|
+
|
|
9350
|
+
You are in non-interactive mode. This means you will not be able to ask user questions to gather additional information to complete the task. You should try to use available tools to accomplish the task. If unable to precede further, you may try to end the task and provide a reason.
|
|
9351
|
+
`;
|
|
9332
9352
|
};
|
|
9333
|
-
var
|
|
9334
|
-
|
|
9335
|
-
|
|
9336
|
-
|
|
9337
|
-
|
|
9338
|
-
};
|
|
9353
|
+
var customInstructions = (customInstructions2) => {
|
|
9354
|
+
const joined = customInstructions2.join(`
|
|
9355
|
+
`);
|
|
9356
|
+
if (joined.trim() === "") {
|
|
9357
|
+
return "";
|
|
9339
9358
|
}
|
|
9340
|
-
|
|
9341
|
-
|
|
9342
|
-
|
|
9343
|
-
|
|
9344
|
-
|
|
9345
|
-
|
|
9346
|
-
|
|
9359
|
+
return `
|
|
9360
|
+
====
|
|
9361
|
+
|
|
9362
|
+
USER'S CUSTOM INSTRUCTIONS
|
|
9363
|
+
|
|
9364
|
+
The following additional instructions are provided by the user, and should be followed to the best of your ability without interfering with the TOOL USE guidelines.
|
|
9365
|
+
|
|
9366
|
+
${joined}`;
|
|
9347
9367
|
};
|
|
9348
|
-
var
|
|
9349
|
-
|
|
9368
|
+
var customScripts = (commands) => {
|
|
9369
|
+
const joined = Object.entries(commands).map(([name, command]) => {
|
|
9370
|
+
if (typeof command === "string") {
|
|
9371
|
+
return `- ${name}
|
|
9372
|
+
- Command: \`${command}\``;
|
|
9373
|
+
}
|
|
9374
|
+
return `- ${name}
|
|
9375
|
+
- Command: \`${command.command}\`
|
|
9376
|
+
- Description: ${command.description}`;
|
|
9377
|
+
}).join(`
|
|
9378
|
+
`);
|
|
9379
|
+
if (joined.trim() === "") {
|
|
9380
|
+
return "";
|
|
9381
|
+
}
|
|
9382
|
+
return `
|
|
9383
|
+
====
|
|
9384
|
+
|
|
9385
|
+
USER'S CUSTOM COMMANDS
|
|
9386
|
+
|
|
9387
|
+
The following additional commands are provided by the user, and should be followed to the best of your ability without interfering with the TOOL USE guidelines.
|
|
9388
|
+
|
|
9389
|
+
${joined}`;
|
|
9350
9390
|
};
|
|
9351
|
-
var
|
|
9352
|
-
|
|
9353
|
-
|
|
9354
|
-
|
|
9391
|
+
var responsePrompts = {
|
|
9392
|
+
errorInvokeTool: (tool, error) => `An error occurred while invoking the tool "${tool}": ${error}`,
|
|
9393
|
+
requireUseTool: "Error: You must use a tool before proceeding. Making sure the tool is invoked using xml tags.",
|
|
9394
|
+
toolResults: (tool, result) => `<tool_response>
|
|
9395
|
+
<tool_name>${tool}</tool_name>
|
|
9396
|
+
<tool_result>
|
|
9397
|
+
${result}
|
|
9398
|
+
</tool_result>
|
|
9399
|
+
</tool_response>`
|
|
9355
9400
|
};
|
|
9356
|
-
|
|
9357
|
-
|
|
9358
|
-
|
|
9359
|
-
|
|
9360
|
-
|
|
9361
|
-
|
|
9362
|
-
|
|
9363
|
-
|
|
9364
|
-
|
|
9365
|
-
|
|
9366
|
-
|
|
9367
|
-
|
|
9368
|
-
|
|
9369
|
-
|
|
9370
|
-
|
|
9371
|
-
|
|
9372
|
-
|
|
9373
|
-
|
|
9374
|
-
|
|
9375
|
-
|
|
9376
|
-
|
|
9377
|
-
|
|
9378
|
-
|
|
9379
|
-
|
|
9380
|
-
|
|
9381
|
-
|
|
9382
|
-
|
|
9383
|
-
|
|
9384
|
-
|
|
9385
|
-
|
|
9386
|
-
examples: [
|
|
9387
|
-
{
|
|
9388
|
-
description: "Hand over a coding task to the coder agent",
|
|
9389
|
-
parameters: [
|
|
9390
|
-
{
|
|
9391
|
-
name: "agent_name",
|
|
9392
|
-
value: "Coder"
|
|
9393
|
-
},
|
|
9394
|
-
{
|
|
9395
|
-
name: "task",
|
|
9396
|
-
value: "Implement the login feature"
|
|
9397
|
-
},
|
|
9398
|
-
{
|
|
9399
|
-
name: "context",
|
|
9400
|
-
value: "We need a secure login system with email and password"
|
|
9401
|
-
},
|
|
9402
|
-
{
|
|
9403
|
-
name: "files",
|
|
9404
|
-
value: "src/auth/login.ts,src/auth/types.ts"
|
|
9405
|
-
}
|
|
9406
|
-
]
|
|
9401
|
+
|
|
9402
|
+
// src/Agent/AgentBase.ts
|
|
9403
|
+
var TaskEventKind;
|
|
9404
|
+
((TaskEventKind2) => {
|
|
9405
|
+
TaskEventKind2["StartTask"] = "StartTask";
|
|
9406
|
+
TaskEventKind2["StartRequest"] = "StartRequest";
|
|
9407
|
+
TaskEventKind2["EndRequest"] = "EndRequest";
|
|
9408
|
+
TaskEventKind2["Usage"] = "Usage";
|
|
9409
|
+
TaskEventKind2["Text"] = "Text";
|
|
9410
|
+
TaskEventKind2["Reasoning"] = "Reasoning";
|
|
9411
|
+
TaskEventKind2["ToolUse"] = "ToolUse";
|
|
9412
|
+
TaskEventKind2["ToolReply"] = "ToolReply";
|
|
9413
|
+
TaskEventKind2["ToolInvalid"] = "ToolInvalid";
|
|
9414
|
+
TaskEventKind2["ToolError"] = "ToolError";
|
|
9415
|
+
TaskEventKind2["ToolInterrupted"] = "ToolInterrupted";
|
|
9416
|
+
TaskEventKind2["ToolHandOver"] = "ToolHandOver";
|
|
9417
|
+
TaskEventKind2["UsageExceeded"] = "UsageExceeded";
|
|
9418
|
+
TaskEventKind2["EndTask"] = "EndTask";
|
|
9419
|
+
})(TaskEventKind ||= {});
|
|
9420
|
+
|
|
9421
|
+
class AgentBase {
|
|
9422
|
+
ai;
|
|
9423
|
+
config;
|
|
9424
|
+
handlers;
|
|
9425
|
+
constructor(name, ai, config) {
|
|
9426
|
+
this.ai = ai;
|
|
9427
|
+
if (config.agents && Object.keys(config.agents).length > 0) {
|
|
9428
|
+
const agents = agentsPrompt(config.agents, name);
|
|
9429
|
+
config.systemPrompt += `
|
|
9430
|
+
${agents}`;
|
|
9407
9431
|
}
|
|
9408
|
-
|
|
9409
|
-
};
|
|
9410
|
-
|
|
9411
|
-
|
|
9412
|
-
|
|
9413
|
-
|
|
9414
|
-
|
|
9415
|
-
|
|
9416
|
-
type: "HandOver" /* HandOver */,
|
|
9417
|
-
agentName,
|
|
9432
|
+
this.config = config;
|
|
9433
|
+
const handlers = {};
|
|
9434
|
+
for (const tool of config.tools) {
|
|
9435
|
+
handlers[tool.name] = tool;
|
|
9436
|
+
}
|
|
9437
|
+
this.handlers = handlers;
|
|
9438
|
+
}
|
|
9439
|
+
async startTask({
|
|
9418
9440
|
task,
|
|
9419
9441
|
context,
|
|
9420
|
-
|
|
9421
|
-
};
|
|
9422
|
-
};
|
|
9423
|
-
var isAvailable10 = (_provider) => {
|
|
9424
|
-
return true;
|
|
9425
|
-
};
|
|
9426
|
-
var handOver_default = {
|
|
9427
|
-
...toolInfo10,
|
|
9428
|
-
handler: handler10,
|
|
9429
|
-
isAvailable: isAvailable10
|
|
9430
|
-
};
|
|
9431
|
-
// src/tools/removeFile.ts
|
|
9432
|
-
var toolInfo11 = {
|
|
9433
|
-
name: "remove_file",
|
|
9434
|
-
description: "Request to remove a file at the specified path.",
|
|
9435
|
-
parameters: [
|
|
9436
|
-
{
|
|
9437
|
-
name: "path",
|
|
9438
|
-
description: "The path of the file to remove",
|
|
9439
|
-
required: true,
|
|
9440
|
-
usageValue: "File path here"
|
|
9441
|
-
}
|
|
9442
|
-
],
|
|
9443
|
-
examples: [
|
|
9444
|
-
{
|
|
9445
|
-
description: "Request to remove a file",
|
|
9446
|
-
parameters: [
|
|
9447
|
-
{
|
|
9448
|
-
name: "path",
|
|
9449
|
-
value: "src/main.js"
|
|
9450
|
-
}
|
|
9451
|
-
]
|
|
9442
|
+
callback = () => {
|
|
9452
9443
|
}
|
|
9453
|
-
|
|
9454
|
-
|
|
9455
|
-
|
|
9456
|
-
|
|
9457
|
-
|
|
9458
|
-
|
|
9459
|
-
|
|
9444
|
+
}) {
|
|
9445
|
+
const taskInfo = {
|
|
9446
|
+
messages: [],
|
|
9447
|
+
inputTokens: 0,
|
|
9448
|
+
outputTokens: 0,
|
|
9449
|
+
cacheWriteTokens: 0,
|
|
9450
|
+
cacheReadTokens: 0,
|
|
9451
|
+
totalCost: 0
|
|
9460
9452
|
};
|
|
9453
|
+
let text = `<task>${task}</task>`;
|
|
9454
|
+
if (context) {
|
|
9455
|
+
text += `
|
|
9456
|
+
<context>${context}</context>`;
|
|
9457
|
+
}
|
|
9458
|
+
callback({ kind: "StartTask" /* StartTask */, info: taskInfo, systemPrompt: this.config.systemPrompt });
|
|
9459
|
+
return await this.#processLoop(text, taskInfo, callback);
|
|
9461
9460
|
}
|
|
9462
|
-
|
|
9463
|
-
|
|
9464
|
-
|
|
9465
|
-
|
|
9466
|
-
|
|
9467
|
-
|
|
9468
|
-
}
|
|
9469
|
-
|
|
9470
|
-
|
|
9471
|
-
|
|
9472
|
-
|
|
9473
|
-
|
|
9474
|
-
|
|
9475
|
-
|
|
9476
|
-
};
|
|
9477
|
-
// src/tools/renameFile.ts
|
|
9478
|
-
var toolInfo12 = {
|
|
9479
|
-
name: "rename_file",
|
|
9480
|
-
description: "Request to rename a file from source path to target path.",
|
|
9481
|
-
parameters: [
|
|
9482
|
-
{
|
|
9483
|
-
name: "sourcePath",
|
|
9484
|
-
description: "The current path of the file",
|
|
9485
|
-
required: true,
|
|
9486
|
-
usageValue: "Source file path here"
|
|
9487
|
-
},
|
|
9488
|
-
{
|
|
9489
|
-
name: "targetPath",
|
|
9490
|
-
description: "The new path for the file",
|
|
9491
|
-
required: true,
|
|
9492
|
-
usageValue: "Target file path here"
|
|
9461
|
+
async#processLoop(userMessage, taskInfo, callback) {
|
|
9462
|
+
let nextRequest = userMessage;
|
|
9463
|
+
while (nextRequest) {
|
|
9464
|
+
if (this.ai.usageMeter.isLimitExceeded().result) {
|
|
9465
|
+
callback({ kind: "UsageExceeded" /* UsageExceeded */, info: taskInfo });
|
|
9466
|
+
return [{ type: "UsageExceeded" }, taskInfo];
|
|
9467
|
+
}
|
|
9468
|
+
const response = await this.#request(taskInfo, nextRequest, callback);
|
|
9469
|
+
const [newMessage, exitReason] = await this.#handleResponse(taskInfo, response, callback);
|
|
9470
|
+
if (exitReason) {
|
|
9471
|
+
callback({ kind: "EndTask" /* EndTask */, info: taskInfo });
|
|
9472
|
+
return [exitReason, taskInfo];
|
|
9473
|
+
}
|
|
9474
|
+
nextRequest = newMessage;
|
|
9493
9475
|
}
|
|
9494
|
-
|
|
9495
|
-
|
|
9496
|
-
|
|
9497
|
-
|
|
9498
|
-
|
|
9499
|
-
|
|
9500
|
-
|
|
9501
|
-
|
|
9502
|
-
|
|
9503
|
-
|
|
9504
|
-
|
|
9505
|
-
|
|
9476
|
+
callback({ kind: "EndTask" /* EndTask */, info: taskInfo });
|
|
9477
|
+
return [{ type: "Exit" /* Exit */, message: "Task completed successfully" }, taskInfo];
|
|
9478
|
+
}
|
|
9479
|
+
async continueTask(userMessage, taskInfo, callback = () => {
|
|
9480
|
+
}) {
|
|
9481
|
+
return await this.#processLoop(userMessage, taskInfo, callback);
|
|
9482
|
+
}
|
|
9483
|
+
async#request(info, userMessage, callback) {
|
|
9484
|
+
await callback({ kind: "StartRequest" /* StartRequest */, info, userMessage });
|
|
9485
|
+
info.messages.push({
|
|
9486
|
+
role: "user",
|
|
9487
|
+
content: userMessage
|
|
9488
|
+
});
|
|
9489
|
+
const stream = this.ai.send(this.config.systemPrompt, info.messages);
|
|
9490
|
+
let currentAssistantMessage = "";
|
|
9491
|
+
for await (const chunk of stream) {
|
|
9492
|
+
switch (chunk.type) {
|
|
9493
|
+
case "usage":
|
|
9494
|
+
info.inputTokens = chunk.inputTokens ?? 0;
|
|
9495
|
+
info.outputTokens = chunk.outputTokens ?? 0;
|
|
9496
|
+
info.cacheWriteTokens = chunk.cacheWriteTokens ?? 0;
|
|
9497
|
+
info.cacheReadTokens = chunk.cacheReadTokens ?? 0;
|
|
9498
|
+
info.totalCost = chunk.totalCost;
|
|
9499
|
+
await callback({ kind: "Usage" /* Usage */, info });
|
|
9500
|
+
break;
|
|
9501
|
+
case "text":
|
|
9502
|
+
currentAssistantMessage += chunk.text;
|
|
9503
|
+
await callback({ kind: "Text" /* Text */, info, newText: chunk.text });
|
|
9504
|
+
break;
|
|
9505
|
+
case "reasoning":
|
|
9506
|
+
await callback({ kind: "Reasoning" /* Reasoning */, info, newText: chunk.text });
|
|
9507
|
+
break;
|
|
9508
|
+
}
|
|
9509
|
+
}
|
|
9510
|
+
if (!currentAssistantMessage) {
|
|
9511
|
+
throw new Error("No assistant message received");
|
|
9512
|
+
}
|
|
9513
|
+
info.messages.push({
|
|
9514
|
+
role: "assistant",
|
|
9515
|
+
content: currentAssistantMessage
|
|
9516
|
+
});
|
|
9517
|
+
const ret = parseAssistantMessage(currentAssistantMessage, this.config.tools, this.config.toolNamePrefix);
|
|
9518
|
+
await callback({ kind: "EndRequest" /* EndRequest */, info });
|
|
9519
|
+
return ret;
|
|
9520
|
+
}
|
|
9521
|
+
async#handleResponse(info, response, callback) {
|
|
9522
|
+
const toolReponses = [];
|
|
9523
|
+
outer:
|
|
9524
|
+
for (const content of response) {
|
|
9525
|
+
switch (content.type) {
|
|
9526
|
+
case "text":
|
|
9527
|
+
break;
|
|
9528
|
+
case "tool_use": {
|
|
9529
|
+
await callback({ kind: "ToolUse" /* ToolUse */, info, tool: content.name });
|
|
9530
|
+
const toolResp = await this.#invokeTool(content.name, content.params);
|
|
9531
|
+
switch (toolResp.type) {
|
|
9532
|
+
case "Reply" /* Reply */:
|
|
9533
|
+
await callback({ kind: "ToolReply" /* ToolReply */, info, tool: content.name });
|
|
9534
|
+
toolReponses.push({ tool: content.name, response: toolResp.message });
|
|
9535
|
+
break;
|
|
9536
|
+
case "Exit" /* Exit */:
|
|
9537
|
+
return [undefined, toolResp];
|
|
9538
|
+
case "Invalid" /* Invalid */:
|
|
9539
|
+
await callback({ kind: "ToolInvalid" /* ToolInvalid */, info, tool: content.name });
|
|
9540
|
+
toolReponses.push({ tool: content.name, response: toolResp.message });
|
|
9541
|
+
break outer;
|
|
9542
|
+
case "Error" /* Error */:
|
|
9543
|
+
await callback({ kind: "ToolError" /* ToolError */, info, tool: content.name });
|
|
9544
|
+
toolReponses.push({ tool: content.name, response: toolResp.message });
|
|
9545
|
+
break outer;
|
|
9546
|
+
case "Interrupted" /* Interrupted */:
|
|
9547
|
+
await callback({ kind: "ToolInterrupted" /* ToolInterrupted */, info, tool: content.name });
|
|
9548
|
+
return [undefined, toolResp];
|
|
9549
|
+
case "HandOver" /* HandOver */:
|
|
9550
|
+
await callback({
|
|
9551
|
+
kind: "ToolHandOver" /* ToolHandOver */,
|
|
9552
|
+
info,
|
|
9553
|
+
tool: content.name,
|
|
9554
|
+
agentName: toolResp.agentName,
|
|
9555
|
+
task: toolResp.task,
|
|
9556
|
+
context: toolResp.context,
|
|
9557
|
+
files: toolResp.files
|
|
9558
|
+
});
|
|
9559
|
+
return [undefined, toolResp];
|
|
9560
|
+
}
|
|
9561
|
+
break;
|
|
9562
|
+
}
|
|
9506
9563
|
}
|
|
9507
|
-
|
|
9564
|
+
}
|
|
9565
|
+
if (toolReponses.length === 0 && !this.config.interactive) {
|
|
9566
|
+
return [responsePrompts.requireUseTool, undefined];
|
|
9567
|
+
}
|
|
9568
|
+
const finalResp = toolReponses.map(({ tool, response: response2 }) => responsePrompts.toolResults(tool, response2)).join(`
|
|
9569
|
+
|
|
9570
|
+
`);
|
|
9571
|
+
return [finalResp, undefined];
|
|
9572
|
+
}
|
|
9573
|
+
async#invokeTool(name, args) {
|
|
9574
|
+
try {
|
|
9575
|
+
const handler13 = this.handlers[name]?.handler;
|
|
9576
|
+
if (!handler13) {
|
|
9577
|
+
return {
|
|
9578
|
+
type: "Error" /* Error */,
|
|
9579
|
+
message: responsePrompts.errorInvokeTool(name, "Tool not found"),
|
|
9580
|
+
canRetry: false
|
|
9581
|
+
};
|
|
9582
|
+
}
|
|
9583
|
+
return await handler13(this.config.provider, args);
|
|
9584
|
+
} catch (error) {
|
|
9585
|
+
return {
|
|
9586
|
+
type: "Error" /* Error */,
|
|
9587
|
+
message: responsePrompts.errorInvokeTool(name, error),
|
|
9588
|
+
canRetry: false
|
|
9589
|
+
};
|
|
9508
9590
|
}
|
|
9591
|
+
}
|
|
9592
|
+
get model() {
|
|
9593
|
+
return this.ai.model;
|
|
9594
|
+
}
|
|
9595
|
+
get usage() {
|
|
9596
|
+
return this.ai.usageMeter.usage;
|
|
9597
|
+
}
|
|
9598
|
+
}
|
|
9599
|
+
|
|
9600
|
+
// src/Agent/AnalyzerAgent/prompts.ts
|
|
9601
|
+
var fullSystemPrompt = (info, tools, toolNamePrefix, instructions, scripts, interactive) => `
|
|
9602
|
+
# Analyzer Agent
|
|
9603
|
+
|
|
9604
|
+
## Role
|
|
9605
|
+
You are the **Analyzer** agent, responsible for:
|
|
9606
|
+
1. **Project Structure Analysis** – Understand codebase organization and architecture.
|
|
9607
|
+
2. **Code Pattern Analysis** – Identify common patterns, conventions, and best practices.
|
|
9608
|
+
3. **Dependency Analysis** – Examine project dependencies and their usage.
|
|
9609
|
+
4. **Workflow Analysis** – Understand development tools, scripts, and processes.
|
|
9610
|
+
5. **Documentation Review** – Analyze documentation and code comments.
|
|
9611
|
+
|
|
9612
|
+
> **Note**: The **Analyzer** agent focuses on understanding and analyzing the codebase without making modifications. Your role is to provide insights and understanding that can inform development decisions.
|
|
9613
|
+
|
|
9614
|
+
## Rules
|
|
9615
|
+
1. **Thoroughness**: Conduct comprehensive analysis of relevant project aspects.
|
|
9616
|
+
2. **Pattern Recognition**: Identify recurring patterns, conventions, and architectural decisions.
|
|
9617
|
+
3. **Dependency Mapping**: Track and understand relationships between components.
|
|
9618
|
+
4. **Workflow Understanding**: Analyze build processes, testing approaches, and development tools.
|
|
9619
|
+
5. **Documentation Assessment**: Review documentation quality and completeness.
|
|
9620
|
+
6. **Non-Modification**: Never modify code or files - focus solely on analysis.
|
|
9621
|
+
|
|
9622
|
+
${toolUsePrompt(tools, toolNamePrefix)}
|
|
9623
|
+
${capabilities(toolNamePrefix)}
|
|
9624
|
+
${systemInformation(info)}
|
|
9625
|
+
${customInstructions(instructions)}
|
|
9626
|
+
${customScripts(scripts)}
|
|
9627
|
+
${interactiveMode(interactive)}
|
|
9628
|
+
`;
|
|
9629
|
+
|
|
9630
|
+
// src/Agent/AnalyzerAgent/index.ts
|
|
9631
|
+
class AnalyzerAgent extends AgentBase {
|
|
9632
|
+
constructor(options) {
|
|
9633
|
+
const agentTools = [
|
|
9634
|
+
...options.additionalTools ?? [],
|
|
9635
|
+
askFollowupQuestion_default,
|
|
9636
|
+
attemptCompletion_default,
|
|
9637
|
+
handOver_default,
|
|
9638
|
+
listCodeDefinitionNames_default,
|
|
9639
|
+
listFiles_default,
|
|
9640
|
+
readFile_default,
|
|
9641
|
+
searchFiles_default
|
|
9642
|
+
];
|
|
9643
|
+
const tools = getAvailableTools(options.provider, agentTools);
|
|
9644
|
+
const toolNamePrefix = "tool_";
|
|
9645
|
+
const systemPrompt = fullSystemPrompt({
|
|
9646
|
+
os: options.os
|
|
9647
|
+
}, tools, toolNamePrefix, options.customInstructions ?? [], options.scripts ?? {}, options.interactive);
|
|
9648
|
+
super(analyzerAgentInfo.name, options.ai, {
|
|
9649
|
+
systemPrompt,
|
|
9650
|
+
tools,
|
|
9651
|
+
toolNamePrefix,
|
|
9652
|
+
provider: options.provider,
|
|
9653
|
+
interactive: options.interactive,
|
|
9654
|
+
agents: options.agents
|
|
9655
|
+
});
|
|
9656
|
+
}
|
|
9657
|
+
}
|
|
9658
|
+
var analyzerAgentInfo = {
|
|
9659
|
+
name: "analyzer",
|
|
9660
|
+
responsibilities: [
|
|
9661
|
+
"Analyzing project structure and organization",
|
|
9662
|
+
"Identifying key source code files and their relationships",
|
|
9663
|
+
"Understanding common coding patterns and conventions",
|
|
9664
|
+
"Examining development workflow and tooling",
|
|
9665
|
+
"Analyzing dependencies and their usage patterns"
|
|
9509
9666
|
]
|
|
9510
9667
|
};
|
|
9511
|
-
|
|
9512
|
-
|
|
9513
|
-
|
|
9514
|
-
|
|
9515
|
-
|
|
9516
|
-
|
|
9668
|
+
|
|
9669
|
+
// src/Agent/ArchitectAgent/prompts.ts
|
|
9670
|
+
var fullSystemPrompt2 = (info, tools, toolNamePrefix, instructions, scripts, interactive) => `
|
|
9671
|
+
# Architect Agent
|
|
9672
|
+
|
|
9673
|
+
## Role
|
|
9674
|
+
You are the **Architect** agent, responsible for:
|
|
9675
|
+
1. **Task Analysis** – Understand requirements.
|
|
9676
|
+
2. **File Identification** – Find and select relevant files.
|
|
9677
|
+
3. **File Reading** – Use the provided tools to gather information from these files.
|
|
9678
|
+
4. **Implementation Plan** – Draft a concise plan detailing steps, resources, and dependencies.
|
|
9679
|
+
5. **Review & Improve** – Evaluate and refine the plan.
|
|
9680
|
+
6. **Handover** – Provide the final plan, context, and files to the **Coder** agent.
|
|
9681
|
+
|
|
9682
|
+
> **Note**: The **Architect** agent must not make any direct modifications. Your role is limited to creating the implementation plan and handing it over to the **Coder** agent, who will perform any actual changes.
|
|
9683
|
+
|
|
9684
|
+
## Rules
|
|
9685
|
+
1. **Consistency**: Maintain alignment with the user’s instructions and the system’s objectives at all times.
|
|
9686
|
+
2. **Relevance**: Only read and use files directly related to the task. Avoid unnecessary or tangential information.
|
|
9687
|
+
3. **Conciseness**: Keep all communications and plans succinct, avoiding superfluous or repetitive details.
|
|
9688
|
+
4. **Accuracy**: Ensure the information you gather and any conclusions you draw are correct and verifiable.
|
|
9689
|
+
5. **Clarity**: Present the final plan and any supporting details in a structured and easily understandable format.
|
|
9690
|
+
6. **Minimal Queries**: Ask clarifying questions only when essential, and avoid repeated questioning that does not add value.
|
|
9691
|
+
|
|
9692
|
+
## Steps
|
|
9693
|
+
1. **Analyze Task**
|
|
9694
|
+
- Gather and understand the user’s requirements.
|
|
9695
|
+
- Note any potential constraints or objectives that may influence the plan.
|
|
9696
|
+
|
|
9697
|
+
2. **Identify Relevant Files**
|
|
9698
|
+
- Determine which files or documents are necessary.
|
|
9699
|
+
- Justify why these files are relevant.
|
|
9700
|
+
|
|
9701
|
+
3. **Read Files via Tools**
|
|
9702
|
+
- Utilize the provided tools to access and extract information from the identified files.
|
|
9703
|
+
- Summarize key insights or data for the solution.
|
|
9704
|
+
|
|
9705
|
+
4. **Create Implementation Plan**
|
|
9706
|
+
- Outline tasks, define milestones, and detail resources or dependencies.
|
|
9707
|
+
- Provide clear, concise instructions for each step.
|
|
9708
|
+
|
|
9709
|
+
5. **Review & Improve**
|
|
9710
|
+
- Check the plan for consistency, clarity, and feasibility.
|
|
9711
|
+
- Make adjustments or refinements to ensure accuracy and efficiency.
|
|
9712
|
+
|
|
9713
|
+
6. **Handover**
|
|
9714
|
+
- Deliver the final implementation plan, context, and relevant files to the **Coder** agent.
|
|
9715
|
+
- Provide any additional instructions or clarifications needed for successful implementation.
|
|
9716
|
+
${toolUsePrompt(tools, toolNamePrefix)}
|
|
9717
|
+
${capabilities(toolNamePrefix)}
|
|
9718
|
+
${systemInformation(info)}
|
|
9719
|
+
${customInstructions(instructions)}
|
|
9720
|
+
${customScripts(scripts)}
|
|
9721
|
+
${interactiveMode(interactive)}
|
|
9722
|
+
`;
|
|
9723
|
+
|
|
9724
|
+
// src/Agent/ArchitectAgent/index.ts
|
|
9725
|
+
class ArchitectAgent extends AgentBase {
|
|
9726
|
+
constructor(options) {
|
|
9727
|
+
const agentTools = [
|
|
9728
|
+
...options.additionalTools ?? [],
|
|
9729
|
+
askFollowupQuestion_default,
|
|
9730
|
+
attemptCompletion_default,
|
|
9731
|
+
handOver_default,
|
|
9732
|
+
listCodeDefinitionNames_default,
|
|
9733
|
+
listFiles_default,
|
|
9734
|
+
readFile_default,
|
|
9735
|
+
searchFiles_default
|
|
9736
|
+
];
|
|
9737
|
+
const tools = getAvailableTools(options.provider, agentTools);
|
|
9738
|
+
const toolNamePrefix = "tool_";
|
|
9739
|
+
const systemPrompt = fullSystemPrompt2({
|
|
9740
|
+
os: options.os
|
|
9741
|
+
}, tools, toolNamePrefix, options.customInstructions ?? [], options.scripts ?? {}, options.interactive);
|
|
9742
|
+
super(architectAgentInfo.name, options.ai, {
|
|
9743
|
+
systemPrompt,
|
|
9744
|
+
tools,
|
|
9745
|
+
toolNamePrefix,
|
|
9746
|
+
provider: options.provider,
|
|
9747
|
+
interactive: options.interactive,
|
|
9748
|
+
agents: options.agents
|
|
9749
|
+
});
|
|
9517
9750
|
}
|
|
9518
|
-
|
|
9519
|
-
|
|
9520
|
-
|
|
9521
|
-
|
|
9522
|
-
|
|
9523
|
-
|
|
9524
|
-
|
|
9525
|
-
|
|
9526
|
-
|
|
9527
|
-
return !!provider.renameFile;
|
|
9528
|
-
};
|
|
9529
|
-
var renameFile_default = {
|
|
9530
|
-
...toolInfo12,
|
|
9531
|
-
handler: handler12,
|
|
9532
|
-
isAvailable: isAvailable12
|
|
9751
|
+
}
|
|
9752
|
+
var architectAgentInfo = {
|
|
9753
|
+
name: "architect",
|
|
9754
|
+
responsibilities: [
|
|
9755
|
+
"Analyzing the user’s overall task and requirements.",
|
|
9756
|
+
"Creating plans and making higher-level decisions about system structure and design.",
|
|
9757
|
+
"Reviewing and analyzing existing code or components for maintainability and scalability.",
|
|
9758
|
+
"Laying out the roadmap for implementation."
|
|
9759
|
+
]
|
|
9533
9760
|
};
|
|
9761
|
+
|
|
9534
9762
|
// src/Agent/CoderAgent/prompts.ts
|
|
9535
9763
|
var basePrompt = "You are a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices.";
|
|
9536
9764
|
var editingFilesPrompt = (toolNamePrefix) => `
|
|
@@ -9632,7 +9860,7 @@ You accomplish a given task iteratively, breaking it down into clear steps and w
|
|
|
9632
9860
|
3. Remember, you have extensive capabilities with access to a wide range of tools that can be used in powerful and clever ways as necessary to accomplish each goal. Before calling a tool, do some analysis within <thinking></thinking> tags. First, analyze the file structure provided in environment_details to gain context and insights for proceeding effectively. Then, think about which of the provided tools is the most relevant tool to accomplish the user's task. Next, go through each of the required parameters of the relevant tool and determine if the user has directly provided or given enough information to infer a value. When deciding if the parameter can be inferred, carefully consider all the context to see if it supports a specific value. If all of the required parameters are present or can be reasonably inferred, close the thinking tag and proceed with the tool use.
|
|
9633
9861
|
4. Once you've completed the user's task, you must use the ${toolNamePrefix}attempt_completion tool to present the result of the task to the user.
|
|
9634
9862
|
5. The user may provide feedback, which you can use to make improvements and try again. But DO NOT continue in pointless back and forth conversations, i.e. don't end your responses with questions or offers for further assistance.`;
|
|
9635
|
-
var
|
|
9863
|
+
var fullSystemPrompt3 = (info, tools, toolNamePrefix, instructions, scripts, interactive) => `
|
|
9636
9864
|
${basePrompt}
|
|
9637
9865
|
${toolUsePrompt(tools, toolNamePrefix)}
|
|
9638
9866
|
${editingFilesPrompt(toolNamePrefix)}
|
|
@@ -9651,7 +9879,7 @@ class CoderAgent extends AgentBase {
|
|
|
9651
9879
|
const combinedTools = [...options.additionalTools ?? [], ...Object.values(exports_allTools)];
|
|
9652
9880
|
const tools = getAvailableTools(options.provider, combinedTools);
|
|
9653
9881
|
const toolNamePrefix = "tool_";
|
|
9654
|
-
const systemPrompt =
|
|
9882
|
+
const systemPrompt = fullSystemPrompt3({
|
|
9655
9883
|
os: options.os
|
|
9656
9884
|
}, tools, toolNamePrefix, options.customInstructions ?? [], options.scripts ?? {}, options.interactive);
|
|
9657
9885
|
super(coderAgentInfo.name, options.ai, {
|
|
@@ -9665,7 +9893,7 @@ class CoderAgent extends AgentBase {
|
|
|
9665
9893
|
}
|
|
9666
9894
|
}
|
|
9667
9895
|
var coderAgentInfo = {
|
|
9668
|
-
name: "
|
|
9896
|
+
name: "coder",
|
|
9669
9897
|
responsibilities: [
|
|
9670
9898
|
"Editing and refactoring existing code.",
|
|
9671
9899
|
"Creating new features or modules.",
|
|
@@ -9673,98 +9901,6 @@ var coderAgentInfo = {
|
|
|
9673
9901
|
"Maintaining coding standards, lint rules, and general code quality."
|
|
9674
9902
|
]
|
|
9675
9903
|
};
|
|
9676
|
-
// src/Agent/ArchitectAgent/prompts.ts
|
|
9677
|
-
var fullSystemPrompt2 = (info, tools, toolNamePrefix, instructions, scripts, interactive) => `
|
|
9678
|
-
# Architect Agent
|
|
9679
|
-
|
|
9680
|
-
## Role
|
|
9681
|
-
You are the **Architect** agent, responsible for:
|
|
9682
|
-
1. **Task Analysis** – Understand requirements.
|
|
9683
|
-
2. **File Identification** – Find and select relevant files.
|
|
9684
|
-
3. **File Reading** – Use the provided tools to gather information from these files.
|
|
9685
|
-
4. **Implementation Plan** – Draft a concise plan detailing steps, resources, and dependencies.
|
|
9686
|
-
5. **Review & Improve** – Evaluate and refine the plan.
|
|
9687
|
-
6. **Handover** – Provide the final plan, context, and files to the **Coder** agent.
|
|
9688
|
-
|
|
9689
|
-
> **Note**: The **Architect** agent must not make any direct modifications. Your role is limited to creating the implementation plan and handing it over to the **Coder** agent, who will perform any actual changes.
|
|
9690
|
-
|
|
9691
|
-
## Rules
|
|
9692
|
-
1. **Consistency**: Maintain alignment with the user’s instructions and the system’s objectives at all times.
|
|
9693
|
-
2. **Relevance**: Only read and use files directly related to the task. Avoid unnecessary or tangential information.
|
|
9694
|
-
3. **Conciseness**: Keep all communications and plans succinct, avoiding superfluous or repetitive details.
|
|
9695
|
-
4. **Accuracy**: Ensure the information you gather and any conclusions you draw are correct and verifiable.
|
|
9696
|
-
5. **Clarity**: Present the final plan and any supporting details in a structured and easily understandable format.
|
|
9697
|
-
6. **Minimal Queries**: Ask clarifying questions only when essential, and avoid repeated questioning that does not add value.
|
|
9698
|
-
|
|
9699
|
-
## Steps
|
|
9700
|
-
1. **Analyze Task**
|
|
9701
|
-
- Gather and understand the user’s requirements.
|
|
9702
|
-
- Note any potential constraints or objectives that may influence the plan.
|
|
9703
|
-
|
|
9704
|
-
2. **Identify Relevant Files**
|
|
9705
|
-
- Determine which files or documents are necessary.
|
|
9706
|
-
- Justify why these files are relevant.
|
|
9707
|
-
|
|
9708
|
-
3. **Read Files via Tools**
|
|
9709
|
-
- Utilize the provided tools to access and extract information from the identified files.
|
|
9710
|
-
- Summarize key insights or data for the solution.
|
|
9711
|
-
|
|
9712
|
-
4. **Create Implementation Plan**
|
|
9713
|
-
- Outline tasks, define milestones, and detail resources or dependencies.
|
|
9714
|
-
- Provide clear, concise instructions for each step.
|
|
9715
|
-
|
|
9716
|
-
5. **Review & Improve**
|
|
9717
|
-
- Check the plan for consistency, clarity, and feasibility.
|
|
9718
|
-
- Make adjustments or refinements to ensure accuracy and efficiency.
|
|
9719
|
-
|
|
9720
|
-
6. **Handover**
|
|
9721
|
-
- Deliver the final implementation plan, context, and relevant files to the **Coder** agent.
|
|
9722
|
-
- Provide any additional instructions or clarifications needed for successful implementation.
|
|
9723
|
-
${toolUsePrompt(tools, toolNamePrefix)}
|
|
9724
|
-
${capabilities(toolNamePrefix)}
|
|
9725
|
-
${systemInformation(info)}
|
|
9726
|
-
${customInstructions(instructions)}
|
|
9727
|
-
${customScripts(scripts)}
|
|
9728
|
-
${interactiveMode(interactive)}
|
|
9729
|
-
`;
|
|
9730
|
-
|
|
9731
|
-
// src/Agent/ArchitectAgent/index.ts
|
|
9732
|
-
class ArchitectAgent extends AgentBase {
|
|
9733
|
-
constructor(options) {
|
|
9734
|
-
const agentTools = [
|
|
9735
|
-
...options.additionalTools ?? [],
|
|
9736
|
-
askFollowupQuestion_default,
|
|
9737
|
-
attemptCompletion_default,
|
|
9738
|
-
handOver_default,
|
|
9739
|
-
listCodeDefinitionNames_default,
|
|
9740
|
-
listFiles_default,
|
|
9741
|
-
readFile_default,
|
|
9742
|
-
searchFiles_default
|
|
9743
|
-
];
|
|
9744
|
-
const tools = getAvailableTools(options.provider, agentTools);
|
|
9745
|
-
const toolNamePrefix = "tool_";
|
|
9746
|
-
const systemPrompt = fullSystemPrompt2({
|
|
9747
|
-
os: options.os
|
|
9748
|
-
}, tools, toolNamePrefix, options.customInstructions ?? [], options.scripts ?? {}, options.interactive);
|
|
9749
|
-
super(architectAgentInfo.name, options.ai, {
|
|
9750
|
-
systemPrompt,
|
|
9751
|
-
tools,
|
|
9752
|
-
toolNamePrefix,
|
|
9753
|
-
provider: options.provider,
|
|
9754
|
-
interactive: options.interactive,
|
|
9755
|
-
agents: options.agents
|
|
9756
|
-
});
|
|
9757
|
-
}
|
|
9758
|
-
}
|
|
9759
|
-
var architectAgentInfo = {
|
|
9760
|
-
name: "Architect",
|
|
9761
|
-
responsibilities: [
|
|
9762
|
-
"Analyzing the user’s overall task and requirements.",
|
|
9763
|
-
"Creating plans and making higher-level decisions about system structure and design.",
|
|
9764
|
-
"Reviewing and analyzing existing code or components for maintainability and scalability.",
|
|
9765
|
-
"Laying out the roadmap for implementation."
|
|
9766
|
-
]
|
|
9767
|
-
};
|
|
9768
9904
|
// src/Agent/MultiAgent.ts
|
|
9769
9905
|
class MultiAgent {
|
|
9770
9906
|
#config;
|
|
@@ -9775,30 +9911,19 @@ class MultiAgent {
|
|
|
9775
9911
|
get model() {
|
|
9776
9912
|
return this.#activeAgent?.model;
|
|
9777
9913
|
}
|
|
9778
|
-
async#startTask(agentName, task, context,
|
|
9914
|
+
async#startTask(agentName, task, context, callback) {
|
|
9779
9915
|
this.#activeAgent = await this.#config.createAgent(agentName);
|
|
9780
9916
|
const [exitReason, info] = await this.#activeAgent.startTask({
|
|
9781
9917
|
task,
|
|
9782
9918
|
context,
|
|
9783
|
-
maxIterations,
|
|
9784
9919
|
callback
|
|
9785
9920
|
});
|
|
9786
9921
|
if (typeof exitReason === "string") {
|
|
9787
9922
|
return [exitReason, info];
|
|
9788
9923
|
}
|
|
9789
9924
|
if (exitReason.type === "HandOver") {
|
|
9790
|
-
const
|
|
9791
|
-
|
|
9792
|
-
return ["MaxIterations", info];
|
|
9793
|
-
}
|
|
9794
|
-
const context2 = await this.#config.getContext(agentName, exitReason.context, exitReason.files);
|
|
9795
|
-
const [exitReason2, info2] = await this.#startTask(exitReason.agentName, exitReason.task, context2, remainIteration, callback);
|
|
9796
|
-
info2.inputTokens += info.inputTokens;
|
|
9797
|
-
info2.outputTokens += info.outputTokens;
|
|
9798
|
-
info2.cacheWriteTokens += info.cacheWriteTokens;
|
|
9799
|
-
info2.cacheReadTokens += info.cacheReadTokens;
|
|
9800
|
-
info2.totalCost = (info.totalCost ?? 0) + (info2.totalCost ?? 0);
|
|
9801
|
-
return [exitReason2, info2];
|
|
9925
|
+
const context2 = await this.#config.getContext?.(agentName, exitReason.context, exitReason.files);
|
|
9926
|
+
return await this.#startTask(exitReason.agentName, exitReason.task, context2, callback);
|
|
9802
9927
|
}
|
|
9803
9928
|
return [exitReason, info];
|
|
9804
9929
|
}
|
|
@@ -9806,8 +9931,7 @@ class MultiAgent {
|
|
|
9806
9931
|
if (this.#activeAgent) {
|
|
9807
9932
|
throw new Error("An active agent already exists");
|
|
9808
9933
|
}
|
|
9809
|
-
|
|
9810
|
-
return this.#startTask(options.agentName, options.task, options.context, maxIterations, options.callback);
|
|
9934
|
+
return this.#startTask(options.agentName, options.task, options.context, options.callback);
|
|
9811
9935
|
}
|
|
9812
9936
|
async continueTask(userMessage, taskInfo, callback = () => {
|
|
9813
9937
|
}) {
|
|
@@ -9817,6 +9941,9 @@ class MultiAgent {
|
|
|
9817
9941
|
return this.#activeAgent.continueTask(userMessage, taskInfo, callback);
|
|
9818
9942
|
}
|
|
9819
9943
|
}
|
|
9944
|
+
|
|
9945
|
+
// src/Agent/index.ts
|
|
9946
|
+
var allAgents = [architectAgentInfo, coderAgentInfo, analyzerAgentInfo];
|
|
9820
9947
|
// src/AiTool/generateGitCommitMessage.ts
|
|
9821
9948
|
var prompt = `
|
|
9822
9949
|
You are an advanced assistant specialized in creating concise and accurate Git commit messages. When you receive:
|
|
@@ -9889,6 +10016,9 @@ You are given:
|
|
|
9889
10016
|
|
|
9890
10017
|
Your task:
|
|
9891
10018
|
1. Consider the optional context (if provided).
|
|
10019
|
+
- If an issue number is found, add "Closes #xxx" at the beginning of the PR description
|
|
10020
|
+
- IMPORTANT: Use ONLY the exact format "Closes #xxx" at the beginning of the description
|
|
10021
|
+
- DO NOT use variations like "Closes issue #xxx" or other formats
|
|
9892
10022
|
2. Analyze the combined commit messages and diffs.
|
|
9893
10023
|
3. Produce a single GitHub Pull Request title.
|
|
9894
10024
|
4. Produce a Pull Request description that explains the changes.
|
|
@@ -9924,7 +10054,7 @@ Below is an **example** of the input and output:
|
|
|
9924
10054
|
Example Input:
|
|
9925
10055
|
<tool_input>
|
|
9926
10056
|
<tool_input_branch_name>feature/refactor-logging</tool_input_branch_name>
|
|
9927
|
-
<tool_input_context>Focus on clean code and maintainability</tool_input_context>
|
|
10057
|
+
<tool_input_context>Implementing changes for issue #123 - Focus on clean code and maintainability</tool_input_context>
|
|
9928
10058
|
<tool_input_commit_messages>
|
|
9929
10059
|
Remove debug logs
|
|
9930
10060
|
Refactor order validation logic
|
|
@@ -9945,6 +10075,8 @@ Example Output:
|
|
|
9945
10075
|
<tool_output>
|
|
9946
10076
|
<tool_output_pr_title>Refactor Order Validation and Remove Debug Logs</tool_output_pr_title>
|
|
9947
10077
|
<tool_output_pr_description>
|
|
10078
|
+
closes #123
|
|
10079
|
+
|
|
9948
10080
|
This PR removes unnecessary debug print statements and updates order validation
|
|
9949
10081
|
to use the new validate_and_process method for improved maintainability.
|
|
9950
10082
|
</tool_output_pr_description>
|
|
@@ -9989,21 +10121,102 @@ ${output}`);
|
|
|
9989
10121
|
}
|
|
9990
10122
|
};
|
|
9991
10123
|
|
|
10124
|
+
// src/AiTool/generateProjectConfig.ts
|
|
10125
|
+
var prompt3 = `You are an analyzer agent responsible for examining project files and generating appropriate polkacodes configuration. Your task is to:
|
|
10126
|
+
|
|
10127
|
+
1. Read and analyze the provided files using tool_read_file to understand:
|
|
10128
|
+
- Build tools and package manager (e.g., bun, npm)
|
|
10129
|
+
- Testing frameworks and patterns
|
|
10130
|
+
- Code style tools and rules
|
|
10131
|
+
- Project structure and conventions
|
|
10132
|
+
- Common development workflows
|
|
10133
|
+
|
|
10134
|
+
2. Generate a YAML configuration that captures:
|
|
10135
|
+
- scripts section based on package.json scripts and CI workflows
|
|
10136
|
+
- rules section based on project conventions, tools, and patterns
|
|
10137
|
+
|
|
10138
|
+
3. Use tool_attempt_completion to return the final configuration in this format:
|
|
10139
|
+
|
|
10140
|
+
<tool_attempt_completion>
|
|
10141
|
+
<tool_parameter_result>
|
|
10142
|
+
scripts:
|
|
10143
|
+
test:
|
|
10144
|
+
command: "bun test"
|
|
10145
|
+
description: "Run tests with bun:test"
|
|
10146
|
+
lint:
|
|
10147
|
+
command: "biome check ."
|
|
10148
|
+
description: "Check code style with Biome"
|
|
10149
|
+
|
|
10150
|
+
rules:
|
|
10151
|
+
- "Use \`bun\` as package manager"
|
|
10152
|
+
- "Write tests using bun:test with snapshots"
|
|
10153
|
+
- "Follow Biome code style"
|
|
10154
|
+
</tool_parameter_result>
|
|
10155
|
+
</tool_attempt_completion>
|
|
10156
|
+
|
|
10157
|
+
Focus on:
|
|
10158
|
+
- Package manager and dependency management
|
|
10159
|
+
- Testing frameworks and patterns
|
|
10160
|
+
- Code style and linting rules
|
|
10161
|
+
- File organization and naming conventions
|
|
10162
|
+
- Build and development workflows
|
|
10163
|
+
|
|
10164
|
+
The configuration should accurately reflect the project's structure, tools, and conventions.
|
|
10165
|
+
`;
|
|
10166
|
+
var generateProjectConfig_default = {
|
|
10167
|
+
name: "generateProjectConfig",
|
|
10168
|
+
description: "Analyzes project files to generate polkacodes config sections",
|
|
10169
|
+
prompt: prompt3,
|
|
10170
|
+
formatInput: (params) => {
|
|
10171
|
+
return `<tool_input>
|
|
10172
|
+
${params.join(`
|
|
10173
|
+
`)}
|
|
10174
|
+
</tool_input>`;
|
|
10175
|
+
},
|
|
10176
|
+
parseOutput: (output) => {
|
|
10177
|
+
return output.trim();
|
|
10178
|
+
},
|
|
10179
|
+
agent: "analyzer"
|
|
10180
|
+
};
|
|
10181
|
+
|
|
9992
10182
|
// src/AiTool/index.ts
|
|
9993
10183
|
var executeTool = async (definition, ai, params) => {
|
|
9994
|
-
const { response, usage } = await ai.request(definition.prompt, [
|
|
10184
|
+
const { response, usage } = await ai.request(definition.prompt, [
|
|
10185
|
+
{ role: "user", content: definition.formatInput(params) }
|
|
10186
|
+
]);
|
|
9995
10187
|
return {
|
|
9996
10188
|
response: definition.parseOutput(response),
|
|
9997
10189
|
usage
|
|
9998
10190
|
};
|
|
9999
10191
|
};
|
|
10192
|
+
var executeAgentTool = async (definition, agent, params, callback) => {
|
|
10193
|
+
if (!definition.agent) {
|
|
10194
|
+
throw new Error("Agent not specified");
|
|
10195
|
+
}
|
|
10196
|
+
const [exitReason] = await agent.startTask({
|
|
10197
|
+
agentName: definition.agent,
|
|
10198
|
+
task: definition.prompt,
|
|
10199
|
+
context: definition.formatInput(params),
|
|
10200
|
+
callback
|
|
10201
|
+
});
|
|
10202
|
+
if (exitReason.type === "Exit" /* Exit */) {
|
|
10203
|
+
return definition.parseOutput(exitReason.message);
|
|
10204
|
+
}
|
|
10205
|
+
throw new Error(`Tool execution failed: ${exitReason.type}`);
|
|
10206
|
+
};
|
|
10000
10207
|
var makeTool = (definition) => {
|
|
10001
10208
|
return async (ai, params) => {
|
|
10002
10209
|
return executeTool(definition, ai, params);
|
|
10003
10210
|
};
|
|
10004
10211
|
};
|
|
10212
|
+
var makeAgentTool = (definition) => {
|
|
10213
|
+
return async (agent, params, callback) => {
|
|
10214
|
+
return executeAgentTool(definition, agent, params, callback);
|
|
10215
|
+
};
|
|
10216
|
+
};
|
|
10005
10217
|
var generateGitCommitMessage = makeTool(generateGitCommitMessage_default);
|
|
10006
10218
|
var generateGithubPullRequestDetails = makeTool(generateGithubPullRequestDetails_default);
|
|
10219
|
+
var generateProjectConfig = makeAgentTool(generateProjectConfig_default);
|
|
10007
10220
|
export {
|
|
10008
10221
|
writeToFile_default as writeToFile,
|
|
10009
10222
|
searchFiles_default as searchFiles,
|
|
@@ -10013,14 +10226,17 @@ export {
|
|
|
10013
10226
|
readFile_default as readFile,
|
|
10014
10227
|
openAiModelInfoSaneDefaults,
|
|
10015
10228
|
makeTool,
|
|
10229
|
+
makeAgentTool,
|
|
10016
10230
|
listFiles_default as listFiles,
|
|
10017
10231
|
listCodeDefinitionNames_default as listCodeDefinitionNames,
|
|
10018
10232
|
handOver_default as handOver,
|
|
10019
10233
|
getAvailableTools,
|
|
10234
|
+
generateProjectConfig,
|
|
10020
10235
|
generateGithubPullRequestDetails,
|
|
10021
10236
|
generateGitCommitMessage,
|
|
10022
10237
|
executeTool,
|
|
10023
10238
|
executeCommand_default as executeCommand,
|
|
10239
|
+
executeAgentTool,
|
|
10024
10240
|
defaultModels,
|
|
10025
10241
|
deepSeekModels,
|
|
10026
10242
|
deepSeekDefaultModelId,
|
|
@@ -10031,13 +10247,17 @@ export {
|
|
|
10031
10247
|
architectAgentInfo,
|
|
10032
10248
|
anthropicModels,
|
|
10033
10249
|
anthropicDefaultModelId,
|
|
10250
|
+
analyzerAgentInfo,
|
|
10034
10251
|
exports_allTools as allTools,
|
|
10252
|
+
allAgents,
|
|
10253
|
+
UsageMeter,
|
|
10035
10254
|
ToolResponseType,
|
|
10036
10255
|
TaskEventKind,
|
|
10037
10256
|
MultiAgent,
|
|
10038
10257
|
MockProvider,
|
|
10039
10258
|
CoderAgent,
|
|
10040
10259
|
ArchitectAgent,
|
|
10260
|
+
AnalyzerAgent,
|
|
10041
10261
|
AiServiceProvider,
|
|
10042
10262
|
AgentBase
|
|
10043
10263
|
};
|