pi-goal-list-loop-audit 0.38.0 → 0.38.2
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 +17 -0
- package/docs/INDEX.md +1 -1
- package/extensions/drafter-model.ts +13 -6
- package/extensions/loops/goal-activation.ts +2 -2
- package/extensions/loops/goal-auditor-hooks.ts +3 -0
- package/extensions/loops/goal-list-queue.ts +45 -12
- package/extensions/loops/goal-settings-ui.ts +8 -62
- package/extensions/loops/goal-tools.ts +1 -0
- package/extensions/settings-menu.ts +4 -20
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.38.2 — thinking selected with model, remove standalone rows (2026-09-02)
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
`Drafter thinking` and `Auditor thinking` standalone rows removed from `/glla` — thinking is now selected **with** the model pick (the existing `Drafter agent` / `Auditor agent` flows already prompt for thinking immediately after the model, and that ladder is model-aware via `auditorThinkingLevels`). Main had no standalone thinking row; Drafter/Auditor now match it. Stored `drafterThinkingLevel` / `auditorThinkingLevel` keys remain read for fallback-chain rendering (`modelThinkingText`) and for the model-pick ladder, but there is no separate editor — re-pick the model to change thinking. Prevents stale thinking selection and the "Main has no selector, others do" inconsistency.
|
|
7
|
+
|
|
8
|
+
## 0.38.1 — drafter/auditor fallback parity with Main (2026-09-02)
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
Drafter model selection now emits the same `model_fallback_select` ledger as Main (`scope: drafter`) for every forbidden/unregistered skip, so `forbiddenModels` edits mid-interview are honored even when the user edits settings while the interview is open.
|
|
12
|
+
|
|
13
|
+
Drafter recovery after a provider failure now walks the dedicated 0-10 chain via `ModelSelector` with the bounded ladder (`5s → base*2^(n-1) cap 5h`, base `mainModelRetryMinutes` default 15) and `forbiddenModels` re-check, instead of an immediate unbounded loop over the lease candidates. Same-model pin (drafter pinned to the session model) remains a same-model retry and is preserved.
|
|
14
|
+
|
|
15
|
+
Auditor `model_fallback_select` ledger (`scope: auditor`) now fires for both the settings-time `resolveAuditorModel` walk and the detached audit fallback (`runAuditorFallbackWithPolicy` via `runDetachedCompletionWithFallback`), closing the gap where detached retries skipped forbidden/unregistered refs silently. `forbiddenRefs` and `retryBaseMinutes` were already wired; `onSelection` is now forwarded.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
`Drafter fallback agents` menu row → `Drafter fallback models (up to 10)` with count prefix `N/10 · 1. ref → 2. ref` and the shared `ordered and deselectable: current drafter → fallback 1 → fallback 2…` description, matching Main and Auditor rows. Prompt title and notification strings updated to `models` vocabulary. Watchdog budgets (`auditorToolTimeoutMs 5m`, `auditorStallMs 10m` x2 cap 4x) remain independent of the ladder and unchanged.
|
|
19
|
+
|
|
3
20
|
## 0.38.0 — event-driven supervision and drafting discipline (2026-09-02)
|
|
4
21
|
|
|
5
22
|
### Fixed
|
package/docs/INDEX.md
CHANGED
|
@@ -18,7 +18,7 @@ For shipped docs, the relevant entry points are:
|
|
|
18
18
|
failback; v0.35.9 hardened cross-version npm tarball checks; v0.35.10
|
|
19
19
|
handles multi-entry npm dry-run reports; v0.35.11 accepts both npm report
|
|
20
20
|
shapes; v0.35.12 supports npm 12's keyed pack reports; v0.35.13 fixes stale-API recovery loops.
|
|
21
|
-
v0.35.14–v0.38.
|
|
21
|
+
v0.35.14–v0.38.2 continue through the supervisor freeze (`/glla pause`),
|
|
22
22
|
load hold, auditor picker parity, Windows launch fix, zombie-watchdog
|
|
23
23
|
subagent carve-out, due-wait backstop, the `/glla agents` visibility panel,
|
|
24
24
|
durable state-root selection, blank-until-resume auditor context, frozen
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
9
9
|
|
|
10
|
-
import { isForbiddenModel } from "./goal-loop-core.js";
|
|
10
|
+
import { appendLedger, isForbiddenModel } from "./goal-loop-core.js";
|
|
11
11
|
import { MAX_MAIN_MODEL_FALLBACKS, modelRef, normalizeMainModelFallbackRefs } from "./main-model-recovery.js";
|
|
12
12
|
import { ModelSelector } from "./model-selector.js";
|
|
13
13
|
import type { Settings } from "./goal-settings.js";
|
|
@@ -63,15 +63,22 @@ export function resolveDrafterModel(ctx: ExtensionContext, settings: Pick<Settin
|
|
|
63
63
|
getChain: () => configuredRefs,
|
|
64
64
|
resolve: (ref) => resolveDrafterModelRef(ctx, ref),
|
|
65
65
|
isForbidden: forbidden,
|
|
66
|
+
record: (event) => {
|
|
67
|
+
appendLedger(ctx.cwd, "model_fallback_select", {
|
|
68
|
+
scope: event.scope.kind,
|
|
69
|
+
fromRef: event.fromRef,
|
|
70
|
+
toRef: event.toRef,
|
|
71
|
+
reason: event.reason,
|
|
72
|
+
});
|
|
73
|
+
},
|
|
66
74
|
});
|
|
67
75
|
const attempted: string[] = [];
|
|
68
76
|
const candidates: DrafterModelCandidate[] = [];
|
|
69
77
|
|
|
70
|
-
//
|
|
71
|
-
//
|
|
72
|
-
//
|
|
73
|
-
//
|
|
74
|
-
// available if the first drafting turn fails.
|
|
78
|
+
// KEEP: drafting intentionally leases the current model when pinned (unlike
|
|
79
|
+
// Main which skips `current` via nextUntriedModelRef because it just failed).
|
|
80
|
+
// Align ledger to Main but keep this lease gate — removing it would force a
|
|
81
|
+
// needless setModel when the user pinned the drafter to the session model.
|
|
75
82
|
const configuredPrimary = configuredRefs[0];
|
|
76
83
|
if (
|
|
77
84
|
configuredPrimary &&
|
|
@@ -2023,8 +2023,8 @@ export function registerGoalRuntime(pi: ExtensionAPI): void {
|
|
|
2023
2023
|
// an interview must retry that chain before the main-goal recovery path;
|
|
2024
2024
|
// otherwise a drafting failure would silently consume main-model backups.
|
|
2025
2025
|
if (lastA?.stopReason === "error" && draftingTarget !== null) {
|
|
2026
|
-
const retryDrafting = (globalThis as any).handleDrafterModelFailure as ((context: ExtensionContext) => Promise<boolean>) | undefined;
|
|
2027
|
-
if (retryDrafting) await retryDrafting(ctx);
|
|
2026
|
+
const retryDrafting = (globalThis as any).handleDrafterModelFailure as ((context: ExtensionContext, error?: string) => Promise<boolean>) | undefined;
|
|
2027
|
+
if (retryDrafting) await retryDrafting(ctx, (rawLastA as any)?.errorMessage ?? (rawLastA as any)?.error ?? lastA.text);
|
|
2028
2028
|
// Whether a configured fallback was available or not, drafting owns
|
|
2029
2029
|
// this error. Leave the interview open for an explicit user retry and
|
|
2030
2030
|
// never pass the same failure into main-goal recovery.
|
|
@@ -904,6 +904,7 @@ export async function runDetachedCompletionWithFallback(
|
|
|
904
904
|
onFallback?: (from: AuditorModelCandidate, to: AuditorModelCandidate, error: string) => void;
|
|
905
905
|
forbiddenRefs?: readonly string[];
|
|
906
906
|
retryBaseMinutes?: number;
|
|
907
|
+
onSelection?: (event: { scope: { kind: string }; fromRef?: string; toRef?: string; reason: string }) => void;
|
|
907
908
|
} = {},
|
|
908
909
|
): Promise<{ result: DetachedAuditResult; retriedOnce: boolean; fallbackUsed: boolean; via: string }> {
|
|
909
910
|
return runAuditorFallbackWithPolicy(candidates, run, {
|
|
@@ -911,6 +912,7 @@ export async function runDetachedCompletionWithFallback(
|
|
|
911
912
|
shouldRetry: opts.shouldRetry,
|
|
912
913
|
sleep: opts.sleep,
|
|
913
914
|
retryBaseMinutes: opts.retryBaseMinutes,
|
|
915
|
+
onSelection: opts.onSelection,
|
|
914
916
|
resumeCandidateRef: opts.resumeCandidateRef,
|
|
915
917
|
attemptedRefs: opts.attemptedRefs,
|
|
916
918
|
retryCandidateRef: opts.retryCandidateRef,
|
|
@@ -1101,6 +1103,7 @@ async function retryStoredCompletionAudit(origin: CompletionAuditOrigin = "provi
|
|
|
1101
1103
|
shouldRetry: () => detachedAuditContext(generation, goalId, claim.attemptId!) !== null,
|
|
1102
1104
|
forbiddenRefs: settings.forbiddenModels,
|
|
1103
1105
|
retryBaseMinutes: settings.mainModelRetryMinutes,
|
|
1106
|
+
onSelection: (event: { scope: { kind: string }; fromRef?: string; toRef?: string; reason: string }) => appendLedger(liveCtx.cwd, "model_fallback_select", { scope: "auditor", fromRef: event.fromRef, toRef: event.toRef, reason: event.reason }),
|
|
1104
1107
|
resumeCandidateRef: persistedAuditorCandidateRef,
|
|
1105
1108
|
attemptedRefs: persistedAuditorAttemptedRefs,
|
|
1106
1109
|
retryCandidateRef: persistedAuditorRetryCandidateRef,
|
|
@@ -371,6 +371,7 @@ import {
|
|
|
371
371
|
resolveDrafterModel,
|
|
372
372
|
type DrafterModelCandidate,
|
|
373
373
|
} from "../drafter-model.js";
|
|
374
|
+
import { ModelSelector } from "../model-selector.js";
|
|
374
375
|
import {
|
|
375
376
|
assessSuspiciousObjective,
|
|
376
377
|
deriveObjectiveFromContract,
|
|
@@ -553,25 +554,57 @@ async function restoreDrafterModel(): Promise<void> {
|
|
|
553
554
|
}
|
|
554
555
|
|
|
555
556
|
/**
|
|
556
|
-
* Generic drafting recovery: walk the dedicated chain
|
|
557
|
-
*
|
|
558
|
-
*
|
|
557
|
+
* Generic drafting recovery: walk the dedicated chain via ModelSelector so
|
|
558
|
+
* forbidden/unregistered refs are skipped with the same ledger as Main,
|
|
559
|
+
* and provider retries use the bounded ladder (5s → base*2^(n-1) cap 5h).
|
|
560
|
+
* The session model remains the last resort; same-model lease is preserved.
|
|
559
561
|
*/
|
|
560
|
-
async function handleDrafterModelFailure(ctx: ExtensionContext): Promise<boolean> {
|
|
562
|
+
async function handleDrafterModelFailure(ctx: ExtensionContext, error?: string): Promise<boolean> {
|
|
561
563
|
const lease = draftingModelLease;
|
|
562
564
|
if (!lease || draftingTarget === null || lease.generation !== sessionGeneration || !extensionApi) return false;
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
565
|
+
const settings = loadSettings(ctx.cwd);
|
|
566
|
+
const failure = classifyMainModelFailure(error);
|
|
567
|
+
if (failure.kind === "non-recoverable") return false;
|
|
568
|
+
const configuredRefs = lease.candidates.filter((candidate) => candidate.via === "configured").map((candidate) => candidate.ref);
|
|
569
|
+
const selector = new ModelSelector({
|
|
570
|
+
getChain: () => configuredRefs,
|
|
571
|
+
resolve: (ref) => lease.candidates.find((candidate) => candidate.ref.toLowerCase() === ref.toLowerCase())?.model,
|
|
572
|
+
isForbidden: (ref) => isForbiddenModel(ref, settings.forbiddenModels),
|
|
573
|
+
record: (event) =>
|
|
574
|
+
appendLedger(ctx.cwd, "model_fallback_select", {
|
|
575
|
+
scope: "drafter",
|
|
576
|
+
fromRef: event.fromRef,
|
|
577
|
+
toRef: event.toRef,
|
|
578
|
+
reason: event.reason,
|
|
579
|
+
}),
|
|
580
|
+
});
|
|
581
|
+
let attempt = lease.attempted.length;
|
|
582
|
+
for (;;) {
|
|
583
|
+
const pick = selector.selectNextValid({ kind: "drafter" }, lease.activeRef, lease.attempted);
|
|
584
|
+
for (const visited of selector.lastVisitedRefs) {
|
|
585
|
+
if (!lease.attempted.some((ref) => ref.toLowerCase() === visited.toLowerCase())) lease.attempted.push(visited);
|
|
586
|
+
}
|
|
587
|
+
if (!("model" in pick)) break;
|
|
588
|
+
const delayMs = mainModelFailureDelayMs(failure, ++attempt, (settings as any).mainModelRetryMinutes ?? 15);
|
|
589
|
+
if (delayMs > 5_000) await new Promise<void>((resolve) => setTimeout(resolve, delayMs));
|
|
566
590
|
let switched = false;
|
|
567
|
-
try {
|
|
568
|
-
|
|
591
|
+
try {
|
|
592
|
+
switched = await extensionApi.setModel(pick.model);
|
|
593
|
+
} catch {
|
|
594
|
+
switched = false;
|
|
595
|
+
}
|
|
596
|
+
const alreadyActive = pick.ref.toLowerCase() === lease.activeRef.toLowerCase();
|
|
569
597
|
if (!switched && !alreadyActive) continue;
|
|
570
598
|
const previous = lease.activeRef;
|
|
571
|
-
lease.activeRef =
|
|
599
|
+
lease.activeRef = pick.ref;
|
|
572
600
|
lease.activeThinkingLevel = applyDrafterThinkingLevel(ctx, lease.requestedThinkingLevel);
|
|
573
|
-
appendLedger(ctx.cwd, alreadyActive ? "drafter_model_retry" : "drafter_model_fallback", {
|
|
574
|
-
|
|
601
|
+
appendLedger(ctx.cwd, alreadyActive ? "drafter_model_retry" : "drafter_model_fallback", {
|
|
602
|
+
from: previous,
|
|
603
|
+
to: pick.ref,
|
|
604
|
+
attempted: lease.attempted.slice(),
|
|
605
|
+
delayMs,
|
|
606
|
+
});
|
|
607
|
+
ctx.ui.notify(`Drafting provider failed; retrying the existing interview on ${pick.ref} after ${Math.round(delayMs / 1000)}s.`, "warning");
|
|
575
608
|
const safeSteer = (globalThis as any).safeSteerUser as ((context: ExtensionContext, text: string) => boolean) | undefined;
|
|
576
609
|
if (!safeSteer || !safeSteer(ctx, DRAFTER_RECOVERY_PROMPT)) return false;
|
|
577
610
|
draftingSeedInFlight = true;
|
|
@@ -554,9 +554,13 @@ export function resolveAuditorModel(
|
|
|
554
554
|
resolve: (candidate) => tryRef(candidate).model,
|
|
555
555
|
isForbidden: forbidden,
|
|
556
556
|
record: (event) => {
|
|
557
|
+
appendLedger(ctx.cwd, "model_fallback_select", {
|
|
558
|
+
scope: "auditor",
|
|
559
|
+
fromRef: event.fromRef,
|
|
560
|
+
toRef: event.toRef,
|
|
561
|
+
reason: event.reason,
|
|
562
|
+
});
|
|
557
563
|
if (event.reason === "forbidden" && event.toRef) {
|
|
558
|
-
// Forbidden is an explicit user gate, not an unavailable-model
|
|
559
|
-
// warning. Keep the forensic ledger entry but do not nudge the UI.
|
|
560
564
|
appendLedger(ctx.cwd, "auditor_model_fallback", { configured: event.toRef, reason: "forbidden" });
|
|
561
565
|
return;
|
|
562
566
|
}
|
|
@@ -1183,52 +1187,18 @@ export async function handleSettingChoice(id: string, ctx: ExtensionContext): Pr
|
|
|
1183
1187
|
);
|
|
1184
1188
|
return;
|
|
1185
1189
|
}
|
|
1186
|
-
case "drafterThinkingLevel": {
|
|
1187
|
-
const settings = loadSettings(ctx.cwd);
|
|
1188
|
-
const pickedModel = settings.drafterModel
|
|
1189
|
-
? resolvePickedModel(ctx, { kind: "ref", ref: settings.drafterModel })
|
|
1190
|
-
: (ctx.model as any);
|
|
1191
|
-
const levels = auditorThinkingLevels(pickedModel);
|
|
1192
|
-
if (levels.length <= 1) {
|
|
1193
|
-
ctx.ui.notify(
|
|
1194
|
-
`Drafter agent ${pickedModel ? `${pickedModel.provider}/${pickedModel.id}` : "(session)"} exposes no thinking levels — drafting runs with thinking off.`,
|
|
1195
|
-
"info",
|
|
1196
|
-
);
|
|
1197
|
-
return;
|
|
1198
|
-
}
|
|
1199
|
-
const preferred = settings.drafterThinkingLevel ?? ctx.thinkingLevel ?? "high";
|
|
1200
|
-
const thinking = await ctx.ui.select(
|
|
1201
|
-
"Drafter thinking — TEMPORARY DRAFTING AGENT ONLY (your session thinking is restored afterward)",
|
|
1202
|
-
drafterThinkingChoiceOptions(
|
|
1203
|
-
levels,
|
|
1204
|
-
levels.includes(preferred) ? preferred : levels.includes("high") ? "high" : levels[levels.length - 1],
|
|
1205
|
-
settings.drafterThinkingLevel === undefined,
|
|
1206
|
-
),
|
|
1207
|
-
);
|
|
1208
|
-
if (thinking) {
|
|
1209
|
-
if (thinking.startsWith("session —")) {
|
|
1210
|
-
saveSettings("global", ctx.cwd, { drafterThinkingLevel: undefined });
|
|
1211
|
-
ctx.ui.notify("Drafter thinking: inherited from the session.", "info");
|
|
1212
|
-
} else {
|
|
1213
|
-
const level = thinking.split(" ")[0] as ConfiguredThinkingLevel;
|
|
1214
|
-
saveSettings("global", ctx.cwd, { drafterThinkingLevel: level });
|
|
1215
|
-
ctx.ui.notify(`Drafter thinking: ${level}.`, "info");
|
|
1216
|
-
}
|
|
1217
|
-
}
|
|
1218
|
-
return;
|
|
1219
|
-
}
|
|
1220
1190
|
case "drafterModelFallbacks": {
|
|
1221
1191
|
const global = loadGlobalSettings();
|
|
1222
1192
|
const current = normalizeMainModelFallbackRefs(global.drafterModelFallbacks);
|
|
1223
1193
|
const refs = await promptModelRefs(
|
|
1224
1194
|
ctx,
|
|
1225
|
-
`Drafter fallback
|
|
1195
|
+
`Drafter fallback models (up to ${MAX_MAIN_MODEL_FALLBACKS}) — ordered; the session model is the last resort; forbidden models are hidden`,
|
|
1226
1196
|
current,
|
|
1227
1197
|
{ excludeRefs: normalizeModelRefs(loadSettings(ctx.cwd).forbiddenModels), maxSelections: MAX_MAIN_MODEL_FALLBACKS, currentRef: modelRef(ctx.model) },
|
|
1228
1198
|
);
|
|
1229
1199
|
if (refs === undefined) return;
|
|
1230
1200
|
saveSettings("global", ctx.cwd, { drafterModelFallbacks: refs.length ? refs : undefined });
|
|
1231
|
-
ctx.ui.notify(refs.length ? `Drafter fallback
|
|
1201
|
+
ctx.ui.notify(refs.length ? `Drafter fallback models saved: ${refs.join(" → ")}.` : "Drafter fallback models cleared — the session model remains the last resort.", "info");
|
|
1232
1202
|
return;
|
|
1233
1203
|
}
|
|
1234
1204
|
case "forbiddenModels": {
|
|
@@ -1312,30 +1282,6 @@ export async function handleSettingChoice(id: string, ctx: ExtensionContext): Pr
|
|
|
1312
1282
|
ctx.ui.notify(`Auditor model: ${pick.kind === "session" ? "session model (override cleared)" : pick.ref}${t ? ` · thinking ${t.split(" ")[0]}` : ""}`, "info");
|
|
1313
1283
|
return;
|
|
1314
1284
|
}
|
|
1315
|
-
case "auditorThinkingLevel": {
|
|
1316
|
-
// v0.34.127: standalone path — the v0.31.4 comment claimed "/glla
|
|
1317
|
-
// thinking=" is the direct path, but no such action ever existed; the
|
|
1318
|
-
// ONLY way to change the level was re-picking the auditor model. The
|
|
1319
|
-
// Auditor thinking row fixes that with the same ladder + dialog the
|
|
1320
|
-
// model flow uses.
|
|
1321
|
-
const curThinking = loadSettings(ctx.cwd).auditorThinkingLevel;
|
|
1322
|
-
const inheritedThinking = ctx.thinkingLevel ?? "max";
|
|
1323
|
-
const resolved = resolveAuditorModel(ctx);
|
|
1324
|
-
const levels = auditorThinkingLevels(resolved.model);
|
|
1325
|
-
if (levels.length <= 1) {
|
|
1326
|
-
ctx.ui.notify(
|
|
1327
|
-
`Auditor model ${resolved.model ? `${resolved.model.provider}/${resolved.model.id}` : "(session)"} exposes no thinking levels — the auditor runs with thinking off.`,
|
|
1328
|
-
"info",
|
|
1329
|
-
);
|
|
1330
|
-
return;
|
|
1331
|
-
}
|
|
1332
|
-
const t = await ctx.ui.select(
|
|
1333
|
-
"Auditor thinking — DETACHED auditor worker ONLY (your session model's thinking is untouched)",
|
|
1334
|
-
levels.map((lv) => `${lv} — ${THINKING_DESCR[lv] ?? ""}${lv === (curThinking ?? inheritedThinking) ? " (current)" : ""}`),
|
|
1335
|
-
);
|
|
1336
|
-
if (t) saveSettings("global", ctx.cwd, { auditorThinkingLevel: t.split(" ")[0] as Settings["auditorThinkingLevel"] });
|
|
1337
|
-
return;
|
|
1338
|
-
}
|
|
1339
1285
|
case "auditorModelFallbacks": {
|
|
1340
1286
|
const settings = loadGlobalSettings();
|
|
1341
1287
|
const current = normalizeMainModelFallbackRefs(settings.auditorModelFallbacks);
|
|
@@ -889,6 +889,7 @@ function registerAgentTools(pi: any): void {
|
|
|
889
889
|
shouldRetry: () => detachedAuditContext(auditGeneration, auditGoalId, auditAttemptId) !== null,
|
|
890
890
|
forbiddenRefs: settings.forbiddenModels,
|
|
891
891
|
retryBaseMinutes: settings.mainModelRetryMinutes,
|
|
892
|
+
onSelection: (event: { scope: { kind: string }; fromRef?: string; toRef?: string; reason: string }) => appendLedger(ctx.cwd, "model_fallback_select", { scope: "auditor", fromRef: event.fromRef, toRef: event.toRef, reason: event.reason }),
|
|
892
893
|
resumeCandidateRef: persistedAuditorCandidateRef,
|
|
893
894
|
attemptedRefs: persistedAuditorAttemptedRefs,
|
|
894
895
|
retryCandidateRef: persistedAuditorRetryCandidateRef,
|
|
@@ -311,23 +311,15 @@ export function buildSettingsRows(
|
|
|
311
311
|
sourceText: src("drafterModel"),
|
|
312
312
|
description: "temporary agent/model used only during /goal, /list, and /loop drafting; after confirmation or interruption the session agent is restored",
|
|
313
313
|
},
|
|
314
|
-
{
|
|
315
|
-
id: "drafterThinkingLevel",
|
|
316
|
-
section: "drafter",
|
|
317
|
-
label: "Drafter thinking",
|
|
318
|
-
valueText: settings.drafterThinkingLevel ? settings.drafterThinkingLevel : `inherit ${sessionThinking}`,
|
|
319
|
-
sourceText: src("drafterThinkingLevel"),
|
|
320
|
-
description: "requested drafting-agent reasoning level — the same request follows the drafter fallback chain and Pi clamps it per model; unset inherits the session level",
|
|
321
|
-
},
|
|
322
314
|
{
|
|
323
315
|
id: "drafterModelFallbacks",
|
|
324
316
|
section: "drafter",
|
|
325
|
-
label:
|
|
317
|
+
label: `Drafter fallback models (up to ${MAX_MAIN_MODEL_FALLBACKS})`,
|
|
326
318
|
valueText: settings.drafterModelFallbacks?.length
|
|
327
|
-
?
|
|
328
|
-
:
|
|
319
|
+
? `${settings.drafterModelFallbacks.length}/${MAX_MAIN_MODEL_FALLBACKS} · ${settings.drafterModelFallbacks.map((ref, index) => `${index + 1}. ${modelThinkingText(ref, drafterThinking, subagent)}`).join(" → ")}`
|
|
320
|
+
: `0/${MAX_MAIN_MODEL_FALLBACKS} · ${sessionRef} · ${drafterThinking} (last resort)`,
|
|
329
321
|
sourceText: src("drafterModelFallbacks"),
|
|
330
|
-
description: "ordered
|
|
322
|
+
description: "ordered and deselectable: current drafter → fallback 1 → fallback 2…; every recoverable provider failure switches one eligible fallback at a time",
|
|
331
323
|
},
|
|
332
324
|
);
|
|
333
325
|
|
|
@@ -358,14 +350,6 @@ export function buildSettingsRows(
|
|
|
358
350
|
sourceText: src("auditorModel"),
|
|
359
351
|
description: "provider/model override for the isolated auditor agent — the fallback chain below runs after this primary; its thinking defaults to the parent session",
|
|
360
352
|
},
|
|
361
|
-
{
|
|
362
|
-
id: "auditorThinkingLevel",
|
|
363
|
-
section: "auditor",
|
|
364
|
-
label: "Auditor thinking",
|
|
365
|
-
valueText: settings.auditorThinkingLevel ?? sessionThinking,
|
|
366
|
-
sourceText: src("auditorThinkingLevel"),
|
|
367
|
-
description: "DETACHED auditor worker's reasoning level — unset inherits the parent session dial (including max); an explicit value overrides it",
|
|
368
|
-
},
|
|
369
353
|
{
|
|
370
354
|
id: "auditorModelFallbacks",
|
|
371
355
|
section: "auditor",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-goal-list-loop-audit",
|
|
3
|
-
"version": "0.38.
|
|
3
|
+
"version": "0.38.2",
|
|
4
4
|
"description": "Mission control for autonomous pi: interview-drafted goals, an audited task queue, and forever-loops (metric, spec, project-audit) that run for hours. A detached extension-less auditor process re-verifies every completion with raw evidence without holding the main pi turn; confirmed drafts, decision pauses and consent gates keep you in charge.",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"author": "dracon",
|