pi-llama-cpp 0.11.0 → 0.12.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.
@@ -0,0 +1,352 @@
1
+ import { beforeEach, describe, expect, it } from "vitest";
2
+ import { FALLBACK_CTX } from "../src/constants";
3
+ import type { LlamaServer, ModelOverride } from "../src/interfaces/settings";
4
+ import { SingleModel } from "../src/models/singleModel";
5
+ import { Server } from "../src/server";
6
+ import {
7
+ addOverrideEntry,
8
+ applyCostFieldValue,
9
+ formatOverrideSummary,
10
+ parseCostValue,
11
+ removeOverrideEntry,
12
+ updateOverrideEntry,
13
+ } from "../src/ui/overrideEntryEditor";
14
+ import { createMockServer, mockRpc } from "./mocks";
15
+
16
+ beforeEach(() => {
17
+ mockRpc.mockReset();
18
+ });
19
+
20
+ const createModel = (overrides?: Record<string, ModelOverride>): SingleModel =>
21
+ new SingleModel(
22
+ {
23
+ id: "test",
24
+ tags: [],
25
+ object: "model",
26
+ owned_by: "test",
27
+ created: Date.now(),
28
+ },
29
+ createMockServer({ overrides }),
30
+ );
31
+
32
+ /** Standard server responses: /props for capabilities, /v1/models for n_ctx */
33
+ const mockDetection = (nCtx: number | undefined) =>
34
+ mockRpc.mockImplementation((endpoint: string) => {
35
+ if (endpoint.startsWith("/props")) {
36
+ return Promise.resolve({ modalities: { vision: false } });
37
+ }
38
+ return Promise.resolve({
39
+ data: [{ id: "test", meta: nCtx === undefined ? {} : { n_ctx: nCtx } }],
40
+ });
41
+ });
42
+
43
+ // ─── Pattern matching (Server.findOverrideForModel) ───────────────────────
44
+
45
+ describe("Server.findOverrideForModel", () => {
46
+ const makeServer = (overrides: Record<string, ModelOverride>): Server =>
47
+ createMockServer({ overrides });
48
+
49
+ it("should match a model by id prefix", () => {
50
+ const server = makeServer({ lla: { reasoning: false } });
51
+ expect(server.findOverrideForModel("llama-3")).toEqual({
52
+ reasoning: false,
53
+ });
54
+ });
55
+
56
+ it("should return undefined when no pattern matches", () => {
57
+ const server = makeServer({ qwen: { reasoning: false } });
58
+ expect(server.findOverrideForModel("llama-3")).toBeUndefined();
59
+ });
60
+
61
+ it("should prefer the longest (most specific) matching pattern", () => {
62
+ const server = makeServer({
63
+ llama: { reasoning: false },
64
+ "llama-3-8b": { reasoning: true, contextSize: 128 },
65
+ });
66
+ expect(server.findOverrideForModel("llama-3-8b")).toEqual({
67
+ reasoning: true,
68
+ contextSize: 128,
69
+ });
70
+ expect(server.findOverrideForModel("llama-3-70b")).toEqual({
71
+ reasoning: false,
72
+ });
73
+ });
74
+
75
+ it("should ignore empty patterns", () => {
76
+ const server = makeServer({ "": { reasoning: false } });
77
+ expect(server.findOverrideForModel("llama-3")).toBeUndefined();
78
+ });
79
+ });
80
+
81
+ // ─── reasoning override ────────────────────────────────────────────────────
82
+
83
+ describe("BaseModel reasoning override", () => {
84
+ it("should default to true when no override matches", () => {
85
+ expect(createModel().reasoning).toBe(true);
86
+ });
87
+
88
+ it("should let the override win over the default", () => {
89
+ const model = createModel({ test: { reasoning: false } });
90
+ expect(model.reasoning).toBe(false);
91
+ });
92
+ });
93
+
94
+ // ─── capabilities override ────────────────────────────────────────────────
95
+
96
+ describe("BaseModel capabilities override", () => {
97
+ it("should fully replace detection without contacting the server", async () => {
98
+ mockRpc.mockImplementation(() => {
99
+ throw new Error("override must not trigger a fetch");
100
+ });
101
+
102
+ const model = createModel({ test: { capabilities: ["text", "image"] } });
103
+ const capabilities = await model.getCapabilities();
104
+
105
+ expect(capabilities).toEqual(["text", "image"]);
106
+ expect(mockRpc).not.toHaveBeenCalled();
107
+ });
108
+
109
+ it("should not intercept detection when no override matches", async () => {
110
+ mockDetection(8192);
111
+
112
+ const model = createModel({ other: { capabilities: ["text"] } });
113
+ const capabilities = await model.getCapabilities();
114
+
115
+ expect(capabilities).toEqual(["text"]);
116
+ expect(mockRpc).toHaveBeenCalled();
117
+ });
118
+ });
119
+
120
+ // ─── contextSize override ─────────────────────────────────────────────────
121
+
122
+ describe("BaseModel.getContextSize with contextSize override", () => {
123
+ it("should return the overridden context size instead of the detected one", async () => {
124
+ mockDetection(8192);
125
+
126
+ const model = createModel({ test: { contextSize: 32768 } });
127
+ const ctxSize = await model.getContextSize();
128
+
129
+ expect(ctxSize).toBe(32768);
130
+ });
131
+
132
+ it("should treat a stored 0 as absent and autodetect", async () => {
133
+ mockDetection(8192);
134
+
135
+ const model = createModel({ test: { contextSize: 0 } });
136
+ const ctxSize = await model.getContextSize();
137
+
138
+ expect(ctxSize).toBe(8192);
139
+ });
140
+
141
+ it("should autodetect when no override matches", async () => {
142
+ mockDetection(8192);
143
+
144
+ const model = createModel({ other: { contextSize: 32768 } });
145
+ const ctxSize = await model.getContextSize();
146
+
147
+ expect(ctxSize).toBe(8192);
148
+ });
149
+ });
150
+
151
+ // ─── toProviderConfig (cost, maxTokens, compat, precedence) ───────────────
152
+
153
+ describe("toProviderConfig overrides", () => {
154
+ it("should merge a partial cost override with zero defaults", async () => {
155
+ mockDetection(8192);
156
+
157
+ const model = createModel({ test: { cost: { input: 0.2 } } });
158
+ const config = await model.toProviderConfig();
159
+
160
+ expect(config.cost).toEqual({
161
+ input: 0.2,
162
+ output: 0,
163
+ cacheRead: 0,
164
+ cacheWrite: 0,
165
+ });
166
+ });
167
+
168
+ it("should default every cost field to zero without an override", async () => {
169
+ mockDetection(8192);
170
+
171
+ const model = createModel();
172
+ const config = await model.toProviderConfig();
173
+
174
+ expect(config.cost).toEqual({
175
+ input: 0,
176
+ output: 0,
177
+ cacheRead: 0,
178
+ cacheWrite: 0,
179
+ });
180
+ });
181
+
182
+ it("should pass a compat override through to the provider config", async () => {
183
+ mockDetection(8192);
184
+
185
+ const compat = {
186
+ supportsStore: false,
187
+ maxTokensField: "max_tokens",
188
+ } as const;
189
+ const model = createModel({ test: { compat } });
190
+ const config = await model.toProviderConfig();
191
+
192
+ expect(config.compat).toEqual(compat);
193
+ });
194
+
195
+ it("should leave compat undefined without an override", async () => {
196
+ mockDetection(8192);
197
+
198
+ const model = createModel();
199
+ const config = await model.toProviderConfig();
200
+
201
+ expect(config.compat).toBeUndefined();
202
+ });
203
+
204
+ it("should use the overridden context size for contextWindow and as the maxTokens fallback", async () => {
205
+ mockDetection(8192);
206
+
207
+ const model = createModel({ test: { contextSize: 32768 } });
208
+ const config = await model.toProviderConfig();
209
+
210
+ expect(config.contextWindow).toBe(32768);
211
+ expect(config.maxTokens).toBe(32768);
212
+ });
213
+
214
+ it("should prefer an explicit maxTokens override over the contextSize override", async () => {
215
+ mockDetection(8192);
216
+
217
+ const model = createModel({
218
+ test: { contextSize: 32768, maxTokens: 4096 },
219
+ });
220
+ const config = await model.toProviderConfig();
221
+
222
+ expect(config.contextWindow).toBe(32768);
223
+ expect(config.maxTokens).toBe(4096);
224
+ });
225
+
226
+ it("should use the detected context size when no override matches", async () => {
227
+ mockDetection(8192);
228
+
229
+ const model = createModel();
230
+ const config = await model.toProviderConfig();
231
+
232
+ expect(config.contextWindow).toBe(8192);
233
+ expect(config.maxTokens).toBe(8192);
234
+ });
235
+
236
+ it("should fall back to FALLBACK_CTX when the model is missing from detection", async () => {
237
+ mockRpc.mockImplementation((endpoint: string) => {
238
+ if (endpoint.startsWith("/props")) {
239
+ return Promise.resolve({ modalities: { vision: false } });
240
+ }
241
+ // /v1/models: no entry for this model → getContextSize throws → fallback
242
+ return Promise.resolve({ data: [] });
243
+ });
244
+
245
+ const model = createModel();
246
+ const config = await model.toProviderConfig();
247
+
248
+ expect(config.contextWindow).toBe(FALLBACK_CTX);
249
+ expect(config.maxTokens).toBe(FALLBACK_CTX);
250
+ });
251
+ });
252
+
253
+ // ─── formatOverrideSummary ────────────────────────────────────────────────
254
+
255
+ describe("formatOverrideSummary", () => {
256
+ it("should render every configured field", () => {
257
+ const summary = formatOverrideSummary({
258
+ cost: { input: 0.2, output: 0.6, cacheRead: 0.01 },
259
+ capabilities: ["text", "image"],
260
+ reasoning: false,
261
+ contextSize: 32768,
262
+ maxTokens: 4096,
263
+ });
264
+
265
+ expect(summary).toContain("input: $0.2");
266
+ expect(summary).toContain("output: $0.6");
267
+ expect(summary).toContain("cache read: $0.01");
268
+ expect(summary).toContain("capabilities: text,image");
269
+ expect(summary).toContain("reasoning: false");
270
+ expect(summary).toContain("contextSize: 32768");
271
+ expect(summary).toContain("maxTokens: 4096");
272
+ });
273
+
274
+ it("should omit zero, undefined and empty fields", () => {
275
+ const summary = formatOverrideSummary({
276
+ cost: { input: 0, output: 0.6 },
277
+ reasoning: undefined,
278
+ });
279
+
280
+ expect(summary).not.toContain("input:");
281
+ expect(summary).toContain("output: $0.6");
282
+ expect(summary).not.toContain("capabilities");
283
+ expect(summary).not.toContain("reasoning");
284
+ expect(summary).not.toContain("contextSize");
285
+ expect(summary).not.toContain("maxTokens");
286
+ });
287
+
288
+ it("should render an em dash for an empty override", () => {
289
+ expect(formatOverrideSummary({})).toBe("—");
290
+ });
291
+ });
292
+
293
+ // ─── override entry list helpers (overrideEntryEditor) ────────────────────
294
+
295
+ describe("override entry list helpers", () => {
296
+ const servers = [
297
+ { url: "http://a", overrides: { "a-1": { reasoning: false } } },
298
+ { url: "http://b" },
299
+ ] as LlamaServer[];
300
+
301
+ it("addOverrideEntry should append a pattern → override entry", () => {
302
+ const next = addOverrideEntry(servers, 0, "a-2", { contextSize: 4096 });
303
+ expect(next[0].overrides).toEqual({
304
+ "a-1": { reasoning: false },
305
+ "a-2": { contextSize: 4096 },
306
+ });
307
+ });
308
+
309
+ it("updateOverrideEntry should replace in place without reordering", () => {
310
+ const next = updateOverrideEntry(servers, 0, 0, "a-renamed", {
311
+ reasoning: true,
312
+ });
313
+ expect(Object.keys(next[0].overrides!)).toEqual(["a-renamed"]);
314
+ expect(next[0].overrides!["a-renamed"]).toEqual({ reasoning: true });
315
+ expect(next[1]).toBe(servers[1]);
316
+ });
317
+
318
+ it("removeOverrideEntry should drop only the targeted entry", () => {
319
+ const withTwo = addOverrideEntry(servers, 0, "a-2", {});
320
+ const next = removeOverrideEntry(withTwo, 0, 0);
321
+ expect(Object.keys(next[0].overrides!)).toEqual(["a-2"]);
322
+ });
323
+
324
+ it("parseCostValue should accept blank, non-negative numbers; reject the rest", () => {
325
+ expect(parseCostValue("")).toBe(0);
326
+ expect(parseCostValue(" 0.5 ")).toBe(0.5);
327
+ expect(parseCostValue("-1")).toBeNull();
328
+ expect(parseCostValue("abc")).toBeNull();
329
+ expect(parseCostValue("Infinity")).toBeNull();
330
+ });
331
+
332
+ it("applyCostFieldValue should set a positive value, keeping other fields", () => {
333
+ const next = applyCostFieldValue({ input: 0.2 }, "output", 0.6);
334
+ expect(next).toEqual({ input: 0.2, output: 0.6 });
335
+ });
336
+
337
+ it("applyCostFieldValue should remove the field on zero", () => {
338
+ const next = applyCostFieldValue({ input: 0.2, output: 0.6 }, "input", 0);
339
+ expect(next).toEqual({ output: 0.6 });
340
+ });
341
+
342
+ it("applyCostFieldValue should return undefined when the last field is zeroed", () => {
343
+ expect(applyCostFieldValue({ input: 0.2 }, "input", 0)).toBeUndefined();
344
+ expect(applyCostFieldValue(undefined, "input", 0)).toBeUndefined();
345
+ });
346
+
347
+ it("applyCostFieldValue should treat an empty override as unset cost", () => {
348
+ expect(applyCostFieldValue(undefined, "input", 0.5)).toEqual({
349
+ input: 0.5,
350
+ });
351
+ });
352
+ });
@@ -154,16 +154,16 @@ describe("Server postRequest", () => {
154
154
  });
