-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.js
More file actions
104 lines (93 loc) · 3.06 KB
/
Copy pathmain.js
File metadata and controls
104 lines (93 loc) · 3.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
const { app, BrowserWindow, ipcMain, shell } = require('electron');
const path = require('path');
function createWindow() {
const win = new BrowserWindow({
width: 1440,
height: 960,
minWidth: 980,
minHeight: 700,
backgroundColor: '#0d0d12',
autoHideMenuBar: true,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
contextIsolation: true,
nodeIntegration: false,
sandbox: true
}
});
win.loadFile('index.html');
win.webContents.setWindowOpenHandler(({ url }) => {
if (url.startsWith('https://') || url.startsWith('http://')) shell.openExternal(url);
return { action: 'deny' };
});
}
function normalizeServerUrl(value) {
let raw = String(value || 'http://127.0.0.1:11434').trim();
if (!/^https?:\/\//i.test(raw)) raw = `http://${raw}`;
const url = new URL(raw);
if (!['http:', 'https:'].includes(url.protocol) || url.username || url.password) {
throw new Error('Ungültige Ollama-Serveradresse.');
}
return url.origin;
}
async function ollamaRequest(serverUrl, endpoint, options) {
let response;
try {
response = await fetch(`${normalizeServerUrl(serverUrl)}${endpoint}`, options);
} catch {
throw new Error('Ollama ist nicht erreichbar. Bitte Ollama starten und erneut versuchen.');
}
const text = await response.text();
let data;
try {
data = text ? JSON.parse(text) : {};
} catch {
data = { error: text || `HTTP ${response.status}` };
}
if (!response.ok) {
throw new Error(data.error || `Ollama-Fehler ${response.status}`);
}
return data;
}
ipcMain.handle('ollama:status', (_event, serverUrl) => ollamaRequest(serverUrl, '/api/tags'));
ipcMain.handle('ollama:model-info', (_event, serverUrl, model) => ollamaRequest(serverUrl, '/api/show', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ model })
}));
ipcMain.handle('ollama:chat', (_event, payload) => {
const model = String(payload?.model || '').trim();
const serverUrl = payload?.serverUrl;
const prompt = String(payload?.prompt || '');
const image = String(payload?.image || '');
const schema = payload?.schema && typeof payload.schema === 'object' ? payload.schema : null;
if (!model || !prompt) throw new Error('Modell oder Prompt fehlt.');
if (model.length > 200 || prompt.length > 100000 || image.length > 30_000_000) {
throw new Error('Die Ollama-Anfrage ist zu groß.');
}
return ollamaRequest(serverUrl, '/api/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
model,
stream: false,
think: false,
format: schema || 'json',
options: { temperature: 0.4, num_predict: 4096 },
messages: [{
role: 'user',
content: prompt,
...(image ? { images: [image] } : {})
}]
})
});
});
app.whenReady().then(() => {
createWindow();
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow();
});
});
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit();
});