llm-switcher 1.6.8 → 1.6.9

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/ui.html CHANGED
@@ -1100,26 +1100,26 @@
1100
1100
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M4 12h16M12 4v16"/><circle cx="12" cy="12" r="8"/></svg>
1101
1101
  Routes & Profiles<span class="ct" id="ct-routes"></span>
1102
1102
  </a>
1103
- <a class="nav-link" href="#/compact" data-nav="compact">
1104
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M4 14h6m0 0v6m0-6L3 21"/><path d="M20 10h-6m0 0V4m0 6l7-7"/><circle cx="12" cy="12" r="2"/></svg>
1105
- Idle Compaction<span class="ct" id="ct-compact"></span>
1106
- </a>
1107
- <a class="nav-link" href="#/goal-check" data-nav="goal-check">
1108
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/><path d="m9 12 2 2 4-4"/></svg>
1109
- Goal Check<span class="ct" id="ct-goal-check"></span>
1103
+ <a class="nav-link" href="#/logs" data-nav="logs">
1104
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6"/><path d="m9 15 2 2 4-4"/></svg>
1105
+ Request Inspector<span class="ct" id="ct-logs"></span>
1110
1106
  </a>
1111
1107
  <a class="nav-link" href="#/models" data-nav="models">
1112
1108
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><rect x="3" y="4" width="18" height="6" rx="1.5"/><rect x="3" y="14" width="18" height="6" rx="1.5"/></svg>
1113
1109
  Model Catalog<span class="ct" id="ct-models"></span>
1114
1110
  </a>
1115
- <a class="nav-link" href="#/logs" data-nav="logs">
1116
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6"/><path d="m9 15 2 2 4-4"/></svg>
1117
- Request Inspector<span class="ct" id="ct-logs"></span>
1118
- </a>
1119
1111
  <a class="nav-link" href="#/doctor" data-nav="doctor">
1120
1112
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="12" r="9"/><path d="m9 12 2 2 4-4"/></svg>
1121
1113
  System Doctor
1122
1114
  </a>
1115
+ <a class="nav-link" href="#/goal-check" data-nav="goal-check">
1116
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/><path d="m9 12 2 2 4-4"/></svg>
1117
+ Goal Check<span class="ct" id="ct-goal-check"></span>
1118
+ </a>
1119
+ <a class="nav-link" href="#/compact" data-nav="compact">
1120
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M4 14h6m0 0v6m0-6L3 21"/><path d="M20 10h-6m0 0V4m0 6l7-7"/><circle cx="12" cy="12" r="2"/></svg>
1121
+ Idle Compaction<span class="ct" id="ct-compact"></span>
1122
+ </a>
1123
1123
  <a class="nav-link" href="#/docs" data-nav="docs">
1124
1124
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H20v20H6.5a2.5 2.5 0 0 1-2.5-2.5Z"/><path d="M6 6h10M6 10h10M6 14h7"/></svg>
1125
1125
  Docs & Guide
@@ -1745,15 +1745,16 @@
1745
1745
  <span>Mục Lục Hướng Dẫn</span>
1746
1746
  </div>
1747
1747
  <a class="docs-toc-link active" href="#doc-overview">1. Tổng Quan & Kiến Trúc</a>
1748
- <a class="docs-toc-link" href="#doc-install">2. Hướng Dẫn Cài Đặt</a>
1749
- <a class="docs-toc-link" href="#doc-cli">3. Lệnh CLI & Vận Hành</a>
1750
- <a class="docs-toc-link" href="#doc-blindfold">4. Blindfold Mode & CA</a>
1751
- <a class="docs-toc-link" href="#doc-agy">5. Antigravity CLI (agy)</a>
1752
- <a class="docs-toc-link" href="#doc-optimizers">6. Tối Ưu Token & Healer</a>
1753
- <a class="docs-toc-link" href="#doc-agent-mcp">7. Agent Skill & MCP Server</a>
1754
- <a class="docs-toc-link" href="#doc-advanced">8. Compaction & Goal Check</a>
1755
- <a class="docs-toc-link" href="#doc-config">9. Cấu Hình config.json</a>
1756
- <a class="docs-toc-link" href="#doc-faq">10. Xử Lý Sự Cố (FAQ)</a>
1748
+ <a class="docs-toc-link" href="#doc-install">2. Cài Đặt LLM Switcher</a>
1749
+ <a class="docs-toc-link" href="#doc-intact">3. intact Gateway & Pooler</a>
1750
+ <a class="docs-toc-link" href="#doc-cli">4. Lệnh CLI & Vận Hành</a>
1751
+ <a class="docs-toc-link" href="#doc-blindfold">5. Blindfold Mode & CA</a>
1752
+ <a class="docs-toc-link" href="#doc-agy">6. Antigravity CLI (agy)</a>
1753
+ <a class="docs-toc-link" href="#doc-optimizers">7. Tối Ưu Token & Healer</a>
1754
+ <a class="docs-toc-link" href="#doc-agent-mcp">8. Agent Skill & MCP Server</a>
1755
+ <a class="docs-toc-link" href="#doc-advanced">9. Compaction & Goal Check</a>
1756
+ <a class="docs-toc-link" href="#doc-config">10. Cấu Hình config.json</a>
1757
+ <a class="docs-toc-link" href="#doc-faq">11. Xử Lý Sự Cố (FAQ)</a>
1757
1758
  </nav>
1758
1759
 
1759
1760
  <!-- Main Documentation Content -->
@@ -1765,11 +1766,11 @@
1765
1766
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4M12 8h.01"/></svg>
1766
1767
  1. Tổng Quan & Kiến Trúc Cốt Lõi
1767
1768
  </h2>
1768
- <span class="badge" style="background:var(--accent-soft); color:var(--accent); font-weight:600;">v1.6.8 · Zero-Dependency</span>
1769
+ <span class="badge" style="background:var(--accent-soft); color:var(--accent); font-weight:600;">v1.6.8 · Zero-Dependency · Multi-Protocol Edge Gateway</span>
1769
1770
  </div>
1770
1771
  <div class="doc-prose">
1771
1772
  <p>
1772
- <strong>LLM Switcher</strong> là cổng ngõ biên (Edge Gateway) và bộ chuyển đổi đa giao thức LLM siêu nhẹ, hoàn toàn <strong>Zero-Dependency</strong> (xây dựng 100% bằng thư viện chuẩn của Node.js, không cần chạy <code>npm install</code>, khởi động &lt;50ms). Hệ thống đóng vai trò cầu nối thông minh và trong suốt giữa các AI Coding CLI hàng đầu (<strong>Claude Code</strong>, <strong>OpenAI Codex</strong>, <strong>Antigravity CLI <code>agy</code></strong>) với mọi nhà cung cấp mô hình LLM (OpenAI-compatible, Anthropic Native, Vertex Native, Google Code Assist).
1773
+ <strong>LLM Switcher</strong> là cổng ngõ biên (Edge Gateway) và bộ điều phối chuyển đổi đa giao thức LLM siêu nhẹ, hoàn toàn <strong>Zero-Dependency</strong> (xây dựng 100% bằng thư viện chuẩn của Node.js: <code>http</code>, <code>fs</code>, <code>os</code>, <code>path</code>, <code>crypto</code>, <code>fetch</code>; không cần <code>npm install</code>, thời gian khởi động lạnh &lt;50ms). Hệ thống đóng vai trò cầu nối thông minh và trong suốt giữa các AI Coding CLI hàng đầu (<strong>Claude Code</strong>, <strong>OpenAI Codex</strong>, <strong>Antigravity CLI <code>agy</code></strong>) với mọi nhà cung cấp mô hình LLM (OpenAI-compatible, Anthropic Native, Vertex Native, Google Code Assist).
1773
1774
  </p>
1774
1775
 
1775
1776
  <div class="doc-callout info">
@@ -1782,8 +1783,8 @@
1782
1783
  <pre>[Claude Code / Codex / agy CLI]
1783
1784
  │ (1. Khởi chạy qua Launcher Shim: nạp HTTPS_PROXY & CA in-memory)
1784
1785
  ▼
1785
- [Blindfold Interceptor :3457] ──(TLS giải mã nội bộ cho anthropic/openai)
1786
- │ (2. Strip credential client, chuyển tiếp /v1/messages, /v1/responses)
1786
+ [Blindfold Interceptor :3457] ──(TLS giải mã nội bộ cho anthropic/openai/chatgpt)
1787
+ │ (2. Bóc tách credential client, chuyển tiếp /v1/messages, /v1/responses)
1787
1788
  ▼
1788
1789
  [LLM Switcher Edge Gateway :3456]
1789
1790
  │ ├── Healer Engine (Tự sửa schema rỗng {}, cứu tool_result mồ côi, gộp lượt)
@@ -1795,11 +1796,49 @@
1795
1796
 
1796
1797
  <h3>4 Trụ Cột Đột Phá Của Hệ Thống</h3>
1797
1798
  <ul>
1798
- <li><strong>100% Native Emulation:</strong> Chuyển đổi mọi phản hồi từ upstream thành luồng Anthropic SSE chuẩn (<code>thinking_delta</code> + <code>tool_use</code>) cho Claude Code, và Responses API events chuẩn cho Codex.</li>
1799
- <li><strong>Zero Config Mutation:</strong> Tuyệt đối không đọc/ghi <code>~/.claude/settings.json</code> hay <code>~/.codex/config.toml</code>. Không bao giờ xuất hiện banner cảnh báo của nhà cung cấp.</li>
1800
- <li><strong>Cửa Sổ Context Theo Model Thực Tế:</strong> Tự động phát hiện cửa sổ ngữ cảnh chính thức từ upstream (ví dụ 1M tokens), truyền đúng <code>max_context_window</code> và <code>context_window</code> trong <code>/v1/models</code> để Codex tự tin lập kế hoạch và nén lịch sử chính xác.</li>
1799
+ <li><strong>100% Native Emulation:</strong> Chuyển đổi mọi phản hồi từ upstream thành luồng Anthropic SSE chuẩn (<code>thinking_delta</code> + <code>tool_use</code>) cho Claude Code, và Responses API events chuẩn cho Codex. CLI nhận được response native và hoàn toàn tin cậy server.</li>
1800
+ <li><strong>Zero Config Mutation:</strong> Tuyệt đối không đọc/ghi <code>~/.claude/settings.json</code> hay <code>~/.codex/config.toml</code>, và không ghi biến môi trường nào mà công cụ đọc như cấu hình. Không bao giờ xuất hiện banner cảnh báo "Custom API endpoint configured".</li>
1801
+ <li><strong>Cửa Sổ Context Theo Model Thực Tế:</strong> Tự động phát hiện cửa sổ ngữ cảnh chính thức từ upstream (ví dụ 1M tokens), truyền đúng <code>max_context_window</code> và <code>context_window</code> trong <code>/v1/models</code> để Codex tự tin lập kế hoạch và nén lịch sử chính xác. Claude Code tự ước lượng phiên theo model nó gọi.</li>
1801
1802
  <li><strong>Bifrost Passthrough:</strong> Khi bạn dùng tài khoản của chính nhà cung cấp đó trên pool của <a href="https://github.com/louisphamdev/intact" target="_blank" style="color:var(--accent);">intact</a>, request sẽ đi xuyên qua nguyên vẹn 100% byte-for-byte, bỏ qua bộ dịch giao thức và Healer, chỉ thay đổi API key an toàn.</li>
1802
1803
  </ul>
1804
+
1805
+ <h3>Thư Viện Sơ Đồ Tương Tác Archify</h3>
1806
+ <table class="doc-table">
1807
+ <thead>
1808
+ <tr>
1809
+ <th style="width:30%;">Sơ đồ</th>
1810
+ <th>Mô tả luồng</th>
1811
+ <th style="width:25%;">Liên kết xem tương tác</th>
1812
+ </tr>
1813
+ </thead>
1814
+ <tbody>
1815
+ <tr>
1816
+ <td><strong>System Topology</strong></td>
1817
+ <td>Kiến trúc tổng thể: Dev Clients ➔ Optimizers ➔ Gateway & Healer Core ➔ Upstream Providers.</td>
1818
+ <td><a href="docs/diagrams/system-architecture.html" target="_blank" style="color:var(--accent);">📊 Mở Interactive Viewer</a></td>
1819
+ </tr>
1820
+ <tr>
1821
+ <td><strong>IR Healer Pipeline</strong></td>
1822
+ <td>Chuẩn hóa request, sửa schema lỗi, tổng hợp stream SSE và cơ chế abort propagation.</td>
1823
+ <td><a href="docs/diagrams/ir-translation-pipeline.html" target="_blank" style="color:var(--accent);">🔄 Mở Interactive Viewer</a></td>
1824
+ </tr>
1825
+ <tr>
1826
+ <td><strong>Codex Blindfold Routing</strong></td>
1827
+ <td>Luồng TLS CONNECT proxy, bóc tách credential và định tuyến an toàn theo host.</td>
1828
+ <td><a href="docs/diagrams/blindfold-request-routing.html" target="_blank" style="color:var(--accent);">🛡️ Mở Interactive Viewer</a></td>
1829
+ </tr>
1830
+ <tr>
1831
+ <td><strong>Switch Lifecycle</strong></td>
1832
+ <td>Vòng đời chuyển đổi profile zero-downtime, ghi cấu hình CAS và sync interceptor.</td>
1833
+ <td><a href="docs/diagrams/blindfold-switch-lifecycle.html" target="_blank" style="color:var(--accent);">⚡ Mở Interactive Viewer</a></td>
1834
+ </tr>
1835
+ <tr>
1836
+ <td><strong>Model Name Resolution</strong></td>
1837
+ <td>Cơ chế ánh xạ tên mô hình công khai và phân giải slot Codex.</td>
1838
+ <td><a href="docs/diagrams/codex-model-name-resolution.html" target="_blank" style="color:var(--accent);">🏷️ Mở Interactive Viewer</a></td>
1839
+ </tr>
1840
+ </tbody>
1841
+ </table>
1803
1842
  </div>
