@agent-smith/cli 0.0.102 → 0.0.104
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cmd/clicmds/aliases.js +23 -0
- package/dist/cmd/clicmds/cache.js +2 -2
- package/dist/cmd/clicmds/cmds.js +3 -8
- package/dist/cmd/lib/agents/cmd.d.ts +3 -0
- package/dist/cmd/lib/agents/cmd.js +10 -0
- package/dist/cmd/lib/tasks/cmd.js +13 -15
- package/dist/cmd/lib/tasks/read.js +11 -1
- package/dist/cmd/lib/tasks/utils.d.ts +1 -1
- package/dist/cmd/lib/tasks/utils.js +5 -4
- package/dist/cmd/lib/utils.d.ts +1 -3
- package/dist/cmd/lib/utils.js +1 -9
- package/dist/cmd/lib/workflows/cmd.js +57 -10
- package/dist/cmd/lib/workflows/read.js +5 -92
- package/dist/cmd/sys/read_features.js +17 -4
- package/dist/db/read.js +2 -1
- package/dist/db/schemas.js +10 -2
- package/dist/db/write.js +13 -0
- package/dist/index.js +5 -0
- package/dist/interfaces.d.ts +11 -6
- package/dist/state/auto/usercmds.d.ts +4 -1
- package/dist/state/auto/usercmds.js +2 -1
- package/dist/state/features.js +2 -0
- package/package.json +3 -3
|
@@ -2,9 +2,32 @@ import { allOptions } from "../options.js";
|
|
|
2
2
|
import { executeTaskCmd } from "../lib/tasks/cmd.js";
|
|
3
3
|
import { executeActionCmd } from "../lib/actions/cmd.js";
|
|
4
4
|
import { executeWorkflowCmd } from "../lib/workflows/cmd.js";
|
|
5
|
+
import { executeAgentCmd } from "../lib/agents/cmd.js";
|
|
5
6
|
function initCommandsFromAliases(program, aliases, features) {
|
|
6
7
|
aliases.forEach((alias) => {
|
|
7
8
|
switch (alias.type) {
|
|
9
|
+
case "agent":
|
|
10
|
+
const agcmd = program.command(`${alias.name} [prompt_and_vars...]`)
|
|
11
|
+
.description("agent: " + alias.name)
|
|
12
|
+
.action(async (...args) => {
|
|
13
|
+
await executeAgentCmd(alias.name, args);
|
|
14
|
+
});
|
|
15
|
+
allOptions.forEach(o => agcmd.addOption(o));
|
|
16
|
+
if (features.agent[alias.name]?.variables) {
|
|
17
|
+
const rtv = features.agent[alias.name].variables?.required;
|
|
18
|
+
if (rtv) {
|
|
19
|
+
for (const name of Object.keys(rtv)) {
|
|
20
|
+
agcmd.option(`--${name} <value>`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
const otv = features.agent[alias.name].variables?.optional;
|
|
24
|
+
if (otv) {
|
|
25
|
+
for (const name of Object.keys(otv)) {
|
|
26
|
+
agcmd.option(`--${name} <value>`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
break;
|
|
8
31
|
case "task":
|
|
9
32
|
const tcmd = program.command(`${alias.name} [prompt_and_vars...]`)
|
|
10
33
|
.description("task: " + alias.name)
|
|
@@ -15,8 +15,8 @@ function createCacheFileContent(cmdFeats) {
|
|
|
15
15
|
++i;
|
|
16
16
|
});
|
|
17
17
|
const finalImports = imports.join("\n");
|
|
18
|
-
const cmds = `const cmds = [ ${cmdNames.join(", ")} ]
|
|
19
|
-
const end = "export { cmds }";
|
|
18
|
+
const cmds = `const cmds = [ ${cmdNames.join(", ")} ];\nconst isCacheReady = true;`;
|
|
19
|
+
const end = "export { isCacheReady, cmds }";
|
|
20
20
|
return `${finalImports}\n\n${cmds}\n\n${end}`;
|
|
21
21
|
}
|
|
22
22
|
function ensureUserCmdsCacheFileExists(cacheFilePath) {
|
package/dist/cmd/clicmds/cmds.js
CHANGED
|
@@ -1,29 +1,24 @@
|
|
|
1
1
|
import colors from "ansi-colors";
|
|
2
2
|
import path from "path";
|
|
3
|
-
import { pathToFileURL } from 'url';
|
|
4
3
|
import YAML from 'yaml';
|
|
5
4
|
import { cacheFilePath, dbPath } from "../../conf.js";
|
|
6
5
|
import { readFeaturePaths, readFeaturesType, readTaskSetting } from "../../db/read.js";
|
|
7
6
|
import { cleanupFeaturePaths, deleteTaskSetting, updateAliases, updateFeatures, upsertTaskSettings } from "../../db/write.js";
|
|
7
|
+
import { isCacheReady, cmds } from "../../state/auto/usercmds.js";
|
|
8
8
|
import { getFeatureSpec, readFeaturesDirs } from "../../state/features.js";
|
|
9
9
|
import { readPluginsPaths } from "../../state/plugins.js";
|
|
10
10
|
import { runMode } from "../../state/state.js";
|
|
11
11
|
import { initTaskSettings, isTaskSettingsInitialized, tasksSettings } from '../../state/tasks.js';
|
|
12
|
-
import { cmds } from "../../state/auto/usercmds.js";
|
|
13
12
|
import { deleteFileIfExists } from "../sys/delete_file.js";
|
|
14
13
|
import { readCmd } from "../sys/read_cmds.js";
|
|
15
14
|
import { readTask } from "../sys/read_task.js";
|
|
16
15
|
import { updateUserCmdsCache } from './cache.js';
|
|
17
16
|
async function initUserCmds(cmdFeats) {
|
|
18
17
|
const features = Object.values(cmdFeats);
|
|
19
|
-
if (features.length == 0) {
|
|
20
|
-
return [];
|
|
21
|
-
}
|
|
22
18
|
let endCmds = cmds;
|
|
23
|
-
if (
|
|
19
|
+
if (!isCacheReady) {
|
|
24
20
|
updateUserCmdsCache(cacheFilePath, features);
|
|
25
|
-
const
|
|
26
|
-
const usrCmds = new Array();
|
|
21
|
+
const usrCmds = [];
|
|
27
22
|
for (const feat of features) {
|
|
28
23
|
const cmdPath = path.join(feat.path, feat.name + "." + feat.ext);
|
|
29
24
|
const c = await readCmd(feat.name, cmdPath);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { parseCommandArgs } from "../options_parsers.js";
|
|
2
|
+
import { getTaskPrompt } from "../tasks/utils.js";
|
|
3
|
+
import { executeTask } from "../tasks/cmd.js";
|
|
4
|
+
async function executeAgentCmd(name, targs = []) {
|
|
5
|
+
const ca = parseCommandArgs(targs);
|
|
6
|
+
const prompt = await getTaskPrompt(name, ca.args, ca.options);
|
|
7
|
+
ca.options.isAgent = true;
|
|
8
|
+
return await executeTask(name, { prompt: prompt }, ca.options);
|
|
9
|
+
}
|
|
10
|
+
export { executeAgentCmd, };
|
|
@@ -10,7 +10,7 @@ import { initTaskSettings, isTaskSettingsInitialized, tasksSettings } from "../.
|
|
|
10
10
|
import { chat, program } from "../../cmds.js";
|
|
11
11
|
import { parseCommandArgs } from "../options_parsers.js";
|
|
12
12
|
import { runtimeDataError, runtimeError, runtimeWarning } from "../user_msgs.js";
|
|
13
|
-
import {
|
|
13
|
+
import { processOutput } from "../utils.js";
|
|
14
14
|
import { readTask } from "./read.js";
|
|
15
15
|
import { getTaskPrompt } from "./utils.js";
|
|
16
16
|
async function executeTask(name, payload, options) {
|
|
@@ -86,17 +86,18 @@ async function executeTask(name, payload, options) {
|
|
|
86
86
|
console.log("Task model:", model);
|
|
87
87
|
console.log("Task vars:", vars);
|
|
88
88
|
}
|
|
89
|
+
let emittedTokens = 0;
|
|
89
90
|
const printToken = (t) => {
|
|
90
91
|
if (options?.tokens === true) {
|
|
91
92
|
let txt = t;
|
|
92
93
|
txt = c ? t : `\x1b[100m${t}\x1b[0m`;
|
|
93
94
|
process.stdout.write(txt);
|
|
94
|
-
++i;
|
|
95
95
|
c = !c;
|
|
96
96
|
}
|
|
97
97
|
else {
|
|
98
98
|
process.stdout.write(t);
|
|
99
99
|
}
|
|
100
|
+
++emittedTokens;
|
|
100
101
|
};
|
|
101
102
|
let hasTools = false;
|
|
102
103
|
if (task.def?.tools) {
|
|
@@ -113,12 +114,11 @@ async function executeTask(name, payload, options) {
|
|
|
113
114
|
return `${ts} ${color.bold(i.toString())} ${te}`;
|
|
114
115
|
};
|
|
115
116
|
const perfTimer = usePerfTimer(false);
|
|
116
|
-
let i = 0;
|
|
117
117
|
const processToken = (t) => {
|
|
118
|
-
if (
|
|
118
|
+
if (emittedTokens == 0) {
|
|
119
119
|
perfTimer.start();
|
|
120
120
|
}
|
|
121
|
-
spinner.text = formatTokenCount(
|
|
121
|
+
spinner.text = formatTokenCount(emittedTokens);
|
|
122
122
|
if (!options?.verbose && !options?.debug) {
|
|
123
123
|
if (hasThink && tpl) {
|
|
124
124
|
if (t == tpl.tags.think?.start) {
|
|
@@ -129,7 +129,7 @@ async function executeTask(name, payload, options) {
|
|
|
129
129
|
else if (t == tpl.tags.think?.end) {
|
|
130
130
|
continueWrite = true;
|
|
131
131
|
skipNextEmptyLinesToken = true;
|
|
132
|
-
let msg = color.dim("Thinking:") + ` ${
|
|
132
|
+
let msg = color.dim("Thinking:") + ` ${emittedTokens} ${color.dim("tokens")}`;
|
|
133
133
|
msg = msg + " " + color.dim(perfTimer.time());
|
|
134
134
|
spinner.info(msg);
|
|
135
135
|
return;
|
|
@@ -139,7 +139,7 @@ async function executeTask(name, payload, options) {
|
|
|
139
139
|
else {
|
|
140
140
|
if (tpl) {
|
|
141
141
|
if (t == tpl.tags.think?.end) {
|
|
142
|
-
let msg = color.dim("Thinking:") + ` ${
|
|
142
|
+
let msg = color.dim("Thinking:") + ` ${emittedTokens} ${color.dim("tokens")}`;
|
|
143
143
|
msg = msg + " " + color.dim(perfTimer.time());
|
|
144
144
|
console.log(msg);
|
|
145
145
|
}
|
|
@@ -165,17 +165,15 @@ async function executeTask(name, payload, options) {
|
|
|
165
165
|
}
|
|
166
166
|
printToken(t);
|
|
167
167
|
}
|
|
168
|
-
++
|
|
168
|
+
++emittedTokens;
|
|
169
169
|
};
|
|
170
|
-
const spinnerInit = (name) => ora(`Executing ${name} tool ...\n`);
|
|
171
|
-
let tcspinner;
|
|
172
170
|
const onToolCall = (tc) => {
|
|
173
171
|
console.log("⚒️ ", color.bold(name), "=>", `${color.yellowBright(tc.name)}`, tc.arguments);
|
|
174
|
-
tcspinner = spinnerInit(tc.name);
|
|
175
|
-
tcspinner.start();
|
|
176
172
|
};
|
|
177
173
|
const onToolCallEnd = (tr) => {
|
|
178
|
-
|
|
174
|
+
if (options?.debug) {
|
|
175
|
+
console.log(tr);
|
|
176
|
+
}
|
|
179
177
|
};
|
|
180
178
|
if (options?.onToken) {
|
|
181
179
|
task.agent.lm.onToken = options.onToken;
|
|
@@ -250,7 +248,7 @@ async function executeTask(name, payload, options) {
|
|
|
250
248
|
}
|
|
251
249
|
if (options?.debug === true || options?.verbose === true) {
|
|
252
250
|
try {
|
|
253
|
-
console.log("
|
|
251
|
+
console.log(emittedTokens.toString(), color.dim("tokens"), out.answer.stats.tokensPerSecond, color.dim("tps"));
|
|
254
252
|
if (options?.debug === true) {
|
|
255
253
|
console.log(out.answer.stats);
|
|
256
254
|
}
|
|
@@ -259,7 +257,7 @@ async function executeTask(name, payload, options) {
|
|
|
259
257
|
runtimeWarning("Error formating stats:", `${e}`);
|
|
260
258
|
}
|
|
261
259
|
}
|
|
262
|
-
if (options?.backend) {
|
|
260
|
+
if (options?.backend || settings?.backend) {
|
|
263
261
|
agent.lm = backend.value;
|
|
264
262
|
}
|
|
265
263
|
return out;
|
|
@@ -16,7 +16,7 @@ async function readTask(name, payload, options, agent) {
|
|
|
16
16
|
console.log("Payload:", payload);
|
|
17
17
|
console.log("Task options:", options);
|
|
18
18
|
}
|
|
19
|
-
const { taskFileSpec, taskPath } = openTaskSpec(name);
|
|
19
|
+
const { taskFileSpec, taskPath } = openTaskSpec(name, options?.isAgent);
|
|
20
20
|
const taskDir = path.dirname(taskPath);
|
|
21
21
|
const opts = payload?.inferParams ? { ...options, ...payload.inferParams } : options;
|
|
22
22
|
const conf = parseTaskConfigOptions(opts);
|
|
@@ -98,9 +98,19 @@ async function readTask(name, payload, options, agent) {
|
|
|
98
98
|
return res;
|
|
99
99
|
case "task":
|
|
100
100
|
options.isToolCall = true;
|
|
101
|
+
options.isAgent = false;
|
|
101
102
|
const tres = await executeTask(toolName, params, options);
|
|
102
103
|
options.isToolCall = false;
|
|
103
104
|
return tres.answer.text;
|
|
105
|
+
case "agent":
|
|
106
|
+
options.isToolCall = true;
|
|
107
|
+
options.isAgent = true;
|
|
108
|
+
const agres = await executeTask(toolName, params, options);
|
|
109
|
+
options.isToolCall = false;
|
|
110
|
+
if (agres?.answer?.text) {
|
|
111
|
+
return agres.answer.text;
|
|
112
|
+
}
|
|
113
|
+
return agres;
|
|
104
114
|
case "workflow":
|
|
105
115
|
const wres = await executeWorkflow(toolName, params, options);
|
|
106
116
|
return wres;
|
|
@@ -4,14 +4,15 @@ import { readTask } from "../../../cmd/sys/read_task.js";
|
|
|
4
4
|
import { getFeatureSpec } from "../../../state/features.js";
|
|
5
5
|
import { runtimeDataError } from '../user_msgs.js';
|
|
6
6
|
import { readPromptFile } from '../utils.js';
|
|
7
|
-
function openTaskSpec(name) {
|
|
8
|
-
const
|
|
7
|
+
function openTaskSpec(name, isAgent = false) {
|
|
8
|
+
const ft = isAgent ? "agent" : "task";
|
|
9
|
+
const { found, path } = getFeatureSpec(name, ft);
|
|
9
10
|
if (!found) {
|
|
10
|
-
throw new Error(
|
|
11
|
+
throw new Error(`${ft} ${name} not found`);
|
|
11
12
|
}
|
|
12
13
|
const res = readTask(path);
|
|
13
14
|
if (!res.found) {
|
|
14
|
-
throw new Error(
|
|
15
|
+
throw new Error(`${ft} ${name}, ${path} not found`);
|
|
15
16
|
}
|
|
16
17
|
const taskFileSpec = YAML.parse(res.ymlTask);
|
|
17
18
|
taskFileSpec.name = name;
|
package/dist/cmd/lib/utils.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { InferenceStats } from "@locallm/types";
|
|
2
1
|
declare function readPromptFile(): string;
|
|
3
2
|
declare function processOutput(res: any): Promise<void>;
|
|
4
|
-
|
|
5
|
-
export { formatStats, processOutput, readPromptFile, };
|
|
3
|
+
export { processOutput, readPromptFile, };
|
package/dist/cmd/lib/utils.js
CHANGED
|
@@ -46,12 +46,4 @@ async function processOutput(res) {
|
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
-
|
|
50
|
-
const buf = new Array();
|
|
51
|
-
buf.push(`${stats.tokensPerSecond} tps`);
|
|
52
|
-
buf.push(`- ${stats.totalTimeSeconds}s`);
|
|
53
|
-
buf.push(`(${stats.ingestionTimeSeconds}s ingestion /`);
|
|
54
|
-
buf.push(`${stats.inferenceTimeSeconds}s inference)`);
|
|
55
|
-
return buf.join(" ");
|
|
56
|
-
}
|
|
57
|
-
export { formatStats, processOutput, readPromptFile, };
|
|
49
|
+
export { processOutput, readPromptFile, };
|
|
@@ -5,6 +5,9 @@ import { executeTask } from "../tasks/cmd.js";
|
|
|
5
5
|
import { getTaskPrompt } from "../tasks/utils.js";
|
|
6
6
|
import { readWorkflow } from "./read.js";
|
|
7
7
|
import colors from "ansi-colors";
|
|
8
|
+
import { getFeatureSpec } from "../../../state/features.js";
|
|
9
|
+
import { pathToFileURL } from "node:url";
|
|
10
|
+
import { runtimeError } from "../user_msgs.js";
|
|
8
11
|
async function executeWorkflow(wname, args, options = {}) {
|
|
9
12
|
const { workflow, found } = await readWorkflow(wname);
|
|
10
13
|
if (!found) {
|
|
@@ -27,26 +30,46 @@ async function executeWorkflow(wname, args, options = {}) {
|
|
|
27
30
|
switch (step.type) {
|
|
28
31
|
case "task":
|
|
29
32
|
try {
|
|
30
|
-
let
|
|
33
|
+
let tdata = taskRes;
|
|
31
34
|
if (i == 0) {
|
|
32
|
-
|
|
35
|
+
tdata.prompt = await getTaskPrompt(step.name, taskRes.cmdArgs, options);
|
|
33
36
|
}
|
|
34
37
|
else {
|
|
35
38
|
if (prevStepType) {
|
|
36
39
|
if (prevStepType == "task") {
|
|
37
|
-
|
|
40
|
+
tdata.prompt = taskRes.answer.text;
|
|
38
41
|
}
|
|
39
42
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
}
|
|
44
|
+
if (!tdata?.prompt) {
|
|
45
|
+
throw new Error(`Workflow ${wname} step ${i + 1}: provide a prompt for the task ${step.name}`);
|
|
46
|
+
}
|
|
47
|
+
const tr = await executeTask(step.name, tdata, options);
|
|
48
|
+
taskRes = { ...tr, ...taskRes };
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
throw new Error(`workflow task ${i + 1}: ${e}`);
|
|
52
|
+
}
|
|
53
|
+
break;
|
|
54
|
+
case "agent":
|
|
55
|
+
try {
|
|
56
|
+
let tdata = taskRes;
|
|
57
|
+
if (i == 0) {
|
|
58
|
+
tdata.prompt = await getTaskPrompt(step.name, taskRes.cmdArgs, options);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
if (prevStepType) {
|
|
62
|
+
if (prevStepType == "task") {
|
|
63
|
+
tdata.prompt = taskRes.answer.text;
|
|
43
64
|
}
|
|
44
65
|
}
|
|
45
66
|
}
|
|
46
|
-
if (!
|
|
67
|
+
if (!tdata?.prompt) {
|
|
47
68
|
throw new Error(`Workflow ${wname} step ${i + 1}: provide a prompt for the task ${step.name}`);
|
|
48
69
|
}
|
|
49
|
-
|
|
70
|
+
options.isAgent = true;
|
|
71
|
+
const tr = await executeTask(step.name, tdata, options);
|
|
72
|
+
options.isAgent = false;
|
|
50
73
|
taskRes = { ...tr, ...taskRes };
|
|
51
74
|
}
|
|
52
75
|
catch (e) {
|
|
@@ -79,7 +102,7 @@ async function executeWorkflow(wname, args, options = {}) {
|
|
|
79
102
|
taskRes.args = adres;
|
|
80
103
|
}
|
|
81
104
|
else {
|
|
82
|
-
taskRes = { ...adres
|
|
105
|
+
taskRes = { ...adres };
|
|
83
106
|
}
|
|
84
107
|
if (i == finalTaskIndex) {
|
|
85
108
|
console.log(taskRes);
|
|
@@ -89,8 +112,32 @@ async function executeWorkflow(wname, args, options = {}) {
|
|
|
89
112
|
throw new Error(`workflow adaptater ${i + 1}: ${e}`);
|
|
90
113
|
}
|
|
91
114
|
break;
|
|
115
|
+
case "cmd":
|
|
116
|
+
try {
|
|
117
|
+
const { found, path } = getFeatureSpec(step.name, "cmd");
|
|
118
|
+
if (!found) {
|
|
119
|
+
throw new Error(`Command ${step.name} not found`);
|
|
120
|
+
}
|
|
121
|
+
const url = pathToFileURL(path).href;
|
|
122
|
+
const jsa = await import(url);
|
|
123
|
+
if (!jsa?.runCmd) {
|
|
124
|
+
runtimeError(`workflow ${wname}: can not import the runCmd function from step ${i} for command ${step.name}: please add a runCmd function export`);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const cres = await jsa.runCmd(args, options);
|
|
128
|
+
if (typeof cres == "string" || Array.isArray(cres)) {
|
|
129
|
+
taskRes.args = cres;
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
taskRes = { ...cres, ...taskRes };
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
catch (e) {
|
|
136
|
+
throw new Error(`workflow command ${i + 1}: ${e}`);
|
|
137
|
+
}
|
|
138
|
+
break;
|
|
92
139
|
default:
|
|
93
|
-
throw new Error(`unknown
|
|
140
|
+
throw new Error(`unknown workflow step type ${step.type} in workflow ${wname}`);
|
|
94
141
|
}
|
|
95
142
|
prevStepType = step.type;
|
|
96
143
|
++i;
|
|
@@ -1,104 +1,17 @@
|
|
|
1
|
-
import { Agent } from '@agent-smith/agent';
|
|
2
|
-
import { Task } from '@agent-smith/task';
|
|
3
1
|
import { default as fs } from "fs";
|
|
4
2
|
import YAML from 'yaml';
|
|
5
|
-
import { backend } from '../../../state/backends.js';
|
|
6
3
|
import { getFeatureSpec } from '../../../state/features.js';
|
|
7
|
-
import { readTask } from "../../sys/read_task.js";
|
|
8
|
-
import { pythonAction, systemAction } from '../actions/cmd.js';
|
|
9
|
-
import { createJsAction } from '../actions/read.js';
|
|
10
|
-
import { pathToFileURL } from 'url';
|
|
11
4
|
async function _createWorkflowFromSpec(spec) {
|
|
12
5
|
const steps = [];
|
|
13
|
-
let i = 1;
|
|
14
6
|
for (const step of spec.steps) {
|
|
15
7
|
const type = Object.keys(step)[0];
|
|
16
8
|
const sval = step[type];
|
|
17
9
|
const name = sval;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
switch (ext) {
|
|
24
|
-
case "js":
|
|
25
|
-
const url = pathToFileURL(path).href;
|
|
26
|
-
const { action } = await import(url);
|
|
27
|
-
const at = action;
|
|
28
|
-
const wf = {
|
|
29
|
-
name: name,
|
|
30
|
-
type: "action",
|
|
31
|
-
run: at,
|
|
32
|
-
};
|
|
33
|
-
steps.push(wf);
|
|
34
|
-
break;
|
|
35
|
-
case "mjs":
|
|
36
|
-
const url2 = pathToFileURL(path).href;
|
|
37
|
-
const mjsa = await import(url2);
|
|
38
|
-
const act = createJsAction(mjsa.action);
|
|
39
|
-
const wf2 = {
|
|
40
|
-
name: name,
|
|
41
|
-
type: "action",
|
|
42
|
-
run: act,
|
|
43
|
-
};
|
|
44
|
-
steps.push(wf2);
|
|
45
|
-
break;
|
|
46
|
-
case "yml":
|
|
47
|
-
const _t1 = systemAction(path);
|
|
48
|
-
const wf3 = {
|
|
49
|
-
name: name,
|
|
50
|
-
type: "action",
|
|
51
|
-
run: _t1,
|
|
52
|
-
};
|
|
53
|
-
steps.push(wf3);
|
|
54
|
-
break;
|
|
55
|
-
case "py":
|
|
56
|
-
const _t = pythonAction(path);
|
|
57
|
-
const wf4 = {
|
|
58
|
-
name: name,
|
|
59
|
-
type: "action",
|
|
60
|
-
run: _t,
|
|
61
|
-
};
|
|
62
|
-
steps.push(wf4);
|
|
63
|
-
break;
|
|
64
|
-
default:
|
|
65
|
-
throw new Error(`Unknown feature extension ${ext}`);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
else if (type == "adaptater") {
|
|
69
|
-
const { found, path } = getFeatureSpec(name, "adaptater");
|
|
70
|
-
if (!found) {
|
|
71
|
-
throw new Error(`Adaptater ${name} not found`);
|
|
72
|
-
}
|
|
73
|
-
const url = pathToFileURL(path).href;
|
|
74
|
-
const jsa = await import(url);
|
|
75
|
-
const act = createJsAction(jsa.action);
|
|
76
|
-
const wf = {
|
|
77
|
-
name: name,
|
|
78
|
-
type: "adaptater",
|
|
79
|
-
run: act,
|
|
80
|
-
};
|
|
81
|
-
steps.push(wf);
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
const { found, path } = getFeatureSpec(name, "task");
|
|
85
|
-
if (!found) {
|
|
86
|
-
throw new Error(`Task ${name} not found`);
|
|
87
|
-
}
|
|
88
|
-
const res = readTask(path);
|
|
89
|
-
if (!res.found) {
|
|
90
|
-
throw new Error(`Unable to read task ${name} ${path}`);
|
|
91
|
-
}
|
|
92
|
-
const agent = new Agent(backend.value);
|
|
93
|
-
const tsk = Task.fromYaml(agent, res.ymlTask);
|
|
94
|
-
const wf = {
|
|
95
|
-
name: name,
|
|
96
|
-
type: "task",
|
|
97
|
-
run: tsk.run,
|
|
98
|
-
};
|
|
99
|
-
steps.push(wf);
|
|
100
|
-
}
|
|
101
|
-
++i;
|
|
10
|
+
const wf = {
|
|
11
|
+
name: name,
|
|
12
|
+
type: type == "command" ? "cmd" : type,
|
|
13
|
+
};
|
|
14
|
+
steps.push(wf);
|
|
102
15
|
}
|
|
103
16
|
return steps;
|
|
104
17
|
}
|
|
@@ -6,10 +6,8 @@ function _readDir(dir, ext) {
|
|
|
6
6
|
const filepath = path.join(dir, filename);
|
|
7
7
|
const isDir = fs.statSync(filepath).isDirectory();
|
|
8
8
|
if (!isDir) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
fileNames.push(filename);
|
|
12
|
-
}
|
|
9
|
+
if (ext.includes(path.extname(filename))) {
|
|
10
|
+
fileNames.push(filename);
|
|
13
11
|
}
|
|
14
12
|
}
|
|
15
13
|
});
|
|
@@ -22,6 +20,7 @@ function readFeaturesDir(dir) {
|
|
|
22
20
|
cmd: [],
|
|
23
21
|
workflow: [],
|
|
24
22
|
adaptater: [],
|
|
23
|
+
agent: [],
|
|
25
24
|
};
|
|
26
25
|
let dirpath = path.join(dir, "tasks");
|
|
27
26
|
if (fs.existsSync(dirpath)) {
|
|
@@ -37,6 +36,20 @@ function readFeaturesDir(dir) {
|
|
|
37
36
|
});
|
|
38
37
|
});
|
|
39
38
|
}
|
|
39
|
+
dirpath = path.join(dir, "agents");
|
|
40
|
+
if (fs.existsSync(dirpath)) {
|
|
41
|
+
const data = _readDir(dirpath, [".yml"]);
|
|
42
|
+
data.forEach((filename) => {
|
|
43
|
+
const parts = filename.split(".");
|
|
44
|
+
const ext = parts.pop();
|
|
45
|
+
const name = parts.join("");
|
|
46
|
+
feats.agent.push({
|
|
47
|
+
name: name,
|
|
48
|
+
path: path.join(dirpath),
|
|
49
|
+
ext: ext,
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
}
|
|
40
53
|
dirpath = path.join(dir, "workflows");
|
|
41
54
|
if (fs.existsSync(dirpath)) {
|
|
42
55
|
const data = _readDir(dirpath, [".yml"]);
|
package/dist/db/read.js
CHANGED
|
@@ -43,8 +43,9 @@ function readFeaturesType(type) {
|
|
|
43
43
|
}
|
|
44
44
|
function readFeatures() {
|
|
45
45
|
const feats = {
|
|
46
|
-
task: {}, action: {}, cmd: {}, workflow: {}, adaptater: {}
|
|
46
|
+
task: {}, action: {}, cmd: {}, workflow: {}, adaptater: {}, agent: {}
|
|
47
47
|
};
|
|
48
|
+
feats.agent = readFeaturesType("agent");
|
|
48
49
|
feats.task = readFeaturesType("task");
|
|
49
50
|
feats.action = readFeaturesType("action");
|
|
50
51
|
feats.cmd = readFeaturesType("cmd");
|
package/dist/db/schemas.js
CHANGED
|
@@ -19,6 +19,13 @@ const tasks = `CREATE TABLE IF NOT EXISTS task (
|
|
|
19
19
|
variables TEXT,
|
|
20
20
|
ext TEXT NOT NULL CHECK ( ext IN ('yml') )
|
|
21
21
|
);`;
|
|
22
|
+
const agents = `CREATE TABLE IF NOT EXISTS agent (
|
|
23
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
24
|
+
name TEXT UNIQUE NOT NULL,
|
|
25
|
+
path TEXT NOT NULL,
|
|
26
|
+
variables TEXT,
|
|
27
|
+
ext TEXT NOT NULL CHECK ( ext IN ('yml') )
|
|
28
|
+
);`;
|
|
22
29
|
const workflow = `CREATE TABLE IF NOT EXISTS workflow (
|
|
23
30
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
24
31
|
name TEXT UNIQUE NOT NULL,
|
|
@@ -51,12 +58,12 @@ const tool = `CREATE TABLE IF NOT EXISTS tool (
|
|
|
51
58
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
52
59
|
name TEXT UNIQUE NOT NULL,
|
|
53
60
|
spec TEXT NOT NULL,
|
|
54
|
-
type TEXT NOT NULL CHECK ( type IN ('task', 'action', 'workflow') )
|
|
61
|
+
type TEXT NOT NULL CHECK ( type IN ('agent', 'task', 'action', 'workflow') )
|
|
55
62
|
);`;
|
|
56
63
|
const alias = `CREATE TABLE IF NOT EXISTS aliases (
|
|
57
64
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
58
65
|
name TEXT UNIQUE NOT NULL,
|
|
59
|
-
type TEXT NOT NULL CHECK ( type IN ('task', 'action', 'workflow') )
|
|
66
|
+
type TEXT NOT NULL CHECK ( type IN ('agent', 'task', 'action', 'workflow') )
|
|
60
67
|
);`;
|
|
61
68
|
const backend = `CREATE TABLE IF NOT EXISTS backend (
|
|
62
69
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
@@ -93,5 +100,6 @@ const schemas = [
|
|
|
93
100
|
adaptater,
|
|
94
101
|
backend,
|
|
95
102
|
tasksSettings,
|
|
103
|
+
agents,
|
|
96
104
|
];
|
|
97
105
|
export { schemas };
|
package/dist/db/write.js
CHANGED
|
@@ -96,6 +96,9 @@ function updateAliases(feats) {
|
|
|
96
96
|
const deleteStmt = db.prepare("DELETE FROM aliases");
|
|
97
97
|
deleteStmt.run();
|
|
98
98
|
let existingAliases = new Array();
|
|
99
|
+
feats.agent.forEach((feat) => {
|
|
100
|
+
existingAliases = _updateAlias(existingAliases, feat.name, "agent");
|
|
101
|
+
});
|
|
99
102
|
feats.task.forEach((feat) => {
|
|
100
103
|
existingAliases = _updateAlias(existingAliases, feat.name, "task");
|
|
101
104
|
});
|
|
@@ -158,6 +161,16 @@ function upsertTool(name, type, toolDoc) {
|
|
|
158
161
|
}
|
|
159
162
|
}
|
|
160
163
|
function updateFeatures(feats) {
|
|
164
|
+
upsertAndCleanFeatures(feats.agent, "agent");
|
|
165
|
+
feats.agent.forEach((feat) => {
|
|
166
|
+
const { toolDoc, variables } = extractTaskToolDocAndVariables(feat.name, feat.ext, feat.path);
|
|
167
|
+
if (toolDoc.length > 0) {
|
|
168
|
+
upsertTool(feat.name, "agent", toolDoc);
|
|
169
|
+
}
|
|
170
|
+
if (Object.keys(variables.required).length > 0 || Object.keys(variables.optional).length > 0) {
|
|
171
|
+
updateVariables(feat.name, JSON.stringify(variables, null, " "));
|
|
172
|
+
}
|
|
173
|
+
});
|
|
161
174
|
upsertAndCleanFeatures(feats.task, "task");
|
|
162
175
|
feats.task.forEach((feat) => {
|
|
163
176
|
const { toolDoc, variables } = extractTaskToolDocAndVariables(feat.name, feat.ext, feat.path);
|
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import { query } from "./cli.js";
|
|
|
4
4
|
import { buildCmds, parseCmd } from './cmd/cmds.js';
|
|
5
5
|
import { formatMode, init, inputMode, isChatMode, outputMode, runMode } from './state/state.js';
|
|
6
6
|
import { updateConfCmd } from './cmd/clicmds/updateconf.js';
|
|
7
|
+
import { resetDbCmd } from './cmd/clicmds/cmds.js';
|
|
7
8
|
async function main() {
|
|
8
9
|
const nargs = argv.length;
|
|
9
10
|
if (nargs == 2) {
|
|
@@ -14,6 +15,10 @@ async function main() {
|
|
|
14
15
|
await updateConfCmd(argv.slice(-1));
|
|
15
16
|
return;
|
|
16
17
|
}
|
|
18
|
+
else if (argv[2] == "reset") {
|
|
19
|
+
await resetDbCmd();
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
17
22
|
}
|
|
18
23
|
await init();
|
|
19
24
|
const program = await buildCmds();
|
package/dist/interfaces.d.ts
CHANGED
|
@@ -8,6 +8,11 @@ interface FeatureSpec {
|
|
|
8
8
|
variables?: TaskVariables;
|
|
9
9
|
}
|
|
10
10
|
interface Features {
|
|
11
|
+
agent: Array<{
|
|
12
|
+
name: string;
|
|
13
|
+
path: string;
|
|
14
|
+
ext: AgentExtension;
|
|
15
|
+
}>;
|
|
11
16
|
task: Array<{
|
|
12
17
|
name: string;
|
|
13
18
|
path: string;
|
|
@@ -100,7 +105,6 @@ interface FinalLmTaskConfig {
|
|
|
100
105
|
interface WorkflowStep {
|
|
101
106
|
name: string;
|
|
102
107
|
type: string;
|
|
103
|
-
run: FeatureExecutor;
|
|
104
108
|
}
|
|
105
109
|
interface McpServerSpec {
|
|
106
110
|
command: string;
|
|
@@ -136,14 +140,15 @@ type OutputMode = "txt" | "clipboard";
|
|
|
136
140
|
type RunMode = "cli" | "cmd";
|
|
137
141
|
type FormatMode = "text" | "markdown";
|
|
138
142
|
type VerbosityMode = "quiet" | "verbose" | "debug";
|
|
139
|
-
type FeatureType = "task" | "action" | "cmd" | "workflow" | "adaptater";
|
|
140
|
-
type ToolType = "task" | "action" | "cmd" | "workflow";
|
|
143
|
+
type FeatureType = "task" | "agent" | "action" | "cmd" | "workflow" | "adaptater";
|
|
144
|
+
type ToolType = "task" | "agent" | "action" | "cmd" | "workflow";
|
|
141
145
|
type ActionExtension = "js" | "mjs" | "py" | "yml";
|
|
142
146
|
type TaskExtension = "yml";
|
|
147
|
+
type AgentExtension = "yml";
|
|
143
148
|
type AdaptaterExtension = "js";
|
|
144
149
|
type WorkflowExtension = "yml";
|
|
145
150
|
type CmdExtension = "js";
|
|
146
|
-
type FeatureExtension = TaskExtension | CmdExtension | ActionExtension | WorkflowExtension;
|
|
147
|
-
type AliasType = "task" | "action" | "workflow";
|
|
151
|
+
type FeatureExtension = TaskExtension | AgentExtension | CmdExtension | ActionExtension | WorkflowExtension;
|
|
152
|
+
type AliasType = "task" | "agent" | "action" | "workflow";
|
|
148
153
|
type FeatureExecutor<I = any, O = any> = (params: I, options: Record<string, any>) => Promise<O>;
|
|
149
|
-
export { InputMode, VerbosityMode, OutputMode, RunMode, FormatMode, FeatureType, ActionExtension, TaskExtension, WorkflowExtension, AdaptaterExtension, CmdExtension, FeatureSpec, Features, ConfigFile, FeatureExtension, AliasType, ToolType, Settings, DbModelDef, ModelSpec, ModelfileSpec, ModelPack, LmTaskFileSpec, LmTaskConfig, FinalLmTaskConfig, McpServerSpec, McpServerTool, InferenceBackend, ConfInferenceBackend, FeatureExecutor, WorkflowStep, TaskSettings, };
|
|
154
|
+
export { InputMode, VerbosityMode, OutputMode, RunMode, FormatMode, FeatureType, ActionExtension, TaskExtension, AgentExtension, WorkflowExtension, AdaptaterExtension, CmdExtension, FeatureSpec, Features, ConfigFile, FeatureExtension, AliasType, ToolType, Settings, DbModelDef, ModelSpec, ModelfileSpec, ModelPack, LmTaskFileSpec, LmTaskConfig, FinalLmTaskConfig, McpServerSpec, McpServerTool, InferenceBackend, ConfInferenceBackend, FeatureExecutor, WorkflowStep, TaskSettings, };
|
package/dist/state/features.js
CHANGED
|
@@ -8,9 +8,11 @@ function readFeaturesDirs(featuresPaths) {
|
|
|
8
8
|
cmd: [],
|
|
9
9
|
workflow: [],
|
|
10
10
|
adaptater: [],
|
|
11
|
+
agent: [],
|
|
11
12
|
};
|
|
12
13
|
featuresPaths.forEach((dir) => {
|
|
13
14
|
const _f = readFeaturesDir(dir);
|
|
15
|
+
_f.agent.forEach((item) => feats.agent.push(item));
|
|
14
16
|
_f.task.forEach((item) => feats.task.push(item));
|
|
15
17
|
_f.action.forEach((item) => feats.action.push(item));
|
|
16
18
|
_f.cmd.forEach((item) => feats.cmd.push(item));
|
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.
|
|
5
|
+
"version": "0.0.104",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"buildrl": "rm -rf dist/* && rollup -c",
|
|
8
8
|
"build": "rm -rf dist/* && tsc",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"@inquirer/prompts": "^8.1.0",
|
|
18
18
|
"@intrinsicai/gbnfgen": "0.12.0",
|
|
19
19
|
"@locallm/api": "^0.7.3",
|
|
20
|
-
"@modelcontextprotocol/sdk": "^1.25.
|
|
20
|
+
"@modelcontextprotocol/sdk": "^1.25.2",
|
|
21
21
|
"@vue/reactivity": "^3.5.26",
|
|
22
22
|
"ansi-colors": "^4.1.3",
|
|
23
23
|
"better-sqlite3": "^12.5.0",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"@types/node": "^25.0.3",
|
|
41
41
|
"openai": "^6.15.0",
|
|
42
42
|
"restmix": "^0.6.1",
|
|
43
|
-
"rollup": "^4.
|
|
43
|
+
"rollup": "^4.55.1",
|
|
44
44
|
"ts-node": "^10.9.2",
|
|
45
45
|
"tslib": "2.8.1",
|
|
46
46
|
"typescript": "^5.9.3"
|