pi-goal-list-loop-audit 0.24.4 → 0.24.6
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,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* pi-goal-list-loop-audit — v0.
|
|
2
|
+
* pi-goal-list-loop-audit — v0.24.5
|
|
3
3
|
* extensions/goal-loop-core.ts
|
|
4
4
|
*
|
|
5
5
|
* Shared types, state machine, JSONL persistence, helpers.
|
|
@@ -703,3 +703,44 @@ export function classifySessionCtx(ownerSession: unknown, ownerLive: boolean, se
|
|
|
703
703
|
if (!ownerSession || !ownerLive) return "claim";
|
|
704
704
|
return sessionManager === ownerSession ? "refresh" : "foreign";
|
|
705
705
|
}
|
|
706
|
+
|
|
707
|
+
// =================================================================
|
|
708
|
+
// v0.24.5: tool-visibility self-heal
|
|
709
|
+
// =================================================================
|
|
710
|
+
//
|
|
711
|
+
// Root cause (INCIDENT-COMPLETION-BLACKHOLE-2026-07-23): external
|
|
712
|
+
// extensions like pi-plugin-list-selector-modlist call pi.setActiveTools
|
|
713
|
+
// with a frozen tool snapshot at session_start. When glla's session_start
|
|
714
|
+
// handler runs BEFORE theirs (load order), our lazily-registered agent
|
|
715
|
+
// tools get registered, briefly auto-activated, then wiped from the
|
|
716
|
+
// model-facing active set on the very next pi.setActiveTools call from
|
|
717
|
+
// modlist. Commands, widget, watchdog keep working (they don't go
|
|
718
|
+
// through the tool registry), but every agent tool — complete_goal,
|
|
719
|
+
// propose_loop_draft, etc. — answers "Tool not found" to the model.
|
|
720
|
+
//
|
|
721
|
+
// Self-heal: any handler that triggers registerAgentTools must also
|
|
722
|
+
// ensure the registered tool names are present in pi.getActiveTools(),
|
|
723
|
+
// re-adding any missing ones via pi.setActiveTools. Once per session,
|
|
724
|
+
// notify the user naming the external allowlist as the likely culprit
|
|
725
|
+
// so they can fix their profile once and silence it.
|
|
726
|
+
|
|
727
|
+
export const GLLA_TOOL_NAMES = [
|
|
728
|
+
"complete_goal",
|
|
729
|
+
"pause_goal",
|
|
730
|
+
"complete_task",
|
|
731
|
+
"update_task_status",
|
|
732
|
+
"propose_goal_draft",
|
|
733
|
+
"propose_loop_draft",
|
|
734
|
+
"propose_loop_refine",
|
|
735
|
+
"list_add",
|
|
736
|
+
"list_activate",
|
|
737
|
+
"list_status",
|
|
738
|
+
"propose_task_list",
|
|
739
|
+
] as const;
|
|
740
|
+
|
|
741
|
+
export type GllaToolName = (typeof GLLA_TOOL_NAMES)[number];
|
|
742
|
+
|
|
743
|
+
export function missingGllaTools(activeNames: readonly string[]): readonly GllaToolName[] {
|
|
744
|
+
const active = new Set(activeNames);
|
|
745
|
+
return GLLA_TOOL_NAMES.filter((n) => !active.has(n));
|
|
746
|
+
}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
// pi-goal-list-loop-audit — v0.24.6
|
|
2
|
+
// extensions/goal-loop-subagents.ts
|
|
3
|
+
//
|
|
4
|
+
// Subagent model inheritance fix (v0.24.6, Section I of the eager-continuation
|
|
5
|
+
// contract). pi-subagents v0.14.3's default Explore agent pins
|
|
6
|
+
// "anthropic/claude-haiku-4-5" (default-agents.ts:40). Its model resolution is
|
|
7
|
+
// explicit option > agent config > parent model (agent-runner.ts:720), so an
|
|
8
|
+
// Explore spawn NEVER inherits the session model — it silently routes to a
|
|
9
|
+
// different provider with a different quota pool. On rigs where the session
|
|
10
|
+
// model is local/alternative (e.g. MiniMax-M3) and claude-haiku-4-5 resolves
|
|
11
|
+
// through a quota-capped key (OpenRouter), three concurrent Explore spawns
|
|
12
|
+
// exhaust the key with 403 "Key limit exceeded" while the parent session is
|
|
13
|
+
// unaffected.
|
|
14
|
+
//
|
|
15
|
+
// pi-subagents has no per-agent model setting (subagents.json covers
|
|
16
|
+
// concurrency/scope/etc., not models). Its supported override mechanism is
|
|
17
|
+
// user agent files: <agentDir>/agents/<Name>.md fully replaces the default
|
|
18
|
+
// config of the same name (custom-agents.ts + agent-types.ts overlay by
|
|
19
|
+
// exact key). A file that omits "model:" falls through to the parent model.
|
|
20
|
+
//
|
|
21
|
+
// This module manages exactly one override file — Explore.md — the only
|
|
22
|
+
// default agent with a model pin today. It writes/updates/removes the file
|
|
23
|
+
// according to glla settings, and NEVER touches a file it didn't write
|
|
24
|
+
// (marker frontmatter field). If tintinweb pins more defaults later, the
|
|
25
|
+
// drift test in tests/subagent-model-override.test.ts fails and prompts us
|
|
26
|
+
// to add embedded copies here.
|
|
27
|
+
|
|
28
|
+
import * as fs from "node:fs";
|
|
29
|
+
import * as os from "node:os";
|
|
30
|
+
import * as path from "node:path";
|
|
31
|
+
|
|
32
|
+
/** Frontmatter marker identifying files this module wrote. Files without it
|
|
33
|
+
* are user-owned: never modified, never deleted. */
|
|
34
|
+
export const SUBAGENT_MANAGED_MARKER = "pi-goal-list-loop-audit";
|
|
35
|
+
|
|
36
|
+
/** Default pi-subagents agents that pin a model. Today: only Explore
|
|
37
|
+
* (anthropic/claude-haiku-4-5). Plan and general-purpose already inherit the
|
|
38
|
+
* parent model. Guarded by the drift test. */
|
|
39
|
+
export const KNOWN_PINNED_DEFAULT_AGENTS = ["Explore"] as const;
|
|
40
|
+
|
|
41
|
+
/** Strategy for subagent model selection. Default "inherit-parent": managed
|
|
42
|
+
* override drops the model pin so subagents share the session model AND its
|
|
43
|
+
* quota pool. "agent-default": upstream behavior (Explore pins haiku). */
|
|
44
|
+
export type SubagentModelStrategy = "inherit-parent" | "agent-default";
|
|
45
|
+
|
|
46
|
+
// ---- Embedded default-agent copies (verbatim from pi-subagents v0.14.3
|
|
47
|
+
// src/default-agents.ts; drift-tested against the installed package) ----
|
|
48
|
+
|
|
49
|
+
export const EXPLORE_DEFAULT_DESCRIPTION = "Fast read-only search agent for locating code. Use it to find files by pattern (eg. \"src/components/**/*.tsx\"), grep for symbols or keywords (eg. \"API endpoints\"), or answer \"where is X defined / which files reference Y.\" Do NOT use it for code review, design-doc auditing, cross-file consistency checks, or open-ended analysis \u2014 it reads excerpts rather than whole files and will miss content past its read window. When calling, specify search breadth: \"quick\" for a single targeted lookup, \"medium\" for moderate exploration, or \"very thorough\" to search across multiple locations and naming conventions.";
|
|
50
|
+
|
|
51
|
+
export const EXPLORE_DEFAULT_SYSTEM_PROMPT = `# CRITICAL: READ-ONLY MODE - NO FILE MODIFICATIONS
|
|
52
|
+
You are a file search specialist. You excel at thoroughly navigating and exploring codebases.
|
|
53
|
+
Your role is EXCLUSIVELY to search and analyze existing code. You do NOT have access to file editing tools.
|
|
54
|
+
|
|
55
|
+
You are STRICTLY PROHIBITED from:
|
|
56
|
+
- Creating new files
|
|
57
|
+
- Modifying existing files
|
|
58
|
+
- Deleting files
|
|
59
|
+
- Moving or copying files
|
|
60
|
+
- Creating temporary files anywhere, including /tmp
|
|
61
|
+
- Using redirect operators (>, >>, |) or heredocs to write to files
|
|
62
|
+
- Running ANY commands that change system state
|
|
63
|
+
|
|
64
|
+
Use Bash ONLY for read-only operations: ls, git status, git log, git diff, find, cat, head, tail.
|
|
65
|
+
|
|
66
|
+
# Tool Usage
|
|
67
|
+
- Use the find tool for file pattern matching (NOT the bash find command)
|
|
68
|
+
- Use the grep tool for content search (NOT bash grep/rg command)
|
|
69
|
+
- Use the read tool for reading files (NOT bash cat/head/tail)
|
|
70
|
+
- Use Bash ONLY for read-only operations
|
|
71
|
+
- Make independent tool calls in parallel for efficiency
|
|
72
|
+
- Adapt search approach based on thoroughness level specified
|
|
73
|
+
|
|
74
|
+
# Output
|
|
75
|
+
- Use absolute file paths in all references
|
|
76
|
+
- Report findings as regular messages
|
|
77
|
+
- Do not use emojis
|
|
78
|
+
- Be thorough and precise`;
|
|
79
|
+
|
|
80
|
+
export const EXPLORE_DEFAULT_TOOLS = "read, bash, grep, find, ls";
|
|
81
|
+
|
|
82
|
+
interface EmbeddedAgentDefault {
|
|
83
|
+
description: string;
|
|
84
|
+
systemPrompt: string;
|
|
85
|
+
tools: string;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Embedded copies keyed by agent name. Only agents in
|
|
89
|
+
* KNOWN_PINNED_DEFAULT_AGENTS need entries. */
|
|
90
|
+
const EMBEDDED_DEFAULTS: Record<string, EmbeddedAgentDefault> = {
|
|
91
|
+
Explore: {
|
|
92
|
+
description: EXPLORE_DEFAULT_DESCRIPTION,
|
|
93
|
+
systemPrompt: EXPLORE_DEFAULT_SYSTEM_PROMPT,
|
|
94
|
+
tools: EXPLORE_DEFAULT_TOOLS,
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/** Default global agent dir (pi-subagents reads $PI_CODING_AGENT_DIR/agents,
|
|
99
|
+
* default ~/.pi/agent/agents). Parameterized in sync for tests. */
|
|
100
|
+
export function defaultAgentDir(): string {
|
|
101
|
+
return path.join(os.homedir(), ".pi", "agent");
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** Build the override .md file content. With `model`, the pin is written;
|
|
105
|
+
* without, the file falls through to the parent session model. */
|
|
106
|
+
export function buildAgentOverrideMd(name: string, model?: string): string {
|
|
107
|
+
const def = EMBEDDED_DEFAULTS[name];
|
|
108
|
+
if (!def) throw new Error(`no embedded default config for agent "${name}"`);
|
|
109
|
+
const yamlDesc = "'" + def.description.replace(/'/g, "''") + "'";
|
|
110
|
+
const lines = [
|
|
111
|
+
"---",
|
|
112
|
+
`description: ${yamlDesc}`,
|
|
113
|
+
`tools: ${def.tools}`,
|
|
114
|
+
"prompt_mode: replace",
|
|
115
|
+
];
|
|
116
|
+
if (model) lines.push(`model: ${model}`);
|
|
117
|
+
lines.push(
|
|
118
|
+
`x-managed-by: ${SUBAGENT_MANAGED_MARKER}`,
|
|
119
|
+
model
|
|
120
|
+
? `x-glla-note: model pinned to ${model} by glla subagentModelOverrides. Remove the file or change /glla subagent settings to inherit the session model.`
|
|
121
|
+
: "x-glla-note: model pin removed (upstream default pins a fixed model) so this agent inherits the parent session model and its quota pool. Managed by glla — flip /glla subagent strategy to agent-default to restore upstream behavior.",
|
|
122
|
+
"---",
|
|
123
|
+
"",
|
|
124
|
+
def.systemPrompt,
|
|
125
|
+
"",
|
|
126
|
+
);
|
|
127
|
+
return lines.join("\n");
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function hasManagedMarker(content: string): boolean {
|
|
131
|
+
return content.includes(`x-managed-by: ${SUBAGENT_MANAGED_MARKER}`);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export interface SubagentSyncResult {
|
|
135
|
+
written: string[];
|
|
136
|
+
removed: string[];
|
|
137
|
+
/** Files left untouched because the user owns them (no marker). */
|
|
138
|
+
skipped: Array<{ name: string; reason: string }>;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/** Sync <agentDir>/agents/<Name>.md with the desired state. Idempotent:
|
|
142
|
+
* writes only when content differs. Never touches non-managed files. */
|
|
143
|
+
export function syncSubagentModelOverrides(opts: {
|
|
144
|
+
agentDir: string;
|
|
145
|
+
strategy: SubagentModelStrategy;
|
|
146
|
+
overrides?: Record<string, string>;
|
|
147
|
+
}): SubagentSyncResult {
|
|
148
|
+
const result: SubagentSyncResult = { written: [], removed: [], skipped: [] };
|
|
149
|
+
const overrides = opts.overrides ?? {};
|
|
150
|
+
const names = new Set<string>([...KNOWN_PINNED_DEFAULT_AGENTS, ...Object.keys(overrides)]);
|
|
151
|
+
|
|
152
|
+
for (const name of names) {
|
|
153
|
+
const overrideModel = overrides[name];
|
|
154
|
+
if (overrideModel !== undefined && !EMBEDDED_DEFAULTS[name]) {
|
|
155
|
+
result.skipped.push({
|
|
156
|
+
name,
|
|
157
|
+
reason: `no embedded default config for "${name}" — create ${name}.md manually (only ${KNOWN_PINNED_DEFAULT_AGENTS.join("/")} are glla-managed)`,
|
|
158
|
+
});
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
const file = path.join(opts.agentDir, "agents", `${name}.md`);
|
|
162
|
+
const desired = overrideModel
|
|
163
|
+
? buildAgentOverrideMd(name, overrideModel)
|
|
164
|
+
: opts.strategy === "inherit-parent"
|
|
165
|
+
? buildAgentOverrideMd(name)
|
|
166
|
+
: undefined; // agent-default + no per-type override → file should be absent
|
|
167
|
+
|
|
168
|
+
const exists = fs.existsSync(file);
|
|
169
|
+
const current = exists ? fs.readFileSync(file, "utf-8") : undefined;
|
|
170
|
+
|
|
171
|
+
if (desired === undefined) {
|
|
172
|
+
if (exists && hasManagedMarker(current!)) {
|
|
173
|
+
fs.unlinkSync(file);
|
|
174
|
+
result.removed.push(name);
|
|
175
|
+
} else if (exists) {
|
|
176
|
+
result.skipped.push({ name, reason: "user-owned file (no glla marker) — left untouched" });
|
|
177
|
+
}
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (exists && !hasManagedMarker(current!)) {
|
|
182
|
+
result.skipped.push({ name, reason: "user-owned file (no glla marker) — left untouched" });
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
if (current === desired) continue; // idempotent no-op
|
|
186
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
187
|
+
fs.writeFileSync(file, desired);
|
|
188
|
+
result.written.push(name);
|
|
189
|
+
}
|
|
190
|
+
return result;
|
|
191
|
+
}
|
package/extensions/loops/goal.ts
CHANGED
|
@@ -63,6 +63,7 @@ import {
|
|
|
63
63
|
shouldAutoResumeOnSessionStart,
|
|
64
64
|
statusLabel,
|
|
65
65
|
writeGoalMd,
|
|
66
|
+
missingGllaTools,
|
|
66
67
|
} from "../goal-loop-core.js";
|
|
67
68
|
import { runGoalCompletionAuditor } from "../goal-loop-auditor.js";
|
|
68
69
|
import {
|
|
@@ -74,6 +75,11 @@ import {
|
|
|
74
75
|
pushCapped as pushRepetitionCapped,
|
|
75
76
|
} from "../goal-loop-repetition.js";
|
|
76
77
|
import { buildStatusText, buildWidgetLines, type AuditDisplayProgress } from "../goal-loop-display.js";
|
|
78
|
+
import {
|
|
79
|
+
defaultAgentDir,
|
|
80
|
+
syncSubagentModelOverrides,
|
|
81
|
+
type SubagentModelStrategy,
|
|
82
|
+
} from "../goal-loop-subagents.js";
|
|
77
83
|
import {
|
|
78
84
|
applyMeasurement,
|
|
79
85
|
applyMetriclessTick,
|
|
@@ -2263,6 +2269,18 @@ interface Settings {
|
|
|
2263
2269
|
* interview floor is skipped — the seed carries the intent (unattended
|
|
2264
2270
|
* rigs). Default off: nothing activates before the user confirms. */
|
|
2265
2271
|
autoAcceptDrafts?: boolean;
|
|
2272
|
+
/** v0.24.6: subagent model strategy for pi-subagents default agents that
|
|
2273
|
+
* pin a model (Explore pins claude-haiku-4-5, which silently routes
|
|
2274
|
+
* subagents to a different provider/quota pool than the session).
|
|
2275
|
+
* "inherit-parent" (default) writes a managed ~/.pi/agent/agents/Explore.md
|
|
2276
|
+
* override without the model pin so subagents share the session model and
|
|
2277
|
+
* its quota; "agent-default" restores upstream behavior. Applies to NEW
|
|
2278
|
+
* sessions (pi-subagents registers agents at session start). */
|
|
2279
|
+
subagentModelStrategy?: SubagentModelStrategy;
|
|
2280
|
+
/** v0.24.6: per-agent-type model pin, e.g. { "Explore": "minimax/MiniMax-M3" }.
|
|
2281
|
+
* Always wins over subagentModelStrategy — the managed override is written
|
|
2282
|
+
* WITH this pin regardless of strategy. */
|
|
2283
|
+
subagentModelOverrides?: Record<string, string>;
|
|
2266
2284
|
}
|
|
2267
2285
|
|
|
2268
2286
|
const DEFAULT_SETTINGS: Settings = {
|
|
@@ -2270,6 +2288,9 @@ const DEFAULT_SETTINGS: Settings = {
|
|
|
2270
2288
|
// pi, auditor follows), floor "high" — the auditor is the verification
|
|
2271
2289
|
// gate, depth is worth more there than speed. /glla thinking= overrides.
|
|
2272
2290
|
auditorThinkingLevel: undefined,
|
|
2291
|
+
// v0.24.6: subagents inherit the session model by default — one quota
|
|
2292
|
+
// pool, no surprise 403s from a pinned default agent's provider.
|
|
2293
|
+
subagentModelStrategy: "inherit-parent",
|
|
2273
2294
|
};
|
|
2274
2295
|
|
|
2275
2296
|
// Two-tier config (v0.7.0): GLOBAL is the normal home — you set things once
|
|
@@ -2407,6 +2428,8 @@ async function openSettingsUI(ctx: ExtensionContext): Promise<void> {
|
|
|
2407
2428
|
`Notify command — ${show("notifyCmd", "(off)")}`,
|
|
2408
2429
|
`Token limit per goal — ${show("tokenLimit", "(off)")}`,
|
|
2409
2430
|
`Wedge alert minutes — ${show("wedgeAlertMinutes", `(${WEDGE_ALERT_DEFAULT_MINUTES}m default)`)}`,
|
|
2431
|
+
`Subagent model strategy — ${show("subagentModelStrategy", "(inherit-parent)")}`,
|
|
2432
|
+
`Subagent Explore model pin — ${loadSettings(ctx.cwd).subagentModelOverrides?.Explore ?? "(follows strategy)"}`,
|
|
2410
2433
|
"Done",
|
|
2411
2434
|
],
|
|
2412
2435
|
);
|
|
@@ -2440,6 +2463,26 @@ async function openSettingsUI(ctx: ExtensionContext): Promise<void> {
|
|
|
2440
2463
|
else if (!v.trim()) saveSettings("global", ctx.cwd, { wedgeAlertMinutes: undefined });
|
|
2441
2464
|
else ctx.ui.notify(`Not a non-negative integer: ${v}`, "warning");
|
|
2442
2465
|
}
|
|
2466
|
+
} else if (choice.startsWith("Subagent model strategy")) {
|
|
2467
|
+
const v = await ctx.ui.select("Subagent model (pi-subagents default agents)", [
|
|
2468
|
+
"inherit-parent — subagents share your session model + its quota pool (fixes separate-provider 403s; search agents may run on a pricier model)",
|
|
2469
|
+
"agent-default — upstream behavior: Explore pins claude-haiku-4-5 (cheap search, but a SEPARATE provider quota from your session)",
|
|
2470
|
+
]);
|
|
2471
|
+
if (v) {
|
|
2472
|
+
const strategy: SubagentModelStrategy = v.startsWith("agent-default") ? "agent-default" : "inherit-parent";
|
|
2473
|
+
saveSettings("global", ctx.cwd, { subagentModelStrategy: strategy });
|
|
2474
|
+
ctx.ui.notify("Subagent model strategy saved — applies to NEW pi sessions (pi-subagents registers agents at session start).", "info");
|
|
2475
|
+
}
|
|
2476
|
+
} else if (choice.startsWith("Subagent Explore model pin")) {
|
|
2477
|
+
const v = await ctx.ui.input("Model pin for Explore subagents", "provider/model-id e.g. minimax/MiniMax-M3 — always wins over strategy; empty = follow strategy");
|
|
2478
|
+
if (v !== undefined) {
|
|
2479
|
+
const current = loadSettings(ctx.cwd).subagentModelOverrides ?? {};
|
|
2480
|
+
const next = { ...current };
|
|
2481
|
+
if (v.trim()) next.Explore = v.trim();
|
|
2482
|
+
else delete next.Explore;
|
|
2483
|
+
saveSettings("global", ctx.cwd, { subagentModelOverrides: Object.keys(next).length > 0 ? next : undefined });
|
|
2484
|
+
ctx.ui.notify("Explore model pin saved — applies to NEW pi sessions.", "info");
|
|
2485
|
+
}
|
|
2443
2486
|
}
|
|
2444
2487
|
} catch {
|
|
2445
2488
|
return;
|
|
@@ -2729,6 +2772,29 @@ export default function (pi: ExtensionAPI): void {
|
|
|
2729
2772
|
// "no active goal" if called).
|
|
2730
2773
|
let registeredCtx: ExtensionContext | null = null;
|
|
2731
2774
|
|
|
2775
|
+
// v0.24.5 tool-visibility self-heal: surface the notify exactly once
|
|
2776
|
+
// per session so the user learns about an external allowlist once and
|
|
2777
|
+
// can fix their profile to silence it.
|
|
2778
|
+
let toolHealNotified = false;
|
|
2779
|
+
function ensureAgentToolsActive(pi: ExtensionAPI, ctx: ExtensionContext): void {
|
|
2780
|
+
try {
|
|
2781
|
+
const active = pi.getActiveTools();
|
|
2782
|
+
const missing = missingGllaTools(active);
|
|
2783
|
+
if (missing.length === 0) return;
|
|
2784
|
+
pi.setActiveTools([...active, ...missing]);
|
|
2785
|
+
if (!toolHealNotified) {
|
|
2786
|
+
toolHealNotified = true;
|
|
2787
|
+
const list = missing.join(", ");
|
|
2788
|
+
ctx.ui.notify(
|
|
2789
|
+
`glla: ${missing.length} agent tool(s) were hidden by an external tool allowlist (e.g. a modlist profile) and have been re-activated (${list}). Add them to your allowlist profile to silence this.`,
|
|
2790
|
+
"warning",
|
|
2791
|
+
);
|
|
2792
|
+
}
|
|
2793
|
+
} catch {
|
|
2794
|
+
// Older pi without getActiveTools/setActiveTools — nothing we can do.
|
|
2795
|
+
}
|
|
2796
|
+
}
|
|
2797
|
+
|
|
2732
2798
|
pi.on("message_start", async (event: any, _ctx: ExtensionContext) => {
|
|
2733
2799
|
// v0.14.0 drafting floor: count real user replies while drafting. Our
|
|
2734
2800
|
// own injected draft prompt arrives as a user message — skip that one.
|
|
@@ -2773,8 +2839,25 @@ export default function (pi: ExtensionAPI): void {
|
|
|
2773
2839
|
registerAgentTools(pi, ctx);
|
|
2774
2840
|
registeredCtx = ctx;
|
|
2775
2841
|
}
|
|
2842
|
+
ensureAgentToolsActive(pi, ctx);
|
|
2776
2843
|
warnOnCommandCollision(ctx);
|
|
2777
2844
|
warnIfAuditorProviderRisky(ctx);
|
|
2845
|
+
// v0.24.6: sync the pi-subagents model override (managed Explore.md) with
|
|
2846
|
+
// settings. Idempotent; applies to NEW sessions (pi-subagents registers
|
|
2847
|
+
// its agents at its own session start).
|
|
2848
|
+
try {
|
|
2849
|
+
const s = loadSettings(ctx.cwd);
|
|
2850
|
+
const sync = syncSubagentModelOverrides({
|
|
2851
|
+
agentDir: defaultAgentDir(),
|
|
2852
|
+
strategy: s.subagentModelStrategy ?? "inherit-parent",
|
|
2853
|
+
overrides: s.subagentModelOverrides,
|
|
2854
|
+
});
|
|
2855
|
+
for (const skip of sync.skipped) {
|
|
2856
|
+
ctx.ui.notify(`glla subagent override skipped [${skip.name}]: ${skip.reason}`, "warning");
|
|
2857
|
+
}
|
|
2858
|
+
} catch (err) {
|
|
2859
|
+
ctx.ui.notify(`glla subagent override sync failed: ${err instanceof Error ? err.message : String(err)}`, "warning");
|
|
2860
|
+
}
|
|
2778
2861
|
// Restore gate (v0.21.0): a fresh session ("startup"/"new", or a pi too
|
|
2779
2862
|
// old to report a reason) has no conversation context for the restored
|
|
2780
2863
|
// work — HOLD instead of auto-firing, so opening pi in a folder never
|
|
@@ -2853,6 +2936,7 @@ export default function (pi: ExtensionAPI): void {
|
|
|
2853
2936
|
registerAgentTools(pi, ctx);
|
|
2854
2937
|
registeredCtx = ctx;
|
|
2855
2938
|
}
|
|
2939
|
+
ensureAgentToolsActive(pi, ctx);
|
|
2856
2940
|
// Nudge accounting: a supervising turn with zero tool calls is a nudge
|
|
2857
2941
|
// (no real progress); 3 consecutive → pause. Tool-use turns reset it.
|
|
2858
2942
|
if (isSupervising()) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-goal-list-loop-audit",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.6",
|
|
4
4
|
"description": "Goal. Loop. Audit. Done. — a pi-coding-agent extension that supervises long-running work, with isolated auditor on each completion. Beat bamboozling by design: the auditor runs in a fresh session with no extensions, no skills, no editor — only the read tools needed to verify your goal.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "dracon",
|