VirtualKimi commited on
Commit
5f17517
·
verified ·
1 Parent(s): 4de5991

Upload 28 files

Browse files
index.html CHANGED
@@ -419,9 +419,9 @@
419
  <div class="inline-row">
420
  <button class="kimi-button" id="test-api"><i class="fas fa-wifi"></i> Test API
421
  Key</button>
422
- <span id="api-key-presence-test" class="presence-dot" aria-label="API key presence"
423
- data-i18n-title="api_key_presence_hint"
424
- title="Green = API key saved for current provider. Grey = no key saved."></span>
425
  <span id="api-status" role="status" aria-live="polite"></span>
426
  </div>
427
  </div>
@@ -791,8 +791,8 @@
791
  <i class="fas fa-coffee"></i>
792
  <span>Ko-fi</span>
793
  </a>
794
- <a href="https://www.youtube.com/@VirtualKimi" target="_blank" rel="noopener noreferrer"
795
- class="creator-link">
796
  <i class="fab fa-youtube"></i>
797
  <span>Youtube</span>
798
  </a>
 
419
  <div class="inline-row">
420
  <button class="kimi-button" id="test-api"><i class="fas fa-wifi"></i> Test API
421
  Key</button>
422
+ <span id="api-key-presence-test" class="presence-dot" aria-label="API test status"
423
+ data-i18n-title="api_key_test_hint"
424
+ title="Green = API connectivity verified. Grey = not tested or failed."></span>
425
  <span id="api-status" role="status" aria-live="polite"></span>
426
  </div>
427
  </div>
 
791
  <i class="fas fa-coffee"></i>
792
  <span>Ko-fi</span>
793
  </a>
794
+ <a href="https://www.youtube.com/@VirtualKimi" target="_blank"
795
+ rel="noopener noreferrer" class="creator-link">
796
  <i class="fab fa-youtube"></i>
797
  <span>Youtube</span>
798
  </a>
