@@ -16,6 +16,7 @@ export interface FetchAIResponseParams {
1616 receiveToken : ( token : string ) => Promise < any [ ] > ;
1717 activeMintUrl ?: string | null ;
1818 onStreamingUpdate : ( content : string ) => void ;
19+ onThinkingUpdate : ( content : string ) => void ;
1920 onMessagesUpdate : ( messages : Message [ ] ) => void ;
2021 onMessageAppend : ( message : Message ) => void ;
2122 onBalanceUpdate : ( balance : number ) => void ;
@@ -42,6 +43,7 @@ export const fetchAIResponse = async (params: FetchAIResponseParams): Promise<vo
4243 receiveToken,
4344 activeMintUrl,
4445 onStreamingUpdate,
46+ onThinkingUpdate,
4547 onMessagesUpdate,
4648 onMessageAppend,
4749 onBalanceUpdate,
@@ -126,7 +128,7 @@ export const fetchAIResponse = async (params: FetchAIResponseParams): Promise<vo
126128 throw new Error ( 'Response body is not available' ) ;
127129 }
128130
129- const streamingResult = await processStreamingResponse ( response , onStreamingUpdate , selectedModel ?. id ) ;
131+ const streamingResult = await processStreamingResponse ( response , onStreamingUpdate , onThinkingUpdate , selectedModel ?. id ) ;
130132
131133 if ( streamingResult . content ) {
132134 const assistantMessage = createTextMessage ( 'assistant' , streamingResult . content ) ;
@@ -146,6 +148,7 @@ export const fetchAIResponse = async (params: FetchAIResponseParams): Promise<vo
146148 }
147149
148150 onStreamingUpdate ( '' ) ;
151+ onThinkingUpdate ( '' ) ;
149152
150153 // Handle refund and balance update
151154 await handlePostResponseRefund ( {
@@ -290,13 +293,15 @@ interface StreamingResult {
290293async function processStreamingResponse (
291294 response : Response ,
292295 onStreamingUpdate : ( content : string ) => void ,
296+ onThinkingUpdate : ( content : string ) => void ,
293297 modelId ?: string
294298) : Promise < StreamingResult > {
295299 const reader = response . body ! . getReader ( ) ;
296300 const decoder = new TextDecoder ( 'utf-8' ) ;
297301 let accumulatedContent = '' ;
298302 let accumulatedThinking = '' ;
299303 let isInThinking = false ;
304+ let isInContent = false ;
300305 let usage : StreamingResult [ 'usage' ] ;
301306 let model : string | undefined ;
302307 let finish_reason : string | undefined ;
@@ -324,18 +329,52 @@ async function processStreamingResponse(
324329 try {
325330 const parsedData = JSON . parse ( jsonData ) ;
326331
327- // Handle content delta
332+ // Handle reasoning delta. OpenRouter does this.
328333 if ( parsedData . choices &&
334+ parsedData . choices [ 0 ] &&
335+ parsedData . choices [ 0 ] . delta &&
336+ parsedData . choices [ 0 ] . delta . reasoning ) {
337+
338+ let newContent ;
339+ if ( ! isInThinking ) {
340+ newContent = "<thinking> " + parsedData . choices [ 0 ] . delta . reasoning ;
341+ isInThinking = true ;
342+ }
343+ else {
344+ newContent = parsedData . choices [ 0 ] . delta . reasoning ;
345+ }
346+ const thinkingResult = extractThinkingFromStream ( newContent , accumulatedThinking ) ;
347+ accumulatedThinking = thinkingResult . thinking ;
348+ onThinkingUpdate ( accumulatedThinking )
349+ }
350+
351+ // Handle content delta
352+ else if ( parsedData . choices &&
329353 parsedData . choices [ 0 ] &&
330354 parsedData . choices [ 0 ] . delta &&
331355 parsedData . choices [ 0 ] . delta . content ) {
332356
357+ if ( isInThinking && ! isInContent ) {
358+ const newContent = "</thinking>" ;
359+ const thinkingResult = extractThinkingFromStream ( newContent , accumulatedThinking ) ;
360+ accumulatedThinking = thinkingResult . thinking ;
361+ onThinkingUpdate ( accumulatedThinking ) ;
362+
363+ if ( thinkingResult . content ) {
364+ accumulatedContent += thinkingResult . content ;
365+ onStreamingUpdate ( accumulatedContent ) ;
366+ }
367+ isInThinking = false ;
368+ isInContent = true ;
369+ }
370+
333371 const newContent = parsedData . choices [ 0 ] . delta . content ;
334372
335373 if ( modelId && isThinkingCapableModel ( modelId ) ) {
336374 const thinkingResult = extractThinkingFromStream ( newContent , accumulatedThinking ) ;
337375 accumulatedThinking = thinkingResult . thinking ;
338376 isInThinking = thinkingResult . isInThinking ;
377+ onThinkingUpdate ( accumulatedThinking ) ;
339378
340379 if ( thinkingResult . content ) {
341380 accumulatedContent += thinkingResult . content ;
@@ -379,7 +418,7 @@ async function processStreamingResponse(
379418
380419 return {
381420 content : accumulatedContent ,
382- thinking : ( modelId && isThinkingCapableModel ( modelId ) && accumulatedThinking ) ? accumulatedThinking : undefined ,
421+ thinking : ( modelId && accumulatedThinking ) ? accumulatedThinking : undefined ,
383422 usage,
384423 model,
385424 finish_reason
0 commit comments