@saltcorn/agents 0.6.2 → 0.6.3

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 (2) hide show
  1. package/agent-view.js +117 -34
  2. package/package.json +1 -1
package/agent-view.js CHANGED
@@ -169,6 +169,7 @@ const uploadForm = (viewname, req) =>
169
169
  type: "file",
170
170
  class: "d-none",
171
171
  accept: "image/*",
172
+ multiple: true,
172
173
  onchange: `agent_file_attach(event)`,
173
174
  }),
174
175
  span({ class: "ms-2 filename-label" }),
@@ -584,9 +585,15 @@ const run = async (
584
585
  cursor: pointer;
585
586
  }
586
587
  .copilot-entry span.attach_agent_image_wrap {
587
- position: relative;
588
+ position: relative;
588
589
  top: -1.8rem;
589
- left: 0.2rem;
590
+ left: 0.2rem;
591
+ }
592
+ .copilot-entry.dragover {
593
+ outline: 2px dashed var(--tblr-primary, #0054a6);
594
+ outline-offset: -2px;
595
+ background: var(--tblr-primary-bg-subtle, rgba(0, 84, 166, 0.05));
596
+ border-radius: 0.25rem;
590
597
  }
591
598
  .copilot-entry .explainer {
592
599
  position: relative;
@@ -620,9 +627,15 @@ const run = async (
620
627
  }
621
628
  function processCopilotResponse(res) {
622
629
  console.log("processCopilotResponse", res)
623
- const hadFile = $("input#attach_agent_image").val();
624
- let fileBadge = hadFile ? '<span class="badge text-bg-info"><i class="fas fa-image me-1"></i>'+$("input#attach_agent_image")[0].files?.item?.(0)?.name||"File"+'</span>': ""
625
- $("span.filename-label").text("");
630
+ const fileInput = $("input#attach_agent_image")[0];
631
+ let fileBadge = "";
632
+ if (fileInput?.files?.length) {
633
+ fileBadge = Array.from(fileInput.files).map(f =>
634
+ '<span class="badge text-bg-info"><i class="fas fa-image me-1"></i>'+f.name+'</span>'
635
+ ).join(" ");
636
+ }
637
+ $("span.filename-label").text("").removeClass("me-2");
638
+ _agentDT.items.clear();
626
639
  $("input#attach_agent_image").val(null);
627
640
  $("#sendbuttonicon").attr("class","far fa-paper-plane");
628
641
  const $runidin= $("input[name=run_id")
@@ -639,8 +652,32 @@ const run = async (
639
652
  $("#copilotinteractions").append(res.response)
640
653
  }
641
654
  window.processCopilotResponse = processCopilotResponse;
655
+ const _agentDT = new DataTransfer();
656
+ function setAgentFiles(files) {
657
+ for (const f of files) _agentDT.items.add(f);
658
+ document.getElementById('attach_agent_image').files = _agentDT.files;
659
+ updateFileLabel();
660
+ }
661
+ function updateFileLabel() {
662
+ const n = _agentDT.files.length;
663
+ const $label = $(".attach_agent_image_wrap span.filename-label");
664
+ if (n === 0) {
665
+ $label.html("").removeClass("me-2");
666
+ } else {
667
+ $label.addClass("me-2");
668
+ const text = n === 1 ? _agentDT.files[0].name : n + " files";
669
+ $label.html(text + ' <span class="badge text-bg-secondary" style="cursor:pointer;font-size:.65em;vertical-align:middle" onclick="clearAgentFiles()" title="Remove files">&times;</span>');
670
+ }
671
+ }
672
+ function clearAgentFiles() {
673
+ _agentDT.items.clear();
674
+ $("input#attach_agent_image").val(null);
675
+ updateFileLabel();
676
+ }
677
+ window.clearAgentFiles = clearAgentFiles;
642
678
  function agent_file_attach(e) {
643
- $(".attach_agent_image_wrap span.filename-label").text(e.target.files[0].name)
679
+ _agentDT.items.clear();
680
+ setAgentFiles(e.target.files);
644
681
  }
645
682
  function restore_old_button_elem(btn) {
646
683
  const oldText = $(btn).data("old-text");
@@ -692,6 +729,44 @@ const run = async (
692
729
  }
693
730
  }
694
731
  document.getElementById("inputuserinput").addEventListener("keydown", submitOnEnter);
732
+ if (document.getElementById('attach_agent_image')) {
733
+ let _dragCtr = 0;
734
+ const _copilotEntry = document.querySelector('.copilot-entry');
735
+ _copilotEntry.addEventListener('dragover', function(e) {
736
+ e.preventDefault();
737
+ });
738
+ _copilotEntry.addEventListener('dragenter', function(e) {
739
+ e.preventDefault();
740
+ _dragCtr++;
741
+ this.classList.add('dragover');
742
+ });
743
+ _copilotEntry.addEventListener('dragleave', function(e) {
744
+ _dragCtr--;
745
+ if (_dragCtr === 0) this.classList.remove('dragover');
746
+ });
747
+ _copilotEntry.addEventListener('drop', function(e) {
748
+ e.preventDefault();
749
+ _dragCtr = 0;
750
+ this.classList.remove('dragover');
751
+ const imgs = Array.from(e.dataTransfer.files).filter(f => f.type.startsWith('image/'));
752
+ if (imgs.length) setAgentFiles(imgs);
753
+ });
754
+ document.getElementById('inputuserinput').addEventListener('paste', function(e) {
755
+ const items = e.clipboardData?.items;
756
+ if (!items) return;
757
+ const pastedFiles = [];
758
+ for (const item of items) {
759
+ if (item.type.startsWith('image/')) {
760
+ const file = item.getAsFile();
761
+ if (file) pastedFiles.push(file);
762
+ }
763
+ }
764
+ if (pastedFiles.length) {
765
+ e.preventDefault();
766
+ setAgentFiles(pastedFiles);
767
+ }
768
+ });
769
+ }
695
770
  function spin_send_button() {
696
771
  $("#sendbuttonicon").attr("class","fas fa-spinner fa-spin");
697
772
  };`,
@@ -753,35 +828,43 @@ const interact = async (table_id, viewname, config, body, { req, res }) => {
753
828
  }
754
829
  let fileBadges = "";
755
830
  if (config.image_upload && req.files?.file) {
756
- const file = await File.from_req_files(
757
- req.files.file,
758
- req.user ? req.user.id : null,
759
- 100,
760
- // file_field?.attributes?.folder
761
- );
762
- fileBadges = span(
763
- { class: "badge text-bg-info" },
764
- i({ class: "fas fa-image me-1" }),
765
- file.filename,
766
- );
767
- const baseUrl = getState().getConfig("base_url").replace(/\/$/, "");
768
- let imageurl;
769
- if (
770
- !config.image_base64 &&
771
- baseUrl &&
772
- !baseUrl.includes("http://localhost:")
773
- ) {
774
- imageurl = `${baseUrl}/files/serve/${file.path_to_serve}`;
775
- } else {
776
- const b64 = await file.get_contents("base64");
777
- imageurl = `data:${file.mimetype};base64,${b64}`;
831
+ const rawFiles = Array.isArray(req.files.file)
832
+ ? req.files.file
833
+ : [req.files.file];
834
+ const badges = [];
835
+ for (const rawFile of rawFiles) {
836
+ const file = await File.from_req_files(
837
+ rawFile,
838
+ req.user ? req.user.id : null,
839
+ 100,
840
+ );
841
+ badges.push(
842
+ span(
843
+ { class: "badge text-bg-info" },
844
+ i({ class: "fas fa-image me-1" }),
845
+ file.filename,
846
+ ),
847
+ );
848
+ const baseUrl = getState().getConfig("base_url").replace(/\/$/, "");
849
+ let imageurl;
850
+ if (
851
+ !config.image_base64 &&
852
+ baseUrl &&
853
+ !baseUrl.includes("http://localhost:")
854
+ ) {
855
+ imageurl = `${baseUrl}/files/serve/${file.path_to_serve}`;
856
+ } else {
857
+ const b64 = await file.get_contents("base64");
858
+ imageurl = `data:${file.mimetype};base64,${b64}`;
859
+ }
860
+ await getState().functions.llm_add_message.run("image", imageurl, {
861
+ chat: run.context.interactions || [],
862
+ });
863
+ await addToContext(run, {
864
+ interactions: run.context.interactions || [],
865
+ });
778
866
  }
779
- await getState().functions.llm_add_message.run("image", imageurl, {
780
- chat: run.context.interactions || [],
781
- });
782
- await addToContext(run, {
783
- interactions: run.context.interactions || [],
784
- });
867
+ fileBadges = badges.join("");
785
868
  }
786
869
  await addToContext(run, {
787
870
  interactions: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saltcorn/agents",
3
- "version": "0.6.2",
3
+ "version": "0.6.3",
4
4
  "description": "AI agents for Saltcorn",
5
5
  "main": "index.js",
6
6
  "dependencies": {