@@ -88,6 +88,44 @@ function createUndescribedImageContext(
8888 } ;
8989}
9090
91+ function mergeImagePayloads ( params : {
92+ baseImages ?: ImageContent [ ] ;
93+ baseImageOrder ?: PromptImageOrderEntry [ ] ;
94+ nextImages ?: ImageContent [ ] ;
95+ nextImageOrder ?: PromptImageOrderEntry [ ] ;
96+ } ) : {
97+ images ?: ImageContent [ ] ;
98+ imageOrder ?: PromptImageOrderEntry [ ] ;
99+ } {
100+ const nextImages = params . nextImages ?? [ ] ;
101+ if ( nextImages . length === 0 ) {
102+ return { images : params . baseImages , imageOrder : params . baseImageOrder } ;
103+ }
104+ const images = [ ...( params . baseImages ?? [ ] ) , ...nextImages ] ;
105+ const nextOrder =
106+ params . nextImageOrder && params . nextImageOrder . length === nextImages . length
107+ ? params . nextImageOrder
108+ : nextImages . map ( ( ) => "inline" as const ) ;
109+ return {
110+ images,
111+ imageOrder : [ ...( params . baseImageOrder ?? [ ] ) , ...nextOrder ] ,
112+ } ;
113+ }
114+
115+ export function takeCurrentTurnImages ( ctx : MsgContext ) : {
116+ images ?: ImageContent [ ] ;
117+ imageOrder ?: PromptImageOrderEntry [ ] ;
118+ } {
119+ const images = ctx . CurrentTurnImages ;
120+ const imageOrder = ctx . CurrentTurnImageOrder ;
121+ if ( images && images . length > 0 ) {
122+ delete ctx . CurrentTurnImages ;
123+ delete ctx . CurrentTurnImageOrder ;
124+ return { images, imageOrder } ;
125+ }
126+ return { } ;
127+ }
128+
91129/** Resolves current-turn image attachments that were not already described by media understanding. */
92130export async function resolveCurrentTurnImages ( params : {
93131 ctx : MsgContext ;
@@ -98,30 +136,37 @@ export async function resolveCurrentTurnImages(params: {
98136 images ?: ImageContent [ ] ;
99137 imageOrder ?: PromptImageOrderEntry [ ] ;
100138} > {
139+ const extractedImages = takeCurrentTurnImages ( params . ctx ) ;
140+ let resolved = mergeImagePayloads ( {
141+ baseImages : params . images ,
142+ baseImageOrder : params . imageOrder ,
143+ nextImages : extractedImages . images ,
144+ nextImageOrder : extractedImages . imageOrder ,
145+ } ) ;
101146 if ( Array . isArray ( params . images ) && params . images . length > 0 ) {
102- return { images : params . images , imageOrder : params . imageOrder } ;
147+ return resolved ;
103148 }
104149
105150 const currentImageAttachments = collectCurrentImageAttachments ( params . ctx ) ;
106151 if ( currentImageAttachments . length === 0 ) {
107- return { images : params . images , imageOrder : params . imageOrder } ;
152+ return resolved ;
108153 }
109154 const describedImageIndexes = collectDescribedImageAttachmentIndexes ( params . ctx ) ;
110155 const undescribedImageAttachments = currentImageAttachments . filter (
111156 ( attachment ) => ! describedImageIndexes . has ( attachment . index ) ,
112157 ) ;
113158 if ( undescribedImageAttachments . length === 0 ) {
114- return { images : params . images , imageOrder : params . imageOrder } ;
159+ return resolved ;
115160 }
116161
117162 try {
118163 // Only send undescribed current images natively; described images already exist as text context.
119- const resolved = await resolveAgentTurnAttachments ( {
164+ const attachmentResult = await resolveAgentTurnAttachments ( {
120165 ctx : createUndescribedImageContext ( params . ctx , undescribedImageAttachments ) ,
121166 cfg : params . cfg ,
122167 includeRecentHistoryImages : false ,
123168 } ) ;
124- const images = resolved . attachments . map (
169+ const images = attachmentResult . attachments . map (
125170 ( attachment ) : ImageContent => ( {
126171 type : "image" ,
127172 data : attachment . data ,
@@ -132,15 +177,22 @@ export async function resolveCurrentTurnImages(params: {
132177 logVerbose (
133178 `agent-runner: native OpenClaw media resolution produced ${ images . length } /${ undescribedImageAttachments . length } current image attachment(s); falling back to prompt image refs` ,
134179 ) ;
135- return { images : params . images , imageOrder : params . imageOrder } ;
180+ return resolved ;
181+ }
182+ if ( images . length === 0 ) {
183+ return resolved ;
136184 }
137- return images . length > 0
138- ? { images, imageOrder : images . map ( ( ) => "inline" as const ) }
139- : { images : params . images , imageOrder : params . imageOrder } ;
185+ resolved = mergeImagePayloads ( {
186+ baseImages : resolved . images ,
187+ baseImageOrder : resolved . imageOrder ,
188+ nextImages : images ,
189+ nextImageOrder : images . map ( ( ) => "inline" as const ) ,
190+ } ) ;
191+ return resolved ;
140192 } catch ( error ) {
141193 logVerbose (
142194 `agent-runner: media attachment image resolution failed, proceeding without native images: ${ formatErrorMessage ( error ) } ` ,
143195 ) ;
144- return { images : params . images , imageOrder : params . imageOrder } ;
196+ return resolved ;
145197 }
146198}
0 commit comments