freegate 0.6.24 → 0.6.26

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/lib/compactor.js CHANGED
@@ -13,21 +13,23 @@ const COMPACT_THRESHOLD = 60000; // tokens — compact above 60k. estimateToken
13
13
  // Empirically opencode reads ~2x our estimate on real sessions,
14
14
  // so 60k est ≈ 120-160k real — safely below free-model windows
15
15
  // while keeping context summaries fresh.
16
- const KEEP_RECENT_TOKENS = 30000; // tokens — recent messages kept untouched (preserve session context)
16
+ const KEEP_RECENT_TOKENS = 12000; // tokens — recent messages kept untouched (preserve session context)
17
+ // Оригинально было 10000 — компактный живой хвост. Я поднял
18
+ // до 30000, и модель получала большой НЕсжатый последний
19
+ // блок → на длинной сессии тонула и переставала вызывать
20
+ // инструменты («замирала»). 12000 — стабильный баланс, как
21
+ // в рабочем «раньше», но с небольшим запасом.
17
22
  const MAX_COMPACT_THRESHOLD = 100000; // est tokens — cap for window-aware thresholds (≈200k real,
18
23
  // sits safely inside even 512k/1M windows without compacting too early)
19
24
  const SUMMARY_MAX_TOKENS = 2000; // tokens — summary length cap (detailed enough to not lose the work)
20
- const CHARS_PER_TOKEN = 3.0; // heuristic chars→tokens. БОЛЬШЕ делитель = МЕНЬШЕ оценка.
21
- // Реальная плотность смешанного кода/текста ~4-6 chars на
22
- // токен (не 1.5-2). chars/3.0 приближает оценку к реальным
23
- // токенам, поэтому порог 60000 достигается только на реально
24
- // больших диалогах (10+ компактированных страниц), а не на
25
- // каждом рабочем чате с агентами.
26
- // Раньше (1.5) оценка завышалась в ~4-6 раз → компакции шли
27
- // на 86% запросов. Каждая компакция отдельный LLM-вызов
28
- // перед ответом = агент «замирает» / виснет на середине.
29
- // window-aware routing всё равно исключает малые окна (or-lfm
30
- // 65k) для больших запросов, так что запас к окнам сохранён.
25
+ const CHARS_PER_TOKEN = 2.0; // heuristic chars→tokens. 3.0 СЛИШКОМ занижал оценку:
26
+ // window-aware фильтр не отсеивал groq (окно 131k) при
27
+ // реальном контексте 140k+ groq принимал слишком большой
28
+ // запрос и МОЛЧАЛ («no first token») каскад → зависание
29
+ // на минуты. 2.0: диалог 300k+ символов оценивается >131k
30
+ // (groq отсеивается) и компактится (>60k), но обычный
31
+ // рабочий диалог агента компактится реже, чем при 1.5.
32
+ // Баланс: не занижаем для окна, не завышаем для компакций.
31
33
 
32
34
  // Reliability-ordered long-context summarizers. Порядок важен: getSummary идёт
33
35
  // по списку и ждёт ПЕРВЫЙ отвечающий (до 30с). Медленные/непроверенные в начале
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "freegate",
3
- "version": "0.6.24",
3
+ "version": "0.6.26",
4
4
  "description": "Free multi-provider LLM gateway with automatic failover. One OpenAI-compatible endpoint routes to many free models (Groq, Mistral, Gemini, NIM, OpenRouter, ZAI, Cerebras, DeepSeek and more). Never pay for LLMs.",
5
5
  "license": "MIT",
