@polka-codes/cli-shared 0.8.3 → 0.8.5

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 (2) hide show
  1. package/dist/index.js +199 -53
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -36840,10 +36840,16 @@ ${search}`);
36840
36840
  };
36841
36841
  // ../core/src/tools/utils/getArg.ts
36842
36842
  var getString = (args2, name2, defaultValue) => {
36843
+ if (typeof args2 !== "object" || Array.isArray(args2)) {
36844
+ throw new Error(`Invalid argument type: ${name2} ${args2}`);
36845
+ }
36843
36846
  const ret = args2[name2] ?? defaultValue;
36844
36847
  if (ret === undefined) {
36845
36848
  throw new Error(`Missing required argument: ${name2}`);
36846
36849
  }
36850
+ if (typeof ret !== "string") {
36851
+ throw new Error(`Invalid argument type: ${name2} ${ret}`);
36852
+ }
36847
36853
  return ret;
36848
36854
  };
36849
36855
  var getStringArray = (args2, name2, defaultValue) => {
@@ -36857,6 +36863,9 @@ var getStringArray = (args2, name2, defaultValue) => {
36857
36863
  if (ret === "") {
36858
36864
  return [];
36859
36865
  }
36866
+ if (typeof ret !== "string") {
36867
+ throw new Error(`Invalid argument type: ${name2} ${ret}`);
36868
+ }
36860
36869
  return ret.split(",").map((s2) => s2.trim());
36861
36870
  };
36862
36871
  var getBoolean = (args2, name2, defaultValue) => {
@@ -36867,13 +36876,16 @@ var getBoolean = (args2, name2, defaultValue) => {
36867
36876
  }
36868
36877
  return defaultValue;
36869
36878
  }
36879
+ if (typeof ret !== "string") {
36880
+ throw new Error(`Invalid argument type: ${name2} ${ret}`);
36881
+ }
36870
36882
  switch (ret.toLowerCase()) {
36871
36883
  case "true":
36872
36884
  return true;
36873
36885
  case "false":
36874
36886
  return false;
36875
36887
  default:
36876
- throw new Error(`Invalid argument value: ${name2}`);
36888
+ throw new Error(`Invalid argument value: ${name2} ${ret}`);
36877
36889
  }
36878
36890
  };
36879
36891
  var getInt = (args2, name2, defaultValue) => {
@@ -36884,50 +36896,104 @@ var getInt = (args2, name2, defaultValue) => {
36884
36896
  }
36885
36897
  return defaultValue;
36886
36898
  }
36899
+ if (typeof ret !== "string") {
36900
+ throw new Error(`Invalid argument type: ${name2} ${ret}`);
36901
+ }
36887
36902
  const parsed = Number.parseInt(ret);
36888
36903
  if (Number.isNaN(parsed)) {
36889
- throw new Error(`Invalid argument value: ${name2}`);
36904
+ throw new Error(`Invalid argument value: ${name2} ${ret}`);
36890
36905
  }
36891
36906
  return parsed;
36892
36907
  };
36908
+ var getArray = (args2, name2, defaultValue) => {
36909
+ if (typeof args2 !== "object" || Array.isArray(args2)) {
36910
+ throw new Error(`Invalid argument type: ${name2} ${args2}`);
36911
+ }
36912
+ const ret = args2[name2];
36913
+ if (ret === undefined) {
36914
+ if (defaultValue === undefined) {
36915
+ throw new Error(`Missing required argument: ${name2}`);
36916
+ }
36917
+ return defaultValue;
36918
+ }
36919
+ if (Array.isArray(ret)) {
36920
+ return ret;
36921
+ }
36922
+ return [ret];
36923
+ };
36893
36924
  // ../core/src/tools/askFollowupQuestion.ts
36894
36925
  var toolInfo = {
36895
36926
  name: "ask_followup_question",
36896
- 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.",
36927
+ description: "Call this when vital details are missing. Pose each follow-up as one direct, unambiguous question. If it speeds the reply, add up to five short, mutually-exclusive answer options. Group any related questions in the same call to avoid a back-and-forth chain.",
36897
36928
  parameters: [
36898
36929
  {
36899
- name: "question",
36900
- description: "The question to ask the user. This should be a clear, specific question that addresses the information you need.",
36930
+ name: "questions",
36931
+ description: "One or more follow-up questions you need answered before you can continue.",
36901
36932
  required: true,
36902
- usageValue: "Your question here"
36903
- },
36904
- {
36905
- name: "options",
36906
- description: "A comma separated list of possible answers to the question. Ordered by preference. If not provided, the user will be prompted to provide an answer.",
36907
- required: false,
36908
- usageValue: "A comma separated list of possible answers (optional)"
36933
+ allowMultiple: true,
36934
+ children: [
36935
+ {
36936
+ name: "prompt",
36937
+ description: "The text of the question.",
36938
+ required: true,
36939
+ usageValue: "question text here"
36940
+ },
36941
+ {
36942
+ name: "options",
36943
+ description: "Ordered list of suggested answers (omit if none).",
36944
+ required: false,
36945
+ allowMultiple: true,
36946
+ usageValue: "suggested answer here"
36947
+ }
36948
+ ]
36909
36949
  }
36910
36950
  ],
36911
36951
  examples: [
36912
36952
  {
36913
- description: "Request to ask a question",
36953
+ description: "Single clarifying question (no options)",
36914
36954
  parameters: [
36915
36955
  {
36916
- name: "question",
36917
- value: "What is the name of the project?"
36956
+ name: "questions",
36957
+ value: { prompt: "What is the target deployment environment?" }
36918
36958
  }
36919
36959
  ]
36920
36960
  },
36921
36961
  {
36922
- description: "Request to ask a question with options",
36962
+ description: "Single question with multiple-choice options",
36923
36963
  parameters: [
36924
36964
  {
36925
- name: "question",
36926
- value: "What framework do you use?"
36927
- },
36965
+ name: "questions",
36966
+ value: {
36967
+ prompt: "Which frontend framework are you using?",
36968
+ options: ["React", "Angular", "Vue", "Svelte"]
36969
+ }
36970
+ }
36971
+ ]
36972
+ },
36973
+ {
36974
+ description: "Two related questions in one call",
36975
+ parameters: [
36928
36976
  {
36929
- name: "options",
36930
- value: "React,Angular,Vue,Svelte"
36977
+ name: "questions",
36978
+ value: [
36979
+ { prompt: "What type of application are you building?" },
36980
+ {
36981
+ prompt: "Preferred programming language?",
36982
+ options: ["JavaScript", "TypeScript", "Python", "Java"]
36983
+ }
36984
+ ]
36985
+ }
36986
+ ]
36987
+ },
36988
+ {
36989
+ description: "Binary (yes/no) confirmation",
36990
+ parameters: [
36991
+ {
36992
+ name: "questions",
36993
+ value: {
36994
+ prompt: "Is it acceptable to refactor existing tests to improve performance?",
36995
+ options: ["Yes", "No"]
36996
+ }
36931
36997
  }
36932
36998
  ]
36933
36999
  }
@@ -36941,13 +37007,26 @@ var handler = async (provider, args2) => {
36941
37007
  message: "Not possible to ask followup question. Abort."
36942
37008
  };
36943
37009
  }
36944
- const question = getString(args2, "question");
36945
- const options = getStringArray(args2, "options", []);
36946
- const answer = await provider.askFollowupQuestion(question, options);
37010
+ const questions = getArray(args2, "questions");
37011
+ if (!questions || questions.length === 0) {
37012
+ return {
37013
+ type: "Error" /* Error */,
37014
+ message: "No questions provided"
37015
+ };
37016
+ }
37017
+ const answers = [];
37018
+ for (const question of questions) {
37019
+ const prompt = getString(question, "prompt");
37020
+ const options = getArray(question, "options", []);
37021
+ const answer = await provider.askFollowupQuestion(prompt, options);
37022
+ answers.push(`<ask_followup_question_answer question="${prompt}">
37023
+ ${answer}
37024
+ </ask_followup_question_answer>`);
37025
+ }
36947
37026
  return {
36948
37027
  type: "Reply" /* Reply */,
36949
- message: `<ask_followup_question_question>${question}</ask_followup_question_question>
36950
- <ask_followup_question_answer>${answer}</ask_followup_question_answer>`
37028
+ message: answers.join(`
37029
+ `)
36951
37030
  };
36952
37031
  };
36953
37032
  var isAvailable = (provider) => {
@@ -37084,33 +37163,27 @@ var delegate_default = {
37084
37163
  // ../core/src/tools/executeCommand.ts
37085
37164
  var toolInfo4 = {
37086
37165
  name: "execute_command",
37087
- description: `Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Commands will also be executed in the project root directory regardless of executed commands in previous tool uses.`,
37166
+ description: "Run a single CLI command. The command is always executed in the project-root working directory (regardless of earlier commands). Prefer one-off shell commands over wrapper scripts for flexibility. After an `execute_command` call, no other tool calls are allowed in the same assistant response.",
37088
37167
  parameters: [
37089
37168
  {
37090
37169
  name: "command",
37091
- description: "The CLI command to execute. This should be valid for the current operating system. Ensure the command is properly formatted and does not contain any harmful instructions.",
37170
+ description: "The exact command to run (valid for the current OS). It must be correctly formatted and free of harmful instructions.",
37092
37171
  required: true,
37093
- usageValue: "Your command here"
37172
+ usageValue: "your-command-here"
37094
37173
  },
37095
37174
  {
37096
37175
  name: "requires_approval",
37097
- description: `A boolean indicating whether this command requires explicit user approval before execution in case the user has auto-approve mode enabled. Set to 'true' for potentially impactful operations like installing/uninstalling packages, deleting/overwriting files, system configuration changes, network operations, or any commands that could have unintended side effects. Set to 'false' for safe operations like reading files/directories, running development servers, building projects, and other non-destructive operations.`,
37176
+ description: "Set to `true` for commands that install/uninstall software, modify or delete files, change system settings, perform network operations, or have other side effects. Use `false` for safe, read-only, or purely local development actions (e.g., listing files, make a build, running tests).",
37098
37177
  required: false,
37099
- usageValue: "true or false"
37178
+ usageValue: "true | false"
37100
37179
  }
37101
37180
  ],
37102
37181
  examples: [
37103
37182
  {
37104
- description: "Request to execute a command",
37183
+ description: "Make a build",
37105
37184
  parameters: [
37106
- {
37107
- name: "command",
37108
- value: "npm run dev"
37109
- },
37110
- {
37111
- name: "requires_approval",
37112
- value: "false"
37113
- }
37185
+ { name: "command", value: "npm run build" },
37186
+ { name: "requires_approval", value: "false" }
37114
37187
  ]
37115
37188
  }
37116
37189
  ],
@@ -38072,6 +38145,23 @@ var getAvailableTools = ({
38072
38145
  };
38073
38146
 
38074
38147
  // ../core/src/Agent/parseAssistantMessage.ts
38148
+ function parseNestedParameters(content, parameterPrefix) {
38149
+ const result = {};
38150
+ const nestedParamRegex = new RegExp(`<${parameterPrefix}([^>]+)>([\\s\\S]*?)<\\/${parameterPrefix}\\1>`, "gs");
38151
+ while (true) {
38152
+ const match = nestedParamRegex.exec(content);
38153
+ if (match === null)
38154
+ break;
38155
+ const paramName = match[1];
38156
+ const paramContent = match[2].trim();
38157
+ if (paramContent.includes(`<${parameterPrefix}`)) {
38158
+ result[paramName] = parseNestedParameters(paramContent, parameterPrefix);
38159
+ } else {
38160
+ result[paramName] = paramContent;
38161
+ }
38162
+ }
38163
+ return result;
38164
+ }
38075
38165
  function parseAssistantMessage(assistantMessage, tools, toolNamePrefix) {
38076
38166
  const parameterPrefix = `${toolNamePrefix}parameter_`;
38077
38167
  const results = [];
@@ -38100,10 +38190,25 @@ function parseAssistantMessage(assistantMessage, tools, toolNamePrefix) {
38100
38190
  for (const param of tool.parameters) {
38101
38191
  const paramName = `${parameterPrefix}${param.name}`;
38102
38192
  const escapedParamName = paramName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
38103
- const paramPattern = `<${escapedParamName}>([\\s\\S]*?)<\\/${escapedParamName}>`;
38104
- const paramMatch = fullTagContent.match(new RegExp(paramPattern, "s"));
38105
- if (paramMatch) {
38106
- params[param.name] = paramMatch[1].trim();
38193
+ const paramRegex = new RegExp(`<${escapedParamName}>([\\s\\S]*?)<\\/${escapedParamName}>`, "gs");
38194
+ const paramMatches = [];
38195
+ while (true) {
38196
+ const paramMatch = paramRegex.exec(fullTagContent);
38197
+ if (paramMatch === null)
38198
+ break;
38199
+ paramMatches.push(paramMatch[1].trim());
38200
+ }
38201
+ if (paramMatches.length > 0) {
38202
+ if (paramMatches.length === 1) {
38203
+ const paramContent = paramMatches[0];
38204
+ if (paramContent.includes(`<${parameterPrefix}`)) {
38205
+ params[param.name] = parseNestedParameters(paramContent, parameterPrefix);
38206
+ } else {
38207
+ params[param.name] = paramContent;
38208
+ }
38209
+ } else {
38210
+ params[param.name] = paramMatches;
38211
+ }
38107
38212
  }
38108
38213
  }
38109
38214
  results.push({
@@ -38135,6 +38240,20 @@ function parseAssistantMessage(assistantMessage, tools, toolNamePrefix) {
38135
38240
  }
38136
38241
 
38137
38242
  // ../core/src/Agent/prompts.ts
38243
+ var renderParameterValue = (key, value, parameterPrefix) => {
38244
+ if (typeof value === "string") {
38245
+ return `<${parameterPrefix}${key}>${value}</${parameterPrefix}${key}>`;
38246
+ }
38247
+ if (Array.isArray(value)) {
38248
+ return value.map((v2) => renderParameterValue(key, v2, parameterPrefix)).join(`
38249
+ `);
38250
+ }
38251
+ const inner = Object.entries(value).map(([key2, v2]) => renderParameterValue(key2, v2, parameterPrefix)).join(`
38252
+ `);
38253
+ return `<${parameterPrefix}${key}>
38254
+ ${inner}
38255
+ </${parameterPrefix}${key}>`;
38256
+ };
38138
38257
  var toolInfoPrompt = (tool, toolNamePrefix, parameterPrefix) => `
