@agent-smith/cli 0.0.36 → 0.0.38
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/cmds.js +25 -5
- package/dist/cmd/lib/execute_action.d.ts +4 -4
- package/dist/cmd/lib/execute_action.js +33 -10
- package/dist/cmd/lib/execute_job.js +8 -5
- package/dist/cmd/lib/execute_task.d.ts +3 -1
- package/dist/cmd/lib/execute_task.js +17 -12
- package/dist/cmd/lib/utils.d.ts +3 -3
- package/dist/cmd/lib/utils.js +9 -4
- package/dist/cmd/lib/workflows/cmd.d.ts +3 -0
- package/dist/cmd/lib/workflows/cmd.js +51 -0
- package/dist/cmd/lib/workflows/read.d.ts +7 -0
- package/dist/cmd/lib/workflows/read.js +104 -0
- package/dist/cmd/sys/read_features.js +15 -0
- package/dist/cmd/sys/run_python.d.ts +2 -1
- package/dist/cmd/sys/run_python.js +6 -17
- package/dist/db/read.js +2 -1
- package/dist/db/schemas.js +8 -2
- package/dist/db/write.js +4 -0
- package/dist/interfaces.d.ts +14 -4
- package/dist/main.d.ts +2 -1
- package/dist/main.js +2 -1
- package/dist/state/features.js +2 -0
- package/package.json +6 -6
package/dist/cmd/clicmds/cmds.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { formatMode, isChatMode, promptfile } from "../../state/state.js";
|
|
1
|
+
import { formatMode, isChatMode, isDebug, promptfile } from "../../state/state.js";
|
|
2
2
|
import { getFeatureSpec, readFeaturesDirs } from "../../state/features.js";
|
|
3
3
|
import { readAliases, readFeatures } from "../../db/read.js";
|
|
4
4
|
import { cleanupFeaturePaths, updateAliases, updateFeatures, updatePromptfilePath } from "../../db/write.js";
|
|
@@ -9,6 +9,7 @@ import { executeJobCmd, readJob } from "../lib/execute_job.js";
|
|
|
9
9
|
import { executeTaskCmd } from "../lib/execute_task.js";
|
|
10
10
|
import { readCmds } from "../sys/read_cmds.js";
|
|
11
11
|
import { readTask } from "../lib/utils.js";
|
|
12
|
+
import { executeWorkflowCmd } from "../lib/workflows/cmd.js";
|
|
12
13
|
let cmds = {
|
|
13
14
|
q: {
|
|
14
15
|
cmd: async () => process.exit(0),
|
|
@@ -41,6 +42,11 @@ let cmds = {
|
|
|
41
42
|
description: "execute a job",
|
|
42
43
|
args: "arguments: \n-job (required): the job name\n-args: arguments if any for the job"
|
|
43
44
|
},
|
|
45
|
+
w: {
|
|
46
|
+
cmd: _executeWorkflowCmd,
|
|
47
|
+
description: "execute a workflow",
|
|
48
|
+
args: "arguments: \n-workflow (required): the workflow name\n-args: arguments if any for the workflow"
|
|
49
|
+
},
|
|
44
50
|
a: {
|
|
45
51
|
cmd: executeActionCmd,
|
|
46
52
|
description: "execute an action",
|
|
@@ -74,6 +80,11 @@ function initAliases() {
|
|
|
74
80
|
cmd: (args = [], options) => _executeJobCmd([alias.name, ...args], options),
|
|
75
81
|
description: "job: " + alias.name,
|
|
76
82
|
};
|
|
83
|
+
case "workflow":
|
|
84
|
+
_cmds[alias.name] = {
|
|
85
|
+
cmd: (args = [], options) => _executeWorkflowCmd([alias.name, ...args], options),
|
|
86
|
+
description: "wokflow: " + alias.name,
|
|
87
|
+
};
|
|
77
88
|
}
|
|
78
89
|
});
|
|
79
90
|
return _cmds;
|
|
@@ -86,7 +97,7 @@ async function initCmds() {
|
|
|
86
97
|
return cmds;
|
|
87
98
|
}
|
|
88
99
|
async function pingCmd(args = [], options) {
|
|
89
|
-
const isUp = await initAgent(
|
|
100
|
+
const isUp = await initAgent(isDebug.value);
|
|
90
101
|
return isUp;
|
|
91
102
|
}
|
|
92
103
|
async function _updateConfCmd(args = [], options) {
|
|
@@ -120,13 +131,13 @@ async function _executeTaskCmd(args = [], options) {
|
|
|
120
131
|
console.warn("Provide a task name");
|
|
121
132
|
return;
|
|
122
133
|
}
|
|
123
|
-
const {
|
|
124
|
-
if (
|
|
134
|
+
const { data, error } = await executeTaskCmd(args, options);
|
|
135
|
+
if (error) {
|
|
125
136
|
console.warn(error);
|
|
126
137
|
}
|
|
127
138
|
if (formatMode.value == "markdown") {
|
|
128
139
|
console.log("\n------------------\n");
|
|
129
|
-
console.log(marked.parse(data).trim());
|
|
140
|
+
console.log(marked.parse(data.text).trim());
|
|
130
141
|
}
|
|
131
142
|
else {
|
|
132
143
|
console.log();
|
|
@@ -144,6 +155,15 @@ async function _executeJobCmd(args = [], options) {
|
|
|
144
155
|
const res = await executeJobCmd(name, args, options);
|
|
145
156
|
return res;
|
|
146
157
|
}
|
|
158
|
+
async function _executeWorkflowCmd(args = [], options) {
|
|
159
|
+
if (args.length == 0) {
|
|
160
|
+
console.warn("Provide a workflow name");
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
const name = args.shift();
|
|
164
|
+
const res = await executeWorkflowCmd(name, args, options);
|
|
165
|
+
return res;
|
|
166
|
+
}
|
|
147
167
|
async function _readTaskCmd(args = [], options) {
|
|
148
168
|
if (args.length == 0) {
|
|
149
169
|
console.warn("Provide a task name");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AgentTask } from "@agent-smith/jobs";
|
|
2
|
-
import { FeatureType } from "../../interfaces.js";
|
|
3
|
-
declare function systemAction(path: string): AgentTask<FeatureType
|
|
4
|
-
declare function pythonAction(path: string): AgentTask<FeatureType
|
|
5
|
-
declare function executeActionCmd(args?: Array<string>, options?: any, quiet?: boolean): Promise<any
|
|
2
|
+
import { FeatureType, NodeReturnType } from "../../interfaces.js";
|
|
3
|
+
declare function systemAction(path: string): AgentTask<FeatureType, Array<string>, NodeReturnType<string>>;
|
|
4
|
+
declare function pythonAction(path: string): AgentTask<FeatureType, Array<string>, NodeReturnType<string | Record<string, any> | Array<any>>>;
|
|
5
|
+
declare function executeActionCmd(args?: Array<string> | Record<string, any>, options?: any, quiet?: boolean): Promise<NodeReturnType<any>>;
|
|
6
6
|
export { executeActionCmd, systemAction, pythonAction };
|
|
@@ -15,7 +15,7 @@ function systemAction(path) {
|
|
|
15
15
|
actionSpec.data.args = [];
|
|
16
16
|
}
|
|
17
17
|
const out = await execute(actionSpec.data.cmd, [...actionSpec.data.args, ...args]);
|
|
18
|
-
return { data: out.trim()
|
|
18
|
+
return { data: out.trim() };
|
|
19
19
|
}
|
|
20
20
|
});
|
|
21
21
|
return action;
|
|
@@ -25,24 +25,44 @@ function pythonAction(path) {
|
|
|
25
25
|
id: "python_action",
|
|
26
26
|
title: "",
|
|
27
27
|
run: async (args) => {
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
const { data, error } = await runPyScript(pyShell, "python3", path, args);
|
|
29
|
+
if (error) {
|
|
30
|
+
return { data: {}, error: error };
|
|
31
|
+
}
|
|
32
|
+
const txt = data.join("\n");
|
|
33
|
+
let final = txt;
|
|
31
34
|
if (txt.startsWith("{") || txt.startsWith("[")) {
|
|
32
|
-
|
|
35
|
+
final = JSON.parse(final);
|
|
33
36
|
}
|
|
34
|
-
|
|
37
|
+
const res = { data: final };
|
|
38
|
+
return res;
|
|
35
39
|
}
|
|
36
40
|
});
|
|
37
41
|
return action;
|
|
38
42
|
}
|
|
39
43
|
async function executeActionCmd(args = [], options = {}, quiet = false) {
|
|
40
|
-
const
|
|
44
|
+
const isWorkflow = !Array.isArray(args);
|
|
45
|
+
let name;
|
|
46
|
+
if (!isWorkflow) {
|
|
47
|
+
name = args.shift();
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
if (!args.name) {
|
|
51
|
+
throw new Error("Provide an action name param");
|
|
52
|
+
}
|
|
53
|
+
name = args.name;
|
|
54
|
+
delete args.name;
|
|
55
|
+
}
|
|
41
56
|
const { found, path, ext } = getFeatureSpec(name, "action");
|
|
42
57
|
if (!found) {
|
|
43
|
-
|
|
58
|
+
throw new Error("Action not found");
|
|
44
59
|
}
|
|
45
60
|
let act;
|
|
61
|
+
if (!["js", "mjs"].includes(ext)) {
|
|
62
|
+
if (isWorkflow) {
|
|
63
|
+
throw new Error(`Action ${name} param error: ${typeof args}, ${args}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
46
66
|
switch (ext) {
|
|
47
67
|
case "js":
|
|
48
68
|
const { action } = await import(path);
|
|
@@ -65,11 +85,14 @@ async function executeActionCmd(args = [], options = {}, quiet = false) {
|
|
|
65
85
|
if (input) {
|
|
66
86
|
args.push(input);
|
|
67
87
|
}
|
|
68
|
-
const res = await act.run(args,
|
|
88
|
+
const res = await act.run(args, options);
|
|
89
|
+
if (res?.error) {
|
|
90
|
+
throw res.error;
|
|
91
|
+
}
|
|
69
92
|
if (!quiet) {
|
|
70
93
|
console.log(res.data);
|
|
71
94
|
}
|
|
72
95
|
await processOutput(res);
|
|
73
|
-
return {
|
|
96
|
+
return { data: res.data };
|
|
74
97
|
}
|
|
75
98
|
export { executeActionCmd, systemAction, pythonAction };
|
|
@@ -12,8 +12,7 @@ async function executeJobCmd(name, args = [], options = {}) {
|
|
|
12
12
|
console.log("Running job", name, Object.keys(job.tasks).length, "tasks");
|
|
13
13
|
}
|
|
14
14
|
if (!found) {
|
|
15
|
-
|
|
16
|
-
return { error: `Job ${name} not found` };
|
|
15
|
+
throw new Error(`Job ${name} not found`);
|
|
17
16
|
}
|
|
18
17
|
await job.start();
|
|
19
18
|
let res = {};
|
|
@@ -26,7 +25,7 @@ async function executeJobCmd(name, args = [], options = {}) {
|
|
|
26
25
|
const chain = task.properties?.chain;
|
|
27
26
|
const { found, path } = getFeatureSpec(name, "task");
|
|
28
27
|
if (!found) {
|
|
29
|
-
|
|
28
|
+
throw new Error(`Task ${name} not found`);
|
|
30
29
|
}
|
|
31
30
|
const tres = readTask(path);
|
|
32
31
|
if (!tres.found) {
|
|
@@ -154,6 +153,9 @@ async function executeJobCmd(name, args = [], options = {}) {
|
|
|
154
153
|
}
|
|
155
154
|
try {
|
|
156
155
|
res = await job.runTask(name, _p, options);
|
|
156
|
+
if (res?.error) {
|
|
157
|
+
throw new Error(`Error executing job action ${res.error}`);
|
|
158
|
+
}
|
|
157
159
|
}
|
|
158
160
|
catch (e) {
|
|
159
161
|
throw new Error(`Error executing job action ${e}`);
|
|
@@ -170,7 +172,7 @@ async function executeJobCmd(name, args = [], options = {}) {
|
|
|
170
172
|
params = { ...res.data, ...nextParams };
|
|
171
173
|
}
|
|
172
174
|
catch (err) {
|
|
173
|
-
|
|
175
|
+
throw new Error(`Error executing (${task.type}) task ${name}: ${err}`);
|
|
174
176
|
}
|
|
175
177
|
}
|
|
176
178
|
++i;
|
|
@@ -248,7 +250,8 @@ async function _createJobFromSpec(spec) {
|
|
|
248
250
|
if (t?.chain) {
|
|
249
251
|
at.properties = { "chain": true };
|
|
250
252
|
}
|
|
251
|
-
|
|
253
|
+
const tsk = at;
|
|
254
|
+
tasks[t.name] = tsk;
|
|
252
255
|
}
|
|
253
256
|
}
|
|
254
257
|
job.tasks = tasks;
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import { NodeReturnType } from "../../interfaces.js";
|
|
2
|
+
import { InferenceResult } from "@locallm/types/dist/interfaces.js";
|
|
3
|
+
declare function executeTaskCmd(args?: Array<string> | Record<string, any>, options?: any): Promise<NodeReturnType<InferenceResult>>;
|
|
2
4
|
export { executeTaskCmd };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { brain, initAgent, taskBuilder } from "../../agent.js";
|
|
2
2
|
import { getFeatureSpec } from "../../state/features.js";
|
|
3
|
-
import { isChatMode, isDebug } from "../../state/state.js";
|
|
3
|
+
import { isChatMode, isDebug, isVerbose } from "../../state/state.js";
|
|
4
4
|
import { initTaskConf, initTaskParams, initTaskVars, parseInputOptions, readTask } from "./utils.js";
|
|
5
5
|
async function executeTaskCmd(args = [], options = {}) {
|
|
6
6
|
await initAgent();
|
|
@@ -8,10 +8,10 @@ async function executeTaskCmd(args = [], options = {}) {
|
|
|
8
8
|
console.log("Task args:", args);
|
|
9
9
|
console.log("Task options:", options);
|
|
10
10
|
}
|
|
11
|
-
const
|
|
11
|
+
const isWorkflow = !Array.isArray(args);
|
|
12
12
|
let name;
|
|
13
13
|
let pr;
|
|
14
|
-
if (!
|
|
14
|
+
if (!isWorkflow) {
|
|
15
15
|
name = args.shift();
|
|
16
16
|
const _pr = await parseInputOptions(options);
|
|
17
17
|
if (!_pr) {
|
|
@@ -37,11 +37,10 @@ async function executeTaskCmd(args = [], options = {}) {
|
|
|
37
37
|
name = args.name;
|
|
38
38
|
delete args.name;
|
|
39
39
|
pr = args.prompt;
|
|
40
|
-
delete args.prompt;
|
|
41
40
|
}
|
|
42
41
|
const { found, path } = getFeatureSpec(name, "task");
|
|
43
42
|
if (!found) {
|
|
44
|
-
return {
|
|
43
|
+
return { data: {}, error: new Error(`Task ${name} not found`) };
|
|
45
44
|
}
|
|
46
45
|
const res = readTask(path);
|
|
47
46
|
if (!res.found) {
|
|
@@ -51,7 +50,7 @@ async function executeTaskCmd(args = [], options = {}) {
|
|
|
51
50
|
const task = taskBuilder.fromYaml(res.ymlTask);
|
|
52
51
|
let conf = {};
|
|
53
52
|
let vars = {};
|
|
54
|
-
if (!
|
|
53
|
+
if (!isWorkflow) {
|
|
55
54
|
const tv = initTaskVars(args, taskSpec?.inferParams ? taskSpec.inferParams : {});
|
|
56
55
|
conf = tv.conf;
|
|
57
56
|
vars = tv.vars;
|
|
@@ -82,20 +81,26 @@ async function executeTaskCmd(args = [], options = {}) {
|
|
|
82
81
|
process.stdout.write(t);
|
|
83
82
|
});
|
|
84
83
|
conf.expert = ex;
|
|
85
|
-
if (isDebug.value) {
|
|
84
|
+
if (isDebug.value || isVerbose.value) {
|
|
86
85
|
conf.debug = true;
|
|
87
86
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
87
|
+
let ir;
|
|
88
|
+
try {
|
|
89
|
+
ir = await task.run({ prompt: pr, ...vars }, conf);
|
|
90
|
+
}
|
|
91
|
+
catch (err) {
|
|
92
|
+
throw new Error(`Error executing task: ${name} ${err}`);
|
|
91
93
|
}
|
|
92
94
|
conf.prompt = pr;
|
|
93
95
|
if (isChatMode.value) {
|
|
94
96
|
if (brain.ex.name != ex.name) {
|
|
95
97
|
brain.setDefaultExpert(ex);
|
|
96
98
|
}
|
|
97
|
-
brain.ex.template.pushToHistory({ user: pr, assistant:
|
|
99
|
+
brain.ex.template.pushToHistory({ user: pr, assistant: ir.text });
|
|
100
|
+
}
|
|
101
|
+
if (isDebug.value) {
|
|
102
|
+
console.log("\n", ir.stats);
|
|
98
103
|
}
|
|
99
|
-
return {
|
|
104
|
+
return { data: ir };
|
|
100
105
|
}
|
|
101
106
|
export { executeTaskCmd };
|
package/dist/cmd/lib/utils.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { AgentTask } from "@agent-smith/jobs
|
|
1
|
+
import { AgentTask } from "@agent-smith/jobs";
|
|
2
2
|
import { LmTask } from "@agent-smith/lmtask";
|
|
3
|
-
import { FeatureType } from "../../interfaces.js";
|
|
3
|
+
import { FeatureType, NodeReturnType } from "../../interfaces.js";
|
|
4
4
|
declare function setOptions(args: Array<string> | undefined, options: Record<string, any>): Promise<Array<string>>;
|
|
5
5
|
declare function readPromptFile(): string;
|
|
6
6
|
declare function processOutput(res: any): Promise<void>;
|
|
@@ -20,5 +20,5 @@ declare function initTaskVars(args: Array<any>, inferParams: Record<string, any>
|
|
|
20
20
|
vars: Record<string, any>;
|
|
21
21
|
};
|
|
22
22
|
declare function parseInputOptions(options: any): Promise<string | null>;
|
|
23
|
-
declare function createJsAction(action: CallableFunction): AgentTask<FeatureType
|
|
23
|
+
declare function createJsAction(action: CallableFunction): AgentTask<FeatureType, any, NodeReturnType<any>>;
|
|
24
24
|
export { createJsAction, initTaskConf, initTaskParams, initTaskVars, initActionVars, parseInputOptions, processOutput, readPromptFile, readTask, readTasksDir, setOptions };
|
package/dist/cmd/lib/utils.js
CHANGED
|
@@ -44,7 +44,6 @@ async function processOutput(res) {
|
|
|
44
44
|
let hasOutput = false;
|
|
45
45
|
if (res?.data) {
|
|
46
46
|
data = res.data;
|
|
47
|
-
0;
|
|
48
47
|
hasOutput = true;
|
|
49
48
|
}
|
|
50
49
|
if (res?.text) {
|
|
@@ -129,7 +128,7 @@ function initTaskConf(conf, taskSpec) {
|
|
|
129
128
|
function initTaskParams(params, inferParams) {
|
|
130
129
|
const conf = { inferParams: inferParams };
|
|
131
130
|
if (!params?.prompt) {
|
|
132
|
-
throw new Error(`Error initializing task
|
|
131
|
+
throw new Error(`Error initializing task params: provide a prompt`);
|
|
133
132
|
}
|
|
134
133
|
if (params?.images) {
|
|
135
134
|
conf.inferParams.images = params.images;
|
|
@@ -236,8 +235,14 @@ function createJsAction(action) {
|
|
|
236
235
|
id: "",
|
|
237
236
|
title: "",
|
|
238
237
|
run: async (args) => {
|
|
239
|
-
|
|
240
|
-
|
|
238
|
+
try {
|
|
239
|
+
const res = await action(args);
|
|
240
|
+
return { ok: true, data: res };
|
|
241
|
+
}
|
|
242
|
+
catch (e) {
|
|
243
|
+
const err = new Error(`Error executing action ${e}`);
|
|
244
|
+
return { ok: false, data: {}, error: err };
|
|
245
|
+
}
|
|
241
246
|
}
|
|
242
247
|
});
|
|
243
248
|
return task;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { isDebug, isVerbose } from "../../../state/state.js";
|
|
2
|
+
import { readWorkflow } from "./read.js";
|
|
3
|
+
import { executeTaskCmd } from "../execute_task.js";
|
|
4
|
+
import { executeActionCmd } from "../execute_action.js";
|
|
5
|
+
async function executeWorkflowCmd(name, args = [], options = {}) {
|
|
6
|
+
const { workflow, found } = await readWorkflow(name);
|
|
7
|
+
if (!found) {
|
|
8
|
+
throw new Error(`Workflow ${name} not found`);
|
|
9
|
+
}
|
|
10
|
+
const stepNames = Object.keys(workflow);
|
|
11
|
+
if (isDebug.value || isVerbose.value) {
|
|
12
|
+
console.log("Running workflow", name, stepNames.length, "steps");
|
|
13
|
+
}
|
|
14
|
+
let params = {};
|
|
15
|
+
let i = 0;
|
|
16
|
+
const finalTaskIndex = stepNames.length + 1;
|
|
17
|
+
let taskRes = { data: {}, error: new Error("Empty task res") };
|
|
18
|
+
for (const [name, step] of Object.entries(workflow)) {
|
|
19
|
+
if (isDebug.value || isVerbose.value) {
|
|
20
|
+
console.log(`${i + 1}: ${step.type} ${name}`);
|
|
21
|
+
}
|
|
22
|
+
const p = i == 0 ? [name, ...args] : { name: name, ...params };
|
|
23
|
+
switch (step.type) {
|
|
24
|
+
case "task":
|
|
25
|
+
try {
|
|
26
|
+
taskRes = await executeTaskCmd(p, options);
|
|
27
|
+
}
|
|
28
|
+
catch (e) {
|
|
29
|
+
throw new Error(`Wokflow ${i + 1} error: ${e}`);
|
|
30
|
+
}
|
|
31
|
+
break;
|
|
32
|
+
case "action":
|
|
33
|
+
try {
|
|
34
|
+
taskRes = await executeActionCmd(p, options, true);
|
|
35
|
+
if (i == finalTaskIndex) {
|
|
36
|
+
console.log(taskRes.data);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch (e) {
|
|
40
|
+
throw new Error(`Wokflow ${i + 1} error: ${e}`);
|
|
41
|
+
}
|
|
42
|
+
break;
|
|
43
|
+
default:
|
|
44
|
+
throw new Error(`Unknown task type ${step.type} in workflow ${name}`);
|
|
45
|
+
}
|
|
46
|
+
params = taskRes;
|
|
47
|
+
++i;
|
|
48
|
+
}
|
|
49
|
+
return taskRes;
|
|
50
|
+
}
|
|
51
|
+
export { executeWorkflowCmd, };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { AgentTask } from "@agent-smith/jobs";
|
|
2
|
+
import { FeatureType, NodeReturnType } from '../../../interfaces.js';
|
|
3
|
+
declare function readWorkflow(name: string): Promise<{
|
|
4
|
+
found: boolean;
|
|
5
|
+
workflow: Record<string, AgentTask<FeatureType, any, NodeReturnType<any>, Record<string, any>>>;
|
|
6
|
+
}>;
|
|
7
|
+
export { readWorkflow, };
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import YAML from 'yaml';
|
|
2
|
+
import { default as fs } from "fs";
|
|
3
|
+
import { taskBuilder } from '../../../agent.js';
|
|
4
|
+
import { getFeatureSpec } from '../../../state/features.js';
|
|
5
|
+
import { createJsAction, readTask } from '../utils.js';
|
|
6
|
+
import { pythonAction, systemAction } from './../execute_action.js';
|
|
7
|
+
async function _createWorkflowFromSpec(spec) {
|
|
8
|
+
const steps = {};
|
|
9
|
+
for (const step of spec.steps) {
|
|
10
|
+
const type = Object.keys(step)[0];
|
|
11
|
+
const sval = step[type];
|
|
12
|
+
let name;
|
|
13
|
+
if (typeof sval == "string") {
|
|
14
|
+
name = sval;
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
name = step[type].name;
|
|
18
|
+
}
|
|
19
|
+
if (type == "action") {
|
|
20
|
+
const { found, path, ext } = getFeatureSpec(name, "action");
|
|
21
|
+
if (!found) {
|
|
22
|
+
throw new Error(`Action ${name} not found`);
|
|
23
|
+
}
|
|
24
|
+
switch (ext) {
|
|
25
|
+
case "js":
|
|
26
|
+
const { action } = await import(path);
|
|
27
|
+
const at = action;
|
|
28
|
+
at.type = "action";
|
|
29
|
+
steps[name] = at;
|
|
30
|
+
break;
|
|
31
|
+
case "mjs":
|
|
32
|
+
const mjsa = await import(path);
|
|
33
|
+
const act = createJsAction(mjsa.action);
|
|
34
|
+
act.type = "action";
|
|
35
|
+
steps[name] = act;
|
|
36
|
+
break;
|
|
37
|
+
case "yml":
|
|
38
|
+
const _t1 = systemAction(path);
|
|
39
|
+
_t1.type = "action";
|
|
40
|
+
steps[name] = _t1;
|
|
41
|
+
break;
|
|
42
|
+
case "py":
|
|
43
|
+
const _t = pythonAction(path);
|
|
44
|
+
_t.type = "action";
|
|
45
|
+
steps[name] = _t;
|
|
46
|
+
break;
|
|
47
|
+
default:
|
|
48
|
+
throw new Error(`Unknown feature extension ${ext}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
const { found, path } = getFeatureSpec(name, "task");
|
|
53
|
+
if (!found) {
|
|
54
|
+
throw new Error(`Task ${name} not found`);
|
|
55
|
+
}
|
|
56
|
+
const res = readTask(path);
|
|
57
|
+
if (!res.found) {
|
|
58
|
+
throw new Error(`Unable to read task ${name} ${path}`);
|
|
59
|
+
}
|
|
60
|
+
const tsk = taskBuilder.fromYaml(res.ymlTask, "task");
|
|
61
|
+
steps[name] = tsk;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return steps;
|
|
65
|
+
}
|
|
66
|
+
async function _readWorkflowFromDisk(name) {
|
|
67
|
+
const { found, path } = getFeatureSpec(name, "workflow");
|
|
68
|
+
if (!found) {
|
|
69
|
+
return { found: false, data: {} };
|
|
70
|
+
}
|
|
71
|
+
if (!fs.existsSync(path)) {
|
|
72
|
+
return { data: {}, found: false };
|
|
73
|
+
}
|
|
74
|
+
const file = fs.readFileSync(path, 'utf8');
|
|
75
|
+
const data = YAML.parse(file);
|
|
76
|
+
data.name = name;
|
|
77
|
+
return { data: data, found: true };
|
|
78
|
+
}
|
|
79
|
+
async function readWorkflow(name) {
|
|
80
|
+
const { found, ext } = getFeatureSpec(name, "workflow");
|
|
81
|
+
if (!found) {
|
|
82
|
+
return { found: false, workflow: {} };
|
|
83
|
+
}
|
|
84
|
+
let wf = {};
|
|
85
|
+
switch (ext) {
|
|
86
|
+
case "yml":
|
|
87
|
+
const { data } = await _readWorkflowFromDisk(name);
|
|
88
|
+
try {
|
|
89
|
+
const workflow = await _createWorkflowFromSpec(data);
|
|
90
|
+
if (!found) {
|
|
91
|
+
return { found: false, workflow: {} };
|
|
92
|
+
}
|
|
93
|
+
wf = workflow;
|
|
94
|
+
}
|
|
95
|
+
catch (e) {
|
|
96
|
+
throw new Error(`Workflow create error: ${e}`);
|
|
97
|
+
}
|
|
98
|
+
break;
|
|
99
|
+
default:
|
|
100
|
+
throw new Error(`Workflow extension ${ext} not implemented`);
|
|
101
|
+
}
|
|
102
|
+
return { found: true, workflow: wf };
|
|
103
|
+
}
|
|
104
|
+
export { readWorkflow, };
|
|
@@ -21,6 +21,7 @@ function readFeaturesDir(dir) {
|
|
|
21
21
|
job: [],
|
|
22
22
|
action: [],
|
|
23
23
|
cmd: [],
|
|
24
|
+
workflow: []
|
|
24
25
|
};
|
|
25
26
|
let dirpath = path.join(dir, "tasks");
|
|
26
27
|
if (fs.existsSync(dirpath)) {
|
|
@@ -50,6 +51,20 @@ function readFeaturesDir(dir) {
|
|
|
50
51
|
});
|
|
51
52
|
});
|
|
52
53
|
}
|
|
54
|
+
dirpath = path.join(dir, "workflows");
|
|
55
|
+
if (fs.existsSync(dirpath)) {
|
|
56
|
+
const data = _readDir(dirpath, [".yml"]);
|
|
57
|
+
data.forEach((filename) => {
|
|
58
|
+
const parts = filename.split(".");
|
|
59
|
+
const ext = parts.pop();
|
|
60
|
+
const name = parts.join("");
|
|
61
|
+
feats.workflow.push({
|
|
62
|
+
name: name,
|
|
63
|
+
path: path.join(dirpath),
|
|
64
|
+
ext: ext,
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
}
|
|
53
68
|
dirpath = path.join(dir, "actions");
|
|
54
69
|
if (fs.existsSync(dirpath)) {
|
|
55
70
|
const data = _readDir(dirpath, ["yml", ".js", "mjs", ".py"]);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { NodeReturnType } from '../../interfaces.js';
|
|
1
2
|
import { PythonShell } from 'python-shell';
|
|
2
|
-
declare function runPyScript(rsShell: PythonShell, pythonPath: string, scriptPath: string, scriptArgs: Array<string>,
|
|
3
|
+
declare function runPyScript(rsShell: PythonShell, pythonPath: string, scriptPath: string, scriptArgs: Array<string>, onEmitLine?: CallableFunction): Promise<NodeReturnType<Array<string>>>;
|
|
3
4
|
export { runPyScript };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PythonShell } from 'python-shell';
|
|
2
|
-
async function runPyScript(rsShell, pythonPath, scriptPath, scriptArgs,
|
|
2
|
+
async function runPyScript(rsShell, pythonPath, scriptPath, scriptArgs, onEmitLine) {
|
|
3
3
|
const _options = {
|
|
4
4
|
mode: "text",
|
|
5
5
|
pythonPath: pythonPath,
|
|
@@ -9,35 +9,24 @@ async function runPyScript(rsShell, pythonPath, scriptPath, scriptArgs, handleOu
|
|
|
9
9
|
let promiseResolve;
|
|
10
10
|
let promise = new Promise((resolve) => promiseResolve = resolve);
|
|
11
11
|
rsShell = new PythonShell(scriptPath, _options);
|
|
12
|
-
const
|
|
12
|
+
const res = { data: new Array() };
|
|
13
13
|
function handleLine(msg) {
|
|
14
14
|
if (onEmitLine) {
|
|
15
15
|
onEmitLine(msg);
|
|
16
16
|
}
|
|
17
|
-
|
|
17
|
+
res.data.push(msg);
|
|
18
18
|
}
|
|
19
19
|
rsShell.on('message', function (message) {
|
|
20
|
-
|
|
21
|
-
handleLine(message);
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
rsShell.on('stderr', function (err) {
|
|
25
|
-
console.log("STDERR", err);
|
|
26
|
-
if (handleOutputFrom == "stderr") {
|
|
27
|
-
handleLine(err);
|
|
28
|
-
}
|
|
29
|
-
else {
|
|
30
|
-
promiseResolve(true);
|
|
31
|
-
}
|
|
20
|
+
handleLine(message);
|
|
32
21
|
});
|
|
33
22
|
rsShell.on('pythonError', function (err) {
|
|
34
23
|
console.log("PYERR", `${err.message}, ${err.traceback}`);
|
|
35
|
-
|
|
24
|
+
res.error = new Error(err.traceback.toString());
|
|
36
25
|
});
|
|
37
26
|
rsShell.end(function (err, code, signal) {
|
|
38
27
|
promiseResolve(true);
|
|
39
28
|
});
|
|
40
29
|
await promise;
|
|
41
|
-
return
|
|
30
|
+
return res;
|
|
42
31
|
}
|
|
43
32
|
export { runPyScript };
|
package/dist/db/read.js
CHANGED
|
@@ -27,11 +27,12 @@ function _readFeaturesType(type) {
|
|
|
27
27
|
return f;
|
|
28
28
|
}
|
|
29
29
|
function readFeatures() {
|
|
30
|
-
const feats = { task: {}, job: {}, action: {}, cmd: {} };
|
|
30
|
+
const feats = { task: {}, job: {}, action: {}, cmd: {}, workflow: {} };
|
|
31
31
|
feats.task = _readFeaturesType("task");
|
|
32
32
|
feats.job = _readFeaturesType("job");
|
|
33
33
|
feats.action = _readFeaturesType("action");
|
|
34
34
|
feats.cmd = _readFeaturesType("cmd");
|
|
35
|
+
feats.workflow = _readFeaturesType("workflow");
|
|
35
36
|
return feats;
|
|
36
37
|
}
|
|
37
38
|
function readAliases() {
|
package/dist/db/schemas.js
CHANGED
|
@@ -24,6 +24,12 @@ const jobs = `CREATE TABLE IF NOT EXISTS job (
|
|
|
24
24
|
path TEXT NOT NULL,
|
|
25
25
|
ext TEXT NOT NULL CHECK ( ext IN ('yml') )
|
|
26
26
|
);`;
|
|
27
|
+
const workflow = `CREATE TABLE IF NOT EXISTS workflow (
|
|
28
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
29
|
+
name TEXT UNIQUE NOT NULL,
|
|
30
|
+
path TEXT NOT NULL,
|
|
31
|
+
ext TEXT NOT NULL CHECK ( ext IN ('yml') )
|
|
32
|
+
);`;
|
|
27
33
|
const actions = `CREATE TABLE IF NOT EXISTS action (
|
|
28
34
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
29
35
|
name TEXT UNIQUE NOT NULL,
|
|
@@ -39,9 +45,9 @@ const cmds = `CREATE TABLE IF NOT EXISTS cmd (
|
|
|
39
45
|
const aliases = `CREATE TABLE IF NOT EXISTS aliases (
|
|
40
46
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
41
47
|
name TEXT UNIQUE NOT NULL,
|
|
42
|
-
type TEXT NOT NULL CHECK ( type IN ('task', 'action', 'job') )
|
|
48
|
+
type TEXT NOT NULL CHECK ( type IN ('task', 'action', 'job', 'workflow') )
|
|
43
49
|
);`;
|
|
44
50
|
const schemas = [
|
|
45
|
-
filepaths, featurespaths, tasks, jobs, actions, cmds, plugins, aliases
|
|
51
|
+
filepaths, featurespaths, tasks, jobs, workflow, actions, cmds, plugins, aliases
|
|
46
52
|
];
|
|
47
53
|
export { schemas };
|
package/dist/db/write.js
CHANGED
|
@@ -62,6 +62,9 @@ function updateAliases(feats) {
|
|
|
62
62
|
feats.job.forEach((feat) => {
|
|
63
63
|
existingAliases = _updateAlias(existingAliases, feat.name, "job");
|
|
64
64
|
});
|
|
65
|
+
feats.workflow.forEach((feat) => {
|
|
66
|
+
existingAliases = _updateAlias(existingAliases, feat.name, "workflow");
|
|
67
|
+
});
|
|
65
68
|
}
|
|
66
69
|
function upsertAndCleanFeatures(feats, type) {
|
|
67
70
|
const stmt = db.prepare(`SELECT name FROM ${type}`);
|
|
@@ -88,5 +91,6 @@ function updateFeatures(feats) {
|
|
|
88
91
|
upsertAndCleanFeatures(feats.job, "job");
|
|
89
92
|
upsertAndCleanFeatures(feats.action, "action");
|
|
90
93
|
upsertAndCleanFeatures(feats.cmd, "cmd");
|
|
94
|
+
upsertAndCleanFeatures(feats.workflow, "workflow");
|
|
91
95
|
}
|
|
92
96
|
export { updatePromptfilePath, insertFeaturesPathIfNotExists, insertPluginIfNotExists, updateFeatures, updateAliases, cleanupFeaturePaths, };
|
package/dist/interfaces.d.ts
CHANGED
|
@@ -29,22 +29,32 @@ interface Features {
|
|
|
29
29
|
path: string;
|
|
30
30
|
ext: ActionExtension;
|
|
31
31
|
}>;
|
|
32
|
+
workflow: Array<{
|
|
33
|
+
name: string;
|
|
34
|
+
path: string;
|
|
35
|
+
ext: WorkflowExtension;
|
|
36
|
+
}>;
|
|
32
37
|
}
|
|
33
38
|
interface ConfigFile {
|
|
34
39
|
promptfile?: string;
|
|
35
40
|
features?: Array<string>;
|
|
36
41
|
plugins?: Array<string>;
|
|
37
42
|
}
|
|
43
|
+
interface NodeReturnType<T = Record<string, any>> {
|
|
44
|
+
data: T;
|
|
45
|
+
error?: Error;
|
|
46
|
+
}
|
|
38
47
|
type CmdExecutor = (args: Array<string>, options: any) => Promise<any>;
|
|
39
48
|
type InputMode = "manual" | "promptfile" | "clipboard";
|
|
40
49
|
type OutputMode = "txt" | "clipboard";
|
|
41
50
|
type RunMode = "cli" | "cmd";
|
|
42
51
|
type FormatMode = "text" | "markdown";
|
|
43
|
-
type FeatureType = "task" | "job" | "action" | "cmd";
|
|
52
|
+
type FeatureType = "task" | "job" | "action" | "cmd" | "workflow";
|
|
44
53
|
type ActionExtension = "js" | "mjs" | "py" | "yml";
|
|
45
54
|
type TaskExtension = "yml";
|
|
55
|
+
type WorkflowExtension = "yml";
|
|
46
56
|
type JobExtension = "yml";
|
|
47
57
|
type CmdExtension = "js";
|
|
48
|
-
type FeatureExtension = TaskExtension | JobExtension | CmdExtension | ActionExtension;
|
|
49
|
-
type AliasType = "task" | "action" | "job";
|
|
50
|
-
export { Cmd, CmdExecutor, InputMode, OutputMode, RunMode, FormatMode, FeatureType, ActionExtension, TaskExtension, JobExtension, CmdExtension, FeatureSpec, Features, ConfigFile, FeatureExtension, AliasType, };
|
|
58
|
+
type FeatureExtension = TaskExtension | JobExtension | CmdExtension | ActionExtension | WorkflowExtension;
|
|
59
|
+
type AliasType = "task" | "action" | "job" | "workflow";
|
|
60
|
+
export { Cmd, CmdExecutor, NodeReturnType, InputMode, OutputMode, RunMode, FormatMode, FeatureType, ActionExtension, TaskExtension, JobExtension, WorkflowExtension, CmdExtension, FeatureSpec, Features, ConfigFile, FeatureExtension, AliasType, };
|
package/dist/main.d.ts
CHANGED
|
@@ -2,7 +2,8 @@ import { execute, run } from "./cmd/sys/execute.js";
|
|
|
2
2
|
import { executeJobCmd } from "./cmd/lib/execute_job.js";
|
|
3
3
|
import { executeActionCmd } from "./cmd/lib/execute_action.js";
|
|
4
4
|
import { executeTaskCmd } from "./cmd/lib/execute_task.js";
|
|
5
|
+
import { executeWorkflowCmd } from "./cmd/lib/workflows/cmd.js";
|
|
5
6
|
import { writeToClipboard } from "./cmd/sys/clipboard.js";
|
|
6
7
|
import { pingCmd } from "./cmd/clicmds/cmds.js";
|
|
7
8
|
import { initAgent } from "./agent.js";
|
|
8
|
-
export { execute, run, pingCmd, executeJobCmd, executeActionCmd, executeTaskCmd, writeToClipboard, initAgent, };
|
|
9
|
+
export { execute, run, pingCmd, executeJobCmd, executeWorkflowCmd, executeActionCmd, executeTaskCmd, writeToClipboard, initAgent, };
|
package/dist/main.js
CHANGED
|
@@ -2,7 +2,8 @@ import { execute, run } from "./cmd/sys/execute.js";
|
|
|
2
2
|
import { executeJobCmd } from "./cmd/lib/execute_job.js";
|
|
3
3
|
import { executeActionCmd } from "./cmd/lib/execute_action.js";
|
|
4
4
|
import { executeTaskCmd } from "./cmd/lib/execute_task.js";
|
|
5
|
+
import { executeWorkflowCmd } from "./cmd/lib/workflows/cmd.js";
|
|
5
6
|
import { writeToClipboard } from "./cmd/sys/clipboard.js";
|
|
6
7
|
import { pingCmd } from "./cmd/clicmds/cmds.js";
|
|
7
8
|
import { initAgent } from "./agent.js";
|
|
8
|
-
export { execute, run, pingCmd, executeJobCmd, executeActionCmd, executeTaskCmd, writeToClipboard, initAgent, };
|
|
9
|
+
export { execute, run, pingCmd, executeJobCmd, executeWorkflowCmd, executeActionCmd, executeTaskCmd, writeToClipboard, initAgent, };
|
package/dist/state/features.js
CHANGED
|
@@ -7,6 +7,7 @@ function readFeaturesDirs(featuresPaths) {
|
|
|
7
7
|
job: [],
|
|
8
8
|
action: [],
|
|
9
9
|
cmd: [],
|
|
10
|
+
workflow: [],
|
|
10
11
|
};
|
|
11
12
|
featuresPaths.forEach((dir) => {
|
|
12
13
|
const _f = readFeaturesDir(dir);
|
|
@@ -14,6 +15,7 @@ function readFeaturesDirs(featuresPaths) {
|
|
|
14
15
|
_f.job.forEach((item) => feats.job.push(item));
|
|
15
16
|
_f.action.forEach((item) => feats.action.push(item));
|
|
16
17
|
_f.cmd.forEach((item) => feats.cmd.push(item));
|
|
18
|
+
_f.workflow.forEach((item) => feats.workflow.push(item));
|
|
17
19
|
});
|
|
18
20
|
return feats;
|
|
19
21
|
}
|
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.38",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"buildrl": "rm -rf dist/* && rollup -c",
|
|
8
8
|
"build": "rm -rf dist/* && tsc --noCheck",
|
|
@@ -11,17 +11,17 @@
|
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"@agent-smith/brain": "^0.0.38",
|
|
14
|
-
"@agent-smith/jobs": "^0.0.
|
|
15
|
-
"@agent-smith/lmtask": "^0.0.
|
|
14
|
+
"@agent-smith/jobs": "^0.0.13",
|
|
15
|
+
"@agent-smith/lmtask": "^0.0.31",
|
|
16
16
|
"@agent-smith/tfm": "^0.1.1",
|
|
17
17
|
"@inquirer/prompts": "^7.3.3",
|
|
18
18
|
"@inquirer/select": "^4.0.10",
|
|
19
19
|
"@vue/reactivity": "^3.5.13",
|
|
20
|
-
"better-sqlite3": "^11.
|
|
20
|
+
"better-sqlite3": "^11.9.0",
|
|
21
21
|
"clipboardy": "^4.0.0",
|
|
22
22
|
"commander": "^13.1.0",
|
|
23
23
|
"marked-terminal": "^7.3.0",
|
|
24
|
-
"modprompt": "^0.10.
|
|
24
|
+
"modprompt": "^0.10.4",
|
|
25
25
|
"python-shell": "^5.0.0",
|
|
26
26
|
"yaml": "^2.7.0"
|
|
27
27
|
},
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"@agent-smith/tmem-jobs": "^0.0.4",
|
|
30
30
|
"@commander-js/extra-typings": "^13.1.0",
|
|
31
31
|
"@locallm/types": "^0.1.5",
|
|
32
|
-
"@rollup/plugin-node-resolve": "^16.0.
|
|
32
|
+
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
33
33
|
"@rollup/plugin-typescript": "^12.1.2",
|
|
34
34
|
"@types/better-sqlite3": "^7.6.12",
|
|
35
35
|
"@types/marked-terminal": "^6.1.1",
|