@benvargas/pi-openai-fast 1.0.1 → 1.0.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/README.md +8 -5
- package/extensions/index.ts +50 -32
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
This extension does not change the model, thinking level, tools, or prompts. It only adds `service_tier=priority` to provider requests when fast mode is active and the current model matches the configured supported-model list.
|
|
6
6
|
|
|
7
|
-
Requires pi `0.
|
|
7
|
+
Requires pi `0.74.0` or newer.
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
@@ -26,6 +26,7 @@ pi -e npm:@benvargas/pi-openai-fast
|
|
|
26
26
|
- `/fast status` reports the current fast-mode state.
|
|
27
27
|
- `--fast` starts the session with fast mode enabled.
|
|
28
28
|
- By default, fast mode persists across new pi sessions via a JSON config file.
|
|
29
|
+
- Startup state comes from the selected config file, not from resumed session/thread history.
|
|
29
30
|
|
|
30
31
|
Example:
|
|
31
32
|
|
|
@@ -50,7 +51,9 @@ Default config:
|
|
|
50
51
|
"active": false,
|
|
51
52
|
"supportedModels": [
|
|
52
53
|
"openai/gpt-5.4",
|
|
53
|
-
"openai
|
|
54
|
+
"openai/gpt-5.5",
|
|
55
|
+
"openai-codex/gpt-5.4",
|
|
56
|
+
"openai-codex/gpt-5.5"
|
|
54
57
|
]
|
|
55
58
|
}
|
|
56
59
|
```
|
|
@@ -58,15 +61,15 @@ Default config:
|
|
|
58
61
|
Settings:
|
|
59
62
|
|
|
60
63
|
- `persistState`: when `true`, `/fast` writes the current on/off state to config so it resumes in new pi sessions. Default: `true`.
|
|
61
|
-
- `active`: persisted fast-mode state used when `persistState` is enabled.
|
|
64
|
+
- `active`: persisted fast-mode state used on startup when `persistState` is enabled.
|
|
62
65
|
- `supportedModels`: list of `provider/model-id` strings that should receive `service_tier=priority`.
|
|
63
66
|
|
|
64
|
-
Project config overrides global config. If fast mode is enabled on a model that is not in `supportedModels`, the setting stays on but requests are left unchanged until you switch back to a configured model.
|
|
67
|
+
Project config overrides global config. `/fast on` and `/fast off` write to the selected config file, so if a project config exists the remembered state is project-specific. If fast mode is enabled on a model that is not in `supportedModels`, the setting stays on but requests are left unchanged until you switch back to a configured model.
|
|
65
68
|
|
|
66
69
|
## Notes
|
|
67
70
|
|
|
68
|
-
- Fast mode still stores session state in the current session branch.
|
|
69
71
|
- When `persistState` is enabled, the last `/fast` setting also carries across brand-new pi sessions.
|
|
72
|
+
- Resumed sessions do not override the config-backed startup state.
|
|
70
73
|
- On configured models, fast mode maps to OpenAI `service_tier=priority`.
|
|
71
74
|
|
|
72
75
|
## Uninstall
|
package/extensions/index.ts
CHANGED
|
@@ -1,15 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI fast mode for pi.
|
|
3
|
+
*
|
|
4
|
+
* `/fast` and `--fast` toggle `service_tier=priority` for configured models.
|
|
5
|
+
* This extension does not change the selected model, thinking level, tools, or prompts.
|
|
6
|
+
*
|
|
7
|
+
* Startup state comes from `pi-openai-fast.json`, not resumed session history.
|
|
8
|
+
* Config precedence is project `.pi/extensions/pi-openai-fast.json` over
|
|
9
|
+
* global `~/.pi/agent/extensions/pi-openai-fast.json`.
|
|
10
|
+
*
|
|
11
|
+
* `supportedModels` controls which `provider/model-id` pairs receive the flag.
|
|
12
|
+
*/
|
|
1
13
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
14
|
import { homedir } from "node:os";
|
|
3
15
|
import { dirname, join } from "node:path";
|
|
4
|
-
import type { ExtensionAPI, ExtensionContext } from "@
|
|
16
|
+
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
5
17
|
|
|
6
18
|
const FAST_COMMAND = "fast";
|
|
7
19
|
const FAST_FLAG = "fast";
|
|
8
|
-
const FAST_STATE_ENTRY = "pi-openai-fast.state";
|
|
9
20
|
const FAST_CONFIG_BASENAME = "pi-openai-fast.json";
|
|
10
21
|
const FAST_COMMAND_ARGS = ["on", "off", "status"] as const;
|
|
11
22
|
const FAST_SERVICE_TIER = "priority";
|
|
12
|
-
const DEFAULT_SUPPORTED_MODEL_KEYS = [
|
|
23
|
+
const DEFAULT_SUPPORTED_MODEL_KEYS = [
|
|
24
|
+
"openai/gpt-5.4",
|
|
25
|
+
"openai/gpt-5.5",
|
|
26
|
+
"openai-codex/gpt-5.4",
|
|
27
|
+
"openai-codex/gpt-5.5",
|
|
28
|
+
] as const;
|
|
29
|
+
const LEGACY_DEFAULT_SUPPORTED_MODEL_KEYS = ["openai/gpt-5.4", "openai-codex/gpt-5.4"] as const;
|
|
13
30
|
|
|
14
31
|
interface FastModeState {
|
|
15
32
|
active: boolean;
|
|
@@ -121,22 +138,18 @@ function parseSupportedModels(value: unknown): FastSupportedModel[] | undefined
|
|
|
121
138
|
return models;
|
|
122
139
|
}
|
|
123
140
|
|
|
124
|
-
function
|
|
125
|
-
if (!
|
|
126
|
-
return
|
|
141
|
+
function sameModelKeys(left: readonly string[] | undefined, right: readonly string[]): boolean {
|
|
142
|
+
if (!left || left.length !== right.length) {
|
|
143
|
+
return false;
|
|
127
144
|
}
|
|
128
|
-
return
|
|
145
|
+
return left.every((value, index) => value === right[index]);
|
|
129
146
|
}
|
|
130
147
|
|
|
131
|
-
function
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
const entry = entries[i];
|
|
135
|
-
if (entry.type === "custom" && entry.customType === FAST_STATE_ENTRY) {
|
|
136
|
-
return parseFastModeState(entry.data);
|
|
137
|
-
}
|
|
148
|
+
function migrateSupportedModelKeys(value: string[] | undefined): string[] | undefined {
|
|
149
|
+
if (sameModelKeys(value, LEGACY_DEFAULT_SUPPORTED_MODEL_KEYS)) {
|
|
150
|
+
return [...DEFAULT_SUPPORTED_MODEL_KEYS];
|
|
138
151
|
}
|
|
139
|
-
return
|
|
152
|
+
return value;
|
|
140
153
|
}
|
|
141
154
|
|
|
142
155
|
function readConfigFile(filePath: string): FastConfigFile | null {
|
|
@@ -194,7 +207,8 @@ function resolveFastConfig(cwd: string, homeDir: string = homedir()): ResolvedFa
|
|
|
194
207
|
const selectedConfigPath = existsSync(projectConfigPath) ? projectConfigPath : globalConfigPath;
|
|
195
208
|
const merged = { ...globalConfig, ...projectConfig };
|
|
196
209
|
const supportedModels =
|
|
197
|
-
parseSupportedModels(merged.supportedModels) ??
|
|
210
|
+
parseSupportedModels(migrateSupportedModelKeys(merged.supportedModels)) ??
|
|
211
|
+
parseSupportedModels(DEFAULT_SUPPORTED_MODEL_KEYS);
|
|
198
212
|
|
|
199
213
|
return {
|
|
200
214
|
configPath: selectedConfigPath,
|
|
@@ -251,9 +265,19 @@ function applyFastServiceTier(payload: unknown): unknown {
|
|
|
251
265
|
|
|
252
266
|
export default function piOpenAIFast(pi: ExtensionAPI): void {
|
|
253
267
|
let state: FastModeState = { active: false };
|
|
268
|
+
let cachedConfig: ResolvedFastConfig | undefined;
|
|
269
|
+
|
|
270
|
+
function refreshConfig(ctx: ExtensionContext): ResolvedFastConfig {
|
|
271
|
+
cachedConfig = resolveFastConfig(getConfigCwd(ctx));
|
|
272
|
+
return cachedConfig;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function getConfig(ctx: ExtensionContext): ResolvedFastConfig {
|
|
276
|
+
return cachedConfig ?? refreshConfig(ctx);
|
|
277
|
+
}
|
|
254
278
|
|
|
255
279
|
function persistState(config: ResolvedFastConfig): void {
|
|
256
|
-
|
|
280
|
+
cachedConfig = { ...config, active: state.active };
|
|
257
281
|
if (!config.persistState) {
|
|
258
282
|
return;
|
|
259
283
|
}
|
|
@@ -262,7 +286,7 @@ export default function piOpenAIFast(pi: ExtensionAPI): void {
|
|
|
262
286
|
}
|
|
263
287
|
|
|
264
288
|
async function enableFastMode(ctx: ExtensionContext, options?: { notify?: boolean }): Promise<void> {
|
|
265
|
-
const config =
|
|
289
|
+
const config = refreshConfig(ctx);
|
|
266
290
|
if (state.active) {
|
|
267
291
|
if (options?.notify !== false) {
|
|
268
292
|
ctx.ui.notify("Fast mode is already on.", "info");
|
|
@@ -279,7 +303,7 @@ export default function piOpenAIFast(pi: ExtensionAPI): void {
|
|
|
279
303
|
}
|
|
280
304
|
|
|
281
305
|
async function disableFastMode(ctx: ExtensionContext, options?: { notify?: boolean }): Promise<void> {
|
|
282
|
-
const config =
|
|
306
|
+
const config = refreshConfig(ctx);
|
|
283
307
|
if (!state.active) {
|
|
284
308
|
if (options?.notify !== false) {
|
|
285
309
|
ctx.ui.notify("Fast mode is already off.", "info");
|
|
@@ -334,10 +358,7 @@ export default function piOpenAIFast(pi: ExtensionAPI): void {
|
|
|
334
358
|
await disableFastMode(ctx);
|
|
335
359
|
return;
|
|
336
360
|
case "status":
|
|
337
|
-
ctx.ui.notify(
|
|
338
|
-
describeCurrentState(ctx, state.active, resolveFastConfig(getConfigCwd(ctx)).supportedModels),
|
|
339
|
-
"info",
|
|
340
|
-
);
|
|
361
|
+
ctx.ui.notify(describeCurrentState(ctx, state.active, refreshConfig(ctx).supportedModels), "info");
|
|
341
362
|
return;
|
|
342
363
|
default:
|
|
343
364
|
ctx.ui.notify("Usage: /fast [on|off|status]", "error");
|
|
@@ -346,7 +367,7 @@ export default function piOpenAIFast(pi: ExtensionAPI): void {
|
|
|
346
367
|
});
|
|
347
368
|
|
|
348
369
|
pi.on("before_provider_request", (event, ctx) => {
|
|
349
|
-
const config =
|
|
370
|
+
const config = getConfig(ctx);
|
|
350
371
|
if (!state.active || !isFastSupportedModel(ctx.model, config.supportedModels)) {
|
|
351
372
|
return;
|
|
352
373
|
}
|
|
@@ -354,11 +375,8 @@ export default function piOpenAIFast(pi: ExtensionAPI): void {
|
|
|
354
375
|
});
|
|
355
376
|
|
|
356
377
|
pi.on("session_start", async (_event, ctx) => {
|
|
357
|
-
const config =
|
|
358
|
-
|
|
359
|
-
const persistedState =
|
|
360
|
-
config.persistState && typeof config.active === "boolean" ? { active: config.active } : undefined;
|
|
361
|
-
state = savedState ?? persistedState ?? { active: false };
|
|
378
|
+
const config = refreshConfig(ctx);
|
|
379
|
+
state = config.persistState && typeof config.active === "boolean" ? { active: config.active } : { active: false };
|
|
362
380
|
|
|
363
381
|
if (pi.getFlag(FAST_FLAG) === true) {
|
|
364
382
|
if (!state.active) {
|
|
@@ -369,7 +387,7 @@ export default function piOpenAIFast(pi: ExtensionAPI): void {
|
|
|
369
387
|
return;
|
|
370
388
|
}
|
|
371
389
|
|
|
372
|
-
if (
|
|
390
|
+
if (state.active) {
|
|
373
391
|
ctx.ui.notify(describeCurrentState(ctx, state.active, config.supportedModels), "info");
|
|
374
392
|
}
|
|
375
393
|
});
|
|
@@ -378,16 +396,16 @@ export default function piOpenAIFast(pi: ExtensionAPI): void {
|
|
|
378
396
|
export const _test = {
|
|
379
397
|
FAST_COMMAND,
|
|
380
398
|
FAST_FLAG,
|
|
381
|
-
FAST_STATE_ENTRY,
|
|
382
399
|
FAST_CONFIG_BASENAME,
|
|
383
400
|
FAST_COMMAND_ARGS,
|
|
384
401
|
FAST_SERVICE_TIER,
|
|
385
402
|
DEFAULT_SUPPORTED_MODEL_KEYS,
|
|
403
|
+
LEGACY_DEFAULT_SUPPORTED_MODEL_KEYS,
|
|
386
404
|
DEFAULT_CONFIG_FILE,
|
|
387
405
|
getConfigPaths,
|
|
388
|
-
parseFastModeState,
|
|
389
406
|
parseSupportedModelKey,
|
|
390
407
|
parseSupportedModels,
|
|
408
|
+
migrateSupportedModelKeys,
|
|
391
409
|
readConfigFile,
|
|
392
410
|
resolveFastConfig,
|
|
393
411
|
isFastSupportedModel,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@benvargas/pi-openai-fast",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "OpenAI fast mode toggle for pi - Enables priority service tier on supported GPT-5
|
|
3
|
+
"version": "1.0.4",
|
|
4
|
+
"description": "OpenAI fast mode toggle for pi - Enables priority service tier on supported GPT-5 models",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi",
|
|
7
7
|
"pi-package",
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"openai",
|
|
11
11
|
"codex",
|
|
12
12
|
"gpt-5.4",
|
|
13
|
+
"gpt-5.5",
|
|
13
14
|
"fast",
|
|
14
15
|
"priority",
|
|
15
16
|
"service-tier"
|
|
@@ -26,7 +27,7 @@
|
|
|
26
27
|
]
|
|
27
28
|
},
|
|
28
29
|
"peerDependencies": {
|
|
29
|
-
"@
|
|
30
|
+
"@earendil-works/pi-coding-agent": ">=0.74.0"
|
|
30
31
|
},
|
|
31
32
|
"repository": {
|
|
32
33
|
"type": "git",
|