@saltcorn/agents 0.3.0 → 0.3.1
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/agent-view.js +61 -45
- package/common.js +56 -7
- package/package.json +1 -1
- package/skills/GenerateImage.js +98 -0
- package/skills/PreloadData.js +0 -1
package/agent-view.js
CHANGED
|
@@ -39,6 +39,7 @@ const {
|
|
|
39
39
|
wrapCard,
|
|
40
40
|
wrapSegment,
|
|
41
41
|
process_interaction,
|
|
42
|
+
find_image_tool,
|
|
42
43
|
} = require("./common");
|
|
43
44
|
const MarkdownIt = require("markdown-it"),
|
|
44
45
|
md = new MarkdownIt();
|
|
@@ -157,7 +158,6 @@ const run = async (
|
|
|
157
158
|
for (const interact of run.context.interactions) {
|
|
158
159
|
switch (interact.role) {
|
|
159
160
|
case "user":
|
|
160
|
-
console.log(interact.content);
|
|
161
161
|
if (interact.content?.[0]?.type === "image_url") {
|
|
162
162
|
const image_url = interact.content[0].image_url.url;
|
|
163
163
|
if (image_url.startsWith("data"))
|
|
@@ -187,58 +187,74 @@ const run = async (
|
|
|
187
187
|
break;
|
|
188
188
|
case "assistant":
|
|
189
189
|
case "system":
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
190
|
+
|
|
191
|
+
for (const tool_call of interact.tool_calls || []) {
|
|
192
|
+
const toolSkill = find_tool(
|
|
193
|
+
tool_call.function.name,
|
|
194
|
+
action.configuration
|
|
195
|
+
);
|
|
196
|
+
if (toolSkill) {
|
|
197
|
+
const row = JSON.parse(tool_call.function.arguments);
|
|
198
|
+
if (toolSkill.tool.renderToolCall) {
|
|
199
|
+
const rendered = await toolSkill.tool.renderToolCall(row, {
|
|
200
|
+
req,
|
|
201
|
+
});
|
|
202
|
+
if (rendered)
|
|
203
|
+
interactMarkups.push(
|
|
204
|
+
wrapSegment(
|
|
205
|
+
wrapCard(
|
|
206
|
+
toolSkill.skill.skill_label ||
|
|
207
|
+
toolSkill.skill.constructor.skill_name,
|
|
208
|
+
rendered
|
|
209
|
+
),
|
|
210
|
+
action.name
|
|
211
|
+
)
|
|
212
|
+
);
|
|
213
|
+
}
|
|
201
214
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
if (toolSkill) {
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
|
|
215
|
+
}
|
|
216
|
+
for (const image_call of interact.content?.image_calls || []) {
|
|
217
|
+
|
|
218
|
+
const toolSkill = find_image_tool(action.configuration);
|
|
219
|
+
if (toolSkill) {
|
|
220
|
+
if (toolSkill.tool.renderToolResponse) {
|
|
221
|
+
const rendered = await toolSkill.tool.renderToolResponse(
|
|
222
|
+
image_call,
|
|
223
|
+
{
|
|
211
224
|
req,
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
)
|
|
223
|
-
|
|
224
|
-
|
|
225
|
+
}
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
if (rendered)
|
|
229
|
+
interactMarkups.push(
|
|
230
|
+
wrapSegment(
|
|
231
|
+
wrapCard(
|
|
232
|
+
toolSkill.skill.skill_label ||
|
|
233
|
+
toolSkill.skill.constructor.skill_name,
|
|
234
|
+
rendered
|
|
235
|
+
),
|
|
236
|
+
action.name
|
|
237
|
+
)
|
|
238
|
+
);
|
|
225
239
|
}
|
|
226
240
|
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
interactMarkups.push(
|
|
244
|
+
div(
|
|
245
|
+
{ class: "interaction-segment" },
|
|
246
|
+
span({ class: "badge bg-secondary" }, action.name),
|
|
247
|
+
typeof interact.content === "string"
|
|
248
|
+
? md.render(interact.content)
|
|
249
|
+
: typeof interact.content?.content === "string"
|
|
250
|
+
? md.render(interact.content.content)
|
|
251
|
+
: interact.content
|
|
252
|
+
)
|
|
253
|
+
);
|
|
237
254
|
break;
|
|
238
255
|
case "tool":
|
|
239
256
|
if (interact.content !== "Action run") {
|
|
240
257
|
let markupContent;
|
|
241
|
-
console.log("interact", interact);
|
|
242
258
|
const toolSkill = find_tool(interact.name, action.configuration);
|
|
243
259
|
try {
|
|
244
260
|
if (toolSkill?.tool?.renderToolResponse)
|
package/common.js
CHANGED
|
@@ -12,6 +12,7 @@ const get_skills = () => {
|
|
|
12
12
|
require("./skills/Trigger"),
|
|
13
13
|
require("./skills/Table"),
|
|
14
14
|
require("./skills/PreloadData"),
|
|
15
|
+
require("./skills/GenerateImage"),
|
|
15
16
|
//require("./skills/AdaptiveFeedback"),
|
|
16
17
|
];
|
|
17
18
|
};
|
|
@@ -34,7 +35,7 @@ const get_skill_instances = (config) => {
|
|
|
34
35
|
const find_tool = (name, config) => {
|
|
35
36
|
const skills = get_skill_instances(config);
|
|
36
37
|
for (const skill of skills) {
|
|
37
|
-
const skillTools = skill.provideTools();
|
|
38
|
+
const skillTools = skill.provideTools?.();
|
|
38
39
|
const tools = !skillTools
|
|
39
40
|
? []
|
|
40
41
|
: Array.isArray(skillTools)
|
|
@@ -45,6 +46,20 @@ const find_tool = (name, config) => {
|
|
|
45
46
|
}
|
|
46
47
|
};
|
|
47
48
|
|
|
49
|
+
const find_image_tool = (config) => {
|
|
50
|
+
const skills = get_skill_instances(config);
|
|
51
|
+
for (const skill of skills) {
|
|
52
|
+
const skillTools = skill.provideTools?.();
|
|
53
|
+
const tools = !skillTools
|
|
54
|
+
? []
|
|
55
|
+
: Array.isArray(skillTools)
|
|
56
|
+
? skillTools
|
|
57
|
+
: [skillTools];
|
|
58
|
+
const found = tools.find((t) => t?.type === "image_generation");
|
|
59
|
+
if (found) return { tool: found, skill };
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
48
63
|
const getCompletionArguments = async (config, user) => {
|
|
49
64
|
let tools = [];
|
|
50
65
|
|
|
@@ -52,7 +67,7 @@ const getCompletionArguments = async (config, user) => {
|
|
|
52
67
|
|
|
53
68
|
const skills = get_skill_instances(config);
|
|
54
69
|
for (const skill of skills) {
|
|
55
|
-
const sysPr = await skill.systemPrompt({ user });
|
|
70
|
+
const sysPr = await skill.systemPrompt?.({ user });
|
|
56
71
|
if (sysPr) sysPrompts.push(sysPr);
|
|
57
72
|
const skillTools = skill.provideTools?.();
|
|
58
73
|
if (skillTools && Array.isArray(skillTools)) tools.push(...skillTools);
|
|
@@ -133,10 +148,43 @@ const process_interaction = async (
|
|
|
133
148
|
const complArgs = await getCompletionArguments(config, req.user);
|
|
134
149
|
complArgs.chat = run.context.interactions;
|
|
135
150
|
//complArgs.debugResult = true;
|
|
136
|
-
console.log("complArgs", JSON.stringify(complArgs, null, 2));
|
|
151
|
+
//console.log("complArgs", JSON.stringify(complArgs, null, 2));
|
|
137
152
|
|
|
138
153
|
const answer = await getState().functions.llm_generate.run("", complArgs);
|
|
139
|
-
console.log("answer", answer);
|
|
154
|
+
//console.log("answer", answer);
|
|
155
|
+
|
|
156
|
+
const responses = [];
|
|
157
|
+
if (typeof answer === "object" && answer.image_calls) {
|
|
158
|
+
for (const image_call of answer.image_calls) {
|
|
159
|
+
const tool = find_image_tool(config);
|
|
160
|
+
let prcRes;
|
|
161
|
+
if (tool?.tool.process) {
|
|
162
|
+
prcRes = await tool.tool.process(image_call, { req });
|
|
163
|
+
if (prcRes?.result === null) delete image_call.result;
|
|
164
|
+
if (prcRes?.filename) image_call.filename = prcRes?.filename;
|
|
165
|
+
}
|
|
166
|
+
if (tool?.tool.renderToolResponse) {
|
|
167
|
+
const rendered = await tool.tool.renderToolResponse(
|
|
168
|
+
{ ...image_call, ...(prcRes || {}) },
|
|
169
|
+
{
|
|
170
|
+
req,
|
|
171
|
+
}
|
|
172
|
+
);
|
|
173
|
+
if (rendered)
|
|
174
|
+
responses.push(
|
|
175
|
+
wrapSegment(
|
|
176
|
+
wrapCard(
|
|
177
|
+
tool.skill.skill_label || tool.skill.constructor.skill_name,
|
|
178
|
+
rendered
|
|
179
|
+
),
|
|
180
|
+
agent_label
|
|
181
|
+
)
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (answer.content && !answer.tool_calls)
|
|
186
|
+
responses.push(wrapSegment(md.render(answer.content), agent_label));
|
|
187
|
+
}
|
|
140
188
|
await addToContext(run, {
|
|
141
189
|
interactions:
|
|
142
190
|
typeof answer === "object" && answer.tool_calls
|
|
@@ -149,8 +197,6 @@ const process_interaction = async (
|
|
|
149
197
|
]
|
|
150
198
|
: [{ role: "assistant", content: answer }],
|
|
151
199
|
});
|
|
152
|
-
const responses = [];
|
|
153
|
-
|
|
154
200
|
if (typeof answer === "object" && answer.tool_calls) {
|
|
155
201
|
if (answer.content)
|
|
156
202
|
responses.push(wrapSegment(md.render(answer.content), agent_label));
|
|
@@ -213,6 +259,7 @@ const process_interaction = async (
|
|
|
213
259
|
{
|
|
214
260
|
role: "tool",
|
|
215
261
|
tool_call_id: tool_call.id,
|
|
262
|
+
call_id: tool_call.call_id,
|
|
216
263
|
name: tool_call.function.name,
|
|
217
264
|
content:
|
|
218
265
|
result && typeof result !== "string"
|
|
@@ -228,7 +275,8 @@ const process_interaction = async (
|
|
|
228
275
|
...prevResponses,
|
|
229
276
|
...responses,
|
|
230
277
|
]);
|
|
231
|
-
} else
|
|
278
|
+
} else if (typeof answer === "string")
|
|
279
|
+
responses.push(wrapSegment(md.render(answer), agent_label));
|
|
232
280
|
|
|
233
281
|
return {
|
|
234
282
|
json: {
|
|
@@ -251,4 +299,5 @@ module.exports = {
|
|
|
251
299
|
wrapCard,
|
|
252
300
|
wrapSegment,
|
|
253
301
|
process_interaction,
|
|
302
|
+
find_image_tool,
|
|
254
303
|
};
|
package/package.json
CHANGED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
const { div, pre } = require("@saltcorn/markup/tags");
|
|
2
|
+
const Workflow = require("@saltcorn/data/models/workflow");
|
|
3
|
+
const Form = require("@saltcorn/data/models/form");
|
|
4
|
+
const Table = require("@saltcorn/data/models/table");
|
|
5
|
+
const File = require("@saltcorn/data/models/file");
|
|
6
|
+
const View = require("@saltcorn/data/models/view");
|
|
7
|
+
const { getState } = require("@saltcorn/data/db/state");
|
|
8
|
+
const db = require("@saltcorn/data/db");
|
|
9
|
+
const { eval_expression } = require("@saltcorn/data/models/expression");
|
|
10
|
+
const { interpolate } = require("@saltcorn/data/utils");
|
|
11
|
+
|
|
12
|
+
class GenerateImage {
|
|
13
|
+
static skill_name = "Image generation";
|
|
14
|
+
|
|
15
|
+
get skill_label() {
|
|
16
|
+
return `Image generation`;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
constructor(cfg) {
|
|
20
|
+
Object.assign(this, cfg);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
static async configFields() {
|
|
24
|
+
return [
|
|
25
|
+
{
|
|
26
|
+
name: "quality",
|
|
27
|
+
label: "Quality",
|
|
28
|
+
type: "String",
|
|
29
|
+
required: true,
|
|
30
|
+
attributes: { options: ["auto", "low", "medium", "high"] },
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: "size",
|
|
34
|
+
label: "Size",
|
|
35
|
+
type: "String",
|
|
36
|
+
required: true,
|
|
37
|
+
attributes: {
|
|
38
|
+
options: ["auto", "1024x1024", "1536x1024", "1024x1536"],
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: "format",
|
|
43
|
+
label: "Format",
|
|
44
|
+
type: "String",
|
|
45
|
+
required: true,
|
|
46
|
+
attributes: { options: ["png", "jpeg", "webp"] },
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: "transparent",
|
|
50
|
+
label: "Transparent",
|
|
51
|
+
type: "Bool",
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: "save_file",
|
|
55
|
+
label: "Save file",
|
|
56
|
+
type: "String",
|
|
57
|
+
required: true,
|
|
58
|
+
attributes: { options: ["Always", "Never"] }, //, "Button"] },
|
|
59
|
+
},
|
|
60
|
+
];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
provideTools() {
|
|
64
|
+
const tool = {
|
|
65
|
+
type: "image_generation",
|
|
66
|
+
size: this.size,
|
|
67
|
+
quality: this.quality,
|
|
68
|
+
process: async (v, { req }) => {
|
|
69
|
+
if (this.save_file === "Always") {
|
|
70
|
+
const buf = Buffer.from(v.result, "base64");
|
|
71
|
+
const file = await File.from_contents(
|
|
72
|
+
`genimg.${v.output_format}`,
|
|
73
|
+
`image/${v.output_format}`,
|
|
74
|
+
buf,
|
|
75
|
+
req?.user?.id,
|
|
76
|
+
100
|
|
77
|
+
);
|
|
78
|
+
return { filename: file.path_to_serve, result: null };
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
renderToolResponse: (v) => {
|
|
82
|
+
const [ws, hs] = v.size.split("x");
|
|
83
|
+
if (v.filename)
|
|
84
|
+
return `<img height="${+hs / 4}" width="${
|
|
85
|
+
+ws / 4
|
|
86
|
+
}" src="/files/serve/${v.filename}" />`;
|
|
87
|
+
else
|
|
88
|
+
return `<img height="${+hs / 4}" width="${+ws / 4}" src="data:image/${
|
|
89
|
+
v.output_format
|
|
90
|
+
};base64, ${v.result}" />`;
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
if (this.transparent) tool.background = "transparent";
|
|
94
|
+
return tool;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
module.exports = GenerateImage;
|
package/skills/PreloadData.js
CHANGED