fix(coding-agent): sync agent state after newSession setup callback

Move setup callback handling from interactive/rpc modes into AgentSession.newSession().
After setup() runs, sync agent state via replaceMessages() so the LLM has context
and the UI renders the messages properly.

fixes #968
This commit is contained in:
Mario Zechner 2026-01-26 22:25:09 +01:00
parent 0134a2a73d
commit f86e3c3103
4 changed files with 25 additions and 15 deletions

View file

@ -65,7 +65,7 @@ import type { BashExecutionMessage, CustomMessage } from "./messages.js";
import type { ModelRegistry } from "./model-registry.js";
import { expandPromptTemplate, type PromptTemplate } from "./prompt-templates.js";
import type { ResourceLoader } from "./resource-loader.js";
import type { BranchSummaryEntry, CompactionEntry, NewSessionOptions, SessionManager } from "./session-manager.js";
import type { BranchSummaryEntry, CompactionEntry, SessionManager } from "./session-manager.js";
import type { SettingsManager } from "./settings-manager.js";
import { buildSystemPrompt } from "./system-prompt.js";
import type { BashOperations } from "./tools/bash.js";
@ -1049,10 +1049,14 @@ export class AgentSession {
* Start a new session, optionally with initial messages and parent tracking.
* Clears all messages and starts a new session.
* Listeners are preserved and will continue receiving events.
* @param options - Optional initial messages and parent session path
* @param options.parentSession - Optional parent session path for tracking
* @param options.setup - Optional callback to initialize session (e.g., append messages)
* @returns true if completed, false if cancelled by extension
*/
async newSession(options?: NewSessionOptions): Promise<boolean> {
async newSession(options?: {
parentSession?: string;
setup?: (sessionManager: SessionManager) => Promise<void>;
}): Promise<boolean> {
const previousSessionFile = this.sessionFile;
// Emit session_before_switch event with reason "new" (can be cancelled)
@ -1070,11 +1074,20 @@ export class AgentSession {
this._disconnectFromAgent();
await this.abort();
this.agent.reset();
this.sessionManager.newSession(options);
this.sessionManager.newSession({ parentSession: options?.parentSession });
this.agent.sessionId = this.sessionManager.getSessionId();
this._steeringMessages = [];
this._followUpMessages = [];
this._pendingNextTurnMessages = [];
// Run setup callback if provided (e.g., to append initial messages)
if (options?.setup) {
await options.setup(this.sessionManager);
// Sync agent state with session manager after setup
const sessionContext = this.sessionManager.buildSessionContext();
this.agent.replaceMessages(sessionContext.messages);
}
this._reconnectToAgent();
// Emit session_switch event with reason "new" to extensions