pi-mtplx 0.1.6 → 0.1.7

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 CHANGED
@@ -36,6 +36,7 @@ Run `/mtplx` to open an interactive menu:
36
36
  | -------- | ------------- |
37
37
  | **Toggle (on/off)** | Start or stop the MTPLX server |
38
38
  | **Fan Curves** | Set the thermal profile (`default`, `smart`, `max`) |
39
+ | **SSD Session Cache** | Enable or disable MTPLX's SSD-backed session cache for subsequent server starts (on by default) |
39
40
  | **Models** | Register or unregister models — ✓ means registered (click to unregister), ✗ means available (click to register) |
40
41
  | **Uninstall** | Remove the `mtplx` provider from Pi's config |
41
42
 
@@ -9,17 +9,24 @@
9
9
  import { acquire, release, stopServer } from "../src/mtplx-process.ts";
10
10
  import { getFanMode, health, setFanMode, setFanModeValue } from "../src/mtplx-client.ts";
11
11
  import { MTPLX_PROVIDER, manageModels, removeModel, removePiMtplxProvider } from "../src/model-discovery.ts";
12
- import { FAN_MODES, isMtplxModel, saveFanMode, type FanMode } from "../src/utils.ts";
12
+ import { FAN_MODES, isMtplxModel, loadSsdSessionCache, saveFanMode, saveSsdSessionCache, type FanMode } from "../src/utils.ts";
13
13
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
14
14
 
15
15
  export default function mtplxAutostart(pi: ExtensionAPI): void {
16
16
  pi.registerCommand("mtplx", {
17
- description: "MTPLX — toggle the server, pick a fan curve, manage models, or uninstall",
17
+ description: "MTPLX — toggle the server, configure fan and SSD cache, manage models, or uninstall",
18
18
  handler: async (_args, ctx) => {
19
19
  const current = await health();
20
20
  const status = current ? "on" : "off";
21
21
  await ctx.ui.setStatus("mtplx", `MTPLX: ${status}`);
22
- const topChoices = [`Toggle (${status})`, `Fan Curves (current: ${getFanMode()})`, "Models", "Uninstall (remove provider)"];
22
+ const ssdSessionCache = loadSsdSessionCache();
23
+ const topChoices = [
24
+ `Toggle (${status})`,
25
+ `Fan Curves (current: ${getFanMode()})`,
26
+ `SSD Session Cache (current: ${ssdSessionCache ? "on" : "off"})`,
27
+ "Models",
28
+ "Uninstall (remove provider)",
29
+ ];
23
30
  const top = await ctx.ui.select("MTPLX", topChoices, undefined);
24
31
  if (!top) return;
25
32
  if (top.startsWith("Toggle")) {
@@ -47,6 +54,17 @@ export default function mtplxAutostart(pi: ExtensionAPI): void {
47
54
  }
48
55
  ctx.ui.notify(`MTPLX fan mode set to ${getFanMode()}`, "info");
49
56
  }
57
+ if (top.startsWith("SSD Session Cache")) {
58
+ const choices = [
59
+ ssdSessionCache ? "Off" : "Off (current)",
60
+ ssdSessionCache ? "On (current)" : "On",
61
+ ];
62
+ const picked = await ctx.ui.select("MTPLX — SSD session cache for future server starts", choices, undefined);
63
+ if (!picked) return;
64
+ const enabled = picked.startsWith("On");
65
+ saveSsdSessionCache(enabled);
66
+ ctx.ui.notify(`MTPLX SSD session cache will be ${enabled ? "on" : "off"} the next time the server starts.`, "info");
67
+ }
50
68
  if (top.startsWith("Models")) {
51
69
  await manageModels(ctx);
52
70
  }
@@ -87,4 +105,4 @@ export default function mtplxAutostart(pi: ExtensionAPI): void {
87
105
  console.error(`MTPLX cleanup on quit failed: ${error instanceof Error ? error.message : String(error)}`);
88
106
  }
89
107
  });
90
- }
108
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-mtplx",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "Zero-config MTPLX integration for Pi coding agent",
5
5
  "keywords": [
6
6
  "pi-package",
@@ -21,7 +21,7 @@ import { promisify } from "node:util";
21
21
  import type { ChildProcess } from "node:child_process";
22
22
  import { getFanMode, health, setFanMode, type Health } from "./mtplx-client.ts";
23
23
  import { MTPLX_MODELS } from "./model-discovery.ts";
24
- import { HOST, PORT, READY_TIMEOUT_MS, POLL_MS, sleep, commandError, portIsOccupied } from "./utils.ts";
24
+ import { HOST, PORT, READY_TIMEOUT_MS, POLL_MS, loadSsdSessionCache, sleep, commandError, portIsOccupied } from "./utils.ts";
25
25
 
26
26
  const execFileAsync = promisify(execFile);
27
27
 
@@ -118,9 +118,9 @@ export async function startServer(modelId: string): Promise<void> {
118
118
  HOST,
119
119
  "--port",
120
120
  String(PORT),
121
- // Keep the KV-cache SSD cold tier off (CLI default is `on`). Do not remove.
121
+ // Explicitly pass the user's persisted choice; this extension defaults it to on.
122
122
  "--ssd-session-cache",
123
- "off",
123
+ loadSsdSessionCache() ? "on" : "off",
124
124
  ],
125
125
  { detached: true, stdio: "ignore" },
126
126
  );
@@ -210,4 +210,4 @@ export function release(): void {
210
210
  activeModel = undefined;
211
211
  for (const resolve of idleWaiters.splice(0)) resolve();
212
212
  }
213
- }
213
+ }
package/src/utils.ts CHANGED
@@ -13,6 +13,7 @@ export const POLL_MS = 500;
13
13
 
