pi-llama-cpp 0.11.0 → 0.13.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/README.md +186 -58
- package/package.json +5 -5
- package/src/constants.ts +8 -0
- package/src/interfaces/server.ts +7 -0
- package/src/interfaces/settings.ts +67 -1
- package/src/managers/command.ts +110 -31
- package/src/managers/events.ts +2 -2
- package/src/managers/server.ts +14 -11
- package/src/managers/settings.ts +120 -45
- package/src/models/baseModel.ts +37 -7
- package/src/models/routerModel.ts +2 -1
- package/src/server.ts +62 -23
- package/src/sse/manager.ts +9 -8
- package/src/ui/dialog.ts +290 -0
- package/src/ui/overrideEntryEditor.ts +119 -0
- package/src/ui/overrideSettingsList.ts +710 -0
- package/src/ui/serverListEditor.ts +19 -441
- package/src/ui/serverSettingsList.ts +513 -0
- package/src/ui/strings.ts +127 -0
- package/src/utils/health.ts +48 -0
- package/src/utils/settingsStore.ts +2 -6
- package/tests/commandManager.test.ts +132 -16
- package/tests/dialog.test.ts +228 -0
- package/tests/events.test.ts +12 -9
- package/tests/health.test.ts +116 -0
- package/tests/legacyModel.test.ts +4 -19
- package/tests/mocks.ts +12 -8
- package/tests/overrides.test.ts +384 -0
- package/tests/server.test.ts +59 -16
- package/tests/serverManager.test.ts +28 -62
- package/tests/settings.test.ts +489 -43
- package/tests/settingsStore.test.ts +0 -19
- package/tests/singleModel.test.ts +32 -0
- package/tests/sseManager.test.ts +4 -4
- package/tests/serverListEditor.test.ts +0 -637
|
@@ -27,7 +27,7 @@ const mockPi = {
|
|
|
27
27
|
* `settings.resolveServers()` — the same path a real scan takes.
|
|
28
28
|
*/
|
|
29
29
|
const createManager = async (...servers: Server[]): Promise<ServerManager> => {
|
|
30
|
-
vi.mocked(settingsStub.resolveServers).
|
|
30
|
+
vi.mocked(settingsStub.resolveServers).mockResolvedValue(servers);
|
|
31
31
|
const manager = new ServerManager(settingsStub);
|
|
32
32
|
await manager.update(mockPi as any);
|
|
33
33
|
return manager;
|
|
@@ -45,40 +45,6 @@ beforeEach(() => {
|
|
|
45
45
|
});
|
|
46
46
|
});
|
|
47
47
|
|
|
48
|
-
describe("Server", () => {
|
|
49
|
-
it("should generate provider IDs from URLs", () => {
|
|
50
|
-
const server1 = new Server(settingsStub, {
|
|
51
|
-
baseUrl: "http://127.0.0.1:8080",
|
|
52
|
-
});
|
|
53
|
-
expect(server1.providerId).toBe("llama-server=http://127.0.0.1:8080");
|
|
54
|
-
const server2 = new Server(settingsStub, {
|
|
55
|
-
baseUrl: "http://10.0.0.5:8080",
|
|
56
|
-
});
|
|
57
|
-
expect(server2.providerId).toBe("llama-server=http://10.0.0.5:8080");
|
|
58
|
-
const server3 = new Server(settingsStub, { baseUrl: "http://127.0.0.1" });
|
|
59
|
-
expect(server3.providerId).toBe("llama-server=http://127.0.0.1");
|
|
60
|
-
const server4 = new Server(settingsStub, {
|
|
61
|
-
baseUrl: "http://127.0.0.1:80",
|
|
62
|
-
});
|
|
63
|
-
expect(server4.providerId).toBe("llama-server=http://127.0.0.1:80");
|
|
64
|
-
const server5 = new Server(settingsStub, {
|
|
65
|
-
baseUrl: "https://127.0.0.1:443",
|
|
66
|
-
});
|
|
67
|
-
expect(server5.providerId).toBe("llama-server=https://127.0.0.1:443");
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it("should generate provider names from URLs", () => {
|
|
71
|
-
const server1 = new Server(settingsStub, {
|
|
72
|
-
baseUrl: "http://127.0.0.1:8080",
|
|
73
|
-
});
|
|
74
|
-
expect(server1.providerName).toBe("Llama.cpp (http://127.0.0.1:8080)");
|
|
75
|
-
const server2 = new Server(settingsStub, {
|
|
76
|
-
baseUrl: "http://10.0.0.5:8080",
|
|
77
|
-
});
|
|
78
|
-
expect(server2.providerName).toBe("Llama.cpp (http://10.0.0.5:8080)");
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
|
|
82
48
|
describe("ServerManager", () => {
|
|
83
49
|
it("should register providers for all servers", async () => {
|
|
84
50
|
const mockModel = {
|
|
@@ -103,7 +69,7 @@ describe("ServerManager", () => {
|
|
|
103
69
|
"llama-server=http://127.0.0.1:8080",
|
|
104
70
|
{
|
|
105
71
|
name: "Llama.cpp (http://127.0.0.1:8080)",
|
|
106
|
-
baseUrl: "http://127.0.0.1:8080",
|
|
72
|
+
baseUrl: "http://127.0.0.1:8080/v1",
|
|
107
73
|
api: "openai-completions",
|
|
108
74
|
apiKey: "key-1",
|
|
109
75
|
models: [{ id: "test-model" }],
|
|
@@ -113,7 +79,7 @@ describe("ServerManager", () => {
|
|
|
113
79
|
"llama-server=http://127.0.0.1:8081",
|
|
114
80
|
{
|
|
115
81
|
name: "Llama.cpp (http://127.0.0.1:8081)",
|
|
116
|
-
baseUrl: "http://127.0.0.1:8081",
|
|
82
|
+
baseUrl: "http://127.0.0.1:8081/v1",
|
|
117
83
|
api: "openai-completions",
|
|
118
84
|
apiKey: "key-2",
|
|
119
85
|
models: [{ id: "test-model" }],
|
|
@@ -134,7 +100,7 @@ describe("ServerManager", () => {
|
|
|
134
100
|
});
|
|
135
101
|
const manager = await createManager(server1, server2);
|
|
136
102
|
|
|
137
|
-
const allModels = manager.getAllModels();
|
|
103
|
+
const allModels = await manager.getAllModels();
|
|
138
104
|
|
|
139
105
|
expect(allModels).toHaveLength(2);
|
|
140
106
|
expect(allModels[0]).toBe(mockModel1);
|
|
@@ -153,13 +119,13 @@ describe("ServerManager", () => {
|
|
|
153
119
|
|
|
154
120
|
it("should register servers added after the first scan", async () => {
|
|
155
121
|
const server1 = makeServer("http://127.0.0.1:8080", "model-1");
|
|
156
|
-
vi.mocked(settingsStub.resolveServers).
|
|
122
|
+
vi.mocked(settingsStub.resolveServers).mockResolvedValue([server1]);
|
|
157
123
|
const manager = new ServerManager(settingsStub);
|
|
158
124
|
await manager.update(mockPi as any);
|
|
159
125
|
expect(manager.servers).toHaveLength(1);
|
|
160
126
|
|
|
161
127
|
const server2 = makeServer("http://127.0.0.1:8081", "model-2");
|
|
162
|
-
vi.mocked(settingsStub.resolveServers).
|
|
128
|
+
vi.mocked(settingsStub.resolveServers).mockResolvedValue([
|
|
163
129
|
server1,
|
|
164
130
|
server2,
|
|
165
131
|
]);
|
|
@@ -167,13 +133,11 @@ describe("ServerManager", () => {
|
|
|
167
133
|
|
|
168
134
|
expect(mockPi.registerProvider).toHaveBeenCalledWith(
|
|
169
135
|
"llama-server=http://127.0.0.1:8081",
|
|
170
|
-
expect.objectContaining({ baseUrl: "http://127.0.0.1:8081" }),
|
|
136
|
+
expect.objectContaining({ baseUrl: "http://127.0.0.1:8081/v1" }),
|
|
171
137
|
);
|
|
172
138
|
expect(manager.servers).toHaveLength(2);
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
"model-2",
|
|
176
|
-
]);
|
|
139
|
+
const models = await manager.getAllModels();
|
|
140
|
+
expect(models.map((m) => m.id)).toEqual(["model-1", "model-2"]);
|
|
177
141
|
});
|
|
178
142
|
|
|
179
143
|
it("should unregister and disconnect removed servers on the next scan", async () => {
|
|
@@ -190,7 +154,7 @@ describe("ServerManager", () => {
|
|
|
190
154
|
const manager = await createManager(server1, server2);
|
|
191
155
|
expect(manager.servers).toHaveLength(2);
|
|
192
156
|
|
|
193
|
-
vi.mocked(settingsStub.resolveServers).
|
|
157
|
+
vi.mocked(settingsStub.resolveServers).mockResolvedValue([server1]);
|
|
194
158
|
await manager.update(mockPi as any);
|
|
195
159
|
|
|
196
160
|
expect(mockPi.unregisterProvider).toHaveBeenCalledTimes(1);
|
|
@@ -200,7 +164,9 @@ describe("ServerManager", () => {
|
|
|
200
164
|
expect(disconnectRemoved).toHaveBeenCalledTimes(1);
|
|
201
165
|
// Surviving providers keep their SSE manager connected (today's behavior)
|
|
202
166
|
expect(disconnectKept).not.toHaveBeenCalled();
|
|
203
|
-
expect(manager.getAllModels().map((m) => m.id)).toEqual([
|
|
167
|
+
expect((await manager.getAllModels()).map((m) => m.id)).toEqual([
|
|
168
|
+
"model-1",
|
|
169
|
+
]);
|
|
204
170
|
});
|
|
205
171
|
|
|
206
172
|
it("should unregister the old provider when a server URL changes", async () => {
|
|
@@ -208,7 +174,7 @@ describe("ServerManager", () => {
|
|
|
208
174
|
makeServer("http://127.0.0.1:8080", "model-1"),
|
|
209
175
|
);
|
|
210
176
|
|
|
211
|
-
vi.mocked(settingsStub.resolveServers).
|
|
177
|
+
vi.mocked(settingsStub.resolveServers).mockResolvedValue([
|
|
212
178
|
makeServer("http://127.0.0.1:9090", "model-1"),
|
|
213
179
|
]);
|
|
214
180
|
await manager.update(mockPi as any);
|
|
@@ -218,7 +184,7 @@ describe("ServerManager", () => {
|
|
|
218
184
|
);
|
|
219
185
|
expect(mockPi.registerProvider).toHaveBeenCalledWith(
|
|
220
186
|
"llama-server=http://127.0.0.1:9090",
|
|
221
|
-
expect.objectContaining({ baseUrl: "http://127.0.0.1:9090" }),
|
|
187
|
+
expect.objectContaining({ baseUrl: "http://127.0.0.1:9090/v1" }),
|
|
222
188
|
);
|
|
223
189
|
expect(manager.servers[0]?.providerId).toBe(
|
|
224
190
|
"llama-server=http://127.0.0.1:9090",
|
|
@@ -238,7 +204,7 @@ describe("ServerManager", () => {
|
|
|
238
204
|
customId: "my-custom-id",
|
|
239
205
|
customName: "B",
|
|
240
206
|
});
|
|
241
|
-
vi.mocked(settingsStub.resolveServers).
|
|
207
|
+
vi.mocked(settingsStub.resolveServers).mockResolvedValue([renamed]);
|
|
242
208
|
await manager.update(mockPi as any);
|
|
243
209
|
|
|
244
210
|
expect(mockPi.unregisterProvider).not.toHaveBeenCalled();
|
|
@@ -256,7 +222,7 @@ describe("ServerManager", () => {
|
|
|
256
222
|
|
|
257
223
|
expect(manager.servers).toHaveLength(1);
|
|
258
224
|
expect(mockPi.registerProvider).toHaveBeenCalledTimes(1);
|
|
259
|
-
expect(manager.getAllModels()).toHaveLength(1);
|
|
225
|
+
expect(await manager.getAllModels()).toHaveLength(1);
|
|
260
226
|
});
|
|
261
227
|
|
|
262
228
|
it("should return undefined from getServer for a removed server's model", async () => {
|
|
@@ -264,7 +230,7 @@ describe("ServerManager", () => {
|
|
|
264
230
|
makeServer("http://127.0.0.1:8080", "model-1"),
|
|
265
231
|
);
|
|
266
232
|
|
|
267
|
-
const live = manager.getAllModels()[0];
|
|
233
|
+
const live = (await manager.getAllModels())[0];
|
|
268
234
|
expect(manager.getServer(live)).toBe(manager.servers[0]);
|
|
269
235
|
|
|
270
236
|
const orphan = { serverUrl: "http://gone:1" } as unknown as BaseModel;
|
|
@@ -276,7 +242,7 @@ describe("ServerManager", () => {
|
|
|
276
242
|
const sortBy = () => vi.mocked(settingsStub.resolveSortBy);
|
|
277
243
|
|
|
278
244
|
it("should return models in API order when sortBy is 'api'", async () => {
|
|
279
|
-
sortBy().
|
|
245
|
+
sortBy().mockResolvedValue("api");
|
|
280
246
|
|
|
281
247
|
const mockModelA = createMockModel("model-a");
|
|
282
248
|
const mockModelZ = createMockModel("model-z");
|
|
@@ -287,7 +253,7 @@ describe("ServerManager", () => {
|
|
|
287
253
|
}),
|
|
288
254
|
);
|
|
289
255
|
|
|
290
|
-
const allModels = manager.getAllModels();
|
|
256
|
+
const allModels = await manager.getAllModels();
|
|
291
257
|
|
|
292
258
|
expect(allModels).toHaveLength(2);
|
|
293
259
|
expect(allModels[0]).toBe(mockModelA);
|
|
@@ -295,7 +261,7 @@ describe("ServerManager", () => {
|
|
|
295
261
|
});
|
|
296
262
|
|
|
297
263
|
it("should sort models by ID ascending when sortBy is 'asc'", async () => {
|
|
298
|
-
sortBy().
|
|
264
|
+
sortBy().mockResolvedValue("asc");
|
|
299
265
|
|
|
300
266
|
const mockModelZ = createMockModel("model-z");
|
|
301
267
|
const mockModelA = createMockModel("model-a");
|
|
@@ -306,7 +272,7 @@ describe("ServerManager", () => {
|
|
|
306
272
|
}),
|
|
307
273
|
);
|
|
308
274
|
|
|
309
|
-
const allModels = manager.getAllModels();
|
|
275
|
+
const allModels = await manager.getAllModels();
|
|
310
276
|
|
|
311
277
|
expect(allModels).toHaveLength(2);
|
|
312
278
|
expect(allModels[0]).toBe(mockModelA);
|
|
@@ -314,7 +280,7 @@ describe("ServerManager", () => {
|
|
|
314
280
|
});
|
|
315
281
|
|
|
316
282
|
it("should sort models by ID descending when sortBy is 'desc'", async () => {
|
|
317
|
-
sortBy().
|
|
283
|
+
sortBy().mockResolvedValue("desc");
|
|
318
284
|
|
|
319
285
|
const mockModelA = createMockModel("model-a");
|
|
320
286
|
const mockModelZ = createMockModel("model-z");
|
|
@@ -325,7 +291,7 @@ describe("ServerManager", () => {
|
|
|
325
291
|
}),
|
|
326
292
|
);
|
|
327
293
|
|
|
328
|
-
const allModels = manager.getAllModels();
|
|
294
|
+
const allModels = await manager.getAllModels();
|
|
329
295
|
|
|
330
296
|
expect(allModels).toHaveLength(2);
|
|
331
297
|
expect(allModels[0]).toBe(mockModelZ);
|
|
@@ -333,7 +299,7 @@ describe("ServerManager", () => {
|
|
|
333
299
|
});
|
|
334
300
|
|
|
335
301
|
it("should sort models by name ascending when sortBy is 'asc-name'", async () => {
|
|
336
|
-
sortBy().
|
|
302
|
+
sortBy().mockResolvedValue("asc-name");
|
|
337
303
|
|
|
338
304
|
const mockModelB = createMockModel("zebra", { id: "model-b" });
|
|
339
305
|
const mockModelA = createMockModel("alpha", { id: "model-a" });
|
|
@@ -344,7 +310,7 @@ describe("ServerManager", () => {
|
|
|
344
310
|
}),
|
|
345
311
|
);
|
|
346
312
|
|
|
347
|
-
const allModels = manager.getAllModels();
|
|
313
|
+
const allModels = await manager.getAllModels();
|
|
348
314
|
|
|
349
315
|
expect(allModels).toHaveLength(2);
|
|
350
316
|
expect(allModels[0]).toBe(mockModelA);
|
|
@@ -352,7 +318,7 @@ describe("ServerManager", () => {
|
|
|
352
318
|
});
|
|
353
319
|
|
|
354
320
|
it("should sort models by name descending when sortBy is 'desc-name'", async () => {
|
|
355
|
-
sortBy().
|
|
321
|
+
sortBy().mockResolvedValue("desc-name");
|
|
356
322
|
|
|
357
323
|
const mockModelA = createMockModel("alpha", { id: "model-a" });
|
|
358
324
|
const mockModelB = createMockModel("zebra", { id: "model-b" });
|
|
@@ -363,7 +329,7 @@ describe("ServerManager", () => {
|
|
|
363
329
|
}),
|
|
364
330
|
);
|
|
365
331
|
|
|
366
|
-
const allModels = manager.getAllModels();
|
|
332
|
+
const allModels = await manager.getAllModels();
|
|
367
333
|
|
|
368
334
|
expect(allModels).toHaveLength(2);
|
|
369
335
|
expect(allModels[0]).toBe(mockModelB);
|