Skip to content

Commit 15ac90d

Browse files
committed
Re-implement token caching for Vercel AI SDK usage with Anthropic provider (fixes #58)
1 parent 462cff6 commit 15ac90d

File tree

2 files changed

+41
-55
lines changed

2 files changed

+41
-55
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"mycoder-agent": patch
3+
---
4+
5+
Re-implemented token caching for Vercel AI SDK usage with Anthropic provider to reduce token consumption during repeated API calls.

packages/agent/src/core/toolAgent.ts

Lines changed: 36 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
ToolResultPart,
99
ToolSet,
1010
tool as makeTool,
11+
Message
1112
} from 'ai';
1213
import chalk from 'chalk';
1314

@@ -191,62 +192,39 @@ async function executeTools(
191192
};
192193
}
193194

194-
/*
195-
// a function that takes a list of messages and returns a list of messages but with the last message having a cache_control of ephemeral
196-
function addCacheControlToTools<T>(messages: T[]): T[] {
197-
return messages.map((m, i) => ({
198-
...m,
199-
...(i === messages.length - 1
200-
? { cache_control: { type: 'ephemeral' } }
201-
: {}),
202-
}));
203-
}
204-
205-
function addCacheControlToContentBlocks(
206-
content: ContentBlockParam[],
207-
): ContentBlockParam[] {
208-
return content.map((c, i) => {
209-
if (i === content.length - 1) {
210-
if (
211-
c.type === 'text' ||
212-
c.type === 'document' ||
213-
c.type === 'image' ||
214-
c.type === 'tool_use' ||
215-
c.type === 'tool_result' ||
216-
c.type === 'thinking' ||
217-
c.type === 'redacted_thinking'
218-
) {
219-
return { ...c, cache_control: { type: 'ephemeral' } };
220-
}
195+
/**
196+
* Adds cache control to the messages for token caching with the Vercel AI SDK
197+
* This marks the last message as ephemeral to prevent it from being cached
198+
* which helps reduce token usage when making multiple API calls
199+
*/
200+
function addCacheControlToMessages(messages: CoreMessage[]): CoreMessage[] {
201+
if (messages.length === 0) return messages;
202+
203+
// Create a deep copy of the messages array to avoid mutating the original
204+
const result = JSON.parse(JSON.stringify(messages)) as CoreMessage[];
205+
206+
// Get the last message
207+
const lastMessage = result[result.length - 1];
208+
209+
// Add cache_control to the last message
210+
if (lastMessage) {
211+
// For the Vercel AI SDK, we need to add the cache_control property
212+
// to indicate that this message should not be cached
213+
(lastMessage as any).cache_control = { type: 'ephemeral' };
214+
215+
// If the message has content array, mark each content item as ephemeral
216+
if (Array.isArray(lastMessage.content)) {
217+
lastMessage.content = lastMessage.content.map(item => {
218+
return {
219+
...item,
220+
cache_control: { type: 'ephemeral' }
221+
};
222+
});
221223
}
222-
return c;
223-
});
224+
}
225+
226+
return result;
224227
}
225-
function addCacheControlToMessages(
226-
messages: Anthropic.Messages.MessageParam[],
227-
): Anthropic.Messages.MessageParam[] {
228-
return messages.map((m, i) => {
229-
if (typeof m.content === 'string') {
230-
return {
231-
...m,
232-
content: [
233-
{
234-
type: 'text',
235-
text: m.content,
236-
cache_control: { type: 'ephemeral' },
237-
},
238-
] as ContentBlockParam[],
239-
};
240-
}
241-
return {
242-
...m,
243-
content:
244-
i >= messages.length - 2
245-
? addCacheControlToContentBlocks(m.content)
246-
: m.content,
247-
};
248-
});
249-
}*/
250228

251229
export const toolAgent = async (
252230
initialPrompt: string,
@@ -293,10 +271,13 @@ export const toolAgent = async (
293271
parameters: tool.parameters,
294272
});
295273
});
274+
// Apply cache control to messages for token caching
275+
const messagesWithCacheControl = addCacheControlToMessages(messages);
276+
296277
const generateTextProps = {
297278
model: config.model,
298279
temperature: config.temperature,
299-
messages,
280+
messages: messagesWithCacheControl,
300281
system: systemPrompt,
301282
tools: toolSet,
302283
};

0 commit comments

Comments
 (0)