@@ -148,6 +148,46 @@ function extractResponseText(response: CodexResponse): string | null {
148148 return null
149149}
150150
151+ function extractTextFromEvent ( event : Record < string , unknown > ) : string | null {
152+ const eventType = event . type
153+ if ( eventType === 'response.output_text.delta' && typeof event . delta === 'string' ) {
154+ return event . delta
155+ }
156+ if ( eventType === 'response.output_text.done' && typeof event . text === 'string' ) {
157+ return event . text
158+ }
159+ if ( eventType === 'response.completed' && typeof event . response === 'object' && event . response ) {
160+ return extractResponseText ( event . response as CodexResponse )
161+ }
162+ return null
163+ }
164+
165+ function extractTextFromSse ( body : string ) : string | null {
166+ const lines = body . split ( '\n' )
167+ let output = ''
168+
169+ for ( const line of lines ) {
170+ if ( ! line . startsWith ( 'data:' ) ) {
171+ continue
172+ }
173+ const data = line . slice ( 5 ) . trim ( )
174+ if ( ! data || data === '[DONE]' ) {
175+ continue
176+ }
177+ try {
178+ const payload = JSON . parse ( data ) as Record < string , unknown >
179+ const chunk = extractTextFromEvent ( payload )
180+ if ( chunk ) {
181+ output += chunk
182+ }
183+ } catch {
184+ continue
185+ }
186+ }
187+
188+ return output . trim ( ) ? output : null
189+ }
190+
151191export async function generateWithChatGPT (
152192 title : string ,
153193 sources : Array < { name : string ; title : string ; description : string ; url : string } > ,
@@ -210,7 +250,7 @@ Write the full article now:`
210250 } ,
211251 body : JSON . stringify ( {
212252 model : MODEL_NAME ,
213- stream : false ,
253+ stream : true ,
214254 store : false ,
215255 include : [ 'reasoning.encrypted_content' ] ,
216256 instructions : 'You are a senior NFL beat reporter writing for a professional sports news website. Write in third-person AP style, using only the provided sources.' ,
@@ -239,13 +279,8 @@ Write the full article now:`
239279 return null
240280 }
241281
242- const data = await response . json ( ) as CodexResponse
243- if ( data . error ?. message ) {
244- console . warn ( ` ⚠️ ChatGPT error: ${ data . error . message } ` )
245- return null
246- }
247-
248- const generatedText = extractResponseText ( data )
282+ const responseBody = await response . text ( )
283+ const generatedText = extractTextFromSse ( responseBody )
249284 if ( ! generatedText ) {
250285 console . warn ( ' ⚠️ ChatGPT response missing text' )
251286 return null
0 commit comments