Skip to content

Commit 10c1e7d

Browse files
committed
Add cache control key to messages in OpenAI compatible provider
1 parent 421e197 commit 10c1e7d

File tree

1 file changed

+36
-1
lines changed

1 file changed

+36
-1
lines changed

src/api/providers/openai.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl
7272
}
7373

7474
if (this.options.openAiStreamingEnabled ?? true) {
75-
const systemMessage: OpenAI.Chat.ChatCompletionSystemMessageParam = {
75+
let systemMessage: OpenAI.Chat.ChatCompletionSystemMessageParam = {
7676
role: "system",
7777
content: systemPrompt,
7878
}
@@ -83,7 +83,42 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl
8383
} else if (ark) {
8484
convertedMessages = [systemMessage, ...convertToSimpleMessages(messages)]
8585
} else {
86+
if (modelInfo.supportsPromptCache) {
87+
systemMessage = {
88+
role: "system",
89+
content: [
90+
{
91+
type: "text",
92+
text: systemPrompt,
93+
// @ts-ignore-next-line
94+
cache_control: { type: "ephemeral" },
95+
},
96+
],
97+
}
98+
}
8699
convertedMessages = [systemMessage, ...convertToOpenAiMessages(messages)]
100+
if (modelInfo.supportsPromptCache) {
101+
// Note: the following logic is copied from openrouter:
102+
// Add cache_control to the last two user messages
103+
// (note: this works because we only ever add one user message at a time, but if we added multiple we'd need to mark the user message before the last assistant message)
104+
const lastTwoUserMessages = convertedMessages.filter((msg) => msg.role === "user").slice(-2)
105+
lastTwoUserMessages.forEach((msg) => {
106+
if (typeof msg.content === "string") {
107+
msg.content = [{ type: "text", text: msg.content }]
108+
}
109+
if (Array.isArray(msg.content)) {
110+
// NOTE: this is fine since env details will always be added at the end. but if it weren't there, and the user added a image_url type message, it would pop a text part before it and then move it after to the end.
111+
let lastTextPart = msg.content.filter((part) => part.type === "text").pop()
112+
113+
if (!lastTextPart) {
114+
lastTextPart = { type: "text", text: "..." }
115+
msg.content.push(lastTextPart)
116+
}
117+
// @ts-ignore-next-line
118+
lastTextPart["cache_control"] = { type: "ephemeral" }
119+
}
120+
})
121+
}
87122
}
88123

89124
const requestOptions: OpenAI.Chat.Completions.ChatCompletionCreateParamsStreaming = {

0 commit comments

Comments
 (0)