2026-03-03 08:45:26 -06:00
import { asString , asNumber , parseObject , parseJson } from "@paperclipai/adapter-utils/server-utils" ;
2026-02-18 13:53:03 -06:00
export function parseCodexJsonl ( stdout : string ) {
let sessionId : string | null = null ;
2026-04-10 22:26:21 -05:00
let finalMessage : string | null = null ;
2026-02-19 14:39:37 -06:00
let errorMessage : string | null = null ;
2026-02-18 13:53:03 -06:00
const usage = {
inputTokens : 0 ,
cachedInputTokens : 0 ,
outputTokens : 0 ,
} ;
for ( const rawLine of stdout . split ( /\r?\n/ ) ) {
const line = rawLine . trim ( ) ;
if ( ! line ) continue ;
const event = parseJson ( line ) ;
if ( ! event ) continue ;
const type = asString ( event . type , "" ) ;
if ( type === "thread.started" ) {
sessionId = asString ( event . thread_id , sessionId ? ? "" ) || sessionId ;
continue ;
}
2026-02-19 14:39:37 -06:00
if ( type === "error" ) {
const msg = asString ( event . message , "" ) . trim ( ) ;
if ( msg ) errorMessage = msg ;
continue ;
}
2026-02-18 13:53:03 -06:00
if ( type === "item.completed" ) {
const item = parseObject ( event . item ) ;
if ( asString ( item . type , "" ) === "agent_message" ) {
const text = asString ( item . text , "" ) ;
2026-04-10 22:26:21 -05:00
if ( text ) finalMessage = text ;
2026-02-18 13:53:03 -06:00
}
continue ;
}
if ( type === "turn.completed" ) {
const usageObj = parseObject ( event . usage ) ;
usage . inputTokens = asNumber ( usageObj . input_tokens , usage . inputTokens ) ;
usage . cachedInputTokens = asNumber ( usageObj . cached_input_tokens , usage . cachedInputTokens ) ;
usage . outputTokens = asNumber ( usageObj . output_tokens , usage . outputTokens ) ;
2026-02-19 14:39:37 -06:00
continue ;
}
if ( type === "turn.failed" ) {
const err = parseObject ( event . error ) ;
const msg = asString ( err . message , "" ) . trim ( ) ;
if ( msg ) errorMessage = msg ;
2026-02-18 13:53:03 -06:00
}
}
return {
sessionId ,
2026-04-10 22:26:21 -05:00
summary : finalMessage?.trim ( ) ? ? "" ,
2026-02-18 13:53:03 -06:00
usage ,
2026-02-19 14:39:37 -06:00
errorMessage ,
2026-02-18 13:53:03 -06:00
} ;
}
2026-02-19 14:01:58 -06:00
export function isCodexUnknownSessionError ( stdout : string , stderr : string ) : boolean {
const haystack = ` ${ stdout } \ n ${ stderr } `
. split ( /\r?\n/ )
. map ( ( line ) = > line . trim ( ) )
. filter ( Boolean )
. join ( "\n" ) ;
2026-04-06 17:07:11 +09:00
return /unknown (session|thread)|session .* not found|thread .* not found|conversation .* not found|missing rollout path for thread|state db missing rollout path|no rollout found for thread id/i . test (
2026-02-19 14:01:58 -06:00
haystack ,
) ;
}