pi-llama-cpp 0.9.0 → 0.9.2

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-llama-cpp",
3
- "version": "0.9.0",
3
+ "version": "0.9.2",
4
4
  "description": "Pi extension for llama.cpp integration. Supports router, single and legacy models. Supports multiple servers.",
5
5
  "keywords": [
6
6
  "pi",
@@ -32,13 +32,13 @@
32
32
  ]
33
33
  },
34
34
  "peerDependencies": {
35
- "@earendil-works/pi-ai": "*",
36
- "@earendil-works/pi-coding-agent": "*",
37
- "@earendil-works/pi-tui": "*"
35
+ "@earendil-works/pi-ai": ">=0.84.0",
36
+ "@earendil-works/pi-coding-agent": ">=0.84.0",
37
+ "@earendil-works/pi-tui": ">=0.84.0"
38
38
  },
39
39
  "devDependencies": {
40
- "@types/node": "^26.1.1",
40
+ "@types/node": "^26.2.0",
41
41
  "prettier-plugin-organize-imports": "^4.3.0",
42
- "vitest": "^4.1.10"
42
+ "vitest": "^4.1.11"
43
43
  }
44
44
  }
package/src/index.ts CHANGED
@@ -47,8 +47,8 @@ export default async function (pi: ExtensionAPI) {
47
47
 
48
48
  pi.on(
49
49
  "before_provider_request",
50
- async (event: BeforeProviderRequestEvent) =>
51
- await eventManager.onBeforeProviderRequest(event),
50
+ async (event: BeforeProviderRequestEvent, ctx: ExtensionContext) =>
51
+ await eventManager.onBeforeProviderRequest(event, ctx),
52
52
  );
53
53
 
54
54
  pi.on(
@@ -177,15 +177,20 @@ export class CommandManager {
177
177
  }
178
178
  };
179
179
 
180
+ const onFinished = async () => {
181
+ cleanupProgress();
182
+ EventManager.resetInflightModel();
183
+
184
+ // Re-scan providers to ensure accuracy of loaded models
185
+ await this.serverManager.update(pi);
186
+
187
+ // Force TUI refresh so Pi picks up the updated model states
188
+ ctx.ui.setStatus(PROVIDER_NAME, " ");
189
+ ctx.ui.setStatus(PROVIDER_NAME, undefined);
190
+ };
191
+
180
192
  // Load the model without blocking the UI
181
- model
182
- .load()
183
- .then(onSuccess)
184
- .catch(onFailure)
185
- .finally(() => {
186
- cleanupProgress();
187
- EventManager.resetInflightModel();
188
- });
193
+ model.load().then(onSuccess).catch(onFailure).finally(onFinished);
189
194
  }
190
195
  }
191
196
 
