pi-openai-toolkit 0.14.13 → 0.15.1

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.
@@ -1,6 +1,7 @@
1
1
  import type { AgentTool } from "@earendil-works/pi-agent-core";
2
2
  import { createReadOnlyTools, type ExtensionAPI, type ExtensionContext } from "@earendil-works/pi-coding-agent";
3
- import { loadToolkitConfig } from "../config";
3
+ import { loadToolkitConfig, resolveToolkitConfig, type ResolvedToolkitConfig } from "../config";
4
+ import { notifyConfigIssues } from "../config/notifications";
4
5
  import {
5
6
  DEFAULT_AUTO_MODE_CONFIG,
6
7
  type AutoModeConfig,
@@ -152,6 +153,12 @@ export function registerAutoModeExtension(
152
153
  let callIndex = 0;
153
154
  let scoringInFlight = false;
154
155
 
156
+ function readConfig(ctx: ExtensionContext, model = ctx.model): ResolvedToolkitConfig {
157
+ const resolved = resolveToolkitConfig(loadConfig(), model);
158
+ notifyConfigIssues(ctx, resolved);
159
+ return resolved;
160
+ }
161
+
155
162
  function updateStatus(ctx: ExtensionContext, reviewingTool?: string): void {
156
163
  if (!ctx.hasUI) return;
157
164
  if (ctx.mode === "tui") {
@@ -188,7 +195,7 @@ export function registerAutoModeExtension(
188
195
  if (!isAutoModeEligible(ctx.model, config)) {
189
196
  if (ctx.hasUI) {
190
197
  ctx.ui.notify(
191
- "Auto mode needs an allowlisted model in autoMode.models and a configured autoMode.reviewerModel.",
198
+ "Auto mode needs availability for the current model and a configured reviewerModel.",
192
199
  "warning",
193
200
  );
194
201
  }
@@ -373,10 +380,14 @@ export function registerAutoModeExtension(
373
380
  pi.registerCommand(AUTO_MODE_COMMAND, {
374
381
  description: "Model-reviewed tool approval: /auto [on|off|status|all|side]",
375
382
  handler: async (args, ctx) => {
376
- const { config } = loadConfig();
377
- const auto = config.autoMode;
378
- applyConfiguredGate(runtime, auto);
383
+ const resolved = readConfig(ctx);
384
+ const auto = resolved.config.autoMode;
379
385
  const sub = args.trim().toLowerCase();
386
+ if (resolved.invalidFeatures.includes("autoMode") && sub !== "off") {
387
+ if (ctx.hasUI) ctx.ui.notify("Auto-mode configuration is invalid; the existing gate remains engaged until /auto off or a valid configuration is supplied.", "error");
388
+ return;
389
+ }
390
+ applyConfiguredGate(runtime, auto);
380
391
 
381
392
  switch (sub) {
382
393
  case "on":
@@ -419,7 +430,8 @@ export function registerAutoModeExtension(
419
430
  });
420
431
 
421
432
  pi.on("session_start", (event, ctx) => {
422
- const { config } = loadConfig();
433
+ const resolved = readConfig(ctx);
434
+ const { config } = resolved;
423
435
  toolReviewRenderer.clear();
424
436
  if (
425
437
  !toolReviewRenderer.supported &&
@@ -438,7 +450,8 @@ export function registerAutoModeExtension(
438
450
  resetScoreTracker(tracker);
439
451
  resetRejectionBreaker(breaker);
440
452
  callIndex = 0;
441
- const startedFromFlag = pi.getFlag(AUTO_MODE_FLAG) === true && engage(ctx, config.autoMode);
453
+ const requestedFromFlag = pi.getFlag(AUTO_MODE_FLAG) === true;
454
+ const startedFromFlag = requestedFromFlag && (resolved.invalidFeatures.includes("autoMode") ? (runtime.engaged = true) : engage(ctx, config.autoMode));
442
455
  if (startedFromFlag && event.reason === "startup" && ctx.mode === "tui") {
443
456
  ctx.ui.notify(`Auto mode on. Reviewing: ${describeGate(runtime)}`, "info");
444
457
  }
@@ -446,8 +459,9 @@ export function registerAutoModeExtension(
446
459
  });
447
460
 
448
461
  pi.on("model_select", (event, ctx) => {
449
- const { config } = loadConfig();
450
- if (runtime.engaged && !isAutoModeEligible(event.model, config.autoMode)) {
462
+ const resolved = readConfig(ctx, event.model);
463
+ const { config } = resolved;
464
+ if (!resolved.invalidFeatures.includes("autoMode") && runtime.engaged && !isAutoModeEligible(event.model, config.autoMode)) {
451
465
  disengage(ctx);
452
466
  if (ctx.hasUI) ctx.ui.notify("Auto mode off: this model is not allowlisted.", "warning");
453
467
  }
@@ -455,7 +469,9 @@ export function registerAutoModeExtension(
455
469
  });
456
470
 
457
471
  pi.on("before_agent_start", (_event, ctx) => {
458
- const { config } = loadConfig();
472
+ const resolved = readConfig(ctx);
473
+ const { config } = resolved;
474
+ if (resolved.invalidFeatures.includes("autoMode")) { resetScoreTracker(tracker); updateStatus(ctx); return; }
459
475
  applyConfiguredGate(runtime, config.autoMode);
460
476
  if (runtime.engaged && !isAutoModeEligible(ctx.model, config.autoMode)) {
461
477
  disengage(ctx);
@@ -472,8 +488,12 @@ export function registerAutoModeExtension(
472
488
  callIndex += 1;
473
489
  if (!runtime.engaged) return undefined;
474
490
 
475
- const { config } = loadConfig();
476
- const auto = config.autoMode;
491
+ const resolved = readConfig(ctx);
492
+ if (resolved.invalidFeatures.includes("autoMode")) {
493
+ resetScoreTracker(tracker);
494
+ return { block: true, reason: "Auto-mode configuration is invalid. The gate remains engaged; fix the configuration or explicitly use /auto off." };
495
+ }
496
+ const auto = resolved.config.autoMode;
477
497
  applyConfiguredGate(runtime, auto);
478
498
 
479
499
  if (!isAutoModeEligible(ctx.model, auto)) {
@@ -622,8 +642,10 @@ export function registerAutoModeExtension(
622
642
 
623
643
  pi.on("tool_result", (event, ctx) => {
624
644
  if (!runtime.engaged) return undefined;
625
- const { config } = loadConfig();
645
+ const resolved = readConfig(ctx);
646
+ const { config } = resolved;
626
647
  const auto = config.autoMode;
648
+ if (resolved.invalidFeatures.includes("autoMode") || !isAutoModeEligible(ctx.model, auto)) { resetScoreTracker(tracker); return undefined; }
627
649
  if (auto.classifier.enabled && shouldReviewTool(event.toolName, runtime)) {
628
650
  scheduleClassification(ctx, auto, {
629
651
  toolName: event.toolName,