@oh-my-pi/pi-coding-agent 16.0.8 → 16.0.9
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 +10 -0
- package/dist/cli.js +2925 -2847
- package/dist/types/cli/args.d.ts +1 -0
- package/dist/types/commands/launch.d.ts +3 -0
- package/dist/types/goals/runtime.d.ts +4 -1
- package/dist/types/modes/print-mode.d.ts +2 -0
- package/package.json +12 -12
- package/src/cli/args.ts +3 -0
- package/src/cli/flag-tables.ts +1 -0
- package/src/commands/launch.ts +3 -0
- package/src/goals/runtime.ts +19 -7
- package/src/main.ts +8 -0
- package/src/modes/interactive-mode.ts +7 -3
- package/src/modes/print-mode.ts +5 -1
- package/src/prompts/advisor/advise-tool.md +3 -1
- package/src/prompts/advisor/system.md +55 -12
- package/src/session/agent-session.ts +10 -2
package/dist/types/cli/args.d.ts
CHANGED
|
@@ -127,6 +127,9 @@ export default class Index extends Command {
|
|
|
127
127
|
"no-title": import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"boolean"> & {
|
|
128
128
|
description: string;
|
|
129
129
|
};
|
|
130
|
+
"print-thoughts": import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"boolean"> & {
|
|
131
|
+
description: string;
|
|
132
|
+
};
|
|
130
133
|
"max-time": import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"string"> & {
|
|
131
134
|
description: string;
|
|
132
135
|
};
|
|
@@ -36,6 +36,7 @@ export declare class GoalRuntime {
|
|
|
36
36
|
#private;
|
|
37
37
|
constructor(host: GoalRuntimeHost);
|
|
38
38
|
get snapshot(): GoalRuntimeSnapshot;
|
|
39
|
+
clearAccounting(): void;
|
|
39
40
|
onTurnStart(turnId: string, baselineUsage: GoalTokenUsage): void;
|
|
40
41
|
onToolCompleted(toolName: string): Promise<void>;
|
|
41
42
|
onGoalToolCompleted(): Promise<void>;
|
|
@@ -46,7 +47,9 @@ export declare class GoalRuntime {
|
|
|
46
47
|
onTaskAborted(options?: {
|
|
47
48
|
reason?: "interrupted" | "internal";
|
|
48
49
|
}): Promise<void>;
|
|
49
|
-
onThreadResumed(
|
|
50
|
+
onThreadResumed(options?: {
|
|
51
|
+
preserveActiveGoal?: boolean;
|
|
52
|
+
}): Promise<GoalModeState | undefined>;
|
|
50
53
|
onBudgetMutated(newBudget: number | undefined): Promise<GoalModeState | undefined>;
|
|
51
54
|
flushUsage(steering: GoalBudgetSteering, currentUsage?: GoalTokenUsage): Promise<void>;
|
|
52
55
|
createGoal(input: {
|
|
@@ -19,6 +19,8 @@ export interface PrintModeOptions {
|
|
|
19
19
|
initialMessage?: string;
|
|
20
20
|
/** Images to attach to the initial message */
|
|
21
21
|
initialImages?: ImageContent[];
|
|
22
|
+
/** If true, include thinking blocks in text output */
|
|
23
|
+
printThoughts?: boolean;
|
|
22
24
|
}
|
|
23
25
|
/**
|
|
24
26
|
* Run in print (single-shot) mode.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-coding-agent",
|
|
4
|
-
"version": "16.0.
|
|
4
|
+
"version": "16.0.9",
|
|
5
5
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -48,17 +48,17 @@
|
|
|
48
48
|
"@agentclientprotocol/sdk": "0.25.0",
|
|
49
49
|
"@babel/parser": "^7.29.7",
|
|
50
50
|
"@mozilla/readability": "^0.6.0",
|
|
51
|
-
"@oh-my-pi/hashline": "16.0.
|
|
52
|
-
"@oh-my-pi/omp-stats": "16.0.
|
|
53
|
-
"@oh-my-pi/pi-agent-core": "16.0.
|
|
54
|
-
"@oh-my-pi/pi-ai": "16.0.
|
|
55
|
-
"@oh-my-pi/pi-catalog": "16.0.
|
|
56
|
-
"@oh-my-pi/pi-mnemopi": "16.0.
|
|
57
|
-
"@oh-my-pi/pi-natives": "16.0.
|
|
58
|
-
"@oh-my-pi/pi-tui": "16.0.
|
|
59
|
-
"@oh-my-pi/pi-utils": "16.0.
|
|
60
|
-
"@oh-my-pi/pi-wire": "16.0.
|
|
61
|
-
"@oh-my-pi/snapcompact": "16.0.
|
|
51
|
+
"@oh-my-pi/hashline": "16.0.9",
|
|
52
|
+
"@oh-my-pi/omp-stats": "16.0.9",
|
|
53
|
+
"@oh-my-pi/pi-agent-core": "16.0.9",
|
|
54
|
+
"@oh-my-pi/pi-ai": "16.0.9",
|
|
55
|
+
"@oh-my-pi/pi-catalog": "16.0.9",
|
|
56
|
+
"@oh-my-pi/pi-mnemopi": "16.0.9",
|
|
57
|
+
"@oh-my-pi/pi-natives": "16.0.9",
|
|
58
|
+
"@oh-my-pi/pi-tui": "16.0.9",
|
|
59
|
+
"@oh-my-pi/pi-utils": "16.0.9",
|
|
60
|
+
"@oh-my-pi/pi-wire": "16.0.9",
|
|
61
|
+
"@oh-my-pi/snapcompact": "16.0.9",
|
|
62
62
|
"@opentelemetry/api": "^1.9.1",
|
|
63
63
|
"@opentelemetry/context-async-hooks": "^2.7.1",
|
|
64
64
|
"@opentelemetry/exporter-trace-otlp-proto": "^0.218.0",
|
package/src/cli/args.ts
CHANGED
|
@@ -56,6 +56,7 @@ export interface Args {
|
|
|
56
56
|
noExtensions?: boolean;
|
|
57
57
|
pluginDirs?: string[];
|
|
58
58
|
print?: boolean;
|
|
59
|
+
printThoughts?: boolean;
|
|
59
60
|
export?: string;
|
|
60
61
|
noSkills?: boolean;
|
|
61
62
|
skills?: string[];
|
|
@@ -200,6 +201,8 @@ export function parseArgs(inputArgs: string[], extensionFlags?: Map<string, { ty
|
|
|
200
201
|
result.advisor = true;
|
|
201
202
|
} else if (arg === "--print" || arg === "-p") {
|
|
202
203
|
result.print = true;
|
|
204
|
+
} else if (arg === "--print-thoughts") {
|
|
205
|
+
result.printThoughts = true;
|
|
203
206
|
} else if (arg === "--no-extensions") {
|
|
204
207
|
result.noExtensions = true;
|
|
205
208
|
} else if (arg === "--no-skills") {
|
package/src/cli/flag-tables.ts
CHANGED
package/src/commands/launch.ts
CHANGED
|
@@ -136,6 +136,9 @@ export default class Index extends Command {
|
|
|
136
136
|
"no-title": Flags.boolean({
|
|
137
137
|
description: "Disable title auto-generation",
|
|
138
138
|
}),
|
|
139
|
+
"print-thoughts": Flags.boolean({
|
|
140
|
+
description: "Include thinking blocks in print mode text output",
|
|
141
|
+
}),
|
|
139
142
|
"max-time": Flags.string({
|
|
140
143
|
description: "Stop the session after this many seconds",
|
|
141
144
|
}),
|
package/src/goals/runtime.ts
CHANGED
|
@@ -178,8 +178,8 @@ export class GoalRuntime {
|
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
-
#markActiveAccounting(goal: Goal): void {
|
|
182
|
-
if (this.#wallClock.activeGoalId !== goal.id) {
|
|
181
|
+
#markActiveAccounting(goal: Goal, resetWallClock = false): void {
|
|
182
|
+
if (resetWallClock || this.#wallClock.activeGoalId !== goal.id) {
|
|
183
183
|
this.#wallClock = { lastAccountedAt: this.#now(), activeGoalId: goal.id };
|
|
184
184
|
}
|
|
185
185
|
if (this.#turnSnapshot) {
|
|
@@ -195,6 +195,12 @@ export class GoalRuntime {
|
|
|
195
195
|
}
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
+
clearAccounting(): void {
|
|
199
|
+
this.#turnSnapshot = undefined;
|
|
200
|
+
this.#clearActiveAccounting();
|
|
201
|
+
this.#budgetReportedFor = undefined;
|
|
202
|
+
}
|
|
203
|
+
|
|
198
204
|
onTurnStart(turnId: string, baselineUsage: GoalTokenUsage): void {
|
|
199
205
|
this.#turnSnapshot = { turnId, baselineUsage: { ...baselineUsage } };
|
|
200
206
|
const state = this.#host.getState();
|
|
@@ -235,7 +241,7 @@ export class GoalRuntime {
|
|
|
235
241
|
return;
|
|
236
242
|
}
|
|
237
243
|
await this.#withAccounting(async () => {
|
|
238
|
-
await this.#flushUsageLocked("suppressed");
|
|
244
|
+
await this.#flushUsageLocked("suppressed", undefined, options?.reason === "internal");
|
|
239
245
|
this.#turnSnapshot = undefined;
|
|
240
246
|
if (options?.reason !== "interrupted") return;
|
|
241
247
|
const cloned = this.#getStateClone();
|
|
@@ -249,9 +255,14 @@ export class GoalRuntime {
|
|
|
249
255
|
});
|
|
250
256
|
}
|
|
251
257
|
|
|
252
|
-
async onThreadResumed(): Promise<GoalModeState | undefined> {
|
|
258
|
+
async onThreadResumed(options?: { preserveActiveGoal?: boolean }): Promise<GoalModeState | undefined> {
|
|
253
259
|
const state = this.#getStateClone();
|
|
254
260
|
if (!state) return undefined;
|
|
261
|
+
if (options?.preserveActiveGoal && state.enabled && state.goal.status === "active") {
|
|
262
|
+
this.#markActiveAccounting(state.goal, true);
|
|
263
|
+
await this.#commitState(state, { emit: true });
|
|
264
|
+
return state;
|
|
265
|
+
}
|
|
255
266
|
if (state.goal.status === "active") {
|
|
256
267
|
state.enabled = false;
|
|
257
268
|
state.goal.status = "paused";
|
|
@@ -301,6 +312,7 @@ export class GoalRuntime {
|
|
|
301
312
|
async #flushUsageLocked(
|
|
302
313
|
steering: GoalBudgetSteering,
|
|
303
314
|
currentUsage: GoalTokenUsage = this.#host.getCurrentUsage(),
|
|
315
|
+
persistWallClock = false,
|
|
304
316
|
): Promise<void> {
|
|
305
317
|
const state = this.#getStateClone();
|
|
306
318
|
if (!state?.enabled || !isAccountingStatus(state.goal)) return;
|
|
@@ -333,10 +345,10 @@ export class GoalRuntime {
|
|
|
333
345
|
if (this.#wallClock.activeGoalId === state.goal.id && wallSeconds > 0) {
|
|
334
346
|
this.#wallClock.lastAccountedAt += wallSeconds * 1000;
|
|
335
347
|
}
|
|
336
|
-
|
|
337
348
|
// Persisting wall-clock-only accounting on every tool event bloats /goal sessions with full
|
|
338
|
-
// objective snapshots. Keep
|
|
339
|
-
|
|
349
|
+
// objective snapshots. Keep normal tool flushes in memory/UI only, but make wall-clock
|
|
350
|
+
// usage durable before internal session switches because the active runtime is leaving.
|
|
351
|
+
const shouldPersistUsage = tokenDelta > 0 || flippedToBudgetLimited || (persistWallClock && wallSeconds > 0);
|
|
340
352
|
await this.#commitState(state, { persist: shouldPersistUsage ? "goal" : undefined });
|
|
341
353
|
|
|
342
354
|
if (state.goal.status !== "budget-limited") {
|
package/src/main.ts
CHANGED
|
@@ -1039,6 +1039,13 @@ export async function runRootCommand(
|
|
|
1039
1039
|
});
|
|
1040
1040
|
}
|
|
1041
1041
|
|
|
1042
|
+
// --print-thoughts (single-shot print mode) must surface reasoning, so un-hide
|
|
1043
|
+
// thinking before the session is built — otherwise a passive hideThinkingBlock
|
|
1044
|
+
// setting makes the provider omit summaries and the flag prints nothing. An
|
|
1045
|
+
// explicit --hide-thinking below still wins.
|
|
1046
|
+
if (parsedArgs.printThoughts && !isProtocolMode && !isInteractive) {
|
|
1047
|
+
settingsInstance.override("hideThinkingBlock", false);
|
|
1048
|
+
}
|
|
1042
1049
|
// Apply --hide-thinking CLI flag (ephemeral, not persisted)
|
|
1043
1050
|
if (parsedArgs.hideThinking) {
|
|
1044
1051
|
settingsInstance.override("hideThinkingBlock", true);
|
|
@@ -1373,6 +1380,7 @@ export async function runRootCommand(
|
|
|
1373
1380
|
messages: initialArgs.messages,
|
|
1374
1381
|
initialMessage,
|
|
1375
1382
|
initialImages,
|
|
1383
|
+
printThoughts: initialArgs.printThoughts,
|
|
1376
1384
|
});
|
|
1377
1385
|
if ($env.PI_TIMING) {
|
|
1378
1386
|
logger.printTimings();
|
|
@@ -797,7 +797,7 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
797
797
|
await this.initHooksAndCustomTools();
|
|
798
798
|
|
|
799
799
|
// Restore mode from session (e.g. plan mode on resume)
|
|
800
|
-
this.session.setSessionSwitchReconciler?.(() => this.#reconcileModeFromSession());
|
|
800
|
+
this.session.setSessionSwitchReconciler?.(() => this.#reconcileModeFromSession({ preserveActiveGoal: true }));
|
|
801
801
|
await this.#reconcileModeFromSession();
|
|
802
802
|
|
|
803
803
|
// Brand-new sessions optionally start in plan mode when the user has made it
|
|
@@ -1783,11 +1783,12 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
1783
1783
|
}
|
|
1784
1784
|
|
|
1785
1785
|
/** Reconcile mode state from session entries on resume/switch. */
|
|
1786
|
-
async #reconcileModeFromSession(): Promise<void> {
|
|
1786
|
+
async #reconcileModeFromSession(options?: { preserveActiveGoal?: boolean }): Promise<void> {
|
|
1787
1787
|
await this.#clearTransientModeState();
|
|
1788
1788
|
const sessionContext = this.sessionManager.buildSessionContext();
|
|
1789
1789
|
const goalEnabled = this.session.settings.get("goal.enabled");
|
|
1790
1790
|
if (!goalEnabled && (sessionContext.mode === "goal" || sessionContext.mode === "goal_paused")) {
|
|
1791
|
+
this.session.goalRuntime.clearAccounting();
|
|
1791
1792
|
this.sessionManager.appendModeChange("none");
|
|
1792
1793
|
return;
|
|
1793
1794
|
}
|
|
@@ -1802,7 +1803,9 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
1802
1803
|
mode: "active",
|
|
1803
1804
|
goal,
|
|
1804
1805
|
});
|
|
1805
|
-
const restored = await this.session.goalRuntime.onThreadResumed(
|
|
1806
|
+
const restored = await this.session.goalRuntime.onThreadResumed({
|
|
1807
|
+
preserveActiveGoal: options?.preserveActiveGoal,
|
|
1808
|
+
});
|
|
1806
1809
|
this.goalModeEnabled = restored?.enabled === true;
|
|
1807
1810
|
this.goalModePaused = restored?.enabled !== true && restored?.goal.status === "paused";
|
|
1808
1811
|
// sdk.ts excludes "goal" from the initial active tool set unconditionally.
|
|
@@ -1815,6 +1818,7 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
1815
1818
|
this.#updateGoalModeStatus();
|
|
1816
1819
|
return;
|
|
1817
1820
|
}
|
|
1821
|
+
this.session.goalRuntime.clearAccounting();
|
|
1818
1822
|
if (!this.session.settings.get("plan.enabled")) {
|
|
1819
1823
|
// Clear stale plan/plan_paused mode so re-enabling the setting
|
|
1820
1824
|
// later doesn't unexpectedly restore an old plan session.
|
package/src/modes/print-mode.ts
CHANGED
|
@@ -24,6 +24,8 @@ export interface PrintModeOptions {
|
|
|
24
24
|
initialMessage?: string;
|
|
25
25
|
/** Images to attach to the initial message */
|
|
26
26
|
initialImages?: ImageContent[];
|
|
27
|
+
/** If true, include thinking blocks in text output */
|
|
28
|
+
printThoughts?: boolean;
|
|
27
29
|
}
|
|
28
30
|
|
|
29
31
|
/**
|
|
@@ -31,7 +33,7 @@ export interface PrintModeOptions {
|
|
|
31
33
|
* Sends prompts to the agent and outputs the result.
|
|
32
34
|
*/
|
|
33
35
|
export async function runPrintMode(session: AgentSession, options: PrintModeOptions): Promise<void> {
|
|
34
|
-
const { mode, messages = [], initialMessage, initialImages } = options;
|
|
36
|
+
const { mode, messages = [], initialMessage, initialImages, printThoughts } = options;
|
|
35
37
|
|
|
36
38
|
// Emit session header for JSON mode
|
|
37
39
|
if (mode === "json") {
|
|
@@ -108,6 +110,8 @@ export async function runPrintMode(session: AgentSession, options: PrintModeOpti
|
|
|
108
110
|
for (const content of assistantMsg.content) {
|
|
109
111
|
if (content.type === "text") {
|
|
110
112
|
process.stdout.write(`${sanitizeText(content.text)}\n`);
|
|
113
|
+
} else if (printThoughts && content.type === "thinking" && content.thinking.trim().length > 0) {
|
|
114
|
+
process.stdout.write(`${sanitizeText(content.thinking)}\n`);
|
|
111
115
|
}
|
|
112
116
|
}
|
|
113
117
|
}
|
|
@@ -1 +1,3 @@
|
|
|
1
|
-
Send one concrete, terse piece of advice to the agent you are watching.
|
|
1
|
+
Send one concrete, terse piece of advice to the agent you are watching.
|
|
2
|
+
- Use sparingly; stay silent when nothing matters.
|
|
3
|
+
- Call it to head off likely-wrong or materially wasteful work.
|
|
@@ -1,32 +1,75 @@
|
|
|
1
1
|
<system-conventions>
|
|
2
2
|
RFC 2119 applies to MUST, REQUIRED, SHOULD, RECOMMENDED, MAY, OPTIONAL. `NEVER` and `AVOID` are aliases for `MUST NOT` and `SHOULD NOT`.
|
|
3
|
-
You can explore the workspace; budget is 2–3 tool calls per advise (exception: critical bugs warrant deeper verification before raising a blocker).
|
|
4
3
|
</system-conventions>
|
|
5
4
|
|
|
6
|
-
You bring a different angle.
|
|
7
|
-
|
|
5
|
+
You bring a different angle, and advocate for the user and the code-quality & robustness.
|
|
6
|
+
You're watching over the main agent as a peer-programmer:
|
|
7
|
+
- They might not have thought about an edge case, or realized a more elegant approach exists.
|
|
8
|
+
- They might be sinking deeper into a hole that will not get the user's request accomplished.
|
|
9
|
+
|
|
8
10
|
Your job is to offer that view before they sink work into the wrong direction.
|
|
9
11
|
|
|
10
12
|
<workflow>
|
|
11
|
-
You receive the agent's transcript incrementally, including
|
|
13
|
+
You receive the agent's transcript incrementally, including their thoughts.
|
|
12
14
|
You have read-only access through `read`, `search`, `find` to verify your suspicions.
|
|
13
|
-
Keep exploration lean
|
|
15
|
+
Keep exploration lean:
|
|
16
|
+
- 2–3 tool calls per advise.
|
|
17
|
+
- Exception: critical bugs may need deeper verification before raising a blocker.
|
|
14
18
|
</workflow>
|
|
15
19
|
|
|
16
20
|
<communication>
|
|
17
|
-
|
|
18
|
-
|
|
21
|
+
- You call `advise` to surface your commentary to the driving agent; at most one `advise` per update.
|
|
22
|
+
- Prefer silence when the agent is on track.
|
|
23
|
+
- Address the agent directly.
|
|
24
|
+
- Offer alternatives, not lectures.
|
|
25
|
+
- NEVER restate information the agent already has, including errors they have seen.
|
|
26
|
+
- Examples: type errors, LSP diagnostics, failed builds, failing tests, lint.
|
|
27
|
+
- NEVER repeat advice you already gave.
|
|
28
|
+
- NEVER nitpick about things user stated they are okay with. You are the advocate for the user.
|
|
19
29
|
</communication>
|
|
20
30
|
|
|
21
31
|
<critical>
|
|
22
|
-
|
|
32
|
+
A low-confidence bar applies ONLY to concrete technical risk:
|
|
33
|
+
- Generic uncertainty, vague unease, or user-intent ambiguity → stay SILENT.
|
|
34
|
+
|
|
23
35
|
NEVER advise just to second-guess decisions the agent understands and is committed to, if you are not certain.
|
|
36
|
+
|
|
37
|
+
NEVER advise on intent or process:
|
|
38
|
+
- Do not push the agent to ask for clarification, confirm scope, or summarize input before acting.
|
|
39
|
+
- Do not question whether the user's ask is clear enough.
|
|
40
|
+
- Intent is the agent's domain; it defaults to informed action.
|
|
41
|
+
- Your lane: correctness, edge cases, design, process.
|
|
42
|
+
|
|
43
|
+
Cite the exact instruction or risk.
|
|
24
44
|
</critical>
|
|
25
45
|
|
|
26
46
|
<completeness>
|
|
27
|
-
**`nit`**
|
|
28
|
-
|
|
29
|
-
|
|
47
|
+
**`nit`**
|
|
48
|
+
- Non-urgent cleanup, refactor, style, missed opportunity.
|
|
49
|
+
- Folded at next step boundary; agent keeps working.
|
|
50
|
+
- Examples:
|
|
51
|
+
- Edge cases that don't break correctness.
|
|
52
|
+
- Simplifications.
|
|
53
|
+
- Better approach the agent can consider.
|
|
54
|
+
|
|
55
|
+
**`concern`**
|
|
56
|
+
- Agent might be heading wrong or missed something material.
|
|
57
|
+
- Offers your view; agent decides.
|
|
58
|
+
- Use when:
|
|
59
|
+
- Exploring wrong code path.
|
|
60
|
+
- Picking fragile approach when better exists.
|
|
61
|
+
- Not parallelizing when user request is obviously parallelizable.
|
|
62
|
+
- Missing constraint.
|
|
63
|
+
- Edge case about to be baked in.
|
|
64
|
+
|
|
65
|
+
**`blocker`**
|
|
66
|
+
- Stop and reconsider.
|
|
67
|
+
- Use ONLY when the agent making progress will clearly:
|
|
68
|
+
- Waste the users time with a larger refactor.
|
|
69
|
+
- Will require the user to interrupt the agent later on, due to them going in circles without a solution.
|
|
70
|
+
- Be fundamentally unsound.
|
|
71
|
+
- Verify thoroughly before raising.
|
|
30
72
|
</completeness>
|
|
31
73
|
|
|
32
|
-
You MAY suggest an approach or fix if you've explored enough to be confident.
|
|
74
|
+
You MAY suggest an approach or fix if you've explored enough to be confident.
|
|
75
|
+
Offer the better designs, not just the warning.
|
|
@@ -7375,7 +7375,7 @@ export class AgentSession {
|
|
|
7375
7375
|
throw new Error("Compaction already in progress");
|
|
7376
7376
|
}
|
|
7377
7377
|
this.#disconnectFromAgent();
|
|
7378
|
-
await this.abort();
|
|
7378
|
+
await this.abort({ goalReason: "internal" });
|
|
7379
7379
|
const compactionAbortController = new AbortController();
|
|
7380
7380
|
this.#compactionAbortController = compactionAbortController;
|
|
7381
7381
|
|
|
@@ -7543,6 +7543,10 @@ export class AgentSession {
|
|
|
7543
7543
|
const newEntries = this.sessionManager.getEntries();
|
|
7544
7544
|
const sessionContext = this.buildDisplaySessionContext();
|
|
7545
7545
|
this.agent.replaceMessages(sessionContext.messages);
|
|
7546
|
+
// Compaction discarded the conversation history that carried the approved
|
|
7547
|
+
// plan reference. Clear the sent-flag so #buildPlanReferenceMessage re-reads
|
|
7548
|
+
// the plan from disk and re-injects it on the next turn (issue #1246).
|
|
7549
|
+
this.#planReferenceSent = false;
|
|
7546
7550
|
this.#advisorRuntime?.reset();
|
|
7547
7551
|
this.#syncTodoPhasesFromBranch();
|
|
7548
7552
|
this.#closeCodexProviderSessionsForHistoryRewrite();
|
|
@@ -9409,6 +9413,10 @@ export class AgentSession {
|
|
|
9409
9413
|
const newEntries = this.sessionManager.getEntries();
|
|
9410
9414
|
const sessionContext = this.buildDisplaySessionContext();
|
|
9411
9415
|
this.agent.replaceMessages(sessionContext.messages);
|
|
9416
|
+
// Compaction discarded the conversation history that carried the approved
|
|
9417
|
+
// plan reference. Clear the sent-flag so #buildPlanReferenceMessage re-reads
|
|
9418
|
+
// the plan from disk and re-injects it on the next turn (issue #1246).
|
|
9419
|
+
this.#planReferenceSent = false;
|
|
9412
9420
|
this.#advisorRuntime?.reset();
|
|
9413
9421
|
this.#syncTodoPhasesFromBranch();
|
|
9414
9422
|
this.#closeCodexProviderSessionsForHistoryRewrite();
|
|
@@ -10960,7 +10968,7 @@ export class AgentSession {
|
|
|
10960
10968
|
}
|
|
10961
10969
|
|
|
10962
10970
|
this.#disconnectFromAgent();
|
|
10963
|
-
await this.abort();
|
|
10971
|
+
await this.abort({ goalReason: "internal" });
|
|
10964
10972
|
|
|
10965
10973
|
// Flush pending writes before switching so restore snapshots reflect committed state.
|
|
10966
10974
|
await this.sessionManager.flush();
|