diff --git a/app/assets/js/main-legacy.js b/app/assets/js/main-legacy.js
index e19938c3..6002032c 100644
--- a/app/assets/js/main-legacy.js
+++ b/app/assets/js/main-legacy.js
@@ -26853,10 +26853,11 @@ ${info.features.map((f) => ` • ${f}`).join("\n")}
return;
}
} else {
- // Standard provider - check API key
+ // Standard provider - check API key (local Ollama/LM Studio need none)
+ const localCompat = ['local-openai', 'ollama', 'lmstudio', 'vllm'].includes(provider);
const hasApiKey = selectedOption?.dataset.apiKey && selectedOption.dataset.apiKey.length > 0;
- if (!hasApiKey) {
+ if (!hasApiKey && !localCompat) {
showToast('No API key configured for this provider. Please add in Settings.', 'error');
Logger.error('[AI] No API key for provider:', provider);
return;
@@ -27650,7 +27651,8 @@ ${info.features.map((f) => ` • ${f}`).join("\n")}
// Store full API config as data attribute
option.dataset.apiUrl = api.apiUrl;
option.dataset.model = api.model;
- option.dataset.apiKey = api.apiKey;
+ option.dataset.apiKey = api.apiKey || (localCompat ? 'ollama' : '');
+ option.dataset.apiKeyOptional = localCompat ? 'true' : 'false';
if (hasApiKey) {
hasUsableProvider = true;
diff --git a/app/assets/js/settings.js b/app/assets/js/settings.js
index 109ef27e..f9c67fd6 100644
--- a/app/assets/js/settings.js
+++ b/app/assets/js/settings.js
@@ -651,7 +651,7 @@ async function saveCurrentPreferences() {
// Only update if field has value, otherwise keep existing (skip redaction markers)
const existingKey = (existing?.apiKey && !existing.apiKey.startsWith('[REDACTED:')) ? existing.apiKey : '';
- const apiKey = apiKeyField || existingKey || '';
+ const apiKey = apiKeyField || existingKey || (provider.apiKeyOptional ? 'ollama' : '');
const apiUrl = apiUrlField || existing?.apiUrl || provider.defaultUrl;
return {
diff --git a/app/index.html b/app/index.html
index 86c276c4..402f9b49 100644
--- a/app/index.html
+++ b/app/index.html
@@ -148,7 +148,7 @@
-
+