-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
feat(builtin_commands): add multi-language support for /help command #8134
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| { | ||
| "metadata": { | ||
| "display_name": "Встроенные команды", | ||
| "desc": "Встроенный плагин AstrBot, предоставляющий команды /reset, /help, /sid и другие." | ||
| }, | ||
| "config": { | ||
| "builtin_commands": { | ||
| "配置": "Конфигурация" | ||
| }, | ||
| "help_language": { | ||
| "description": "Язык ответа команды", | ||
| "hint": "Выберите язык ответа для команд /help и других", | ||
| "labels": { | ||
| "en-US": "Английский", | ||
| "zh-CN": "Упрощенный китайский", | ||
| "zh-TW": "Традиционный китайский", | ||
| "ru-RU": "Русский" | ||
| } | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| { | ||
| "metadata": { | ||
| "display_name": "內建指令", | ||
| "desc": "AstrBot 自帶插件,提供 /reset、/help、/sid 等內建指令。" | ||
| }, | ||
| "config": { | ||
| "builtin_commands": { | ||
| "配置": "配置" | ||
| }, | ||
| "help_language": { | ||
| "description": "指令回復語言", | ||
| "hint": "選擇 /help 等指令的回復語言", | ||
| "labels": { | ||
| "en-US": "英語", | ||
| "zh-CN": "簡體中文", | ||
| "zh-TW": "繁體中文", | ||
| "ru-RU": "俄語" | ||
| } | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| { | ||
| "help_language": { | ||
| "description": "指令回复语言", | ||
| "type": "string", | ||
| "hint": "选择 /help 等指令的回复语言", | ||
| "default": "zh-CN", | ||
| "options": ["en-US", "zh-CN", "zh-TW", "ru-RU"], | ||
| "labels": { | ||
| "en-US": "English", | ||
| "zh-CN": "简体中文", | ||
| "zh-TW": "繁体中文", | ||
| "ru-RU": "俄语" | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -6,10 +6,79 @@ | |||||||||
| from astrbot.core.star import command_management | ||||||||||
| from astrbot.core.utils.io import get_dashboard_version | ||||||||||
|
|
||||||||||
| TRANSLATIONS = { | ||||||||||
| "en-US": { | ||||||||||
| "no_commands": "No enabled built-in commands.", | ||||||||||
| "version_format": "AstrBot v{version}(WebUI: {dashboard_version})", | ||||||||||
| "commands": { | ||||||||||
| "help": "Show help message", | ||||||||||
| "sid": "Get session ID and other related information", | ||||||||||
| "reset": "Reset conversation history", | ||||||||||
| "stop": "Stop agent execution", | ||||||||||
| "new": "Create new conversation", | ||||||||||
| "stats": "Show token usage statistics for the current conversation", | ||||||||||
| "provider": "View or switch LLM Provider", | ||||||||||
| "dashboard_update": "Update AstrBot WebUI", | ||||||||||
| "set": "Set session variable", | ||||||||||
| "unset": "Unset session variable", | ||||||||||
| }, | ||||||||||
| }, | ||||||||||
| "zh-CN": { | ||||||||||
| "no_commands": "没有启用的内置指令。", | ||||||||||
| "version_format": "AstrBot v{version}(WebUI: {dashboard_version})", | ||||||||||
| "commands": { | ||||||||||
| "help": "显示帮助信息", | ||||||||||
| "sid": "获取会话ID和其他相关信息", | ||||||||||
| "reset": "重置对话历史", | ||||||||||
| "stop": "停止Agent执行", | ||||||||||
| "new": "创建新对话", | ||||||||||
| "stats": "显示当前对话的Token使用统计", | ||||||||||
| "provider": "查看或切换LLM提供商", | ||||||||||
| "dashboard_update": "更新AstrBot WebUI", | ||||||||||
| "set": "设置会话变量", | ||||||||||
| "unset": "取消设置会话变量", | ||||||||||
| }, | ||||||||||
| }, | ||||||||||
| "zh-TW": { | ||||||||||
| "no_commands": "沒有啟用的內建指令。", | ||||||||||
| "version_format": "AstrBot v{version}(WebUI: {dashboard_version})", | ||||||||||
| "commands": { | ||||||||||
| "help": "顯示幫助信息", | ||||||||||
| "sid": "獲取會話ID和其他相關信息", | ||||||||||
| "reset": "重置對話歷史", | ||||||||||
| "stop": "停止Agent執行", | ||||||||||
| "new": "創建新對話", | ||||||||||
| "stats": "顯示當前對話的Token使用統計", | ||||||||||
| "provider": "查看或切換LLM提供商", | ||||||||||
| "dashboard_update": "更新AstrBot WebUI", | ||||||||||
| "set": "設置會話變量", | ||||||||||
| "unset": "取消設置會話變量", | ||||||||||
| }, | ||||||||||
| }, | ||||||||||
| "ru-RU": { | ||||||||||
| "no_commands": "Нет включенных встроенных команд.", | ||||||||||
| "version_format": "AstrBot v{version}(WebUI: {dashboard_version})", | ||||||||||
| "commands": { | ||||||||||
| "help": "Показать справку", | ||||||||||
| "sid": "Получить ID сессии и другую информацию", | ||||||||||
| "reset": "Сбросить историю диалога", | ||||||||||
| "stop": "Остановить выполнение агента", | ||||||||||
| "new": "Создать новый диалог", | ||||||||||
| "stats": "Показать статистику использования токенов", | ||||||||||
| "provider": "Просмотр или смена провайдера LLM", | ||||||||||
| "dashboard_update": "Обновить AstrBot WebUI", | ||||||||||
| "set": "Установить переменную сессии", | ||||||||||
| "unset": "Сбросить переменную сессии", | ||||||||||
| }, | ||||||||||
| }, | ||||||||||
| } | ||||||||||
|
Comment on lines
+9
to
+74
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hardcoding a large translation dictionary directly in the source code is discouraged as it makes maintenance and adding new languages more difficult. Since the plugin already utilizes JSON-based i18n files in the .astrbot-plugin/i18n/ directory, consider leveraging the existing i18n system to manage these strings. |
||||||||||
|
|
||||||||||
|
|
||||||||||
| class HelpCommand: | ||||||||||
| def __init__(self, context: star.Context) -> None: | ||||||||||
| def __init__(self, context: star.Context, config: dict | None = None) -> None: | ||||||||||
| self.context = context | ||||||||||
| self.config = config or {} | ||||||||||
| self.language = self.config.get("help_language", "zh-CN") | ||||||||||
|
|
||||||||||
| async def _query_astrbot_notice(self): | ||||||||||
| try: | ||||||||||
|
|
@@ -23,9 +92,6 @@ async def _query_astrbot_notice(self): | |||||||||
| return "" | ||||||||||
|
|
||||||||||
| async def _build_reserved_command_lines(self) -> list[str]: | ||||||||||
| """ | ||||||||||
| 使用实时指令配置生成内置指令清单,确保重命名/禁用后与实际生效状态保持一致。 | ||||||||||
| """ | ||||||||||
| try: | ||||||||||
| commands = await command_management.list_commands() | ||||||||||
| except BaseException: | ||||||||||
|
|
@@ -37,7 +103,6 @@ def walk(items: list[dict], indent: int = 0) -> None: | |||||||||
| for item in items: | ||||||||||
| if not item.get("reserved") or not item.get("enabled"): | ||||||||||
| continue | ||||||||||
| # 仅展示顶级指令或指令组 | ||||||||||
| if item.get("type") == "sub_command": | ||||||||||
| continue | ||||||||||
| if item.get("parent_signature"): | ||||||||||
|
|
@@ -48,24 +113,28 @@ def walk(items: list[dict], indent: int = 0) -> None: | |||||||||
| or item.get("original_command") | ||||||||||
| or item.get("handler_name") | ||||||||||
| ) | ||||||||||
| if not effective or effective in [ | ||||||||||
| "set", | ||||||||||
| "unset", | ||||||||||
| "help", | ||||||||||
| "dashboard_update", | ||||||||||
| ]: | ||||||||||
| if not effective: | ||||||||||
| continue | ||||||||||
|
Comment on lines
+116
to
117
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The previous logic specifically excluded several internal commands (set, unset, help, dashboard_update) from the help list to keep the output clean. This exclusion has been removed, which will cause these commands to appear in the /help response. If this change was unintentional, please restore the filtering.
Suggested change
|
||||||||||
|
|
||||||||||
| description = item.get("description") or "" | ||||||||||
| desc_text = f" - {description}" if description else "" | ||||||||||
| handler_name = item.get("handler_name", "") | ||||||||||
|
|
||||||||||
| lang_translations = TRANSLATIONS.get(self.language, {}) | ||||||||||
| cmd_translations = lang_translations.get("commands", {}) | ||||||||||
| translated_desc = cmd_translations.get(handler_name, description) | ||||||||||
|
|
||||||||||
| desc_text = f" - {translated_desc}" if translated_desc else "" | ||||||||||
| indent_prefix = " " * indent | ||||||||||
| lines.append(f"{indent_prefix}/{effective}{desc_text}") | ||||||||||
|
|
||||||||||
| walk(commands) | ||||||||||
| return lines | ||||||||||
|
|
||||||||||
| def _get_translation(self, key: str) -> str: | ||||||||||
| lang_translations = TRANSLATIONS.get(self.language, TRANSLATIONS["zh-CN"]) | ||||||||||
| return lang_translations.get(key, key) | ||||||||||
|
|
||||||||||
| async def help(self, event: AstrMessageEvent) -> None: | ||||||||||
| """查看帮助""" | ||||||||||
| notice = "" | ||||||||||
| try: | ||||||||||
| notice = await self._query_astrbot_notice() | ||||||||||
|
|
@@ -77,11 +146,15 @@ async def help(self, event: AstrMessageEvent) -> None: | |||||||||
| commands_section = ( | ||||||||||
| "\n".join(command_lines) | ||||||||||
| if command_lines | ||||||||||
| else "No enabled built-in commands." | ||||||||||
| else self._get_translation("no_commands") | ||||||||||
| ) | ||||||||||
|
|
||||||||||
| version_str = self._get_translation("version_format").format( | ||||||||||
| version=VERSION, dashboard_version=dashboard_version | ||||||||||
| ) | ||||||||||
|
|
||||||||||
| msg_parts = [ | ||||||||||
| f"AstrBot v{VERSION}(WebUI: {dashboard_version})", | ||||||||||
| version_str, | ||||||||||
| commands_section, | ||||||||||
| ] | ||||||||||
| if notice: | ||||||||||
|
|
||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using a Chinese string as a key in an English i18n file is inconsistent. It is recommended to use a neutral, English-based key (e.g., "config_title") across all translation files to maintain consistency and avoid encoding issues.