@saltcorn/agents 0.7.16 → 0.8.0

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.
Files changed (3) hide show
  1. package/action.js +44 -5
  2. package/common.js +41 -38
  3. package/package.json +1 -1
package/action.js CHANGED
@@ -1,9 +1,11 @@
1
1
  const FieldRepeat = require("@saltcorn/data/models/fieldrepeat");
2
2
  const Table = require("@saltcorn/data/models/table");
3
- const { get_skills, process_interaction } = require("./common");
3
+ const View = require("@saltcorn/data/models/view");
4
+ const { p } = require("@saltcorn/markup/tags");
5
+ const { get_skills, process_interaction, wrapSegment } = require("./common");
4
6
  const { applyAsync } = require("@saltcorn/data/utils");
5
7
  const WorkflowRun = require("@saltcorn/data/models/workflow_run");
6
- const { interpolate } = require("@saltcorn/data/utils");
8
+ const { interpolate, escapeHtml } = require("@saltcorn/data/utils");
7
9
  const { getState } = require("@saltcorn/data/db/state");
8
10
 
9
11
  module.exports = {
@@ -36,8 +38,18 @@ module.exports = {
36
38
  sublabel:
37
39
  "When triggered from table event or table view button. Use handlebars <code>{{}}</code> to access table fields. Ignored if run in Agent Chat view.",
38
40
  type: "String",
39
- required: true,
40
- attributes: { options: table.fields.map((f) => f.name) },
41
+ },
42
+ {
43
+ name: "run_id_field",
44
+ type: "String",
45
+ label: "Run ID field",
46
+ sublabel:
47
+ "Set this field to the run ID, when triggered from table event or table view button. Ignored if run in Agent Chat view.",
48
+ attributes: {
49
+ options: table.fields
50
+ .filter((f) => f.type?.name === "Integer" && !f.primary_key)
51
+ .map((f) => f.name),
52
+ },
41
53
  },
42
54
  ]
43
55
  : []),
@@ -87,6 +99,7 @@ module.exports = {
87
99
  user,
88
100
  row,
89
101
  trigger_id,
102
+ table,
90
103
  run_id,
91
104
  req,
92
105
  is_sub_agent,
@@ -108,11 +121,37 @@ module.exports = {
108
121
  context: {
109
122
  implemented_fcall_ids: [],
110
123
  interactions: [],
124
+ html_interactions: [],
111
125
  funcalls: {},
112
126
  },
113
127
  }));
114
128
 
129
+ if (!rest.run && !run_id && table && configuration.run_id_field) {
130
+ await table.updateRow(
131
+ { [configuration.run_id_field]: run.id },
132
+ row[table.pk_name],
133
+ );
134
+ }
135
+ let use_agent_view_config = agent_view_config;
136
+ if (!use_agent_view_config) {
137
+ const agent_views = await View.find({ viewtemplate: "Agent Chat" });
138
+ const agent_view = agent_views.find(
139
+ (v) => v?.configuration?.action_id == trigger_id,
140
+ );
141
+ if (agent_view)
142
+ use_agent_view_config = { ...agent_view.configuration, stream: false };
143
+ }
115
144
  run.context.interactions.push({ role: "user", content: userinput });
