Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
陈曦
sub2api
Commits
0c2a901a
Unverified
Commit
0c2a901a
authored
Jan 18, 2026
by
Wesley Liddick
Committed by
GitHub
Jan 18, 2026
Browse files
Merge pull request #317 from IanShaw027/fix/gemini-issue
fix(gemini,group): 更新 Gemini 模型配置并补齐 SIMPLE 默认分组
parents
dae0d532
a7165b0f
Changes
12
Hide whitespace changes
Inline
Side-by-side
backend/internal/pkg/gemini/models.go
View file @
0c2a901a
...
@@ -16,14 +16,11 @@ type ModelsListResponse struct {
...
@@ -16,14 +16,11 @@ type ModelsListResponse struct {
func
DefaultModels
()
[]
Model
{
func
DefaultModels
()
[]
Model
{
methods
:=
[]
string
{
"generateContent"
,
"streamGenerateContent"
}
methods
:=
[]
string
{
"generateContent"
,
"streamGenerateContent"
}
return
[]
Model
{
return
[]
Model
{
{
Name
:
"models/gemini-3-pro-preview"
,
SupportedGenerationMethods
:
methods
},
{
Name
:
"models/gemini-3-flash-preview"
,
SupportedGenerationMethods
:
methods
},
{
Name
:
"models/gemini-2.5-pro"
,
SupportedGenerationMethods
:
methods
},
{
Name
:
"models/gemini-2.5-flash"
,
SupportedGenerationMethods
:
methods
},
{
Name
:
"models/gemini-2.0-flash"
,
SupportedGenerationMethods
:
methods
},
{
Name
:
"models/gemini-2.0-flash"
,
SupportedGenerationMethods
:
methods
},
{
Name
:
"models/gemini-1.5-pro"
,
SupportedGenerationMethods
:
methods
},
{
Name
:
"models/gemini-2.5-flash"
,
SupportedGenerationMethods
:
methods
},
{
Name
:
"models/gemini-1.5-flash"
,
SupportedGenerationMethods
:
methods
},
{
Name
:
"models/gemini-2.5-pro"
,
SupportedGenerationMethods
:
methods
},
{
Name
:
"models/gemini-1.5-flash-8b"
,
SupportedGenerationMethods
:
methods
},
{
Name
:
"models/gemini-3-flash-preview"
,
SupportedGenerationMethods
:
methods
},
{
Name
:
"models/gemini-3-pro-preview"
,
SupportedGenerationMethods
:
methods
},
}
}
}
}
...
...
backend/internal/pkg/geminicli/models.go
View file @
0c2a901a
...
@@ -12,10 +12,10 @@ type Model struct {
...
@@ -12,10 +12,10 @@ type Model struct {
// DefaultModels is the curated Gemini model list used by the admin UI "test account" flow.
// DefaultModels is the curated Gemini model list used by the admin UI "test account" flow.
var
DefaultModels
=
[]
Model
{
var
DefaultModels
=
[]
Model
{
{
ID
:
"gemini-2.0-flash"
,
Type
:
"model"
,
DisplayName
:
"Gemini 2.0 Flash"
,
CreatedAt
:
""
},
{
ID
:
"gemini-2.0-flash"
,
Type
:
"model"
,
DisplayName
:
"Gemini 2.0 Flash"
,
CreatedAt
:
""
},
{
ID
:
"gemini-2.5-pro"
,
Type
:
"model"
,
DisplayName
:
"Gemini 2.5 Pro"
,
CreatedAt
:
""
},
{
ID
:
"gemini-2.5-flash"
,
Type
:
"model"
,
DisplayName
:
"Gemini 2.5 Flash"
,
CreatedAt
:
""
},
{
ID
:
"gemini-2.5-flash"
,
Type
:
"model"
,
DisplayName
:
"Gemini 2.5 Flash"
,
CreatedAt
:
""
},
{
ID
:
"gemini-
3
-pro
-preview
"
,
Type
:
"model"
,
DisplayName
:
"Gemini
3
Pro
Preview
"
,
CreatedAt
:
""
},
{
ID
:
"gemini-
2.5
-pro"
,
Type
:
"model"
,
DisplayName
:
"Gemini
2.5
Pro"
,
CreatedAt
:
""
},
{
ID
:
"gemini-3-flash-preview"
,
Type
:
"model"
,
DisplayName
:
"Gemini 3 Flash Preview"
,
CreatedAt
:
""
},
{
ID
:
"gemini-3-flash-preview"
,
Type
:
"model"
,
DisplayName
:
"Gemini 3 Flash Preview"
,
CreatedAt
:
""
},
{
ID
:
"gemini-3-pro-preview"
,
Type
:
"model"
,
DisplayName
:
"Gemini 3 Pro Preview"
,
CreatedAt
:
""
},
}
}
// DefaultTestModel is the default model to preselect in test flows.
// DefaultTestModel is the default model to preselect in test flows.
...
...
backend/internal/repository/ent.go
View file @
0c2a901a
...
@@ -65,5 +65,18 @@ func InitEnt(cfg *config.Config) (*ent.Client, *sql.DB, error) {
...
@@ -65,5 +65,18 @@ func InitEnt(cfg *config.Config) (*ent.Client, *sql.DB, error) {
// 创建 Ent 客户端,绑定到已配置的数据库驱动。
// 创建 Ent 客户端,绑定到已配置的数据库驱动。
client
:=
ent
.
NewClient
(
ent
.
Driver
(
drv
))
client
:=
ent
.
NewClient
(
ent
.
Driver
(
drv
))
// SIMPLE 模式:启动时补齐各平台默认分组。
// - anthropic/openai/gemini: 确保存在 <platform>-default
// - antigravity: 仅要求存在 >=2 个未软删除分组(用于 claude/gemini 混合调度场景)
if
cfg
.
RunMode
==
config
.
RunModeSimple
{
seedCtx
,
seedCancel
:=
context
.
WithTimeout
(
context
.
Background
(),
30
*
time
.
Second
)
defer
seedCancel
()
if
err
:=
ensureSimpleModeDefaultGroups
(
seedCtx
,
client
);
err
!=
nil
{
_
=
client
.
Close
()
return
nil
,
nil
,
err
}
}
return
client
,
drv
.
DB
(),
nil
return
client
,
drv
.
DB
(),
nil
}
}
backend/internal/repository/simple_mode_default_groups.go
0 → 100644
View file @
0c2a901a
package
repository
import
(
"context"
"fmt"
dbent
"github.com/Wei-Shaw/sub2api/ent"
"github.com/Wei-Shaw/sub2api/ent/group"
"github.com/Wei-Shaw/sub2api/internal/service"
)
func
ensureSimpleModeDefaultGroups
(
ctx
context
.
Context
,
client
*
dbent
.
Client
)
error
{
if
client
==
nil
{
return
fmt
.
Errorf
(
"nil ent client"
)
}
requiredByPlatform
:=
map
[
string
]
int
{
service
.
PlatformAnthropic
:
1
,
service
.
PlatformOpenAI
:
1
,
service
.
PlatformGemini
:
1
,
service
.
PlatformAntigravity
:
2
,
}
for
platform
,
minCount
:=
range
requiredByPlatform
{
count
,
err
:=
client
.
Group
.
Query
()
.
Where
(
group
.
PlatformEQ
(
platform
),
group
.
DeletedAtIsNil
())
.
Count
(
ctx
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"count groups for platform %s: %w"
,
platform
,
err
)
}
if
platform
==
service
.
PlatformAntigravity
{
if
count
<
minCount
{
for
i
:=
count
;
i
<
minCount
;
i
++
{
name
:=
fmt
.
Sprintf
(
"%s-default-%d"
,
platform
,
i
+
1
)
if
err
:=
createGroupIfNotExists
(
ctx
,
client
,
name
,
platform
);
err
!=
nil
{
return
err
}
}
}
continue
}
// Non-antigravity platforms: ensure <platform>-default exists.
name
:=
platform
+
"-default"
if
err
:=
createGroupIfNotExists
(
ctx
,
client
,
name
,
platform
);
err
!=
nil
{
return
err
}
}
return
nil
}
func
createGroupIfNotExists
(
ctx
context
.
Context
,
client
*
dbent
.
Client
,
name
,
platform
string
)
error
{
exists
,
err
:=
client
.
Group
.
Query
()
.
Where
(
group
.
NameEQ
(
name
),
group
.
DeletedAtIsNil
())
.
Exist
(
ctx
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"check group exists %s: %w"
,
name
,
err
)
}
if
exists
{
return
nil
}
_
,
err
=
client
.
Group
.
Create
()
.
SetName
(
name
)
.
SetDescription
(
"Auto-created default group"
)
.
SetPlatform
(
platform
)
.
SetStatus
(
service
.
StatusActive
)
.
SetSubscriptionType
(
service
.
SubscriptionTypeStandard
)
.
SetRateMultiplier
(
1.0
)
.
SetIsExclusive
(
false
)
.
Save
(
ctx
)
if
err
!=
nil
{
if
dbent
.
IsConstraintError
(
err
)
{
// Concurrent server startups may race on creation; treat as success.
return
nil
}
return
fmt
.
Errorf
(
"create default group %s: %w"
,
name
,
err
)
}
return
nil
}
backend/internal/repository/simple_mode_default_groups_integration_test.go
0 → 100644
View file @
0c2a901a
//go:build integration
package
repository
import
(
"context"
"testing"
"time"
"github.com/Wei-Shaw/sub2api/ent/group"
"github.com/Wei-Shaw/sub2api/internal/service"
"github.com/stretchr/testify/require"
)
func
TestEnsureSimpleModeDefaultGroups_CreatesMissingDefaults
(
t
*
testing
.
T
)
{
ctx
:=
context
.
Background
()
tx
:=
testEntTx
(
t
)
client
:=
tx
.
Client
()
seedCtx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
10
*
time
.
Second
)
defer
cancel
()
require
.
NoError
(
t
,
ensureSimpleModeDefaultGroups
(
seedCtx
,
client
))
assertGroupExists
:=
func
(
name
string
)
{
exists
,
err
:=
client
.
Group
.
Query
()
.
Where
(
group
.
NameEQ
(
name
),
group
.
DeletedAtIsNil
())
.
Exist
(
seedCtx
)
require
.
NoError
(
t
,
err
)
require
.
True
(
t
,
exists
,
"expected group %s to exist"
,
name
)
}
assertGroupExists
(
service
.
PlatformAnthropic
+
"-default"
)
assertGroupExists
(
service
.
PlatformOpenAI
+
"-default"
)
assertGroupExists
(
service
.
PlatformGemini
+
"-default"
)
assertGroupExists
(
service
.
PlatformAntigravity
+
"-default-1"
)
assertGroupExists
(
service
.
PlatformAntigravity
+
"-default-2"
)
}
func
TestEnsureSimpleModeDefaultGroups_IgnoresSoftDeletedGroups
(
t
*
testing
.
T
)
{
ctx
:=
context
.
Background
()
tx
:=
testEntTx
(
t
)
client
:=
tx
.
Client
()
seedCtx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
10
*
time
.
Second
)
defer
cancel
()
// Create and then soft-delete an anthropic default group.
g
,
err
:=
client
.
Group
.
Create
()
.
SetName
(
service
.
PlatformAnthropic
+
"-default"
)
.
SetPlatform
(
service
.
PlatformAnthropic
)
.
SetStatus
(
service
.
StatusActive
)
.
SetSubscriptionType
(
service
.
SubscriptionTypeStandard
)
.
SetRateMultiplier
(
1.0
)
.
SetIsExclusive
(
false
)
.
Save
(
seedCtx
)
require
.
NoError
(
t
,
err
)
_
,
err
=
client
.
Group
.
Delete
()
.
Where
(
group
.
IDEQ
(
g
.
ID
))
.
Exec
(
seedCtx
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
ensureSimpleModeDefaultGroups
(
seedCtx
,
client
))
// New active one should exist.
count
,
err
:=
client
.
Group
.
Query
()
.
Where
(
group
.
NameEQ
(
service
.
PlatformAnthropic
+
"-default"
),
group
.
DeletedAtIsNil
())
.
Count
(
seedCtx
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
1
,
count
)
}
func
TestEnsureSimpleModeDefaultGroups_AntigravityNeedsTwoGroupsOnlyByCount
(
t
*
testing
.
T
)
{
ctx
:=
context
.
Background
()
tx
:=
testEntTx
(
t
)
client
:=
tx
.
Client
()
seedCtx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
10
*
time
.
Second
)
defer
cancel
()
mustCreateGroup
(
t
,
client
,
&
service
.
Group
{
Name
:
"ag-custom-1-"
+
time
.
Now
()
.
Format
(
time
.
RFC3339Nano
),
Platform
:
service
.
PlatformAntigravity
})
mustCreateGroup
(
t
,
client
,
&
service
.
Group
{
Name
:
"ag-custom-2-"
+
time
.
Now
()
.
Format
(
time
.
RFC3339Nano
),
Platform
:
service
.
PlatformAntigravity
})
require
.
NoError
(
t
,
ensureSimpleModeDefaultGroups
(
seedCtx
,
client
))
count
,
err
:=
client
.
Group
.
Query
()
.
Where
(
group
.
PlatformEQ
(
service
.
PlatformAntigravity
),
group
.
DeletedAtIsNil
())
.
Count
(
seedCtx
)
require
.
NoError
(
t
,
err
)
require
.
GreaterOrEqual
(
t
,
count
,
2
)
}
backend/internal/service/antigravity_model_mapping_test.go
View file @
0c2a901a
...
@@ -30,7 +30,7 @@ func TestIsAntigravityModelSupported(t *testing.T) {
...
@@ -30,7 +30,7 @@ func TestIsAntigravityModelSupported(t *testing.T) {
{
"可映射 - claude-3-haiku-20240307"
,
"claude-3-haiku-20240307"
,
true
},
{
"可映射 - claude-3-haiku-20240307"
,
"claude-3-haiku-20240307"
,
true
},
// Gemini 前缀透传
// Gemini 前缀透传
{
"Gemini前缀 - gemini-
1
.5-pro"
,
"gemini-
1
.5-pro"
,
true
},
{
"Gemini前缀 - gemini-
2
.5-pro"
,
"gemini-
2
.5-pro"
,
true
},
{
"Gemini前缀 - gemini-unknown-model"
,
"gemini-unknown-model"
,
true
},
{
"Gemini前缀 - gemini-unknown-model"
,
"gemini-unknown-model"
,
true
},
{
"Gemini前缀 - gemini-future-version"
,
"gemini-future-version"
,
true
},
{
"Gemini前缀 - gemini-future-version"
,
"gemini-future-version"
,
true
},
...
@@ -142,10 +142,10 @@ func TestAntigravityGatewayService_GetMappedModel(t *testing.T) {
...
@@ -142,10 +142,10 @@ func TestAntigravityGatewayService_GetMappedModel(t *testing.T) {
expected
:
"gemini-2.5-flash"
,
expected
:
"gemini-2.5-flash"
,
},
},
{
{
name
:
"Gemini透传 - gemini-
1
.5-pro"
,
name
:
"Gemini透传 - gemini-
2
.5-pro"
,
requestedModel
:
"gemini-
1
.5-pro"
,
requestedModel
:
"gemini-
2
.5-pro"
,
accountMapping
:
nil
,
accountMapping
:
nil
,
expected
:
"gemini-
1
.5-pro"
,
expected
:
"gemini-
2
.5-pro"
,
},
},
{
{
name
:
"Gemini透传 - gemini-future-model"
,
name
:
"Gemini透传 - gemini-future-model"
,
...
...
backend/internal/service/gemini_multiplatform_test.go
View file @
0c2a901a
...
@@ -599,7 +599,7 @@ func TestGeminiMessagesCompatService_isModelSupportedByAccount(t *testing.T) {
...
@@ -599,7 +599,7 @@ func TestGeminiMessagesCompatService_isModelSupportedByAccount(t *testing.T) {
name
:
"Gemini平台-有映射配置-只支持配置的模型"
,
name
:
"Gemini平台-有映射配置-只支持配置的模型"
,
account
:
&
Account
{
account
:
&
Account
{
Platform
:
PlatformGemini
,
Platform
:
PlatformGemini
,
Credentials
:
map
[
string
]
any
{
"model_mapping"
:
map
[
string
]
any
{
"gemini-
1
.5-pro"
:
"x"
}},
Credentials
:
map
[
string
]
any
{
"model_mapping"
:
map
[
string
]
any
{
"gemini-
2
.5-pro"
:
"x"
}},
},
},
model
:
"gemini-2.5-flash"
,
model
:
"gemini-2.5-flash"
,
expected
:
false
,
expected
:
false
,
...
...
backend/internal/service/pricing_service.go
View file @
0c2a901a
...
@@ -531,8 +531,8 @@ func (s *PricingService) buildModelLookupCandidates(modelLower string) []string
...
@@ -531,8 +531,8 @@ func (s *PricingService) buildModelLookupCandidates(modelLower string) []string
func
normalizeModelNameForPricing
(
model
string
)
string
{
func
normalizeModelNameForPricing
(
model
string
)
string
{
// Common Gemini/VertexAI forms:
// Common Gemini/VertexAI forms:
// - models/gemini-2.0-flash-exp
// - models/gemini-2.0-flash-exp
// - publishers/google/models/gemini-
1
.5-pro
// - publishers/google/models/gemini-
2
.5-pro
// - projects/.../locations/.../publishers/google/models/gemini-
1
.5-pro
// - projects/.../locations/.../publishers/google/models/gemini-
2
.5-pro
model
=
strings
.
TrimSpace
(
model
)
model
=
strings
.
TrimSpace
(
model
)
model
=
strings
.
TrimLeft
(
model
,
"/"
)
model
=
strings
.
TrimLeft
(
model
,
"/"
)
model
=
strings
.
TrimPrefix
(
model
,
"models/"
)
model
=
strings
.
TrimPrefix
(
model
,
"models/"
)
...
...
frontend/src/components/account/AccountTestModal.vue
View file @
0c2a901a
...
@@ -292,8 +292,11 @@ const loadAvailableModels = async () => {
...
@@ -292,8 +292,11 @@ const loadAvailableModels = async () => {
if
(
availableModels
.
value
.
length
>
0
)
{
if
(
availableModels
.
value
.
length
>
0
)
{
if
(
props
.
account
.
platform
===
'
gemini
'
)
{
if
(
props
.
account
.
platform
===
'
gemini
'
)
{
const
preferred
=
const
preferred
=
availableModels
.
value
.
find
((
m
)
=>
m
.
id
===
'
gemini-2.0-flash
'
)
||
availableModels
.
value
.
find
((
m
)
=>
m
.
id
===
'
gemini-2.5-flash
'
)
||
availableModels
.
value
.
find
((
m
)
=>
m
.
id
===
'
gemini-2.5-pro
'
)
||
availableModels
.
value
.
find
((
m
)
=>
m
.
id
===
'
gemini-2.5-pro
'
)
||
availableModels
.
value
.
find
((
m
)
=>
m
.
id
===
'
gemini-3-pro
'
)
availableModels
.
value
.
find
((
m
)
=>
m
.
id
===
'
gemini-3-flash-preview
'
)
||
availableModels
.
value
.
find
((
m
)
=>
m
.
id
===
'
gemini-3-pro-preview
'
)
selectedModelId
.
value
=
preferred
?.
id
||
availableModels
.
value
[
0
].
id
selectedModelId
.
value
=
preferred
?.
id
||
availableModels
.
value
[
0
].
id
}
else
{
}
else
{
// Try to select Sonnet as default, otherwise use first model
// Try to select Sonnet as default, otherwise use first model
...
...
frontend/src/components/admin/account/AccountTestModal.vue
View file @
0c2a901a
...
@@ -232,8 +232,11 @@ const loadAvailableModels = async () => {
...
@@ -232,8 +232,11 @@ const loadAvailableModels = async () => {
if
(
availableModels
.
value
.
length
>
0
)
{
if
(
availableModels
.
value
.
length
>
0
)
{
if
(
props
.
account
.
platform
===
'
gemini
'
)
{
if
(
props
.
account
.
platform
===
'
gemini
'
)
{
const
preferred
=
const
preferred
=
availableModels
.
value
.
find
((
m
)
=>
m
.
id
===
'
gemini-2.0-flash
'
)
||
availableModels
.
value
.
find
((
m
)
=>
m
.
id
===
'
gemini-2.5-flash
'
)
||
availableModels
.
value
.
find
((
m
)
=>
m
.
id
===
'
gemini-2.5-pro
'
)
||
availableModels
.
value
.
find
((
m
)
=>
m
.
id
===
'
gemini-2.5-pro
'
)
||
availableModels
.
value
.
find
((
m
)
=>
m
.
id
===
'
gemini-3-pro
'
)
availableModels
.
value
.
find
((
m
)
=>
m
.
id
===
'
gemini-3-flash-preview
'
)
||
availableModels
.
value
.
find
((
m
)
=>
m
.
id
===
'
gemini-3-pro-preview
'
)
selectedModelId
.
value
=
preferred
?.
id
||
availableModels
.
value
[
0
].
id
selectedModelId
.
value
=
preferred
?.
id
||
availableModels
.
value
[
0
].
id
}
else
{
}
else
{
// Try to select Sonnet as default, otherwise use first model
// Try to select Sonnet as default, otherwise use first model
...
...
frontend/src/components/keys/UseKeyModal.vue
View file @
0c2a901a
...
@@ -443,7 +443,7 @@ $env:ANTHROPIC_AUTH_TOKEN="${apiKey}"`
...
@@ -443,7 +443,7 @@ $env:ANTHROPIC_AUTH_TOKEN="${apiKey}"`
}
}
function
generateGeminiCliContent
(
baseUrl
:
string
,
apiKey
:
string
):
FileConfig
{
function
generateGeminiCliContent
(
baseUrl
:
string
,
apiKey
:
string
):
FileConfig
{
const
model
=
'
gemini-2.
5-pro
'
const
model
=
'
gemini-2.
0-flash
'
const
modelComment
=
t
(
'
keys.useKeyModal.gemini.modelComment
'
)
const
modelComment
=
t
(
'
keys.useKeyModal.gemini.modelComment
'
)
let
path
:
string
let
path
:
string
let
content
:
string
let
content
:
string
...
@@ -548,14 +548,22 @@ function generateOpenCodeConfig(platform: string, baseUrl: string, apiKey: strin
...
@@ -548,14 +548,22 @@ function generateOpenCodeConfig(platform: string, baseUrl: string, apiKey: strin
}
}
}
}
const
geminiModels
=
{
const
geminiModels
=
{
'
gemini-3-pro-high
'
:
{
name
:
'
Gemini 3 Pro High
'
},
'
gemini-2.0-flash
'
:
{
name
:
'
Gemini 2.0 Flash
'
},
'
gemini-2.5-flash
'
:
{
name
:
'
Gemini 2.5 Flash
'
},
'
gemini-2.5-pro
'
:
{
name
:
'
Gemini 2.5 Pro
'
},
'
gemini-3-flash-preview
'
:
{
name
:
'
Gemini 3 Flash Preview
'
},
'
gemini-3-pro-preview
'
:
{
name
:
'
Gemini 3 Pro Preview
'
}
}
const
antigravityGeminiModels
=
{
'
gemini-2.5-flash
'
:
{
name
:
'
Gemini 2.5 Flash
'
},
'
gemini-2.5-flash-lite
'
:
{
name
:
'
Gemini 2.5 Flash Lite
'
},
'
gemini-2.5-flash-thinking
'
:
{
name
:
'
Gemini 2.5 Flash Thinking
'
},
'
gemini-3-flash
'
:
{
name
:
'
Gemini 3 Flash
'
},
'
gemini-3-pro-low
'
:
{
name
:
'
Gemini 3 Pro Low
'
},
'
gemini-3-pro-low
'
:
{
name
:
'
Gemini 3 Pro Low
'
},
'
gemini-3-pro-high
'
:
{
name
:
'
Gemini 3 Pro High
'
},
'
gemini-3-pro-preview
'
:
{
name
:
'
Gemini 3 Pro Preview
'
},
'
gemini-3-pro-preview
'
:
{
name
:
'
Gemini 3 Pro Preview
'
},
'
gemini-3-pro-image
'
:
{
name
:
'
Gemini 3 Pro Image
'
},
'
gemini-3-pro-image
'
:
{
name
:
'
Gemini 3 Pro Image
'
}
'
gemini-3-flash
'
:
{
name
:
'
Gemini 3 Flash
'
},
'
gemini-2.5-flash-thinking
'
:
{
name
:
'
Gemini 2.5 Flash Thinking
'
},
'
gemini-2.5-flash
'
:
{
name
:
'
Gemini 2.5 Flash
'
},
'
gemini-2.5-flash-lite
'
:
{
name
:
'
Gemini 2.5 Flash Lite
'
}
}
}
const
claudeModels
=
{
const
claudeModels
=
{
'
claude-opus-4-5-thinking
'
:
{
name
:
'
Claude Opus 4.5 Thinking
'
},
'
claude-opus-4-5-thinking
'
:
{
name
:
'
Claude Opus 4.5 Thinking
'
},
...
@@ -575,7 +583,7 @@ function generateOpenCodeConfig(platform: string, baseUrl: string, apiKey: strin
...
@@ -575,7 +583,7 @@ function generateOpenCodeConfig(platform: string, baseUrl: string, apiKey: strin
}
else
if
(
platform
===
'
antigravity-gemini
'
)
{
}
else
if
(
platform
===
'
antigravity-gemini
'
)
{
provider
[
platform
].
npm
=
'
@ai-sdk/google
'
provider
[
platform
].
npm
=
'
@ai-sdk/google
'
provider
[
platform
].
name
=
'
Antigravity (Gemini)
'
provider
[
platform
].
name
=
'
Antigravity (Gemini)
'
provider
[
platform
].
models
=
g
eminiModels
provider
[
platform
].
models
=
antigravityG
eminiModels
}
else
if
(
platform
===
'
openai
'
)
{
}
else
if
(
platform
===
'
openai
'
)
{
provider
[
platform
].
models
=
openaiModels
provider
[
platform
].
models
=
openaiModels
}
}
...
...
frontend/src/composables/useModelWhitelist.ts
View file @
0c2a901a
...
@@ -43,13 +43,13 @@ export const claudeModels = [
...
@@ -43,13 +43,13 @@ export const claudeModels = [
// Google Gemini
// Google Gemini
const
geminiModels
=
[
const
geminiModels
=
[
'
gemini-2.0-flash
'
,
'
gemini-2.0-flash-lite-preview
'
,
'
gemini-2.0-flash-exp
'
,
// Keep in sync with backend curated Gemini lists.
'
gemini-2.0-pro-exp
'
,
'
gemini-2.0-flash-thinking-exp
'
,
// This list is intentionally conservative (models commonly available across OAuth/API key).
'
gemini-2.
5-pro-exp-03-25
'
,
'
gemini-2.5-pro-preview-03-25
'
,
'
gemini-2.
0-flash
'
,
'
gemini-
3-pro-preview
'
,
'
gemini-
2.5-flash
'
,
'
gemini-
1
.5-pro
'
,
'
gemini-1.5-pro-latest
'
,
'
gemini-
2
.5-pro
'
,
'
gemini-
1.5-flash
'
,
'
gemini-1.5-flash-latest
'
,
'
gemini-1.5-flash-8b
'
,
'
gemini-
3-flash-preview
'
,
'
gemini-
exp-1206
'
'
gemini-
3-pro-preview
'
]
]
// 智谱 GLM
// 智谱 GLM
...
@@ -229,9 +229,8 @@ const openaiPresetMappings = [
...
@@ -229,9 +229,8 @@ const openaiPresetMappings = [
const
geminiPresetMappings
=
[
const
geminiPresetMappings
=
[
{
label
:
'
Flash 2.0
'
,
from
:
'
gemini-2.0-flash
'
,
to
:
'
gemini-2.0-flash
'
,
color
:
'
bg-blue-100 text-blue-700 hover:bg-blue-200 dark:bg-blue-900/30 dark:text-blue-400
'
},
{
label
:
'
Flash 2.0
'
,
from
:
'
gemini-2.0-flash
'
,
to
:
'
gemini-2.0-flash
'
,
color
:
'
bg-blue-100 text-blue-700 hover:bg-blue-200 dark:bg-blue-900/30 dark:text-blue-400
'
},
{
label
:
'
Flash Lite
'
,
from
:
'
gemini-2.0-flash-lite-preview
'
,
to
:
'
gemini-2.0-flash-lite-preview
'
,
color
:
'
bg-indigo-100 text-indigo-700 hover:bg-indigo-200 dark:bg-indigo-900/30 dark:text-indigo-400
'
},
{
label
:
'
2.5 Flash
'
,
from
:
'
gemini-2.5-flash
'
,
to
:
'
gemini-2.5-flash
'
,
color
:
'
bg-indigo-100 text-indigo-700 hover:bg-indigo-200 dark:bg-indigo-900/30 dark:text-indigo-400
'
},
{
label
:
'
1.5 Pro
'
,
from
:
'
gemini-1.5-pro
'
,
to
:
'
gemini-1.5-pro
'
,
color
:
'
bg-purple-100 text-purple-700 hover:bg-purple-200 dark:bg-purple-900/30 dark:text-purple-400
'
},
{
label
:
'
2.5 Pro
'
,
from
:
'
gemini-2.5-pro
'
,
to
:
'
gemini-2.5-pro
'
,
color
:
'
bg-purple-100 text-purple-700 hover:bg-purple-200 dark:bg-purple-900/30 dark:text-purple-400
'
}
{
label
:
'
1.5 Flash
'
,
from
:
'
gemini-1.5-flash
'
,
to
:
'
gemini-1.5-flash
'
,
color
:
'
bg-emerald-100 text-emerald-700 hover:bg-emerald-200 dark:bg-emerald-900/30 dark:text-emerald-400
'
}
]
]
// =====================
// =====================
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment