@@ -439,6 +439,54 @@ describe('thinking support (reasoning_content)', () => {
439439 expect ( blockStarts [ 1 ] . content_block . type ) . toBe ( 'tool_use' )
440440 } )
441441
442+ test ( 'opens thinking block on empty reasoning_content (DeepSeek v4 direct-answer)' , async ( ) => {
443+ // DeepSeek v4 thinking mode sometimes streams reasoning_content: ""
444+ // before answering directly. We must still open a thinking block so the
445+ // resulting assistant message carries an (empty) thinking block — that
446+ // round-trips back as reasoning_content: "" in the next request,
447+ // satisfying DeepSeek's requirement (see issue #399).
448+ const events = await collectEvents ( [
449+ makeChunk ( {
450+ choices : [
451+ {
452+ index : 0 ,
453+ delta : { reasoning_content : '' } ,
454+ finish_reason : null ,
455+ } ,
456+ ] ,
457+ } ) ,
458+ makeChunk ( {
459+ choices : [
460+ {
461+ index : 0 ,
462+ delta : { content : 'Direct answer.' } ,
463+ finish_reason : null ,
464+ } ,
465+ ] ,
466+ } ) ,
467+ makeChunk ( {
468+ choices : [ { index : 0 , delta : { } , finish_reason : 'stop' } ] ,
469+ } ) ,
470+ ] )
471+
472+ // A thinking block was opened (and closed before the text block starts)
473+ const blockStarts = events . filter (
474+ e => e . type === 'content_block_start' ,
475+ ) as any [ ]
476+ expect ( blockStarts . length ) . toBe ( 2 )
477+ expect ( blockStarts [ 0 ] . content_block . type ) . toBe ( 'thinking' )
478+ expect ( blockStarts [ 0 ] . content_block . thinking ) . toBe ( '' )
479+ expect ( blockStarts [ 1 ] . content_block . type ) . toBe ( 'text' )
480+
481+ // No empty thinking_delta should be emitted — the empty string is
482+ // already conveyed by the thinking block's initial value.
483+ const thinkingDeltas = events . filter (
484+ e =>
485+ e . type === 'content_block_delta' && e . delta . type === 'thinking_delta' ,
486+ )
487+ expect ( thinkingDeltas . length ) . toBe ( 0 )
488+ } )
489+
442490 test ( 'thinking block index is 0, text block index is 1' , async ( ) => {
443491 const events = await collectEvents ( [
444492 makeChunk ( {
0 commit comments