Feature/lmstudio provider (#30)

* chore: just a plan update

* Add LM Studio as local AI provider (OpenAI-compatible, like Ollama)

* Convert WebP thumbnails to JPEG before image analysis for LM Studio compatibility

* Strengthen language enforcement in image analysis prompt for local models

* Use i18n localized prompts for image analysis instead of English instructions

* Add airplane mode (Flugmodus) with status bar toggle and offline model preferences

* Fix flightmode: persist model IDs, skip network when offline, airplane icon

* Auto-fallback to offline models in airplane mode for chat, title, and image analysis

* Auto-select first local model as offline fallback when no explicit offline model configured

* Block git fetch/pull/push and site upload in airplane mode

* fix: thumbnails optimized for AI

* fix: error handling in airplane mode

---------

Co-authored-by: hugo <hugoms@me.com>
This commit is contained in:
Georg Bauer
2026-03-02 13:35:42 +01:00
committed by GitHub
parent 4b4a9c1c8b
commit 5747925503
34 changed files with 2215 additions and 105 deletions

View File

@@ -321,6 +321,24 @@ export const electronAPI: ElectronAPI = {
getOllamaModelCapabilities: () => ipcRenderer.invoke('chat:getOllamaModelCapabilities'),
setOllamaModelCapabilities: (modelId: string, caps: { tools: boolean; vision: boolean }) => ipcRenderer.invoke('chat:setOllamaModelCapabilities', modelId, caps),
// LM Studio (Local)
getLmstudioEnabled: () => ipcRenderer.invoke('chat:getLmstudioEnabled'),
setLmstudioEnabled: (enabled: boolean) => ipcRenderer.invoke('chat:setLmstudioEnabled', enabled),
getLmstudioModels: () => ipcRenderer.invoke('chat:getLmstudioModels'),
getLmstudioModelCapabilities: () => ipcRenderer.invoke('chat:getLmstudioModelCapabilities'),
setLmstudioModelCapabilities: (modelId: string, caps: { tools: boolean; vision: boolean }) => ipcRenderer.invoke('chat:setLmstudioModelCapabilities', modelId, caps),
// Offline / Airplane Mode
getOfflineMode: () => ipcRenderer.invoke('chat:getOfflineMode'),
setOfflineMode: (enabled: boolean) => ipcRenderer.invoke('chat:setOfflineMode', enabled),
getOfflineChatModel: () => ipcRenderer.invoke('chat:getOfflineChatModel'),
setOfflineChatModel: (modelId: string | null) => ipcRenderer.invoke('chat:setOfflineChatModel', modelId),
getOfflineTitleModel: () => ipcRenderer.invoke('chat:getOfflineTitleModel'),
setOfflineTitleModel: (modelId: string | null) => ipcRenderer.invoke('chat:setOfflineTitleModel', modelId),
getOfflineImageAnalysisModel: () => ipcRenderer.invoke('chat:getOfflineImageAnalysisModel'),
setOfflineImageAnalysisModel: (modelId: string | null) => ipcRenderer.invoke('chat:setOfflineImageAnalysisModel', modelId),
getKnownLocalModels: () => ipcRenderer.invoke('chat:getKnownLocalModels'),
// Per-Purpose Model Preferences
getTitleModel: () => ipcRenderer.invoke('chat:getTitleModel'),
setTitleModel: (modelId: string | null) => ipcRenderer.invoke('chat:setTitleModel', modelId),