fix(git): materialize draft session for generate (#1761)
* fix(git): materialize draft session for generate * fix(sync): remove redundant draft session side effects --------- Co-authored-by: Leonid Skorobogatyy <bash@opencode.itc.local>
This commit is contained in:
committed by
GitHub
co-authored by
Leonid Skorobogatyy
parent
b0e476ab7c
commit
03e6f789a4
@@ -30,6 +30,7 @@ import { markPendingUserSendAnimation } from "@/lib/userSendAnimation"
|
||||
import { flattenAssistantTextParts } from "@/lib/messages/messageText"
|
||||
import { composeForkSessionMessage } from "@/lib/messages/executionMeta"
|
||||
import { waitForPendingDraftWorktreeRequest } from "@/lib/worktrees/pendingDraftWorktree"
|
||||
import { waitForWorktreeBootstrap } from "@/lib/worktrees/worktreeBootstrap"
|
||||
import { resolveProjectForSessionDirectory } from "@/lib/projectResolution"
|
||||
import {
|
||||
getSyncSessions,
|
||||
@@ -408,6 +409,75 @@ const writeRuntimeSessionMemory = (key: string, patch: Partial<RuntimeSessionMem
|
||||
})
|
||||
}
|
||||
|
||||
type MaterializedDraftSession = {
|
||||
sessionId: string
|
||||
directory: string | null
|
||||
agent?: string
|
||||
syntheticParts?: SyntheticContextPart[]
|
||||
}
|
||||
|
||||
export async function materializeOpenDraftSession(selection: {
|
||||
providerID: string
|
||||
modelID: string
|
||||
agent?: string
|
||||
variant?: string
|
||||
}): Promise<MaterializedDraftSession | null> {
|
||||
const store = useSessionUIStore.getState()
|
||||
const draft = store.newSessionDraft
|
||||
if (!draft?.open) return null
|
||||
|
||||
const trimmedAgent = typeof selection.agent === "string" && selection.agent.trim().length > 0
|
||||
? selection.agent.trim()
|
||||
: undefined
|
||||
let draftDirectoryOverride = draft.bootstrapPendingDirectory ?? draft.directoryOverride ?? null
|
||||
const draftProjectId = draft.selectedProjectId ?? null
|
||||
|
||||
if (draft.pendingWorktreeRequestId) {
|
||||
draftDirectoryOverride = await waitForPendingDraftWorktreeRequest(draft.pendingWorktreeRequestId)
|
||||
store.resolvePendingDraftWorktreeTarget(draft.pendingWorktreeRequestId, draftDirectoryOverride)
|
||||
}
|
||||
|
||||
if (draftDirectoryOverride) {
|
||||
await waitForWorktreeBootstrap(draftDirectoryOverride)
|
||||
}
|
||||
|
||||
const created = await store.createSession(draft.title, draftDirectoryOverride, draft.parentID ?? null)
|
||||
if (!created?.id) throw new Error("Failed to create session")
|
||||
|
||||
persistDraftTarget({
|
||||
projectId: draftProjectId,
|
||||
directory: normalizePath(draftDirectoryOverride ?? created.directory ?? null),
|
||||
})
|
||||
|
||||
const draftSyntheticParts = draft.syntheticParts
|
||||
const createdDirectory = normalizePath(draftDirectoryOverride ?? created.directory ?? null)
|
||||
const configState = useConfigStore.getState()
|
||||
void activateConfigForDirectory(createdDirectory).catch((error) => {
|
||||
console.warn("Failed to activate directory after creating session:", error)
|
||||
})
|
||||
|
||||
const effectiveDraftAgent = trimmedAgent ?? configState.currentAgentName
|
||||
|
||||
useSelectionStore.getState().saveSessionModelSelection(created.id, selection.providerID, selection.modelID)
|
||||
|
||||
if (effectiveDraftAgent) {
|
||||
useSelectionStore.getState().saveSessionAgentSelection(created.id, effectiveDraftAgent)
|
||||
useSelectionStore.getState().saveAgentModelForSession(created.id, effectiveDraftAgent, selection.providerID, selection.modelID)
|
||||
useSelectionStore.getState().saveAgentModelVariantForSession(created.id, effectiveDraftAgent, selection.providerID, selection.modelID, selection.variant)
|
||||
}
|
||||
|
||||
store.initializeNewOpenChamberSession(created.id, configState.agents ?? [])
|
||||
|
||||
store.setCurrentSession(created.id, createdDirectory)
|
||||
|
||||
return {
|
||||
sessionId: created.id,
|
||||
directory: createdDirectory,
|
||||
agent: effectiveDraftAgent,
|
||||
syntheticParts: draftSyntheticParts,
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Store
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -919,59 +989,21 @@ export const useSessionUIStore = create<SessionUIState>()((set, get) => ({
|
||||
|
||||
// ---- New session from draft ----
|
||||
if (!options?.sessionId && draft?.open) {
|
||||
const draftTargetFolderId = draft.targetFolderId
|
||||
let draftDirectoryOverride = draft.bootstrapPendingDirectory ?? draft.directoryOverride ?? null
|
||||
const draftProjectId = draft.selectedProjectId ?? null
|
||||
|
||||
if (draft.pendingWorktreeRequestId) {
|
||||
draftDirectoryOverride = await waitForPendingDraftWorktreeRequest(draft.pendingWorktreeRequestId)
|
||||
get().resolvePendingDraftWorktreeTarget(draft.pendingWorktreeRequestId, draftDirectoryOverride)
|
||||
}
|
||||
|
||||
const created = await get().createSession(draft.title, draftDirectoryOverride, draft.parentID ?? null)
|
||||
if (!created?.id) throw new Error("Failed to create session")
|
||||
|
||||
persistDraftTarget({
|
||||
projectId: draftProjectId,
|
||||
directory: normalizePath(draftDirectoryOverride ?? created.directory ?? null),
|
||||
const createdDraftSession = await materializeOpenDraftSession({
|
||||
providerID,
|
||||
modelID,
|
||||
agent: trimmedAgent,
|
||||
variant,
|
||||
})
|
||||
if (!createdDraftSession) throw new Error("Failed to create session")
|
||||
|
||||
const draftSyntheticParts = draft.syntheticParts
|
||||
const createdDirectory = normalizePath(draftDirectoryOverride ?? created.directory ?? null)
|
||||
const configState = useConfigStore.getState()
|
||||
void activateConfigForDirectory(createdDirectory).catch((error) => {
|
||||
console.warn("Failed to activate directory after creating session:", error)
|
||||
})
|
||||
|
||||
const effectiveDraftAgent = trimmedAgent ?? configState.currentAgentName
|
||||
|
||||
useSelectionStore.getState().saveSessionModelSelection(created.id, providerID, modelID)
|
||||
|
||||
if (effectiveDraftAgent) {
|
||||
useSelectionStore.getState().saveSessionAgentSelection(created.id, effectiveDraftAgent)
|
||||
useSelectionStore.getState().saveAgentModelForSession(created.id, effectiveDraftAgent, providerID, modelID)
|
||||
useSelectionStore.getState().saveAgentModelVariantForSession(created.id, effectiveDraftAgent, providerID, modelID, variant)
|
||||
}
|
||||
|
||||
get().initializeNewOpenChamberSession(created.id, configState.agents ?? [])
|
||||
|
||||
get().closeNewSessionDraft()
|
||||
get().setCurrentSession(created.id, createdDirectory)
|
||||
|
||||
if (draftTargetFolderId) {
|
||||
const scopeKey = draftDirectoryOverride || created.directory || null
|
||||
if (scopeKey) {
|
||||
useSessionFoldersStore.getState().addSessionToFolder(scopeKey, draftTargetFolderId, created.id)
|
||||
}
|
||||
}
|
||||
|
||||
const mergedAdditionalParts = draftSyntheticParts?.length
|
||||
? [...(additionalParts || []), ...draftSyntheticParts]
|
||||
const mergedAdditionalParts = createdDraftSession.syntheticParts?.length
|
||||
? [...(additionalParts || []), ...createdDraftSession.syntheticParts]
|
||||
: additionalParts
|
||||
|
||||
notifyMessageSent(created.id)
|
||||
notifyMessageSent(createdDraftSession.sessionId)
|
||||
|
||||
markPendingUserSendAnimation(created.id)
|
||||
markPendingUserSendAnimation(createdDraftSession.sessionId)
|
||||
|
||||
const files = attachments?.map((a) => ({
|
||||
type: "file" as const,
|
||||
@@ -981,12 +1013,12 @@ export const useSessionUIStore = create<SessionUIState>()((set, get) => ({
|
||||
}))
|
||||
|
||||
await routeMessage({
|
||||
sessionId: created.id,
|
||||
directory: createdDirectory,
|
||||
sessionId: createdDraftSession.sessionId,
|
||||
directory: createdDraftSession.directory,
|
||||
content,
|
||||
providerID,
|
||||
modelID,
|
||||
agent: effectiveDraftAgent,
|
||||
agent: createdDraftSession.agent,
|
||||
agentMentionName,
|
||||
variant,
|
||||
inputMode,
|
||||
|
||||
Reference in New Issue
Block a user