pi-set-model 0.1.3 → 0.1.4
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/CHANGELOG.md +10 -0
- package/LICENSE +0 -0
- package/README.md +4 -2
- package/package.json +19 -4
- package/set-model.ts +13 -5
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.4 - 2026-08-23
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- Mark Pi's host-provided SDK packages as optional wildcard peers so npm does not install a redundant Pi SDK dependency tree.
|
|
8
|
+
- Verify development and tests against Pi SDK 0.84.2 while retaining runtime compatibility with Pi 0.84.1 and newer.
|
|
9
|
+
- Reject empty saved preference fields and explicitly clamp restored thinking levels with Pi's model-capability helper.
|
|
10
|
+
- Document that the individual package and GitHub bundle must not be installed together.
|
package/LICENSE
CHANGED
|
File without changes
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# pi-set-model
|
|
2
2
|
|
|
3
|
-
Remembers Pi's selected model and thinking level for each project folder. Requires
|
|
3
|
+
Remembers Pi's selected model and thinking level for each project folder. Requires Pi 0.84.1 or newer (tested with the current Pi 0.84.2 release).
|
|
4
4
|
|
|
5
5
|
After selecting a model and thinking level, explicitly save that combination for the current working directory with `/set-model set`. New Pi sessions opened in that directory restore it, rather than retaining the model selected in another project. Later `/model` or thinking changes do not modify the saved preference unless you run `/set-model set` again.
|
|
6
6
|
|
|
@@ -8,6 +8,8 @@ Preferences are stored in the project at `.pi/set-model.json`; they are never sh
|
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
11
|
+
> **Avoid duplicate installation.** Install this npm package or the GitHub bundle, not both. Loading both copies can duplicate commands and preference-restoration handlers.
|
|
12
|
+
|
|
11
13
|
```bash
|
|
12
14
|
pi install npm:pi-set-model
|
|
13
15
|
```
|
|
@@ -31,7 +33,7 @@ Autocomplete completes `/setm...` to `/set-model` without adding a trailing spac
|
|
|
31
33
|
|
|
32
34
|
The folder is Pi's current working directory. Run Pi from the project root when you want one preference for the whole project. The setting is saved at `<cwd>/.pi/set-model.json`.
|
|
33
35
|
|
|
34
|
-
If the saved model is unavailable or has no configured API key, Pi keeps the active model and shows a warning. Thinking levels are restored after the model and
|
|
36
|
+
If the saved model is unavailable or has no configured API key, Pi keeps the active model and shows a warning. Empty or malformed preference fields are ignored. Thinking levels are restored after the model and explicitly clamped with Pi's model-capability helper; the restore notice identifies an unsupported saved level. When the session ends, the model and thinking level that were active before the project preference was applied are restored.
|
|
35
37
|
|
|
36
38
|
## Issues and feedback
|
|
37
39
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-set-model",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Pi extension that remembers model and thinking level per project folder",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
@@ -14,10 +14,25 @@
|
|
|
14
14
|
},
|
|
15
15
|
"bugs": { "url": "https://github.com/hknet/pi-extensions/issues" },
|
|
16
16
|
"homepage": "https://github.com/hknet/pi-extensions/tree/main/packages/pi-set-model#readme",
|
|
17
|
-
"files": ["set-model.ts", "README.md"],
|
|
17
|
+
"files": ["set-model.ts", "README.md", "CHANGELOG.md"],
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=22.19.0"
|
|
20
|
+
},
|
|
18
21
|
"peerDependencies": {
|
|
19
|
-
"@earendil-works/pi-
|
|
20
|
-
"@earendil-works/pi-
|
|
22
|
+
"@earendil-works/pi-ai": "*",
|
|
23
|
+
"@earendil-works/pi-coding-agent": "*",
|
|
24
|
+
"@earendil-works/pi-tui": "*"
|
|
25
|
+
},
|
|
26
|
+
"peerDependenciesMeta": {
|
|
27
|
+
"@earendil-works/pi-ai": {
|
|
28
|
+
"optional": true
|
|
29
|
+
},
|
|
30
|
+
"@earendil-works/pi-coding-agent": {
|
|
31
|
+
"optional": true
|
|
32
|
+
},
|
|
33
|
+
"@earendil-works/pi-tui": {
|
|
34
|
+
"optional": true
|
|
35
|
+
}
|
|
21
36
|
},
|
|
22
37
|
"pi": { "extensions": ["./set-model.ts"] }
|
|
23
38
|
}
|
package/set-model.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { mkdir, readFile, rename, unlink, writeFile } from "node:fs/promises";
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
|
+
import { clampThinkingLevel } from "@earendil-works/pi-ai";
|
|
3
4
|
import { CONFIG_DIR_NAME, type ExtensionAPI, type ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
4
5
|
import type { AutocompleteItem } from "@earendil-works/pi-tui";
|
|
5
6
|
|
|
@@ -38,10 +39,13 @@ export async function loadPreference(path: string): Promise<ProjectPreference |
|
|
|
38
39
|
const preference = parsed as Partial<ProjectPreference>;
|
|
39
40
|
if (
|
|
40
41
|
typeof preference.provider !== "string" ||
|
|
42
|
+
preference.provider.trim() === "" ||
|
|
41
43
|
typeof preference.model !== "string" ||
|
|
42
|
-
|
|
44
|
+
preference.model.trim() === "" ||
|
|
45
|
+
typeof preference.thinkingLevel !== "string" ||
|
|
46
|
+
preference.thinkingLevel.trim() === ""
|
|
43
47
|
) {
|
|
44
|
-
throw new Error("expected provider, model, and thinkingLevel");
|
|
48
|
+
throw new Error("expected non-empty provider, model, and thinkingLevel strings");
|
|
45
49
|
}
|
|
46
50
|
return preference as ProjectPreference;
|
|
47
51
|
} catch (error: unknown) {
|
|
@@ -160,15 +164,19 @@ export default function setModelExtension(pi: ExtensionAPI) {
|
|
|
160
164
|
ctx.ui.notify(`No API key for project model: ${preference.provider}/${preference.model}`, "warning");
|
|
161
165
|
return;
|
|
162
166
|
}
|
|
163
|
-
|
|
167
|
+
const restoredThinkingLevel = clampThinkingLevel(model, preference.thinkingLevel);
|
|
168
|
+
pi.setThinkingLevel(restoredThinkingLevel);
|
|
164
169
|
modelBeforeProjectPreference = previousModel;
|
|
165
170
|
thinkingBeforeProjectPreference = previousThinkingLevel;
|
|
166
171
|
|
|
167
|
-
if (modelChanged) {
|
|
172
|
+
if (modelChanged || restoredThinkingLevel !== preference.thinkingLevel) {
|
|
168
173
|
ctx.ui.notify(
|
|
169
174
|
ctx.ui.theme.fg(
|
|
170
175
|
"accent",
|
|
171
|
-
`Project model restored: ${preference.provider}/${preference.model} · thinking: ${pi.getThinkingLevel()}
|
|
176
|
+
`Project model restored: ${preference.provider}/${preference.model} · thinking: ${pi.getThinkingLevel()}` +
|
|
177
|
+
(restoredThinkingLevel !== preference.thinkingLevel
|
|
178
|
+
? ` (saved level ${preference.thinkingLevel} is unsupported)`
|
|
179
|
+
: ""),
|
|
172
180
|
),
|
|
173
181
|
"info",
|
|
174
182
|
);
|