feat: Modify the Gemini account verification logic (#12155)

Refs https://github.com/1Panel-dev/1Panel/issues/12149
This commit is contained in:
CityFun
2026-03-12 09:07:33 +00:00
committed by GitHub
parent 6db2a9352e
commit fb87cf545f
5 changed files with 50 additions and 11 deletions
+2 -5
View File
@@ -192,12 +192,9 @@ var catalog = map[string]Meta{
EnvKey: "GEMINI_API_KEY",
Enabled: true,
Models: []Model{
{ID: "google/gemini-1.5-flash", Name: "Gemini 1.5 Flash"},
{ID: "google/gemini-1.5-pro", Name: "Gemini 1.5 Pro"},
{ID: "google/gemini-2.0-flash", Name: "Gemini 2.0 Flash"},
{ID: "google/gemini-2.5-flash", Name: "Gemini 2.5 Flash"},
{ID: "google/gemini-2.5-pro", Name: "Gemini 2.5 Pro"},
{ID: "google/gemini-3-flash-preview", Name: "Gemini 3 Flash Preview"},
{ID: "google/gemini-flash-latest", Name: "Gemini Flash Latest"},
{ID: "google/gemini-3-pro-preview", Name: "Gemini 3 Pro Preview"},
},
},
"moonshot": {
+6
View File
@@ -24,6 +24,8 @@ func BuildOpenClawPatch(provider, modelName, apiType string, maxTokens, contextW
switch provider {
case "deepseek":
return buildDeepseekPatch(modelName, baseURL, apiKey), nil
case "gemini":
return buildGeminiPatch(modelName), nil
case "moonshot", "kimi":
return buildMoonshotPatch(provider, modelName, modelID, baseURL, apiKey), nil
case "bailian-coding-plan":
@@ -45,6 +47,10 @@ func BuildOpenClawPatch(provider, modelName, apiType string, maxTokens, contextW
}
}
func buildGeminiPatch(modelName string) *OpenClawPatch {
return &OpenClawPatch{PrimaryModel: modelName}
}
func buildDeepseekPatch(modelName, baseURL, apiKey string) *OpenClawPatch {
return &OpenClawPatch{
PrimaryModel: modelName,
+12 -2
View File
@@ -69,11 +69,21 @@ func BuildVerifyRequest(provider, baseURL, apiKey string) VerifyRequest {
request.URL = base + "/v1/models"
}
case "gemini":
request.Method = http.MethodPost
if strings.Contains(base, "/v1beta") {
request.URL = fmt.Sprintf("%s/models?key=%s", base, apiKey)
request.URL = base + "/models/gemini-3-flash-preview:generateContent"
} else {
request.URL = fmt.Sprintf("%s/v1beta/models?key=%s", base, apiKey)
request.URL = base + "/v1beta/models/gemini-3-flash-preview:generateContent"
}
headers["x-goog-api-key"] = apiKey
headers["Content-Type"] = "application/json"
request.Body = mustJSON(map[string]interface{}{
"contents": []map[string]interface{}{{
"parts": []map[string]string{{
"text": "Explain how AI works in a few words",
}},
}},
})
case "zai":
headers["Authorization"] = fmt.Sprintf("Bearer %s", apiKey)
request.URL = base + "/models"
+15 -1
View File
@@ -384,7 +384,7 @@ func (a AgentService) UpdateModelConfig(req dto.AgentModelConfigUpdateReq) error
if modelName == "" {
return buserr.New("ErrAgentProviderMismatch")
}
if provider != "custom" && provider != "vllm" && !strings.HasPrefix(modelName, provider+"/") {
if provider != "custom" && provider != "vllm" && !modelMatchesProvider(provider, modelName) {
return buserr.New("ErrAgentProviderMismatch")
}
baseURL := strings.TrimSpace(account.BaseURL)
@@ -1950,6 +1950,20 @@ func normalizeAgentType(agentType string) string {
return trim
}
func modelMatchesProvider(provider, modelName string) bool {
prefix := providerModelPrefix(provider)
return prefix != "" && strings.HasPrefix(strings.TrimSpace(modelName), prefix+"/")
}
func providerModelPrefix(provider string) string {
switch strings.ToLower(strings.TrimSpace(provider)) {
case "gemini":
return "google"
default:
return strings.ToLower(strings.TrimSpace(provider))
}
}
func isSupportedAgentType(agentType string) bool {
switch normalizeAgentType(agentType) {
case constant.AppOpenclaw, constant.AppCopaw:
@@ -52,6 +52,15 @@ const accountOptions = ref<AI.AgentAccountItem[]>([]);
const modelOptions = ref<AI.ProviderModelInfo[]>([]);
const provdier = ref('');
const getModelPrefix = (provider: string) => {
switch (provider) {
case 'gemini':
return 'google';
default:
return provider;
}
};
const form = reactive({
accountId: undefined as unknown as number,
manualModel: false,
@@ -128,8 +137,9 @@ const handleAccountChange = () => {
setModelsByProvider(selected.provider);
return;
}
const modelPrefix = getModelPrefix(selected.provider);
setModelsByProvider(selected.provider);
if (!form.manualModel && (!form.model || !form.model.startsWith(`${selected.provider}/`))) {
if (!form.manualModel && (!form.model || !form.model.startsWith(`${modelPrefix}/`))) {
form.model = modelOptions.value.length > 0 ? modelOptions.value[0].id : '';
}
};
@@ -150,7 +160,8 @@ const handleManualModelChange = (val: unknown) => {
form.model = '';
return;
}
if (!form.model || !form.model.startsWith(`${selected.provider}/`)) {
const modelPrefix = getModelPrefix(selected.provider);
if (!form.model || !form.model.startsWith(`${modelPrefix}/`)) {
form.model = modelOptions.value.length > 0 ? modelOptions.value[0].id : '';
}
};
@@ -172,13 +183,14 @@ const load = async (agent: AI.AgentItem) => {
form.accountId = currentAccount.id;
provdier.value = currentAccount.provider;
setModelsByProvider(currentAccount.provider);
const modelPrefix = getModelPrefix(currentAccount.provider);
const inProviderModels = modelOptions.value.some((item) => item.id === agent.model);
form.manualModel =
currentAccount.provider === 'custom' ||
currentAccount.provider === 'vllm' ||
currentAccount.provider === 'ollama' ||
!inProviderModels;
if (agent.model && (form.manualModel || agent.model.startsWith(`${currentAccount.provider}/`))) {
if (agent.model && (form.manualModel || agent.model.startsWith(`${modelPrefix}/`))) {
form.model = agent.model;
} else {
form.model = modelOptions.value.length > 0 ? modelOptions.value[0].id : '';