@polka-codes/core 0.4.6 → 0.4.8

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