bunnyquery 1.5.2 → 1.5.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/bunnyquery.css CHANGED
@@ -246,14 +246,16 @@
246
246
  /* ============================================================================
247
247
  * AUTH VIEWS (login / signup / forgot / verify / settings)
248
248
  * ==========================================================================*/
249
- /* padded parent that nests a standalone page (login / signup / verify / …) */
249
+ /* padded parent that nests a standalone page (login / signup / verify / …).
250
+ Sits below the shared .bq-section-title header (the top-left service badge),
251
+ so the top padding is small — the header supplies the top spacing. */
250
252
  .bq-page {
251
253
  flex: 1;
252
254
  min-height: 0;
253
255
  overflow-y: auto;
254
256
  display: flex;
255
257
  flex-direction: column;
256
- padding: 2.5rem 1.5rem;
258
+ padding: 1rem 1.5rem 2.5rem;
257
259
  }
258
260
  .bq-settings {
259
261
  flex: 1;
@@ -264,6 +266,15 @@
264
266
  color: var(--bq-ink);
265
267
  }
266
268
 
269
+ /* full-box loading view: fill the space above the footer and center the bunny */
270
+ .bq-page-loading {
271
+ flex: 1;
272
+ min-height: 0;
273
+ display: flex;
274
+ align-items: center;
275
+ justify-content: center;
276
+ }
277
+
267
278
  .bq-page-footer {
268
279
  flex-shrink: 0;
269
280
  text-align: center;
@@ -276,6 +287,12 @@
276
287
  text-decoration: none;
277
288
  }
278
289
  .bq-page-footer-link:hover { text-decoration: underline; }
290
+ .bq-page-footer-version {
291
+ font-family: var(--bq-mono);
292
+ font-size: 0.7rem;
293
+ color: var(--bq-muted);
294
+ margin-top: 0.25rem;
295
+ }
279
296
 
280
297
  .bq-settings-title {
281
298
  font-size: 1.5rem;
@@ -559,11 +576,11 @@
559
576
  align-items: center;
560
577
  gap: 0.45rem;
561
578
  padding: 0.3rem 0.6rem;
562
- border: 1px solid var(--bq-line);
563
- background: var(--bq-paper);
579
+ border: 1px solid var(--bq-main);
580
+ background: var(--bq-main-bg);
564
581
  font-size: 0.75rem;
565
582
  font-family: var(--bq-mono);
566
- color: var(--bq-ink);
583
+ color: var(--bq-main);
567
584
  max-width: 100%;
568
585
  overflow: hidden;
569
586
  }
@@ -608,7 +625,16 @@
608
625
  margin: 0 auto;
609
626
  padding: 1.25rem 0 2rem;
610
627
  }
611
- .bq-chat-settings-loading { text-align: center; padding: 2.5rem 0; color: var(--bq-muted); }
628
+ /* fill the messages box and center the bunny (matches .bq-history-loading.is-initial).
629
+ Resolves against .bq-messages (position: relative), not the max-width settings wrap. */
630
+ .bq-chat-settings-loading {
631
+ position: absolute;
632
+ inset: 0;
633
+ display: flex;
634
+ align-items: center;
635
+ justify-content: center;
636
+ color: var(--bq-muted);
637
+ }
612
638
 
613
639
  /* chat container + scroll area */
