fix: resolve task lane stale state, partial submit, and closure bugs #125
@@ -259,6 +259,11 @@ export default function AssistantChatPage() {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const handleNewChat = async () => {
|
const handleNewChat = async () => {
|
||||||
|
// Clear stale state immediately — don't wait for API to return
|
||||||
|
setShowTaskLane(false)
|
||||||
|
setActiveQuestions([])
|
||||||
|
setActiveActions([])
|
||||||
|
setMessages([])
|
||||||
try {
|
try {
|
||||||
const session = await aiSessionsApi.createChatSession({
|
const session = await aiSessionsApi.createChatSession({
|
||||||
intake_type: 'free_text',
|
intake_type: 'free_text',
|
||||||
@@ -275,11 +280,6 @@ export default function AssistantChatPage() {
|
|||||||
currentChatRef.current = session.session_id
|
currentChatRef.current = session.session_id
|
||||||
setChats(prev => [chatItem, ...prev])
|
setChats(prev => [chatItem, ...prev])
|
||||||
setActiveChatId(session.session_id)
|
setActiveChatId(session.session_id)
|
||||||
setMessages([])
|
|
||||||
// Clear TaskLane from previous session
|
|
||||||
setShowTaskLane(false)
|
|
||||||
setActiveQuestions([])
|
|
||||||
setActiveActions([])
|
|
||||||
} catch {
|
} catch {
|
||||||
toast.error('Failed to create chat')
|
toast.error('Failed to create chat')
|
||||||
}
|
}
|
||||||
@@ -315,11 +315,14 @@ export default function AssistantChatPage() {
|
|||||||
setMessages(prev => [...prev, { role: 'user', content: userMessage }])
|
setMessages(prev => [...prev, { role: 'user', content: userMessage }])
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
|
|
||||||
|
const sentForChatId = activeChatId
|
||||||
try {
|
try {
|
||||||
const response = await aiSessionsApi.sendChatMessage(activeChatId, {
|
const response = await aiSessionsApi.sendChatMessage(activeChatId, {
|
||||||
message: userMessage,
|
message: userMessage,
|
||||||
upload_ids: completedUploadIds.length > 0 ? completedUploadIds : undefined,
|
upload_ids: completedUploadIds.length > 0 ? completedUploadIds : undefined,
|
||||||
})
|
})
|
||||||
|
// Guard: discard if user switched to a different chat while this was in flight
|
||||||
|
if (currentChatRef.current !== sentForChatId) return
|
||||||
analytics.aiFeatureUsed({ feature: 'assistant_chat' })
|
analytics.aiFeatureUsed({ feature: 'assistant_chat' })
|
||||||
setMessages(prev => [
|
setMessages(prev => [
|
||||||
...prev,
|
...prev,
|
||||||
@@ -327,20 +330,20 @@ export default function AssistantChatPage() {
|
|||||||
])
|
])
|
||||||
setChats(prev =>
|
setChats(prev =>
|
||||||
prev.map(c =>
|
prev.map(c =>
|
||||||
c.id === activeChatId
|
c.id === sentForChatId
|
||||||
? { ...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 ? userMessage.slice(0, 100) : c.title, updated_at: new Date().toISOString() }
|
||||||
: c
|
: c
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
// Load branches if fork was created
|
// Load branches if fork was created
|
||||||
if (response.fork && activeChatId) {
|
if (response.fork && sentForChatId) {
|
||||||
branching.loadBranches(activeChatId)
|
branching.loadBranches(sentForChatId)
|
||||||
}
|
}
|
||||||
// Show task lane if AI sent questions or actions
|
// Show task lane if AI sent questions or actions
|
||||||
const hasQuestions = response.questions && response.questions.length > 0
|
const hasQuestions = response.questions && response.questions.length > 0
|
||||||
const hasActions = response.actions && response.actions.length > 0
|
const hasActions = response.actions && response.actions.length > 0
|
||||||
if (hasQuestions || hasActions) {
|
if (hasQuestions || hasActions) {
|
||||||
if (activeChatId) clearTaskState(activeChatId)
|
clearTaskState(sentForChatId)
|
||||||
setActiveQuestions(response.questions || [])
|
setActiveQuestions(response.questions || [])
|
||||||
setActiveActions(response.actions || [])
|
setActiveActions(response.actions || [])
|
||||||
setShowTaskLane(true)
|
setShowTaskLane(true)
|
||||||
@@ -377,19 +380,22 @@ export default function AssistantChatPage() {
|
|||||||
setMessages(prev => [...prev, { role: 'user', content: userMessage }])
|
setMessages(prev => [...prev, { role: 'user', content: userMessage }])
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
|
|
||||||
|
const sentForChatId = activeChatId
|
||||||
try {
|
try {
|
||||||
const response = await aiSessionsApi.sendChatMessage(activeChatId, { message: userMessage })
|
const response = await aiSessionsApi.sendChatMessage(activeChatId, { message: userMessage })
|
||||||
|
// Guard: discard if user switched to a different chat while this was in flight
|
||||||
|
if (currentChatRef.current !== sentForChatId) return
|
||||||
setMessages(prev => [
|
setMessages(prev => [
|
||||||
...prev,
|
...prev,
|
||||||
{ role: 'assistant', content: response.content, suggestedFlows: response.suggested_flows, fork: response.fork, actions: response.actions, questions: response.questions },
|
{ role: 'assistant', content: response.content, suggestedFlows: response.suggested_flows, fork: response.fork, actions: response.actions, questions: response.questions },
|
||||||
])
|
])
|
||||||
if (response.fork && activeChatId) {
|
if (response.fork && sentForChatId) {
|
||||||
branching.loadBranches(activeChatId)
|
branching.loadBranches(sentForChatId)
|
||||||
}
|
}
|
||||||
// Update task lane based on AI response
|
// Update task lane based on AI response
|
||||||
const hasQuestions = response.questions && response.questions.length > 0
|
const hasQuestions = response.questions && response.questions.length > 0
|
||||||
const hasActions = response.actions && response.actions.length > 0
|
const hasActions = response.actions && response.actions.length > 0
|
||||||
if (activeChatId) clearTaskState(activeChatId)
|
clearTaskState(sentForChatId)
|
||||||
if (hasQuestions || hasActions) {
|
if (hasQuestions || hasActions) {
|
||||||
setActiveQuestions(response.questions || [])
|
setActiveQuestions(response.questions || [])
|
||||||
setActiveActions(response.actions || [])
|
setActiveActions(response.actions || [])
|
||||||
@@ -430,6 +436,10 @@ export default function AssistantChatPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleResumeNew = async (summary: string) => {
|
const handleResumeNew = async (summary: string) => {
|
||||||
|
// Clear stale state immediately — don't wait for API to return
|
||||||
|
setShowTaskLane(false)
|
||||||
|
setActiveQuestions([])
|
||||||
|
setActiveActions([])
|
||||||
try {
|
try {
|
||||||
const resumePrompt = `I'm continuing a previous troubleshooting session. Here's where we left off:\n\n${summary}\n\nPlease review this context and help me continue from where we stopped.`
|
const resumePrompt = `I'm continuing a previous troubleshooting session. Here's where we left off:\n\n${summary}\n\nPlease review this context and help me continue from where we stopped.`
|
||||||
const session = await aiSessionsApi.createChatSession({
|
const session = await aiSessionsApi.createChatSession({
|
||||||
|
|||||||
Reference in New Issue
Block a user