@@ -21,6 +21,7 @@ import type {
2121 AnthropicMessagesPayload ,
2222 AnthropicTextBlock ,
2323 AnthropicToolResultBlock ,
24+ AnthropicToolResultContentBlock ,
2425 AnthropicUserContentBlock ,
2526} from "./anthropic-types"
2627
@@ -185,32 +186,112 @@ const mergeContentWithText = (
185186 tr : AnthropicToolResultBlock ,
186187 textBlock : AnthropicTextBlock ,
187188) : AnthropicToolResultBlock => {
189+ const normalizedToolResult = normalizeToolResultContentCacheControl ( tr )
190+ const mergedToolResult = mergeToolResultCacheControl ( normalizedToolResult , [
191+ textBlock ,
192+ ] )
193+ const sanitizedTextBlock = stripContentBlockCacheControl ( textBlock )
194+
188195 if ( typeof tr . content === "string" ) {
189- return { ...tr , content : `${ tr . content } \n\n${ textBlock . text } ` }
196+ return {
197+ ...mergedToolResult ,
198+ content : `${ tr . content } \n\n${ textBlock . text } ` ,
199+ }
190200 }
191201 // Unable to merge, discard other text blocks, wait for the next round of re-request
192202 if ( hasToolRef ( tr ) ) {
193203 return tr
194204 }
195205 return {
196- ...tr ,
197- content : [ ...tr . content , textBlock ] ,
206+ ...mergedToolResult ,
207+ content : [ ...normalizedToolResult . content , sanitizedTextBlock ] ,
198208 }
199209}
200210
201211const mergeContentWithTexts = (
202212 tr : AnthropicToolResultBlock ,
203213 textBlocks : Array < AnthropicTextBlock > ,
204214) : AnthropicToolResultBlock => {
215+ const normalizedToolResult = normalizeToolResultContentCacheControl ( tr )
216+ const mergedToolResult = mergeToolResultCacheControl (
217+ normalizedToolResult ,
218+ textBlocks ,
219+ )
220+ const sanitizedTextBlocks = textBlocks . map ( stripContentBlockCacheControl )
221+
205222 if ( typeof tr . content === "string" ) {
206223 const appendedTexts = textBlocks . map ( ( tb ) => tb . text ) . join ( "\n\n" )
207- return { ...tr , content : `${ tr . content } \n\n${ appendedTexts } ` }
224+ return {
225+ ...mergedToolResult ,
226+ content : `${ tr . content } \n\n${ appendedTexts } ` ,
227+ }
208228 }
209229 // Unable to merge, discard other text blocks, wait for the next round of re-request
210230 if ( hasToolRef ( tr ) ) {
211231 return tr
212232 }
213- return { ...tr , content : [ ...tr . content , ...textBlocks ] }
233+ return {
234+ ...mergedToolResult ,
235+ content : [ ...normalizedToolResult . content , ...sanitizedTextBlocks ] ,
236+ }
237+ }
238+
239+ const mergeToolResultCacheControl = (
240+ tr : AnthropicToolResultBlock ,
241+ textBlocks : Array < AnthropicTextBlock > ,
242+ ) : AnthropicToolResultBlock => {
243+ const cacheControl = textBlocks
244+ . map ( ( block ) => block . cache_control )
245+ . findLast (
246+ ( candidate ) : candidate is AnthropicCacheControl =>
247+ Boolean ( candidate ) && typeof candidate === "object" ,
248+ )
249+
250+ if ( cacheControl ) {
251+ return { ...tr , cache_control : { ...cacheControl } }
252+ }
253+
254+ return tr . cache_control ?
255+ { ...tr , cache_control : { ...tr . cache_control } }
256+ : tr
257+ }
258+
259+ const stripContentBlockCacheControl = (
260+ block : AnthropicTextBlock ,
261+ ) : AnthropicTextBlock => {
262+ if ( ! block . cache_control ) {
263+ return block
264+ }
265+
266+ return {
267+ text : block . text ,
268+ type : "text" ,
269+ }
270+ }
271+
272+ const normalizeToolResultContentCacheControl = (
273+ tr : AnthropicToolResultBlock ,
274+ ) : AnthropicToolResultBlock & {
275+ content : Array < AnthropicToolResultContentBlock >
276+ } => {
277+ if ( typeof tr . content === "string" ) {
278+ return { ...tr , content : [ { type : "text" , text : tr . content } ] }
279+ }
280+
281+ let cacheControl = tr . cache_control
282+ const content = tr . content . map ( ( block ) => {
283+ if ( ! ( "cache_control" in block ) || ! block . cache_control ) {
284+ return block
285+ }
286+
287+ cacheControl = block . cache_control
288+ const { cache_control : _cacheControl , ...rest } = block
289+ return rest
290+ } )
291+
292+ return cacheControl ?
293+ { ...tr , cache_control : cacheControl , content }
294+ : { ...tr , content }
214295}
215296
216297const mergeContentWithAttachments = (
0 commit comments