1+ import { db } from '@sim/db'
2+ import { user } from '@sim/db/schema'
13import { createLogger } from '@sim/logger'
24import { getErrorMessage } from '@sim/utils/errors'
5+ import { eq } from 'drizzle-orm'
36import { env } from '@/lib/core/config/env'
47import type { OrchestratorResult } from '@/lib/mothership/request/types'
58
69const logger = createLogger ( 'ChatLog' )
710
811const CHAT_LOG_TIMEOUT_MS = 5_000
912
10- /** The finished turn's identity, captured when the user's message is admitted . */
13+ /** The turn a Chat send admitted — rebuilt identically when a relay pod recovers it . */
1114export interface ChatTurnLogContext {
1215 chatId : string
1316 messageId : string
1417 requestId : string
1518 userId : string
16- userEmail ?: string
1719 userMessage : string
1820 mode : 'assistant' | 'agent' | 'plan'
1921 startedAt : number
@@ -34,6 +36,28 @@ export function logChatTurn(
3436) : void {
3537 const url = env . SIM_LOGGING_WORKFLOW_URL
3638 if ( ! url ) return
39+ const durationMs = Date . now ( ) - context . startedAt
40+ void sendChatTurn ( url , context , result , status , durationMs ) . catch ( ( error ) => {
41+ logger . warn ( 'Chat log workflow request failed' , {
42+ chatId : context . chatId ,
43+ requestId : context . requestId ,
44+ error : getErrorMessage ( error ) ,
45+ } )
46+ } )
47+ }
48+
49+ async function sendChatTurn (
50+ url : string ,
51+ context : ChatTurnLogContext ,
52+ result : OrchestratorResult ,
53+ status : ChatTurnStatus ,
54+ durationMs : number
55+ ) : Promise < void > {
56+ const [ row ] = await db
57+ . select ( { email : user . email } )
58+ . from ( user )
59+ . where ( eq ( user . id , context . userId ) )
60+ . limit ( 1 )
3761
3862 const headers : Record < string , string > = { 'Content-Type' : 'application/json' }
3963 if ( env . SIM_LOGGING_WORKFLOW_API_KEY ) headers [ 'X-API-Key' ] = env . SIM_LOGGING_WORKFLOW_API_KEY
@@ -45,7 +69,7 @@ export function logChatTurn(
4569 chatId : context . chatId ,
4670 messageId : context . messageId ,
4771 userId : context . userId ,
48- userEmail : context . userEmail ,
72+ userEmail : row ?. email ,
4973 userMessage : context . userMessage ,
5074 assistantResponse : result . content ,
5175 status,
@@ -55,34 +79,25 @@ export function logChatTurn(
5579 mode : context . mode ,
5680 source : 'workspace-chat' ,
5781 startedAt : new Date ( context . startedAt ) . toISOString ( ) ,
58- durationMs : Date . now ( ) - context . startedAt ,
82+ durationMs,
5983 usage : {
6084 inputTokens : result . usage ?. prompt ?? 0 ,
6185 outputTokens : result . usage ?. completion ?? 0 ,
6286 } ,
6387 }
6488
65- void fetch ( url , {
89+ const response = await fetch ( url , {
6690 method : 'POST' ,
6791 headers,
6892 body : JSON . stringify ( { input } ) ,
6993 signal : AbortSignal . timeout ( CHAT_LOG_TIMEOUT_MS ) ,
7094 } )
71- . then ( async ( response ) => {
72- await response . body ?. cancel ( )
73- if ( ! response . ok ) {
74- logger . warn ( 'Chat log workflow returned a non-2xx status' , {
75- status : response . status ,
76- chatId : context . chatId ,
77- requestId : context . requestId ,
78- } )
79- }
80- } )
81- . catch ( ( error ) => {
82- logger . warn ( 'Chat log workflow request failed' , {
83- chatId : context . chatId ,
84- requestId : context . requestId ,
85- error : getErrorMessage ( error ) ,
86- } )
95+ await response . body ?. cancel ( )
96+ if ( ! response . ok ) {
97+ logger . warn ( 'Chat log workflow returned a non-2xx status' , {
98+ status : response . status ,
99+ chatId : context . chatId ,
100+ requestId : context . requestId ,
87101 } )
102+ }
88103}
0 commit comments