groove-dev 0.24.9 → 0.24.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/node_modules/@groove-dev/daemon/src/api.js +29 -0
- package/node_modules/@groove-dev/daemon/src/providers/ollama.js +23 -0
- package/node_modules/@groove-dev/gui/dist/assets/{index-DjxlUkR9.css → index-BwmIyTkm.css} +1 -1
- package/node_modules/@groove-dev/gui/dist/assets/{index-C7dW1iUw.js → index-Df8BnR7l.js} +29 -29
- package/node_modules/@groove-dev/gui/dist/index.html +2 -2
- package/node_modules/@groove-dev/gui/src/components/agents/ollama-setup.jsx +103 -1
- package/package.json +1 -1
- package/packages/daemon/src/api.js +29 -0
- package/packages/daemon/src/providers/ollama.js +23 -0
- package/packages/gui/dist/assets/{index-DjxlUkR9.css → index-BwmIyTkm.css} +1 -1
- package/packages/gui/dist/assets/{index-C7dW1iUw.js → index-Df8BnR7l.js} +29 -29
- package/packages/gui/dist/index.html +2 -2
- package/packages/gui/src/components/agents/ollama-setup.jsx +103 -1
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<link rel="icon" type="image/png" href="/favicon.png" />
|
|
7
7
|
<title>Groove GUI</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-Df8BnR7l.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/assets/vendor-C0HXlhrU.js">
|
|
10
10
|
<link rel="modulepreload" crossorigin href="/assets/reactflow-BQPfi37R.js">
|
|
11
11
|
<link rel="modulepreload" crossorigin href="/assets/codemirror-BBL3i_JW.js">
|
|
12
12
|
<link rel="modulepreload" crossorigin href="/assets/xterm--7_ns2zW.js">
|
|
13
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
13
|
+
<link rel="stylesheet" crossorigin href="/assets/index-BwmIyTkm.css">
|
|
14
14
|
</head>
|
|
15
15
|
<body>
|
|
16
16
|
<div id="root"></div>
|
|
@@ -242,6 +242,72 @@ function ModelRow({ model, isInstalled, isRecommended, canRun, onPull, onDelete,
|
|
|
242
242
|
);
|
|
243
243
|
}
|
|
244
244
|
|
|
245
|
+
/* ── Server Status Bar ────────────────────────────────────────── */
|
|
246
|
+
|
|
247
|
+
function ServerStatusBar({ onStopped }) {
|
|
248
|
+
const [action, setAction] = useState(null); // 'stopping' | 'restarting'
|
|
249
|
+
const addToast = useGrooveStore((s) => s.addToast);
|
|
250
|
+
|
|
251
|
+
async function handleStop() {
|
|
252
|
+
setAction('stopping');
|
|
253
|
+
try {
|
|
254
|
+
const result = await api.post('/providers/ollama/stop');
|
|
255
|
+
if (result.ok) {
|
|
256
|
+
addToast('info', 'Ollama server stopped');
|
|
257
|
+
if (onStopped) onStopped();
|
|
258
|
+
} else {
|
|
259
|
+
addToast('error', 'Could not stop server');
|
|
260
|
+
}
|
|
261
|
+
} catch (err) {
|
|
262
|
+
addToast('error', 'Stop failed', err.message);
|
|
263
|
+
}
|
|
264
|
+
setAction(null);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
async function handleRestart() {
|
|
268
|
+
setAction('restarting');
|
|
269
|
+
try {
|
|
270
|
+
const result = await api.post('/providers/ollama/restart');
|
|
271
|
+
if (result.ok) {
|
|
272
|
+
addToast('success', 'Ollama server restarted');
|
|
273
|
+
} else {
|
|
274
|
+
addToast('error', 'Restart failed');
|
|
275
|
+
}
|
|
276
|
+
} catch (err) {
|
|
277
|
+
addToast('error', 'Restart failed', err.message);
|
|
278
|
+
}
|
|
279
|
+
setAction(null);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
return (
|
|
283
|
+
<div className="flex items-center gap-2 bg-success/8 border border-success/20 rounded-lg px-3 py-2">
|
|
284
|
+
<span className="relative flex-shrink-0 w-[6px] h-[6px]">
|
|
285
|
+
<span className="absolute inset-0 rounded-full bg-success" />
|
|
286
|
+
<span className="absolute inset-[-2px] rounded-full bg-success opacity-20 animate-pulse" />
|
|
287
|
+
</span>
|
|
288
|
+
<span className="text-xs font-sans text-success font-semibold">Server Running</span>
|
|
289
|
+
<span className="text-2xs font-mono text-text-4">:11434</span>
|
|
290
|
+
<div className="flex-1" />
|
|
291
|
+
<button
|
|
292
|
+
onClick={handleRestart}
|
|
293
|
+
disabled={!!action}
|
|
294
|
+
className="flex items-center gap-1 text-2xs font-sans text-text-3 hover:text-accent cursor-pointer transition-colors disabled:opacity-40"
|
|
295
|
+
>
|
|
296
|
+
<RefreshCw size={10} className={action === 'restarting' ? 'animate-spin' : ''} />
|
|
297
|
+
{action === 'restarting' ? 'Restarting...' : 'Restart'}
|
|
298
|
+
</button>
|
|
299
|
+
<button
|
|
300
|
+
onClick={handleStop}
|
|
301
|
+
disabled={!!action}
|
|
302
|
+
className="flex items-center gap-1 text-2xs font-sans text-text-3 hover:text-danger cursor-pointer transition-colors disabled:opacity-40"
|
|
303
|
+
>
|
|
304
|
+
<AlertCircle size={10} />
|
|
305
|
+
{action === 'stopping' ? 'Stopping...' : 'Stop'}
|
|
306
|
+
</button>
|
|
307
|
+
</div>
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
|
|
245
311
|
/* ── Model Browser (installed) ─────────────────────────────── */
|
|
246
312
|
|
|
247
313
|
function ModelBrowser({ onModelChange }) {
|
|
@@ -249,6 +315,7 @@ function ModelBrowser({ onModelChange }) {
|
|
|
249
315
|
const [pulling, setPulling] = useState(null);
|
|
250
316
|
const [category, setCategory] = useState('code');
|
|
251
317
|
const [showAll, setShowAll] = useState(false);
|
|
318
|
+
const [serverStopped, setServerStopped] = useState(false);
|
|
252
319
|
const addToast = useGrooveStore((s) => s.addToast);
|
|
253
320
|
|
|
254
321
|
const retried = useRef(false);
|
|
@@ -256,7 +323,6 @@ function ModelBrowser({ onModelChange }) {
|
|
|
256
323
|
function load() {
|
|
257
324
|
api.get('/providers/ollama/models').then((result) => {
|
|
258
325
|
setData(result);
|
|
259
|
-
// If no installed models on first load, retry once after 2s (server may still be warming up)
|
|
260
326
|
if (!retried.current && result.installed?.length === 0) {
|
|
261
327
|
retried.current = true;
|
|
262
328
|
setTimeout(load, 2000);
|
|
@@ -300,8 +366,44 @@ function ModelBrowser({ onModelChange }) {
|
|
|
300
366
|
const filtered = catalog.filter((m) => m.category === category);
|
|
301
367
|
const visible = showAll ? filtered : filtered.filter((m) => m.ramGb <= maxRam);
|
|
302
368
|
|
|
369
|
+
if (serverStopped) {
|
|
370
|
+
return (
|
|
371
|
+
<div className="space-y-3 p-3">
|
|
372
|
+
<div className="flex items-center gap-2 bg-warning/8 border border-warning/20 rounded-lg px-3 py-2.5">
|
|
373
|
+
<AlertCircle size={14} className="text-warning flex-shrink-0" />
|
|
374
|
+
<span className="text-xs font-sans text-text-2">
|
|
375
|
+
<span className="text-warning font-semibold">Ollama server stopped.</span>
|
|
376
|
+
{' '}Start it again to pull and use models.
|
|
377
|
+
</span>
|
|
378
|
+
</div>
|
|
379
|
+
<Button
|
|
380
|
+
variant="primary"
|
|
381
|
+
size="md"
|
|
382
|
+
onClick={async () => {
|
|
383
|
+
try {
|
|
384
|
+
const result = await api.post('/providers/ollama/serve');
|
|
385
|
+
if (result.ok) {
|
|
386
|
+
addToast('success', 'Ollama server started!');
|
|
387
|
+
setServerStopped(false);
|
|
388
|
+
retried.current = false;
|
|
389
|
+
setTimeout(load, 2000);
|
|
390
|
+
}
|
|
391
|
+
} catch (err) {
|
|
392
|
+
addToast('error', 'Could not start server', err.message);
|
|
393
|
+
}
|
|
394
|
+
}}
|
|
395
|
+
className="w-full gap-1.5"
|
|
396
|
+
>
|
|
397
|
+
<Zap size={12} />
|
|
398
|
+
Start Ollama Server
|
|
399
|
+
</Button>
|
|
400
|
+
</div>
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
|
|
303
404
|
return (
|
|
304
405
|
<div className="space-y-2 p-3">
|
|
406
|
+
<ServerStatusBar onStopped={() => setServerStopped(true)} />
|
|
305
407
|
<HardwareBar hardware={hardware} />
|
|
306
408
|
|
|
307
409
|
{/* Installed count */}
|