6
6
  "bin": {
package/providers.json CHANGED
@@ -646,7 +646,7 @@
646
646
  "gemini-gemma-4-26b-a4b-it": {
647
647
  "endpoint": "https://generativelanguage.googleapis.com/v1beta/openai/chat/completions",
648
648
  "model": "gemma-4-26b-a4b-it",
649
- "priority": 7,
649
+ "priority": 6,
650
650
  "dailyLimit": 1500,
651
651
  "keyHint": "gemini → Keys (автодобавлено, general)",
652
652
  "envVar": "PROVIDER_GEMINI_APIKEY",
@@ -666,7 +666,7 @@
666
666
  "gemini-gemini-flash-lite-latest": {
667
667
  "endpoint": "https://generativelanguage.googleapis.com/v1beta/openai/chat/completions",
668
668
  "model": "gemini-flash-lite-latest",
669
- "priority": 3,
669
+ "priority": 4,
670
670
  "dailyLimit": 1500,
671
671
  "keyHint": "gemini → Keys (автодобавлено, general)",
672
672
  "envVar": "PROVIDER_GEMINI_APIKEY",
@@ -676,7 +676,7 @@
676
676
  "gemini-gemini-3-1-flash-lite-preview": {
677
677
  "endpoint": "https://generativelanguage.googleapis.com/v1beta/openai/chat/completions",
678
678
  "model": "gemini-3.1-flash-lite-preview",
679
- "priority": 2,
679
+ "priority": 3,
680
680
  "dailyLimit": 1500,
681
681
  "keyHint": "gemini → Keys (автодобавлено, general)",
682
682
  "envVar": "PROVIDER_GEMINI_APIKEY",
@@ -686,7 +686,7 @@
686
686
  "gemini-gemini-3-5-flash": {
687
687
  "endpoint": "https://generativelanguage.googleapis.com/v1beta/openai/chat/completions",
688
688
  "model": "gemini-3.5-flash",
689
- "priority": 6,
689
+ "priority": 7,
690
690
  "dailyLimit": 1500,
691
691
  "keyHint": "gemini → Keys (автодобавлено, general)",
692
692
  "envVar": "PROVIDER_GEMINI_APIKEY",
@@ -696,7 +696,7 @@
696
696
  "gemini-gemini-3-5-flash-lite": {
697
697
  "endpoint": "https://generativelanguage.googleapis.com/v1beta/openai/chat/completions",
698
698
  "model": "gemini-3.5-flash-lite",
699
- "priority": 4,
699
+ "priority": 2,
700
700
  "dailyLimit": 1500,
701
701
  "keyHint": "gemini → Keys (автодобавлено, general)",
702
702
  "envVar": "PROVIDER_GEMINI_APIKEY",
@@ -712,5 +712,15 @@
712
712
  "envVar": "PROVIDER_GEMINI_APIKEY",
713
713
  "free": true,
714
714
  "category": "general"
715
+ },
716
+ "hf-Qwen3-Coder-Next": {
717
+ "endpoint": "https://router.huggingface.co/v1/chat/completions",
718
+ "model": "Qwen/Qwen3-Coder-Next",
719
+ "priority": 1,
720
+ "dailyLimit": 200,
721
+ "keyHint": "huggingface → Keys (автодобавлено, coding)",
722
+ "envVar": "PROVIDER_HF_APIKEY",
723
+ "free": true,
724
+ "category": "coding"
715
725
  }
716
726
  }
package/server.js CHANGED
@@ -619,13 +619,17 @@ async function handleChatCompletion(req, res, body) {
619
619
  // requests keep the full fast pool.
620
620
  const requestTokens = estimateTokens(body.messages);
621
621
  const MIN_WINDOW = 50000; // below this we don't filter (typical requests)
622
+ // Запас 1.3×: estimateTokens на диалогах с инструментами/кодом ЗАНИЖАЕТ реальный
623
+ // размер (opencode показывает ~140k, а прокси оценивает меньше). Без запаса малые
624
+ // окна (groq 131k, or-lfm 65k) берут большие запросы → 400/молчание → «замирание».
625
+ const WINDOW_SAFETY = 1.3;
622
626
  let windowPool = healthy2;
623
627
  let upgradeNoCapable = false; // апгрейд, но ни один здоровый провайдер не держит запрос
624
628
  if (requestTokens > MIN_WINDOW || windowUpgraded) {
625
629
  const capable = healthy2.filter(([_, p]) => {
626
630
  const win = p.context_window || 0;
627
631
  // Unknown/0 window providers are kept (heuristic) — better to try than drop.
628
- return win === 0 || win >= requestTokens;
632
+ return win === 0 || win >= requestTokens * WINDOW_SAFETY;
629
633
  });
630
634
  if (capable.length > 0) {
631
635
  windowPool = capable;