1804
1843
  </section>
1805
1844
 
@@ -1808,16 +1847,16 @@
1808
1847
  <div class="doc-section-h">
1809
1848
  <h2>
1810
1849
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3"/></svg>
1811
- 2. Hướng Dẫn Cài Đặt Đa Nền Tảng
1850
+ 2. Hướng Dẫn Cài Đặt Chi Tiết & Toàn Diện (Đa Nền Tảng)
1812
1851
  </h2>
1813
1852
  <span class="badge" style="background:var(--ok-soft); color:var(--ok); font-weight:600;">Linux · macOS · Windows</span>
1814
1853
  </div>
1815
1854
  <div class="doc-prose">
1816
1855
  <p>
1817
- <strong>Yêu cầu hệ thống:</strong> Node.js phiên bản <strong>18.17 trở lên</strong>. Gateway không yêu cầu bất kỳ thư viện npm phụ thuộc nào bên ngoài.
1856
+ <strong>Yêu cầu hệ thống:</strong> Node.js phiên bản <strong>18.17 trở lên</strong> (LTS). Gateway không yêu cầu bất kỳ thư viện npm phụ thuộc nào bên ngoài (Zero Dependencies).
1818
1857
  </p>
1819
1858
 
1820
- <h3>Cách 1: Cài Đặt Toàn Cục Qua npm (Khuyên dùng)</h3>
1859
+ <h3>Cách 1: Cài Đặt Toàn Cục Qua npm (Khuyên dùng cho Người dùng cuối)</h3>
1821
1860
  <div class="doc-codebox">
1822
1861
  <div class="doc-codebox-bar">
1823
1862
  <span>Terminal · npm global install</span>
@@ -1825,15 +1864,15 @@
1825
1864
  </div>
1826
1865
  <pre>npm install -g llm-switcher
1827
1866
 
1828
- # Khởi tạo thư mục dữ liệu và sao chép cấu hình mẫu:
1867
+ # Khởi tạo thư mục dữ liệu với quyền bảo mật 700 và sao chép cấu hình mẫu:
1829
1868
  mkdir -p -m 700 ~/.llm-switcher
1830
1869
  cp "$(npm root -g)/llm-switcher/config.example.json" ~/.llm-switcher/config.json</pre>
1831
1870
  </div>
1832
1871
  <p>
1833
- <em>Ghi chú:</em> Khi cài đặt qua npm, file cấu hình <code>config.json</code>, khóa token <code>admin.token</code> và các file khởi chạy được lưu trữ an toàn trong <code>~/.llm-switcher</code>. Khi bạn chạy lệnh nâng cấp (update), cấu hình của bạn được giữ nguyên vẹn.
1872
+ <em>Ghi chú:</em> Khi cài đặt qua npm, file cấu hình <code>config.json</code>, khóa bảo mật <code>admin.token</code> và các file launcher được lưu trữ an toàn trong <code>~/.llm-switcher</code>. Khi bạn chạy lệnh nâng cấp (<code>switch update</code>), npm chỉ ghi đè thư mục package code, cấu hình và token của bạn được giữ nguyên vẹn.
1834
1873
  </p>
1835
1874
 
1836
- <h3>Cách 2: Cài Đặt Từ Git Clone (Dành cho Developer)</h3>
1875
+ <h3>Cách 2: Cài Đặt Từ Git Clone (Dành cho Developer & Tự build)</h3>
1837
1876
  <div class="doc-codebox">
1838
1877
  <div class="doc-codebox-bar">
1839
1878
  <span>Terminal · Git Checkout</span>
@@ -1842,26 +1881,34 @@ cp "$(npm root -g)/llm-switcher/config.example.json" ~/.llm-switcher/config.json
1842
1881
  <pre>git clone https://github.com/louisphamdev/llm-switcher.git
1843
1882
  cd llm-switcher
1844
1883
 
1845
- # Sao chép file cấu hình (config.json được gitignore bảo vệ an toàn):
1884
+ # Sao chép file cấu hình mẫu (config.json được gitignore bảo vệ an toàn):
1846
1885
  cp config.example.json config.json</pre>
1847
1886
  </div>
1887
+ <p>
1888
+ Với bản git checkout, thư mục dữ liệu nằm ngay tại thư mục checkout. Nếu muốn chỉ định một thư mục dữ liệu khác bất kỳ, hãy đặt biến môi trường <code>LLM_SWITCHER_HOME=/path/to/data</code>.
1889
+ </p>
1848
1890
 
1849
1891
  <h3>Cài Đặt Launcher Shims (Bắt buộc để định tuyến trong suốt)</h3>
1850
1892
  <p>
1851
- Lệnh <code>switch shim install</code> tạo các wrapper siêu nhẹ trong <code>~/.llm-switcher/bin</code> để tiêm biến môi trường vào tiến trình CLI mà không can thiệp vào shell hay file cài đặt của hệ thống.
1893
+ Lệnh <code>switch shim install</code> tạo các wrapper siêu nhẹ trong <code>~/.llm-switcher/bin</code> để tiêm biến môi trường (<code>HTTPS_PROXY</code>, chứng chỉ CA, <code>CLOUD_CODE_URL</code>) vào từng tiến trình CLI độc lập mà không can thiệp vào shell hay file cài đặt của hệ thống.
1852
1894
  </p>
1853
1895
  <div class="doc-codebox">
1854
1896
  <div class="doc-codebox-bar">
1855
- <span>Terminal · Cấu hình PATH</span>
1856
- <button type="button" class="btn btn-outline btn-sm" onclick="copyDocCode(this, 'switch shim install\n# Linux / macOS: thêm vào ~/.bashrc hoặc ~/.zshrc:\nexport PATH=&quot;$HOME/.llm-switcher/bin:$PATH&quot;')">Copy</button>
1897
+ <span>Terminal · Cấu hình PATH cho Shims</span>
1898
+ <button type="button" class="btn btn-outline btn-sm" onclick="copyDocCode(this, 'switch shim install\n# Linux & macOS: Thêm vào ~/.bashrc hoặc ~/.zshrc:\nexport PATH=&quot;$HOME/.llm-switcher/bin:$PATH&quot;')">Copy</button>
1857
1899
  </div>
1858
1900
  <pre>switch shim install
1859
1901
 
1860
- # Linux & macOS: Thêm dòng sau vào ~/.bashrc hoặc ~/.zshrc rồi mở terminal mới:
1902
+ # Linux & macOS (Bash/Zsh): Thêm dòng sau vào ~/.bashrc hoặc ~/.zshrc rồi mở terminal mới:
1861
1903
  export PATH="$HOME/.llm-switcher/bin:$PATH"
1862
1904
 
1863
- # Windows (Command Prompt): Đặt đường dẫn sau lên trước trong PATH User:
1864
- %USERPROFILE%\.llm-switcher\bin</pre>
1905
+ # Windows (Command Prompt / PowerShell):
1906
+ # Thêm %USERPROFILE%\.llm-switcher\bin lên ĐẦU trong biến môi trường PATH của User:
1907
+ # (System Properties ➔ Environment Variables ➔ User Variables ➔ Path)</pre>
1908
+ </div>
1909
+
1910
+ <div class="doc-callout warning">
1911
+ <strong>Tại sao Launcher Shims là bắt buộc?</strong> Khi bạn mở một terminal mới và chạy <code>claude --resume</code>, nếu không có shim, shell sẽ chạy binary gốc và gọi thẳng tới server của Anthropic mà không đi qua Gateway (bỏ qua Healer và pool quota). Shim nằm ở đầu <code>PATH</code> sẽ chặn trước, nạp đúng biến định tuyến in-memory cho tiến trình đó và dọn sạch các biến rác cũ.
1865
1912
  </div>
1866
1913
 
1867
1914
  <h3>Cài Đặt Dịch Vụ Nền Tự Khởi Động (OS Background Service)</h3>
@@ -1870,29 +1917,375 @@ export PATH="$HOME/.llm-switcher/bin:$PATH"
1870
1917
  </p>
1871
1918
  <div class="doc-codebox">
1872
1919
  <div class="doc-codebox-bar">
1873
- <span>Terminal · Service Install</span>
1874
- <button type="button" class="btn btn-outline btn-sm" onclick="copyDocCode(this, 'switch service install --autoupdate')">Copy</button>
1920
+ <span>Terminal · Service Install & Quản trị Daemon</span>
1921
+ <button type="button" class="btn btn-outline btn-sm" onclick="copyDocCode(this, 'switch service install --autoupdate\nswitch service status\nswitch service uninstall')">Copy</button>
1875
1922
  </div>
1876
- <pre># Cài đặt dịch vụ chạy ngầm kèm cờ tự động cập nhật bản mới khi đăng nhập:
1923
+ <pre># Cài đặt daemon chạy ngầm, tự động cập nhật bản mới nhất mỗi khi đăng nhập:
1877
1924
  switch service install --autoupdate
1878
1925
 
1879
- # Kiểm tra trạng thái hoặc gỡ bỏ khi không dùng:
1926
+ # Kiểm tra trạng thái dịch vụ nền:
1927
+ switch service status
1928
+
1929
+ # Gỡ bỏ dịch vụ nền khi không cần nữa:
1880
1930
  switch service uninstall</pre>
1881
1931
  </div>
1882
1932
  <div class="doc-callout info">
1883
- <strong>Mẹo cho máy chủ Linux (SSH):</strong> Để dịch vụ systemd user service tiếp tục chạy cả khi bạn ngắt kết nối SSH, hãy chạy lệnh: <code>loginctl enable-linger $USER</code> một lần duy nhất.
1933
+ <strong>Ghi chú cho Linux / Server SSH:</strong> Dịch vụ trên Linux là <code>systemd --user</code> service. Để gateway tiếp tục chạy sau khi bạn thoát phiên SSH, hãy chạy lệnh: <code>loginctl enable-linger $USER</code> một lần duy nhất.
1934
+ </div>
1935
+
1936
+ <h3>Nâng Cấp Phiên Bản Mới (Seamless Hot Update)</h3>
1937
+ <div class="doc-codebox">
1938
+ <div class="doc-codebox-bar">
1939
+ <span>Terminal · switch update</span>
1940
+ <button type="button" class="btn btn-outline btn-sm" onclick="copyDocCode(this, 'switch update')">Copy</button>
1941
+ </div>
1942
+ <pre>switch update</pre>
1943
+ </div>
1944
+ <div class="doc-callout info">
1945
+ <strong>💡 Thiết lập Upstream Pooler:</strong> Sau khi cài đặt LLM Switcher trên máy trạm, bạn nên cài đặt thêm <strong>intact Gateway</strong> (chạy trên server riêng hoặc ngay trên localhost) để quản lý đa tài khoản, xoay vòng key và kích hoạt tính năng <strong>Bifrost Passthrough</strong>. Xem cẩm nang chi tiết tại mục kế tiếp: <a href="#doc-intact" style="color:var(--accent); font-weight:600;">3. intact Gateway — Cài Đặt & Vận Hành</a>.
1884
1946
  </div>
1885
1947
  </div>
1886
1948
  </section>
1887
1949
 