614
640
  .bq-chat {
@@ -756,6 +782,8 @@
756
782
  .bq-input::placeholder { color: var(--bq-placeholder); }
757
783
  .bq-input:focus { outline: none; border-color: var(--bq-ink); }
758
784
  .bq-input:disabled { opacity: 0.5; cursor: default; }
785
+ /* Attach button hidden (frozen DB): reclaim the reserved left gutter. */
786
+ .bq-input.bq-input--noattach { padding-left: 0.7rem; }
759
787
  .bq-input-row .btn {
760
788
  align-self: flex-end;
761
789
  min-width: 5.5rem;
package/bunnyquery.js CHANGED
@@ -1794,22 +1794,22 @@ ${options.inlineContentPlaceholder}
1794
1794
  var id = this.host.getIdentity();
1795
1795
  var svcId = id.serviceId, plat = id.platform;
1796
1796
  if (!svcId || plat === "none" || !this.host.isViewMounted()) return;
1797
+ var presentIds = {};
1798
+ var pendingIds = {};
1799
+ this.state.messages.forEach(function(m) {
1800
+ var sid = m._serverItemId;
1801
+ if (sid == null) return;
1802
+ presentIds[sid] = true;
1803
+ if (m.isPending || m.isPendingInProcess || m.isPendingQueued) pendingIds[sid] = true;
1804
+ });
1797
1805
  for (var i = this.bgTaskQueue.length - 1; i >= 0; i--) {
1798
1806
  var e = this.bgTaskQueue[i];
1799
1807
  if (e.serviceId !== svcId || e.platform !== plat) continue;
1800
- var present = this.state.messages.some(function(m) {
1801
- return m._serverItemId === e.id;
1802
- });
1803
- var stillPending = this.state.messages.some(function(m) {
1804
- return m._serverItemId === e.id && (m.isPending || m.isPendingInProcess || m.isPendingQueued);
1805
- });
1806
- if (present && !stillPending) this.bgTaskQueue.splice(i, 1);
1808
+ if (presentIds[e.id] && !pendingIds[e.id]) this.bgTaskQueue.splice(i, 1);
1807
1809
  }
1808
1810
  this.bgTaskQueue.forEach(function(entry) {
1809
1811
  if (entry.serviceId !== svcId || entry.platform !== plat) return;
1810
- if (self.state.messages.some(function(m) {
1811
- return m._serverItemId === entry.id;
1812
- })) return;
1812
+ if (presentIds[entry.id]) return;
1813
1813
  var isRunning = entry.status === "running";
1814
1814
  var userBubble = { role: "user", content: self.host.formatIndexingLabel(entry.filename, entry.mime, entry.size, entry.storagePath, entry.isReindex), isBackgroundTask: true, _serverItemId: entry.id };
1815
1815
  if (isRunning) userBubble.isPendingInProcess = true;
@@ -1818,6 +1818,7 @@ ${options.inlineContentPlaceholder}
1818
1818
  if (isRunning) {
1819
1819
  self.state.messages.push({ role: "assistant", content: "", isPending: true, isPendingInProcess: true, isBackgroundTask: true, _serverItemId: entry.id });
1820
1820
  }
1821
+ presentIds[entry.id] = true;
1821
1822
  self.host.notify();
1822
1823
  self.updateHistoryCache();
1823
1824
  self.host.scrollToBottom(false);
@@ -2213,7 +2214,7 @@ ${options.inlineContentPlaceholder}
2213
2214
  (function() {
2214
2215
  var MCP_PROD = "https://mcp.broadwayinc.computer";
2215
2216
  var MCP_DEV = "https://mcp-dev.broadwayinc.computer";
2216
- var BQ_VERSION = "1.5.1" ;
2217
+ var BQ_VERSION = "1.5.4" ;
2217
2218
  var ATTACHMENT_URL_EXPIRES_SECONDS = 600;
2218
2219
  var GOOGLE_AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth";
2219
2220
  var GOOGLE_TOKEN_URL = "https://oauth2.googleapis.com/token";
@@ -2453,7 +2454,29 @@ ${options.inlineContentPlaceholder}
2453
2454
  if (node) S.root.appendChild(node);
2454
2455
  }
2455
2456
  function pageRoot(content) {
2456
- return h("div", { class: "bq-page" }, h("div", { class: "bq-settings" }, content), pageFooter());
2457
+ return h(
2458
+ "div",
2459
+ { class: "bq-meta" },
2460
+ h(
2461
+ "div",
2462
+ { class: "bq-section-title" },
2463
+ h(
2464
+ "div",
2465
+ { class: "bq-title-row" },
2466
+ h(
2467
+ "div",
2468
+ { class: "bq-title-left" },
2469
+ h("span", { class: "bq-agent-badge", text: agentBadgeText() })
2470
+ )
2471
+ )
2472
+ ),
2473
+ h(
2474
+ "div",
2475
+ { class: "bq-page" },
2476
+ h("div", { class: "bq-settings" }, content),
2477
+ pageFooter()
2478
+ )
2479
+ );
2457
2480
  }
2458
2481
  function pageFooter() {
2459
2482
  return h(
@@ -2465,7 +2488,8 @@ ${options.inlineContentPlaceholder}
2465
2488
  target: "_blank",
2466
2489
  rel: "noopener noreferrer",
2467
2490
  text: "www.bunnyquery.com"
2468
- })
2491
+ }),
2492
+ h("div", { class: "bq-page-footer-version", text: "v" + BQ_VERSION })
2469
2493
  );
2470
2494
  }
2471
2495
  var BUNNY_FRAME_A = ' (\\(\\\n ( - -)\n c(")(")';
@@ -2497,12 +2521,15 @@ ${options.inlineContentPlaceholder}
2497
2521
  }
