Skip to content

扩展阿里云订阅计划支持 - #4571

Closed
yutons wants to merge 1 commit into
QuantumNous:mainfrom
yutons:yutons
Closed

扩展阿里云订阅计划支持#4571
yutons wants to merge 1 commit into
QuantumNous:mainfrom
yutons:yutons

Conversation

@yutons

@yutons yutons commented May 1, 2026

Copy link
Copy Markdown

⚠️ 提交说明 / PR Notice

Important

  • 请提供人工撰写的简洁摘要,避免直接粘贴未经整理的 AI 输出。

扩展阿里云百炼订阅计划支持,新增 Token Plan(企业版)和 Coding Plan(个人版)两种订阅渠道。

📝 变更描述 / Description

(简述:做了什么?为什么这样改能生效?请基于你对代码逻辑的理解来写,避免粘贴未经整理的内容)

阿里云百炼的订阅计划提供了独立的 API 端点,这些端点原生兼容 OpenAI 和 Anthropic 协议,因此请求无需转换为阿里 DashScope
原生格式,可以直接透传。本次变更复用了已有的 ChannelSpecialBases 机制(此前已用于火山引擎 Coding
Plan),将两种阿里云订阅计划注册为特殊 Base URL:

后端改动:

  • constant/channel.go:在 ChannelSpecialBases 中新增 ali-token-plan 和 ali-coding-plan 两条记录,分别配置 Claude 和
    OpenAI 协议的独立端点
  • relay/channel/ali/adaptor.go:当检测到 base_url 命中特殊计划时,跳过 DashScope
    格式转换和专用头(X-DashScope-SSE/X-DashScope-Async),直接透传请求;Claude 格式请求委托给 Claude
    适配器处理响应;同时将 GetRequestURL 从变量累加重构为提前返回,逻辑更清晰
  • controller/channel_upstream_update.go:修复模型列表拉取逻辑,特殊计划使用计划自身的 OpenAIBaseURL/models
    而非硬编码的 /compatible-mode/v1/models

前端改动:

  • 渠道编辑抽屉中为阿里云渠道(type 17)新增 Base URL 下拉选择器,提供三个选项:标准 DashScope 地址、Token Plan、Coding
    Plan
  • 新增隐藏点击解锁机制(10 次点击标签),解锁后可输入自定义 API 地址
  • 默认 Base URL 设为 https://dashscope.aliyuncs.com

i18n 改动:

  • 6 种语言文件新增阿里计划相关翻译键,并对部分键做了字母序重排

🚀 变更类型 / Type of change

  • 🐛 Bug 修复 (Bug fix) - 请关联对应 Issue,避免将设计取舍、理解偏差或预期不一致直接归类为 bug
  • [√] ✨ 新功能 (New feature) - 重大特性建议先通过 Issue 沟通
  • ⚡ 性能优化 / 重构 (Refactor)
  • 📝 文档更新 (Documentation)

🔗 关联任务 / Related Issue

  • Closes # (如有)

✅ 提交前检查项 / Checklist

  • [√] 人工确认: 我已亲自整理并撰写此描述,没有直接粘贴未经处理的 AI 输出。
  • [√] 非重复提交: 我已搜索现有的 IssuesPRs,确认不是重复提交。
  • Bug fix 说明: 若此 PR 标记为 Bug fix,我已提交或关联对应 Issue,且不会将设计取舍、预期不一致或理解偏差直接归类为 bug。
  • 变更理解: 我已理解这些更改的工作原理及可能影响。
  • 范围聚焦: 本 PR 未包含任何与当前任务无关的代码改动。
  • 本地验证: 已在本地运行并通过测试或手动验证,维护者可以据此复核结果。
  • 安全合规: 代码中无敏感凭据,且符合项目代码规范。

📸 运行证明 / Proof of Work

(请在此粘贴截图、关键日志或测试报告,以证明变更生效)
image
image

