@benvargas/pi-openai-fast 1.0.4 → 1.1.0

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
@@ -39,7 +39,11 @@ pi -e npm:@benvargas/pi-openai-fast --fast
39
39
  Config files follow the same project-over-global pattern as the other packages:
40
40
 
41
41
  - Project: `<repo>/.pi/extensions/pi-openai-fast.json`
42
- - Global: `~/.pi/agent/extensions/pi-openai-fast.json`
42
+ - Global: `<agent dir>/extensions/pi-openai-fast.json`
43
+
44
+ The global path uses pi's agent directory — typically `~/.pi/agent`, but it follows `PI_CODING_AGENT_DIR` when that is set, matching where pi itself reads and writes config.
45
+
46
+ Releases before this one always used `~/.pi/agent`, even with `PI_CODING_AGENT_DIR` set. If the agent directory differs from `~/.pi/agent` and has no config yet, an existing `~/.pi/agent/extensions/pi-openai-fast.json` is copied there once so previous settings carry over; a config already present in the agent directory is never overwritten.
43
47
 
44
48
  If neither exists, the extension writes a default global config on first run.
45
49
 
@@ -51,9 +55,16 @@ Default config:
51
55
  "active": false,
52
56
  "supportedModels": [
53
57
  "openai/gpt-5.4",
58
+ "openai/gpt-5.4-mini",
54
59
  "openai/gpt-5.5",
60
+ "openai/gpt-5.6-sol",
61
+ "openai/gpt-5.6-terra",
62
+ "openai/gpt-5.6-luna",
55
63
  "openai-codex/gpt-5.4",
56
- "openai-codex/gpt-5.5"
64
+ "openai-codex/gpt-5.5",
65
+ "openai-codex/gpt-5.6-sol",
66
+ "openai-codex/gpt-5.6-terra",
67
+ "openai-codex/gpt-5.6-luna"
57
68
  ]
58
69
  }
