@saltcorn/agents 0.5.8 → 0.6.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/action.js +109 -0
- package/agent-view.js +296 -239
- package/common.js +195 -164
- package/index.js +8 -90
- package/package.json +9 -2
- package/public/jquery.autogrow-textarea.js +205 -0
- package/skills/EmbeddingRetrieval.js +2 -0
- package/skills/FTSRetrieval.js +1 -0
- package/skills/PreloadData.js +7 -2
- package/skills/Table.js +1 -0
- package/skills/Trigger.js +2 -0
- package/tests/action.test.js +80 -0
- package/tests/agentcfg.js +46 -0
- package/tests/configs.js +34 -0
- package/tests/view.test.js +89 -0
package/common.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const { getState } = require("@saltcorn/data/db/state");
|
|
2
|
-
const { div, span } = require("@saltcorn/markup/tags");
|
|
2
|
+
const { div, span, button } = require("@saltcorn/markup/tags");
|
|
3
3
|
const Trigger = require("@saltcorn/data/models/trigger");
|
|
4
4
|
const View = require("@saltcorn/data/models/view");
|
|
5
5
|
const { interpolate } = require("@saltcorn/data/utils");
|
|
@@ -21,8 +21,8 @@ const nubBy = (f, xs) => {
|
|
|
21
21
|
const get_skills = () => {
|
|
22
22
|
const state = getState();
|
|
23
23
|
const exchange_skills = nubBy(
|
|
24
|
-
(c) => c.
|
|
25
|
-
state.exchange?.agent_skills || []
|
|
24
|
+
(c) => c.skill_name,
|
|
25
|
+
state.exchange?.agent_skills || [],
|
|
26
26
|
);
|
|
27
27
|
|
|
28
28
|
return [
|
|
@@ -62,8 +62,8 @@ const find_tool = (name, config) => {
|
|
|
62
62
|
const tools = !skillTools
|
|
63
63
|
? []
|
|
64
64
|
: Array.isArray(skillTools)
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
? skillTools
|
|
66
|
+
: [skillTools];
|
|
67
67
|
const found = tools.find((t) => t?.function?.name === name);
|
|
68
68
|
if (found) return { tool: found, skill };
|
|
69
69
|
}
|
|
@@ -76,8 +76,8 @@ const find_image_tool = (config) => {
|
|
|
76
76
|
const tools = !skillTools
|
|
77
77
|
? []
|
|
78
78
|
: Array.isArray(skillTools)
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
? skillTools
|
|
80
|
+
: [skillTools];
|
|
81
81
|
const found = tools.find((t) => t?.type === "image_generation");
|
|
82
82
|
if (found) return { tool: found, skill };
|
|
83
83
|
}
|
|
@@ -97,7 +97,7 @@ const getCompletionArguments = async (
|
|
|
97
97
|
config,
|
|
98
98
|
user,
|
|
99
99
|
triggering_row,
|
|
100
|
-
formbody
|
|
100
|
+
formbody,
|
|
101
101
|
) => {
|
|
102
102
|
let tools = [];
|
|
103
103
|
|
|
@@ -131,11 +131,11 @@ const incompleteCfgMsg = () => {
|
|
|
131
131
|
!plugin_cfgs["large-language-model"]
|
|
132
132
|
) {
|
|
133
133
|
const modName = Object.keys(plugin_cfgs).find((m) =>
|
|
134
|
-
m.includes("large-language-model")
|
|
134
|
+
m.includes("large-language-model"),
|
|
135
135
|
);
|
|
136
136
|
if (modName)
|
|
137
137
|
return `LLM module not configured. Please configure <a href="/plugins/configure/${encodeURIComponent(
|
|
138
|
-
modName
|
|
138
|
+
modName,
|
|
139
139
|
)}">here<a> before using copilot.`;
|
|
140
140
|
else
|
|
141
141
|
return `LLM module not configured. Please install and configure <a href="/plugins">here<a> before using copilot.`;
|
|
@@ -150,7 +150,8 @@ const addToContext = async (run, newCtx) => {
|
|
|
150
150
|
if (Array.isArray(run.context[k])) {
|
|
151
151
|
if (!Array.isArray(newCtx[k]))
|
|
152
152
|
throw new Error("Must be array to append to array");
|
|
153
|
-
run.context[k]
|
|
153
|
+
if (k === "interactions") run.context[k] = newCtx[k];
|
|
154
|
+
else run.context[k].push(...newCtx[k]);
|
|
154
155
|
changed = true;
|
|
155
156
|
} else if (typeof run.context[k] === "object") {
|
|
156
157
|
if (typeof newCtx[k] !== "object")
|
|
@@ -178,26 +179,9 @@ const wrapCard = (title, ...inners) =>
|
|
|
178
179
|
span({ class: "badge bg-info ms-1" }, title) +
|
|
179
180
|
div(
|
|
180
181
|
{ class: "card mb-3 bg-secondary-subtle" },
|
|
181
|
-
div({ class: "card-body" }, inners)
|
|
182
|
+
div({ class: "card-body" }, inners),
|
|
182
183
|
);
|
|
183
184
|
|
|
184
|
-
const only_response_text_if_present = (interact) => {
|
|
185
|
-
if (
|
|
186
|
-
interact.role === "tool" &&
|
|
187
|
-
interact.call_id &&
|
|
188
|
-
interact.content?.[0] === "{"
|
|
189
|
-
) {
|
|
190
|
-
try {
|
|
191
|
-
const result = JSON.parse(interact.content);
|
|
192
|
-
if (result.responseText)
|
|
193
|
-
return { ...interact, content: result.responseText };
|
|
194
|
-
} catch {
|
|
195
|
-
//ignore, not json content
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
return interact;
|
|
199
|
-
};
|
|
200
|
-
|
|
201
185
|
const is_debug_mode = (config, user) => user?.role_id === 1;
|
|
202
186
|
|
|
203
187
|
const process_interaction = async (
|
|
@@ -207,7 +191,8 @@ const process_interaction = async (
|
|
|
207
191
|
agent_label = "Copilot",
|
|
208
192
|
prevResponses = [],
|
|
209
193
|
triggering_row = {},
|
|
210
|
-
agentsViewCfg = { stream: false }
|
|
194
|
+
agentsViewCfg = { stream: false },
|
|
195
|
+
dyn_updates = false,
|
|
211
196
|
) => {
|
|
212
197
|
const { stream, viewname } = agentsViewCfg;
|
|
213
198
|
const sysState = getState();
|
|
@@ -215,9 +200,10 @@ const process_interaction = async (
|
|
|
215
200
|
config,
|
|
216
201
|
req.user,
|
|
217
202
|
triggering_row,
|
|
218
|
-
req.body
|
|
203
|
+
req.body,
|
|
219
204
|
);
|
|
220
|
-
complArgs.
|
|
205
|
+
complArgs.appendToChat = true;
|
|
206
|
+
complArgs.chat = run.context.interactions;
|
|
221
207
|
//complArgs.debugResult = true;
|
|
222
208
|
//console.log("complArgs", JSON.stringify(complArgs, null, 2));
|
|
223
209
|
const debugMode = is_debug_mode(config, req.user);
|
|
@@ -240,13 +226,30 @@ const process_interaction = async (
|
|
|
240
226
|
}
|
|
241
227
|
const answer = await sysState.functions.llm_generate.run("", complArgs);
|
|
242
228
|
|
|
243
|
-
//console.log(
|
|
229
|
+
//console.log("answer", answer);
|
|
244
230
|
|
|
245
231
|
if (debugMode)
|
|
246
232
|
await addToContext(run, {
|
|
247
233
|
api_interactions: [debugCollector],
|
|
248
234
|
});
|
|
235
|
+
await addToContext(run, {
|
|
236
|
+
interactions: complArgs.chat,
|
|
237
|
+
});
|
|
249
238
|
const responses = [];
|
|
239
|
+
const add_response = async (resp) => {
|
|
240
|
+
if (dyn_updates)
|
|
241
|
+
getState().emitDynamicUpdate(
|
|
242
|
+
db.getTenantSchema(),
|
|
243
|
+
{
|
|
244
|
+
eval_js: `processCopilotResponse({response: ${JSON.stringify(resp)}, run_id: ${run.id}})`,
|
|
245
|
+
},
|
|
246
|
+
[req.user.id],
|
|
247
|
+
);
|
|
248
|
+
else responses.push(resp);
|
|
249
|
+
await addToContext(run, {
|
|
250
|
+
html_interactions: [resp],
|
|
251
|
+
});
|
|
252
|
+
};
|
|
250
253
|
if (answer && typeof answer === "object" && answer.image_calls) {
|
|
251
254
|
for (const image_call of answer.image_calls) {
|
|
252
255
|
const tool = find_image_tool(config);
|
|
@@ -261,176 +264,203 @@ const process_interaction = async (
|
|
|
261
264
|
{ ...image_call, ...(prcRes || {}) },
|
|
262
265
|
{
|
|
263
266
|
req,
|
|
264
|
-
}
|
|
267
|
+
},
|
|
265
268
|
);
|
|
266
269
|
if (rendered)
|
|
267
|
-
|
|
270
|
+
add_response(
|
|
268
271
|
wrapSegment(
|
|
269
272
|
wrapCard(
|
|
270
273
|
tool.skill.skill_label || tool.skill.constructor.skill_name,
|
|
271
|
-
rendered
|
|
274
|
+
rendered,
|
|
272
275
|
),
|
|
273
|
-
agent_label
|
|
274
|
-
)
|
|
276
|
+
agent_label,
|
|
277
|
+
),
|
|
275
278
|
);
|
|
276
279
|
}
|
|
277
280
|
}
|
|
278
281
|
if (answer.content && !answer.tool_calls)
|
|
279
|
-
|
|
282
|
+
add_response(
|
|
280
283
|
req.disable_markdown_render
|
|
281
284
|
? answer
|
|
282
|
-
: wrapSegment(md.render(answer.content), agent_label)
|
|
285
|
+
: wrapSegment(md.render(answer.content), agent_label),
|
|
283
286
|
);
|
|
284
287
|
}
|
|
285
|
-
|
|
286
|
-
await addToContext(run, {
|
|
287
|
-
interactions: answer.messages,
|
|
288
|
-
});
|
|
289
|
-
else
|
|
290
|
-
await addToContext(run, {
|
|
291
|
-
interactions:
|
|
292
|
-
typeof answer === "object" && answer.tool_calls
|
|
293
|
-
? [
|
|
294
|
-
{
|
|
295
|
-
role: "assistant",
|
|
296
|
-
tool_calls: answer.tool_calls,
|
|
297
|
-
content: answer.content,
|
|
298
|
-
},
|
|
299
|
-
]
|
|
300
|
-
: [{ role: "assistant", content: answer }],
|
|
301
|
-
});
|
|
288
|
+
|
|
302
289
|
if (
|
|
303
290
|
answer &&
|
|
304
291
|
typeof answer === "object" &&
|
|
305
|
-
(answer.
|
|
292
|
+
(answer.hasToolCalls || answer.mcp_calls)
|
|
306
293
|
) {
|
|
307
294
|
if (answer.content)
|
|
308
|
-
|
|
295
|
+
add_response(
|
|
309
296
|
req.disable_markdown_render
|
|
310
297
|
? answer
|
|
311
|
-
: wrapSegment(md.render(answer.content), agent_label)
|
|
298
|
+
: wrapSegment(md.render(answer.content), agent_label),
|
|
312
299
|
);
|
|
313
300
|
//const actions = [];
|
|
314
301
|
let hasResult = false;
|
|
315
302
|
if ((answer.mcp_calls || []).length && !answer.content) hasResult = true;
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
"call function",
|
|
319
|
-
tool_call.toolName || tool_call.function?.name
|
|
320
|
-
);
|
|
303
|
+
if (answer.hasToolCalls)
|
|
304
|
+
for (const tool_call of answer.getToolCalls()) {
|
|
305
|
+
console.log("call function", tool_call.tool_name);
|
|
321
306
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
},
|
|
328
|
-
});
|
|
307
|
+
await addToContext(run, {
|
|
308
|
+
funcalls: {
|
|
309
|
+
[tool_call.tool_call_id]: tool_call,
|
|
310
|
+
},
|
|
311
|
+
});
|
|
329
312
|
|
|
330
|
-
|
|
331
|
-
tool_call.toolName || tool_call.function?.name,
|
|
332
|
-
config
|
|
333
|
-
);
|
|
313
|
+
const tool = find_tool(tool_call.tool_name, config);
|
|
334
314
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
: JSON.parse(tool_call.function.arguments);
|
|
350
|
-
const rendered = await tool.tool.renderToolCall(row, {
|
|
351
|
-
req,
|
|
352
|
-
});
|
|
353
|
-
if (rendered)
|
|
354
|
-
responses.push(
|
|
355
|
-
wrapSegment(
|
|
356
|
-
wrapCard(
|
|
357
|
-
tool.skill.skill_label || tool.skill.constructor.skill_name,
|
|
358
|
-
rendered
|
|
359
|
-
),
|
|
360
|
-
agent_label
|
|
361
|
-
)
|
|
315
|
+
if (tool) {
|
|
316
|
+
let stop = false,
|
|
317
|
+
myHasResult = false;
|
|
318
|
+
if (stream && viewname) {
|
|
319
|
+
let content =
|
|
320
|
+
"Using skill: " + tool.skill.skill_label ||
|
|
321
|
+
tool.skill.constructor.skill_name;
|
|
322
|
+
const view = View.findOne({ name: viewname });
|
|
323
|
+
const pageLoadTag = req.body.page_load_tag;
|
|
324
|
+
view.emitRealTimeEvent(
|
|
325
|
+
`STREAM_CHUNK?page_load_tag=${pageLoadTag}`,
|
|
326
|
+
{
|
|
327
|
+
content,
|
|
328
|
+
},
|
|
362
329
|
);
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
: JSON.parse(tool_call.function.arguments),
|
|
369
|
-
{ req }
|
|
370
|
-
);
|
|
371
|
-
if (
|
|
372
|
-
(typeof result === "object" && Object.keys(result || {}).length) ||
|
|
373
|
-
typeof result === "string"
|
|
374
|
-
) {
|
|
375
|
-
if (tool.tool.renderToolResponse) {
|
|
376
|
-
const rendered = await tool.tool.renderToolResponse(result, {
|
|
330
|
+
}
|
|
331
|
+
if (tool.tool.renderToolCall) {
|
|
332
|
+
const row = tool_call.input;
|
|
333
|
+
|
|
334
|
+
const rendered = await tool.tool.renderToolCall(row, {
|
|
377
335
|
req,
|
|
378
336
|
});
|
|
379
337
|
if (rendered)
|
|
380
|
-
|
|
338
|
+
add_response(
|
|
381
339
|
wrapSegment(
|
|
382
340
|
wrapCard(
|
|
383
341
|
tool.skill.skill_label || tool.skill.constructor.skill_name,
|
|
384
|
-
rendered
|
|
342
|
+
rendered,
|
|
385
343
|
),
|
|
386
|
-
agent_label
|
|
387
|
-
)
|
|
344
|
+
agent_label,
|
|
345
|
+
),
|
|
388
346
|
);
|
|
389
347
|
}
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
await addToContext(run, {
|
|
394
|
-
interactions: [
|
|
395
|
-
{
|
|
396
|
-
role: "tool",
|
|
397
|
-
content: [
|
|
398
|
-
{
|
|
399
|
-
type: "tool-result",
|
|
400
|
-
toolCallId: tool_call.toolCallId,
|
|
401
|
-
toolName: tool_call.toolName,
|
|
402
|
-
output:
|
|
403
|
-
!result || typeof result === "string"
|
|
404
|
-
? {
|
|
405
|
-
type: "text",
|
|
406
|
-
value: result || "Action run",
|
|
407
|
-
}
|
|
408
|
-
: {
|
|
409
|
-
type: "json",
|
|
410
|
-
value: JSON.parse(JSON.stringify(result)),
|
|
411
|
-
},
|
|
412
|
-
},
|
|
413
|
-
],
|
|
414
|
-
},
|
|
415
|
-
],
|
|
348
|
+
myHasResult = true;
|
|
349
|
+
const result = await tool.tool.process(tool_call.input, {
|
|
350
|
+
req,
|
|
416
351
|
});
|
|
417
|
-
|
|
352
|
+
if (result.stop) stop = true;
|
|
353
|
+
if (
|
|
354
|
+
(typeof result === "object" && Object.keys(result || {}).length) ||
|
|
355
|
+
typeof result === "string"
|
|
356
|
+
) {
|
|
357
|
+
if (tool.tool.renderToolResponse) {
|
|
358
|
+
const rendered = await tool.tool.renderToolResponse(result, {
|
|
359
|
+
req,
|
|
360
|
+
});
|
|
361
|
+
if (rendered)
|
|
362
|
+
add_responses(
|
|
363
|
+
wrapSegment(
|
|
364
|
+
wrapCard(
|
|
365
|
+
tool.skill.skill_label ||
|
|
366
|
+
tool.skill.constructor.skill_name,
|
|
367
|
+
rendered,
|
|
368
|
+
),
|
|
369
|
+
agent_label,
|
|
370
|
+
),
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
myHasResult = true;
|
|
374
|
+
}
|
|
375
|
+
await sysState.functions.llm_add_message.run(
|
|
376
|
+
"tool_response",
|
|
377
|
+
!result || typeof result === "string"
|
|
378
|
+
? {
|
|
379
|
+
type: "text",
|
|
380
|
+
value: result || "Action run",
|
|
381
|
+
}
|
|
382
|
+
: {
|
|
383
|
+
type: "json",
|
|
384
|
+
value: JSON.parse(JSON.stringify(result)),
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
chat: run.context.interactions,
|
|
388
|
+
tool_call,
|
|
389
|
+
},
|
|
390
|
+
);
|
|
391
|
+
|
|
418
392
|
await addToContext(run, {
|
|
419
|
-
interactions:
|
|
420
|
-
{
|
|
421
|
-
role: "tool",
|
|
422
|
-
tool_call_id: tool_call.toolCallId || tool_call.id,
|
|
423
|
-
call_id: tool_call.call_id,
|
|
424
|
-
name: tool_call.toolName || tool_call.function.name,
|
|
425
|
-
content:
|
|
426
|
-
result && typeof result !== "string"
|
|
427
|
-
? JSON.stringify(result)
|
|
428
|
-
: result || "Action run",
|
|
429
|
-
},
|
|
430
|
-
],
|
|
393
|
+
interactions: run.context.interactions,
|
|
431
394
|
});
|
|
395
|
+
if (tool.tool.postProcess && !stop) {
|
|
396
|
+
const chat = run.context.interactions;
|
|
397
|
+
let generateUsed = false;
|
|
398
|
+
const postprocres = await tool.tool.postProcess({
|
|
399
|
+
tool_call,
|
|
400
|
+
result,
|
|
401
|
+
chat,
|
|
402
|
+
req,
|
|
403
|
+
async generate(prompt, opts = {}) {
|
|
404
|
+
generateUsed = true;
|
|
405
|
+
return await sysState.functions.llm_generate.run(prompt, {
|
|
406
|
+
chat,
|
|
407
|
+
appendToChat: true,
|
|
408
|
+
...opts,
|
|
409
|
+
});
|
|
410
|
+
},
|
|
411
|
+
});
|
|
412
|
+
if (generateUsed)
|
|
413
|
+
await addToContext(run, {
|
|
414
|
+
interactions: chat,
|
|
415
|
+
});
|
|
416
|
+
if (postprocres.stop) stop = true;
|
|
417
|
+
if (postprocres.add_system_prompt)
|
|
418
|
+
await addToContext(run, {
|
|
419
|
+
interactions: [
|
|
420
|
+
...chat,
|
|
421
|
+
{ role: "system", content: postprocres.add_system_prompt },
|
|
422
|
+
],
|
|
423
|
+
});
|
|
424
|
+
if (postprocres.add_response)
|
|
425
|
+
add_response(
|
|
426
|
+
wrapSegment(
|
|
427
|
+
wrapCard(
|
|
428
|
+
tool.skill.skill_label || tool.skill.constructor.skill_name,
|
|
429
|
+
postprocres.add_response,
|
|
430
|
+
),
|
|
431
|
+
agent_label,
|
|
432
|
+
),
|
|
433
|
+
);
|
|
434
|
+
if (postprocres.add_user_action && viewname) {
|
|
435
|
+
const user_actions = Array.isArray()
|
|
436
|
+
? postprocres.add_user_action
|
|
437
|
+
: [postprocres.add_user_action];
|
|
438
|
+
for (const uact of user_actions) {
|
|
439
|
+
uact.rndid = Math.floor(Math.random() * 16777215).toString(16);
|
|
440
|
+
uact.tool_call = tool_call;
|
|
441
|
+
}
|
|
442
|
+
await addToContext(run, {
|
|
443
|
+
user_actions,
|
|
444
|
+
});
|
|
445
|
+
add_response(
|
|
446
|
+
div(
|
|
447
|
+
{ class: "d-flex mb-2" },
|
|
448
|
+
user_actions.map((ua) =>
|
|
449
|
+
button(
|
|
450
|
+
{
|
|
451
|
+
class: "btn btn-primary", //press_store_button(this, true);
|
|
452
|
+
onclick: `view_post('${viewname}', 'execute_user_action', {uaname: "${ua.name}",rndid: "${ua.rndid}", run_id: ${run.id}}, processExecuteResponse)`,
|
|
453
|
+
},
|
|
454
|
+
ua.label,
|
|
455
|
+
),
|
|
456
|
+
),
|
|
457
|
+
),
|
|
458
|
+
);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
if (myHasResult && !stop) hasResult = true;
|
|
462
|
+
}
|
|
432
463
|
}
|
|
433
|
-
}
|
|
434
464
|
if (hasResult)
|
|
435
465
|
return await process_interaction(
|
|
436
466
|
run,
|
|
@@ -439,13 +469,14 @@ const process_interaction = async (
|
|
|
439
469
|
agent_label,
|
|
440
470
|
[...prevResponses, ...responses],
|
|
441
471
|
triggering_row,
|
|
442
|
-
agentsViewCfg
|
|
472
|
+
agentsViewCfg,
|
|
473
|
+
dyn_updates,
|
|
443
474
|
);
|
|
444
475
|
} else if (typeof answer === "string")
|
|
445
|
-
|
|
476
|
+
add_response(
|
|
446
477
|
req.disable_markdown_render
|
|
447
478
|
? answer
|
|
448
|
-
: wrapSegment(md.render(answer), agent_label)
|
|
479
|
+
: wrapSegment(md.render(answer), agent_label),
|
|
449
480
|
);
|
|
450
481
|
|
|
451
482
|
return {
|
package/index.js
CHANGED
|
@@ -25,97 +25,15 @@ module.exports = {
|
|
|
25
25
|
}/markdown-it.min.js`,
|
|
26
26
|
onlyViews: ["Agent Chat"],
|
|
27
27
|
},
|
|
28
|
+
{
|
|
29
|
+
script: `/plugins/public/agents@${
|
|
30
|
+
require("./package.json").version
|
|
31
|
+
}/jquery.autogrow-textarea.js`,
|
|
32
|
+
onlyViews: ["Agent Chat"],
|
|
33
|
+
},
|
|
28
34
|
],
|
|
29
35
|
actions: {
|
|
30
|
-
Agent:
|
|
31
|
-
disableInBuilder: true,
|
|
32
|
-
disableInList: true,
|
|
33
|
-
disableInWorkflow: true,
|
|
34
|
-
configFields: async ({ table, mode }) => {
|
|
35
|
-
const skills = get_skills();
|
|
36
|
-
const skills_fields = [];
|
|
37
|
-
for (const skill of skills) {
|
|
38
|
-
if (skill.configFields) {
|
|
39
|
-
const fields = await applyAsync(skill.configFields, undefined);
|
|
40
|
-
for (const field of fields) {
|
|
41
|
-
if (!field.showIf) field.showIf = {};
|
|
42
|
-
field.showIf.skill_type = skill.skill_name;
|
|
43
|
-
skills_fields.push(field);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
const tables_with_json_field = (await Table.find({})).filter(
|
|
48
|
-
(table) =>
|
|
49
|
-
!table.external &&
|
|
50
|
-
!table.provider_name &&
|
|
51
|
-
table.fields.some((f) => f.type?.name === "JSON")
|
|
52
|
-
);
|
|
53
|
-
return [
|
|
54
|
-
...(table
|
|
55
|
-
? [
|
|
56
|
-
{
|
|
57
|
-
name: "prompt",
|
|
58
|
-
label: "Prompt",
|
|
59
|
-
sublabel:
|
|
60
|
-
"When triggered from table event or table view button. Use handlebars <code>{{}}</code> to access table fields. Ignored if run in Agent Chat view.",
|
|
61
|
-
type: "String",
|
|
62
|
-
required: true,
|
|
63
|
-
attributes: { options: table.fields.map((f) => f.name) },
|
|
64
|
-
},
|
|
65
|
-
]
|
|
66
|
-
: []),
|
|
67
|
-
{
|
|
68
|
-
name: "sys_prompt",
|
|
69
|
-
label: "System prompt",
|
|
70
|
-
sublabel:
|
|
71
|
-
"Additional information for the system prompt. Use interpolations <code>{{ }}</code> to access triggering row variables or user",
|
|
72
|
-
type: "String",
|
|
73
|
-
fieldview: "textarea",
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
name: "model",
|
|
77
|
-
label: "Model",
|
|
78
|
-
sublabel: "Override default model name",
|
|
79
|
-
type: "String",
|
|
80
|
-
},
|
|
81
|
-
new FieldRepeat({
|
|
82
|
-
name: "skills",
|
|
83
|
-
label: "Skills",
|
|
84
|
-
fields: [
|
|
85
|
-
{
|
|
86
|
-
name: "skill_type",
|
|
87
|
-
label: "Type",
|
|
88
|
-
type: "String",
|
|
89
|
-
required: true,
|
|
90
|
-
attributes: { options: skills.map((s) => s.skill_name) },
|
|
91
|
-
},
|
|
92
|
-
...skills_fields,
|
|
93
|
-
],
|
|
94
|
-
}),
|
|
95
|
-
];
|
|
96
|
-
},
|
|
97
|
-
run: async ({ configuration, user, row, trigger_id, req, ...rest }) => {
|
|
98
|
-
const userinput = interpolate(configuration.prompt, row, user);
|
|
99
|
-
const run = await WorkflowRun.create({
|
|
100
|
-
status: "Running",
|
|
101
|
-
started_by: user?.id,
|
|
102
|
-
trigger_id: trigger_id || undefined,
|
|
103
|
-
context: {
|
|
104
|
-
implemented_fcall_ids: [],
|
|
105
|
-
interactions: [{ role: "user", content: userinput }],
|
|
106
|
-
funcalls: {},
|
|
107
|
-
},
|
|
108
|
-
});
|
|
109
|
-
return await process_interaction(
|
|
110
|
-
run,
|
|
111
|
-
configuration,
|
|
112
|
-
req,
|
|
113
|
-
undefined,
|
|
114
|
-
[],
|
|
115
|
-
row
|
|
116
|
-
);
|
|
117
|
-
},
|
|
118
|
-
},
|
|
36
|
+
Agent: require("./action"),
|
|
119
37
|
},
|
|
120
38
|
functions: {
|
|
121
39
|
agent_generate: {
|
|
@@ -153,7 +71,7 @@ module.exports = {
|
|
|
153
71
|
? opts.disable_markdown_render
|
|
154
72
|
: !opts?.render_markdown,
|
|
155
73
|
},
|
|
156
|
-
null
|
|
74
|
+
null,
|
|
157
75
|
);
|
|
158
76
|
return {
|
|
159
77
|
text: result.json.response,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saltcorn/agents",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "AI agents for Saltcorn",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"dependencies": {
|
|
@@ -15,6 +15,12 @@
|
|
|
15
15
|
"author": "Tom Nielsen",
|
|
16
16
|
"license": "MIT",
|
|
17
17
|
"repository": "github:saltcorn/agents",
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"jest": "^29.7.0"
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"test": "jest tests --runInBand"
|
|
23
|
+
},
|
|
18
24
|
"eslintConfig": {
|
|
19
25
|
"extends": "eslint:recommended",
|
|
20
26
|
"parserOptions": {
|
|
@@ -22,7 +28,8 @@
|
|
|
22
28
|
},
|
|
23
29
|
"env": {
|
|
24
30
|
"node": true,
|
|
25
|
-
"es6": true
|
|
31
|
+
"es6": true,
|
|
32
|
+
"jest/globals": true
|
|
26
33
|
},
|
|
27
34
|
"rules": {
|
|
28
35
|
"no-unused-vars": "off",
|