Summary by CodeRabbit

  • New Features

    • Added support for Ali special coding and token plans with dedicated API endpoints
    • Introduced DashScope integration with preset API endpoint selections
    • Implemented unlock flow for custom API address editing in Ali channel configuration
  • Documentation

    • Added coding plan configuration reference for subscription providers
  • Internationalization

    • Added translations for new Ali plan features and API endpoint management across all supported languages

@coderabbitai

coderabbitai Bot commented May 1, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

This PR introduces support for special coding plans from Aliyun/DashScope and other providers with dedicated base URL endpoints. It adds configuration mappings, updates request routing logic to prefer special plan URLs when available, implements a UI unlock flow for custom API endpoint editing, and extends internationalization support across multiple languages.

Changes

Cohort / File(s) Summary
Documentation & Configuration
coding-plan.md, constant/channel.go
Introduces new documentation for coding subscription plans across multiple providers and adds special base URL mappings (ClaudeBaseURL, OpenAIBaseURL) for Ali token and coding plans to enable provider-specific endpoint routing.
Backend Request Routing
controller/channel_upstream_update.go, relay/channel/ali/adaptor.go
Updates model fetching and request handling to check special base URL mappings and route Ali channel requests to Claude or OpenAI endpoints when available, with fallback to standard Ali-compatible mode; removes legacy workaround code.
Frontend UI Components
web/default/src/features/channels/components/drawers/channel-mutate-drawer.tsx
Adds unlock flow for Ali/DashScope (type 17) similar to VolcEngine, introduces conditional form rendering for base URL editing with preset region/endpoint selection before unlock and free-form input after, and auto-populates default DashScope endpoint.
Internationalization
web/default/src/i18n/locales/en.json, fr.json, ja.json, ru.json, vi.json, zh.json
Adds translations for Ali coding plans, token plans, base price, API endpoint selection, DashScope examples/URLs, and fixes footer attribution key naming (footer.newapi.projectAttributionSuffix) consistently across all supported languages; reorders existing UI string keys.

Sequence Diagram

sequenceDiagram
    participant User as User (Frontend)
    participant Controller as Controller
    participant Adaptor as Ali Adaptor
    participant Provider as Ali Provider

    User->>Controller: Request models for Ali channel
    Controller->>Controller: Check ChannelSpecialBases for base URL
    alt Has Special Base URL
        Controller->>Provider: Fetch from /models with OpenAIBaseURL
    else Standard Ali Channel
        Controller->>Provider: Fetch from /compatible-mode/v1/models
    end
    Provider-->>Controller: Model list

    User->>User: Send request with special plan

    User->>Adaptor: Process request
    Adaptor->>Adaptor: Check if base URL is "special"
    alt Is Claude Request
        Adaptor->>Adaptor: Use ClaudeBaseURL directly
        Adaptor->>Provider: Route to {ClaudeBaseURL}/v1/messages
    else Is Other Format
        Adaptor->>Adaptor: Use OpenAIBaseURL directly
        Adaptor->>Provider: Route to {OpenAIBaseURL}/chat/completions
    else Fallback
        Adaptor->>Provider: Use standard Ali-compatible endpoint
    end
    Provider-->>Adaptor: Response
    Adaptor-->>User: Processed response
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • seefs001
  • Calcium-Ion

Poem

🐰 Special plans hop through the gateway,
Ali routes find their own playway,
Claude and OpenAI dance in harmony,
With unlock flows, smooth as can be,
Multi-tongue translates our spree! 🌍

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: extending Alibaba Cloud subscription plan support by adding new Ali-token-plan and ali-coding-plan entries throughout the codebase.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (1)
web/default/src/features/channels/components/drawers/channel-mutate-drawer.tsx (1)

404-405: ⚡ Quick win

Use hierarchical i18n keys for the newly added Ali strings

New translation calls use literal English phrases as keys. Please switch these new entries to stable hierarchical keys (e.g. channels.ali.tokenPlan, channels.ali.unlockToast, channels.ali.selectEndpoint) for consistency and maintainability.

As per coding guidelines "Use hierarchical, semantically clear translation keys with consistent naming (e.g., dashboard.overview.title)".

