okengine 0.9.1 → 0.10.0
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/AGENTS.md +1 -1
- package/manifest.v1.schema.json +9 -1
- package/package.json +3 -3
- package/site/content/docs/console/runs.mdx +10 -0
- package/site/content/docs/console/traces.mdx +4 -0
- package/site/content/docs/elements/ai.mdx +54 -32
- package/site/content/docs/elements/channel.mdx +97 -9
- package/site/content/docs/elements/clock.mdx +1 -0
- package/site/content/docs/elements/flow.mdx +42 -8
- package/site/content/docs/get-started/basic-usage.mdx +5 -1
- package/site/content/docs/get-started/installation.mdx +9 -5
- package/site/content/docs/meta.json +2 -0
- package/site/content/docs/providers/azure-redis.mdx +85 -0
- package/site/content/docs/providers/cockroachdb.mdx +86 -0
- package/site/content/docs/providers/digitalocean-caching.mdx +88 -0
- package/site/content/docs/providers/dragonfly-cloud.mdx +82 -0
- package/site/content/docs/providers/elasticache.mdx +92 -0
- package/site/content/docs/providers/index.mdx +101 -0
- package/site/content/docs/providers/memorystore.mdx +89 -0
- package/site/content/docs/providers/meta.json +20 -0
- package/site/content/docs/providers/neon.mdx +115 -0
- package/site/content/docs/providers/redis-cloud.mdx +93 -0
- package/site/content/docs/providers/supabase.mdx +117 -0
- package/site/content/docs/providers/upstash.mdx +91 -0
- package/site/content/docs/providers/yugabytedb.mdx +95 -0
- package/site/content/docs/recipes/caddy.mdx +128 -0
- package/site/content/docs/recipes/cockroachdb.mdx +127 -0
- package/site/content/docs/recipes/dragonfly.mdx +125 -0
- package/site/content/docs/recipes/index.mdx +146 -0
- package/site/content/docs/recipes/llama-cpp.mdx +153 -0
- package/site/content/docs/recipes/mailpit.mdx +136 -0
- package/site/content/docs/recipes/meilisearch.mdx +139 -0
- package/site/content/docs/recipes/meta.json +31 -0
- package/site/content/docs/recipes/ollama.mdx +142 -0
- package/site/content/docs/recipes/openbao.mdx +141 -0
- package/site/content/docs/recipes/pgdog.mdx +137 -0
- package/site/content/docs/recipes/postgres.mdx +136 -0
- package/site/content/docs/recipes/redis.mdx +130 -0
- package/site/content/docs/recipes/rustfs.mdx +148 -0
- package/site/content/docs/recipes/sglang.mdx +105 -0
- package/site/content/docs/recipes/supabase-docker.mdx +145 -0
- package/site/content/docs/recipes/timescale.mdx +129 -0
- package/site/content/docs/recipes/traefik.mdx +136 -0
- package/site/content/docs/recipes/valkey.mdx +121 -0
- package/site/content/docs/recipes/vllm.mdx +106 -0
- package/site/content/docs/recipes/yugabytedb.mdx +135 -0
- package/site/content/docs/reference/cli.md +42 -6
- package/site/content/docs/reference/configuration.mdx +5 -3
- package/site/content/docs/reference/environment-variables.mdx +12 -12
- package/site/content/docs/reference/fx.mdx +38 -4
- package/src/cli/ai-setup/ai-setup.test.ts +32 -12
- package/src/cli/ai-setup/apply.ts +65 -23
- package/src/cli/ai-setup/catalog.ts +1316 -35
- package/src/cli/ai-setup/detect-ollama.ts +47 -0
- package/src/cli/ai-setup/index.ts +44 -7
- package/src/cli/ai-setup/prompts.ts +430 -486
- package/src/cli/ai-setup/recommend.test.ts +150 -50
- package/src/cli/ai-setup/recommend.ts +118 -101
- package/src/cli/ask-seed.test.ts +68 -0
- package/src/cli/ask-seed.ts +79 -0
- package/src/cli/db-seed-redact.test.ts +25 -0
- package/src/cli/db-seed.ts +36 -7
- package/src/cli/db.test.ts +1 -1
- package/src/cli/db.ts +2 -2
- package/src/cli/dev-controls.test.ts +107 -0
- package/src/cli/dev-controls.ts +354 -0
- package/src/cli/dev-schema-sync.ts +12 -4
- package/src/cli/dev.test.ts +50 -30
- package/src/cli/dev.ts +607 -66
- package/src/cli/drizzle-env.test.ts +40 -6
- package/src/cli/drizzle-env.ts +22 -1
- package/src/cli/ensure-drizzle-config.ts +6 -4
- package/src/cli/hero-meta.test.ts +13 -1
- package/src/cli/hero-meta.ts +28 -6
- package/src/cli/index.ts +5 -0
- package/src/cli/registry.ts +24 -0
- package/src/cli/replay.test.ts +105 -0
- package/src/cli/replay.ts +206 -0
- package/src/compiler/extract.ts +3 -3
- package/src/config/index.ts +3 -3
- package/src/console/server/claim.ts +3 -1
- package/src/console/ui/dist/assets/{index-ClX0ZCe5.js → index-D-9KFce5.js} +2 -2
- package/src/console/ui/dist/assets/panel-overview-CW0CQEc2.js +1 -0
- package/src/console/ui/dist/assets/panel-runs-BxuyDI3x.js +1 -0
- package/src/console/ui/dist/assets/{panel-signals-Dsxdu_AR.js → panel-signals-BXofbj7v.js} +1 -1
- package/src/console/ui/dist/assets/{panel-store-hy7O8HOs.js → panel-store-B8mH-arU.js} +1 -1
- package/src/console/ui/dist/assets/{panel-traces-CBiAe5go.js → panel-traces-DSA-ZWnf.js} +1 -1
- package/src/console/ui/dist/index.html +1 -1
- package/src/console/ui/overview/slo.ts +31 -3
- package/src/console/ui/overview/types.ts +6 -0
- package/src/console/ui/runs/errors.test.ts +53 -0
- package/src/console/ui/runs/errors.ts +88 -0
- package/src/console/ui/runs/index.ts +8 -0
- package/src/console/ui/runs/search.ts +16 -0
- package/src/console/ui/shell/panels/runs/RunsPanel.tsx +72 -1
- package/src/docker/ai-model-status.test.ts +101 -0
- package/src/docker/ai-model-status.ts +276 -0
- package/src/docker/compose-health.test.ts +115 -0
- package/src/docker/compose-health.ts +234 -0
- package/src/docker/compose.ts +24 -8
- package/src/docker/derive.ts +35 -9
- package/src/docker/docker.test.ts +304 -12
- package/src/docker/helpers.ts +56 -0
- package/src/docker/index.ts +52 -0
- package/src/docker/ollama-pull.ts +232 -0
- package/src/docker/recipes/cockroach.ts +24 -0
- package/src/docker/recipes/index.ts +32 -0
- package/src/docker/recipes/llama-cpp.ts +273 -0
- package/src/docker/recipes/ollama.ts +19 -23
- package/src/docker/recipes/pgdog.ts +4 -1
- package/src/docker/recipes/postgres.ts +5 -18
- package/src/docker/recipes/sglang.ts +55 -0
- package/src/docker/recipes/supabase.ts +21 -0
- package/src/docker/recipes/timescale.ts +18 -0
- package/src/docker/recipes/vllm.ts +44 -0
- package/src/docker/recipes/yugabyte.ts +23 -0
- package/src/docker/stack-id.test.ts +22 -0
- package/src/docker/stack-id.ts +38 -4
- package/src/docker/types.ts +15 -0
- package/src/drivers/ai-ollama.integration.test.ts +7 -4
- package/src/drivers/signal-engine.ts +10 -0
- package/src/drivers/signal-postgres.ts +24 -2
- package/src/drivers/signal-types.ts +10 -0
- package/src/elements/channel/fallback.test.ts +91 -0
- package/src/elements/channel/hard-bounce.test.ts +82 -0
- package/src/elements/channel/injection.test.ts +153 -0
- package/src/elements/channel/locale-ar.test.ts +102 -0
- package/src/elements/channel/otp-delivery.ts +5 -2
- package/src/elements/channel/receipts-ledger.test.ts +100 -0
- package/src/elements/channel/runtime.ts +24 -1
- package/src/elements/channel/test-helpers.ts +60 -0
- package/src/elements/channel/whatsapp-compliance.test.ts +124 -0
- package/src/elements/store/cache.ts +1 -1
- package/src/elements/store/emit-drizzle.ts +43 -9
- package/src/elements/store/runtime.ts +1 -1
- package/src/elements/store/schema-decl.test.ts +2 -0
- package/src/elements/store/schema-decl.ts +15 -0
- package/src/elements/store/seed.ts +1 -1
- package/src/index.ts +1 -0
- package/src/kernel/app.ts +117 -10
- package/src/kernel/boot-bind/signal.ts +6 -2
- package/src/kernel/boot-bind/store.ts +2 -1
- package/src/kernel/boot.test.ts +6 -5
- package/src/kernel/boot.ts +8 -3
- package/src/kernel/compensate.test.ts +131 -0
- package/src/kernel/correlation.test.ts +108 -0
- package/src/kernel/effect-timing.test.ts +82 -0
- package/src/kernel/flow.ts +38 -0
- package/src/kernel/fx-runs.test.ts +49 -0
- package/src/kernel/fx.test.ts +14 -0
- package/src/kernel/fx.ts +111 -1
- package/src/manifest/types.ts +8 -2
- package/src/runs/collect.ts +3 -0
- package/src/runs/export-otlp.ts +64 -0
- package/src/runs/index.ts +16 -0
- package/src/runs/parquet.ts +9 -0
- package/src/runs/types.ts +5 -0
- package/src/runs/window.test.ts +68 -0
- package/src/runs/window.ts +148 -0
- package/src/runtime/boot-warn.test.ts +45 -0
- package/src/runtime/boot-warn.ts +17 -0
- package/src/runtime/dev-request-log.ts +5 -5
- package/src/term.test.ts +95 -10
- package/src/term.ts +369 -14
- package/src/console/ui/dist/assets/panel-overview-DONDzBd2.js +0 -1
- package/src/console/ui/dist/assets/panel-runs-D5zf-D9c.js +0 -1
|
@@ -1,65 +1,446 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Curated
|
|
2
|
+
* Curated model catalog for `oke ai setup` / create-oke AI wizard.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Tiers map to machine RAM classes (not download size). Manual lists show
|
|
5
|
+
* up to 10 entries with modalities.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
/** Role a model can fill in the wizard. */
|
|
9
9
|
export type CatalogRole = "chat" | "vision" | "embed";
|
|
10
10
|
|
|
11
|
-
/**
|
|
11
|
+
/** Speed / quality tier for the Select model step. */
|
|
12
|
+
export type ModelTier = "ultra-fast" | "fast" | "balanced" | "smart";
|
|
13
|
+
|
|
14
|
+
/** Capability tags shown in manual model lists. */
|
|
15
|
+
export type ModelModality = "text" | "vision" | "code" | "reasoning";
|
|
16
|
+
|
|
17
|
+
/** One curated local model entry (Ollama tag or Docker Hub `ai/` id). */
|
|
12
18
|
export type CatalogModel = {
|
|
13
19
|
readonly id: string;
|
|
14
20
|
readonly label: string;
|
|
15
21
|
readonly hint: string;
|
|
16
22
|
readonly role: CatalogRole;
|
|
17
23
|
readonly recommended?: boolean;
|
|
18
|
-
/** Approximate RAM (GB) needed to run comfortably. */
|
|
24
|
+
/** Approximate RAM (GB) needed to run comfortably (machine tier). */
|
|
19
25
|
readonly ramGb: number;
|
|
26
|
+
readonly tier: ModelTier;
|
|
27
|
+
readonly modalities: readonly ModelModality[];
|
|
20
28
|
};
|
|
21
29
|
|
|
22
|
-
/**
|
|
30
|
+
/** Tier menu rows (prompt labels). */
|
|
31
|
+
export const MODEL_TIERS: readonly {
|
|
32
|
+
readonly value: ModelTier;
|
|
33
|
+
readonly label: string;
|
|
34
|
+
readonly hint: string;
|
|
35
|
+
readonly minRamGb: number;
|
|
36
|
+
readonly maxRamGb: number;
|
|
37
|
+
}[] = [
|
|
38
|
+
{
|
|
39
|
+
value: "ultra-fast",
|
|
40
|
+
label: "Ultra Fast",
|
|
41
|
+
hint: "~1GB–~2GB RAM",
|
|
42
|
+
minRamGb: 1,
|
|
43
|
+
maxRamGb: 2,
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
value: "fast",
|
|
47
|
+
label: "Fast",
|
|
48
|
+
hint: "~4GB–~8GB RAM",
|
|
49
|
+
minRamGb: 4,
|
|
50
|
+
maxRamGb: 8,
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
value: "balanced",
|
|
54
|
+
label: "Balanced",
|
|
55
|
+
hint: "~8GB–~16GB RAM",
|
|
56
|
+
minRamGb: 8,
|
|
57
|
+
maxRamGb: 16,
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
value: "smart",
|
|
61
|
+
label: "Smart",
|
|
62
|
+
hint: "~24GB–~32GB RAM",
|
|
63
|
+
minRamGb: 24,
|
|
64
|
+
maxRamGb: 32,
|
|
65
|
+
},
|
|
66
|
+
];
|
|
67
|
+
|
|
68
|
+
/** Chat / multimodal models (curated; manual pick shows ≤10 per tier). */
|
|
23
69
|
export const CHAT_MODELS: readonly CatalogModel[] = [
|
|
70
|
+
// Ultra Fast (~1–2GB)
|
|
71
|
+
{
|
|
72
|
+
id: "smollm2:135m",
|
|
73
|
+
label: "SmolLM2 135M",
|
|
74
|
+
hint: "Tiny · on-device",
|
|
75
|
+
role: "chat",
|
|
76
|
+
ramGb: 1,
|
|
77
|
+
tier: "ultra-fast",
|
|
78
|
+
modalities: ["text"],
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
id: "qwen2.5:0.5b",
|
|
82
|
+
label: "Qwen2.5 0.5B",
|
|
83
|
+
hint: "Smallest Qwen",
|
|
84
|
+
role: "chat",
|
|
85
|
+
ramGb: 1,
|
|
86
|
+
tier: "ultra-fast",
|
|
87
|
+
modalities: ["text", "code"],
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
id: "llama3.2:1b",
|
|
91
|
+
label: "Llama 3.2 1B",
|
|
92
|
+
hint: "Meta tiny",
|
|
93
|
+
role: "chat",
|
|
94
|
+
ramGb: 2,
|
|
95
|
+
tier: "ultra-fast",
|
|
96
|
+
modalities: ["text"],
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
id: "gemma3:1b",
|
|
100
|
+
label: "Gemma 3 1B",
|
|
101
|
+
hint: "Google tiny",
|
|
102
|
+
role: "chat",
|
|
103
|
+
ramGb: 2,
|
|
104
|
+
tier: "ultra-fast",
|
|
105
|
+
modalities: ["text"],
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
id: "qwen2.5:1.5b",
|
|
109
|
+
label: "Qwen2.5 1.5B",
|
|
110
|
+
hint: "Small coding",
|
|
111
|
+
role: "chat",
|
|
112
|
+
recommended: true,
|
|
113
|
+
ramGb: 2,
|
|
114
|
+
tier: "ultra-fast",
|
|
115
|
+
modalities: ["text", "code"],
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
id: "deepseek-r1:1.5b",
|
|
119
|
+
label: "DeepSeek R1 1.5B",
|
|
120
|
+
hint: "Tiny reasoning",
|
|
121
|
+
role: "chat",
|
|
122
|
+
ramGb: 2,
|
|
123
|
+
tier: "ultra-fast",
|
|
124
|
+
modalities: ["text", "reasoning"],
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
id: "moondream",
|
|
128
|
+
label: "Moondream",
|
|
129
|
+
hint: "Tiny vision",
|
|
130
|
+
role: "chat",
|
|
131
|
+
ramGb: 2,
|
|
132
|
+
tier: "ultra-fast",
|
|
133
|
+
modalities: ["text", "vision"],
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
id: "tinydolphin",
|
|
137
|
+
label: "TinyDolphin",
|
|
138
|
+
hint: "Ultra-compact chat",
|
|
139
|
+
role: "chat",
|
|
140
|
+
ramGb: 1,
|
|
141
|
+
tier: "ultra-fast",
|
|
142
|
+
modalities: ["text"],
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
id: "phi3:mini",
|
|
146
|
+
label: "Phi-3 Mini",
|
|
147
|
+
hint: "Microsoft compact",
|
|
148
|
+
role: "chat",
|
|
149
|
+
ramGb: 2,
|
|
150
|
+
tier: "ultra-fast",
|
|
151
|
+
modalities: ["text", "code"],
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
id: "stable-code:3b",
|
|
155
|
+
label: "Stable Code 3B",
|
|
156
|
+
hint: "Compact coder",
|
|
157
|
+
role: "chat",
|
|
158
|
+
ramGb: 2,
|
|
159
|
+
tier: "ultra-fast",
|
|
160
|
+
modalities: ["text", "code"],
|
|
161
|
+
},
|
|
162
|
+
|
|
163
|
+
// Fast (~4–8GB)
|
|
164
|
+
{
|
|
165
|
+
id: "llama3.2:3b",
|
|
166
|
+
label: "Llama 3.2 3B",
|
|
167
|
+
hint: "Small general",
|
|
168
|
+
role: "chat",
|
|
169
|
+
ramGb: 4,
|
|
170
|
+
tier: "fast",
|
|
171
|
+
modalities: ["text"],
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
id: "phi4-mini",
|
|
175
|
+
label: "Phi-4 Mini",
|
|
176
|
+
hint: "Strong small",
|
|
177
|
+
role: "chat",
|
|
178
|
+
ramGb: 4,
|
|
179
|
+
tier: "fast",
|
|
180
|
+
modalities: ["text", "code"],
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
id: "qwen2.5:3b",
|
|
184
|
+
label: "Qwen2.5 3B",
|
|
185
|
+
hint: "Coding · small",
|
|
186
|
+
role: "chat",
|
|
187
|
+
ramGb: 4,
|
|
188
|
+
tier: "fast",
|
|
189
|
+
modalities: ["text", "code"],
|
|
190
|
+
},
|
|
24
191
|
{
|
|
25
192
|
id: "gemma4:e4b",
|
|
26
193
|
label: "Gemma 4 4B",
|
|
27
|
-
hint: "Fast
|
|
194
|
+
hint: "Fast default",
|
|
28
195
|
role: "chat",
|
|
29
196
|
recommended: true,
|
|
30
197
|
ramGb: 8,
|
|
198
|
+
tier: "fast",
|
|
199
|
+
modalities: ["text"],
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
id: "qwen2.5:7b",
|
|
203
|
+
label: "Qwen2.5 7B",
|
|
204
|
+
hint: "Coding workhorse",
|
|
205
|
+
role: "chat",
|
|
206
|
+
ramGb: 8,
|
|
207
|
+
tier: "fast",
|
|
208
|
+
modalities: ["text", "code"],
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
id: "mistral:7b",
|
|
212
|
+
label: "Mistral 7B",
|
|
213
|
+
hint: "General purpose",
|
|
214
|
+
role: "chat",
|
|
215
|
+
ramGb: 8,
|
|
216
|
+
tier: "fast",
|
|
217
|
+
modalities: ["text"],
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
id: "deepseek-r1:7b",
|
|
221
|
+
label: "DeepSeek R1 7B",
|
|
222
|
+
hint: "Reasoning",
|
|
223
|
+
role: "chat",
|
|
224
|
+
ramGb: 8,
|
|
225
|
+
tier: "fast",
|
|
226
|
+
modalities: ["text", "reasoning"],
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
id: "llava:7b",
|
|
230
|
+
label: "LLaVA 7B",
|
|
231
|
+
hint: "Vision-language",
|
|
232
|
+
role: "chat",
|
|
233
|
+
ramGb: 8,
|
|
234
|
+
tier: "fast",
|
|
235
|
+
modalities: ["text", "vision"],
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
id: "qwen3-vl:4b",
|
|
239
|
+
label: "Qwen3-VL 4B",
|
|
240
|
+
hint: "Vision-language",
|
|
241
|
+
role: "chat",
|
|
242
|
+
ramGb: 8,
|
|
243
|
+
tier: "fast",
|
|
244
|
+
modalities: ["text", "vision"],
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
id: "granite3.3:8b",
|
|
248
|
+
label: "Granite 3.3 8B",
|
|
249
|
+
hint: "IBM enterprise",
|
|
250
|
+
role: "chat",
|
|
251
|
+
ramGb: 8,
|
|
252
|
+
tier: "fast",
|
|
253
|
+
modalities: ["text", "code"],
|
|
254
|
+
},
|
|
255
|
+
|
|
256
|
+
// Balanced (~8–16GB)
|
|
257
|
+
{
|
|
258
|
+
id: "deepseek-r1:8b",
|
|
259
|
+
label: "DeepSeek R1 8B",
|
|
260
|
+
hint: "Strong reasoning",
|
|
261
|
+
role: "chat",
|
|
262
|
+
ramGb: 10,
|
|
263
|
+
tier: "balanced",
|
|
264
|
+
modalities: ["text", "reasoning"],
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
id: "llama3.1:8b",
|
|
268
|
+
label: "Llama 3.1 8B",
|
|
269
|
+
hint: "General purpose",
|
|
270
|
+
role: "chat",
|
|
271
|
+
ramGb: 10,
|
|
272
|
+
tier: "balanced",
|
|
273
|
+
modalities: ["text"],
|
|
31
274
|
},
|
|
32
275
|
{
|
|
33
276
|
id: "qwen3.5:9b",
|
|
34
277
|
label: "Qwen3.5 9B",
|
|
35
|
-
hint: "Better coding
|
|
278
|
+
hint: "Better coding",
|
|
279
|
+
role: "chat",
|
|
280
|
+
recommended: true,
|
|
281
|
+
ramGb: 16,
|
|
282
|
+
tier: "balanced",
|
|
283
|
+
modalities: ["text", "code"],
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
id: "llama4:scout",
|
|
287
|
+
label: "Llama 4 Scout",
|
|
288
|
+
hint: "General purpose",
|
|
289
|
+
role: "chat",
|
|
290
|
+
ramGb: 16,
|
|
291
|
+
tier: "balanced",
|
|
292
|
+
modalities: ["text"],
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
id: "qwen2.5:14b",
|
|
296
|
+
label: "Qwen2.5 14B",
|
|
297
|
+
hint: "Larger Qwen",
|
|
298
|
+
role: "chat",
|
|
299
|
+
ramGb: 16,
|
|
300
|
+
tier: "balanced",
|
|
301
|
+
modalities: ["text", "code"],
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
id: "qwen2.5-coder:14b",
|
|
305
|
+
label: "Qwen2.5 Coder 14B",
|
|
306
|
+
hint: "Coding specialist",
|
|
307
|
+
role: "chat",
|
|
308
|
+
ramGb: 16,
|
|
309
|
+
tier: "balanced",
|
|
310
|
+
modalities: ["text", "code"],
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
id: "mistral-nemo",
|
|
314
|
+
label: "Mistral Nemo",
|
|
315
|
+
hint: "12B-class general",
|
|
316
|
+
role: "chat",
|
|
317
|
+
ramGb: 12,
|
|
318
|
+
tier: "balanced",
|
|
319
|
+
modalities: ["text"],
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
id: "llava:13b",
|
|
323
|
+
label: "LLaVA 13B",
|
|
324
|
+
hint: "Vision-language",
|
|
325
|
+
role: "chat",
|
|
326
|
+
ramGb: 16,
|
|
327
|
+
tier: "balanced",
|
|
328
|
+
modalities: ["text", "vision"],
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
id: "gemma2:9b",
|
|
332
|
+
label: "Gemma 2 9B",
|
|
333
|
+
hint: "Google mid",
|
|
334
|
+
role: "chat",
|
|
335
|
+
ramGb: 12,
|
|
336
|
+
tier: "balanced",
|
|
337
|
+
modalities: ["text"],
|
|
338
|
+
},
|
|
339
|
+
{
|
|
340
|
+
id: "command-r",
|
|
341
|
+
label: "Command R",
|
|
342
|
+
hint: "Cohere RAG-friendly",
|
|
36
343
|
role: "chat",
|
|
37
344
|
ramGb: 16,
|
|
345
|
+
tier: "balanced",
|
|
346
|
+
modalities: ["text"],
|
|
347
|
+
},
|
|
348
|
+
|
|
349
|
+
// Smart (~24–32GB)
|
|
350
|
+
{
|
|
351
|
+
id: "gemma2:27b",
|
|
352
|
+
label: "Gemma 2 27B",
|
|
353
|
+
hint: "Large Gemma",
|
|
354
|
+
role: "chat",
|
|
355
|
+
ramGb: 24,
|
|
356
|
+
tier: "smart",
|
|
357
|
+
modalities: ["text"],
|
|
38
358
|
},
|
|
39
359
|
{
|
|
40
360
|
id: "qwen3.5:27b",
|
|
41
361
|
label: "Qwen3.5 27B",
|
|
42
|
-
hint: "Best local quality
|
|
362
|
+
hint: "Best local quality",
|
|
43
363
|
role: "chat",
|
|
364
|
+
recommended: true,
|
|
44
365
|
ramGb: 32,
|
|
366
|
+
tier: "smart",
|
|
367
|
+
modalities: ["text", "code"],
|
|
45
368
|
},
|
|
46
369
|
{
|
|
47
|
-
id: "
|
|
48
|
-
label: "
|
|
49
|
-
hint: "
|
|
370
|
+
id: "qwen2.5:32b",
|
|
371
|
+
label: "Qwen2.5 32B",
|
|
372
|
+
hint: "Large Qwen",
|
|
50
373
|
role: "chat",
|
|
51
|
-
ramGb:
|
|
374
|
+
ramGb: 32,
|
|
375
|
+
tier: "smart",
|
|
376
|
+
modalities: ["text", "code"],
|
|
52
377
|
},
|
|
53
378
|
{
|
|
54
|
-
id: "
|
|
55
|
-
label: "
|
|
56
|
-
hint: "
|
|
379
|
+
id: "qwen2.5-coder:32b",
|
|
380
|
+
label: "Qwen2.5 Coder 32B",
|
|
381
|
+
hint: "Large coder",
|
|
57
382
|
role: "chat",
|
|
58
|
-
ramGb:
|
|
383
|
+
ramGb: 32,
|
|
384
|
+
tier: "smart",
|
|
385
|
+
modalities: ["text", "code"],
|
|
386
|
+
},
|
|
387
|
+
{
|
|
388
|
+
id: "deepseek-r1:32b",
|
|
389
|
+
label: "DeepSeek R1 32B",
|
|
390
|
+
hint: "Large reasoning",
|
|
391
|
+
role: "chat",
|
|
392
|
+
ramGb: 32,
|
|
393
|
+
tier: "smart",
|
|
394
|
+
modalities: ["text", "reasoning"],
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
id: "mixtral:8x7b",
|
|
398
|
+
label: "Mixtral 8x7B",
|
|
399
|
+
hint: "MoE general",
|
|
400
|
+
role: "chat",
|
|
401
|
+
ramGb: 26,
|
|
402
|
+
tier: "smart",
|
|
403
|
+
modalities: ["text"],
|
|
404
|
+
},
|
|
405
|
+
{
|
|
406
|
+
id: "command-r-plus",
|
|
407
|
+
label: "Command R+",
|
|
408
|
+
hint: "Cohere large",
|
|
409
|
+
role: "chat",
|
|
410
|
+
ramGb: 32,
|
|
411
|
+
tier: "smart",
|
|
412
|
+
modalities: ["text"],
|
|
413
|
+
},
|
|
414
|
+
{
|
|
415
|
+
id: "mistral-small:24b",
|
|
416
|
+
label: "Mistral Small 24B",
|
|
417
|
+
hint: "Mistral mid-large",
|
|
418
|
+
role: "chat",
|
|
419
|
+
ramGb: 24,
|
|
420
|
+
tier: "smart",
|
|
421
|
+
modalities: ["text"],
|
|
422
|
+
},
|
|
423
|
+
{
|
|
424
|
+
id: "llama3.1:70b",
|
|
425
|
+
label: "Llama 3.1 70B",
|
|
426
|
+
hint: "Needs ~40GB+; listed for reference",
|
|
427
|
+
role: "chat",
|
|
428
|
+
ramGb: 40,
|
|
429
|
+
tier: "smart",
|
|
430
|
+
modalities: ["text"],
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
id: "qwen2.5:72b",
|
|
434
|
+
label: "Qwen2.5 72B",
|
|
435
|
+
hint: "Needs ~48GB+; listed for reference",
|
|
436
|
+
role: "chat",
|
|
437
|
+
ramGb: 48,
|
|
438
|
+
tier: "smart",
|
|
439
|
+
modalities: ["text", "code"],
|
|
59
440
|
},
|
|
60
441
|
];
|
|
61
442
|
|
|
62
|
-
/** Vision
|
|
443
|
+
/** Vision-only short list (legacy / optional). */
|
|
63
444
|
export const VISION_MODELS: readonly CatalogModel[] = [
|
|
64
445
|
{
|
|
65
446
|
id: "qwen3-vl:4b",
|
|
@@ -68,17 +449,21 @@ export const VISION_MODELS: readonly CatalogModel[] = [
|
|
|
68
449
|
role: "vision",
|
|
69
450
|
recommended: true,
|
|
70
451
|
ramGb: 8,
|
|
452
|
+
tier: "fast",
|
|
453
|
+
modalities: ["text", "vision"],
|
|
71
454
|
},
|
|
72
455
|
{
|
|
73
|
-
id: "
|
|
74
|
-
label: "
|
|
75
|
-
hint: "
|
|
456
|
+
id: "llava:7b",
|
|
457
|
+
label: "LLaVA 7B",
|
|
458
|
+
hint: "Vision-language",
|
|
76
459
|
role: "vision",
|
|
77
460
|
ramGb: 8,
|
|
461
|
+
tier: "fast",
|
|
462
|
+
modalities: ["text", "vision"],
|
|
78
463
|
},
|
|
79
464
|
];
|
|
80
465
|
|
|
81
|
-
/** Embedding models. */
|
|
466
|
+
/** Embedding models (applied automatically — no download prompt). */
|
|
82
467
|
export const EMBED_MODELS: readonly CatalogModel[] = [
|
|
83
468
|
{
|
|
84
469
|
id: "nomic-embed-text",
|
|
@@ -87,6 +472,8 @@ export const EMBED_MODELS: readonly CatalogModel[] = [
|
|
|
87
472
|
role: "embed",
|
|
88
473
|
recommended: true,
|
|
89
474
|
ramGb: 1,
|
|
475
|
+
tier: "ultra-fast",
|
|
476
|
+
modalities: ["text"],
|
|
90
477
|
},
|
|
91
478
|
{
|
|
92
479
|
id: "bge-m3",
|
|
@@ -94,6 +481,8 @@ export const EMBED_MODELS: readonly CatalogModel[] = [
|
|
|
94
481
|
hint: "Multilingual + long docs",
|
|
95
482
|
role: "embed",
|
|
96
483
|
ramGb: 2,
|
|
484
|
+
tier: "ultra-fast",
|
|
485
|
+
modalities: ["text"],
|
|
97
486
|
},
|
|
98
487
|
{
|
|
99
488
|
id: "jina-embeddings-v4",
|
|
@@ -101,6 +490,8 @@ export const EMBED_MODELS: readonly CatalogModel[] = [
|
|
|
101
490
|
hint: "High-quality embedder",
|
|
102
491
|
role: "embed",
|
|
103
492
|
ramGb: 2,
|
|
493
|
+
tier: "ultra-fast",
|
|
494
|
+
modalities: ["text"],
|
|
104
495
|
},
|
|
105
496
|
];
|
|
106
497
|
|
|
@@ -112,25 +503,56 @@ export const ALL_CURATED: readonly CatalogModel[] = [
|
|
|
112
503
|
];
|
|
113
504
|
|
|
114
505
|
/**
|
|
115
|
-
*
|
|
506
|
+
* Sort catalog rows by RAM ascending, then label (stable pick lists).
|
|
507
|
+
*
|
|
508
|
+
* @param models - Catalog entries
|
|
509
|
+
*/
|
|
510
|
+
function byRamThenLabel(models: readonly CatalogModel[]): CatalogModel[] {
|
|
511
|
+
return [...models].sort((a, b) => a.ramGb - b.ramGb || a.label.localeCompare(b.label));
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
/**
|
|
515
|
+
* Chat models in a tier (≤10 for manual pick), ordered by RAM.
|
|
516
|
+
*
|
|
517
|
+
* @param tier - Speed / quality tier
|
|
518
|
+
*/
|
|
519
|
+
export function modelsForTier(tier: ModelTier): readonly CatalogModel[] {
|
|
520
|
+
return byRamThenLabel(CHAT_MODELS.filter((m) => m.tier === tier)).slice(0, 10);
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/**
|
|
524
|
+
* Recommended chat model for a tier (falls back to first in tier).
|
|
116
525
|
*
|
|
117
|
-
*
|
|
526
|
+
* @param tier - Selected tier
|
|
527
|
+
* @param totalRamGb - Prefer models that fit when RAM is known
|
|
528
|
+
*/
|
|
529
|
+
export function recommendForTier(tier: ModelTier, totalRamGb: number | null = null): CatalogModel {
|
|
530
|
+
const list = modelsForTier(tier);
|
|
531
|
+
const headroom = 4;
|
|
532
|
+
const fits =
|
|
533
|
+
totalRamGb !== null && Number.isFinite(totalRamGb)
|
|
534
|
+
? list.filter((m) => m.ramGb + headroom <= totalRamGb || m.ramGb <= totalRamGb)
|
|
535
|
+
: list;
|
|
536
|
+
const pool = fits.length > 0 ? fits : list;
|
|
537
|
+
return pool.find((m) => m.recommended) ?? pool[pool.length - 1] ?? list[0]!;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
/**
|
|
541
|
+
* Recommend a chat model for the host RAM (comfortable headroom).
|
|
118
542
|
*
|
|
119
543
|
* @param totalRamGb - Detected total system RAM in GB (or null)
|
|
120
544
|
*/
|
|
121
545
|
export function recommendChatModel(totalRamGb: number | null): CatalogModel {
|
|
122
|
-
// Keep catalog free of recommend.ts cycles — same rules as comfortableChatModels.
|
|
123
546
|
const HEADROOM = 4;
|
|
124
547
|
const sorted = [...CHAT_MODELS].sort((a, b) => a.ramGb - b.ramGb);
|
|
125
548
|
const smallest = sorted[0]!;
|
|
126
549
|
if (totalRamGb === null || !Number.isFinite(totalRamGb)) {
|
|
127
|
-
return CHAT_MODELS.find((m) => m.recommended) ?? smallest;
|
|
550
|
+
return CHAT_MODELS.find((m) => m.recommended && m.tier === "fast") ?? smallest;
|
|
128
551
|
}
|
|
129
552
|
const comfortable = sorted.filter(
|
|
130
553
|
(m) => (m.id === smallest.id && m.ramGb <= totalRamGb) || m.ramGb + HEADROOM <= totalRamGb,
|
|
131
554
|
);
|
|
132
555
|
if (comfortable.length > 0) return comfortable[comfortable.length - 1]!;
|
|
133
|
-
// Fall back to largest that meets the machine tier (tight but runnable).
|
|
134
556
|
const tierOk = sorted.filter((m) => m.ramGb <= totalRamGb);
|
|
135
557
|
return tierOk.length > 0 ? tierOk[tierOk.length - 1]! : smallest;
|
|
136
558
|
}
|
|
@@ -145,6 +567,11 @@ export function recommendForRole(role: "vision" | "embed"): CatalogModel {
|
|
|
145
567
|
return list.find((m) => m.recommended) ?? list[0]!;
|
|
146
568
|
}
|
|
147
569
|
|
|
570
|
+
/** Format modalities for a list row. */
|
|
571
|
+
export function formatModalities(modalities: readonly ModelModality[]): string {
|
|
572
|
+
return modalities.join(" · ");
|
|
573
|
+
}
|
|
574
|
+
|
|
148
575
|
/** Thin cloud provider menu (non-Ollama). */
|
|
149
576
|
export const CLOUD_PROVIDERS = [
|
|
150
577
|
{
|
|
@@ -152,31 +579,42 @@ export const CLOUD_PROVIDERS = [
|
|
|
152
579
|
label: "OpenAI",
|
|
153
580
|
driver: "openai-compatible" as const,
|
|
154
581
|
baseUrl: "https://api.openai.com/v1",
|
|
582
|
+
apiKeyEnv: "OPENAI_API_KEY",
|
|
583
|
+
},
|
|
584
|
+
{
|
|
585
|
+
value: "anthropic",
|
|
586
|
+
label: "Anthropic",
|
|
587
|
+
driver: "anthropic" as const,
|
|
588
|
+
baseUrl: undefined,
|
|
589
|
+
apiKeyEnv: "ANTHROPIC_API_KEY",
|
|
155
590
|
},
|
|
156
|
-
{ value: "anthropic", label: "Anthropic", driver: "anthropic" as const, baseUrl: undefined },
|
|
157
591
|
{
|
|
158
592
|
value: "gemini",
|
|
159
593
|
label: "Gemini",
|
|
160
594
|
driver: "openai-compatible" as const,
|
|
161
595
|
baseUrl: undefined,
|
|
596
|
+
apiKeyEnv: "OPENAI_API_KEY",
|
|
162
597
|
},
|
|
163
598
|
{
|
|
164
599
|
value: "lmstudio",
|
|
165
600
|
label: "LM Studio",
|
|
166
601
|
driver: "openai-compatible" as const,
|
|
167
602
|
baseUrl: "http://127.0.0.1:1234/v1",
|
|
603
|
+
apiKeyEnv: undefined,
|
|
168
604
|
},
|
|
169
605
|
{
|
|
170
606
|
value: "openrouter",
|
|
171
607
|
label: "OpenRouter",
|
|
172
608
|
driver: "openai-compatible" as const,
|
|
173
609
|
baseUrl: "https://openrouter.ai/api/v1",
|
|
610
|
+
apiKeyEnv: "OPENAI_API_KEY",
|
|
174
611
|
},
|
|
175
612
|
{
|
|
176
613
|
value: "custom",
|
|
177
614
|
label: "Custom OpenAI Compatible",
|
|
178
615
|
driver: "openai-compatible" as const,
|
|
179
616
|
baseUrl: undefined,
|
|
617
|
+
apiKeyEnv: "OPENAI_API_KEY",
|
|
180
618
|
},
|
|
181
619
|
] as const;
|
|
182
620
|
|
|
@@ -188,25 +626,79 @@ export type CloudModel = {
|
|
|
188
626
|
readonly recommended?: boolean;
|
|
189
627
|
};
|
|
190
628
|
|
|
191
|
-
/**
|
|
629
|
+
/** Up to 10 curated / “latest” chat models per cloud provider. */
|
|
192
630
|
export const CLOUD_CHAT_MODELS: Readonly<Record<string, readonly CloudModel[]>> = {
|
|
193
631
|
openai: [
|
|
194
|
-
{ id: "gpt-
|
|
195
|
-
{ id: "gpt-
|
|
632
|
+
{ id: "gpt-4.1-nano", label: "GPT-4.1 nano", hint: "Fastest · cheapest" },
|
|
633
|
+
{ id: "gpt-4.1-mini", label: "GPT-4.1 mini", hint: "Fast · cheap" },
|
|
634
|
+
{ id: "gpt-4o-mini", label: "GPT-4o mini", hint: "Fast default", recommended: true },
|
|
196
635
|
{ id: "gpt-4.1", label: "GPT-4.1", hint: "Latest flagship" },
|
|
636
|
+
{ id: "gpt-4o", label: "GPT-4o", hint: "Strong general / vision" },
|
|
197
637
|
{ id: "o4-mini", label: "o4-mini", hint: "Reasoning · lower cost" },
|
|
638
|
+
{ id: "o3-mini", label: "o3-mini", hint: "Reasoning" },
|
|
639
|
+
{ id: "o3", label: "o3", hint: "Deep reasoning" },
|
|
640
|
+
{ id: "gpt-4.1-mini-2025-04-14", label: "GPT-4.1 mini (dated)", hint: "Pinned snapshot" },
|
|
641
|
+
{ id: "chatgpt-4o-latest", label: "ChatGPT-4o latest", hint: "ChatGPT-aligned" },
|
|
198
642
|
],
|
|
199
643
|
anthropic: [
|
|
644
|
+
{
|
|
645
|
+
id: "claude-haiku-4-20250514",
|
|
646
|
+
label: "Claude Haiku 4",
|
|
647
|
+
hint: "Fast · cheap",
|
|
648
|
+
},
|
|
200
649
|
{
|
|
201
650
|
id: "claude-sonnet-4-20250514",
|
|
202
651
|
label: "Claude Sonnet 4",
|
|
203
652
|
hint: "Balanced default",
|
|
204
653
|
recommended: true,
|
|
205
654
|
},
|
|
206
|
-
{
|
|
207
|
-
|
|
655
|
+
{
|
|
656
|
+
id: "claude-opus-4-20250514",
|
|
657
|
+
label: "Claude Opus 4",
|
|
658
|
+
hint: "Highest quality",
|
|
659
|
+
},
|
|
660
|
+
{
|
|
661
|
+
id: "claude-3-7-sonnet-20250219",
|
|
662
|
+
label: "Claude 3.7 Sonnet",
|
|
663
|
+
hint: "Prior mid-tier",
|
|
664
|
+
},
|
|
665
|
+
{
|
|
666
|
+
id: "claude-3-5-haiku-20241022",
|
|
667
|
+
label: "Claude 3.5 Haiku",
|
|
668
|
+
hint: "Prior Haiku",
|
|
669
|
+
},
|
|
670
|
+
{
|
|
671
|
+
id: "claude-3-5-sonnet-20241022",
|
|
672
|
+
label: "Claude 3.5 Sonnet",
|
|
673
|
+
hint: "Prior Sonnet",
|
|
674
|
+
},
|
|
675
|
+
{
|
|
676
|
+
id: "claude-3-opus-20240229",
|
|
677
|
+
label: "Claude 3 Opus",
|
|
678
|
+
hint: "Legacy Opus",
|
|
679
|
+
},
|
|
680
|
+
{
|
|
681
|
+
id: "claude-3-haiku-20240307",
|
|
682
|
+
label: "Claude 3 Haiku",
|
|
683
|
+
hint: "Legacy Haiku",
|
|
684
|
+
},
|
|
685
|
+
{
|
|
686
|
+
id: "claude-3-sonnet-20240229",
|
|
687
|
+
label: "Claude 3 Sonnet",
|
|
688
|
+
hint: "Legacy Sonnet",
|
|
689
|
+
},
|
|
690
|
+
{
|
|
691
|
+
id: "claude-2.1",
|
|
692
|
+
label: "Claude 2.1",
|
|
693
|
+
hint: "Legacy",
|
|
694
|
+
},
|
|
208
695
|
],
|
|
209
696
|
gemini: [
|
|
697
|
+
{
|
|
698
|
+
id: "gemini-2.5-flash-lite",
|
|
699
|
+
label: "Gemini 2.5 Flash-Lite",
|
|
700
|
+
hint: "Fastest",
|
|
701
|
+
},
|
|
210
702
|
{
|
|
211
703
|
id: "gemini-2.5-flash",
|
|
212
704
|
label: "Gemini 2.5 Flash",
|
|
@@ -214,6 +706,13 @@ export const CLOUD_CHAT_MODELS: Readonly<Record<string, readonly CloudModel[]>>
|
|
|
214
706
|
recommended: true,
|
|
215
707
|
},
|
|
216
708
|
{ id: "gemini-2.5-pro", label: "Gemini 2.5 Pro", hint: "Higher quality" },
|
|
709
|
+
{ id: "gemini-2.0-flash", label: "Gemini 2.0 Flash", hint: "Prior Flash" },
|
|
710
|
+
{ id: "gemini-2.0-flash-lite", label: "Gemini 2.0 Flash-Lite", hint: "Prior Lite" },
|
|
711
|
+
{ id: "gemini-1.5-flash", label: "Gemini 1.5 Flash", hint: "Legacy Flash" },
|
|
712
|
+
{ id: "gemini-1.5-pro", label: "Gemini 1.5 Pro", hint: "Legacy Pro" },
|
|
713
|
+
{ id: "gemini-2.5-flash-preview", label: "Gemini 2.5 Flash preview", hint: "Preview" },
|
|
714
|
+
{ id: "gemini-2.5-pro-preview", label: "Gemini 2.5 Pro preview", hint: "Preview" },
|
|
715
|
+
{ id: "gemma-3-27b-it", label: "Gemma 3 27B IT", hint: "Open weights via API" },
|
|
217
716
|
],
|
|
218
717
|
openrouter: [
|
|
219
718
|
{
|
|
@@ -222,8 +721,15 @@ export const CLOUD_CHAT_MODELS: Readonly<Record<string, readonly CloudModel[]>>
|
|
|
222
721
|
hint: "via OpenRouter",
|
|
223
722
|
recommended: true,
|
|
224
723
|
},
|
|
724
|
+
{ id: "openai/gpt-4.1", label: "GPT-4.1", hint: "via OpenRouter" },
|
|
725
|
+
{ id: "openai/o4-mini", label: "o4-mini", hint: "via OpenRouter" },
|
|
225
726
|
{ id: "anthropic/claude-sonnet-4", label: "Claude Sonnet 4", hint: "via OpenRouter" },
|
|
727
|
+
{ id: "anthropic/claude-opus-4", label: "Claude Opus 4", hint: "via OpenRouter" },
|
|
728
|
+
{ id: "anthropic/claude-haiku-4", label: "Claude Haiku 4", hint: "via OpenRouter" },
|
|
226
729
|
{ id: "google/gemini-2.5-flash", label: "Gemini 2.5 Flash", hint: "via OpenRouter" },
|
|
730
|
+
{ id: "google/gemini-2.5-pro", label: "Gemini 2.5 Pro", hint: "via OpenRouter" },
|
|
731
|
+
{ id: "meta-llama/llama-4-scout", label: "Llama 4 Scout", hint: "via OpenRouter" },
|
|
732
|
+
{ id: "deepseek/deepseek-r1", label: "DeepSeek R1", hint: "via OpenRouter" },
|
|
227
733
|
],
|
|
228
734
|
lmstudio: [
|
|
229
735
|
{
|
|
@@ -244,12 +750,21 @@ export const CLOUD_CHAT_MODELS: Readonly<Record<string, readonly CloudModel[]>>
|
|
|
244
750
|
};
|
|
245
751
|
|
|
246
752
|
/**
|
|
247
|
-
* Curated chat models for a cloud provider (
|
|
753
|
+
* Curated chat models for a cloud provider (deduped, ≤10).
|
|
248
754
|
*
|
|
249
755
|
* @param provider - Menu provider id
|
|
250
756
|
*/
|
|
251
757
|
export function cloudChatModels(provider: string): readonly CloudModel[] {
|
|
252
|
-
|
|
758
|
+
const list = CLOUD_CHAT_MODELS[provider] ?? [];
|
|
759
|
+
const seen = new Set<string>();
|
|
760
|
+
const out: CloudModel[] = [];
|
|
761
|
+
for (const m of list) {
|
|
762
|
+
if (seen.has(m.id)) continue;
|
|
763
|
+
seen.add(m.id);
|
|
764
|
+
out.push(m);
|
|
765
|
+
if (out.length >= 10) break;
|
|
766
|
+
}
|
|
767
|
+
return out;
|
|
253
768
|
}
|
|
254
769
|
|
|
255
770
|
/**
|
|
@@ -261,3 +776,769 @@ export function recommendCloudChat(provider: string): string {
|
|
|
261
776
|
const list = cloudChatModels(provider);
|
|
262
777
|
return list.find((m) => m.recommended)?.id ?? list[0]?.id ?? "gpt-4o-mini";
|
|
263
778
|
}
|
|
779
|
+
|
|
780
|
+
/**
|
|
781
|
+
* Curated Docker Hub `ai/` chat models for llama.cpp (`LLAMA_ARG_DOCKER_REPO`).
|
|
782
|
+
* Ids omit the `ai/` org prefix (llama.cpp default). ≥10 per tier; manual pick
|
|
783
|
+
* shows up to 20. HF-origin weights are only listed when published under
|
|
784
|
+
* Docker Hub [`ai/`](https://hub.docker.com/u/ai) (recipe cannot load raw HF ids).
|
|
785
|
+
*/
|
|
786
|
+
export const LLAMA_CPP_CHAT_MODELS: readonly CatalogModel[] = [
|
|
787
|
+
// Ultra Fast (~1–2GB)
|
|
788
|
+
{
|
|
789
|
+
id: "smollm2",
|
|
790
|
+
label: "SmolLM2",
|
|
791
|
+
hint: "Default · lightest",
|
|
792
|
+
role: "chat",
|
|
793
|
+
recommended: true,
|
|
794
|
+
ramGb: 1,
|
|
795
|
+
tier: "ultra-fast",
|
|
796
|
+
modalities: ["text"],
|
|
797
|
+
},
|
|
798
|
+
{
|
|
799
|
+
id: "smollm2:135M-Q4_K_M",
|
|
800
|
+
label: "SmolLM2 135M",
|
|
801
|
+
hint: "Tiny smoke test",
|
|
802
|
+
role: "chat",
|
|
803
|
+
ramGb: 1,
|
|
804
|
+
tier: "ultra-fast",
|
|
805
|
+
modalities: ["text"],
|
|
806
|
+
},
|
|
807
|
+
{
|
|
808
|
+
id: "functiongemma",
|
|
809
|
+
label: "FunctionGemma 270M",
|
|
810
|
+
hint: "Tool calling",
|
|
811
|
+
role: "chat",
|
|
812
|
+
ramGb: 1,
|
|
813
|
+
tier: "ultra-fast",
|
|
814
|
+
modalities: ["text", "code"],
|
|
815
|
+
},
|
|
816
|
+
{
|
|
817
|
+
id: "gemma3:270m",
|
|
818
|
+
label: "Gemma 3 270M",
|
|
819
|
+
hint: "Google tiny",
|
|
820
|
+
role: "chat",
|
|
821
|
+
ramGb: 1,
|
|
822
|
+
tier: "ultra-fast",
|
|
823
|
+
modalities: ["text"],
|
|
824
|
+
},
|
|
825
|
+
{
|
|
826
|
+
id: "granite-4.0-h-nano:350M-Q8_0",
|
|
827
|
+
label: "Granite 4.0 H Nano 350M",
|
|
828
|
+
hint: "IBM tiny",
|
|
829
|
+
role: "chat",
|
|
830
|
+
ramGb: 1,
|
|
831
|
+
tier: "ultra-fast",
|
|
832
|
+
modalities: ["text"],
|
|
833
|
+
},
|
|
834
|
+
{
|
|
835
|
+
id: "qwen3:0.6B-Q4_K_M",
|
|
836
|
+
label: "Qwen3 0.6B",
|
|
837
|
+
hint: "Small coding",
|
|
838
|
+
role: "chat",
|
|
839
|
+
ramGb: 2,
|
|
840
|
+
tier: "ultra-fast",
|
|
841
|
+
modalities: ["text", "code"],
|
|
842
|
+
},
|
|
843
|
+
{
|
|
844
|
+
id: "smolvlm:500M-Q8_0",
|
|
845
|
+
label: "SmolVLM 500M",
|
|
846
|
+
hint: "Tiny vision",
|
|
847
|
+
role: "chat",
|
|
848
|
+
ramGb: 2,
|
|
849
|
+
tier: "ultra-fast",
|
|
850
|
+
modalities: ["text", "vision"],
|
|
851
|
+
},
|
|
852
|
+
{
|
|
853
|
+
id: "llama3.2:1B-Q4_0",
|
|
854
|
+
label: "Llama 3.2 1B",
|
|
855
|
+
hint: "Meta tiny",
|
|
856
|
+
role: "chat",
|
|
857
|
+
ramGb: 2,
|
|
858
|
+
tier: "ultra-fast",
|
|
859
|
+
modalities: ["text"],
|
|
860
|
+
},
|
|
861
|
+
{
|
|
862
|
+
id: "granite-4.0-h-nano",
|
|
863
|
+
label: "Granite 4.0 H Nano 1B",
|
|
864
|
+
hint: "IBM nano",
|
|
865
|
+
role: "chat",
|
|
866
|
+
ramGb: 2,
|
|
867
|
+
tier: "ultra-fast",
|
|
868
|
+
modalities: ["text"],
|
|
869
|
+
},
|
|
870
|
+
{
|
|
871
|
+
id: "qwen2.5:0.5B-F16",
|
|
872
|
+
label: "Qwen2.5 0.5B",
|
|
873
|
+
hint: "Small coding",
|
|
874
|
+
role: "chat",
|
|
875
|
+
ramGb: 2,
|
|
876
|
+
tier: "ultra-fast",
|
|
877
|
+
modalities: ["text", "code"],
|
|
878
|
+
},
|
|
879
|
+
{
|
|
880
|
+
id: "smollm2:360M-Q4_K_M",
|
|
881
|
+
label: "SmolLM2 360M",
|
|
882
|
+
hint: "Small instruct",
|
|
883
|
+
role: "chat",
|
|
884
|
+
ramGb: 1,
|
|
885
|
+
tier: "ultra-fast",
|
|
886
|
+
modalities: ["text"],
|
|
887
|
+
},
|
|
888
|
+
{
|
|
889
|
+
id: "smollm2:135M-Q4_0",
|
|
890
|
+
label: "SmolLM2 135M Q4_0",
|
|
891
|
+
hint: "Tiny Q4_0",
|
|
892
|
+
role: "chat",
|
|
893
|
+
ramGb: 1,
|
|
894
|
+
tier: "ultra-fast",
|
|
895
|
+
modalities: ["text"],
|
|
896
|
+
},
|
|
897
|
+
{
|
|
898
|
+
id: "gemma3:270m-q4_K_M",
|
|
899
|
+
label: "Gemma 3 270M Q4",
|
|
900
|
+
hint: "Google tiny Q4",
|
|
901
|
+
role: "chat",
|
|
902
|
+
ramGb: 1,
|
|
903
|
+
tier: "ultra-fast",
|
|
904
|
+
modalities: ["text"],
|
|
905
|
+
},
|
|
906
|
+
{
|
|
907
|
+
id: "functiongemma:q4_K_M",
|
|
908
|
+
label: "FunctionGemma Q4",
|
|
909
|
+
hint: "Tool calling Q4",
|
|
910
|
+
role: "chat",
|
|
911
|
+
ramGb: 1,
|
|
912
|
+
tier: "ultra-fast",
|
|
913
|
+
modalities: ["text", "code"],
|
|
914
|
+
},
|
|
915
|
+
{
|
|
916
|
+
id: "qwen3:0.6B-Q4_0",
|
|
917
|
+
label: "Qwen3 0.6B Q4_0",
|
|
918
|
+
hint: "Small coding",
|
|
919
|
+
role: "chat",
|
|
920
|
+
ramGb: 2,
|
|
921
|
+
tier: "ultra-fast",
|
|
922
|
+
modalities: ["text", "code"],
|
|
923
|
+
},
|
|
924
|
+
{
|
|
925
|
+
id: "llama3.2:1B-Q8_0",
|
|
926
|
+
label: "Llama 3.2 1B Q8",
|
|
927
|
+
hint: "Meta tiny Q8",
|
|
928
|
+
role: "chat",
|
|
929
|
+
ramGb: 2,
|
|
930
|
+
tier: "ultra-fast",
|
|
931
|
+
modalities: ["text"],
|
|
932
|
+
},
|
|
933
|
+
{
|
|
934
|
+
id: "granite-4.0-nano:350M-BF16",
|
|
935
|
+
label: "Granite 4.0 Nano 350M",
|
|
936
|
+
hint: "IBM nano",
|
|
937
|
+
role: "chat",
|
|
938
|
+
ramGb: 2,
|
|
939
|
+
tier: "ultra-fast",
|
|
940
|
+
modalities: ["text"],
|
|
941
|
+
},
|
|
942
|
+
{
|
|
943
|
+
id: "smolvlm",
|
|
944
|
+
label: "SmolVLM",
|
|
945
|
+
hint: "Tiny vision default",
|
|
946
|
+
role: "chat",
|
|
947
|
+
ramGb: 2,
|
|
948
|
+
tier: "ultra-fast",
|
|
949
|
+
modalities: ["text", "vision"],
|
|
950
|
+
},
|
|
951
|
+
{
|
|
952
|
+
id: "granite3.3:2b",
|
|
953
|
+
label: "Granite 3.3 2B",
|
|
954
|
+
hint: "IBM 2B",
|
|
955
|
+
role: "chat",
|
|
956
|
+
ramGb: 2,
|
|
957
|
+
tier: "ultra-fast",
|
|
958
|
+
modalities: ["text", "code"],
|
|
959
|
+
},
|
|
960
|
+
{
|
|
961
|
+
id: "gemma3:270m-q8_0",
|
|
962
|
+
label: "Gemma 3 270M Q8",
|
|
963
|
+
hint: "Google tiny Q8",
|
|
964
|
+
role: "chat",
|
|
965
|
+
ramGb: 1,
|
|
966
|
+
tier: "ultra-fast",
|
|
967
|
+
modalities: ["text"],
|
|
968
|
+
},
|
|
969
|
+
// Fast (~4–8GB) — Gemma 4 · Qwen near the top
|
|
970
|
+
{
|
|
971
|
+
id: "llama3.2",
|
|
972
|
+
label: "Llama 3.2 3B",
|
|
973
|
+
hint: "Balanced local chat",
|
|
974
|
+
role: "chat",
|
|
975
|
+
recommended: true,
|
|
976
|
+
ramGb: 4,
|
|
977
|
+
tier: "fast",
|
|
978
|
+
modalities: ["text"],
|
|
979
|
+
},
|
|
980
|
+
{
|
|
981
|
+
id: "gemma4:e2b-q4_K_M",
|
|
982
|
+
label: "Gemma 4 E2B",
|
|
983
|
+
hint: "Popular · multimodal",
|
|
984
|
+
role: "chat",
|
|
985
|
+
ramGb: 8,
|
|
986
|
+
tier: "fast",
|
|
987
|
+
modalities: ["text", "vision"],
|
|
988
|
+
},
|
|
989
|
+
{
|
|
990
|
+
id: "qwen3:4B-UD-Q4_K_XL",
|
|
991
|
+
label: "Qwen3 4B",
|
|
992
|
+
hint: "Popular · coding · agents",
|
|
993
|
+
role: "chat",
|
|
994
|
+
ramGb: 6,
|
|
995
|
+
tier: "fast",
|
|
996
|
+
modalities: ["text", "code"],
|
|
997
|
+
},
|
|
998
|
+
{
|
|
999
|
+
id: "qwen2.5:3B-Q4_K_M",
|
|
1000
|
+
label: "Qwen2.5 3B",
|
|
1001
|
+
hint: "Coding",
|
|
1002
|
+
role: "chat",
|
|
1003
|
+
ramGb: 4,
|
|
1004
|
+
tier: "fast",
|
|
1005
|
+
modalities: ["text", "code"],
|
|
1006
|
+
},
|
|
1007
|
+
{
|
|
1008
|
+
id: "gemma3:4b",
|
|
1009
|
+
label: "Gemma 3 4B",
|
|
1010
|
+
hint: "Reasoning",
|
|
1011
|
+
role: "chat",
|
|
1012
|
+
ramGb: 8,
|
|
1013
|
+
tier: "fast",
|
|
1014
|
+
modalities: ["text", "reasoning"],
|
|
1015
|
+
},
|
|
1016
|
+
{
|
|
1017
|
+
id: "gemma3n:e2b",
|
|
1018
|
+
label: "Gemma 3n E2B",
|
|
1019
|
+
hint: "On-device multimodal",
|
|
1020
|
+
role: "chat",
|
|
1021
|
+
ramGb: 8,
|
|
1022
|
+
tier: "fast",
|
|
1023
|
+
modalities: ["text", "vision"],
|
|
1024
|
+
},
|
|
1025
|
+
{
|
|
1026
|
+
id: "qwen3-vl:2B-UD-Q4_K_XL",
|
|
1027
|
+
label: "Qwen3-VL 2B",
|
|
1028
|
+
hint: "Vision",
|
|
1029
|
+
role: "chat",
|
|
1030
|
+
ramGb: 6,
|
|
1031
|
+
tier: "fast",
|
|
1032
|
+
modalities: ["text", "vision"],
|
|
1033
|
+
},
|
|
1034
|
+
{
|
|
1035
|
+
id: "smollm3",
|
|
1036
|
+
label: "SmolLM3",
|
|
1037
|
+
hint: "On-device chat",
|
|
1038
|
+
role: "chat",
|
|
1039
|
+
ramGb: 4,
|
|
1040
|
+
tier: "fast",
|
|
1041
|
+
modalities: ["text"],
|
|
1042
|
+
},
|
|
1043
|
+
{
|
|
1044
|
+
id: "ministral3:3B-Q4_K_M",
|
|
1045
|
+
label: "Ministral 3B",
|
|
1046
|
+
hint: "Mistral small",
|
|
1047
|
+
role: "chat",
|
|
1048
|
+
ramGb: 4,
|
|
1049
|
+
tier: "fast",
|
|
1050
|
+
modalities: ["text", "code"],
|
|
1051
|
+
},
|
|
1052
|
+
{
|
|
1053
|
+
id: "nemotron-3-nano:4b",
|
|
1054
|
+
label: "Nemotron 3 Nano 4B",
|
|
1055
|
+
hint: "NVIDIA nano",
|
|
1056
|
+
role: "chat",
|
|
1057
|
+
ramGb: 6,
|
|
1058
|
+
tier: "fast",
|
|
1059
|
+
modalities: ["text", "code"],
|
|
1060
|
+
},
|
|
1061
|
+
{
|
|
1062
|
+
id: "granite-4.0-micro",
|
|
1063
|
+
label: "Granite 4.0 Micro 3B",
|
|
1064
|
+
hint: "IBM micro",
|
|
1065
|
+
role: "chat",
|
|
1066
|
+
ramGb: 4,
|
|
1067
|
+
tier: "fast",
|
|
1068
|
+
modalities: ["text", "code"],
|
|
1069
|
+
},
|
|
1070
|
+
{
|
|
1071
|
+
id: "granite4:micro",
|
|
1072
|
+
label: "Granite 4 Micro",
|
|
1073
|
+
hint: "IBM micro Q4",
|
|
1074
|
+
role: "chat",
|
|
1075
|
+
ramGb: 4,
|
|
1076
|
+
tier: "fast",
|
|
1077
|
+
modalities: ["text"],
|
|
1078
|
+
},
|
|
1079
|
+
{
|
|
1080
|
+
id: "moondream2",
|
|
1081
|
+
label: "Moondream2 1.5B",
|
|
1082
|
+
hint: "Vision",
|
|
1083
|
+
role: "chat",
|
|
1084
|
+
ramGb: 6,
|
|
1085
|
+
tier: "fast",
|
|
1086
|
+
modalities: ["text", "vision"],
|
|
1087
|
+
},
|
|
1088
|
+
{
|
|
1089
|
+
id: "medgemma:4b",
|
|
1090
|
+
label: "MedGemma 4B",
|
|
1091
|
+
hint: "Medical",
|
|
1092
|
+
role: "chat",
|
|
1093
|
+
ramGb: 8,
|
|
1094
|
+
tier: "fast",
|
|
1095
|
+
modalities: ["text", "vision"],
|
|
1096
|
+
},
|
|
1097
|
+
{
|
|
1098
|
+
id: "granite4.1:3b",
|
|
1099
|
+
label: "Granite 4.1 3B",
|
|
1100
|
+
hint: "IBM 3B",
|
|
1101
|
+
role: "chat",
|
|
1102
|
+
ramGb: 4,
|
|
1103
|
+
tier: "fast",
|
|
1104
|
+
modalities: ["text", "code"],
|
|
1105
|
+
},
|
|
1106
|
+
{
|
|
1107
|
+
id: "llama3.2:3B-Q4_K_M",
|
|
1108
|
+
label: "Llama 3.2 3B Q4",
|
|
1109
|
+
hint: "Meta 3B Q4",
|
|
1110
|
+
role: "chat",
|
|
1111
|
+
ramGb: 4,
|
|
1112
|
+
tier: "fast",
|
|
1113
|
+
modalities: ["text"],
|
|
1114
|
+
},
|
|
1115
|
+
{
|
|
1116
|
+
id: "gemma4:e2b",
|
|
1117
|
+
label: "Gemma 4 E2B default",
|
|
1118
|
+
hint: "Popular · multimodal",
|
|
1119
|
+
role: "chat",
|
|
1120
|
+
ramGb: 8,
|
|
1121
|
+
tier: "fast",
|
|
1122
|
+
modalities: ["text", "vision"],
|
|
1123
|
+
},
|
|
1124
|
+
{
|
|
1125
|
+
id: "gemma3:4b-q4_K_M",
|
|
1126
|
+
label: "Gemma 3 4B Q4",
|
|
1127
|
+
hint: "Reasoning Q4",
|
|
1128
|
+
role: "chat",
|
|
1129
|
+
ramGb: 8,
|
|
1130
|
+
tier: "fast",
|
|
1131
|
+
modalities: ["text", "reasoning"],
|
|
1132
|
+
},
|
|
1133
|
+
{
|
|
1134
|
+
id: "smollm3:Q4_K_M",
|
|
1135
|
+
label: "SmolLM3 Q4",
|
|
1136
|
+
hint: "On-device Q4",
|
|
1137
|
+
role: "chat",
|
|
1138
|
+
ramGb: 4,
|
|
1139
|
+
tier: "fast",
|
|
1140
|
+
modalities: ["text"],
|
|
1141
|
+
},
|
|
1142
|
+
{
|
|
1143
|
+
id: "granite3.3:2b-q4_K_M",
|
|
1144
|
+
label: "Granite 3.3 2B Q4",
|
|
1145
|
+
hint: "IBM 2B Q4",
|
|
1146
|
+
role: "chat",
|
|
1147
|
+
ramGb: 4,
|
|
1148
|
+
tier: "fast",
|
|
1149
|
+
modalities: ["text", "code"],
|
|
1150
|
+
},
|
|
1151
|
+
// Balanced (~8–16GB) — Gemma 4 E4B · Qwen near the top
|
|
1152
|
+
{
|
|
1153
|
+
id: "qwen3:8B-Q4_K_M",
|
|
1154
|
+
label: "Qwen3 8B",
|
|
1155
|
+
hint: "Popular · coding · agents",
|
|
1156
|
+
role: "chat",
|
|
1157
|
+
recommended: true,
|
|
1158
|
+
ramGb: 12,
|
|
1159
|
+
tier: "balanced",
|
|
1160
|
+
modalities: ["text", "code"],
|
|
1161
|
+
},
|
|
1162
|
+
{
|
|
1163
|
+
id: "gemma4:e4b",
|
|
1164
|
+
label: "Gemma 4 E4B",
|
|
1165
|
+
hint: "Popular · multimodal",
|
|
1166
|
+
role: "chat",
|
|
1167
|
+
ramGb: 16,
|
|
1168
|
+
tier: "balanced",
|
|
1169
|
+
modalities: ["text", "vision", "reasoning"],
|
|
1170
|
+
},
|
|
1171
|
+
{
|
|
1172
|
+
id: "qwen2.5:7B-Q4_K_M",
|
|
1173
|
+
label: "Qwen2.5 7B",
|
|
1174
|
+
hint: "Coding",
|
|
1175
|
+
role: "chat",
|
|
1176
|
+
ramGb: 12,
|
|
1177
|
+
tier: "balanced",
|
|
1178
|
+
modalities: ["text", "code"],
|
|
1179
|
+
},
|
|
1180
|
+
{
|
|
1181
|
+
id: "qwen3-vl:8B",
|
|
1182
|
+
label: "Qwen3-VL 8B",
|
|
1183
|
+
hint: "Vision",
|
|
1184
|
+
role: "chat",
|
|
1185
|
+
ramGb: 16,
|
|
1186
|
+
tier: "balanced",
|
|
1187
|
+
modalities: ["text", "vision", "code"],
|
|
1188
|
+
},
|
|
1189
|
+
{
|
|
1190
|
+
id: "llama3.1:8B-Q4_K_M",
|
|
1191
|
+
label: "Llama 3.1 8B",
|
|
1192
|
+
hint: "Meta general",
|
|
1193
|
+
role: "chat",
|
|
1194
|
+
ramGb: 12,
|
|
1195
|
+
tier: "balanced",
|
|
1196
|
+
modalities: ["text"],
|
|
1197
|
+
},
|
|
1198
|
+
{
|
|
1199
|
+
id: "gemma3n:e4b",
|
|
1200
|
+
label: "Gemma 3n E4B",
|
|
1201
|
+
hint: "On-device multimodal",
|
|
1202
|
+
role: "chat",
|
|
1203
|
+
ramGb: 16,
|
|
1204
|
+
tier: "balanced",
|
|
1205
|
+
modalities: ["text", "vision"],
|
|
1206
|
+
},
|
|
1207
|
+
{
|
|
1208
|
+
id: "mistral",
|
|
1209
|
+
label: "Mistral 7B",
|
|
1210
|
+
hint: "General + code",
|
|
1211
|
+
role: "chat",
|
|
1212
|
+
ramGb: 12,
|
|
1213
|
+
tier: "balanced",
|
|
1214
|
+
modalities: ["text", "code"],
|
|
1215
|
+
},
|
|
1216
|
+
{
|
|
1217
|
+
id: "deepseek-r1-distill-llama:8B-Q4_K_M",
|
|
1218
|
+
label: "DeepSeek R1 8B",
|
|
1219
|
+
hint: "Reasoning distill",
|
|
1220
|
+
role: "chat",
|
|
1221
|
+
ramGb: 12,
|
|
1222
|
+
tier: "balanced",
|
|
1223
|
+
modalities: ["text", "reasoning"],
|
|
1224
|
+
},
|
|
1225
|
+
{
|
|
1226
|
+
id: "mistral-nemo",
|
|
1227
|
+
label: "Mistral Nemo 12B",
|
|
1228
|
+
hint: "General",
|
|
1229
|
+
role: "chat",
|
|
1230
|
+
ramGb: 16,
|
|
1231
|
+
tier: "balanced",
|
|
1232
|
+
modalities: ["text", "code"],
|
|
1233
|
+
},
|
|
1234
|
+
{
|
|
1235
|
+
id: "ministral3:8B-Q4_K_M",
|
|
1236
|
+
label: "Ministral 8B",
|
|
1237
|
+
hint: "Mistral instruct",
|
|
1238
|
+
role: "chat",
|
|
1239
|
+
ramGb: 12,
|
|
1240
|
+
tier: "balanced",
|
|
1241
|
+
modalities: ["text", "code"],
|
|
1242
|
+
},
|
|
1243
|
+
{
|
|
1244
|
+
id: "granite-4.0-h-tiny",
|
|
1245
|
+
label: "Granite 4.0 H Tiny 7B",
|
|
1246
|
+
hint: "IBM tiny",
|
|
1247
|
+
role: "chat",
|
|
1248
|
+
ramGb: 12,
|
|
1249
|
+
tier: "balanced",
|
|
1250
|
+
modalities: ["text", "code"],
|
|
1251
|
+
},
|
|
1252
|
+
{
|
|
1253
|
+
id: "ministral-3:8b-instruct",
|
|
1254
|
+
label: "Ministral 3 8B Instruct",
|
|
1255
|
+
hint: "Instruct",
|
|
1256
|
+
role: "chat",
|
|
1257
|
+
ramGb: 12,
|
|
1258
|
+
tier: "balanced",
|
|
1259
|
+
modalities: ["text", "code"],
|
|
1260
|
+
},
|
|
1261
|
+
{
|
|
1262
|
+
id: "granite3.3:8b",
|
|
1263
|
+
label: "Granite 3.3 8B",
|
|
1264
|
+
hint: "IBM 8B",
|
|
1265
|
+
role: "chat",
|
|
1266
|
+
ramGb: 12,
|
|
1267
|
+
tier: "balanced",
|
|
1268
|
+
modalities: ["text", "code"],
|
|
1269
|
+
},
|
|
1270
|
+
{
|
|
1271
|
+
id: "granite4.1:8b",
|
|
1272
|
+
label: "Granite 4.1 8B",
|
|
1273
|
+
hint: "IBM 8B",
|
|
1274
|
+
role: "chat",
|
|
1275
|
+
ramGb: 12,
|
|
1276
|
+
tier: "balanced",
|
|
1277
|
+
modalities: ["text", "code"],
|
|
1278
|
+
},
|
|
1279
|
+
{
|
|
1280
|
+
id: "qwen3:8B-Q4_0",
|
|
1281
|
+
label: "Qwen3 8B Q4_0",
|
|
1282
|
+
hint: "Coding Q4_0",
|
|
1283
|
+
role: "chat",
|
|
1284
|
+
ramGb: 12,
|
|
1285
|
+
tier: "balanced",
|
|
1286
|
+
modalities: ["text", "code"],
|
|
1287
|
+
},
|
|
1288
|
+
{
|
|
1289
|
+
id: "gemma4:e4b-q4_K_M",
|
|
1290
|
+
label: "Gemma 4 E4B Q4",
|
|
1291
|
+
hint: "Popular · multimodal Q4",
|
|
1292
|
+
role: "chat",
|
|
1293
|
+
ramGb: 16,
|
|
1294
|
+
tier: "balanced",
|
|
1295
|
+
modalities: ["text", "vision", "reasoning"],
|
|
1296
|
+
},
|
|
1297
|
+
{
|
|
1298
|
+
id: "ministral-3:8b-reasoning",
|
|
1299
|
+
label: "Ministral 3 8B Reasoning",
|
|
1300
|
+
hint: "Reasoning",
|
|
1301
|
+
role: "chat",
|
|
1302
|
+
ramGb: 12,
|
|
1303
|
+
tier: "balanced",
|
|
1304
|
+
modalities: ["text", "reasoning", "code"],
|
|
1305
|
+
},
|
|
1306
|
+
{
|
|
1307
|
+
id: "llama3.1",
|
|
1308
|
+
label: "Llama 3.1 8B",
|
|
1309
|
+
hint: "Meta default",
|
|
1310
|
+
role: "chat",
|
|
1311
|
+
ramGb: 12,
|
|
1312
|
+
tier: "balanced",
|
|
1313
|
+
modalities: ["text"],
|
|
1314
|
+
},
|
|
1315
|
+
{
|
|
1316
|
+
id: "qwen2.5",
|
|
1317
|
+
label: "Qwen2.5 7B",
|
|
1318
|
+
hint: "Coding default",
|
|
1319
|
+
role: "chat",
|
|
1320
|
+
ramGb: 12,
|
|
1321
|
+
tier: "balanced",
|
|
1322
|
+
modalities: ["text", "code"],
|
|
1323
|
+
},
|
|
1324
|
+
{
|
|
1325
|
+
id: "gemma3n",
|
|
1326
|
+
label: "Gemma 3n",
|
|
1327
|
+
hint: "On-device default",
|
|
1328
|
+
role: "chat",
|
|
1329
|
+
ramGb: 16,
|
|
1330
|
+
tier: "balanced",
|
|
1331
|
+
modalities: ["text", "vision"],
|
|
1332
|
+
},
|
|
1333
|
+
// Smart (~24–32GB) — Gemma 4 31B · Qwen family near the top
|
|
1334
|
+
{
|
|
1335
|
+
id: "phi4",
|
|
1336
|
+
label: "Phi-4 14B",
|
|
1337
|
+
hint: "Reasoning",
|
|
1338
|
+
role: "chat",
|
|
1339
|
+
recommended: true,
|
|
1340
|
+
ramGb: 24,
|
|
1341
|
+
tier: "smart",
|
|
1342
|
+
modalities: ["text", "reasoning", "code"],
|
|
1343
|
+
},
|
|
1344
|
+
{
|
|
1345
|
+
id: "gemma4:31b",
|
|
1346
|
+
label: "Gemma 4 31B",
|
|
1347
|
+
hint: "Popular · large multimodal",
|
|
1348
|
+
role: "chat",
|
|
1349
|
+
ramGb: 32,
|
|
1350
|
+
tier: "smart",
|
|
1351
|
+
modalities: ["text", "vision", "reasoning"],
|
|
1352
|
+
},
|
|
1353
|
+
{
|
|
1354
|
+
id: "qwen3.5:27b",
|
|
1355
|
+
label: "Qwen3.5 27B",
|
|
1356
|
+
hint: "Popular · general · coding",
|
|
1357
|
+
role: "chat",
|
|
1358
|
+
ramGb: 32,
|
|
1359
|
+
tier: "smart",
|
|
1360
|
+
modalities: ["text", "code"],
|
|
1361
|
+
},
|
|
1362
|
+
{
|
|
1363
|
+
id: "qwen3:30B-A3B-Q4_K_M",
|
|
1364
|
+
label: "Qwen3 30B-A3B",
|
|
1365
|
+
hint: "MoE · coding",
|
|
1366
|
+
role: "chat",
|
|
1367
|
+
ramGb: 24,
|
|
1368
|
+
tier: "smart",
|
|
1369
|
+
modalities: ["text", "code"],
|
|
1370
|
+
},
|
|
1371
|
+
{
|
|
1372
|
+
id: "qwen3-coder:30B",
|
|
1373
|
+
label: "Qwen3-Coder 30B",
|
|
1374
|
+
hint: "Coding agent",
|
|
1375
|
+
role: "chat",
|
|
1376
|
+
ramGb: 24,
|
|
1377
|
+
tier: "smart",
|
|
1378
|
+
modalities: ["text", "code"],
|
|
1379
|
+
},
|
|
1380
|
+
{
|
|
1381
|
+
id: "qwen3-vl:32B-UD-Q4_K_XL",
|
|
1382
|
+
label: "Qwen3-VL 32B",
|
|
1383
|
+
hint: "Vision",
|
|
1384
|
+
role: "chat",
|
|
1385
|
+
ramGb: 32,
|
|
1386
|
+
tier: "smart",
|
|
1387
|
+
modalities: ["text", "vision", "code"],
|
|
1388
|
+
},
|
|
1389
|
+
{
|
|
1390
|
+
id: "gemma3:27b",
|
|
1391
|
+
label: "Gemma 3 27B",
|
|
1392
|
+
hint: "Large reasoning",
|
|
1393
|
+
role: "chat",
|
|
1394
|
+
ramGb: 32,
|
|
1395
|
+
tier: "smart",
|
|
1396
|
+
modalities: ["text", "reasoning"],
|
|
1397
|
+
},
|
|
1398
|
+
{
|
|
1399
|
+
id: "qwq:32B-Q4_K_M",
|
|
1400
|
+
label: "QwQ 32B",
|
|
1401
|
+
hint: "Reasoning",
|
|
1402
|
+
role: "chat",
|
|
1403
|
+
ramGb: 32,
|
|
1404
|
+
tier: "smart",
|
|
1405
|
+
modalities: ["text", "reasoning"],
|
|
1406
|
+
},
|
|
1407
|
+
{
|
|
1408
|
+
id: "gpt-oss:20b",
|
|
1409
|
+
label: "GPT-OSS 20B",
|
|
1410
|
+
hint: "Open weights",
|
|
1411
|
+
role: "chat",
|
|
1412
|
+
ramGb: 24,
|
|
1413
|
+
tier: "smart",
|
|
1414
|
+
modalities: ["text", "reasoning"],
|
|
1415
|
+
},
|
|
1416
|
+
{
|
|
1417
|
+
id: "magistral-small-3.2",
|
|
1418
|
+
label: "Magistral Small 24B",
|
|
1419
|
+
hint: "Reasoning",
|
|
1420
|
+
role: "chat",
|
|
1421
|
+
ramGb: 24,
|
|
1422
|
+
tier: "smart",
|
|
1423
|
+
modalities: ["text", "reasoning"],
|
|
1424
|
+
},
|
|
1425
|
+
{
|
|
1426
|
+
id: "ministral3:14B",
|
|
1427
|
+
label: "Ministral 14B",
|
|
1428
|
+
hint: "Mistral mid",
|
|
1429
|
+
role: "chat",
|
|
1430
|
+
ramGb: 24,
|
|
1431
|
+
tier: "smart",
|
|
1432
|
+
modalities: ["text", "code"],
|
|
1433
|
+
},
|
|
1434
|
+
{
|
|
1435
|
+
id: "nemotron-3-nano:30b-a3b",
|
|
1436
|
+
label: "Nemotron 3 Nano 30B-A3B",
|
|
1437
|
+
hint: "NVIDIA MoE",
|
|
1438
|
+
role: "chat",
|
|
1439
|
+
ramGb: 24,
|
|
1440
|
+
tier: "smart",
|
|
1441
|
+
modalities: ["text", "code"],
|
|
1442
|
+
},
|
|
1443
|
+
{
|
|
1444
|
+
id: "devstral-small-2",
|
|
1445
|
+
label: "Devstral Small 2",
|
|
1446
|
+
hint: "Coding",
|
|
1447
|
+
role: "chat",
|
|
1448
|
+
ramGb: 24,
|
|
1449
|
+
tier: "smart",
|
|
1450
|
+
modalities: ["text", "code"],
|
|
1451
|
+
},
|
|
1452
|
+
{
|
|
1453
|
+
id: "medgemma:27b-text",
|
|
1454
|
+
label: "MedGemma 27B Text",
|
|
1455
|
+
hint: "Medical",
|
|
1456
|
+
role: "chat",
|
|
1457
|
+
ramGb: 32,
|
|
1458
|
+
tier: "smart",
|
|
1459
|
+
modalities: ["text"],
|
|
1460
|
+
},
|
|
1461
|
+
{
|
|
1462
|
+
id: "gemma4:26b-a4b-q4_K_M",
|
|
1463
|
+
label: "Gemma 4 26B-A4B",
|
|
1464
|
+
hint: "Popular · MoE multimodal",
|
|
1465
|
+
role: "chat",
|
|
1466
|
+
ramGb: 32,
|
|
1467
|
+
tier: "smart",
|
|
1468
|
+
modalities: ["text", "vision", "reasoning"],
|
|
1469
|
+
},
|
|
1470
|
+
{
|
|
1471
|
+
id: "glm-4.7-flash",
|
|
1472
|
+
label: "GLM-4.7 Flash",
|
|
1473
|
+
hint: "MoE flash",
|
|
1474
|
+
role: "chat",
|
|
1475
|
+
ramGb: 24,
|
|
1476
|
+
tier: "smart",
|
|
1477
|
+
modalities: ["text", "code"],
|
|
1478
|
+
},
|
|
1479
|
+
{
|
|
1480
|
+
id: "granite4.1:30b",
|
|
1481
|
+
label: "Granite 4.1 30B",
|
|
1482
|
+
hint: "IBM 30B",
|
|
1483
|
+
role: "chat",
|
|
1484
|
+
ramGb: 32,
|
|
1485
|
+
tier: "smart",
|
|
1486
|
+
modalities: ["text", "code"],
|
|
1487
|
+
},
|
|
1488
|
+
{
|
|
1489
|
+
id: "deepcoder-preview",
|
|
1490
|
+
label: "DeepCoder Preview 14B",
|
|
1491
|
+
hint: "Coding",
|
|
1492
|
+
role: "chat",
|
|
1493
|
+
ramGb: 24,
|
|
1494
|
+
tier: "smart",
|
|
1495
|
+
modalities: ["text", "code"],
|
|
1496
|
+
},
|
|
1497
|
+
{
|
|
1498
|
+
id: "qwen3:14B-Q6_K",
|
|
1499
|
+
label: "Qwen3 14B",
|
|
1500
|
+
hint: "Coding mid",
|
|
1501
|
+
role: "chat",
|
|
1502
|
+
ramGb: 24,
|
|
1503
|
+
tier: "smart",
|
|
1504
|
+
modalities: ["text", "code"],
|
|
1505
|
+
},
|
|
1506
|
+
{
|
|
1507
|
+
id: "nemotron3",
|
|
1508
|
+
label: "Nemotron 3 30B",
|
|
1509
|
+
hint: "NVIDIA",
|
|
1510
|
+
role: "chat",
|
|
1511
|
+
ramGb: 32,
|
|
1512
|
+
tier: "smart",
|
|
1513
|
+
modalities: ["text", "code"],
|
|
1514
|
+
},
|
|
1515
|
+
];
|
|
1516
|
+
|
|
1517
|
+
/**
|
|
1518
|
+
* llama.cpp chat models in a tier (manual pick shows up to 20), ordered by RAM.
|
|
1519
|
+
*
|
|
1520
|
+
* @param tier - Speed / quality tier
|
|
1521
|
+
*/
|
|
1522
|
+
export function llamaCppModelsForTier(tier: ModelTier): readonly CatalogModel[] {
|
|
1523
|
+
return byRamThenLabel(LLAMA_CPP_CHAT_MODELS.filter((m) => m.tier === tier)).slice(0, 20);
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1526
|
+
/**
|
|
1527
|
+
* Recommended Docker Hub `ai/` model for a tier (RAM-aware).
|
|
1528
|
+
*
|
|
1529
|
+
* @param tier - Selected tier
|
|
1530
|
+
* @param totalRamGb - Prefer models that fit when RAM is known
|
|
1531
|
+
*/
|
|
1532
|
+
export function recommendLlamaCppForTier(
|
|
1533
|
+
tier: ModelTier,
|
|
1534
|
+
totalRamGb: number | null = null,
|
|
1535
|
+
): CatalogModel {
|
|
1536
|
+
const list = llamaCppModelsForTier(tier);
|
|
1537
|
+
const headroom = 4;
|
|
1538
|
+
const fits =
|
|
1539
|
+
totalRamGb !== null && Number.isFinite(totalRamGb)
|
|
1540
|
+
? list.filter((m) => m.ramGb + headroom <= totalRamGb || m.ramGb <= totalRamGb)
|
|
1541
|
+
: list;
|
|
1542
|
+
const pool = fits.length > 0 ? fits : list;
|
|
1543
|
+
return pool.find((m) => m.recommended) ?? pool[pool.length - 1] ?? list[0]!;
|
|
1544
|
+
}
|