@saltcorn/agents 0.7.10 → 0.7.11

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 CHANGED
@@ -120,7 +120,12 @@ const configuration_workflow = (req) =>
120
120
  type: "String",
121
121
  required: true,
122
122
  attributes: {
123
- options: ["Standard", "No card", "Modern chat", "Modern chat - no card"],
123
+ options: [
124
+ "Standard",
125
+ "No card",
126
+ "Modern chat",
127
+ "Modern chat - no card",
128
+ ],
124
129
  },
125
130
  },
126
131
  {
@@ -289,9 +294,7 @@ const run = async (
289
294
  if (interact.content?.[0]?.type === "image_url") {
290
295
  const image_url = interact.content[0].image_url.url;
291
296
  if (image_url.startsWith("data"))
292
- interactMarkups.push(
293
- wrapSegment("File", "You", true, layout),
294
- );
297
+ interactMarkups.push(wrapSegment("File", "You", true, layout));
295
298
  else
296
299
  interactMarkups.push(
297
300
  wrapSegment(
@@ -303,12 +306,7 @@ const run = async (
303
306
  );
304
307
  } else
305
308
  interactMarkups.push(
306
- wrapSegment(
307
- md.render(interact.content),
308
- "You",
309
- true,
310
- layout,
311
- ),
309
+ wrapSegment(md.render(interact.content), "You", true, layout),
312
310
  );
313
311
  break;
314
312
  case "assistant":
@@ -494,8 +492,7 @@ const run = async (
494
492
  ),
495
493
  explainer && small({ class: "explainer" }, i(explainer)),
496
494
  ),
497
- stream &&
498
- realTimeCollabScript(viewname, rndid, layout),
495
+ stream && realTimeCollabScript(viewname, rndid, layout),
499
496
  );
500
497
 
501
498
  const isModernSidebar = layout && layout.startsWith("Modern chat");
@@ -527,7 +524,8 @@ const run = async (
527
524
  )
528
525
  : div(
529
526
  {
530
- class: "d-flex flex-wrap justify-content-between align-middle mb-2",
527
+ class:
528
+ "d-flex flex-wrap justify-content-between align-middle mb-2",
531
529
  },
532
530
  div(
533
531
  { class: "d-flex" },
@@ -564,7 +562,10 @@ const run = async (
564
562
  (isActive ? " active-session" : ""),
565
563
  },
566
564
  div(
567
- { class: "d-flex justify-content-between align-items-center mb-1" },
565
+ {
566
+ class:
567
+ "d-flex justify-content-between align-items-center mb-1",
568
+ },
568
569
  small(
569
570
  { class: "text-muted text-truncate", style: "min-width:0" },
570
571
  localeDateTime(run.started_at),
@@ -592,10 +593,7 @@ const run = async (
592
593
  onclick: `delprevrun(event, ${run.id})`,
593
594
  }),
594
595
  ),
595
- p(
596
- { class: "prevrun_content" },
597
- preview,
598
- ),
596
+ p({ class: "prevrun_content" }, preview),
599
597
  );
600
598
  }),
601
599
  )
@@ -1108,7 +1106,10 @@ const run = async (
1108
1106
  const isModern = layout && layout.startsWith("Modern chat");
1109
1107
  const main_chat =
1110
1108
  layout === "Modern chat"
1111
- ? div({ class: "card" }, div({ class: "card-body modern-chat-layout" }, main_inner))
1109
+ ? div(
1110
+ { class: "card" },
1111
+ div({ class: "card-body modern-chat-layout" }, main_inner),
1112
+ )
1112
1113
  : layout === "Modern chat - no card"
1113
1114
  ? div({ class: "modern-chat-layout" }, main_inner)
1114
1115
  : layout === "No card"
@@ -1437,6 +1438,34 @@ const execute_user_action = async (
1437
1438
  ...uadata.tool_call.input,
1438
1439
  ...uadata.input,
1439
1440
  });
