diff --git a/src/langbot/pkg/discover/engine.py b/src/langbot/pkg/discover/engine.py index ca7f2588..0563c20f 100644 --- a/src/langbot/pkg/discover/engine.py +++ b/src/langbot/pkg/discover/engine.py @@ -17,7 +17,10 @@ class I18nString(pydantic.BaseModel): """英文""" zh_Hans: typing.Optional[str] = None - """中文""" + """简体中文""" + + zh_Hant: typing.Optional[str] = None + """繁体中文""" ja_JP: typing.Optional[str] = None """日文""" @@ -29,6 +32,8 @@ class I18nString(pydantic.BaseModel): dic['en_US'] = self.en_US if self.zh_Hans is not None: dic['zh_Hans'] = self.zh_Hans + if self.zh_Hant is not None: + dic['zh_Hant'] = self.zh_Hant if self.ja_JP is not None: dic['ja_JP'] = self.ja_JP return dic diff --git a/src/langbot/pkg/platform/sources/aiocqhttp.yaml b/src/langbot/pkg/platform/sources/aiocqhttp.yaml index 7c530c19..e073fe57 100644 --- a/src/langbot/pkg/platform/sources/aiocqhttp.yaml +++ b/src/langbot/pkg/platform/sources/aiocqhttp.yaml @@ -5,19 +5,25 @@ metadata: label: en_US: OneBot v11 zh_Hans: OneBot v11 + zh_Hant: OneBot v11 description: en_US: OneBot v11 Adapter, used for QQ bots zh_Hans: OneBot v11 适配器,用于接入 QQ 机器人协议端,请查看文档了解使用方式 + zh_Hant: OneBot v11 適配器,用於接入 QQ 機器人協定端,請查看文件了解使用方式 icon: onebot.png spec: + categories: + - protocol config: - name: host label: en_US: Host zh_Hans: 主机 + zh_Hant: 主機 description: en_US: The host that OneBot v11 listens on for reverse WebSocket connections. Unless you know what you're doing, use 0.0.0.0 zh_Hans: OneBot v11 监听的反向 WS 主机,除非你知道自己在做什么,否则请写 0.0.0.0 + zh_Hant: OneBot v11 監聽的反向 WS 主機,除非你知道自己在做什麼,否則請填 0.0.0.0 type: string required: true default: 0.0.0.0 @@ -25,9 +31,11 @@ spec: label: en_US: Port zh_Hans: 端口 + zh_Hant: 連接埠 description: en_US: Port zh_Hans: 监听的端口 + zh_Hant: 監聽的連接埠 type: integer required: true default: 2280 @@ -35,9 +43,11 @@ spec: label: en_US: Access Token zh_Hans: 访问令牌 + zh_Hant: 存取令牌 description: en_US: Custom connection token for the protocol endpoint. If the protocol endpoint is not set, don't fill it zh_Hans: 自定义的与协议端的连接令牌,若协议端未设置,则不填 + zh_Hant: 自訂的與協定端的連線令牌,若協定端未設定,則不填 type: string required: false default: "" diff --git a/src/langbot/pkg/platform/sources/dingtalk.yaml b/src/langbot/pkg/platform/sources/dingtalk.yaml index c5cb2f85..160e5114 100644 --- a/src/langbot/pkg/platform/sources/dingtalk.yaml +++ b/src/langbot/pkg/platform/sources/dingtalk.yaml @@ -5,16 +5,21 @@ metadata: label: en_US: DingTalk zh_Hans: 钉钉 + zh_Hant: 釘釘 description: en_US: DingTalk Adapter zh_Hans: 钉钉适配器,请查看文档了解使用方式 + zh_Hant: 釘釘適配器,請查看文件了解使用方式 icon: dingtalk.svg spec: + categories: + - china config: - name: client_id label: en_US: Client ID zh_Hans: 客户端ID + zh_Hant: 用戶端ID type: string required: true default: "" @@ -22,6 +27,7 @@ spec: label: en_US: Client Secret zh_Hans: 客户端密钥 + zh_Hant: 用戶端密鑰 type: string required: true default: "" @@ -29,6 +35,7 @@ spec: label: en_US: Robot Code zh_Hans: 机器人代码 + zh_Hant: 機器人代碼 type: string required: true default: "" @@ -36,6 +43,7 @@ spec: label: en_US: Robot Name zh_Hans: 机器人名称 + zh_Hant: 機器人名稱 type: string required: true default: "" @@ -43,6 +51,7 @@ spec: label: en_US: Markdown Card zh_Hans: 是否使用 Markdown 卡片 + zh_Hant: 是否使用 Markdown 卡片 type: boolean required: false default: true @@ -50,9 +59,11 @@ spec: label: en_US: Enable Stream Reply Mode zh_Hans: 启用钉钉卡片流式回复模式 + zh_Hant: 啟用釘釘卡片串流回覆模式 description: en_US: If enabled, the bot will use the stream of lark reply mode zh_Hans: 如果启用,将使用钉钉卡片流式方式来回复内容 + zh_Hant: 如果啟用,將使用釘釘卡片串流方式來回覆內容 type: boolean required: true default: false @@ -60,6 +71,7 @@ spec: label: en_US: Card Auto Layout zh_Hans: 卡片宽屏自动布局 + zh_Hant: 卡片寬螢幕自動佈局 type: boolean required: false default: false @@ -67,6 +79,7 @@ spec: label: en_US: card template id zh_Hans: 卡片模板ID + zh_Hant: 卡片範本ID type: string required: true default: "填写你的卡片template_id" diff --git a/src/langbot/pkg/platform/sources/discord.yaml b/src/langbot/pkg/platform/sources/discord.yaml index 57392994..24564999 100644 --- a/src/langbot/pkg/platform/sources/discord.yaml +++ b/src/langbot/pkg/platform/sources/discord.yaml @@ -5,17 +5,25 @@ metadata: label: en_US: Discord zh_Hans: Discord + zh_Hant: Discord + ja_JP: Discord description: en_US: Discord Adapter zh_Hans: Discord 适配器,需要可连接 Discord 服务器的网络环境 - ja_JP: Discord アダプター + zh_Hant: Discord 適配器,需要可連線 Discord 伺服器的網路環境 + ja_JP: Discord アダプター、Discord サーバーに接続可能なネットワーク環境が必要です icon: discord.svg spec: + categories: + - popular + - global config: - name: client_id label: en_US: Client ID zh_Hans: 客户端ID + zh_Hant: 用戶端ID + ja_JP: クライアント ID type: string required: true default: "" @@ -23,6 +31,8 @@ spec: label: en_US: Token zh_Hans: 令牌 + zh_Hant: 令牌 + ja_JP: トークン type: string required: true default: "" diff --git a/src/langbot/pkg/platform/sources/kook.yaml b/src/langbot/pkg/platform/sources/kook.yaml index c0da62c7..cca9db59 100644 --- a/src/langbot/pkg/platform/sources/kook.yaml +++ b/src/langbot/pkg/platform/sources/kook.yaml @@ -5,16 +5,21 @@ metadata: label: en_US: KOOK zh_Hans: KOOK + zh_Hant: KOOK description: en_US: KOOK Adapter (formerly KaiHeiLa) zh_Hans: KOOK 适配器(原开黑啦),支持频道消息和私聊消息 + zh_Hant: KOOK 適配器(原開黑啦),支援頻道訊息和私聊訊息 icon: kook.png spec: + categories: + - china config: - name: token label: en_US: Bot Token zh_Hans: 机器人令牌 + zh_Hant: 機器人令牌 type: string required: true default: "" diff --git a/src/langbot/pkg/platform/sources/lark.yaml b/src/langbot/pkg/platform/sources/lark.yaml index 2b84d415..1217d6ca 100644 --- a/src/langbot/pkg/platform/sources/lark.yaml +++ b/src/langbot/pkg/platform/sources/lark.yaml @@ -5,17 +5,26 @@ metadata: label: en_US: Lark zh_Hans: 飞书 + zh_Hant: 飛書 + ja_JP: Lark description: en_US: Lark Adapter, supports both long connection and Webhook modes. Please refer to the documentation for usage details. zh_Hans: 飞书适配器,支持长连接和 Webhook 两种接入方式,请查看文档了解使用方式 + zh_Hant: 飛書適配器,支援長連線和 Webhook 兩種接入方式,請查看文件了解使用方式 ja_JP: Lark アダプター、長期接続およびWebhookモードの両方をサポートしています。使用方法の詳細については、ドキュメントを参照してください。 icon: lark.svg spec: + categories: + - popular + - china + - global config: - name: app_id label: en_US: App ID zh_Hans: 应用ID + zh_Hant: 應用ID + ja_JP: アプリ ID type: string required: true default: "" @@ -23,6 +32,8 @@ spec: label: en_US: App Secret zh_Hans: 应用密钥 + zh_Hant: 應用密鑰 + ja_JP: アプリシークレット type: string required: true default: "" @@ -30,9 +41,13 @@ spec: label: en_US: Bot Name zh_Hans: 机器人名称 + zh_Hant: 機器人名稱 + ja_JP: ボット名 description: en_US: Must be the same as the name of the bot in Lark, otherwise the bot will not be able to receive messages in the group zh_Hans: 必须与飞书机器人名称一致,否则机器人将无法在群内正常接收消息 + zh_Hant: 必須與飛書機器人名稱一致,否則機器人將無法在群組內正常接收訊息 + ja_JP: Lark のボット名と一致する必要があります。一致しない場合、グループ内でメッセージを受信できません type: string required: true default: "" @@ -40,9 +55,13 @@ spec: label: en_US: Enable Webhook Mode zh_Hans: 启用Webhook模式 + zh_Hant: 啟用 Webhook 模式 + ja_JP: Webhook モードを有効化 description: en_US: If enabled, the bot will use webhook mode to receive messages. Otherwise, it will use WS long connection mode zh_Hans: 如果启用,机器人将使用 Webhook 模式接收消息。否则,将使用 WS 长连接模式 + zh_Hant: 如果啟用,機器人將使用 Webhook 模式接收訊息。否則,將使用 WS 長連線模式 + ja_JP: 有効にすると、ボットは Webhook モードでメッセージを受信します。無効の場合は WS 長期接続モードを使用します type: boolean required: true default: false @@ -50,9 +69,13 @@ spec: label: en_US: Webhook Callback URL zh_Hans: Webhook 回调地址 + zh_Hant: Webhook 回調地址 + ja_JP: Webhook コールバック URL description: en_US: Copy this URL and paste it into your Lark app's webhook configuration zh_Hans: 复制此地址并粘贴到飞书应用的 Webhook 配置中 + zh_Hant: 複製此地址並貼到飛書應用的 Webhook 設定中 + ja_JP: この URL をコピーして Lark アプリの Webhook 設定に貼り付けてください type: webhook-url required: false default: "" @@ -64,9 +87,13 @@ spec: label: en_US: Encrypt Key zh_Hans: 加密密钥 + zh_Hant: 加密密鑰 + ja_JP: 暗号化キー description: en_US: Only valid when webhook mode is enabled, please fill in the encrypt key zh_Hans: 仅在启用 Webhook 模式时有效,请填写加密密钥 + zh_Hant: 僅在啟用 Webhook 模式時有效,請填寫加密密鑰 + ja_JP: Webhook モードが有効な場合にのみ有効です。暗号化キーを入力してください type: string required: true default: "" @@ -78,9 +105,13 @@ spec: label: en_US: Enable Stream Reply Mode zh_Hans: 启用飞书流式回复模式 + zh_Hant: 啟用飛書串流回覆模式 + ja_JP: ストリーミング返信モードを有効化 description: en_US: If enabled, the bot will use the stream of lark reply mode zh_Hans: 如果启用,将使用飞书流式方式来回复内容 + zh_Hant: 如果啟用,將使用飛書串流方式來回覆內容 + ja_JP: 有効にすると、ボットはストリーミングモードでメッセージに返信します type: boolean required: true default: false @@ -88,28 +119,40 @@ spec: label: en_US: App Type zh_Hans: 应用类型 + zh_Hant: 應用類型 + ja_JP: アプリタイプ description: en_US: Default to self-built application, refer to https://open.feishu.cn/document/platform-overveiw/overview zh_Hans: 默认为企业自建应用,参考 https://open.feishu.cn/document/platform-overveiw/overview + zh_Hant: 預設為企業自建應用,參考 https://open.feishu.cn/document/platform-overveiw/overview + ja_JP: デフォルトはカスタムアプリです。詳細は https://open.feishu.cn/document/platform-overveiw/overview を参照してください type: select options: - name: self label: en_US: Self-built Application zh_Hans: 自建应用 + zh_Hant: 自建應用 + ja_JP: カスタムアプリ - name: isv label: en_US: Store Application zh_Hans: 商店应用 + zh_Hant: 商店應用 + ja_JP: ストアアプリ required: false default: self - name: bot_added_welcome label: en_US: Bot Welcome Message zh_Hans: 机器人进群欢迎语 + zh_Hant: 機器人進群歡迎語 + ja_JP: ボット参加時のウェルカムメッセージ description: en_US: Welcome message when the bot is added to a group, supports Markdown format zh_Hans: 机器人进群欢迎语,支持 Markdown 格式 + zh_Hant: 機器人進群歡迎語,支援 Markdown 格式 + ja_JP: ボットがグループに追加された際のウェルカムメッセージ。Markdown 形式に対応しています type: text required: false default: "" diff --git a/src/langbot/pkg/platform/sources/line.yaml b/src/langbot/pkg/platform/sources/line.yaml index 1944cc81..75cd3121 100644 --- a/src/langbot/pkg/platform/sources/line.yaml +++ b/src/langbot/pkg/platform/sources/line.yaml @@ -5,13 +5,16 @@ metadata: label: en_US: LINE zh_Hans: LINE + zh_Hant: LINE description: en_US: LINE Adapter, requires a public URL to receive LINE message pushes, please refer to the documentation for usage details zh_Hans: LINE适配器,需要公网地址以接收 LINE 消息推送,请查看文档了解使用方式 + zh_Hant: LINE 適配器,需要公網地址以接收 LINE 訊息推送,請查看文件了解使用方式 ja_JP: LINEアダプター、LINEのメッセージプッシュを受信するためにパブリックURLが必要です。使用方法の詳細については、ドキュメントを参照してください。 - zh_Hant: LINE適配器,需要公网地址以接收 LINE 消息推送,请查看文档了解使用方式 icon: line.png spec: + categories: + - global config: - name: webhook_url label: @@ -23,7 +26,7 @@ spec: en_US: Copy this URL and paste it into your LINE channel's webhook configuration zh_Hans: 复制此地址并粘贴到 LINE 频道的 Webhook 配置中 ja_JP: この URL をコピーして LINE チャンネルの Webhook 設定に貼り付けてください - zh_Hant: 複製此地址並粘貼到 LINE 頻道的 Webhook 配置中 + zh_Hant: 複製此地址並貼到 LINE 頻道的 Webhook 設定中 type: webhook-url required: false default: "" @@ -32,7 +35,7 @@ spec: en_US: Channel access token zh_Hans: 频道访问令牌 ja_JP: チャンネルアクセストークン - zh_Hant: 頻道訪問令牌 + zh_Hant: 頻道存取令牌 type: string required: true default: "" @@ -41,12 +44,12 @@ spec: en_US: Channel secret zh_Hans: 消息密钥 ja_JP: チャンネルシークレット - zh_Hant: 消息密钥 + zh_Hant: 訊息密鑰 description: en_US: Only valid when webhook mode is enabled, please fill in the encrypt key zh_Hans: 请填写加密密钥 ja_JP: Webhookモードが有効な場合にのみ、暗号化キーを入力してください - zh_Hant: 請填寫加密密钥 + zh_Hant: 請填寫加密密鑰 type: string required: true default: "" diff --git a/src/langbot/pkg/platform/sources/officialaccount.yaml b/src/langbot/pkg/platform/sources/officialaccount.yaml index c42a7c88..6e6952b2 100644 --- a/src/langbot/pkg/platform/sources/officialaccount.yaml +++ b/src/langbot/pkg/platform/sources/officialaccount.yaml @@ -5,19 +5,25 @@ metadata: label: en_US: Official Account zh_Hans: 微信公众号 + zh_Hant: 微信公眾號 description: en_US: Official Account Adapter zh_Hans: 微信公众号适配器,需要公网地址以接收消息推送,请查看文档了解使用方式 + zh_Hant: 微信公眾號適配器,需要公網地址以接收訊息推送,請查看文件了解使用方式 icon: officialaccount.png spec: + categories: + - china config: - name: webhook_url label: en_US: Webhook Callback URL zh_Hans: Webhook 回调地址 + zh_Hant: Webhook 回調地址 description: en_US: Copy this URL and paste it into your Official Account webhook configuration zh_Hans: 复制此地址并粘贴到微信公众号的 Webhook 配置中 + zh_Hant: 複製此地址並貼到微信公眾號的 Webhook 設定中 type: webhook-url required: false default: "" @@ -25,13 +31,14 @@ spec: label: en_US: Token zh_Hans: 令牌 - type: string + zh_Hant: 令牌 required: true default: "" - name: EncodingAESKey label: en_US: EncodingAESKey zh_Hans: 消息加解密密钥 + zh_Hant: 訊息加解密密鑰 type: string required: true default: "" @@ -39,6 +46,7 @@ spec: label: en_US: App ID zh_Hans: 应用ID + zh_Hant: 應用ID type: string required: true default: "" @@ -46,6 +54,7 @@ spec: label: en_US: App Secret zh_Hans: 应用密钥 + zh_Hant: 應用密鑰 type: string required: true default: "" @@ -53,6 +62,7 @@ spec: label: en_US: Mode zh_Hans: 接入模式 + zh_Hant: 接入模式 type: string required: true default: "drop" @@ -60,6 +70,7 @@ spec: label: en_US: Loading Message zh_Hans: 加载消息 + zh_Hant: 載入訊息 type: string required: true default: "AI正在思考中,请发送任意内容获取回复。" @@ -67,9 +78,11 @@ spec: label: en_US: API Base URL zh_Hans: API 基础 URL + zh_Hant: API 基礎 URL description: en_US: API Base URL, used for accessing the Official Account API. If you are deploying in an internal network environment and accessing the Official Account API through a reverse proxy, please fill in this item according to the documentation. zh_Hans: 可选,若您部署在内网环境并通过反向代理访问微信公众号 API,可根据文档修改此项 + zh_Hant: 可選,若您部署在內網環境並透過反向代理存取微信公眾號 API,可根據文件修改此項 type: string required: false default: "https://api.weixin.qq.com" diff --git a/src/langbot/pkg/platform/sources/openclaw_weixin.yaml b/src/langbot/pkg/platform/sources/openclaw_weixin.yaml index c203d760..ac1a206b 100644 --- a/src/langbot/pkg/platform/sources/openclaw_weixin.yaml +++ b/src/langbot/pkg/platform/sources/openclaw_weixin.yaml @@ -5,19 +5,26 @@ metadata: label: en_US: OpenClaw WeChat zh_Hans: 个人微信机器人 + zh_Hant: 個人微信機器人 description: en_US: OpenClaw WeChat adapter, supports personal WeChat via QR code login zh_Hans: 微信官方个人助手,扫码即可登录使用 + zh_Hant: 微信官方個人助手,掃碼即可登入使用 icon: wechat.png spec: + categories: + - popular + - china config: - name: base_url label: en_US: API Base URL zh_Hans: API 基础地址 + zh_Hant: API 基礎地址 description: en_US: The base URL of the OpenClaw WeChat backend API zh_Hans: OpenClaw 微信后端 API 的基础地址 + zh_Hant: OpenClaw 微信後端 API 的基礎地址 type: string required: true default: "https://ilinkai.weixin.qq.com" @@ -25,9 +32,11 @@ spec: label: en_US: Token zh_Hans: 令牌 + zh_Hant: 令牌 description: en_US: Bearer token obtained after QR code login authorization. Leave empty to trigger QR code login on startup. zh_Hans: 扫码登录授权后获取的 Bearer 令牌。请留空并保存,将在启动时输出二维码到日志,扫码后即可自动登录。 + zh_Hant: 掃碼登入授權後取得的 Bearer 令牌。請留空並儲存,將在啟動時輸出 QR Code 到日誌,掃碼後即可自動登入。 type: string required: false default: "" @@ -35,9 +44,11 @@ spec: label: en_US: Account ID zh_Hans: 账号标识 + zh_Hant: 帳號標識 description: en_US: A label for this WeChat account (used for display purposes) zh_Hans: 此微信账号的标识(用于显示) + zh_Hant: 此微信帳號的標識(用於顯示) type: string required: false default: "openclaw-weixin" @@ -45,9 +56,11 @@ spec: label: en_US: Poll Timeout (seconds) zh_Hans: 轮询超时(秒) + zh_Hant: 輪詢逾時(秒) description: en_US: Long-poll timeout for getUpdates, the server may hold the request up to this duration zh_Hans: getUpdates 长轮询超时时间,服务端最多持有请求的时长 + zh_Hant: getUpdates 長輪詢逾時時間,伺服端最多持有請求的時長 type: integer required: false default: 35 diff --git a/src/langbot/pkg/platform/sources/qqofficial.yaml b/src/langbot/pkg/platform/sources/qqofficial.yaml index a374265a..ad526e49 100644 --- a/src/langbot/pkg/platform/sources/qqofficial.yaml +++ b/src/langbot/pkg/platform/sources/qqofficial.yaml @@ -5,19 +5,25 @@ metadata: label: en_US: QQ Official API zh_Hans: QQ 官方 API + zh_Hant: QQ 官方 API description: en_US: QQ Official API (Webhook) zh_Hans: QQ 官方 API (Webhook),需要公网地址以接收消息推送,请查看文档了解使用方式 + zh_Hant: QQ 官方 API (Webhook),需要公網地址以接收訊息推送,請查看文件了解使用方式 icon: qqofficial.svg spec: + categories: + - china config: - name: webhook_url label: en_US: Webhook Callback URL zh_Hans: Webhook 回调地址 + zh_Hant: Webhook 回調地址 description: en_US: Copy this URL and paste it into your QQ Official API webhook configuration zh_Hans: 复制此地址并粘贴到 QQ 官方 API 的 Webhook 配置中 + zh_Hant: 複製此地址並貼到 QQ 官方 API 的 Webhook 設定中 type: webhook-url required: false default: "" @@ -25,6 +31,7 @@ spec: label: en_US: App ID zh_Hans: 应用ID + zh_Hant: 應用ID type: string required: true default: "" @@ -32,6 +39,7 @@ spec: label: en_US: Secret zh_Hans: 密钥 + zh_Hant: 密鑰 type: string required: true default: "" @@ -39,6 +47,7 @@ spec: label: en_US: Token zh_Hans: 令牌 + zh_Hant: 令牌 type: string required: true default: "" diff --git a/src/langbot/pkg/platform/sources/satori.yaml b/src/langbot/pkg/platform/sources/satori.yaml index e1635286..edeeb715 100644 --- a/src/langbot/pkg/platform/sources/satori.yaml +++ b/src/langbot/pkg/platform/sources/satori.yaml @@ -5,36 +5,45 @@ metadata: label: en_US: Satori zh_Hans: Satori + zh_Hant: Satori description: en_US: SatoriAdapter zh_Hans: Satori 协议适配器,支持多种平台的接入,请查看文档了解使用方式 + zh_Hant: Satori 協定適配器,支援多種平台的接入,請查看文件了解使用方式 icon: satori.png spec: + categories: + - protocol config: - name: platform label: en_US: Platform zh_Hans: 平台名称 + zh_Hant: 平台名稱 type: string required: true default: "llonebot" description: en_US: The platform name (e.g., llonebot, discord, telegram) zh_Hans: 平台名称(如 llonebot, discord, telegram) + zh_Hant: 平台名稱(如 llonebot、discord、telegram) - name: host label: en_US: Host zh_Hans: 主机地址 + zh_Hant: 主機地址 type: string required: true default: "127.0.0.1" description: en_US: The host address of LLOneBot Satori server (e.g., 127.0.0.1, localhost, 192.168.1.100) zh_Hans: LLOneBot Satori服务器的主机地址(如 127.0.0.1, localhost, 192.168.1.100) + zh_Hant: LLOneBot Satori 伺服器的主機地址(如 127.0.0.1、localhost、192.168.1.100) - name: port label: en_US: Port zh_Hans: 监听端口 + zh_Hant: 監聽連接埠 type: integer required: true default: 5600 @@ -42,6 +51,7 @@ spec: label: en_US: Satori API Endpoint zh_Hans: Satori API 终结点 + zh_Hant: Satori API 端點 type: string required: true default: "http://localhost:5600/v1" @@ -49,6 +59,7 @@ spec: label: en_US: Satori WebSocket Endpoint zh_Hans: Satori WebSocket 终结点 + zh_Hant: Satori WebSocket 端點 type: string required: true default: "ws://localhost:5600/v1/events" @@ -56,6 +67,7 @@ spec: label: en_US: Token zh_Hans: 令牌 + zh_Hant: 令牌 type: string required: true default: "" diff --git a/src/langbot/pkg/platform/sources/slack.yaml b/src/langbot/pkg/platform/sources/slack.yaml index 2f3a438b..1e61c86f 100644 --- a/src/langbot/pkg/platform/sources/slack.yaml +++ b/src/langbot/pkg/platform/sources/slack.yaml @@ -5,21 +5,30 @@ metadata: label: en_US: Slack zh_Hans: Slack + zh_Hant: Slack + ja_JP: Slack description: en_US: Slack Adapter zh_Hans: Slack 适配器,需要公网地址以接收 Slack 消息推送,请查看文档了解使用方式 + zh_Hant: Slack 適配器,需要公網地址以接收 Slack 訊息推送,請查看文件了解使用方式 ja_JP: Slack アダプター、Slackのメッセージプッシュを受信するためにパブリックURLが必要です。使用方法の詳細については、ドキュメントを参照してください。 - zh_Hant: Slack 适配器,需要公网地址以接收 Slack 消息推送,请查看文档了解使用方式 icon: slack.png spec: + categories: + - popular + - global config: - name: webhook_url label: en_US: Webhook Callback URL zh_Hans: Webhook 回调地址 + zh_Hant: Webhook 回調地址 + ja_JP: Webhook コールバック URL description: en_US: Copy this URL and paste it into your Slack app's event subscription configuration zh_Hans: 复制此地址并粘贴到 Slack 应用的事件订阅配置中 + zh_Hant: 複製此地址並貼到 Slack 應用的事件訂閱設定中 + ja_JP: この URL をコピーして Slack アプリのイベントサブスクリプション設定に貼り付けてください type: webhook-url required: false default: "" @@ -27,6 +36,8 @@ spec: label: en_US: Bot Token zh_Hans: 机器人令牌 + zh_Hant: 機器人令牌 + ja_JP: ボットトークン type: string required: true default: "" @@ -34,6 +45,8 @@ spec: label: en_US: signing_secret zh_Hans: 密钥 + zh_Hant: 密鑰 + ja_JP: 署名シークレット type: string required: true default: "" diff --git a/src/langbot/pkg/platform/sources/telegram.yaml b/src/langbot/pkg/platform/sources/telegram.yaml index 14c84289..5faef3f9 100644 --- a/src/langbot/pkg/platform/sources/telegram.yaml +++ b/src/langbot/pkg/platform/sources/telegram.yaml @@ -5,16 +5,25 @@ metadata: label: en_US: Telegram zh_Hans: 电报 + zh_Hant: Telegram + ja_JP: Telegram description: en_US: Telegram Adapter zh_Hans: Telegram 适配器,请查看文档了解使用方式 + zh_Hant: Telegram 適配器,請查看文件了解使用方式 + ja_JP: Telegram アダプター。使用方法の詳細については、ドキュメントを参照してください。 icon: telegram.svg spec: + categories: + - popular + - global config: - name: token label: en_US: Token zh_Hans: 令牌 + zh_Hant: 令牌 + ja_JP: トークン type: string required: true default: "token_from_botfather" @@ -22,6 +31,8 @@ spec: label: en_US: Markdown Card zh_Hans: 是否使用 Markdown 卡片 + zh_Hant: 是否使用 Markdown 卡片 + ja_JP: Markdown カードを使用 type: boolean required: false default: true @@ -29,9 +40,13 @@ spec: label: en_US: Enable Stream Reply Mode zh_Hans: 启用电报流式回复模式 + zh_Hant: 啟用 Telegram 串流回覆模式 + ja_JP: ストリーミング返信モードを有効化 description: en_US: If enabled, the bot will use the stream of telegram reply mode zh_Hans: 如果启用,将使用电报流式方式来回复内容 + zh_Hant: 如果啟用,將使用 Telegram 串流方式來回覆內容 + ja_JP: 有効にすると、ボットはストリーミングモードでメッセージに返信します type: boolean required: true default: false diff --git a/src/langbot/pkg/platform/sources/websocket.yaml b/src/langbot/pkg/platform/sources/websocket.yaml index a358a030..83680330 100644 --- a/src/langbot/pkg/platform/sources/websocket.yaml +++ b/src/langbot/pkg/platform/sources/websocket.yaml @@ -5,11 +5,15 @@ metadata: label: en_US: "WebSocket Chat" zh_Hans: "WebSocket 聊天" + zh_Hant: "WebSocket 聊天" description: en_US: "WebSocket adapter for bidirectional real-time communication" zh_Hans: "用于双向实时通信的 WebSocket 适配器" + zh_Hant: "用於雙向即時通訊的 WebSocket 適配器" icon: "" spec: + categories: + - protocol config: [] execution: python: diff --git a/src/langbot/pkg/platform/sources/wechatpad.yaml b/src/langbot/pkg/platform/sources/wechatpad.yaml index f1e1b674..1d7e2b41 100644 --- a/src/langbot/pkg/platform/sources/wechatpad.yaml +++ b/src/langbot/pkg/platform/sources/wechatpad.yaml @@ -5,16 +5,21 @@ metadata: label: en_US: WeChatPad zh_Hans: WeChatPad(个人微信ipad) + zh_Hant: WeChatPad(個人微信iPad) description: en_US: WeChatPad Adapter zh_Hans: WeChatPad 适配器,基于WeChatPad的个人微信解决方案,请查看文档了解使用方式 + zh_Hant: WeChatPad 適配器,基於 WeChatPad 的個人微信解決方案,請查看文件了解使用方式 icon: wechatpad.png spec: + categories: + - china config: - name: wechatpad_url label: en_US: WeChatPad ERL zh_CN: WeChatPad URL + zh_Hant: WeChatPad URL type: string required: true default: "" @@ -22,6 +27,7 @@ spec: label: en_US: WeChatPad_Ws zh_CN: WeChatPad_Ws + zh_Hant: WeChatPad_Ws type: string required: true default: "" @@ -29,6 +35,7 @@ spec: label: en_US: Admin_Key zh_CN: 管理员密匙 + zh_Hant: 管理員密鑰 type: string required: true default: "" @@ -36,6 +43,7 @@ spec: label: en_US: Token zh_CN: 令牌 + zh_Hant: 令牌 type: string required: true default: "" @@ -43,6 +51,7 @@ spec: label: en_US: wxid zh_CN: wxid + zh_Hant: wxid type: string required: true default: "" diff --git a/src/langbot/pkg/platform/sources/wecom.yaml b/src/langbot/pkg/platform/sources/wecom.yaml index ecbb51ba..0fe6cac7 100644 --- a/src/langbot/pkg/platform/sources/wecom.yaml +++ b/src/langbot/pkg/platform/sources/wecom.yaml @@ -5,19 +5,26 @@ metadata: label: en_US: WeCom zh_Hans: 企业微信 + zh_Hant: 企業微信 description: en_US: WeCom Adapter zh_Hans: 企业微信内部机器人,请查看文档了解使用方式 + zh_Hant: 企業微信內部機器人,請查看文件了解使用方式 icon: wecom.png spec: + categories: + - popular + - china config: - name: webhook_url label: en_US: Webhook Callback URL zh_Hans: Webhook 回调地址 + zh_Hant: Webhook 回調地址 description: en_US: Copy this URL and paste it into your WeCom app's webhook configuration zh_Hans: 复制此地址并粘贴到企业微信应用的 Webhook 配置中 + zh_Hant: 複製此地址並貼到企業微信應用的 Webhook 設定中 type: webhook-url required: false default: "" @@ -25,6 +32,7 @@ spec: label: en_US: Corpid zh_Hans: 企业ID + zh_Hant: 企業ID type: string required: true default: "" @@ -32,6 +40,7 @@ spec: label: en_US: Secret zh_Hans: 密钥 (Secret) + zh_Hant: 密鑰 (Secret) type: string required: true default: "" @@ -39,6 +48,7 @@ spec: label: en_US: Token zh_Hans: 令牌 (Token) + zh_Hant: 令牌 (Token) type: string required: true default: "" @@ -46,6 +56,7 @@ spec: label: en_US: EncodingAESKey zh_Hans: 消息加解密密钥 (EncodingAESKey) + zh_Hant: 訊息加解密密鑰 (EncodingAESKey) type: string required: true default: "" @@ -53,9 +64,11 @@ spec: label: en_US: API Base URL zh_Hans: API 基础 URL + zh_Hant: API 基礎 URL description: en_US: API Base URL, used for accessing the WeCom API. If you are deploying in an internal network environment and accessing the WeCom Customer Service API through a reverse proxy, please fill in this item according to the documentation. zh_Hans: 可选,若您部署在内网环境并通过反向代理访问企业微信 API,可根据文档填写此项 + zh_Hant: 可選,若您部署在內網環境並透過反向代理存取企業微信 API,可根據文件填寫此項 type: string required: false default: "https://qyapi.weixin.qq.com/cgi-bin" diff --git a/src/langbot/pkg/platform/sources/wecombot.yaml b/src/langbot/pkg/platform/sources/wecombot.yaml index 7b5c34ba..2405a7a3 100644 --- a/src/langbot/pkg/platform/sources/wecombot.yaml +++ b/src/langbot/pkg/platform/sources/wecombot.yaml @@ -5,16 +5,21 @@ metadata: label: en_US: WeComBot zh_Hans: 企业微信智能机器人 + zh_Hant: 企業微信智慧機器人 description: en_US: WeComBot Adapter zh_Hans: 企业微信智能机器人,支持长连接和 Webhook 两种接入方式,请查看文档了解使用方式 + zh_Hant: 企業微信智慧機器人,支援長連線和 Webhook 兩種接入方式,請查看文件了解使用方式 icon: wecombot.png spec: + categories: + - china config: - name: BotId label: en_US: BotId zh_Hans: 机器人ID (BotId) + zh_Hant: 機器人ID (BotId) type: string required: true default: "" @@ -22,6 +27,7 @@ spec: label: en_US: Robot Name zh_Hans: 机器人名称 + zh_Hant: 機器人名稱 type: string required: true default: "" @@ -29,9 +35,11 @@ spec: label: en_US: Enable Webhook Mode zh_Hans: 启用Webhook模式 + zh_Hant: 啟用 Webhook 模式 description: en_US: If enabled, the bot will use webhook mode to receive messages. Otherwise, it will use WS long connection mode zh_Hans: 如果启用,机器人将使用 Webhook 模式接收消息。否则,将使用 WS 长连接模式 + zh_Hant: 如果啟用,機器人將使用 Webhook 模式接收訊息。否則,將使用 WS 長連線模式 type: boolean required: true default: false @@ -39,9 +47,11 @@ spec: label: en_US: Webhook Callback URL zh_Hans: Webhook 回调地址 + zh_Hant: Webhook 回調地址 description: en_US: Copy this URL and paste it into your WeComBot webhook configuration zh_Hans: 复制此地址并粘贴到企业微信智能机器人的 Webhook 配置中 + zh_Hant: 複製此地址並貼到企業微信智慧機器人的 Webhook 設定中 type: webhook-url required: false default: "" @@ -53,9 +63,11 @@ spec: label: en_US: Secret zh_Hans: 机器人密钥 (Secret) + zh_Hant: 機器人密鑰 (Secret) description: en_US: Required for WebSocket long connection mode zh_Hans: 使用 WS 长连接模式时必填 + zh_Hant: 使用 WS 長連線模式時必填 type: string required: false default: "" @@ -63,9 +75,11 @@ spec: label: en_US: Corpid zh_Hans: 企业ID + zh_Hant: 企業ID description: en_US: Required for Webhook mode zh_Hans: 使用 Webhook 模式时必填 + zh_Hant: 使用 Webhook 模式時必填 type: string required: false default: "" @@ -73,9 +87,11 @@ spec: label: en_US: Token zh_Hans: 令牌 (Token) + zh_Hant: 令牌 (Token) description: en_US: Required for Webhook mode zh_Hans: 使用 Webhook 模式时必填 + zh_Hant: 使用 Webhook 模式時必填 type: string required: false default: "" @@ -83,9 +99,11 @@ spec: label: en_US: EncodingAESKey zh_Hans: 消息加解密密钥 (EncodingAESKey) + zh_Hant: 訊息加解密密鑰 (EncodingAESKey) description: en_US: Required for Webhook mode. Optional for WebSocket mode (used for file decryption) zh_Hans: 使用 Webhook 模式时必填。WebSocket 模式下可选(用于文件解密) + zh_Hant: 使用 Webhook 模式時必填。WebSocket 模式下可選(用於檔案解密) type: string required: false default: "" @@ -93,9 +111,11 @@ spec: label: en_US: Enable Stream Reply zh_Hans: 启用流式回复 + zh_Hant: 啟用串流回覆 description: en_US: If enabled, the bot will use streaming mode to reply messages zh_Hans: 如果启用,机器人将使用流式模式回复消息 + zh_Hant: 如果啟用,機器人將使用串流模式回覆訊息 type: boolean required: false default: true diff --git a/src/langbot/pkg/platform/sources/wecomcs.yaml b/src/langbot/pkg/platform/sources/wecomcs.yaml index f28cad75..b14b4885 100644 --- a/src/langbot/pkg/platform/sources/wecomcs.yaml +++ b/src/langbot/pkg/platform/sources/wecomcs.yaml @@ -5,19 +5,25 @@ metadata: label: en_US: WeComCustomerService zh_Hans: 企业微信客服 + zh_Hant: 企業微信客服 description: en_US: WeComCSAdapter zh_Hans: 企业微信对外客服机器人,需要公网地址以接收消息推送,请查看文档了解使用方式 + zh_Hant: 企業微信對外客服機器人,需要公網地址以接收訊息推送,請查看文件了解使用方式 icon: wecom.png spec: + categories: + - china config: - name: webhook_url label: en_US: Webhook Callback URL zh_Hans: Webhook 回调地址 + zh_Hant: Webhook 回調地址 description: en_US: Copy this URL and paste it into your WeCom Customer Service webhook configuration zh_Hans: 复制此地址并粘贴到企业微信客服的 Webhook 配置中 + zh_Hant: 複製此地址並貼到企業微信客服的 Webhook 設定中 type: webhook-url required: false default: "" @@ -25,6 +31,7 @@ spec: label: en_US: Corpid zh_Hans: 企业ID + zh_Hant: 企業ID type: string required: true default: "" @@ -32,6 +39,7 @@ spec: label: en_US: Secret zh_Hans: 密钥 + zh_Hant: 密鑰 type: string required: true default: "" @@ -39,6 +47,7 @@ spec: label: en_US: Token zh_Hans: 令牌 + zh_Hant: 令牌 type: string required: true default: "" @@ -46,6 +55,7 @@ spec: label: en_US: EncodingAESKey zh_Hans: 消息加解密密钥 + zh_Hant: 訊息加解密密鑰 type: string required: true default: "" @@ -53,9 +63,11 @@ spec: label: en_US: API Base URL zh_Hans: API 基础 URL + zh_Hant: API 基礎 URL description: en_US: API Base URL, used for accessing the WeCom API. If you are deploying in an internal network environment and accessing the WeCom Customer Service API through a reverse proxy, please fill in this item according to the documentation. zh_Hans: 可选,若您部署在内网环境并通过反向代理访问企业微信 API,可根据文档修改此项 + zh_Hant: 可選,若您部署在內網環境並透過反向代理存取企業微信 API,可根據文件修改此項 type: string required: false default: "https://qyapi.weixin.qq.com/cgi-bin" diff --git a/src/langbot/templates/metadata/pipeline/ai.yaml b/src/langbot/templates/metadata/pipeline/ai.yaml index c94a1f4c..600fd7a6 100644 --- a/src/langbot/templates/metadata/pipeline/ai.yaml +++ b/src/langbot/templates/metadata/pipeline/ai.yaml @@ -23,30 +23,30 @@ stages: label: en_US: Local Agent zh_Hans: 内置 Agent - - name: tbox-app-api - label: - en_US: Tbox App API - zh_Hans: 蚂蚁百宝箱平台 API - name: dify-service-api label: en_US: Dify Service API zh_Hans: Dify 服务 API - - name: dashscope-app-api - label: - en_US: Aliyun Dashscope App API - zh_Hans: 阿里云百炼平台 API - name: n8n-service-api label: en_US: n8n Workflow API zh_Hans: n8n 工作流 API - - name: langflow-api - label: - en_US: Langflow API - zh_Hans: Langflow API - name: coze-api label: en_US: Coze API zh_Hans: 扣子 API + - name: tbox-app-api + label: + en_US: Tbox App API + zh_Hans: 蚂蚁百宝箱平台 API + - name: dashscope-app-api + label: + en_US: Aliyun Dashscope App API + zh_Hans: 阿里云百炼平台 API + - name: langflow-api + label: + en_US: Langflow API + zh_Hans: Langflow API - name: local-agent label: en_US: Local Agent @@ -104,28 +104,6 @@ stages: field: __system.is_wizard operator: neq value: true - - name: tbox-app-api - label: - en_US: Tbox App API - zh_Hans: 蚂蚁百宝箱平台 API - description: - en_US: Configure the Tbox App API of the pipeline - zh_Hans: 配置蚂蚁百宝箱平台 API - config: - - name: api-key - label: - en_US: API Key - zh_Hans: API 密钥 - type: string - required: true - default: '' - - name: app-id - label: - en_US: App ID - zh_Hans: 应用 ID - type: string - required: true - default: '' - name: dify-service-api label: en_US: Dify Service API @@ -178,54 +156,6 @@ stages: type: string required: true default: 'your-api-key' - - name: dashscope-app-api - label: - en_US: Aliyun Dashscope App API - zh_Hans: 阿里云百炼平台 API - description: - en_US: Configure the Aliyun Dashscope App API of the pipeline - zh_Hans: 配置阿里云百炼平台 API - config: - - name: app-type - label: - en_US: App Type - zh_Hans: 应用类型 - type: select - required: true - default: agent - options: - - name: agent - label: - en_US: Agent - zh_Hans: Agent - - name: workflow - label: - en_US: Workflow - zh_Hans: 工作流 - - name: api-key - label: - en_US: API Key - zh_Hans: API 密钥 - type: string - required: true - default: 'your-api-key' - - name: app-id - label: - en_US: App ID - zh_Hans: 应用 ID - type: string - required: true - default: 'your-app-id' - - name: references_quote - label: - en_US: References Quote - zh_Hans: 引用文本 - description: - en_US: The text prompt when the references are included - zh_Hans: 包含引用资料时的文本提示 - type: string - required: false - default: '参考资料来自:' - name: n8n-service-api label: en_US: n8n Workflow API @@ -375,6 +305,131 @@ stages: type: string required: false default: 'response' + - name: coze-api + label: + en_US: coze API + zh_Hans: 扣子 API + description: + en_US: Configure the Coze API of the pipeline + zh_Hans: 配置Coze API + config: + - name: api-key + label: + en_US: API Key + zh_Hans: API 密钥 + description: + en_US: The API key for the Coze server + zh_Hans: Coze服务器的 API 密钥 + type: string + required: true + default: '' + - name: bot-id + label: + en_US: Bot ID + zh_Hans: 机器人 ID + description: + en_US: The ID of the bot to run + zh_Hans: 要运行的机器人 ID + type: string + required: true + default: '' + - name: api-base + label: + en_US: API Base URL + zh_Hans: API 基础 URL + description: + en_US: The base URL for the Coze API, please use https://api.coze.com for global Coze edition(coze.com). + zh_Hans: Coze API 的基础 URL,请使用 https://api.coze.com 用于全球 Coze 版(coze.com) + type: string + default: "https://api.coze.cn" + - name: auto-save-history + label: + en_US: Auto Save History + zh_Hans: 自动保存历史 + description: + en_US: Whether to automatically save conversation history + zh_Hans: 是否自动保存对话历史 + type: boolean + default: true + - name: timeout + label: + en_US: Request Timeout + zh_Hans: 请求超时 + description: + en_US: Timeout in seconds for API requests + zh_Hans: API 请求超时时间(秒) + type: number + default: 120 + - name: tbox-app-api + label: + en_US: Tbox App API + zh_Hans: 蚂蚁百宝箱平台 API + description: + en_US: Configure the Tbox App API of the pipeline + zh_Hans: 配置蚂蚁百宝箱平台 API + config: + - name: api-key + label: + en_US: API Key + zh_Hans: API 密钥 + type: string + required: true + default: '' + - name: app-id + label: + en_US: App ID + zh_Hans: 应用 ID + type: string + required: true + default: '' + - name: dashscope-app-api + label: + en_US: Aliyun Dashscope App API + zh_Hans: 阿里云百炼平台 API + description: + en_US: Configure the Aliyun Dashscope App API of the pipeline + zh_Hans: 配置阿里云百炼平台 API + config: + - name: app-type + label: + en_US: App Type + zh_Hans: 应用类型 + type: select + required: true + default: agent + options: + - name: agent + label: + en_US: Agent + zh_Hans: Agent + - name: workflow + label: + en_US: Workflow + zh_Hans: 工作流 + - name: api-key + label: + en_US: API Key + zh_Hans: API 密钥 + type: string + required: true + default: 'your-api-key' + - name: app-id + label: + en_US: App ID + zh_Hans: 应用 ID + type: string + required: true + default: 'your-app-id' + - name: references_quote + label: + en_US: References Quote + zh_Hans: 引用文本 + description: + en_US: The text prompt when the references are included + zh_Hans: 包含引用资料时的文本提示 + type: string + required: false + default: '参考资料来自:' - name: langflow-api label: en_US: Langflow API @@ -442,59 +497,4 @@ stages: zh_Hans: 可选的流程调整参数 type: json required: false - default: '{}' - - name: coze-api - label: - en_US: coze API - zh_Hans: 扣子 API - description: - en_US: Configure the Coze API of the pipeline - zh_Hans: 配置Coze API - config: - - name: api-key - label: - en_US: API Key - zh_Hans: API 密钥 - description: - en_US: The API key for the Coze server - zh_Hans: Coze服务器的 API 密钥 - type: string - required: true - default: '' - - name: bot-id - label: - en_US: Bot ID - zh_Hans: 机器人 ID - description: - en_US: The ID of the bot to run - zh_Hans: 要运行的机器人 ID - type: string - required: true - default: '' - - name: api-base - label: - en_US: API Base URL - zh_Hans: API 基础 URL - description: - en_US: The base URL for the Coze API, please use https://api.coze.com for global Coze edition(coze.com). - zh_Hans: Coze API 的基础 URL,请使用 https://api.coze.com 用于全球 Coze 版(coze.com) - type: string - default: "https://api.coze.cn" - - name: auto-save-history - label: - en_US: Auto Save History - zh_Hans: 自动保存历史 - description: - en_US: Whether to automatically save conversation history - zh_Hans: 是否自动保存对话历史 - type: boolean - default: true - - name: timeout - label: - en_US: Request Timeout - zh_Hans: 请求超时 - description: - en_US: Timeout in seconds for API requests - zh_Hans: API 请求超时时间(秒) - type: number - default: 120 \ No newline at end of file + default: '{}' \ No newline at end of file diff --git a/web/src/app/home/bots/components/bot-form/BotForm.tsx b/web/src/app/home/bots/components/bot-form/BotForm.tsx index 8fdcd9bb..ef4edbae 100644 --- a/web/src/app/home/bots/components/bot-form/BotForm.tsx +++ b/web/src/app/home/bots/components/bot-form/BotForm.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useRef, useState } from 'react'; +import React, { useEffect, useMemo, useRef, useState } from 'react'; import { IChooseAdapterEntity, IPipelineEntity, @@ -35,6 +35,7 @@ import { SelectContent, SelectGroup, SelectItem, + SelectLabel, SelectTrigger, SelectValue, } from '@/components/ui/select'; @@ -47,6 +48,10 @@ import { } from '@/components/ui/card'; import { extractI18nObject } from '@/i18n/I18nProvider'; import { CustomApiError } from '@/app/infra/entities/common'; +import { + groupByCategory, + getCategoryLabel, +} from '@/app/infra/entities/adapter-categories'; const getFormSchema = (t: (key: string) => string) => z.object({ @@ -113,6 +118,12 @@ export default function BotForm({ const currentAdapter = form.watch('adapter'); const currentAdapterConfig = form.watch('adapter_config'); + // Group adapters by category for the Select dropdown + const groupedAdapters = useMemo( + () => groupByCategory(adapterNameList), + [adapterNameList], + ); + // Notify parent when dirty state changes const { isDirty } = form.formState; useEffect(() => { @@ -183,6 +194,7 @@ export default function BotForm({ return { label: extractI18nObject(item.label), value: item.name, + categories: item.spec.categories, }; }), ); @@ -483,20 +495,31 @@ export default function BotForm({ )} - - {adapterNameList.map((item) => ( - -
- - {item.label} -
-
- ))} -
+ {groupedAdapters.map((group) => ( + + {group.categoryId && ( + + {getCategoryLabel(t, group.categoryId)} + + )} + {group.items.map((item) => ( + +
+ + {item.label} +
+
+ ))} +
+ ))}
diff --git a/web/src/app/home/bots/components/bot-form/ChooseEntity.ts b/web/src/app/home/bots/components/bot-form/ChooseEntity.ts index 2366aebe..b7ba8696 100644 --- a/web/src/app/home/bots/components/bot-form/ChooseEntity.ts +++ b/web/src/app/home/bots/components/bot-form/ChooseEntity.ts @@ -1,6 +1,7 @@ export interface IChooseAdapterEntity { label: string; value: string; + categories?: string[]; } export interface IPipelineEntity { diff --git a/web/src/app/infra/entities/adapter-categories.ts b/web/src/app/infra/entities/adapter-categories.ts new file mode 100644 index 00000000..b30f590b --- /dev/null +++ b/web/src/app/infra/entities/adapter-categories.ts @@ -0,0 +1,88 @@ +import i18n from 'i18next'; + +/** + * All known adapter category IDs. + */ +export const ADAPTER_CATEGORIES = [ + 'popular', + 'china', + 'global', + 'protocol', +] as const; + +export type AdapterCategoryId = (typeof ADAPTER_CATEGORIES)[number]; + +/** + * Returns the ordered list of category IDs based on the current locale. + * + * - zh-Hans: popular -> china -> global -> protocol + * - All other locales: popular -> global -> china -> protocol + * + * `popular` is always first. + */ +export function getOrderedCategories(): AdapterCategoryId[] { + const lang = i18n.language; + if (lang === 'zh-Hans') { + return ['popular', 'china', 'global', 'protocol']; + } + return ['popular', 'global', 'china', 'protocol']; +} + +/** + * Groups items that have a `categories` string array into ordered category + * buckets. An item can appear in multiple groups if it belongs to multiple + * categories. Items without any recognised category are collected into a + * trailing "uncategorized" group (null key). + */ +export function groupByCategory( + items: T[], +): { categoryId: AdapterCategoryId | null; items: T[] }[] { + const ordered = getOrderedCategories(); + const buckets = new Map(); + + // Initialise buckets in display order + for (const cat of ordered) { + buckets.set(cat, []); + } + buckets.set(null, []); + + for (const item of items) { + const cats = item.categories; + if (!cats || cats.length === 0) { + buckets.get(null)!.push(item); + continue; + } + + let placed = false; + for (const cat of cats) { + if (ordered.includes(cat as AdapterCategoryId)) { + buckets.get(cat as AdapterCategoryId)!.push(item); + placed = true; + } + } + if (!placed) { + buckets.get(null)!.push(item); + } + } + + // Build result, skipping empty buckets + const result: { categoryId: AdapterCategoryId | null; items: T[] }[] = []; + for (const [categoryId, groupItems] of buckets) { + if (groupItems.length > 0) { + result.push({ categoryId, items: groupItems }); + } + } + return result; +} + +/** + * Resolve the i18n display name for a category ID using the + * `bots.adapterCategory.*` translation keys. + */ +export function getCategoryLabel( + t: (key: string) => string, + categoryId: AdapterCategoryId | null, +): string { + if (categoryId === null) return ''; + return t(`bots.adapterCategory.${categoryId}`); +} diff --git a/web/src/app/infra/entities/api/index.ts b/web/src/app/infra/entities/api/index.ts index 1da6ae92..bdec55ca 100644 --- a/web/src/app/infra/entities/api/index.ts +++ b/web/src/app/infra/entities/api/index.ts @@ -117,6 +117,7 @@ export interface Adapter { description: I18nObject; icon?: string; spec: { + categories?: string[]; config: IDynamicFormItemSchema[]; }; } diff --git a/web/src/app/wizard/page.tsx b/web/src/app/wizard/page.tsx index 4ca21b34..063c0a6c 100644 --- a/web/src/app/wizard/page.tsx +++ b/web/src/app/wizard/page.tsx @@ -41,6 +41,10 @@ import { import DynamicFormComponent from '@/app/home/components/dynamic-form/DynamicFormComponent'; import { BotLogListComponent } from '@/app/home/bots/components/bot-log/view/BotLogListComponent'; import { extractI18nObject } from '@/i18n/I18nProvider'; +import { + groupByCategory, + getCategoryLabel, +} from '@/app/infra/entities/adapter-categories'; import { Button } from '@/components/ui/button'; import { @@ -490,18 +494,27 @@ export default function WizardPage() { const [isSkipping, setIsSkipping] = useState(false); const handleSkipConfirm = useCallback(async () => { - if (systemInfo.wizard_status === 'none') { - setIsSkipping(true); - try { + setIsSkipping(true); + try { + if (systemInfo.wizard_status === 'none') { await httpClient.updateWizardStatus('skipped'); systemInfo.wizard_status = 'skipped'; - } catch { - toast.error(t('wizard.skipSaveError')); - setIsSkipping(false); - return; // Dialog stays open — user can retry } + // Always clear persisted progress so re-entering starts fresh + await httpClient.saveWizardProgress({ + step: 0, + selected_adapter: null, + created_bot_uuid: null, + bot_saved: false, + selected_runner: null, + }); + systemInfo.wizard_progress = null; + } catch { + toast.error(t('wizard.skipSaveError')); setIsSkipping(false); + return; } + setIsSkipping(false); setShowSkipConfirm(false); router.push('/home'); }, [router, t]); @@ -727,6 +740,14 @@ function StepPlatform({ }) { const { t } = useTranslation(); + const groupedAdapters = useMemo(() => { + const withCategories = adapters.map((a) => ({ + ...a, + categories: a.spec.categories, + })); + return groupByCategory(withCategories); + }, [adapters]); + return (
@@ -735,45 +756,54 @@ function StepPlatform({ {t('wizard.platform.description')}

-
- {adapters.map((adapter) => ( - onSelect(adapter.name)} - > - - -
- - {extractI18nObject(adapter.label)} - -
- {selected === adapter.name && ( -
-
- + {groupedAdapters.map((group) => ( +
+ {group.categoryId && ( +

+ {getCategoryLabel(t, group.categoryId)} +

+ )} +
+ {group.items.map((adapter) => ( + onSelect(adapter.name)} + > + + +
+ + {extractI18nObject(adapter.label)} +
-
- )} - - -

- {extractI18nObject(adapter.description)} -

-
- - ))} -
+ {selected === adapter.name && ( +
+
+ +
+
+ )} + + +

+ {extractI18nObject(adapter.description)} +

+
+ + ))} +
+
+ ))}
); } @@ -1118,18 +1148,27 @@ function StepDone() { const [isCompleting, setIsCompleting] = useState(false); const handleBack = useCallback(async () => { - if (systemInfo.wizard_status === 'none') { - setIsCompleting(true); - try { + setIsCompleting(true); + try { + if (systemInfo.wizard_status === 'none') { await httpClient.updateWizardStatus('completed'); systemInfo.wizard_status = 'completed'; - } catch { - toast.error(t('wizard.completeSaveError')); - setIsCompleting(false); - return; // Don't navigate — let user retry } + // Always clear persisted progress so re-entering starts fresh + await httpClient.saveWizardProgress({ + step: 0, + selected_adapter: null, + created_bot_uuid: null, + bot_saved: false, + selected_runner: null, + }); + systemInfo.wizard_progress = null; + } catch { + toast.error(t('wizard.completeSaveError')); setIsCompleting(false); + return; } + setIsCompleting(false); router.push('/home/bots'); }, [router, t]); diff --git a/web/src/i18n/locales/en-US.ts b/web/src/i18n/locales/en-US.ts index 10e2e656..22ea474b 100644 --- a/web/src/i18n/locales/en-US.ts +++ b/web/src/i18n/locales/en-US.ts @@ -321,6 +321,12 @@ const enUS = { webhookSaasHint: 'Webhook requires a publicly accessible domain. LangBot Cloud provides a ready-to-use public endpoint for your bot.', webhookSaasLink: 'Learn more about LangBot Cloud', + adapterCategory: { + popular: 'Popular', + china: 'China', + global: 'Global', + protocol: 'Protocol', + }, logLevel: 'Log Level', allLevels: 'All Levels', selectLevel: 'Select Level', diff --git a/web/src/i18n/locales/ja-JP.ts b/web/src/i18n/locales/ja-JP.ts index 3fe04bf0..619282bf 100644 --- a/web/src/i18n/locales/ja-JP.ts +++ b/web/src/i18n/locales/ja-JP.ts @@ -326,6 +326,12 @@ webhookSaasHint: 'Webhook には公開アクセス可能なドメインが必要です。LangBot Cloud では、ボット用のパブリックエンドポイントをすぐにご利用いただけます。', webhookSaasLink: 'LangBot Cloud の詳細はこちら', + adapterCategory: { + popular: '人気', + china: '中国', + global: 'グローバル', + protocol: 'プロトコル', + }, logLevel: 'ログレベル', allLevels: 'すべてのレベル', selectLevel: 'レベルを選択', diff --git a/web/src/i18n/locales/zh-Hans.ts b/web/src/i18n/locales/zh-Hans.ts index 20306d52..308cf603 100644 --- a/web/src/i18n/locales/zh-Hans.ts +++ b/web/src/i18n/locales/zh-Hans.ts @@ -306,6 +306,12 @@ const zhHans = { webhookSaasHint: 'Webhook 需要公网可访问的域名。LangBot Cloud 为你的机器人提供开箱即用的公网地址。', webhookSaasLink: '了解 LangBot Cloud', + adapterCategory: { + popular: '热门', + china: '中国', + global: '全球', + protocol: '协议', + }, logLevel: '日志级别', allLevels: '全部级别', selectLevel: '选择级别', diff --git a/web/src/i18n/locales/zh-Hant.ts b/web/src/i18n/locales/zh-Hant.ts index b43f58bb..5804a3fa 100644 --- a/web/src/i18n/locales/zh-Hant.ts +++ b/web/src/i18n/locales/zh-Hant.ts @@ -305,6 +305,12 @@ const zhHant = { webhookSaasHint: 'Webhook 需要公網可存取的網域。LangBot Cloud 為你的機器人提供即開即用的公網位址。', webhookSaasLink: '了解 LangBot Cloud', + adapterCategory: { + popular: '熱門', + china: '中國', + global: '全球', + protocol: '協定', + }, logLevel: '日誌級別', allLevels: '全部級別', selectLevel: '選擇級別',