llm-switcher 1.1.2 → 1.1.3

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/README.md CHANGED
@@ -191,7 +191,12 @@ flowchart LR
191
191
 
192
192
  ---
193
193
 
194
- ## Changes in 1.1.2
194
+ ## Changes in 1.1.3
195
+
196
+ - **Dashboard.** Opened without its access token, the page no longer waits on "Checking status...". It says that it is locked and names `switch ui`, which opens it with the token.
197
+ - **Dashboard.** The Codex model names (session, review, subagent) are on the **Models** tab, next to the other model settings. The **Blindfold** tab holds only the interceptor settings.
198
+
199
+ ### Changes in 1.1.2
195
200
 
196
201
  - **npm package.** Install with `npm install -g llm-switcher` and run `switch`. An npm install keeps its data in `~/.llm-switcher`, so an upgrade does not erase your configuration. A git checkout keeps its data next to the code, as before.
197
202
  - **Contract lab.** The gateway can send a small sample of complete exchanges to an [intact](https://github.com/louisphamdev/intact) server, which finds fields that the converter loses. It is off by default. See "Contract lab" below.
package/README.vi.md CHANGED
@@ -191,7 +191,12 @@ flowchart LR
191
191
 
192
192
  ---
193
193
 
194
- ## Thay đổi trong bản 1.1.2
194
+ ## Thay đổi trong bản 1.1.3
195
+
196
+ - **Dashboard.** Khi mở mà thiếu access token, trang không còn đứng ở "Checking status...". Trang báo đang bị khoá và chỉ lệnh `switch ui`, lệnh này mở trang kèm token.
197
+ - **Dashboard.** Tên model của Codex (session, review, subagent) nằm ở tab **Models**, cạnh các cấu hình model khác. Tab **Blindfold** chỉ còn cấu hình interceptor.
198
+
199
+ ### Thay đổi trong bản 1.1.2
195
200
 
196
201
  - **Gói npm.** Cài bằng `npm install -g llm-switcher` rồi chạy `switch`. Bản cài bằng npm lưu dữ liệu trong `~/.llm-switcher`, nên nâng cấp không xoá cấu hình. Bản git checkout vẫn lưu dữ liệu cạnh mã nguồn như trước.
197
202
  - **Contract lab.** Gateway có thể gửi một phần nhỏ các lượt trao đổi hoàn chỉnh lên server [intact](https://github.com/louisphamdev/intact) để tìm field mà converter làm mất. Mặc định tính năng này tắt. Xem mục "Contract lab" bên dưới.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "llm-switcher",
3
- "version": "1.1.2",
3
+ "version": "1.1.3",
4
4
  "description": "Zero-dependency multi-protocol edge gateway & provider switcher for Claude Code, Codex, OpenAI and Gemini clients",
5
5
  "keywords": [
6
6
  "llm",
package/ui.html CHANGED
@@ -940,7 +940,7 @@
940
940
  <button id="tab-button-general" type="button" class="tab-btn active" role="tab" aria-selected="true" aria-controls="tab-general" tabindex="0" onclick="switchTab('tab-general')">General</button>
941
941
  <button id="tab-button-routing" type="button" class="tab-btn" role="tab" aria-selected="false" aria-controls="tab-routing" tabindex="-1" onclick="switchTab('tab-routing')">Routing</button>
942
942
  <button id="tab-button-models" type="button" class="tab-btn" role="tab" aria-selected="false" aria-controls="tab-models" tabindex="-1" onclick="switchTab('tab-models')">Models</button>
943
- <button id="tab-button-codex" type="button" class="tab-btn" role="tab" aria-selected="false" aria-controls="tab-codex" tabindex="-1" onclick="switchTab('tab-codex')" hidden>Codex</button>
943
+ <button id="tab-button-codex" type="button" class="tab-btn" role="tab" aria-selected="false" aria-controls="tab-codex" tabindex="-1" onclick="switchTab('tab-codex')" hidden>Blindfold</button>
944
944
  <button id="tab-button-inspector" type="button" class="tab-btn" role="tab" aria-selected="false" aria-controls="tab-inspector" tabindex="-1" onclick="switchTab('tab-inspector'); loadInspectorLogs();">Request log</button>
945
945
  </div>
946
946
 
@@ -1037,23 +1037,10 @@
1037
1037
  <!-- Dynamically populated via renderModelSlots -->
1038
1038
  </div>
1039
1039
 
1040
- <!-- Model Explorer Box -->
1041
- <div class="form-group full" id="model-browser" style="display: none; margin-top: 14px;">
1042
- <div class="model-browser">
1043
- <div class="model-browser-header">
1044
- <span id="model-count-label" style="font-size: 11px; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em;">Available Upstream Models</span>
1045
- <label class="sr-only" for="model-filter">Filter upstream models</label>
1046
- <input type="search" id="model-filter" placeholder="Filter models" style="padding: 5px 9px; font-size: 11px; width: 200px;" oninput="filterModels()">
1047
- </div>
1048
- <div id="model-items" class="model-list-scroll"></div>
1049
- </div>
1050
- </div>
1051
- </div>
1052
-
1053
- <!-- Tab 4: Live Inspector -->
1054
- <!-- Tab 4: Codex — only the names this CLI is allowed to observe -->
1055
- <div id="tab-codex" class="tab-pane" role="tabpanel" aria-labelledby="tab-button-codex" hidden>
1056
- <div class="warning-callout">
1040
+ <!-- Codex model config lives with the other model config; only the interceptor stays on its own tab. -->
1041
+ <div id="codex-names" style="margin-top: 16px;" hidden>
1042
+ <span style="font-size: 12px; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em;">Names Codex sees</span>
1043
+ <div class="warning-callout">
1057
1044
  <span class="badge badge-convert">NOTE</span>
1058
1045
  <div>
1059
1046
  <strong>Codex sees only these names.</strong> The slot aliases <code>main</code>, <code>review</code> and
@@ -1076,7 +1063,24 @@
1076
1063
  <input type="text" id="p-public-subagent" list="model-options" placeholder="e.g. gpt-5.6-luna">
1077
1064
  </div>
1078
1065
  </div>
1066
+ </div>
1079
1067
 
1068
+ <!-- Model Explorer Box -->
1069
+ <div class="form-group full" id="model-browser" style="display: none; margin-top: 14px;">
1070
+ <div class="model-browser">
1071
+ <div class="model-browser-header">
1072
+ <span id="model-count-label" style="font-size: 11px; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em;">Available Upstream Models</span>
1073
+ <label class="sr-only" for="model-filter">Filter upstream models</label>
1074
+ <input type="search" id="model-filter" placeholder="Filter models" style="padding: 5px 9px; font-size: 11px; width: 200px;" oninput="filterModels()">
1075
+ </div>
1076
+ <div id="model-items" class="model-list-scroll"></div>
1077
+ </div>
1078
+ </div>
1079
+ </div>
1080
+
1081
+ <!-- Tab 4: Live Inspector -->
1082
+ <!-- Tab 4: Codex — only the names this CLI is allowed to observe -->
1083
+ <div id="tab-codex" class="tab-pane" role="tabpanel" aria-labelledby="tab-button-codex" hidden>
1080
1084
  <div class="form-grid" style="border-top: 1px solid var(--border); padding-top: 12px; margin-top: 12px;">
1081
1085
  <div class="form-group full">
1082
1086
  <label style="display: flex; align-items: center; gap: 6px; cursor: pointer; text-transform: none;">
@@ -1382,6 +1386,8 @@
1382
1386
  const applies = servesCodex(format);
1383
1387
  const btn = document.getElementById('tab-button-codex');
1384
1388
  if (btn) btn.hidden = !applies;
1389
+ const names = document.getElementById('codex-names');
1390
+ if (names) names.hidden = !applies;
1385
1391
  if (!applies && document.getElementById('tab-codex')?.classList.contains('active')) {
1386
1392
  switchTab('tab-general');
1387
1393
  }
@@ -1468,6 +1474,11 @@
1468
1474
  try {
1469
1475
  const res = await api('/api/status');
1470
1476
  const data = await res.json();
1477
+ if (res.status === 401) {
1478
+ document.getElementById('status-title').textContent = 'Dashboard locked';
1479
+ document.getElementById('status-sub').textContent = 'Run `switch ui` in a terminal. It opens this page with its access token.';
1480
+ return;
1481
+ }
1471
1482
  if (!res.ok) {
1472
1483
  showToast(data.error || `Gateway error HTTP ${res.status}`, true);
1473
1484
  return;