145
+ run.context.html_interactions.push(
146
+ wrapSegment(
147
+ p(escapeHtml(userinput)),
148
+ "You",
149
+ true,
150
+ use_agent_view_config?.layout,
151
+ req?.user,
152
+ ),
153
+ );
154
+
116
155
  return await process_interaction(
117
156
  run,
118
157
  configuration,
@@ -120,7 +159,7 @@ module.exports = {
120
159
  agent_label || undefined,
121
160
  [],
122
161
  row,
123
- agent_view_config || { stream: false },
162
+ use_agent_view_config || { stream: false },
124
163
  dyn_updates,
125
164
  is_sub_agent,
126
165
  );
package/common.js CHANGED
@@ -403,26 +403,13 @@ const process_interaction = async (
403
403
  const response_label = is_sub_agent
404
404
  ? agent_label
405
405
  : tool.skill.skill_label || tool.skill.constructor.skill_name;
406
+ let rendered_tool_call = "";
406
407
  if (tool.tool.renderToolCall) {
407
408
  const row = tool_call.input;
408
409
 
409
- const rendered = await tool.tool.renderToolCall(row, {
410
+ rendered_tool_call = await tool.tool.renderToolCall(row, {
410
411
  req,
411
412
  });
412
- if (rendered)
413
- add_response(
414
- wrapSegment(
415
- wrapCard(
416
- response_label,
417
- typeof rendered === "string"
418
- ? md.render(rendered)
419
- : rendered,
420
- ),
421
- agent_label,
422
- false,
423
- layout,
424
- ),
425
- );
426
413
  }
427
414
  myHasResult = true;
428
415
  let result = await tool.tool.process(tool_call.input, {
@@ -431,7 +418,8 @@ const process_interaction = async (
431
418
  const tool_response = result.add_response || result;
432
419
  toolResults[tool_call.tool_call_id] = result;
433
420
  if (result?.stop) stop = true;
434
- if (result?.add_user_action && viewname) {
421
+ let add_user_action_html = "";
422
+ if (result?.add_user_action) {
435
423
  const user_actions = Array.isArray()
436
424
  ? result.add_user_action
437
425
  : [result.add_user_action];
@@ -442,46 +430,61 @@ const process_interaction = async (
442
430
  await addToContext(run, {
443
431
  user_actions,
444
432
  });
445
- add_response(
446
- div(
447
- { class: "d-flex mb-2" },
448
- user_actions.map((ua) =>
449
- button(
450
- {
451
- "data-useraction-id": ua.rndid,
452
- class: "btn btn-primary", //press_store_button(this, true);
453
- onclick: `view_post('${viewname}', 'execute_user_action', {uaname: "${ua.name}",rndid: "${ua.rndid}", run_id: ${run.id}}, processExecuteResponse)`,
454
- },
455
- ua.label,
456
- ),
433
+ add_user_action_html = div(
434
+ { class: "d-flex mb-2" },
435
+ user_actions.map((ua) =>
436
+ button(
437
+ {
438
+ "data-useraction-id": ua.rndid,
439
+ class: "btn btn-primary", //press_store_button(this, true);
440
+ onclick: `view_post(${viewname ? `'${viewname}'` : `$(this).closest('[data-sc-embed-viewname]').attr('data-sc-embed-viewname')`}, 'execute_user_action', {uaname: "${ua.name}",rndid: "${ua.rndid}", run_id: ${run.id}}, processExecuteResponse)`,
441
+ },
442
+ ua.label,
457
443
  ),
458
444
  ),
459
445
  );
460
446
  }
447
+ let rendered_tool_response = "";
461
448
  if (
462
449
  (typeof tool_response === "object" &&
463
450
  Object.keys(tool_response || {}).length) ||
464
451
  typeof tool_response === "string"
465
452
  ) {
466
453
  if (tool.tool.renderToolResponse) {
467
- const rendered = await tool.tool.renderToolResponse(
454
+ rendered_tool_response = await tool.tool.renderToolResponse(
468
455
  tool_response,
469
456
  {
470
457
  req,
458
+ tool_call,
471
459
  },
472
460
  );
473
- if (rendered)
474
- add_response(
475
- wrapSegment(
476
- wrapCard(response_label, rendered),
477
- agent_label,
478
- false,
479
- layout,
480
- ),
481
- );
482
461
  }
483
462
  myHasResult = true;
484
463
  }
464
+ if (
465
+ rendered_tool_call ||
466
+ add_user_action_html ||
467
+ rendered_tool_response
468
+ )
469
+ add_response(
470
+ wrapSegment(
471
+ div(
472
+ rendered_tool_call &&
473
+ wrapCard(
474
+ response_label,
475
+ typeof rendered_tool_call === "string"
476
+ ? md.render(rendered_tool_call)
477
+ : rendered_tool_call,
478
+ ),
479
+ rendered_tool_response,
480
+ add_user_action_html,
481
+ ),
482
+ agent_label,
483
+ false,
484
+ layout,
485
+ ),
486
+ );
487
+
485
488
  await sysState.functions.llm_add_message.run(
486
489
  "tool_response",
487
490
  !tool_response || typeof tool_response === "string"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saltcorn/agents",
3
- "version": "0.7.16",
3
+ "version": "0.8.0",
4
4
  "description": "AI agents for Saltcorn",
5
5
  "main": "index.js",
6
6
  "dependencies": {