import React from 'react'; import { useSessionAssistState } from '@/hooks/useSessionAssist'; import { useI18n } from '@/lib/i18n'; import { TimelineRevealGateContext } from '@/components/chat/timelineRevealGate'; interface SessionRecapNoteProps { sessionId: string; directory?: string; isMobile: boolean; } // Quiet one-paragraph recap of the agent's last reply, rendered right under // the last message (above the reserved bottom gap). Appears only after the // 1-minute quiet window, so the layout shift happens off-screen in practice. export const SessionRecapNote: React.FC = React.memo(({ sessionId, directory, isMobile }) => { const { visibleRecap, sessionKnown } = useSessionAssistState(sessionId, directory); const { t } = useI18n(); // The recap is part of the opened session's finished picture: until the // session record is in memory it cannot be decided, and appearing a commit // later would grow the footer under a viewport already pinned to the end. const revealGate = React.useContext(TimelineRevealGateContext); React.useLayoutEffect(() => { if (sessionKnown) return undefined; const release = revealGate?.hold(); return release ?? undefined; }, [revealGate, sessionKnown]); if (!visibleRecap) { return null; } return (
{/* The last assistant turn carries pb-8 — pull the recap up into that gap. */}
{t('chat.recap.label')} {visibleRecap}
); }); SessionRecapNote.displayName = 'SessionRecapNote';