@agent-smith/cli 0.0.100 → 0.0.101

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.
@@ -6,8 +6,9 @@ declare class McpClient {
6
6
  transport: StdioClientTransport;
7
7
  client: Client;
8
8
  authorizedTools: Array<string> | null;
9
+ askUserTools: Array<string> | null;
9
10
  tools: Record<string, ToolSpec>;
10
- constructor(servername: string, command: string, args: Array<string>, authorizedTools?: Array<string> | null);
11
+ constructor(servername: string, command: string, args: Array<string>, authorizedTools?: Array<string> | null, askUserTools?: Array<string> | null);
11
12
  start(): Promise<void>;
12
13
  stop(): Promise<void>;
13
14
  extractTools(): Promise<Array<ToolSpec>>;
@@ -1,12 +1,14 @@
1
1
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
2
  import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
3
+ import { confirmToolUsage } from "./tools.js";
3
4
  class McpClient {
4
5
  name;
5
6
  transport;
6
7
  client;
7
8
  authorizedTools = null;
9
+ askUserTools = null;
8
10
  tools = {};
9
- constructor(servername, command, args, authorizedTools = null) {
11
+ constructor(servername, command, args, authorizedTools = null, askUserTools = null) {
10
12
  this.name = servername;
11
13
  const okargs = new Array();
12
14
  for (const arg of args) {
@@ -29,6 +31,9 @@ class McpClient {
29
31
  if (authorizedTools) {
30
32
  this.authorizedTools = authorizedTools;
31
33
  }
34
+ if (askUserTools) {
35
+ this.askUserTools = askUserTools;
36
+ }
32
37
  }
33
38
  async start() {
34
39
  await this.client.connect(this.transport);
@@ -66,6 +71,11 @@ class McpClient {
66
71
  arguments: args,
67
72
  execute: exec
68
73
  };
74
+ if (this.askUserTools) {
75
+ if (this.askUserTools.includes(tool.name)) {
76
+ t.canRun = confirmToolUsage;
77
+ }
78
+ }
69
79
  this.tools[tool.name] = t;
70
80
  toolSpecs.push(t);
71
81
  }
@@ -1,4 +1,4 @@
1
1
  import { TaskOutput } from "@agent-smith/task";
2
- declare function executeTask(name: string, payload: Record<string, any>, options: Record<string, any>, quiet?: boolean): Promise<TaskOutput>;
2
+ declare function executeTask(name: string, payload: Record<string, any>, options: Record<string, any>): Promise<TaskOutput>;
3
3
  declare function executeTaskCmd(name: string, targs?: Array<any>): Promise<TaskOutput>;
4
4
  export { executeTask, executeTaskCmd };
@@ -13,7 +13,7 @@ import { runtimeDataError, runtimeError, runtimeWarning } from "../user_msgs.js"
13
13
  import { formatStats, processOutput } from "../utils.js";
14
14
  import { readTask } from "./read.js";
15
15
  import { getTaskPrompt } from "./utils.js";
16
- async function executeTask(name, payload, options, quiet) {
16
+ async function executeTask(name, payload, options) {
17
17
  if (!isTaskSettingsInitialized.value) {
18
18
  initTaskSettings();
19
19
  }
@@ -167,7 +167,7 @@ async function executeTask(name, payload, options, quiet) {
167
167
  }
168
168
  ++i;
169
169
  };
170
- const spinnerInit = (name) => ora(`Executing ${name} tool ...`);
170
+ const spinnerInit = (name) => ora(`Executing ${name} tool ...\n`);
171
171
  let tcspinner;
172
172
  const onToolCall = (tc) => {
173
173
  console.log("⚒️ ", color.bold(name), "=>", `${color.yellowBright(tc.name)}`, tc.arguments);
@@ -228,7 +228,7 @@ async function executeTask(name, payload, options, quiet) {
228
228
  }
229
229
  mcpServers.forEach(async (s) => await s.stop());
230
230
  await processOutput(out);
231
- if (isChatMode.value) {
231
+ if (!options?.isToolCall && isChatMode.value) {
232
232
  if (tpl) {
233
233
  setChatTemplate(tpl);
234
234
  }
@@ -8,6 +8,7 @@ import { executeWorkflow } from "../workflows/cmd.js";
8
8
  import { executeTask } from "./cmd.js";
9
9
  import { configureTaskModel, mergeInferParams } from "./conf.js";
10
10
  import { openTaskSpec } from "./utils.js";
11
+ import { confirmToolUsage } from "../tools.js";
11
12
  async function readTask(name, payload, options, agent) {
12
13
  if (options?.debug) {
13
14
  console.log("Task", name);
@@ -54,7 +55,19 @@ async function readTask(name, payload, options, agent) {
54
55
  }
55
56
  if (taskFileSpec?.mcp) {
56
57
  for (const [servername, tool] of Object.entries(taskFileSpec.mcp)) {
57
- const mcp = new McpClient(servername, tool.command, tool.arguments, tool?.tools ?? null);
58
+ const authorizedTools = new Array();
59
+ const askUserTools = new Array();
60
+ if (tool?.tools) {
61
+ tool.tools.forEach(t => {
62
+ let tn = t;
63
+ if (t.endsWith("?")) {
64
+ tn = t.slice(0, -1);
65
+ askUserTools.push(tn);
66
+ }
67
+ authorizedTools.push(tn);
68
+ });
69
+ }
70
+ const mcp = new McpClient(servername, tool.command, tool.arguments, authorizedTools.length > 0 ? authorizedTools : null, askUserTools.length > 0 ? askUserTools : null);
58
71
  mcpServers.push(mcp);
59
72
  await mcp.start();
60
73
  const tools = await mcp.extractTools();
@@ -62,21 +75,29 @@ async function readTask(name, payload, options, agent) {
62
75
  }
63
76
  }
64
77
  if (taskSpec.toolsList) {
65
- for (const toolName of taskSpec.toolsList) {
78
+ for (const rawToolName of taskSpec.toolsList) {
79
+ let toolName = rawToolName;
80
+ let autoRunTool = true;
81
+ if (rawToolName.endsWith("?")) {
82
+ autoRunTool = false;
83
+ toolName = rawToolName.slice(0, -1);
84
+ }
66
85
  const { found, tool, type } = readTool(toolName);
67
86
  if (!found) {
68
87
  throw new Error(`tool ${toolName} not found for task ${taskSpec.name}`);
69
88
  }
89
+ const quiet = !options?.debug;
70
90
  const lmTool = {
71
91
  ...tool,
72
92
  execute: async (params) => {
73
93
  switch (type) {
74
94
  case "action":
75
- const res = await executeAction(toolName, params, options, true);
95
+ const res = await executeAction(toolName, params, options, quiet);
76
96
  return res;
77
97
  case "task":
78
- conf.quiet = !options?.debug;
79
- const tres = await executeTask(name, params, options, true);
98
+ options.isToolCall = true;
99
+ const tres = await executeTask(toolName, params, options);
100
+ options.isToolCall = false;
80
101
  return tres.answer.text;
81
102
  case "workflow":
82
103
  const wres = await executeWorkflow(toolName, params, options);
@@ -86,13 +107,15 @@ async function readTask(name, payload, options, agent) {
86
107
  }
87
108
  }
88
109
  };
110
+ if (!autoRunTool) {
111
+ lmTool.canRun = confirmToolUsage;
112
+ }
89
113
  taskSpec.tools.push(lmTool);
90
114
  }
91
115
  delete taskSpec.toolsList;
92
116
  }
93
117
  ;
94
118
  const task = new Task(agent, taskSpec);
95
- task.addTools(taskSpec.tools);
96
119
  if (model?.inferParams?.tsGrammar) {
97
120
  model.inferParams.grammar = serializeGrammar(await compile(model.inferParams.tsGrammar, "Grammar"));
98
121
  delete model.inferParams.tsGrammar;
@@ -1,4 +1,6 @@
1
1
  import { FeatureExtension } from '../../interfaces.js';
2
+ import { type ToolCallSpec } from '@locallm/types';
3
+ declare function confirmToolUsage(toolCall: ToolCallSpec): Promise<boolean>;
2
4
  declare function extractTaskToolDocAndVariables(name: string, ext: FeatureExtension, dirPath: string): {
3
5
  toolDoc: string;
4
6
  variables: {
@@ -10,4 +12,4 @@ declare function extractToolDoc(name: string, ext: FeatureExtension, dirPath: st
10
12
  found: boolean;
11
13
  toolDoc: string;
12
14
  };
13
- export { extractToolDoc, extractTaskToolDocAndVariables, };
15
+ export { extractToolDoc, extractTaskToolDocAndVariables, confirmToolUsage, };
@@ -1,6 +1,17 @@
1
1
  import YAML from 'yaml';
2
2
  import * as fs from 'fs';
3
3
  import { readYmlFile } from '../sys/read_yml_file.js';
4
+ import { confirm } from '@inquirer/prompts';
5
+ async function confirmToolUsage(toolCall) {
6
+ let args;
7
+ if (toolCall?.arguments) {
8
+ args = `with arguments ${JSON.stringify(toolCall.arguments)}`;
9
+ }
10
+ else {
11
+ args = "with no arguments";
12
+ }
13
+ return await confirm({ message: `Execute tool ${toolCall.name} ${args}?` });
14
+ }
4
15
  function _extractToolDoc(filePath, startComment, endComment) {
5
16
  try {
6
17
  const fileContent = fs.readFileSync(filePath, 'utf-8');
@@ -127,4 +138,4 @@ function extractToolDoc(name, ext, dirPath) {
127
138
  }
128
139
  return { found: true, toolDoc: spec };
129
140
  }
130
- export { extractToolDoc, extractTaskToolDocAndVariables, };
141
+ export { extractToolDoc, extractTaskToolDocAndVariables, confirmToolUsage, };
@@ -46,7 +46,7 @@ async function executeWorkflow(wname, args, options = {}) {
46
46
  if (!pr) {
47
47
  throw new Error(`Workflow ${wname} step ${i + 1}: provide a prompt for the task ${step.name}`);
48
48
  }
49
- const tr = await executeTask(step.name, { prompt: pr }, options, true);
49
+ const tr = await executeTask(step.name, { prompt: pr }, options);
50
50
  taskRes = { ...tr, ...taskRes };
51
51
  }
52
52
  catch (e) {
@@ -1,9 +1,2 @@
1
- import { cmd as c1 } from "file:///home/ggg/dev/js/agent-smith-plugins/system/fs/dist/cmds/lsdir.js";
2
- import { cmd as c2 } from "file:///home/ggg/dev/js/agent-smith-plugins/code/git/dist/cmds/commit.js";
3
- import { cmd as c3 } from "file:///home/ggg/dev/js/agent-smith-plugins/code/git/dist/cmds/commita.js";
4
- import { cmd as c4 } from "file:///home/ggg/dev/js/snowind-astro/features/cmds/design-component.js";
5
- import { cmd as c5 } from "file:///home/ggg/dev/js/docdundee/package/features/dist/cmds/tsdoccmd.js";
6
-
7
- const cmds = [ c1, c2, c3, c4, c5 ]
8
-
9
- export { cmds }
1
+ const cmds = new Array();
2
+ export { cmds };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@agent-smith/cli",
3
3
  "description": "Agent Smith: terminal client for language model agents",
4
4
  "repository": "https://github.com/synw/agent-smith",
5
- "version": "0.0.100",
5
+ "version": "0.0.101",
6
6
  "scripts": {
7
7
  "buildrl": "rm -rf dist/* && rollup -c",
8
8
  "build": "rm -rf dist/* && tsc",
@@ -10,8 +10,8 @@
10
10
  "watch": "tsc --noCheck -p . -w"
11
11
  },
12
12
  "dependencies": {
13
- "@agent-smith/agent": "^0.1.8",
14
- "@agent-smith/task": "^0.1.9",
13
+ "@agent-smith/agent": "^0.2.0",
14
+ "@agent-smith/task": "^0.2.0",
15
15
  "@agent-smith/tfm": "^0.2.0",
16
16
  "@inquirer/prompts": "^8.1.0",
17
17
  "@intrinsicai/gbnfgen": "0.12.0",
@@ -31,7 +31,7 @@
31
31
  "@agent-smith/tmem-jobs": "^0.0.4",
32
32
  "@cfworker/json-schema": "^4.1.1",
33
33
  "@commander-js/extra-typings": "^14.0.0",
34
- "@locallm/types": "^0.6.5",
34
+ "@locallm/types": "^0.6.7",
35
35
  "@rollup/plugin-node-resolve": "^16.0.3",
36
36
  "@rollup/plugin-typescript": "^12.3.0",
37
37
  "@types/better-sqlite3": "^7.6.13",