bunnyquery 1.8.1 → 1.8.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.js +183 -12
- package/dist/engine.cjs +201 -4
- package/dist/engine.cjs.map +1 -1
- package/dist/engine.d.mts +98 -2
- package/dist/engine.d.ts +98 -2
- package/dist/engine.mjs +183 -5
- package/dist/engine.mjs.map +1 -1
- package/package.json +1 -1
- package/src/engine/download_encoding.ts +281 -0
- package/src/engine/errors.ts +34 -0
- package/src/engine/index.ts +3 -0
- package/src/engine/requests.ts +4 -1
- package/src/engine/session.ts +25 -3
package/bunnyquery.js
CHANGED
|
@@ -433,6 +433,19 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
433
433
|
}
|
|
434
434
|
|
|
435
435
|
// src/engine/errors.ts
|
|
436
|
+
var STATUS_MESSAGE = {
|
|
437
|
+
"408": "The AI provider timed out before it started.",
|
|
438
|
+
"409": "The AI provider rejected the request as conflicting.",
|
|
439
|
+
"413": "The request was too large for the AI provider.",
|
|
440
|
+
"429": "The AI provider is rate limiting requests right now.",
|
|
441
|
+
"500": "The AI provider hit an internal error.",
|
|
442
|
+
"502": "The AI provider is temporarily unreachable.",
|
|
443
|
+
"503": "The AI provider is temporarily unavailable.",
|
|
444
|
+
"504": "The AI provider timed out."
|
|
445
|
+
};
|
|
446
|
+
function isTransientStatus(status) {
|
|
447
|
+
return status === 408 || status === 425 || status === 429 || status >= 500;
|
|
448
|
+
}
|
|
436
449
|
function getErrorMessage(input) {
|
|
437
450
|
if (!input) return "Something went wrong.";
|
|
438
451
|
if (typeof input === "string") return input;
|
|
@@ -440,6 +453,11 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
440
453
|
if (input.body && input.body.error && input.body.error.message) return input.body.error.message;
|
|
441
454
|
if (input.body && typeof input.body.message === "string") return input.body.message;
|
|
442
455
|
if (input.message) return input.message;
|
|
456
|
+
var status = typeof input.status_code === "number" ? input.status_code : typeof input.status === "number" ? input.status : 0;
|
|
457
|
+
if (status) {
|
|
458
|
+
var text = STATUS_MESSAGE[String(status)] || (status >= 500 ? "The AI provider returned a server error." : "The AI provider rejected the request.");
|
|
459
|
+
return text + " (error " + status + ")" + (isTransientStatus(status) ? " This is usually temporary, please try again." : "");
|
|
460
|
+
}
|
|
443
461
|
return "Something went wrong.";
|
|
444
462
|
}
|
|
445
463
|
function isErrorResponseBody(response) {
|
|
@@ -852,6 +870,163 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
852
870
|
};
|
|
853
871
|
}
|
|
854
872
|
|
|
873
|
+
// src/engine/download_encoding.ts
|
|
874
|
+
var BOM = "\uFEFF";
|
|
875
|
+
var BOM_EXTS = /* @__PURE__ */ new Set(["csv", "tsv", "tab", "txt", "text", "log"]);
|
|
876
|
+
var HTML_EXTS = /* @__PURE__ */ new Set(["html", "htm", "xhtml"]);
|
|
877
|
+
var XML_EXTS = /* @__PURE__ */ new Set(["xml", "svg", "rss", "atom", "xsl", "xslt", "plist", "kml"]);
|
|
878
|
+
var RTF_EXTS = /* @__PURE__ */ new Set(["rtf"]);
|
|
879
|
+
var EXT_CONTENT_TYPES = {
|
|
880
|
+
csv: "text/csv; charset=utf-8",
|
|
881
|
+
tsv: "text/tab-separated-values; charset=utf-8",
|
|
882
|
+
tab: "text/tab-separated-values; charset=utf-8",
|
|
883
|
+
txt: "text/plain; charset=utf-8",
|
|
884
|
+
text: "text/plain; charset=utf-8",
|
|
885
|
+
log: "text/plain; charset=utf-8",
|
|
886
|
+
md: "text/markdown; charset=utf-8",
|
|
887
|
+
markdown: "text/markdown; charset=utf-8",
|
|
888
|
+
json: "application/json; charset=utf-8",
|
|
889
|
+
jsonl: "application/x-ndjson; charset=utf-8",
|
|
890
|
+
ndjson: "application/x-ndjson; charset=utf-8",
|
|
891
|
+
geojson: "application/geo+json; charset=utf-8",
|
|
892
|
+
yaml: "text/yaml; charset=utf-8",
|
|
893
|
+
yml: "text/yaml; charset=utf-8",
|
|
894
|
+
toml: "text/plain; charset=utf-8",
|
|
895
|
+
ini: "text/plain; charset=utf-8",
|
|
896
|
+
sql: "text/plain; charset=utf-8",
|
|
897
|
+
html: "text/html; charset=utf-8",
|
|
898
|
+
htm: "text/html; charset=utf-8",
|
|
899
|
+
xhtml: "application/xhtml+xml; charset=utf-8",
|
|
900
|
+
xml: "application/xml; charset=utf-8",
|
|
901
|
+
svg: "image/svg+xml; charset=utf-8",
|
|
902
|
+
css: "text/css; charset=utf-8",
|
|
903
|
+
js: "text/javascript; charset=utf-8",
|
|
904
|
+
ts: "text/plain; charset=utf-8",
|
|
905
|
+
py: "text/x-python; charset=utf-8",
|
|
906
|
+
sh: "text/x-shellscript; charset=utf-8",
|
|
907
|
+
srt: "application/x-subrip; charset=utf-8",
|
|
908
|
+
vtt: "text/vtt; charset=utf-8",
|
|
909
|
+
ics: "text/calendar; charset=utf-8",
|
|
910
|
+
vcf: "text/vcard; charset=utf-8",
|
|
911
|
+
// RTF is 7-bit ASCII by specification, so it takes no charset parameter.
|
|
912
|
+
rtf: "application/rtf",
|
|
913
|
+
// Binary types the model can only ever REFERENCE, never author in a fence, but
|
|
914
|
+
// which keep the type sensible if one ever shows up.
|
|
915
|
+
pdf: "application/pdf",
|
|
916
|
+
png: "image/png",
|
|
917
|
+
jpg: "image/jpeg",
|
|
918
|
+
jpeg: "image/jpeg",
|
|
919
|
+
gif: "image/gif",
|
|
920
|
+
webp: "image/webp"
|
|
921
|
+
};
|
|
922
|
+
function normalizeExt(ext) {
|
|
923
|
+
return String(ext || "").trim().replace(/^\./, "").toLowerCase();
|
|
924
|
+
}
|
|
925
|
+
function extOf(filename) {
|
|
926
|
+
const name = String(filename || "");
|
|
927
|
+
const dot = name.lastIndexOf(".");
|
|
928
|
+
return dot > 0 ? normalizeExt(name.slice(dot + 1)) : "";
|
|
929
|
+
}
|
|
930
|
+
function encodingClassForExt(ext) {
|
|
931
|
+
const e = normalizeExt(ext);
|
|
932
|
+
if (BOM_EXTS.has(e)) return "bom";
|
|
933
|
+
if (HTML_EXTS.has(e)) return "html";
|
|
934
|
+
if (XML_EXTS.has(e)) return "xml";
|
|
935
|
+
if (RTF_EXTS.has(e)) return "rtf";
|
|
936
|
+
return "none";
|
|
937
|
+
}
|
|
938
|
+
function contentTypeForExt(ext, fallback = "text/plain; charset=utf-8") {
|
|
939
|
+
return EXT_CONTENT_TYPES[normalizeExt(ext)] || fallback;
|
|
940
|
+
}
|
|
941
|
+
function hasBom(text) {
|
|
942
|
+
return typeof text === "string" && text.charCodeAt(0) === 65279;
|
|
943
|
+
}
|
|
944
|
+
var HTML_HEAD_WINDOW = 4096;
|
|
945
|
+
var META_CHARSET_RE = /<meta[^>]+charset\s*=\s*["']?\s*([a-z0-9_-]+)/i;
|
|
946
|
+
var META_HTTP_EQUIV_RE = /<meta[^>]+http-equiv\s*=\s*["']?content-type["']?[^>]*>/i;
|
|
947
|
+
function ensureHtmlCharset(text) {
|
|
948
|
+
const src = String(text == null ? "" : text);
|
|
949
|
+
const head = src.slice(0, HTML_HEAD_WINDOW);
|
|
950
|
+
const declared = META_CHARSET_RE.exec(head);
|
|
951
|
+
if (declared) {
|
|
952
|
+
if (declared[1].toLowerCase().replace(/[^a-z0-9]/g, "") === "utf8") return src;
|
|
953
|
+
const start = declared.index + declared[0].length - declared[1].length;
|
|
954
|
+
return src.slice(0, start) + "utf-8" + src.slice(start + declared[1].length);
|
|
955
|
+
}
|
|
956
|
+
const httpEquiv = META_HTTP_EQUIV_RE.exec(head);
|
|
957
|
+
if (httpEquiv) {
|
|
958
|
+
return src.slice(0, httpEquiv.index) + '<meta charset="utf-8">' + src.slice(httpEquiv.index + httpEquiv[0].length);
|
|
959
|
+
}
|
|
960
|
+
const tag = '<meta charset="utf-8">';
|
|
961
|
+
const headOpen = /<head[^>]*>/i.exec(head);
|
|
962
|
+
if (headOpen) {
|
|
963
|
+
const at = headOpen.index + headOpen[0].length;
|
|
964
|
+
return src.slice(0, at) + "\n" + tag + src.slice(at);
|
|
965
|
+
}
|
|
966
|
+
const htmlOpen = /<html[^>]*>/i.exec(head);
|
|
967
|
+
if (htmlOpen) {
|
|
968
|
+
const at = htmlOpen.index + htmlOpen[0].length;
|
|
969
|
+
return src.slice(0, at) + "\n<head>" + tag + "</head>" + src.slice(at);
|
|
970
|
+
}
|
|
971
|
+
const doctype = /<!doctype[^>]*>/i.exec(head);
|
|
972
|
+
if (doctype) {
|
|
973
|
+
const at = doctype.index + doctype[0].length;
|
|
974
|
+
return src.slice(0, at) + "\n" + tag + src.slice(at);
|
|
975
|
+
}
|
|
976
|
+
return tag + "\n" + src;
|
|
977
|
+
}
|
|
978
|
+
var XML_DECL_RE = /^\s*<\?xml\s[^?]*\?>/i;
|
|
979
|
+
function ensureXmlEncoding(text) {
|
|
980
|
+
const src = String(text == null ? "" : text);
|
|
981
|
+
const decl = XML_DECL_RE.exec(src);
|
|
982
|
+
if (!decl) return src;
|
|
983
|
+
const found = /encoding\s*=\s*["']([^"']*)["']/i.exec(decl[0]);
|
|
984
|
+
if (!found) return src;
|
|
985
|
+
if (found[1].toLowerCase().replace(/[^a-z0-9]/g, "") === "utf8") return src;
|
|
986
|
+
const fixedDecl = decl[0].slice(0, found.index) + found[0].replace(found[1], "UTF-8") + decl[0].slice(found.index + found[0].length);
|
|
987
|
+
return fixedDecl + src.slice(decl[0].length);
|
|
988
|
+
}
|
|
989
|
+
var RTF_SIGNATURE_RE = /^[\s]*\{\\rtf/i;
|
|
990
|
+
function looksLikeRtf(text) {
|
|
991
|
+
return RTF_SIGNATURE_RE.test(String(text == null ? "" : text));
|
|
992
|
+
}
|
|
993
|
+
function escapeRtfNonAscii(text) {
|
|
994
|
+
const src = String(text == null ? "" : text);
|
|
995
|
+
let out = "";
|
|
996
|
+
let plainFrom = 0;
|
|
997
|
+
for (let i = 0; i < src.length; i++) {
|
|
998
|
+
const code = src.charCodeAt(i);
|
|
999
|
+
if (code < 128) continue;
|
|
1000
|
+
out += src.slice(plainFrom, i);
|
|
1001
|
+
out += `\\u${code > 32767 ? code - 65536 : code}?`;
|
|
1002
|
+
plainFrom = i + 1;
|
|
1003
|
+
}
|
|
1004
|
+
return plainFrom === 0 ? src : out + src.slice(plainFrom);
|
|
1005
|
+
}
|
|
1006
|
+
function applyEncodingDeclaration(text, ext) {
|
|
1007
|
+
const src = String(text == null ? "" : text);
|
|
1008
|
+
switch (encodingClassForExt(ext)) {
|
|
1009
|
+
case "bom":
|
|
1010
|
+
return hasBom(src) ? src : BOM + src;
|
|
1011
|
+
case "html":
|
|
1012
|
+
return ensureHtmlCharset(src);
|
|
1013
|
+
case "xml":
|
|
1014
|
+
return ensureXmlEncoding(src);
|
|
1015
|
+
case "rtf":
|
|
1016
|
+
return looksLikeRtf(src) ? escapeRtfNonAscii(src) : hasBom(src) ? src : BOM + src;
|
|
1017
|
+
default:
|
|
1018
|
+
return src;
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
function prepareDownloadText(filename, body) {
|
|
1022
|
+
const ext = extOf(filename);
|
|
1023
|
+
return {
|
|
1024
|
+
ext,
|
|
1025
|
+
text: applyEncodingDeclaration(body, ext),
|
|
1026
|
+
contentType: contentTypeForExt(ext)
|
|
1027
|
+
};
|
|
1028
|
+
}
|
|
1029
|
+
|
|
855
1030
|
// src/engine/time.ts
|
|
856
1031
|
function wallClockNow() {
|
|
857
1032
|
return Date.now();
|
|
@@ -1013,7 +1188,7 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
1013
1188
|
return { ...m, content: blocks };
|
|
1014
1189
|
});
|
|
1015
1190
|
}
|
|
1016
|
-
var POLL_INTERVAL =
|
|
1191
|
+
var POLL_INTERVAL = 3e3;
|
|
1017
1192
|
async function callClaudeWithMcp({
|
|
1018
1193
|
prompt,
|
|
1019
1194
|
messages,
|
|
@@ -1937,7 +2112,7 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
1937
2112
|
var chatQueue = useBgQueue ? userId + BG_INDEXING_QUEUE_SUFFIX : userId;
|
|
1938
2113
|
if (offChat) {
|
|
1939
2114
|
var offHistory = (this.aiChatHistoryCache[key] ? this.aiChatHistoryCache[key].messages : []).filter(function(m) {
|
|
1940
|
-
return !m.isPending && !m.isPendingQueued && !m.isPendingInProcess && !m.isPendingOlder && !m.isCancelled && !m.isBackgroundTask;
|
|
2115
|
+
return !m.isPending && !m.isPendingQueued && !m.isPendingInProcess && !m.isPendingOlder && !m.isCancelled && !m.isBackgroundTask && !m.isError;
|
|
1941
2116
|
});
|
|
1942
2117
|
var offBounded = buildBoundedChatMessages({
|
|
1943
2118
|
platform: aiPlatform,
|
|
@@ -1972,7 +2147,7 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
1972
2147
|
}
|
|
1973
2148
|
if (isQueuedSend) {
|
|
1974
2149
|
var resolvedHistory = this.state.messages.filter(function(m) {
|
|
1975
|
-
return !m.isPending && !m.isPendingQueued && !m.isPendingInProcess && !m.isPendingOlder && !m.isCancelled && !m.isBackgroundTask;
|
|
2150
|
+
return !m.isPending && !m.isPendingQueued && !m.isPendingInProcess && !m.isPendingOlder && !m.isCancelled && !m.isBackgroundTask && !m.isError;
|
|
1976
2151
|
});
|
|
1977
2152
|
var boundedQ = buildBoundedChatMessages({
|
|
1978
2153
|
platform: aiPlatform,
|
|
@@ -2023,7 +2198,7 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
2023
2198
|
this.state.sending = true;
|
|
2024
2199
|
this.host.scrollToBottom(true);
|
|
2025
2200
|
var historyForLlm = this.state.messages.filter(function(m) {
|
|
2026
|
-
return !m.isCancelled && !m.isBackgroundTask;
|
|
2201
|
+
return !m.isPending && !m.isPendingQueued && !m.isPendingInProcess && !m.isPendingOlder && !m.isCancelled && !m.isBackgroundTask && !m.isError;
|
|
2027
2202
|
});
|
|
2028
2203
|
if (llmComposed !== composed) {
|
|
2029
2204
|
for (var li = historyForLlm.length - 1; li >= 0; li--) {
|
|
@@ -3632,7 +3807,7 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
3632
3807
|
(function() {
|
|
3633
3808
|
var MCP_PROD = "https://mcp.broadwayinc.computer";
|
|
3634
3809
|
var MCP_DEV = "https://mcp-dev.broadwayinc.computer";
|
|
3635
|
-
var BQ_VERSION = "1.8.
|
|
3810
|
+
var BQ_VERSION = "1.8.2" ;
|
|
3636
3811
|
var ATTACHMENT_URL_EXPIRES_SECONDS = 600;
|
|
3637
3812
|
var GOOGLE_AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth";
|
|
3638
3813
|
var GOOGLE_TOKEN_URL = "https://oauth2.googleapis.com/token";
|
|
@@ -5518,13 +5693,9 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
5518
5693
|
var key = filename + "\0" + body;
|
|
5519
5694
|
var existing = fileBlobCache.get(key);
|
|
5520
5695
|
if (existing) return existing;
|
|
5521
|
-
var
|
|
5522
|
-
var
|
|
5523
|
-
var
|
|
5524
|
-
var needsBom = ext === "csv" || ext === "tsv" || ext === "tab";
|
|
5525
|
-
var type = isText ? contentType + "; charset=utf-8" : contentType;
|
|
5526
|
-
var data = needsBom ? "\uFEFF" + body : body;
|
|
5527
|
-
var href = URL.createObjectURL(new Blob([data], { type }));
|
|
5696
|
+
var prepared = prepareDownloadText(filename, body);
|
|
5697
|
+
var type = EXT_CONTENT_TYPES[extOf(filename)] || mimeGetType(filename) || "text/plain; charset=utf-8";
|
|
5698
|
+
var href = URL.createObjectURL(new Blob([prepared.text], { type }));
|
|
5528
5699
|
fileBlobCache.set(key, href);
|
|
5529
5700
|
return href;
|
|
5530
5701
|
}
|
package/dist/engine.cjs
CHANGED
|
@@ -439,6 +439,19 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
439
439
|
}
|
|
440
440
|
|
|
441
441
|
// src/engine/errors.ts
|
|
442
|
+
var STATUS_MESSAGE = {
|
|
443
|
+
"408": "The AI provider timed out before it started.",
|
|
444
|
+
"409": "The AI provider rejected the request as conflicting.",
|
|
445
|
+
"413": "The request was too large for the AI provider.",
|
|
446
|
+
"429": "The AI provider is rate limiting requests right now.",
|
|
447
|
+
"500": "The AI provider hit an internal error.",
|
|
448
|
+
"502": "The AI provider is temporarily unreachable.",
|
|
449
|
+
"503": "The AI provider is temporarily unavailable.",
|
|
450
|
+
"504": "The AI provider timed out."
|
|
451
|
+
};
|
|
452
|
+
function isTransientStatus(status) {
|
|
453
|
+
return status === 408 || status === 425 || status === 429 || status >= 500;
|
|
454
|
+
}
|
|
442
455
|
function getErrorMessage(input) {
|
|
443
456
|
if (!input) return "Something went wrong.";
|
|
444
457
|
if (typeof input === "string") return input;
|
|
@@ -446,6 +459,11 @@ function getErrorMessage(input) {
|
|
|
446
459
|
if (input.body && input.body.error && input.body.error.message) return input.body.error.message;
|
|
447
460
|
if (input.body && typeof input.body.message === "string") return input.body.message;
|
|
448
461
|
if (input.message) return input.message;
|
|
462
|
+
var status = typeof input.status_code === "number" ? input.status_code : typeof input.status === "number" ? input.status : 0;
|
|
463
|
+
if (status) {
|
|
464
|
+
var text = STATUS_MESSAGE[String(status)] || (status >= 500 ? "The AI provider returned a server error." : "The AI provider rejected the request.");
|
|
465
|
+
return text + " (error " + status + ")" + (isTransientStatus(status) ? " This is usually temporary, please try again." : "");
|
|
466
|
+
}
|
|
449
467
|
return "Something went wrong.";
|
|
450
468
|
}
|
|
451
469
|
function isErrorResponseBody(response) {
|
|
@@ -869,6 +887,166 @@ function buildBoundedChatMessages(options) {
|
|
|
869
887
|
};
|
|
870
888
|
}
|
|
871
889
|
|
|
890
|
+
// src/engine/download_encoding.ts
|
|
891
|
+
var BOM = "\uFEFF";
|
|
892
|
+
var BOM_EXTS = /* @__PURE__ */ new Set(["csv", "tsv", "tab", "txt", "text", "log"]);
|
|
893
|
+
var HTML_EXTS = /* @__PURE__ */ new Set(["html", "htm", "xhtml"]);
|
|
894
|
+
var XML_EXTS = /* @__PURE__ */ new Set(["xml", "svg", "rss", "atom", "xsl", "xslt", "plist", "kml"]);
|
|
895
|
+
var RTF_EXTS = /* @__PURE__ */ new Set(["rtf"]);
|
|
896
|
+
var EXT_CONTENT_TYPES = {
|
|
897
|
+
csv: "text/csv; charset=utf-8",
|
|
898
|
+
tsv: "text/tab-separated-values; charset=utf-8",
|
|
899
|
+
tab: "text/tab-separated-values; charset=utf-8",
|
|
900
|
+
txt: "text/plain; charset=utf-8",
|
|
901
|
+
text: "text/plain; charset=utf-8",
|
|
902
|
+
log: "text/plain; charset=utf-8",
|
|
903
|
+
md: "text/markdown; charset=utf-8",
|
|
904
|
+
markdown: "text/markdown; charset=utf-8",
|
|
905
|
+
json: "application/json; charset=utf-8",
|
|
906
|
+
jsonl: "application/x-ndjson; charset=utf-8",
|
|
907
|
+
ndjson: "application/x-ndjson; charset=utf-8",
|
|
908
|
+
geojson: "application/geo+json; charset=utf-8",
|
|
909
|
+
yaml: "text/yaml; charset=utf-8",
|
|
910
|
+
yml: "text/yaml; charset=utf-8",
|
|
911
|
+
toml: "text/plain; charset=utf-8",
|
|
912
|
+
ini: "text/plain; charset=utf-8",
|
|
913
|
+
sql: "text/plain; charset=utf-8",
|
|
914
|
+
html: "text/html; charset=utf-8",
|
|
915
|
+
htm: "text/html; charset=utf-8",
|
|
916
|
+
xhtml: "application/xhtml+xml; charset=utf-8",
|
|
917
|
+
xml: "application/xml; charset=utf-8",
|
|
918
|
+
svg: "image/svg+xml; charset=utf-8",
|
|
919
|
+
css: "text/css; charset=utf-8",
|
|
920
|
+
js: "text/javascript; charset=utf-8",
|
|
921
|
+
ts: "text/plain; charset=utf-8",
|
|
922
|
+
py: "text/x-python; charset=utf-8",
|
|
923
|
+
sh: "text/x-shellscript; charset=utf-8",
|
|
924
|
+
srt: "application/x-subrip; charset=utf-8",
|
|
925
|
+
vtt: "text/vtt; charset=utf-8",
|
|
926
|
+
ics: "text/calendar; charset=utf-8",
|
|
927
|
+
vcf: "text/vcard; charset=utf-8",
|
|
928
|
+
// RTF is 7-bit ASCII by specification, so it takes no charset parameter.
|
|
929
|
+
rtf: "application/rtf",
|
|
930
|
+
// Binary types the model can only ever REFERENCE, never author in a fence, but
|
|
931
|
+
// which keep the type sensible if one ever shows up.
|
|
932
|
+
pdf: "application/pdf",
|
|
933
|
+
png: "image/png",
|
|
934
|
+
jpg: "image/jpeg",
|
|
935
|
+
jpeg: "image/jpeg",
|
|
936
|
+
gif: "image/gif",
|
|
937
|
+
webp: "image/webp"
|
|
938
|
+
};
|
|
939
|
+
function normalizeExt(ext) {
|
|
940
|
+
return String(ext || "").trim().replace(/^\./, "").toLowerCase();
|
|
941
|
+
}
|
|
942
|
+
function extOf(filename) {
|
|
943
|
+
const name = String(filename || "");
|
|
944
|
+
const dot = name.lastIndexOf(".");
|
|
945
|
+
return dot > 0 ? normalizeExt(name.slice(dot + 1)) : "";
|
|
946
|
+
}
|
|
947
|
+
function encodingClassForExt(ext) {
|
|
948
|
+
const e = normalizeExt(ext);
|
|
949
|
+
if (BOM_EXTS.has(e)) return "bom";
|
|
950
|
+
if (HTML_EXTS.has(e)) return "html";
|
|
951
|
+
if (XML_EXTS.has(e)) return "xml";
|
|
952
|
+
if (RTF_EXTS.has(e)) return "rtf";
|
|
953
|
+
return "none";
|
|
954
|
+
}
|
|
955
|
+
function needsBomForExt(ext) {
|
|
956
|
+
return encodingClassForExt(ext) === "bom";
|
|
957
|
+
}
|
|
958
|
+
function contentTypeForExt(ext, fallback = "text/plain; charset=utf-8") {
|
|
959
|
+
return EXT_CONTENT_TYPES[normalizeExt(ext)] || fallback;
|
|
960
|
+
}
|
|
961
|
+
function hasBom(text) {
|
|
962
|
+
return typeof text === "string" && text.charCodeAt(0) === 65279;
|
|
963
|
+
}
|
|
964
|
+
var HTML_HEAD_WINDOW = 4096;
|
|
965
|
+
var META_CHARSET_RE = /<meta[^>]+charset\s*=\s*["']?\s*([a-z0-9_-]+)/i;
|
|
966
|
+
var META_HTTP_EQUIV_RE = /<meta[^>]+http-equiv\s*=\s*["']?content-type["']?[^>]*>/i;
|
|
967
|
+
function ensureHtmlCharset(text) {
|
|
968
|
+
const src = String(text == null ? "" : text);
|
|
969
|
+
const head = src.slice(0, HTML_HEAD_WINDOW);
|
|
970
|
+
const declared = META_CHARSET_RE.exec(head);
|
|
971
|
+
if (declared) {
|
|
972
|
+
if (declared[1].toLowerCase().replace(/[^a-z0-9]/g, "") === "utf8") return src;
|
|
973
|
+
const start = declared.index + declared[0].length - declared[1].length;
|
|
974
|
+
return src.slice(0, start) + "utf-8" + src.slice(start + declared[1].length);
|
|
975
|
+
}
|
|
976
|
+
const httpEquiv = META_HTTP_EQUIV_RE.exec(head);
|
|
977
|
+
if (httpEquiv) {
|
|
978
|
+
return src.slice(0, httpEquiv.index) + '<meta charset="utf-8">' + src.slice(httpEquiv.index + httpEquiv[0].length);
|
|
979
|
+
}
|
|
980
|
+
const tag = '<meta charset="utf-8">';
|
|
981
|
+
const headOpen = /<head[^>]*>/i.exec(head);
|
|
982
|
+
if (headOpen) {
|
|
983
|
+
const at = headOpen.index + headOpen[0].length;
|
|
984
|
+
return src.slice(0, at) + "\n" + tag + src.slice(at);
|
|
985
|
+
}
|
|
986
|
+
const htmlOpen = /<html[^>]*>/i.exec(head);
|
|
987
|
+
if (htmlOpen) {
|
|
988
|
+
const at = htmlOpen.index + htmlOpen[0].length;
|
|
989
|
+
return src.slice(0, at) + "\n<head>" + tag + "</head>" + src.slice(at);
|
|
990
|
+
}
|
|
991
|
+
const doctype = /<!doctype[^>]*>/i.exec(head);
|
|
992
|
+
if (doctype) {
|
|
993
|
+
const at = doctype.index + doctype[0].length;
|
|
994
|
+
return src.slice(0, at) + "\n" + tag + src.slice(at);
|
|
995
|
+
}
|
|
996
|
+
return tag + "\n" + src;
|
|
997
|
+
}
|
|
998
|
+
var XML_DECL_RE = /^\s*<\?xml\s[^?]*\?>/i;
|
|
999
|
+
function ensureXmlEncoding(text) {
|
|
1000
|
+
const src = String(text == null ? "" : text);
|
|
1001
|
+
const decl = XML_DECL_RE.exec(src);
|
|
1002
|
+
if (!decl) return src;
|
|
1003
|
+
const found = /encoding\s*=\s*["']([^"']*)["']/i.exec(decl[0]);
|
|
1004
|
+
if (!found) return src;
|
|
1005
|
+
if (found[1].toLowerCase().replace(/[^a-z0-9]/g, "") === "utf8") return src;
|
|
1006
|
+
const fixedDecl = decl[0].slice(0, found.index) + found[0].replace(found[1], "UTF-8") + decl[0].slice(found.index + found[0].length);
|
|
1007
|
+
return fixedDecl + src.slice(decl[0].length);
|
|
1008
|
+
}
|
|
1009
|
+
var RTF_SIGNATURE_RE = /^[\s]*\{\\rtf/i;
|
|
1010
|
+
function looksLikeRtf(text) {
|
|
1011
|
+
return RTF_SIGNATURE_RE.test(String(text == null ? "" : text));
|
|
1012
|
+
}
|
|
1013
|
+
function escapeRtfNonAscii(text) {
|
|
1014
|
+
const src = String(text == null ? "" : text);
|
|
1015
|
+
let out = "";
|
|
1016
|
+
let plainFrom = 0;
|
|
1017
|
+
for (let i = 0; i < src.length; i++) {
|
|
1018
|
+
const code = src.charCodeAt(i);
|
|
1019
|
+
if (code < 128) continue;
|
|
1020
|
+
out += src.slice(plainFrom, i);
|
|
1021
|
+
out += `\\u${code > 32767 ? code - 65536 : code}?`;
|
|
1022
|
+
plainFrom = i + 1;
|
|
1023
|
+
}
|
|
1024
|
+
return plainFrom === 0 ? src : out + src.slice(plainFrom);
|
|
1025
|
+
}
|
|
1026
|
+
function applyEncodingDeclaration(text, ext) {
|
|
1027
|
+
const src = String(text == null ? "" : text);
|
|
1028
|
+
switch (encodingClassForExt(ext)) {
|
|
1029
|
+
case "bom":
|
|
1030
|
+
return hasBom(src) ? src : BOM + src;
|
|
1031
|
+
case "html":
|
|
1032
|
+
return ensureHtmlCharset(src);
|
|
1033
|
+
case "xml":
|
|
1034
|
+
return ensureXmlEncoding(src);
|
|
1035
|
+
case "rtf":
|
|
1036
|
+
return looksLikeRtf(src) ? escapeRtfNonAscii(src) : hasBom(src) ? src : BOM + src;
|
|
1037
|
+
default:
|
|
1038
|
+
return src;
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
function prepareDownloadText(filename, body) {
|
|
1042
|
+
const ext = extOf(filename);
|
|
1043
|
+
return {
|
|
1044
|
+
ext,
|
|
1045
|
+
text: applyEncodingDeclaration(body, ext),
|
|
1046
|
+
contentType: contentTypeForExt(ext)
|
|
1047
|
+
};
|
|
1048
|
+
}
|
|
1049
|
+
|
|
872
1050
|
// src/engine/time.ts
|
|
873
1051
|
function wallClockNow() {
|
|
874
1052
|
return Date.now();
|
|
@@ -1041,7 +1219,7 @@ function applyHistoryCacheBreakpoint(messages) {
|
|
|
1041
1219
|
return { ...m, content: blocks };
|
|
1042
1220
|
});
|
|
1043
1221
|
}
|
|
1044
|
-
var POLL_INTERVAL =
|
|
1222
|
+
var POLL_INTERVAL = 3e3;
|
|
1045
1223
|
async function callClaudeWithMcp({
|
|
1046
1224
|
prompt,
|
|
1047
1225
|
messages,
|
|
@@ -1990,7 +2168,7 @@ var ChatSession = class {
|
|
|
1990
2168
|
var chatQueue = useBgQueue ? userId + BG_INDEXING_QUEUE_SUFFIX : userId;
|
|
1991
2169
|
if (offChat) {
|
|
1992
2170
|
var offHistory = (this.aiChatHistoryCache[key] ? this.aiChatHistoryCache[key].messages : []).filter(function(m) {
|
|
1993
|
-
return !m.isPending && !m.isPendingQueued && !m.isPendingInProcess && !m.isPendingOlder && !m.isCancelled && !m.isBackgroundTask;
|
|
2171
|
+
return !m.isPending && !m.isPendingQueued && !m.isPendingInProcess && !m.isPendingOlder && !m.isCancelled && !m.isBackgroundTask && !m.isError;
|
|
1994
2172
|
});
|
|
1995
2173
|
var offBounded = buildBoundedChatMessages({
|
|
1996
2174
|
platform: aiPlatform,
|
|
@@ -2025,7 +2203,7 @@ var ChatSession = class {
|
|
|
2025
2203
|
}
|
|
2026
2204
|
if (isQueuedSend) {
|
|
2027
2205
|
var resolvedHistory = this.state.messages.filter(function(m) {
|
|
2028
|
-
return !m.isPending && !m.isPendingQueued && !m.isPendingInProcess && !m.isPendingOlder && !m.isCancelled && !m.isBackgroundTask;
|
|
2206
|
+
return !m.isPending && !m.isPendingQueued && !m.isPendingInProcess && !m.isPendingOlder && !m.isCancelled && !m.isBackgroundTask && !m.isError;
|
|
2029
2207
|
});
|
|
2030
2208
|
var boundedQ = buildBoundedChatMessages({
|
|
2031
2209
|
platform: aiPlatform,
|
|
@@ -2076,7 +2254,7 @@ var ChatSession = class {
|
|
|
2076
2254
|
this.state.sending = true;
|
|
2077
2255
|
this.host.scrollToBottom(true);
|
|
2078
2256
|
var historyForLlm = this.state.messages.filter(function(m) {
|
|
2079
|
-
return !m.isCancelled && !m.isBackgroundTask;
|
|
2257
|
+
return !m.isPending && !m.isPendingQueued && !m.isPendingInProcess && !m.isPendingOlder && !m.isCancelled && !m.isBackgroundTask && !m.isError;
|
|
2080
2258
|
});
|
|
2081
2259
|
if (llmComposed !== composed) {
|
|
2082
2260
|
for (var li = historyForLlm.length - 1; li >= 0; li--) {
|
|
@@ -3682,6 +3860,8 @@ function buildChatDisplayList(messages, opts) {
|
|
|
3682
3860
|
}
|
|
3683
3861
|
|
|
3684
3862
|
exports.BG_INDEXING_QUEUE_SUFFIX = BG_INDEXING_QUEUE_SUFFIX;
|
|
3863
|
+
exports.BOM = BOM;
|
|
3864
|
+
exports.BOM_EXTS = BOM_EXTS;
|
|
3685
3865
|
exports.CLAUDE_INPUT_CAP_RATIO = CLAUDE_INPUT_CAP_RATIO;
|
|
3686
3866
|
exports.CLAUDE_PER_REQUEST_INPUT_CAP = CLAUDE_PER_REQUEST_INPUT_CAP;
|
|
3687
3867
|
exports.CONTEXT_WINDOW_BY_MODEL = CONTEXT_WINDOW_BY_MODEL;
|
|
@@ -3692,9 +3872,12 @@ exports.DEFAULT_OPENAI_MODEL = DEFAULT_OPENAI_MODEL;
|
|
|
3692
3872
|
exports.EXPIRED_ATTACHMENT_URL_HOST = EXPIRED_ATTACHMENT_URL_HOST;
|
|
3693
3873
|
exports.EXPIRED_ATTACHMENT_URL_ORIGIN = EXPIRED_ATTACHMENT_URL_ORIGIN;
|
|
3694
3874
|
exports.EXPIRED_LINK_REFRESH_EXPIRES_SECONDS = EXPIRED_LINK_REFRESH_EXPIRES_SECONDS;
|
|
3875
|
+
exports.EXT_CONTENT_TYPES = EXT_CONTENT_TYPES;
|
|
3695
3876
|
exports.HISTORY_BUDGET_RATIO = HISTORY_BUDGET_RATIO;
|
|
3696
3877
|
exports.HISTORY_FILL_SLACK_PX = HISTORY_FILL_SLACK_PX;
|
|
3697
3878
|
exports.HISTORY_TOKEN_BUDGET = HISTORY_TOKEN_BUDGET;
|
|
3879
|
+
exports.HTML_EXTS = HTML_EXTS;
|
|
3880
|
+
exports.HTML_HEAD_WINDOW = HTML_HEAD_WINDOW;
|
|
3698
3881
|
exports.LINK_LABEL_MAX_DISPLAY_CHARS = LINK_LABEL_MAX_DISPLAY_CHARS;
|
|
3699
3882
|
exports.LINK_REFRESH_WINDOW_MS = LINK_REFRESH_WINDOW_MS;
|
|
3700
3883
|
exports.MAX_HISTORY_FILL_PAGES = MAX_HISTORY_FILL_PAGES;
|
|
@@ -3705,7 +3888,10 @@ exports.MIN_INPUT_TOKEN_BUDGET = MIN_INPUT_TOKEN_BUDGET;
|
|
|
3705
3888
|
exports.OUTPUT_TOKEN_RESERVE = OUTPUT_TOKEN_RESERVE;
|
|
3706
3889
|
exports.POLL_INTERVAL = POLL_INTERVAL;
|
|
3707
3890
|
exports.RENDER_FROM_TOKEN = RENDER_FROM_TOKEN;
|
|
3891
|
+
exports.RTF_EXTS = RTF_EXTS;
|
|
3708
3892
|
exports.TOOL_AND_RESPONSE_BUFFER = TOOL_AND_RESPONSE_BUFFER;
|
|
3893
|
+
exports.XML_EXTS = XML_EXTS;
|
|
3894
|
+
exports.applyEncodingDeclaration = applyEncodingDeclaration;
|
|
3709
3895
|
exports.buildAiAgentValue = buildAiAgentValue;
|
|
3710
3896
|
exports.buildBoundedChatMessages = buildBoundedChatMessages;
|
|
3711
3897
|
exports.buildChatDisplayList = buildChatDisplayList;
|
|
@@ -3725,11 +3911,17 @@ exports.classifyInlineLink = classifyInlineLink;
|
|
|
3725
3911
|
exports.clearAttachmentParsers = clearAttachmentParsers;
|
|
3726
3912
|
exports.composeUserMessage = composeUserMessage;
|
|
3727
3913
|
exports.configureChatEngine = configureChatEngine;
|
|
3914
|
+
exports.contentTypeForExt = contentTypeForExt;
|
|
3728
3915
|
exports.createHistoryFiller = createHistoryFiller;
|
|
3729
3916
|
exports.createInlineLinkRegex = createInlineLinkRegex;
|
|
3730
3917
|
exports.encodePathSegments = encodePathSegments;
|
|
3918
|
+
exports.encodingClassForExt = encodingClassForExt;
|
|
3919
|
+
exports.ensureHtmlCharset = ensureHtmlCharset;
|
|
3920
|
+
exports.ensureXmlEncoding = ensureXmlEncoding;
|
|
3921
|
+
exports.escapeRtfNonAscii = escapeRtfNonAscii;
|
|
3731
3922
|
exports.estimateMessageTokens = estimateMessageTokens;
|
|
3732
3923
|
exports.estimateTextTokens = estimateTextTokens;
|
|
3924
|
+
exports.extOf = extOf;
|
|
3733
3925
|
exports.extractClaudeText = extractClaudeText;
|
|
3734
3926
|
exports.extractLastUserTextFromRequest = extractLastUserTextFromRequest;
|
|
3735
3927
|
exports.extractOpenAIText = extractOpenAIText;
|
|
@@ -3745,6 +3937,7 @@ exports.getErrorMessage = getErrorMessage;
|
|
|
3745
3937
|
exports.getExpiredAttachmentVisiblePath = getExpiredAttachmentVisiblePath;
|
|
3746
3938
|
exports.getProjectContextWindow = getProjectContextWindow;
|
|
3747
3939
|
exports.groupAttachmentFailures = groupAttachmentFailures;
|
|
3940
|
+
exports.hasBom = hasBom;
|
|
3748
3941
|
exports.isAuthExpiredError = isAuthExpiredError;
|
|
3749
3942
|
exports.isBgIndexingQueue = isBgIndexingQueue;
|
|
3750
3943
|
exports.isErrorResponseBody = isErrorResponseBody;
|
|
@@ -3756,9 +3949,12 @@ exports.isServerExtractable = isServerExtractable;
|
|
|
3756
3949
|
exports.isServiceDbAttachmentHref = isServiceDbAttachmentHref;
|
|
3757
3950
|
exports.listClaudeModels = listClaudeModels;
|
|
3758
3951
|
exports.listOpenAIModels = listOpenAIModels;
|
|
3952
|
+
exports.looksLikeRtf = looksLikeRtf;
|
|
3759
3953
|
exports.makeExtractPlaceholder = makeExtractPlaceholder;
|
|
3760
3954
|
exports.mapHistoryListToMessages = mapHistoryListToMessages;
|
|
3955
|
+
exports.needsBomForExt = needsBomForExt;
|
|
3761
3956
|
exports.normalizeAttachmentPathCandidate = normalizeAttachmentPathCandidate;
|
|
3957
|
+
exports.normalizeExt = normalizeExt;
|
|
3762
3958
|
exports.normalizeTextContent = normalizeTextContent;
|
|
3763
3959
|
exports.normalizeTrailingInlineToken = normalizeTrailingInlineToken;
|
|
3764
3960
|
exports.notifyAgentSaveAttachment = notifyAgentSaveAttachment;
|
|
@@ -3766,6 +3962,7 @@ exports.parseAiAgentValue = parseAiAgentValue;
|
|
|
3766
3962
|
exports.parseAttachmentContent = parseAttachmentContent;
|
|
3767
3963
|
exports.parseIndexingLabel = parseIndexingLabel;
|
|
3768
3964
|
exports.parseIndexingRequestText = parseIndexingRequestText;
|
|
3965
|
+
exports.prepareDownloadText = prepareDownloadText;
|
|
3769
3966
|
exports.readExpiredAttachmentHref = readExpiredAttachmentHref;
|
|
3770
3967
|
exports.registerAttachmentParser = registerAttachmentParser;
|
|
3771
3968
|
exports.registerModelContextWindows = registerModelContextWindows;
|