@@ -14,6 +14,7 @@ import {
1414 requestChatTitle ,
1515 SSE_RESPONSE_HEADERS ,
1616} from '@/lib/copilot/chat-streaming'
17+ import { appendCopilotLogContext } from '@/lib/copilot/logging'
1718import { COPILOT_REQUEST_MODES } from '@/lib/copilot/models'
1819import { orchestrateCopilotStream } from '@/lib/copilot/orchestrator'
1920import { getStreamMeta , readStreamEvents } from '@/lib/copilot/orchestrator/stream/buffer'
@@ -182,25 +183,36 @@ export async function POST(req: NextRequest) {
182183 const wf = await getWorkflowById ( workflowId )
183184 resolvedWorkspaceId = wf ?. workspaceId ?? undefined
184185 } catch {
185- logger . warn ( `[${ tracker . requestId } ] Failed to resolve workspaceId from workflow` )
186+ logger . warn (
187+ appendCopilotLogContext ( 'Failed to resolve workspaceId from workflow' , {
188+ requestId : tracker . requestId ,
189+ messageId : userMessageId ,
190+ } )
191+ )
186192 }
187193
188194 const userMessageIdToUse = userMessageId || crypto . randomUUID ( )
189195 try {
190- logger . info ( `[${ tracker . requestId } ] Received chat POST` , {
191- workflowId,
192- hasContexts : Array . isArray ( normalizedContexts ) ,
193- contextsCount : Array . isArray ( normalizedContexts ) ? normalizedContexts . length : 0 ,
194- contextsPreview : Array . isArray ( normalizedContexts )
195- ? normalizedContexts . map ( ( c : any ) => ( {
196- kind : c ?. kind ,
197- chatId : c ?. chatId ,
198- workflowId : c ?. workflowId ,
199- executionId : ( c as any ) ?. executionId ,
200- label : c ?. label ,
201- } ) )
202- : undefined ,
203- } )
196+ logger . info (
197+ appendCopilotLogContext ( 'Received chat POST' , {
198+ requestId : tracker . requestId ,
199+ messageId : userMessageIdToUse ,
200+ } ) ,
201+ {
202+ workflowId,
203+ hasContexts : Array . isArray ( normalizedContexts ) ,
204+ contextsCount : Array . isArray ( normalizedContexts ) ? normalizedContexts . length : 0 ,
205+ contextsPreview : Array . isArray ( normalizedContexts )
206+ ? normalizedContexts . map ( ( c : any ) => ( {
207+ kind : c ?. kind ,
208+ chatId : c ?. chatId ,
209+ workflowId : c ?. workflowId ,
210+ executionId : ( c as any ) ?. executionId ,
211+ label : c ?. label ,
212+ } ) )
213+ : undefined ,
214+ }
215+ )
204216 } catch { }
205217
206218 let currentChat : any = null
@@ -238,22 +250,40 @@ export async function POST(req: NextRequest) {
238250 actualChatId
239251 )
240252 agentContexts = processed
241- logger . info ( `[${ tracker . requestId } ] Contexts processed for request` , {
242- processedCount : agentContexts . length ,
243- kinds : agentContexts . map ( ( c ) => c . type ) ,
244- lengthPreview : agentContexts . map ( ( c ) => c . content ?. length ?? 0 ) ,
245- } )
253+ logger . info (
254+ appendCopilotLogContext ( 'Contexts processed for request' , {
255+ requestId : tracker . requestId ,
256+ messageId : userMessageIdToUse ,
257+ } ) ,
258+ {
259+ processedCount : agentContexts . length ,
260+ kinds : agentContexts . map ( ( c ) => c . type ) ,
261+ lengthPreview : agentContexts . map ( ( c ) => c . content ?. length ?? 0 ) ,
262+ }
263+ )
246264 if (
247265 Array . isArray ( normalizedContexts ) &&
248266 normalizedContexts . length > 0 &&
249267 agentContexts . length === 0
250268 ) {
251269 logger . warn (
252- `[${ tracker . requestId } ] Contexts provided but none processed. Check executionId for logs contexts.`
270+ appendCopilotLogContext (
271+ 'Contexts provided but none processed. Check executionId for logs contexts.' ,
272+ {
273+ requestId : tracker . requestId ,
274+ messageId : userMessageIdToUse ,
275+ }
276+ )
253277 )
254278 }
255279 } catch ( e ) {
256- logger . error ( `[${ tracker . requestId } ] Failed to process contexts` , e )
280+ logger . error (
281+ appendCopilotLogContext ( 'Failed to process contexts' , {
282+ requestId : tracker . requestId ,
283+ messageId : userMessageIdToUse ,
284+ } ) ,
285+ e
286+ )
257287 }
258288 }
259289
@@ -283,7 +313,10 @@ export async function POST(req: NextRequest) {
283313 agentContexts . push ( result . value )
284314 } else if ( result . status === 'rejected' ) {
285315 logger . error (
286- `[${ tracker . requestId } ] Failed to resolve resource attachment` ,
316+ appendCopilotLogContext ( 'Failed to resolve resource attachment' , {
317+ requestId : tracker . requestId ,
318+ messageId : userMessageIdToUse ,
319+ } ) ,
287320 result . reason
288321 )
289322 }
@@ -324,20 +357,26 @@ export async function POST(req: NextRequest) {
324357 )
325358
326359 try {
327- logger . info ( `[${ tracker . requestId } ] About to call Sim Agent` , {
328- hasContext : agentContexts . length > 0 ,
329- contextCount : agentContexts . length ,
330- hasFileAttachments : Array . isArray ( requestPayload . fileAttachments ) ,
331- messageLength : message . length ,
332- mode : effectiveMode ,
333- hasTools : Array . isArray ( requestPayload . tools ) ,
334- toolCount : Array . isArray ( requestPayload . tools ) ? requestPayload . tools . length : 0 ,
335- hasBaseTools : Array . isArray ( requestPayload . baseTools ) ,
336- baseToolCount : Array . isArray ( requestPayload . baseTools )
337- ? requestPayload . baseTools . length
338- : 0 ,
339- hasCredentials : ! ! requestPayload . credentials ,
340- } )
360+ logger . info (
361+ appendCopilotLogContext ( 'About to call Sim Agent' , {
362+ requestId : tracker . requestId ,
363+ messageId : userMessageIdToUse ,
364+ } ) ,
365+ {
366+ hasContext : agentContexts . length > 0 ,
367+ contextCount : agentContexts . length ,
368+ hasFileAttachments : Array . isArray ( requestPayload . fileAttachments ) ,
369+ messageLength : message . length ,
370+ mode : effectiveMode ,
371+ hasTools : Array . isArray ( requestPayload . tools ) ,
372+ toolCount : Array . isArray ( requestPayload . tools ) ? requestPayload . tools . length : 0 ,
373+ hasBaseTools : Array . isArray ( requestPayload . baseTools ) ,
374+ baseToolCount : Array . isArray ( requestPayload . baseTools )
375+ ? requestPayload . baseTools . length
376+ : 0 ,
377+ hasCredentials : ! ! requestPayload . credentials ,
378+ }
379+ )
341380 } catch { }
342381
343382 if ( stream && actualChatId ) {
@@ -481,10 +520,16 @@ export async function POST(req: NextRequest) {
481520 . where ( eq ( copilotChats . id , actualChatId ) )
482521 }
483522 } catch ( error ) {
484- logger . error ( `[${ tracker . requestId } ] Failed to persist chat messages` , {
485- chatId : actualChatId ,
486- error : error instanceof Error ? error . message : 'Unknown error' ,
487- } )
523+ logger . error (
524+ appendCopilotLogContext ( 'Failed to persist chat messages' , {
525+ requestId : tracker . requestId ,
526+ messageId : userMessageIdToUse ,
527+ } ) ,
528+ {
529+ chatId : actualChatId ,
530+ error : error instanceof Error ? error . message : 'Unknown error' ,
531+ }
532+ )
488533 }
489534 } ,
490535 } ,
@@ -510,13 +555,19 @@ export async function POST(req: NextRequest) {
510555 provider : typeof requestPayload ?. provider === 'string' ? requestPayload . provider : undefined ,
511556 }
512557
513- logger . info ( `[${ tracker . requestId } ] Non-streaming response from orchestrator:` , {
514- hasContent : ! ! responseData . content ,
515- contentLength : responseData . content ?. length || 0 ,
516- model : responseData . model ,
517- provider : responseData . provider ,
518- toolCallsCount : responseData . toolCalls ?. length || 0 ,
519- } )
558+ logger . info (
559+ appendCopilotLogContext ( 'Non-streaming response from orchestrator' , {
560+ requestId : tracker . requestId ,
561+ messageId : userMessageIdToUse ,
562+ } ) ,
563+ {
564+ hasContent : ! ! responseData . content ,
565+ contentLength : responseData . content ?. length || 0 ,
566+ model : responseData . model ,
567+ provider : responseData . provider ,
568+ toolCallsCount : responseData . toolCalls ?. length || 0 ,
569+ }
570+ )
520571
521572 // Save messages if we have a chat
522573 if ( currentChat && responseData . content ) {
@@ -549,8 +600,13 @@ export async function POST(req: NextRequest) {
549600
550601 // Start title generation in parallel if this is first message (non-streaming)
551602 if ( actualChatId && ! currentChat . title && conversationHistory . length === 0 ) {
552- logger . info ( `[${ tracker . requestId } ] Starting title generation for non-streaming response` )
553- requestChatTitle ( { message, model : selectedModel , provider } )
603+ logger . info (
604+ appendCopilotLogContext ( 'Starting title generation for non-streaming response' , {
605+ requestId : tracker . requestId ,
606+ messageId : userMessageIdToUse ,
607+ } )
608+ )
609+ requestChatTitle ( { message, model : selectedModel , provider, messageId : userMessageIdToUse } )
554610 . then ( async ( title ) => {
555611 if ( title ) {
556612 await db
@@ -560,11 +616,22 @@ export async function POST(req: NextRequest) {
560616 updatedAt : new Date ( ) ,
561617 } )
562618 . where ( eq ( copilotChats . id , actualChatId ! ) )
563- logger . info ( `[${ tracker . requestId } ] Generated and saved title: ${ title } ` )
619+ logger . info (
620+ appendCopilotLogContext ( `Generated and saved title: ${ title } ` , {
621+ requestId : tracker . requestId ,
622+ messageId : userMessageIdToUse ,
623+ } )
624+ )
564625 }
565626 } )
566627 . catch ( ( error ) => {
567- logger . error ( `[${ tracker . requestId } ] Title generation failed:` , error )
628+ logger . error (
629+ appendCopilotLogContext ( 'Title generation failed' , {
630+ requestId : tracker . requestId ,
631+ messageId : userMessageIdToUse ,
632+ } ) ,
633+ error
634+ )
568635 } )
569636 }
570637
@@ -578,11 +645,17 @@ export async function POST(req: NextRequest) {
578645 . where ( eq ( copilotChats . id , actualChatId ! ) )
579646 }
580647
581- logger . info ( `[${ tracker . requestId } ] Returning non-streaming response` , {
582- duration : tracker . getDuration ( ) ,
583- chatId : actualChatId ,
584- responseLength : responseData . content ?. length || 0 ,
585- } )
648+ logger . info (
649+ appendCopilotLogContext ( 'Returning non-streaming response' , {
650+ requestId : tracker . requestId ,
651+ messageId : userMessageIdToUse ,
652+ } ) ,
653+ {
654+ duration : tracker . getDuration ( ) ,
655+ chatId : actualChatId ,
656+ responseLength : responseData . content ?. length || 0 ,
657+ }
658+ )
586659
587660 return NextResponse . json ( {
588661 success : true ,
@@ -606,21 +679,33 @@ export async function POST(req: NextRequest) {
606679 const duration = tracker . getDuration ( )
607680
608681 if ( error instanceof z . ZodError ) {
609- logger . error ( `[${ tracker . requestId } ] Validation error:` , {
610- duration,
611- errors : error . errors ,
612- } )
682+ logger . error (
683+ appendCopilotLogContext ( 'Validation error' , {
684+ requestId : tracker . requestId ,
685+ messageId : pendingChatStreamID ?? undefined ,
686+ } ) ,
687+ {
688+ duration,
689+ errors : error . errors ,
690+ }
691+ )
613692 return NextResponse . json (
614693 { error : 'Invalid request data' , details : error . errors } ,
615694 { status : 400 }
616695 )
617696 }
618697
619- logger . error ( `[${ tracker . requestId } ] Error handling copilot chat:` , {
620- duration,
621- error : error instanceof Error ? error . message : 'Unknown error' ,
622- stack : error instanceof Error ? error . stack : undefined ,
623- } )
698+ logger . error (
699+ appendCopilotLogContext ( 'Error handling copilot chat' , {
700+ requestId : tracker . requestId ,
701+ messageId : pendingChatStreamID ?? undefined ,
702+ } ) ,
703+ {
704+ duration,
705+ error : error instanceof Error ? error . message : 'Unknown error' ,
706+ stack : error instanceof Error ? error . stack : undefined ,
707+ }
708+ )
624709
625710 return NextResponse . json (
626711 { error : error instanceof Error ? error . message : 'Internal server error' } ,
@@ -665,11 +750,16 @@ export async function GET(req: NextRequest) {
665750 status : meta ?. status || 'unknown' ,
666751 }
667752 } catch ( err ) {
668- logger . warn ( 'Failed to read stream snapshot for chat' , {
669- chatId,
670- conversationId : chat . conversationId ,
671- error : err instanceof Error ? err . message : String ( err ) ,
672- } )
753+ logger . warn (
754+ appendCopilotLogContext ( 'Failed to read stream snapshot for chat' , {
755+ messageId : chat . conversationId || undefined ,
756+ } ) ,
757+ {
758+ chatId,
759+ conversationId : chat . conversationId ,
760+ error : err instanceof Error ? err . message : String ( err ) ,
761+ }
762+ )
673763 }
674764 }
675765
@@ -688,7 +778,11 @@ export async function GET(req: NextRequest) {
688778 ...( streamSnapshot ? { streamSnapshot } : { } ) ,
689779 }
690780
691- logger . info ( `Retrieved chat ${ chatId } ` )
781+ logger . info (
782+ appendCopilotLogContext ( `Retrieved chat ${ chatId } ` , {
783+ messageId : chat . conversationId || undefined ,
784+ } )
785+ )
692786 return NextResponse . json ( { success : true , chat : transformedChat } )
693787 }
694788
@@ -750,7 +844,7 @@ export async function GET(req: NextRequest) {
750844 chats : transformedChats ,
751845 } )
752846 } catch ( error ) {
753- logger . error ( 'Error fetching copilot chats: ' , error )
847+ logger . error ( 'Error fetching copilot chats' , error )
754848 return createInternalServerErrorResponse ( 'Failed to fetch chats' )
755849 }
756850}
0 commit comments