pi-goal-x 0.31.4 → 0.31.5
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/README.md +10 -5
- package/assets/badge-dark.svg +2 -2
- package/assets/badge-light.svg +2 -2
- package/extensions/goal-commands.ts +2 -1
- package/extensions/goal-core-tools.ts +2 -2
- package/extensions/goal-scheduler.ts +20 -2
- package/extensions/goal-settings.ts +11 -0
- package/extensions/prompts/goal-prompts.ts +5 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<a href="https://pi.dev/packages?type=extension" target="_blank" rel="noopener noreferrer">
|
|
7
7
|
<picture>
|
|
8
8
|
<source media="(prefers-color-scheme: dark)" srcset="assets/badge-dark.svg">
|
|
9
|
-
<img src="assets/badge-light.svg" alt="TOP 0.3% of Pi coding agent extensions: #7 of 3,
|
|
9
|
+
<img src="assets/badge-light.svg" alt="TOP 0.3% of Pi coding agent extensions: #7 of 3,352 by downloads · Sep 16, 2026 (best recorded rank)" width="480">
|
|
10
10
|
</picture>
|
|
11
11
|
</a>
|
|
12
12
|
</div>
|
|
@@ -115,7 +115,8 @@ Open `/goal-settings` to change these options. You can save defaults for all pro
|
|
|
115
115
|
|
|
116
116
|
| Setting | What it controls |
|
|
117
117
|
| --- | --- |
|
|
118
|
-
|
|
|
118
|
+
| Explicit execution contracts (`strictExecutionContract`) | Opt-in ready/wait protocol with one missing-decision repair, then pause. Defaults to `false`: successful executions continue automatically. |
|
|
119
|
+
| Autonomous run allowance (`maxAutonomousRuns`) | Positive whole number of extension-started runs per creation or `/goal-resume` period. **Unset means unlimited; zero disables automatic continuation.** Settings edits change the limit without resetting usage. |
|
|
119
120
|
| Task tracking (`disableTasks`) | Turn task lists on or off. Set to `true` to disable them. |
|
|
120
121
|
| Subtask depth (`subtaskDepth`) | Limit how many levels of subtasks the agent can create. |
|
|
121
122
|
| Completion requirements (`disableContracts`) | Turn explicit goal and task completion requirements on or off. Set to `true` to disable them. |
|
|
@@ -123,9 +124,11 @@ Open `/goal-settings` to change these options. You can save defaults for all pro
|
|
|
123
124
|
| Auditor provider, model, and thinking level | Choose which model reviews completed work and its reasoning effort. |
|
|
124
125
|
|
|
125
126
|
|
|
126
|
-
###
|
|
127
|
+
### Automatic continuation and optional execution contracts
|
|
127
128
|
|
|
128
|
-
|
|
129
|
+
Active goals continue automatically after successful executions, including reasoning-only responses and final-task verification. No tool call, task update, scheduling declaration, or cooldown is required. Unproductive loops remain possible; optional run limits and token budgets still apply.
|
|
130
|
+
|
|
131
|
+
Enable `strictExecutionContract: true` in `/goal-settings` or your global/project settings to require explicit ready/wait decisions. In that mode, a missing decision permits one repair prompt within the remaining allowance, then pauses. This is a user preference; agents should not enable it merely to continue.
|
|
129
132
|
|
|
130
133
|
Set an appropriate allowance in `/goal-settings`, or in `.pi/pi-goal-x-settings.json`:
|
|
131
134
|
|
|
@@ -133,7 +136,9 @@ Set an appropriate allowance in `/goal-settings`, or in `.pi/pi-goal-x-settings.
|
|
|
133
136
|
{ "maxAutonomousRuns": 20 }
|
|
134
137
|
```
|
|
135
138
|
|
|
136
|
-
Agents may edit this setting. Changing it does not replenish consumed runs; explicit `/goal-resume` renews the period and continues now, including from a waiting goal.
|
|
139
|
+
Agents may edit this setting. Changing it does not replenish consumed runs; explicit `/goal-resume` renews the period and continues now, including from a waiting goal. No configured allowance is required unless the effective limit is zero, which disables resume. Tool calls within a run are not separate runs. Existing token budgets still apply.
|
|
140
|
+
|
|
141
|
+
Explicit `ready` is optional in default mode. New `wait` declarations require strict mode; otherwise they return a non-terminating error. Previously saved waits retain their deadline, checks, and repair rules when upgrading or disabling strict mode, and may be re-declared with the same identity. Mode changes never resume a paused goal or renew consumed runs.
|
|
137
142
|
|
|
138
143
|
```js
|
|
139
144
|
update_goal({ continuation: { kind: "ready", next_action: "Verify the build artifacts" } })
|
package/assets/badge-dark.svg
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="480" height="54" viewBox="0 0 480 54" role="img" aria-label="TOP 0.3% of Pi coding agent extensions: #7 of 3,
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="480" height="54" viewBox="0 0 480 54" role="img" aria-label="TOP 0.3% of Pi coding agent extensions: #7 of 3,352 by downloads · Sep 16, 2026 (best recorded rank)">
|
|
2
2
|
<!-- Dark mode -->
|
|
3
3
|
<style>
|
|
4
4
|
.frame { fill: #14181f; stroke: #2a3040; stroke-width: 1; }
|
|
@@ -13,6 +13,6 @@
|
|
|
13
13
|
<text class="rank" x="18" y="34">TOP 0.3%</text>
|
|
14
14
|
<line class="divider" x1="128" y1="13" x2="128" y2="41"/>
|
|
15
15
|
<text class="label" x="143" y="25">of Pi coding agent extensions</text>
|
|
16
|
-
<text class="meta" x="143" y="41">#7 of 3,
|
|
16
|
+
<text class="meta" x="143" y="41">#7 of 3,352 by downloads · Sep 16, 2026</text>
|
|
17
17
|
</a>
|
|
18
18
|
</svg>
|
package/assets/badge-light.svg
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="480" height="54" viewBox="0 0 480 54" role="img" aria-label="TOP 0.3% of Pi coding agent extensions: #7 of 3,
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="480" height="54" viewBox="0 0 480 54" role="img" aria-label="TOP 0.3% of Pi coding agent extensions: #7 of 3,352 by downloads · Sep 16, 2026 (best recorded rank)">
|
|
2
2
|
<!-- Light mode -->
|
|
3
3
|
<style>
|
|
4
4
|
.frame { fill: #f6f8fa; stroke: #d0d7de; stroke-width: 1; }
|
|
@@ -13,6 +13,6 @@
|
|
|
13
13
|
<text class="rank" x="18" y="34">TOP 0.3%</text>
|
|
14
14
|
<line class="divider" x1="128" y1="13" x2="128" y2="41"/>
|
|
15
15
|
<text class="label" x="143" y="25">of Pi coding agent extensions</text>
|
|
16
|
-
<text class="meta" x="143" y="41">#7 of 3,
|
|
16
|
+
<text class="meta" x="143" y="41">#7 of 3,352 by downloads · Sep 16, 2026</text>
|
|
17
17
|
</a>
|
|
18
18
|
</svg>
|
|
@@ -370,6 +370,7 @@ export function registerGoalCommands(core: GoalCore): void {
|
|
|
370
370
|
{ key: "autoSelectSingleGoal", label: "autoSelectSingleGoal", section: "Goal behavior", kind: "boolean" },
|
|
371
371
|
{ key: "hideUnfocusedBanner", label: "hideUnfocusedBanner", section: "Goal behavior", kind: "boolean" },
|
|
372
372
|
{ key: "disableContracts", label: "disableContracts", section: "Goal behavior", kind: "boolean" },
|
|
373
|
+
{ key: "strictExecutionContract", label: "explicit execution contracts (opt-in)", section: "Goal behavior", kind: "boolean" },
|
|
373
374
|
{ key: "maxAutonomousRuns", label: "autonomous run allowance", section: "Goal behavior", kind: "positiveInteger" },
|
|
374
375
|
{ key: "stallTimeoutMinutes", label: "stall timeout (minutes)", section: "Goal behavior", kind: "positiveInteger" },
|
|
375
376
|
{ key: "objectiveMaxChars", label: "max objective length (0 = none)", section: "Goal behavior", kind: "positiveInteger" },
|
|
@@ -389,7 +390,7 @@ export function registerGoalCommands(core: GoalCore): void {
|
|
|
389
390
|
];
|
|
390
391
|
|
|
391
392
|
function settingsValue(config: GoalSettings, key: keyof GoalSettings | string): string {
|
|
392
|
-
if (key === "disabled" || key === "disableTasks" || key === "disableContracts" || key === "autoSelectSingleGoal" || key === "auditorProjectResources" || key === "hideUnfocusedBanner") {
|
|
393
|
+
if (key === "strictExecutionContract" || key === "disabled" || key === "disableTasks" || key === "disableContracts" || key === "autoSelectSingleGoal" || key === "auditorProjectResources" || key === "hideUnfocusedBanner") {
|
|
393
394
|
return config[key] === true ? "true" : "false";
|
|
394
395
|
}
|
|
395
396
|
if (key === "subtaskDepth") return config.subtaskDepth !== undefined ? String(config.subtaskDepth) : "1";
|
|
@@ -509,8 +509,8 @@ async function runGoalAgentPauseFlow(ctx: ExtensionContext, reason: string | und
|
|
|
509
509
|
pi.registerTool(defineTool({
|
|
510
510
|
name: "update_goal",
|
|
511
511
|
label: "Update Goal",
|
|
512
|
-
description: "
|
|
513
|
-
promptSnippet: "
|
|
512
|
+
description: "Update lifecycle status or optionally save continuation. New waits require strictExecutionContract opt-in. Wait: future ISO deadline; reuse wait_id/deadline without polling on recheck. Completion is audited.",
|
|
513
|
+
promptSnippet: "Complete, block, pause, or optionally save a scheduling decision.",
|
|
514
514
|
promptGuidelines: [],
|
|
515
515
|
parameters: Type.Object({
|
|
516
516
|
status: Type.Optional(StringEnum(["complete", "blocked", "paused"] as const, { description: "Exclusive with continuation." })),
|
|
@@ -23,6 +23,13 @@ export class GoalScheduler {
|
|
|
23
23
|
|
|
24
24
|
private owner(ctx: ExtensionContext): string { return ctx.sessionManager.getSessionId() || "unknown-session"; }
|
|
25
25
|
private limit(ctx: ExtensionContext): number | undefined { return loadGoalSettings(ctx.cwd).maxAutonomousRuns; }
|
|
26
|
+
private strict(ctx: ExtensionContext, s: GoalSchedulerState): boolean {
|
|
27
|
+
return loadGoalSettings(ctx.cwd).strictExecutionContract === true || !!s.wait;
|
|
28
|
+
}
|
|
29
|
+
private implicitReady(s: GoalSchedulerState): void {
|
|
30
|
+
s.phase = "ready"; s.dispatch = undefined; s.generation = randomUUID();
|
|
31
|
+
s.decision = { kind: "ready", nextAction: "Continue pursuing the goal, then verify and complete it when satisfied.", purpose: "ready" };
|
|
32
|
+
}
|
|
26
33
|
private available(ctx: ExtensionContext, s: GoalSchedulerState): boolean {
|
|
27
34
|
const limit = this.limit(ctx);
|
|
28
35
|
return limit === undefined || s.used < limit;
|
|
@@ -148,6 +155,7 @@ export class GoalScheduler {
|
|
|
148
155
|
if (typeof input.next_action !== "string" || !input.next_action.trim() || input.next_action.length > 2000) throw new Error("ready requires a nonempty next_action (at most 2000 characters).");
|
|
149
156
|
s.phase = "ready"; s.decision = { kind: "ready", nextAction: input.next_action.trim(), purpose: "ready" }; s.wait = undefined;
|
|
150
157
|
} else if (input.kind === "wait") {
|
|
158
|
+
if (!this.strict(ctx, s)) throw new Error("New waits require strictExecutionContract=true in /goal-settings. This is a user preference; continue pursuing the goal without a wait unless the user opts in.");
|
|
151
159
|
if (typeof input.reason !== "string" || !input.reason.trim() || input.reason.length > 2000) throw new Error("wait requires a nonempty reason (at most 2000 characters).");
|
|
152
160
|
const deadline = Date.parse(input.deadline);
|
|
153
161
|
if (!/T.*(?:Z|[+-]\d\d:\d\d)$/.test(input.deadline) || !Number.isSafeInteger(deadline) || deadline <= Date.now()) throw new Error("wait requires a future ISO deadline with a timezone.");
|
|
@@ -230,11 +238,16 @@ export class GoalScheduler {
|
|
|
230
238
|
settled(ctx: ExtensionContext, successful = true): void {
|
|
231
239
|
this.inRun = false;
|
|
232
240
|
if (this.denied || (this.runGoalId && this.core.state.goal?.id !== this.runGoalId)) return;
|
|
241
|
+
invalidateGoalSettingsCache();
|
|
233
242
|
this.safe(ctx, () => {
|
|
234
243
|
const goal = this.core.state.goal;
|
|
235
244
|
if (!goal || goal.status !== "active" || !goal.autoContinue || !successful) return;
|
|
236
245
|
if (this.declared && goal.scheduler?.decision) { this.schedule(ctx); return; }
|
|
237
246
|
const s = this.state(ctx, goal);
|
|
247
|
+
if (!this.strict(ctx, s)) {
|
|
248
|
+
this.update(ctx, state => this.implicitReady(state));
|
|
249
|
+
this.schedule(ctx); return;
|
|
250
|
+
}
|
|
238
251
|
if (s.repairUsed || !this.available(ctx, s)) {
|
|
239
252
|
this.pause(ctx, !this.available(ctx, s) ? this.allowanceReason(ctx) : "No execution disposition after the contract-repair prompt. Use /goal-resume to continue.");
|
|
240
253
|
return;
|
|
@@ -248,7 +261,7 @@ export class GoalScheduler {
|
|
|
248
261
|
}
|
|
249
262
|
recover(ctx: ExtensionContext): void {
|
|
250
263
|
this.safe(ctx, () => {
|
|
251
|
-
this.update(ctx, s => { s.phase = "ready"; s.dispatch = undefined; s.decision = { kind: "ready", nextAction: "Retry after the provider error, then declare an execution disposition.", purpose: "recovery" }; });
|
|
264
|
+
this.update(ctx, s => { s.phase = "ready"; s.dispatch = undefined; s.decision = { kind: "ready", nextAction: this.strict(ctx, s) ? "Retry after the provider error, then declare an execution disposition." : "Retry after the provider error and continue pursuing the goal.", purpose: "recovery" }; });
|
|
252
265
|
this.schedule(ctx);
|
|
253
266
|
});
|
|
254
267
|
}
|
|
@@ -264,11 +277,15 @@ export class GoalScheduler {
|
|
|
264
277
|
}
|
|
265
278
|
schedule(ctx: ExtensionContext): void {
|
|
266
279
|
if (this.inRun) return;
|
|
280
|
+
invalidateGoalSettingsCache();
|
|
267
281
|
this.safe(ctx, () => {
|
|
268
282
|
this.core.reconcileFocusedGoalFromDisk(ctx);
|
|
269
283
|
const g = this.core.state.goal;
|
|
270
284
|
if (!g || g.status !== "active" || !g.autoContinue || !g.scheduler) return;
|
|
271
|
-
|
|
285
|
+
let s = this.state(ctx, g);
|
|
286
|
+
if (s.phase === "ready" && s.decision?.kind === "ready" && s.decision.purpose === "repair" && !this.strict(ctx, s)) {
|
|
287
|
+
s = this.update(ctx, state => this.implicitReady(state)).scheduler!;
|
|
288
|
+
}
|
|
272
289
|
if (!["ready", "waiting"].includes(s.phase)) return;
|
|
273
290
|
if (budgetReached(g)) { this.pause(ctx, "Goal token budget exhausted."); return; }
|
|
274
291
|
if (!this.available(ctx, s)) { this.pause(ctx, this.allowanceReason(ctx)); return; }
|
|
@@ -299,6 +316,7 @@ export class GoalScheduler {
|
|
|
299
316
|
if (s.generation !== generation) throw new Error("Scheduling generation changed.");
|
|
300
317
|
if (g.status !== "active" || !g.autoContinue || budgetReached(g) || !this.available(ctx, s)) throw new Error(this.allowanceReason(ctx));
|
|
301
318
|
if (s.wait && Date.now() >= s.wait.deadline) throw new Error("Wait deadline reached.");
|
|
319
|
+
if (s.phase === "ready" && s.decision?.kind === "ready" && s.decision.purpose === "repair" && !this.strict(ctx, s)) this.implicitReady(s);
|
|
302
320
|
let kind = s.phase === "ready" && s.decision?.kind === "ready" ? s.decision.purpose : undefined;
|
|
303
321
|
if (s.phase === "waiting" && s.wait) {
|
|
304
322
|
if (s.wait.signalled) kind = "wake";
|
|
@@ -104,6 +104,7 @@ export interface GoalSettingsResolvedShape {
|
|
|
104
104
|
stallTimeoutMinutes?: number;
|
|
105
105
|
/** Optional extension-run limit per creation/resume; zero disables, absent inherits (default unlimited). */
|
|
106
106
|
maxAutonomousRuns?: number;
|
|
107
|
+
strictExecutionContract?: boolean;
|
|
107
108
|
/**
|
|
108
109
|
* Maximum objective length in characters (0/unset = no limit, the
|
|
109
110
|
* default; >0 caps objectives in create_goal, propose_goal_draft, and
|
|
@@ -331,6 +332,7 @@ const ALLOWED_SETTINGS_KEYS = new Set([
|
|
|
331
332
|
"auditorProjectResources",
|
|
332
333
|
"stallTimeoutMinutes",
|
|
333
334
|
"maxAutonomousRuns",
|
|
335
|
+
"strictExecutionContract",
|
|
334
336
|
"objectiveMaxChars",
|
|
335
337
|
"keybindings",
|
|
336
338
|
"hideUnfocusedBanner",
|
|
@@ -380,6 +382,7 @@ export function parseSettingsLayer(
|
|
|
380
382
|
|
|
381
383
|
for (const [key, value] of Object.entries(record)) {
|
|
382
384
|
switch (key) {
|
|
385
|
+
case "strictExecutionContract":
|
|
383
386
|
case "disableTasks":
|
|
384
387
|
case "disableContracts":
|
|
385
388
|
case "disabled":
|
|
@@ -790,6 +793,11 @@ function resolvedSettingsSnapshot(cwd: string, env: NodeJS.ProcessEnv): Settings
|
|
|
790
793
|
globalValue: global.layer.oracle?.maxFailedAttemptsPerBlocker,
|
|
791
794
|
defaultValue: 2,
|
|
792
795
|
}));
|
|
796
|
+
const strictExecutionContract = track("strictExecutionContract", resolveLeaf<boolean>({
|
|
797
|
+
projectValue: project.layer.strictExecutionContract,
|
|
798
|
+
globalValue: global.layer.strictExecutionContract,
|
|
799
|
+
defaultValue: false,
|
|
800
|
+
}));
|
|
793
801
|
const maxAutonomousRuns = track("maxAutonomousRuns", resolveLeaf<number | undefined>({
|
|
794
802
|
projectValue: project.layer.maxAutonomousRuns,
|
|
795
803
|
globalValue: global.layer.maxAutonomousRuns,
|
|
@@ -855,6 +863,7 @@ function resolvedSettingsSnapshot(cwd: string, env: NodeJS.ProcessEnv): Settings
|
|
|
855
863
|
hideUnfocusedBanner,
|
|
856
864
|
stallTimeoutMinutes,
|
|
857
865
|
maxAutonomousRuns,
|
|
866
|
+
strictExecutionContract,
|
|
858
867
|
objectiveMaxChars,
|
|
859
868
|
keybindings,
|
|
860
869
|
networkRecovery: {
|
|
@@ -1204,6 +1213,7 @@ function buildPersistedLayer(settings: GoalSettings): Record<string, unknown> {
|
|
|
1204
1213
|
if (so.maxFailedAttemptsPerBlocker !== undefined) o.maxFailedAttemptsPerBlocker = so.maxFailedAttemptsPerBlocker;
|
|
1205
1214
|
if (Object.keys(o).length > 0) persisted.oracle = o;
|
|
1206
1215
|
}
|
|
1216
|
+
if (settings.strictExecutionContract !== undefined) persisted.strictExecutionContract = settings.strictExecutionContract;
|
|
1207
1217
|
if (settings.maxAutonomousRuns !== undefined) persisted.maxAutonomousRuns = settings.maxAutonomousRuns;
|
|
1208
1218
|
if (settings.stallTimeoutMinutes !== undefined) persisted.stallTimeoutMinutes = settings.stallTimeoutMinutes;
|
|
1209
1219
|
if (settings.objectiveMaxChars !== undefined) persisted.objectiveMaxChars = settings.objectiveMaxChars;
|
|
@@ -1248,6 +1258,7 @@ export function effectiveSettingsReport(cwd: string, env: NodeJS.ProcessEnv = pr
|
|
|
1248
1258
|
{ key: "thinkingLevel", label: "thinking_level", format: () => snapshot.value.thinkingLevel ?? "(default)" },
|
|
1249
1259
|
{ key: "auditorProjectResources", label: "auditor project resources", format: () => String(snapshot.value.auditorProjectResources) },
|
|
1250
1260
|
{ key: "hideUnfocusedBanner", label: "hide unfocused banner", format: () => String(snapshot.value.hideUnfocusedBanner) },
|
|
1261
|
+
{ key: "strictExecutionContract", label: "explicit execution contracts (opt-in)", format: () => String(snapshot.value.strictExecutionContract) },
|
|
1251
1262
|
{ key: "maxAutonomousRuns", label: "autonomous run allowance", format: () => snapshot.value.maxAutonomousRuns === 0 ? "0 (disabled)" : String(snapshot.value.maxAutonomousRuns ?? "unlimited (default)") },
|
|
1252
1263
|
{ key: "stallTimeoutMinutes", label: "stall timeout (minutes)", format: () => String(snapshot.value.stallTimeoutMinutes) },
|
|
1253
1264
|
{ key: "objectiveMaxChars", label: "max objective length (0 = none)", format: () => String(snapshot.value.objectiveMaxChars) },
|
|
@@ -183,11 +183,12 @@ export function sisyphusDisciplineBlock(goal: GoalRecord): string {
|
|
|
183
183
|
}
|
|
184
184
|
|
|
185
185
|
/** Shared outcome/blocker policy for active goals (bounded). */
|
|
186
|
-
function lifecyclePolicyBlock(autonomous: boolean): string {
|
|
186
|
+
function lifecyclePolicyBlock(autonomous: boolean, strict: boolean): string {
|
|
187
187
|
return [
|
|
188
188
|
"[OUTCOMES]",
|
|
189
189
|
'- Automatic runs default to unlimited. maxAutonomousRuns in .pi/pi-goal-x-settings.json caps runs; 0 disables (agents may set it). Only creation or user /goal-resume renews usage.',
|
|
190
|
-
...(autonomous ? ['- End execution with update_goal: ready for runnable work, wait for an external condition, or a status below. Saved decisions terminate; further work invalidates them. Missing decisions allow one repair. Never busy-poll.'] : []),
|
|
190
|
+
...(autonomous && strict ? ['- End execution with update_goal: ready for runnable work, wait for an external condition, or a status below. Saved decisions terminate; further work invalidates them. Missing decisions allow one repair. Never busy-poll.'] : []),
|
|
191
|
+
...(autonomous && !strict ? ['- Continue pursuing the goal automatically after each execution; no scheduling declaration is required. Optional ready saves a next action. New waits require user opt-in to strictExecutionContract; do not enable it merely to continue.'] : []),
|
|
191
192
|
'- update_goal({status: "complete"}) only when every requirement is satisfied; the independent completion auditor checks actual evidence. Approval archives; rejection requires rework.',
|
|
192
193
|
'- update_goal({status: "blocked"}) only after the SAME blocker recurs on three consecutive goal turns; keep trying concrete steps before then.',
|
|
193
194
|
'- update_goal({status: "paused", reason: "…"}) pauses immediately. User controls: /goal-pause, /goal-resume, /goal-clear.',
|
|
@@ -207,7 +208,7 @@ let promptCacheChars = 0;
|
|
|
207
208
|
function cachedPrompt(goal: GoalRecord, settings: GoalSettings | undefined, kind: "goal" | "continuation", build: () => string): string {
|
|
208
209
|
const key = [kind, goal.id, goal.status, goal.autoContinue, goal.sisyphus, goal.objective,
|
|
209
210
|
goal.verificationContract, settings?.disableTasks ? undefined : taskIndex(goal.taskList?.tasks),
|
|
210
|
-
goal.taskList?.blockCompletion, promptProfile(), goal.currentTaskId, settings?.disableTasks, settings?.disableContracts, settings?.maxAutonomousRuns !== 0];
|
|
211
|
+
goal.taskList?.blockCompletion, promptProfile(), goal.currentTaskId, settings?.disableTasks, settings?.disableContracts, settings?.maxAutonomousRuns !== 0, settings?.strictExecutionContract === true, !!goal.scheduler?.wait];
|
|
211
212
|
for (let i = promptFragmentCache.length - 1; i >= 0; i--) {
|
|
212
213
|
const entry = promptFragmentCache[i]!;
|
|
213
214
|
if (key.every((part, j) => part === entry.key[j])) return entry.value;
|
|
@@ -238,7 +239,7 @@ function buildGoalPrompt(goal: GoalRecord, settings?: GoalSettings): string {
|
|
|
238
239
|
// Bound individual data fields so essential rules can never be sliced off.
|
|
239
240
|
return [
|
|
240
241
|
`[PI GOAL ACTIVE goalId=${goal.id}]`,
|
|
241
|
-
lifecyclePolicyBlock(settings?.maxAutonomousRuns !== 0), sisyphusDisciplineBlock(goal),
|
|
242
|
+
lifecyclePolicyBlock(settings?.maxAutonomousRuns !== 0, settings?.strictExecutionContract === true || !!goal.scheduler?.wait), sisyphusDisciplineBlock(goal),
|
|
242
243
|
`Status: ${statusLabel(goal)}\nMode: ${goal.sisyphus ? "sisyphus" : "regular"}`,
|
|
243
244
|
untrustedObjectiveBlock(goal), taskListBlock(goal, settings), verificationContractBlock(goal, settings),
|
|
244
245
|
].filter(Boolean).join("\n\n");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-goal-x",
|
|
3
|
-
"version": "0.31.
|
|
3
|
+
"version": "0.31.5",
|
|
4
4
|
"description": "Adds /goal to pi: conversational goal planning, flexible or ordered goals, persistent progress, and an independent completion auditor.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "pi-goal-x contributors",
|