@@ -10,62 +10,67 @@ import type {
1010 UserCodebuffMessage ,
1111} from '../types/messages/codebuff-message'
1212import type { ModelMessage } from 'ai'
13+ import type { ProviderMetadata } from 'src/types/messages/provider-metadata'
1314
1415export function toContentString ( msg : ModelMessage ) : string {
1516 const { content } = msg
1617 if ( typeof content === 'string' ) return content
1718 return content . map ( ( item ) => ( item as any ) ?. text ?? '' ) . join ( '\n' )
1819}
1920
20- export function withCacheControl < T extends CodebuffMessage > ( msg : T ) : T {
21- const message = deepCopy ( msg )
22- if ( ! message . providerOptions ) {
23- message . providerOptions = { }
21+ export function withCacheControl <
22+ T extends { providerOptions ?: ProviderMetadata } ,
23+ > ( obj : T ) : T {
24+ const wrapper = deepCopy ( obj )
25+ if ( ! wrapper . providerOptions ) {
26+ wrapper . providerOptions = { }
2427 }
25- if ( ! message . providerOptions . anthropic ) {
26- message . providerOptions . anthropic = { }
28+ if ( ! wrapper . providerOptions . anthropic ) {
29+ wrapper . providerOptions . anthropic = { }
2730 }
28- message . providerOptions . anthropic . cacheControl = { type : 'ephemeral' }
29- if ( ! message . providerOptions . openrouter ) {
30- message . providerOptions . openrouter = { }
31+ wrapper . providerOptions . anthropic . cacheControl = { type : 'ephemeral' }
32+ if ( ! wrapper . providerOptions . openrouter ) {
33+ wrapper . providerOptions . openrouter = { }
3134 }
32- message . providerOptions . openrouter . cacheControl = { type : 'ephemeral' }
33- return message
35+ wrapper . providerOptions . openrouter . cacheControl = { type : 'ephemeral' }
36+ return wrapper
3437}
3538
36- export function withoutCacheControl < T extends CodebuffMessage > ( msg : T ) : T {
37- const message = deepCopy ( msg )
38- if ( hasKey ( message . providerOptions ?. anthropic ?. cacheControl , 'type' ) ) {
39- delete message . providerOptions ?. anthropic ?. cacheControl ?. type
39+ export function withoutCacheControl <
40+ T extends { providerOptions ?: ProviderMetadata } ,
41+ > ( obj : T ) : T {
42+ const wrapper = deepCopy ( obj )
43+ if ( hasKey ( wrapper . providerOptions ?. anthropic ?. cacheControl , 'type' ) ) {
44+ delete wrapper . providerOptions ?. anthropic ?. cacheControl ?. type
4045 }
4146 if (
42- Object . keys ( message . providerOptions ?. anthropic ?. cacheControl ?? { } )
47+ Object . keys ( wrapper . providerOptions ?. anthropic ?. cacheControl ?? { } )
4348 . length === 0
4449 ) {
45- delete message . providerOptions ?. anthropic ?. cacheControl
50+ delete wrapper . providerOptions ?. anthropic ?. cacheControl
4651 }
47- if ( Object . keys ( message . providerOptions ?. anthropic ?? { } ) . length === 0 ) {
48- delete message . providerOptions ?. anthropic
52+ if ( Object . keys ( wrapper . providerOptions ?. anthropic ?? { } ) . length === 0 ) {
53+ delete wrapper . providerOptions ?. anthropic
4954 }
5055
51- if ( hasKey ( message . providerOptions ?. openrouter ?. cacheControl , 'type' ) ) {
52- delete message . providerOptions ?. openrouter ?. cacheControl ?. type
56+ if ( hasKey ( wrapper . providerOptions ?. openrouter ?. cacheControl , 'type' ) ) {
57+ delete wrapper . providerOptions ?. openrouter ?. cacheControl ?. type
5358 }
5459 if (
55- Object . keys ( message . providerOptions ?. openrouter ?. cacheControl ?? { } )
60+ Object . keys ( wrapper . providerOptions ?. openrouter ?. cacheControl ?? { } )
5661 . length === 0
5762 ) {
58- delete message . providerOptions ?. openrouter ?. cacheControl
63+ delete wrapper . providerOptions ?. openrouter ?. cacheControl
5964 }
60- if ( Object . keys ( message . providerOptions ?. openrouter ?? { } ) . length === 0 ) {
61- delete message . providerOptions ?. openrouter
65+ if ( Object . keys ( wrapper . providerOptions ?. openrouter ?? { } ) . length === 0 ) {
66+ delete wrapper . providerOptions ?. openrouter
6267 }
6368
64- if ( Object . keys ( message . providerOptions ?? { } ) . length === 0 ) {
65- delete message . providerOptions
69+ if ( Object . keys ( wrapper . providerOptions ?? { } ) . length === 0 ) {
70+ delete wrapper . providerOptions
6671 }
6772
68- return message
73+ return wrapper
6974}
7075
7176type Nested < P > = Parameters < typeof buildArray < P > > [ 0 ]
@@ -204,9 +209,7 @@ export function convertCbToModelMessages({
204209 messages : CodebuffMessage [ ]
205210 includeCacheControl ?: boolean
206211} ) : ModelMessage [ ] {
207- const noToolMessages = buildArray (
208- messages . map ( ( m ) => convertToolMessages ( withoutCacheControl ( m ) ) ) ,
209- )
212+ const noToolMessages = buildArray ( messages . map ( ( m ) => convertToolMessages ( m ) ) )
210213
211214 const aggregated : typeof noToolMessages = [ ]
212215 for ( const message of noToolMessages ) {
@@ -250,10 +253,27 @@ export function convertCbToModelMessages({
250253 if ( index <= 0 ) {
251254 continue
252255 }
253- aggregated [ index - 1 ] = withCacheControl ( aggregated [ index - 1 ] )
256+ const prevMessage = aggregated [ index - 1 ]
257+ const contentBlock = prevMessage . content
258+ if ( typeof contentBlock === 'string' ) {
259+ aggregated [ index - 1 ] = withCacheControl ( aggregated [ index - 1 ] )
260+ continue
261+ }
262+ contentBlock [ contentBlock . length - 1 ] = withCacheControl (
263+ contentBlock [ contentBlock . length - 1 ] ,
264+ )
265+ }
266+
267+ const lastMessage = aggregated [ aggregated . length - 1 ]
268+ const contentBlock = lastMessage . content
269+ if ( typeof contentBlock === 'string' ) {
270+ aggregated [ aggregated . length - 1 ] = withCacheControl (
271+ aggregated [ aggregated . length - 1 ] ,
272+ )
273+ return aggregated
254274 }
255- aggregated [ aggregated . length - 1 ] = withCacheControl (
256- aggregated [ aggregated . length - 1 ] ,
275+ contentBlock [ contentBlock . length - 1 ] = withCacheControl (
276+ contentBlock [ contentBlock . length - 1 ] ,
257277 )
258278
259279 return aggregated
0 commit comments