diff --git a/agent/app/provider/catalog.go b/agent/app/provider/catalog.go
index 624a626b1..6776febe6 100644
--- a/agent/app/provider/catalog.go
+++ b/agent/app/provider/catalog.go
@@ -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",
diff --git a/agent/app/service/agents.go b/agent/app/service/agents.go
index 680ae3f6e..16c1186e7 100644
--- a/agent/app/service/agents.go
+++ b/agent/app/service/agents.go
@@ -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)
}
diff --git a/frontend/src/views/ai/agents/model/add/index.vue b/frontend/src/views/ai/agents/model/add/index.vue
index c930d19e4..1a1f22af4 100644
--- a/frontend/src/views/ai/agents/model/add/index.vue
+++ b/frontend/src/views/ai/agents/model/add/index.vue
@@ -16,7 +16,9 @@
- {{ $t('aiTools.agents.customProviderHelper') }}
+
+ {{ $t('aiTools.agents.customProviderHelper') }}
+
{{ $t('terminal.rememberPassword') }}
diff --git a/frontend/src/views/ai/agents/model/index.vue b/frontend/src/views/ai/agents/model/index.vue
index d9e9966c6..0fef0877b 100644
--- a/frontend/src/views/ai/agents/model/index.vue
+++ b/frontend/src/views/ai/agents/model/index.vue
@@ -12,7 +12,7 @@
-
+
{{ getAgentProviderDisplayName(row.provider, row.providerName) }}