@@ -10,6 +10,11 @@ import {
1010 ToolCallResultEvent ,
1111 StateSnapshotEvent ,
1212 StateDeltaEvent ,
13+ ReasoningStartEvent ,
14+ ReasoningMessageStartEvent ,
15+ ReasoningMessageContentEvent ,
16+ ReasoningMessageEndEvent ,
17+ ReasoningEndEvent ,
1318} from "@ag-ui/client" ;
1419import { randomUUID } from "@copilotkit/shared" ;
1520
@@ -232,6 +237,8 @@ export async function* convertTanStackStream(
232237) : AsyncGenerator < BaseEvent > {
233238 const messageId = randomUUID ( ) ;
234239 const toolNamesById = new Map < string , string > ( ) ;
240+ let isInReasoning = false ;
241+ let reasoningMessageId = randomUUID ( ) ;
235242
236243 for await ( const chunk of stream ) {
237244 if ( abortSignal . aborted ) break ;
@@ -323,11 +330,45 @@ export async function* convertTanStackStream(
323330 } ;
324331 yield resultEvent ;
325332 toolNamesById . delete ( toolCallId ) ;
333+ } else if ( type === "REASONING_START" ) {
334+ isInReasoning = true ;
335+ reasoningMessageId = ( raw . messageId as string ) ?? randomUUID ( ) ;
336+ const startEvt : ReasoningStartEvent = {
337+ type : EventType . REASONING_START ,
338+ messageId : reasoningMessageId ,
339+ } ;
340+ yield startEvt ;
341+ } else if ( type === "REASONING_MESSAGE_START" ) {
342+ const evt : ReasoningMessageStartEvent = {
343+ type : EventType . REASONING_MESSAGE_START ,
344+ messageId : reasoningMessageId ,
345+ role : "reasoning" ,
346+ } ;
347+ yield evt ;
348+ } else if ( type === "REASONING_MESSAGE_CONTENT" ) {
349+ const evt : ReasoningMessageContentEvent = {
350+ type : EventType . REASONING_MESSAGE_CONTENT ,
351+ messageId : reasoningMessageId ,
352+ delta : raw . delta as string ,
353+ } ;
354+ yield evt ;
355+ } else if ( type === "REASONING_MESSAGE_END" ) {
356+ const evt : ReasoningMessageEndEvent = {
357+ type : EventType . REASONING_MESSAGE_END ,
358+ messageId : reasoningMessageId ,
359+ } ;
360+ yield evt ;
361+ } else if ( type === "REASONING_END" ) {
362+ isInReasoning = false ;
363+ const evt : ReasoningEndEvent = {
364+ type : EventType . REASONING_END ,
365+ messageId : reasoningMessageId ,
366+ } ;
367+ yield evt ;
326368 }
327369 // Unhandled chunk types are silently ignored.
328- // Known gap: REASONING events are not yet converted from TanStack streams.
329- // Reasoning will not surface when using the TanStack backend.
330- // Use the AI SDK backend if reasoning is required.
370+ // Reasoning auto-close (closing an open reasoning lifecycle when text/tool
371+ // arrives without explicit close events) is handled in the next task.
331372 }
332373}
333374
0 commit comments