|
8 | 8 | ToolResultPart, |
9 | 9 | ToolSet, |
10 | 10 | tool as makeTool, |
11 | | - Message |
12 | 11 | } from 'ai'; |
13 | 12 | import chalk from 'chalk'; |
14 | 13 |
|
@@ -192,40 +191,47 @@ async function executeTools( |
192 | 191 | }; |
193 | 192 | } |
194 | 193 |
|
| 194 | +function createCacheControlMessageFromSystemPrompt( |
| 195 | + systemPrompt: string, |
| 196 | +): CoreMessage { |
| 197 | + return { |
| 198 | + role: 'system', |
| 199 | + content: systemPrompt, |
| 200 | + providerOptions: { |
| 201 | + anthropic: { cacheControl: { type: 'ephemeral' } }, |
| 202 | + }, |
| 203 | + }; |
| 204 | +} |
| 205 | + |
195 | 206 | /** |
196 | 207 | * Adds cache control to the messages for token caching with the Vercel AI SDK |
197 | 208 | * This marks the last two messages as ephemeral which allows the conversation up to that |
198 | 209 | * point to be cached (with a ~5 minute window), reducing token usage when making multiple API calls |
199 | 210 | */ |
200 | 211 | function addCacheControlToMessages(messages: CoreMessage[]): CoreMessage[] { |
201 | 212 | if (messages.length <= 1) return messages; |
202 | | - |
| 213 | + |
203 | 214 | // Create a deep copy of the messages array to avoid mutating the original |
204 | 215 | const result = JSON.parse(JSON.stringify(messages)) as CoreMessage[]; |
205 | | - |
| 216 | + |
206 | 217 | // Get the last two messages (if available) |
207 | | - const lastTwoMessageIndices = [ |
208 | | - messages.length - 1, |
209 | | - messages.length - 2 |
210 | | - ]; |
211 | | - |
| 218 | + const lastTwoMessageIndices = [messages.length - 1, messages.length - 2]; |
| 219 | + |
212 | 220 | // Add providerOptions with anthropic cache control to the last two messages |
213 | | - lastTwoMessageIndices.forEach(index => { |
| 221 | + lastTwoMessageIndices.forEach((index) => { |
214 | 222 | if (index >= 0) { |
215 | 223 | const message = result[index]; |
216 | 224 | if (message) { |
217 | 225 | // For the Vercel AI SDK, we need to add the providerOptions.anthropic property |
218 | 226 | // with cacheControl: 'ephemeral' to enable token caching |
219 | 227 | message.providerOptions = { |
220 | 228 | ...message.providerOptions, |
221 | | - anthropic: { |
222 | | - cacheControl: 'ephemeral' |
223 | | - } |
| 229 | + anthropic: { cacheControl: { type: 'ephemeral' } }, |
224 | 230 | }; |
225 | 231 | } |
226 | 232 | } |
227 | 233 | }); |
228 | | - |
| 234 | + |
229 | 235 | return result; |
230 | 236 | } |
231 | 237 |
|
@@ -275,13 +281,15 @@ export const toolAgent = async ( |
275 | 281 | }); |
276 | 282 | }); |
277 | 283 | // Apply cache control to messages for token caching |
278 | | - const messagesWithCacheControl = addCacheControlToMessages(messages); |
279 | | - |
| 284 | + const messagesWithCacheControl = [ |
| 285 | + createCacheControlMessageFromSystemPrompt(systemPrompt), |
| 286 | + ...addCacheControlToMessages(messages), |
| 287 | + ]; |
| 288 | + |
280 | 289 | const generateTextProps = { |
281 | 290 | model: config.model, |
282 | 291 | temperature: config.temperature, |
283 | 292 | messages: messagesWithCacheControl, |
284 | | - system: systemPrompt, |
285 | 293 | tools: toolSet, |
286 | 294 | }; |
287 | 295 | const { text, toolCalls } = await generateText(generateTextProps); |
|
0 commit comments