feat: 适配 claude-opus-4-8
This commit is contained in:
parent
37044b83eb
commit
514ac5c6a1
@ -72,6 +72,7 @@ const (
|
||||
// 与前端 useModelWhitelist.ts 中的 antigravityDefaultMappings 保持一致
|
||||
var DefaultAntigravityModelMapping = map[string]string{
|
||||
// Claude 白名单
|
||||
"claude-opus-4-8": "claude-opus-4-8", // 官方模型
|
||||
"claude-opus-4-7": "claude-opus-4-7", // 官方模型
|
||||
"claude-opus-4-6-thinking": "claude-opus-4-6-thinking", // 官方模型
|
||||
"claude-opus-4-6": "claude-opus-4-6-thinking", // 简称映射
|
||||
@ -122,6 +123,7 @@ var DefaultAntigravityModelMapping = map[string]string{
|
||||
// aws_region 自动调整为匹配的区域前缀(如 eu.、apac.、jp. 等)
|
||||
var DefaultBedrockModelMapping = map[string]string{
|
||||
// Claude Opus
|
||||
"claude-opus-4-8": "us.anthropic.claude-opus-4-8-v1",
|
||||
"claude-opus-4-7": "us.anthropic.claude-opus-4-7-v1",
|
||||
"claude-opus-4-6-thinking": "us.anthropic.claude-opus-4-6-v1",
|
||||
"claude-opus-4-6": "us.anthropic.claude-opus-4-6-v1",
|
||||
|
||||
@ -24,3 +24,27 @@ func TestDefaultAntigravityModelMapping_ImageCompatibilityAliases(t *testing.T)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultAntigravityModelMapping_ContainsOpus48(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got, ok := DefaultAntigravityModelMapping["claude-opus-4-8"]
|
||||
if !ok {
|
||||
t.Fatal("expected mapping for claude-opus-4-8 to exist")
|
||||
}
|
||||
if got != "claude-opus-4-8" {
|
||||
t.Fatalf("unexpected claude-opus-4-8 mapping: got %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultBedrockModelMapping_ContainsOpus48(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got, ok := DefaultBedrockModelMapping["claude-opus-4-8"]
|
||||
if !ok {
|
||||
t.Fatal("expected Bedrock mapping for claude-opus-4-8 to exist")
|
||||
}
|
||||
if got != "us.anthropic.claude-opus-4-8-v1" {
|
||||
t.Fatalf("unexpected Bedrock claude-opus-4-8 mapping: got %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,6 +155,7 @@ var claudeModels = []modelDef{
|
||||
{ID: "claude-opus-4-6", DisplayName: "Claude Opus 4.6", CreatedAt: "2026-02-05T00:00:00Z"},
|
||||
{ID: "claude-opus-4-6-thinking", DisplayName: "Claude Opus 4.6 Thinking", CreatedAt: "2026-02-05T00:00:00Z"},
|
||||
{ID: "claude-opus-4-7", DisplayName: "Claude Opus 4.7", CreatedAt: "2026-04-17T00:00:00Z"},
|
||||
{ID: "claude-opus-4-8", DisplayName: "Claude Opus 4.8", CreatedAt: "2026-05-29T00:00:00Z"},
|
||||
{ID: "claude-sonnet-4-6", DisplayName: "Claude Sonnet 4.6", CreatedAt: "2026-02-17T00:00:00Z"},
|
||||
}
|
||||
|
||||
|
||||
@ -12,6 +12,7 @@ func TestDefaultModels_ContainsNewAndLegacyImageModels(t *testing.T) {
|
||||
}
|
||||
|
||||
requiredIDs := []string{
|
||||
"claude-opus-4-8",
|
||||
"claude-opus-4-6-thinking",
|
||||
"gemini-2.5-flash-image",
|
||||
"gemini-2.5-flash-image-preview",
|
||||
|
||||
@ -204,6 +204,8 @@ type modelInfo struct {
|
||||
// 只有在此映射表中的模型才会注入身份提示词
|
||||
// 注意:模型映射逻辑在网关层完成;这里仅用于按模型前缀判断是否注入身份提示词。
|
||||
var modelInfoMap = map[string]modelInfo{
|
||||
"claude-opus-4-8": {DisplayName: "Claude Opus 4.8", CanonicalID: "claude-opus-4-8"},
|
||||
"claude-opus-4-7": {DisplayName: "Claude Opus 4.7", CanonicalID: "claude-opus-4-7"},
|
||||
"claude-opus-4-5": {DisplayName: "Claude Opus 4.5", CanonicalID: "claude-opus-4-5-20250929"},
|
||||
"claude-opus-4-6": {DisplayName: "Claude Opus 4.6", CanonicalID: "claude-opus-4-6"},
|
||||
"claude-sonnet-4-6": {DisplayName: "Claude Sonnet 4.6", CanonicalID: "claude-sonnet-4-6"},
|
||||
@ -587,7 +589,8 @@ func maxOutputTokensLimit(model string) int {
|
||||
func isAntigravityOpusHighTierModel(model string) bool {
|
||||
lower := strings.ToLower(model)
|
||||
return strings.HasPrefix(lower, "claude-opus-4-6") ||
|
||||
strings.HasPrefix(lower, "claude-opus-4-7")
|
||||
strings.HasPrefix(lower, "claude-opus-4-7") ||
|
||||
strings.HasPrefix(lower, "claude-opus-4-8")
|
||||
}
|
||||
|
||||
func buildGenerationConfig(req *ClaudeRequest) *GeminiGenerationConfig {
|
||||
|
||||
@ -134,6 +134,12 @@ var DefaultModels = []Model{
|
||||
DisplayName: "Claude Opus 4.7",
|
||||
CreatedAt: "2026-04-17T00:00:00Z",
|
||||
},
|
||||
{
|
||||
ID: "claude-opus-4-8",
|
||||
Type: "model",
|
||||
DisplayName: "Claude Opus 4.8",
|
||||
CreatedAt: "2026-05-29T00:00:00Z",
|
||||
},
|
||||
{
|
||||
ID: "claude-sonnet-4-6",
|
||||
Type: "model",
|
||||
|
||||
@ -88,6 +88,18 @@ func TestAntigravityGatewayService_GetMappedModel(t *testing.T) {
|
||||
accountMapping: nil,
|
||||
expected: "claude-sonnet-4-5",
|
||||
},
|
||||
{
|
||||
name: "默认映射透传 - claude-opus-4-8",
|
||||
requestedModel: "claude-opus-4-8",
|
||||
accountMapping: nil,
|
||||
expected: "claude-opus-4-8",
|
||||
},
|
||||
{
|
||||
name: "默认映射透传 - claude-opus-4-7",
|
||||
requestedModel: "claude-opus-4-7",
|
||||
accountMapping: nil,
|
||||
expected: "claude-opus-4-7",
|
||||
},
|
||||
{
|
||||
name: "默认映射透传 - claude-opus-4-6-thinking",
|
||||
requestedModel: "claude-opus-4-6-thinking",
|
||||
@ -210,6 +222,7 @@ func TestAntigravityGatewayService_IsModelSupported(t *testing.T) {
|
||||
{"直接支持 - gemini-3-flash", "gemini-3-flash", true},
|
||||
|
||||
// 可映射(有明确前缀映射)
|
||||
{"可映射 - claude-opus-4-8", "claude-opus-4-8", true},
|
||||
{"可映射 - claude-opus-4-6", "claude-opus-4-6", true},
|
||||
|
||||
// 前缀透传(claude 和 gemini 前缀)
|
||||
|
||||
@ -174,6 +174,7 @@ func TestIsBedrockClaude45OrNewer(t *testing.T) {
|
||||
expect bool
|
||||
}{
|
||||
{"us.anthropic.claude-opus-4-6-v1", true},
|
||||
{"us.anthropic.claude-opus-4-8-v1", true},
|
||||
{"us.anthropic.claude-sonnet-4-6", true},
|
||||
{"us.anthropic.claude-sonnet-4-5-20250929-v1:0", true},
|
||||
{"us.anthropic.claude-opus-4-5-20251101-v1:0", true},
|
||||
@ -511,6 +512,20 @@ func TestResolveBedrockModelID(t *testing.T) {
|
||||
assert.Equal(t, "au.anthropic.claude-opus-4-6-v1", modelID)
|
||||
})
|
||||
|
||||
t.Run("default opus 4.8 mapping uses regional Bedrock model id", func(t *testing.T) {
|
||||
account := &Account{
|
||||
Platform: PlatformAnthropic,
|
||||
Type: AccountTypeBedrock,
|
||||
Credentials: map[string]any{
|
||||
"aws_region": "eu-west-1",
|
||||
},
|
||||
}
|
||||
|
||||
modelID, ok := ResolveBedrockModelID(account, "claude-opus-4-8")
|
||||
require.True(t, ok)
|
||||
assert.Equal(t, "eu.anthropic.claude-opus-4-8-v1", modelID)
|
||||
})
|
||||
|
||||
t.Run("force global rewrites anthropic regional model id", func(t *testing.T) {
|
||||
account := &Account{
|
||||
Platform: PlatformAnthropic,
|
||||
@ -714,6 +729,7 @@ func TestIsBedrockOpus47OrNewer(t *testing.T) {
|
||||
modelID string
|
||||
expect bool
|
||||
}{
|
||||
{"us.anthropic.claude-opus-4-8-v1", true},
|
||||
{"us.anthropic.claude-opus-4-7-v1", true},
|
||||
{"us.anthropic.claude-opus-4-6-v1", false},
|
||||
{"us.anthropic.claude-opus-4-5-20251101-v1:0", false},
|
||||
@ -886,10 +902,12 @@ func TestIsBedrockOpus47OrNewer_EdgeCases(t *testing.T) {
|
||||
modelID string
|
||||
expect bool
|
||||
}{
|
||||
{"anthropic.claude-opus-4-8-v1", true},
|
||||
{"anthropic.claude-opus-4-7-v1", true},
|
||||
{"us.anthropic.claude-opus-4-7-20270101-v1:0", true},
|
||||
{"", false},
|
||||
// Forward() passes parsed.Model (standard names), not Bedrock IDs
|
||||
{"claude-opus-4-8", true},
|
||||
{"claude-opus-4-7", true},
|
||||
{"claude-opus-4-6", false},
|
||||
{"claude-sonnet-4-7", false},
|
||||
|
||||
16
backend/migrations/144_add_opus48_to_model_mapping.sql
Normal file
16
backend/migrations/144_add_opus48_to_model_mapping.sql
Normal file
@ -0,0 +1,16 @@
|
||||
-- 为已持久化的 Antigravity model_mapping 添加 claude-opus-4-8。
|
||||
--
|
||||
-- 未持久化 model_mapping 的账号会直接使用 DefaultAntigravityModelMapping,
|
||||
-- 因此这里只需要回填已有映射对象。
|
||||
|
||||
UPDATE accounts
|
||||
SET credentials = jsonb_set(
|
||||
credentials,
|
||||
'{model_mapping,claude-opus-4-8}',
|
||||
'"claude-opus-4-8"'::jsonb,
|
||||
true
|
||||
)
|
||||
WHERE platform = 'antigravity'
|
||||
AND deleted_at IS NULL
|
||||
AND jsonb_typeof(credentials->'model_mapping') = 'object'
|
||||
AND credentials->'model_mapping'->>'claude-opus-4-8' IS NULL;
|
||||
@ -222,6 +222,8 @@ const formatScopeName = (scope: string): string => {
|
||||
// Claude 系列
|
||||
'claude-opus-4-6': 'COpus46',
|
||||
'claude-opus-4-6-thinking': 'COpus46T',
|
||||
'claude-opus-4-7': 'COpus47',
|
||||
'claude-opus-4-8': 'COpus48',
|
||||
'claude-sonnet-4-6': 'CSon46',
|
||||
'claude-sonnet-4-5': 'CSon45',
|
||||
'claude-sonnet-4-5-thinking': 'CSon45T',
|
||||
|
||||
@ -664,6 +664,7 @@ const antigravityClaudeUsageFromAPI = computed(() =>
|
||||
getAntigravityUsageFromAPI([
|
||||
'claude-sonnet-4-5', 'claude-opus-4-5-thinking',
|
||||
'claude-sonnet-4-6', 'claude-opus-4-6', 'claude-opus-4-6-thinking',
|
||||
'claude-opus-4-7', 'claude-opus-4-8',
|
||||
])
|
||||
)
|
||||
|
||||
|
||||
@ -35,6 +35,11 @@ describe('useModelWhitelist', () => {
|
||||
expect(models).toContain('gemini-3-pro-image')
|
||||
})
|
||||
|
||||
it('Claude 模型列表包含 Opus 4.8', () => {
|
||||
expect(getModelsByPlatform('claude')).toContain('claude-opus-4-8')
|
||||
expect(getModelsByPlatform('antigravity')).toContain('claude-opus-4-8')
|
||||
})
|
||||
|
||||
it('gemini 模型列表包含原生生图模型', () => {
|
||||
const models = getModelsByPlatform('gemini')
|
||||
|
||||
|
||||
@ -29,6 +29,7 @@ export const claudeModels = [
|
||||
'claude-opus-4-5-20251101',
|
||||
'claude-opus-4-6',
|
||||
'claude-opus-4-7',
|
||||
'claude-opus-4-8',
|
||||
'claude-sonnet-4-6'
|
||||
]
|
||||
|
||||
@ -53,6 +54,7 @@ const antigravityModels = [
|
||||
'claude-opus-4-6',
|
||||
'claude-opus-4-6-thinking',
|
||||
'claude-opus-4-7',
|
||||
'claude-opus-4-8',
|
||||
'claude-opus-4-5-thinking',
|
||||
'claude-sonnet-4-6',
|
||||
'claude-sonnet-4-5',
|
||||
@ -238,6 +240,7 @@ const anthropicPresetMappings = [
|
||||
{ label: 'Opus 4.5', from: 'claude-opus-4-5-20251101', to: 'claude-opus-4-5-20251101', color: 'bg-purple-100 text-purple-700 hover:bg-purple-200 dark:bg-purple-900/30 dark:text-purple-400' },
|
||||
{ label: 'Opus 4.6', from: 'claude-opus-4-6', to: 'claude-opus-4-6', color: 'bg-purple-100 text-purple-700 hover:bg-purple-200 dark:bg-purple-900/30 dark:text-purple-400' },
|
||||
{ label: 'Opus 4.7', from: 'claude-opus-4-7', to: 'claude-opus-4-7', color: 'bg-purple-100 text-purple-700 hover:bg-purple-200 dark:bg-purple-900/30 dark:text-purple-400' },
|
||||
{ label: 'Opus 4.8', from: 'claude-opus-4-8', to: 'claude-opus-4-8', color: 'bg-purple-100 text-purple-700 hover:bg-purple-200 dark:bg-purple-900/30 dark:text-purple-400' },
|
||||
{ label: 'Haiku 3.5', from: 'claude-3-5-haiku-20241022', to: 'claude-3-5-haiku-20241022', color: 'bg-green-100 text-green-700 hover:bg-green-200 dark:bg-green-900/30 dark:text-green-400' },
|
||||
{ label: 'Haiku 4.5', from: 'claude-haiku-4-5-20251001', to: 'claude-haiku-4-5-20251001', color: 'bg-emerald-100 text-emerald-700 hover:bg-emerald-200 dark:bg-emerald-900/30 dark:text-emerald-400' },
|
||||
{ label: 'Opus->Sonnet', from: 'claude-opus-4-6', to: 'claude-sonnet-4-5-20250929', color: 'bg-amber-100 text-amber-700 hover:bg-amber-200 dark:bg-amber-900/30 dark:text-amber-400' }
|
||||
@ -297,13 +300,15 @@ const antigravityPresetMappings = [
|
||||
{ label: 'Sonnet 4.5', from: 'claude-sonnet-4-5', to: 'claude-sonnet-4-5', color: 'bg-cyan-100 text-cyan-700 hover:bg-cyan-200 dark:bg-cyan-900/30 dark:text-cyan-400' },
|
||||
{ label: 'Opus 4.6', from: 'claude-opus-4-6', to: 'claude-opus-4-6-thinking', color: 'bg-pink-100 text-pink-700 hover:bg-pink-200 dark:bg-pink-900/30 dark:text-pink-400' },
|
||||
{ label: 'Opus 4.6-thinking', from: 'claude-opus-4-6-thinking', to: 'claude-opus-4-6-thinking', color: 'bg-pink-100 text-pink-700 hover:bg-pink-200 dark:bg-pink-900/30 dark:text-pink-400' },
|
||||
{ label: 'Opus 4.7', from: 'claude-opus-4-7', to: 'claude-opus-4-7', color: 'bg-pink-100 text-pink-700 hover:bg-pink-200 dark:bg-pink-900/30 dark:text-pink-400' }
|
||||
{ label: 'Opus 4.7', from: 'claude-opus-4-7', to: 'claude-opus-4-7', color: 'bg-pink-100 text-pink-700 hover:bg-pink-200 dark:bg-pink-900/30 dark:text-pink-400' },
|
||||
{ label: 'Opus 4.8', from: 'claude-opus-4-8', to: 'claude-opus-4-8', color: 'bg-pink-100 text-pink-700 hover:bg-pink-200 dark:bg-pink-900/30 dark:text-pink-400' }
|
||||
]
|
||||
|
||||
// Bedrock 预设映射(与后端 DefaultBedrockModelMapping 保持一致)
|
||||
const bedrockPresetMappings = [
|
||||
{ label: 'Opus 4.6', from: 'claude-opus-4-6', to: 'us.anthropic.claude-opus-4-6-v1', color: 'bg-pink-100 text-pink-700 hover:bg-pink-200 dark:bg-pink-900/30 dark:text-pink-400' },
|
||||
{ label: 'Opus 4.7', from: 'claude-opus-4-7', to: 'us.anthropic.claude-opus-4-7-v1', color: 'bg-pink-100 text-pink-700 hover:bg-pink-200 dark:bg-pink-900/30 dark:text-pink-400' },
|
||||
{ label: 'Opus 4.8', from: 'claude-opus-4-8', to: 'us.anthropic.claude-opus-4-8-v1', color: 'bg-pink-100 text-pink-700 hover:bg-pink-200 dark:bg-pink-900/30 dark:text-pink-400' },
|
||||
{ label: 'Sonnet 4.6', from: 'claude-sonnet-4-6', to: 'us.anthropic.claude-sonnet-4-6', color: 'bg-cyan-100 text-cyan-700 hover:bg-cyan-200 dark:bg-cyan-900/30 dark:text-cyan-400' },
|
||||
{ label: 'Opus 4.5', from: 'claude-opus-4-5-thinking', to: 'us.anthropic.claude-opus-4-5-20251101-v1:0', color: 'bg-pink-100 text-pink-700 hover:bg-pink-200 dark:bg-pink-900/30 dark:text-pink-400' },
|
||||
{ label: 'Sonnet 4.5', from: 'claude-sonnet-4-5', to: 'us.anthropic.claude-sonnet-4-5-20250929-v1:0', color: 'bg-cyan-100 text-cyan-700 hover:bg-cyan-200 dark:bg-cyan-900/30 dark:text-cyan-400' },
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user