mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-26 03:31:24 +08:00
fix/anthropic-vertex (#11397)
* 100m * feat: add web search header for Claude 4 series models * fix: typo * fix: identify model --------- Co-authored-by: defi-failure <159208748+defi-failure@users.noreply.github.com>
This commit is contained in:
parent
f98a063a8f
commit
a1ac3207f1
@ -1,13 +1,32 @@
|
||||
import { isClaude45ReasoningModel } from '@renderer/config/models'
|
||||
import { isClaude4SeriesModel, isClaude45ReasoningModel } from '@renderer/config/models'
|
||||
import { isAwsBedrockProvider } from '@renderer/config/providers'
|
||||
import { isVertexProvider } from '@renderer/hooks/useVertexAI'
|
||||
import { getProviderByModel } from '@renderer/services/AssistantService'
|
||||
import type { Assistant, Model } from '@renderer/types'
|
||||
import { isToolUseModeFunction } from '@renderer/utils/assistant'
|
||||
|
||||
// https://docs.claude.com/en/docs/build-with-claude/extended-thinking#interleaved-thinking
|
||||
const INTERLEAVED_THINKING_HEADER = 'interleaved-thinking-2025-05-14'
|
||||
// https://docs.claude.com/en/docs/build-with-claude/context-windows#1m-token-context-window
|
||||
const CONTEXT_100M_HEADER = 'context-1m-2025-08-07'
|
||||
// https://docs.cloud.google.com/vertex-ai/generative-ai/docs/partner-models/claude/web-search
|
||||
const WEBSEARCH_HEADER = 'web-search-2025-03-05'
|
||||
|
||||
export function addAnthropicHeaders(assistant: Assistant, model: Model): string[] {
|
||||
const anthropicHeaders: string[] = []
|
||||
if (isClaude45ReasoningModel(model) && isToolUseModeFunction(assistant)) {
|
||||
const provider = getProviderByModel(model)
|
||||
if (
|
||||
isClaude45ReasoningModel(model) &&
|
||||
isToolUseModeFunction(assistant) &&
|
||||
!(isVertexProvider(provider) && isAwsBedrockProvider(provider))
|
||||
) {
|
||||
anthropicHeaders.push(INTERLEAVED_THINKING_HEADER)
|
||||
}
|
||||
if (isClaude4SeriesModel(model)) {
|
||||
if (isVertexProvider(provider) && assistant.enableWebSearch) {
|
||||
anthropicHeaders.push(WEBSEARCH_HEADER)
|
||||
}
|
||||
anthropicHeaders.push(CONTEXT_100M_HEADER)
|
||||
}
|
||||
return anthropicHeaders
|
||||
}
|
||||
|
||||
@ -21,8 +21,6 @@ import {
|
||||
isSupportedThinkingTokenModel,
|
||||
isWebSearchModel
|
||||
} from '@renderer/config/models'
|
||||
import { isAwsBedrockProvider } from '@renderer/config/providers'
|
||||
import { isVertexProvider } from '@renderer/hooks/useVertexAI'
|
||||
import { getAssistantSettings, getDefaultModel } from '@renderer/services/AssistantService'
|
||||
import store from '@renderer/store'
|
||||
import type { CherryWebSearchConfig } from '@renderer/store/websearch'
|
||||
@ -179,8 +177,7 @@ export async function buildStreamTextParams(
|
||||
|
||||
let headers: Record<string, string | undefined> = options.requestOptions?.headers ?? {}
|
||||
|
||||
// https://docs.claude.com/en/docs/build-with-claude/extended-thinking#interleaved-thinking
|
||||
if (!isVertexProvider(provider) && !isAwsBedrockProvider(provider) && isAnthropicModel(model)) {
|
||||
if (isAnthropicModel(model)) {
|
||||
const newBetaHeaders = { 'anthropic-beta': addAnthropicHeaders(assistant, model).join(',') }
|
||||
headers = combineHeaders(headers, newBetaHeaders)
|
||||
}
|
||||
|
||||
@ -382,6 +382,12 @@ export function isClaude45ReasoningModel(model: Model): boolean {
|
||||
return regex.test(modelId)
|
||||
}
|
||||
|
||||
export function isClaude4SeriesModel(model: Model): boolean {
|
||||
const modelId = getLowerBaseModelName(model.id, '/')
|
||||
const regex = /claude-(sonnet|opus|haiku)-4(?:[.-]\d+)?(?:-[\w-]+)?$/i
|
||||
return regex.test(modelId)
|
||||
}
|
||||
|
||||
export function isClaudeReasoningModel(model?: Model): boolean {
|
||||
if (!model) {
|
||||
return false
|
||||
|
||||
@ -11,10 +11,11 @@ import {
|
||||
isVertexAiProvider
|
||||
} from '../providers'
|
||||
import { isEmbeddingModel, isRerankModel } from './embedding'
|
||||
import { isClaude4SeriesModel } from './reasoning'
|
||||
import { isAnthropicModel } from './utils'
|
||||
import { isPureGenerateImageModel, isTextToImageModel } from './vision'
|
||||
|
||||
export const CLAUDE_SUPPORTED_WEBSEARCH_REGEX = new RegExp(
|
||||
const CLAUDE_SUPPORTED_WEBSEARCH_REGEX = new RegExp(
|
||||
`\\b(?:claude-3(-|\\.)(7|5)-sonnet(?:-[\\w-]+)|claude-3(-|\\.)5-haiku(?:-[\\w-]+)|claude-(haiku|sonnet|opus)-4(?:-[\\w-]+)?)\\b`,
|
||||
'i'
|
||||
)
|
||||
@ -73,11 +74,11 @@ export function isWebSearchModel(model: Model): boolean {
|
||||
|
||||
const modelId = getLowerBaseModelName(model.id, '/')
|
||||
|
||||
// bedrock和vertex不支持
|
||||
if (
|
||||
isAnthropicModel(model) &&
|
||||
!(provider.id === SystemProviderIds['aws-bedrock'] || provider.id === SystemProviderIds.vertexai)
|
||||
) {
|
||||
// bedrock不支持
|
||||
if (isAnthropicModel(model) && !(provider.id === SystemProviderIds['aws-bedrock'])) {
|
||||
if (isVertexAiProvider(provider)) {
|
||||
return isClaude4SeriesModel(model)
|
||||
}
|
||||
return CLAUDE_SUPPORTED_WEBSEARCH_REGEX.test(modelId)
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user