fix(coding-agent): send resolve reminder on push

This commit is contained in:
can1357
2026-03-01 04:03:20 +01:00
parent e3caff6c06
commit 40e921284b
4 changed files with 156 additions and 16 deletions
@@ -291,6 +291,7 @@ export class AgentSession {
// Event subscription state
#unsubscribeAgent?: () => void;
#unsubscribePendingActionPush?: () => void;
#eventListeners: AgentSessionEventListener[] = [];
/** Tracks pending steering messages for UI display. Removed when delivered. */
@@ -397,6 +398,21 @@ export class AgentSession {
this.#obfuscator = config.obfuscator;
this.agent.providerSessionState = this.#providerSessionState;
this.#pendingActionStore = config.pendingActionStore;
this.#unsubscribePendingActionPush = this.#pendingActionStore?.subscribePush(action => {
const reminderText = [
"<system-reminder>",
"This is a preview. Call the `resolve` tool to apply or discard these changes.",
"</system-reminder>",
].join("\n");
this.agent.steer({
role: "custom",
customType: "resolve-reminder",
content: reminderText,
display: false,
details: { toolName: action.sourceToolName },
timestamp: Date.now(),
});
});
this.#syncTodoPhasesFromBranch();
// Always subscribe to agent events for internal handling
@@ -688,22 +704,6 @@ export class AgentSession {
{ deliverAs: "nextTurn" },
);
}
if (!isError && this.#pendingActionStore?.hasPending) {
const reminderText = [
"<system-reminder>",
"This is a preview. Call the `resolve` tool to apply or discard these changes.",
"</system-reminder>",
].join("\n");
await this.sendCustomMessage(
{
customType: "resolve-reminder",
content: reminderText,
display: false,
details: { toolName },
},
{ deliverAs: "nextTurn" },
);
}
}
}
@@ -1443,6 +1443,8 @@ export class AgentSession {
state.close();
}
this.#providerSessionState.clear();
this.#unsubscribePendingActionPush?.();
this.#unsubscribePendingActionPush = undefined;
this.#disconnectFromAgent();
this.#eventListeners = [];
}
@@ -10,9 +10,14 @@ export interface PendingAction {
export class PendingActionStore {
#actions: PendingAction[] = [];
#pushListeners = new Set<(action: PendingAction, count: number) => void>();
push(action: PendingAction): void {
this.#actions.push(action);
const count = this.#actions.length;
for (const listener of this.#pushListeners) {
listener(action, count);
}
}
peek(): PendingAction | null {
@@ -23,10 +28,21 @@ export class PendingActionStore {
return this.#actions.pop() ?? null;
}
subscribePush(listener: (action: PendingAction, count: number) => void): () => void {
this.#pushListeners.add(listener);
return () => {
this.#pushListeners.delete(listener);
};
}
clear(): void {
this.#actions = [];
}
get count(): number {
return this.#actions.length;
}
get hasPending(): boolean {
return this.#actions.length > 0;
}