fix(chat): preserve Gemini CLI history sessions on reopen

When reopening a Gemini CLI history session, session/load fails with
"Authentication required" and the fallback session/new overwrites the
DB external_id with a new session ID that has no corresponding file,
causing all historical messages to disappear.

- Skip session/new when session/load returns "Authentication required"
- Add Gemini to the parser fallback so stale external_ids recover via
  folder_path + started_at matching
- Guard externalIdSavedRef for existing conversations to prevent
  session/new from overwriting the persisted external_id
- Only update conversation status on disconnect when user has sent a
  message, avoiding spurious "completed" flips on pure history views

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
xintaofei
2026-04-10 22:32:56 +08:00
parent 3dfa913584
commit e4eb7f67eb
3 changed files with 21 additions and 7 deletions

View File

@@ -225,7 +225,9 @@ const ConversationTabView = memo(function ConversationTabView({
// resolves, we can't update the DB status yet. This ref records the
// desired status so the createConversation callback can apply it.
const deferredStatusRef = useRef<string | null>(null)
const externalIdSavedRef = useRef(false)
// For existing conversations (opened from sidebar), the external_id is
// already persisted — don't let a session/new fallback overwrite it.
const externalIdSavedRef = useRef(conversationId != null)
const sessionIdRef = useRef<string | null>(null)
const syncCancelRef = useRef<(() => void) | null>(null)
@@ -477,6 +479,11 @@ const ConversationTabView = memo(function ConversationTabView({
if (statusUpdatedRef.current) return
const persistedId = dbConvIdRef.current
if (!persistedId) return
// Only update status if the user actually interacted in this session.
// A pure history view (opened from sidebar, no messages sent) should
// not flip the conversation to "completed" just because the ACP
// connection disconnected (e.g. agent auth expired).
if (!hasSentMessage) return
if (connStatus === "disconnected") {
statusUpdatedRef.current = true
updateConversationLocal(persistedId, { status: "completed" })
@@ -490,7 +497,7 @@ const ConversationTabView = memo(function ConversationTabView({
console.error("[ConversationTabView] update status:", e)
)
}
}, [connStatus, updateConversationLocal])
}, [connStatus, hasSentMessage, updateConversationLocal])
useEffect(() => {
if (dbConversationId == null) return