@polka-codes/cli 0.4.6 → 0.4.8
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 +4 -0
- package/dist/index.js +1528 -1196
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -24611,7 +24611,7 @@ var require_emoji_regex2 = __commonJS((exports, module) => {
|
|
|
24611
24611
|
});
|
|
24612
24612
|
|
|
24613
24613
|
// src/index.ts
|
|
24614
|
-
var
|
|
24614
|
+
var import_config7 = __toESM(require_config(), 1);
|
|
24615
24615
|
|
|
24616
24616
|
// ../../node_modules/commander/esm.mjs
|
|
24617
24617
|
var import__ = __toESM(require_commander(), 1);
|
|
@@ -24629,7 +24629,7 @@ var {
|
|
|
24629
24629
|
Help
|
|
24630
24630
|
} = import__.default;
|
|
24631
24631
|
// package.json
|
|
24632
|
-
var version = "0.4.
|
|
24632
|
+
var version = "0.4.8";
|
|
24633
24633
|
|
|
24634
24634
|
// ../../node_modules/@anthropic-ai/sdk/version.mjs
|
|
24635
24635
|
var VERSION = "0.36.2";
|
|
@@ -27807,10 +27807,78 @@ Anthropic.Models = Models2;
|
|
|
27807
27807
|
Anthropic.ModelInfosPage = ModelInfosPage;
|
|
27808
27808
|
Anthropic.Beta = Beta;
|
|
27809
27809
|
|
|
27810
|
+
// ../core/src/AiService/UsageMeter.ts
|
|
27811
|
+
class UsageMeter {
|
|
27812
|
+
#usage = {
|
|
27813
|
+
inputTokens: 0,
|
|
27814
|
+
outputTokens: 0,
|
|
27815
|
+
cacheWriteTokens: 0,
|
|
27816
|
+
cacheReadTokens: 0,
|
|
27817
|
+
totalCost: 0
|
|
27818
|
+
};
|
|
27819
|
+
#messageCount = 0;
|
|
27820
|
+
maxCost;
|
|
27821
|
+
maxMessageCount;
|
|
27822
|
+
constructor(options = {}) {
|
|
27823
|
+
this.maxCost = options.maxCost || 1000;
|
|
27824
|
+
this.maxMessageCount = options.maxMessageCount || 1000;
|
|
27825
|
+
}
|
|
27826
|
+
addUsage(usage, model) {
|
|
27827
|
+
this.#usage.inputTokens += usage.inputTokens ?? 0;
|
|
27828
|
+
this.#usage.outputTokens += usage.outputTokens ?? 0;
|
|
27829
|
+
this.#usage.cacheWriteTokens += usage.cacheWriteTokens ?? 0;
|
|
27830
|
+
this.#usage.cacheReadTokens += usage.cacheReadTokens ?? 0;
|
|
27831
|
+
if (!usage.totalCost && model) {
|
|
27832
|
+
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;
|
|
27833
|
+
}
|
|
27834
|
+
this.#usage.totalCost += usage.totalCost ?? 0;
|
|
27835
|
+
}
|
|
27836
|
+
incrementMessageCount(count = 1) {
|
|
27837
|
+
this.#messageCount += count;
|
|
27838
|
+
}
|
|
27839
|
+
isLimitExceeded() {
|
|
27840
|
+
const messageCount = this.#messageCount >= this.maxMessageCount;
|
|
27841
|
+
const cost = this.#usage.totalCost >= this.maxCost;
|
|
27842
|
+
return {
|
|
27843
|
+
messageCount,
|
|
27844
|
+
cost,
|
|
27845
|
+
result: messageCount || cost
|
|
27846
|
+
};
|
|
27847
|
+
}
|
|
27848
|
+
get usage() {
|
|
27849
|
+
return { ...this.#usage };
|
|
27850
|
+
}
|
|
27851
|
+
printUsage() {
|
|
27852
|
+
console.log("Usages:");
|
|
27853
|
+
console.log(`Input tokens: ${this.#usage.inputTokens}`);
|
|
27854
|
+
console.log(`Output tokens: ${this.#usage.outputTokens}`);
|
|
27855
|
+
console.log(`Cache read tokens: ${this.#usage.cacheReadTokens}`);
|
|
27856
|
+
console.log(`Cache write tokens: ${this.#usage.cacheWriteTokens}`);
|
|
27857
|
+
console.log(`Total cost: ${this.#usage.totalCost}`);
|
|
27858
|
+
}
|
|
27859
|
+
}
|
|
27860
|
+
|
|
27810
27861
|
// ../core/src/AiService/AiServiceBase.ts
|
|
27811
27862
|
class AiServiceBase {
|
|
27863
|
+
usageMeter;
|
|
27864
|
+
constructor(usageMeter) {
|
|
27865
|
+
this.usageMeter = usageMeter ?? new UsageMeter;
|
|
27866
|
+
}
|
|
27867
|
+
async* send(systemPrompt, messages) {
|
|
27868
|
+
this.usageMeter.incrementMessageCount();
|
|
27869
|
+
const stream = this.sendImpl(systemPrompt, messages);
|
|
27870
|
+
for await (const chunk of stream) {
|
|
27871
|
+
switch (chunk.type) {
|
|
27872
|
+
case "usage":
|
|
27873
|
+
this.usageMeter.addUsage(chunk, this.model.info);
|
|
27874
|
+
break;
|
|
27875
|
+
}
|
|
27876
|
+
yield chunk;
|
|
27877
|
+
}
|
|
27878
|
+
}
|
|
27812
27879
|
async request(systemPrompt, messages) {
|
|
27813
|
-
|
|
27880
|
+
this.usageMeter.incrementMessageCount();
|
|
27881
|
+
const stream = this.sendImpl(systemPrompt, messages);
|
|
27814
27882
|
const usage = {
|
|
27815
27883
|
inputTokens: 0,
|
|
27816
27884
|
outputTokens: 0,
|
|
@@ -27836,6 +27904,7 @@ class AiServiceBase {
|
|
|
27836
27904
|
reasoning += chunk.text;
|
|
27837
27905
|
}
|
|
27838
27906
|
}
|
|
27907
|
+
this.usageMeter.addUsage(usage, this.model.info);
|
|
27839
27908
|
return {
|
|
27840
27909
|
response: resp,
|
|
27841
27910
|
reasoning,
|
|
@@ -27927,7 +27996,7 @@ class AnthropicService extends AiServiceBase {
|
|
|
27927
27996
|
#client;
|
|
27928
27997
|
model;
|
|
27929
27998
|
constructor(options) {
|
|
27930
|
-
super();
|
|
27999
|
+
super(options.usageMeter);
|
|
27931
28000
|
this.#options = options;
|
|
27932
28001
|
this.#client = new Anthropic({
|
|
27933
28002
|
apiKey: options.apiKey,
|
|
@@ -27939,7 +28008,7 @@ class AnthropicService extends AiServiceBase {
|
|
|
27939
28008
|
info: anthropicModels[id] ?? anthropicModels[anthropicDefaultModelId]
|
|
27940
28009
|
};
|
|
27941
28010
|
}
|
|
27942
|
-
async*
|
|
28011
|
+
async* sendImpl(systemPrompt, messages) {
|
|
27943
28012
|
let stream;
|
|
27944
28013
|
const modelId = this.model.id;
|
|
27945
28014
|
switch (modelId) {
|
|
@@ -32801,7 +32870,7 @@ class DeepSeekService extends AiServiceBase {
|
|
|
32801
32870
|
#client;
|
|
32802
32871
|
model;
|
|
32803
32872
|
constructor(options) {
|
|
32804
|
-
super();
|
|
32873
|
+
super(options.usageMeter);
|
|
32805
32874
|
this.#client = new openai_default({
|
|
32806
32875
|
baseURL: "https://api.deepseek.com/v1",
|
|
32807
32876
|
apiKey: options.apiKey
|
|
@@ -32812,7 +32881,7 @@ class DeepSeekService extends AiServiceBase {
|
|
|
32812
32881
|
info: deepSeekModels[id] ?? deepSeekModels[deepSeekDefaultModelId]
|
|
32813
32882
|
};
|
|
32814
32883
|
}
|
|
32815
|
-
async*
|
|
32884
|
+
async* sendImpl(systemPrompt, messages) {
|
|
32816
32885
|
const openAiMessages = [
|
|
32817
32886
|
{ role: "system", content: systemPrompt },
|
|
32818
32887
|
...convertToOpenAiMessages(messages)
|
|
@@ -32857,7 +32926,7 @@ class OllamaService extends AiServiceBase {
|
|
|
32857
32926
|
#client;
|
|
32858
32927
|
model;
|
|
32859
32928
|
constructor(options) {
|
|
32860
|
-
super();
|
|
32929
|
+
super(options.usageMeter);
|
|
32861
32930
|
this.#client = new openai_default({
|
|
32862
32931
|
baseURL: `${options.baseUrl || "http://localhost:11434"}/v1`,
|
|
32863
32932
|
apiKey: "ollama"
|
|
@@ -32867,7 +32936,7 @@ class OllamaService extends AiServiceBase {
|
|
|
32867
32936
|
info: openAiModelInfoSaneDefaults
|
|
32868
32937
|
};
|
|
32869
32938
|
}
|
|
32870
|
-
async*
|
|
32939
|
+
async* sendImpl(systemPrompt, messages) {
|
|
32871
32940
|
const openAiMessages = [
|
|
32872
32941
|
{ role: "system", content: systemPrompt },
|
|
32873
32942
|
...convertToOpenAiMessages(messages)
|
|
@@ -32896,7 +32965,7 @@ class OpenRouterService extends AiServiceBase {
|
|
|
32896
32965
|
#apiKey;
|
|
32897
32966
|
model;
|
|
32898
32967
|
constructor(options) {
|
|
32899
|
-
super();
|
|
32968
|
+
super(options.usageMeter);
|
|
32900
32969
|
if (!options.model) {
|
|
32901
32970
|
throw new Error("OpenRouter requires a model");
|
|
32902
32971
|
}
|
|
@@ -32917,7 +32986,7 @@ class OpenRouterService extends AiServiceBase {
|
|
|
32917
32986
|
info: {}
|
|
32918
32987
|
};
|
|
32919
32988
|
}
|
|
32920
|
-
async*
|
|
32989
|
+
async* sendImpl(systemPrompt, messages) {
|
|
32921
32990
|
const openAiMessages = [
|
|
32922
32991
|
{ role: "system", content: systemPrompt },
|
|
32923
32992
|
...convertToOpenAiMessages(messages)
|
|
@@ -33070,1099 +33139,671 @@ var createService = (provider, options) => {
|
|
|
33070
33139
|
var getAvailableTools = (provider, allTools) => {
|
|
33071
33140
|
return allTools.filter((tool) => tool.isAvailable(provider));
|
|
33072
33141
|
};
|
|
33142
|
+
// ../core/src/tools/allTools.ts
|
|
33143
|
+
var exports_allTools = {};
|
|
33144
|
+
__export(exports_allTools, {
|
|
33145
|
+
writeToFile: () => writeToFile_default,
|
|
33146
|
+
searchFiles: () => searchFiles_default,
|
|
33147
|
+
replaceInFile: () => replaceInFile_default,
|
|
33148
|
+
renameFile: () => renameFile_default,
|
|
33149
|
+
removeFile: () => removeFile_default,
|
|
33150
|
+
readFile: () => readFile_default,
|
|
33151
|
+
listFiles: () => listFiles_default,
|
|
33152
|
+
listCodeDefinitionNames: () => listCodeDefinitionNames_default,
|
|
33153
|
+
handOver: () => handOver_default,
|
|
33154
|
+
executeCommand: () => executeCommand_default,
|
|
33155
|
+
attemptCompletion: () => attemptCompletion_default,
|
|
33156
|
+
askFollowupQuestion: () => askFollowupQuestion_default
|
|
33157
|
+
});
|
|
33073
33158
|
|
|
33074
|
-
// ../core/src/
|
|
33075
|
-
|
|
33076
|
-
const
|
|
33077
|
-
const
|
|
33078
|
-
|
|
33079
|
-
|
|
33080
|
-
|
|
33081
|
-
|
|
33082
|
-
|
|
33083
|
-
|
|
33084
|
-
|
|
33085
|
-
|
|
33086
|
-
|
|
33087
|
-
|
|
33088
|
-
if (beforeTag) {
|
|
33089
|
-
results.push({
|
|
33090
|
-
type: "text",
|
|
33091
|
-
content: beforeTag
|
|
33092
|
-
});
|
|
33159
|
+
// ../core/src/tools/utils/replaceInFile.ts
|
|
33160
|
+
var replaceInFile = async (fileContent, diff) => {
|
|
33161
|
+
const blockPattern = /<<<<<+ SEARCH\s*\r?\n([\s\S]*?)\r?\n=======[ \t]*\r?\n([\s\S]*?)\r?\n?>>>>>+ REPLACE/g;
|
|
33162
|
+
const blocks = [];
|
|
33163
|
+
for (let match = blockPattern.exec(diff);match !== null; match = blockPattern.exec(diff)) {
|
|
33164
|
+
blocks.push({ search: match[1], replace: match[2] });
|
|
33165
|
+
}
|
|
33166
|
+
if (blocks.length === 0) {
|
|
33167
|
+
throw new Error("No valid diff blocks found.");
|
|
33168
|
+
}
|
|
33169
|
+
const findAndReplace = (content, search, replace) => {
|
|
33170
|
+
let index = content.indexOf(search);
|
|
33171
|
+
if (index !== -1) {
|
|
33172
|
+
return content.slice(0, index) + replace + content.slice(index + search.length);
|
|
33093
33173
|
}
|
|
33094
|
-
const
|
|
33095
|
-
const
|
|
33096
|
-
const
|
|
33097
|
-
|
|
33098
|
-
if (
|
|
33099
|
-
const
|
|
33100
|
-
|
|
33101
|
-
|
|
33102
|
-
|
|
33103
|
-
|
|
33104
|
-
|
|
33105
|
-
|
|
33106
|
-
|
|
33174
|
+
const trimmedSearch = search.trim();
|
|
33175
|
+
const trimmedContent = content.trim();
|
|
33176
|
+
const offset = content.indexOf(trimmedContent);
|
|
33177
|
+
index = trimmedContent.indexOf(trimmedSearch);
|
|
33178
|
+
if (index !== -1) {
|
|
33179
|
+
const absoluteIndex = offset + index;
|
|
33180
|
+
return content.slice(0, absoluteIndex) + replace + content.slice(absoluteIndex + trimmedSearch.length);
|
|
33181
|
+
}
|
|
33182
|
+
const normalizedSearch = trimmedSearch.replace(/\s+/g, " ");
|
|
33183
|
+
const normalizedContent = trimmedContent.replace(/\s+/g, " ");
|
|
33184
|
+
index = normalizedContent.indexOf(normalizedSearch);
|
|
33185
|
+
if (index !== -1) {
|
|
33186
|
+
let runningIndex = 0;
|
|
33187
|
+
let actualPos = offset;
|
|
33188
|
+
for (const segment of trimmedSearch.replace(/\s+/g, " ").split(" ")) {
|
|
33189
|
+
const segIndex = content.indexOf(segment, actualPos);
|
|
33190
|
+
if (segIndex === -1) {
|
|
33191
|
+
break;
|
|
33107
33192
|
}
|
|
33193
|
+
if (runningIndex === 0) {
|
|
33194
|
+
actualPos = segIndex;
|
|
33195
|
+
} else {
|
|
33196
|
+
actualPos = segIndex + segment.length;
|
|
33197
|
+
}
|
|
33198
|
+
runningIndex++;
|
|
33108
33199
|
}
|
|
33109
|
-
|
|
33110
|
-
|
|
33111
|
-
|
|
33112
|
-
|
|
33113
|
-
});
|
|
33114
|
-
} else {
|
|
33115
|
-
results.push({
|
|
33116
|
-
type: "text",
|
|
33117
|
-
content: fullTagContent
|
|
33118
|
-
});
|
|
33200
|
+
const strippedSearch = trimmedSearch.replace(/\s+/g, "");
|
|
33201
|
+
const endPos = actualPos;
|
|
33202
|
+
const startPos = endPos - strippedSearch.length;
|
|
33203
|
+
return content.slice(0, startPos) + replace + content.slice(endPos);
|
|
33119
33204
|
}
|
|
33120
|
-
|
|
33205
|
+
throw new Error(`Could not find the following text in file:
|
|
33206
|
+
${search}`);
|
|
33207
|
+
};
|
|
33208
|
+
let updatedFile = fileContent;
|
|
33209
|
+
for (const { search, replace } of blocks) {
|
|
33210
|
+
updatedFile = findAndReplace(updatedFile, search, replace);
|
|
33121
33211
|
}
|
|
33122
|
-
|
|
33123
|
-
|
|
33124
|
-
|
|
33125
|
-
|
|
33126
|
-
|
|
33212
|
+
return updatedFile;
|
|
33213
|
+
};
|
|
33214
|
+
// ../core/src/tools/utils/getArg.ts
|
|
33215
|
+
var getString = (args, name, defaultValue) => {
|
|
33216
|
+
const ret = args[name] ?? defaultValue;
|
|
33217
|
+
if (ret === undefined) {
|
|
33218
|
+
throw new Error(`Missing required argument: ${name}`);
|
|
33127
33219
|
}
|
|
33128
|
-
|
|
33129
|
-
|
|
33130
|
-
|
|
33131
|
-
|
|
33132
|
-
|
|
33220
|
+
return ret;
|
|
33221
|
+
};
|
|
33222
|
+
var getStringArray = (args, name, defaultValue) => {
|
|
33223
|
+
const ret = args[name];
|
|
33224
|
+
if (ret === undefined) {
|
|
33225
|
+
if (defaultValue === undefined) {
|
|
33226
|
+
throw new Error(`Missing required argument: ${name}`);
|
|
33227
|
+
}
|
|
33228
|
+
return defaultValue;
|
|
33133
33229
|
}
|
|
33134
|
-
|
|
33135
|
-
|
|
33136
|
-
|
|
33137
|
-
// ../core/src/Agent/prompts.ts
|
|
33138
|
-
var toolInfoPrompt = (tool, toolNamePrefix, parameterPrefix) => `
|
|
33139
|
-
## ${toolNamePrefix}${tool.name}
|
|
33140
|
-
|
|
33141
|
-
Description: ${tool.description}
|
|
33142
|
-
|
|
33143
|
-
Parameters:
|
|
33144
|
-
${tool.parameters.map((param) => `- ${parameterPrefix}${param.name}: (${param.required ? "required" : "optional"}) ${param.description}`).join(`
|
|
33145
|
-
`)}
|
|
33146
|
-
|
|
33147
|
-
Usage:
|
|
33148
|
-
<${toolNamePrefix}${tool.name}>
|
|
33149
|
-
${tool.parameters.map((param) => `<${parameterPrefix}${param.name}>${param.usageValue}</${parameterPrefix}${param.name}>`).join(`
|
|
33150
|
-
`)}
|
|
33151
|
-
</${toolNamePrefix}${tool.name}>`;
|
|
33152
|
-
var toolInfoExamplesPrompt = (idx, tool, example, toolNamePrefix, parameterPrefix) => `
|
|
33153
|
-
## Example ${idx + 1}: ${example.description}
|
|
33154
|
-
|
|
33155
|
-
<${toolNamePrefix}${tool.name}>
|
|
33156
|
-
${example.parameters.map((param) => `<${parameterPrefix}${param.name}>${param.value}</${parameterPrefix}${param.name}>`).join(`
|
|
33157
|
-
`)}
|
|
33158
|
-
</${toolNamePrefix}${tool.name}>
|
|
33159
|
-
`;
|
|
33160
|
-
var toolUsePrompt = (tools, toolNamePrefix) => {
|
|
33161
|
-
if (tools.length === 0) {
|
|
33162
|
-
return "";
|
|
33230
|
+
if (ret === "") {
|
|
33231
|
+
return [];
|
|
33163
33232
|
}
|
|
33164
|
-
|
|
33165
|
-
|
|
33166
|
-
|
|
33167
|
-
|
|
33168
|
-
|
|
33169
|
-
|
|
33170
|
-
|
|
33171
|
-
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.
|
|
33172
|
-
|
|
33173
|
-
# Tool Use Formatting
|
|
33174
|
-
|
|
33175
|
-
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:
|
|
33176
|
-
|
|
33177
|
-
<${toolNamePrefix}tool_name>
|
|
33178
|
-
<${parameterPrefix}name1>value1</${parameterPrefix}name1>
|
|
33179
|
-
<${parameterPrefix}name2>value2</${parameterPrefix}name2>
|
|
33180
|
-
...
|
|
33181
|
-
</${toolNamePrefix}tool_name>
|
|
33182
|
-
|
|
33183
|
-
For example:
|
|
33184
|
-
|
|
33185
|
-
<${toolNamePrefix}read_file>
|
|
33186
|
-
<${parameterPrefix}path>src/main.js</${parameterPrefix}path>
|
|
33187
|
-
</${toolNamePrefix}read_file>
|
|
33188
|
-
|
|
33189
|
-
Always adhere to this format for the tool use to ensure proper parsing and execution.
|
|
33190
|
-
|
|
33191
|
-
# Tools
|
|
33192
|
-
${tools.map((tool) => toolInfoPrompt(tool, toolNamePrefix, parameterPrefix)).join(`
|
|
33193
|
-
`)}
|
|
33194
|
-
|
|
33195
|
-
# Tool Use Examples
|
|
33196
|
-
${tools.map((tool) => {
|
|
33197
|
-
let promp = "";
|
|
33198
|
-
for (const example of tool.examples ?? []) {
|
|
33199
|
-
promp += toolInfoExamplesPrompt(exampleIndex++, tool, example, toolNamePrefix, parameterPrefix);
|
|
33233
|
+
return ret.split(",").map((s2) => s2.trim());
|
|
33234
|
+
};
|
|
33235
|
+
var getBoolean = (args, name, defaultValue) => {
|
|
33236
|
+
const ret = args[name];
|
|
33237
|
+
if (ret === undefined) {
|
|
33238
|
+
if (defaultValue === undefined) {
|
|
33239
|
+
throw new Error(`Missing required argument: ${name}`);
|
|
33200
33240
|
}
|
|
33201
|
-
return
|
|
33202
|
-
}).join("")}
|
|
33203
|
-
# Tool Use Guidelines
|
|
33204
|
-
|
|
33205
|
-
1. **In \`<thinking>\` tags**, assess what information you have and what you need to proceed.
|
|
33206
|
-
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.
|
|
33207
|
-
3. **Formulate tool use only in the specified XML format** for each tool.
|
|
33208
|
-
4. **Wait for the user’s response** after each tool use. Do not proceed until you have their confirmation.
|
|
33209
|
-
5. The user’s response may include:
|
|
33210
|
-
- Tool success or failure details
|
|
33211
|
-
- Linter errors
|
|
33212
|
-
- Terminal output or other relevant feedback
|
|
33213
|
-
6. **Never repeat or quote the entire tool command** in your final user-facing message. Summarize outcomes clearly and avoid echoing commands verbatim.
|
|
33214
|
-
7. **Respond concisely** and move the conversation forward. Do not re-issue the same command or re-trigger tool use without necessity.
|
|
33215
|
-
8. Follow these steps **iteratively**, confirming success and addressing issues as you go.
|
|
33216
|
-
|
|
33217
|
-
By adhering to these guidelines:
|
|
33218
|
-
- You maintain clarity without accidentally re-invoking tools.
|
|
33219
|
-
- You confirm each step’s results before proceeding.
|
|
33220
|
-
- You provide only the necessary information in user-facing replies to prevent re-interpretation as new commands.`;
|
|
33221
|
-
};
|
|
33222
|
-
var agentsPrompt = (agents, name) => `
|
|
33223
|
-
====
|
|
33224
|
-
|
|
33225
|
-
AVAILABLE AGENTS
|
|
33226
|
-
|
|
33227
|
-
The following agents are available for task handover:
|
|
33228
|
-
${agents.map((agent) => `
|
|
33229
|
-
- **${agent.name}**
|
|
33230
|
-
- Responsibilities:
|
|
33231
|
-
${agent.responsibilities.map((resp) => ` - ${resp}`).join(`
|
|
33232
|
-
`)}`).join(`
|
|
33233
|
-
`)}
|
|
33234
|
-
|
|
33235
|
-
- **Current Agent Role**
|
|
33236
|
-
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.
|
|
33237
|
-
`;
|
|
33238
|
-
var capabilities = (toolNamePrefix) => `
|
|
33239
|
-
====
|
|
33240
|
-
|
|
33241
|
-
CAPABILITIES
|
|
33242
|
-
|
|
33243
|
-
- 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.
|
|
33244
|
-
- 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.`;
|
|
33245
|
-
var systemInformation = (info) => `
|
|
33246
|
-
====
|
|
33247
|
-
|
|
33248
|
-
SYSTEM INFORMATION
|
|
33249
|
-
|
|
33250
|
-
Operating System: ${info.os}`;
|
|
33251
|
-
var interactiveMode = (interactive) => {
|
|
33252
|
-
if (interactive) {
|
|
33253
|
-
return `
|
|
33254
|
-
====
|
|
33255
|
-
|
|
33256
|
-
INTERACTIVE MODE
|
|
33257
|
-
|
|
33258
|
-
You are in interactive mode. This means you may ask user questions to gather additional information to complete the task.
|
|
33259
|
-
`;
|
|
33241
|
+
return defaultValue;
|
|
33260
33242
|
}
|
|
33261
|
-
|
|
33262
|
-
|
|
33263
|
-
|
|
33264
|
-
|
|
33265
|
-
|
|
33266
|
-
|
|
33267
|
-
|
|
33268
|
-
};
|
|
33269
|
-
var customInstructions = (customInstructions2) => {
|
|
33270
|
-
const joined = customInstructions2.join(`
|
|
33271
|
-
`);
|
|
33272
|
-
if (joined.trim() === "") {
|
|
33273
|
-
return "";
|
|
33243
|
+
switch (ret.toLowerCase()) {
|
|
33244
|
+
case "true":
|
|
33245
|
+
return true;
|
|
33246
|
+
case "false":
|
|
33247
|
+
return false;
|
|
33248
|
+
default:
|
|
33249
|
+
throw new Error(`Invalid argument value: ${name}`);
|
|
33274
33250
|
}
|
|
33275
|
-
return `
|
|
33276
|
-
====
|
|
33277
|
-
|
|
33278
|
-
USER'S CUSTOM INSTRUCTIONS
|
|
33279
|
-
|
|
33280
|
-
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.
|
|
33281
|
-
|
|
33282
|
-
${joined}`;
|
|
33283
33251
|
};
|
|
33284
|
-
var
|
|
33285
|
-
const
|
|
33286
|
-
|
|
33287
|
-
|
|
33288
|
-
|
|
33252
|
+
var getInt = (args, name, defaultValue) => {
|
|
33253
|
+
const ret = args[name];
|
|
33254
|
+
if (ret === undefined) {
|
|
33255
|
+
if (defaultValue === undefined) {
|
|
33256
|
+
throw new Error(`Missing required argument: ${name}`);
|
|
33289
33257
|
}
|
|
33290
|
-
return
|
|
33291
|
-
- Command: \`${command.command}\`
|
|
33292
|
-
- Description: ${command.description}`;
|
|
33293
|
-
}).join(`
|
|
33294
|
-
`);
|
|
33295
|
-
if (joined.trim() === "") {
|
|
33296
|
-
return "";
|
|
33258
|
+
return defaultValue;
|
|
33297
33259
|
}
|
|
33298
|
-
|
|
33299
|
-
|
|
33300
|
-
|
|
33301
|
-
|
|
33302
|
-
|
|
33303
|
-
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.
|
|
33304
|
-
|
|
33305
|
-
${joined}`;
|
|
33306
|
-
};
|
|
33307
|
-
var responsePrompts = {
|
|
33308
|
-
errorInvokeTool: (tool, error) => `An error occurred while invoking the tool "${tool}": ${error}`,
|
|
33309
|
-
requireUseTool: "Error: You must use a tool before proceeding. Making sure the tool is invoked using xml tags.",
|
|
33310
|
-
toolResults: (tool, result) => `<tool_response>
|
|
33311
|
-
<tool_name>${tool}</tool_name>
|
|
33312
|
-
<tool_result>
|
|
33313
|
-
${result}
|
|
33314
|
-
</tool_result>
|
|
33315
|
-
</tool_response>`
|
|
33260
|
+
const parsed = Number.parseInt(ret);
|
|
33261
|
+
if (Number.isNaN(parsed)) {
|
|
33262
|
+
throw new Error(`Invalid argument value: ${name}`);
|
|
33263
|
+
}
|
|
33264
|
+
return parsed;
|
|
33316
33265
|
};
|
|
33317
|
-
|
|
33318
|
-
|
|
33319
|
-
|
|
33320
|
-
|
|
33321
|
-
|
|
33322
|
-
|
|
33323
|
-
|
|
33324
|
-
|
|
33325
|
-
|
|
33326
|
-
|
|
33327
|
-
|
|
33328
|
-
|
|
33266
|
+
// ../core/src/tools/askFollowupQuestion.ts
|
|
33267
|
+
var toolInfo = {
|
|
33268
|
+
name: "ask_followup_question",
|
|
33269
|
+
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.",
|
|
33270
|
+
parameters: [
|
|
33271
|
+
{
|
|
33272
|
+
name: "question",
|
|
33273
|
+
description: "The question to ask the user. This should be a clear, specific question that addresses the information you need.",
|
|
33274
|
+
required: true,
|
|
33275
|
+
usageValue: "Your question here"
|
|
33276
|
+
},
|
|
33277
|
+
{
|
|
33278
|
+
name: "options",
|
|
33279
|
+
description: "A comma separated list of possible answers to the question. If not provided, the user will be prompted to provide an answer.",
|
|
33280
|
+
required: false,
|
|
33281
|
+
usageValue: "A comma separated list of possible answers (optional)"
|
|
33329
33282
|
}
|
|
33330
|
-
|
|
33331
|
-
|
|
33332
|
-
|
|
33333
|
-
|
|
33283
|
+
],
|
|
33284
|
+
examples: [
|
|
33285
|
+
{
|
|
33286
|
+
description: "Request to ask a question",
|
|
33287
|
+
parameters: [
|
|
33288
|
+
{
|
|
33289
|
+
name: "question",
|
|
33290
|
+
value: "What is the name of the project?"
|
|
33291
|
+
}
|
|
33292
|
+
]
|
|
33293
|
+
},
|
|
33294
|
+
{
|
|
33295
|
+
description: "Request to ask a question with options",
|
|
33296
|
+
parameters: [
|
|
33297
|
+
{
|
|
33298
|
+
name: "question",
|
|
33299
|
+
value: "What framework do you use?"
|
|
33300
|
+
},
|
|
33301
|
+
{
|
|
33302
|
+
name: "options",
|
|
33303
|
+
value: "React,Angular,Vue,Svelte"
|
|
33304
|
+
}
|
|
33305
|
+
]
|
|
33334
33306
|
}
|
|
33335
|
-
|
|
33307
|
+
]
|
|
33308
|
+
};
|
|
33309
|
+
var handler = async (provider, args) => {
|
|
33310
|
+
if (!provider.askFollowupQuestion) {
|
|
33311
|
+
return {
|
|
33312
|
+
type: "Error" /* Error */,
|
|
33313
|
+
message: "Not possible to ask followup question. Abort."
|
|
33314
|
+
};
|
|
33336
33315
|
}
|
|
33337
|
-
|
|
33338
|
-
|
|
33339
|
-
|
|
33340
|
-
|
|
33341
|
-
|
|
33316
|
+
const question = getString(args, "question");
|
|
33317
|
+
const options = getStringArray(args, "options", []);
|
|
33318
|
+
const answer = await provider.askFollowupQuestion(question, options);
|
|
33319
|
+
return {
|
|
33320
|
+
type: "Reply" /* Reply */,
|
|
33321
|
+
message: `<ask_followup_question_question>${question}</ask_followup_question_question>
|
|
33322
|
+
<ask_followup_question_answer>${answer}</ask_followup_question_answer>`
|
|
33323
|
+
};
|
|
33324
|
+
};
|
|
33325
|
+
var isAvailable = (provider) => {
|
|
33326
|
+
return !!provider.askFollowupQuestion;
|
|
33327
|
+
};
|
|
33328
|
+
var askFollowupQuestion_default = {
|
|
33329
|
+
...toolInfo,
|
|
33330
|
+
handler,
|
|
33331
|
+
isAvailable
|
|
33332
|
+
};
|
|
33333
|
+
// ../core/src/tools/attemptCompletion.ts
|
|
33334
|
+
var toolInfo2 = {
|
|
33335
|
+
name: "attempt_completion",
|
|
33336
|
+
description: "Use this tool when you believe the user’s requested task is complete. Indicate that your work is finished, but acknowledge the user may still provide additional instructions or questions if they want to continue.",
|
|
33337
|
+
parameters: [
|
|
33338
|
+
{
|
|
33339
|
+
name: "result",
|
|
33340
|
+
description: "The result of the task. Formulate this result in a way that is final and does not require further input from the user. Don't end your result with questions or offers for further assistance.",
|
|
33341
|
+
required: true,
|
|
33342
|
+
usageValue: "Your final result description here"
|
|
33342
33343
|
}
|
|
33343
|
-
|
|
33344
|
-
|
|
33345
|
-
|
|
33344
|
+
],
|
|
33345
|
+
examples: [
|
|
33346
|
+
{
|
|
33347
|
+
description: "Request to present the result of the task",
|
|
33348
|
+
parameters: [
|
|
33349
|
+
{
|
|
33350
|
+
name: "result",
|
|
33351
|
+
value: "Your final result description here"
|
|
33352
|
+
}
|
|
33353
|
+
]
|
|
33346
33354
|
}
|
|
33347
|
-
|
|
33348
|
-
|
|
33349
|
-
|
|
33350
|
-
|
|
33351
|
-
|
|
33352
|
-
|
|
33353
|
-
|
|
33354
|
-
|
|
33355
|
-
|
|
33356
|
-
totalCost: 0
|
|
33355
|
+
]
|
|
33356
|
+
};
|
|
33357
|
+
var handler2 = async (provider, args) => {
|
|
33358
|
+
const result = getString(args, "result");
|
|
33359
|
+
const moreMessage = await provider.attemptCompletion?.(result);
|
|
33360
|
+
if (!moreMessage) {
|
|
33361
|
+
return {
|
|
33362
|
+
type: "Exit" /* Exit */,
|
|
33363
|
+
message: result
|
|
33357
33364
|
};
|
|
33358
|
-
let text = `<task>${task}</task>`;
|
|
33359
|
-
if (context) {
|
|
33360
|
-
text += `
|
|
33361
|
-
<context>${context}</context>`;
|
|
33362
|
-
}
|
|
33363
|
-
callback({ kind: "StartTask" /* StartTask */, info: taskInfo, systemPrompt: this.config.systemPrompt });
|
|
33364
|
-
return await this.#processLoop(text, taskInfo, callback);
|
|
33365
33365
|
}
|
|
33366
|
-
|
|
33367
|
-
|
|
33368
|
-
|
|
33369
|
-
|
|
33370
|
-
|
|
33371
|
-
|
|
33372
|
-
|
|
33373
|
-
|
|
33374
|
-
|
|
33375
|
-
|
|
33376
|
-
|
|
33377
|
-
|
|
33378
|
-
|
|
33379
|
-
|
|
33366
|
+
return {
|
|
33367
|
+
type: "Reply" /* Reply */,
|
|
33368
|
+
message: `<user_message>${moreMessage}</user_message>`
|
|
33369
|
+
};
|
|
33370
|
+
};
|
|
33371
|
+
var isAvailable2 = (provider) => {
|
|
33372
|
+
return true;
|
|
33373
|
+
};
|
|
33374
|
+
var attemptCompletion_default = {
|
|
33375
|
+
...toolInfo2,
|
|
33376
|
+
handler: handler2,
|
|
33377
|
+
isAvailable: isAvailable2
|
|
33378
|
+
};
|
|
33379
|
+
// ../core/src/tools/executeCommand.ts
|
|
33380
|
+
var toolInfo3 = {
|
|
33381
|
+
name: "execute_command",
|
|
33382
|
+
description: `Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Commands will also be executed in the project root directory regardless of executed commands in previous tool uses.`,
|
|
33383
|
+
parameters: [
|
|
33384
|
+
{
|
|
33385
|
+
name: "command",
|
|
33386
|
+
description: "The CLI command to execute. This should be valid for the current operating system. Ensure the command is properly formatted and does not contain any harmful instructions.",
|
|
33387
|
+
required: true,
|
|
33388
|
+
usageValue: "Your command here"
|
|
33389
|
+
},
|
|
33390
|
+
{
|
|
33391
|
+
name: "requires_approval",
|
|
33392
|
+
description: `A boolean indicating whether this command requires explicit user approval before execution in case the user has auto-approve mode enabled. Set to 'true' for potentially impactful operations like installing/uninstalling packages, deleting/overwriting files, system configuration changes, network operations, or any commands that could have unintended side effects. Set to 'false' for safe operations like reading files/directories, running development servers, building projects, and other non-destructive operations.`,
|
|
33393
|
+
required: false,
|
|
33394
|
+
usageValue: "true or false"
|
|
33380
33395
|
}
|
|
33381
|
-
|
|
33382
|
-
|
|
33396
|
+
],
|
|
33397
|
+
examples: [
|
|
33398
|
+
{
|
|
33399
|
+
description: "Request to execute a command",
|
|
33400
|
+
parameters: [
|
|
33401
|
+
{
|
|
33402
|
+
name: "command",
|
|
33403
|
+
value: "npm run dev"
|
|
33404
|
+
},
|
|
33405
|
+
{
|
|
33406
|
+
name: "requires_approval",
|
|
33407
|
+
value: "false"
|
|
33408
|
+
}
|
|
33409
|
+
]
|
|
33410
|
+
}
|
|
33411
|
+
]
|
|
33412
|
+
};
|
|
33413
|
+
var handler3 = async (provider, args) => {
|
|
33414
|
+
if (!provider.executeCommand) {
|
|
33415
|
+
return {
|
|
33416
|
+
type: "Error" /* Error */,
|
|
33417
|
+
message: "Not possible to execute command. Abort."
|
|
33418
|
+
};
|
|
33383
33419
|
}
|
|
33384
|
-
|
|
33385
|
-
|
|
33386
|
-
|
|
33420
|
+
const command = getString(args, "command");
|
|
33421
|
+
const requiresApproval = getBoolean(args, "requires_approval", false);
|
|
33422
|
+
const result = await provider.executeCommand?.(command, requiresApproval);
|
|
33423
|
+
const message = `<command>${command}</command>
|
|
33424
|
+
<command_exit_code>${result.exitCode}</command_exit_code>
|
|
33425
|
+
<command_stdout>
|
|
33426
|
+
${result.stdout}
|
|
33427
|
+
</command_stdout>
|
|
33428
|
+
<command_stderr>
|
|
33429
|
+
${result.stderr}
|
|
33430
|
+
</command_stderr>`;
|
|
33431
|
+
if (result.exitCode === 0) {
|
|
33432
|
+
return {
|
|
33433
|
+
type: "Reply" /* Reply */,
|
|
33434
|
+
message
|
|
33435
|
+
};
|
|
33387
33436
|
}
|
|
33388
|
-
|
|
33389
|
-
|
|
33390
|
-
|
|
33391
|
-
|
|
33392
|
-
|
|
33393
|
-
|
|
33394
|
-
|
|
33395
|
-
|
|
33396
|
-
|
|
33397
|
-
|
|
33398
|
-
|
|
33399
|
-
|
|
33400
|
-
|
|
33401
|
-
|
|
33402
|
-
|
|
33403
|
-
|
|
33404
|
-
|
|
33405
|
-
|
|
33406
|
-
|
|
33407
|
-
|
|
33408
|
-
|
|
33409
|
-
|
|
33410
|
-
|
|
33411
|
-
await callback({ kind: "Reasoning" /* Reasoning */, info, newText: chunk.text });
|
|
33412
|
-
break;
|
|
33413
|
-
}
|
|
33414
|
-
}
|
|
33415
|
-
if (!currentAssistantMessage) {
|
|
33416
|
-
throw new Error("No assistant message received");
|
|
33437
|
+
return {
|
|
33438
|
+
type: "Error" /* Error */,
|
|
33439
|
+
message
|
|
33440
|
+
};
|
|
33441
|
+
};
|
|
33442
|
+
var isAvailable3 = (provider) => {
|
|
33443
|
+
return !!provider.executeCommand;
|
|
33444
|
+
};
|
|
33445
|
+
var executeCommand_default = {
|
|
33446
|
+
...toolInfo3,
|
|
33447
|
+
handler: handler3,
|
|
33448
|
+
isAvailable: isAvailable3
|
|
33449
|
+
};
|
|
33450
|
+
// ../core/src/tools/listCodeDefinitionNames.ts
|
|
33451
|
+
var toolInfo4 = {
|
|
33452
|
+
name: "list_code_definition_names",
|
|
33453
|
+
description: "Request to list definition names (classes, functions, methods, etc.) used in a file. This tool provides insights into the codebase structure and important constructs, encapsulating high-level concepts and relationships that are crucial for understanding the overall architecture.",
|
|
33454
|
+
parameters: [
|
|
33455
|
+
{
|
|
33456
|
+
name: "path",
|
|
33457
|
+
description: "The path of a code file to list top level source code definitions for.",
|
|
33458
|
+
required: true,
|
|
33459
|
+
usageValue: "Directory path here"
|
|
33417
33460
|
}
|
|
33418
|
-
|
|
33419
|
-
|
|
33420
|
-
|
|
33421
|
-
|
|
33422
|
-
|
|
33423
|
-
|
|
33424
|
-
|
|
33461
|
+
]
|
|
33462
|
+
};
|
|
33463
|
+
var handler4 = async (provider, args) => {
|
|
33464
|
+
if (!provider.listCodeDefinitionNames) {
|
|
33465
|
+
return {
|
|
33466
|
+
type: "Error" /* Error */,
|
|
33467
|
+
message: "Not possible to list code definition names. Abort."
|
|
33468
|
+
};
|
|
33425
33469
|
}
|
|
33426
|
-
|
|
33427
|
-
|
|
33428
|
-
|
|
33429
|
-
|
|
33430
|
-
|
|
33431
|
-
|
|
33432
|
-
|
|
33433
|
-
|
|
33434
|
-
|
|
33435
|
-
|
|
33436
|
-
|
|
33437
|
-
|
|
33438
|
-
|
|
33439
|
-
|
|
33440
|
-
|
|
33441
|
-
|
|
33442
|
-
|
|
33443
|
-
|
|
33444
|
-
|
|
33445
|
-
|
|
33446
|
-
|
|
33447
|
-
|
|
33448
|
-
|
|
33449
|
-
|
|
33450
|
-
|
|
33451
|
-
|
|
33452
|
-
|
|
33453
|
-
|
|
33454
|
-
|
|
33455
|
-
|
|
33456
|
-
|
|
33457
|
-
|
|
33458
|
-
|
|
33459
|
-
|
|
33460
|
-
|
|
33461
|
-
|
|
33462
|
-
|
|
33463
|
-
|
|
33464
|
-
|
|
33465
|
-
|
|
33466
|
-
|
|
33467
|
-
|
|
33470
|
+
const path = getString(args, "path");
|
|
33471
|
+
const files = await provider.listCodeDefinitionNames(path);
|
|
33472
|
+
return {
|
|
33473
|
+
type: "Reply" /* Reply */,
|
|
33474
|
+
message: `<list_code_definition_names_path>${path}</list_code_definition_names_path>
|
|
33475
|
+
<list_code_definition_names_files>
|
|
33476
|
+
${files.join(`
|
|
33477
|
+
`)}
|
|
33478
|
+
</list_code_definition_names_files>`
|
|
33479
|
+
};
|
|
33480
|
+
};
|
|
33481
|
+
var isAvailable4 = (provider) => {
|
|
33482
|
+
return !!provider.listCodeDefinitionNames;
|
|
33483
|
+
};
|
|
33484
|
+
var listCodeDefinitionNames_default = {
|
|
33485
|
+
...toolInfo4,
|
|
33486
|
+
handler: handler4,
|
|
33487
|
+
isAvailable: isAvailable4
|
|
33488
|
+
};
|
|
33489
|
+
// ../core/src/tools/listFiles.ts
|
|
33490
|
+
var toolInfo5 = {
|
|
33491
|
+
name: "list_files",
|
|
33492
|
+
description: "Request to list files and directories within the specified directory. If recursive is true, it will list all files and directories recursively. If recursive is false or not provided, it will only list the top-level contents. Do not use this tool to confirm the existence of files you may have created, as the user will let you know if the files were created successfully or not.",
|
|
33493
|
+
parameters: [
|
|
33494
|
+
{
|
|
33495
|
+
name: "path",
|
|
33496
|
+
description: "The path of the directory to list contents for (relative to the current working directory)",
|
|
33497
|
+
required: true,
|
|
33498
|
+
usageValue: "Directory path here"
|
|
33499
|
+
},
|
|
33500
|
+
{
|
|
33501
|
+
name: "max_count",
|
|
33502
|
+
description: "The maximum number of files to list. Default to 2000",
|
|
33503
|
+
required: false,
|
|
33504
|
+
usageValue: "Maximum number of files to list (optional)"
|
|
33505
|
+
},
|
|
33506
|
+
{
|
|
33507
|
+
name: "recursive",
|
|
33508
|
+
description: "Whether to list files recursively. Use true for recursive listing, false or omit for top-level only.",
|
|
33509
|
+
required: false,
|
|
33510
|
+
usageValue: "true or false (optional)"
|
|
33511
|
+
}
|
|
33512
|
+
],
|
|
33513
|
+
examples: [
|
|
33514
|
+
{
|
|
33515
|
+
description: "Request to list files",
|
|
33516
|
+
parameters: [
|
|
33517
|
+
{
|
|
33518
|
+
name: "path",
|
|
33519
|
+
value: "src"
|
|
33520
|
+
},
|
|
33521
|
+
{
|
|
33522
|
+
name: "max_count",
|
|
33523
|
+
value: "100"
|
|
33468
33524
|
}
|
|
33469
|
-
|
|
33470
|
-
if (toolReponses.length === 0 && !this.config.interactive) {
|
|
33471
|
-
return [responsePrompts.requireUseTool, undefined];
|
|
33525
|
+
]
|
|
33472
33526
|
}
|
|
33473
|
-
|
|
33474
|
-
|
|
33475
|
-
|
|
33476
|
-
|
|
33527
|
+
]
|
|
33528
|
+
};
|
|
33529
|
+
var handler5 = async (provider, args) => {
|
|
33530
|
+
if (!provider.listFiles) {
|
|
33531
|
+
return {
|
|
33532
|
+
type: "Error" /* Error */,
|
|
33533
|
+
message: "Not possible to list files. Abort."
|
|
33534
|
+
};
|
|
33477
33535
|
}
|
|
33478
|
-
|
|
33479
|
-
|
|
33480
|
-
|
|
33481
|
-
|
|
33482
|
-
|
|
33483
|
-
|
|
33484
|
-
|
|
33485
|
-
|
|
33486
|
-
|
|
33487
|
-
|
|
33488
|
-
|
|
33489
|
-
|
|
33490
|
-
return {
|
|
33491
|
-
type: "Error" /* Error */,
|
|
33492
|
-
message: responsePrompts.errorInvokeTool(name, error),
|
|
33493
|
-
canRetry: false
|
|
33494
|
-
};
|
|
33495
|
-
}
|
|
33496
|
-
}
|
|
33497
|
-
get model() {
|
|
33498
|
-
return this.ai.model;
|
|
33499
|
-
}
|
|
33500
|
-
}
|
|
33501
|
-
// ../core/src/tools/allTools.ts
|
|
33502
|
-
var exports_allTools = {};
|
|
33503
|
-
__export(exports_allTools, {
|
|
33504
|
-
writeToFile: () => writeToFile_default,
|
|
33505
|
-
searchFiles: () => searchFiles_default,
|
|
33506
|
-
replaceInFile: () => replaceInFile_default,
|
|
33507
|
-
renameFile: () => renameFile_default,
|
|
33508
|
-
removeFile: () => removeFile_default,
|
|
33509
|
-
readFile: () => readFile_default,
|
|
33510
|
-
listFiles: () => listFiles_default,
|
|
33511
|
-
listCodeDefinitionNames: () => listCodeDefinitionNames_default,
|
|
33512
|
-
handOver: () => handOver_default,
|
|
33513
|
-
executeCommand: () => executeCommand_default,
|
|
33514
|
-
attemptCompletion: () => attemptCompletion_default,
|
|
33515
|
-
askFollowupQuestion: () => askFollowupQuestion_default
|
|
33516
|
-
});
|
|
33517
|
-
|
|
33518
|
-
// ../core/src/tools/utils/replaceInFile.ts
|
|
33519
|
-
var replaceInFile = async (fileContent, diff) => {
|
|
33520
|
-
const blockPattern = /<<<<<+ SEARCH\s*\r?\n([\s\S]*?)\r?\n=======[ \t]*\r?\n([\s\S]*?)\r?\n?>>>>>+ REPLACE/g;
|
|
33521
|
-
const blocks = [];
|
|
33522
|
-
for (let match = blockPattern.exec(diff);match !== null; match = blockPattern.exec(diff)) {
|
|
33523
|
-
blocks.push({ search: match[1], replace: match[2] });
|
|
33524
|
-
}
|
|
33525
|
-
if (blocks.length === 0) {
|
|
33526
|
-
throw new Error("No valid diff blocks found.");
|
|
33527
|
-
}
|
|
33528
|
-
const findAndReplace = (content, search, replace) => {
|
|
33529
|
-
let index = content.indexOf(search);
|
|
33530
|
-
if (index !== -1) {
|
|
33531
|
-
return content.slice(0, index) + replace + content.slice(index + search.length);
|
|
33532
|
-
}
|
|
33533
|
-
const trimmedSearch = search.trim();
|
|
33534
|
-
const trimmedContent = content.trim();
|
|
33535
|
-
const offset = content.indexOf(trimmedContent);
|
|
33536
|
-
index = trimmedContent.indexOf(trimmedSearch);
|
|
33537
|
-
if (index !== -1) {
|
|
33538
|
-
const absoluteIndex = offset + index;
|
|
33539
|
-
return content.slice(0, absoluteIndex) + replace + content.slice(absoluteIndex + trimmedSearch.length);
|
|
33540
|
-
}
|
|
33541
|
-
const normalizedSearch = trimmedSearch.replace(/\s+/g, " ");
|
|
33542
|
-
const normalizedContent = trimmedContent.replace(/\s+/g, " ");
|
|
33543
|
-
index = normalizedContent.indexOf(normalizedSearch);
|
|
33544
|
-
if (index !== -1) {
|
|
33545
|
-
let runningIndex = 0;
|
|
33546
|
-
let actualPos = offset;
|
|
33547
|
-
for (const segment of trimmedSearch.replace(/\s+/g, " ").split(" ")) {
|
|
33548
|
-
const segIndex = content.indexOf(segment, actualPos);
|
|
33549
|
-
if (segIndex === -1) {
|
|
33550
|
-
break;
|
|
33551
|
-
}
|
|
33552
|
-
if (runningIndex === 0) {
|
|
33553
|
-
actualPos = segIndex;
|
|
33554
|
-
} else {
|
|
33555
|
-
actualPos = segIndex + segment.length;
|
|
33556
|
-
}
|
|
33557
|
-
runningIndex++;
|
|
33558
|
-
}
|
|
33559
|
-
const strippedSearch = trimmedSearch.replace(/\s+/g, "");
|
|
33560
|
-
const endPos = actualPos;
|
|
33561
|
-
const startPos = endPos - strippedSearch.length;
|
|
33562
|
-
return content.slice(0, startPos) + replace + content.slice(endPos);
|
|
33563
|
-
}
|
|
33564
|
-
throw new Error(`Could not find the following text in file:
|
|
33565
|
-
${search}`);
|
|
33536
|
+
const path = getString(args, "path");
|
|
33537
|
+
const maxCount = getInt(args, "max_count", 2000);
|
|
33538
|
+
const recursive = getBoolean(args, "recursive", true);
|
|
33539
|
+
const [files, limitReached] = await provider.listFiles(path, recursive, maxCount);
|
|
33540
|
+
return {
|
|
33541
|
+
type: "Reply" /* Reply */,
|
|
33542
|
+
message: `<list_files_path>${path}</list_files_path>
|
|
33543
|
+
<list_files_files>
|
|
33544
|
+
${files.join(`
|
|
33545
|
+
`)}
|
|
33546
|
+
</list_files_files>
|
|
33547
|
+
<list_files_truncated>${limitReached}</list_files_truncated>`
|
|
33566
33548
|
};
|
|
33567
|
-
let updatedFile = fileContent;
|
|
33568
|
-
for (const { search, replace } of blocks) {
|
|
33569
|
-
updatedFile = findAndReplace(updatedFile, search, replace);
|
|
33570
|
-
}
|
|
33571
|
-
return updatedFile;
|
|
33572
|
-
};
|
|
33573
|
-
// ../core/src/tools/utils/getArg.ts
|
|
33574
|
-
var getString = (args, name, defaultValue) => {
|
|
33575
|
-
const ret = args[name] ?? defaultValue;
|
|
33576
|
-
if (ret === undefined) {
|
|
33577
|
-
throw new Error(`Missing required argument: ${name}`);
|
|
33578
|
-
}
|
|
33579
|
-
return ret;
|
|
33580
|
-
};
|
|
33581
|
-
var getStringArray = (args, name, defaultValue) => {
|
|
33582
|
-
const ret = args[name];
|
|
33583
|
-
if (ret === undefined) {
|
|
33584
|
-
if (defaultValue === undefined) {
|
|
33585
|
-
throw new Error(`Missing required argument: ${name}`);
|
|
33586
|
-
}
|
|
33587
|
-
return defaultValue;
|
|
33588
|
-
}
|
|
33589
|
-
if (ret === "") {
|
|
33590
|
-
return [];
|
|
33591
|
-
}
|
|
33592
|
-
return ret.split(",").map((s2) => s2.trim());
|
|
33593
33549
|
};
|
|
33594
|
-
var
|
|
33595
|
-
|
|
33596
|
-
if (ret === undefined) {
|
|
33597
|
-
if (defaultValue === undefined) {
|
|
33598
|
-
throw new Error(`Missing required argument: ${name}`);
|
|
33599
|
-
}
|
|
33600
|
-
return defaultValue;
|
|
33601
|
-
}
|
|
33602
|
-
switch (ret.toLowerCase()) {
|
|
33603
|
-
case "true":
|
|
33604
|
-
return true;
|
|
33605
|
-
case "false":
|
|
33606
|
-
return false;
|
|
33607
|
-
default:
|
|
33608
|
-
throw new Error(`Invalid argument value: ${name}`);
|
|
33609
|
-
}
|
|
33550
|
+
var isAvailable5 = (provider) => {
|
|
33551
|
+
return !!provider.listFiles;
|
|
33610
33552
|
};
|
|
33611
|
-
var
|
|
33612
|
-
|
|
33613
|
-
|
|
33614
|
-
|
|
33615
|
-
throw new Error(`Missing required argument: ${name}`);
|
|
33616
|
-
}
|
|
33617
|
-
return defaultValue;
|
|
33618
|
-
}
|
|
33619
|
-
const parsed = Number.parseInt(ret);
|
|
33620
|
-
if (Number.isNaN(parsed)) {
|
|
33621
|
-
throw new Error(`Invalid argument value: ${name}`);
|
|
33622
|
-
}
|
|
33623
|
-
return parsed;
|
|
33553
|
+
var listFiles_default = {
|
|
33554
|
+
...toolInfo5,
|
|
33555
|
+
handler: handler5,
|
|
33556
|
+
isAvailable: isAvailable5
|
|
33624
33557
|
};
|
|
33625
|
-
// ../core/src/tools/
|
|
33626
|
-
var
|
|
33627
|
-
name: "
|
|
33628
|
-
description: "
|
|
33558
|
+
// ../core/src/tools/readFile.ts
|
|
33559
|
+
var toolInfo6 = {
|
|
33560
|
+
name: "read_file",
|
|
33561
|
+
description: "Request to read the contents of one or multiple files at the specified paths. Use comma separated paths to read multiple files. Use this when you need to examine the contents of an existing file you do not know the contents of, for example to analyze code, review text files, or extract information from configuration files. May not be suitable for other types of binary files, as it returns the raw content as a string. Try to list all the potential files are relevent to the task, and then use this tool to read all the relevant files.",
|
|
33629
33562
|
parameters: [
|
|
33630
33563
|
{
|
|
33631
|
-
name: "
|
|
33632
|
-
description: "The
|
|
33564
|
+
name: "path",
|
|
33565
|
+
description: "The path of the file to read",
|
|
33633
33566
|
required: true,
|
|
33634
|
-
usageValue: "
|
|
33635
|
-
},
|
|
33636
|
-
{
|
|
33637
|
-
name: "options",
|
|
33638
|
-
description: "A comma separated list of possible answers to the question. If not provided, the user will be prompted to provide an answer.",
|
|
33639
|
-
required: false,
|
|
33640
|
-
usageValue: "A comma separated list of possible answers (optional)"
|
|
33567
|
+
usageValue: "Comma separated paths here"
|
|
33641
33568
|
}
|
|
33642
33569
|
],
|
|
33643
33570
|
examples: [
|
|
33644
33571
|
{
|
|
33645
|
-
description: "Request to
|
|
33572
|
+
description: "Request to read the contents of a file",
|
|
33646
33573
|
parameters: [
|
|
33647
33574
|
{
|
|
33648
|
-
name: "
|
|
33649
|
-
value: "
|
|
33575
|
+
name: "path",
|
|
33576
|
+
value: "src/main.js"
|
|
33650
33577
|
}
|
|
33651
33578
|
]
|
|
33652
33579
|
},
|
|
33653
33580
|
{
|
|
33654
|
-
description: "Request to
|
|
33581
|
+
description: "Request to read multiple files",
|
|
33655
33582
|
parameters: [
|
|
33656
33583
|
{
|
|
33657
|
-
name: "
|
|
33658
|
-
value: "
|
|
33659
|
-
},
|
|
33660
|
-
{
|
|
33661
|
-
name: "options",
|
|
33662
|
-
value: "React,Angular,Vue,Svelte"
|
|
33584
|
+
name: "path",
|
|
33585
|
+
value: "src/main.js,src/index.js"
|
|
33663
33586
|
}
|
|
33664
33587
|
]
|
|
33665
33588
|
}
|
|
33666
33589
|
]
|
|
33667
33590
|
};
|
|
33668
|
-
var
|
|
33669
|
-
if (!provider.
|
|
33591
|
+
var handler6 = async (provider, args) => {
|
|
33592
|
+
if (!provider.readFile) {
|
|
33670
33593
|
return {
|
|
33671
33594
|
type: "Error" /* Error */,
|
|
33672
|
-
message: "Not possible to
|
|
33595
|
+
message: "Not possible to read file. Abort."
|
|
33673
33596
|
};
|
|
33674
33597
|
}
|
|
33675
|
-
const
|
|
33676
|
-
const
|
|
33677
|
-
const
|
|
33598
|
+
const paths = getStringArray(args, "path");
|
|
33599
|
+
const resp = [];
|
|
33600
|
+
for (const path of paths) {
|
|
33601
|
+
const fileContent = await provider.readFile(path);
|
|
33602
|
+
const isEmpty = fileContent.trim().length === 0;
|
|
33603
|
+
if (isEmpty) {
|
|
33604
|
+
resp.push(`<read_file_file_content path="${path}" is_empty="true" />`);
|
|
33605
|
+
} else {
|
|
33606
|
+
resp.push(`<read_file_file_conten path="${path}">${fileContent}</read_file_file_content>`);
|
|
33607
|
+
}
|
|
33608
|
+
}
|
|
33678
33609
|
return {
|
|
33679
33610
|
type: "Reply" /* Reply */,
|
|
33680
|
-
message:
|
|
33681
|
-
|
|
33611
|
+
message: resp.join(`
|
|
33612
|
+
`)
|
|
33682
33613
|
};
|
|
33683
33614
|
};
|
|
33684
|
-
var
|
|
33685
|
-
return !!provider.
|
|
33615
|
+
var isAvailable6 = (provider) => {
|
|
33616
|
+
return !!provider.readFile;
|
|
33686
33617
|
};
|
|
33687
|
-
var
|
|
33688
|
-
...
|
|
33689
|
-
handler,
|
|
33690
|
-
isAvailable
|
|
33618
|
+
var readFile_default = {
|
|
33619
|
+
...toolInfo6,
|
|
33620
|
+
handler: handler6,
|
|
33621
|
+
isAvailable: isAvailable6
|
|
33691
33622
|
};
|
|
33692
|
-
// ../core/src/tools/
|
|
33693
|
-
var
|
|
33694
|
-
name: "
|
|
33695
|
-
description: "
|
|
33623
|
+
// ../core/src/tools/replaceInFile.ts
|
|
33624
|
+
var toolInfo7 = {
|
|
33625
|
+
name: "replace_in_file",
|
|
33626
|
+
description: "Request to replace sections of content in an existing file using SEARCH/REPLACE blocks that define exact changes to specific parts of the file. This tool should be used when you need to make targeted changes to specific parts of a file.",
|
|
33696
33627
|
parameters: [
|
|
33697
33628
|
{
|
|
33698
|
-
name: "
|
|
33699
|
-
description: "The
|
|
33629
|
+
name: "path",
|
|
33630
|
+
description: "The path of the file to modify",
|
|
33700
33631
|
required: true,
|
|
33701
|
-
usageValue: "
|
|
33702
|
-
}
|
|
33703
|
-
],
|
|
33704
|
-
examples: [
|
|
33632
|
+
usageValue: "File path here"
|
|
33633
|
+
},
|
|
33705
33634
|
{
|
|
33706
|
-
|
|
33707
|
-
|
|
33708
|
-
|
|
33709
|
-
|
|
33710
|
-
|
|
33711
|
-
|
|
33712
|
-
|
|
33713
|
-
|
|
33714
|
-
|
|
33715
|
-
|
|
33716
|
-
|
|
33717
|
-
|
|
33718
|
-
|
|
33719
|
-
|
|
33720
|
-
|
|
33721
|
-
|
|
33722
|
-
|
|
33723
|
-
|
|
33724
|
-
|
|
33725
|
-
|
|
33726
|
-
|
|
33727
|
-
|
|
33728
|
-
|
|
33729
|
-
|
|
33730
|
-
|
|
33731
|
-
return true;
|
|
33732
|
-
};
|
|
33733
|
-
var attemptCompletion_default = {
|
|
33734
|
-
...toolInfo2,
|
|
33735
|
-
handler: handler2,
|
|
33736
|
-
isAvailable: isAvailable2
|
|
33737
|
-
};
|
|
33738
|
-
// ../core/src/tools/executeCommand.ts
|
|
33739
|
-
var toolInfo3 = {
|
|
33740
|
-
name: "execute_command",
|
|
33741
|
-
description: `Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Commands will also be executed in the project root directory regardless of executed commands in previous tool uses.`,
|
|
33742
|
-
parameters: [
|
|
33743
|
-
{
|
|
33744
|
-
name: "command",
|
|
33745
|
-
description: "The CLI command to execute. This should be valid for the current operating system. Ensure the command is properly formatted and does not contain any harmful instructions.",
|
|
33635
|
+
name: "diff",
|
|
33636
|
+
description: `One or more SEARCH/REPLACE blocks following this exact format:
|
|
33637
|
+
\`\`\`
|
|
33638
|
+
<<<<<<< SEARCH
|
|
33639
|
+
[exact content to find]
|
|
33640
|
+
=======
|
|
33641
|
+
[new content to replace with]
|
|
33642
|
+
>>>>>>> REPLACE
|
|
33643
|
+
\`\`\`
|
|
33644
|
+
Critical rules:
|
|
33645
|
+
1. SEARCH content must match the associated file section to find EXACTLY:
|
|
33646
|
+
* Match character-for-character including whitespace, indentation, line endings
|
|
33647
|
+
* Include all comments, docstrings, etc.
|
|
33648
|
+
2. SEARCH/REPLACE blocks will ONLY replace the first match occurrence.
|
|
33649
|
+
* Including multiple unique SEARCH/REPLACE blocks if you need to make multiple changes.
|
|
33650
|
+
* Include *just* enough lines in each SEARCH section to uniquely match each set of lines that need to change.
|
|
33651
|
+
* When using multiple SEARCH/REPLACE blocks, list them in the order they appear in the file.
|
|
33652
|
+
3. Keep SEARCH/REPLACE blocks concise:
|
|
33653
|
+
* Break large SEARCH/REPLACE blocks into a series of smaller blocks that each change a small portion of the file.
|
|
33654
|
+
* Include just the changing lines, and a few surrounding lines if needed for uniqueness.
|
|
33655
|
+
* Do not include long runs of unchanging lines in SEARCH/REPLACE blocks.
|
|
33656
|
+
* Each line must be complete. Never truncate lines mid-way through as this can cause matching failures.
|
|
33657
|
+
4. Special operations:
|
|
33658
|
+
* To move code: Use two SEARCH/REPLACE blocks (one to delete from original + one to insert at new location)
|
|
33659
|
+
* To delete code: Use empty REPLACE section`,
|
|
33746
33660
|
required: true,
|
|
33747
|
-
usageValue: "
|
|
33748
|
-
},
|
|
33749
|
-
{
|
|
33750
|
-
name: "requires_approval",
|
|
33751
|
-
description: `A boolean indicating whether this command requires explicit user approval before execution in case the user has auto-approve mode enabled. Set to 'true' for potentially impactful operations like installing/uninstalling packages, deleting/overwriting files, system configuration changes, network operations, or any commands that could have unintended side effects. Set to 'false' for safe operations like reading files/directories, running development servers, building projects, and other non-destructive operations.`,
|
|
33752
|
-
required: false,
|
|
33753
|
-
usageValue: "true or false"
|
|
33661
|
+
usageValue: "Search and replace blocks here"
|
|
33754
33662
|
}
|
|
33755
33663
|
],
|
|
33756
33664
|
examples: [
|
|
33757
33665
|
{
|
|
33758
|
-
description: "Request to
|
|
33666
|
+
description: "Request to replace sections of content in a file",
|
|
33759
33667
|
parameters: [
|
|
33760
33668
|
{
|
|
33761
|
-
name: "
|
|
33762
|
-
value: "
|
|
33669
|
+
name: "path",
|
|
33670
|
+
value: "src/main.js"
|
|
33763
33671
|
},
|
|
33764
33672
|
{
|
|
33765
|
-
name: "
|
|
33766
|
-
value:
|
|
33673
|
+
name: "diff",
|
|
33674
|
+
value: `
|
|
33675
|
+
<<<<<<< SEARCH
|
|
33676
|
+
import React from 'react';
|
|
33677
|
+
=======
|
|
33678
|
+
import React, { useState } from 'react';
|
|
33679
|
+
>>>>>>> REPLACE
|
|
33680
|
+
|
|
33681
|
+
<<<<<<< SEARCH
|
|
33682
|
+
function handleSubmit() {
|
|
33683
|
+
saveData();
|
|
33684
|
+
setLoading(false);
|
|
33685
|
+
}
|
|
33686
|
+
|
|
33687
|
+
=======
|
|
33688
|
+
>>>>>>> REPLACE
|
|
33689
|
+
|
|
33690
|
+
<<<<<<< SEARCH
|
|
33691
|
+
return (
|
|
33692
|
+
<div>
|
|
33693
|
+
=======
|
|
33694
|
+
function handleSubmit() {
|
|
33695
|
+
saveData();
|
|
33696
|
+
setLoading(false);
|
|
33697
|
+
}
|
|
33698
|
+
|
|
33699
|
+
return (
|
|
33700
|
+
<div>
|
|
33701
|
+
>>>>>>> REPLACE
|
|
33702
|
+
`
|
|
33767
33703
|
}
|
|
33768
33704
|
]
|
|
33769
33705
|
}
|
|
33770
33706
|
]
|
|
33771
33707
|
};
|
|
33772
|
-
var
|
|
33773
|
-
if (!provider.
|
|
33774
|
-
return {
|
|
33775
|
-
type: "Error" /* Error */,
|
|
33776
|
-
message: "Not possible to execute command. Abort."
|
|
33777
|
-
};
|
|
33778
|
-
}
|
|
33779
|
-
const command = getString(args, "command");
|
|
33780
|
-
const requiresApproval = getBoolean(args, "requires_approval", false);
|
|
33781
|
-
const result = await provider.executeCommand?.(command, requiresApproval);
|
|
33782
|
-
const message = `<command>${command}</command>
|
|
33783
|
-
<command_exit_code>${result.exitCode}</command_exit_code>
|
|
33784
|
-
<command_stdout>
|
|
33785
|
-
${result.stdout}
|
|
33786
|
-
</command_stdout>
|
|
33787
|
-
<command_stderr>
|
|
33788
|
-
${result.stderr}
|
|
33789
|
-
</command_stderr>`;
|
|
33790
|
-
if (result.exitCode === 0) {
|
|
33791
|
-
return {
|
|
33792
|
-
type: "Reply" /* Reply */,
|
|
33793
|
-
message
|
|
33794
|
-
};
|
|
33795
|
-
}
|
|
33796
|
-
return {
|
|
33797
|
-
type: "Error" /* Error */,
|
|
33798
|
-
message
|
|
33799
|
-
};
|
|
33800
|
-
};
|
|
33801
|
-
var isAvailable3 = (provider) => {
|
|
33802
|
-
return !!provider.executeCommand;
|
|
33803
|
-
};
|
|
33804
|
-
var executeCommand_default = {
|
|
33805
|
-
...toolInfo3,
|
|
33806
|
-
handler: handler3,
|
|
33807
|
-
isAvailable: isAvailable3
|
|
33808
|
-
};
|
|
33809
|
-
// ../core/src/tools/listCodeDefinitionNames.ts
|
|
33810
|
-
var toolInfo4 = {
|
|
33811
|
-
name: "list_code_definition_names",
|
|
33812
|
-
description: "Request to list definition names (classes, functions, methods, etc.) used in a file. This tool provides insights into the codebase structure and important constructs, encapsulating high-level concepts and relationships that are crucial for understanding the overall architecture.",
|
|
33813
|
-
parameters: [
|
|
33814
|
-
{
|
|
33815
|
-
name: "path",
|
|
33816
|
-
description: "The path of a code file to list top level source code definitions for.",
|
|
33817
|
-
required: true,
|
|
33818
|
-
usageValue: "Directory path here"
|
|
33819
|
-
}
|
|
33820
|
-
]
|
|
33821
|
-
};
|
|
33822
|
-
var handler4 = async (provider, args) => {
|
|
33823
|
-
if (!provider.listCodeDefinitionNames) {
|
|
33708
|
+
var handler7 = async (provider, args) => {
|
|
33709
|
+
if (!provider.readFile || !provider.writeFile) {
|
|
33824
33710
|
return {
|
|
33825
33711
|
type: "Error" /* Error */,
|
|
33826
|
-
message: "Not possible to
|
|
33712
|
+
message: "Not possible to replace in file. Abort."
|
|
33827
33713
|
};
|
|
33828
33714
|
}
|
|
33829
33715
|
const path = getString(args, "path");
|
|
33830
|
-
const
|
|
33716
|
+
const diff = getString(args, "diff");
|
|
33717
|
+
const fileContent = await provider.readFile(path);
|
|
33718
|
+
const result = await replaceInFile(fileContent, diff);
|
|
33719
|
+
await provider.writeFile(path, result);
|
|
33831
33720
|
return {
|
|
33832
33721
|
type: "Reply" /* Reply */,
|
|
33833
|
-
message: `<
|
|
33834
|
-
<list_code_definition_names_files>
|
|
33835
|
-
${files.join(`
|
|
33836
|
-
`)}
|
|
33837
|
-
</list_code_definition_names_files>`
|
|
33722
|
+
message: `<replace_in_file_path>${path}</replace_in_file_path>`
|
|
33838
33723
|
};
|
|
33839
33724
|
};
|
|
33840
|
-
var
|
|
33841
|
-
return !!provider.
|
|
33725
|
+
var isAvailable7 = (provider) => {
|
|
33726
|
+
return !!provider.readFile && !!provider.writeFile;
|
|
33842
33727
|
};
|
|
33843
|
-
var
|
|
33844
|
-
...
|
|
33845
|
-
handler:
|
|
33846
|
-
isAvailable:
|
|
33728
|
+
var replaceInFile_default = {
|
|
33729
|
+
...toolInfo7,
|
|
33730
|
+
handler: handler7,
|
|
33731
|
+
isAvailable: isAvailable7
|
|
33847
33732
|
};
|
|
33848
|
-
// ../core/src/tools/
|
|
33849
|
-
var
|
|
33850
|
-
name: "
|
|
33851
|
-
description: "Request to
|
|
33733
|
+
// ../core/src/tools/searchFiles.ts
|
|
33734
|
+
var toolInfo8 = {
|
|
33735
|
+
name: "search_files",
|
|
33736
|
+
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.",
|
|
33852
33737
|
parameters: [
|
|
33853
33738
|
{
|
|
33854
33739
|
name: "path",
|
|
33855
|
-
description: "The path of the directory to
|
|
33740
|
+
description: "The path of the directory to search in (relative to the current working directory). This directory will be recursively searched.",
|
|
33856
33741
|
required: true,
|
|
33857
33742
|
usageValue: "Directory path here"
|
|
33858
33743
|
},
|
|
33859
33744
|
{
|
|
33860
|
-
name: "
|
|
33861
|
-
description: "The
|
|
33862
|
-
required:
|
|
33863
|
-
usageValue: "
|
|
33745
|
+
name: "regex",
|
|
33746
|
+
description: "The regular expression pattern to search for. Uses Rust regex syntax.",
|
|
33747
|
+
required: true,
|
|
33748
|
+
usageValue: "Your regex pattern here"
|
|
33864
33749
|
},
|
|
33865
33750
|
{
|
|
33866
|
-
name: "
|
|
33867
|
-
description:
|
|
33751
|
+
name: "file_pattern",
|
|
33752
|
+
description: 'Glob pattern to filter files (e.g., "*.ts" for TypeScript files). If not provided, it will search all files (*).',
|
|
33868
33753
|
required: false,
|
|
33869
|
-
usageValue: "
|
|
33754
|
+
usageValue: "file pattern here (optional)"
|
|
33870
33755
|
}
|
|
33871
33756
|
],
|
|
33872
33757
|
examples: [
|
|
33873
33758
|
{
|
|
33874
|
-
description: "Request to
|
|
33759
|
+
description: "Request to perform a regex search across files",
|
|
33875
33760
|
parameters: [
|
|
33876
33761
|
{
|
|
33877
33762
|
name: "path",
|
|
33878
33763
|
value: "src"
|
|
33879
33764
|
},
|
|
33880
33765
|
{
|
|
33881
|
-
name: "
|
|
33882
|
-
value: "
|
|
33766
|
+
name: "regex",
|
|
33767
|
+
value: "^components/"
|
|
33768
|
+
},
|
|
33769
|
+
{
|
|
33770
|
+
name: "file_pattern",
|
|
33771
|
+
value: "*.ts"
|
|
33883
33772
|
}
|
|
33884
33773
|
]
|
|
33885
33774
|
}
|
|
33886
33775
|
]
|
|
33887
33776
|
};
|
|
33888
|
-
var
|
|
33889
|
-
if (!provider.
|
|
33777
|
+
var handler8 = async (provider, args) => {
|
|
33778
|
+
if (!provider.searchFiles) {
|
|
33890
33779
|
return {
|
|
33891
33780
|
type: "Error" /* Error */,
|
|
33892
|
-
message: "Not possible to
|
|
33781
|
+
message: "Not possible to search files. Abort."
|
|
33893
33782
|
};
|
|
33894
33783
|
}
|
|
33895
33784
|
const path = getString(args, "path");
|
|
33896
|
-
const
|
|
33897
|
-
const
|
|
33898
|
-
const
|
|
33785
|
+
const regex = getString(args, "regex");
|
|
33786
|
+
const filePattern = getString(args, "file_pattern", "*");
|
|
33787
|
+
const files = await provider.searchFiles(path, regex, filePattern);
|
|
33899
33788
|
return {
|
|
33900
33789
|
type: "Reply" /* Reply */,
|
|
33901
|
-
message: `<
|
|
33902
|
-
<
|
|
33790
|
+
message: `<search_files_path>${path}</search_files_path>
|
|
33791
|
+
<search_files_regex>${regex}</search_files_regex>
|
|
33792
|
+
<search_files_file_pattern>${filePattern}</search_files_file_pattern>
|
|
33793
|
+
<search_files_files>
|
|
33903
33794
|
${files.join(`
|
|
33904
33795
|
`)}
|
|
33905
|
-
</
|
|
33906
|
-
|
|
33796
|
+
</search_files_files>
|
|
33797
|
+
`
|
|
33907
33798
|
};
|
|
33908
33799
|
};
|
|
33909
|
-
var
|
|
33910
|
-
return !!provider.
|
|
33800
|
+
var isAvailable8 = (provider) => {
|
|
33801
|
+
return !!provider.searchFiles;
|
|
33911
33802
|
};
|
|
33912
|
-
var
|
|
33913
|
-
...
|
|
33914
|
-
handler:
|
|
33915
|
-
isAvailable:
|
|
33916
|
-
};
|
|
33917
|
-
// ../core/src/tools/readFile.ts
|
|
33918
|
-
var toolInfo6 = {
|
|
33919
|
-
name: "read_file",
|
|
33920
|
-
description: "Request to read the contents of one or multiple files at the specified paths. Use comma separated paths to read multiple files. Use this when you need to examine the contents of an existing file you do not know the contents of, for example to analyze code, review text files, or extract information from configuration files. May not be suitable for other types of binary files, as it returns the raw content as a string. Try to list all the potential files are relevent to the task, and then use this tool to read all the relevant files.",
|
|
33921
|
-
parameters: [
|
|
33922
|
-
{
|
|
33923
|
-
name: "path",
|
|
33924
|
-
description: "The path of the file to read",
|
|
33925
|
-
required: true,
|
|
33926
|
-
usageValue: "Comma separated paths here"
|
|
33927
|
-
}
|
|
33928
|
-
],
|
|
33929
|
-
examples: [
|
|
33930
|
-
{
|
|
33931
|
-
description: "Request to read the contents of a file",
|
|
33932
|
-
parameters: [
|
|
33933
|
-
{
|
|
33934
|
-
name: "path",
|
|
33935
|
-
value: "src/main.js"
|
|
33936
|
-
}
|
|
33937
|
-
]
|
|
33938
|
-
},
|
|
33939
|
-
{
|
|
33940
|
-
description: "Request to read multiple files",
|
|
33941
|
-
parameters: [
|
|
33942
|
-
{
|
|
33943
|
-
name: "path",
|
|
33944
|
-
value: "src/main.js,src/index.js"
|
|
33945
|
-
}
|
|
33946
|
-
]
|
|
33947
|
-
}
|
|
33948
|
-
]
|
|
33949
|
-
};
|
|
33950
|
-
var handler6 = async (provider, args) => {
|
|
33951
|
-
if (!provider.readFile) {
|
|
33952
|
-
return {
|
|
33953
|
-
type: "Error" /* Error */,
|
|
33954
|
-
message: "Not possible to read file. Abort."
|
|
33955
|
-
};
|
|
33956
|
-
}
|
|
33957
|
-
const paths = getStringArray(args, "path");
|
|
33958
|
-
const resp = [];
|
|
33959
|
-
for (const path of paths) {
|
|
33960
|
-
const fileContent = await provider.readFile(path);
|
|
33961
|
-
const isEmpty = fileContent.trim().length === 0;
|
|
33962
|
-
if (isEmpty) {
|
|
33963
|
-
resp.push(`<read_file_file_content path="${path}" is_empty="true" />`);
|
|
33964
|
-
} else {
|
|
33965
|
-
resp.push(`<read_file_file_conten path="${path}">${fileContent}</read_file_file_content>`);
|
|
33966
|
-
}
|
|
33967
|
-
}
|
|
33968
|
-
return {
|
|
33969
|
-
type: "Reply" /* Reply */,
|
|
33970
|
-
message: resp.join(`
|
|
33971
|
-
`)
|
|
33972
|
-
};
|
|
33973
|
-
};
|
|
33974
|
-
var isAvailable6 = (provider) => {
|
|
33975
|
-
return !!provider.readFile;
|
|
33976
|
-
};
|
|
33977
|
-
var readFile_default = {
|
|
33978
|
-
...toolInfo6,
|
|
33979
|
-
handler: handler6,
|
|
33980
|
-
isAvailable: isAvailable6
|
|
33981
|
-
};
|
|
33982
|
-
// ../core/src/tools/replaceInFile.ts
|
|
33983
|
-
var toolInfo7 = {
|
|
33984
|
-
name: "replace_in_file",
|
|
33985
|
-
description: "Request to replace sections of content in an existing file using SEARCH/REPLACE blocks that define exact changes to specific parts of the file. This tool should be used when you need to make targeted changes to specific parts of a file.",
|
|
33986
|
-
parameters: [
|
|
33987
|
-
{
|
|
33988
|
-
name: "path",
|
|
33989
|
-
description: "The path of the file to modify",
|
|
33990
|
-
required: true,
|
|
33991
|
-
usageValue: "File path here"
|
|
33992
|
-
},
|
|
33993
|
-
{
|
|
33994
|
-
name: "diff",
|
|
33995
|
-
description: `One or more SEARCH/REPLACE blocks following this exact format:
|
|
33996
|
-
\`\`\`
|
|
33997
|
-
<<<<<<< SEARCH
|
|
33998
|
-
[exact content to find]
|
|
33999
|
-
=======
|
|
34000
|
-
[new content to replace with]
|
|
34001
|
-
>>>>>>> REPLACE
|
|
34002
|
-
\`\`\`
|
|
34003
|
-
Critical rules:
|
|
34004
|
-
1. SEARCH content must match the associated file section to find EXACTLY:
|
|
34005
|
-
* Match character-for-character including whitespace, indentation, line endings
|
|
34006
|
-
* Include all comments, docstrings, etc.
|
|
34007
|
-
2. SEARCH/REPLACE blocks will ONLY replace the first match occurrence.
|
|
34008
|
-
* Including multiple unique SEARCH/REPLACE blocks if you need to make multiple changes.
|
|
34009
|
-
* Include *just* enough lines in each SEARCH section to uniquely match each set of lines that need to change.
|
|
34010
|
-
* When using multiple SEARCH/REPLACE blocks, list them in the order they appear in the file.
|
|
34011
|
-
3. Keep SEARCH/REPLACE blocks concise:
|
|
34012
|
-
* Break large SEARCH/REPLACE blocks into a series of smaller blocks that each change a small portion of the file.
|
|
34013
|
-
* Include just the changing lines, and a few surrounding lines if needed for uniqueness.
|
|
34014
|
-
* Do not include long runs of unchanging lines in SEARCH/REPLACE blocks.
|
|
34015
|
-
* Each line must be complete. Never truncate lines mid-way through as this can cause matching failures.
|
|
34016
|
-
4. Special operations:
|
|
34017
|
-
* To move code: Use two SEARCH/REPLACE blocks (one to delete from original + one to insert at new location)
|
|
34018
|
-
* To delete code: Use empty REPLACE section`,
|
|
34019
|
-
required: true,
|
|
34020
|
-
usageValue: "Search and replace blocks here"
|
|
34021
|
-
}
|
|
34022
|
-
],
|
|
34023
|
-
examples: [
|
|
34024
|
-
{
|
|
34025
|
-
description: "Request to replace sections of content in a file",
|
|
34026
|
-
parameters: [
|
|
34027
|
-
{
|
|
34028
|
-
name: "path",
|
|
34029
|
-
value: "src/main.js"
|
|
34030
|
-
},
|
|
34031
|
-
{
|
|
34032
|
-
name: "diff",
|
|
34033
|
-
value: `
|
|
34034
|
-
<<<<<<< SEARCH
|
|
34035
|
-
import React from 'react';
|
|
34036
|
-
=======
|
|
34037
|
-
import React, { useState } from 'react';
|
|
34038
|
-
>>>>>>> REPLACE
|
|
34039
|
-
|
|
34040
|
-
<<<<<<< SEARCH
|
|
34041
|
-
function handleSubmit() {
|
|
34042
|
-
saveData();
|
|
34043
|
-
setLoading(false);
|
|
34044
|
-
}
|
|
34045
|
-
|
|
34046
|
-
=======
|
|
34047
|
-
>>>>>>> REPLACE
|
|
34048
|
-
|
|
34049
|
-
<<<<<<< SEARCH
|
|
34050
|
-
return (
|
|
34051
|
-
<div>
|
|
34052
|
-
=======
|
|
34053
|
-
function handleSubmit() {
|
|
34054
|
-
saveData();
|
|
34055
|
-
setLoading(false);
|
|
34056
|
-
}
|
|
34057
|
-
|
|
34058
|
-
return (
|
|
34059
|
-
<div>
|
|
34060
|
-
>>>>>>> REPLACE
|
|
34061
|
-
`
|
|
34062
|
-
}
|
|
34063
|
-
]
|
|
34064
|
-
}
|
|
34065
|
-
]
|
|
34066
|
-
};
|
|
34067
|
-
var handler7 = async (provider, args) => {
|
|
34068
|
-
if (!provider.readFile || !provider.writeFile) {
|
|
34069
|
-
return {
|
|
34070
|
-
type: "Error" /* Error */,
|
|
34071
|
-
message: "Not possible to replace in file. Abort."
|
|
34072
|
-
};
|
|
34073
|
-
}
|
|
34074
|
-
const path = getString(args, "path");
|
|
34075
|
-
const diff = getString(args, "diff");
|
|
34076
|
-
const fileContent = await provider.readFile(path);
|
|
34077
|
-
const result = await replaceInFile(fileContent, diff);
|
|
34078
|
-
await provider.writeFile(path, result);
|
|
34079
|
-
return {
|
|
34080
|
-
type: "Reply" /* Reply */,
|
|
34081
|
-
message: `<replace_in_file_path>${path}</replace_in_file_path>`
|
|
34082
|
-
};
|
|
34083
|
-
};
|
|
34084
|
-
var isAvailable7 = (provider) => {
|
|
34085
|
-
return !!provider.readFile && !!provider.writeFile;
|
|
34086
|
-
};
|
|
34087
|
-
var replaceInFile_default = {
|
|
34088
|
-
...toolInfo7,
|
|
34089
|
-
handler: handler7,
|
|
34090
|
-
isAvailable: isAvailable7
|
|
34091
|
-
};
|
|
34092
|
-
// ../core/src/tools/searchFiles.ts
|
|
34093
|
-
var toolInfo8 = {
|
|
34094
|
-
name: "search_files",
|
|
34095
|
-
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.",
|
|
34096
|
-
parameters: [
|
|
34097
|
-
{
|
|
34098
|
-
name: "path",
|
|
34099
|
-
description: "The path of the directory to search in (relative to the current working directory). This directory will be recursively searched.",
|
|
34100
|
-
required: true,
|
|
34101
|
-
usageValue: "Directory path here"
|
|
34102
|
-
},
|
|
34103
|
-
{
|
|
34104
|
-
name: "regex",
|
|
34105
|
-
description: "The regular expression pattern to search for. Uses Rust regex syntax.",
|
|
34106
|
-
required: true,
|
|
34107
|
-
usageValue: "Your regex pattern here"
|
|
34108
|
-
},
|
|
34109
|
-
{
|
|
34110
|
-
name: "file_pattern",
|
|
34111
|
-
description: 'Glob pattern to filter files (e.g., "*.ts" for TypeScript files). If not provided, it will search all files (*).',
|
|
34112
|
-
required: false,
|
|
34113
|
-
usageValue: "file pattern here (optional)"
|
|
34114
|
-
}
|
|
34115
|
-
],
|
|
34116
|
-
examples: [
|
|
34117
|
-
{
|
|
34118
|
-
description: "Request to perform a regex search across files",
|
|
34119
|
-
parameters: [
|
|
34120
|
-
{
|
|
34121
|
-
name: "path",
|
|
34122
|
-
value: "src"
|
|
34123
|
-
},
|
|
34124
|
-
{
|
|
34125
|
-
name: "regex",
|
|
34126
|
-
value: "^components/"
|
|
34127
|
-
},
|
|
34128
|
-
{
|
|
34129
|
-
name: "file_pattern",
|
|
34130
|
-
value: "*.ts"
|
|
34131
|
-
}
|
|
34132
|
-
]
|
|
34133
|
-
}
|
|
34134
|
-
]
|
|
34135
|
-
};
|
|
34136
|
-
var handler8 = async (provider, args) => {
|
|
34137
|
-
if (!provider.searchFiles) {
|
|
34138
|
-
return {
|
|
34139
|
-
type: "Error" /* Error */,
|
|
34140
|
-
message: "Not possible to search files. Abort."
|
|
34141
|
-
};
|
|
34142
|
-
}
|
|
34143
|
-
const path = getString(args, "path");
|
|
34144
|
-
const regex = getString(args, "regex");
|
|
34145
|
-
const filePattern = getString(args, "file_pattern", "*");
|
|
34146
|
-
const files = await provider.searchFiles(path, regex, filePattern);
|
|
34147
|
-
return {
|
|
34148
|
-
type: "Reply" /* Reply */,
|
|
34149
|
-
message: `<search_files_path>${path}</search_files_path>
|
|
34150
|
-
<search_files_regex>${regex}</search_files_regex>
|
|
34151
|
-
<search_files_file_pattern>${filePattern}</search_files_file_pattern>
|
|
34152
|
-
<search_files_files>
|
|
34153
|
-
${files.join(`
|
|
34154
|
-
`)}
|
|
34155
|
-
</search_files_files>
|
|
34156
|
-
`
|
|
34157
|
-
};
|
|
34158
|
-
};
|
|
34159
|
-
var isAvailable8 = (provider) => {
|
|
34160
|
-
return !!provider.searchFiles;
|
|
34161
|
-
};
|
|
34162
|
-
var searchFiles_default = {
|
|
34163
|
-
...toolInfo8,
|
|
34164
|
-
handler: handler8,
|
|
34165
|
-
isAvailable: isAvailable8
|
|
33803
|
+
var searchFiles_default = {
|
|
33804
|
+
...toolInfo8,
|
|
33805
|
+
handler: handler8,
|
|
33806
|
+
isAvailable: isAvailable8
|
|
34166
33807
|
};
|
|
34167
33808
|
// ../core/src/tools/writeToFile.ts
|
|
34168
33809
|
var toolInfo9 = {
|
|
@@ -34268,7 +33909,7 @@ var toolInfo10 = {
|
|
|
34268
33909
|
parameters: [
|
|
34269
33910
|
{
|
|
34270
33911
|
name: "agent_name",
|
|
34271
|
-
value: "
|
|
33912
|
+
value: "coder"
|
|
34272
33913
|
},
|
|
34273
33914
|
{
|
|
34274
33915
|
name: "task",
|
|
@@ -34394,22 +34035,608 @@ var handler12 = async (provider, args) => {
|
|
|
34394
34035
|
message: "Not possible to rename file. Abort."
|
|
34395
34036
|
};
|
|
34396
34037
|
}
|
|
34397
|
-
const sourcePath = getString(args, "sourcePath");
|
|
34398
|
-
const targetPath = getString(args, "targetPath");
|
|
34399
|
-
await provider.renameFile(sourcePath, targetPath);
|
|
34400
|
-
return {
|
|
34401
|
-
type: "Reply" /* Reply */,
|
|
34402
|
-
message: `<rename_file_path>${targetPath}</rename_file_path><status>Success</status>`
|
|
34403
|
-
};
|
|
34404
|
-
};
|
|
34405
|
-
var isAvailable12 = (provider) => {
|
|
34406
|
-
return !!provider.renameFile;
|
|
34407
|
-
};
|
|
34408
|
-
var renameFile_default = {
|
|
34409
|
-
...toolInfo12,
|
|
34410
|
-
handler: handler12,
|
|
34411
|
-
isAvailable: isAvailable12
|
|
34038
|
+
const sourcePath = getString(args, "sourcePath");
|
|
34039
|
+
const targetPath = getString(args, "targetPath");
|
|
34040
|
+
await provider.renameFile(sourcePath, targetPath);
|
|
34041
|
+
return {
|
|
34042
|
+
type: "Reply" /* Reply */,
|
|
34043
|
+
message: `<rename_file_path>${targetPath}</rename_file_path><status>Success</status>`
|
|
34044
|
+
};
|
|
34045
|
+
};
|
|
34046
|
+
var isAvailable12 = (provider) => {
|
|
34047
|
+
return !!provider.renameFile;
|
|
34048
|
+
};
|
|
34049
|
+
var renameFile_default = {
|
|
34050
|
+
...toolInfo12,
|
|
34051
|
+
handler: handler12,
|
|
34052
|
+
isAvailable: isAvailable12
|
|
34053
|
+
};
|
|
34054
|
+
// ../core/src/Agent/parseAssistantMessage.ts
|
|
34055
|
+
function parseAssistantMessage(assistantMessage, tools, toolNamePrefix) {
|
|
34056
|
+
const parameterPrefix = `${toolNamePrefix}parameter_`;
|
|
34057
|
+
const results = [];
|
|
34058
|
+
const toolTags = tools.map((tool) => `${toolNamePrefix}${tool.name}`);
|
|
34059
|
+
const toolPattern = toolTags.join("|");
|
|
34060
|
+
let remainingMessage = assistantMessage;
|
|
34061
|
+
let match;
|
|
34062
|
+
const tagRegex = new RegExp(`<(${toolPattern})>([\\s\\S]*?)<\\/\\1>`, "s");
|
|
34063
|
+
while (true) {
|
|
34064
|
+
match = tagRegex.exec(remainingMessage);
|
|
34065
|
+
if (match === null)
|
|
34066
|
+
break;
|
|
34067
|
+
const beforeTag = remainingMessage.slice(0, match.index).trim();
|
|
34068
|
+
if (beforeTag) {
|
|
34069
|
+
results.push({
|
|
34070
|
+
type: "text",
|
|
34071
|
+
content: beforeTag
|
|
34072
|
+
});
|
|
34073
|
+
}
|
|
34074
|
+
const tagName = match[1];
|
|
34075
|
+
const toolName = tagName.replace(toolNamePrefix, "");
|
|
34076
|
+
const tool = tools.find((t2) => t2.name === toolName);
|
|
34077
|
+
const fullTagContent = match[0];
|
|
34078
|
+
if (tool) {
|
|
34079
|
+
const params = {};
|
|
34080
|
+
for (const param of tool.parameters) {
|
|
34081
|
+
const paramName = `${parameterPrefix}${param.name}`;
|
|
34082
|
+
const escapedParamName = paramName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
34083
|
+
const paramPattern = `<${escapedParamName}>([\\s\\S]*?)<\\/${escapedParamName}>`;
|
|
34084
|
+
const paramMatch = fullTagContent.match(new RegExp(paramPattern, "s"));
|
|
34085
|
+
if (paramMatch) {
|
|
34086
|
+
params[param.name] = paramMatch[1].trim();
|
|
34087
|
+
}
|
|
34088
|
+
}
|
|
34089
|
+
results.push({
|
|
34090
|
+
type: "tool_use",
|
|
34091
|
+
name: toolName,
|
|
34092
|
+
params
|
|
34093
|
+
});
|
|
34094
|
+
} else {
|
|
34095
|
+
results.push({
|
|
34096
|
+
type: "text",
|
|
34097
|
+
content: fullTagContent
|
|
34098
|
+
});
|
|
34099
|
+
}
|
|
34100
|
+
remainingMessage = remainingMessage.slice(match.index + fullTagContent.length);
|
|
34101
|
+
}
|
|
34102
|
+
if (remainingMessage.trim()) {
|
|
34103
|
+
results.push({
|
|
34104
|
+
type: "text",
|
|
34105
|
+
content: remainingMessage.trim()
|
|
34106
|
+
});
|
|
34107
|
+
}
|
|
34108
|
+
if (results.length === 0) {
|
|
34109
|
+
results.push({
|
|
34110
|
+
type: "text",
|
|
34111
|
+
content: assistantMessage
|
|
34112
|
+
});
|
|
34113
|
+
}
|
|
34114
|
+
return results;
|
|
34115
|
+
}
|
|
34116
|
+
|
|
34117
|
+
// ../core/src/Agent/prompts.ts
|
|
34118
|
+
var toolInfoPrompt = (tool, toolNamePrefix, parameterPrefix) => `
|
|
34119
|
+
## ${toolNamePrefix}${tool.name}
|
|
34120
|
+
|
|
34121
|
+
Description: ${tool.description}
|
|
34122
|
+
|
|
34123
|
+
Parameters:
|
|
34124
|
+
${tool.parameters.map((param) => `- ${parameterPrefix}${param.name}: (${param.required ? "required" : "optional"}) ${param.description}`).join(`
|
|
34125
|
+
`)}
|
|
34126
|
+
|
|
34127
|
+
Usage:
|
|
34128
|
+
<${toolNamePrefix}${tool.name}>
|
|
34129
|
+
${tool.parameters.map((param) => `<${parameterPrefix}${param.name}>${param.usageValue}</${parameterPrefix}${param.name}>`).join(`
|
|
34130
|
+
`)}
|
|
34131
|
+
</${toolNamePrefix}${tool.name}>`;
|
|
34132
|
+
var toolInfoExamplesPrompt = (idx, tool, example, toolNamePrefix, parameterPrefix) => `
|
|
34133
|
+
## Example ${idx + 1}: ${example.description}
|
|
34134
|
+
|
|
34135
|
+
<${toolNamePrefix}${tool.name}>
|
|
34136
|
+
${example.parameters.map((param) => `<${parameterPrefix}${param.name}>${param.value}</${parameterPrefix}${param.name}>`).join(`
|
|
34137
|
+
`)}
|
|
34138
|
+
</${toolNamePrefix}${tool.name}>
|
|
34139
|
+
`;
|
|
34140
|
+
var toolUsePrompt = (tools, toolNamePrefix) => {
|
|
34141
|
+
if (tools.length === 0) {
|
|
34142
|
+
return "";
|
|
34143
|
+
}
|
|
34144
|
+
const parameterPrefix = `${toolNamePrefix}parameter_`;
|
|
34145
|
+
let exampleIndex = 0;
|
|
34146
|
+
return `
|
|
34147
|
+
====
|
|
34148
|
+
|
|
34149
|
+
TOOL USE
|
|
34150
|
+
|
|
34151
|
+
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.
|
|
34152
|
+
|
|
34153
|
+
# Tool Use Formatting
|
|
34154
|
+
|
|
34155
|
+
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:
|
|
34156
|
+
|
|
34157
|
+
<${toolNamePrefix}tool_name>
|
|
34158
|
+
<${parameterPrefix}name1>value1</${parameterPrefix}name1>
|
|
34159
|
+
<${parameterPrefix}name2>value2</${parameterPrefix}name2>
|
|
34160
|
+
...
|
|
34161
|
+
</${toolNamePrefix}tool_name>
|
|
34162
|
+
|
|
34163
|
+
For example:
|
|
34164
|
+
|
|
34165
|
+
<${toolNamePrefix}read_file>
|
|
34166
|
+
<${parameterPrefix}path>src/main.js</${parameterPrefix}path>
|
|
34167
|
+
</${toolNamePrefix}read_file>
|
|
34168
|
+
|
|
34169
|
+
Always adhere to this format for the tool use to ensure proper parsing and execution.
|
|
34170
|
+
|
|
34171
|
+
# Tools
|
|
34172
|
+
${tools.map((tool) => toolInfoPrompt(tool, toolNamePrefix, parameterPrefix)).join(`
|
|
34173
|
+
`)}
|
|
34174
|
+
|
|
34175
|
+
# Tool Use Examples
|
|
34176
|
+
${tools.map((tool) => {
|
|
34177
|
+
let promp = "";
|
|
34178
|
+
for (const example of tool.examples ?? []) {
|
|
34179
|
+
promp += toolInfoExamplesPrompt(exampleIndex++, tool, example, toolNamePrefix, parameterPrefix);
|
|
34180
|
+
}
|
|
34181
|
+
return promp;
|
|
34182
|
+
}).join("")}
|
|
34183
|
+
# Tool Use Guidelines
|
|
34184
|
+
|
|
34185
|
+
1. **In \`<thinking>\` tags**, assess what information you have and what you need to proceed.
|
|
34186
|
+
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.
|
|
34187
|
+
3. **Formulate tool use only in the specified XML format** for each tool.
|
|
34188
|
+
4. **Wait for the user’s response** after each tool use. Do not proceed until you have their confirmation.
|
|
34189
|
+
5. The user’s response may include:
|
|
34190
|
+
- Tool success or failure details
|
|
34191
|
+
- Linter errors
|
|
34192
|
+
- Terminal output or other relevant feedback
|
|
34193
|
+
6. **Never repeat or quote the entire tool command** in your final user-facing message. Summarize outcomes clearly and avoid echoing commands verbatim.
|
|
34194
|
+
7. **Respond concisely** and move the conversation forward. Do not re-issue the same command or re-trigger tool use without necessity.
|
|
34195
|
+
8. Follow these steps **iteratively**, confirming success and addressing issues as you go.
|
|
34196
|
+
|
|
34197
|
+
By adhering to these guidelines:
|
|
34198
|
+
- You maintain clarity without accidentally re-invoking tools.
|
|
34199
|
+
- You confirm each step’s results before proceeding.
|
|
34200
|
+
- You provide only the necessary information in user-facing replies to prevent re-interpretation as new commands.`;
|
|
34201
|
+
};
|
|
34202
|
+
var agentsPrompt = (agents, name) => `
|
|
34203
|
+
====
|
|
34204
|
+
|
|
34205
|
+
AVAILABLE AGENTS
|
|
34206
|
+
|
|
34207
|
+
The following agents are available for task handover:
|
|
34208
|
+
${agents.map((agent) => `
|
|
34209
|
+
- **${agent.name}**
|
|
34210
|
+
- Responsibilities:
|
|
34211
|
+
${agent.responsibilities.map((resp) => ` - ${resp}`).join(`
|
|
34212
|
+
`)}`).join(`
|
|
34213
|
+
`)}
|
|
34214
|
+
|
|
34215
|
+
- **Current Agent Role**
|
|
34216
|
+
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.
|
|
34217
|
+
`;
|
|
34218
|
+
var capabilities = (toolNamePrefix) => `
|
|
34219
|
+
====
|
|
34220
|
+
|
|
34221
|
+
CAPABILITIES
|
|
34222
|
+
|
|
34223
|
+
- 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.
|
|
34224
|
+
- 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.`;
|
|
34225
|
+
var systemInformation = (info) => `
|
|
34226
|
+
====
|
|
34227
|
+
|
|
34228
|
+
SYSTEM INFORMATION
|
|
34229
|
+
|
|
34230
|
+
Operating System: ${info.os}`;
|
|
34231
|
+
var interactiveMode = (interactive) => {
|
|
34232
|
+
if (interactive) {
|
|
34233
|
+
return `
|
|
34234
|
+
====
|
|
34235
|
+
|
|
34236
|
+
INTERACTIVE MODE
|
|
34237
|
+
|
|
34238
|
+
You are in interactive mode. This means you may ask user questions to gather additional information to complete the task.
|
|
34239
|
+
`;
|
|
34240
|
+
}
|
|
34241
|
+
return `
|
|
34242
|
+
====
|
|
34243
|
+
|
|
34244
|
+
NON-INTERACTIVE MODE
|
|
34245
|
+
|
|
34246
|
+
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.
|
|
34247
|
+
`;
|
|
34248
|
+
};
|
|
34249
|
+
var customInstructions = (customInstructions2) => {
|
|
34250
|
+
const joined = customInstructions2.join(`
|
|
34251
|
+
`);
|
|
34252
|
+
if (joined.trim() === "") {
|
|
34253
|
+
return "";
|
|
34254
|
+
}
|
|
34255
|
+
return `
|
|
34256
|
+
====
|
|
34257
|
+
|
|
34258
|
+
USER'S CUSTOM INSTRUCTIONS
|
|
34259
|
+
|
|
34260
|
+
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.
|
|
34261
|
+
|
|
34262
|
+
${joined}`;
|
|
34263
|
+
};
|
|
34264
|
+
var customScripts = (commands) => {
|
|
34265
|
+
const joined = Object.entries(commands).map(([name, command]) => {
|
|
34266
|
+
if (typeof command === "string") {
|
|
34267
|
+
return `- ${name}
|
|
34268
|
+
- Command: \`${command}\``;
|
|
34269
|
+
}
|
|
34270
|
+
return `- ${name}
|
|
34271
|
+
- Command: \`${command.command}\`
|
|
34272
|
+
- Description: ${command.description}`;
|
|
34273
|
+
}).join(`
|
|
34274
|
+
`);
|
|
34275
|
+
if (joined.trim() === "") {
|
|
34276
|
+
return "";
|
|
34277
|
+
}
|
|
34278
|
+
return `
|
|
34279
|
+
====
|
|
34280
|
+
|
|
34281
|
+
USER'S CUSTOM COMMANDS
|
|
34282
|
+
|
|
34283
|
+
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.
|
|
34284
|
+
|
|
34285
|
+
${joined}`;
|
|
34286
|
+
};
|
|
34287
|
+
var responsePrompts = {
|
|
34288
|
+
errorInvokeTool: (tool, error) => `An error occurred while invoking the tool "${tool}": ${error}`,
|
|
34289
|
+
requireUseTool: "Error: You must use a tool before proceeding. Making sure the tool is invoked using xml tags.",
|
|
34290
|
+
toolResults: (tool, result) => `<tool_response>
|
|
34291
|
+
<tool_name>${tool}</tool_name>
|
|
34292
|
+
<tool_result>
|
|
34293
|
+
${result}
|
|
34294
|
+
</tool_result>
|
|
34295
|
+
</tool_response>`
|
|
34296
|
+
};
|
|
34297
|
+
|
|
34298
|
+
// ../core/src/Agent/AgentBase.ts
|
|
34299
|
+
class AgentBase {
|
|
34300
|
+
ai;
|
|
34301
|
+
config;
|
|
34302
|
+
handlers;
|
|
34303
|
+
constructor(name, ai, config) {
|
|
34304
|
+
this.ai = ai;
|
|
34305
|
+
if (config.agents && Object.keys(config.agents).length > 0) {
|
|
34306
|
+
const agents = agentsPrompt(config.agents, name);
|
|
34307
|
+
config.systemPrompt += `
|
|
34308
|
+
${agents}`;
|
|
34309
|
+
}
|
|
34310
|
+
this.config = config;
|
|
34311
|
+
const handlers = {};
|
|
34312
|
+
for (const tool of config.tools) {
|
|
34313
|
+
handlers[tool.name] = tool;
|
|
34314
|
+
}
|
|
34315
|
+
this.handlers = handlers;
|
|
34316
|
+
}
|
|
34317
|
+
async startTask({
|
|
34318
|
+
task,
|
|
34319
|
+
context,
|
|
34320
|
+
callback = () => {
|
|
34321
|
+
}
|
|
34322
|
+
}) {
|
|
34323
|
+
const taskInfo = {
|
|
34324
|
+
messages: [],
|
|
34325
|
+
inputTokens: 0,
|
|
34326
|
+
outputTokens: 0,
|
|
34327
|
+
cacheWriteTokens: 0,
|
|
34328
|
+
cacheReadTokens: 0,
|
|
34329
|
+
totalCost: 0
|
|
34330
|
+
};
|
|
34331
|
+
let text = `<task>${task}</task>`;
|
|
34332
|
+
if (context) {
|
|
34333
|
+
text += `
|
|
34334
|
+
<context>${context}</context>`;
|
|
34335
|
+
}
|
|
34336
|
+
callback({ kind: "StartTask" /* StartTask */, info: taskInfo, systemPrompt: this.config.systemPrompt });
|
|
34337
|
+
return await this.#processLoop(text, taskInfo, callback);
|
|
34338
|
+
}
|
|
34339
|
+
async#processLoop(userMessage, taskInfo, callback) {
|
|
34340
|
+
let nextRequest = userMessage;
|
|
34341
|
+
while (nextRequest) {
|
|
34342
|
+
if (this.ai.usageMeter.isLimitExceeded().result) {
|
|
34343
|
+
callback({ kind: "UsageExceeded" /* UsageExceeded */, info: taskInfo });
|
|
34344
|
+
return [{ type: "UsageExceeded" }, taskInfo];
|
|
34345
|
+
}
|
|
34346
|
+
const response = await this.#request(taskInfo, nextRequest, callback);
|
|
34347
|
+
const [newMessage, exitReason] = await this.#handleResponse(taskInfo, response, callback);
|
|
34348
|
+
if (exitReason) {
|
|
34349
|
+
callback({ kind: "EndTask" /* EndTask */, info: taskInfo });
|
|
34350
|
+
return [exitReason, taskInfo];
|
|
34351
|
+
}
|
|
34352
|
+
nextRequest = newMessage;
|
|
34353
|
+
}
|
|
34354
|
+
callback({ kind: "EndTask" /* EndTask */, info: taskInfo });
|
|
34355
|
+
return [{ type: "Exit" /* Exit */, message: "Task completed successfully" }, taskInfo];
|
|
34356
|
+
}
|
|
34357
|
+
async continueTask(userMessage, taskInfo, callback = () => {
|
|
34358
|
+
}) {
|
|
34359
|
+
return await this.#processLoop(userMessage, taskInfo, callback);
|
|
34360
|
+
}
|
|
34361
|
+
async#request(info, userMessage, callback) {
|
|
34362
|
+
await callback({ kind: "StartRequest" /* StartRequest */, info, userMessage });
|
|
34363
|
+
info.messages.push({
|
|
34364
|
+
role: "user",
|
|
34365
|
+
content: userMessage
|
|
34366
|
+
});
|
|
34367
|
+
const stream = this.ai.send(this.config.systemPrompt, info.messages);
|
|
34368
|
+
let currentAssistantMessage = "";
|
|
34369
|
+
for await (const chunk of stream) {
|
|
34370
|
+
switch (chunk.type) {
|
|
34371
|
+
case "usage":
|
|
34372
|
+
info.inputTokens = chunk.inputTokens ?? 0;
|
|
34373
|
+
info.outputTokens = chunk.outputTokens ?? 0;
|
|
34374
|
+
info.cacheWriteTokens = chunk.cacheWriteTokens ?? 0;
|
|
34375
|
+
info.cacheReadTokens = chunk.cacheReadTokens ?? 0;
|
|
34376
|
+
info.totalCost = chunk.totalCost;
|
|
34377
|
+
await callback({ kind: "Usage" /* Usage */, info });
|
|
34378
|
+
break;
|
|
34379
|
+
case "text":
|
|
34380
|
+
currentAssistantMessage += chunk.text;
|
|
34381
|
+
await callback({ kind: "Text" /* Text */, info, newText: chunk.text });
|
|
34382
|
+
break;
|
|
34383
|
+
case "reasoning":
|
|
34384
|
+
await callback({ kind: "Reasoning" /* Reasoning */, info, newText: chunk.text });
|
|
34385
|
+
break;
|
|
34386
|
+
}
|
|
34387
|
+
}
|
|
34388
|
+
if (!currentAssistantMessage) {
|
|
34389
|
+
throw new Error("No assistant message received");
|
|
34390
|
+
}
|
|
34391
|
+
info.messages.push({
|
|
34392
|
+
role: "assistant",
|
|
34393
|
+
content: currentAssistantMessage
|
|
34394
|
+
});
|
|
34395
|
+
const ret = parseAssistantMessage(currentAssistantMessage, this.config.tools, this.config.toolNamePrefix);
|
|
34396
|
+
await callback({ kind: "EndRequest" /* EndRequest */, info });
|
|
34397
|
+
return ret;
|
|
34398
|
+
}
|
|
34399
|
+
async#handleResponse(info, response, callback) {
|
|
34400
|
+
const toolReponses = [];
|
|
34401
|
+
outer:
|
|
34402
|
+
for (const content of response) {
|
|
34403
|
+
switch (content.type) {
|
|
34404
|
+
case "text":
|
|
34405
|
+
break;
|
|
34406
|
+
case "tool_use": {
|
|
34407
|
+
await callback({ kind: "ToolUse" /* ToolUse */, info, tool: content.name });
|
|
34408
|
+
const toolResp = await this.#invokeTool(content.name, content.params);
|
|
34409
|
+
switch (toolResp.type) {
|
|
34410
|
+
case "Reply" /* Reply */:
|
|
34411
|
+
await callback({ kind: "ToolReply" /* ToolReply */, info, tool: content.name });
|
|
34412
|
+
toolReponses.push({ tool: content.name, response: toolResp.message });
|
|
34413
|
+
break;
|
|
34414
|
+
case "Exit" /* Exit */:
|
|
34415
|
+
return [undefined, toolResp];
|
|
34416
|
+
case "Invalid" /* Invalid */:
|
|
34417
|
+
await callback({ kind: "ToolInvalid" /* ToolInvalid */, info, tool: content.name });
|
|
34418
|
+
toolReponses.push({ tool: content.name, response: toolResp.message });
|
|
34419
|
+
break outer;
|
|
34420
|
+
case "Error" /* Error */:
|
|
34421
|
+
await callback({ kind: "ToolError" /* ToolError */, info, tool: content.name });
|
|
34422
|
+
toolReponses.push({ tool: content.name, response: toolResp.message });
|
|
34423
|
+
break outer;
|
|
34424
|
+
case "Interrupted" /* Interrupted */:
|
|
34425
|
+
await callback({ kind: "ToolInterrupted" /* ToolInterrupted */, info, tool: content.name });
|
|
34426
|
+
return [undefined, toolResp];
|
|
34427
|
+
case "HandOver" /* HandOver */:
|
|
34428
|
+
await callback({
|
|
34429
|
+
kind: "ToolHandOver" /* ToolHandOver */,
|
|
34430
|
+
info,
|
|
34431
|
+
tool: content.name,
|
|
34432
|
+
agentName: toolResp.agentName,
|
|
34433
|
+
task: toolResp.task,
|
|
34434
|
+
context: toolResp.context,
|
|
34435
|
+
files: toolResp.files
|
|
34436
|
+
});
|
|
34437
|
+
return [undefined, toolResp];
|
|
34438
|
+
}
|
|
34439
|
+
break;
|
|
34440
|
+
}
|
|
34441
|
+
}
|
|
34442
|
+
}
|
|
34443
|
+
if (toolReponses.length === 0 && !this.config.interactive) {
|
|
34444
|
+
return [responsePrompts.requireUseTool, undefined];
|
|
34445
|
+
}
|
|
34446
|
+
const finalResp = toolReponses.map(({ tool, response: response2 }) => responsePrompts.toolResults(tool, response2)).join(`
|
|
34447
|
+
|
|
34448
|
+
`);
|
|
34449
|
+
return [finalResp, undefined];
|
|
34450
|
+
}
|
|
34451
|
+
async#invokeTool(name, args) {
|
|
34452
|
+
try {
|
|
34453
|
+
const handler13 = this.handlers[name]?.handler;
|
|
34454
|
+
if (!handler13) {
|
|
34455
|
+
return {
|
|
34456
|
+
type: "Error" /* Error */,
|
|
34457
|
+
message: responsePrompts.errorInvokeTool(name, "Tool not found"),
|
|
34458
|
+
canRetry: false
|
|
34459
|
+
};
|
|
34460
|
+
}
|
|
34461
|
+
return await handler13(this.config.provider, args);
|
|
34462
|
+
} catch (error) {
|
|
34463
|
+
return {
|
|
34464
|
+
type: "Error" /* Error */,
|
|
34465
|
+
message: responsePrompts.errorInvokeTool(name, error),
|
|
34466
|
+
canRetry: false
|
|
34467
|
+
};
|
|
34468
|
+
}
|
|
34469
|
+
}
|
|
34470
|
+
get model() {
|
|
34471
|
+
return this.ai.model;
|
|
34472
|
+
}
|
|
34473
|
+
get usage() {
|
|
34474
|
+
return this.ai.usageMeter.usage;
|
|
34475
|
+
}
|
|
34476
|
+
}
|
|
34477
|
+
|
|
34478
|
+
// ../core/src/Agent/AnalyzerAgent/prompts.ts
|
|
34479
|
+
var fullSystemPrompt = (info, tools, toolNamePrefix, instructions, scripts, interactive) => `
|
|
34480
|
+
# Analyzer Agent
|
|
34481
|
+
|
|
34482
|
+
## Role
|
|
34483
|
+
You are the **Analyzer** agent, responsible for:
|
|
34484
|
+
1. **Project Structure Analysis** – Understand codebase organization and architecture.
|
|
34485
|
+
2. **Code Pattern Analysis** – Identify common patterns, conventions, and best practices.
|
|
34486
|
+
3. **Dependency Analysis** – Examine project dependencies and their usage.
|
|
34487
|
+
4. **Workflow Analysis** – Understand development tools, scripts, and processes.
|
|
34488
|
+
5. **Documentation Review** – Analyze documentation and code comments.
|
|
34489
|
+
|
|
34490
|
+
> **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.
|
|
34491
|
+
|
|
34492
|
+
## Rules
|
|
34493
|
+
1. **Thoroughness**: Conduct comprehensive analysis of relevant project aspects.
|
|
34494
|
+
2. **Pattern Recognition**: Identify recurring patterns, conventions, and architectural decisions.
|
|
34495
|
+
3. **Dependency Mapping**: Track and understand relationships between components.
|
|
34496
|
+
4. **Workflow Understanding**: Analyze build processes, testing approaches, and development tools.
|
|
34497
|
+
5. **Documentation Assessment**: Review documentation quality and completeness.
|
|
34498
|
+
6. **Non-Modification**: Never modify code or files - focus solely on analysis.
|
|
34499
|
+
|
|
34500
|
+
${toolUsePrompt(tools, toolNamePrefix)}
|
|
34501
|
+
${capabilities(toolNamePrefix)}
|
|
34502
|
+
${systemInformation(info)}
|
|
34503
|
+
${customInstructions(instructions)}
|
|
34504
|
+
${customScripts(scripts)}
|
|
34505
|
+
${interactiveMode(interactive)}
|
|
34506
|
+
`;
|
|
34507
|
+
|
|
34508
|
+
// ../core/src/Agent/AnalyzerAgent/index.ts
|
|
34509
|
+
class AnalyzerAgent extends AgentBase {
|
|
34510
|
+
constructor(options) {
|
|
34511
|
+
const agentTools = [
|
|
34512
|
+
...options.additionalTools ?? [],
|
|
34513
|
+
askFollowupQuestion_default,
|
|
34514
|
+
attemptCompletion_default,
|
|
34515
|
+
handOver_default,
|
|
34516
|
+
listCodeDefinitionNames_default,
|
|
34517
|
+
listFiles_default,
|
|
34518
|
+
readFile_default,
|
|
34519
|
+
searchFiles_default
|
|
34520
|
+
];
|
|
34521
|
+
const tools = getAvailableTools(options.provider, agentTools);
|
|
34522
|
+
const toolNamePrefix = "tool_";
|
|
34523
|
+
const systemPrompt = fullSystemPrompt({
|
|
34524
|
+
os: options.os
|
|
34525
|
+
}, tools, toolNamePrefix, options.customInstructions ?? [], options.scripts ?? {}, options.interactive);
|
|
34526
|
+
super(analyzerAgentInfo.name, options.ai, {
|
|
34527
|
+
systemPrompt,
|
|
34528
|
+
tools,
|
|
34529
|
+
toolNamePrefix,
|
|
34530
|
+
provider: options.provider,
|
|
34531
|
+
interactive: options.interactive,
|
|
34532
|
+
agents: options.agents
|
|
34533
|
+
});
|
|
34534
|
+
}
|
|
34535
|
+
}
|
|
34536
|
+
var analyzerAgentInfo = {
|
|
34537
|
+
name: "analyzer",
|
|
34538
|
+
responsibilities: [
|
|
34539
|
+
"Analyzing project structure and organization",
|
|
34540
|
+
"Identifying key source code files and their relationships",
|
|
34541
|
+
"Understanding common coding patterns and conventions",
|
|
34542
|
+
"Examining development workflow and tooling",
|
|
34543
|
+
"Analyzing dependencies and their usage patterns"
|
|
34544
|
+
]
|
|
34545
|
+
};
|
|
34546
|
+
|
|
34547
|
+
// ../core/src/Agent/ArchitectAgent/prompts.ts
|
|
34548
|
+
var fullSystemPrompt2 = (info, tools, toolNamePrefix, instructions, scripts, interactive) => `
|
|
34549
|
+
# Architect Agent
|
|
34550
|
+
|
|
34551
|
+
## Role
|
|
34552
|
+
You are the **Architect** agent, responsible for:
|
|
34553
|
+
1. **Task Analysis** – Understand requirements.
|
|
34554
|
+
2. **File Identification** – Find and select relevant files.
|
|
34555
|
+
3. **File Reading** – Use the provided tools to gather information from these files.
|
|
34556
|
+
4. **Implementation Plan** – Draft a concise plan detailing steps, resources, and dependencies.
|
|
34557
|
+
5. **Review & Improve** – Evaluate and refine the plan.
|
|
34558
|
+
6. **Handover** – Provide the final plan, context, and files to the **Coder** agent.
|
|
34559
|
+
|
|
34560
|
+
> **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.
|
|
34561
|
+
|
|
34562
|
+
## Rules
|
|
34563
|
+
1. **Consistency**: Maintain alignment with the user’s instructions and the system’s objectives at all times.
|
|
34564
|
+
2. **Relevance**: Only read and use files directly related to the task. Avoid unnecessary or tangential information.
|
|
34565
|
+
3. **Conciseness**: Keep all communications and plans succinct, avoiding superfluous or repetitive details.
|
|
34566
|
+
4. **Accuracy**: Ensure the information you gather and any conclusions you draw are correct and verifiable.
|
|
34567
|
+
5. **Clarity**: Present the final plan and any supporting details in a structured and easily understandable format.
|
|
34568
|
+
6. **Minimal Queries**: Ask clarifying questions only when essential, and avoid repeated questioning that does not add value.
|
|
34569
|
+
|
|
34570
|
+
## Steps
|
|
34571
|
+
1. **Analyze Task**
|
|
34572
|
+
- Gather and understand the user’s requirements.
|
|
34573
|
+
- Note any potential constraints or objectives that may influence the plan.
|
|
34574
|
+
|
|
34575
|
+
2. **Identify Relevant Files**
|
|
34576
|
+
- Determine which files or documents are necessary.
|
|
34577
|
+
- Justify why these files are relevant.
|
|
34578
|
+
|
|
34579
|
+
3. **Read Files via Tools**
|
|
34580
|
+
- Utilize the provided tools to access and extract information from the identified files.
|
|
34581
|
+
- Summarize key insights or data for the solution.
|
|
34582
|
+
|
|
34583
|
+
4. **Create Implementation Plan**
|
|
34584
|
+
- Outline tasks, define milestones, and detail resources or dependencies.
|
|
34585
|
+
- Provide clear, concise instructions for each step.
|
|
34586
|
+
|
|
34587
|
+
5. **Review & Improve**
|
|
34588
|
+
- Check the plan for consistency, clarity, and feasibility.
|
|
34589
|
+
- Make adjustments or refinements to ensure accuracy and efficiency.
|
|
34590
|
+
|
|
34591
|
+
6. **Handover**
|
|
34592
|
+
- Deliver the final implementation plan, context, and relevant files to the **Coder** agent.
|
|
34593
|
+
- Provide any additional instructions or clarifications needed for successful implementation.
|
|
34594
|
+
${toolUsePrompt(tools, toolNamePrefix)}
|
|
34595
|
+
${capabilities(toolNamePrefix)}
|
|
34596
|
+
${systemInformation(info)}
|
|
34597
|
+
${customInstructions(instructions)}
|
|
34598
|
+
${customScripts(scripts)}
|
|
34599
|
+
${interactiveMode(interactive)}
|
|
34600
|
+
`;
|
|
34601
|
+
|
|
34602
|
+
// ../core/src/Agent/ArchitectAgent/index.ts
|
|
34603
|
+
class ArchitectAgent extends AgentBase {
|
|
34604
|
+
constructor(options) {
|
|
34605
|
+
const agentTools = [
|
|
34606
|
+
...options.additionalTools ?? [],
|
|
34607
|
+
askFollowupQuestion_default,
|
|
34608
|
+
attemptCompletion_default,
|
|
34609
|
+
handOver_default,
|
|
34610
|
+
listCodeDefinitionNames_default,
|
|
34611
|
+
listFiles_default,
|
|
34612
|
+
readFile_default,
|
|
34613
|
+
searchFiles_default
|
|
34614
|
+
];
|
|
34615
|
+
const tools = getAvailableTools(options.provider, agentTools);
|
|
34616
|
+
const toolNamePrefix = "tool_";
|
|
34617
|
+
const systemPrompt = fullSystemPrompt2({
|
|
34618
|
+
os: options.os
|
|
34619
|
+
}, tools, toolNamePrefix, options.customInstructions ?? [], options.scripts ?? {}, options.interactive);
|
|
34620
|
+
super(architectAgentInfo.name, options.ai, {
|
|
34621
|
+
systemPrompt,
|
|
34622
|
+
tools,
|
|
34623
|
+
toolNamePrefix,
|
|
34624
|
+
provider: options.provider,
|
|
34625
|
+
interactive: options.interactive,
|
|
34626
|
+
agents: options.agents
|
|
34627
|
+
});
|
|
34628
|
+
}
|
|
34629
|
+
}
|
|
34630
|
+
var architectAgentInfo = {
|
|
34631
|
+
name: "architect",
|
|
34632
|
+
responsibilities: [
|
|
34633
|
+
"Analyzing the user’s overall task and requirements.",
|
|
34634
|
+
"Creating plans and making higher-level decisions about system structure and design.",
|
|
34635
|
+
"Reviewing and analyzing existing code or components for maintainability and scalability.",
|
|
34636
|
+
"Laying out the roadmap for implementation."
|
|
34637
|
+
]
|
|
34412
34638
|
};
|
|
34639
|
+
|
|
34413
34640
|
// ../core/src/Agent/CoderAgent/prompts.ts
|
|
34414
34641
|
var basePrompt = "You are a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices.";
|
|
34415
34642
|
var editingFilesPrompt = (toolNamePrefix) => `
|
|
@@ -34511,7 +34738,7 @@ You accomplish a given task iteratively, breaking it down into clear steps and w
|
|
|
34511
34738
|
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.
|
|
34512
34739
|
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.
|
|
34513
34740
|
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.`;
|
|
34514
|
-
var
|
|
34741
|
+
var fullSystemPrompt3 = (info, tools, toolNamePrefix, instructions, scripts, interactive) => `
|
|
34515
34742
|
${basePrompt}
|
|
34516
34743
|
${toolUsePrompt(tools, toolNamePrefix)}
|
|
34517
34744
|
${editingFilesPrompt(toolNamePrefix)}
|
|
@@ -34530,7 +34757,7 @@ class CoderAgent extends AgentBase {
|
|
|
34530
34757
|
const combinedTools = [...options.additionalTools ?? [], ...Object.values(exports_allTools)];
|
|
34531
34758
|
const tools = getAvailableTools(options.provider, combinedTools);
|
|
34532
34759
|
const toolNamePrefix = "tool_";
|
|
34533
|
-
const systemPrompt =
|
|
34760
|
+
const systemPrompt = fullSystemPrompt3({
|
|
34534
34761
|
os: options.os
|
|
34535
34762
|
}, tools, toolNamePrefix, options.customInstructions ?? [], options.scripts ?? {}, options.interactive);
|
|
34536
34763
|
super(coderAgentInfo.name, options.ai, {
|
|
@@ -34544,7 +34771,7 @@ class CoderAgent extends AgentBase {
|
|
|
34544
34771
|
}
|
|
34545
34772
|
}
|
|
34546
34773
|
var coderAgentInfo = {
|
|
34547
|
-
name: "
|
|
34774
|
+
name: "coder",
|
|
34548
34775
|
responsibilities: [
|
|
34549
34776
|
"Editing and refactoring existing code.",
|
|
34550
34777
|
"Creating new features or modules.",
|
|
@@ -34552,98 +34779,6 @@ var coderAgentInfo = {
|
|
|
34552
34779
|
"Maintaining coding standards, lint rules, and general code quality."
|
|
34553
34780
|
]
|
|
34554
34781
|
};
|
|
34555
|
-
// ../core/src/Agent/ArchitectAgent/prompts.ts
|
|
34556
|
-
var fullSystemPrompt2 = (info, tools, toolNamePrefix, instructions, scripts, interactive) => `
|
|
34557
|
-
# Architect Agent
|
|
34558
|
-
|
|
34559
|
-
## Role
|
|
34560
|
-
You are the **Architect** agent, responsible for:
|
|
34561
|
-
1. **Task Analysis** – Understand requirements.
|
|
34562
|
-
2. **File Identification** – Find and select relevant files.
|
|
34563
|
-
3. **File Reading** – Use the provided tools to gather information from these files.
|
|
34564
|
-
4. **Implementation Plan** – Draft a concise plan detailing steps, resources, and dependencies.
|
|
34565
|
-
5. **Review & Improve** – Evaluate and refine the plan.
|
|
34566
|
-
6. **Handover** – Provide the final plan, context, and files to the **Coder** agent.
|
|
34567
|
-
|
|
34568
|
-
> **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.
|
|
34569
|
-
|
|
34570
|
-
## Rules
|
|
34571
|
-
1. **Consistency**: Maintain alignment with the user’s instructions and the system’s objectives at all times.
|
|
34572
|
-
2. **Relevance**: Only read and use files directly related to the task. Avoid unnecessary or tangential information.
|
|
34573
|
-
3. **Conciseness**: Keep all communications and plans succinct, avoiding superfluous or repetitive details.
|
|
34574
|
-
4. **Accuracy**: Ensure the information you gather and any conclusions you draw are correct and verifiable.
|
|
34575
|
-
5. **Clarity**: Present the final plan and any supporting details in a structured and easily understandable format.
|
|
34576
|
-
6. **Minimal Queries**: Ask clarifying questions only when essential, and avoid repeated questioning that does not add value.
|
|
34577
|
-
|
|
34578
|
-
## Steps
|
|
34579
|
-
1. **Analyze Task**
|
|
34580
|
-
- Gather and understand the user’s requirements.
|
|
34581
|
-
- Note any potential constraints or objectives that may influence the plan.
|
|
34582
|
-
|
|
34583
|
-
2. **Identify Relevant Files**
|
|
34584
|
-
- Determine which files or documents are necessary.
|
|
34585
|
-
- Justify why these files are relevant.
|
|
34586
|
-
|
|
34587
|
-
3. **Read Files via Tools**
|
|
34588
|
-
- Utilize the provided tools to access and extract information from the identified files.
|
|
34589
|
-
- Summarize key insights or data for the solution.
|
|
34590
|
-
|
|
34591
|
-
4. **Create Implementation Plan**
|
|
34592
|
-
- Outline tasks, define milestones, and detail resources or dependencies.
|
|
34593
|
-
- Provide clear, concise instructions for each step.
|
|
34594
|
-
|
|
34595
|
-
5. **Review & Improve**
|
|
34596
|
-
- Check the plan for consistency, clarity, and feasibility.
|
|
34597
|
-
- Make adjustments or refinements to ensure accuracy and efficiency.
|
|
34598
|
-
|
|
34599
|
-
6. **Handover**
|
|
34600
|
-
- Deliver the final implementation plan, context, and relevant files to the **Coder** agent.
|
|
34601
|
-
- Provide any additional instructions or clarifications needed for successful implementation.
|
|
34602
|
-
${toolUsePrompt(tools, toolNamePrefix)}
|
|
34603
|
-
${capabilities(toolNamePrefix)}
|
|
34604
|
-
${systemInformation(info)}
|
|
34605
|
-
${customInstructions(instructions)}
|
|
34606
|
-
${customScripts(scripts)}
|
|
34607
|
-
${interactiveMode(interactive)}
|
|
34608
|
-
`;
|
|
34609
|
-
|
|
34610
|
-
// ../core/src/Agent/ArchitectAgent/index.ts
|
|
34611
|
-
class ArchitectAgent extends AgentBase {
|
|
34612
|
-
constructor(options) {
|
|
34613
|
-
const agentTools = [
|
|
34614
|
-
...options.additionalTools ?? [],
|
|
34615
|
-
askFollowupQuestion_default,
|
|
34616
|
-
attemptCompletion_default,
|
|
34617
|
-
handOver_default,
|
|
34618
|
-
listCodeDefinitionNames_default,
|
|
34619
|
-
listFiles_default,
|
|
34620
|
-
readFile_default,
|
|
34621
|
-
searchFiles_default
|
|
34622
|
-
];
|
|
34623
|
-
const tools = getAvailableTools(options.provider, agentTools);
|
|
34624
|
-
const toolNamePrefix = "tool_";
|
|
34625
|
-
const systemPrompt = fullSystemPrompt2({
|
|
34626
|
-
os: options.os
|
|
34627
|
-
}, tools, toolNamePrefix, options.customInstructions ?? [], options.scripts ?? {}, options.interactive);
|
|
34628
|
-
super(architectAgentInfo.name, options.ai, {
|
|
34629
|
-
systemPrompt,
|
|
34630
|
-
tools,
|
|
34631
|
-
toolNamePrefix,
|
|
34632
|
-
provider: options.provider,
|
|
34633
|
-
interactive: options.interactive,
|
|
34634
|
-
agents: options.agents
|
|
34635
|
-
});
|
|
34636
|
-
}
|
|
34637
|
-
}
|
|
34638
|
-
var architectAgentInfo = {
|
|
34639
|
-
name: "Architect",
|
|
34640
|
-
responsibilities: [
|
|
34641
|
-
"Analyzing the user’s overall task and requirements.",
|
|
34642
|
-
"Creating plans and making higher-level decisions about system structure and design.",
|
|
34643
|
-
"Reviewing and analyzing existing code or components for maintainability and scalability.",
|
|
34644
|
-
"Laying out the roadmap for implementation."
|
|
34645
|
-
]
|
|
34646
|
-
};
|
|
34647
34782
|
// ../core/src/Agent/MultiAgent.ts
|
|
34648
34783
|
class MultiAgent {
|
|
34649
34784
|
#config;
|
|
@@ -34654,30 +34789,19 @@ class MultiAgent {
|
|
|
34654
34789
|
get model() {
|
|
34655
34790
|
return this.#activeAgent?.model;
|
|
34656
34791
|
}
|
|
34657
|
-
async#startTask(agentName, task, context,
|
|
34792
|
+
async#startTask(agentName, task, context, callback) {
|
|
34658
34793
|
this.#activeAgent = await this.#config.createAgent(agentName);
|
|
34659
34794
|
const [exitReason, info] = await this.#activeAgent.startTask({
|
|
34660
34795
|
task,
|
|
34661
34796
|
context,
|
|
34662
|
-
maxIterations,
|
|
34663
34797
|
callback
|
|
34664
34798
|
});
|
|
34665
34799
|
if (typeof exitReason === "string") {
|
|
34666
34800
|
return [exitReason, info];
|
|
34667
34801
|
}
|
|
34668
34802
|
if (exitReason.type === "HandOver") {
|
|
34669
|
-
const
|
|
34670
|
-
|
|
34671
|
-
return ["MaxIterations", info];
|
|
34672
|
-
}
|
|
34673
|
-
const context2 = await this.#config.getContext(agentName, exitReason.context, exitReason.files);
|
|
34674
|
-
const [exitReason2, info2] = await this.#startTask(exitReason.agentName, exitReason.task, context2, remainIteration, callback);
|
|
34675
|
-
info2.inputTokens += info.inputTokens;
|
|
34676
|
-
info2.outputTokens += info.outputTokens;
|
|
34677
|
-
info2.cacheWriteTokens += info.cacheWriteTokens;
|
|
34678
|
-
info2.cacheReadTokens += info.cacheReadTokens;
|
|
34679
|
-
info2.totalCost = (info.totalCost ?? 0) + (info2.totalCost ?? 0);
|
|
34680
|
-
return [exitReason2, info2];
|
|
34803
|
+
const context2 = await this.#config.getContext?.(agentName, exitReason.context, exitReason.files);
|
|
34804
|
+
return await this.#startTask(exitReason.agentName, exitReason.task, context2, callback);
|
|
34681
34805
|
}
|
|
34682
34806
|
return [exitReason, info];
|
|
34683
34807
|
}
|
|
@@ -34685,8 +34809,7 @@ class MultiAgent {
|
|
|
34685
34809
|
if (this.#activeAgent) {
|
|
34686
34810
|
throw new Error("An active agent already exists");
|
|
34687
34811
|
}
|
|
34688
|
-
|
|
34689
|
-
return this.#startTask(options.agentName, options.task, options.context, maxIterations, options.callback);
|
|
34812
|
+
return this.#startTask(options.agentName, options.task, options.context, options.callback);
|
|
34690
34813
|
}
|
|
34691
34814
|
async continueTask(userMessage, taskInfo, callback = () => {
|
|
34692
34815
|
}) {
|
|
@@ -34696,6 +34819,9 @@ class MultiAgent {
|
|
|
34696
34819
|
return this.#activeAgent.continueTask(userMessage, taskInfo, callback);
|
|
34697
34820
|
}
|
|
34698
34821
|
}
|
|
34822
|
+
|
|
34823
|
+
// ../core/src/Agent/index.ts
|
|
34824
|
+
var allAgents = [architectAgentInfo, coderAgentInfo, analyzerAgentInfo];
|
|
34699
34825
|
// ../core/src/AiTool/generateGitCommitMessage.ts
|
|
34700
34826
|
var prompt = `
|
|
34701
34827
|
You are an advanced assistant specialized in creating concise and accurate Git commit messages. When you receive:
|
|
@@ -34768,6 +34894,9 @@ You are given:
|
|
|
34768
34894
|
|
|
34769
34895
|
Your task:
|
|
34770
34896
|
1. Consider the optional context (if provided).
|
|
34897
|
+
- If an issue number is found, add "Closes #xxx" at the beginning of the PR description
|
|
34898
|
+
- IMPORTANT: Use ONLY the exact format "Closes #xxx" at the beginning of the description
|
|
34899
|
+
- DO NOT use variations like "Closes issue #xxx" or other formats
|
|
34771
34900
|
2. Analyze the combined commit messages and diffs.
|
|
34772
34901
|
3. Produce a single GitHub Pull Request title.
|
|
34773
34902
|
4. Produce a Pull Request description that explains the changes.
|
|
@@ -34803,7 +34932,7 @@ Below is an **example** of the input and output:
|
|
|
34803
34932
|
Example Input:
|
|
34804
34933
|
<tool_input>
|
|
34805
34934
|
<tool_input_branch_name>feature/refactor-logging</tool_input_branch_name>
|
|
34806
|
-
<tool_input_context>Focus on clean code and maintainability</tool_input_context>
|
|
34935
|
+
<tool_input_context>Implementing changes for issue #123 - Focus on clean code and maintainability</tool_input_context>
|
|
34807
34936
|
<tool_input_commit_messages>
|
|
34808
34937
|
Remove debug logs
|
|
34809
34938
|
Refactor order validation logic
|
|
@@ -34824,6 +34953,8 @@ Example Output:
|
|
|
34824
34953
|
<tool_output>
|
|
34825
34954
|
<tool_output_pr_title>Refactor Order Validation and Remove Debug Logs</tool_output_pr_title>
|
|
34826
34955
|
<tool_output_pr_description>
|
|
34956
|
+
closes #123
|
|
34957
|
+
|
|
34827
34958
|
This PR removes unnecessary debug print statements and updates order validation
|
|
34828
34959
|
to use the new validate_and_process method for improved maintainability.
|
|
34829
34960
|
</tool_output_pr_description>
|
|
@@ -34868,21 +34999,102 @@ ${output}`);
|
|
|
34868
34999
|
}
|
|
34869
35000
|
};
|
|
34870
35001
|
|
|
35002
|
+
// ../core/src/AiTool/generateProjectConfig.ts
|
|
35003
|
+
var prompt3 = `You are an analyzer agent responsible for examining project files and generating appropriate polkacodes configuration. Your task is to:
|
|
35004
|
+
|
|
35005
|
+
1. Read and analyze the provided files using tool_read_file to understand:
|
|
35006
|
+
- Build tools and package manager (e.g., bun, npm)
|
|
35007
|
+
- Testing frameworks and patterns
|
|
35008
|
+
- Code style tools and rules
|
|
35009
|
+
- Project structure and conventions
|
|
35010
|
+
- Common development workflows
|
|
35011
|
+
|
|
35012
|
+
2. Generate a YAML configuration that captures:
|
|
35013
|
+
- scripts section based on package.json scripts and CI workflows
|
|
35014
|
+
- rules section based on project conventions, tools, and patterns
|
|
35015
|
+
|
|
35016
|
+
3. Use tool_attempt_completion to return the final configuration in this format:
|
|
35017
|
+
|
|
35018
|
+
<tool_attempt_completion>
|
|
35019
|
+
<tool_parameter_result>
|
|
35020
|
+
scripts:
|
|
35021
|
+
test:
|
|
35022
|
+
command: "bun test"
|
|
35023
|
+
description: "Run tests with bun:test"
|
|
35024
|
+
lint:
|
|
35025
|
+
command: "biome check ."
|
|
35026
|
+
description: "Check code style with Biome"
|
|
35027
|
+
|
|
35028
|
+
rules:
|
|
35029
|
+
- "Use \`bun\` as package manager"
|
|
35030
|
+
- "Write tests using bun:test with snapshots"
|
|
35031
|
+
- "Follow Biome code style"
|
|
35032
|
+
</tool_parameter_result>
|
|
35033
|
+
</tool_attempt_completion>
|
|
35034
|
+
|
|
35035
|
+
Focus on:
|
|
35036
|
+
- Package manager and dependency management
|
|
35037
|
+
- Testing frameworks and patterns
|
|
35038
|
+
- Code style and linting rules
|
|
35039
|
+
- File organization and naming conventions
|
|
35040
|
+
- Build and development workflows
|
|
35041
|
+
|
|
35042
|
+
The configuration should accurately reflect the project's structure, tools, and conventions.
|
|
35043
|
+
`;
|
|
35044
|
+
var generateProjectConfig_default = {
|
|
35045
|
+
name: "generateProjectConfig",
|
|
35046
|
+
description: "Analyzes project files to generate polkacodes config sections",
|
|
35047
|
+
prompt: prompt3,
|
|
35048
|
+
formatInput: (params) => {
|
|
35049
|
+
return `<tool_input>
|
|
35050
|
+
${params.join(`
|
|
35051
|
+
`)}
|
|
35052
|
+
</tool_input>`;
|
|
35053
|
+
},
|
|
35054
|
+
parseOutput: (output) => {
|
|
35055
|
+
return output.trim();
|
|
35056
|
+
},
|
|
35057
|
+
agent: "analyzer"
|
|
35058
|
+
};
|
|
35059
|
+
|
|
34871
35060
|
// ../core/src/AiTool/index.ts
|
|
34872
35061
|
var executeTool = async (definition, ai, params) => {
|
|
34873
|
-
const { response, usage } = await ai.request(definition.prompt, [
|
|
35062
|
+
const { response, usage } = await ai.request(definition.prompt, [
|
|
35063
|
+
{ role: "user", content: definition.formatInput(params) }
|
|
35064
|
+
]);
|
|
34874
35065
|
return {
|
|
34875
35066
|
response: definition.parseOutput(response),
|
|
34876
35067
|
usage
|
|
34877
35068
|
};
|
|
34878
35069
|
};
|
|
35070
|
+
var executeAgentTool = async (definition, agent, params, callback) => {
|
|
35071
|
+
if (!definition.agent) {
|
|
35072
|
+
throw new Error("Agent not specified");
|
|
35073
|
+
}
|
|
35074
|
+
const [exitReason] = await agent.startTask({
|
|
35075
|
+
agentName: definition.agent,
|
|
35076
|
+
task: definition.prompt,
|
|
35077
|
+
context: definition.formatInput(params),
|
|
35078
|
+
callback
|
|
35079
|
+
});
|
|
35080
|
+
if (exitReason.type === "Exit" /* Exit */) {
|
|
35081
|
+
return definition.parseOutput(exitReason.message);
|
|
35082
|
+
}
|
|
35083
|
+
throw new Error(`Tool execution failed: ${exitReason.type}`);
|
|
35084
|
+
};
|
|
34879
35085
|
var makeTool = (definition) => {
|
|
34880
35086
|
return async (ai, params) => {
|
|
34881
35087
|
return executeTool(definition, ai, params);
|
|
34882
35088
|
};
|
|
34883
35089
|
};
|
|
35090
|
+
var makeAgentTool = (definition) => {
|
|
35091
|
+
return async (agent, params, callback) => {
|
|
35092
|
+
return executeAgentTool(definition, agent, params, callback);
|
|
35093
|
+
};
|
|
35094
|
+
};
|
|
34884
35095
|
var generateGitCommitMessage = makeTool(generateGitCommitMessage_default);
|
|
34885
35096
|
var generateGithubPullRequestDetails = makeTool(generateGithubPullRequestDetails_default);
|
|
35097
|
+
var generateProjectConfig = makeAgentTool(generateProjectConfig_default);
|
|
34886
35098
|
// src/Chat.ts
|
|
34887
35099
|
import readline from "node:readline";
|
|
34888
35100
|
|
|
@@ -35149,9 +35361,9 @@ async function searchFiles(path2, regex, filePattern, cwd, excludeFiles) {
|
|
|
35149
35361
|
}
|
|
35150
35362
|
|
|
35151
35363
|
// src/provider.ts
|
|
35152
|
-
var getProvider = (options) => {
|
|
35364
|
+
var getProvider = (agentName, config, options = {}) => {
|
|
35153
35365
|
const ig = import_ignore2.default().add(options.excludeFiles ?? []);
|
|
35154
|
-
|
|
35366
|
+
const provider2 = {
|
|
35155
35367
|
readFile: async (path2) => {
|
|
35156
35368
|
if (ig.ignores(path2)) {
|
|
35157
35369
|
throw new Error(`Not allow to access file ${path2}`);
|
|
@@ -35185,7 +35397,7 @@ var getProvider = (options) => {
|
|
|
35185
35397
|
},
|
|
35186
35398
|
executeCommand: (command, needApprove) => {
|
|
35187
35399
|
return new Promise((resolve2, reject) => {
|
|
35188
|
-
options.command
|
|
35400
|
+
options.command?.onStarted(command);
|
|
35189
35401
|
const child = spawn2(command, [], {
|
|
35190
35402
|
shell: true,
|
|
35191
35403
|
stdio: "pipe"
|
|
@@ -35194,16 +35406,16 @@ var getProvider = (options) => {
|
|
|
35194
35406
|
let stderrText = "";
|
|
35195
35407
|
child.stdout.on("data", (data) => {
|
|
35196
35408
|
const dataStr = data.toString();
|
|
35197
|
-
options.command
|
|
35409
|
+
options.command?.onStdout(dataStr);
|
|
35198
35410
|
stdoutText += dataStr;
|
|
35199
35411
|
});
|
|
35200
35412
|
child.stderr.on("data", (data) => {
|
|
35201
35413
|
const dataStr = data.toString();
|
|
35202
|
-
options.command
|
|
35414
|
+
options.command?.onStderr(dataStr);
|
|
35203
35415
|
stderrText += dataStr;
|
|
35204
35416
|
});
|
|
35205
35417
|
child.on("close", (code) => {
|
|
35206
|
-
options.command
|
|
35418
|
+
options.command?.onExit(code ?? 0);
|
|
35207
35419
|
resolve2({
|
|
35208
35420
|
stdout: stdoutText,
|
|
35209
35421
|
stderr: stderrText,
|
|
@@ -35211,36 +35423,58 @@ var getProvider = (options) => {
|
|
|
35211
35423
|
});
|
|
35212
35424
|
});
|
|
35213
35425
|
child.on("error", (err) => {
|
|
35214
|
-
options.command
|
|
35426
|
+
options.command?.onError(err);
|
|
35215
35427
|
reject(err);
|
|
35216
35428
|
});
|
|
35217
35429
|
});
|
|
35430
|
+
},
|
|
35431
|
+
attemptCompletion: async (result) => {
|
|
35432
|
+
const cmd = (config.hooks?.agents?.[agentName]?.beforeCompletion ?? config.hooks?.agents?.default?.beforeCompletion)?.trim();
|
|
35433
|
+
if (cmd) {
|
|
35434
|
+
try {
|
|
35435
|
+
const { exitCode, stdout, stderr } = await provider2.executeCommand(cmd, false);
|
|
35436
|
+
if (exitCode !== 0) {
|
|
35437
|
+
return `
|
|
35438
|
+
<command>${cmd}</command>
|
|
35439
|
+
<command_exit_code>${exitCode}</command_exit_code>
|
|
35440
|
+
<command_stdout>
|
|
35441
|
+
${stdout}
|
|
35442
|
+
</command_stdout>
|
|
35443
|
+
<command_stderr>
|
|
35444
|
+
${stderr}
|
|
35445
|
+
</command_stderr>`;
|
|
35446
|
+
}
|
|
35447
|
+
} catch (error) {
|
|
35448
|
+
console.warn(`Failed to execute hook: ${error}`);
|
|
35449
|
+
}
|
|
35450
|
+
}
|
|
35451
|
+
return;
|
|
35218
35452
|
}
|
|
35219
35453
|
};
|
|
35454
|
+
return provider2;
|
|
35220
35455
|
};
|
|
35221
35456
|
|
|
35222
35457
|
// src/Runner.ts
|
|
35223
35458
|
class Runner {
|
|
35224
35459
|
#options;
|
|
35225
35460
|
#multiAgent;
|
|
35226
|
-
#
|
|
35227
|
-
inputTokens: 0,
|
|
35228
|
-
outputTokens: 0,
|
|
35229
|
-
cacheWriteTokens: 0,
|
|
35230
|
-
cacheReadTokens: 0,
|
|
35231
|
-
totalCost: 0
|
|
35232
|
-
};
|
|
35461
|
+
#usageMeter;
|
|
35233
35462
|
constructor(options) {
|
|
35234
35463
|
this.#options = options;
|
|
35464
|
+
this.#usageMeter = new UsageMeter({
|
|
35465
|
+
maxCost: options.budget,
|
|
35466
|
+
maxMessageCount: options.maxMessageCount
|
|
35467
|
+
});
|
|
35235
35468
|
const service = createService(options.provider, {
|
|
35236
35469
|
apiKey: options.apiKey,
|
|
35237
|
-
model: options.model
|
|
35470
|
+
model: options.model,
|
|
35471
|
+
usageMeter: this.#usageMeter
|
|
35238
35472
|
});
|
|
35239
35473
|
let rules2 = options.config.rules;
|
|
35240
35474
|
if (typeof rules2 === "string") {
|
|
35241
35475
|
rules2 = [rules2];
|
|
35242
35476
|
}
|
|
35243
|
-
const
|
|
35477
|
+
const providerOptions = {
|
|
35244
35478
|
command: {
|
|
35245
35479
|
onStarted(command) {
|
|
35246
35480
|
console.log(`$ >>>> $ ${command}`);
|
|
@@ -35259,29 +35493,40 @@ class Runner {
|
|
|
35259
35493
|
}
|
|
35260
35494
|
},
|
|
35261
35495
|
excludeFiles: options.config.excludeFiles
|
|
35262
|
-
}
|
|
35496
|
+
};
|
|
35263
35497
|
const platform = os.platform();
|
|
35264
35498
|
const agents = [coderAgentInfo, architectAgentInfo];
|
|
35265
35499
|
this.#multiAgent = new MultiAgent({
|
|
35266
35500
|
createAgent: async (name) => {
|
|
35267
|
-
|
|
35268
|
-
|
|
35501
|
+
const agentName = name.trim().toLowerCase();
|
|
35502
|
+
switch (agentName) {
|
|
35503
|
+
case coderAgentInfo.name:
|
|
35269
35504
|
return new CoderAgent({
|
|
35270
35505
|
ai: service,
|
|
35271
35506
|
os: platform,
|
|
35272
35507
|
customInstructions: rules2,
|
|
35273
35508
|
scripts: options.config.scripts,
|
|
35274
|
-
provider:
|
|
35509
|
+
provider: getProvider("coder", options.config, providerOptions),
|
|
35275
35510
|
interactive: options.interactive,
|
|
35276
35511
|
agents
|
|
35277
35512
|
});
|
|
35278
|
-
case architectAgentInfo.name
|
|
35513
|
+
case architectAgentInfo.name:
|
|
35279
35514
|
return new ArchitectAgent({
|
|
35280
35515
|
ai: service,
|
|
35281
35516
|
os: platform,
|
|
35282
35517
|
customInstructions: rules2,
|
|
35283
35518
|
scripts: options.config.scripts,
|
|
35284
|
-
provider:
|
|
35519
|
+
provider: getProvider("architect", options.config, providerOptions),
|
|
35520
|
+
interactive: options.interactive,
|
|
35521
|
+
agents
|
|
35522
|
+
});
|
|
35523
|
+
case analyzerAgentInfo.name:
|
|
35524
|
+
return new AnalyzerAgent({
|
|
35525
|
+
ai: service,
|
|
35526
|
+
os: platform,
|
|
35527
|
+
customInstructions: rules2,
|
|
35528
|
+
scripts: options.config.scripts,
|
|
35529
|
+
provider: getProvider("analyzer", options.config, providerOptions),
|
|
35285
35530
|
interactive: options.interactive,
|
|
35286
35531
|
agents
|
|
35287
35532
|
});
|
|
@@ -35291,6 +35536,7 @@ class Runner {
|
|
|
35291
35536
|
},
|
|
35292
35537
|
getContext: async (name, context, files) => {
|
|
35293
35538
|
let ret = await this.#defaultContext(name);
|
|
35539
|
+
const unreadableFiles = [];
|
|
35294
35540
|
if (files) {
|
|
35295
35541
|
for (const file of files) {
|
|
35296
35542
|
try {
|
|
@@ -35299,7 +35545,18 @@ class Runner {
|
|
|
35299
35545
|
<file_content path="${file}">${fileContent}</file_content>`;
|
|
35300
35546
|
} catch (error) {
|
|
35301
35547
|
console.warn(`Failed to read file: ${file}`, error);
|
|
35548
|
+
unreadableFiles.push(file);
|
|
35549
|
+
}
|
|
35550
|
+
}
|
|
35551
|
+
if (unreadableFiles.length > 0) {
|
|
35552
|
+
ret += `
|
|
35553
|
+
<unreadable_files>
|
|
35554
|
+
`;
|
|
35555
|
+
for (const file of unreadableFiles) {
|
|
35556
|
+
ret += `${file}
|
|
35557
|
+
`;
|
|
35302
35558
|
}
|
|
35559
|
+
ret += "</unreadable_files>";
|
|
35303
35560
|
}
|
|
35304
35561
|
}
|
|
35305
35562
|
if (context) {
|
|
@@ -35331,45 +35588,18 @@ ${fileList.join(`
|
|
|
35331
35588
|
agentName,
|
|
35332
35589
|
task,
|
|
35333
35590
|
context: await this.#defaultContext(agentName),
|
|
35334
|
-
callback: this.#
|
|
35591
|
+
callback: this.#options.eventCallback
|
|
35335
35592
|
});
|
|
35336
35593
|
return [exitReason, info];
|
|
35337
35594
|
}
|
|
35338
|
-
#taskEventCallback = (event) => {
|
|
35339
|
-
if (event.kind === "Usage" /* Usage */) {
|
|
35340
|
-
this.#usage.inputTokens += event.info.inputTokens;
|
|
35341
|
-
this.#usage.outputTokens += event.info.outputTokens;
|
|
35342
|
-
this.#usage.cacheReadTokens += event.info.cacheReadTokens;
|
|
35343
|
-
this.#usage.cacheWriteTokens += event.info.cacheWriteTokens;
|
|
35344
|
-
let totalCost = event.info.totalCost ?? 0;
|
|
35345
|
-
if (!totalCost) {
|
|
35346
|
-
const modelInfo = this.#multiAgent.model?.info;
|
|
35347
|
-
const inputCost = (modelInfo?.inputPrice ?? 0) * event.info.inputTokens;
|
|
35348
|
-
const outputCost = (modelInfo?.outputPrice ?? 0) * event.info.outputTokens;
|
|
35349
|
-
const cacheReadCost = (modelInfo?.cacheReadsPrice ?? 0) * event.info.cacheReadTokens;
|
|
35350
|
-
const cacheWriteCost = (modelInfo?.cacheWritesPrice ?? 0) * event.info.cacheWriteTokens;
|
|
35351
|
-
totalCost = (inputCost + outputCost + cacheReadCost + cacheWriteCost) / 1e6;
|
|
35352
|
-
}
|
|
35353
|
-
this.#usage.totalCost += totalCost;
|
|
35354
|
-
}
|
|
35355
|
-
this.#options.eventCallback(event);
|
|
35356
|
-
};
|
|
35357
35595
|
async continueTask(message, taskInfo) {
|
|
35358
|
-
return await this.#multiAgent.continueTask(message, taskInfo, this.#
|
|
35596
|
+
return await this.#multiAgent.continueTask(message, taskInfo, this.#options.eventCallback);
|
|
35359
35597
|
}
|
|
35360
35598
|
get usage() {
|
|
35361
|
-
return this.#usage;
|
|
35599
|
+
return this.#usageMeter.usage;
|
|
35362
35600
|
}
|
|
35363
35601
|
printUsage() {
|
|
35364
|
-
|
|
35365
|
-
return;
|
|
35366
|
-
}
|
|
35367
|
-
console.log("Usages:");
|
|
35368
|
-
console.log(`Input tokens: ${this.#usage.inputTokens}`);
|
|
35369
|
-
console.log(`Output tokens: ${this.#usage.outputTokens}`);
|
|
35370
|
-
console.log(`Cache read tokens: ${this.#usage.cacheReadTokens}`);
|
|
35371
|
-
console.log(`Cache write tokens: ${this.#usage.cacheWriteTokens}`);
|
|
35372
|
-
console.log(`Total cost: ${this.#usage.totalCost}`);
|
|
35602
|
+
this.#usageMeter.printUsage();
|
|
35373
35603
|
}
|
|
35374
35604
|
}
|
|
35375
35605
|
|
|
@@ -39420,6 +39650,9 @@ var z2 = /* @__PURE__ */ Object.freeze({
|
|
|
39420
39650
|
});
|
|
39421
39651
|
|
|
39422
39652
|
// src/config.ts
|
|
39653
|
+
var agentNameValues = allAgents.map((agent) => agent.name);
|
|
39654
|
+
var agentNames = z2.enum([agentNameValues[0], ...agentNameValues.slice(1)]);
|
|
39655
|
+
var agentNameOrDefault = z2.union([agentNames, z2.literal("default")]);
|
|
39423
39656
|
var providerModelSchema = z2.object({
|
|
39424
39657
|
provider: z2.string().optional(),
|
|
39425
39658
|
model: z2.string().optional()
|
|
@@ -39437,14 +39670,16 @@ var configSchema = z2.object({
|
|
|
39437
39670
|
})).optional(),
|
|
39438
39671
|
defaultProvider: z2.string().optional(),
|
|
39439
39672
|
defaultModel: z2.string().optional(),
|
|
39440
|
-
|
|
39673
|
+
maxMessageCount: z2.number().int().positive().optional(),
|
|
39674
|
+
budget: z2.number().int().positive().optional(),
|
|
39675
|
+
hooks: z2.object({
|
|
39676
|
+
agents: z2.record(agentNameOrDefault, z2.object({ beforeCompletion: z2.string().optional() })).optional()
|
|
39677
|
+
}).optional(),
|
|
39441
39678
|
scripts: z2.record(z2.string(), z2.string().or(z2.object({
|
|
39442
39679
|
command: z2.string(),
|
|
39443
39680
|
description: z2.string()
|
|
39444
39681
|
}))).optional(),
|
|
39445
|
-
agents: z2.
|
|
39446
|
-
default: agentSchema.optional()
|
|
39447
|
-
}).catchall(agentSchema).optional(),
|
|
39682
|
+
agents: z2.record(agentNameOrDefault, agentSchema).optional(),
|
|
39448
39683
|
commands: z2.object({
|
|
39449
39684
|
default: providerModelSchema.optional()
|
|
39450
39685
|
}).catchall(providerModelSchema).optional(),
|
|
@@ -39527,10 +39762,17 @@ var readConfig = (path2) => {
|
|
|
39527
39762
|
const config = $parse(file);
|
|
39528
39763
|
return configSchema.parse(config);
|
|
39529
39764
|
};
|
|
39765
|
+
var readLocalConfig = (path2) => {
|
|
39766
|
+
try {
|
|
39767
|
+
return readConfig(path2 ?? localConfigFileName);
|
|
39768
|
+
} catch (error) {
|
|
39769
|
+
return;
|
|
39770
|
+
}
|
|
39771
|
+
};
|
|
39530
39772
|
|
|
39531
39773
|
// src/options.ts
|
|
39532
39774
|
function addSharedOptions(command) {
|
|
39533
|
-
return command.option("-c --config <path>", "Path to config file").option("--api-provider <provider>", "API provider").option("--model <model>", "Model ID").option("--api-key <key>", "API key").option("--max-
|
|
39775
|
+
return command.option("-c --config <path>", "Path to config file").option("--api-provider <provider>", "API provider").option("--model <model>", "Model ID").option("--api-key <key>", "API key").option("--max-messages <iterations>", "Maximum number of messages to send. Default to 50", Number.parseInt, 50).option("--budget <budget>", "Budget for the AI service. Default to $1000", Number.parseFloat, 1000).option("-v --verbose", "Enable verbose output. Use -v for level 1, -vv for level 2", (value, prev) => prev + 1, 0);
|
|
39534
39776
|
}
|
|
39535
39777
|
|
|
39536
39778
|
class ApiProviderConfig {
|
|
@@ -39598,7 +39840,8 @@ function parseOptions(options, cwd = process.cwd(), home = os2.homedir()) {
|
|
|
39598
39840
|
...config
|
|
39599
39841
|
});
|
|
39600
39842
|
return {
|
|
39601
|
-
|
|
39843
|
+
maxMessageCount: options.maxMessageCount ?? config.maxMessageCount ?? 30,
|
|
39844
|
+
budget: options.budget ?? Number(process.env.POLKA_BUDGET) ?? config.budget ?? 1000,
|
|
39602
39845
|
verbose: options.verbose ?? 0,
|
|
39603
39846
|
config,
|
|
39604
39847
|
providerConfig
|
|
@@ -40159,8 +40402,11 @@ ${event.systemPrompt}`);
|
|
|
40159
40402
|
console.log("Files:", event.files);
|
|
40160
40403
|
console.log();
|
|
40161
40404
|
break;
|
|
40162
|
-
case "
|
|
40163
|
-
console.log(
|
|
40405
|
+
case "UsageExceeded" /* UsageExceeded */:
|
|
40406
|
+
console.log(`
|
|
40407
|
+
|
|
40408
|
+
======= Usage Exceeded ========
|
|
40409
|
+
`);
|
|
40164
40410
|
break;
|
|
40165
40411
|
case "EndTask" /* EndTask */:
|
|
40166
40412
|
break;
|
|
@@ -41094,11 +41340,11 @@ class ScreenManager {
|
|
|
41094
41340
|
render(content, bottomContent = "") {
|
|
41095
41341
|
const promptLine = lastLine(content);
|
|
41096
41342
|
const rawPromptLine = import_strip_ansi.default(promptLine);
|
|
41097
|
-
let
|
|
41343
|
+
let prompt4 = rawPromptLine;
|
|
41098
41344
|
if (this.rl.line.length > 0) {
|
|
41099
|
-
|
|
41345
|
+
prompt4 = prompt4.slice(0, -this.rl.line.length);
|
|
41100
41346
|
}
|
|
41101
|
-
this.rl.setPrompt(
|
|
41347
|
+
this.rl.setPrompt(prompt4);
|
|
41102
41348
|
this.cursorPos = this.rl.getCursorPos();
|
|
41103
41349
|
const width = readlineWidth();
|
|
41104
41350
|
content = breakLines(content, width);
|
|
@@ -41168,7 +41414,7 @@ function getCallSites() {
|
|
|
41168
41414
|
function createPrompt(view) {
|
|
41169
41415
|
const callSites = getCallSites();
|
|
41170
41416
|
const callerFilename = callSites[1]?.getFileName?.();
|
|
41171
|
-
const
|
|
41417
|
+
const prompt4 = (config, context = {}) => {
|
|
41172
41418
|
const { input = process.stdin, signal } = context;
|
|
41173
41419
|
const cleanups = new Set;
|
|
41174
41420
|
const output = new import_mute_stream.default;
|
|
@@ -41229,7 +41475,7 @@ function createPrompt(view) {
|
|
|
41229
41475
|
}).then(() => promise), { cancel });
|
|
41230
41476
|
});
|
|
41231
41477
|
};
|
|
41232
|
-
return
|
|
41478
|
+
return prompt4;
|
|
41233
41479
|
}
|
|
41234
41480
|
// ../../node_modules/@inquirer/core/dist/esm/lib/Separator.js
|
|
41235
41481
|
var import_yoctocolors_cjs2 = __toESM(require_yoctocolors_cjs(), 1);
|
|
@@ -41701,8 +41947,9 @@ ${provider2.toUpperCase()}_API_KEY=${apiKey}`;
|
|
|
41701
41947
|
});
|
|
41702
41948
|
|
|
41703
41949
|
// src/commands/chat.ts
|
|
41704
|
-
var runChat = async (
|
|
41705
|
-
const
|
|
41950
|
+
var runChat = async (opts, command) => {
|
|
41951
|
+
const options = command?.parent?.opts() ?? opts ?? {};
|
|
41952
|
+
const { config, providerConfig, maxMessageCount, verbose, budget } = parseOptions(options);
|
|
41706
41953
|
let { provider: provider2, model, apiKey } = providerConfig.getConfigForAgent("coder") ?? {};
|
|
41707
41954
|
if (!provider2) {
|
|
41708
41955
|
const newConfig = await configPrompt({ provider: provider2, model, apiKey });
|
|
@@ -41720,7 +41967,8 @@ var runChat = async (options) => {
|
|
|
41720
41967
|
model: model ?? defaultModels[provider2],
|
|
41721
41968
|
apiKey,
|
|
41722
41969
|
config: config ?? {},
|
|
41723
|
-
|
|
41970
|
+
maxMessageCount,
|
|
41971
|
+
budget,
|
|
41724
41972
|
interactive: true,
|
|
41725
41973
|
eventCallback: printEvent(verbose)
|
|
41726
41974
|
});
|
|
@@ -41737,24 +41985,20 @@ var runChat = async (options) => {
|
|
|
41737
41985
|
taskInfo = info;
|
|
41738
41986
|
exitReason = reason;
|
|
41739
41987
|
}
|
|
41740
|
-
switch (exitReason) {
|
|
41741
|
-
case "
|
|
41742
|
-
console.log("
|
|
41988
|
+
switch (exitReason.type) {
|
|
41989
|
+
case "UsageExceeded":
|
|
41990
|
+
console.log("Usage exceeded.");
|
|
41743
41991
|
chat2.close();
|
|
41744
41992
|
break;
|
|
41745
41993
|
case "WaitForUserInput":
|
|
41746
41994
|
break;
|
|
41747
|
-
|
|
41748
|
-
|
|
41749
|
-
|
|
41750
|
-
|
|
41751
|
-
|
|
41752
|
-
|
|
41753
|
-
|
|
41754
|
-
chat2.close();
|
|
41755
|
-
return;
|
|
41756
|
-
}
|
|
41757
|
-
}
|
|
41995
|
+
case "Interrupted" /* Interrupted */:
|
|
41996
|
+
console.log("Interrupted.");
|
|
41997
|
+
chat2.close();
|
|
41998
|
+
break;
|
|
41999
|
+
case "Exit" /* Exit */:
|
|
42000
|
+
chat2.close();
|
|
42001
|
+
return;
|
|
41758
42002
|
}
|
|
41759
42003
|
},
|
|
41760
42004
|
onExit: async () => {
|
|
@@ -41766,7 +42010,7 @@ var runChat = async (options) => {
|
|
|
41766
42010
|
};
|
|
41767
42011
|
|
|
41768
42012
|
// src/commands/commit.ts
|
|
41769
|
-
import { execSync } from "node:child_process";
|
|
42013
|
+
import { execSync, spawnSync } from "node:child_process";
|
|
41770
42014
|
|
|
41771
42015
|
// ../../node_modules/ora/index.js
|
|
41772
42016
|
import process10 from "node:process";
|
|
@@ -42373,8 +42617,9 @@ function ora(options) {
|
|
|
42373
42617
|
}
|
|
42374
42618
|
|
|
42375
42619
|
// src/commands/commit.ts
|
|
42376
|
-
var commitCommand = new Command("commit").description("Create a commit with AI-generated message").option("-a, --all", "Stage all files before committing").argument("[message]", "Optional context for the commit message generation").action(async (message,
|
|
42620
|
+
var commitCommand = new Command("commit").description("Create a commit with AI-generated message").option("-a, --all", "Stage all files before committing").argument("[message]", "Optional context for the commit message generation").action(async (message, _options, command) => {
|
|
42377
42621
|
const spinner = ora("Gathering information...").start();
|
|
42622
|
+
const options = command.parent?.opts() ?? {};
|
|
42378
42623
|
const { providerConfig } = parseOptions(options);
|
|
42379
42624
|
const { provider: provider2, model, apiKey } = providerConfig.getConfigForCommand("commit") ?? {};
|
|
42380
42625
|
console.log("Provider:", provider2);
|
|
@@ -42413,25 +42658,110 @@ var commitCommand = new Command("commit").description("Create a commit with AI-g
|
|
|
42413
42658
|
spinner.text = "Generating commit message...";
|
|
42414
42659
|
const result = await generateGitCommitMessage(ai, { diff, context: message });
|
|
42415
42660
|
spinner.succeed("Commit message generated");
|
|
42661
|
+
console.log(`
|
|
42662
|
+
Commit message:
|
|
42663
|
+
${result.response}`);
|
|
42416
42664
|
try {
|
|
42417
|
-
|
|
42665
|
+
spawnSync("git", ["commit", "-m", result.response], { stdio: "inherit" });
|
|
42418
42666
|
} catch {
|
|
42419
42667
|
console.error("Error: Commit failed");
|
|
42420
42668
|
process.exit(1);
|
|
42421
42669
|
}
|
|
42422
|
-
console.log(`
|
|
42423
|
-
Commit message:
|
|
42424
|
-
${result.response}`);
|
|
42425
42670
|
} catch (error) {
|
|
42426
42671
|
console.error("Error:", error);
|
|
42427
42672
|
process.exit(1);
|
|
42428
42673
|
}
|
|
42429
42674
|
});
|
|
42430
42675
|
|
|
42676
|
+
// src/commands/init.ts
|
|
42677
|
+
import os4 from "node:os";
|
|
42678
|
+
import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "node:fs";
|
|
42679
|
+
var initCommand = new Command("init").description("Initialize polkacodes configuration");
|
|
42680
|
+
initCommand.action(async (_options, command) => {
|
|
42681
|
+
const options = command.parent?.opts() ?? {};
|
|
42682
|
+
try {
|
|
42683
|
+
const localConfig = readLocalConfig() ?? {};
|
|
42684
|
+
if (localConfig) {
|
|
42685
|
+
const proceed = await esm_default2({
|
|
42686
|
+
message: `Found existing config at ${localConfigFileName}. Do you want to proceed? This will overwrite the existing config.`,
|
|
42687
|
+
default: false
|
|
42688
|
+
});
|
|
42689
|
+
if (!proceed) {
|
|
42690
|
+
console.log("Cancelled");
|
|
42691
|
+
return;
|
|
42692
|
+
}
|
|
42693
|
+
}
|
|
42694
|
+
const { config: existingConfig, providerConfig, verbose } = parseOptions(options);
|
|
42695
|
+
let { provider: provider2, model, apiKey } = providerConfig.getConfigForCommand("init") ?? {};
|
|
42696
|
+
console.log("Provider:", provider2);
|
|
42697
|
+
console.log("Model:", model);
|
|
42698
|
+
if (!provider2) {
|
|
42699
|
+
const newConfig = await configPrompt({ provider: provider2, model, apiKey });
|
|
42700
|
+
provider2 = newConfig.provider;
|
|
42701
|
+
model = newConfig.model;
|
|
42702
|
+
apiKey = newConfig.apiKey;
|
|
42703
|
+
localConfig.defaultProvider = provider2;
|
|
42704
|
+
localConfig.defaultModel = model;
|
|
42705
|
+
}
|
|
42706
|
+
const service = createService(provider2, {
|
|
42707
|
+
apiKey: apiKey ?? process.env.POLKA_API_KEY ?? options.apiKey ?? existingConfig.providers?.[provider2]?.apiKey,
|
|
42708
|
+
model
|
|
42709
|
+
});
|
|
42710
|
+
const multiAgent = new MultiAgent({
|
|
42711
|
+
createAgent: async (name) => {
|
|
42712
|
+
const agentName = name.trim().toLowerCase();
|
|
42713
|
+
switch (agentName) {
|
|
42714
|
+
case analyzerAgentInfo.name:
|
|
42715
|
+
return new AnalyzerAgent({
|
|
42716
|
+
ai: service,
|
|
42717
|
+
os: os4.platform(),
|
|
42718
|
+
provider: getProvider("analyzer", existingConfig),
|
|
42719
|
+
interactive: false
|
|
42720
|
+
});
|
|
42721
|
+
default:
|
|
42722
|
+
throw new Error(`Unknown agent: ${name}`);
|
|
42723
|
+
}
|
|
42724
|
+
}
|
|
42725
|
+
});
|
|
42726
|
+
console.log("Analyzing project files...");
|
|
42727
|
+
const files = {};
|
|
42728
|
+
const [relevantFiles] = await listFiles(".", true, 1000, process.cwd());
|
|
42729
|
+
for (const filePath of relevantFiles) {
|
|
42730
|
+
if (typeof filePath === "string" && existsSync3(filePath)) {
|
|
42731
|
+
try {
|
|
42732
|
+
const content = readFileSync3(filePath, "utf8");
|
|
42733
|
+
files[filePath] = content;
|
|
42734
|
+
} catch (error) {
|
|
42735
|
+
console.warn(`Failed to read file: ${filePath}`);
|
|
42736
|
+
}
|
|
42737
|
+
}
|
|
42738
|
+
}
|
|
42739
|
+
const { response: generatedConfig } = await generateProjectConfig(multiAgent, relevantFiles, printEvent(verbose));
|
|
42740
|
+
const parsedConfig = generatedConfig ? $parse(generatedConfig) : {};
|
|
42741
|
+
const config = {
|
|
42742
|
+
...localConfig,
|
|
42743
|
+
...parsedConfig
|
|
42744
|
+
};
|
|
42745
|
+
if (apiKey) {
|
|
42746
|
+
config.providers = {
|
|
42747
|
+
[provider2]: {
|
|
42748
|
+
apiKey
|
|
42749
|
+
}
|
|
42750
|
+
};
|
|
42751
|
+
}
|
|
42752
|
+
writeFileSync2(localConfigFileName, $stringify(config));
|
|
42753
|
+
console.log(`Configuration saved to ${localConfigFileName}`);
|
|
42754
|
+
} catch (error) {
|
|
42755
|
+
console.error("Failed to generate configuration:", error);
|
|
42756
|
+
process.exit(1);
|
|
42757
|
+
}
|
|
42758
|
+
});
|
|
42759
|
+
|
|
42431
42760
|
// src/commands/pr.ts
|
|
42432
|
-
import { execSync as execSync2, spawnSync } from "node:child_process";
|
|
42433
|
-
var prCommand = new Command("pr").description("Create a GitHub pull request").argument("[message]", "Optional context for the commit message generation").action(async (message,
|
|
42761
|
+
import { execSync as execSync2, spawnSync as spawnSync2 } from "node:child_process";
|
|
42762
|
+
var prCommand = new Command("pr").description("Create a GitHub pull request").argument("[message]", "Optional context for the commit message generation").action(async (message, _options, command) => {
|
|
42434
42763
|
const spinner = ora("Gathering information...").start();
|
|
42764
|
+
const options = command.parent?.opts() ?? {};
|
|
42435
42765
|
const { providerConfig } = parseOptions(options);
|
|
42436
42766
|
const { provider: provider2, model, apiKey } = providerConfig.getConfigForCommand("pr") ?? {};
|
|
42437
42767
|
console.log("Provider:", provider2);
|
|
@@ -42481,7 +42811,7 @@ var prCommand = new Command("pr").description("Create a GitHub pull request").ar
|
|
|
42481
42811
|
});
|
|
42482
42812
|
spinner.succeed("Pull request details generated");
|
|
42483
42813
|
await new Promise((resolve2) => setTimeout(resolve2, 10));
|
|
42484
|
-
|
|
42814
|
+
spawnSync2("gh", ["pr", "create", "--title", prDetails.response.title.trim(), "--body", prDetails.response.description.trim()], {
|
|
42485
42815
|
stdio: "inherit"
|
|
42486
42816
|
});
|
|
42487
42817
|
} catch (error) {
|
|
@@ -42541,7 +42871,7 @@ var runTask = async (taskArg, options) => {
|
|
|
42541
42871
|
process.exit(1);
|
|
42542
42872
|
}
|
|
42543
42873
|
}
|
|
42544
|
-
const { providerConfig, config,
|
|
42874
|
+
const { providerConfig, config, maxMessageCount, verbose, budget } = parseOptions(options);
|
|
42545
42875
|
let { provider: provider2, model, apiKey } = providerConfig.getConfigForAgent("coder") ?? {};
|
|
42546
42876
|
if (!provider2) {
|
|
42547
42877
|
const newConfig = await configPrompt({ provider: provider2, model, apiKey });
|
|
@@ -42556,7 +42886,8 @@ var runTask = async (taskArg, options) => {
|
|
|
42556
42886
|
model: model ?? defaultModels[provider2],
|
|
42557
42887
|
apiKey,
|
|
42558
42888
|
config: config ?? {},
|
|
42559
|
-
|
|
42889
|
+
maxMessageCount,
|
|
42890
|
+
budget,
|
|
42560
42891
|
interactive: false,
|
|
42561
42892
|
eventCallback: printEvent(verbose)
|
|
42562
42893
|
});
|
|
@@ -42570,6 +42901,7 @@ program2.name("polka-codes").description("Polka Codes CLI").version(version);
|
|
|
42570
42901
|
program2.argument("[task]", "The task to execute").action(runTask);
|
|
42571
42902
|
program2.command("chat").description("Start an interactive chat session").action(runChat);
|
|
42572
42903
|
program2.addCommand(configCommand);
|
|
42904
|
+
program2.addCommand(initCommand);
|
|
42573
42905
|
program2.addCommand(commitCommand);
|
|
42574
42906
|
program2.addCommand(prCommand);
|
|
42575
42907
|
addSharedOptions(program2);
|