@polka-codes/cli 0.4.7 → 0.4.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/dist/index.js +1494 -1189
- 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.9";
|
|
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,7 +35361,7 @@ async function searchFiles(path2, regex, filePattern, cwd, excludeFiles) {
|
|
|
35149
35361
|
}
|
|
35150
35362
|
|
|
35151
35363
|
// src/provider.ts
|
|
35152
|
-
var getProvider = (agentName, config, 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) => {
|
|
@@ -35185,7 +35397,7 @@ var getProvider = (agentName, config, 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 = (agentName, config, 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,7 +35423,7 @@ var getProvider = (agentName, config, 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
|
});
|
|
@@ -35246,18 +35458,17 @@ ${stderr}
|
|
|
35246
35458
|
class Runner {
|
|
35247
35459
|
#options;
|
|
35248
35460
|
#multiAgent;
|
|
35249
|
-
#
|
|
35250
|
-
inputTokens: 0,
|
|
35251
|
-
outputTokens: 0,
|
|
35252
|
-
cacheWriteTokens: 0,
|
|
35253
|
-
cacheReadTokens: 0,
|
|
35254
|
-
totalCost: 0
|
|
35255
|
-
};
|
|
35461
|
+
#usageMeter;
|
|
35256
35462
|
constructor(options) {
|
|
35257
35463
|
this.#options = options;
|
|
35464
|
+
this.#usageMeter = new UsageMeter({
|
|
35465
|
+
maxCost: options.budget,
|
|
35466
|
+
maxMessageCount: options.maxMessageCount
|
|
35467
|
+
});
|
|
35258
35468
|
const service = createService(options.provider, {
|
|
35259
35469
|
apiKey: options.apiKey,
|
|
35260
|
-
model: options.model
|
|
35470
|
+
model: options.model,
|
|
35471
|
+
usageMeter: this.#usageMeter
|
|
35261
35472
|
});
|
|
35262
35473
|
let rules2 = options.config.rules;
|
|
35263
35474
|
if (typeof rules2 === "string") {
|
|
@@ -35289,7 +35500,7 @@ class Runner {
|
|
|
35289
35500
|
createAgent: async (name) => {
|
|
35290
35501
|
const agentName = name.trim().toLowerCase();
|
|
35291
35502
|
switch (agentName) {
|
|
35292
|
-
case coderAgentInfo.name
|
|
35503
|
+
case coderAgentInfo.name:
|
|
35293
35504
|
return new CoderAgent({
|
|
35294
35505
|
ai: service,
|
|
35295
35506
|
os: platform,
|
|
@@ -35299,7 +35510,7 @@ class Runner {
|
|
|
35299
35510
|
interactive: options.interactive,
|
|
35300
35511
|
agents
|
|
35301
35512
|
});
|
|
35302
|
-
case architectAgentInfo.name
|
|
35513
|
+
case architectAgentInfo.name:
|
|
35303
35514
|
return new ArchitectAgent({
|
|
35304
35515
|
ai: service,
|
|
35305
35516
|
os: platform,
|
|
@@ -35309,12 +35520,23 @@ class Runner {
|
|
|
35309
35520
|
interactive: options.interactive,
|
|
35310
35521
|
agents
|
|
35311
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),
|
|
35530
|
+
interactive: options.interactive,
|
|
35531
|
+
agents
|
|
35532
|
+
});
|
|
35312
35533
|
default:
|
|
35313
35534
|
throw new Error(`Unknown agent: ${name}`);
|
|
35314
35535
|
}
|
|
35315
35536
|
},
|
|
35316
35537
|
getContext: async (name, context, files) => {
|
|
35317
35538
|
let ret = await this.#defaultContext(name);
|
|
35539
|
+
const unreadableFiles = [];
|
|
35318
35540
|
if (files) {
|
|
35319
35541
|
for (const file of files) {
|
|
35320
35542
|
try {
|
|
@@ -35323,7 +35545,18 @@ class Runner {
|
|
|
35323
35545
|
<file_content path="${file}">${fileContent}</file_content>`;
|
|
35324
35546
|
} catch (error) {
|
|
35325
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
|
+
`;
|
|
35326
35558
|
}
|
|
35559
|
+
ret += "</unreadable_files>";
|
|
35327
35560
|
}
|
|
35328
35561
|
}
|
|
35329
35562
|
if (context) {
|
|
@@ -35355,45 +35588,18 @@ ${fileList.join(`
|
|
|
35355
35588
|
agentName,
|
|
35356
35589
|
task,
|
|
35357
35590
|
context: await this.#defaultContext(agentName),
|
|
35358
|
-
callback: this.#
|
|
35591
|
+
callback: this.#options.eventCallback
|
|
35359
35592
|
});
|
|
35360
35593
|
return [exitReason, info];
|
|
35361
35594
|
}
|
|
35362
|
-
#taskEventCallback = (event) => {
|
|
35363
|
-
if (event.kind === "Usage" /* Usage */) {
|
|
35364
|
-
this.#usage.inputTokens += event.info.inputTokens;
|
|
35365
|
-
this.#usage.outputTokens += event.info.outputTokens;
|
|
35366
|
-
this.#usage.cacheReadTokens += event.info.cacheReadTokens;
|
|
35367
|
-
this.#usage.cacheWriteTokens += event.info.cacheWriteTokens;
|
|
35368
|
-
let totalCost = event.info.totalCost ?? 0;
|
|
35369
|
-
if (!totalCost) {
|
|
35370
|
-
const modelInfo = this.#multiAgent.model?.info;
|
|
35371
|
-
const inputCost = (modelInfo?.inputPrice ?? 0) * event.info.inputTokens;
|
|
35372
|
-
const outputCost = (modelInfo?.outputPrice ?? 0) * event.info.outputTokens;
|
|
35373
|
-
const cacheReadCost = (modelInfo?.cacheReadsPrice ?? 0) * event.info.cacheReadTokens;
|
|
35374
|
-
const cacheWriteCost = (modelInfo?.cacheWritesPrice ?? 0) * event.info.cacheWriteTokens;
|
|
35375
|
-
totalCost = (inputCost + outputCost + cacheReadCost + cacheWriteCost) / 1e6;
|
|
35376
|
-
}
|
|
35377
|
-
this.#usage.totalCost += totalCost;
|
|
35378
|
-
}
|
|
35379
|
-
this.#options.eventCallback(event);
|
|
35380
|
-
};
|
|
35381
35595
|
async continueTask(message, taskInfo) {
|
|
35382
|
-
return await this.#multiAgent.continueTask(message, taskInfo, this.#
|
|
35596
|
+
return await this.#multiAgent.continueTask(message, taskInfo, this.#options.eventCallback);
|
|
35383
35597
|
}
|
|
35384
35598
|
get usage() {
|
|
35385
|
-
return this.#usage;
|
|
35599
|
+
return this.#usageMeter.usage;
|
|
35386
35600
|
}
|
|
35387
35601
|
printUsage() {
|
|
35388
|
-
|
|
35389
|
-
return;
|
|
35390
|
-
}
|
|
35391
|
-
console.log("Usages:");
|
|
35392
|
-
console.log(`Input tokens: ${this.#usage.inputTokens}`);
|
|
35393
|
-
console.log(`Output tokens: ${this.#usage.outputTokens}`);
|
|
35394
|
-
console.log(`Cache read tokens: ${this.#usage.cacheReadTokens}`);
|
|
35395
|
-
console.log(`Cache write tokens: ${this.#usage.cacheWriteTokens}`);
|
|
35396
|
-
console.log(`Total cost: ${this.#usage.totalCost}`);
|
|
35602
|
+
this.#usageMeter.printUsage();
|
|
35397
35603
|
}
|
|
35398
35604
|
}
|
|
35399
35605
|
|
|
@@ -39444,7 +39650,8 @@ var z2 = /* @__PURE__ */ Object.freeze({
|
|
|
39444
39650
|
});
|
|
39445
39651
|
|
|
39446
39652
|
// src/config.ts
|
|
39447
|
-
var
|
|
39653
|
+
var agentNameValues = allAgents.map((agent) => agent.name);
|
|
39654
|
+
var agentNames = z2.enum([agentNameValues[0], ...agentNameValues.slice(1)]);
|
|
39448
39655
|
var agentNameOrDefault = z2.union([agentNames, z2.literal("default")]);
|
|
39449
39656
|
var providerModelSchema = z2.object({
|
|
39450
39657
|
provider: z2.string().optional(),
|
|
@@ -39463,7 +39670,8 @@ var configSchema = z2.object({
|
|
|
39463
39670
|
})).optional(),
|
|
39464
39671
|
defaultProvider: z2.string().optional(),
|
|
39465
39672
|
defaultModel: z2.string().optional(),
|
|
39466
|
-
|
|
39673
|
+
maxMessageCount: z2.number().int().positive().optional(),
|
|
39674
|
+
budget: z2.number().int().positive().optional(),
|
|
39467
39675
|
hooks: z2.object({
|
|
39468
39676
|
agents: z2.record(agentNameOrDefault, z2.object({ beforeCompletion: z2.string().optional() })).optional()
|
|
39469
39677
|
}).optional(),
|
|
@@ -39554,10 +39762,17 @@ var readConfig = (path2) => {
|
|
|
39554
39762
|
const config = $parse(file);
|
|
39555
39763
|
return configSchema.parse(config);
|
|
39556
39764
|
};
|
|
39765
|
+
var readLocalConfig = (path2) => {
|
|
39766
|
+
try {
|
|
39767
|
+
return readConfig(path2 ?? localConfigFileName);
|
|
39768
|
+
} catch (error) {
|
|
39769
|
+
return;
|
|
39770
|
+
}
|
|
39771
|
+
};
|
|
39557
39772
|
|
|
39558
39773
|
// src/options.ts
|
|
39559
39774
|
function addSharedOptions(command) {
|
|
39560
|
-
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);
|
|
39561
39776
|
}
|
|
39562
39777
|
|
|
39563
39778
|
class ApiProviderConfig {
|
|
@@ -39625,7 +39840,8 @@ function parseOptions(options, cwd = process.cwd(), home = os2.homedir()) {
|
|
|
39625
39840
|
...config
|
|
39626
39841
|
});
|
|
39627
39842
|
return {
|
|
39628
|
-
|
|
39843
|
+
maxMessageCount: options.maxMessageCount ?? config.maxMessageCount ?? 30,
|
|
39844
|
+
budget: options.budget ?? Number(process.env.POLKA_BUDGET) ?? config.budget ?? 1000,
|
|
39629
39845
|
verbose: options.verbose ?? 0,
|
|
39630
39846
|
config,
|
|
39631
39847
|
providerConfig
|
|
@@ -40186,8 +40402,11 @@ ${event.systemPrompt}`);
|
|
|
40186
40402
|
console.log("Files:", event.files);
|
|
40187
40403
|
console.log();
|
|
40188
40404
|
break;
|
|
40189
|
-
case "
|
|
40190
|
-
console.log(
|
|
40405
|
+
case "UsageExceeded" /* UsageExceeded */:
|
|
40406
|
+
console.log(`
|
|
40407
|
+
|
|
40408
|
+
======= Usage Exceeded ========
|
|
40409
|
+
`);
|
|
40191
40410
|
break;
|
|
40192
40411
|
case "EndTask" /* EndTask */:
|
|
40193
40412
|
break;
|
|
@@ -41121,11 +41340,11 @@ class ScreenManager {
|
|
|
41121
41340
|
render(content, bottomContent = "") {
|
|
41122
41341
|
const promptLine = lastLine(content);
|
|
41123
41342
|
const rawPromptLine = import_strip_ansi.default(promptLine);
|
|
41124
|
-
let
|
|
41343
|
+
let prompt4 = rawPromptLine;
|
|
41125
41344
|
if (this.rl.line.length > 0) {
|
|
41126
|
-
|
|
41345
|
+
prompt4 = prompt4.slice(0, -this.rl.line.length);
|
|
41127
41346
|
}
|
|
41128
|
-
this.rl.setPrompt(
|
|
41347
|
+
this.rl.setPrompt(prompt4);
|
|
41129
41348
|
this.cursorPos = this.rl.getCursorPos();
|
|
41130
41349
|
const width = readlineWidth();
|
|
41131
41350
|
content = breakLines(content, width);
|
|
@@ -41195,7 +41414,7 @@ function getCallSites() {
|
|
|
41195
41414
|
function createPrompt(view) {
|
|
41196
41415
|
const callSites = getCallSites();
|
|
41197
41416
|
const callerFilename = callSites[1]?.getFileName?.();
|
|
41198
|
-
const
|
|
41417
|
+
const prompt4 = (config, context = {}) => {
|
|
41199
41418
|
const { input = process.stdin, signal } = context;
|
|
41200
41419
|
const cleanups = new Set;
|
|
41201
41420
|
const output = new import_mute_stream.default;
|
|
@@ -41256,7 +41475,7 @@ function createPrompt(view) {
|
|
|
41256
41475
|
}).then(() => promise), { cancel });
|
|
41257
41476
|
});
|
|
41258
41477
|
};
|
|
41259
|
-
return
|
|
41478
|
+
return prompt4;
|
|
41260
41479
|
}
|
|
41261
41480
|
// ../../node_modules/@inquirer/core/dist/esm/lib/Separator.js
|
|
41262
41481
|
var import_yoctocolors_cjs2 = __toESM(require_yoctocolors_cjs(), 1);
|
|
@@ -41728,8 +41947,9 @@ ${provider2.toUpperCase()}_API_KEY=${apiKey}`;
|
|
|
41728
41947
|
});
|
|
41729
41948
|
|
|
41730
41949
|
// src/commands/chat.ts
|
|
41731
|
-
var runChat = async (
|
|
41732
|
-
const
|
|
41950
|
+
var runChat = async (opts, command) => {
|
|
41951
|
+
const options = command?.parent?.opts() ?? opts ?? {};
|
|
41952
|
+
const { config, providerConfig, maxMessageCount, verbose, budget } = parseOptions(options);
|
|
41733
41953
|
let { provider: provider2, model, apiKey } = providerConfig.getConfigForAgent("coder") ?? {};
|
|
41734
41954
|
if (!provider2) {
|
|
41735
41955
|
const newConfig = await configPrompt({ provider: provider2, model, apiKey });
|
|
@@ -41747,7 +41967,8 @@ var runChat = async (options) => {
|
|
|
41747
41967
|
model: model ?? defaultModels[provider2],
|
|
41748
41968
|
apiKey,
|
|
41749
41969
|
config: config ?? {},
|
|
41750
|
-
|
|
41970
|
+
maxMessageCount,
|
|
41971
|
+
budget,
|
|
41751
41972
|
interactive: true,
|
|
41752
41973
|
eventCallback: printEvent(verbose)
|
|
41753
41974
|
});
|
|
@@ -41764,24 +41985,20 @@ var runChat = async (options) => {
|
|
|
41764
41985
|
taskInfo = info;
|
|
41765
41986
|
exitReason = reason;
|
|
41766
41987
|
}
|
|
41767
|
-
switch (exitReason) {
|
|
41768
|
-
case "
|
|
41769
|
-
console.log("
|
|
41988
|
+
switch (exitReason.type) {
|
|
41989
|
+
case "UsageExceeded":
|
|
41990
|
+
console.log("Usage exceeded.");
|
|
41770
41991
|
chat2.close();
|
|
41771
41992
|
break;
|
|
41772
41993
|
case "WaitForUserInput":
|
|
41773
41994
|
break;
|
|
41774
|
-
|
|
41775
|
-
|
|
41776
|
-
|
|
41777
|
-
|
|
41778
|
-
|
|
41779
|
-
|
|
41780
|
-
|
|
41781
|
-
chat2.close();
|
|
41782
|
-
return;
|
|
41783
|
-
}
|
|
41784
|
-
}
|
|
41995
|
+
case "Interrupted" /* Interrupted */:
|
|
41996
|
+
console.log("Interrupted.");
|
|
41997
|
+
chat2.close();
|
|
41998
|
+
break;
|
|
41999
|
+
case "Exit" /* Exit */:
|
|
42000
|
+
chat2.close();
|
|
42001
|
+
return;
|
|
41785
42002
|
}
|
|
41786
42003
|
},
|
|
41787
42004
|
onExit: async () => {
|
|
@@ -41793,7 +42010,7 @@ var runChat = async (options) => {
|
|
|
41793
42010
|
};
|
|
41794
42011
|
|
|
41795
42012
|
// src/commands/commit.ts
|
|
41796
|
-
import { execSync } from "node:child_process";
|
|
42013
|
+
import { execSync, spawnSync } from "node:child_process";
|
|
41797
42014
|
|
|
41798
42015
|
// ../../node_modules/ora/index.js
|
|
41799
42016
|
import process10 from "node:process";
|
|
@@ -42400,8 +42617,9 @@ function ora(options) {
|
|
|
42400
42617
|
}
|
|
42401
42618
|
|
|
42402
42619
|
// src/commands/commit.ts
|
|
42403
|
-
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, localOptions, command) => {
|
|
42404
42621
|
const spinner = ora("Gathering information...").start();
|
|
42622
|
+
const options = command.parent?.opts() ?? {};
|
|
42405
42623
|
const { providerConfig } = parseOptions(options);
|
|
42406
42624
|
const { provider: provider2, model, apiKey } = providerConfig.getConfigForCommand("commit") ?? {};
|
|
42407
42625
|
console.log("Provider:", provider2);
|
|
@@ -42419,7 +42637,7 @@ var commitCommand = new Command("commit").description("Create a commit with AI-g
|
|
|
42419
42637
|
const stagedFiles = status.split(`
|
|
42420
42638
|
`).filter((line) => line.match(/^[MADRC]/));
|
|
42421
42639
|
if (stagedFiles.length === 0) {
|
|
42422
|
-
if (
|
|
42640
|
+
if (localOptions.all) {
|
|
42423
42641
|
execSync("git add .");
|
|
42424
42642
|
} else {
|
|
42425
42643
|
spinner.stopAndPersist();
|
|
@@ -42440,25 +42658,110 @@ var commitCommand = new Command("commit").description("Create a commit with AI-g
|
|
|
42440
42658
|
spinner.text = "Generating commit message...";
|
|
42441
42659
|
const result = await generateGitCommitMessage(ai, { diff, context: message });
|
|
42442
42660
|
spinner.succeed("Commit message generated");
|
|
42661
|
+
console.log(`
|
|
42662
|
+
Commit message:
|
|
42663
|
+
${result.response}`);
|
|
42443
42664
|
try {
|
|
42444
|
-
|
|
42665
|
+
spawnSync("git", ["commit", "-m", result.response], { stdio: "inherit" });
|
|
42445
42666
|
} catch {
|
|
42446
42667
|
console.error("Error: Commit failed");
|
|
42447
42668
|
process.exit(1);
|
|
42448
42669
|
}
|
|
42449
|
-
console.log(`
|
|
42450
|
-
Commit message:
|
|
42451
|
-
${result.response}`);
|
|
42452
42670
|
} catch (error) {
|
|
42453
42671
|
console.error("Error:", error);
|
|
42454
42672
|
process.exit(1);
|
|
42455
42673
|
}
|
|
42456
42674
|
});
|
|
42457
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
|
+
|
|
42458
42760
|
// src/commands/pr.ts
|
|
42459
|
-
import { execSync as execSync2, spawnSync } from "node:child_process";
|
|
42460
|
-
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) => {
|
|
42461
42763
|
const spinner = ora("Gathering information...").start();
|
|
42764
|
+
const options = command.parent?.opts() ?? {};
|
|
42462
42765
|
const { providerConfig } = parseOptions(options);
|
|
42463
42766
|
const { provider: provider2, model, apiKey } = providerConfig.getConfigForCommand("pr") ?? {};
|
|
42464
42767
|
console.log("Provider:", provider2);
|
|
@@ -42508,7 +42811,7 @@ var prCommand = new Command("pr").description("Create a GitHub pull request").ar
|
|
|
42508
42811
|
});
|
|
42509
42812
|
spinner.succeed("Pull request details generated");
|
|
42510
42813
|
await new Promise((resolve2) => setTimeout(resolve2, 10));
|
|
42511
|
-
|
|
42814
|
+
spawnSync2("gh", ["pr", "create", "--title", prDetails.response.title.trim(), "--body", prDetails.response.description.trim()], {
|
|
42512
42815
|
stdio: "inherit"
|
|
42513
42816
|
});
|
|
42514
42817
|
} catch (error) {
|
|
@@ -42568,7 +42871,7 @@ var runTask = async (taskArg, options) => {
|
|
|
42568
42871
|
process.exit(1);
|
|
42569
42872
|
}
|
|
42570
42873
|
}
|
|
42571
|
-
const { providerConfig, config,
|
|
42874
|
+
const { providerConfig, config, maxMessageCount, verbose, budget } = parseOptions(options);
|
|
42572
42875
|
let { provider: provider2, model, apiKey } = providerConfig.getConfigForAgent("coder") ?? {};
|
|
42573
42876
|
if (!provider2) {
|
|
42574
42877
|
const newConfig = await configPrompt({ provider: provider2, model, apiKey });
|
|
@@ -42583,7 +42886,8 @@ var runTask = async (taskArg, options) => {
|
|
|
42583
42886
|
model: model ?? defaultModels[provider2],
|
|
42584
42887
|
apiKey,
|
|
42585
42888
|
config: config ?? {},
|
|
42586
|
-
|
|
42889
|
+
maxMessageCount,
|
|
42890
|
+
budget,
|
|
42587
42891
|
interactive: false,
|
|
42588
42892
|
eventCallback: printEvent(verbose)
|
|
42589
42893
|
});
|
|
@@ -42597,6 +42901,7 @@ program2.name("polka-codes").description("Polka Codes CLI").version(version);
|
|
|
42597
42901
|
program2.argument("[task]", "The task to execute").action(runTask);
|
|
42598
42902
|
program2.command("chat").description("Start an interactive chat session").action(runChat);
|
|
42599
42903
|
program2.addCommand(configCommand);
|
|
42904
|
+
program2.addCommand(initCommand);
|
|
42600
42905
|
program2.addCommand(commitCommand);
|
|
42601
42906
|
program2.addCommand(prCommand);
|
|
42602
42907
|
addSharedOptions(program2);
|