* chore(release): open v3.8.14 development cycle Version bump 3.8.13 -> 3.8.14 (root + electron + open-sse + openapi + lockfiles). Seed the v3.8.14 changelog with the four post-tag hotfixes that shipped to Docker/Electron in v3.8.13 but missed the immutable npm 3.8.13 (#3336 SSRF / CodeQL #323, #3334/#3335/#3339 Electron packaging). i18n CHANGELOG mirrors get the in-progress placeholder section. * feat: add per-provider custom headers support for OpenAI/Anthropic-compatible nodes (#3338) Integrated into release/v3.8.14 * fix: Kiro Builder ID token import fails with Bad credentials (#3333) Integrated into release/v3.8.14 — adds Builder ID cached-creds + OIDC refresh path for Kiro token import, with regression tests (#3333). * Improve code quality: auto-pr/docstrings-1780792063 (#3337) Integrated into release/v3.8.14 — docstring for context analytics route re-export. * fix(catalog): remove minimaxai/minimax-m3 from NVIDIA NIM tier (404 upstream) (#3329) (#3341) NVIDIA NIM does not host minimaxai/minimax-m3 — every request returns 404 page not found, while sibling minimaxai/minimax-m2.7 on the same provider works. Advertising a model that 404s is a catalog bug; remove it from the nvidia tier (it remains on the tiers that actually serve MiniMax M3). Re-add only once NVIDIA serves it. Co-authored-by: mikmaneggahommie <mikmaneggahommie@users.noreply.github.com> * fix(cli): write OpenCode config to ~/.config on all platforms incl. Windows (#3330) (#3343) resolveOpencodeConfigDir used %APPDATA% on Windows, but OpenCode reads its config from XDG ~/.config/opencode/ on every platform (on Windows: %USERPROFILE%\.config\opencode\, NOT %APPDATA%). So a Windows user who configured OpenCode via the dashboard had the file written where OpenCode never looks — it silently had no effect. Use the XDG path (XDG_CONFIG_HOME || ~/.config) unconditionally. Update the UI note + route JSDoc, and flip the three tests that encoded the old %APPDATA% behavior (t40 per-platform + card-note, cli-runtime-extended getCliConfigPaths). Co-authored-by: abdulkadirozyurt <abdulkadirozyurt@users.noreply.github.com> * fix(proxy): make auto-selection fallback opt-in (#3332) (#3344) selectWorkingProxyFallback (Step 11 of resolveProxyForConnection) listed ALL registry proxies, ignoring assignments and per-connection proxy_enabled, and returned the first working one with level:'autoSelect'. So a single proxy added to the registry silently became a global fallback for every connection's traffic. Gate it behind a new PROXY_AUTO_SELECT_ENABLED feature flag (default off): the fallback now no-ops unless the operator opts in. No registry proxy becomes a silent global default anymore. Co-authored-by: hertznsk <hertznsk@users.noreply.github.com> * fix(sse): treat MiniMax M3 as multimodal so vision isn't stripped (#3328) (#3342) MiniMax M3 via the opencode provider (oc/minimax-m3-free) appeared blind: image inputs didn't reach the model, while the same model in Cline could see them. Verified empirically that MiniMax M3 on the opencode upstream IS multimodal -- a base64 image is described correctly (it returns 403 only for remote image URLs, which it doesn't accept). Root cause: OmniRoute treated MiniMax M3 as a non-vision model in two places, so when compression was active the image was replaced with a text placeholder before dispatch: - compression's modelSupportsVision() heuristic (lite.ts) only matched gpt-4/4o/claude-3/gemini/vision -- minimax was absent -> replaceImageUrls stripped the image. - the opencode minimax-m3-free catalog entry lacked supportsVision, so the combo vision-capability gate could also exclude/mishandle it. Add 'minimax-m3' to the vision heuristic and supportsVision: true to the opencode minimax-m3-free entry. TDD: a failing-then-passing test in compression/lite.test.ts proves replaceImageUrls now keeps images for minimax-m3 ids, plus a registry assertion mirroring the #2822 qwen test. Reported-by: @mikmaneggahommie * docs(i18n): translate 25 core documentation files to Indonesian (#3348) Integrated into release/v3.8.14 — Indonesian i18n docs. * fix(review): resolve /review-reviews battery findings (LEDGER-1..11) on v3.8.14 (#3350) Integrated into release/v3.8.14 — /review-reviews battery hardening (LEDGER-1..11) for #3338 custom-headers + #3333 kiro, plus cycle-test drift fixes (#3329/#3330/#3332). * fix(provider-proxy): honor per-account proxy toggles (#3349) Integrated into release/v3.8.14 — honor per-account proxy toggles + auto-fallback opt-in via PROXY_AUTO_SELECT_ENABLED. * fix(dashboard): remove duplicate Distribute Proxies button on provider page (#3352) * fix(providers): reduce proxy label noise (#3346) Integrated into release/v3.8.14 — reduce proxy label noise + a11y (aria-label/sr-only). * fix(duckduckgo): restore bare Response contract and rebase onto release/v3.8.14 (#3323) Integrated into release/v3.8.14 — browser-backed cookie providers (duckduckgo/claude-web) with restored executor contract + unit tests. * fix(noauth): expose only usable model aliases (#3345) Integrated into release/v3.8.14 — noauth usable-alias filtering + registry alias plumbing (veo-free). * fix(dashboard): stop infinite config-load loop on Hermes Agent detail page (#3353) * fix(electron): tree-kill the server on exit/update to release the omniroute.exe lock (#3347) (#3354) * chore(release): finalize v3.8.14 changelog + clear release-gate drift - CHANGELOG: finalize the v3.8.14 section (date, full New Features/Bug Fixes/ Maintenance coverage of all 16 cycle commits, Contributors hall of 12). - docs: document OMNIROUTE_BROWSER_POOL + WEB_COOKIE_USE_BROWSER (#3323) in .env.example + ENVIRONMENT.md; regenerate the id/llm.txt strict mirror (#3348 had translated it; llm.txt mirrors must match root). - test(proxy-fetch): #3323 made tlsClient.available a computed getter — stub it via Object.defineProperty instead of assignment (5 tests were red on the base). * fix(translator): coerce Gemini functionDeclaration parameters to an OBJECT schema (#3357) (#3360) * fix(gemini): resolve truncation/suppression of false positive textual tool call markers in backticks (#3358) Integrated into release/v3.8.14 — Gemini/Antigravity textual tool-call marker normalization (no false-positive suppression + split-chunk buffering). * docs(changelog): add #3358 Gemini textual tool-call normalization to v3.8.14 * fix(dashboard): surface real analytics error instead of generic placeholder (#3356) (#3361) The Analytics page discarded the server's error body on a non-OK response and rendered a generic "An error occurred", so users (and maintainers) could not see why /api/usage/analytics 500'd after an upgrade. Now the route returns the real reason via buildErrorBody (sanitized, Hard Rule #12) and the page surfaces it via a new readFetchErrorMessage helper that handles both the OpenAI-style and legacy error shapes. Reported-by: @superti4r --------- Co-authored-by: PizzaV <103120356+pizzav-xyz@users.noreply.github.com> Co-authored-by: Someres <168349709+quanturbo@users.noreply.github.com> Co-authored-by: Dong Mengzhe <154944819+Lang-Qiu@users.noreply.github.com> Co-authored-by: mikmaneggahommie <mikmaneggahommie@users.noreply.github.com> Co-authored-by: abdulkadirozyurt <abdulkadirozyurt@users.noreply.github.com> Co-authored-by: hertznsk <hertznsk@users.noreply.github.com> Co-authored-by: Krisna Santosa <54174372+KrisnaSantosa15@users.noreply.github.com> Co-authored-by: Randi <55005611+rdself@users.noreply.github.com> Co-authored-by: Wilson <pedbookmed@gmail.com> Co-authored-by: Paijo <14921983+oyi77@users.noreply.github.com> Co-authored-by: Ardem2025 <ardemb22@gmail.com>
6.8 KiB
Context Relay
🌐 Languages: 🇺🇸 English · 🇪🇸 es · 🇫🇷 fr · 🇩🇪 de · 🇮🇹 it · 🇷🇺 ru · 🇨🇳 zh-CN · 🇯🇵 ja · 🇰🇷 ko · 🇸🇦 ar · 🇮🇳 hi · 🇮🇳 in · 🇹🇭 th · 🇻🇳 vi · 🇮🇩 id · 🇲🇾 ms · 🇳🇱 nl · 🇵🇱 pl · 🇸🇪 sv · 🇳🇴 no · 🇩🇰 da · 🇫🇮 fi · 🇵🇹 pt · 🇷🇴 ro · 🇭🇺 hu · 🇧🇬 bg · 🇸🇰 sk · 🇺🇦 uk-UA · 🇮🇱 he · 🇵🇭 phi · 🇧🇷 pt-BR · 🇨🇿 cs · 🇹🇷 tr
context-relay adalah strategi combo yang menjaga kesinambungan sesi ketika akun aktif
berputar sebelum percakapan selesai.
Runtime saat ini berperilaku seperti routing prioritas untuk pemilihan model, kemudian menambahkan lapisan handoff di atasnya:
- sebelum akun aktif habis, OmniRoute menghasilkan ringkasan terstruktur yang ringkas
- setelah autentikasi memilih akun berbeda untuk sesi yang sama, OmniRoute menyuntikkan ringkasan tersebut sebagai pesan sistem ke dalam permintaan berikutnya
- setelah handoff berhasil dikonsumsi, handoff tersebut dihapus dari penyimpanan
Kapan Menggunakannya
Gunakan context-relay ketika semua kondisi berikut terpenuhi:
- combo diharapkan berputar di antara beberapa akun dari penyedia yang sama
- kehilangan kesinambungan percakapan jangka pendek akan mengurangi kualitas tugas
- penyedia mengekspos informasi kuota yang cukup untuk memprediksi batas akun yang akan datang
Ini paling berguna untuk sesi coding atau riset yang berjalan lama yang mungkin melampaui satu jendela akun.
Alur Runtime
Perilaku saat ini secara sengaja dibagi ke dalam dua lapisan runtime.
0% hingga 84% kuota terpakai
Tidak ada handoff yang dihasilkan. Permintaan berperilaku seperti routing prioritas normal.
85% hingga 94% kuota terpakai
Jika penyedia aktif diaktifkan di handoffProviders, OmniRoute menghasilkan ringkasan handoff
terstruktur di latar belakang sebelum akun habis sepenuhnya.
Detail penting:
- ambang batas peringatan default adalah
0.85 - batas keras untuk pembuatan adalah
0.95 - hanya satu pembuatan handoff yang sedang berjalan yang diizinkan per
sessionId + comboName - jika handoff aktif sudah ada untuk sesi/combo tersebut, tidak ada ringkasan duplikat yang dihasilkan
95% atau lebih kuota terpakai
Tidak ada handoff baru yang dihasilkan. Pada titik ini sistem sudah berada dalam kondisi habis atau mendekati habis dan runtime menghindari penjadwalan permintaan ringkasan lain.
Setelah rotasi akun
Ketika permintaan berikutnya untuk sesi yang sama menghasilkan akun terautentikasi yang berbeda, OmniRoute menambahkan handoff yang tersimpan sebagai pesan sistem. Penyuntikan hanya terjadi setelah pergantian akun nyata diketahui.
Muatan Handoff
Muatan handoff yang dipersistenkan disimpan di context_handoffs dan mencakup:
sessionIdcomboNamefromAccountsummarykeyDecisionstaskProgressactiveEntitiesmessageCountmodelwarningThresholdPctgeneratedAtexpiresAt
Model ringkasan diperintahkan untuk mengembalikan objek JSON dengan struktur berikut:
{
"summary": "Dense summary of what matters for continuity",
"keyDecisions": ["Decision 1", "Decision 2"],
"taskProgress": "What is done, what is pending, and the next step",
"activeEntities": ["fileA.ts", "feature X", "provider Y"]
}
Pada saat penyuntikan, OmniRoute mengonversi muatan tersebut menjadi pesan sistem <context_handoff>
agar akun berikutnya dapat melanjutkan dengan konteks lokal yang benar.
Konfigurasi
context-relay mendukung kolom konfigurasi berikut:
handoffThreshold: ambang batas peringatan untuk pembuatan ringkasan, default0.85handoffModel: penggantian model opsional yang hanya digunakan untuk pembuatan ringkasanhandoffProviders: daftar izin penyedia yang diperbolehkan memicu pembuatan handoff
Nilai default global dapat dikonfigurasi di Pengaturan, dan nilai spesifik combo dapat menggantikannya di halaman Combos.
Catatan Arsitektur
Implementasi saat ini tidak menggunakan pengendali handleContextRelayCombo yang berdiri sendiri.
Sebaliknya:
open-sse/services/combo.tsmemutuskan apakah giliran yang berhasil harus menghasilkan handoffsrc/sse/handlers/chat.tsmenyuntikkan handoff hanya setelah autentikasi menyelesaikan akun aktual yang digunakan untuk permintaan
Pemisahan ini disengaja dalam basis kode saat ini karena loop combo saja tidak mengetahui apakah permintaan tetap pada akun yang sama atau benar-benar berpindah akun.
Keterbatasan
- Dukungan runtime yang efektif saat ini terpusat pada rotasi kuota
codex. handoffProviderssudah dimodelkan sebagai permukaan konfigurasi, tetapi pembuatan handoff nyata masih bergantung pada jalur kuota spesifik penyedia.- Ringkasan secara sengaja dibuat ringkas dan berbasis riwayat terkini; ini bukan mekanisme pemutaran ulang transkrip penuh.
- Handoff dicakupkan oleh
sessionId + comboNamedan kedaluwarsa secara otomatis. - Jika sesi tidak berpindah akun, handoff yang tersimpan tidak disuntikkan.
Pola Penggunaan yang Disarankan
- gunakan beberapa akun dari penyedia yang sama
- pertahankan nilai
sessionIdyang stabil sepanjang sesi - atur
handoffThresholdcukup awal untuk menyisakan ruang bagi permintaan ringkasan latar belakang - perlakukan fitur ini sebagai bantuan kesinambungan, bukan sebagai pengganti memori persisten