Also applies to: 1781-1785, 1789-1789

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@web/default/src/features/channels/components/drawers/channel-mutate-drawer.tsx`
around lines 404 - 405, Replace the new literal-English i18n keys in
ChannelMutateDrawer with hierarchical keys: locate the t(...) calls around the
toast.info call and the other translation uses in this file (the
ChannelMutateDrawer component) and change strings like 'Ali custom API address
editing unlocked' and the other literal phrases at the noted positions to stable
hierarchical keys such as channels.ali.unlockToast, channels.ali.tokenPlan,
channels.ali.selectEndpoint; update the corresponding translation JSON entries
to match these new keys and ensure the t(...) calls use those hierarchical keys
instead of raw English sentences.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@relay/channel/ali/adaptor.go`:
- Around line 95-111: In GetRequestURL, the special-plan OpenAIBaseURL override
is applied before checking info.RelayMode, causing non-Claude requests for plans
like ali-token-plan to always route to /chat/completions; move the
specialPlan.OpenAIBaseURL handling inside the RelayMode switch (the same place
where Claude handling and supportsAliAnthropicMessages are evaluated) so that
for each RelayMode (e.g., RelayModeCompletion, RelayModeEmbedding,
RelayModeResponse, image relay) you return the mode-appropriate
OpenAI-compatible path using specialPlan.OpenAIBaseURL when present, falling
back to baseUrl paths otherwise; update logic around info.RelayFormat and
info.RelayMode in GetRequestURL to perform the OpenAIBaseURL override per mode
rather than unconditionally.

In
`@web/default/src/features/channels/components/drawers/channel-mutate-drawer.tsx`:
- Around line 1759-1762: The FormLabel currently only handles mouse clicks
(onClick={handleAliApiConfigSecretClick}) which is not keyboard-accessible; make
the unlock trigger keyboard-operable by giving the FormLabel a semantics and
keyboard handlers: add a focusable attribute (tabIndex=0), semantic role
(role="button"), an onKeyDown handler that calls handleAliApiConfigSecretClick
when Enter or Space is pressed, and include appropriate ARIA attributes (e.g.,
aria-label describing the action and aria-expanded or aria-pressed as
applicable) so screen readers and keyboard users can operate the hidden-unlock
control.
- Around line 632-638: When switching channel type to Ali (the currentType ===
17 branch in channel-mutate-drawer.tsx) we must normalize base_url instead of
only setting it when empty; update the logic in the currentType === 17 handler
(where form.getValues('base_url') and form.setValue('base_url',
'https://dashscope.aliyuncs.com') are used) to either validate the existing
base_url against an expected Ali pattern and replace it with the default if it
doesn't match, or simply overwrite it with 'https://dashscope.aliyuncs.com'
whenever currentType becomes 17 so incompatible sentinel values from other
channel types cannot persist.

In `@web/default/src/i18n/locales/fr.json`:
- Around line 211-213: The French locale has two values still in English; update
the JSON value strings for the keys "Ali Coding Plan" and "Ali Token Plan" to
their French translations so the UI is consistently localized (e.g., replace
"Ali Coding Plan" value and "Ali Token Plan" value with appropriate French
phrases matching the surrounding style).

In `@web/default/src/i18n/locales/ru.json`:
- Around line 211-213: Replace the two English display values so Russian users
don't see mixed-language options: update the JSON entries for the keys "Ali
Coding Plan" and "Ali Token Plan" to Russian strings (for example, "План
кодирования Ali" for "Ali Coding Plan" and "Токен-план Ali" or "План токенов
Ali" for "Ali Token Plan") and ensure the key "Ali custom API address editing
unlocked" remains correctly localized; edit the values for those keys in ru.json
accordingly and run a quick UI check to confirm the selector shows only Russian
labels.

In `@web/default/src/i18n/locales/vi.json`:
- Around line 211-213: The vi.json entries for the new Ali plan labels use
English values; update the values for the keys "Ali Coding Plan" and "Ali Token
Plan" to Vietnamese so the UI is fully localized (keep the keys unchanged, only
replace the right-hand string values for "Ali Coding Plan" and "Ali Token Plan"
with appropriate Vietnamese translations).