38139
38258
  ## ${toolNamePrefix}${tool.name}
38140
38259
 
@@ -38149,11 +38268,11 @@ Usage:
38149
38268
  ${tool.parameters.map((param) => `<${parameterPrefix}${param.name}>${param.usageValue}</${parameterPrefix}${param.name}>`).join(`
38150
38269
  `)}
38151
38270
  </${toolNamePrefix}${tool.name}>`;
38152
- var toolInfoExamplesPrompt = (idx, tool, example, toolNamePrefix, parameterPrefix) => `
38153
- ## Example ${idx + 1}: ${example.description}
38271
+ var toolInfoExamplesPrompt = (tool, example, toolNamePrefix, parameterPrefix) => `
38272
+ ## Example: ${example.description}
38154
38273
 
38155
38274
  <${toolNamePrefix}${tool.name}>
38156
- ${example.parameters.map((param) => `<${parameterPrefix}${param.name}>${param.value}</${parameterPrefix}${param.name}>`).join(`
38275
+ ${example.parameters.map((param) => `${renderParameterValue(param.name, param.value, parameterPrefix)}`).join(`
38157
38276
  `)}
38158
38277
  </${toolNamePrefix}${tool.name}>
38159
38278
  `;
@@ -38162,7 +38281,6 @@ var toolUsePrompt = (tools, toolNamePrefix) => {
38162
38281
  return "";
38163
38282
  }
38164
38283
  const parameterPrefix = `${toolNamePrefix}parameter_`;
38165
- let exampleIndex = 0;
38166
38284
  return `