kimi-js/kimi-module.js CHANGED
@@ -898,14 +898,32 @@ async function loadSettingsData() {
898
 
899
  // Update API key input
900
  const apiKeyInput = document.getElementById("openrouter-api-key");
901
- if (apiKeyInput) apiKeyInput.value = apiKey;
 
 
 
 
 
 
 
 
 
 
 
 
902
  const providerSelect = document.getElementById("llm-provider");
903
  if (providerSelect) providerSelect.value = provider;
904
  const baseUrlInput = document.getElementById("llm-base-url");
905
  if (baseUrlInput) baseUrlInput.value = baseUrl;
906
  const modelIdInput = document.getElementById("llm-model-id");
907
- if (modelIdInput) modelIdInput.value = modelId;
908
- if (provider !== "openrouter" && apiKeyInput) apiKeyInput.value = genericKey;
 
 
 
 
 
 
909
  const apiKeyLabel = document.getElementById("api-key-label");
910
  if (apiKeyLabel) {
911
  const labelByProvider = {
 
898
 
899
  // Update API key input
900
  const apiKeyInput = document.getElementById("openrouter-api-key");
901
+ if (apiKeyInput) {
902
+ const keyPrefMap = {
903
+ openrouter: "openrouterApiKey",
904
+ openai: "apiKey_openai",
905
+ groq: "apiKey_groq",
906
+ together: "apiKey_together",
907
+ deepseek: "apiKey_deepseek",
908
+ "openai-compatible": "apiKey_custom"
909
+ };
910
+ const keyPref = keyPrefMap[provider];
911
+ const providerKey = keyPref && preferences[keyPref] ? preferences[keyPref] : genericKey;
912
+ apiKeyInput.value = providerKey || "";
913
+ }
914
  const providerSelect = document.getElementById("llm-provider");
915
  if (providerSelect) providerSelect.value = provider;
916
  const baseUrlInput = document.getElementById("llm-base-url");
917
  if (baseUrlInput) baseUrlInput.value = baseUrl;
918
  const modelIdInput = document.getElementById("llm-model-id");
919
+ if (modelIdInput) {
920
+ if (provider === "openrouter") {
921
+ modelIdInput.value = modelId;
922
+ } else {
923
+ modelIdInput.value = ""; // only placeholder for non-OpenRouter providers
924
+ }
925
+ }
926
+ // For non-OpenRouter providers we keep placeholder per provider; the value is already set above.
927
  const apiKeyLabel = document.getElementById("api-key-label");
928
  if (apiKeyLabel) {
929
  const labelByProvider = {
kimi-js/kimi-script.js CHANGED
@@ -79,10 +79,14 @@ document.addEventListener("DOMContentLoaded", async function () {
79
  savedBadge: () => document.getElementById("api-key-saved"),
80
  statusSpan: () => document.getElementById("api-status"),
81
  testBtn: () => document.getElementById("test-api"),
 
82
  setPresence(color) {
83
  const dot = this.presenceDot();
84
- const dot2 = this.presenceDotTest();
85
  if (dot) dot.style.backgroundColor = color;
 
 
 
 
86
  if (dot2) dot2.style.backgroundColor = color;
87
  },
88
  clearStatus() {
@@ -103,6 +107,8 @@ document.addEventListener("DOMContentLoaded", async function () {
103
  const currentVal = (ApiUi.apiKeyInput() || {}).value || "";
104
  const colorInit = currentVal && currentVal.length > 0 ? "#4caf50" : "#9e9e9e";
105
  ApiUi.setPresence(colorInit);
 
 
106
  }
107
 
108
  // Initialize API config UI from saved preferences
@@ -126,7 +132,14 @@ document.addEventListener("DOMContentLoaded", async function () {
126
  const modelIdInput = ApiUi.modelIdInput();
127
  const apiKeyInput = ApiUi.apiKeyInput();
128
  if (baseUrlInput) baseUrlInput.value = baseUrl || "";
129
- if (modelIdInput && modelId && !modelIdInput.value) modelIdInput.value = modelId;
 
 
 
 
 
 
 
130
  // Load the provider-specific key
131
  const keyPrefMap = {
132
  openrouter: "openrouterApiKey",
@@ -140,6 +153,7 @@ document.addEventListener("DOMContentLoaded", async function () {
140
  const storedKey = await window.kimiDB.getPreference(keyPref, "");
141
  if (apiKeyInput) apiKeyInput.value = storedKey || "";
142
  ApiUi.setPresence(storedKey ? "#4caf50" : "#9e9e9e");
 
143
  const savedBadge = ApiUi.savedBadge();
144
  if (savedBadge) savedBadge.style.display = storedKey ? "inline" : "none";
145
  ApiUi.clearStatus();
@@ -206,8 +220,10 @@ document.addEventListener("DOMContentLoaded", async function () {
206
  baseUrlInput.value = provider === "openrouter" ? "https://openrouter.ai/api/v1/chat/completions" : p.url;
207
  }
208
  if (apiKeyInput) apiKeyInput.placeholder = p.keyPh;
209
- if (modelIdInput && !modelIdInput.value) {
210
  modelIdInput.placeholder = p.model;
 
 
211
  }
212
  if (window.kimiDB) {
213
  await window.kimiDB.setPreference("llmProvider", provider);
@@ -230,6 +246,8 @@ document.addEventListener("DOMContentLoaded", async function () {
230
  if (apiKeyInput) apiKeyInput.value = storedKey || "";
231
  const color = storedKey && storedKey.length > 0 ? "#4caf50" : "#9e9e9e";
232
  ApiUi.setPresence(color);
 
 
233
  ApiUi.setTestEnabled(!!(window.KIMI_VALIDATORS && window.KIMI_VALIDATORS.validateApiKey(storedKey || "")));
234
 
235
  // Dynamic label per provider
@@ -656,11 +674,17 @@ document.addEventListener("DOMContentLoaded", async function () {
656
  }
657
 
658
  if (window.kimiDB) {
659
- if (provider === "openrouter") {
660
- await window.kimiDB.setPreference("openrouterApiKey", apiKey);
661
- } else {
662
- await window.kimiDB.setPreference("llmApiKey", apiKey);
663
- }
 
 
 
 
 
 
664
  await window.kimiDB.setPreference("llmProvider", provider);
665
  if (baseUrl) await window.kimiDB.setPreference("llmBaseUrl", baseUrl);
666
  if (modelId) await window.kimiDB.setPreference("llmModelId", modelId);
@@ -696,11 +720,12 @@ document.addEventListener("DOMContentLoaded", async function () {
696
  statusSpan.textContent = `Test response: \"${result.response.substring(0, 50)}...\"`;
697
  }, 1000);
698
  }
699
- ApiUi.setPresence("#4caf50");
 
700
  } else {
701
  statusSpan.textContent = `${result.error}`;
702
  statusSpan.style.color = "#ff6b6b";
703
-
704
  if (result.error.includes("similaires disponibles")) {
705
  setTimeout(() => {}, 1000);
706
  }
@@ -708,11 +733,13 @@ document.addEventListener("DOMContentLoaded", async function () {
708
  } else {
709
  statusSpan.textContent = "LLM manager not initialized";
710
  statusSpan.style.color = "#ff6b6b";
 
711
  }
712
  } catch (error) {
713
  console.error("Error while testing API:", error);
714
  statusSpan.textContent = `Error: ${error.message}`;
715
  statusSpan.style.color = "#ff6b6b";
 
716
 
717
  if (error.message.includes("non disponible")) {
718
  setTimeout(() => {}, 1000);
@@ -754,6 +781,8 @@ document.addEventListener("DOMContentLoaded", async function () {
754
  savedBadge.style.display = value ? "inline" : "none";
755
  }
756
  ApiUi.setPresence(value ? "#4caf50" : "#9e9e9e");
 
 
757
  ApiUi.clearStatus();
758
  } catch (e) {
759
  // Validation error from DB
@@ -763,6 +792,7 @@ document.addEventListener("DOMContentLoaded", async function () {
763
  s.style.color = "#ff6b6b";
764
  }
765
  ApiUi.setTestEnabled(false);
 
766
  }
767
  }
768
  }, window.KIMI_SECURITY_CONFIG?.DEBOUNCE_DELAY || 300);
 
79
  savedBadge: () => document.getElementById("api-key-saved"),
80
  statusSpan: () => document.getElementById("api-status"),
81
  testBtn: () => document.getElementById("test-api"),
82
+ // Saved key indicator (left dot)
83
  setPresence(color) {
84
  const dot = this.presenceDot();
 
85
  if (dot) dot.style.backgroundColor = color;
86
+ },
87
+ // Test result indicator (right dot)
88
+ setTestPresence(color) {
89
+ const dot2 = this.presenceDotTest();
90
  if (dot2) dot2.style.backgroundColor = color;
91
  },
92
  clearStatus() {
 
107
  const currentVal = (ApiUi.apiKeyInput() || {}).value || "";
108
  const colorInit = currentVal && currentVal.length > 0 ? "#4caf50" : "#9e9e9e";
109
  ApiUi.setPresence(colorInit);
110
+ // On load, test status is unknown
111
+ ApiUi.setTestPresence("#9e9e9e");
112
  }
113
 
114
  // Initialize API config UI from saved preferences
 
132
  const modelIdInput = ApiUi.modelIdInput();
133
  const apiKeyInput = ApiUi.apiKeyInput();
134
  if (baseUrlInput) baseUrlInput.value = baseUrl || "";
135
+ // Only prefill model for OpenRouter, others should show placeholder only
136
+ if (modelIdInput) {
137
+ if (provider === "openrouter") {
138
+ if (!modelIdInput.value) modelIdInput.value = modelId;
139
+ } else {
140
+ modelIdInput.value = "";
141
+ }
142
+ }
143
  // Load the provider-specific key
144
  const keyPrefMap = {
145
  openrouter: "openrouterApiKey",
 
153
  const storedKey = await window.kimiDB.getPreference(keyPref, "");
154
  if (apiKeyInput) apiKeyInput.value = storedKey || "";
155
  ApiUi.setPresence(storedKey ? "#4caf50" : "#9e9e9e");
156
+ ApiUi.setTestPresence("#9e9e9e");
157
  const savedBadge = ApiUi.savedBadge();
158
  if (savedBadge) savedBadge.style.display = storedKey ? "inline" : "none";
159
  ApiUi.clearStatus();
 
220
  baseUrlInput.value = provider === "openrouter" ? "https://openrouter.ai/api/v1/chat/completions" : p.url;
221
  }
222
  if (apiKeyInput) apiKeyInput.placeholder = p.keyPh;
223
+ if (modelIdInput) {
224
  modelIdInput.placeholder = p.model;
225
+ // Value only for OpenRouter; others cleared to encourage provider-specific model naming
226
+ modelIdInput.value = provider === "openrouter" && window.kimiLLM ? window.kimiLLM.currentModel : "";
227
  }
228
  if (window.kimiDB) {
229
  await window.kimiDB.setPreference("llmProvider", provider);
 
246
  if (apiKeyInput) apiKeyInput.value = storedKey || "";
247
  const color = storedKey && storedKey.length > 0 ? "#4caf50" : "#9e9e9e";
248
  ApiUi.setPresence(color);
249
+ // Changing provider invalidates previous test state
250
+ ApiUi.setTestPresence("#9e9e9e");
251
  ApiUi.setTestEnabled(!!(window.KIMI_VALIDATORS && window.KIMI_VALIDATORS.validateApiKey(storedKey || "")));
252
 
253
  // Dynamic label per provider
 
674
  }
675
 
676
  if (window.kimiDB) {
677
+ // Save API key under provider-specific preference key
678
+ const keyPrefMap = {
679
+ openrouter: "openrouterApiKey",
680
+ openai: "apiKey_openai",
681
+ groq: "apiKey_groq",
682
+ together: "apiKey_together",
683
+ deepseek: "apiKey_deepseek",
684
+ "openai-compatible": "apiKey_custom"
685
+ };
686
+ const keyPref = keyPrefMap[provider] || "llmApiKey";
687
+ await window.kimiDB.setPreference(keyPref, apiKey);
688
  await window.kimiDB.setPreference("llmProvider", provider);
689
  if (baseUrl) await window.kimiDB.setPreference("llmBaseUrl", baseUrl);
690
  if (modelId) await window.kimiDB.setPreference("llmModelId", modelId);
 
720
  statusSpan.textContent = `Test response: \"${result.response.substring(0, 50)}...\"`;
721
  }, 1000);
722
  }
723
+ // Mark test success explicitly
724
+ ApiUi.setTestPresence("#4caf50");
725
  } else {
726
  statusSpan.textContent = `${result.error}`;
727
  statusSpan.style.color = "#ff6b6b";
728
+ ApiUi.setTestPresence("#9e9e9e");
729
  if (result.error.includes("similaires disponibles")) {
730
  setTimeout(() => {}, 1000);
731
  }
 
733
  } else {
734
  statusSpan.textContent = "LLM manager not initialized";
735
  statusSpan.style.color = "#ff6b6b";
736
+ ApiUi.setTestPresence("#9e9e9e");
737
  }
738
  } catch (error) {
739
  console.error("Error while testing API:", error);
740
  statusSpan.textContent = `Error: ${error.message}`;
741
  statusSpan.style.color = "#ff6b6b";
742
+ ApiUi.setTestPresence("#9e9e9e");
743
 
744
  if (error.message.includes("non disponible")) {
745
  setTimeout(() => {}, 1000);
 
781
  savedBadge.style.display = value ? "inline" : "none";
782
  }
783
  ApiUi.setPresence(value ? "#4caf50" : "#9e9e9e");
784
+ // Any key change invalidates previous test state
785
+ ApiUi.setTestPresence("#9e9e9e");
786
  ApiUi.clearStatus();
787
  } catch (e) {
788
  // Validation error from DB
 
792
  s.style.color = "#ff6b6b";
793
  }
794
  ApiUi.setTestEnabled(false);
795
+ ApiUi.setTestPresence("#9e9e9e");
796
  }
797
  }
798
  }, window.KIMI_SECURITY_CONFIG?.DEBOUNCE_DELAY || 300);
kimi-locale/de.json CHANGED
@@ -194,6 +194,7 @@
194
  "api_connection_failed": "❌ API-Verbindung fehlgeschlagen",
195
  "voice_test_message": "Hallo mein Liebling! Hier ist meine neue Stimme, die mit allen Einstellungen konfiguriert ist! Gefällt sie dir?",
196
  "api_key_presence_hint": "Grün = API-Schlüssel für aktuellen Anbieter gespeichert. Grau = kein Schlüssel gespeichert.",
 
197
  "memory_system": "Gedächtnissystem",
198
  "enable_memory": "Intelligentes Gedächtnis aktivieren",
199
  "memory_stats": "Gedächtnisstatistiken",
 
194
  "api_connection_failed": "❌ API-Verbindung fehlgeschlagen",
195
  "voice_test_message": "Hallo mein Liebling! Hier ist meine neue Stimme, die mit allen Einstellungen konfiguriert ist! Gefällt sie dir?",
196
  "api_key_presence_hint": "Grün = API-Schlüssel für aktuellen Anbieter gespeichert. Grau = kein Schlüssel gespeichert.",
197
+ "api_key_test_hint": "Grün = API-Konnektivität verifiziert. Grau = nicht getestet oder fehlgeschlagen.",
198
  "memory_system": "Gedächtnissystem",
199
  "enable_memory": "Intelligentes Gedächtnis aktivieren",
200
  "memory_stats": "Gedächtnisstatistiken",
kimi-locale/en.json CHANGED
@@ -201,5 +201,6 @@
201
  "memory_management": "Memory Management",
202
  "add": "Add",
203
  "help_providers": "You can use multiple AI providers: OpenRouter, OpenAI, Groq, Together, DeepSeek, Custom OpenAI-compatible, or Local (Ollama). Enter the Base URL and Model ID when required, save your API key per provider, then use ‘Test API Key’.",
204
- "api_key_presence_hint": "Green = API key saved for current provider. Grey = no key saved."
 
205
  }
 
201
  "memory_management": "Memory Management",
202
  "add": "Add",
203
  "help_providers": "You can use multiple AI providers: OpenRouter, OpenAI, Groq, Together, DeepSeek, Custom OpenAI-compatible, or Local (Ollama). Enter the Base URL and Model ID when required, save your API key per provider, then use ‘Test API Key’.",
204
+ "api_key_presence_hint": "Green = API key saved for current provider. Grey = no key saved.",
205
+ "api_key_test_hint": "Green = API connectivity verified. Grey = not tested or failed."
206
  }
kimi-locale/es.json CHANGED
@@ -194,6 +194,7 @@
194
  "api_connection_failed": "¡Falló la conexión API!",
195
  "voice_test_message": "¡Hola mi amor! ¡Aquí está mi nueva voz configurada con todas las configuraciones! ¿Te gusta?",
196
  "api_key_presence_hint": "Verde = clave API guardada para el proveedor actual. Gris = ninguna clave guardada.",
 
197
  "memory_system": "Sistema de Memoria",
198
  "enable_memory": "Activar Memoria Inteligente",
199
  "memory_stats": "Estadísticas de Memoria",
 
194
  "api_connection_failed": "¡Falló la conexión API!",
195
  "voice_test_message": "¡Hola mi amor! ¡Aquí está mi nueva voz configurada con todas las configuraciones! ¿Te gusta?",
196
  "api_key_presence_hint": "Verde = clave API guardada para el proveedor actual. Gris = ninguna clave guardada.",
197
+ "api_key_test_hint": "Verde = conectividad de la API verificada. Gris = no probado o fallido.",
198
  "memory_system": "Sistema de Memoria",
199
  "enable_memory": "Activar Memoria Inteligente",
200
  "memory_stats": "Estadísticas de Memoria",
kimi-locale/fr.json CHANGED
@@ -201,5 +201,6 @@
201
  "memory_management": "Gestion de la Mémoire",
202
  "add": "Ajouter",
203
  "help_providers": "Vous pouvez utiliser plusieurs fournisseurs d’IA : OpenRouter, OpenAI, Groq, Together, DeepSeek, un service OpenAI‑compatible personnalisé, ou Local (Ollama). Renseignez la Base URL et le Model ID si nécessaire, enregistrez votre clé API par fournisseur, puis utilisez ‘Test API Key’.",
204
- "api_key_presence_hint": "Vert = clé API enregistrée pour le fournisseur courant. Gris = aucune clé enregistrée."
 
205
  }
 
201
  "memory_management": "Gestion de la Mémoire",
202
  "add": "Ajouter",
203
  "help_providers": "Vous pouvez utiliser plusieurs fournisseurs d’IA : OpenRouter, OpenAI, Groq, Together, DeepSeek, un service OpenAI‑compatible personnalisé, ou Local (Ollama). Renseignez la Base URL et le Model ID si nécessaire, enregistrez votre clé API par fournisseur, puis utilisez ‘Test API Key’.",
204
+ "api_key_presence_hint": "Vert = clé API enregistrée pour le fournisseur courant. Gris = aucune clé enregistrée.",
205
+ "api_key_test_hint": "Vert = connectivité API vérifiée. Gris = non testé ou échec."
206
  }
kimi-locale/it.json CHANGED
@@ -194,6 +194,7 @@
194
  "api_connection_failed": "❌ Connessione API fallita",
195
  "voice_test_message": "Ciao amore mio! Ecco la mia nuova voce configurata con tutte le impostazioni! Ti piace?",
196
  "api_key_presence_hint": "Verde = chiave API salvata per il provider corrente. Grigio = nessuna chiave salvata.",
 
197
  "memory_system": "Sistema di Memoria",
198
  "enable_memory": "Abilita Memoria Intelligente",
199
  "memory_stats": "Statistiche della Memoria",
 
194
  "api_connection_failed": "❌ Connessione API fallita",
195
  "voice_test_message": "Ciao amore mio! Ecco la mia nuova voce configurata con tutte le impostazioni! Ti piace?",
196
  "api_key_presence_hint": "Verde = chiave API salvata per il provider corrente. Grigio = nessuna chiave salvata.",
197
+ "api_key_test_hint": "Verde = connettività API verificata. Grigio = non testata o fallita.",
198
  "memory_system": "Sistema di Memoria",
199
  "enable_memory": "Abilita Memoria Intelligente",
200
  "memory_stats": "Statistiche della Memoria",
kimi-locale/ja.json CHANGED
@@ -194,6 +194,7 @@
194
  "api_connection_failed": "❌ API接続失敗",
195
  "voice_test_message": "こんにちは、私の愛する人!これがすべての設定で構成された私の新しい声です!気に入りましたか?",
196
  "api_key_presence_hint": "緑 = 現在のプロバイダー用のAPIキーが保存されています。灰色 = 保存されたキーがありません。",
 
197
  "memory_system": "メモリシステム",
198
  "enable_memory": "インテリジェントメモリを有効にする",
199
  "memory_stats": "メモリ統計",
 
194
  "api_connection_failed": "❌ API接続失敗",
195
  "voice_test_message": "こんにちは、私の愛する人!これがすべての設定で構成された私の新しい声です!気に入りましたか?",
196
  "api_key_presence_hint": "緑 = 現在のプロバイダー用のAPIキーが保存されています。灰色 = 保存されたキーがありません。",
197
+ "api_key_test_hint": "緑 = API接続が確認されました。灰色 = 未テストまたは失敗。",
198
  "memory_system": "メモリシステム",
199
  "enable_memory": "インテリジェントメモリを有効にする",
200
  "memory_stats": "メモリ統計",
kimi-locale/zh.json CHANGED
@@ -194,6 +194,7 @@
194
  "api_connection_failed": "❌ API连接失败",
195
  "voice_test_message": "你好我的爱人!这是我用所有设置配置的新声音!你喜欢吗?",
196
  "api_key_presence_hint": "绿色 = 当前提供商已保存 API 密钥。灰色 = 未保存任何密钥。",
 
197
  "memory_system": "记忆系统",
198
  "enable_memory": "启用智能记忆",
199
  "memory_stats": "记忆统计",
 
194
  "api_connection_failed": "❌ API连接失败",
195
  "voice_test_message": "你好我的爱人!这是我用所有设置配置的新声音!你喜欢吗?",
196
  "api_key_presence_hint": "绿色 = 当前提供商已保存 API 密钥。灰色 = 未保存任何密钥。",
197
+ "api_key_test_hint": "绿色 = API 连接已验证。灰色 = 未测试或失败。",
198
  "memory_system": "记忆系统",
199
  "enable_memory": "启用智能记忆",
200
  "memory_stats": "记忆统计",