@monotykamary/pi-better-openai 0.2.8 → 0.2.10

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 CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.10
4
+
5
+ - Hide disabled image, web search, and decision tools and their prompt guidance, including from pi-fabric capture.
6
+ - Apply settings and decision-command toggles immediately without reactivating unrelated tools; retain execution guards and configuration commands.
7
+ - Add real Pi regression coverage for startup, live toggles, nested-call availability, and prompt updates.
8
+ - Update brace-expansion to 5.0.11 and undici to 8.10.2 to resolve high-severity security advisories.
9
+
10
+ ## 0.2.9
11
+
12
+ - Validate Pi 1.0.0 with exact development pins and wildcard host peers.
13
+ - Exercise real-host registration, startup, and repeated shutdown offline.
14
+ - Scope Vitest to owned tests so ignored research checkouts do not enter release checks.
15
+
3
16
  ## 0.2.8
4
17
 
5
18
  - Add GPT-6.1 Sol fallback metadata and Fast support for the GPT-6 model family.
package/README.md CHANGED
@@ -139,6 +139,8 @@ Example config:
139
139
  }
140
140
  ```
141
141
 
142
+ Setting `image.enabled`, `websearch.enabled`, or `decisions.enabled` to `false` hides that tool and removes its system-prompt guidance, including from pi-fabric capture. Changes in `/openai-settings` or `/openai-decisions` apply immediately; use `/reload` after editing config files manually. Configuration commands remain available.
143
+
142
144
  ## Service tiers
143
145
 
144
146
  `/openai-tier fast` requests `service_tier: "priority"`. `/openai-tier standard` explicitly requests `"default"`, clearing an inherited Fast/Ultrafast request tier on OpenAI providers. Legacy disabled configurations without an explicit tier leave payloads untouched. `/fast` and the `--fast` flag never select Ultrafast.
package/index.ts CHANGED
@@ -83,6 +83,7 @@ import { registerOpenAIImage, _imageTest } from "./src/image.ts";
83
83
  import { registerOpenAIWebSearch, _websearchTest } from "./src/websearch.ts";
84
84
  import { registerOpenAILive } from "./src/live/index.ts";
85
85
  import { registerOpenAIDecisions } from "./src/decisions.ts";
86
+ import type { OptionalTool } from "./src/optional-tool.ts";
86
87
  import {
87
88
  type CodexPetPackage,
88
89
  codexHome,
@@ -280,6 +281,7 @@ export default function betterOpenAI(pi: ExtensionAPI): void {
280
281
 
281
282
  const fastController = new FastController(SERVICE_TIER);
282
283
  let cachedConfig: ResolvedConfig | undefined;
284
+ const optionalTools = new Map<"image" | "websearch" | "decisions", OptionalTool>();
283
285
  let footerTotals = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0 };
284
286
  let footerInstalled = false;
285
287
  let statusInstalled = false;
@@ -327,8 +329,13 @@ export default function betterOpenAI(pi: ExtensionAPI): void {
327
329
  });
328
330
  }
329
331
 
332
+ function syncToolExposure(cfg: ResolvedConfig): void {
333
+ for (const [feature, tool] of optionalTools) tool.setEnabled(cfg[feature].enabled);
334
+ }
335
+
330
336
  function refresh(ctx: ExtensionContext): ResolvedConfig {
331
337
  cachedConfig = resolveConfig(ctx.cwd || process.cwd());
338
+ syncToolExposure(cachedConfig);
332
339
  return cachedConfig;
333
340
  }
334
341
 
@@ -1187,9 +1194,10 @@ export default function betterOpenAI(pi: ExtensionAPI): void {
1187
1194
  },
1188
1195
  });
1189
1196
 
1190
- registerOpenAIImage(pi, config);
1191
- registerOpenAIWebSearch(pi, config);
1192
- registerOpenAIDecisions(pi, config, refresh);
1197
+ optionalTools.set("image", registerOpenAIImage(pi, config));
1198
+ optionalTools.set("websearch", registerOpenAIWebSearch(pi, config));
1199
+ optionalTools.set("decisions", registerOpenAIDecisions(pi, config, refresh));
1200
+ if (cachedConfig) syncToolExposure(cachedConfig);
1193
1201
  registerOpenAILive(pi, config);
1194
1202
  registerOpenAIPets(pi, {
1195
1203
  wake: async (ctx, slug) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@monotykamary/pi-better-openai",
3
- "version": "0.2.8",
3
+ "version": "0.2.10",
4
4
  "description": "Improve OpenAI in pi with fast mode, usage stats, realtime voice, image generation, and footer polish.",
5
5
  "keywords": [
6
6
  "fast",
@@ -61,13 +61,13 @@
61
61
  "https-proxy-agent": "9.1.0",
62
62
  "proxy-from-env": "2.1.0",
63
63
  "sharp": "0.35.4",
64
- "undici": "8.10.0",
64
+ "undici": "8.10.2",
65
65
  "ws": "8.21.2"
66
66
  },
67
67
  "devDependencies": {
68
- "@earendil-works/pi-ai": "0.99.0",
69
- "@earendil-works/pi-coding-agent": "0.99.0",
70
- "@earendil-works/pi-tui": "0.99.0",
68
+ "@earendil-works/pi-ai": "1.0.0",
69
+ "@earendil-works/pi-coding-agent": "1.0.0",
70
+ "@earendil-works/pi-tui": "1.0.0",
71
71
  "@types/node": "~22.19.0",
72
72
  "@types/proxy-from-env": "1.0.4",
73
73
  "@types/ws": "8.18.1",
@@ -89,13 +89,13 @@
89
89
  "@oh-my-pi/pi-natives-win32-x64": "17.2.9"
90
90
  },
91
91
  "overrides": {
92
- "@earendil-works/pi-agent-core": "0.99.0",
93
- "@earendil-works/pi-ai": "0.99.0",
94
- "brace-expansion": "5.0.9",
92
+ "@earendil-works/pi-agent-core": "1.0.0",
93
+ "@earendil-works/pi-ai": "1.0.0",
94
+ "brace-expansion": "5.0.11",
95
95
  "nanoid": "3.3.18",
96
96
  "postcss": "8.5.25",
97
97
  "protobufjs": "7.6.5",
98
- "undici": "8.10.0"
98
+ "undici": "8.10.2"
99
99
  },
100
100
  "engines": {
101
101
  "node": ">=22.19.0"
package/src/decisions.ts CHANGED
@@ -13,6 +13,7 @@ import {
13
13
  type DecisionsConfig,
14
14
  type ResolvedConfig,
15
15
  } from "./config.ts";
16
+ import { registerOptionalTool, type OptionalTool } from "./optional-tool.ts";
16
17
 
17
18
  export const OPENAI_DECIDE_TOOL = "openai_decide";
18
19
  export const OPENAI_DECISIONS_COMMAND = "openai-decisions";
@@ -335,7 +336,7 @@ export function registerOpenAIDecisions(
335
336
  pi: ExtensionAPI,
336
337
  getConfig: (ctx: ExtensionContext) => ResolvedConfig,
337
338
  refreshConfig: (ctx: ExtensionContext) => ResolvedConfig,
338
- ): void {
339
+ ): OptionalTool {
339
340
  function save(ctx: ExtensionContext, patch: DecisionsConfig): void {
340
341
  const cfg = refreshConfig(ctx);
341
342
  const raw = readRawConfig(cfg.configPath);
@@ -343,7 +344,7 @@ export function registerOpenAIDecisions(
343
344
  ...raw,
344
345
  decisions: { ...(isRecord(raw.decisions) ? raw.decisions : {}), ...patch },
345
346
  });
346
- refreshConfig(ctx);
347
+ tool.setEnabled(refreshConfig(ctx).decisions.enabled);
347
348
  }
348
349
 
349
350
  pi.registerCommand(OPENAI_DECISIONS_COMMAND, {
@@ -388,7 +389,7 @@ export function registerOpenAIDecisions(
388
389
  }
389
390
  },
390
391
  });
391
- pi.registerTool({
392
+ const tool = registerOptionalTool(pi, {
392
393
  name: OPENAI_DECIDE_TOOL,
393
394
  label: "Typed decision",
394
395
  description:
@@ -402,4 +403,5 @@ export function registerOpenAIDecisions(
402
403
  execute: (_id, params, signal, _onUpdate, ctx) =>
403
404
  evaluateDecision(ctx, getConfig(ctx), params, signal),
404
405
  });
406
+ return tool;
405
407
  }
package/src/image.ts CHANGED
@@ -13,6 +13,7 @@ import {
13
13
  } from "./codex-auth.ts";
14
14
  import { maskIdentifier, sanitizeDiagnosticError } from "./format.ts";
15
15
  import { piAgentDir, resolveUserPath } from "./paths.ts";
16
+ import { registerOptionalTool, type OptionalTool } from "./optional-tool.ts";
16
17
 
17
18
  const OPENAI_IMAGE_TOOL = "openai_image";
18
19
  const OPENAI_IMAGE_COMMAND = "openai-image";
@@ -464,7 +465,7 @@ function resultText(result: CodexImageResult): string {
464
465
  export function registerOpenAIImage(
465
466
  pi: ExtensionAPI,
466
467
  getConfig: (ctx: ExtensionContext) => ResolvedConfig,
467
- ): { getDebug: (ctx: ExtensionContext) => Promise<ImageGenerationDebug> } {
468
+ ): OptionalTool & { getDebug: (ctx: ExtensionContext) => Promise<ImageGenerationDebug> } {
468
469
  let lastStatus: string | undefined;
469
470
  let lastError: string | undefined;
470
471
 
@@ -581,7 +582,7 @@ export function registerOpenAIImage(
581
582
  },
582
583
  });
583
584
 
584
- pi.registerTool({
585
+ const tool = registerOptionalTool(pi, {
585
586
  name: OPENAI_IMAGE_TOOL,
586
587
  label: "OpenAI image",
587
588
  description:
@@ -616,7 +617,7 @@ export function registerOpenAIImage(
616
617
  },
617
618
  });
618
619
 
619
- return { getDebug };
620
+ return { getDebug, ...tool };
620
621
  }
621
622
 
622
623
  export const _imageTest = {
@@ -0,0 +1,27 @@
1
+ import type { TSchema } from "@earendil-works/pi-ai";
2
+ import type { ExtensionAPI, ToolDefinition } from "@earendil-works/pi-coding-agent";
3
+
4
+ export interface OptionalTool {
5
+ setEnabled(enabled: boolean): void;
6
+ }
7
+
8
+ /** Hidden exposure withdraws both native calls and Fabric capture, unlike deactivation alone. */
9
+ export function registerOptionalTool<TParams extends TSchema, TDetails>(
10
+ pi: ExtensionAPI,
11
+ definition: ToolDefinition<TParams, TDetails>,
12
+ ): OptionalTool {
13
+ let enabled: boolean | undefined;
14
+ const tool: OptionalTool = {
15
+ setEnabled(next) {
16
+ if (enabled === next) return;
17
+ pi.registerTool({
18
+ ...definition,
19
+ exposure: next ? (definition.exposure ?? "direct") : "hidden",
20
+ });
21
+ enabled = next;
22
+ },
23
+ };
24
+ // The factory has no session cwd yet. Stay unreachable until config is resolved.
25
+ tool.setEnabled(false);
26
+ return tool;
27
+ }
package/src/websearch.ts CHANGED
@@ -8,6 +8,7 @@ import {
8
8
  } from "./config.ts";
9
9
  import { getCodexCredentials, type CodexCredentialsWithSource } from "./codex-auth.ts";
10
10
  import { maskIdentifier, sanitizeDiagnosticError } from "./format.ts";
11
+ import { registerOptionalTool, type OptionalTool } from "./optional-tool.ts";
11
12
 
12
13
  export const OPENAI_WEBSEARCH_TOOL = "openai_websearch";
13
14
  export const OPENAI_WEBSEARCH_COMMAND = "openai-websearch";
@@ -316,7 +317,7 @@ async function requestWebSearch(
316
317
  export function registerOpenAIWebSearch(
317
318
  pi: ExtensionAPI,
318
319
  getConfig: (ctx: ExtensionContext) => ResolvedConfig,
319
- ): { getDebug: (ctx: ExtensionContext) => Promise<WebSearchDebug> } {
320
+ ): OptionalTool & { getDebug: (ctx: ExtensionContext) => Promise<WebSearchDebug> } {
320
321
  let lastStatus: string | undefined;
321
322
  let lastError: string | undefined;
322
323
 
@@ -402,7 +403,7 @@ export function registerOpenAIWebSearch(
402
403
  },
403
404
  });
404
405
 
405
- pi.registerTool({
406
+ const tool = registerOptionalTool(pi, {
406
407
  name: OPENAI_WEBSEARCH_TOOL,
407
408
  label: "OpenAI web search",
408
409
  description:
@@ -426,7 +427,7 @@ export function registerOpenAIWebSearch(
426
427
  },
427
428
  });
428
429
 
429
- return { getDebug };
430
+ return { getDebug, ...tool };
430
431
  }
431
432
 
432
433
  export const _websearchTest = {