38167
38285
  ====
38168
38286
 
@@ -38180,11 +38298,39 @@ Tool use is formatted using XML-style tags. The tool name is enclosed in opening
38180
38298
  ...
38181
38299
  </${toolNamePrefix}tool_name>
38182
38300
 
38183
- For example:
38301
+ ## Array Parameters
38302
+
38303
+ To create an array of values for a parameter, repeat the parameter tag multiple times:
38304
+
38305
+ <${toolNamePrefix}process_file>
38306
+ <${parameterPrefix}path>test.ts</${parameterPrefix}path>
38307
+ <${parameterPrefix}path>main.ts</${parameterPrefix}path>
38308
+ </${toolNamePrefix}process_file>
38309
+
38310
+ ## Nested Object Parameters
38311
+
38312
+ To create nested objects, nest parameter tags within other parameter tags:
38313
+
38314
+ <${toolNamePrefix}example_tool>
38315
+ <${parameterPrefix}key>
38316
+ <${parameterPrefix}key2>value</${parameterPrefix}key2>
38317
+ <${parameterPrefix}key3>value2</${parameterPrefix}key3>
38318
+ </${parameterPrefix}key>
38319
+ </${toolNamePrefix}example_tool>
38320
+
38321
+ You can also combine array parameters with nested objects:
38184
38322
 
