mirror of
https://github.com/Anil-matcha/Open-Generative-AI.git
synced 2026-05-07 01:17:18 +00:00
The desktop app already has a bundled sd.cpp engine for local generation. This adds a second, complementary engine: an HTTP client that talks to a user-run Wan2GP Gradio server (https://github.com/deepbeepmeep/Wan2GP). Useful when sd.cpp can't run a target model — Wan2GP brings video models (Wan 2.2, Hunyuan, LTX) and large image models (Flux, Qwen-Image) without bundling Python or weights into the app. Architecture - Each model in the unified catalog now carries a `provider` field (`'sdcpp' | 'wan2gp'`). The renderer's `localAI.generate()` routes to the right backend based on that flag. - sd.cpp keeps its existing IPC channels (`local-ai:*`) untouched. Wan2GP gets its own channel namespace (`wan2gp:*`) and lives in its own `electron/lib/wan2gpProvider.js`. - Wan2GP server URL is persisted in `userData/local-ai/wan2gp.json`. `Settings → Local Models` exposes a config bar to test/save the URL. - Generation streams Gradio v4 SSE protocol; both engines emit progress on the shared `local-ai:progress` channel. ImageStudio - Local-model dropdown now filters out video models (`type === 'video'`) since the studio is image-only. SD 1.5 / SDXL / Z-Image (sd.cpp) and Flux / Qwen-Image (Wan2GP) still surface; Wan/Hunyuan/LTX are hidden until the Video Studio is wired up to the same surface. - Progress event handler updated to tolerate both engines' shapes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
77 lines
2.2 KiB
JavaScript
77 lines
2.2 KiB
JavaScript
const { app, BrowserWindow, shell } = require('electron');
|
|
const path = require('path');
|
|
const { register: registerLocalInference } = require('./lib/localInference');
|
|
const { register: registerWan2gp } = require('./lib/wan2gpProvider');
|
|
|
|
// 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();
|
|
registerWan2gp();
|
|
|
|
app.on('activate', () => {
|
|
if (BrowserWindow.getAllWindows().length === 0) {
|
|
createWindow();
|
|
}
|
|
});
|
|
});
|
|
|
|
app.on('window-all-closed', () => {
|
|
if (process.platform !== 'darwin') {
|
|
app.quit();
|
|
}
|
|
});
|