@saltcorn/agents 0.7.3 → 0.7.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/action.js +4 -0
- package/common.js +23 -6
- package/package.json +1 -1
- package/skills/GenerateAndRunJsCode.js +51 -18
- package/skills/ModelPicker.js +3 -2
- package/skills/Subagent.js +28 -4
- package/tests/action.test.js +2 -2
package/action.js
CHANGED
|
@@ -89,6 +89,7 @@ module.exports = {
|
|
|
89
89
|
trigger_id,
|
|
90
90
|
run_id,
|
|
91
91
|
req,
|
|
92
|
+
is_sub_agent,
|
|
92
93
|
...rest
|
|
93
94
|
}) => {
|
|
94
95
|
const userinput = interpolate(configuration.prompt, row, user);
|
|
@@ -114,6 +115,9 @@ module.exports = {
|
|
|
114
115
|
undefined,
|
|
115
116
|
[],
|
|
116
117
|
row,
|
|
118
|
+
{ stream: false },
|
|
119
|
+
false,
|
|
120
|
+
is_sub_agent
|
|
117
121
|
);
|
|
118
122
|
},
|
|
119
123
|
};
|
package/common.js
CHANGED
|
@@ -239,6 +239,7 @@ const process_interaction = async (
|
|
|
239
239
|
triggering_row = {},
|
|
240
240
|
agentsViewCfg = { stream: false },
|
|
241
241
|
dyn_updates = false,
|
|
242
|
+
is_sub_agent = false,
|
|
242
243
|
) => {
|
|
243
244
|
const { stream, viewname, layout } = agentsViewCfg;
|
|
244
245
|
const sysState = getState();
|
|
@@ -276,7 +277,9 @@ const process_interaction = async (
|
|
|
276
277
|
run.context.interactions[run.context.interactions.length - 1];
|
|
277
278
|
|
|
278
279
|
const answer = await sysState.functions.llm_generate.run(
|
|
279
|
-
lastInteract?.role === "user"
|
|
280
|
+
lastInteract?.role === "user" || lastInteract?.role === "tool"
|
|
281
|
+
? ""
|
|
282
|
+
: "Continue",
|
|
280
283
|
complArgs,
|
|
281
284
|
);
|
|
282
285
|
|
|
@@ -290,6 +293,7 @@ const process_interaction = async (
|
|
|
290
293
|
interactions: complArgs.chat,
|
|
291
294
|
});
|
|
292
295
|
const responses = [];
|
|
296
|
+
const raw_responses = [];
|
|
293
297
|
|
|
294
298
|
const add_response = async (resp, not_final) => {
|
|
295
299
|
if (dyn_updates)
|
|
@@ -457,7 +461,7 @@ const process_interaction = async (
|
|
|
457
461
|
interactions: run.context.interactions,
|
|
458
462
|
});
|
|
459
463
|
|
|
460
|
-
if (myHasResult && !stop) hasResult = true;
|
|
464
|
+
if (myHasResult && !stop && !tool.tool.postProcess) hasResult = true;
|
|
461
465
|
}
|
|
462
466
|
}
|
|
463
467
|
|
|
@@ -520,10 +524,15 @@ const process_interaction = async (
|
|
|
520
524
|
],
|
|
521
525
|
});
|
|
522
526
|
if (postprocres.add_response) {
|
|
527
|
+
if (!postprocres.add_responses)
|
|
528
|
+
postprocres.add_responses = [postprocres.add_response];
|
|
529
|
+
else postprocres.add_responses.push(postprocres.add_response);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
for (const add_resp of postprocres.add_responses || []) {
|
|
533
|
+
raw_responses.push(add_resp);
|
|
523
534
|
const renderedAddResponse =
|
|
524
|
-
typeof
|
|
525
|
-
? md.render(postprocres.add_response)
|
|
526
|
-
: postprocres.add_response;
|
|
535
|
+
typeof add_resp === "string" ? md.render(add_resp) : add_resp;
|
|
527
536
|
add_response(
|
|
528
537
|
wrapSegment(
|
|
529
538
|
wrapCard(
|
|
@@ -537,7 +546,7 @@ const process_interaction = async (
|
|
|
537
546
|
);
|
|
538
547
|
//replace tool response with this
|
|
539
548
|
// run.context.interactions.forEach((ic) => {});
|
|
540
|
-
const result =
|
|
549
|
+
const result = add_resp;
|
|
541
550
|
await sysState.functions.llm_add_message.run(
|
|
542
551
|
"assistant",
|
|
543
552
|
!result || typeof result === "string"
|
|
@@ -605,6 +614,7 @@ const process_interaction = async (
|
|
|
605
614
|
triggering_row,
|
|
606
615
|
agentsViewCfg,
|
|
607
616
|
dyn_updates,
|
|
617
|
+
is_sub_agent,
|
|
608
618
|
);
|
|
609
619
|
} else if (typeof answer === "string")
|
|
610
620
|
add_response(
|
|
@@ -625,15 +635,22 @@ const process_interaction = async (
|
|
|
625
635
|
return {
|
|
626
636
|
json: {
|
|
627
637
|
success: "ok",
|
|
638
|
+
...(is_sub_agent ? { raw_responses } : {}),
|
|
628
639
|
response: [...prevResponses, ...responses].join(""),
|
|
629
640
|
run_id: run?.id,
|
|
630
641
|
},
|
|
631
642
|
};
|
|
632
643
|
};
|
|
633
644
|
|
|
645
|
+
const replaceUserContinue = (chat, newPrompt) => {
|
|
646
|
+
const lastChat = chat[chat.length - 1];
|
|
647
|
+
console.log("lastChat", lastChat);
|
|
648
|
+
};
|
|
649
|
+
|
|
634
650
|
module.exports = {
|
|
635
651
|
get_skills,
|
|
636
652
|
get_skill_class,
|
|
653
|
+
replaceUserContinue,
|
|
637
654
|
incompleteCfgMsg,
|
|
638
655
|
find_tool,
|
|
639
656
|
get_skill_instances,
|
package/package.json
CHANGED
|
@@ -16,6 +16,7 @@ const { button } = require("@saltcorn/markup/tags");
|
|
|
16
16
|
const { validID } = require("@saltcorn/markup/layout_utils");
|
|
17
17
|
|
|
18
18
|
const vm = require("vm");
|
|
19
|
+
const { replaceUserContinue } = require("../common");
|
|
19
20
|
|
|
20
21
|
//const { fieldProperties } = require("./helpers");
|
|
21
22
|
|
|
@@ -100,7 +101,8 @@ class GenerateAndRunJsCodeSkill {
|
|
|
100
101
|
},
|
|
101
102
|
{
|
|
102
103
|
name: "allow_functions",
|
|
103
|
-
label: "Allow
|
|
104
|
+
label: "Allow system functions",
|
|
105
|
+
sublabel: "Allow calls to functions from codepages and modules",
|
|
104
106
|
type: "Bool",
|
|
105
107
|
},
|
|
106
108
|
...(Table.subClass
|
|
@@ -131,12 +133,14 @@ class GenerateAndRunJsCodeSkill {
|
|
|
131
133
|
req,
|
|
132
134
|
generate,
|
|
133
135
|
emit_update,
|
|
136
|
+
chat,
|
|
134
137
|
...rest
|
|
135
138
|
}) => {
|
|
136
139
|
//console.log("postprocess args", { tool_call, ...rest });
|
|
137
140
|
emit_update("Generating code");
|
|
138
|
-
const
|
|
139
|
-
|
|
141
|
+
const gen_the_code = async (extra) => {
|
|
142
|
+
const str = await generate(
|
|
143
|
+
`You will now be asked to write JavaScript code.
|
|
140
144
|
${this.code_description ? "\nSome more information: " + this.code_description : ""}
|
|
141
145
|
${this.allow_fetch ? "\nYou can use the standard fetch JavaScript function to make HTTP(S) requests." : ""}
|
|
142
146
|
${this.allow_table ? getTablePrompt(this.read_only) : ""}
|
|
@@ -165,24 +169,53 @@ const y = await anotherAsyncFunction(x)
|
|
|
165
169
|
return { x, y }
|
|
166
170
|
\`\`\`
|
|
167
171
|
|
|
172
|
+
${extra || ""}
|
|
168
173
|
|
|
169
174
|
Now generate the JavaScript code required by the user.`,
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
const res = await this.runCode(js_code, { user: req.user });
|
|
180
|
-
//console.log("code response", res);
|
|
181
|
-
getState().log(6, "Code answer: " + JSON.stringify(res));
|
|
182
|
-
return {
|
|
183
|
-
stop: typeof res ==="string",
|
|
184
|
-
add_response: res,
|
|
175
|
+
);
|
|
176
|
+
getState().log(
|
|
177
|
+
6,
|
|
178
|
+
"Generated code:\n--BEGIN CODE--\n" + str + "\n--END CODE--\n",
|
|
179
|
+
);
|
|
180
|
+
const js_code = str.includes("```javascript")
|
|
181
|
+
? str.split("```javascript")[1].split("```")[0]
|
|
182
|
+
: str;
|
|
183
|
+
return js_code;
|
|
185
184
|
};
|
|
185
|
+
const js_code = await gen_the_code();
|
|
186
|
+
emit_update("Running code");
|
|
187
|
+
try {
|
|
188
|
+
const res = await this.runCode(js_code, { user: req.user });
|
|
189
|
+
//console.log("code response", res);
|
|
190
|
+
getState().log(6, "Code answer: " + JSON.stringify(res));
|
|
191
|
+
return {
|
|
192
|
+
stop: typeof res === "string",
|
|
193
|
+
add_response: res,
|
|
194
|
+
};
|
|
195
|
+
} catch (err) {
|
|
196
|
+
console.error(err);
|
|
197
|
+
const retry_js_code =
|
|
198
|
+
await gen_the_code(`You were previously asked to complete this task. This was the code generated:
|
|
199
|
+
\`\`\`javascript
|
|
200
|
+
${js_code}
|
|
201
|
+
\`\`\`
|
|
202
|
+
|
|
203
|
+
this code produced the following error:
|
|
204
|
+
|
|
205
|
+
\`\`\`
|
|
206
|
+
${err.message}
|
|
207
|
+
\`\`\`
|
|
208
|
+
|
|
209
|
+
Correct this error.
|
|
210
|
+
`);
|
|
211
|
+
const res = await this.runCode(retry_js_code, { user: req.user });
|
|
212
|
+
//console.log("code response", res);
|
|
213
|
+
getState().log(6, "Code retry answer: " + JSON.stringify(res));
|
|
214
|
+
return {
|
|
215
|
+
stop: typeof res === "string",
|
|
216
|
+
add_response: res,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
186
219
|
},
|
|
187
220
|
function: {
|
|
188
221
|
name: this.tool_name,
|
package/skills/ModelPicker.js
CHANGED
|
@@ -34,8 +34,9 @@ class ModelPicker {
|
|
|
34
34
|
class: ["form-select form-select-sm w-unset", klass],
|
|
35
35
|
name: "modelpicker",
|
|
36
36
|
},
|
|
37
|
-
this.placeholder &&
|
|
38
|
-
|
|
37
|
+
this.placeholder &&
|
|
38
|
+
option({ disabled: true }, this.placeholder || "Select model"),
|
|
39
|
+
option({ value: "" }, this.default_label || "Standard"),
|
|
39
40
|
alt_config_options.map((o) => option(o)),
|
|
40
41
|
);
|
|
41
42
|
}
|
package/skills/Subagent.js
CHANGED
|
@@ -8,6 +8,7 @@ const { getState } = require("@saltcorn/data/db/state");
|
|
|
8
8
|
const db = require("@saltcorn/data/db");
|
|
9
9
|
const { fieldProperties } = require("./helpers");
|
|
10
10
|
const agent_action = require("../action");
|
|
11
|
+
const { replaceUserContinue } = require("../common");
|
|
11
12
|
|
|
12
13
|
class SubagentToSkill {
|
|
13
14
|
static skill_name = "Subagent";
|
|
@@ -45,7 +46,12 @@ class SubagentToSkill {
|
|
|
45
46
|
required: true,
|
|
46
47
|
attributes: { options: actions.map((a) => a.name) },
|
|
47
48
|
},
|
|
48
|
-
|
|
49
|
+
{
|
|
50
|
+
name: "handover_prompt",
|
|
51
|
+
label: "Handover prompt",
|
|
52
|
+
sublabel: `Optional. The prompt initialising the subagent. Example: "Continue answering my query using the tool now at you disposal"`,
|
|
53
|
+
type: "String",
|
|
54
|
+
},
|
|
49
55
|
];
|
|
50
56
|
}
|
|
51
57
|
|
|
@@ -65,14 +71,32 @@ class SubagentToSkill {
|
|
|
65
71
|
/*renderToolCall({ phrase }, { req }) {
|
|
66
72
|
return div({ class: "border border-primary p-2 m-2" }, phrase);
|
|
67
73
|
},*/
|
|
68
|
-
postProcess: async ({
|
|
69
|
-
|
|
74
|
+
postProcess: async ({
|
|
75
|
+
tool_call,
|
|
76
|
+
req,
|
|
77
|
+
generate,
|
|
78
|
+
emit_update,
|
|
79
|
+
run,
|
|
80
|
+
chat,
|
|
81
|
+
}) => {
|
|
82
|
+
getState().log(6, "Running subagent", this.agent_name);
|
|
83
|
+
const subres = await agent_action.run({
|
|
70
84
|
row: {},
|
|
71
|
-
configuration: {
|
|
85
|
+
configuration: {
|
|
86
|
+
...trigger.configuration,
|
|
87
|
+
prompt:
|
|
88
|
+
this.handover_prompt ||
|
|
89
|
+
"Your instructions and tools have changed. Continue answering my query using the instructions and tools at you disposal, if any",
|
|
90
|
+
},
|
|
72
91
|
user: req.user,
|
|
73
92
|
run_id: run.id,
|
|
93
|
+
is_sub_agent: true,
|
|
74
94
|
req,
|
|
75
95
|
});
|
|
96
|
+
getState().log(6, "Subagent response", subres.json.raw_responses);
|
|
97
|
+
|
|
98
|
+
if (subres.json.raw_responses)
|
|
99
|
+
return { add_responses: subres.json.raw_responses };
|
|
76
100
|
return {
|
|
77
101
|
//stop: true,
|
|
78
102
|
//add_response: result,
|
package/tests/action.test.js
CHANGED
|
@@ -41,7 +41,7 @@ beforeAll(async () => {
|
|
|
41
41
|
//await getState().setConfig("log_level", 6);
|
|
42
42
|
});
|
|
43
43
|
|
|
44
|
-
jest.setTimeout(
|
|
44
|
+
jest.setTimeout(40000);
|
|
45
45
|
|
|
46
46
|
const user = { id: 1, role_id: 1 };
|
|
47
47
|
const action = require("../action");
|
|
@@ -128,7 +128,7 @@ for (const nameconfig of require("./configs")) {
|
|
|
128
128
|
const result = await action.run({
|
|
129
129
|
row: {
|
|
130
130
|
theprompt:
|
|
131
|
-
"What is the 16th Fibonacci number (when F1=1 and F2=1)? Consult both the math agent and the oracle and see if they agree",
|
|
131
|
+
"What is the 16th Fibonacci number (when F1=1 and F2=1)? Consult both the math agent and the oracle and see if they agree. Call both the OracleAgent and the MathsAgent tools",
|
|
132
132
|
},
|
|
133
133
|
configuration,
|
|
134
134
|
user,
|