bunnyquery 1.3.0 → 1.3.2

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/bunnyquery.css CHANGED
@@ -828,6 +828,13 @@
828
828
  .bq-modal-desc { margin: 0 0 1.25rem; font-size: 0.85rem; color: var(--bq-muted); line-height: 1.6; }
829
829
  .bq-modal-btns { display: flex; gap: 0.75rem; justify-content: flex-end; align-items: center; }
830
830
 
831
+ /* upload error report dialog (failed files grouped by error) */
832
+ .bq-upload-error-list { display: flex; flex-direction: column; gap: 0.85rem; margin: 0 0 1.25rem; max-height: 50vh; overflow-y: auto; }
833
+ .bq-upload-error-group { border-left: 3px solid var(--bq-danger); padding-left: 0.7rem; }
834
+ .bq-upload-error-heading { margin: 0 0 0.3rem; font-size: 0.82rem; font-weight: 600; color: var(--bq-danger); word-break: break-word; }
835
+ .bq-upload-error-files { margin: 0; padding-left: 1.1rem; font-size: 0.8rem; color: var(--bq-ink); }
836
+ .bq-upload-error-files li { margin: 0.1rem 0; word-break: break-word; }
837
+
831
838
  /* delete/clear (danger) modal accents */
832
839
  .bq-modal-delete-header {
833
840
  display: flex;
package/bunnyquery.js CHANGED
@@ -80,6 +80,28 @@ Extracted content of attached office files (read inline below; do NOT fetch thei
80
80
  return { composed, composedForLlm, extractContent };
81
81
  }
82
82
 
83
+ // src/engine/attachments.ts
84
+ function groupAttachmentFailures(attachments) {
85
+ const groups = {};
86
+ const order = [];
87
+ (attachments || []).forEach(function(att) {
88
+ if (!att || att.status !== "error" && att.status !== "indexError") return;
89
+ const code = String(att.errorCode || "");
90
+ const message = String(
91
+ att.errorDetail || att.errorMessage || (att.status === "indexError" ? "File indexing failed" : "File upload has failed")
92
+ );
93
+ const key = code + "\0" + message;
94
+ if (!groups[key]) {
95
+ groups[key] = { code, message, files: [] };
96
+ order.push(key);
97
+ }
98
+ groups[key].files.push(String(att.name || "(unnamed file)"));
99
+ });
100
+ return order.map(function(k) {
101
+ return groups[k];
102
+ });
103
+ }
104
+
83
105
  // src/engine/prompts/chat_system_prompt.ts
84
106
  function buildChatSystemPrompt(params) {
85
107
  const { formattedServiceId, serviceName, serviceDescription } = params;
@@ -1696,6 +1718,8 @@ ${options.inlineContentPlaceholder}
1696
1718
  att.status = "uploading";
1697
1719
  att.progress = 0;
1698
1720
  att.errorMessage = "";
1721
+ att.errorCode = "";
1722
+ att.errorDetail = "";
1699
1723
  this.host.renderAttachmentChips();
1700
1724
  var members = att.kind === "folder" ? (att.files || []).map(function(f) {
1701
1725
  return { file: f.file, relPath: f.path, storagePath: self.host.storagePathFor(f.path) };
@@ -1777,6 +1801,10 @@ ${options.inlineContentPlaceholder}
1777
1801
  }, function(e) {
1778
1802
  console.error("[chat-engine] indexing request failed", e);
1779
1803
  anyIndexFailed = true;
1804
+ if (!att.errorCode && !att.errorDetail) {
1805
+ att.errorCode = e && (e.code || e.body && e.body.code) || "";
1806
+ att.errorDetail = e && (e.message || e.body && e.body.message) || (typeof e === "string" ? e : "");
1807
+ }
1780
1808
  });
1781
1809
  });
1782
1810
  });
@@ -1831,6 +1859,8 @@ ${options.inlineContentPlaceholder}
1831
1859
  if (removed || aborted) return;
1832
1860
  att.status = "error";
1833
1861
  att.errorMessage = "File upload has failed";
1862
+ att.errorCode = err && (err.code || err.body && err.body.code) || "";
1863
+ att.errorDetail = err && (err.message || err.body && err.body.message) || (typeof err === "string" ? err : "");
1834
1864
  self.host.renderAttachmentChips();
1835
1865
  });
1836
1866
  });
@@ -3561,10 +3591,13 @@ ${options.inlineContentPlaceholder}
3561
3591
  var bgBefore = bgTaskQueue.length;
3562
3592
  session.uploadPendingAttachments().then(function(attachmentUrls) {
3563
3593
  var hasNewIndexing = bgTaskQueue.length > bgBefore;
3594
+ var failureGroups = groupAttachmentFailures(CS.attachments);
3564
3595
  clearSuccessfulAttachments();
3565
- if (!text) return;
3566
- var c = composeUserMessage(text, attachmentUrls);
3567
- session.dispatchComposedMessage(c.composed, hasNewIndexing, c.composedForLlm, c.extractContent);
3596
+ if (text) {
3597
+ var c = composeUserMessage(text, attachmentUrls);
3598
+ session.dispatchComposedMessage(c.composed, hasNewIndexing, c.composedForLlm, c.extractContent);
3599
+ }
3600
+ if (failureGroups.length) showUploadErrorReport(failureGroups);
3568
3601
  }).catch(function(err) {
3569
3602
  console.error("[bunnyquery] attachment upload failed", err);
3570
3603
  CS.uploadingAttachments = false;
@@ -4730,6 +4763,45 @@ ${options.inlineContentPlaceholder}
4730
4763
  }, { dismissible: false });
