Open-Generative-AI/electron/main.js
Anil Matcha 36d392ab78 feat: add local model inference via sd.cpp (Electron-only)
- Scaffold full IPC bridge: preload.js exposes localAI API to renderer
- electron/lib/localInference.js: binary download (Metal-enabled macOS build),
  model management, auxiliary file downloads (Qwen3-4B LLM + FLUX VAE for Z-Image),
  and generation via sd-cli with DYLD_LIBRARY_PATH + xattr quarantine stripping
- electron/lib/modelCatalog.js: Z-Image Turbo/Base (featured) + SD 1.5/SDXL models
- Z-Image requires 3 components loaded via --diffusion-model + --llm + --vae flags
- ImageStudio: Local/API toggle (Electron-only), local model selector, progress bar
- SettingsModal: tabbed UI with Local Models tab (hidden on web/hosted version)
- LocalModelManager: engine status bar, per-model download cards, auxiliary
  component download UI (text encoder + VAE) for Z-Image models
- localInferenceClient.js: safe wrapper with isLocalAIAvailable() guard
- All local features gated behind isLocalAIAvailable() — web version unaffected

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 17:47:17 +05:30

75 lines
2.1 KiB
JavaScript

const { app, BrowserWindow, shell } = require('electron');
const path = require('path');
const { register: registerLocalInference } = require('./lib/localInference');
// Ubuntu 24.04+ sets kernel.apparmor_restrict_unprivileged_userns=1 which
// blocks Chromium's user namespace sandbox. The .deb package ships an AppArmor
// profile that grants the permission cleanly. When running the AppImage on an
// affected system, run once: sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
// or pass --no-sandbox on the command line.
if (process.platform === 'linux') {
app.commandLine.appendSwitch('disable-dev-shm-usage');
}
let mainWindow;
function createWindow() {
const isMac = process.platform === 'darwin';
mainWindow = new BrowserWindow({
width: 1440,
height: 900,
minWidth: 1024,
minHeight: 640,
webPreferences: {
webSecurity: false,
contextIsolation: true,
nodeIntegration: false,
preload: path.join(__dirname, 'preload.js'),
},
...(isMac ? { titleBarStyle: 'hiddenInset' } : {}),
backgroundColor: '#0d0d0d',
show: false,
title: 'Open Generative AI',
});
const indexPath = path.join(__dirname, '../dist/index.html');
mainWindow.loadFile(indexPath).catch((err) => {
console.error('Failed to load index.html:', err);
mainWindow.show();
});
mainWindow.webContents.on('did-fail-load', (event, code, desc) => {
console.error('did-fail-load:', code, desc);
});
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
shell.openExternal(url);
return { action: 'deny' };
});
mainWindow.once('ready-to-show', () => {
mainWindow.show();
});
mainWindow.on('closed', () => {
mainWindow = null;
});
}
app.whenReady().then(() => {
createWindow();
registerLocalInference();
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
});
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});