2498
2522
  function showLoading(label) {
2499
2523
  render("loading", function() {
2500
- return pageRoot(
2524
+ return h(
2525
+ "div",
2526
+ { class: "bq-page" },
2501
2527
  h(
2502
2528
  "div",
2503
- { class: "bq-disabled-inner", style: { marginTop: "3rem" } },
2529
+ { class: "bq-page-loading" },
2504
2530
  bunnyLoader("Loading...")
2505
- )
2531
+ ),
2532
+ pageFooter()
2506
2533
  );
2507
2534
  });
2508
2535
  }
@@ -2917,8 +2944,21 @@ ${options.inlineContentPlaceholder}
2917
2944
  }
2918
2945
  function authShell(title, children, opts) {
2919
2946
  opts = opts || {};
2920
- var kids = authHeader(title).concat(children);
2921
- if (opts.back !== false) {
2947
+ var kids = [];
2948
+ if (opts.topBack) {
2949
+ kids.push(h(
2950
+ "div",
2951
+ { class: "bq-settings-top" },
2952
+ h("button", {
2953
+ class: "bq-link",
2954
+ type: "button",
2955
+ onclick: opts.topBack.onClick,
2956
+ text: opts.topBack.label || "\u2190 Back"
2957
+ })
2958
+ ));
2959
+ }
2960
+ kids = kids.concat(authHeader(title)).concat(children);
2961
+ if (opts.back !== false && !opts.topBack) {
2922
2962
  kids.push(h(
2923
2963
  "div",
2924
2964
  { class: "bq-actions", style: { marginTop: "1.5rem" } },
@@ -3313,7 +3353,13 @@ ${options.inlineContentPlaceholder}
3313
3353
  note,
3314
3354
  h("div", { class: "bq-form-bottom" }, btn)
3315
3355
  )
3316
- ], { back: false });
3356
+ ], { topBack: {
3357
+ label: "\u2190 Back to settings",
3358
+ onClick: function() {
3359
+ renderChat();
3360
+ openChatSettings();
3361
+ }
3362
+ } });
3317
3363
  sendCode(note);
3318
3364
  return shell;
3319
3365
  }
@@ -3768,6 +3814,8 @@ ${options.inlineContentPlaceholder}
3768
3814
  // [{ id, name, file, status, progress, uploadedUrl, storagePath, errorMessage }]
3769
3815
  uploadingAttachments: false,
3770
3816
  attachmentWarning: "",
3817
+ attachmentCapHit: false,
3818
+ // true once an add hit MAX_ATTACHMENT_FILE_COUNT; blocks the composer
3771
3819
  attachmentsRow: null,
3772
3820
  // .bq-attachments DOM node
3773
3821
  attachBtnEl: null,
@@ -4201,7 +4249,7 @@ ${options.inlineContentPlaceholder}
4201
4249
  return (reindex ? "Reindexing: " : "Indexing: ") + nameLabel + (extras.length ? " \xB7 " + extras.join(" \xB7 ") : "");
