@saltcorn/agents 0.4.3 → 0.4.4

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
@@ -86,6 +86,12 @@ const configuration_workflow = (req) =>
86
86
  name: "prev_runs_closed",
87
87
  label: "Initially closed",
88
88
  type: "Bool",
89
+ showIf: { show_prev_runs: true },
90
+ },
91
+ {
92
+ name: "stream",
93
+ label: "Stream response",
94
+ type: "Bool",
89
95
  },
90
96
  {
91
97
  name: "placeholder",
@@ -161,6 +167,7 @@ const run = async (
161
167
  placeholder,
162
168
  explainer,
163
169
  image_upload,
170
+ stream,
164
171
  },
165
172
  state,
166
173
  { res, req }
@@ -320,7 +327,7 @@ const run = async (
320
327
  const input_form = form(
321
328
  {
322
329
  onsubmit: `event.preventDefault();spin_send_button();view_post('${viewname}', 'interact', new FormData(this), processCopilotResponse);return false;`,
323
- class: "form-namespace copilot mt-2",
330
+ class: ["form-namespace copilot mt-2 agent-view"],
324
331
  method: "post",
325
332
  },
326
333
  input({
@@ -365,7 +372,8 @@ const run = async (
365
372
  class: "debugicon fas fa-bug",
366
373
  }),
367
374
  explainer && small({ class: "explainer" }, i(explainer))
368
- )
375
+ ),
376
+ stream && div({ class: "next_response_scratch" })
369
377
  );
370
378
 
371
379
  const prev_runs_side_bar = div(
@@ -497,6 +505,7 @@ const run = async (
497
505
  if(hadFile)
498
506
  $("#copilotinteractions").append(wrapSegment('File', "You"))
499
507
  $("textarea[name=userinput]").val("")
508
+ $('form.agent-view div.next_response_scratch').html("")
500
509
 
501
510
  if(res.response)
502
511
  $("#copilotinteractions").append(res.response)
@@ -657,7 +666,8 @@ const interact = async (table_id, viewname, config, body, { req, res }) => {
657
666
  req,
658
667
  action.name,
659
668
  [],
660
- triggering_row
669
+ triggering_row,
670
+ config.stream
661
671
  );
662
672
  };
663
673
 
package/common.js CHANGED
@@ -2,6 +2,7 @@ const { getState } = require("@saltcorn/data/db/state");
2
2
  const { div, span } = require("@saltcorn/markup/tags");
3
3
  const Trigger = require("@saltcorn/data/models/trigger");
4
4
  const { interpolate } = require("@saltcorn/data/utils");
5
+ const db = require("@saltcorn/data/db");
5
6
 
6
7
  const MarkdownIt = require("markdown-it"),
7
8
  md = new MarkdownIt();
@@ -190,8 +191,10 @@ const process_interaction = async (
190
191
  req,
191
192
  agent_label = "Copilot",
192
193
  prevResponses = [],
193
- triggering_row = {}
194
+ triggering_row = {},
195
+ stream = false
194
196
  ) => {
197
+ const sysState = getState();
195
198
  const complArgs = await getCompletionArguments(
196
199
  config,
197
200
  req.user,
@@ -203,7 +206,24 @@ const process_interaction = async (
203
206
  const debugMode = is_debug_mode(config, req.user);
204
207
  const debugCollector = {};
205
208
  if (debugMode) complArgs.debugCollector = debugCollector;
206
- const answer = await getState().functions.llm_generate.run("", complArgs);
209
+ if (stream && sysState.getConfig("enable_dynamic_updates") && req.user) {
210
+ complArgs.streamCallback = (response) => {
211
+ const content =
212
+ response.choices[0].content || response.choices[0].delta?.content;
213
+ if (content)
214
+ sysState?.emitDynamicUpdate(
215
+ db.getTenantSchema(),
216
+ {
217
+ eval_js: `$('form.agent-view div.next_response_scratch').append(${JSON.stringify(
218
+ content
219
+ )})`,
220
+ },
221
+ [req.user.id]
222
+ );
223
+ };
224
+ }
225
+ const answer = await sysState.functions.llm_generate.run("", complArgs);
226
+
207
227
  if (debugMode)
208
228
  await addToContext(run, {
209
229
  api_interactions: [debugCollector],
@@ -263,7 +283,7 @@ const process_interaction = async (
263
283
  let hasResult = false;
264
284
  if ((answer.mcp_calls || []).length && !answer.content) hasResult = true;
265
285
  for (const tool_call of answer.tool_calls || []) {
266
- console.log("call function", tool_call.function);
286
+ console.log("call function", tool_call.function?.name);
267
287
 
268
288
  await addToContext(run, {
269
289
  funcalls: { [tool_call.id]: tool_call.function },
@@ -272,6 +292,24 @@ const process_interaction = async (
272
292
  const tool = find_tool(tool_call.function?.name, config);
273
293
 
274
294
  if (tool) {
295
+ if (
296
+ stream &&
297
+ sysState.getConfig("enable_dynamic_updates") &&
298
+ req.user
299
+ ) {
300
+ let content =
301
+ "Using skill: " + tool.skill.skill_label ||
302
+ tool.skill.constructor.skill_name;
303
+ sysState?.emitDynamicUpdate(
304
+ db.getTenantSchema(),
305
+ {
306
+ eval_js: `$('form.agent-view div.next_response_scratch').append(${JSON.stringify(
307
+ content
308
+ )})`,
309
+ },
310
+ [req.user.id]
311
+ );
312
+ }
275
313
  if (tool.tool.renderToolCall) {
276
314
  const row = JSON.parse(tool_call.function.arguments);
277
315
  const rendered = await tool.tool.renderToolCall(row, {
@@ -337,7 +375,8 @@ const process_interaction = async (
337
375
  req,
338
376
  agent_label,
339
377
  [...prevResponses, ...responses],
340
- triggering_row
378
+ triggering_row,
379
+ stream
341
380
  );
342
381
  } else if (typeof answer === "string")
343
382
  responses.push(wrapSegment(md.render(answer), agent_label));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saltcorn/agents",
3
- "version": "0.4.3",
3
+ "version": "0.4.4",
4
4
  "description": "AI agents for Saltcorn",
5
5
  "main": "index.js",
6
6
  "dependencies": {
@@ -11,7 +11,7 @@ const db = require("@saltcorn/data/db");
11
11
  const { eval_expression } = require("@saltcorn/data/models/expression");
12
12
  const { interpolate } = require("@saltcorn/data/utils");
13
13
  const vm = require("vm");
14
- const fetch = require("node-fetch");
14
+ const fetch = global.fetch || require("node-fetch");
15
15
 
16
16
  class PreloadData {
17
17
  static skill_name = "Preload Data";