---

Nitpick comments:
In
`@web/default/src/features/channels/components/drawers/channel-mutate-drawer.tsx`:
- Around line 404-405: Replace the new literal-English i18n keys in
ChannelMutateDrawer with hierarchical keys: locate the t(...) calls around the
toast.info call and the other translation uses in this file (the
ChannelMutateDrawer component) and change strings like 'Ali custom API address
editing unlocked' and the other literal phrases at the noted positions to stable
hierarchical keys such as channels.ali.unlockToast, channels.ali.tokenPlan,
channels.ali.selectEndpoint; update the corresponding translation JSON entries
to match these new keys and ensure the t(...) calls use those hierarchical keys
instead of raw English sentences.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b3eae75b-009a-40f6-89aa-e1171686d899

📥 Commits

Reviewing files that changed from the base of the PR and between dac55f0 and 7deafdc.

📒 Files selected for processing (11)
  • coding-plan.md
  • constant/channel.go
  • controller/channel_upstream_update.go
  • relay/channel/ali/adaptor.go
  • web/default/src/features/channels/components/drawers/channel-mutate-drawer.tsx
  • web/default/src/i18n/locales/en.json
  • web/default/src/i18n/locales/fr.json
  • web/default/src/i18n/locales/ja.json
  • web/default/src/i18n/locales/ru.json
  • web/default/src/i18n/locales/vi.json
  • web/default/src/i18n/locales/zh.json

