Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 04c3018360 | |||
| 2699f1cd5c |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -41,3 +41,4 @@ CLAUDE.md
|
||||
dev.env
|
||||
backend/vessel-backend
|
||||
data/
|
||||
backend/data-dev/
|
||||
|
||||
@@ -18,7 +18,7 @@ import (
|
||||
)
|
||||
|
||||
// Version is set at build time via -ldflags, or defaults to dev
|
||||
var Version = "0.4.6"
|
||||
var Version = "0.4.7"
|
||||
|
||||
func getEnvOrDefault(key, defaultValue string) string {
|
||||
if value := os.Getenv(key); value != "" {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vessel",
|
||||
"version": "0.4.6",
|
||||
"version": "0.4.7",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -146,7 +146,8 @@ class LocalModelsState {
|
||||
const response = await checkForUpdates();
|
||||
|
||||
this.updatesAvailable = response.updatesAvailable;
|
||||
this.modelsWithUpdates = new Set(response.updates.map(m => m.name));
|
||||
// Handle null/undefined updates array from API
|
||||
this.modelsWithUpdates = new Set((response.updates ?? []).map(m => m.name));
|
||||
|
||||
return response;
|
||||
} catch (err) {
|
||||
|
||||
@@ -236,7 +236,10 @@
|
||||
// Initialize stores (backend handles heavy operations)
|
||||
localModelsState.init();
|
||||
modelRegistry.init();
|
||||
modelsState.refresh();
|
||||
modelsState.refresh().then(() => {
|
||||
// Fetch capabilities for all installed models
|
||||
modelsState.fetchAllCapabilities();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -493,6 +496,7 @@
|
||||
{:else}
|
||||
<div class="space-y-2">
|
||||
{#each localModelsState.models as model (model.name)}
|
||||
{@const caps = modelsState.getCapabilities(model.name) ?? []}
|
||||
<div class="group rounded-lg border border-theme bg-theme-secondary p-4 transition-colors hover:border-theme-subtle">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex-1">
|
||||
@@ -513,6 +517,36 @@
|
||||
<span>Parameters: {model.parameterSize}</span>
|
||||
<span>Quantization: {model.quantizationLevel}</span>
|
||||
</div>
|
||||
<!-- Capabilities (from Ollama runtime - verified) -->
|
||||
{#if caps.length > 0}
|
||||
<div class="mt-2 flex flex-wrap gap-1.5">
|
||||
{#if caps.includes('vision')}
|
||||
<span class="inline-flex items-center gap-1 rounded px-1.5 py-0.5 text-xs bg-purple-900/50 text-purple-300">
|
||||
<span>👁</span><span>Vision</span>
|
||||
</span>
|
||||
{/if}
|
||||
{#if caps.includes('tools')}
|
||||
<span class="inline-flex items-center gap-1 rounded px-1.5 py-0.5 text-xs bg-blue-900/50 text-blue-300">
|
||||
<span>🔧</span><span>Tools</span>
|
||||
</span>
|
||||
{/if}
|
||||
{#if caps.includes('thinking')}
|
||||
<span class="inline-flex items-center gap-1 rounded px-1.5 py-0.5 text-xs bg-pink-900/50 text-pink-300">
|
||||
<span>🧠</span><span>Thinking</span>
|
||||
</span>
|
||||
{/if}
|
||||
{#if caps.includes('embedding')}
|
||||
<span class="inline-flex items-center gap-1 rounded px-1.5 py-0.5 text-xs bg-amber-900/50 text-amber-300">
|
||||
<span>📊</span><span>Embedding</span>
|
||||
</span>
|
||||
{/if}
|
||||
{#if caps.includes('code')}
|
||||
<span class="inline-flex items-center gap-1 rounded px-1.5 py-0.5 text-xs bg-emerald-900/50 text-emerald-300">
|
||||
<span>💻</span><span>Code</span>
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
{#if deleteConfirm === model.name}
|
||||
|
||||
Reference in New Issue
Block a user