4202
4250
  }
4203
4251
  function sanitizeStorageSegment(name) {
4204
- var n = String(name == null ? "file" : name).trim().replace(/[^A-Za-z0-9._-]+/g, "_").replace(/_{2,}/g, "_").replace(/^[_]+/, "");
4252
+ var n = String(name == null ? "file" : name).normalize("NFC").trim().replace(/[^\p{L}\p{N}._ -]+/gu, "_").replace(/ {2,}/g, " ").replace(/_{2,}/g, "_").replace(/^[_ ]+/, "");
4205
4253
  return n || "file";
4206
4254
  }
4207
4255
  function attachmentStoragePath(relPath) {
@@ -4285,6 +4333,8 @@ ${options.inlineContentPlaceholder}
4285
4333
  var FILE_ICON_SVG = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>';
4286
4334
  var FOLDER_ICON_SVG = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>';
4287
4335
  var MAX_CHATBOX_FILE_COUNT = 20;
4336
+ var MAX_ATTACHMENT_FILE_COUNT = 100;
4337
+ var VISIBLE_CHIP_CAP = 30;
4288
4338
  var ESTIMATED_BYTES_PER_TOKEN = 3;
4289
4339
  var ESTIMATED_PDF_BYTES_PER_TOKEN = 5e3;
4290
4340
  var ESTIMATED_IMAGE_TOKENS = 800;
@@ -4337,6 +4387,10 @@ ${options.inlineContentPlaceholder}
4337
4387
  return el ? (el.value || "").trim() : "";
4338
4388
  }
4339
4389
  function recomputeAttachmentWarning() {
4390
+ if (CS.attachmentCapHit) {
4391
+ CS.attachmentWarning = "You can attach up to " + MAX_ATTACHMENT_FILE_COUNT + " files per message.";
4392
+ return;
4393
+ }
4340
4394
  if (!currentChatInputText()) {
4341
4395
  CS.attachmentWarning = "";
4342
4396
  return;
@@ -4379,19 +4433,36 @@ ${options.inlineContentPlaceholder}
4379
4433
  CS.attachments.forEach(function(a) {
4380
4434
  seen[attachmentKey(a)] = true;
4381
4435
  });
4436
+ var remaining = MAX_ATTACHMENT_FILE_COUNT - attachmentFileCount();
4437
+ var dropped = 0;
4382
4438
  var changed = false;
4383
4439
  (attObjs || []).forEach(function(a) {
4384
4440
  if (!a) return;
4385
4441
  var k = attachmentKey(a);
4386
4442
  if (seen[k]) return;
4443
+ var count = a.kind === "folder" ? a.files ? a.files.length : 0 : 1;
4444
+ if (remaining <= 0) {
4445
+ dropped += count;
4446
+ return;
4447
+ }
4448
+ if (a.kind === "folder" && count > remaining) {
4449
+ dropped += count - remaining;
4450
+ a.files = a.files.slice(0, remaining);
4451
+ count = remaining;
4452
+ }
4387
4453
  seen[k] = true;
4388
4454
  CS.attachments.push(a);
4455
+ remaining -= count;
4389
4456
  changed = true;
4390
4457
  });
4458
+ if (dropped > 0) CS.attachmentCapHit = true;
4391
4459
  if (changed) {
4392
4460
  recomputeAttachmentWarning();
4393
4461
  renderAttachmentChips();
4394
4462
  scheduleAttachmentOverflowRecompute();
4463
+ } else if (dropped > 0) {
4464
+ recomputeAttachmentWarning();
4465
+ renderAttachmentChips();
4395
4466
  }
4396
4467
  updateComposerControls();
4397
4468
  }
@@ -4466,11 +4537,11 @@ ${options.inlineContentPlaceholder}
4466
4537
  CS.visibleAttachmentCount = Infinity;
4467
4538
  return;
4468
4539
  }
