fix: stabilize cockpit and assistant session handoff
This commit is contained in:
@@ -310,23 +310,34 @@ export function useAssistantSession() {
|
|||||||
// Callback for pages to handle triage updates from chat responses.
|
// Callback for pages to handle triage updates from chat responses.
|
||||||
const onTriageUpdateRef = useRef<((update: TriageUpdate) => void) | null>(null)
|
const onTriageUpdateRef = useRef<((update: TriageUpdate) => void) | null>(null)
|
||||||
|
|
||||||
const handleSend = async () => {
|
const sendMessage = useCallback(async (
|
||||||
if (!input.trim() || !activeChatId || loadingRef.current) return
|
rawMessage: string,
|
||||||
|
options?: {
|
||||||
|
uploadIds?: string[]
|
||||||
|
clearComposer?: boolean
|
||||||
|
}
|
||||||
|
) => {
|
||||||
|
const message = rawMessage.trim()
|
||||||
|
if (!message || !activeChatId || loadingRef.current) return
|
||||||
loadingRef.current = true
|
loadingRef.current = true
|
||||||
|
|
||||||
const sendChatId = activeChatId
|
const sendChatId = activeChatId
|
||||||
const userMessage = input.trim()
|
const uploadIds = options?.uploadIds
|
||||||
const completedUploadIds = pendingUploads
|
const completedUploadIds = uploadIds ?? pendingUploads
|
||||||
.filter((u) => u.status === 'done' && u.result?.id)
|
.filter((u) => u.status === 'done' && u.result?.id)
|
||||||
.map((u) => u.result!.id)
|
.map((u) => u.result!.id)
|
||||||
setInput('')
|
if (options?.clearComposer !== false) {
|
||||||
setPendingUploads([])
|
setInput('')
|
||||||
setMessages(prev => [...prev, { role: 'user', content: userMessage }])
|
if (!uploadIds) {
|
||||||
|
setPendingUploads([])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setMessages(prev => [...prev, { role: 'user', content: message }])
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await aiSessionsApi.sendChatMessage(sendChatId, {
|
const response = await aiSessionsApi.sendChatMessage(sendChatId, {
|
||||||
message: userMessage,
|
message,
|
||||||
upload_ids: completedUploadIds.length > 0 ? completedUploadIds : undefined,
|
upload_ids: completedUploadIds.length > 0 ? completedUploadIds : undefined,
|
||||||
})
|
})
|
||||||
if (currentChatRef.current !== sendChatId) return
|
if (currentChatRef.current !== sendChatId) return
|
||||||
@@ -335,7 +346,7 @@ export function useAssistantSession() {
|
|||||||
setChats(prev =>
|
setChats(prev =>
|
||||||
prev.map(c =>
|
prev.map(c =>
|
||||||
c.id === sendChatId
|
c.id === sendChatId
|
||||||
? { ...c, message_count: c.message_count + 2, title: c.message_count === 0 ? userMessage.slice(0, 100) : c.title, updated_at: new Date().toISOString() }
|
? { ...c, message_count: c.message_count + 2, title: c.message_count === 0 ? message.slice(0, 100) : c.title, updated_at: new Date().toISOString() }
|
||||||
: c
|
: c
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -353,12 +364,17 @@ export function useAssistantSession() {
|
|||||||
requestAnimationFrame(() => inputRef.current?.focus())
|
requestAnimationFrame(() => inputRef.current?.focus())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}, [activeChatId, pendingUploads, processResponse])
|
||||||
|
|
||||||
|
const handleSend = async () => {
|
||||||
|
await sendMessage(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle prefill from command palette / dashboard handoff
|
// Handle prefill from command palette / dashboard handoff
|
||||||
const handlePrefill = useCallback((_prefillRoute: string) => {
|
const handlePrefill = useCallback((_prefillRoute: string) => {
|
||||||
const state = location.state as { prefill?: string; uploadIds?: string[] } | null
|
const state = location.state as { prefill?: string; logs?: string; uploadIds?: string[] } | null
|
||||||
const prefill = state?.prefill
|
const prefill = state?.prefill
|
||||||
|
const logs = state?.logs?.trim()
|
||||||
const uploadIds = state?.uploadIds
|
const uploadIds = state?.uploadIds
|
||||||
if (!prefill || prefillHandledRef.current) return
|
if (!prefill || prefillHandledRef.current) return
|
||||||
prefillHandledRef.current = true
|
prefillHandledRef.current = true
|
||||||
@@ -372,11 +388,18 @@ export function useAssistantSession() {
|
|||||||
setActiveQuestions([])
|
setActiveQuestions([])
|
||||||
setActiveActions([])
|
setActiveActions([])
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
|
if (logs) {
|
||||||
|
setShowLogs(true)
|
||||||
|
setLogContent(logs)
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const initialMessage = logs
|
||||||
|
? `${prefill}\n\nAttached logs/output:\n\`\`\`\n${logs}\n\`\`\``
|
||||||
|
: prefill
|
||||||
const session = await aiSessionsApi.createChatSession({
|
const session = await aiSessionsApi.createChatSession({
|
||||||
intake_type: 'free_text',
|
intake_type: 'free_text',
|
||||||
intake_content: { text: prefill },
|
intake_content: { text: initialMessage },
|
||||||
})
|
})
|
||||||
const prefillChatId = session.session_id
|
const prefillChatId = session.session_id
|
||||||
currentChatRef.current = prefillChatId
|
currentChatRef.current = prefillChatId
|
||||||
@@ -390,10 +413,10 @@ export function useAssistantSession() {
|
|||||||
}
|
}
|
||||||
setChats(prev => [chatItem, ...prev])
|
setChats(prev => [chatItem, ...prev])
|
||||||
setActiveChatId(prefillChatId)
|
setActiveChatId(prefillChatId)
|
||||||
setMessages([{ role: 'user', content: prefill }])
|
setMessages([{ role: 'user', content: initialMessage }])
|
||||||
|
|
||||||
const response = await aiSessionsApi.sendChatMessage(prefillChatId, {
|
const response = await aiSessionsApi.sendChatMessage(prefillChatId, {
|
||||||
message: prefill,
|
message: initialMessage,
|
||||||
upload_ids: uploadIds?.length ? uploadIds : undefined,
|
upload_ids: uploadIds?.length ? uploadIds : undefined,
|
||||||
})
|
})
|
||||||
if (currentChatRef.current !== prefillChatId) return
|
if (currentChatRef.current !== prefillChatId) return
|
||||||
@@ -561,7 +584,7 @@ export function useAssistantSession() {
|
|||||||
setShowTaskLane, setActiveQuestions, setActiveActions,
|
setShowTaskLane, setActiveQuestions, setActiveActions,
|
||||||
// Handlers
|
// Handlers
|
||||||
loadChats, selectChat, handleNewChat, handleDeleteChat, handleTogglePin,
|
loadChats, selectChat, handleNewChat, handleDeleteChat, handleTogglePin,
|
||||||
handleSend, handleConclude, handleResumeNew,
|
handleSend, sendMessage, handleConclude, handleResumeNew,
|
||||||
handleKeyDown, handlePaste,
|
handleKeyDown, handlePaste,
|
||||||
handleDragOver, handleDragEnter, handleDragLeave, handleDrop,
|
handleDragOver, handleDragEnter, handleDragLeave, handleDrop,
|
||||||
handleFileSelect, handleRemoveUpload, retryUpload,
|
handleFileSelect, handleRemoveUpload, retryUpload,
|
||||||
|
|||||||
@@ -85,6 +85,12 @@ export default function CockpitPage() {
|
|||||||
prevMessageCountRef.current = session.messages.length
|
prevMessageCountRef.current = session.messages.length
|
||||||
}, [session.messages.length, showOnboarding])
|
}, [session.messages.length, showOnboarding])
|
||||||
|
|
||||||
|
// Reset local step UI when switching cases or when a new action set arrives.
|
||||||
|
useEffect(() => {
|
||||||
|
setActiveStepIndex(0)
|
||||||
|
setCompletedSteps(new Set())
|
||||||
|
}, [session.activeChatId, session.activeActions])
|
||||||
|
|
||||||
// ── Triage handlers ──
|
// ── Triage handlers ──
|
||||||
|
|
||||||
const handleTriageFieldSave = useCallback(async (field: keyof TriageMeta, value: string) => {
|
const handleTriageFieldSave = useCallback(async (field: keyof TriageMeta, value: string) => {
|
||||||
@@ -306,8 +312,7 @@ export default function CockpitPage() {
|
|||||||
<FlowPilotAsks
|
<FlowPilotAsks
|
||||||
questions={session.activeQuestions}
|
questions={session.activeQuestions}
|
||||||
onAnswer={(answer) => {
|
onAnswer={(answer) => {
|
||||||
session.setInput(answer)
|
void session.sendMessage(answer, { clearComposer: false })
|
||||||
setTimeout(() => session.handleSend(), 10)
|
|
||||||
}}
|
}}
|
||||||
loading={session.loading}
|
loading={session.loading}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user