@saltcorn/agents 0.4.4 → 0.4.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/agent-view.js CHANGED
@@ -43,6 +43,7 @@ const {
43
43
  find_image_tool,
44
44
  is_debug_mode,
45
45
  get_initial_interactions,
46
+ get_skill_instances,
46
47
  } = require("./common");
47
48
  const MarkdownIt = require("markdown-it"),
48
49
  md = new MarkdownIt();
@@ -323,6 +324,14 @@ const run = async (
323
324
  }
324
325
  runInteractions = interactMarkups.join("");
325
326
  }
327
+ const skill_form_widgets = [];
328
+ for (const skill of get_skill_instances(action.configuration)) {
329
+ if (skill.formWidget)
330
+ skill_form_widgets.push(
331
+ await skill.formWidget({ user: req.user, klass: "skill-form-widget" })
332
+ );
333
+ }
334
+
326
335
  const debugMode = is_debug_mode(action.configuration, req.user);
327
336
  const input_form = form(
328
337
  {
@@ -371,6 +380,7 @@ const run = async (
371
380
  onclick: "press_agent_debug_button()",
372
381
  class: "debugicon fas fa-bug",
373
382
  }),
383
+ skill_form_widgets,
374
384
  explainer && small({ class: "explainer" }, i(explainer))
375
385
  ),
376
386
  stream && div({ class: "next_response_scratch" })
@@ -457,6 +467,12 @@ const run = async (
457
467
  top: -1.8rem;
458
468
  left: 0.1rem;
459
469
  cursor: pointer;
470
+ }
471
+ .copilot-entry .skill-form-widget {
472
+ position: relative;
473
+ top: -2rem;
474
+ left: 0.4rem;
475
+ display: inline;
460
476
  }
