@@ -50,13 +50,25 @@ const ChatMessageSchema = z.object({
5050 contexts : z
5151 . array (
5252 z . object ( {
53- kind : z . enum ( [ 'past_chat' , 'workflow' , 'blocks' , 'logs' , 'knowledge' , 'templates' ] ) ,
53+ kind : z . enum ( [
54+ 'past_chat' ,
55+ 'workflow' ,
56+ 'current_workflow' ,
57+ 'blocks' ,
58+ 'logs' ,
59+ 'workflow_block' ,
60+ 'knowledge' ,
61+ 'templates' ,
62+ 'docs' ,
63+ ] ) ,
5464 label : z . string ( ) ,
5565 chatId : z . string ( ) . optional ( ) ,
5666 workflowId : z . string ( ) . optional ( ) ,
5767 knowledgeId : z . string ( ) . optional ( ) ,
5868 blockId : z . string ( ) . optional ( ) ,
5969 templateId : z . string ( ) . optional ( ) ,
70+ executionId : z . string ( ) . optional ( ) ,
71+ // For workflow_block, provide both workflowId and blockId
6072 } )
6173 )
6274 . optional ( ) ,
@@ -105,6 +117,7 @@ export async function POST(req: NextRequest) {
105117 kind : c ?. kind ,
106118 chatId : c ?. chatId ,
107119 workflowId : c ?. workflowId ,
120+ executionId : ( c as any ) ?. executionId ,
108121 label : c ?. label ,
109122 } ) )
110123 : undefined ,
@@ -115,13 +128,18 @@ export async function POST(req: NextRequest) {
115128 if ( Array . isArray ( contexts ) && contexts . length > 0 ) {
116129 try {
117130 const { processContextsServer } = await import ( '@/lib/copilot/process-contents' )
118- const processed = await processContextsServer ( contexts as any , authenticatedUserId )
131+ const processed = await processContextsServer ( contexts as any , authenticatedUserId , message )
119132 agentContexts = processed
120133 logger . info ( `[${ tracker . requestId } ] Contexts processed for request` , {
121134 processedCount : agentContexts . length ,
122135 kinds : agentContexts . map ( ( c ) => c . type ) ,
123136 lengthPreview : agentContexts . map ( ( c ) => c . content ?. length ?? 0 ) ,
124137 } )
138+ if ( Array . isArray ( contexts ) && contexts . length > 0 && agentContexts . length === 0 ) {
139+ logger . warn (
140+ `[${ tracker . requestId } ] Contexts provided but none processed. Check executionId for logs contexts.`
141+ )
142+ }
125143 } catch ( e ) {
126144 logger . error ( `[${ tracker . requestId } ] Failed to process contexts` , e )
127145 }
@@ -474,16 +492,6 @@ export async function POST(req: NextRequest) {
474492 break
475493 }
476494
477- // Check if client disconnected before processing chunk
478- try {
479- // Forward the chunk to client immediately
480- controller . enqueue ( value )
481- } catch ( error ) {
482- // Client disconnected - stop reading from sim agent
483- reader . cancel ( ) // Stop reading from sim agent
484- break
485- }
486-
487495 // Decode and parse SSE events for logging and capturing content
488496 const decodedChunk = decoder . decode ( value , { stream : true } )
489497 buffer += decodedChunk
@@ -583,6 +591,47 @@ export async function POST(req: NextRequest) {
583591
584592 default :
585593 }
594+
595+ // Emit to client: rewrite 'error' events into user-friendly assistant message
596+ if ( event ?. type === 'error' ) {
597+ try {
598+ const displayMessage : string =
599+ ( event ?. data && ( event . data . displayMessage as string ) ) ||
600+ 'Sorry, I encountered an error. Please try again.'
601+ const formatted = `_${ displayMessage } _`
602+ // Accumulate so it persists to DB as assistant content
603+ assistantContent += formatted
604+ // Send as content chunk
605+ try {
606+ controller . enqueue (
607+ encoder . encode (
608+ `data: ${ JSON . stringify ( { type : 'content' , data : formatted } ) } \n\n`
609+ )
610+ )
611+ } catch ( enqueueErr ) {
612+ reader . cancel ( )
613+ break
614+ }
615+ // Then close this response cleanly for the client
616+ try {
617+ controller . enqueue (
618+ encoder . encode ( `data: ${ JSON . stringify ( { type : 'done' } ) } \n\n` )
619+ )
620+ } catch ( enqueueErr ) {
621+ reader . cancel ( )
622+ break
623+ }
624+ } catch { }
625+ // Do not forward the original error event
626+ } else {
627+ // Forward original event to client
628+ try {
629+ controller . enqueue ( encoder . encode ( `data: ${ jsonStr } \n\n` ) )
630+ } catch ( enqueueErr ) {
631+ reader . cancel ( )
632+ break
633+ }
634+ }
586635 } catch ( e ) {
587636 // Enhanced error handling for large payloads and parsing issues
588637 const lineLength = line . length
@@ -615,10 +664,37 @@ export async function POST(req: NextRequest) {
615664 logger . debug ( `[${ tracker . requestId } ] Processing remaining buffer: "${ buffer } "` )
616665 if ( buffer . startsWith ( 'data: ' ) ) {
617666 try {
618- const event = JSON . parse ( buffer . slice ( 6 ) )
667+ const jsonStr = buffer . slice ( 6 )
668+ const event = JSON . parse ( jsonStr )
619669 if ( event . type === 'content' && event . data ) {
620670 assistantContent += event . data
621671 }
672+ // Forward remaining event, applying same error rewrite behavior
673+ if ( event ?. type === 'error' ) {
674+ const displayMessage : string =
675+ ( event ?. data && ( event . data . displayMessage as string ) ) ||
676+ 'Sorry, I encountered an error. Please try again.'
677+ const formatted = `_${ displayMessage } _`
678+ assistantContent += formatted
679+ try {
680+ controller . enqueue (
681+ encoder . encode (
682+ `data: ${ JSON . stringify ( { type : 'content' , data : formatted } ) } \n\n`
683+ )
684+ )
685+ controller . enqueue (
686+ encoder . encode ( `data: ${ JSON . stringify ( { type : 'done' } ) } \n\n` )
687+ )
688+ } catch ( enqueueErr ) {
689+ reader . cancel ( )
690+ }
691+ } else {
692+ try {
693+ controller . enqueue ( encoder . encode ( `data: ${ jsonStr } \n\n` ) )
694+ } catch ( enqueueErr ) {
695+ reader . cancel ( )
696+ }
697+ }
622698 } catch ( e ) {
623699 logger . warn ( `[${ tracker . requestId } ] Failed to parse final buffer: "${ buffer } "` )
624700 }
0 commit comments