Comment on lines 95 to +111
func (a *Adaptor) GetRequestURL(info *relaycommon.RelayInfo) (string, error) {
var fullRequestURL string
baseUrl := info.ChannelBaseUrl
specialPlan, hasSpecialPlan := channelconstant.ChannelSpecialBases[baseUrl]

switch info.RelayFormat {
case types.RelayFormatClaude:
if hasSpecialPlan && specialPlan.ClaudeBaseURL != "" {
return fmt.Sprintf("%s/v1/messages", specialPlan.ClaudeBaseURL), nil
}
if supportsAliAnthropicMessages(info.UpstreamModelName) {
fullRequestURL = fmt.Sprintf("%s/apps/anthropic/v1/messages", info.ChannelBaseUrl)
} else {
fullRequestURL = fmt.Sprintf("%s/compatible-mode/v1/chat/completions", info.ChannelBaseUrl)
return fmt.Sprintf("%s/apps/anthropic/v1/messages", baseUrl), nil
}
return fmt.Sprintf("%s/compatible-mode/v1/chat/completions", baseUrl), nil
default:
if hasSpecialPlan && specialPlan.OpenAIBaseURL != "" {
return fmt.Sprintf("%s/chat/completions", specialPlan.OpenAIBaseURL), nil
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Keep special-plan routing mode-aware.

This early return sends every non-Claude special-plan request to /chat/completions, so embeddings, completions, responses, and any image relay that reaches this path will hit the wrong upstream endpoint once ChannelBaseUrl is ali-token-plan or ali-coding-plan. Move the OpenAIBaseURL override inside the RelayMode switch so each mode still maps to its own OpenAI-compatible path.

Suggested direction
 	default:
-		if hasSpecialPlan && specialPlan.OpenAIBaseURL != "" {
-			return fmt.Sprintf("%s/chat/completions", specialPlan.OpenAIBaseURL), nil
-		}
+		openAIBaseURL := baseUrl
+		if hasSpecialPlan && specialPlan.OpenAIBaseURL != "" {
+			openAIBaseURL = specialPlan.OpenAIBaseURL
+		}
 		switch info.RelayMode {
 		case constant.RelayModeEmbeddings:
+			if hasSpecialPlan && specialPlan.OpenAIBaseURL != "" {
+				return fmt.Sprintf("%s/embeddings", openAIBaseURL), nil
+			}
 			return fmt.Sprintf("%s/compatible-mode/v1/embeddings", baseUrl), nil
 		case constant.RelayModeRerank:
 			return fmt.Sprintf("%s/api/v1/services/rerank/text-rerank/text-rerank", baseUrl), nil
 		case constant.RelayModeResponses:
+			if hasSpecialPlan && specialPlan.OpenAIBaseURL != "" {
+				return fmt.Sprintf("%s/responses", openAIBaseURL), nil
+			}
 			return fmt.Sprintf("%s/api/v2/apps/protocols/compatible-mode/v1/responses", baseUrl), nil
 		case constant.RelayModeImagesGenerations:
 			if isSyncImageModel(info.OriginModelName) {
 				return fmt.Sprintf("%s/api/v1/services/aigc/multimodal-generation/generation", baseUrl), nil
 			} else {
 				return fmt.Sprintf("%s/api/v1/services/aigc/text2image/image-synthesis", baseUrl), nil
 			}
 		case constant.RelayModeImagesEdits:
 			if isOldWanModel(info.OriginModelName) {
 				return fmt.Sprintf("%s/api/v1/services/aigc/image2image/image-synthesis", baseUrl), nil
 			} else if isWanModel(info.OriginModelName) {
 				return fmt.Sprintf("%s/api/v1/services/aigc/image-generation/generation", baseUrl), nil
 			} else {
 				return fmt.Sprintf("%s/api/v1/services/aigc/multimodal-generation/generation", baseUrl), nil
 			}
 		case constant.RelayModeCompletions:
+			if hasSpecialPlan && specialPlan.OpenAIBaseURL != "" {
+				return fmt.Sprintf("%s/completions", openAIBaseURL), nil
+			}
 			return fmt.Sprintf("%s/compatible-mode/v1/completions", baseUrl), nil
 		default:
+			if hasSpecialPlan && specialPlan.OpenAIBaseURL != "" {
+				return fmt.Sprintf("%s/chat/completions", openAIBaseURL), nil
+			}
 			return fmt.Sprintf("%s/compatible-mode/v1/chat/completions", baseUrl), nil
 		}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@relay/channel/ali/adaptor.go` around lines 95 - 111, In GetRequestURL, the
special-plan OpenAIBaseURL override is applied before checking info.RelayMode,
causing non-Claude requests for plans like ali-token-plan to always route to
/chat/completions; move the specialPlan.OpenAIBaseURL handling inside the
RelayMode switch (the same place where Claude handling and
supportsAliAnthropicMessages are evaluated) so that for each RelayMode (e.g.,
RelayModeCompletion, RelayModeEmbedding, RelayModeResponse, image relay) you
return the mode-appropriate OpenAI-compatible path using
specialPlan.OpenAIBaseURL when present, falling back to baseUrl paths otherwise;
update logic around info.RelayFormat and info.RelayMode in GetRequestURL to
perform the OpenAIBaseURL override per mode rather than unconditionally.

Comment on lines +632 to +638
// Type 17 (Ali) - set default base_url
if (currentType === 17) {
const currentBaseUrlValue = form.getValues('base_url')
if (!currentBaseUrlValue || currentBaseUrlValue === '') {
form.setValue('base_url', 'https://dashscope.aliyuncs.com')
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Normalize base_url when switching to Ali type to avoid invalid sentinel carry-over

For type 17, defaulting only on empty values lets incompatible values (e.g. from other channel types like doubao-coding-plan) persist and be submitted. This can break upstream requests.

Suggested fix
+const ALI_DEFAULT_BASE_URL = 'https://dashscope.aliyuncs.com'
+const ALI_PRESET_BASE_URLS = new Set([
+  ALI_DEFAULT_BASE_URL,
+  'ali-token-plan',
+  'ali-coding-plan',
+])

  // Type 17 (Ali) - set default base_url
  if (currentType === 17) {
-   const currentBaseUrlValue = form.getValues('base_url')
-   if (!currentBaseUrlValue || currentBaseUrlValue === '') {
-     form.setValue('base_url', 'https://dashscope.aliyuncs.com')
-   }
+   const currentBaseUrlValue = (form.getValues('base_url') || '').trim()
+   if (!currentBaseUrlValue || !ALI_PRESET_BASE_URLS.has(currentBaseUrlValue)) {
+     form.setValue('base_url', ALI_DEFAULT_BASE_URL)
+   }
  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Type 17 (Ali) - set default base_url
if (currentType === 17) {
const currentBaseUrlValue = form.getValues('base_url')
if (!currentBaseUrlValue || currentBaseUrlValue === '') {
form.setValue('base_url', 'https://dashscope.aliyuncs.com')
}
}
const ALI_DEFAULT_BASE_URL = 'https://dashscope.aliyuncs.com'
const ALI_PRESET_BASE_URLS = new Set([
ALI_DEFAULT_BASE_URL,
'ali-token-plan',
'ali-coding-plan',
])
// Type 17 (Ali) - set default base_url
if (currentType === 17) {
const currentBaseUrlValue = (form.getValues('base_url') || '').trim()
if (!currentBaseUrlValue || !ALI_PRESET_BASE_URLS.has(currentBaseUrlValue)) {
form.setValue('base_url', ALI_DEFAULT_BASE_URL)
}
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@web/default/src/features/channels/components/drawers/channel-mutate-drawer.tsx`
around lines 632 - 638, When switching channel type to Ali (the currentType ===
17 branch in channel-mutate-drawer.tsx) we must normalize base_url instead of
only setting it when empty; update the logic in the currentType === 17 handler
(where form.getValues('base_url') and form.setValue('base_url',
'https://dashscope.aliyuncs.com') are used) to either validate the existing
base_url against an expected Ali pattern and replace it with the default if it
doesn't match, or simply overwrite it with 'https://dashscope.aliyuncs.com'
whenever currentType becomes 17 so incompatible sentinel values from other
channel types cannot persist.

Comment on lines +1759 to +1762
<FormLabel
className='cursor-pointer select-none'
onClick={handleAliApiConfigSecretClick}
>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Make the hidden unlock interaction keyboard-operable

The unlock trigger is click-only on a label; keyboard users cannot perform this interaction.

Suggested fix
<FormLabel
-  className='cursor-pointer select-none'
+  className='cursor-pointer select-none'
+  role='button'
+  tabIndex={0}
   onClick={handleAliApiConfigSecretClick}
+  onKeyDown={(e) => {
+    if (e.key === 'Enter' || e.key === ' ') {
+      e.preventDefault()
+      handleAliApiConfigSecretClick()
+    }
+  }}
>

As per coding guidelines "Ensure keyboard operability and logical focus order; use ARIA attributes (aria-label, aria-expanded, aria-hidden) when necessary".

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<FormLabel
className='cursor-pointer select-none'
onClick={handleAliApiConfigSecretClick}
>
<FormLabel
className='cursor-pointer select-none'
role='button'
tabIndex={0}
onClick={handleAliApiConfigSecretClick}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault()
handleAliApiConfigSecretClick()
}
}}
>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@web/default/src/features/channels/components/drawers/channel-mutate-drawer.tsx`
around lines 1759 - 1762, The FormLabel currently only handles mouse clicks
(onClick={handleAliApiConfigSecretClick}) which is not keyboard-accessible; make
the unlock trigger keyboard-operable by giving the FormLabel a semantics and
keyboard handlers: add a focusable attribute (tabIndex=0), semantic role
(role="button"), an onKeyDown handler that calls handleAliApiConfigSecretClick
when Enter or Space is pressed, and include appropriate ARIA attributes (e.g.,
aria-label describing the action and aria-expanded or aria-pressed as
applicable) so screen readers and keyboard users can operate the hidden-unlock
control.

Comment on lines +211 to +213
"Ali Coding Plan": "Ali Coding Plan",
"Ali custom API address editing unlocked": "Édition d'adresse API Ali personnalisée déverrouillée",
"Ali Token Plan": "Ali Token Plan",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Translate the new Ali plan labels in the French locale

Line 211 and Line 213 are still English while related strings are localized, so the selector will look mixed-language in French UI.

Proposed fix
-    "Ali Coding Plan": "Ali Coding Plan",
+    "Ali Coding Plan": "Plan Ali Coding",
     "Ali custom API address editing unlocked": "Édition d'adresse API Ali personnalisée déverrouillée",
-    "Ali Token Plan": "Ali Token Plan",
+    "Ali Token Plan": "Plan Ali Token",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/default/src/i18n/locales/fr.json` around lines 211 - 213, The French
locale has two values still in English; update the JSON value strings for the
keys "Ali Coding Plan" and "Ali Token Plan" to their French translations so the
UI is consistently localized (e.g., replace "Ali Coding Plan" value and "Ali
Token Plan" value with appropriate French phrases matching the surrounding
style).

