@juicesharp/rpiv-advisor 1.19.0 → 1.20.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.
@@ -39,15 +39,11 @@ export function reconcileAdvisorTool(
39
39
 
40
40
  export function registerAdvisorBeforeAgentStart(pi: ExtensionAPI): void {
41
41
  pi.on("before_agent_start", async (_event, ctx) => {
42
- const advisor = getAdvisorModel();
43
- if (!advisor) {
44
- const active = pi.getActiveTools();
45
- if (active.includes(ADVISOR_TOOL_NAME)) {
46
- pi.setActiveTools(active.filter((n) => n !== ADVISOR_TOOL_NAME));
47
- }
48
- return;
49
- }
50
- reconcileAdvisorTool(pi, ctx, { blocked: isExecutorBlocked(ctx, pi.getThinkingLevel()) });
42
+ // No model → blocked (strip); model present → defer to the executor
43
+ // blocklist. Routes through the reconcile hub so all strip/add logic
44
+ // lives in one place rather than re-inlining the filter here.
45
+ const blocked = !getAdvisorModel() || isExecutorBlocked(ctx, pi.getThinkingLevel());
46
+ reconcileAdvisorTool(pi, ctx, { blocked });
51
47
  });
52
48
  }
53
49
 
@@ -7,6 +7,7 @@
7
7
  import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
8
8
  import { modelKey, parseModelKey } from "@juicesharp/rpiv-config";
9
9
  import { loadAdvisorConfig, validateDisabledForModels } from "./config.js";
10
+ import { reconcileAdvisorTool } from "./handlers.js";
10
11
  import { ADVISOR_TOOL_NAME, errModelUnavailable, msgAdvisorRestored, msgAdvisorRestoredInactive } from "./messages.js";
11
12
  import { isExecutorBlocked, setDisabledForModels } from "./policy.js";
12
13
  import { setAdvisorEffort, setAdvisorModel } from "./state.js";
@@ -32,10 +33,32 @@ export function restoreAdvisorState(ctx: ExtensionContext, pi: ExtensionAPI): vo
32
33
 
33
34
  setDisabledForModels(validateDisabledForModels(config.disabledForModels));
34
35
 
35
- if (!config.modelKey) return;
36
+ // No usable advisor model → clear in-memory selection, then strip the tool
37
+ // (and its prompt block) from the active set. Clearing state mirrors the
38
+ // /advisor disable path (command.ts applyDisable): `selectedAdvisor` is
39
+ // module-level and persists across session_start fires, so leaving it stale
40
+ // would let the per-turn before_agent_start strip read a truthy model and
41
+ // re-add the very tool we just stripped (e.g. a configured model removed
42
+ // from the registry mid-process). The tool is registered active-by-default
43
+ // at load, so its promptSnippet/promptGuidelines otherwise linger in the
44
+ // base system prompt even though every advisor() call would fail with
45
+ // ERR_NO_MODEL. See issue #72.
46
+ const deactivate = (): void => {
47
+ setAdvisorModel(undefined);
48
+ setAdvisorEffort(undefined);
49
+ reconcileAdvisorTool(pi, ctx, { blocked: true });
50
+ };
51
+
52
+ if (!config.modelKey) {
53
+ deactivate();
54
+ return;
55
+ }
36
56
 
37
57
  const parsed = parseModelKey(config.modelKey);
38
- if (!parsed) return;
58
+ if (!parsed) {
59
+ deactivate();
60
+ return;
61
+ }
39
62
 
40
63
  const notifyOnce = (msg: string, level: "info" | "warning" | "error"): void => {
41
64
  if (!ctx.hasUI || restoreAnnounced) return;
@@ -45,6 +68,7 @@ export function restoreAdvisorState(ctx: ExtensionContext, pi: ExtensionAPI): vo
45
68
 
46
69
  const model = ctx.modelRegistry.find(parsed.provider, parsed.modelId);
47
70
  if (!model) {
71
+ deactivate();
48
72
  notifyOnce(errModelUnavailable(config.modelKey), "warning");
49
73
  return;
50
74
  }
@@ -55,6 +79,7 @@ export function restoreAdvisorState(ctx: ExtensionContext, pi: ExtensionAPI): vo
55
79
  }
56
80
 
57
81
  if (isExecutorBlocked(ctx, pi.getThinkingLevel())) {
82
+ reconcileAdvisorTool(pi, ctx, { blocked: true });
58
83
  const advisorLabel = modelKey(model);
59
84
  notifyOnce(msgAdvisorRestoredInactive(advisorLabel, config.effort), "info");
60
85
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juicesharp/rpiv-advisor",
3
- "version": "1.19.0",
3
+ "version": "1.20.0",
4
4
  "description": "Pi extension. A second opinion the model can request from a stronger reviewer model before it acts.",
5
5
  "keywords": [
6
6
  "pi-package",
@@ -41,7 +41,7 @@
41
41
  ]
42
42
  },
43
43
  "dependencies": {
44
- "@juicesharp/rpiv-config": "^1.19.0"
44
+ "@juicesharp/rpiv-config": "^1.20.0"
45
45
  },
46
46
  "peerDependencies": {
47
47
  "@earendil-works/pi-ai": "*",