461
477
  .session-open-sessions, .open-prev-runs {
462
478
  cursor: pointer;
@@ -692,13 +708,22 @@ const debug_info = async (table_id, viewname, config, body, { req, res }) => {
692
708
  if (table) triggering_row = await table.getRow({ [pk]: triggering_row_id });
693
709
  }
694
710
  const run = await WorkflowRun.findOne({ id: +run_id });
695
- const complArgs = await getCompletionArguments(
696
- action.configuration,
697
- req.user,
698
- triggering_row
699
- );
711
+ let sysPrompt = "";
712
+ if (
713
+ run.context.api_interactions?.[0].request?.messages?.[0]?.role === "system"
714
+ ) {
715
+ sysPrompt =
716
+ run.context.api_interactions?.[0].request?.messages?.[0].content;
717
+ } else {
718
+ const complArgs = await getCompletionArguments(
719
+ action.configuration,
720
+ req.user,
721
+ triggering_row
722
+ );
723
+ sysPrompt = complArgs.systemPrompt;
724
+ }
700
725
  const debug_html = div(
701
- div(h4("System prompt"), pre(complArgs.systemPrompt)),
726
+ div(h4("System prompt"), pre(sysPrompt)),
702
727
  div(
703
728
  h4("API interactions"),
704
729
  pre(JSON.stringify(run.context.api_interactions, null, 2))
package/common.js CHANGED
@@ -32,6 +32,7 @@ const get_skills = () => {
32
32
  require("./skills/PreloadData"),
33
33
  require("./skills/GenerateImage"),
34
34
  require("./skills/ModelContextProtocol"),
35
+ require("./skills/PromptPicker"),
35
36
  //require("./skills/AdaptiveFeedback"),
36
37
  ...exchange_skills,
37
38
  ];
@@ -90,7 +91,12 @@ const get_initial_interactions = async (config, user, triggering_row) => {
90
91
  return interacts;
91
92
  };
92
93
 
93
- const getCompletionArguments = async (config, user, triggering_row) => {
94
+ const getCompletionArguments = async (
95
+ config,
96
+ user,
97
+ triggering_row,
98
+ formbody
99
+ ) => {
94
100
  let tools = [];
95
101
 
96
102
  let sysPrompts = [
@@ -99,7 +105,11 @@ const getCompletionArguments = async (config, user, triggering_row) => {
99
105
 
100
106
  const skills = get_skill_instances(config);
101
107
  for (const skill of skills) {
102
- const sysPr = await skill.systemPrompt?.({ user, triggering_row });
108
+ const sysPr = await skill.systemPrompt?.({
109
+ ...(formbody || {}),
110
+ user,
111
+ triggering_row,
112
+ });
103
113
  if (sysPr) sysPrompts.push(sysPr);
104
114
  const skillTools = skill.provideTools?.();
105
115
  if (skillTools && Array.isArray(skillTools)) tools.push(...skillTools);
@@ -198,7 +208,8 @@ const process_interaction = async (
198
208
  const complArgs = await getCompletionArguments(
199
209
  config,
200
210
  req.user,
201
- triggering_row
211
+ triggering_row,
212
+ req.body
202
213
  );
203
214
  complArgs.chat = run.context.interactions.map(only_response_text_if_present);
204
215
  //complArgs.debugResult = true;
@@ -224,6 +235,8 @@ const process_interaction = async (
224
235
  }
225
236
  const answer = await sysState.functions.llm_generate.run("", complArgs);
226
237
 
238
+ //console.log({answer});
239
+
227
240
  if (debugMode)
228
241
  await addToContext(run, {
229
242
  api_interactions: [debugCollector],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saltcorn/agents",
3
- "version": "0.4.4",
3
+ "version": "0.4.5",
4
4
  "description": "AI agents for Saltcorn",
5
5
  "main": "index.js",
6
6
  "dependencies": {
@@ -69,7 +69,7 @@ class PreloadData {
69
69
  const table = Table.findOne(this.table_name);
70
70
  const q = eval_expression(
71
71
  this.preload_query,
72
- {},
72
+ triggering_row || {},
73
73
  user,
74
74
  "PreloadData query"
75
75
  );
@@ -0,0 +1,51 @@
1
+ const Workflow = require("@saltcorn/data/models/workflow");
2
+ const Form = require("@saltcorn/data/models/form");
3
+ const FieldRepeat = require("@saltcorn/data/models/fieldrepeat");
4
+ const { select, option } = require("@saltcorn/markup/tags");
5
+ const { eval_expression } = require("@saltcorn/data/models/expression");
6
+ const { validID } = require("@saltcorn/markup/layout_utils");
7
+
8
+ class PromptPicker {
9
+ static skill_name = "Prompt picker";
10
+ get skill_label() {
11
+ return `Prompt picker`;
12
+ }
13
+ constructor(cfg) {
14
+ Object.assign(this, cfg);
15
+ this.options = eval_expression(
16
+ this.options_obj,
17
+ {},
18
+ null,
19
+ "Prompt picker options"
20
+ );
21
+ this.formname = validID("pp" + Object.keys(this.options));
22
+ }
23
+ static async configFields() {
24
+ return [
25
+ { name: "placeholder", label: "Placeholder", type: "String" },
26
+ {
27
+ name: "options_obj",
28
+ label: "System prompt contents",
29
+ sublabel: `JavaScript object where the keys are the options and values are added to system prompt. Example:<br><code>{"Pirate":"Speak like a pirate", "Pop star":"Speak like a pop star"}</code>`,
30
+ type: "String",
31
+ fieldview: "textarea",
32
+ required: true,
33
+ },
34
+ ];
35
+ }
36
+ async formWidget({ user, klass }) {
37
+ return select(
38
+ {
39
+ class: ["form-select form-select-sm w-unset", klass],
40
+ name: this.formname,
41
+ },
42
+ this.placeholder && option({ disabled: true }, this.placeholder),
43
+ Object.keys(this.options).map((o) => option(o))
44
+ );
45
+ }
46
+ systemPrompt(body) {
47
+ if (body[this.formname]) return this.options[body[this.formname]];
48
+ }
49
+ }
50
+
51
+ module.exports = PromptPicker;