bunnyquery 1.1.2 → 1.1.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.
Files changed (2) hide show
  1. package/bunnyquery.js +37 -6
  2. package/package.json +1 -1
package/bunnyquery.js CHANGED
@@ -982,7 +982,11 @@
982
982
  }
983
983
  if (userTurn) out.push({ role: 'user', content: userTurn, id: item.id });
984
984
 
985
- if (item.status === 'pending') {
985
+ // Treat 'running' (worker has claimed the item) identically to
986
+ // 'pending'. The list endpoint returns the raw stts value; the
987
+ // single-item polling path normalises it server-side but the list
988
+ // path does not — same fix as agent.vue mapHistoryListToMessages.
989
+ if (item.status === 'pending' || item.status === 'running') {
986
990
  out.push({ role: 'assistant', content: '', id: item.id, isPending: true });
987
991
  } else if (item.status === 'failed' || isErrorResponseBody(res)) {
988
992
  out.push({
@@ -1035,6 +1039,7 @@
1035
1039
  this._loadingOlder = false;
1036
1040
  this._loadingFirstHistory = false;
1037
1041
  this._initialHistoryLoaded = false;
1042
+ this._isPromptComposing = false;
1038
1043
 
1039
1044
  this.refs = {};
1040
1045
 
@@ -1456,12 +1461,11 @@
1456
1461
  rows: '1',
1457
1462
  placeholder: `Ask anything about ${this.projectName || 'the project'}...`,
1458
1463
  oninput: (e) => this._autoGrow(e.target),
1459
- onkeydown: (e) => {
1460
- if (e.key === 'Enter' && !e.shiftKey) {
1461
- e.preventDefault();
1462
- this._sendMessage();
1463
- }
1464
+ onkeydown: (e) => this._handlePromptEnter(e),
1465
+ oncompositionstart: () => {
1466
+ this._isPromptComposing = true;
1464
1467
  },
1468
+ oncompositionend: () => this._handlePromptCompositionEnd(),
1465
1469
  });
1466
1470
  const sendBtn = $('button', { type: 'submit', class: 'btn' }, 'Send');
1467
1471
 
@@ -1609,6 +1613,23 @@
1609
1613
  el.style.height = Math.min(el.scrollHeight, 200) + 'px';
1610
1614
  }
1611
1615
 
1616
+ _handlePromptCompositionEnd() {
1617
+ this._isPromptComposing = false;
1618
+ if (this.refs.textarea) {
1619
+ this._autoGrow(this.refs.textarea);
1620
+ }
1621
+ }
1622
+
1623
+ _handlePromptEnter(e) {
1624
+ if (e.key !== 'Enter' || e.shiftKey) return;
1625
+ if (e.isComposing || this._isPromptComposing || e.keyCode === 229 || e.which === 229) {
1626
+ return;
1627
+ }
1628
+
1629
+ e.preventDefault();
1630
+ Promise.resolve().then(() => this._sendMessage());
1631
+ }
1632
+
1612
1633
  _anyPending() {
1613
1634
  return this.messages.some((m) => m.isPending);
1614
1635
  }
@@ -2286,6 +2307,16 @@
2286
2307
  async _runPendingPoll() {
2287
2308
  // Defensive: if somehow re-entered, drop the duplicate.
2288
2309
  if (this._pollingPending) return;
2310
+ // When _sendMessage is actively dispatching or the typewriter is
2311
+ // running, skip replacing this.messages. The locally-pushed
2312
+ // optimistic messages (user turn + pending assistant) have no
2313
+ // server id and would be silently dropped by the merge, causing
2314
+ // the message to transiently disappear. Reschedule so polling
2315
+ // resumes as soon as the send/typewrite finishes.
2316
+ if (this.sending || this.typing) {
2317
+ this._schedulePendingPoll();
2318
+ return;
2319
+ }
2289
2320
  this._pollingPending = true;
2290
2321
  try {
2291
2322
  const res = await getChatHistory(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bunnyquery",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "description": "BunnyQuery AI chat client",
5
5
  "main": "bunnyquery.js",
6
6
  "files": [