bunnyquery 1.4.4 → 1.4.6
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.js +144 -77
- package/dist/engine.cjs +143 -75
- package/dist/engine.cjs.map +1 -1
- package/dist/engine.mjs +143 -75
- package/dist/engine.mjs.map +1 -1
- package/package.json +1 -1
- package/src/engine/session.ts +185 -70
package/dist/engine.mjs
CHANGED
|
@@ -1068,10 +1068,18 @@ function mapHistoryListToMessages(list, platform, opts) {
|
|
|
1068
1068
|
}
|
|
1069
1069
|
|
|
1070
1070
|
// src/engine/session.ts
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1071
|
+
var _g = typeof globalThis !== "undefined" ? globalThis : {};
|
|
1072
|
+
function nowMs() {
|
|
1073
|
+
return _g.performance && typeof _g.performance.now === "function" ? _g.performance.now() : Date.now();
|
|
1074
|
+
}
|
|
1075
|
+
function nextFrame(cb) {
|
|
1076
|
+
if (typeof _g.requestAnimationFrame === "function") {
|
|
1077
|
+
_g.requestAnimationFrame(cb);
|
|
1078
|
+
return;
|
|
1079
|
+
}
|
|
1080
|
+
setTimeout(function() {
|
|
1081
|
+
cb(nowMs());
|
|
1082
|
+
}, 16);
|
|
1075
1083
|
}
|
|
1076
1084
|
var ChatSession = class {
|
|
1077
1085
|
constructor(host) {
|
|
@@ -1122,11 +1130,17 @@ var ChatSession = class {
|
|
|
1122
1130
|
}
|
|
1123
1131
|
dispatchAgentRequest(params) {
|
|
1124
1132
|
var self = this;
|
|
1133
|
+
var dispatchItemId;
|
|
1125
1134
|
var sendAndPoll = function() {
|
|
1126
1135
|
return Promise.resolve(
|
|
1127
1136
|
self._callProviderFor(params.aiPlatform, params.text, params.boundedMessages, params.systemPrompt, params.aiModel, params.userId, params.extractContent)
|
|
1128
1137
|
).then(function(initial) {
|
|
1129
1138
|
if (initial && initial.poll && (initial.status === "pending" || initial.status === "running")) {
|
|
1139
|
+
if (initial.id) {
|
|
1140
|
+
if (dispatchItemId && dispatchItemId !== initial.id) self.historyItemPolls.delete(dispatchItemId);
|
|
1141
|
+
dispatchItemId = initial.id;
|
|
1142
|
+
self.historyItemPolls.set(initial.id, true);
|
|
1143
|
+
}
|
|
1130
1144
|
return initial.poll({ latency: POLL_INTERVAL });
|
|
1131
1145
|
}
|
|
1132
1146
|
return initial;
|
|
@@ -1149,37 +1163,29 @@ var ChatSession = class {
|
|
|
1149
1163
|
return { content: getErrorMessage(err), isError: true };
|
|
1150
1164
|
}).then(function(result) {
|
|
1151
1165
|
delete self.pendingAgentRequests[params.key];
|
|
1166
|
+
if (dispatchItemId) self.historyItemPolls.delete(dispatchItemId);
|
|
1152
1167
|
var existing = self.aiChatHistoryCache[params.key] || { messages: [], endOfList: false, startKeyHistory: [] };
|
|
1153
1168
|
var reply = { role: "assistant", content: result.content, isError: result.isError };
|
|
1154
|
-
var
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
} else {
|
|
1162
|
-
var msgs = existing.messages.slice();
|
|
1163
|
-
var idx = -1;
|
|
1164
|
-
for (var i = msgs.length - 1; i >= 0; i--) {
|
|
1165
|
-
var m = msgs[i];
|
|
1166
|
-
if (m && m.isPending && m.role === "assistant" && !m.isBackgroundTask) {
|
|
1167
|
-
idx = i;
|
|
1168
|
-
break;
|
|
1169
|
-
}
|
|
1170
|
-
}
|
|
1171
|
-
if (idx !== -1) {
|
|
1172
|
-
reply._serverItemId = msgs[idx]._serverItemId;
|
|
1173
|
-
msgs[idx] = reply;
|
|
1174
|
-
} else {
|
|
1175
|
-
msgs.push(reply);
|
|
1169
|
+
var msgs = existing.messages.slice();
|
|
1170
|
+
var idx = -1;
|
|
1171
|
+
for (var i = msgs.length - 1; i >= 0; i--) {
|
|
1172
|
+
var m = msgs[i];
|
|
1173
|
+
if (m && m.isPending && m.role === "assistant" && !m.isBackgroundTask) {
|
|
1174
|
+
idx = i;
|
|
1175
|
+
break;
|
|
1176
1176
|
}
|
|
1177
|
-
self.aiChatHistoryCache[params.key] = {
|
|
1178
|
-
messages: msgs,
|
|
1179
|
-
endOfList: existing.endOfList,
|
|
1180
|
-
startKeyHistory: existing.startKeyHistory
|
|
1181
|
-
};
|
|
1182
1177
|
}
|
|
1178
|
+
if (idx !== -1) {
|
|
1179
|
+
reply._serverItemId = msgs[idx]._serverItemId;
|
|
1180
|
+
msgs[idx] = reply;
|
|
1181
|
+
} else {
|
|
1182
|
+
msgs.push(reply);
|
|
1183
|
+
}
|
|
1184
|
+
self.aiChatHistoryCache[params.key] = {
|
|
1185
|
+
messages: msgs,
|
|
1186
|
+
endOfList: existing.endOfList,
|
|
1187
|
+
startKeyHistory: existing.startKeyHistory
|
|
1188
|
+
};
|
|
1183
1189
|
return result;
|
|
1184
1190
|
});
|
|
1185
1191
|
this.pendingAgentRequests[params.key] = run;
|
|
@@ -1232,6 +1238,7 @@ var ChatSession = class {
|
|
|
1232
1238
|
self.host.notify();
|
|
1233
1239
|
}
|
|
1234
1240
|
if (result && result.poll && (result.status === "pending" || result.status === "running")) {
|
|
1241
|
+
if (serverId) self.historyItemPolls.set(serverId, true);
|
|
1235
1242
|
return result.poll({ latency: POLL_INTERVAL }).then(function(res) {
|
|
1236
1243
|
return self.onQueuedSendResponse(capturedComposed, res, capturedPlatform, serverId);
|
|
1237
1244
|
}).catch(function(err) {
|
|
@@ -1321,7 +1328,9 @@ var ChatSession = class {
|
|
|
1321
1328
|
if (existing._serverItemId !== void 0) promoted._serverItemId = existing._serverItemId;
|
|
1322
1329
|
if (existing.isSendingToServer) promoted.isSendingToServer = true;
|
|
1323
1330
|
this.state.messages[nextIdx] = promoted;
|
|
1324
|
-
|
|
1331
|
+
var placeholder = { role: "assistant", content: "", isPending: true };
|
|
1332
|
+
if (existing._serverItemId !== void 0) placeholder._serverItemId = existing._serverItemId;
|
|
1333
|
+
this.state.messages.splice(nextIdx + 1, 0, placeholder);
|
|
1325
1334
|
this.host.notify();
|
|
1326
1335
|
}
|
|
1327
1336
|
resolveQueuedUserBubble(serverId) {
|
|
@@ -1371,6 +1380,7 @@ var ChatSession = class {
|
|
|
1371
1380
|
else this.state.messages.push(msg);
|
|
1372
1381
|
}
|
|
1373
1382
|
onQueuedSendResponse(_composed, response, platform, serverId) {
|
|
1383
|
+
if (serverId) this.historyItemPolls.delete(serverId);
|
|
1374
1384
|
var targetIdx = this.resolveQueuedUserBubble(serverId);
|
|
1375
1385
|
if (targetIdx === void 0) {
|
|
1376
1386
|
this.host.notify();
|
|
@@ -1405,6 +1415,7 @@ var ChatSession = class {
|
|
|
1405
1415
|
this.host.scrollToBottom(true);
|
|
1406
1416
|
}
|
|
1407
1417
|
onQueuedSendError(_composed, err, serverId) {
|
|
1418
|
+
if (serverId) this.historyItemPolls.delete(serverId);
|
|
1408
1419
|
var isNotExists = err && (err.code === "NOT_EXISTS" || err.body && err.body.code === "NOT_EXISTS");
|
|
1409
1420
|
if (isNotExists) {
|
|
1410
1421
|
var userIdx = serverId ? this.state.messages.findIndex(function(m) {
|
|
@@ -1529,61 +1540,118 @@ var ChatSession = class {
|
|
|
1529
1540
|
});
|
|
1530
1541
|
}
|
|
1531
1542
|
// --- typewriter -------------------------------------------------------
|
|
1543
|
+
// Reveal `fullText` into a message bubble at a constant wall-clock RATE
|
|
1544
|
+
// (chars/second) driven by requestAnimationFrame, rather than a fixed number
|
|
1545
|
+
// of characters per fixed-delay tick. This is what keeps typing smooth and
|
|
1546
|
+
// cheap on slow machines:
|
|
1547
|
+
//
|
|
1548
|
+
// * Each frame reveals `elapsed_ms * CHARS_PER_SEC` characters, so the
|
|
1549
|
+
// visual speed is the same regardless of how long a frame actually took.
|
|
1550
|
+
// * As the bubble's markdown grows, each re-render gets more expensive, so
|
|
1551
|
+
// frames get longer — which makes each frame reveal MORE characters and
|
|
1552
|
+
// therefore do FEWER, larger renders. That converts the old O(n^2)
|
|
1553
|
+
// "re-render the whole growing string once per 3 characters" (which got
|
|
1554
|
+
// slower and slower and pegged the CPU) into roughly O(n): the number of
|
|
1555
|
+
// renders self-throttles to what the machine can actually paint.
|
|
1556
|
+
// * rAF paces us to the browser's paint cycle and pauses in background
|
|
1557
|
+
// tabs, so we never queue work faster than it can be drawn.
|
|
1532
1558
|
typewriteIntoIndex(idx, fullText, localId) {
|
|
1533
1559
|
var self = this;
|
|
1534
1560
|
if (!fullText) return Promise.resolve();
|
|
1535
|
-
var
|
|
1536
|
-
var
|
|
1537
|
-
var
|
|
1561
|
+
var CHARS_PER_SEC = 300;
|
|
1562
|
+
var MIN_STEP = 1;
|
|
1563
|
+
var MAX_FRAME_MS = 1e3;
|
|
1564
|
+
var regions = [], m;
|
|
1538
1565
|
var fenceRegex = /```[\w.-]+\.[a-zA-Z0-9]+\n[\s\S]*?```/g;
|
|
1539
|
-
while ((m = fenceRegex.exec(fullText)) !== null)
|
|
1540
|
-
var linkRegions = [], lm;
|
|
1566
|
+
while ((m = fenceRegex.exec(fullText)) !== null) regions.push({ start: m.index, end: m.index + m[0].length });
|
|
1541
1567
|
var linkRegex = createInlineLinkRegex();
|
|
1542
|
-
while ((
|
|
1568
|
+
while ((m = linkRegex.exec(fullText)) !== null) regions.push({ start: m.index, end: m.index + m[0].length });
|
|
1569
|
+
regions.sort(function(a, b) {
|
|
1570
|
+
return a.start - b.start;
|
|
1571
|
+
});
|
|
1543
1572
|
this.state.typing = true;
|
|
1544
1573
|
this.state.typingAbort = false;
|
|
1545
1574
|
var i = 0;
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
var
|
|
1549
|
-
var
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1575
|
+
var last = nowMs();
|
|
1576
|
+
return new Promise(function(resolve) {
|
|
1577
|
+
var done = false;
|
|
1578
|
+
var doc = _g.document;
|
|
1579
|
+
function isHidden() {
|
|
1580
|
+
return !!(doc && doc.hidden);
|
|
1581
|
+
}
|
|
1582
|
+
function cleanup() {
|
|
1583
|
+
if (doc && doc.removeEventListener) doc.removeEventListener("visibilitychange", onVisibility);
|
|
1584
|
+
}
|
|
1585
|
+
function finish() {
|
|
1586
|
+
if (done) return;
|
|
1587
|
+
done = true;
|
|
1588
|
+
cleanup();
|
|
1589
|
+
if (!self.state.typingAbort) {
|
|
1590
|
+
var fi = localId ? self.state.messages.findIndex(function(mm) {
|
|
1591
|
+
return mm._localId === localId;
|
|
1592
|
+
}) : idx;
|
|
1593
|
+
if (fi !== -1) {
|
|
1594
|
+
var t = self.state.messages[fi];
|
|
1595
|
+
if (t) {
|
|
1596
|
+
t.content = fullText;
|
|
1597
|
+
self.host.refreshMessageBubble(fi);
|
|
1598
|
+
}
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
self.state.typing = false;
|
|
1602
|
+
resolve();
|
|
1603
|
+
}
|
|
1604
|
+
function onVisibility() {
|
|
1605
|
+
if (isHidden()) finish();
|
|
1562
1606
|
}
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
var
|
|
1607
|
+
if (doc && doc.addEventListener) doc.addEventListener("visibilitychange", onVisibility);
|
|
1608
|
+
function frame(t) {
|
|
1609
|
+
if (done) return;
|
|
1610
|
+
if (self.state.typingAbort || i >= fullText.length || isHidden()) {
|
|
1611
|
+
finish();
|
|
1612
|
+
return;
|
|
1613
|
+
}
|
|
1614
|
+
var dt = t - last;
|
|
1615
|
+
last = t;
|
|
1616
|
+
if (!(dt > 0)) dt = 16;
|
|
1617
|
+
if (dt > MAX_FRAME_MS) dt = MAX_FRAME_MS;
|
|
1618
|
+
var step = Math.round(dt * CHARS_PER_SEC / 1e3);
|
|
1619
|
+
if (step < MIN_STEP) step = MIN_STEP;
|
|
1620
|
+
var next = Math.min(fullText.length, i + step);
|
|
1621
|
+
for (var changed = true; changed; ) {
|
|
1622
|
+
changed = false;
|
|
1623
|
+
for (var k = 0; k < regions.length; k++) {
|
|
1624
|
+
var r = regions[k];
|
|
1625
|
+
if (next > r.start && i < r.end && r.end > next) {
|
|
1626
|
+
next = r.end;
|
|
1627
|
+
changed = true;
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
if (next > fullText.length) next = fullText.length;
|
|
1632
|
+
i = next;
|
|
1633
|
+
var currentIdx = localId ? self.state.messages.findIndex(function(mm) {
|
|
1578
1634
|
return mm._localId === localId;
|
|
1579
1635
|
}) : idx;
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
self.host.refreshMessageBubble(fi !== -1 ? fi : idx);
|
|
1636
|
+
if (currentIdx === -1) {
|
|
1637
|
+
finish();
|
|
1638
|
+
return;
|
|
1584
1639
|
}
|
|
1640
|
+
var target = self.state.messages[currentIdx];
|
|
1641
|
+
if (!target) {
|
|
1642
|
+
finish();
|
|
1643
|
+
return;
|
|
1644
|
+
}
|
|
1645
|
+
target.content = fullText.slice(0, i);
|
|
1646
|
+
self.host.refreshMessageBubble(currentIdx);
|
|
1647
|
+
self.host.scrollToBottomIfSticky();
|
|
1648
|
+
nextFrame(frame);
|
|
1649
|
+
}
|
|
1650
|
+
if (isHidden()) {
|
|
1651
|
+
finish();
|
|
1652
|
+
return;
|
|
1585
1653
|
}
|
|
1586
|
-
|
|
1654
|
+
nextFrame(frame);
|
|
1587
1655
|
});
|
|
1588
1656
|
}
|
|
1589
1657
|
enqueueTypewrite(idx, fullText, localId) {
|
|
@@ -1897,7 +1965,7 @@ var ChatSession = class {
|
|
|
1897
1965
|
if (item.status !== "running" && item.status !== "pending") return;
|
|
1898
1966
|
if (!item.poll || !item.id) return;
|
|
1899
1967
|
if (self.historyItemPolls.has(item.id)) return;
|
|
1900
|
-
if (
|
|
1968
|
+
if (self.pendingAgentRequests[self.getHistoryCacheKey()] && !item._isBgTask && !item._isOnBgQueue) return;
|
|
1901
1969
|
self.historyItemPolls.set(item.id, true);
|
|
1902
1970
|
var capturedId = item.id;
|
|
1903
1971
|
var pp = item.poll({
|