@@ -72,7 +72,10 @@ export class EventManager {
72
72
  * @param event Request event
73
73
  * @returns Updated payload
74
74
  */
75
- async onBeforeProviderRequest(event: BeforeProviderRequestEvent) {
75
+ async onBeforeProviderRequest(
76
+ event: BeforeProviderRequestEvent,
77
+ ctx: ExtensionContext,
78
+ ) {
76
79
  const payload = event.payload as { model?: string };
77
80
  const { model } = payload;
78
81
  if (!model) return payload;
@@ -86,7 +89,8 @@ export class EventManager {
86
89
 
87
90
  // Retrieve pi's current thinking level, so we can setup a budget
88
91
  const resolver = new ConfigResolver();
89
- const level = resolver.resolveThinkingLevel() ?? "medium";
92
+ const level =
93
+ ctx.thinkingLevel ?? resolver.resolveThinkingLevel() ?? "medium";
90
94
  const budgets = resolver.resolveThinkingBudgets();
91
95
  const thinking_budget_tokens = budgets[level];
92
96
 
@@ -44,6 +44,21 @@ const createNonLlamaPayload = () => ({
44
44
  messages: [{ role: "user", content: "hello" }],
45
45
  });
46
46
 
47
+ const createMockCtx = (
48
+ thinkingLevel?:
49
+ | "off"
50
+ | "minimal"
51
+ | "low"
52
+ | "medium"
53
+ | "high"
54
+ | "xhigh"
55
+ | "max",
56
+ ) =>
57
+ ({
58
+ thinkingLevel,
59
+ ui: { notify: vi.fn() },
60
+ }) as any;
61
+
47
62
  describe("EventManager.onBeforeProviderRequest", () => {
48
63
  describe("normal usage — each thinking level", () => {
49
64
  it.each([
@@ -68,8 +83,10 @@ describe("EventManager.onBeforeProviderRequest", () => {
68
83
  const eventManager = new EventManager([server]);
69
84
  const event = { payload: createPayload("model-a") };
70
85
 
86
+ const ctx = createMockCtx(level as any);
71
87
  const result = (await eventManager.onBeforeProviderRequest(
72
88
  event as any,
89
+ ctx,
73
90
  )) as Record<string, unknown>;
74
91
 
75
92
  expect(result.model).toBe("model-a");
@@ -92,8 +109,10 @@ describe("EventManager.onBeforeProviderRequest", () => {
92
109
  },
93
110
  };
94
111
 
112
+ const ctx = createMockCtx("low");
95
113
  const result = (await eventManager.onBeforeProviderRequest(
96
114
  event as any,
115
+ ctx,
97
116
  )) as Record<string, unknown>;
98
117
 
99
118
  expect(result.messages).toEqual([{ role: "user", content: "test" }]);
@@ -110,7 +129,11 @@ describe("EventManager.onBeforeProviderRequest", () => {
110
129
  const eventManager = new EventManager([server]);
111
130
  const event = { payload: createNonLlamaPayload() };
112
131
 
113
- const result = await eventManager.onBeforeProviderRequest(event as any);
132
+ const ctx = createMockCtx();
133
+ const result = await eventManager.onBeforeProviderRequest(
134
+ event as any,
135
+ ctx,
136
+ );
114
137
 
115
138
  expect(result).toEqual(createNonLlamaPayload());
116
139
  });
@@ -124,7 +147,11 @@ describe("EventManager.onBeforeProviderRequest", () => {
124
147
  const eventManager = new EventManager([server]);
125
148
  const event = { payload: { messages: [] } };
126
149
 
127
- const result = await eventManager.onBeforeProviderRequest(event as any);
150
+ const ctx = createMockCtx();
151
+ const result = await eventManager.onBeforeProviderRequest(
152
+ event as any,
153
+ ctx,
154
+ );
128
155
 
129
156
  expect(result).toEqual({ messages: [] });
130
157
  });
@@ -141,8 +168,10 @@ describe("EventManager.onBeforeProviderRequest", () => {
141
168
  const eventManager = new EventManager([server]);
142
169
  const event = { payload: createPayload("model-a") };
143
170
 
171
+ const ctx = createMockCtx("low");
144
172
  const result = (await eventManager.onBeforeProviderRequest(
145
173
  event as any,
174
+ ctx,
146
175
  )) as Record<string, unknown>;
147
176
 
148
177
  expect(result.thinking_budget_tokens).toBe(4096);
@@ -158,8 +187,10 @@ describe("EventManager.onBeforeProviderRequest", () => {
158
187
  const eventManager = new EventManager([server]);
159
188
  const event = { payload: createPayload("model-a") };
160
189
 
190
+ const ctx = createMockCtx("medium");
161
191
  const result = (await eventManager.onBeforeProviderRequest(
162
192
  event as any,
193
+ ctx,
163
194
  )) as Record<string, unknown>;
164
195
 
165
196
  // medium uses default since user only overrode low
@@ -185,8 +216,10 @@ describe("EventManager.onBeforeProviderRequest", () => {
185
216
  const eventManager = new EventManager([server]);
186
217
  const event = { payload: createPayload("model-a") };
187
218
 
219
+ const ctx = createMockCtx("medium");
188
220
  const result = (await eventManager.onBeforeProviderRequest(
189
221
  event as any,
222
+ ctx,
190
223
  )) as Record<string, unknown>;
191
224
 
192
225
  // Should fall back to default since "medium" is not in user budgets
@@ -207,8 +240,10 @@ describe("EventManager.onBeforeProviderRequest", () => {
207
240
  const eventManager = new EventManager([server]);
208
241
  const event = { payload: createPayload("model-a") };
209
242
 
243
+ const ctx = createMockCtx("off");
210
244
  const result = (await eventManager.onBeforeProviderRequest(
211
245
  event as any,
246
+ ctx,
212
247
  )) as Record<string, unknown>;
213
248
 
214
249
  expect(result).toMatchObject({
@@ -229,8 +264,10 @@ describe("EventManager.onBeforeProviderRequest", () => {
229
264
  const eventManager = new EventManager([server]);
230
265
  const event = { payload: createPayload("model-a") };
231
266
 
267
+ const ctx = createMockCtx("max");
232
268
  const result = (await eventManager.onBeforeProviderRequest(
233
269
  event as any,
270
+ ctx,
234
271
  )) as Record<string, unknown>;
235
272
 
236
273
  expect(result).toEqual(createPayload("model-a"));
@@ -247,8 +284,10 @@ describe("EventManager.onBeforeProviderRequest", () => {
247
284
  const eventManager = new EventManager([server]);
248
285
  const event = { payload: createPayload("model-a") };
249
286
 
287
+ const ctx = createMockCtx("high");
250
288
  const result = (await eventManager.onBeforeProviderRequest(
251
289
  event as any,
290
+ ctx,
252
291
  )) as Record<string, unknown>;
253
292
 
254
293
  expect(result.thinking_budget_tokens).toBe(DEFAULT_THINKING_BUDGETS.high);