14
14
  export type FanMode = "default" | "smart" | "max";
15
15
  export const FAN_MODES: readonly FanMode[] = ["default", "smart", "max"];
16
+ export const DEFAULT_SSD_SESSION_CACHE = true;
16
17
 
17
18
  // Fan mode ("fan curve") applied at autostart, live-updated from `/mtplx` while the
18
19
  // server runs. Persisted to disk so the choice survives Pi restarts: `fanMode` is a
@@ -41,6 +42,30 @@ export function saveFanMode(fanMode: FanMode): void {
41
42
  }
42
43
  }
43
44
 
45
+ // SSD session caching is deliberately opt-in for this extension. Persist the
46
+ // choice independently of the fan setting so a user can enable it without
47
+ // altering their existing thermal preference.
48
+ export const SSD_SESSION_CACHE_FILE = join(homedir(), ".pi", "agent", "mtplx-ssd-session-cache.json");
49
+
50
+ export function loadSsdSessionCache(): boolean {
51
+ try {
52
+ const parsed = JSON.parse(readFileSync(SSD_SESSION_CACHE_FILE, "utf8")) as { enabled?: unknown };
53
+ if (typeof parsed.enabled === "boolean") return parsed.enabled;
54
+ } catch {
55
+ // missing or corrupt file → fall back to the default
56
+ }
57
+ return DEFAULT_SSD_SESSION_CACHE;
58
+ }
59
+
60
+ export function saveSsdSessionCache(enabled: boolean): void {
61
+ try {
62
+ mkdirSync(join(homedir(), ".pi", "agent"), { recursive: true });
63
+ writeFileSync(SSD_SESSION_CACHE_FILE, JSON.stringify({ enabled }, null, 2) + "\n");
64
+ } catch (error) {
65
+ console.error(`MTPLX could not persist SSD session-cache preference: ${error instanceof Error ? error.message : String(error)}`);
66
+ }
67
+ }
68
+
44
69
  // Derive Pi's model id from an artifact ref: "Youssofal/Qwen3.8-27B-MTPLX-Optimized-Quality"
45
70
  // → "mtplx-qwen38-27b-optimized-quality" (same scheme as the built-in entry).
46
71
  export function modelIdFromRef(ref: string): string {
@@ -98,4 +123,4 @@ export function portIsOccupied(): Promise<boolean> {
98
123
  socket.once("timeout", () => done(false));
99
124
  socket.once("error", () => done(false));
100
125
  });
101
- }
126
+ }