mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-04-19 12:58:39 +00:00
feat: support 1M context window via anthropic_beta header for Bedrock
When Claude Code sends a model with [1m] suffix (e.g. claude-opus-4-6[1m]), the relay now adds 'context-1m-2025-08-07' to the anthropic_beta array in the Bedrock request body. This enables the 1M context window preview on Bedrock for supported models (Opus 4.6, Sonnet 4.5, Sonnet 4). Per Anthropic docs: the 1M context requires the beta header on all platforms including Amazon Bedrock.
This commit is contained in:
@@ -136,12 +136,12 @@ class BedrockRelayService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const modelId = this._selectModel(requestBody, bedrockAccount)
|
const { modelId, isLongContext } = this._selectModel(requestBody, bedrockAccount)
|
||||||
const region = this._selectRegion(modelId, bedrockAccount)
|
const region = this._selectRegion(modelId, bedrockAccount)
|
||||||
const client = this._getBedrockClient(region, bedrockAccount)
|
const client = this._getBedrockClient(region, bedrockAccount)
|
||||||
|
|
||||||
// 转换请求格式为Bedrock格式
|
// 转换请求格式为Bedrock格式
|
||||||
const bedrockPayload = this._convertToBedrockFormat(requestBody)
|
const bedrockPayload = this._convertToBedrockFormat(requestBody, { isLongContext })
|
||||||
|
|
||||||
const command = new InvokeModelCommand({
|
const command = new InvokeModelCommand({
|
||||||
modelId,
|
modelId,
|
||||||
@@ -277,12 +277,12 @@ class BedrockRelayService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const modelId = this._selectModel(requestBody, bedrockAccount)
|
const { modelId, isLongContext } = this._selectModel(requestBody, bedrockAccount)
|
||||||
const region = this._selectRegion(modelId, bedrockAccount)
|
const region = this._selectRegion(modelId, bedrockAccount)
|
||||||
const client = this._getBedrockClient(region, bedrockAccount)
|
const client = this._getBedrockClient(region, bedrockAccount)
|
||||||
|
|
||||||
// 转换请求格式为Bedrock格式
|
// 转换请求格式为Bedrock格式
|
||||||
const bedrockPayload = this._convertToBedrockFormat(requestBody)
|
const bedrockPayload = this._convertToBedrockFormat(requestBody, { isLongContext })
|
||||||
|
|
||||||
const command = new InvokeModelWithResponseStreamCommand({
|
const command = new InvokeModelWithResponseStreamCommand({
|
||||||
modelId,
|
modelId,
|
||||||
@@ -399,6 +399,7 @@ class BedrockRelayService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 选择使用的模型
|
// 选择使用的模型
|
||||||
|
// Returns { modelId, isLongContext }
|
||||||
_selectModel(requestBody, bedrockAccount) {
|
_selectModel(requestBody, bedrockAccount) {
|
||||||
let selectedModel
|
let selectedModel
|
||||||
|
|
||||||
@@ -420,15 +421,18 @@ class BedrockRelayService {
|
|||||||
logger.info(`🎯 使用系统默认模型: ${selectedModel}`, { metadata: { source: 'default' } })
|
logger.info(`🎯 使用系统默认模型: ${selectedModel}`, { metadata: { source: 'default' } })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Detect [1m] long context variant before mapping
|
||||||
|
const isLongContext = selectedModel.includes('[1m]')
|
||||||
|
|
||||||
// 如果是标准Claude模型名,需要映射为Bedrock格式
|
// 如果是标准Claude模型名,需要映射为Bedrock格式
|
||||||
const bedrockModel = this._mapToBedrockModel(selectedModel)
|
const bedrockModel = this._mapToBedrockModel(selectedModel)
|
||||||
if (bedrockModel !== selectedModel) {
|
if (bedrockModel !== selectedModel.replace(/\[1m\]$/, '')) {
|
||||||
logger.info(`🔄 模型映射: ${selectedModel} → ${bedrockModel}`, {
|
logger.info(`🔄 模型映射: ${selectedModel} → ${bedrockModel}`, {
|
||||||
metadata: { originalModel: selectedModel, bedrockModel }
|
metadata: { originalModel: selectedModel, bedrockModel, isLongContext }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return bedrockModel
|
return { modelId: bedrockModel, isLongContext }
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将标准Claude模型名映射为Bedrock格式
|
// 将标准Claude模型名映射为Bedrock格式
|
||||||
@@ -546,13 +550,23 @@ class BedrockRelayService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 转换Claude格式请求到Bedrock格式
|
// 转换Claude格式请求到Bedrock格式
|
||||||
_convertToBedrockFormat(requestBody) {
|
_convertToBedrockFormat(requestBody, { isLongContext = false } = {}) {
|
||||||
const bedrockPayload = {
|
const bedrockPayload = {
|
||||||
anthropic_version: 'bedrock-2023-05-31',
|
anthropic_version: 'bedrock-2023-05-31',
|
||||||
max_tokens: Math.min(requestBody.max_tokens || this.maxOutputTokens, this.maxOutputTokens),
|
max_tokens: Math.min(requestBody.max_tokens || this.maxOutputTokens, this.maxOutputTokens),
|
||||||
messages: requestBody.messages || []
|
messages: requestBody.messages || []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enable 1M context window beta when [1m] model variant is requested
|
||||||
|
if (isLongContext) {
|
||||||
|
bedrockPayload.anthropic_beta = [
|
||||||
|
...(requestBody.anthropic_beta || []),
|
||||||
|
'context-1m-2025-08-07'
|
||||||
|
]
|
||||||
|
} else if (requestBody.anthropic_beta) {
|
||||||
|
bedrockPayload.anthropic_beta = requestBody.anthropic_beta
|
||||||
|
}
|
||||||
|
|
||||||
// 添加系统提示词
|
// 添加系统提示词
|
||||||
if (requestBody.system) {
|
if (requestBody.system) {
|
||||||
bedrockPayload.system = requestBody.system
|
bedrockPayload.system = requestBody.system
|
||||||
|
|||||||
Reference in New Issue
Block a user