1- import { CoreMessage , ToolCallPart } from 'ai' ;
1+ // Define our own message types to replace Vercel AI SDK types
2+ export interface MessageContent {
3+ type : string ;
4+ text ?: string ;
5+ toolName ?: string ;
6+ toolCallId ?: string ;
7+ args ?: any ;
8+ result ?: any ;
9+ }
10+
11+ export interface CoreMessage {
12+ role : 'system' | 'user' | 'assistant' | 'tool' ;
13+ content : string | MessageContent [ ] ;
14+ }
15+
16+ export interface ToolCallPart {
17+ type : 'tool-call' ;
18+ toolCallId : string ;
19+ toolName : string ;
20+ args : any ;
21+ }
222
323/**
4- * Creates a cache control message from a system prompt
5- * This is used for token caching with the Vercel AI SDK
24+ * Creates a message for llm-interface with caching enabled
25+ * This function will be enhanced in Phase 3 to support token caching with llm-interface
626 */
727export function createCacheControlMessageFromSystemPrompt (
828 systemPrompt : string ,
929) : CoreMessage {
1030 return {
1131 role : 'system' ,
1232 content : systemPrompt ,
13- providerOptions : {
14- anthropic : { cacheControl : { type : 'ephemeral' } } ,
15- } ,
1633 } ;
1734}
1835
1936/**
20- * Adds cache control to the messages for token caching with the Vercel AI SDK
21- * This marks the last two messages as ephemeral which allows the conversation up to that
22- * point to be cached (with a ~5 minute window), reducing token usage when making multiple API calls
37+ * Adds cache control to the messages
38+ * This function will be enhanced in Phase 3 to support token caching with llm-interface
2339 */
2440export function addCacheControlToMessages (
2541 messages : CoreMessage [ ] ,
2642) : CoreMessage [ ] {
27- if ( messages . length <= 1 ) return messages ;
28-
29- // Create a deep copy of the messages array to avoid mutating the original
30- const result = JSON . parse ( JSON . stringify ( messages ) ) as CoreMessage [ ] ;
31-
32- // Get the last two messages (if available)
33- const lastTwoMessageIndices = [ messages . length - 1 , messages . length - 2 ] ;
34-
35- // Add providerOptions with anthropic cache control to the last two messages
36- lastTwoMessageIndices . forEach ( ( index ) => {
37- if ( index >= 0 ) {
38- const message = result [ index ] ;
39- if ( message ) {
40- // For the Vercel AI SDK, we need to add the providerOptions.anthropic property
41- // with cacheControl: 'ephemeral' to enable token caching
42- message . providerOptions = {
43- ...message . providerOptions ,
44- anthropic : { cacheControl : { type : 'ephemeral' } } ,
45- } ;
46- }
47- }
48- } ) ;
49-
50- return result ;
43+ return messages ;
5144}
5245
5346/**
@@ -56,9 +49,9 @@ export function addCacheControlToMessages(
5649export function formatToolCalls ( toolCalls : any [ ] ) : any [ ] {
5750 return toolCalls . map ( ( call ) => ( {
5851 type : 'tool_use' ,
59- name : call . toolName ,
60- id : call . toolCallId ,
61- input : call . args ,
52+ name : call . name ,
53+ id : call . id ,
54+ input : call . input ,
6255 } ) ) ;
6356}
6457
@@ -68,8 +61,61 @@ export function formatToolCalls(toolCalls: any[]): any[] {
6861export function createToolCallParts ( toolCalls : any [ ] ) : Array < ToolCallPart > {
6962 return toolCalls . map ( ( toolCall ) => ( {
7063 type : 'tool-call' ,
71- toolCallId : toolCall . toolCallId ,
72- toolName : toolCall . toolName ,
73- args : toolCall . args ,
64+ toolCallId : toolCall . id ,
65+ toolName : toolCall . name ,
66+ args : toolCall . input ,
7467 } ) ) ;
7568}
69+
70+ /**
71+ * Converts CoreMessage format to llm-interface message format
72+ */
73+ export function convertToLLMInterfaceMessages ( messages : CoreMessage [ ] ) : any [ ] {
74+ return messages . map ( ( message ) => {
75+ if ( typeof message . content === 'string' ) {
76+ return {
77+ role : message . role ,
78+ content : message . content ,
79+ } ;
80+ } else {
81+ // Handle complex content (text or tool calls)
82+ if (
83+ message . role === 'assistant' &&
84+ message . content . some ( ( c ) => c . type === 'tool-call' )
85+ ) {
86+ // This is a message with tool calls
87+ return {
88+ role : message . role ,
89+ content : message . content
90+ . filter ( ( c ) => c . type === 'text' )
91+ . map ( ( c ) => c . text || '' )
92+ . join ( '' ) ,
93+ tool_calls : message . content
94+ . filter ( ( c ) => c . type === 'tool-call' )
95+ . map ( ( c ) => ( {
96+ id : c . toolCallId || '' ,
97+ type : 'function' ,
98+ function : {
99+ name : c . toolName || '' ,
100+ arguments : JSON . stringify ( c . args || { } ) ,
101+ } ,
102+ } ) ) ,
103+ } ;
104+ } else if ( message . role === 'tool' ) {
105+ // This is a tool response message
106+ const content = message . content [ 0 ] ;
107+ return {
108+ role : 'tool' ,
109+ tool_call_id : content ?. toolCallId || '' ,
110+ content : content ?. result ? JSON . stringify ( content . result ) : '{}' ,
111+ } ;
112+ } else {
113+ // Regular user or assistant message with text content
114+ return {
115+ role : message . role ,
116+ content : message . content . map ( ( c ) => c . text || '' ) . join ( '' ) ,
117+ } ;
118+ }
119+ }
120+ } ) ;
121+ }
0 commit comments