mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-09-22 16:00:51 +00:00
feat(ai-agents): add bailian-coding-plan account support (#12014)
This commit is contained in:
@@ -144,6 +144,24 @@ var catalog = map[string]Meta{
|
||||
{ID: "kimi-coding/k2p5", Name: "Kimi K2.5"},
|
||||
},
|
||||
},
|
||||
"bailian-coding-plan": {
|
||||
Key: "bailian-coding-plan",
|
||||
DisplayName: "阿里云百炼 Coding Plan",
|
||||
Sort: 105,
|
||||
DefaultBaseURL: "https://coding.dashscope.aliyuncs.com/v1",
|
||||
EnvKey: "QWEN_API_KEY",
|
||||
Enabled: true,
|
||||
Models: []Model{
|
||||
{ID: "bailian-coding-plan/qwen3.5-plus", Name: "Qwen3.5-Plus"},
|
||||
{ID: "bailian-coding-plan/qwen3-max", Name: "Qwen3-Max"},
|
||||
{ID: "bailian-coding-plan/qwen3-coder-next", Name: "Qwen3-Coder-Next"},
|
||||
{ID: "bailian-coding-plan/qwen3-coder-plus", Name: "Qwen3-Coder-Plus"},
|
||||
{ID: "bailian-coding-plan/minimax-m2.5", Name: "MiniMax M2.5"},
|
||||
{ID: "bailian-coding-plan/glm-5", Name: "GLM-5"},
|
||||
{ID: "bailian-coding-plan/kimi-k2.5", Name: "Kimi-k2.5"},
|
||||
{ID: "bailian-coding-plan/glm-4.7", Name: "GLM-4.7"},
|
||||
},
|
||||
},
|
||||
"qwen": {
|
||||
Key: "qwen",
|
||||
DisplayName: "Qwen",
|
||||
|
||||
@@ -369,6 +369,9 @@ func (a AgentService) CreateAccount(req dto.AgentAccountCreateReq) error {
|
||||
return buserr.New("ErrAgentApiKeyRequired")
|
||||
}
|
||||
baseURL := strings.TrimSpace(req.BaseURL)
|
||||
if fixedURL, ok := fixedProviderBaseURL(provider); ok {
|
||||
baseURL = fixedURL
|
||||
}
|
||||
if provider == "custom" && baseURL == "" {
|
||||
return buserr.New("ErrAgentBaseURLRequired")
|
||||
}
|
||||
@@ -425,6 +428,9 @@ func (a AgentService) UpdateAccount(req dto.AgentAccountUpdateReq) error {
|
||||
}
|
||||
provider := strings.ToLower(strings.TrimSpace(account.Provider))
|
||||
baseURL := strings.TrimSpace(req.BaseURL)
|
||||
if fixedURL, ok := fixedProviderBaseURL(provider); ok {
|
||||
baseURL = fixedURL
|
||||
}
|
||||
if provider == "custom" && baseURL == "" {
|
||||
return buserr.New("ErrAgentBaseURLRequired")
|
||||
}
|
||||
@@ -523,6 +529,9 @@ func (a AgentService) VerifyAccount(req dto.AgentAccountVerifyReq) error {
|
||||
return buserr.New("ErrAgentApiKeyRequired")
|
||||
}
|
||||
baseURL := strings.TrimSpace(req.BaseURL)
|
||||
if fixedURL, ok := fixedProviderBaseURL(provider); ok {
|
||||
baseURL = fixedURL
|
||||
}
|
||||
if baseURL == "" {
|
||||
if defaultURL, ok := providerDefaultBaseURL(provider); ok {
|
||||
baseURL = defaultURL
|
||||
@@ -1017,6 +1026,9 @@ func verifyProvider(provider, baseURL, apiKey string) error {
|
||||
if provider == "minimax" {
|
||||
return verifyMinimax("https://api.minimax.chat/v1", apiKey)
|
||||
}
|
||||
if provider == "bailian-coding-plan" {
|
||||
return verifyBailianCodingPlan(baseURL, apiKey)
|
||||
}
|
||||
client := &http.Client{Timeout: 10 * time.Second}
|
||||
reqURL, headers := buildVerifyRequest(provider, baseURL, apiKey)
|
||||
request, err := http.NewRequest(http.MethodGet, reqURL, nil)
|
||||
@@ -1037,6 +1049,41 @@ func verifyProvider(provider, baseURL, apiKey string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func verifyBailianCodingPlan(baseURL, apiKey string) error {
|
||||
client := &http.Client{Timeout: 10 * time.Second}
|
||||
base := strings.TrimRight(baseURL, "/")
|
||||
if !strings.Contains(base, "/v1") {
|
||||
base = base + "/v1"
|
||||
}
|
||||
reqURL := base + "/chat/completions"
|
||||
body := map[string]interface{}{
|
||||
"model": "qwen3.5-plus",
|
||||
"messages": []map[string]string{
|
||||
{"role": "user", "content": "test"},
|
||||
},
|
||||
"max_tokens": 1,
|
||||
}
|
||||
payload, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
request, err := http.NewRequest(http.MethodPost, reqURL, bytes.NewBuffer(payload))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
request.Header.Set("Authorization", fmt.Sprintf("Bearer %s", apiKey))
|
||||
request.Header.Set("Content-Type", "application/json")
|
||||
resp, err := client.Do(request)
|
||||
if err != nil {
|
||||
return buserr.WithErr("ErrAgentAccountUnavailable", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode >= 400 {
|
||||
return buserr.WithErr("ErrAgentAccountUnavailable", fmt.Errorf("verify failed: %s", resp.Status))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func verifyMinimax(baseURL, apiKey string) error {
|
||||
client := &http.Client{Timeout: 10 * time.Second}
|
||||
base := strings.TrimRight(baseURL, "/")
|
||||
@@ -1384,6 +1431,37 @@ func writeOpenclawConfig(confDir, provider, modelName, apiType string, maxTokens
|
||||
},
|
||||
},
|
||||
}
|
||||
} else if provider == "bailian-coding-plan" {
|
||||
cfg.Agents.Defaults.Model.Primary = modelName
|
||||
base := baseURL
|
||||
if base == "" {
|
||||
if defaultURL, ok := providerDefaultBaseURL(provider); ok {
|
||||
base = defaultURL
|
||||
}
|
||||
}
|
||||
plainKey := strings.TrimSpace(apiKey)
|
||||
_, useMaxTokens, useContextWindow := resolveRuntimeParams(provider, apiType, maxTokens, contextWindow)
|
||||
cfg.Models = &modelsConfig{
|
||||
Mode: "merge",
|
||||
Providers: map[string]modelProvider{
|
||||
"bailian-coding-plan": {
|
||||
ApiKey: plainKey,
|
||||
BaseUrl: base,
|
||||
Api: "openai-completions",
|
||||
Models: []modelEntry{
|
||||
{
|
||||
ID: modelID,
|
||||
Name: modelID,
|
||||
Reasoning: strings.Contains(strings.ToLower(modelID), "reason") || strings.Contains(strings.ToLower(modelID), "thinking"),
|
||||
Input: []string{"text"},
|
||||
ContextWindow: useContextWindow,
|
||||
MaxTokens: useMaxTokens,
|
||||
Cost: modelCost{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
} else if provider == "minimax" {
|
||||
normalizedID := modelID
|
||||
switch strings.ToLower(modelID) {
|
||||
@@ -1617,6 +1695,15 @@ func providerDefaultBaseURL(provider string) (string, bool) {
|
||||
return providercatalog.DefaultBaseURL(provider)
|
||||
}
|
||||
|
||||
func fixedProviderBaseURL(provider string) (string, bool) {
|
||||
switch strings.ToLower(strings.TrimSpace(provider)) {
|
||||
case "bailian-coding-plan":
|
||||
return providerDefaultBaseURL(provider)
|
||||
default:
|
||||
return "", false
|
||||
}
|
||||
}
|
||||
|
||||
func isSupportedAgentProvider(provider string) bool {
|
||||
return providercatalog.IsEnabled(provider)
|
||||
}
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('aiTools.agents.apiKey')" prop="apiKey">
|
||||
<el-input v-model="form.apiKey" type="password" show-password />
|
||||
<span class="input-help">{{ $t('aiTools.agents.customProviderHelper') }}</span>
|
||||
<span class="input-help" v-if="form.provider === 'custom'">
|
||||
{{ $t('aiTools.agents.customProviderHelper') }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-checkbox v-model="form.rememberApiKey">{{ $t('terminal.rememberPassword') }}</el-checkbox>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<template #main>
|
||||
<ComplexTable :data="items" :pagination-config="paginationConfig" @search="search">
|
||||
<el-table-column :label="$t('commons.table.name')" prop="name" min-width="200" />
|
||||
<el-table-column :label="$t('aiTools.agents.provider')" prop="provider" width="120">
|
||||
<el-table-column :label="$t('aiTools.agents.provider')" prop="provider" width="200">
|
||||
<template #default="{ row }">
|
||||
{{ getAgentProviderDisplayName(row.provider, row.providerName) }}
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user