bunnyquery 1.4.4 → 1.4.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bunnyquery",
3
- "version": "1.4.4",
3
+ "version": "1.4.5",
4
4
  "description": "Embeddable BunnyQuery AI chat widget + its framework-agnostic chat engine",
5
5
  "main": "bunnyquery.js",
6
6
  "exports": {
@@ -105,11 +105,23 @@ export class ChatSession {
105
105
 
106
106
  dispatchAgentRequest(params: any) {
107
107
  var self = this;
108
+ // Id of the in-flight item this dispatch polls. Recorded in
109
+ // historyItemPolls (set below, deleted when the dispatch settles) so a
110
+ // remount / history refetch dedups against THIS poll instead of stacking
111
+ // a duplicate history poll on the same item. (The cacheKey guard alone
112
+ // stops covering an item once pendingAgentRequests clears — e.g. a queued
113
+ // message still in flight after the immediate one resolved.)
114
+ var dispatchItemId: string | undefined;
108
115
  var sendAndPoll = function () {
109
116
  return Promise.resolve(
110
117
  self._callProviderFor(params.aiPlatform, params.text, params.boundedMessages, params.systemPrompt, params.aiModel, params.userId, params.extractContent)
111
118
  ).then(function (initial: any) {
112
119
  if (initial && initial.poll && (initial.status === 'pending' || initial.status === 'running')) {
120
+ if (initial.id) {
121
+ if (dispatchItemId && dispatchItemId !== initial.id) self.historyItemPolls.delete(dispatchItemId);
122
+ dispatchItemId = initial.id;
123
+ self.historyItemPolls.set(initial.id, true);
124
+ }
113
125
  return initial.poll({ latency: POLL_INTERVAL });
114
126
  }
115
127
  return initial;
@@ -142,6 +154,7 @@ export class ChatSession {
142
154
  // independently of the view lifecycle, so a reply is captured even
143
155
  // if the chatbox unmounted mid-request.
144
156
  delete self.pendingAgentRequests[params.key];
157
+ if (dispatchItemId) self.historyItemPolls.delete(dispatchItemId);
145
158
  var existing = self.aiChatHistoryCache[params.key] || { messages: [], endOfList: false, startKeyHistory: [] };
146
159
  var reply: ChatMessage = { role: 'assistant', content: result.content, isError: result.isError };
147
160
 
@@ -235,6 +248,9 @@ export class ChatSession {
235
248
  self.state.messages[sendingIdx] = upd; self.host.notify();
236
249
  }
237
250
  if (result && result.poll && (result.status === 'pending' || result.status === 'running')) {
251
+ // Track this queued item's poll so a remount/refetch dedups
252
+ // against it instead of attaching a duplicate history poll.
253
+ if (serverId) self.historyItemPolls.set(serverId, true);
238
254
  return result.poll({ latency: POLL_INTERVAL })
239
255
  .then(function (res: any) { return self.onQueuedSendResponse(capturedComposed, res, capturedPlatform, serverId); })
240
256
  .catch(function (err: any) { return self.onQueuedSendError(capturedComposed, err, serverId); });
@@ -372,6 +388,7 @@ export class ChatSession {
372
388
  }
373
389
 
374
390
  onQueuedSendResponse(_composed: string, response: any, platform: string, serverId?: string): void {
391
+ if (serverId) this.historyItemPolls.delete(serverId);
375
392
  var targetIdx = this.resolveQueuedUserBubble(serverId);
376
393
  if (targetIdx === undefined) { this.host.notify(); this.updateHistoryCache(); return; }
377
394
  if (isErrorResponseBody(response)) {
@@ -401,6 +418,7 @@ export class ChatSession {
401
418
 
402
419
  onQueuedSendError(_composed: string, err: any, serverId?: string): void {
403
420
  var self = this;
421
+ if (serverId) this.historyItemPolls.delete(serverId);
404
422
  var isNotExists = err && (err.code === 'NOT_EXISTS' || (err.body && err.body.code === 'NOT_EXISTS'));
405
423
  if (isNotExists) {
406
424
  var userIdx = serverId