-
diff --git a/web/frontend/src/components/config/form-model.ts b/web/frontend/src/components/config/form-model.ts
index abbb6d154..10c5c71bb 100644
--- a/web/frontend/src/components/config/form-model.ts
+++ b/web/frontend/src/components/config/form-model.ts
@@ -179,7 +179,10 @@ export function buildFormFromConfig(config: unknown): CoreConfigForm {
EMPTY_FORM.cronExecTimeoutMinutes,
),
maxTokens: asNumberString(defaults.max_tokens, EMPTY_FORM.maxTokens),
- contextWindow: asNumberString(defaults.context_window, EMPTY_FORM.contextWindow),
+ contextWindow: asNumberString(
+ defaults.context_window,
+ EMPTY_FORM.contextWindow,
+ ),
maxToolIterations: asNumberString(
defaults.max_tool_iterations,
EMPTY_FORM.maxToolIterations,
diff --git a/web/frontend/src/hooks/use-sidebar-channels.ts b/web/frontend/src/hooks/use-sidebar-channels.ts
index 5579a955b..22fc24e57 100644
--- a/web/frontend/src/hooks/use-sidebar-channels.ts
+++ b/web/frontend/src/hooks/use-sidebar-channels.ts
@@ -28,15 +28,10 @@ import { getChannelDisplayName } from "@/components/channels/channel-display-nam
import { gatewayAtom } from "@/store/gateway"
const DEFAULT_VISIBLE_CHANNELS = 4
-const CHANNEL_IMPORTANCE_ORDER = [
- "discord",
- "feishu",
- "telegram",
+const CHANNEL_IMPORTANCE_TAIL = [
"slack",
"line",
"wecom",
- "wecom_app",
- "wecom_aibot",
"dingtalk",
"qq",
"onebot",
@@ -47,9 +42,13 @@ const CHANNEL_IMPORTANCE_ORDER = [
"whatsapp",
"whatsapp_native",
]
-const CHANNEL_IMPORTANCE_INDEX = new Map(
- CHANNEL_IMPORTANCE_ORDER.map((name, index) => [name, index]),
-)
+
+function getChannelImportanceOrder(language: string): string[] {
+ const priority = language.startsWith("zh")
+ ? ["feishu", "weixin", "discord", "telegram"]
+ : ["discord", "telegram", "feishu", "weixin"]
+ return [...priority, ...CHANNEL_IMPORTANCE_TAIL]
+}
function IconLark({ className }: { className?: string }) {
return React.createElement("span", {
@@ -75,9 +74,8 @@ const CHANNEL_ICON_MAP: Record<
dingtalk: IconBrandDingtalk,
line: IconBrandLine,
qq: IconBrandQq,
+ weixin: IconBrandWechat,
wecom: IconBrandWechat,
- wecom_app: IconBrandWechat,
- wecom_aibot: IconBrandWechat,
whatsapp: IconBrandWhatsapp,
whatsapp_native: IconBrandWhatsapp,
matrix: IconBrandMatrix,
@@ -134,10 +132,11 @@ export interface SidebarChannelNavItem {
}
interface UseSidebarChannelsOptions {
+ language: string
t: TFunction
}
-export function useSidebarChannels({ t }: UseSidebarChannelsOptions) {
+export function useSidebarChannels({ language, t }: UseSidebarChannelsOptions) {
const gateway = useAtomValue(gatewayAtom)
const [channels, setChannels] = React.useState
([])
const [enabledMap, setEnabledMap] = React.useState>(
@@ -183,6 +182,12 @@ export function useSidebarChannels({ t }: UseSidebarChannelsOptions) {
previousGatewayStatusRef.current = gateway.status
}, [gateway.status, reloadChannels])
+ const channelImportanceIndex = React.useMemo(() => {
+ return new Map(
+ getChannelImportanceOrder(language).map((name, index) => [name, index]),
+ )
+ }, [language])
+
const sortedChannels = React.useMemo(() => {
const list = [...channels]
list.sort((a, b) => {
@@ -193,9 +198,9 @@ export function useSidebarChannels({ t }: UseSidebarChannelsOptions) {
}
const aImportance =
- CHANNEL_IMPORTANCE_INDEX.get(a.name) ?? Number.MAX_SAFE_INTEGER
+ channelImportanceIndex.get(a.name) ?? Number.MAX_SAFE_INTEGER
const bImportance =
- CHANNEL_IMPORTANCE_INDEX.get(b.name) ?? Number.MAX_SAFE_INTEGER
+ channelImportanceIndex.get(b.name) ?? Number.MAX_SAFE_INTEGER
if (aImportance !== bImportance) {
return aImportance - bImportance
}
@@ -205,7 +210,7 @@ export function useSidebarChannels({ t }: UseSidebarChannelsOptions) {
)
})
return list
- }, [channels, enabledMap, t])
+ }, [channelImportanceIndex, channels, enabledMap, t])
const hasMoreChannels = sortedChannels.length > DEFAULT_VISIBLE_CHANNELS
const visibleChannels = showAllChannels
diff --git a/web/frontend/src/i18n/locales/en.json b/web/frontend/src/i18n/locales/en.json
index 66e39ad0e..68105fcea 100644
--- a/web/frontend/src/i18n/locales/en.json
+++ b/web/frontend/src/i18n/locales/en.json
@@ -233,14 +233,31 @@
"qq": "QQ",
"onebot": "OneBot",
"wecom": "WeCom",
- "wecom_app": "WeCom App",
- "wecom_aibot": "WeCom AI Bot",
"whatsapp": "WhatsApp",
"whatsapp_native": "WhatsApp Native",
"pico": "Web",
"maixcam": "MaixCam",
"matrix": "Matrix",
- "irc": "IRC"
+ "irc": "IRC",
+ "weixin": "WeChat"
+ },
+ "weixin": {
+ "warningTitle": "Testing phase, use with caution",
+ "warningDesc": "The WeChat channel is still experimental and may carry a risk of account suspension. Use it only if you understand and accept the risk.",
+ "bindEnableSuccess": "WeChat connected and the channel has been enabled automatically.",
+ "bindTitle": "WeChat Account Binding",
+ "bindDesc": "Scan the QR code with WeChat to bind your personal account.",
+ "bind": "Bind WeChat",
+ "rebind": "Re-bind",
+ "bound": "WeChat Bound",
+ "notBound": "WeChat account not bound yet.",
+ "generating": "Generating QR code...",
+ "scanHint": "Open WeChat and scan the QR code",
+ "scanned": "Scanned — please confirm in WeChat",
+ "expired": "QR code expired",
+ "retry": "Try Again",
+ "refresh": "Refresh QR",
+ "errorGeneric": "An error occurred. Please try again."
},
"field": {
"token": "Bot Token",
@@ -273,7 +290,9 @@
"saveError": "Failed to save channel configuration",
"enabled": "enabled",
"docLink": "Documentation",
- "enableLabel": "Enable channel"
+ "enableLabel": "Enable channel",
+ "restartRequiredTitle": "Gateway restart required",
+ "restartRequiredDesc": "The latest {{name}} configuration has been saved. Restart the gateway for it to take effect."
},
"form": {
"desc": {
diff --git a/web/frontend/src/i18n/locales/zh.json b/web/frontend/src/i18n/locales/zh.json
index 65f2a5548..69ca939cb 100644
--- a/web/frontend/src/i18n/locales/zh.json
+++ b/web/frontend/src/i18n/locales/zh.json
@@ -233,14 +233,31 @@
"qq": "QQ",
"onebot": "OneBot",
"wecom": "企业微信",
- "wecom_app": "企业微信应用",
- "wecom_aibot": "企业微信 AI 机器人",
"whatsapp": "WhatsApp",
"whatsapp_native": "WhatsApp Native",
"pico": "Web",
"maixcam": "MaixCam",
"matrix": "Matrix",
- "irc": "IRC"
+ "irc": "IRC",
+ "weixin": "微信"
+ },
+ "weixin": {
+ "warningTitle": "测试阶段,请谨慎使用",
+ "warningDesc": "微信 Channel 当前仍处于测试阶段,存在封号风险。请仅在充分了解风险的前提下使用。",
+ "bindEnableSuccess": "微信已连接,频道已自动启用。",
+ "bindTitle": "微信账号绑定",
+ "bindDesc": "使用微信扫描二维码以绑定您的个人微信账号。",
+ "bind": "绑定微信",
+ "rebind": "重新绑定",
+ "bound": "微信已绑定",
+ "notBound": "尚未绑定微信账号。",
+ "generating": "正在生成二维码...",
+ "scanHint": "打开微信,扫描二维码",
+ "scanned": "已扫码 — 请在微信中确认",
+ "expired": "二维码已过期",
+ "retry": "重试",
+ "refresh": "刷新二维码",
+ "errorGeneric": "发生错误,请重试。"
},
"field": {
"token": "Bot Token",
@@ -273,7 +290,9 @@
"saveError": "保存频道配置失败",
"enabled": "已启用",
"docLink": "配置文档",
- "enableLabel": "启用频道"
+ "enableLabel": "启用频道",
+ "restartRequiredTitle": "需要重启服务",
+ "restartRequiredDesc": "{{name}} 的最新配置已保存。重启服务后才能正式生效。"
},
"form": {
"desc": {