155
155
  });
156
156
 
157
- describe("Server timeouts", () => {
158
- it("should resolve timeouts from the injected settings", () => {
157
+ describe("Server timeouts", async () => {
158
+ it("should resolve timeouts from the injected settings", async () => {
159
159
  const server = new Server(settings, { baseUrl: "http://127.0.0.1:8080" });
160
160
 
161
- expect(server.serverTimeout).toBe(SERVER_TIMEOUT);
162
- expect(server.pollingTimeout).toBe(POLLING_TIMEOUT);
161
+ expect(await server.getServerTimeout()).toBe(SERVER_TIMEOUT);
162
+ expect(await server.getPollingTimeout()).toBe(POLLING_TIMEOUT);
163
163
  });
164
164
 
165
- it("should return resolved custom values", () => {
166
- vi.mocked(settings.resolveTimeouts).mockReturnValue({
165
+ it("should return resolved custom values", async () => {
166
+ vi.mocked(settings.resolveTimeouts).mockResolvedValue({
167
167
  pollingTimeout: 90000,
168
168
  serverTimeout: 2000,
169
169
  });
@@ -174,23 +174,23 @@ describe("Server timeouts", () => {
174
174
  customName: "My Server",
175
175
  });
176
176
 
177
- expect(server.pollingTimeout).toBe(90000);
177
+ expect(await server.getPollingTimeout()).toBe(90000);
178
178
  });
179
179
 
180
- it("should read timeouts live from settings", () => {
180
+ it("should read timeouts live from settings", async () => {
181
181
  const server = new Server(settings, { baseUrl: "http://127.0.0.1:8080" });
182
182
 
183
- vi.mocked(settings.resolveTimeouts).mockReturnValue({
183
+ vi.mocked(settings.resolveTimeouts).mockResolvedValue({
184
184
  pollingTimeout: 120000,
185
185
  serverTimeout: 3000,
186
186
  });
187
- expect(server.pollingTimeout).toBe(120000);
187
+ expect(await server.getPollingTimeout()).toBe(120000);
188
188
 
189
- vi.mocked(settings.resolveTimeouts).mockReturnValue({
189
+ vi.mocked(settings.resolveTimeouts).mockResolvedValue({
190
190
  pollingTimeout: 90000,
191
191
  serverTimeout: 2000,
192
192
  });
193
- expect(server.pollingTimeout).toBe(90000);
193
+ expect(await server.getPollingTimeout()).toBe(90000);
194
194
  });
195
195
  });
196
196
 
@@ -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).mockReturnValue(servers);
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 = {
@@ -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).mockReturnValue([server1]);
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).mockReturnValue([
128
+ vi.mocked(settingsStub.resolveServers).mockResolvedValue([
163
129
  server1,
164
130
  server2,
165
131
  ]);
@@ -170,10 +136,8 @@ describe("ServerManager", () => {
170
136
  expect.objectContaining({ baseUrl: "http://127.0.0.1:8081" }),
171
137
  );
172
138
  expect(manager.servers).toHaveLength(2);
173
- expect(manager.getAllModels().map((m) => m.id)).toEqual([
174
- "model-1",
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).mockReturnValue([server1]);
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(["model-1"]);
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).mockReturnValue([
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);
@@ -238,7 +204,7 @@ describe("ServerManager", () => {
238
204
  customId: "my-custom-id",
239
205
  customName: "B",
240
206
  });
241
- vi.mocked(settingsStub.resolveServers).mockReturnValue([renamed]);
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().mockReturnValue("api");
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().mockReturnValue("asc");
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().mockReturnValue("desc");
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().mockReturnValue("asc-name");
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().mockReturnValue("desc-name");
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);