1888
- <!-- 3. CLI & OPERATION GUIDE -->
1950
+ <!-- 3. INTACT GATEWAY GUIDE -->
1951
+ <section class="doc-section" id="doc-intact">
1952
+ <div class="doc-section-h">
1953
+ <h2>
1954
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="2" width="20" height="8" rx="2"/><rect x="2" y="14" width="20" height="8" rx="2"/><line x1="6" y1="6" x2="6.01" y2="6"/><line x1="6" y1="18" x2="6.01" y2="18"/></svg>
1955
+ 3. intact Gateway — Cài Đặt & Vận Hành Upstream Pooler (Khuyên Dùng)
1956
+ </h2>
1957
+ <span class="badge" style="background:var(--accent-soft); color:var(--accent); font-weight:600;">Recommended Companion · Multi-Account Pooler · Zero-CGO</span>
1958
+ </div>
1959
+ <div class="doc-prose">
1960
+ <p>
1961
+ <strong>intact</strong> là cổng ủy quyền lưu trữ credential (Credential Proxy) và bộ điều phối pooling đa tài khoản LLM hiệu năng cao được xây dựng chuyên biệt để làm upstream cho <strong>LLM Switcher</strong>. Được viết bằng ngôn ngữ Go thuần (Single Static Binary, <strong>Zero-CGO</strong> với driver SQLite Pure-Go, nhúng toàn bộ Web UI quản trị), intact khởi động tức thì, tiêu tốn cực ít RAM (&lt;30MB) và phục vụ toàn bộ các tài khoản của bạn sau một Base URL thống nhất <code>/v1</code>.
1962
+ </p>
1963
+
1964
+ <div class="doc-callout success">
1965
+ <strong>Mối quan hệ cộng sinh hoàn hảo giữa LLM Switcher và intact:</strong>
1966
+ <ul>
1967
+ <li><strong>LLM Switcher (Client Edge :3456 / :3457):</strong> Chạy trên từng máy dev, bóc tách TLS blindfold không cảnh báo, bảo vệ file cấu hình gốc (Zero-Mutation), tự động vá lỗi schema và cứu tool-result mồ côi bằng Healer Engine, duy trì thinking budget.</li>
1968
+ <li><strong>intact Gateway (Server Pooler :20142):</strong> Chạy trên máy chủ tập trung (hoặc localhost), lưu trữ tập trung và an toàn các API Key / OAuth Token nhạy cảm, cân bằng tải xoay vòng nhiều tài khoản (Round Robin / Fallback), xử lý 429 thông minh (429 Retry Shorter), gắn kết phiên (Conversation stickiness) tối ưu hóa Prompt Cache, tự động lọc lỗi bằng Blacklist và đối chiếu Contract Lab.</li>
1969
+ </ul>
1970
+ </div>
1971
+
1972
+ <h3>2 Tính Năng Đột Phá Độc Quyền Khi Dùng Cặp Đôi Này</h3>
1973
+ <ul>
1974
+ <li>
1975
+ <strong>Bifrost Passthrough Tối Thượng:</strong> Khi một AI Coding CLI (Claude Code, OpenAI Codex, Antigravity CLI <code>agy</code>) gọi đến đúng tài khoản của chính nhà cung cấp đó trên pool intact, request sẽ đi xuyên qua nguyên vẹn <strong>100% byte-for-byte</strong>. Chỉ có token xác thực là được thay thế an toàn. Bộ chuyển đổi giao thức, Healer Engine và Blacklist đều được bỏ qua. intact tự động cấp cờ <code>bifrost_ua</code> trong <code>GET /v1/models/{model}</code> để Switcher kích hoạt chế độ này hoàn toàn tự động.
1976
+ </li>
1977
+ <li>
1978
+ <strong>Chu Trình Tự Cải Thiện 2 Chiều (Two-Loop Self-Improvement):</strong>
1979
+ <ul>
1980
+ <li><em>Vòng 1 (intact sửa lỗi upstream từ chối):</em> Tự động phát hiện lỗi 429 giả mạo từ upstream, sử dụng thuật toán chia đôi (binary search halving) system prompt để cô lập chính xác câu văn bị nhà cung cấp chặn (ví dụ các câu <em>"You are Codex, an agent based on GPT-5"</em> hay <em>"You are a Claude agent..."</em> bị Google Antigravity chặn bằng fake 429), rồi lưu thành bộ lọc blacklist trong cơ sở dữ liệu SQLite. Toàn bộ máy dev nhận bản vá tức thì mà không cần cập nhật gateway.</li>
1981
+ <li><em>Vòng 2 (Switcher sửa lỗi converter làm mất):</em> Khi bật Contract Lab, Switcher gửi các mẫu trao đổi đã che dữ liệu người dùng (giữ nguyên độ dài chuỗi và enum) lên intact. intact so khớp và ghi nhận từng field bị mất. Lệnh <code>switch contract-check</code> tự động tạo test case đỏ và bản sửa nằm trong bộ converter.</li>
1982
+ </ul>
1983
+ </li>
1984
+ </ul>
1985
+
1986
+ <h3>Hướng Dẫn Cài Đặt intact Chi Tiết</h3>
1987
+ <p>
1988
+ intact được đóng gói sẵn thành file binary tĩnh duy nhất cho mọi kiến trúc hệ điều hành: Linux (x64, arm64), macOS (Apple Silicon M-series, Intel), Windows (x64, arm64).
1989
+ </p>
1990
+
1991
+ <h4>Cách 1: Cài Đặt Toàn Cục Qua npm (Khuyên dùng)</h4>
1992
+ <div class="doc-codebox">
1993
+ <div class="doc-codebox-bar">
1994
+ <span>Terminal · npm global install</span>
1995
+ <button type="button" class="btn btn-outline btn-sm" onclick="copyDocCode(this, 'npm install -g intact-gateway\n# Khởi động intact lần đầu:\nintact -db /opt/intact/intact.db -addr 127.0.0.1:20142')">Copy</button>
1996
+ </div>
1997
+ <pre>npm install -g intact-gateway
1998
+
1999
+ # Khởi tạo và chạy intact với file database SQLite chỉ định:
2000
+ intact -db /opt/intact/intact.db -addr 127.0.0.1:20142</pre>
2001
+ </div>
2002
+
2003
+ <h4>Cách 2: Build Từ Mã Nguồn Go (Zero-CGO, Không Cần Toolchain C)</h4>
2004
+ <div class="doc-codebox">
2005
+ <div class="doc-codebox-bar">
2006
+ <span>Terminal · Go Build</span>
2007
+ <button type="button" class="btn btn-outline btn-sm" onclick="copyDocCode(this, 'git clone https://github.com/louisphamdev/intact.git\ncd intact\nCGO_ENABLED=0 go build -o intact ./cmd/intact\n# Cross-compile cho Linux server từ macOS / Windows:\nGOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags=&quot;-s -w&quot; -o intact-linux ./cmd/intact')">Copy</button>
2008
+ </div>
2009
+ <pre>git clone https://github.com/louisphamdev/intact.git
2010
+ cd intact
2011
+
2012
+ # Biên dịch binary tĩnh:
2013
+ CGO_ENABLED=0 go build -o intact ./cmd/intact
2014
+
2015
+ # Hoặc cross-compile cho Linux Server từ máy macOS / Windows:
2016
+ GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags="-s -w" -o intact-linux ./cmd/intact</pre>
2017
+ </div>
2018
+
2019
+ <h3>Bảng Tra Cứu Tham Số Dòng Lệnh (CLI Flags) Của intact</h3>
2020
+ <table class="doc-table">
2021
+ <thead>
2022
+ <tr>
2023
+ <th style="width:28%;">Cờ dòng lệnh</th>
2024
+ <th style="width:25%;">Giá trị mặc định</th>
2025
+ <th>Mô tả chức năng chi tiết</th>
2026
+ </tr>
2027
+ </thead>
2028
+ <tbody>
2029
+ <tr>
2030
+ <td><code>-addr &lt;host:port&gt;</code></td>
2031
+ <td><code>127.0.0.1:20130</code></td>
2032
+ <td>Địa chỉ IP và cổng lắng nghe cho proxy và dashboard (ví dụ: <code>127.0.0.1:20142</code>).</td>
2033
+ </tr>
2034
+ <tr>
2035
+ <td><code>-db &lt;file.db&gt;</code></td>
2036
+ <td><code>intact.db</code></td>
2037
+ <td>Đường dẫn tới tệp SQLite database. Tự động tạo bảng lần đầu và tự migrate schema ở các lần khởi động sau.</td>
2038
+ </tr>
2039
+ <tr>
2040
+ <td><code>-show-totp</code></td>
2041
+ <td><em>(Không)</em></td>
2042
+ <td>In khóa bí mật TOTP của bản cài đặt này và các bước nhập vào app xác thực rồi thoát.</td>
2043
+ </tr>
2044
+ <tr>
2045
+ <td><code>-enroll</code></td>
2046
+ <td><em>(Không)</em></td>
2047
+ <td>Sinh một khóa bí mật TOTP hoàn toàn mới và in ra URI <code>otpauth://</code> để nạp vào <code>INTACT_TOTP_SECRET</code>.</td>
2048
+ </tr>
2049
+ <tr>
2050
+ <td><code>-insecure-no-auth</code></td>
2051
+ <td><em>(Không)</em></td>
2052
+ <td>Khởi động không cần cổng đăng nhập (chỉ cho phép kết nối từ loopback Host để ngăn chặn DNS rebinding).</td>
2053
+ </tr>
2054
+ </tbody>
2055
+ </table>
2056
+
2057
+ <h3>Bảng Tra Cứu Biến Môi Trường (Environment Variables) Của intact</h3>
2058
+ <table class="doc-table">
2059
+ <thead>
2060
+ <tr>
2061
+ <th style="width:34%;">Biến môi trường</th>
2062
+ <th>Mô tả ý nghĩa & cách áp dụng</th>
2063
+ </tr>
2064
+ </thead>
2065
+ <tbody>
2066
+ <tr>
2067
+ <td><code>INTACT_TOTP_SECRET</code></td>
2068
+ <td>Chuỗi Base32 bí mật cho xác thực TOTP trên Dashboard. Khi để trống, intact dùng secret được lưu trong SQLite.</td>
2069
+ </tr>
2070
+ <tr>
2071
+ <td><code>INTACT_API_TOKEN</code></td>
2072
+ <td>Master token. Cho phép gọi toàn quyền vào <code>/v1</code>, <code>/api/*</code> và <code>/mcp</code> mà không cần session cookie.</td>
2073
+ </tr>
2074
+ <tr>
2075
+ <td><code>INTACT_SESSION_KEY</code></td>
2076
+ <td>Khóa ký HMAC cho cookie phiên dashboard. Khi để trống, intact sinh khóa ngẫu nhiên trong RAM mỗi lần khởi động.</td>
2077
+ </tr>
2078
+ <tr>
2079
+ <td><code>INTACT_SESSION_TTL</code></td>
2080
+ <td>Thời gian sống của phiên đăng nhập dashboard tính bằng giây (mặc định: <code>43200</code> = 12 giờ).</td>
2081
+ </tr>
2082
+ <tr>
2083
+ <td><code>INTACT_OWNER_LOOPBACK</code></td>
2084
+ <td>Đặt <code>1</code> để cho phép chủ sở hữu kết nối qua SSH Tunnel loopback không bị giới hạn số lần thử mã đăng nhập.</td>
2085
+ </tr>
2086
+ <tr>
2087
+ <td><code>INTACT_ANTIGRAVITY_CLIENT_SECRET</code></td>
2088
+ <td>Google OAuth client secret của app Antigravity. intact tự động tải lần đầu; chỉ đặt khi lookup tự động bị chặn.</td>
2089
+ </tr>
2090
+ <tr>
2091
+ <td><code>INTACT_ARENA_URL</code></td>
2092
+ <td>Mirror của Hugging Face datasets server để tải bảng xếp hạng LMArena định kỳ (mặc định: <code>https://datasets-server.huggingface.co</code>).</td>
2093
+ </tr>
2094
+ </tbody>
2095
+ </table>
2096
+
2097
+ <h3>Triển Khai Dịch Vụ Nền Production (Systemd Service trên Linux)</h3>
2098
+ <p>
2099
+ Tạo file cấu hình dịch vụ tại <code>/etc/systemd/system/intact.service</code>:
2100
+ </p>
2101
+ <div class="doc-codebox">
2102
+ <div class="doc-codebox-bar">
2103
+ <span>/etc/systemd/system/intact.service</span>
2104
+ <button type="button" class="btn btn-outline btn-sm" onclick="copyDocCode(this, '[Unit]\nDescription=intact LLM Credential Proxy and Account Pooler\nAfter=network.target\n\n[Service]\nUMask=0077\nEnvironmentFile=/opt/intact/intact.env\nExecStart=/opt/intact/intact -db /opt/intact/intact.db -addr 127.0.0.1:20142\nRestart=on-failure\nWorkingDirectory=/opt/intact\n\n[Install]\nWantedBy=multi-user.target')">Copy</button>
2105
+ </div>
2106
+ <pre>[Unit]
2107
+ Description=intact LLM Credential Proxy and Account Pooler
2108
+ After=network.target
2109
+
2110
+ [Service]
2111
+ UMask=0077
2112
+ EnvironmentFile=/opt/intact/intact.env
2113
+ ExecStart=/opt/intact/intact -db /opt/intact/intact.db -addr 127.0.0.1:20142
2114
+ Restart=on-failure
2115
+ WorkingDirectory=/opt/intact
2116
+
2117
+ [Install]
2118
+ WantedBy=multi-user.target</pre>
2119
+ </div>
2120
+ <p>
2121
+ Tạo thư mục làm việc, file biến môi trường bảo mật <code>/opt/intact/intact.env</code> với quyền <code>0600</code> và kích hoạt dịch vụ:
2122
+ </p>
2123
+ <div class="doc-codebox">
2124
+ <div class="doc-codebox-bar">
2125
+ <span>Terminal · Kích hoạt service</span>
2126
+ <button type="button" class="btn btn-outline btn-sm" onclick="copyDocCode(this, 'sudo mkdir -p -m 700 /opt/intact\nsudo touch /opt/intact/intact.env\nsudo chmod 600 /opt/intact/intact.env\nsudo systemctl daemon-reload\nsudo systemctl enable --now intact')">Copy</button>
2127
+ </div>
2128
+ <pre>sudo mkdir -p -m 700 /opt/intact
2129
+ sudo touch /opt/intact/intact.env
2130
+ sudo chmod 600 /opt/intact/intact.env
2131
+ sudo systemctl daemon-reload
2132
+ sudo systemctl enable --now intact</pre>
2133
+ </div>
2134
+
2135
+ <h3>Đưa intact Ra Internet An Toàn Qua Cloudflare Tunnel (Zero-Trust Ingress)</h3>
2136
+ <p>
2137
+ Không cần mở bất kỳ cổng firewall nào trên VPS! Sử dụng Cloudflare Tunnel trỏ tên miền của bạn về cổng loopback của intact:
2138
+ </p>
2139
+ <div class="doc-codebox">
2140
+ <div class="doc-codebox-bar">
2141
+ <span>/etc/cloudflared/config.yml (Ingress snippet)</span>
2142
+ <button type="button" class="btn btn-outline btn-sm" onclick="copyDocCode(this, 'ingress:\n - hostname: intact.yourdomain.com\n service: http://127.0.0.1:20142\n - service: http_status:404')">Copy</button>
2143
+ </div>
2144
+ <pre>ingress:
2145
+ - hostname: intact.yourdomain.com
2146
+ service: http://127.0.0.1:20142
2147
+ - service: http_status:404</pre>
2148
+ </div>
2149
+
2150
+ <h3>Sao Lưu & Nâng Cấp An Toàn (Database Integrity Guarantee)</h3>
2151
+ <p>
2152
+ Vì SQLite sử dụng chế độ WAL (Write-Ahead Logging), <strong>tuyệt đối không dùng lệnh <code>cp</code> sao chép file trực tiếp</strong> vì có thể làm mất dữ liệu chưa kịp flush vào đĩa. Hãy dùng API Online Backup chuẩn:
2153
+ </p>
2154
+ <div class="doc-codebox">
2155
+ <div class="doc-codebox-bar">
2156
+ <span>Terminal · SQLite Online Backup</span>
2157
+ <button type="button" class="btn btn-outline btn-sm" onclick="copyDocCode(this, 'install -d -m 0700 /opt/intact/backup\n(umask 077 && sqlite3 /opt/intact/intact.db &quot;.backup /opt/intact/backup/intact-$(date +%F-%H%M).db&quot;)')">Copy</button>
2158
+ </div>
2159
+ <pre>install -d -m 0700 /opt/intact/backup
2160
+ (umask 077 && sqlite3 /opt/intact/intact.db ".backup /opt/intact/backup/intact-$(date +%F-%H%M).db")</pre>
2161
+ </div>
2162
+ <p>
2163
+ Để nâng cấp: giữ lại file binary cũ <code>intact.prev</code>, tải bản mới thay thế và chạy <code>sudo systemctl restart intact</code>. Schema database sẽ tự động được nâng cấp tương thích ngược.
2164
+ </p>
2165
+
2166
+ <h3>Cẩm Nang Sử Dụng & Vận Hành intact Chi Tiết Nhất</h3>
2167
+ <ol>
2168
+ <li>
2169
+ <strong>Xác Thực TOTP & Đăng Nhập Lần Đầu (Zero-Password):</strong>
2170
+ <p>
2171
+ Chạy lệnh <code>intact -db /opt/intact/intact.db -show-totp</code> (hoặc kiểm tra log <code>journalctl -u intact</code>). Mở Google Authenticator, 1Password hoặc Aegis trên điện thoại, chọn <em>"Enter a setup key"</em>, nhập tên <code>intact</code> và khóa bí mật in ra. Truy cập giao diện Web Dashboard và nhập mã 6 số để đăng nhập.
2172
+ </p>
2173
+ </li>
2174
+ <li>
2175
+ <strong>Thêm Nhà Cung Cấp & Kết Nối (Providers & Connections):</strong>
2176
+ <p>
2177
+ Vào mục <strong>Providers → Add</strong> trên thanh menu của intact:
2178
+ </p>
2179
+ <ul>
2180
+ <li><strong>API-Key Providers:</strong> Groq, OpenRouter, Vertex AI, NVIDIA NIM, DeepSeek, Cloudflare Workers AI... (chỉ cần dán API key).</li>
2181
+ <li><strong>Coding Tool OAuth Sign-ins (Class A):</strong> Claude Code, OpenAI Codex, Antigravity (Google), GitHub Copilot (đăng nhập bằng browser OAuth hoặc device-code).</li>
2182
+ </ul>
2183
+ <div class="doc-callout info">
2184
+ <strong>Lưu ý về Antigravity:</strong> Lần đăng nhập tài khoản Antigravity đầu tiên có thể mất khoảng 1 phút do intact tự động liên hệ Google để tải về OAuth client secret.
2185
+ </div>
2186
+ </li>
2187
+ <li>
2188
+ <strong>Chiến Lược Điều Phối Tải & Xoay Vòng (Rotation & Failover):</strong>
2189
+ <ul>
2190
+ <li><strong>Round Robin (1 req/turn):</strong> Chia đều tải qua từng request giữa các tài khoản đang hoạt động.</li>
2191
+ <li><strong>Round Robin (N reqs/turn):</strong> Phục vụ liên tục N request trên một tài khoản trước khi chuyển sang tài khoản kế tiếp. <em>Đây là chế độ lý tưởng để giữ ấm Prompt Cache (Anthropic/OpenAI prompt cache hits), giúp tiết kiệm 50-90% chi phí và giảm độ trễ tối đa.</em></li>
2192
+ <li><strong>Fallback:</strong> Luôn ưu tiên tài khoản chính (Primary). Chỉ chuyển sang tài khoản dự phòng khi tài khoản chính gặp lỗi 429/500/503 hoặc cạn quota.</li>
2193
+ <li><strong>Standby Account:</strong> Đánh dấu tài khoản dự phòng ngủ đông, chỉ được kích hoạt khi toàn bộ tài khoản chính gặp sự cố.</li>
2194
+ <li><strong>Conversation Stickiness (Gắn kết phiên):</strong> intact tự động nhận diện phiên hội thoại theo Session ID (<code>X-Claude-Code-Session-Id</code>, <code>session_id</code>) và ghim hội thoại vào tài khoản phục vụ trước đó trong vòng 1 giờ để tối đa hoá cache.</li>
2195
+ <li><strong>429 Retry Shorter Đột Phá:</strong> Khi một cuộc trò chuyện dài gặp lỗi rate limit 429 token-per-minute, intact tự động cắt ngắn lịch sử ngữ cảnh và gửi thử lại ngay lập tức trên tài khoản tiếp theo, bảo vệ phiên làm việc của bạn không bị crash giữa chừng.</li>
2196
+ </ul>
2197
+ </li>
2198
+ <li>
2199
+ <strong>Tạo API Key Cho Client:</strong>
2200
+ <p>
2201
+ Vào <strong>Endpoint → API keys → Create</strong>, đặt tên và sao chép mã khóa có định dạng <code>sk-intact-...</code>. Key này sẽ được dán vào cấu hình của LLM Switcher hoặc các ứng dụng bên thứ ba.
2202
+ </p>
2203
+ </li>
2204
+ <li>
2205
+ <strong>Quy Tắc Định Tuyến Mô Hình (Model Routing Syntax):</strong>
2206
+ <ul>
2207
+ <li><strong>Chỉ định rõ provider:</strong> <code>groq/llama-3.3-70b-versatile</code>, <code>antigravity/gemini-3.8-flash-high</code>, <code>codex/gpt-5.5</code>.</li>
2208
+ <li><strong>Tên model trần (bare id):</strong> <code>llama-3.3-70b-versatile</code> (intact sẽ tự động gộp tất cả các tài khoản của mọi provider hỗ trợ mô hình đó thành một pool chung).</li>
2209
+ </ul>
2210
+ </li>
2211
+ <li>
2212
+ <strong>Thử Nghiệm & Giám Sát Với Contract Lab:</strong>
2213
+ <p>
2214
+ Chạy lệnh <code>switch contract-probe</code> từ máy trạm để gửi bộ 6 biến thể dữ liệu mẫu tới intact, kiểm tra độ tương thích của model. Chạy <code>switch contract-check</code> để kéo về các finding sai lệch schema và tự động sinh test case.
2215
+ </p>
2216
+ </li>
2217
+ </ol>
2218
+
2219
+ <h3>Mẫu Cấu Hình Tích Hợp Hoàn Hảo Trong LLM Switcher</h3>
2220
+ <p>
2221
+ Cấu hình <code>config.json</code> trên máy trạm để chuyển tiếp lưu lượng Claude Code, Codex và agy qua intact:
2222
+ </p>
2223
+ <div class="doc-codebox">
2224
+ <div class="doc-codebox-bar">
2225
+ <span>config.json (Tích hợp intact)</span>
2226
+ <button type="button" class="btn btn-outline btn-sm" onclick="copyDocCode(this, document.getElementById('code-intact-config-sample').textContent)">Copy</button>
2227
+ </div>
2228
+ <pre id="code-intact-config-sample">{
2229
+ "port": 3456,
2230
+ "activeProfiles": {
2231
+ "claude": "intact-claude",
2232
+ "codex": "intact-codex",
2233
+ "agy": "agy-intact"
2234
+ },
2235
+ "profiles": {
2236
+ "intact-claude": {
2237
+ "name": "Claude via intact",
2238
+ "tool": "claude",
2239
+ "mode": "convert",
2240
+ "outFormat": "openai-chat",
2241
+ "baseURL": "https://intact.yourdomain.com/v1",
2242
+ "apiKey": "sk-intact-...",
2243
+ "thinkingMode": "auto"
2244
+ },
2245
+ "intact-codex": {
2246
+ "name": "Codex via intact",
2247
+ "tool": "codex",
2248
+ "mode": "convert",
2249
+ "outFormat": "openai-chat",
2250
+ "baseURL": "https://intact.yourdomain.com/v1",
2251
+ "apiKey": "sk-intact-...",
2252
+ "defaultModels": {
2253
+ "main": "gemini-3.8-flash",
2254
+ "review": "gemini-3.7-flash-medium",
2255
+ "subagent": "gemini-3.6-flash-low"
2256
+ }
2257
+ },
2258
+ "agy-intact": {
2259
+ "name": "agy on intact",
2260
+ "tool": "agy",
2261
+ "mode": "convert",
2262
+ "outFormat": "openai-chat",
2263
+ "baseURL": "https://intact.yourdomain.com/v1",
2264
+ "apiKey": "sk-intact-...",
2265
+ "defaultModels": { "main": "antigravity/*" } // Kích hoạt Bifrost passthrough
2266
+ }
2267
+ },
2268
+ "contractLab": {
2269
+ "url": "https://intact.yourdomain.com",
2270
+ "apiKey": "sk-intact-...",
2271
+ "enabled": true
2272
+ }
2273
+ }</pre>
2274
+ </div>
2275
+ <div class="doc-callout info">
2276
+ <strong>Mẹo cấu hình nhanh trên Web UI:</strong> Tại tab <strong>Routes & Profiles</strong>, nhấn <strong>+ Add Profile</strong> và chọn nút <strong>Template Quick-Fill: intact</strong> hoặc <strong>agy on intact</strong> để tự động điền sẵn toàn bộ tham số tối ưu chỉ với 1 click!
2277
+ </div>
2278
+ </div>
2279
+ </section>
2280
+
2281
+ <!-- 4. CLI & OPERATION GUIDE -->
1889
2282
  <section class="doc-section" id="doc-cli">
1890
2283
  <div class="doc-section-h">
1891
2284
  <h2>
1892
2285
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="4 17 10 11 4 5"/><line x1="12" y1="19" x2="20" y2="19"/></svg>
1893
- 3. Hướng Dẫn Sử Dụng & Bảng Tra Cứu Lệnh CLI
2286
+ 4. Lệnh CLI & Cẩm Nang Vận Hành
1894
2287
  </h2>
1895
- <span class="badge" style="background:var(--card2); color:var(--muted);">Cheatsheet</span>
2288
+ <span class="badge" style="background:var(--card2); color:var(--muted);">Bảng Tra Cứu Toàn Diện (Cheatsheet)</span>
1896
2289
  </div>
1897
2290
  <div class="doc-prose">
1898
2291
  <p>
@@ -1901,34 +2294,38 @@ switch service uninstall</pre>
1901
2294
  <table class="doc-table">
1902
2295
  <thead>
1903
2296
  <tr>
1904
- <th style="width:38%;">Lệnh CLI</th>
2297
+ <th style="width:36%;">Lệnh CLI & Cờ</th>
1905
2298
  <th>Mô tả chức năng chi tiết</th>
1906
2299
  </tr>
1907
2300
  </thead>
1908
2301
  <tbody>
1909
2302
  <tr>
1910
- <td><code>switch on [profile]</code></td>
1911
- <td>Khởi động Gateway và kích hoạt profile (mặc định nếu không truyền tên).</td>
2303
+ <td><code>switch ui</code> / <code>web</code> / <code>gui</code></td>
2304
+ <td>Mở giao diện Web Dashboard trên trình duyệt mặc định kèm access token an toàn.</td>
1912
2305
  </tr>
1913
2306
  <tr>
1914
- <td><code>switch off</code></td>
1915
- <td>Dừng hoàn toàn Gateway và khôi phục các công cụ về endpoint chính hãng.</td>
2307
+ <td><code>switch status</code> / <code>st</code></td>
2308
+ <td>Hiển thị trạng thái hoạt động, cổng kết nối và cấu hình routing của cả 3 công cụ CLI.</td>
1916
2309
  </tr>
1917
2310
  <tr>
1918
- <td><code>switch off claude | codex | agy</code></td>
1919
- <td>Tắt chuyển đổi cho một công cụ cụ thể; các công cụ còn lại vẫn tiếp tục hoạt động.</td>
2311
+ <td><code>switch version</code> / <code>-v</code></td>
2312
+ <td>Hiển thị phiên bản hiện tại và kiểm tra xem trên npm có bản phát hành mới hơn không.</td>
1920
2313
  </tr>
1921
2314
  <tr>
1922
- <td><code>switch ui</code></td>
1923
- <td>Mở giao diện Web Dashboard trên trình duyệt mặc định kèm access token an toàn.</td>
2315
+ <td><code>switch doctor</code> / <code>audit</code></td>
2316
+ <td>Quét chẩn đoán: kiểm tra liveness, xung đột port, rò rỉ biến môi trường, shims và phiên CLI đang chạy.</td>
2317
+ </tr>
2318
+ <tr>
2319
+ <td><code>switch update</code> / <code>upgrade</code></td>
2320
+ <td>Tải và nâng cấp lên bản phát hành mới nhất từ npm/git, khởi động lại gateway không làm rớt phiên.</td>
1924
2321
  </tr>
1925
2322
  <tr>
1926
- <td><code>switch status</code></td>
1927
- <td>Hiển thị trạng thái hoạt động và cấu hình routing của cả 3 công cụ CLI.</td>
2323
+ <td><code>switch on [profile]</code> / <code>start</code></td>
2324
+ <td>Khởi động Gateway và kích hoạt profile (mặc định nếu không truyền tên) cho tất cả target tương thích.</td>
1928
2325
  </tr>
1929
2326
  <tr>
1930
2327
  <td><code>switch &lt;profile&gt;</code></td>
1931
- <td>Kích hoạt cùng một profile cho cả Claude Code và Codex.</td>
2328
+ <td>Kích hoạt cùng một profile cho các công cụ tương thích.</td>
1932
2329
  </tr>
1933
2330
  <tr>
1934
2331
  <td><code>switch claude &lt;profile&gt;</code></td>
@@ -1940,64 +2337,129 @@ switch service uninstall</pre>
1940
2337
  </tr>
1941
2338
  <tr>
1942
2339
  <td><code>switch agy &lt;profile&gt;</code></td>
1943
- <td>Kích hoạt profile chỉ định riêng cho <strong>Antigravity CLI</strong>.</td>
2340
+ <td>Kích hoạt profile chỉ định riêng cho <strong>Antigravity CLI (agy)</strong>.</td>
1944
2341
  </tr>
1945
2342
  <tr>
1946
- <td><code>switch doctor</code></td>
1947
- <td>Quét chẩn đoán: kiểm tra loopback binding, xung đột port, rò rỉ biến môi trường và phiên CLI đang chạy.</td>
2343
+ <td><code>switch port &lt;số&gt;</code></td>
2344
+ <td>Đổi cổng lắng nghe của Gateway (mặc định: 3456) và tự động khởi động lại service.</td>
1948
2345
  </tr>
1949
2346
  <tr>
1950
- <td><code>switch update</code></td>
1951
- <td>Tải và nâng cấp lên bản phát hành mới nhất từ npm/git, khởi động lại gateway không làm rớt phiên.</td>
2347
+ <td><code>switch service install [--autoupdate]</code></td>
2348
+ <td>Cài đặt dịch vụ nền tự khởi động cùng OS (systemd / launchd / Task Scheduler).</td>
1952
2349
  </tr>
1953
2350
  <tr>
1954
- <td><code>switch port &lt;số&gt;</code></td>
1955
- <td>Đổi cổng lắng nghe của Gateway (mặc định: 3456) và tự động khởi động lại service.</td>
2351
+ <td><code>switch service uninstall</code></td>
2352
+ <td>Gỡ bỏ hoàn toàn dịch vụ nền tự khởi động của hệ điều hành.</td>
2353
+ </tr>
2354
+ <tr>
2355
+ <td><code>switch shim install</code></td>
2356
+ <td>Cài đặt các launcher shim vào <code>~/.llm-switcher/bin</code> để định tuyến trong suốt.</td>
1956
2357
  </tr>
1957
2358
  <tr>
1958
2359
  <td><code>switch shim status</code></td>
1959
2360
  <td>Kiểm tra tình trạng các launcher shim và phát hiện phiên CLI chạy lọt ra ngoài.</td>
1960
2361
  </tr>
2362
+ <tr>
2363
+ <td><code>switch shim uninstall</code></td>
2364
+ <td>Gỡ bỏ các launcher shim khỏi thư mục bin.</td>
2365
+ </tr>
1961
2366
  <tr>
1962
2367
  <td><code>switch plugin install</code></td>
1963
- <td>Cài đặt thông báo trạng thái định tuyến bên trong Claude Code, Codex và agy.</td>
2368
+ <td>Cài đặt thông báo trạng thái định tuyến (hook notice) bên trong Claude Code, Codex và agy.</td>
2369
+ </tr>
2370
+ <tr>
2371
+ <td><code>switch plugin status</code></td>
2372
+ <td>Kiểm tra tình trạng các plugin hook thông báo trạng thái.</td>
2373
+ </tr>
2374
+ <tr>
2375
+ <td><code>switch plugin uninstall</code></td>
2376
+ <td>Gỡ bỏ các plugin hook thông báo khỏi cấu hình các công cụ.</td>
2377
+ </tr>
2378
+ <tr>
2379
+ <td><code>switch off [claude|codex|agy]</code></td>
2380
+ <td>Khôi phục endpoint chính hãng (cho toàn bộ công cụ nếu không truyền tham số, hoặc cho một công cụ cụ thể).</td>
2381
+ </tr>
2382
+ <tr>
2383
+ <td><code>switch models [--refresh]</code></td>
2384
+ <td>Xem danh mục mô hình phát hiện được cho Claude Code & Codex; <code>--refresh</code> để cập nhật từ upstream.</td>
2385
+ </tr>
2386
+ <tr>
2387
+ <td><code>switch compact on</code> / <code>off</code></td>
2388
+ <td>Bật / tắt tính năng nén prefix ngữ cảnh khi nhàn rỗi cho Claude Code.</td>
1964
2389
  </tr>
1965
2390
  <tr>
1966
- <td><code>switch compact [on|off]</code></td>
1967
- <td>Bật / tắt tính năng nén lịch sử hội thoại khi idle lâu ngày.</td>
2391
+ <td><code>switch compact codex on</code> / <code>off</code></td>
2392
+ <td>Bật / tắt nén prefix ngữ cảnh trên đường truyền cho Codex Responses.</td>
2393
+ </tr>
2394
+ <tr>
2395
+ <td><code>switch compact model &lt;id|none&gt;</code></td>
2396
+ <td>Chỉ định model tóm tắt chạy ngầm (hoặc <code>none</code> để dùng thuật toán cắt tỉa tất định không tốn token).</td>
2397
+ </tr>
2398
+ <tr>
2399
+ <td><code>switch compact idle &lt;phút&gt;</code></td>
2400
+ <td>Đặt ngưỡng thời gian nhàn rỗi (1 – 1440 phút, mặc định: 15) trước khi kích hoạt nén cache.</td>
2401
+ </tr>
2402
+ <tr>
2403
+ <td><code>switch compact min &lt;KB&gt;</code></td>
2404
+ <td>Đặt ngưỡng kích thước payload tối thiểu (8 – 4096 KB, mặc định: 64) để áp dụng nén.</td>
2405
+ </tr>
2406
+ <tr>
2407
+ <td><code>switch compact status</code></td>
2408
+ <td>Hiển thị chi tiết cấu hình và chính sách Idle Compaction hiện tại.</td>
2409
+ </tr>
2410
+ <tr>
2411
+ <td><code>switch contract-probe [--model m]</code></td>
2412
+ <td>Gửi tổ hợp 6 test request kiểm tra hợp đồng chuyển đổi qua Gateway lên intact.</td>
2413
+ </tr>
2414
+ <tr>
2415
+ <td><code>switch contract-check</code></td>
2416
+ <td>Lấy các trường dữ liệu bị mất từ intact và tự động sinh test case kiểm thử độ chính xác.</td>
2417
+ </tr>
2418
+ <tr>
2419
+ <td><code>--port &lt;n&gt;</code> / <code>-p &lt;n&gt;</code></td>
2420
+ <td>Cờ toàn cục để ghi đè tạm thời cổng Gateway cho lệnh đang chạy.</td>
1968
2421
  </tr>
1969
2422
  </tbody>
1970
2423
  </table>
1971
2424
 
2425
+ <h3>Cơ Chế Thông Báo Trạng Thái (Launch Notice)</h3>
2426
+ <p>
2427
+ Để bạn luôn biết phiên làm việc có đang qua Gateway hay không mà không cần mở <code>settings.json</code>:
2428
+ </p>
2429
+ <ul>
2430
+ <li><strong>1. Thông báo từ Shim (Mặc định luôn bật khi có route):</strong> Khi bạn chạy lệnh công cụ, shim in một dòng tóm tắt trên stderr (Linux/macOS) hoặc hiện Windows Toast notification: <code>claude -&gt; intact-claude | intact.example.com | antigravity/gemini-3.8-flash | 1M</code>. Khi công cụ tắt, shim hoàn toàn im lặng.</li>
2431
+ <li><strong>2. Thông báo bên trong Tool (Tùy chọn, cài bằng <code>switch plugin install</code>):</strong> Tạo file hook trực tiếp trong thư mục skills/hooks của tool (Claude Code plugin tại <code>~/.claude/skills/llm-switcher-status/</code>, Codex tại <code>~/.codex/hooks.json</code>, agy tại <code>~/.gemini/antigravity-cli/hooks.json</code>). Báo rõ trạng thái kết nối hoặc cảnh báo nếu Gateway chưa bật.</li>
2432
+ </ul>
2433
+
1972
2434
  <div class="doc-callout warning">
1973
2435
  <strong>Quy tắc quan trọng về môi trường:</strong> Tuyệt đối <em>không</em> thêm <code>source env.sh</code> hay <code>call env.cmd</code> vào file rc của shell. Các biến định tuyến được tự động tiêm độc lập vào từng phiên CLI thông qua các wrapper shim trong <code>~/.llm-switcher/bin</code>.
1974
2436
  </div>
1975
2437
  </div>
1976
2438
  </section>
1977
2439
 
1978
- <!-- 4. BLINDFOLD MODE & CA SECURITY -->
2440
+ <!-- 5. BLINDFOLD MODE & CA SECURITY -->
1979
2441
  <section class="doc-section" id="doc-blindfold">
1980
2442
  <div class="doc-section-h">
1981
2443
  <h2>
1982
2444
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
1983
- 4. Blindfold Mode & Bảo Mật Chứng Chỉ CA
2445
+ 5. Blindfold Mode & Bảo Mật Chứng Chỉ CA
1984
2446
  </h2>
1985
- <span class="badge" style="background:var(--mint); color:#042f2e; font-weight:600;">Port :3457 · Zero-Warning</span>
2447
+ <span class="badge" style="background:var(--mint); color:#042f2e; font-weight:600;">Port :3457 · Zero-Warning Interceptor</span>
1986
2448
  </div>
1987
2449
  <div class="doc-prose">
1988
2450
  <p>
1989
- Trên Codex CLI, khi bạn ghi đè Base URL theo cách thông thường, giao diện <code>/model</code> sẽ hiển thị một dòng cảnh báo phiền toái: <em>"base URL is overridden to http://... Selecting models may not be supported..."</em>.
2451
+ Trên Codex CLI, khi bạn ghi đè Base URL theo cách thông thường (<code>--config openai_base_url=...</code>), giao diện <code>/model</code> sẽ hiển thị một dòng cảnh báo phiền toái: <em>"base URL is overridden to http://... Selecting models may not be supported or work properly."</em>.
1990
2452
  </p>
1991
2453
  <p>
1992
- <strong>Blindfold Mode</strong> giải quyết triệt để vấn đề này. Codex và Claude Code tiếp tục gửi request đến endpoint chính hãng, trong khi LLM Switcher đánh chặn ở tầng mạng thông qua proxy trung gian <code>HTTPS_PROXY=http://127.0.0.1:3457</code>.
2454
+ <strong>Blindfold Mode</strong> giải quyết triệt để vấn đề này. Codex và Claude Code tiếp tục gửi request đến endpoint chính hãng, trong khi LLM Switcher đánh chặn ở tầng mạng thông qua proxy trung gian <code>HTTPS_PROXY=http://127.0.0.1:3457</code>. File cấu hình của tool hoàn toàn nguyên vẹn.
1993
2455
  </p>
1994
2456
 
1995
2457
  <h3>Bảng Định Tuyến Cố Định Của Interceptor (:3457)</h3>
1996
2458
  <table class="doc-table">
1997
2459
  <thead>
1998
2460
  <tr>
1999
- <th>Domain Đích (CONNECT Host)</th>
2000
- <th>Đường Dẫn Bị Đánh Chặn (Về Gateway :3456)</th>
2461
+ <th style="width:28%;">Domain Đích (CONNECT Host)</th>
2462
+ <th style="width:38%;">Đường Dẫn Bị Đánh Chặn (Về Gateway :3456)</th>
2001
2463
  <th>Đường Dẫn Còn Lại (Tunnel Ra Internet Thật)</th>
2002
2464
  </tr>
2003
2465
  </thead>
@@ -2022,28 +2484,34 @@ switch service uninstall</pre>
2022
2484
  <td><em>Không chặn</em></td>
2023
2485
  <td>Tunnel thẳng ra Internet dạng raw TCP, không đọc dữ liệu</td>
2024
2486
  </tr>
2487
+ <tr>
2488
+ <td><em>Địa chỉ nội bộ (127.0.0.1, private IP)</em></td>
2489
+ <td><em>Bị từ chối (HTTP 403/421)</em></td>
2490
+ <td>Chống tấn công SSRF và lạm dụng mạng nội bộ</td>
2491
+ </tr>
2025
2492
  </tbody>
2026
2493
  </table>
2027
2494
 
2028
2495
  <h3>🔒 Cam Kết An Toàn & Cô Lập Chứng Chỉ CA</h3>
2029
2496
  <ul>
2030
- <li><strong>Tự sinh 100% tại máy cục bộ:</strong> Cặp khóa <code>ca.pem</code> và <code>ca.key</code> được tự động tạo lần đầu bằng thư viện crypto chuẩn của Node.js. Private key được bảo vệ với quyền nghiêm ngặt <code>0600</code>.</li>
2497
+ <li><strong>Tự sinh 100% tại máy cục bộ:</strong> Cặp khóa <code>ca.pem</code> và <code>ca.key</code> được tự động tạo lần đầu bằng thư viện crypto chuẩn của Node.js. Private key được bảo vệ với quyền nghiêm ngặt <code>0600</code>. Tuyệt đối không tải key từ Internet.</li>
2031
2498
  <li><strong>Không can thiệp vào Hệ Điều Hành:</strong> Tuyệt đối <em>không</em> cài chứng chỉ vào Windows Certificate Store, macOS Keychain hay Linux <code>/etc/ssl/certs</code>. Bạn <strong>không cần quyền root hay Administrator</strong>.</li>
2032
2499
  <li><strong>Chỉ tin cậy trong phạm vi tiến trình (Process-Scoped):</strong> Chứng chỉ chỉ được tiêm vào bộ nhớ RAM của <code>claude</code> (qua <code>NODE_EXTRA_CA_CERTS</code>) và <code>codex</code> (qua <code>CODEX_CA_CERTIFICATE</code>). Trình duyệt web và ứng dụng khác hoàn toàn không tin cậy chứng chỉ này.</li>
2033
2500
  <li><strong>Ràng buộc tên miền mật mã học (X.509 Name Constraints):</strong> CA được cấu hình bắt buộc chỉ cho phép ký duy nhất cho 3 domain: <code>api.anthropic.com</code>, <code>api.openai.com</code>, và <code>chatgpt.com</code>. Ngay cả khi lộ private key, mọi kết nối tới ngân hàng, Google, GitHub đều bị từ chối ngay lập tức.</li>
2034
2501
  <li><strong>Bảo toàn chứng chỉ VPN / Doanh nghiệp:</strong> Nếu máy bạn có sẵn CA công ty trong <code>NODE_EXTRA_CA_CERTS</code>, script <code>ensure-ca-bundle.mjs</code> sẽ tự động gộp cả 2 chứng chỉ vào một bundle tạm thời, không bao giờ làm đứt mạng nội bộ.</li>
2502
+ <li><strong>Lưu ý tạo chứng chỉ trên Windows:</strong> Chạy lệnh <code>bash blindfold/make-certs.sh</code> trong <strong>Git Bash</strong>. Tuyệt đối không dùng <code>New-SelfSignedCertificate</code> trong PowerShell vì lệnh này thiếu extendedKeyUsage <code>serverAuth</code> gây lỗi handshake.</li>
2035
2503
  </ul>
2036
2504
  </div>
2037
2505
  </section>
2038
2506
 
2039
- <!-- 5. ANTIGRAVITY CLI (AGY) -->
2507
+ <!-- 6. ANTIGRAVITY CLI (AGY) -->
2040
2508
  <section class="doc-section" id="doc-agy">
2041
2509
  <div class="doc-section-h">
2042
2510
  <h2>
2043
2511
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polygon points="12 2 2 7 12 12 22 7 12 2"/><polyline points="2 17 12 22 22 17"/><polyline points="2 12 12 17 22 12"/></svg>
2044
- 5. Cấu Hình Antigravity CLI (agy) & Tiếp Sức An Toàn
2512
+ 6. Antigravity CLI (agy) & Relay Proof An Toàn
2045
2513
  </h2>
2046
- <span class="badge" style="background:var(--warn-soft); color:var(--warn); font-weight:600;">CLOUD_CODE_URL · Relay Proof</span>
2514
+ <span class="badge" style="background:var(--warn-soft); color:var(--warn); font-weight:600;">CLOUD_CODE_URL · Relay Identity Challenge</span>
2047
2515
  </div>
2048
2516
  <div class="doc-prose">
2049
2517
  <p>
@@ -2071,9 +2539,9 @@ agy</pre>
2071
2539
  <table class="doc-table">
2072
2540
  <thead>
2073
2541
  <tr>
2074
- <th>Loại Cuộc Gọi</th>
2075
- <th>Đích Đến Xử Lý</th>
2076
- <th>Ghi Chú Xác Thực</th>
2542
+ <th style="width:30%;">Loại Cuộc Gọi</th>
2543
+ <th style="width:40%;">Đích Đến Xử Lý</th>
2544
+ <th>Ghi Chú Xác Thực & Bảo Mật</th>
2077
2545
  </tr>
2078
2546
  </thead>
2079
2547
  <tbody>
@@ -2084,7 +2552,7 @@ agy</pre>
2084
2552
  </tr>
2085
2553
  <tr>
2086
2554
  <td>Checkpoint summary, model list, quota, đăng nhập</td>
2087
- <td>Google Code Assist chính thức</td>
2555
+ <td>Google Code Assist chính thức (<code>daily-cloudcode-pa.googleapis.com</code>)</td>
2088
2556
  <td>Giữ nguyên vẹn token và headers Google của bạn</td>
2089
2557
  </tr>
2090
2558
  <tr>
@@ -2095,20 +2563,27 @@ agy</pre>
2095
2563
  </tbody>
2096
2564
  </table>
2097
2565
 
2566
+ <h3>Cấu Hình Model Trong Slot <code>main</code> Của agy</h3>
2567
+ <ul>
2568
+ <li><code>*</code>: Tự động chuyển tiếp đúng model mà agy lựa chọn trong giao diện dòng lệnh.</li>
2569
+ <li><code>antigravity/*</code>: Ví dụ <code>antigravity/gemini-3.8-flash-high</code>. intact nhận diện agy là client chính thức của pool Antigravity và cho phép đi xuyên qua <strong>Bifrost</strong> không cần chuyển đổi.</li>
2570
+ <li>Model chỉ định khác (ví dụ: <code>claude/claude-opus-5</code>): Gateway chuyển đổi request Code Assist sang định dạng tương ứng và chuyển câu trả lời về lại định dạng Code Assist.</li>
2571
+ </ul>
2572
+
2098
2573
  <div class="doc-callout info">
2099
- <strong>Bảo vệ Token bằng Relay (<code>agy-relay.mjs</code>):</strong> Do agy gửi token xác thực dạng cleartext tới <code>CLOUD_CODE_URL</code>, shim của Switcher khởi chạy agy đằng sau một relay loopback chuyên dụng. Relay này bắt buộc Gateway phải cung cấp bằng chứng mã hóa dựa trên <code>gateway.secret</code> trước khi chuyển token. Nếu gateway chưa chứng minh được danh tính, agy sẽ nhận mã lỗi 502 và token không bao giờ bị phát tán.
2574
+ <strong>Bảo vệ Token bằng Relay (<code>agy-relay.mjs</code>):</strong> Do agy gửi token xác thực dạng cleartext tới <code>CLOUD_CODE_URL</code>, shim của Switcher khởi chạy agy đằng sau một relay loopback chuyên dụng. Relay này bắt buộc Gateway phải cung cấp bằng chứng mã hóa dựa trên <code>gateway.secret</code> trước khi chuyển token. Nếu gateway chưa chứng minh được danh tính trong 3 giây, agy sẽ fallback về Google endpoint chính thức và token không bao giờ bị phát tán sang tiến trình lạ.
2100
2575
  </div>
2101
2576
  </div>
2102
2577
  </section>
2103
2578
 
2104
- <!-- 6. TOKEN OPTIMIZERS & HEALER ENGINE -->
2579
+ <!-- 7. TOKEN OPTIMIZERS & HEALER ENGINE -->
2105
2580
  <section class="doc-section" id="doc-optimizers">
2106
2581
  <div class="doc-section-h">
2107
2582
  <h2>
2108
2583
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="m12 14 4-4"/><path d="M3.34 19a10 10 0 1 1 17.32 0"/></svg>
2109
- 6. Tối Ưu Token & Healer Engine
2584
+ 7. Tối Ưu Token & Healer Engine
2110
2585
  </h2>
2111
- <span class="badge" style="background:var(--ok-soft); color:var(--ok); font-weight:600;">Headroom · RTK · Ponytail</span>
2586
+ <span class="badge" style="background:var(--ok-soft); color:var(--ok); font-weight:600;">Headroom · RTK · Ponytail Interoperability</span>
2112
2587
  </div>
2113
2588
  <div class="doc-prose">
2114
2589
  <p>
@@ -2118,25 +2593,27 @@ agy</pre>
2118
2593
  <li><strong>Orphaned <code>tool_result</code>:</strong> Optimizer xóa mất lượt <code>assistant</code> chứa <code>tool_use</code> nhưng lại giữ lại lượt <code>user</code> chứa <code>tool_result</code> $\implies$ Anthropic lập tức văng lỗi <code>HTTP 400 (tool_use_id does not correspond to any tool_use)</code>.</li>
2119
2594
  <li><strong>Consecutive <code>user</code> turns:</strong> Xóa các lượt trung gian khiến 2 lượt <code>user</code> đứng liền nhau $\implies$ Vi phạm quy tắc luân phiên role của Anthropic gây crash <code>HTTP 400</code>.</li>
2120
2595
  <li><strong>Reasoning Suppression:</strong> Tự ý gọt bỏ tham số <code>thinking</code> hoặc budget để tiết kiệm token $\implies$ Khiến các model tư duy sâu (Opus, Gemini Flash) trở nên nông cạn, trả lời ngắn cũn và lỗi code.</li>
2596
+ <li><strong>Broken Schemas:</strong> Cắt cụt JSON hoặc trả schema rỗng <code>{}</code> làm Gemini/Vertex từ chối xử lý.</li>
2121
2597
  </ul>
2122
2598
 
2123
2599
  <h3>Mô Hình Phân Tầng Bắt Buộc</h3>
2124
2600
  <div class="doc-codebox">
2125
2601
  <div class="doc-codebox-bar"><span>Kiến trúc tầng bảo vệ</span></div>
2126
2602
  <pre>[CLI Agent] ──> [Optimizer Proxy: Headroom / RTK] ──> [LLM Switcher :3456] ──> [Internet / Upstream]
2127
- │
2128
- ├── 1. Tự chữa lành tool_result mồ côi thành text
2129
- ├── 2. Tự gộp các lượt cùng role liên tiếp
2130
- ├── 3. Tự phục hồi tham số suy luận thinking
2131
- └── 4. Giữ nguyên 100% tracing headers (x-rtk-*)</pre>
2603
+ │
2604
+ ├── 1. Tự chữa lành tool_result mồ côi thành text
2605
+ ├── 2. Tự gộp các lượt cùng role liên tiếp
2606
+ ├── 3. Tự phục hồi tham số suy luận thinking
2607
+ ├── 4. Sửa schema rỗng {} cho Gemini/Vertex
2608
+ └── 5. Giữ nguyên 100% tracing headers (x-rtk-*)</pre>
2132
2609
  </div>
2133
2610
 
2134
2611
  <h3>Ma Trận Bảo Vệ Của Healer Engine</h3>
2135
2612
  <table class="doc-table">
2136
2613
  <thead>
2137
2614
  <tr>
2138
- <th>Tình Huống Lỗi Do Optimizer Gây Ra</th>
2139
- <th>Gọi Trực Tiếp Upstream</th>
2615
+ <th style="width:32%;">Tình Huống Lỗi Do Optimizer Gây Ra</th>
2616
+ <th style="width:30%;">Gọi Trực Tiếp Upstream</th>
2140
2617
  <th>Đi Qua LLM Switcher (Healer Engine)</th>
2141
2618
  </tr>
2142
2619
  </thead>
@@ -2161,12 +2638,22 @@ agy</pre>
2161
2638
  <td>❌ <strong>HTTP 400 Schema Error</strong></td>
2162
2639
  <td>✅ <strong>HTTP 200 OK:</strong> Tự bổ sung type string tương thích</td>
2163
2640
  </tr>
2641
+ <tr>
2642
+ <td>Lượt <code>tool</code> mồ côi trong Chat API</td>
2643
+ <td>❌ <strong>HTTP 400 Crash</strong></td>
2644
+ <td>✅ <strong>HTTP 200 OK:</strong> Chuyển role tool thành ngữ cảnh user an toàn</td>
2645
+ </tr>
2646
+ <tr>
2647
+ <td>Headers tracing (<code>x-rtk-*</code>, <code>traceparent</code>)</td>
2648
+ <td>⚠️ Cảnh báo dropped header</td>
2649
+ <td>✅ <strong>HTTP 200 OK:</strong> Passthrough nguyên vẹn 100%</td>
2650
+ </tr>
2164
2651
  </tbody>
2165
2652
  </table>
2166
2653
 
2167
2654
  <h3>Cấu Hình Chuỗi Cho Các Optimizer</h3>
2168
2655
  <p>
2169
- <strong>Headroom (headroom.yaml hoặc biến môi trường):</strong>
2656
+ <strong>Headroom (trong headroom.yaml hoặc biến môi trường):</strong>
2170
2657
  </p>
2171
2658
  <div class="doc-codebox">
2172
2659
  <div class="doc-codebox-bar"><span>headroom config</span></div>
@@ -2183,14 +2670,14 @@ OPENAI_BASE_URL="http://127.0.0.1:3456/v1"</pre>
2183
2670
  </div>
2184
2671
  </section>
2185
2672
 
2186
- <!-- 7. AGENT SKILL & MCP SERVER -->
2673
+ <!-- 8. AGENT SKILL & MCP SERVER -->
2187
2674
  <section class="doc-section" id="doc-agent-mcp">
2188
2675
  <div class="doc-section-h">
2189
2676
  <h2>
2190
2677
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2a10 10 0 1 0 10 10H12V2z"/><path d="M12 12 2.1 10.5"/></svg>
2191
- 7. Tích Hợp Agent Skill & MCP Server
2678
+ 8. Tích Hợp Agent Skill & MCP Server
2192
2679
  </h2>
2193
- <span class="badge" style="background:var(--accent-soft); color:var(--accent); font-weight:600;">Control-Plane Assets</span>
2680
+ <span class="badge" style="background:var(--accent-soft); color:var(--accent); font-weight:600;">Control-Plane Security & Automation</span>
2194
2681
  </div>
2195
2682
  <div class="doc-prose">
2196
2683
  <p>
@@ -2204,7 +2691,7 @@ OPENAI_BASE_URL="http://127.0.0.1:3456/v1"</pre>
2204
2691
  <ul>
2205
2692
  <li>Mọi request LLM và proxy nén token phải trỏ về <code>http://127.0.0.1:3456</code>.</li>
2206
2693
  <li>Tuyệt đối không sửa <code>~/.claude/settings.json</code> hay <code>~/.codex/config.toml</code>.</li>
2207
- <li>Không bao giờ hướng dẫn sub-agent chạy <code>source env.sh</code>.</li>
2694
+ <li>Không bao giờ hướng dẫn sub-agent chạy <code>source env.sh</code> (đã có launcher shims tự tiêm).</li>
2208
2695
  </ul>
2209
2696
  <div class="doc-codebox">
2210
2697
  <div class="doc-codebox-bar">
@@ -2239,24 +2726,47 @@ cp -r skills/llm-switcher ~/.claude/skills/</pre>
2239
2726
  </div>
2240
2727
 
2241
2728
  <h3>5 Công Cụ MCP Có Sẵn</h3>
2242
- <ul>
2243
- <li><code>switcher_status</code>: Kiểm tra trạng thái cổng Gateway và profile đang kích hoạt cho từng tool.</li>
2244
- <li><code>switcher_audit</code>: Quét toàn diện môi trường máy trạm để phát hiện các request gọi thẳng ra ngoài hoặc tool nén token cấu hình sai.</li>
2245
- <li><code>switcher_switch_profile</code>: Đổi profile linh hoạt theo từng CLI (<code>claude</code>, <code>codex</code>, <code>agy</code>).</li>
2246
- <li><code>switcher_recent_logs</code>: Xem ring buffer các request gần nhất, độ trễ, số token và kết quả bóc tách reasoning block.</li>
2247
- <li><code>switcher_models</code>: Lấy danh mục mô hình mới nhất từ Claude Code và Codex, hỗ trợ đồng bộ động từ upstream.</li>
2248
- </ul>
2729
+ <table class="doc-table">
2730
+ <thead>
2731
+ <tr>
2732
+ <th style="width:30%;">Tên MCP Tool</th>
2733
+ <th>Mô tả chức năng chi tiết</th>
2734
+ </tr>
2735
+ </thead>
2736
+ <tbody>
2737
+ <tr>
2738
+ <td><code>switcher_status</code></td>
2739
+ <td>Kiểm tra trạng thái cổng Gateway, port Blindfold và profile đang kích hoạt cho từng tool.</td>
2740
+ </tr>
2741
+ <tr>
2742
+ <td><code>switcher_audit</code></td>
2743
+ <td>Quét toàn diện môi trường máy trạm để phát hiện các request gọi thẳng ra ngoài hoặc tool nén token cấu hình sai.</td>
2744
+ </tr>
2745
+ <tr>
2746
+ <td><code>switcher_switch_profile</code></td>
2747
+ <td>Đổi profile linh hoạt theo từng CLI (<code>claude</code>, <code>codex</code>, <code>agy</code>) ngay trong phiên làm việc.</td>
2748
+ </tr>
2749
+ <tr>
2750
+ <td><code>switcher_recent_logs</code></td>
2751
+ <td>Xem danh sách request gần nhất, độ trễ, số token và reasoning block (lưu ý: trả về tối đa 150 ký tự đầu của prompt).</td>
2752
+ </tr>
2753
+ <tr>
2754
+ <td><code>switcher_models</code></td>
2755
+ <td>Lấy danh mục mô hình mới nhất từ Claude Code và Codex, hỗ trợ đồng bộ động từ upstream.</td>
2756
+ </tr>
2757
+ </tbody>
2758
+ </table>
2249
2759
  </div>
2250
2760
  </section>
2251
2761
 
2252
- <!-- 8. ADVANCED FEATURES: COMPACTION & GOAL CHECK -->
2762
+ <!-- 9. ADVANCED FEATURES: COMPACTION & GOAL CHECK -->
2253
2763
  <section class="doc-section" id="doc-advanced">
2254
2764
  <div class="doc-section-h">
2255
2765
  <h2>
2256
2766
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>
2257
- 8. Tính Năng Nâng Cao: Compaction & Goal Check
2767
+ 9. Tính Năng Nâng Cao: Compaction, Goal Check & Contract Lab
2258
2768
  </h2>
2259
- <span class="badge" style="background:var(--card2); color:var(--muted);">Pro Features</span>
2769
+ <span class="badge" style="background:var(--card2); color:var(--muted);">Pro Features · Cache & Quality Gate</span>
2260
2770
  </div>
2261
2771
  <div class="doc-prose">
2262
2772
  <h3>A. Idle Compaction (Nén Prefix Khi Nhàn Rỗi)</h3>
@@ -2269,10 +2779,16 @@ cp -r skills/llm-switcher ~/.claude/skills/</pre>
2269
2779
  <div class="doc-codebox">
2270
2780
  <div class="doc-codebox-bar"><span>Terminal · Quản trị Compaction</span></div>
2271
2781
  <pre>switch compact on # Kích hoạt nén cho Claude Code
2272
- switch compact codex on # Kích hoạt nén cho Codex
2782
+ switch compact codex on # Kích hoạt nén cho Codex Responses
2273
2783
  switch compact idle 20 # Đặt ngưỡng nhàn rỗi là 20 phút (1-1440)
2784
+ switch compact min 128 # Ngưỡng kích thước tối thiểu 128 KB
2785
+ switch compact model &lt;model-id&gt; # Chỉ định model tóm tắt chạy ngầm
2786
+ switch compact model none # Tắt tóm tắt model, dùng cắt tỉa tất định
2274
2787
  switch compact status # Kiểm tra cấu hình hiện tại</pre>
2275
2788
  </div>
2789
+ <p>
2790
+ <em>Cắt tỉa tất định (Deterministic Mode):</em> Khi không đặt summary model, hệ thống giữ lại text đầu và gần nhất trong ngân sách (<code>userChars: 3000</code>), loại bỏ payload tool cũ nhưng bảo toàn nguyên vẹn các cặp tool call/result mới nhất (<code>keepRecent: 6</code>) mà không tốn bất kỳ token nào để gọi AI tóm tắt.
2791
+ </p>
2276
2792
 
2277
2793
  <h3>B. Goal Check: Cơ Chế Veto Độc Lập Bằng Jev System One</h3>
2278
2794
  <p>
@@ -2289,21 +2805,35 @@ switch compact status # Kiểm tra cấu hình hiện tại</pre>
2289
2805
  <div class="doc-callout success">
2290
2806
  <strong>Nguyên tắc Fail-Closed:</strong> Gateway chỉ trả về <code>ok: true</code> khi cả evaluator gốc lẫn Jev đồng thuận. Bất kỳ lỗi mạng, timeout hoặc thiếu evidence đều bị Veto (<code>ok: false</code>) để bảo vệ chất lượng công việc. Cấu hình tại tab <strong>Goal Check</strong> trên thanh điều hướng.
2291
2807
  </div>
2808
+
2809
+ <h3>C. Contract Lab: Tự Hoàn Thiện & Chống Rơi Rớt Dữ Liệu Với Intact</h3>
2810
+ <p>
2811
+ Bộ đôi <strong>LLM Switcher</strong> và <strong>intact</strong> vận hành 2 vòng lặp tự sửa lỗi khép kín:
2812
+ </p>
2813
+ <ul>
2814
+ <li><strong>intact sửa lỗi nhà cung cấp từ chối:</strong> Thu thập lỗi 429 giả mạo, replay và bóc tách câu lệnh cấm (như fingerprint Codex/Claude) thành bộ lọc tự động phân phối cho mọi máy trạm.</li>
2815
+ <li><strong>Switcher sửa lỗi rơi rớt field qua chuyển đổi:</strong> Khi bật Contract Lab, Gateway gửi mẫu exchange được che giấu dữ liệu (masking: mọi text nhạy cảm đều biến thành chuỗi ký tự <code>x</code> cùng độ dài, chỉ giữ lại cấu trúc và enum) lên intact. intact so sánh và phát hiện field bị rơi rụng.</li>
2816
+ </ul>
2817
+ <div class="doc-codebox">
2818
+ <div class="doc-codebox-bar"><span>Terminal · Lệnh Contract Lab</span></div>
2819
+ <pre>switch contract-probe # Gửi 6 test probe qua gateway lên intact
2820
+ switch contract-check # Lấy các trường bị mất và tạo file unit test tự động</pre>
2821
+ </div>
2292
2822
  </div>
2293
2823
  </section>
2294
2824
 
2295
- <!-- 9. CONFIG.JSON REFERENCE -->
2825
+ <!-- 10. CONFIG.JSON REFERENCE -->
2296
2826
  <section class="doc-section" id="doc-config">
2297
2827
  <div class="doc-section-h">
2298
2828
  <h2>
2299
2829
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>
2300
- 9. Bảng Cấu Trúc Cấu Hình (config.json)
2830
+ 10. Cấu Trúc Cấu Hình (config.json) & Biến Môi Trường
2301
2831
  </h2>
2302
- <span class="badge" style="background:var(--code); color:#042f2e; font-weight:600;">JSON Schema</span>
2832
+ <span class="badge" style="background:var(--code); color:#042f2e; font-weight:600;">JSON Schema & Environment Reference</span>
2303
2833
  </div>
2304
2834
  <div class="doc-prose">
2305
2835
  <p>
2306
- File <code>config.json</code> nằm trong thư mục dữ liệu (<code>~/.llm-switcher/config.json</code> cho npm, hoặc thư mục gốc repo cho git clone):
2836
+ File <code>config.json</code> nằm trong thư mục dữ liệu (<code>~/.llm-switcher/config.json</code> cho npm, hoặc thư mục gốc repo cho git clone). Dưới đây là schema mẫu đầy đủ tất cả các trường:
2307
2837
  </p>
2308
2838
  <div class="doc-codebox">
2309
2839
  <div class="doc-codebox-bar">
@@ -2327,11 +2857,12 @@ switch compact status # Kiểm tra cấu hình hiện tại</pre>
2327
2857
  "baseURL": "https://intact.example.com/v1",
2328
2858
  "apiKey": "sk-...",
2329
2859
  "thinkingMode": "auto", // auto | native | off
2330
- "thinkingEffort": "auto", // auto | none | low | medium | high | max
2860
+ "thinkingEffort": "auto", // auto | none | low | medium | high | max | ultra
2331
2861
  "defaultModels": {
2332
2862
  "opus": "ag/claude-opus-4-6-thinking",
2333
2863
  "sonnet": "ag/gemini-3.7-flash",
2334
- "haiku": "ag/gemini-3.6-flash-medium"
2864
+ "haiku": "ag/gemini-3.6-flash-medium",
2865
+ "fable": "ag/gemini-3.8-flash"
2335
2866
  }
2336
2867
  },
2337
2868
  "intact-codex": {
@@ -2341,7 +2872,8 @@ switch compact status # Kiểm tra cấu hình hiện tại</pre>
2341
2872
  "outFormat": "openai-chat",
2342
2873
  "baseURL": "https://intact.example.com/v1",
2343
2874
  "apiKey": "sk-...",
2344
- "publicModels": ["gpt-5.6-sol", "gpt-5.6-terra"],
2875
+ "publicModels": ["gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna"],
2876
+ "codexRoles": { "review": "gpt-5.6-sol" },
2345
2877
  "defaultModels": {
2346
2878
  "main": "gemini-3.8-flash",
2347
2879
  "review": "gemini-3.7-flash-medium",
@@ -2358,25 +2890,108 @@ switch compact status # Kiểm tra cấu hình hiện tại</pre>
2358
2890
  "defaultModels": { "main": "antigravity/*" } // * giữ nguyên model của agy (Bifrost)
2359
2891
  }
2360
2892
  },
2361
- "debug": false
2893
+ "debug": false,
2894
+ "idleCompact": {
2895
+ "enabled": false,
2896
+ "codex": false,
2897
+ "idleMinutes": 15,
2898
+ "minBytes": 65536,
2899
+ "model": ""
2900
+ },
2901
+ "goalCheck": {
2902
+ "enabled": false,
2903
+ "backend": "jev",
2904
+ "baseURL": "https://intact.example.com/v1",
2905
+ "apiKey": "sk-...",
2906
+ "model": "typesafe/jev-latest"
2907
+ },
2908
+ "contractLab": {
2909
+ "url": "https://intact.example.com",
2910
+ "apiKey": "sk-...",
2911
+ "enabled": false
2912
+ }
2362
2913
  }</pre>
2363
2914
  </div>
2915
+
2916
+ <h3>Giải Thích Các Tham Số Cấu Hình Quan Trọng</h3>
2917
+ <ul>
2918
+ <li><code>thinkingMode</code>:
2919
+ <ul>
2920
+ <li><code>auto</code> (mặc định cho intact, 9Router): Phục hồi thinking bị cắt, tự thêm chỉ dẫn &lt;think&gt; cho model thường, gửi cả <code>thinking</code> + <code>reasoning_effort</code>.</li>
2921
+ <li><code>native</code> (OpenAI chuẩn): Chỉ gửi <code>reasoning_effort</code> khi client yêu cầu, không sửa prompt, dùng <code>max_completion_tokens</code>.</li>
2922
+ <li><code>off</code>: Tắt hoàn toàn suy luận, không gửi tham số reasoning nào.</li>
2923
+ </ul>
2924
+ </li>
2925
+ <li><code>thinkingEffort</code>: <code>auto</code> (client tự chọn) hoặc ghi đè cứng: <code>none</code>, <code>minimal</code>, <code>low</code>, <code>medium</code>, <code>high</code>, <code>xhigh</code>, <code>max</code>, <code>ultra</code>. Tự động quy đổi sang ngưỡng cao nhất mà provider đích hỗ trợ.</li>
2926
+ </ul>
2927
+
2928
+ <h3>Bảng Tra Cứu Biến Môi Trường (Environment Variables)</h3>
2929
+ <table class="doc-table">
2930
+ <thead>
2931
+ <tr>
2932
+ <th style="width:34%;">Biến Môi Trường</th>
2933
+ <th>Mô tả tác dụng chi tiết</th>
2934
+ </tr>
2935
+ </thead>
2936
+ <tbody>
2937
+ <tr>
2938
+ <td><code>LLM_SWITCHER_HOME</code></td>
2939
+ <td>Đường dẫn thư mục lưu trữ dữ liệu (config, token, shims, logs).</td>
2940
+ </tr>
2941
+ <tr>
2942
+ <td><code>LLM_SWITCHER_CONFIG</code></td>
2943
+ <td>Chỉ định vị trí file <code>config.json</code> bên ngoài thư mục dữ liệu mặc định.</td>
2944
+ </tr>
2945
+ <tr>
2946
+ <td><code>LLM_SWITCHER_PORT</code></td>
2947
+ <td>Ghi đè cổng lắng nghe của Edge Gateway (ưu tiên: cờ <code>--port</code> &gt; env &gt; <code>config.port</code>).</td>
2948
+ </tr>
2949
+ <tr>
2950
+ <td><code>LLM_SWITCHER_BLINDFOLD_PORT</code></td>
2951
+ <td>Ghi đè cổng lắng nghe của Blindfold TLS Interceptor (mặc định: 3457).</td>
2952
+ </tr>
2953
+ <tr>
2954
+ <td><code>LLM_SWITCHER_STATE_DIR</code></td>
2955
+ <td>Tách riêng thư mục runtime launch flags và logs ra khỏi data directory.</td>
2956
+ </tr>
2957
+ <tr>
2958
+ <td><code>LLM_SWITCHER_BLINDFOLD_CERTS</code></td>
2959
+ <td>Đường dẫn tới thư mục chứa chứng chỉ CA (mặc định: <code>blindfold/certs/</code>).</td>
2960
+ </tr>
2961
+ <tr>
2962
+ <td><code>LLM_SWITCHER_CODE_ASSIST_URL</code></td>
2963
+ <td>Địa chỉ máy chủ Google Code Assist nhận cuộc gọi phụ của agy (mặc định: <code>https://daily-cloudcode-pa.googleapis.com</code>).</td>
2964
+ </tr>
2965
+ <tr>
2966
+ <td><code>LLM_SWITCHER_CODE_ASSIST_TIMEOUT_MS</code></td>
2967
+ <td>Thời gian chờ cho các cuộc gọi phụ của agy (mặc định: 300,000 ms = 5 phút).</td>
2968
+ </tr>
2969
+ <tr>
2970
+ <td><code>LLM_SWITCHER_BIFROST_RETRY_MS</code></td>
2971
+ <td>Thời gian chờ trước khi hỏi lại intact sau khi tra cứu Bifrost thất bại (mặc định: 30,000 ms).</td>
2972
+ </tr>
2973
+ <tr>
2974
+ <td><code>CLAUDE_CONFIG_DIR</code></td>
2975
+ <td>Thư mục cấu hình của Claude Code khi tìm <code>settings.json</code> để kiểm tra cảnh báo.</td>
2976
+ </tr>
2977
+ </tbody>
2978
+ </table>
2364
2979
  </div>
2365
2980
  </section>
2366
2981
 
2367
- <!-- 10. TROUBLESHOOTING & FAQ -->
2982
+ <!-- 11. TROUBLESHOOTING & FAQ -->
2368
2983
  <section class="doc-section" id="doc-faq">
2369
2984
  <div class="doc-section-h">
2370
2985
  <h2>
2371
2986
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
2372
- 10. Xử Lý Sự Cố & Câu Hỏi Thường Gặp (FAQ)
2987
+ 11. Xử Lý Sự Cố & Câu Hỏi Thường Gặp (FAQ)
2373
2988
  </h2>
2374
- <span class="badge" style="background:var(--warn-soft); color:var(--warn); font-weight:600;">Troubleshooting</span>
2989
+ <span class="badge" style="background:var(--warn-soft); color:var(--warn); font-weight:600;">Troubleshooting Playbook</span>
2375
2990
  </div>
2376
2991
  <div class="doc-prose">
2377
2992
  <h3>Q1: Lỗi EADDRINUSE: Cổng 3456 hoặc 3457 đã bị tiến trình khác chiếm dụng?</h3>
2378
2993
  <p>
2379
- Chạy lệnh <code>switch doctor</code> để phát hiện tiến trình đang giữ cổng. Bạn có thể đổi cổng gateway sang cổng khác bất kỳ bằng lệnh: <code>switch port 8080</code> (gateway sẽ tự động cập nhật và khởi động lại).
2994
+ Chạy lệnh <code>switch doctor</code> để phát hiện tiến trình đang giữ cổng. Bạn có thể đổi cổng gateway sang cổng khác bất kỳ bằng lệnh: <code>switch port 8080</code> (gateway sẽ tự động cập nhật và khởi động lại). Nếu cổng Blindfold bị chiếm, đổi <code>blindfold.port</code> trong <code>config.json</code>.
2380
2995
  </p>
2381
2996
 
2382
2997
  <h3>Q2: Claude Code hiển thị banner "Custom API endpoint configured"?</h3>
@@ -2386,7 +3001,7 @@ switch compact status # Kiểm tra cấu hình hiện tại</pre>
2386
3001
 
2387
3002
  <h3>Q3: Lệnh <code>claude --resume</code> trong cửa sổ terminal mới không đi qua Gateway?</h3>
2388
3003
  <p>
2389
- Điều này xảy ra khi thư mục shims <code>~/.llm-switcher/bin</code> chưa được đặt lên đầu biến <code>PATH</code> của bạn. Hãy đảm bảo dòng <code>export PATH="$HOME/.llm-switcher/bin:$PATH"</code> có mặt trong <code>~/.bashrc</code> hoặc <code>~/.zshrc</code> và mở một terminal mới.
3004
+ Điều này xảy ra khi thư mục shims <code>~/.llm-switcher/bin</code> chưa được đặt lên đầu biến <code>PATH</code> của bạn. Hãy kiểm tra bằng lệnh <code>switch shim status</code> và đảm bảo dòng <code>export PATH="$HOME/.llm-switcher/bin:$PATH"</code> có mặt trong <code>~/.bashrc</code> hoặc <code>~/.zshrc</code> và mở một terminal mới.
2390
3005
  </p>
2391
3006
 
2392
3007
  <h3>Q4: Claude Code Remote Control (<code>claude rc</code>) có dùng được với Switcher không?</h3>
@@ -2405,6 +3020,26 @@ switch compact status # Kiểm tra cấu hình hiện tại</pre>
2405
3020
  <p>
2406
3021
  LLM Switcher tự động tạo chứng chỉ bằng Node.js crypto khi bạn kích hoạt tool. Nếu muốn tạo thủ công bằng OpenSSL, hãy chạy lệnh <code>bash blindfold/make-certs.sh</code> trong <strong>Git Bash</strong> (không chạy trong PowerShell vì lệnh <code>New-SelfSignedCertificate</code> thiếu thuộc tính <code>serverAuth</code>).
2407
3022
  </p>
3023
+
3024
+ <h3>Q6: Antigravity CLI báo lỗi 502 Bad Gateway khi gọi qua relay?</h3>
3025
+ <p>
3026
+ Điều này xảy ra khi Gateway chưa khởi động hoặc phiên bản Gateway cũ hơn relay dẫn đến không vượt qua thử thách <code>gateway.secret</code>. Hãy chạy <code>switch off</code> rồi <code>switch on</code> để khởi động lại Gateway đồng bộ.
3027
+ </p>
3028
+
3029
+ <h3>Q7: Màn hình <code>/model</code> của Codex không hiển thị đúng model mong muốn?</h3>
3030
+ <p>
3031
+ Đảm bảo profile phục vụ Codex có trường <code>publicModels</code> khai báo danh sách tên model chính thức (ví dụ <code>["gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna"]</code>) tương ứng với các slot <code>main</code>, <code>review</code>, <code>subagent</code> trong <code>defaultModels</code>.
3032
+ </p>
3033
+
3034
+ <h3>Q8: Làm thế nào để gỡ cài đặt sạch sẽ hoặc khôi phục hoàn toàn về mặc định?</h3>
3035
+ <div class="doc-codebox">
3036
+ <div class="doc-codebox-bar"><span>Terminal · Clean Uninstall</span></div>
3037
+ <pre>switch off # Khôi phục endpoint chính hãng
3038
+ switch shim uninstall # Gỡ bỏ launcher shims
3039
+ switch service uninstall # Gỡ bỏ OS background service
3040
+ switch plugin uninstall # Gỡ bỏ các plugin hook thông báo
3041
+ npm uninstall -g llm-switcher # Gỡ bỏ package npm (nếu cài qua npm)</pre>
3042
+ </div>
2408
3043
  </div>
2409
3044
  </section>
2410
3045
  </div>
@@ -2749,7 +3384,7 @@ switch compact status # Kiểm tra cấu hình hiện tại</pre>
2749
3384
  function handleRoute() {
2750
3385
  const hash = window.location.hash || '#/routes';
2751
3386
  const route = hash.replace(/^#\/?/, '').split('/')[0] || 'routes';
2752
- const validRoutes = ['routes', 'compact', 'goal-check', 'models', 'logs', 'doctor', 'docs'];
3387
+ const validRoutes = ['routes', 'logs', 'models', 'doctor', 'goal-check', 'compact', 'docs'];
2753
3388
  const activeRoute = validRoutes.includes(route) ? route : 'routes';
2754
3389
 
2755
3390
  // Update active nav link