+
+
+
+ Ollama Models
+
+ {ollama?.status === 'online' && (
+
+ {ollama.runningCount} active
+
+ )}
+
+
+ {/* Pull Model Input */}
+ {ollama?.status === 'online' && (
+
+
setPullInput(e.target.value)}
+ onKeyDown={e => {
+ if (e.key === 'Enter') handlePull();
+ }}
+ placeholder="Pull a model... e.g. deepseek-r1:32b"
+ className="flex-1 px-3 py-2 rounded-lg text-sm font-mono focus:outline-none focus:ring-2"
+ style={{
+ background: 'var(--surface-muted)',
+ border: '1px solid var(--border-subtle)',
+ color: 'var(--text-primary)',
+ caretColor: 'var(--accent-primary)',
+ }}
+ />
+
+
+ )}
+
+ {ollama?.status !== 'online' ? (
+
+
+
+
+ Ollama is offline
+
+
+ Run "ollama serve" to start
+
+
+
+ ) : (
+
+ {ollama.models.map(model => {
+ const running = isRunning(model.name);
+ const expanded = expandedModel === model.name;
+ return (
+
+
+
+
+ {running ? (
+
+ ) : (
+
+ )}
+
+
+
+
+ {model.name}
+
+ {running && (
+
+ LOADED
+
+ )}
+
+
+ {formatBytes(model.size)}
+ {model.details?.parameter_size && (
+ {model.details.parameter_size}
+ )}
+ {model.details?.quantization_level && (
+ {model.details.quantization_level}
+ )}
+
+
+
+
+ {running ? (
+ <>
+
+
+ >
+ ) : (
+
+ )}
+
+
+
+ {/* Running model VRAM info */}
+ {running &&
+ (() => {
+ const info = getRunningInfo(model.name);
+ return info ? (
+
+ {info.size_vram > 0 && VRAM: {formatBytes(info.size_vram)}}
+ {info.expires_at && (
+ Expires: {new Date(info.expires_at).toLocaleTimeString()}
+ )}
+
+ ) : null;
+ })()}
+ {expanded && (
+
+
Digest: {model.digest?.substring(0, 16)}...
+
Modified: {new Date(model.modified_at).toLocaleString()}
+ {model.details?.family &&
Family: {model.details.family}
}
+
+ {deleteConfirm === model.name ? (
+
+
+ Delete this model?
+
+
+
+
+ ) : (
+
+ )}
+
+
+ )}
+
+ );
+ })}
+ {ollama.models.length === 0 && (
+
+ No models installed. Run "ollama pull <model>" to get started.
+
+ )}
+
+ )}
+