4731
4764
  });
4732
4765
  }
4766
+ function showUploadErrorReport(groups) {
4767
+ if (!groups || !groups.length) return;
4768
+ var totalFiles = groups.reduce(function(n, g) {
4769
+ return n + g.files.length;
4770
+ }, 0);
4771
+ openModal(function(close) {
4772
+ var sections = groups.map(function(g) {
4773
+ var heading = g.code ? g.code + " \u2014 " + g.message : g.message;
4774
+ return h(
4775
+ "div",
4776
+ { class: "bq-upload-error-group" },
4777
+ h("p", { class: "bq-upload-error-heading", text: heading }),
4778
+ h(
4779
+ "ul",
4780
+ { class: "bq-upload-error-files" },
4781
+ g.files.map(function(name) {
4782
+ return h("li", { text: name });
4783
+ })
4784
+ )
4785
+ );
4786
+ });
4787
+ return h(
4788
+ "div",
4789
+ { class: "bq-modal" },
4790
+ h(
4791
+ "div",
4792
+ { class: "bq-modal-delete-header" },
4793
+ h("span", { text: totalFiles === 1 ? "1 file could not be added" : totalFiles + " files could not be added" })
4794
+ ),
4795
+ h("p", { class: "bq-modal-desc", text: "These files were not added to your message. They stay in the attachment row so you can remove or retry them." }),
4796
+ h("div", { class: "bq-upload-error-list" }, sections),
4797
+ h(
4798
+ "div",
4799
+ { class: "bq-modal-btns" },
4800
+ h("button", { class: "btn btn--outline", type: "button", onclick: close }, "Close")
4801
+ )
4802
+ );
4803
+ });
4804
+ }
4733
4805
  function agentBadgeText() {
4734
4806
  if (S.aiPlatform === "none") return "No agent configured";
4735
4807
  return S.serviceName ? "BunnyQuery \xB7 " + S.serviceName : "BunnyQuery";
package/dist/engine.cjs CHANGED
@@ -79,6 +79,28 @@ Extracted content of attached office files (read inline below; do NOT fetch thei
79
79
  return { composed, composedForLlm, extractContent };
80
80
  }
81
81
 
82
+ // src/engine/attachments.ts
83
+ function groupAttachmentFailures(attachments) {
84
+ const groups = {};
85
+ const order = [];
86
+ (attachments || []).forEach(function(att) {
87
+ if (!att || att.status !== "error" && att.status !== "indexError") return;
88
+ const code = String(att.errorCode || "");
89
+ const message = String(
90
+ att.errorDetail || att.errorMessage || (att.status === "indexError" ? "File indexing failed" : "File upload has failed")
91
+ );
92
+ const key = code + "\0" + message;
93
+ if (!groups[key]) {
94
+ groups[key] = { code, message, files: [] };
95
+ order.push(key);
96
+ }
97
+ groups[key].files.push(String(att.name || "(unnamed file)"));
98
+ });
99
+ return order.map(function(k) {
100
+ return groups[k];
101
+ });
102
+ }
103
+
82
104
  // src/engine/prompts/chat_system_prompt.ts
83
105
  function buildChatSystemPrompt(params) {
84
106
  const { formattedServiceId, serviceName, serviceDescription } = params;
@@ -1723,6 +1745,8 @@ var ChatSession = class {
1723
1745
  att.status = "uploading";
1724
1746
  att.progress = 0;
1725
1747
  att.errorMessage = "";
1748
+ att.errorCode = "";
1749
+ att.errorDetail = "";
1726
1750
  this.host.renderAttachmentChips();
1727
1751
  var members = att.kind === "folder" ? (att.files || []).map(function(f) {
1728
1752
  return { file: f.file, relPath: f.path, storagePath: self.host.storagePathFor(f.path) };
@@ -1804,6 +1828,10 @@ var ChatSession = class {
1804
1828
  }, function(e) {
1805
1829
  console.error("[chat-engine] indexing request failed", e);
1806
1830
  anyIndexFailed = true;
1831
+ if (!att.errorCode && !att.errorDetail) {
1832
+ att.errorCode = e && (e.code || e.body && e.body.code) || "";
1833
+ att.errorDetail = e && (e.message || e.body && e.body.message) || (typeof e === "string" ? e : "");
1834
+ }
1807
1835
  });
1808
1836
  });
1809
1837
  });
@@ -1858,6 +1886,8 @@ var ChatSession = class {
1858
1886
  if (removed || aborted) return;
1859
1887
  att.status = "error";
1860
1888
  att.errorMessage = "File upload has failed";
1889
+ att.errorCode = err && (err.code || err.body && err.body.code) || "";
1890
+ att.errorDetail = err && (err.message || err.body && err.body.message) || (typeof err === "string" ? err : "");
1861
1891
  self.host.renderAttachmentChips();
1862
1892
  });
1863
1893
  });
@@ -1922,6 +1952,7 @@ exports.getChatHistory = getChatHistory;
1922
1952
  exports.getContextWindow = getContextWindow;
1923
1953
  exports.getErrorMessage = getErrorMessage;
1924
1954
  exports.getExpiredAttachmentVisiblePath = getExpiredAttachmentVisiblePath;
1955
+ exports.groupAttachmentFailures = groupAttachmentFailures;
1925
1956
  exports.isAuthExpiredError = isAuthExpiredError;
1926
1957
  exports.isErrorResponseBody = isErrorResponseBody;
1927
1958
  exports.isOfficeFile = isOfficeFile;