1441
+ if (result.generate_prompt) {
1442
+ const action =
1443
+ config.agent_action || (await Trigger.findOne({ id: config.action_id }));
1444
+ run.context.interactions.push({
1445
+ role: "user",
1446
+ content: result.generate_prompt,
1447
+ });
1448
+ const dyn_updates = getState().getConfig("enable_dynamic_updates", true);
1449
+
1450
+ await process_interaction(
1451
+ run,
1452
+ action.configuration,
1453
+ req,
1454
+ action.name,
1455
+ [],
1456
+ {}, //row?
1457
+ config,
1458
+ dyn_updates,
1459
+ );
1460
+ const { generate_prompt, ...restResult } = result;
1461
+ return {
1462
+ json: {
1463
+ success: "ok",
1464
+ ...restResult,
1465
+ reload_embedded_view: viewname,
1466
+ },
1467
+ };
1468
+ }
1440
1469
  return {
1441
1470
  json: {
1442
1471
  success: "ok",
package/common.js CHANGED
@@ -41,6 +41,7 @@ const get_skills = () => {
41
41
  require("./skills/WebSearch"),
42
42
  require("./skills/Subagent"),
43
43
  require("./skills/ExternalSkill"),
44
+ require("./skills/PlanApproval"),
44
45
  //require("./skills/AdaptiveFeedback"),
45
46
  ...exchange_skills,
46
47
  ];
@@ -416,9 +417,90 @@ const process_interaction = async (
416
417
  myHasResult = true;
417
418
  let result = await tool.tool.process(tool_call.input, {
418
419
  req,
419
- });
420
+ });
420
421
  toolResults[tool_call.tool_call_id] = result;
422
+ if (result.add_response) {
423
+ if (!result.add_responses)
424
+ result.add_responses = [result.add_response];
425
+ else result.add_responses.push(result.add_response);
426
+ }
427
+
428
+ for (const add_resp of result.add_responses || []) {
429
+ const content =
430
+ add_resp.role && add_resp.content ? add_resp.content : add_resp;
431
+ raw_responses.push(content);
432
+ if (add_resp.md_response !== null) {
433
+ const renderedAddResponse = add_resp.md_response
434
+ ? md.render(add_resp.md_response)
435
+ : typeof content === "string"
436
+ ? md.render(content)
437
+ : content;
438
+ add_response(
439
+ wrapSegment(
440
+ wrapCard(response_label, renderedAddResponse),
441
+ agent_label,
442
+ false,
443
+ layout,
444
+ ),
445
+ );
446
+ }
447
+ if (typeof add_resp.md_response !== "undefined")
448
+ delete add_resp.md_response;
449
+
450
+ const result = content;
451
+
452
+ if (add_resp.role && add_resp.content) {
453
+ await sysState.functions.llm_add_message.run(
454
+ add_resp.role,
455
+ add_resp.content,
456
+ {
457
+ chat: run.context.interactions,
458
+ },
459
+ );
460
+ } else
461
+ await sysState.functions.llm_add_message.run(
462
+ "assistant",
463
+
464
+ !result || typeof result === "string"
465
+ ? result || "Action run"
466
+ : JSON.stringify(result),
467
+
468
+ {
469
+ chat: run.context.interactions,
470
+ },
471
+ );
472
+
473
+ await addToContext(run, {
474
+ interactions: run.context.interactions,
475
+ });
476
+ }
421
477
  if (result?.stop) stop = true;
478
+ if (result?.add_user_action && viewname) {
479
+ const user_actions = Array.isArray()
480
+ ? result.add_user_action
481
+ : [result.add_user_action];
482
+ for (const uact of user_actions) {
483
+ uact.rndid = Math.floor(Math.random() * 16777215).toString(16);
484
+ uact.tool_call = tool_call;
485
+ }
486
+ await addToContext(run, {
487
+ user_actions,
488
+ });
489
+ add_response(
490
+ div(
491
+ { class: "d-flex mb-2" },
492
+ user_actions.map((ua) =>
493
+ button(
494
+ {
495
+ class: "btn btn-primary", //press_store_button(this, true);
496
+ onclick: `view_post('${viewname}', 'execute_user_action', {uaname: "${ua.name}",rndid: "${ua.rndid}", run_id: ${run.id}}, processExecuteResponse)`,
497
+ },
498
+ ua.label,
499
+ ),
500
+ ),
501
+ ),
502
+ );
503
+ }
422
504
  if (
423
505
  (typeof result === "object" && Object.keys(result || {}).length) ||
424
506
  typeof result === "string"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saltcorn/agents",
3
- "version": "0.7.10",
3
+ "version": "0.7.11",
4
4
  "description": "AI agents for Saltcorn",
5
5
  "main": "index.js",
6
6
  "dependencies": {
@@ -0,0 +1,99 @@
1
+ const { div, pre, a } = 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 User = require("@saltcorn/data/models/user");
6
+ const File = require("@saltcorn/data/models/file");
7
+ const View = require("@saltcorn/data/models/view");
8
+ const Trigger = require("@saltcorn/data/models/trigger");
9
+ const FieldRepeat = require("@saltcorn/data/models/fieldrepeat");
10
+ const { getState } = require("@saltcorn/data/db/state");
11
+ const db = require("@saltcorn/data/db");
12
+ const { eval_expression } = require("@saltcorn/data/models/expression");
13
+ const { interpolate, sleep } = require("@saltcorn/data/utils");
14
+ const { features } = require("@saltcorn/data/db/state");
15
+ const { button } = require("@saltcorn/markup/tags");
16
+ const { validID } = require("@saltcorn/markup/layout_utils");
17
+
18
+ const vm = require("vm");
19
+
20
+ //const { fieldProperties } = require("./helpers");
21
+
22
+ class PlanApprovalSkill {
23
+ static skill_name = "Plan approval";
24
+
25
+ get skill_label() {
26
+ return "Plan approval";
27
+ }
28
+
29
+ constructor(cfg) {
30
+ Object.assign(this, cfg);
31
+ }
32
+
33
+ static async configFields() {
34
+ return [
35
+ {
36
+ name: "ini_sys_prompt",
37
+ label: "Initial system prompt",
38
+ type: "String",
39
+ fieldview: "textarea",
40
+ sublabel: "Refer to the tool as <code>submit_plan_for_approval</code>",
41
+ },
42
+ {
43
+ name: "approval_prompt",
44
+ label: "Prompt on approval",
45
+ type: "String",
46
+ fieldview: "textarea",
47
+ sublabel: "If the user approves the plan, what should the agent do?",
48
+ },
49
+ ];
50
+ }
51
+ systemPrompt() {
52
+ return this.ini_sys_prompt;
53
+ }
54
+
55
+ get userActions() {
56
+ return {
57
+ approve_plan: async () => {
58
+ return { generate_prompt: this.approval_prompt };
59
+ },
60
+ };
61
+ }
62
+
63
+ provideTools = () => {
64
+ return {
65
+ type: "function",
66
+ process: async (row) => {
67
+ console.log("process plan row", row);
68
+
69
+ return {
70
+ stop: true,
71
+ add_response: row.plan,
72
+ add_user_action: {
73
+ name: "approve_plan",
74
+ type: "button",
75
+ label: `Approve`,
76
+ input: {},
77
+ },
78
+ };
79
+ },
80
+ function: {
81
+ name: "submit_plan_for_approval",
82
+ description:
83
+ "Submit a plan for approval by the user. If the plan is approved, further instructions about executing it may be given",
84
+ parameters: {
85
+ type: "object",
86
+ required: ["plan"],
87
+ properties: {
88
+ plan: {
89
+ description: "The plan",
90
+ type: "string",
91
+ },
92
+ },
93
+ },
94
+ },
95
+ };
96
+ };
97
+ }
98
+
99
+ module.exports = PlanApprovalSkill;