bunnyquery 1.8.0 → 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 +455 -43
- package/dist/engine.cjs +489 -33
- package/dist/engine.cjs.map +1 -1
- package/dist/engine.d.mts +232 -3
- package/dist/engine.d.ts +232 -3
- package/dist/engine.mjs +462 -34
- package/dist/engine.mjs.map +1 -1
- package/package.json +1 -1
- package/src/engine/ai_agent.ts +80 -0
- package/src/engine/budget.ts +113 -7
- package/src/engine/download_encoding.ts +281 -0
- package/src/engine/errors.ts +34 -0
- package/src/engine/history.ts +48 -18
- package/src/engine/index.ts +11 -0
- package/src/engine/requests.ts +15 -3
- package/src/engine/session.ts +227 -6
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) {
|
|
@@ -757,25 +775,74 @@ function truncateLabelForDisplay(label) {
|
|
|
757
775
|
// src/engine/budget.ts
|
|
758
776
|
var CONTEXT_WINDOW_DEFAULT = { claude: 2e5, openai: 128e3 };
|
|
759
777
|
var CONTEXT_WINDOW_BY_MODEL = {
|
|
760
|
-
|
|
778
|
+
// exact ids
|
|
779
|
+
"claude-opus-5": 1e6,
|
|
780
|
+
"claude-opus-4-8": 1e6,
|
|
781
|
+
"claude-opus-4-7": 1e6,
|
|
782
|
+
"claude-sonnet-5": 1e6,
|
|
783
|
+
"claude-sonnet-4-6": 1e6,
|
|
761
784
|
"claude-sonnet-4": 2e5,
|
|
762
|
-
"
|
|
785
|
+
"claude-haiku-4-5": 2e5,
|
|
786
|
+
"gpt-5.4": 128e3,
|
|
787
|
+
"gpt-5.6-luna": 128e3,
|
|
788
|
+
// family keys
|
|
789
|
+
"claude-opus": 1e6,
|
|
790
|
+
"claude-sonnet": 1e6,
|
|
791
|
+
"claude-haiku": 2e5,
|
|
792
|
+
"gpt-5.6": 128e3,
|
|
793
|
+
"gpt-5": 128e3
|
|
763
794
|
};
|
|
795
|
+
var apiReportedContextWindows = {};
|
|
796
|
+
function registerModelContextWindows(models) {
|
|
797
|
+
if (!Array.isArray(models)) return;
|
|
798
|
+
for (var i = 0; i < models.length; i++) {
|
|
799
|
+
var m = models[i];
|
|
800
|
+
var id = (m && m.id ? String(m.id) : "").trim().toLowerCase();
|
|
801
|
+
var reported = m ? Number(m.max_input_tokens) : NaN;
|
|
802
|
+
if (id && Number.isFinite(reported) && reported > 0) {
|
|
803
|
+
apiReportedContextWindows[id] = Math.floor(reported);
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
var projectContextWindows = {};
|
|
808
|
+
function setProjectContextWindow(serviceId, tokens) {
|
|
809
|
+
var key = (serviceId || "").trim();
|
|
810
|
+
if (!key) return;
|
|
811
|
+
var n = Number(tokens);
|
|
812
|
+
if (Number.isFinite(n) && n > 0) projectContextWindows[key] = Math.floor(n);
|
|
813
|
+
else delete projectContextWindows[key];
|
|
814
|
+
}
|
|
815
|
+
function getProjectContextWindow(serviceId) {
|
|
816
|
+
var key = (serviceId || "").trim();
|
|
817
|
+
return key && projectContextWindows[key] ? projectContextWindows[key] : null;
|
|
818
|
+
}
|
|
764
819
|
var OUTPUT_TOKEN_RESERVE = 22e3;
|
|
765
820
|
var TOOL_AND_RESPONSE_BUFFER = 4e3;
|
|
766
821
|
var MIN_INPUT_TOKEN_BUDGET = 8e3;
|
|
767
822
|
var CLAUDE_PER_REQUEST_INPUT_CAP = 28e3;
|
|
768
823
|
var MAX_HISTORY_MESSAGES = 20;
|
|
769
824
|
var HISTORY_TOKEN_BUDGET = 8e3;
|
|
825
|
+
var CLAUDE_INPUT_CAP_RATIO = 0.16;
|
|
826
|
+
var HISTORY_BUDGET_RATIO = 0.08;
|
|
770
827
|
function estimateTextTokens(text) {
|
|
771
828
|
return Math.ceil((text || "").length / 3);
|
|
772
829
|
}
|
|
773
830
|
function estimateMessageTokens(msg) {
|
|
774
831
|
return estimateTextTokens(msg.content) + estimateTextTokens(msg.role) + 6;
|
|
775
832
|
}
|
|
776
|
-
function getContextWindow(platform, model) {
|
|
833
|
+
function getContextWindow(platform, model, serviceId) {
|
|
834
|
+
var override = serviceId ? getProjectContextWindow(serviceId) : null;
|
|
835
|
+
if (override) return override;
|
|
777
836
|
var normalized = (model || "").trim().toLowerCase();
|
|
778
|
-
if (normalized
|
|
837
|
+
if (normalized) {
|
|
838
|
+
if (apiReportedContextWindows[normalized]) return apiReportedContextWindows[normalized];
|
|
839
|
+
if (CONTEXT_WINDOW_BY_MODEL[normalized]) return CONTEXT_WINDOW_BY_MODEL[normalized];
|
|
840
|
+
var parts = normalized.split("-");
|
|
841
|
+
for (var end = parts.length - 1; end > 0; end--) {
|
|
842
|
+
var family = parts.slice(0, end).join("-");
|
|
843
|
+
if (CONTEXT_WINDOW_BY_MODEL[family]) return CONTEXT_WINDOW_BY_MODEL[family];
|
|
844
|
+
}
|
|
845
|
+
}
|
|
779
846
|
return CONTEXT_WINDOW_DEFAULT[platform];
|
|
780
847
|
}
|
|
781
848
|
function stripFileBlocksFromHistory(content) {
|
|
@@ -783,15 +850,19 @@ function stripFileBlocksFromHistory(content) {
|
|
|
783
850
|
return content.replace(/```([^\n`]+?\.[^\s.`]+)\n[\s\S]*?```/g, "[file previously attached: $1]");
|
|
784
851
|
}
|
|
785
852
|
function buildBoundedChatMessages(options) {
|
|
786
|
-
var contextWindow = getContextWindow(options.platform, options.model);
|
|
853
|
+
var contextWindow = getContextWindow(options.platform, options.model, options.serviceId);
|
|
787
854
|
var contextBasedBudget = Math.max(
|
|
788
855
|
MIN_INPUT_TOKEN_BUDGET,
|
|
789
856
|
contextWindow - OUTPUT_TOKEN_RESERVE - TOOL_AND_RESPONSE_BUFFER
|
|
790
857
|
);
|
|
791
|
-
var
|
|
858
|
+
var scaled = !!(options.serviceId && getProjectContextWindow(options.serviceId));
|
|
859
|
+
var claudeInputCap = scaled ? Math.max(CLAUDE_PER_REQUEST_INPUT_CAP, Math.round(contextBasedBudget * CLAUDE_INPUT_CAP_RATIO)) : CLAUDE_PER_REQUEST_INPUT_CAP;
|
|
860
|
+
var availableInputBudget = options.platform === "claude" ? Math.min(contextBasedBudget, claudeInputCap) : contextBasedBudget;
|
|
792
861
|
var systemCost = estimateTextTokens(options.systemPrompt) + 12;
|
|
793
|
-
var
|
|
794
|
-
var
|
|
862
|
+
var historyAllowance = scaled ? Math.max(HISTORY_TOKEN_BUDGET, Math.round(contextBasedBudget * HISTORY_BUDGET_RATIO)) : HISTORY_TOKEN_BUDGET;
|
|
863
|
+
var budgetForHistory = Math.max(1e3, Math.min(historyAllowance, availableInputBudget - systemCost));
|
|
864
|
+
var maxHistoryMessages = scaled ? Math.max(MAX_HISTORY_MESSAGES, Math.round(MAX_HISTORY_MESSAGES * (budgetForHistory / HISTORY_TOKEN_BUDGET))) : MAX_HISTORY_MESSAGES;
|
|
865
|
+
var windowed = options.history.slice(-maxHistoryMessages);
|
|
795
866
|
var latestIndex = windowed.length - 1;
|
|
796
867
|
var trimmed = windowed.map(function(m, i2) {
|
|
797
868
|
if (i2 === latestIndex) return m;
|
|
@@ -816,6 +887,166 @@ function buildBoundedChatMessages(options) {
|
|
|
816
887
|
};
|
|
817
888
|
}
|
|
818
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
|
+
|
|
819
1050
|
// src/engine/time.ts
|
|
820
1051
|
function wallClockNow() {
|
|
821
1052
|
return Date.now();
|
|
@@ -836,6 +1067,40 @@ function formatChatTimestamp(ms) {
|
|
|
836
1067
|
}
|
|
837
1068
|
}
|
|
838
1069
|
|
|
1070
|
+
// src/engine/ai_agent.ts
|
|
1071
|
+
function normalizePlatform(raw) {
|
|
1072
|
+
var p = (raw || "").trim().toLowerCase();
|
|
1073
|
+
return p === "claude" || p === "openai" ? p : null;
|
|
1074
|
+
}
|
|
1075
|
+
function parseAiAgentValue(value) {
|
|
1076
|
+
var raw = (value || "").trim();
|
|
1077
|
+
if (!raw || raw.toLowerCase() === "none") {
|
|
1078
|
+
return { platform: null, model: "", contextWindow: null, hasPlatform: false };
|
|
1079
|
+
}
|
|
1080
|
+
var firstHash = raw.indexOf("#");
|
|
1081
|
+
if (firstHash === -1) {
|
|
1082
|
+
var only = normalizePlatform(raw);
|
|
1083
|
+
return { platform: only, model: "", contextWindow: null, hasPlatform: !!only };
|
|
1084
|
+
}
|
|
1085
|
+
var platform = normalizePlatform(raw.slice(0, firstHash));
|
|
1086
|
+
var rest = raw.slice(firstHash + 1);
|
|
1087
|
+
var secondHash = rest.indexOf("#");
|
|
1088
|
+
var model = (secondHash === -1 ? rest : rest.slice(0, secondHash)).trim();
|
|
1089
|
+
var windowRaw = secondHash === -1 ? "" : rest.slice(secondHash + 1).trim();
|
|
1090
|
+
var parsedWindow = windowRaw ? Number(windowRaw) : NaN;
|
|
1091
|
+
var contextWindow = Number.isFinite(parsedWindow) && parsedWindow > 0 ? Math.floor(parsedWindow) : null;
|
|
1092
|
+
return { platform, model, contextWindow, hasPlatform: !!platform };
|
|
1093
|
+
}
|
|
1094
|
+
function buildAiAgentValue(platform, model, contextWindow) {
|
|
1095
|
+
var p = (platform || "").trim().toLowerCase();
|
|
1096
|
+
if (!p || p === "none") return "none";
|
|
1097
|
+
var m = (model || "").trim();
|
|
1098
|
+
if (!m) return p;
|
|
1099
|
+
var n = Number(contextWindow);
|
|
1100
|
+
if (!Number.isFinite(n) || n <= 0) return p + "#" + m;
|
|
1101
|
+
return p + "#" + m + "#" + Math.floor(n);
|
|
1102
|
+
}
|
|
1103
|
+
|
|
839
1104
|
// src/engine/requests.ts
|
|
840
1105
|
var ANTHROPIC_MESSAGES_API_URL = "https://api.anthropic.com/v1/messages";
|
|
841
1106
|
var ANTHROPIC_MODELS_API_URL = "https://api.anthropic.com/v1/models";
|
|
@@ -954,7 +1219,7 @@ function applyHistoryCacheBreakpoint(messages) {
|
|
|
954
1219
|
return { ...m, content: blocks };
|
|
955
1220
|
});
|
|
956
1221
|
}
|
|
957
|
-
var POLL_INTERVAL =
|
|
1222
|
+
var POLL_INTERVAL = 3e3;
|
|
958
1223
|
async function callClaudeWithMcp({
|
|
959
1224
|
prompt,
|
|
960
1225
|
messages,
|
|
@@ -1344,7 +1609,8 @@ async function getChatHistory(params, fetchOptions) {
|
|
|
1344
1609
|
method: "POST"
|
|
1345
1610
|
},
|
|
1346
1611
|
{ service: params.service, owner: params.owner },
|
|
1347
|
-
params.queue ? { queue: params.queue } : {}
|
|
1612
|
+
params.queue ? { queue: params.queue } : {},
|
|
1613
|
+
params.status ? { status: params.status } : {}
|
|
1348
1614
|
);
|
|
1349
1615
|
return chatEngineConfig().clientSecretRequestHistory(
|
|
1350
1616
|
p,
|
|
@@ -1381,6 +1647,25 @@ function extractLastUserTextFromRequest(requestBody) {
|
|
|
1381
1647
|
}
|
|
1382
1648
|
return "";
|
|
1383
1649
|
}
|
|
1650
|
+
function isIndexingRequestText(userText) {
|
|
1651
|
+
if (typeof userText !== "string") return false;
|
|
1652
|
+
return userText.indexOf("A new file has just been uploaded") === 0 || userText.indexOf("CONTINUE indexing") === 0;
|
|
1653
|
+
}
|
|
1654
|
+
function parseIndexingRequestText(userText) {
|
|
1655
|
+
if (typeof userText !== "string" || !userText) return null;
|
|
1656
|
+
var nameMatch = userText.match(/^- name: (.+)$/m);
|
|
1657
|
+
if (!nameMatch) return null;
|
|
1658
|
+
var mimeMatch = userText.match(/^- mime type: (.+)$/m);
|
|
1659
|
+
var sizeMatch = userText.match(/^- size \(bytes\): (\d+)$/m);
|
|
1660
|
+
var pathMatch = userText.match(/^- storage path: (.+)$/m);
|
|
1661
|
+
return {
|
|
1662
|
+
name: nameMatch[1].trim(),
|
|
1663
|
+
path: pathMatch ? pathMatch[1].trim() : void 0,
|
|
1664
|
+
mime: mimeMatch ? mimeMatch[1].trim() : void 0,
|
|
1665
|
+
size: sizeMatch ? Number(sizeMatch[1]) : void 0,
|
|
1666
|
+
continued: userText.indexOf("CONTINUE indexing") === 0
|
|
1667
|
+
};
|
|
1668
|
+
}
|
|
1384
1669
|
function mapHistoryListToMessages(list, platform, opts) {
|
|
1385
1670
|
var mapped = [], runningItemIds = [];
|
|
1386
1671
|
var extractAssistantText = platform === "openai" ? extractOpenAIText : extractClaudeText;
|
|
@@ -1405,27 +1690,17 @@ function mapHistoryListToMessages(list, platform, opts) {
|
|
|
1405
1690
|
var displayContent;
|
|
1406
1691
|
var indexFile = void 0;
|
|
1407
1692
|
if (item._isBgTask) {
|
|
1408
|
-
var
|
|
1409
|
-
if (
|
|
1410
|
-
var mimeMatch = userText.match(/^- mime type: (.+)$/m);
|
|
1411
|
-
var sizeMatch = userText.match(/^- size \(bytes\): (\d+)$/m);
|
|
1412
|
-
var pathMatch = userText.match(/^- storage path: (.+)$/m);
|
|
1413
|
-
var isContinuePass = userText.indexOf("CONTINUE indexing") === 0;
|
|
1693
|
+
var ref = parseIndexingRequestText(userText);
|
|
1694
|
+
if (ref) {
|
|
1414
1695
|
displayContent = opts.formatIndexingLabel(
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1696
|
+
ref.name,
|
|
1697
|
+
ref.mime || "",
|
|
1698
|
+
typeof ref.size === "number" ? ref.size : null,
|
|
1699
|
+
ref.path,
|
|
1419
1700
|
false,
|
|
1420
|
-
|
|
1701
|
+
ref.continued
|
|
1421
1702
|
);
|
|
1422
|
-
indexFile =
|
|
1423
|
-
name: nameMatch[1].trim(),
|
|
1424
|
-
path: pathMatch ? pathMatch[1].trim() : void 0,
|
|
1425
|
-
mime: mimeMatch ? mimeMatch[1].trim() : void 0,
|
|
1426
|
-
size: sizeMatch ? Number(sizeMatch[1]) : void 0,
|
|
1427
|
-
continued: isContinuePass
|
|
1428
|
-
};
|
|
1703
|
+
indexFile = ref;
|
|
1429
1704
|
} else {
|
|
1430
1705
|
displayContent = userText;
|
|
1431
1706
|
}
|
|
@@ -1554,6 +1829,8 @@ function createHistoryFiller(base) {
|
|
|
1554
1829
|
}
|
|
1555
1830
|
|
|
1556
1831
|
// src/engine/session.ts
|
|
1832
|
+
var WORKER_PASS_ADOPT_LIMIT = 20;
|
|
1833
|
+
var WORKER_PASS_ADOPT_ATTEMPTS = [0, 2e3, 6e3];
|
|
1557
1834
|
var _g = typeof globalThis !== "undefined" ? globalThis : {};
|
|
1558
1835
|
function nowMs() {
|
|
1559
1836
|
return _g.performance && typeof _g.performance.now === "function" ? _g.performance.now() : Date.now();
|
|
@@ -1573,6 +1850,35 @@ function isPollStopped(res) {
|
|
|
1573
1850
|
var ChatSession = class {
|
|
1574
1851
|
constructor(host) {
|
|
1575
1852
|
this.typewriterQueue = Promise.resolve();
|
|
1853
|
+
/**
|
|
1854
|
+
* Pick up indexing passes the WORKER minted, which no client ever dispatched.
|
|
1855
|
+
*
|
|
1856
|
+
* For a PDF (and for text/grid when windowed indexing is on) the worker writes
|
|
1857
|
+
* pass N+1's row itself, inside pass N's invocation, right after saving pass
|
|
1858
|
+
* N's result. That row reaches this client through nothing at all: it is not in
|
|
1859
|
+
* bgTaskQueue (the client never asked for it) and it is not in state.messages
|
|
1860
|
+
* (only a first-page history load maps it in, which happens on mount, project
|
|
1861
|
+
* switch or tab return). So between two worker passes every pass the client
|
|
1862
|
+
* knows about is settled, and the collapsed row renders "Indexed N passes"
|
|
1863
|
+
* with no spinner and no Stop, for a file that is still being read. A user who
|
|
1864
|
+
* believes that then asks questions against a half-indexed file — which is what
|
|
1865
|
+
* this exists to prevent.
|
|
1866
|
+
*
|
|
1867
|
+
* So when a background indexing pass settles, ask the bg queue what is still
|
|
1868
|
+
* unresolved on it and adopt anything unknown as an ordinary BgTaskEntry.
|
|
1869
|
+
* drainBgTaskQueue then treats it exactly like a pass this client dispatched:
|
|
1870
|
+
* same bubble, same `_indexFile` (so it joins the file's collapsed row), same
|
|
1871
|
+
* poll — and that poll settling runs this again, so the chain is followed to
|
|
1872
|
+
* its end. `status`-scoped so the reply carries the live items only, never a
|
|
1873
|
+
* page of finished ones with their bodies.
|
|
1874
|
+
*
|
|
1875
|
+
* Termination: the only trigger is a pass SETTLING, which happens once per
|
|
1876
|
+
* pass. An adopted item that is still running is not re-adopted (its id is
|
|
1877
|
+
* already polled), and when the queue holds nothing unknown the chain stops on
|
|
1878
|
+
* its own. Nothing here is periodic — a timer that re-reads history is the
|
|
1879
|
+
* shape that previously looped fetchHistoryPage after an already-DONE index.
|
|
1880
|
+
*/
|
|
1881
|
+
this._adoptingWorkerPasses = false;
|
|
1576
1882
|
this.host = host;
|
|
1577
1883
|
this.state = {
|
|
1578
1884
|
messages: [],
|
|
@@ -1862,7 +2168,7 @@ var ChatSession = class {
|
|
|
1862
2168
|
var chatQueue = useBgQueue ? userId + BG_INDEXING_QUEUE_SUFFIX : userId;
|
|
1863
2169
|
if (offChat) {
|
|
1864
2170
|
var offHistory = (this.aiChatHistoryCache[key] ? this.aiChatHistoryCache[key].messages : []).filter(function(m) {
|
|
1865
|
-
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;
|
|
1866
2172
|
});
|
|
1867
2173
|
var offBounded = buildBoundedChatMessages({
|
|
1868
2174
|
platform: aiPlatform,
|
|
@@ -1897,7 +2203,7 @@ var ChatSession = class {
|
|
|
1897
2203
|
}
|
|
1898
2204
|
if (isQueuedSend) {
|
|
1899
2205
|
var resolvedHistory = this.state.messages.filter(function(m) {
|
|
1900
|
-
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;
|
|
1901
2207
|
});
|
|
1902
2208
|
var boundedQ = buildBoundedChatMessages({
|
|
1903
2209
|
platform: aiPlatform,
|
|
@@ -1948,7 +2254,7 @@ var ChatSession = class {
|
|
|
1948
2254
|
this.state.sending = true;
|
|
1949
2255
|
this.host.scrollToBottom(true);
|
|
1950
2256
|
var historyForLlm = this.state.messages.filter(function(m) {
|
|
1951
|
-
return !m.isCancelled && !m.isBackgroundTask;
|
|
2257
|
+
return !m.isPending && !m.isPendingQueued && !m.isPendingInProcess && !m.isPendingOlder && !m.isCancelled && !m.isBackgroundTask && !m.isError;
|
|
1952
2258
|
});
|
|
1953
2259
|
if (llmComposed !== composed) {
|
|
1954
2260
|
for (var li = historyForLlm.length - 1; li >= 0; li--) {
|
|
@@ -2518,8 +2824,21 @@ var ChatSession = class {
|
|
|
2518
2824
|
}
|
|
2519
2825
|
// --- background-task resolution + drain -------------------------------
|
|
2520
2826
|
handleHistoryItemResolution(itemId, response, platform) {
|
|
2827
|
+
var indexRef = this._indexRefOfItem(itemId);
|
|
2521
2828
|
this.applyHistoryItemResolution(itemId, response, platform);
|
|
2522
2829
|
this.promoteNextBgQueuedToRunning();
|
|
2830
|
+
if (indexRef) this._followWorkerIndexingChain(indexRef.name, indexRef.mime);
|
|
2831
|
+
}
|
|
2832
|
+
/** The file an already-rendered background pass is about, off its request
|
|
2833
|
+
* bubble. Null for an ordinary turn, which is most of them. */
|
|
2834
|
+
_indexRefOfItem(itemId) {
|
|
2835
|
+
if (!itemId) return null;
|
|
2836
|
+
for (var i = 0; i < this.state.messages.length; i++) {
|
|
2837
|
+
var m = this.state.messages[i];
|
|
2838
|
+
if (m._serverItemId !== itemId || m.role !== "user" || !m.isBackgroundTask) continue;
|
|
2839
|
+
return m._indexFile || null;
|
|
2840
|
+
}
|
|
2841
|
+
return null;
|
|
2523
2842
|
}
|
|
2524
2843
|
applyHistoryItemResolution(itemId, response, platform) {
|
|
2525
2844
|
this.historyItemPolls.delete(itemId);
|
|
@@ -2653,6 +2972,116 @@ var ChatSession = class {
|
|
|
2653
2972
|
self.cancelQueuedMessage(t.msg, idx === -1 ? t.idx : idx);
|
|
2654
2973
|
});
|
|
2655
2974
|
}
|
|
2975
|
+
/**
|
|
2976
|
+
* True when the WORKER, not this client, drives the rest of this file's chain.
|
|
2977
|
+
* The mirror image of the early returns in maybeResumeIndexing: whatever that
|
|
2978
|
+
* refuses to continue is exactly what nothing client-side is tracking.
|
|
2979
|
+
*/
|
|
2980
|
+
_isWorkerDrivenIndexing(filename, mime) {
|
|
2981
|
+
if (!isPagedReadFile(filename, mime)) return false;
|
|
2982
|
+
if (isImageVisionFile(filename, mime)) return true;
|
|
2983
|
+
return windowedIndexingEnabled() && isWindowedReadFile(filename, mime);
|
|
2984
|
+
}
|
|
2985
|
+
_adoptWorkerIndexingPasses(attempt) {
|
|
2986
|
+
var self = this;
|
|
2987
|
+
if (this._adoptingWorkerPasses) return;
|
|
2988
|
+
var id = this.host.getIdentity();
|
|
2989
|
+
var platform = id.platform;
|
|
2990
|
+
if (!id.serviceId || platform !== "claude" && platform !== "openai") return;
|
|
2991
|
+
if (this.isPollingPaused() || !this.host.isViewMounted()) return;
|
|
2992
|
+
var svcId = id.serviceId, owner = id.owner;
|
|
2993
|
+
var queue = (id.userId || id.serviceId) + BG_INDEXING_QUEUE_SUFFIX;
|
|
2994
|
+
var ask = function(status) {
|
|
2995
|
+
return Promise.resolve(getChatHistory(
|
|
2996
|
+
{ service: svcId, owner, platform, queue, status },
|
|
2997
|
+
{ limit: WORKER_PASS_ADOPT_LIMIT }
|
|
2998
|
+
)).catch(function() {
|
|
2999
|
+
return null;
|
|
3000
|
+
});
|
|
3001
|
+
};
|
|
3002
|
+
this._adoptingWorkerPasses = true;
|
|
3003
|
+
Promise.all([ask("running"), ask("pending")]).then(function(results) {
|
|
3004
|
+
self._adoptingWorkerPasses = false;
|
|
3005
|
+
var now = self.host.getIdentity();
|
|
3006
|
+
if (now.serviceId !== svcId || now.platform !== platform) return;
|
|
3007
|
+
if (!self.host.isViewMounted()) return;
|
|
3008
|
+
var adoptedIds = [];
|
|
3009
|
+
for (var ri = 0; ri < results.length; ri++) {
|
|
3010
|
+
var list = results[ri] && Array.isArray(results[ri].list) ? results[ri].list : [];
|
|
3011
|
+
for (var i = 0; i < list.length; i++) {
|
|
3012
|
+
if (self._adoptWorkerIndexingItem(list[i], svcId, platform)) adoptedIds.push(list[i].id);
|
|
3013
|
+
}
|
|
3014
|
+
}
|
|
3015
|
+
if (adoptedIds.length) {
|
|
3016
|
+
self.drainBgTaskQueue();
|
|
3017
|
+
if (self._isTrackingAny(adoptedIds)) return;
|
|
3018
|
+
}
|
|
3019
|
+
if (attempt + 1 >= WORKER_PASS_ADOPT_ATTEMPTS.length) return;
|
|
3020
|
+
setTimeout(function() {
|
|
3021
|
+
var later = self.host.getIdentity();
|
|
3022
|
+
if (later.serviceId !== svcId || later.platform !== platform) return;
|
|
3023
|
+
if (self.isPollingPaused() || !self.host.isViewMounted()) return;
|
|
3024
|
+
self._adoptWorkerIndexingPasses(attempt + 1);
|
|
3025
|
+
}, WORKER_PASS_ADOPT_ATTEMPTS[attempt + 1]);
|
|
3026
|
+
}, function() {
|
|
3027
|
+
self._adoptingWorkerPasses = false;
|
|
3028
|
+
});
|
|
3029
|
+
}
|
|
3030
|
+
/** Any of these ids still queued or still polled, i.e. surviving work. */
|
|
3031
|
+
_isTrackingAny(ids) {
|
|
3032
|
+
for (var i = 0; i < ids.length; i++) {
|
|
3033
|
+
if (this.historyItemPolls.has(ids[i])) return true;
|
|
3034
|
+
for (var q = 0; q < this.bgTaskQueue.length; q++) {
|
|
3035
|
+
if (this.bgTaskQueue[q].id === ids[i]) return true;
|
|
3036
|
+
}
|
|
3037
|
+
}
|
|
3038
|
+
return false;
|
|
3039
|
+
}
|
|
3040
|
+
/** One live bg-queue item -> a BgTaskEntry, if it is an indexing pass this
|
|
3041
|
+
* client is not already tracking. Returns whether it was adopted. */
|
|
3042
|
+
_adoptWorkerIndexingItem(item, svcId, platform) {
|
|
3043
|
+
if (!item || typeof item.id !== "string" || !item.id) return false;
|
|
3044
|
+
if (item.status !== "pending" && item.status !== "running") return false;
|
|
3045
|
+
if (typeof item.poll !== "function") return false;
|
|
3046
|
+
if (this.historyItemPolls.has(item.id)) return false;
|
|
3047
|
+
for (var q = 0; q < this.bgTaskQueue.length; q++) {
|
|
3048
|
+
if (this.bgTaskQueue[q].id === item.id) return false;
|
|
3049
|
+
}
|
|
3050
|
+
for (var m = 0; m < this.state.messages.length; m++) {
|
|
3051
|
+
var msg = this.state.messages[m];
|
|
3052
|
+
if (msg._serverItemId !== item.id) continue;
|
|
3053
|
+
if (!(msg.isPending || msg.isPendingInProcess || msg.isPendingQueued)) return false;
|
|
3054
|
+
}
|
|
3055
|
+
var body = item.request_body;
|
|
3056
|
+
if (!body || typeof body !== "object") return false;
|
|
3057
|
+
if (platform === "claude" ? !Array.isArray(body.messages) : !Array.isArray(body.input)) return false;
|
|
3058
|
+
var userText = extractLastUserTextFromRequest(body);
|
|
3059
|
+
if (!isIndexingRequestText(userText)) return false;
|
|
3060
|
+
var ref = parseIndexingRequestText(userText);
|
|
3061
|
+
if (!ref || !ref.name) return false;
|
|
3062
|
+
if (!this._isWorkerDrivenIndexing(ref.name, ref.mime)) return false;
|
|
3063
|
+
this.bgTaskQueue.push({
|
|
3064
|
+
serviceId: svcId,
|
|
3065
|
+
platform,
|
|
3066
|
+
id: item.id,
|
|
3067
|
+
filename: ref.name,
|
|
3068
|
+
storagePath: ref.path,
|
|
3069
|
+
mime: ref.mime,
|
|
3070
|
+
size: ref.size,
|
|
3071
|
+
status: item.status === "running" ? "running" : "pending",
|
|
3072
|
+
poll: item.poll,
|
|
3073
|
+
// Drives the "(continuing)" label and marks this as a continuation for
|
|
3074
|
+
// _applyIndexCancellations, which must not read a CONTINUE pass as the
|
|
3075
|
+
// fresh first pass that lifts a stop.
|
|
3076
|
+
resumePass: ref.continued ? 1 : 0
|
|
3077
|
+
});
|
|
3078
|
+
return true;
|
|
3079
|
+
}
|
|
3080
|
+
/** Follow the chain on from a background indexing pass that just settled. */
|
|
3081
|
+
_followWorkerIndexingChain(filename, mime) {
|
|
3082
|
+
if (!this._isWorkerDrivenIndexing(filename, mime)) return;
|
|
3083
|
+
this._adoptWorkerIndexingPasses(0);
|
|
3084
|
+
}
|
|
2656
3085
|
/** Best-effort server-side cancel of a bg-queue item that has no bubble (so
|
|
2657
3086
|
* cancelQueuedMessage, which drives one, has nothing to act on). */
|
|
2658
3087
|
_cancelServerItem(serverId) {
|
|
@@ -2863,8 +3292,7 @@ var ChatSession = class {
|
|
|
2863
3292
|
var chatList = history && Array.isArray(history.list) ? history.list : [];
|
|
2864
3293
|
chatList.forEach(function(item) {
|
|
2865
3294
|
if (isBgIndexingQueue(item.queue_name)) {
|
|
2866
|
-
|
|
2867
|
-
if (typeof userText === "string" && (userText.indexOf("A new file has just been uploaded") === 0 || userText.indexOf("CONTINUE indexing") === 0)) item._isBgTask = true;
|
|
3295
|
+
if (isIndexingRequestText(extractLastUserTextFromRequest(item.request_body))) item._isBgTask = true;
|
|
2868
3296
|
else item._isOnBgQueue = true;
|
|
2869
3297
|
}
|
|
2870
3298
|
});
|
|
@@ -3432,6 +3860,9 @@ function buildChatDisplayList(messages, opts) {
|
|
|
3432
3860
|
}
|
|
3433
3861
|
|
|
3434
3862
|
exports.BG_INDEXING_QUEUE_SUFFIX = BG_INDEXING_QUEUE_SUFFIX;
|
|
3863
|
+
exports.BOM = BOM;
|
|
3864
|
+
exports.BOM_EXTS = BOM_EXTS;
|
|
3865
|
+
exports.CLAUDE_INPUT_CAP_RATIO = CLAUDE_INPUT_CAP_RATIO;
|
|
3435
3866
|
exports.CLAUDE_PER_REQUEST_INPUT_CAP = CLAUDE_PER_REQUEST_INPUT_CAP;
|
|
3436
3867
|
exports.CONTEXT_WINDOW_BY_MODEL = CONTEXT_WINDOW_BY_MODEL;
|
|
3437
3868
|
exports.CONTEXT_WINDOW_DEFAULT = CONTEXT_WINDOW_DEFAULT;
|
|
@@ -3441,8 +3872,12 @@ exports.DEFAULT_OPENAI_MODEL = DEFAULT_OPENAI_MODEL;
|
|
|
3441
3872
|
exports.EXPIRED_ATTACHMENT_URL_HOST = EXPIRED_ATTACHMENT_URL_HOST;
|
|
3442
3873
|
exports.EXPIRED_ATTACHMENT_URL_ORIGIN = EXPIRED_ATTACHMENT_URL_ORIGIN;
|
|
3443
3874
|
exports.EXPIRED_LINK_REFRESH_EXPIRES_SECONDS = EXPIRED_LINK_REFRESH_EXPIRES_SECONDS;
|
|
3875
|
+
exports.EXT_CONTENT_TYPES = EXT_CONTENT_TYPES;
|
|
3876
|
+
exports.HISTORY_BUDGET_RATIO = HISTORY_BUDGET_RATIO;
|
|
3444
3877
|
exports.HISTORY_FILL_SLACK_PX = HISTORY_FILL_SLACK_PX;
|
|
3445
3878
|
exports.HISTORY_TOKEN_BUDGET = HISTORY_TOKEN_BUDGET;
|
|
3879
|
+
exports.HTML_EXTS = HTML_EXTS;
|
|
3880
|
+
exports.HTML_HEAD_WINDOW = HTML_HEAD_WINDOW;
|
|
3446
3881
|
exports.LINK_LABEL_MAX_DISPLAY_CHARS = LINK_LABEL_MAX_DISPLAY_CHARS;
|
|
3447
3882
|
exports.LINK_REFRESH_WINDOW_MS = LINK_REFRESH_WINDOW_MS;
|
|
3448
3883
|
exports.MAX_HISTORY_FILL_PAGES = MAX_HISTORY_FILL_PAGES;
|
|
@@ -3453,7 +3888,11 @@ exports.MIN_INPUT_TOKEN_BUDGET = MIN_INPUT_TOKEN_BUDGET;
|
|
|
3453
3888
|
exports.OUTPUT_TOKEN_RESERVE = OUTPUT_TOKEN_RESERVE;
|
|
3454
3889
|
exports.POLL_INTERVAL = POLL_INTERVAL;
|
|
3455
3890
|
exports.RENDER_FROM_TOKEN = RENDER_FROM_TOKEN;
|
|
3891
|
+
exports.RTF_EXTS = RTF_EXTS;
|
|
3456
3892
|
exports.TOOL_AND_RESPONSE_BUFFER = TOOL_AND_RESPONSE_BUFFER;
|
|
3893
|
+
exports.XML_EXTS = XML_EXTS;
|
|
3894
|
+
exports.applyEncodingDeclaration = applyEncodingDeclaration;
|
|
3895
|
+
exports.buildAiAgentValue = buildAiAgentValue;
|
|
3457
3896
|
exports.buildBoundedChatMessages = buildBoundedChatMessages;
|
|
3458
3897
|
exports.buildChatDisplayList = buildChatDisplayList;
|
|
3459
3898
|
exports.buildChatSystemPrompt = buildChatSystemPrompt;
|
|
@@ -3472,11 +3911,17 @@ exports.classifyInlineLink = classifyInlineLink;
|
|
|
3472
3911
|
exports.clearAttachmentParsers = clearAttachmentParsers;
|
|
3473
3912
|
exports.composeUserMessage = composeUserMessage;
|
|
3474
3913
|
exports.configureChatEngine = configureChatEngine;
|
|
3914
|
+
exports.contentTypeForExt = contentTypeForExt;
|
|
3475
3915
|
exports.createHistoryFiller = createHistoryFiller;
|
|
3476
3916
|
exports.createInlineLinkRegex = createInlineLinkRegex;
|
|
3477
3917
|
exports.encodePathSegments = encodePathSegments;
|
|
3918
|
+
exports.encodingClassForExt = encodingClassForExt;
|
|
3919
|
+
exports.ensureHtmlCharset = ensureHtmlCharset;
|
|
3920
|
+
exports.ensureXmlEncoding = ensureXmlEncoding;
|
|
3921
|
+
exports.escapeRtfNonAscii = escapeRtfNonAscii;
|
|
3478
3922
|
exports.estimateMessageTokens = estimateMessageTokens;
|
|
3479
3923
|
exports.estimateTextTokens = estimateTextTokens;
|
|
3924
|
+
exports.extOf = extOf;
|
|
3480
3925
|
exports.extractClaudeText = extractClaudeText;
|
|
3481
3926
|
exports.extractLastUserTextFromRequest = extractLastUserTextFromRequest;
|
|
3482
3927
|
exports.extractOpenAIText = extractOpenAIText;
|
|
@@ -3490,31 +3935,42 @@ exports.getChatHistory = getChatHistory;
|
|
|
3490
3935
|
exports.getContextWindow = getContextWindow;
|
|
3491
3936
|
exports.getErrorMessage = getErrorMessage;
|
|
3492
3937
|
exports.getExpiredAttachmentVisiblePath = getExpiredAttachmentVisiblePath;
|
|
3938
|
+
exports.getProjectContextWindow = getProjectContextWindow;
|
|
3493
3939
|
exports.groupAttachmentFailures = groupAttachmentFailures;
|
|
3940
|
+
exports.hasBom = hasBom;
|
|
3494
3941
|
exports.isAuthExpiredError = isAuthExpiredError;
|
|
3495
3942
|
exports.isBgIndexingQueue = isBgIndexingQueue;
|
|
3496
3943
|
exports.isErrorResponseBody = isErrorResponseBody;
|
|
3497
3944
|
exports.isHttpUrlLike = isHttpUrlLike;
|
|
3945
|
+
exports.isIndexingRequestText = isIndexingRequestText;
|
|
3498
3946
|
exports.isNonRetryableRequestError = isNonRetryableRequestError;
|
|
3499
3947
|
exports.isOfficeFile = isOfficeFile;
|
|
3500
3948
|
exports.isServerExtractable = isServerExtractable;
|
|
3501
3949
|
exports.isServiceDbAttachmentHref = isServiceDbAttachmentHref;
|
|
3502
3950
|
exports.listClaudeModels = listClaudeModels;
|
|
3503
3951
|
exports.listOpenAIModels = listOpenAIModels;
|
|
3952
|
+
exports.looksLikeRtf = looksLikeRtf;
|
|
3504
3953
|
exports.makeExtractPlaceholder = makeExtractPlaceholder;
|
|
3505
3954
|
exports.mapHistoryListToMessages = mapHistoryListToMessages;
|
|
3955
|
+
exports.needsBomForExt = needsBomForExt;
|
|
3506
3956
|
exports.normalizeAttachmentPathCandidate = normalizeAttachmentPathCandidate;
|
|
3957
|
+
exports.normalizeExt = normalizeExt;
|
|
3507
3958
|
exports.normalizeTextContent = normalizeTextContent;
|
|
3508
3959
|
exports.normalizeTrailingInlineToken = normalizeTrailingInlineToken;
|
|
3509
3960
|
exports.notifyAgentSaveAttachment = notifyAgentSaveAttachment;
|
|
3961
|
+
exports.parseAiAgentValue = parseAiAgentValue;
|
|
3510
3962
|
exports.parseAttachmentContent = parseAttachmentContent;
|
|
3511
3963
|
exports.parseIndexingLabel = parseIndexingLabel;
|
|
3964
|
+
exports.parseIndexingRequestText = parseIndexingRequestText;
|
|
3965
|
+
exports.prepareDownloadText = prepareDownloadText;
|
|
3512
3966
|
exports.readExpiredAttachmentHref = readExpiredAttachmentHref;
|
|
3513
3967
|
exports.registerAttachmentParser = registerAttachmentParser;
|
|
3968
|
+
exports.registerModelContextWindows = registerModelContextWindows;
|
|
3514
3969
|
exports.repairUrlEntities = repairUrlEntities;
|
|
3515
3970
|
exports.repairUrlWhitespace = repairUrlWhitespace;
|
|
3516
3971
|
exports.safeDecodeURIComponent = safeDecodeURIComponent;
|
|
3517
3972
|
exports.sanitizeAttachmentLinksForHistory = sanitizeAttachmentLinksForHistory;
|
|
3973
|
+
exports.setProjectContextWindow = setProjectContextWindow;
|
|
3518
3974
|
exports.stripFileBlocksFromHistory = stripFileBlocksFromHistory;
|
|
3519
3975
|
exports.transformContentWithImages = transformContentWithImages;
|
|
3520
3976
|
exports.transformContentWithOpenAIImages = transformContentWithOpenAIImages;
|