38185
- <${toolNamePrefix}read_file>
38186
- <${parameterPrefix}path>src/main.js</${parameterPrefix}path>
38187
- </${toolNamePrefix}read_file>
38323
+ <${toolNamePrefix}example_tool>
38324
+ <${parameterPrefix}key>
38325
+ <${parameterPrefix}key2>value</${parameterPrefix}key2>
38326
+ <${parameterPrefix}key3>value2</${parameterPrefix}key3>
38327
+ </${parameterPrefix}key>
38328
+ <${parameterPrefix}key>
38329
+ <${parameterPrefix}key2>value3</${parameterPrefix}key2>
38330
+ <${parameterPrefix}key3>value4</${parameterPrefix}key3>
38331
+ <${parameterPrefix}key3>value5</${parameterPrefix}key3>
38332
+ </${parameterPrefix}key>
38333
+ </${toolNamePrefix}example_tool>
38188
38334
 
38189
38335
  Always adhere to this format for the tool use to ensure proper parsing and execution.
38190
38336
 
@@ -38198,7 +38344,7 @@ ${tools.map((tool) => toolInfoPrompt(tool, toolNamePrefix, parameterPrefix)).joi
38198
38344
  ${tools.map((tool) => {
38199
38345
  let promp = "";
38200
38346
  for (const example of tool.examples ?? []) {
38201
- promp += toolInfoExamplesPrompt(exampleIndex++, tool, example, toolNamePrefix, parameterPrefix);
38347
+ promp += toolInfoExamplesPrompt(tool, example, toolNamePrefix, parameterPrefix);
38202
38348
  }
38203
38349
  return promp;
38204
38350
  }).join("")}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@polka-codes/cli-shared",
3
- "version": "0.8.3",
3
+ "version": "0.8.5",
4
4
  "license": "AGPL-3.0",
5
5
  "author": "github@polka.codes",
6
6
  "type": "module",