4469
- CS.visibleAttachmentCount = total;
4540
+ var count = Math.min(total, VISIBLE_CHIP_CAP);
4541
+ CS.visibleAttachmentCount = count;
4470
4542
  renderAttachmentChips();
4471
4543
  var maxHeight = chat.clientHeight * ATTACHMENTS_MAX_HEIGHT_RATIO;
4472
4544
  if (maxHeight <= 0) return;
4473
- var count = total;
4474
4545
  while (count > 0 && row.scrollHeight > maxHeight) {
4475
4546
  count--;
4476
4547
  CS.visibleAttachmentCount = count;
@@ -4495,6 +4566,7 @@ ${options.inlineContentPlaceholder}
4495
4566
  return true;
4496
4567
  });
4497
4568
  CS.visibleAttachmentCount = Infinity;
4569
+ CS.attachmentCapHit = false;
4498
4570
  recomputeAttachmentWarning();
4499
4571
  renderAttachmentChips();
4500
4572
  updateComposerControls();
@@ -4513,6 +4585,7 @@ ${options.inlineContentPlaceholder}
4513
4585
  }
4514
4586
  }
4515
4587
  CS.attachments.splice(i, 1);
4588
+ CS.attachmentCapHit = false;
4516
4589
  recomputeAttachmentWarning();
4517
4590
  renderAttachmentChips();
4518
4591
  updateComposerControls();
@@ -4529,6 +4602,7 @@ ${options.inlineContentPlaceholder}
4529
4602
  });
4530
4603
  CS.attachments = [];
4531
4604
  CS.attachmentWarning = "";
4605
+ CS.attachmentCapHit = false;
4532
4606
  renderAttachmentChips();
4533
4607
  updateComposerControls();
4534
4608
  scheduleAttachmentOverflowRecompute();
@@ -4540,6 +4614,7 @@ ${options.inlineContentPlaceholder}
4540
4614
  CS.attachments.forEach(function(a) {
4541
4615
  a._abort = null;
4542
4616
  });
4617
+ CS.attachmentCapHit = false;
4543
4618
  recomputeAttachmentWarning();
4544
4619
  renderAttachmentChips();
4545
4620
  updateComposerControls();
@@ -4576,7 +4651,7 @@ ${options.inlineContentPlaceholder}
4576
4651
  row.appendChild(h("div", { class: "bq-attachment-warning" }, h("span", { text: CS.attachmentWarning })));
4577
4652
  }
4578
4653
  var sorted = sortedAttachments();
4579
- var vis = CS.visibleAttachmentCount;
4654
+ var vis = Math.min(CS.visibleAttachmentCount, VISIBLE_CHIP_CAP);
4580
4655
  var shown = vis >= sorted.length ? sorted : sorted.slice(0, Math.max(0, vis));
4581
4656
  var hidden = sorted.slice(shown.length);
4582
4657
  shown.forEach(function(att) {
@@ -4610,11 +4685,13 @@ ${options.inlineContentPlaceholder}
4610
4685
  row.appendChild(chip);
4611
4686
  });
4612
4687
  if (hidden.length > 0) {
4688
+ var moreNames = hidden.slice(0, 50).map(function(a) {
4689
+ return a.kind === "folder" ? a.name + "/" : a.name;
4690
+ });
4691
+ if (hidden.length > moreNames.length) moreNames.push("...and " + (hidden.length - moreNames.length) + " more");
4613
4692
  var moreChip = h("div", {
4614
4693
  class: "bq-attachment bq-attachment-more",
4615
- title: hidden.map(function(a) {
4616
- return a.kind === "folder" ? a.name + "/" : a.name;
4617
- }).join("\n")
4694
+ title: moreNames.join("\n")
4618
4695
  });
4619
4696
  moreChip.appendChild(h("span", { class: "bq-attachment-name", text: "\u2026(" + hidden.length + ") more" }));
4620
4697
  if (!CS.uploadingAttachments) {
@@ -4646,11 +4723,18 @@ ${options.inlineContentPlaceholder}
4646
4723
  row.appendChild(removeAll);
4647
4724
  }
4648
4725
  }
