@@ -15,6 +15,7 @@ import {
1515 processContextsServer ,
1616 resolveActiveResourceContext ,
1717} from '@/lib/copilot/chat/process-contents'
18+ import { finalizeAssistantTurn } from '@/lib/copilot/chat/terminal-state'
1819import { COPILOT_REQUEST_MODES } from '@/lib/copilot/constants'
1920import {
2021 createBadRequestResponse ,
@@ -378,6 +379,7 @@ export async function POST(req: NextRequest) {
378379 autoExecuteTools : true ,
379380 interactive : true ,
380381 onComplete : buildOnComplete ( actualChatId , userMessageIdToUse , tracker . requestId ) ,
382+ onError : buildOnError ( actualChatId , userMessageIdToUse , tracker . requestId ) ,
381383 } ,
382384 } )
383385
@@ -419,34 +421,16 @@ function buildOnComplete(
419421 requestId : string
420422) : ( result : OrchestratorResult ) => Promise < void > {
421423 return async ( result ) => {
422- if ( ! chatId || ! result . success ) return
423-
424- const assistantMessage = buildPersistedAssistantMessage ( result , result . requestId )
424+ if ( ! chatId ) return
425425
426426 try {
427- const [ row ] = await db
428- . select ( { messages : copilotChats . messages } )
429- . from ( copilotChats )
430- . where ( eq ( copilotChats . id , chatId ) )
431- . limit ( 1 )
432-
433- const msgs : Record < string , unknown > [ ] = Array . isArray ( row ?. messages ) ? row . messages : [ ]
434- const userIdx = msgs . findIndex ( ( m : Record < string , unknown > ) => m . id === userMessageId )
435- const alreadyHasResponse =
436- userIdx >= 0 &&
437- userIdx + 1 < msgs . length &&
438- ( msgs [ userIdx + 1 ] as Record < string , unknown > ) ?. role === 'assistant'
439-
440- if ( ! alreadyHasResponse ) {
441- await db
442- . update ( copilotChats )
443- . set ( {
444- messages : sql `${ copilotChats . messages } || ${ JSON . stringify ( [ assistantMessage ] ) } ::jsonb` ,
445- conversationId : sql `CASE WHEN ${ copilotChats . conversationId } = ${ userMessageId } THEN NULL ELSE ${ copilotChats . conversationId } END` ,
446- updatedAt : new Date ( ) ,
447- } )
448- . where ( eq ( copilotChats . id , chatId ) )
449- }
427+ await finalizeAssistantTurn ( {
428+ chatId,
429+ userMessageId,
430+ ...( result . success
431+ ? { assistantMessage : buildPersistedAssistantMessage ( result , result . requestId ) }
432+ : { } ) ,
433+ } )
450434 } catch ( error ) {
451435 logger . error ( `[${ requestId } ] Failed to persist chat messages` , {
452436 chatId,
@@ -456,6 +440,25 @@ function buildOnComplete(
456440 }
457441}
458442
443+ function buildOnError (
444+ chatId : string | undefined ,
445+ userMessageId : string ,
446+ requestId : string
447+ ) : ( ) => Promise < void > {
448+ return async ( ) => {
449+ if ( ! chatId ) return
450+
451+ try {
452+ await finalizeAssistantTurn ( { chatId, userMessageId } )
453+ } catch ( error ) {
454+ logger . error ( `[${ requestId } ] Failed to finalize errored chat stream` , {
455+ chatId,
456+ error : error instanceof Error ? error . message : 'Unknown error' ,
457+ } )
458+ }
459+ }
460+ }
461+
459462// ---------------------------------------------------------------------------
460463// GET handler (read-only queries, extracted to queries.ts)
461464// ---------------------------------------------------------------------------
0 commit comments