Comment on lines +211 to +213
"Ali Coding Plan": "Ali Coding Plan",
"Ali custom API address editing unlocked": "Редактирование пользовательского адреса API Ali разблокировано",
"Ali Token Plan": "Ali Token Plan",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize Ali plan labels to avoid mixed-language UI in Russian

Line 211 and Line 213 keep English values, so Russian users will see mixed-language options in the same selector.

Suggested patch
-    "Ali Coding Plan": "Ali Coding Plan",
+    "Ali Coding Plan": "План Ali Coding",
...
-    "Ali Token Plan": "Ali Token Plan",
+    "Ali Token Plan": "План Ali Token",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"Ali Coding Plan": "Ali Coding Plan",
"Ali custom API address editing unlocked": "Редактирование пользовательского адреса API Ali разблокировано",
"Ali Token Plan": "Ali Token Plan",
"Ali Coding Plan": "План Ali Coding",
"Ali custom API address editing unlocked": "Редактирование пользовательского адреса API Ali разблокировано",
"Ali Token Plan": "План Ali Token",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/default/src/i18n/locales/ru.json` around lines 211 - 213, Replace the two
English display values so Russian users don't see mixed-language options: update
the JSON entries for the keys "Ali Coding Plan" and "Ali Token Plan" to Russian
strings (for example, "План кодирования Ali" for "Ali Coding Plan" and
"Токен-план Ali" or "План токенов Ali" for "Ali Token Plan") and ensure the key
"Ali custom API address editing unlocked" remains correctly localized; edit the
values for those keys in ru.json accordingly and run a quick UI check to confirm
the selector shows only Russian labels.

Comment on lines +211 to +213
"Ali Coding Plan": "Ali Coding Plan",
"Ali custom API address editing unlocked": "Đã mở khóa chỉnh sửa địa chỉ API Ali tùy chỉnh",
"Ali Token Plan": "Ali Token Plan",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize the new Ali plan labels for the Vietnamese locale

Line 211 and Line 213 still use English values, which causes mixed-language UI in vi.

💡 Suggested fix
-    "Ali Coding Plan": "Ali Coding Plan",
+    "Ali Coding Plan": "Gói Ali Coding",
...
-    "Ali Token Plan": "Ali Token Plan",
+    "Ali Token Plan": "Gói Ali Token",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"Ali Coding Plan": "Ali Coding Plan",
"Ali custom API address editing unlocked": "Đã mở khóa chỉnh sửa địa chỉ API Ali tùy chỉnh",
"Ali Token Plan": "Ali Token Plan",
"Ali Coding Plan": "Gói Ali Coding",
"Ali custom API address editing unlocked": "Đã mở khóa chỉnh sửa địa chỉ API Ali tùy chỉnh",
"Ali Token Plan": "Gói Ali Token",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/default/src/i18n/locales/vi.json` around lines 211 - 213, The vi.json
entries for the new Ali plan labels use English values; update the values for
the keys "Ali Coding Plan" and "Ali Token Plan" to Vietnamese so the UI is fully
localized (keep the keys unchanged, only replace the right-hand string values
for "Ali Coding Plan" and "Ali Token Plan" with appropriate Vietnamese
translations).

@seefs001

seefs001 commented May 1, 2026

Copy link
Copy Markdown
Collaborator

不考虑Coding Plan相关功能

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants