@saltcorn/agents 0.7.5 → 0.7.6

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 CHANGED
@@ -90,6 +90,8 @@ module.exports = {
90
90
  run_id,
91
91
  req,
92
92
  is_sub_agent,
93
+ agent_view_config,
94
+ dyn_updates,
93
95
  ...rest
94
96
  }) => {
95
97
  const userinput = interpolate(configuration.prompt, row, user);
@@ -115,9 +117,9 @@ module.exports = {
115
117
  undefined,
116
118
  [],
117
119
  row,
118
- { stream: false },
119
- false,
120
- is_sub_agent
120
+ agent_view_config || { stream: false },
121
+ dyn_updates,
122
+ is_sub_agent,
121
123
  );
122
124
  },
123
125
  };
package/agent-view.js CHANGED
@@ -192,13 +192,15 @@ const realTimeCollabScript = (viewname, rndid, layout) => {
192
192
  ['${view.getRealTimeEventName(
193
193
  "STREAM_CHUNK",
194
194
  )}' + \`?page_load_tag=\${_sc_pageloadtag}\`]: async (data) => {
195
+ $(".agent-waiting-indicator").remove();
195
196
  window['stream scratch ${viewname} ${rndid}'].push(data.content)
196
197
  const rendered = md.render(window['stream scratch ${viewname} ${rndid}'].join(""));
197
- $('form.agent-view div.next_response_scratch').html(
198
+ $('div.next_response_scratch').html(
198
199
  (${JSON.stringify(layout || "")} || "").startsWith("Modern chat")
199
200
  ? '<div class="chat-message chat-assistant"><div class="chat-avatar"><i class="fas fa-robot"></i></div><div class="chat-bubble">' + rendered + '</div></div>'
200
201
  : rendered
201
202
  );
203
+ scrollAgentToBottom();
202
204
  }
203
205
  }
204
206
  };
@@ -434,7 +436,7 @@ const run = async (
434
436
  const rndid = Math.floor(Math.random() * 16777215).toString(16);
435
437
  const input_form = form(
436
438
  {
437
- onsubmit: `event.preventDefault();spin_send_button();view_post('${viewname}', 'interact', new FormData(this), ${dyn_updates ? "null" : "processCopilotResponse"});return false;`,
439
+ onsubmit: `event.preventDefault();const _fd=new FormData(this);spin_send_button();view_post('${viewname}', 'interact', _fd, ${dyn_updates ? "null" : "processCopilotResponse"});return false;`,
438
440
  class: ["form-namespace copilot mt-2 agent-view"],
439
441
  method: "post",
440
442
  },
@@ -492,8 +494,7 @@ const run = async (
492
494
  explainer && small({ class: "explainer" }, i(explainer)),
493
495
  ),
494
496
  stream &&
495
- realTimeCollabScript(viewname, rndid, layout) +
496
- div({ class: "next_response_scratch" }),
497
+ realTimeCollabScript(viewname, rndid, layout),
497
498
  );
498
499
 
499
500
  const isModernSidebar = layout && layout.startsWith("Modern chat");
@@ -612,6 +613,7 @@ const run = async (
612
613
  req.__("Sessions"),
613
614
  ),
614
615
  div({ id: "copilotinteractions" }, runInteractions),
616
+ stream ? div({ class: "next_response_scratch" }) : "",
615
617
  input_form,
616
618
  style(
617
619
  `div.interaction-segment:not(:first-child) {border-top: 1px solid #e7e7e7; }
@@ -685,6 +687,14 @@ const run = async (
685
687
  margin-bottom: 0px;
686
688
  display: block;
687
689
  text-overflow: ellipsis;}
690
+ /* Typing / Waiting Indicator */
691
+ .agent-waiting-indicator { display:flex; align-items:center; padding:0.75rem 1rem; }
692
+ .typing-dots { display:flex; gap:4px; align-items:center; }
693
+ .typing-dots span { width:8px; height:8px; border-radius:50%; background:#6c757d; animation:typingBounce 1.4s infinite ease-in-out both; }
694
+ .typing-dots span:nth-child(1) { animation-delay:-0.32s; }
695
+ .typing-dots span:nth-child(2) { animation-delay:-0.16s; }
696
+ .typing-dots span:nth-child(3) { animation-delay:0s; }
697
+ @keyframes typingBounce { 0%,80%,100%{transform:scale(.6);opacity:.4} 40%{transform:scale(1);opacity:1} }
688
698
  /* Modern Chat Layout */
689
699
  .modern-chat-layout {
690
700
  display: flex;
@@ -881,6 +891,16 @@ const run = async (
881
891
  script(domReady(`$( "#inputuserinput" ).autogrow({paddingBottom: 20});`)),
882
892
  script(
883
893
  `
894
+ function scrollAgentToBottom() {
895
+ const container = document.getElementById('copilotinteractions');
896
+ if (container) {
897
+ if (container.scrollHeight > container.clientHeight) {
898
+ container.scrollTo({ top: container.scrollHeight, behavior: 'smooth' });
899
+ }
900
+ const inputForm = document.querySelector('form.agent-view');
901
+ if (inputForm) inputForm.scrollIntoView({ behavior: 'smooth', block: 'end' });
902
+ }
903
+ }
884
904
  function close_session_list() {
885
905
  $("div.prev-runs-list").hide().parents(".col-3").removeClass("col-3").addClass("was-col-3").parent().children(".col-9").removeClass("col-9").addClass("col-12")
886
906
  $("div.open-prev-runs").show()
@@ -916,14 +936,21 @@ const run = async (
916
936
  if(user_input && (!${JSON.stringify(dyn_updates)}))
917
937
  $("#copilotinteractions").append(wrapSegment('<p>'+user_input+'</p>'+fileBadge, "You", true))
918
938
  $("textarea[name=userinput]").val("")
919
- $('form.agent-view div.next_response_scratch').html("")
939
+ $('div.next_response_scratch').html("")
920
940
  window['stream scratch ${viewname} ${rndid}'] = []
921
- if(res.response)
922
- $("#copilotinteractions").append(res.response)
941
+ if(res.response) {
942
+ $(".agent-waiting-indicator").remove();
943
+ $("#copilotinteractions").append(res.response);
944
+ scrollAgentToBottom();
945
+ }
923
946
  }
924
947
  window.processCopilotResponse = processCopilotResponse;
925
948
  window.final_agent_response = () => {
926
949
  $("#sendbuttonicon").attr("class","far fa-paper-plane");
950
+ $(".agent-waiting-indicator").remove();
951
+ $("textarea[name=userinput]").prop("disabled", false).attr("placeholder", ${JSON.stringify(placeholder || "How can I help you?")}).focus();
952
+ $(".copilot-entry .submit-button").css("pointer-events", "");
953
+ scrollAgentToBottom();
927
954
  }
928
955
  window._agentDT = new DataTransfer();
929
956
  function setAgentFiles(files) {
@@ -1046,6 +1073,14 @@ const run = async (
1046
1073
  }
1047
1074
  function spin_send_button() {
1048
1075
  $("#sendbuttonicon").attr("class","fas fa-spinner fa-spin");
1076
+ $("textarea[name=userinput]").prop("disabled", true).attr("placeholder", "Waiting for response...");
1077
+ $(".copilot-entry .submit-button").css("pointer-events", "none");
1078
+ const isModernLayout = ${JSON.stringify((layout || "").startsWith("Modern chat"))};
1079
+ const indicator = isModernLayout
1080
+ ? '<div class="agent-waiting-indicator chat-message chat-assistant"><div class="chat-avatar"><i class="fas fa-robot"></i></div><div class="chat-bubble"><div class="typing-dots"><span></span><span></span><span></span></div></div></div>'
1081
+ : '<div class="agent-waiting-indicator"><div class="typing-dots"><span></span><span></span><span></span></div></div>';
1082
+ $('div.next_response_scratch').before(indicator);
1083
+ scrollAgentToBottom();
1049
1084
  };`,
1050
1085
  stream &&
1051
1086
  domReady(
package/common.js CHANGED
@@ -489,6 +489,8 @@ const process_interaction = async (
489
489
  chat,
490
490
  req,
491
491
  run,
492
+ agent_view_config: agentsViewCfg,
493
+ dyn_updates,
492
494
  async generate(prompt, opts = {}) {
493
495
  generateUsed = true;
494
496
  return await sysState.functions.llm_generate.run(prompt, {
@@ -635,7 +637,7 @@ const process_interaction = async (
635
637
  return {
636
638
  json: {
637
639
  success: "ok",
638
- ...(is_sub_agent ? { raw_responses } : {}),
640
+ ...(is_sub_agent && !stream ? { raw_responses } : {}),
639
641
  response: [...prevResponses, ...responses].join(""),
640
642
  run_id: run?.id,
641
643
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saltcorn/agents",
3
- "version": "0.7.5",
3
+ "version": "0.7.6",
4
4
  "description": "AI agents for Saltcorn",
5
5
  "main": "index.js",
6
6
  "dependencies": {
@@ -78,8 +78,10 @@ class SubagentToSkill {
78
78
  emit_update,
79
79
  run,
80
80
  chat,
81
+ agent_view_config,
82
+ dyn_updates,
81
83
  }) => {
82
- getState().log(6, "Running subagent", this.agent_name);
84
+ getState().log(6, "Running subagent", this.agent_name);
83
85
  const subres = await agent_action.run({
84
86
  row: {},
85
87
  configuration: {
@@ -91,9 +93,15 @@ class SubagentToSkill {
91
93
  user: req.user,
92
94
  run_id: run.id,
93
95
  is_sub_agent: true,
96
+ agent_view_config,
97
+ dyn_updates,
94
98
  req,
95
99
  });
96
- getState().log(6, "Subagent response", subres.json.raw_responses);
100
+ getState().log(
101
+ 6,
102
+ "Subagent response",
103
+ subres?.json?.raw_responses || "No response",
104
+ );
97
105
 
98
106
  if (subres.json.raw_responses)
99
107
  return { add_responses: subres.json.raw_responses };