@agent-smith/cli 0.0.70 → 0.0.80
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 +12 -6
- package/dist/cmd/clicmds/base.js +13 -6
- package/dist/cmd/clicmds/cmds.js +5 -0
- package/dist/cmd/cmds.js +0 -20
- package/dist/cmd/lib/actions/cmd.d.ts +3 -4
- package/dist/cmd/lib/actions/cmd.js +48 -64
- package/dist/cmd/lib/actions/read.d.ts +2 -3
- package/dist/cmd/lib/actions/read.js +9 -14
- package/dist/cmd/lib/adaptaters/cmd.d.ts +1 -1
- package/dist/cmd/lib/adaptaters/cmd.js +7 -4
- package/dist/cmd/lib/mcp.d.ts +3 -3
- package/dist/cmd/lib/options_parsers.js +1 -1
- package/dist/cmd/lib/tasks/cmd.d.ts +3 -4
- package/dist/cmd/lib/tasks/cmd.js +103 -153
- package/dist/cmd/lib/tasks/conf.js +14 -9
- package/dist/cmd/lib/tasks/read.d.ts +11 -0
- package/dist/cmd/lib/tasks/read.js +93 -0
- package/dist/cmd/lib/tools.js +2 -2
- package/dist/cmd/lib/utils.js +3 -1
- package/dist/cmd/lib/workflows/cmd.js +9 -6
- package/dist/cmd/lib/workflows/read.d.ts +3 -4
- package/dist/cmd/lib/workflows/read.js +37 -15
- package/dist/conf.js +49 -1
- package/dist/const.d.ts +3 -0
- package/dist/const.js +24 -0
- package/dist/db/read.d.ts +4 -3
- package/dist/db/read.js +10 -1
- package/dist/db/schemas.js +9 -0
- package/dist/db/write.d.ts +4 -2
- package/dist/db/write.js +38 -2
- package/dist/index.js +2 -2
- package/dist/interfaces.d.ts +23 -10
- package/dist/main.d.ts +3 -3
- package/dist/main.js +2 -2
- package/dist/state/backends.d.ts +7 -0
- package/dist/state/backends.js +128 -0
- package/dist/state/state.d.ts +2 -1
- package/dist/state/state.js +1 -1
- package/dist/utils/perf.js +1 -1
- package/dist/utils/user_msgs.js +5 -5
- package/package.json +19 -20
- package/dist/agent.d.ts +0 -7
- package/dist/agent.js +0 -27
|
@@ -1,112 +1,49 @@
|
|
|
1
|
+
import { Agent } from "@agent-smith/agent";
|
|
2
|
+
import { useTemplateForModel } from "@agent-smith/tfm";
|
|
1
3
|
import { input } from "@inquirer/prompts";
|
|
2
4
|
import { compile, serializeGrammar } from "@intrinsicai/gbnfgen";
|
|
3
|
-
import color from "ansi-colors";
|
|
5
|
+
import { default as color, default as colors } from "ansi-colors";
|
|
6
|
+
import { PromptTemplate } from "modprompt";
|
|
4
7
|
import ora from 'ora';
|
|
5
|
-
import { brain, initAgent, taskBuilder } from "../../../agent.js";
|
|
6
8
|
import { query } from "../../../cli.js";
|
|
7
9
|
import { readClipboard } from "../../../cmd/sys/clipboard.js";
|
|
8
|
-
import { readTool } from "../../../db/read.js";
|
|
9
10
|
import { usePerfTimer } from "../../../main.js";
|
|
11
|
+
import { backend } from "../../../state/backends.js";
|
|
10
12
|
import { isChatMode, runMode } from "../../../state/state.js";
|
|
11
13
|
import { program } from "../../cmds.js";
|
|
12
|
-
import {
|
|
13
|
-
import { parseCommandArgs, parseTaskConfigOptions } from "../options_parsers.js";
|
|
14
|
+
import { parseCommandArgs } from "../options_parsers.js";
|
|
14
15
|
import { runtimeDataError, runtimeWarning } from "../user_msgs.js";
|
|
15
16
|
import { formatStats, processOutput, readPromptFile } from "../utils.js";
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
console.log("Task options:", options);
|
|
25
|
-
}
|
|
26
|
-
const taskFileSpec = openTaskSpec(name);
|
|
27
|
-
const opts = payload?.inferParams ? { ...options, ...payload.inferParams } : options;
|
|
28
|
-
const conf = parseTaskConfigOptions(opts);
|
|
29
|
-
if (options.debug) {
|
|
30
|
-
console.log("conf:", conf);
|
|
31
|
-
}
|
|
32
|
-
conf.inferParams = mergeInferParams(conf.inferParams, taskFileSpec.inferParams ?? {});
|
|
33
|
-
const model = configureTaskModel(conf, taskFileSpec);
|
|
34
|
-
if (options?.ctx) {
|
|
35
|
-
model.ctx = options.ctx;
|
|
36
|
-
}
|
|
37
|
-
const taskSpec = taskFileSpec;
|
|
38
|
-
let vars = {};
|
|
39
|
-
taskSpec.variables?.optional?.forEach(k => {
|
|
40
|
-
if (k in options) {
|
|
41
|
-
vars[k] = options[k];
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
taskSpec.variables?.required?.forEach(k => {
|
|
45
|
-
if (k in options) {
|
|
46
|
-
vars[k] = options[k];
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
const mcpServers = new Array();
|
|
50
|
-
if (taskFileSpec?.mcp) {
|
|
51
|
-
taskSpec.tools = [];
|
|
52
|
-
for (const [servername, tool] of Object.entries(taskFileSpec.mcp)) {
|
|
53
|
-
const mcp = new McpClient(servername, tool.command, tool.args, tool?.tools ?? null);
|
|
54
|
-
mcpServers.push(mcp);
|
|
55
|
-
await mcp.start();
|
|
56
|
-
const tools = await mcp.extractTools();
|
|
57
|
-
tools.forEach(t => taskSpec.tools?.push(t));
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
if (taskSpec.toolsList) {
|
|
61
|
-
if (!taskSpec?.tools) {
|
|
62
|
-
taskSpec.tools = [];
|
|
63
|
-
}
|
|
64
|
-
for (const toolName of taskSpec.toolsList) {
|
|
65
|
-
const { found, tool, type } = readTool(toolName);
|
|
66
|
-
if (!found) {
|
|
67
|
-
throw new Error(`tool ${toolName} not found for task ${taskSpec.name}`);
|
|
68
|
-
}
|
|
69
|
-
const lmTool = {
|
|
70
|
-
...tool,
|
|
71
|
-
execute: async (params) => {
|
|
72
|
-
switch (type) {
|
|
73
|
-
case "action":
|
|
74
|
-
const res = await executeAction(toolName, params, options, true);
|
|
75
|
-
return res;
|
|
76
|
-
case "task":
|
|
77
|
-
conf.quiet = !options?.debug;
|
|
78
|
-
const tres = await executeTask(name, params, options, true);
|
|
79
|
-
return tres.answer.text;
|
|
80
|
-
case "workflow":
|
|
81
|
-
const wres = await executeWorkflow(toolName, params, options);
|
|
82
|
-
return wres;
|
|
83
|
-
default:
|
|
84
|
-
throw new Error(`unknown tool execution function type: ${type} for ${toolName}`);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
taskSpec.tools.push(lmTool);
|
|
89
|
-
}
|
|
90
|
-
delete taskSpec.toolsList;
|
|
91
|
-
}
|
|
92
|
-
;
|
|
93
|
-
const task = taskBuilder.init(taskSpec);
|
|
17
|
+
import { readTask } from "./read.js";
|
|
18
|
+
const tfm = useTemplateForModel();
|
|
19
|
+
async function executeTask(name, payload, options, quiet) {
|
|
20
|
+
const agent = new Agent(backend.value);
|
|
21
|
+
if (options?.debug) {
|
|
22
|
+
console.log("Agent:", colors.bold(agent.lm.name), "( " + agent.lm.providerType + " backend type)");
|
|
23
|
+
}
|
|
24
|
+
const { task, model, conf, vars, mcpServers } = await readTask(name, payload, options, agent);
|
|
94
25
|
if (model?.inferParams?.tsGrammar) {
|
|
95
26
|
model.inferParams.grammar = serializeGrammar(await compile(model.inferParams.tsGrammar, "Grammar"));
|
|
96
27
|
delete model.inferParams.tsGrammar;
|
|
97
28
|
}
|
|
98
|
-
if (options
|
|
29
|
+
if (options?.debug) {
|
|
99
30
|
console.log("Task model:", model);
|
|
100
31
|
}
|
|
101
|
-
const ex = expert ?? brain.getOrCreateExpertForModel(model.name, model.template);
|
|
102
|
-
if (!ex) {
|
|
103
|
-
throw new Error("No expert found for model " + model.name);
|
|
104
|
-
}
|
|
105
|
-
ex.checkStatus();
|
|
106
|
-
let i = 0;
|
|
107
32
|
let c = false;
|
|
108
|
-
const
|
|
109
|
-
|
|
33
|
+
const useTemplates = agent.lm.providerType !== "openai";
|
|
34
|
+
let hasThink = false;
|
|
35
|
+
let tpl = null;
|
|
36
|
+
if (useTemplates) {
|
|
37
|
+
if ((!task.def.model?.template)) {
|
|
38
|
+
const gt = tfm.guess(task.def.model.name);
|
|
39
|
+
if (gt == "none") {
|
|
40
|
+
throw new Error(`Unable to guess the template for ${task.def.model}: please provide a template in the taskDef definition`);
|
|
41
|
+
}
|
|
42
|
+
task.def.model.template = gt;
|
|
43
|
+
}
|
|
44
|
+
tpl = new PromptTemplate(task.def.model.template);
|
|
45
|
+
hasThink = tpl.tags?.think ? true : false;
|
|
46
|
+
}
|
|
110
47
|
const printToken = (t) => {
|
|
111
48
|
if (options?.tokens === true) {
|
|
112
49
|
let txt = t;
|
|
@@ -119,89 +56,99 @@ async function executeTask(name, payload, options, quiet, expert) {
|
|
|
119
56
|
process.stdout.write(t);
|
|
120
57
|
}
|
|
121
58
|
};
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
if (
|
|
140
|
-
if (
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
59
|
+
const hasTools = options?.tools;
|
|
60
|
+
let continueWrite = true;
|
|
61
|
+
let skipNextEmptyLinesToken = false;
|
|
62
|
+
const spinner = ora("Thinking ...");
|
|
63
|
+
const ts = "Thinking";
|
|
64
|
+
const te = color.dim("tokens");
|
|
65
|
+
const formatTokenCount = (i) => {
|
|
66
|
+
return `${ts} ${color.bold(i.toString())} ${te}`;
|
|
67
|
+
};
|
|
68
|
+
const perfTimer = usePerfTimer(false);
|
|
69
|
+
let i = 0;
|
|
70
|
+
const processToken = (t) => {
|
|
71
|
+
if (i == 0) {
|
|
72
|
+
perfTimer.start();
|
|
73
|
+
}
|
|
74
|
+
spinner.text = formatTokenCount(i);
|
|
75
|
+
if (!options?.verbose && !options?.debug) {
|
|
76
|
+
if (hasThink && tpl) {
|
|
77
|
+
if (t == tpl.tags.think?.start) {
|
|
78
|
+
spinner.start();
|
|
79
|
+
continueWrite = false;
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
else if (t == tpl.tags.think?.end) {
|
|
83
|
+
continueWrite = true;
|
|
84
|
+
skipNextEmptyLinesToken = true;
|
|
85
|
+
let msg = color.dim("Thinking:") + ` ${i} ${color.dim("tokens")}`;
|
|
86
|
+
msg = msg + " " + color.dim(perfTimer.time());
|
|
87
|
+
spinner.info(msg);
|
|
88
|
+
return;
|
|
154
89
|
}
|
|
155
90
|
}
|
|
156
|
-
|
|
157
|
-
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
if (tpl) {
|
|
94
|
+
if (t == tpl.tags.think?.end) {
|
|
158
95
|
let msg = color.dim("Thinking:") + ` ${i} ${color.dim("tokens")}`;
|
|
159
96
|
msg = msg + " " + color.dim(perfTimer.time());
|
|
160
97
|
console.log(msg);
|
|
161
98
|
}
|
|
162
99
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
return;
|
|
100
|
+
}
|
|
101
|
+
if (hasTools && tpl) {
|
|
102
|
+
if (t == tpl.tags.toolCall?.start) {
|
|
103
|
+
continueWrite = false;
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
else if (t == tpl.tags.toolCall?.end) {
|
|
107
|
+
if (options?.verbose === true) {
|
|
108
|
+
skipNextEmptyLinesToken = true;
|
|
109
|
+
continueWrite = true;
|
|
174
110
|
}
|
|
111
|
+
return;
|
|
175
112
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
113
|
+
}
|
|
114
|
+
if (continueWrite) {
|
|
115
|
+
if (skipNextEmptyLinesToken) {
|
|
116
|
+
if (t == "\n\n") {
|
|
117
|
+
skipNextEmptyLinesToken = false;
|
|
118
|
+
return;
|
|
182
119
|
}
|
|
183
|
-
printToken(t);
|
|
184
120
|
}
|
|
185
|
-
|
|
186
|
-
}
|
|
187
|
-
|
|
121
|
+
printToken(t);
|
|
122
|
+
}
|
|
123
|
+
++i;
|
|
124
|
+
};
|
|
125
|
+
const spinnerInit = (name) => ora(`Executing ${name} tool ...`);
|
|
126
|
+
let tcspinner;
|
|
188
127
|
const onToolCall = (tc) => {
|
|
189
128
|
console.log("⚒️ ", color.bold(name), "=>", `${color.yellowBright(tc.name)}`, tc.arguments);
|
|
129
|
+
tcspinner = spinnerInit(tc.name);
|
|
130
|
+
tcspinner.start();
|
|
131
|
+
};
|
|
132
|
+
const onToolCallEnd = (tr) => {
|
|
133
|
+
tcspinner.stop();
|
|
190
134
|
};
|
|
191
135
|
if (options?.onToken) {
|
|
192
|
-
|
|
136
|
+
task.agent.lm.onToken = options.onToken;
|
|
193
137
|
}
|
|
194
138
|
else {
|
|
195
|
-
|
|
139
|
+
task.agent.lm.onToken = processToken;
|
|
196
140
|
}
|
|
141
|
+
if (!conf?.inferParams) {
|
|
142
|
+
conf.inferParams = {};
|
|
143
|
+
}
|
|
144
|
+
conf.inferParams.stream = true;
|
|
197
145
|
const tconf = {
|
|
198
|
-
expert: ex,
|
|
199
146
|
model: model,
|
|
200
|
-
debug: options
|
|
147
|
+
debug: options?.debug ?? false,
|
|
201
148
|
onToolCall: onToolCall,
|
|
149
|
+
onToolCallEnd: onToolCallEnd,
|
|
202
150
|
...conf,
|
|
203
151
|
};
|
|
204
|
-
tconf.expert = ex;
|
|
205
152
|
let out;
|
|
206
153
|
try {
|
|
207
154
|
out = await task.run({ prompt: payload.prompt, ...vars }, tconf);
|
|
@@ -227,12 +174,15 @@ async function executeTask(name, payload, options, quiet, expert) {
|
|
|
227
174
|
}
|
|
228
175
|
}
|
|
229
176
|
else {
|
|
230
|
-
await executeTask(name, { ...vars, prompt: prompt }, options, quiet
|
|
177
|
+
await executeTask(name, { ...vars, prompt: prompt }, options, quiet);
|
|
231
178
|
}
|
|
232
179
|
}
|
|
233
180
|
if (options?.debug === true || options?.verbose === true) {
|
|
234
181
|
try {
|
|
235
182
|
console.log("\n", formatStats(out.answer.stats));
|
|
183
|
+
if (options?.debug === true) {
|
|
184
|
+
console.log(out.answer.stats);
|
|
185
|
+
}
|
|
236
186
|
}
|
|
237
187
|
catch (e) {
|
|
238
188
|
runtimeWarning("Error formating stats:", `${e}`);
|
|
@@ -58,20 +58,25 @@ function configureTaskModel(itConf, taskSpec) {
|
|
|
58
58
|
const m = readModel(modelName);
|
|
59
59
|
if (m.found) {
|
|
60
60
|
model = m.modelData;
|
|
61
|
-
model.template = m.modelData.template;
|
|
61
|
+
model.template = templateName ?? m.modelData.template;
|
|
62
62
|
found = true;
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
if (!found) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
if (templateName && modelName) {
|
|
67
|
+
model = { name: modelName, template: templateName };
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
const gt = tfm.guess(modelName);
|
|
71
|
+
if (gt == "none") {
|
|
72
|
+
throw new Error(`Unable to guess the template for ${modelName}: please provide a template name: --tpl templatename`);
|
|
73
|
+
}
|
|
74
|
+
const m = {
|
|
75
|
+
name: modelName,
|
|
76
|
+
template: gt
|
|
77
|
+
};
|
|
78
|
+
model = m;
|
|
69
79
|
}
|
|
70
|
-
const m = {
|
|
71
|
-
name: modelName,
|
|
72
|
-
template: gt
|
|
73
|
-
};
|
|
74
|
-
model = m;
|
|
75
80
|
}
|
|
76
81
|
model.inferParams = ip;
|
|
77
82
|
if (!model?.ctx || !isModelFromTaskFile) {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Agent } from "@agent-smith/agent";
|
|
2
|
+
import { ModelSpec, Task, TaskConf } from "@agent-smith/task";
|
|
3
|
+
import { McpClient } from "../mcp.js";
|
|
4
|
+
declare function readTask(name: string, payload: Record<string, any>, options: Record<string, any>, agent: Agent): Promise<{
|
|
5
|
+
task: Task;
|
|
6
|
+
model: ModelSpec;
|
|
7
|
+
conf: TaskConf;
|
|
8
|
+
vars: Record<string, any>;
|
|
9
|
+
mcpServers: Array<McpClient>;
|
|
10
|
+
}>;
|
|
11
|
+
export { readTask };
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { Task } from "@agent-smith/task";
|
|
2
|
+
import { compile, serializeGrammar } from "@intrinsicai/gbnfgen";
|
|
3
|
+
import { readTool } from "../../../db/read.js";
|
|
4
|
+
import { executeAction } from "../actions/cmd.js";
|
|
5
|
+
import { McpClient } from "../mcp.js";
|
|
6
|
+
import { parseTaskConfigOptions } from "../options_parsers.js";
|
|
7
|
+
import { executeWorkflow } from "../workflows/cmd.js";
|
|
8
|
+
import { executeTask } from "./cmd.js";
|
|
9
|
+
import { configureTaskModel, mergeInferParams } from "./conf.js";
|
|
10
|
+
import { openTaskSpec } from "./utils.js";
|
|
11
|
+
async function readTask(name, payload, options, agent) {
|
|
12
|
+
if (options?.debug) {
|
|
13
|
+
console.log("Payload:", payload);
|
|
14
|
+
console.log("Task options:", options);
|
|
15
|
+
}
|
|
16
|
+
const taskFileSpec = openTaskSpec(name);
|
|
17
|
+
const opts = payload?.inferParams ? { ...options, ...payload.inferParams } : options;
|
|
18
|
+
const conf = parseTaskConfigOptions(opts);
|
|
19
|
+
if (options?.debug) {
|
|
20
|
+
console.log("conf:", conf);
|
|
21
|
+
}
|
|
22
|
+
conf.inferParams = mergeInferParams(conf.inferParams, taskFileSpec.inferParams ?? {});
|
|
23
|
+
const model = configureTaskModel(conf, taskFileSpec);
|
|
24
|
+
if (options?.ctx) {
|
|
25
|
+
model.ctx = options.ctx;
|
|
26
|
+
}
|
|
27
|
+
const taskSpec = taskFileSpec;
|
|
28
|
+
let vars = {};
|
|
29
|
+
if (taskSpec.variables?.optional) {
|
|
30
|
+
for (const k of Object.keys(taskSpec.variables.optional)) {
|
|
31
|
+
if (k in options) {
|
|
32
|
+
vars[k] = options[k];
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (taskSpec.variables?.required) {
|
|
37
|
+
for (const k of Object.keys(taskSpec.variables.required)) {
|
|
38
|
+
if (k in options) {
|
|
39
|
+
vars[k] = options[k];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const mcpServers = new Array();
|
|
44
|
+
if (!taskSpec?.tools) {
|
|
45
|
+
taskSpec.tools = [];
|
|
46
|
+
}
|
|
47
|
+
if (taskFileSpec?.mcp) {
|
|
48
|
+
for (const [servername, tool] of Object.entries(taskFileSpec.mcp)) {
|
|
49
|
+
const mcp = new McpClient(servername, tool.command, tool.args, tool?.tools ?? null);
|
|
50
|
+
mcpServers.push(mcp);
|
|
51
|
+
await mcp.start();
|
|
52
|
+
const tools = await mcp.extractTools();
|
|
53
|
+
tools.forEach(t => taskSpec.tools?.push(t));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (taskSpec.toolsList) {
|
|
57
|
+
for (const toolName of taskSpec.toolsList) {
|
|
58
|
+
const { found, tool, type } = readTool(toolName);
|
|
59
|
+
if (!found) {
|
|
60
|
+
throw new Error(`tool ${toolName} not found for task ${taskSpec.name}`);
|
|
61
|
+
}
|
|
62
|
+
const lmTool = {
|
|
63
|
+
...tool,
|
|
64
|
+
execute: async (params) => {
|
|
65
|
+
switch (type) {
|
|
66
|
+
case "action":
|
|
67
|
+
const res = await executeAction(toolName, params, options, true);
|
|
68
|
+
return res;
|
|
69
|
+
case "task":
|
|
70
|
+
conf.quiet = !options?.debug;
|
|
71
|
+
const tres = await executeTask(name, params, options, true);
|
|
72
|
+
return tres.answer.text;
|
|
73
|
+
case "workflow":
|
|
74
|
+
const wres = await executeWorkflow(toolName, params, options);
|
|
75
|
+
return wres;
|
|
76
|
+
default:
|
|
77
|
+
throw new Error(`unknown tool execution function type: ${type} for ${toolName}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
taskSpec.tools.push(lmTool);
|
|
82
|
+
}
|
|
83
|
+
delete taskSpec.toolsList;
|
|
84
|
+
}
|
|
85
|
+
;
|
|
86
|
+
const task = new Task(agent, taskSpec);
|
|
87
|
+
if (model?.inferParams?.tsGrammar) {
|
|
88
|
+
model.inferParams.grammar = serializeGrammar(await compile(model.inferParams.tsGrammar, "Grammar"));
|
|
89
|
+
delete model.inferParams.tsGrammar;
|
|
90
|
+
}
|
|
91
|
+
return { task, model, conf, vars, mcpServers };
|
|
92
|
+
}
|
|
93
|
+
export { readTask };
|
package/dist/cmd/lib/tools.js
CHANGED
|
@@ -42,7 +42,7 @@ function _extractYamlToolDoc(filePath, name) {
|
|
|
42
42
|
if (!found) {
|
|
43
43
|
return { found: false, tspec: {} };
|
|
44
44
|
}
|
|
45
|
-
if (!data
|
|
45
|
+
if (!data?.tool) {
|
|
46
46
|
return { found: false, tspec: {} };
|
|
47
47
|
}
|
|
48
48
|
data.tool.name = name;
|
|
@@ -78,7 +78,7 @@ function extractTaskToolDocAndVariables(name, ext, dirPath) {
|
|
|
78
78
|
if (!found) {
|
|
79
79
|
throw new Error(`extractTaskToolDocAndVariables: file ${fp} not found`);
|
|
80
80
|
}
|
|
81
|
-
if (data
|
|
81
|
+
if (data?.tool) {
|
|
82
82
|
data.tool.name = name;
|
|
83
83
|
tspec = data.tool;
|
|
84
84
|
res.toolDoc = JSON.stringify(tspec, null, " ");
|
package/dist/cmd/lib/utils.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { marked } from "../../agent.js";
|
|
2
1
|
import { formatMode, initFilepaths, outputMode, promptfilePath } from "../../state/state.js";
|
|
3
2
|
import { writeToClipboard } from "../sys/clipboard.js";
|
|
4
3
|
import { readFile } from "../sys/read.js";
|
|
5
4
|
import { splitThinking } from "../../utils/text.js";
|
|
6
5
|
import { runtimeError } from "./user_msgs.js";
|
|
6
|
+
import { marked } from 'marked';
|
|
7
|
+
import { markedTerminal } from "marked-terminal";
|
|
8
|
+
marked.use(markedTerminal());
|
|
7
9
|
function readPromptFile() {
|
|
8
10
|
initFilepaths();
|
|
9
11
|
return readFile(promptfilePath.value);
|
|
@@ -3,6 +3,7 @@ import { executeAdaptater } from "../adaptaters/cmd.js";
|
|
|
3
3
|
import { parseCommandArgs } from "../options_parsers.js";
|
|
4
4
|
import { executeTask } from "../tasks/cmd.js";
|
|
5
5
|
import { readWorkflow } from "./read.js";
|
|
6
|
+
import colors from "ansi-colors";
|
|
6
7
|
async function executeWorkflow(name, params, options) {
|
|
7
8
|
const { workflow, found } = await readWorkflow(name);
|
|
8
9
|
if (!found) {
|
|
@@ -15,11 +16,11 @@ async function executeWorkflow(name, params, options) {
|
|
|
15
16
|
console.log("Running workflow", name, stepNames.length, "steps");
|
|
16
17
|
}
|
|
17
18
|
let i = 0;
|
|
18
|
-
const finalTaskIndex = stepNames.length
|
|
19
|
+
const finalTaskIndex = stepNames.length - 1;
|
|
19
20
|
let taskRes = params;
|
|
20
21
|
for (const [name, step] of Object.entries(workflow)) {
|
|
21
22
|
if (isDebug || isVerbose) {
|
|
22
|
-
console.log(
|
|
23
|
+
console.log(i + 1, name, colors.dim(step.type));
|
|
23
24
|
}
|
|
24
25
|
switch (step.type) {
|
|
25
26
|
case "task":
|
|
@@ -35,7 +36,7 @@ async function executeWorkflow(name, params, options) {
|
|
|
35
36
|
try {
|
|
36
37
|
const ares = await executeAction(name, taskRes, options, true);
|
|
37
38
|
if (typeof ares == "string") {
|
|
38
|
-
taskRes = {
|
|
39
|
+
taskRes = { args: ares };
|
|
39
40
|
}
|
|
40
41
|
else {
|
|
41
42
|
taskRes = ares;
|
|
@@ -52,11 +53,14 @@ async function executeWorkflow(name, params, options) {
|
|
|
52
53
|
try {
|
|
53
54
|
const ares = await executeAdaptater(name, taskRes, options);
|
|
54
55
|
if (typeof ares == "string") {
|
|
55
|
-
taskRes = {
|
|
56
|
+
taskRes = { args: ares };
|
|
56
57
|
}
|
|
57
58
|
else {
|
|
58
59
|
taskRes = ares;
|
|
59
60
|
}
|
|
61
|
+
if (i == finalTaskIndex) {
|
|
62
|
+
console.log(taskRes);
|
|
63
|
+
}
|
|
60
64
|
}
|
|
61
65
|
catch (e) {
|
|
62
66
|
throw new Error(`workflow adaptater ${i + 1}: ${e}`);
|
|
@@ -72,7 +76,6 @@ async function executeWorkflow(name, params, options) {
|
|
|
72
76
|
}
|
|
73
77
|
async function executeWorkflowCmd(name, wargs) {
|
|
74
78
|
const { args, options } = parseCommandArgs(wargs);
|
|
75
|
-
|
|
76
|
-
return await executeWorkflow(name, params, options);
|
|
79
|
+
return await executeWorkflow(name, { args: args }, options);
|
|
77
80
|
}
|
|
78
81
|
export { executeWorkflow, executeWorkflowCmd, };
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { FeatureType } from '../../../interfaces.js';
|
|
1
|
+
import { WorkflowStep } from '../../../interfaces.js';
|
|
3
2
|
declare function readWorkflow(name: string): Promise<{
|
|
4
3
|
found: boolean;
|
|
5
|
-
workflow: Record<string,
|
|
4
|
+
workflow: Record<string, WorkflowStep>;
|
|
6
5
|
}>;
|
|
7
|
-
export { readWorkflow
|
|
6
|
+
export { readWorkflow };
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Agent } from '@agent-smith/agent';
|
|
2
|
+
import { Task } from '@agent-smith/task';
|
|
2
3
|
import { default as fs } from "fs";
|
|
3
|
-
import
|
|
4
|
+
import YAML from 'yaml';
|
|
5
|
+
import { backend } from '../../../state/backends.js';
|
|
4
6
|
import { getFeatureSpec } from '../../../state/features.js';
|
|
5
7
|
import { readTask } from "../../sys/read_task.js";
|
|
6
8
|
import { pythonAction, systemAction } from '../actions/cmd.js';
|
|
@@ -26,24 +28,36 @@ async function _createWorkflowFromSpec(spec) {
|
|
|
26
28
|
case "js":
|
|
27
29
|
const { action } = await import(path);
|
|
28
30
|
const at = action;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
const wf = {
|
|
32
|
+
type: "action",
|
|
33
|
+
run: at,
|
|
34
|
+
};
|
|
35
|
+
steps[name] = wf;
|
|
31
36
|
break;
|
|
32
37
|
case "mjs":
|
|
33
38
|
const mjsa = await import(path);
|
|
34
39
|
const act = createJsAction(mjsa.action);
|
|
35
|
-
|
|
36
|
-
|
|
40
|
+
const wf2 = {
|
|
41
|
+
type: "action",
|
|
42
|
+
run: act,
|
|
43
|
+
};
|
|
44
|
+
steps[name] = wf2;
|
|
37
45
|
break;
|
|
38
46
|
case "yml":
|
|
39
47
|
const _t1 = systemAction(path);
|
|
40
|
-
|
|
41
|
-
|
|
48
|
+
const wf3 = {
|
|
49
|
+
type: "action",
|
|
50
|
+
run: _t1,
|
|
51
|
+
};
|
|
52
|
+
steps[name] = wf3;
|
|
42
53
|
break;
|
|
43
54
|
case "py":
|
|
44
55
|
const _t = pythonAction(path);
|
|
45
|
-
|
|
46
|
-
|
|
56
|
+
const wf4 = {
|
|
57
|
+
type: "action",
|
|
58
|
+
run: _t,
|
|
59
|
+
};
|
|
60
|
+
steps[name] = wf4;
|
|
47
61
|
break;
|
|
48
62
|
default:
|
|
49
63
|
throw new Error(`Unknown feature extension ${ext}`);
|
|
@@ -56,8 +70,11 @@ async function _createWorkflowFromSpec(spec) {
|
|
|
56
70
|
}
|
|
57
71
|
const jsa = await import(path);
|
|
58
72
|
const act = createJsAction(jsa.action);
|
|
59
|
-
|
|
60
|
-
|
|
73
|
+
const wf = {
|
|
74
|
+
type: "adaptater",
|
|
75
|
+
run: act,
|
|
76
|
+
};
|
|
77
|
+
steps[name] = wf;
|
|
61
78
|
}
|
|
62
79
|
else {
|
|
63
80
|
const { found, path } = getFeatureSpec(name, "task");
|
|
@@ -68,8 +85,13 @@ async function _createWorkflowFromSpec(spec) {
|
|
|
68
85
|
if (!res.found) {
|
|
69
86
|
throw new Error(`Unable to read task ${name} ${path}`);
|
|
70
87
|
}
|
|
71
|
-
const
|
|
72
|
-
|
|
88
|
+
const agent = new Agent(backend.value);
|
|
89
|
+
const tsk = Task.fromYaml(agent, res.ymlTask);
|
|
90
|
+
const wf = {
|
|
91
|
+
type: "task",
|
|
92
|
+
run: tsk.run,
|
|
93
|
+
};
|
|
94
|
+
steps[name] = wf;
|
|
73
95
|
}
|
|
74
96
|
}
|
|
75
97
|
return steps;
|
|
@@ -112,4 +134,4 @@ async function readWorkflow(name) {
|
|
|
112
134
|
}
|
|
113
135
|
return { found: true, workflow: wf };
|
|
114
136
|
}
|
|
115
|
-
export { readWorkflow
|
|
137
|
+
export { readWorkflow };
|