4726
+ function uploadsFrozenForUser() {
4727
+ var conf = S.service && S.service.conf || {};
4728
+ if (!conf.freeze_database) return false;
4729
+ var ag = S.user && typeof S.user.access_group === "number" ? S.user.access_group : 0;
4730
+ return ag < 99;
4731
+ }
4649
4732
  function updateComposerControls() {
4650
4733
  var uploading = CS.uploadingAttachments;
4651
- if (CS.attachBtnEl) CS.attachBtnEl.disabled = uploading;
4652
- if (CS.inputEl) CS.inputEl.disabled = uploading;
4653
- if (CS.sendBtnEl) CS.sendBtnEl.disabled = uploading || !!CS.attachmentWarning;
4734
+ var blocked = uploading || CS.attachmentCapHit;
4735
+ if (CS.attachBtnEl) CS.attachBtnEl.disabled = blocked;
4736
+ if (CS.inputEl) CS.inputEl.disabled = blocked;
4737
+ if (CS.sendBtnEl) CS.sendBtnEl.disabled = blocked || !!CS.attachmentWarning;
4654
4738
  }
4655
4739
  function onAttachInputChange(inputEl) {
4656
4740
  if (inputEl && inputEl.files && inputEl.files.length) addFilesToAttachments(inputEl.files);
@@ -4983,6 +5067,7 @@ ${options.inlineContentPlaceholder}
4983
5067
  CS.attachments = [];
4984
5068
  CS.uploadingAttachments = false;
4985
5069
  CS.attachmentWarning = "";
5070
+ CS.attachmentCapHit = false;
4986
5071
  CS.attachmentsRow = null;
4987
5072
  CS.attachBtnEl = null;
4988
5073
  CS.sendBtnEl = null;
@@ -5069,15 +5154,20 @@ ${options.inlineContentPlaceholder}
5069
5154
  requestAnimationFrame(function() {
5070
5155
  autoGrowInput(input);
5071
5156
  });
5072
- var attachFileInput = h("input", { class: "bq-attach-input", type: "file", multiple: "multiple" });
5073
- attachFileInput.addEventListener("change", function() {
5074
- onAttachInputChange(attachFileInput);
5075
- });
5076
- var attachBtn = h("button", { class: "bq-attach-btn", type: "button", title: "Attach files", html: ATTACH_ICON_SVG });
5077
- attachBtn.addEventListener("click", function() {
5078
- attachFileInput.click();
5079
- });
5080
- CS.attachBtnEl = attachBtn;
5157
+ var attachDisabled = uploadsFrozenForUser();
5158
+ if (attachDisabled) input.classList.add("bq-input--noattach");
5159
+ var attachFileInput = null, attachBtn = null;
5160
+ if (!attachDisabled) {
5161
+ attachFileInput = h("input", { class: "bq-attach-input", type: "file", multiple: "multiple" });
5162
+ attachFileInput.addEventListener("change", function() {
5163
+ onAttachInputChange(attachFileInput);
5164
+ });
5165
+ attachBtn = h("button", { class: "bq-attach-btn", type: "button", title: "Attach files", html: ATTACH_ICON_SVG });
5166
+ attachBtn.addEventListener("click", function() {
5167
+ attachFileInput.click();
5168
+ });
5169
+ CS.attachBtnEl = attachBtn;
5170
+ }
5081
5171
  var attachmentsRow = h("div", { class: "bq-attachments" });
5082
5172
  attachmentsRow.style.display = "none";
5083
5173
  CS.attachmentsRow = attachmentsRow;
@@ -5096,7 +5186,7 @@ ${options.inlineContentPlaceholder}
5096
5186
  chatArea = h("div", { class: "bq-chat" }, box, composer);
5097
5187
  CS.chatEl = chatArea;
5098
5188
  CS.composerEl = composer;
5099
- setupDragAndDrop(chatArea);
5189
+ if (!attachDisabled) setupDragAndDrop(chatArea);
5100
5190
  return h("div", { class: "bq-meta" }, header, chatArea);
5101
5191
  });
