pi-mtplx 0.1.6 → 0.1.8
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 +1 -0
- package/extensions/mtplx.ts +22 -4
- package/package.json +1 -1
- package/src/mtplx-process.ts +4 -6
- package/src/utils.ts +26 -1
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
|
|
package/extensions/mtplx.ts
CHANGED
|
@@ -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,
|
|
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
|
|
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
package/src/mtplx-process.ts
CHANGED
|
@@ -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
|
|
|
@@ -110,17 +110,15 @@ export async function startServer(modelId: string): Promise<void> {
|
|
|
110
110
|
configured.ref,
|
|
111
111
|
"--model-id",
|
|
112
112
|
modelId,
|
|
113
|
-
"--profile",
|
|
114
|
-
"sustained",
|
|
115
113
|
"--fan-mode",
|
|
116
114
|
getFanMode(),
|
|
117
115
|
"--host",
|
|
118
116
|
HOST,
|
|
119
117
|
"--port",
|
|
120
118
|
String(PORT),
|
|
121
|
-
//
|
|
119
|
+
// Explicitly pass the user's persisted choice; this extension defaults it to on.
|
|
122
120
|
"--ssd-session-cache",
|
|
123
|
-
"off",
|
|
121
|
+
loadSsdSessionCache() ? "on" : "off",
|
|
124
122
|
],
|
|
125
123
|
{ detached: true, stdio: "ignore" },
|
|
126
124
|
);
|
|
@@ -210,4 +208,4 @@ export function release(): void {
|
|
|
210
208
|
activeModel = undefined;
|
|
211
209
|
for (const resolve of idleWaiters.splice(0)) resolve();
|
|
212
210
|
}
|
|
213
|
-
}
|
|
211
|
+
}
|
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
|
+
}
|