This commit is contained in:
Saoud Rizwan
2025-02-18 10:49:37 -08:00
parent ec3bd56903
commit e40e6ddbcd
3 changed files with 24 additions and 34 deletions
+3 -6
View File
@@ -103,14 +103,11 @@ export class OpenRouterHandler implements ApiHandler {
let temperature = 0
let topP: number | undefined = undefined
// Handle models based on deepseek-r1
if (this.getModel().id.startsWith("deepseek/deepseek-r1") || this.getModel().id === "perplexity/sonar-reasoning") {
// Recommended temperature for DeepSeek reasoning models
temperature = 0.6
// DeepSeek highly recommends using user instead of system role
openAiMessages = convertToR1Format([{ role: "user", content: systemPrompt }, ...messages])
// Some provider support topP and 0.95 is value that Deepseek used in their benchmarks
// Recommended values from DeepSeek
temperature = 0.7
topP = 0.95
openAiMessages = convertToR1Format([{ role: "user", content: systemPrompt }, ...messages])
}
// Removes messages in the middle when close to context window limit. Should not be applied to models that support prompt caching since it would continuously break the cache.
+21 -27
View File
@@ -1,30 +1,24 @@
import { Anthropic } from "@anthropic-ai/sdk"
import OpenAI from "openai"
type ContentPartText = OpenAI.Chat.ChatCompletionContentPartText
type ContentPartImage = OpenAI.Chat.ChatCompletionContentPartImage
type UserMessage = OpenAI.Chat.ChatCompletionUserMessageParam
type AssistantMessage = OpenAI.Chat.ChatCompletionAssistantMessageParam
type Message = OpenAI.Chat.ChatCompletionMessageParam
type AnthropicMessage = Anthropic.Messages.MessageParam
/**
* Converts Anthropic messages to OpenAI format while merging consecutive messages with the same role.
* Converts Anthropic messages to OpenAI format and merges consecutive messages with the same role.
* This is required for DeepSeek Reasoner which does not support successive messages with the same role.
* DeepSeek highly recommends using 'user' role instead of 'system' role for optimal performance.
*
* @param messages Array of Anthropic messages
* @returns Array of OpenAI messages where consecutive messages with the same role are combined
* @returns Array of OpenAI messages where consecutive messages with the same role are merged together
*/
export function convertToR1Format(messages: AnthropicMessage[]): Message[] {
return messages.reduce<Message[]>((merged, message) => {
export function convertToR1Format(messages: Anthropic.Messages.MessageParam[]): OpenAI.Chat.ChatCompletionMessageParam[] {
return messages.reduce<OpenAI.Chat.ChatCompletionMessageParam[]>((merged, message) => {
const lastMessage = merged[merged.length - 1]
let messageContent: string | (ContentPartText | ContentPartImage)[] = ""
let messageContent: string | (OpenAI.Chat.ChatCompletionContentPartText | OpenAI.Chat.ChatCompletionContentPartImage)[] =
""
let hasImages = false
// Convert content to appropriate format
if (Array.isArray(message.content)) {
const textParts: string[] = []
const imageParts: ContentPartImage[] = []
const imageParts: OpenAI.Chat.ChatCompletionContentPartImage[] = []
message.content.forEach((part) => {
if (part.type === "text") {
@@ -40,7 +34,7 @@ export function convertToR1Format(messages: AnthropicMessage[]): Message[] {
})
if (hasImages) {
const parts: (ContentPartText | ContentPartImage)[] = []
const parts: (OpenAI.Chat.ChatCompletionContentPartText | OpenAI.Chat.ChatCompletionContentPartImage)[] = []
if (textParts.length > 0) {
parts.push({ type: "text", text: textParts.join("\n") })
}
@@ -53,13 +47,11 @@ export function convertToR1Format(messages: AnthropicMessage[]): Message[] {
messageContent = message.content
}
// If last message has same role, merge the content
// If the last message has the same role, merge the content
if (lastMessage?.role === message.role) {
if (typeof lastMessage.content === "string" && typeof messageContent === "string") {
lastMessage.content += `\n${messageContent}`
}
// If either has image content, convert both to array format
else {
} else {
const lastContent = Array.isArray(lastMessage.content)
? lastMessage.content
: [{ type: "text" as const, text: lastMessage.content || "" }]
@@ -69,30 +61,32 @@ export function convertToR1Format(messages: AnthropicMessage[]): Message[] {
: [{ type: "text" as const, text: messageContent }]
if (message.role === "assistant") {
const mergedContent = [...lastContent, ...newContent] as AssistantMessage["content"]
const mergedContent = [
...lastContent,
...newContent,
] as OpenAI.Chat.ChatCompletionAssistantMessageParam["content"]
lastMessage.content = mergedContent
} else {
const mergedContent = [...lastContent, ...newContent] as UserMessage["content"]
const mergedContent = [...lastContent, ...newContent] as OpenAI.Chat.ChatCompletionUserMessageParam["content"]
lastMessage.content = mergedContent
}
}
} else {
// Add as new message with the correct type based on role
// Adds new message with the correct type based on role
if (message.role === "assistant") {
const newMessage: AssistantMessage = {
const newMessage: OpenAI.Chat.ChatCompletionAssistantMessageParam = {
role: "assistant",
content: messageContent as AssistantMessage["content"],
content: messageContent as OpenAI.Chat.ChatCompletionAssistantMessageParam["content"],
}
merged.push(newMessage)
} else {
const newMessage: UserMessage = {
const newMessage: OpenAI.Chat.ChatCompletionUserMessageParam = {
role: "user",
content: messageContent as UserMessage["content"],
content: messageContent as OpenAI.Chat.ChatCompletionUserMessageParam["content"],
}
merged.push(newMessage)
}
}
return merged
}, [])
}
-1
View File
@@ -3137,7 +3137,6 @@ export class Cline {
try {
for await (const chunk of stream) {
if (!chunk) {
// Sometimes chunk is undefined, no idea that can cause it, but this workaround seems to fix it
continue
}
switch (chunk.type) {