@@ -198,12 +198,13 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
198198 providerOptions,
199199 schema : openaiResponsesProviderOptionsSchema ,
200200 } )
201+ const store = openaiOptions ?. store ?? false
201202
202203 const { input, warnings : inputWarnings } = await convertToOpenAIResponsesInput ( {
203204 prompt,
204205 systemMessageMode : modelConfig . systemMessageMode ,
205206 fileIdPrefixes : this . config . fileIdPrefixes ,
206- store : openaiOptions ?. store ?? true ,
207+ store,
207208 hasLocalShellTool : hasOpenAITool ( "openai.local_shell" ) ,
208209 } )
209210
@@ -214,9 +215,12 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
214215 let include : OpenAIResponsesIncludeOptions = openaiOptions ?. include
215216
216217 function addInclude ( key : OpenAIResponsesIncludeValue ) {
218+ if ( include ?. includes ( key ) ) return
217219 include = include != null ? [ ...include , key ] : [ key ]
218220 }
219221
222+ addInclude ( "reasoning.encrypted_content" )
223+
220224 function hasOpenAITool ( id : string ) {
221225 return tools ?. find ( ( tool ) => tool . type === "provider" && tool . id === id ) != null
222226 }
@@ -282,7 +286,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
282286 metadata : openaiOptions ?. metadata ,
283287 parallel_tool_calls : openaiOptions ?. parallelToolCalls ,
284288 previous_response_id : openaiOptions ?. previousResponseId ,
285- store : openaiOptions ?. store ,
289+ store,
286290 user : openaiOptions ?. user ,
287291 instructions : openaiOptions ?. instructions ,
288292 service_tier : openaiOptions ?. serviceTier ,
@@ -840,7 +844,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
840844 {
841845 canonicalId : string // the item.id from output_item.added
842846 encryptedContent ?: string | null
843- summaryParts : number [ ]
847+ summaryParts : Record < number , "active" | "can-conclude" | "concluded" >
844848 }
845849 > = { }
846850
@@ -960,11 +964,14 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
960964 } ,
961965 } )
962966 } else if ( isResponseOutputItemAddedReasoningChunk ( value ) ) {
963- if ( activeReasoning [ value . output_index ] ) return
967+ if ( activeReasoning [ value . output_index ] ) {
968+ currentReasoningOutputIndex = value . output_index
969+ return
970+ }
964971 activeReasoning [ value . output_index ] = {
965972 canonicalId : value . item . id ,
966973 encryptedContent : value . item . encrypted_content ,
967- summaryParts : [ 0 ] ,
974+ summaryParts : { 0 : "active" } ,
968975 }
969976 currentReasoningOutputIndex = value . output_index
970977
@@ -1118,14 +1125,14 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
11181125 } else if ( isResponseOutputItemDoneReasoningChunk ( value ) ) {
11191126 const activeReasoningPart = activeReasoning [ value . output_index ]
11201127 if ( activeReasoningPart ) {
1121- const summaryIndex = activeReasoningPart . summaryParts . at ( - 1 )
1122- if ( summaryIndex !== undefined ) {
1128+ for ( const [ summaryIndex , status ] of Object . entries ( activeReasoningPart . summaryParts ) ) {
1129+ if ( status === "concluded" ) continue
11231130 controller . enqueue ( {
11241131 type : "reasoning-end" ,
11251132 id : `${ activeReasoningPart . canonicalId } :${ summaryIndex } ` ,
11261133 providerMetadata : {
11271134 copilot : {
1128- itemId : activeReasoningPart . canonicalId ,
1135+ itemId : value . item . id ,
11291136 reasoningEncryptedContent : value . item . encrypted_content ?? null ,
11301137 } ,
11311138 } ,
@@ -1230,18 +1237,19 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
12301237 currentReasoningOutputIndex !== null ? activeReasoning [ currentReasoningOutputIndex ] : null
12311238
12321239 // the first reasoning start is pushed in isResponseOutputItemAddedReasoningChunk.
1233- if ( activeItem && value . summary_index > 0 && ! activeItem . summaryParts . includes ( value . summary_index ) ) {
1234- const previousSummaryIndex = activeItem . summaryParts . at ( - 1 )
1235- if ( previousSummaryIndex !== undefined ) {
1240+ if ( activeItem && value . summary_index > 0 && activeItem . summaryParts [ value . summary_index ] === undefined ) {
1241+ for ( const [ summaryIndex , status ] of Object . entries ( activeItem . summaryParts ) ) {
1242+ if ( status !== "can-conclude" ) continue
12361243 controller . enqueue ( {
12371244 type : "reasoning-end" ,
1238- id : `${ activeItem . canonicalId } :${ previousSummaryIndex } ` ,
1245+ id : `${ activeItem . canonicalId } :${ summaryIndex } ` ,
12391246 providerMetadata : {
12401247 copilot : { itemId : activeItem . canonicalId } ,
12411248 } ,
12421249 } )
1250+ activeItem . summaryParts [ Number ( summaryIndex ) ] = "concluded"
12431251 }
1244- activeItem . summaryParts . push ( value . summary_index )
1252+ activeItem . summaryParts [ value . summary_index ] = "active"
12451253
12461254 controller . enqueue ( {
12471255 type : "reasoning-start" ,
@@ -1254,6 +1262,22 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
12541262 } ,
12551263 } )
12561264 }
1265+ } else if ( isResponseReasoningSummaryPartDoneChunk ( value ) ) {
1266+ const activeItem =
1267+ currentReasoningOutputIndex !== null ? activeReasoning [ currentReasoningOutputIndex ] : null
1268+ if ( ! activeItem || activeItem . summaryParts [ value . summary_index ] !== "active" ) return
1269+ if ( body . store === false ) {
1270+ activeItem . summaryParts [ value . summary_index ] = "can-conclude"
1271+ return
1272+ }
1273+ controller . enqueue ( {
1274+ type : "reasoning-end" ,
1275+ id : `${ activeItem . canonicalId } :${ value . summary_index } ` ,
1276+ providerMetadata : {
1277+ copilot : { itemId : activeItem . canonicalId } ,
1278+ } ,
1279+ } )
1280+ activeItem . summaryParts [ value . summary_index ] = "concluded"
12571281 } else if ( isResponseReasoningSummaryTextDeltaChunk ( value ) ) {
12581282 const activeItem =
12591283 currentReasoningOutputIndex !== null ? activeReasoning [ currentReasoningOutputIndex ] : null
@@ -1316,6 +1340,16 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
13161340 controller . enqueue ( { type : "text-end" , id : currentTextId } )
13171341 currentTextId = null
13181342 }
1343+ for ( const activeItem of Object . values ( activeReasoning ) ) {
1344+ for ( const [ summaryIndex , status ] of Object . entries ( activeItem . summaryParts ) ) {
1345+ if ( status === "concluded" ) continue
1346+ controller . enqueue ( {
1347+ type : "reasoning-end" ,
1348+ id : `${ activeItem . canonicalId } :${ summaryIndex } ` ,
1349+ providerMetadata : { copilot : { itemId : activeItem . canonicalId } } ,
1350+ } )
1351+ }
1352+ }
13191353
13201354 const providerMetadata : SharedV3ProviderMetadata = {
13211355 copilot : {
@@ -1564,6 +1598,12 @@ const responseReasoningSummaryTextDeltaSchema = z.object({
15641598 delta : z . string ( ) ,
15651599} )
15661600
1601+ const responseReasoningSummaryPartDoneSchema = z . object ( {
1602+ type : z . literal ( "response.reasoning_summary_part.done" ) ,
1603+ item_id : z . string ( ) ,
1604+ summary_index : z . number ( ) ,
1605+ } )
1606+
15671607const openaiResponsesChunkSchema = z . union ( [
15681608 textDeltaChunkSchema ,
15691609 responseFinishedChunkSchema ,
@@ -1576,6 +1616,7 @@ const openaiResponsesChunkSchema = z.union([
15761616 responseCodeInterpreterCallCodeDoneSchema ,
15771617 responseAnnotationAddedSchema ,
15781618 responseReasoningSummaryPartAddedSchema ,
1619+ responseReasoningSummaryPartDoneSchema ,
15791620 responseReasoningSummaryTextDeltaSchema ,
15801621 errorChunkSchema ,
15811622 z . object ( { type : z . string ( ) } ) . loose ( ) , // fallback for unknown chunks
@@ -1664,6 +1705,12 @@ function isResponseReasoningSummaryPartAddedChunk(
16641705 return chunk . type === "response.reasoning_summary_part.added"
16651706}
16661707
1708+ function isResponseReasoningSummaryPartDoneChunk (
1709+ chunk : z . infer < typeof openaiResponsesChunkSchema > ,
1710+ ) : chunk is z . infer < typeof responseReasoningSummaryPartDoneSchema > {
1711+ return chunk . type === "response.reasoning_summary_part.done"
1712+ }
1713+
16671714function isResponseReasoningSummaryTextDeltaChunk (
16681715 chunk : z . infer < typeof openaiResponsesChunkSchema > ,
16691716) : chunk is z . infer < typeof responseReasoningSummaryTextDeltaSchema > {
0 commit comments