@vtstech/pi-ollama-sync 1.1.2 → 1.1.4
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/ollama-sync.js +81 -74
- package/package.json +2 -2
package/ollama-sync.js
CHANGED
|
@@ -55,6 +55,60 @@ function mergeModels(newModels, oldModels) {
|
|
|
55
55
|
return m;
|
|
56
56
|
});
|
|
57
57
|
}
|
|
58
|
+
async function performSync(overrideUrl) {
|
|
59
|
+
const existing = readModelsJson();
|
|
60
|
+
const config = getProviderConfig(existing);
|
|
61
|
+
const ollamaBaseUrl = overrideUrl ? overrideUrl.replace(/\/v1$/, "").replace(/\/+$/, "") : config.baseUrl?.replace(/\/v1$/, "") ?? getOllamaBaseUrl();
|
|
62
|
+
try {
|
|
63
|
+
const models = await fetchOllamaModels(ollamaBaseUrl);
|
|
64
|
+
if (models.length === 0) {
|
|
65
|
+
return {
|
|
66
|
+
ollamaBaseUrl,
|
|
67
|
+
newModels: [],
|
|
68
|
+
added: [],
|
|
69
|
+
removed: [],
|
|
70
|
+
error: "No models found in Ollama"
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
const sorted = [...models].sort((a, b) => a.size - b.size);
|
|
74
|
+
const contextMap = await fetchContextLengthsBatched(
|
|
75
|
+
ollamaBaseUrl,
|
|
76
|
+
sorted.map((m) => m.name)
|
|
77
|
+
);
|
|
78
|
+
const newModels = sorted.map(
|
|
79
|
+
(m) => buildModelEntry(m, contextMap.get(m.name))
|
|
80
|
+
);
|
|
81
|
+
const oldIds = new Set(
|
|
82
|
+
existing.providers["ollama"]?.models?.map((m) => m.id) ?? []
|
|
83
|
+
);
|
|
84
|
+
const added = newModels.filter((m) => !oldIds.has(m.id));
|
|
85
|
+
const removed = [...oldIds].filter((id) => !newModels.some((m) => m.id === id));
|
|
86
|
+
const mergedModels = mergeModels(
|
|
87
|
+
newModels,
|
|
88
|
+
existing.providers["ollama"]?.models ?? []
|
|
89
|
+
);
|
|
90
|
+
existing.providers["ollama"] = {
|
|
91
|
+
...config,
|
|
92
|
+
baseUrl: ollamaBaseUrl + "/v1",
|
|
93
|
+
models: mergedModels
|
|
94
|
+
};
|
|
95
|
+
writeModelsJson(existing);
|
|
96
|
+
return {
|
|
97
|
+
ollamaBaseUrl,
|
|
98
|
+
newModels,
|
|
99
|
+
added,
|
|
100
|
+
removed
|
|
101
|
+
};
|
|
102
|
+
} catch (err) {
|
|
103
|
+
return {
|
|
104
|
+
ollamaBaseUrl,
|
|
105
|
+
newModels: [],
|
|
106
|
+
added: [],
|
|
107
|
+
removed: [],
|
|
108
|
+
error: err.message
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
}
|
|
58
112
|
function ollama_sync_temp_default(pi) {
|
|
59
113
|
pi.registerCommand("ollama-sync", {
|
|
60
114
|
description: "Sync models from Ollama into models.json. Use: /ollama-sync [url]",
|
|
@@ -69,39 +123,13 @@ function ollama_sync_temp_default(pi) {
|
|
|
69
123
|
const overrideUrl = arg || void 0;
|
|
70
124
|
ctx.ui.setStatus("ollama-sync", "Fetching models from Ollama...");
|
|
71
125
|
try {
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const models = await fetchOllamaModels(ollamaBaseUrl);
|
|
76
|
-
if (models.length === 0) {
|
|
77
|
-
ctx.ui.notify("No models found in Ollama", "info");
|
|
126
|
+
const result = await performSync(overrideUrl);
|
|
127
|
+
if (result.error) {
|
|
128
|
+
ctx.ui.notify(result.error, result.newModels.length === 0 ? "info" : "error");
|
|
78
129
|
ctx.ui.setStatus("ollama-sync", void 0);
|
|
79
130
|
return;
|
|
80
131
|
}
|
|
81
|
-
const
|
|
82
|
-
ctx.ui.setStatus("ollama-sync", "Fetching model details...");
|
|
83
|
-
const contextMap = await fetchContextLengthsBatched(
|
|
84
|
-
ollamaBaseUrl,
|
|
85
|
-
sorted.map((m) => m.name)
|
|
86
|
-
);
|
|
87
|
-
const newModels = sorted.map(
|
|
88
|
-
(m) => buildModelEntry(m, contextMap.get(m.name))
|
|
89
|
-
);
|
|
90
|
-
const oldIds = new Set(
|
|
91
|
-
existing.providers["ollama"]?.models?.map((m) => m.id) ?? []
|
|
92
|
-
);
|
|
93
|
-
const added = newModels.filter((m) => !oldIds.has(m.id));
|
|
94
|
-
const removed = [...oldIds].filter((id) => !newModels.some((m) => m.id === id));
|
|
95
|
-
const mergedModels = mergeModels(
|
|
96
|
-
newModels,
|
|
97
|
-
existing.providers["ollama"]?.models ?? []
|
|
98
|
-
);
|
|
99
|
-
existing.providers["ollama"] = {
|
|
100
|
-
...config,
|
|
101
|
-
baseUrl: ollamaBaseUrl + "/v1",
|
|
102
|
-
models: mergedModels
|
|
103
|
-
};
|
|
104
|
-
writeModelsJson(existing);
|
|
132
|
+
const { ollamaBaseUrl, newModels, added, removed } = result;
|
|
105
133
|
const lines = [""];
|
|
106
134
|
lines.push(` Ollama: ${ollamaBaseUrl}`);
|
|
107
135
|
lines.push(` Synced ${newModels.length} models from Ollama`);
|
|
@@ -161,55 +189,34 @@ function ollama_sync_temp_default(pi) {
|
|
|
161
189
|
},
|
|
162
190
|
async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
|
|
163
191
|
const overrideUrl = params?.url;
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
const ollamaBaseUrl = overrideUrl ? overrideUrl.replace(/\/v1$/, "").replace(/\/+$/, "") : config.baseUrl?.replace(/\/v1$/, "") ?? getOllamaBaseUrl();
|
|
167
|
-
try {
|
|
168
|
-
const models = await fetchOllamaModels(ollamaBaseUrl);
|
|
169
|
-
const sorted = [...models].sort((a, b) => a.size - b.size);
|
|
170
|
-
const contextMap = await fetchContextLengthsBatched(
|
|
171
|
-
ollamaBaseUrl,
|
|
172
|
-
sorted.map((m) => m.name)
|
|
173
|
-
);
|
|
174
|
-
const newModels = sorted.map(
|
|
175
|
-
(m) => buildModelEntry(m, contextMap.get(m.name))
|
|
176
|
-
);
|
|
177
|
-
const mergedModels = mergeModels(
|
|
178
|
-
newModels,
|
|
179
|
-
existing.providers["ollama"]?.models ?? []
|
|
180
|
-
);
|
|
181
|
-
existing.providers["ollama"] = {
|
|
182
|
-
...config,
|
|
183
|
-
baseUrl: ollamaBaseUrl + "/v1",
|
|
184
|
-
models: mergedModels
|
|
185
|
-
};
|
|
186
|
-
writeModelsJson(existing);
|
|
187
|
-
const modelDetails = newModels.map(
|
|
188
|
-
(m) => {
|
|
189
|
-
const ctxStr = m.contextLength ?? "?";
|
|
190
|
-
const sizeStr = m.estimatedSize ? `GPU: ~${bytesHuman(m.estimatedSize.gpu)}, CPU: ~${bytesHuman(m.estimatedSize.cpu)}` : "?";
|
|
191
|
-
return ` \u2022 ${m.id} (${m.parameterSize}, ${m.quantizationLevel}, ctx: ${ctxStr}, ${sizeStr})`;
|
|
192
|
-
}
|
|
193
|
-
).join("\n");
|
|
192
|
+
const result = await performSync(overrideUrl);
|
|
193
|
+
if (result.error) {
|
|
194
194
|
return {
|
|
195
|
-
content: [
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
195
|
+
content: [{ type: "text", text: `Error: ${result.error}` }],
|
|
196
|
+
details: {}
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
const { ollamaBaseUrl, newModels } = result;
|
|
200
|
+
const modelDetails = newModels.map(
|
|
201
|
+
(m) => {
|
|
202
|
+
const ctxStr = m.contextLength ?? "?";
|
|
203
|
+
const sizeStr = m.estimatedSize ? `GPU: ~${bytesHuman(m.estimatedSize.gpu)}, CPU: ~${bytesHuman(m.estimatedSize.cpu)}` : "?";
|
|
204
|
+
return ` \u2022 ${m.id} (${m.parameterSize}, ${m.quantizationLevel}, ctx: ${ctxStr}, ${sizeStr})`;
|
|
205
|
+
}
|
|
206
|
+
).join("\n");
|
|
207
|
+
return {
|
|
208
|
+
content: [
|
|
209
|
+
{
|
|
210
|
+
type: "text",
|
|
211
|
+
text: `${BRANDING}
|
|
199
212
|
|
|
200
213
|
Synced ${newModels.length} models from ${ollamaBaseUrl} to ${MODELS_FILE}. Run /reload to pick up changes.
|
|
201
214
|
|
|
202
215
|
${modelDetails}`
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
} catch (err) {
|
|
208
|
-
return {
|
|
209
|
-
content: [{ type: "text", text: `Error: ${err.message}` }],
|
|
210
|
-
details: {}
|
|
211
|
-
};
|
|
212
|
-
}
|
|
216
|
+
}
|
|
217
|
+
],
|
|
218
|
+
details: { models: newModels }
|
|
219
|
+
};
|
|
213
220
|
}
|
|
214
221
|
});
|
|
215
222
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vtstech/pi-ollama-sync",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.4",
|
|
4
4
|
"description": "Ollama model sync extension for Pi Coding Agent",
|
|
5
5
|
"main": "ollama-sync.js",
|
|
6
6
|
"keywords": ["pi-extensions"],
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"url": "https://github.com/VTSTech/pi-coding-agent"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@vtstech/pi-shared": "1.1.
|
|
17
|
+
"@vtstech/pi-shared": "1.1.4"
|
|
18
18
|
},
|
|
19
19
|
"peerDependencies": {
|
|
20
20
|
"@mariozechner/pi-coding-agent": ">=0.66"
|