fix(sessions): snapshot send target so a project switch cannot reroute a pending send (#2871)

Snapshot the new-session draft (and keep the existing-session target captured) at
submit time, then use that snapshot for draft materialization and routing instead
of re-reading live selection state after async preparation.

Fixes #2222
Fixes #2315
This commit is contained in:
Serhii Dziupin
2026-08-13 12:31:33 +03:00
committed by GitHub
parent 8a6eca5597
commit d3011a6247
3 changed files with 138 additions and 7 deletions
+6 -4
View File
@@ -231,6 +231,8 @@ type SendMessageOptions = {
target?: CapturedSendTarget
sessionId?: string
directory?: string
/** Immutable copy of the new-session draft at submit time; used instead of the live draft. */
draftSnapshot?: NewSessionDraftState
delivery?: 'steer'
}
@@ -609,9 +611,9 @@ export async function materializeOpenDraftSession(selection: {
modelID: string
agent?: string
variant?: string
}): Promise<MaterializedDraftSession | null> {
}, draftOverride?: NewSessionDraftState): Promise<MaterializedDraftSession | null> {
const store = useSessionUIStore.getState()
const draft = store.newSessionDraft
const draft = draftOverride ?? store.newSessionDraft
if (!draft?.open) return null
const draftPermissionAutoAcceptEnabled = draft.permissionAutoAcceptEnabled === true
@@ -1224,7 +1226,7 @@ export const useSessionUIStore = create<SessionUIState>()((set, get) => ({
set({ pendingChangesBarDismissed: map });
}
const draft = get().newSessionDraft
const draft = options?.draftSnapshot ?? get().newSessionDraft
const trimmedAgent = typeof agent === "string" && agent.trim().length > 0 ? agent.trim() : undefined
const goalArm = inputMode !== "shell" && content.trim().length > 0
@@ -1282,7 +1284,7 @@ export const useSessionUIStore = create<SessionUIState>()((set, get) => ({
modelID,
agent: trimmedAgent,
variant,
})
}, options?.draftSnapshot)
if (!createdDraftSession) throw new Error("Failed to create session")
const mergedAdditionalParts = createdDraftSession.syntheticParts?.length