59
70
  ```
@@ -71,6 +82,8 @@ Project config overrides global config. `/fast on` and `/fast off` write to the
71
82
  - When `persistState` is enabled, the last `/fast` setting also carries across brand-new pi sessions.
72
83
  - Resumed sessions do not override the config-backed startup state.
73
84
  - On configured models, fast mode maps to OpenAI `service_tier=priority`.
85
+ - `openai/gpt-5.4-mini` is in the defaults for the API-key provider only: OpenAI publishes Fast-mode pricing for it, but the ChatGPT (`openai-codex`) side offers no fast tier for gpt-5.4-mini. `gpt-5.4-nano`, `gpt-5.4-pro`, and `gpt-5.5-pro` have no published Fast-mode pricing and are left out.
86
+ - If a default set from an older release is found in your config, it is upgraded to the current defaults automatically; customized `supportedModels` lists are left untouched.
74
87
 
75
88
  ## Uninstall
76
89
 
@@ -6,27 +6,54 @@
6
6
  *
7
7
  * Startup state comes from `pi-openai-fast.json`, not resumed session history.
8
8
  * Config precedence is project `.pi/extensions/pi-openai-fast.json` over
9
- * global `~/.pi/agent/extensions/pi-openai-fast.json`.
9
+ * global `<agent dir>/extensions/pi-openai-fast.json`, where the agent dir is
10
+ * pi's getAgentDir() (typically `~/.pi/agent`, honoring PI_CODING_AGENT_DIR).
11
+ * Releases before 0.84 always used `~/.pi/agent`; when the agent dir differs
12
+ * and holds no config yet, the legacy global file is copied there once.
10
13
  *
11
14
  * `supportedModels` controls which `provider/model-id` pairs receive the flag.
12
15
  */
13
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
16
+ import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
14
17
  import { homedir } from "node:os";
15
- import { dirname, join } from "node:path";
16
- import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
18
+ import { dirname, join, resolve } from "node:path";
19
+ import { type ExtensionAPI, type ExtensionContext, getAgentDir } from "@earendil-works/pi-coding-agent";
17
20
 
18
21
  const FAST_COMMAND = "fast";
19
22
  const FAST_FLAG = "fast";
20
23
  const FAST_CONFIG_BASENAME = "pi-openai-fast.json";
21
24
  const FAST_COMMAND_ARGS = ["on", "off", "status"] as const;
22
25
  const FAST_SERVICE_TIER = "priority";
26
+ // `openai/gpt-5.4-mini` has an official Fast-mode price and is API-key only: the
27
+ // ChatGPT (openai-codex) catalog exposes no priority tier for gpt-5.4-mini.
23
28
  const DEFAULT_SUPPORTED_MODEL_KEYS = [
24
29
  "openai/gpt-5.4",
30
+ "openai/gpt-5.4-mini",
25
31
  "openai/gpt-5.5",
32
+ "openai/gpt-5.6-sol",
33
+ "openai/gpt-5.6-terra",
34
+ "openai/gpt-5.6-luna",
26
35
  "openai-codex/gpt-5.4",
27
36
  "openai-codex/gpt-5.5",
37
+ "openai-codex/gpt-5.6-sol",
38
+ "openai-codex/gpt-5.6-terra",
39
+ "openai-codex/gpt-5.6-luna",
40
+ ] as const;
41
+ const LEGACY_DEFAULT_SUPPORTED_MODEL_KEY_SETS = [
42
+ ["openai/gpt-5.4", "openai-codex/gpt-5.4"],
43
+ ["openai/gpt-5.4", "openai/gpt-5.5", "openai-codex/gpt-5.4", "openai-codex/gpt-5.5"],
44
+ [
45
+ "openai/gpt-5.4",
46
+ "openai/gpt-5.5",
47
+ "openai/gpt-5.6-sol",
48
+ "openai/gpt-5.6-terra",
49
+ "openai/gpt-5.6-luna",
50
+ "openai-codex/gpt-5.4",
51
+ "openai-codex/gpt-5.5",
52
+ "openai-codex/gpt-5.6-sol",
53
+ "openai-codex/gpt-5.6-terra",
54
+ "openai-codex/gpt-5.6-luna",
55
+ ],
28
56
  ] as const;
29
- const LEGACY_DEFAULT_SUPPORTED_MODEL_KEYS = ["openai/gpt-5.4", "openai-codex/gpt-5.4"] as const;
30
57
 
31
58
  interface FastModeState {
32
59
  active: boolean;
@@ -71,14 +98,19 @@ function getConfigCwd(ctx: ExtensionContext): string {
71
98
 
72
99
  function getConfigPaths(
73
100
  cwd: string,
74
- homeDir: string = homedir(),
101
+ homeDir?: string,
75
102
  ): {
76
103
  projectConfigPath: string;
77
104
  globalConfigPath: string;
105
+ legacyGlobalConfigPath: string;
78
106
  } {
107
+ const agentDir = homeDir === undefined ? getAgentDir() : join(homeDir, ".pi", "agent");
108
+ // Pre-0.84 releases always wrote the global config under ~/.pi/agent, ignoring PI_CODING_AGENT_DIR.
109
+ const legacyAgentDir = join(homeDir ?? homedir(), ".pi", "agent");
79
110
  return {
80
111
  projectConfigPath: join(cwd, ".pi", "extensions", FAST_CONFIG_BASENAME),
81
- globalConfigPath: join(homeDir, ".pi", "agent", "extensions", FAST_CONFIG_BASENAME),
112
+ globalConfigPath: join(agentDir, "extensions", FAST_CONFIG_BASENAME),
113
+ legacyGlobalConfigPath: join(legacyAgentDir, "extensions", FAST_CONFIG_BASENAME),
82
114
  };
83
115
  }
84
116
 
@@ -146,7 +178,7 @@ function sameModelKeys(left: readonly string[] | undefined, right: readonly stri
146
178
  }
147
179
 
148
180
  function migrateSupportedModelKeys(value: string[] | undefined): string[] | undefined {
149
- if (sameModelKeys(value, LEGACY_DEFAULT_SUPPORTED_MODEL_KEYS)) {
181
+ if (LEGACY_DEFAULT_SUPPORTED_MODEL_KEY_SETS.some((legacyKeys) => sameModelKeys(value, legacyKeys))) {
150
182
  return [...DEFAULT_SUPPORTED_MODEL_KEYS];
151
183
  }
152
184
  return value;
@@ -198,8 +230,25 @@ function ensureDefaultConfigFile(projectConfigPath: string, globalConfigPath: st
198
230
  writeConfigFile(globalConfigPath, DEFAULT_CONFIG_FILE);
199
231
  }
200
232
 
201
- function resolveFastConfig(cwd: string, homeDir: string = homedir()): ResolvedFastConfig {
202
- const { projectConfigPath, globalConfigPath } = getConfigPaths(cwd, homeDir);
233
+ function migrateLegacyGlobalConfigFile(legacyGlobalConfigPath: string, globalConfigPath: string): void {
234
+ if (resolve(legacyGlobalConfigPath) === resolve(globalConfigPath)) {
235
+ return;
236
+ }
237
+ if (existsSync(globalConfigPath) || !existsSync(legacyGlobalConfigPath)) {
238
+ return;
239
+ }
240
+ try {
241
+ mkdirSync(dirname(globalConfigPath), { recursive: true });
242
+ copyFileSync(legacyGlobalConfigPath, globalConfigPath);
243
+ } catch (error) {
244
+ const message = error instanceof Error ? error.message : String(error);
245
+ console.warn(`[pi-openai-fast] Failed to migrate ${legacyGlobalConfigPath} to ${globalConfigPath}: ${message}`);
246
+ }
247
+ }
248
+
249
+ function resolveFastConfig(cwd: string, homeDir?: string): ResolvedFastConfig {
250
+ const { projectConfigPath, globalConfigPath, legacyGlobalConfigPath } = getConfigPaths(cwd, homeDir);
251
+ migrateLegacyGlobalConfigFile(legacyGlobalConfigPath, globalConfigPath);
203
252
  ensureDefaultConfigFile(projectConfigPath, globalConfigPath);
204
253
 
205
254
  const globalConfig = readConfigFile(globalConfigPath) ?? {};
@@ -400,12 +449,13 @@ export const _test = {
400
449
  FAST_COMMAND_ARGS,
401
450
  FAST_SERVICE_TIER,
402
451
  DEFAULT_SUPPORTED_MODEL_KEYS,
403
- LEGACY_DEFAULT_SUPPORTED_MODEL_KEYS,
452
+ LEGACY_DEFAULT_SUPPORTED_MODEL_KEY_SETS,
404
453
  DEFAULT_CONFIG_FILE,
405
454
  getConfigPaths,
406
455
  parseSupportedModelKey,
407
456
  parseSupportedModels,
408
457
  migrateSupportedModelKeys,
458
+ migrateLegacyGlobalConfigFile,
409
459
  readConfigFile,
410
460
  resolveFastConfig,
411
461
  isFastSupportedModel,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@benvargas/pi-openai-fast",
3
- "version": "1.0.4",
3
+ "version": "1.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",
@@ -11,6 +11,7 @@
11
11
  "codex",
12
12
  "gpt-5.4",
13
13
  "gpt-5.5",
14
+ "gpt-5.6",
14
15
  "fast",
15
16
  "priority",
16
17
  "service-tier"