bunnyquery 1.8.0 → 1.8.1

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/dist/engine.cjs CHANGED
@@ -757,25 +757,74 @@ function truncateLabelForDisplay(label) {
757
757
  // src/engine/budget.ts
758
758
  var CONTEXT_WINDOW_DEFAULT = { claude: 2e5, openai: 128e3 };
759
759
  var CONTEXT_WINDOW_BY_MODEL = {
760
- "claude-opus-4-7": 2e5,
760
+ // exact ids
761
+ "claude-opus-5": 1e6,
762
+ "claude-opus-4-8": 1e6,
763
+ "claude-opus-4-7": 1e6,
764
+ "claude-sonnet-5": 1e6,
765
+ "claude-sonnet-4-6": 1e6,
761
766
  "claude-sonnet-4": 2e5,
762
- "gpt-5.4": 128e3
767
+ "claude-haiku-4-5": 2e5,
768
+ "gpt-5.4": 128e3,
769
+ "gpt-5.6-luna": 128e3,
770
+ // family keys
771
+ "claude-opus": 1e6,
772
+ "claude-sonnet": 1e6,
773
+ "claude-haiku": 2e5,
774
+ "gpt-5.6": 128e3,
775
+ "gpt-5": 128e3
763
776
  };
777
+ var apiReportedContextWindows = {};
778
+ function registerModelContextWindows(models) {
779
+ if (!Array.isArray(models)) return;
780
+ for (var i = 0; i < models.length; i++) {
781
+ var m = models[i];
782
+ var id = (m && m.id ? String(m.id) : "").trim().toLowerCase();
783
+ var reported = m ? Number(m.max_input_tokens) : NaN;
784
+ if (id && Number.isFinite(reported) && reported > 0) {
785
+ apiReportedContextWindows[id] = Math.floor(reported);
786
+ }
787
+ }
788
+ }
789
+ var projectContextWindows = {};
790
+ function setProjectContextWindow(serviceId, tokens) {
791
+ var key = (serviceId || "").trim();
792
+ if (!key) return;
793
+ var n = Number(tokens);
794
+ if (Number.isFinite(n) && n > 0) projectContextWindows[key] = Math.floor(n);
795
+ else delete projectContextWindows[key];
796
+ }
797
+ function getProjectContextWindow(serviceId) {
798
+ var key = (serviceId || "").trim();
799
+ return key && projectContextWindows[key] ? projectContextWindows[key] : null;
800
+ }
764
801
  var OUTPUT_TOKEN_RESERVE = 22e3;
765
802
  var TOOL_AND_RESPONSE_BUFFER = 4e3;
766
803
  var MIN_INPUT_TOKEN_BUDGET = 8e3;
767
804
  var CLAUDE_PER_REQUEST_INPUT_CAP = 28e3;
768
805
  var MAX_HISTORY_MESSAGES = 20;
769
806
  var HISTORY_TOKEN_BUDGET = 8e3;
807
+ var CLAUDE_INPUT_CAP_RATIO = 0.16;
808
+ var HISTORY_BUDGET_RATIO = 0.08;
770
809
  function estimateTextTokens(text) {
771
810
  return Math.ceil((text || "").length / 3);
772
811
  }
773
812
  function estimateMessageTokens(msg) {
774
813
  return estimateTextTokens(msg.content) + estimateTextTokens(msg.role) + 6;
775
814
  }
776
- function getContextWindow(platform, model) {
815
+ function getContextWindow(platform, model, serviceId) {
816
+ var override = serviceId ? getProjectContextWindow(serviceId) : null;
817
+ if (override) return override;
777
818
  var normalized = (model || "").trim().toLowerCase();
778
- if (normalized && CONTEXT_WINDOW_BY_MODEL[normalized]) return CONTEXT_WINDOW_BY_MODEL[normalized];
819
+ if (normalized) {
820
+ if (apiReportedContextWindows[normalized]) return apiReportedContextWindows[normalized];
821
+ if (CONTEXT_WINDOW_BY_MODEL[normalized]) return CONTEXT_WINDOW_BY_MODEL[normalized];
822
+ var parts = normalized.split("-");
823
+ for (var end = parts.length - 1; end > 0; end--) {
824
+ var family = parts.slice(0, end).join("-");
825
+ if (CONTEXT_WINDOW_BY_MODEL[family]) return CONTEXT_WINDOW_BY_MODEL[family];
826
+ }
827
+ }
779
828
  return CONTEXT_WINDOW_DEFAULT[platform];
780
829
  }
781
830
  function stripFileBlocksFromHistory(content) {
@@ -783,15 +832,19 @@ function stripFileBlocksFromHistory(content) {
783
832
  return content.replace(/```([^\n`]+?\.[^\s.`]+)\n[\s\S]*?```/g, "[file previously attached: $1]");
784
833
  }
785
834
  function buildBoundedChatMessages(options) {
786
- var contextWindow = getContextWindow(options.platform, options.model);
835
+ var contextWindow = getContextWindow(options.platform, options.model, options.serviceId);
787
836
  var contextBasedBudget = Math.max(
788
837
  MIN_INPUT_TOKEN_BUDGET,
789
838
  contextWindow - OUTPUT_TOKEN_RESERVE - TOOL_AND_RESPONSE_BUFFER
790
839
  );
791
- var availableInputBudget = options.platform === "claude" ? Math.min(contextBasedBudget, CLAUDE_PER_REQUEST_INPUT_CAP) : contextBasedBudget;
840
+ var scaled = !!(options.serviceId && getProjectContextWindow(options.serviceId));
841
+ var claudeInputCap = scaled ? Math.max(CLAUDE_PER_REQUEST_INPUT_CAP, Math.round(contextBasedBudget * CLAUDE_INPUT_CAP_RATIO)) : CLAUDE_PER_REQUEST_INPUT_CAP;
842
+ var availableInputBudget = options.platform === "claude" ? Math.min(contextBasedBudget, claudeInputCap) : contextBasedBudget;
792
843
  var systemCost = estimateTextTokens(options.systemPrompt) + 12;
793
- var budgetForHistory = Math.max(1e3, Math.min(HISTORY_TOKEN_BUDGET, availableInputBudget - systemCost));
794
- var windowed = options.history.slice(-MAX_HISTORY_MESSAGES);
844
+ var historyAllowance = scaled ? Math.max(HISTORY_TOKEN_BUDGET, Math.round(contextBasedBudget * HISTORY_BUDGET_RATIO)) : HISTORY_TOKEN_BUDGET;
845
+ var budgetForHistory = Math.max(1e3, Math.min(historyAllowance, availableInputBudget - systemCost));
846
+ var maxHistoryMessages = scaled ? Math.max(MAX_HISTORY_MESSAGES, Math.round(MAX_HISTORY_MESSAGES * (budgetForHistory / HISTORY_TOKEN_BUDGET))) : MAX_HISTORY_MESSAGES;
847
+ var windowed = options.history.slice(-maxHistoryMessages);
795
848
  var latestIndex = windowed.length - 1;
796
849
  var trimmed = windowed.map(function(m, i2) {
797
850
  if (i2 === latestIndex) return m;
@@ -836,6 +889,40 @@ function formatChatTimestamp(ms) {
836
889
  }
837
890
  }
838
891
 
892
+ // src/engine/ai_agent.ts
893
+ function normalizePlatform(raw) {
894
+ var p = (raw || "").trim().toLowerCase();
895
+ return p === "claude" || p === "openai" ? p : null;
896
+ }
897
+ function parseAiAgentValue(value) {
898
+ var raw = (value || "").trim();
899
+ if (!raw || raw.toLowerCase() === "none") {
900
+ return { platform: null, model: "", contextWindow: null, hasPlatform: false };
901
+ }
902
+ var firstHash = raw.indexOf("#");
903
+ if (firstHash === -1) {
904
+ var only = normalizePlatform(raw);
905
+ return { platform: only, model: "", contextWindow: null, hasPlatform: !!only };
906
+ }
907
+ var platform = normalizePlatform(raw.slice(0, firstHash));
908
+ var rest = raw.slice(firstHash + 1);
909
+ var secondHash = rest.indexOf("#");
910
+ var model = (secondHash === -1 ? rest : rest.slice(0, secondHash)).trim();
911
+ var windowRaw = secondHash === -1 ? "" : rest.slice(secondHash + 1).trim();
912
+ var parsedWindow = windowRaw ? Number(windowRaw) : NaN;
913
+ var contextWindow = Number.isFinite(parsedWindow) && parsedWindow > 0 ? Math.floor(parsedWindow) : null;
914
+ return { platform, model, contextWindow, hasPlatform: !!platform };
915
+ }
916
+ function buildAiAgentValue(platform, model, contextWindow) {
917
+ var p = (platform || "").trim().toLowerCase();
918
+ if (!p || p === "none") return "none";
919
+ var m = (model || "").trim();
920
+ if (!m) return p;
921
+ var n = Number(contextWindow);
922
+ if (!Number.isFinite(n) || n <= 0) return p + "#" + m;
923
+ return p + "#" + m + "#" + Math.floor(n);
924
+ }
925
+
839
926
  // src/engine/requests.ts
840
927
  var ANTHROPIC_MESSAGES_API_URL = "https://api.anthropic.com/v1/messages";
841
928
  var ANTHROPIC_MODELS_API_URL = "https://api.anthropic.com/v1/models";
@@ -1344,7 +1431,8 @@ async function getChatHistory(params, fetchOptions) {
1344
1431
  method: "POST"
1345
1432
  },
1346
1433
  { service: params.service, owner: params.owner },
1347
- params.queue ? { queue: params.queue } : {}
1434
+ params.queue ? { queue: params.queue } : {},
1435
+ params.status ? { status: params.status } : {}
1348
1436
  );
1349
1437
  return chatEngineConfig().clientSecretRequestHistory(
1350
1438
  p,
@@ -1381,6 +1469,25 @@ function extractLastUserTextFromRequest(requestBody) {
1381
1469
  }
1382
1470
  return "";
1383
1471
  }
1472
+ function isIndexingRequestText(userText) {
1473
+ if (typeof userText !== "string") return false;
1474
+ return userText.indexOf("A new file has just been uploaded") === 0 || userText.indexOf("CONTINUE indexing") === 0;
1475
+ }
1476
+ function parseIndexingRequestText(userText) {
1477
+ if (typeof userText !== "string" || !userText) return null;
1478
+ var nameMatch = userText.match(/^- name: (.+)$/m);
1479
+ if (!nameMatch) return null;
1480
+ var mimeMatch = userText.match(/^- mime type: (.+)$/m);
1481
+ var sizeMatch = userText.match(/^- size \(bytes\): (\d+)$/m);
1482
+ var pathMatch = userText.match(/^- storage path: (.+)$/m);
1483
+ return {
1484
+ name: nameMatch[1].trim(),
1485
+ path: pathMatch ? pathMatch[1].trim() : void 0,
1486
+ mime: mimeMatch ? mimeMatch[1].trim() : void 0,
1487
+ size: sizeMatch ? Number(sizeMatch[1]) : void 0,
1488
+ continued: userText.indexOf("CONTINUE indexing") === 0
1489
+ };
1490
+ }
1384
1491
  function mapHistoryListToMessages(list, platform, opts) {
1385
1492
  var mapped = [], runningItemIds = [];
1386
1493
  var extractAssistantText = platform === "openai" ? extractOpenAIText : extractClaudeText;
@@ -1405,27 +1512,17 @@ function mapHistoryListToMessages(list, platform, opts) {
1405
1512
  var displayContent;
1406
1513
  var indexFile = void 0;
1407
1514
  if (item._isBgTask) {
1408
- var nameMatch = userText.match(/^- name: (.+)$/m);
1409
- if (nameMatch) {
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;
1515
+ var ref = parseIndexingRequestText(userText);
1516
+ if (ref) {
1414
1517
  displayContent = opts.formatIndexingLabel(
1415
- nameMatch[1].trim(),
1416
- mimeMatch ? mimeMatch[1].trim() : "",
1417
- sizeMatch ? Number(sizeMatch[1]) : null,
1418
- pathMatch ? pathMatch[1].trim() : void 0,
1518
+ ref.name,
1519
+ ref.mime || "",
1520
+ typeof ref.size === "number" ? ref.size : null,
1521
+ ref.path,
1419
1522
  false,
1420
- isContinuePass
1523
+ ref.continued
1421
1524
  );
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
- };
1525
+ indexFile = ref;
1429
1526
  } else {
1430
1527
  displayContent = userText;
1431
1528
  }
@@ -1554,6 +1651,8 @@ function createHistoryFiller(base) {
1554
1651
  }
1555
1652
 
1556
1653
  // src/engine/session.ts
1654
+ var WORKER_PASS_ADOPT_LIMIT = 20;
1655
+ var WORKER_PASS_ADOPT_ATTEMPTS = [0, 2e3, 6e3];
1557
1656
  var _g = typeof globalThis !== "undefined" ? globalThis : {};
1558
1657
  function nowMs() {
1559
1658
  return _g.performance && typeof _g.performance.now === "function" ? _g.performance.now() : Date.now();
@@ -1573,6 +1672,35 @@ function isPollStopped(res) {
1573
1672
  var ChatSession = class {
1574
1673
  constructor(host) {
1575
1674
  this.typewriterQueue = Promise.resolve();
1675
+ /**
1676
+ * Pick up indexing passes the WORKER minted, which no client ever dispatched.
1677
+ *
1678
+ * For a PDF (and for text/grid when windowed indexing is on) the worker writes
1679
+ * pass N+1's row itself, inside pass N's invocation, right after saving pass
1680
+ * N's result. That row reaches this client through nothing at all: it is not in
1681
+ * bgTaskQueue (the client never asked for it) and it is not in state.messages
1682
+ * (only a first-page history load maps it in, which happens on mount, project
1683
+ * switch or tab return). So between two worker passes every pass the client
1684
+ * knows about is settled, and the collapsed row renders "Indexed N passes"
1685
+ * with no spinner and no Stop, for a file that is still being read. A user who
1686
+ * believes that then asks questions against a half-indexed file — which is what
1687
+ * this exists to prevent.
1688
+ *
1689
+ * So when a background indexing pass settles, ask the bg queue what is still
1690
+ * unresolved on it and adopt anything unknown as an ordinary BgTaskEntry.
1691
+ * drainBgTaskQueue then treats it exactly like a pass this client dispatched:
1692
+ * same bubble, same `_indexFile` (so it joins the file's collapsed row), same
1693
+ * poll — and that poll settling runs this again, so the chain is followed to
1694
+ * its end. `status`-scoped so the reply carries the live items only, never a
1695
+ * page of finished ones with their bodies.
1696
+ *
1697
+ * Termination: the only trigger is a pass SETTLING, which happens once per
1698
+ * pass. An adopted item that is still running is not re-adopted (its id is
1699
+ * already polled), and when the queue holds nothing unknown the chain stops on
1700
+ * its own. Nothing here is periodic — a timer that re-reads history is the
1701
+ * shape that previously looped fetchHistoryPage after an already-DONE index.
1702
+ */
1703
+ this._adoptingWorkerPasses = false;
1576
1704
  this.host = host;
1577
1705
  this.state = {
1578
1706
  messages: [],
@@ -2518,8 +2646,21 @@ var ChatSession = class {
2518
2646
  }
2519
2647
  // --- background-task resolution + drain -------------------------------
2520
2648
  handleHistoryItemResolution(itemId, response, platform) {
2649
+ var indexRef = this._indexRefOfItem(itemId);
2521
2650
  this.applyHistoryItemResolution(itemId, response, platform);
2522
2651
  this.promoteNextBgQueuedToRunning();
2652
+ if (indexRef) this._followWorkerIndexingChain(indexRef.name, indexRef.mime);
2653
+ }
2654
+ /** The file an already-rendered background pass is about, off its request
2655
+ * bubble. Null for an ordinary turn, which is most of them. */
2656
+ _indexRefOfItem(itemId) {
2657
+ if (!itemId) return null;
2658
+ for (var i = 0; i < this.state.messages.length; i++) {
2659
+ var m = this.state.messages[i];
2660
+ if (m._serverItemId !== itemId || m.role !== "user" || !m.isBackgroundTask) continue;
2661
+ return m._indexFile || null;
2662
+ }
2663
+ return null;
2523
2664
  }
2524
2665
  applyHistoryItemResolution(itemId, response, platform) {
2525
2666
  this.historyItemPolls.delete(itemId);
@@ -2653,6 +2794,116 @@ var ChatSession = class {
2653
2794
  self.cancelQueuedMessage(t.msg, idx === -1 ? t.idx : idx);
2654
2795
  });
2655
2796
  }
2797
+ /**
2798
+ * True when the WORKER, not this client, drives the rest of this file's chain.
2799
+ * The mirror image of the early returns in maybeResumeIndexing: whatever that
2800
+ * refuses to continue is exactly what nothing client-side is tracking.
2801
+ */
2802
+ _isWorkerDrivenIndexing(filename, mime) {
2803
+ if (!isPagedReadFile(filename, mime)) return false;
2804
+ if (isImageVisionFile(filename, mime)) return true;
2805
+ return windowedIndexingEnabled() && isWindowedReadFile(filename, mime);
2806
+ }
2807
+ _adoptWorkerIndexingPasses(attempt) {
2808
+ var self = this;
2809
+ if (this._adoptingWorkerPasses) return;
2810
+ var id = this.host.getIdentity();
2811
+ var platform = id.platform;
2812
+ if (!id.serviceId || platform !== "claude" && platform !== "openai") return;
2813
+ if (this.isPollingPaused() || !this.host.isViewMounted()) return;
2814
+ var svcId = id.serviceId, owner = id.owner;
2815
+ var queue = (id.userId || id.serviceId) + BG_INDEXING_QUEUE_SUFFIX;
2816
+ var ask = function(status) {
2817
+ return Promise.resolve(getChatHistory(
2818
+ { service: svcId, owner, platform, queue, status },
2819
+ { limit: WORKER_PASS_ADOPT_LIMIT }
2820
+ )).catch(function() {
2821
+ return null;
2822
+ });
2823
+ };
2824
+ this._adoptingWorkerPasses = true;
2825
+ Promise.all([ask("running"), ask("pending")]).then(function(results) {
2826
+ self._adoptingWorkerPasses = false;
2827
+ var now = self.host.getIdentity();
2828
+ if (now.serviceId !== svcId || now.platform !== platform) return;
2829
+ if (!self.host.isViewMounted()) return;
2830
+ var adoptedIds = [];
2831
+ for (var ri = 0; ri < results.length; ri++) {
2832
+ var list = results[ri] && Array.isArray(results[ri].list) ? results[ri].list : [];
2833
+ for (var i = 0; i < list.length; i++) {
2834
+ if (self._adoptWorkerIndexingItem(list[i], svcId, platform)) adoptedIds.push(list[i].id);
2835
+ }
2836
+ }
2837
+ if (adoptedIds.length) {
2838
+ self.drainBgTaskQueue();
2839
+ if (self._isTrackingAny(adoptedIds)) return;
2840
+ }
2841
+ if (attempt + 1 >= WORKER_PASS_ADOPT_ATTEMPTS.length) return;
2842
+ setTimeout(function() {
2843
+ var later = self.host.getIdentity();
2844
+ if (later.serviceId !== svcId || later.platform !== platform) return;
2845
+ if (self.isPollingPaused() || !self.host.isViewMounted()) return;
2846
+ self._adoptWorkerIndexingPasses(attempt + 1);
2847
+ }, WORKER_PASS_ADOPT_ATTEMPTS[attempt + 1]);
2848
+ }, function() {
2849
+ self._adoptingWorkerPasses = false;
2850
+ });
2851
+ }
2852
+ /** Any of these ids still queued or still polled, i.e. surviving work. */
2853
+ _isTrackingAny(ids) {
2854
+ for (var i = 0; i < ids.length; i++) {
2855
+ if (this.historyItemPolls.has(ids[i])) return true;
2856
+ for (var q = 0; q < this.bgTaskQueue.length; q++) {
2857
+ if (this.bgTaskQueue[q].id === ids[i]) return true;
2858
+ }
2859
+ }
2860
+ return false;
2861
+ }
2862
+ /** One live bg-queue item -> a BgTaskEntry, if it is an indexing pass this
2863
+ * client is not already tracking. Returns whether it was adopted. */
2864
+ _adoptWorkerIndexingItem(item, svcId, platform) {
2865
+ if (!item || typeof item.id !== "string" || !item.id) return false;
2866
+ if (item.status !== "pending" && item.status !== "running") return false;
2867
+ if (typeof item.poll !== "function") return false;
2868
+ if (this.historyItemPolls.has(item.id)) return false;
2869
+ for (var q = 0; q < this.bgTaskQueue.length; q++) {
2870
+ if (this.bgTaskQueue[q].id === item.id) return false;
2871
+ }
2872
+ for (var m = 0; m < this.state.messages.length; m++) {
2873
+ var msg = this.state.messages[m];
2874
+ if (msg._serverItemId !== item.id) continue;
2875
+ if (!(msg.isPending || msg.isPendingInProcess || msg.isPendingQueued)) return false;
2876
+ }
2877
+ var body = item.request_body;
2878
+ if (!body || typeof body !== "object") return false;
2879
+ if (platform === "claude" ? !Array.isArray(body.messages) : !Array.isArray(body.input)) return false;
2880
+ var userText = extractLastUserTextFromRequest(body);
2881
+ if (!isIndexingRequestText(userText)) return false;
2882
+ var ref = parseIndexingRequestText(userText);
2883
+ if (!ref || !ref.name) return false;
2884
+ if (!this._isWorkerDrivenIndexing(ref.name, ref.mime)) return false;
2885
+ this.bgTaskQueue.push({
2886
+ serviceId: svcId,
2887
+ platform,
2888
+ id: item.id,
2889
+ filename: ref.name,
2890
+ storagePath: ref.path,
2891
+ mime: ref.mime,
2892
+ size: ref.size,
2893
+ status: item.status === "running" ? "running" : "pending",
2894
+ poll: item.poll,
2895
+ // Drives the "(continuing)" label and marks this as a continuation for
2896
+ // _applyIndexCancellations, which must not read a CONTINUE pass as the
2897
+ // fresh first pass that lifts a stop.
2898
+ resumePass: ref.continued ? 1 : 0
2899
+ });
2900
+ return true;
2901
+ }
2902
+ /** Follow the chain on from a background indexing pass that just settled. */
2903
+ _followWorkerIndexingChain(filename, mime) {
2904
+ if (!this._isWorkerDrivenIndexing(filename, mime)) return;
2905
+ this._adoptWorkerIndexingPasses(0);
2906
+ }
2656
2907
  /** Best-effort server-side cancel of a bg-queue item that has no bubble (so
2657
2908
  * cancelQueuedMessage, which drives one, has nothing to act on). */
2658
2909
  _cancelServerItem(serverId) {
@@ -2863,8 +3114,7 @@ var ChatSession = class {
2863
3114
  var chatList = history && Array.isArray(history.list) ? history.list : [];
2864
3115
  chatList.forEach(function(item) {
2865
3116
  if (isBgIndexingQueue(item.queue_name)) {
2866
- var userText = extractLastUserTextFromRequest(item.request_body);
2867
- if (typeof userText === "string" && (userText.indexOf("A new file has just been uploaded") === 0 || userText.indexOf("CONTINUE indexing") === 0)) item._isBgTask = true;
3117
+ if (isIndexingRequestText(extractLastUserTextFromRequest(item.request_body))) item._isBgTask = true;
2868
3118
  else item._isOnBgQueue = true;
2869
3119
  }
2870
3120
  });
@@ -3432,6 +3682,7 @@ function buildChatDisplayList(messages, opts) {
3432
3682
  }
3433
3683
 
3434
3684
  exports.BG_INDEXING_QUEUE_SUFFIX = BG_INDEXING_QUEUE_SUFFIX;
3685
+ exports.CLAUDE_INPUT_CAP_RATIO = CLAUDE_INPUT_CAP_RATIO;
3435
3686
  exports.CLAUDE_PER_REQUEST_INPUT_CAP = CLAUDE_PER_REQUEST_INPUT_CAP;
3436
3687
  exports.CONTEXT_WINDOW_BY_MODEL = CONTEXT_WINDOW_BY_MODEL;
3437
3688
  exports.CONTEXT_WINDOW_DEFAULT = CONTEXT_WINDOW_DEFAULT;
@@ -3441,6 +3692,7 @@ exports.DEFAULT_OPENAI_MODEL = DEFAULT_OPENAI_MODEL;
3441
3692
  exports.EXPIRED_ATTACHMENT_URL_HOST = EXPIRED_ATTACHMENT_URL_HOST;
3442
3693
  exports.EXPIRED_ATTACHMENT_URL_ORIGIN = EXPIRED_ATTACHMENT_URL_ORIGIN;
3443
3694
  exports.EXPIRED_LINK_REFRESH_EXPIRES_SECONDS = EXPIRED_LINK_REFRESH_EXPIRES_SECONDS;
3695
+ exports.HISTORY_BUDGET_RATIO = HISTORY_BUDGET_RATIO;
3444
3696
  exports.HISTORY_FILL_SLACK_PX = HISTORY_FILL_SLACK_PX;
3445
3697
  exports.HISTORY_TOKEN_BUDGET = HISTORY_TOKEN_BUDGET;
3446
3698
  exports.LINK_LABEL_MAX_DISPLAY_CHARS = LINK_LABEL_MAX_DISPLAY_CHARS;
@@ -3454,6 +3706,7 @@ exports.OUTPUT_TOKEN_RESERVE = OUTPUT_TOKEN_RESERVE;
3454
3706
  exports.POLL_INTERVAL = POLL_INTERVAL;
3455
3707
  exports.RENDER_FROM_TOKEN = RENDER_FROM_TOKEN;
3456
3708
  exports.TOOL_AND_RESPONSE_BUFFER = TOOL_AND_RESPONSE_BUFFER;
3709
+ exports.buildAiAgentValue = buildAiAgentValue;
3457
3710
  exports.buildBoundedChatMessages = buildBoundedChatMessages;
3458
3711
  exports.buildChatDisplayList = buildChatDisplayList;
3459
3712
  exports.buildChatSystemPrompt = buildChatSystemPrompt;
@@ -3490,11 +3743,13 @@ exports.getChatHistory = getChatHistory;
3490
3743
  exports.getContextWindow = getContextWindow;
3491
3744
  exports.getErrorMessage = getErrorMessage;
3492
3745
  exports.getExpiredAttachmentVisiblePath = getExpiredAttachmentVisiblePath;
3746
+ exports.getProjectContextWindow = getProjectContextWindow;
3493
3747
  exports.groupAttachmentFailures = groupAttachmentFailures;
3494
3748
  exports.isAuthExpiredError = isAuthExpiredError;
3495
3749
  exports.isBgIndexingQueue = isBgIndexingQueue;
3496
3750
  exports.isErrorResponseBody = isErrorResponseBody;
3497
3751
  exports.isHttpUrlLike = isHttpUrlLike;
3752
+ exports.isIndexingRequestText = isIndexingRequestText;
3498
3753
  exports.isNonRetryableRequestError = isNonRetryableRequestError;
3499
3754
  exports.isOfficeFile = isOfficeFile;
3500
3755
  exports.isServerExtractable = isServerExtractable;
@@ -3507,14 +3762,18 @@ exports.normalizeAttachmentPathCandidate = normalizeAttachmentPathCandidate;
3507
3762
  exports.normalizeTextContent = normalizeTextContent;
3508
3763
  exports.normalizeTrailingInlineToken = normalizeTrailingInlineToken;
3509
3764
  exports.notifyAgentSaveAttachment = notifyAgentSaveAttachment;
3765
+ exports.parseAiAgentValue = parseAiAgentValue;
3510
3766
  exports.parseAttachmentContent = parseAttachmentContent;
3511
3767
  exports.parseIndexingLabel = parseIndexingLabel;
3768
+ exports.parseIndexingRequestText = parseIndexingRequestText;
3512
3769
  exports.readExpiredAttachmentHref = readExpiredAttachmentHref;
3513
3770
  exports.registerAttachmentParser = registerAttachmentParser;
3771
+ exports.registerModelContextWindows = registerModelContextWindows;
3514
3772
  exports.repairUrlEntities = repairUrlEntities;
3515
3773
  exports.repairUrlWhitespace = repairUrlWhitespace;
3516
3774
  exports.safeDecodeURIComponent = safeDecodeURIComponent;
3517
3775
  exports.sanitizeAttachmentLinksForHistory = sanitizeAttachmentLinksForHistory;
3776
+ exports.setProjectContextWindow = setProjectContextWindow;
3518
3777
  exports.stripFileBlocksFromHistory = stripFileBlocksFromHistory;
3519
3778
  exports.transformContentWithImages = transformContentWithImages;
3520
3779
  exports.transformContentWithOpenAIImages = transformContentWithOpenAIImages;