offgrid-ai 0.15.4 → 0.15.6
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/package.json +1 -1
- package/src/backends.mjs +6 -4
- package/src/commands/models.mjs +9 -2
package/package.json
CHANGED
package/src/backends.mjs
CHANGED
|
@@ -102,16 +102,18 @@ async function scanOmlxModels() {
|
|
|
102
102
|
// The oMLX API can return the same model multiple times with different
|
|
103
103
|
// ID formats (e.g. "Qwen3.6-35B-A3B-OptiQ-4bit" and
|
|
104
104
|
// "mlx-community--Qwen3.6-35B-A3B-OptiQ-4bit"). Deduplicate by the
|
|
105
|
-
// normalized full name (publisher/model), keeping
|
|
106
|
-
// (which has the most complete metadata
|
|
105
|
+
// normalized full name (publisher/model with / separator), keeping
|
|
106
|
+
// the first entry (which has the most complete metadata).
|
|
107
107
|
const seen = new Set();
|
|
108
108
|
const deduped = [];
|
|
109
109
|
for (const model of body.data.filter(isChatOmlxModel)) {
|
|
110
110
|
const info = lookupOmlxModelInfo(model.id, infoMap);
|
|
111
111
|
const hasPublisher = model.id.includes("/") || model.id.includes("--");
|
|
112
112
|
const fullName = (!hasPublisher && info?.publisher) ? `${info.publisher}/${model.id}` : model.id;
|
|
113
|
-
|
|
114
|
-
|
|
113
|
+
// Normalize: convert -- separator to / for dedup comparison
|
|
114
|
+
const normalized = fullName.replace(/--/g, "/");
|
|
115
|
+
if (seen.has(normalized)) continue;
|
|
116
|
+
seen.add(normalized);
|
|
115
117
|
deduped.push(model);
|
|
116
118
|
}
|
|
117
119
|
|
package/src/commands/models.mjs
CHANGED
|
@@ -82,10 +82,17 @@ export async function modelCommandCenter(initialCatalog) {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
const groups = [];
|
|
85
|
+
const backendColors = {
|
|
86
|
+
"mlx-vlm": pc.yellow,
|
|
87
|
+
"llama-cpp": pc.cyan,
|
|
88
|
+
"llama-cpp-mtp": pc.blue,
|
|
89
|
+
omlx: pc.magenta,
|
|
90
|
+
};
|
|
85
91
|
for (const { backendId, sourceId, items } of byBackend.values()) {
|
|
86
92
|
const backendLabel = backendFor(backendId)?.label ?? backendId;
|
|
87
93
|
const sourceLabel = formatSourceLabel(sourceId);
|
|
88
|
-
const
|
|
94
|
+
const color = backendColors[backendId] ?? pc.dim;
|
|
95
|
+
const sep = `Inference: ${pc.bold(color(backendLabel))} ${pc.dim("|")} Source: ${sourceLabel} (${items.length})`;
|
|
89
96
|
const groupItems = items.map((item) => {
|
|
90
97
|
const opt = modelSelectOption(item, { runningProfilesNow, modelMissingIds, nameWidth, compact: true });
|
|
91
98
|
return { value: opt.value, label: opt.label, description: opt.description };
|
|
@@ -98,7 +105,7 @@ export async function modelCommandCenter(initialCatalog) {
|
|
|
98
105
|
const opt = modelSelectOption(item, { runningProfilesNow, modelMissingIds, nameWidth, compact: true });
|
|
99
106
|
return { value: opt.value, label: opt.label, description: opt.description };
|
|
100
107
|
});
|
|
101
|
-
groups.push({ separator: ` Needs setup (${setupItems.length})`, items: groupItems });
|
|
108
|
+
groups.push({ separator: ` ${pc.bold(pc.yellow(`Needs setup (${setupItems.length})`))}`, items: groupItems });
|
|
102
109
|
}
|
|
103
110
|
|
|
104
111
|
const prompt = createPrompt();
|