5102
5192
  if (S.aiPlatform === "none") return;
@@ -5218,7 +5308,7 @@ ${options.inlineContentPlaceholder}
5218
5308
  }
5219
5309
  function agentBadgeText() {
5220
5310
  if (S.aiPlatform === "none") return "No agent configured";
5221
- return S.serviceName ? "BunnyQuery \xB7 " + S.serviceName : "BunnyQuery";
5311
+ return S.serviceName || "BunnyQuery";
5222
5312
  }
5223
5313
  function parseAiAgentValue(value) {
5224
5314
  var raw = (value || "").trim();
@@ -5272,6 +5362,15 @@ ${options.inlineContentPlaceholder}
5272
5362
  }
5273
5363
  function boot() {
5274
5364
  showLoading();
5365
+ return loadServiceInfo().then(function(conn) {
5366
+ if (conn) {
5367
+ S.service = conn;
5368
+ applyAgentConfig();
5369
+ }
5370
+ }).catch(function() {
5371
+ }).then(bootFlow);
5372
+ }
5373
+ function bootFlow() {
5275
5374
  if (isInboundPlatformOAuth()) {
5276
5375
  stashInboundPlatformOAuth();
5277
5376
  return getProfile().then(function(user) {
package/dist/engine.cjs CHANGED
@@ -1828,22 +1828,22 @@ var ChatSession = class {
1828
1828
  var id = this.host.getIdentity();
1829
1829
  var svcId = id.serviceId, plat = id.platform;
1830
1830
  if (!svcId || plat === "none" || !this.host.isViewMounted()) return;
1831
+ var presentIds = {};
1832
+ var pendingIds = {};
1833
+ this.state.messages.forEach(function(m) {
1834
+ var sid = m._serverItemId;
1835
+ if (sid == null) return;
1836
+ presentIds[sid] = true;
1837
+ if (m.isPending || m.isPendingInProcess || m.isPendingQueued) pendingIds[sid] = true;
1838
+ });
1831
1839
  for (var i = this.bgTaskQueue.length - 1; i >= 0; i--) {
1832
1840
  var e = this.bgTaskQueue[i];
1833
1841
  if (e.serviceId !== svcId || e.platform !== plat) continue;
1834
- var present = this.state.messages.some(function(m) {
1835
- return m._serverItemId === e.id;
1836
- });
1837
- var stillPending = this.state.messages.some(function(m) {
1838
- return m._serverItemId === e.id && (m.isPending || m.isPendingInProcess || m.isPendingQueued);
1839
- });
1840
- if (present && !stillPending) this.bgTaskQueue.splice(i, 1);
1842
+ if (presentIds[e.id] && !pendingIds[e.id]) this.bgTaskQueue.splice(i, 1);
1841
1843
  }
1842
1844
  this.bgTaskQueue.forEach(function(entry) {
1843
1845
  if (entry.serviceId !== svcId || entry.platform !== plat) return;
1844
- if (self.state.messages.some(function(m) {
1845
- return m._serverItemId === entry.id;
1846
- })) return;
1846
+ if (presentIds[entry.id]) return;
1847
1847
  var isRunning = entry.status === "running";
1848
1848
  var userBubble = { role: "user", content: self.host.formatIndexingLabel(entry.filename, entry.mime, entry.size, entry.storagePath, entry.isReindex), isBackgroundTask: true, _serverItemId: entry.id };
1849
1849
  if (isRunning) userBubble.isPendingInProcess = true;
@@ -1852,6 +1852,7 @@ var ChatSession = class {
1852
1852
  if (isRunning) {
1853
1853
  self.state.messages.push({ role: "assistant", content: "", isPending: true, isPendingInProcess: true, isBackgroundTask: true, _serverItemId: entry.id });
1854
1854
  }
1855
+ presentIds[entry.id] = true;
1855
1856
  self.host.notify();
1856
1857
  self.updateHistoryCache();
1857
1858
  self.host.scrollToBottom(false);