From ef97957d183ee260901eb14f1252f31c156441d4 Mon Sep 17 00:00:00 2001 From: united_pooh Date: Fri, 27 Feb 2026 15:30:16 +0800 Subject: [PATCH 01/36] Add i18n support and related files - Add `fluent.runtime` to `pyproject.toml` and `requirements.txt` - Update `astrbot/core/agent/handoff.py` to remove an unnecessary line - Reorganize imports and add missing imports in `astrbot/core/utils/t2i/local_strategy.py` - Add new files for i18n: `astrbot/i18n/ftl_translate.py`, `astrbot/i18n/automatic_i18n.py`, and `astrbot/i18n/locales/zh-cn/i18n_messages.ftl` - Add GitHub workflow for i18n usage check - Add `axios` to `dashboard/src/i18n/composables.ts` and implement language setting API - Add `astrbot/dashboard/routes/lang_route.py` for handling language setting requests --- .github/workflows/i18n-check.yml | 27 + astrbot/core/agent/handoff.py | 1 - astrbot/core/lang.py | 226 ++ astrbot/core/utils/t2i/local_strategy.py | 30 +- astrbot/dashboard/routes/__init__.py | 2 + astrbot/dashboard/routes/lang_route.py | 27 + astrbot/i18n/__init__.py | 0 astrbot/i18n/automatic_i18n.py | 445 +++ astrbot/i18n/ftl_translate.py | 128 + astrbot/i18n/locales/en-us/i18n_messages.ftl | 2921 ++++++++++++++++++ astrbot/i18n/locales/zh-cn/i18n_messages.ftl | 2921 ++++++++++++++++++ dashboard/src/i18n/composables.ts | 21 + pyproject.toml | 1 + requirements.txt | 1 + 14 files changed, 6738 insertions(+), 13 deletions(-) create mode 100644 .github/workflows/i18n-check.yml create mode 100644 astrbot/core/lang.py create mode 100644 astrbot/dashboard/routes/lang_route.py create mode 100644 astrbot/i18n/__init__.py create mode 100644 astrbot/i18n/automatic_i18n.py create mode 100644 astrbot/i18n/ftl_translate.py create mode 100644 astrbot/i18n/locales/en-us/i18n_messages.ftl create mode 100644 astrbot/i18n/locales/zh-cn/i18n_messages.ftl diff --git a/.github/workflows/i18n-check.yml b/.github/workflows/i18n-check.yml new file mode 100644 index 0000000000..485a49db7f --- /dev/null +++ b/.github/workflows/i18n-check.yml @@ -0,0 +1,27 @@ +name: I18n Usage Check + +on: + pull_request: + paths: + - '**.py' + +jobs: + i18n-check: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install fluent.runtime pytest + + - name: Run I18n Check + run: | + pytest --tb=line tests/test_i18n.py diff --git a/astrbot/core/agent/handoff.py b/astrbot/core/agent/handoff.py index 8475009d3f..9510f76cb0 100644 --- a/astrbot/core/agent/handoff.py +++ b/astrbot/core/agent/handoff.py @@ -15,7 +15,6 @@ def __init__( tool_description: str | None = None, **kwargs, ) -> None: - # Avoid passing duplicate `description` to the FunctionTool dataclass. # Some call sites (e.g. SubAgentOrchestrator) pass `description` via kwargs # to override what the main agent sees, while we also compute a default diff --git a/astrbot/core/lang.py b/astrbot/core/lang.py new file mode 100644 index 0000000000..26bbba2add --- /dev/null +++ b/astrbot/core/lang.py @@ -0,0 +1,226 @@ +# lang.py +import threading +from pathlib import Path + +from fluent.runtime import FluentLocalization, FluentResourceLoader + +from astrbot.core.utils.astrbot_path import get_astrbot_path + + +class Lang: + def __init__( + self, + locale: str = "zh-cn", + files: list[str] | None = None, + namespace_paths: dict[str, str | Path] | None = None, + namespace_files: dict[str, list[str]] | None = None, + default_namespace: str = "default", + ): + self._lock = threading.RLock() + self.locale = locale + self.files = files + self.default_namespace = default_namespace + + base_dir = self._get_core_locales_dir() + if namespace_paths is None: + self.namespace_paths: dict[str, Path] = {self.default_namespace: base_dir} + else: + self.namespace_paths = { + namespace: Path(path) for namespace, path in namespace_paths.items() + } + if self.default_namespace not in self.namespace_paths: + self.namespace_paths[self.default_namespace] = base_dir + + self.namespace_files = namespace_files or {} + self.available_locales: list[str] = [] + self.available_locales_by_namespace: dict[str, list[str]] = {} + self._l10n_map: dict[str, FluentLocalization] = {} + self.load_locale(self.locale, self.files) + + @staticmethod + def _get_core_locales_dir() -> Path: + return Path(get_astrbot_path()) / "astrbot" / "i18n" / "locales" + + @staticmethod + def _validate_namespace(namespace: str) -> None: + if not namespace: + raise ValueError("Namespace must not be empty.") + if "." in namespace: + raise ValueError("Namespace must not contain '.'.") + + @staticmethod + def _collect_files(base_dir: Path, files: list[str] | None) -> list[str]: + if files is not None: + return files + + files_set = set() + for locale_dir in (d for d in base_dir.iterdir() if d.is_dir()): + for ftl_file in locale_dir.glob("*.ftl"): + files_set.add(ftl_file.name) + return sorted(files_set) + + @staticmethod + def _match_locale(available_locales: list[str], locale: str) -> str: + return next( + ( + locale_name + for locale_name in available_locales + if locale_name.lower() == locale.lower() + ), + locale, + ) + + def _build_localization( + self, base_dir: Path, locale: str, files: list[str] | None + ) -> tuple[FluentLocalization, list[str]]: + if not base_dir.exists() or not base_dir.is_dir(): + raise ValueError(f"Locale directory does not exist: {base_dir}") + + available_locales = [d.name for d in base_dir.iterdir() if d.is_dir()] + if not available_locales: + raise ValueError(f"No locale directories found under: {base_dir}") + + matched_locale = self._match_locale(available_locales, locale) + merged_files = self._collect_files(base_dir, files) + loader = FluentResourceLoader(str(base_dir / "{locale}")) + + locales_preference = [matched_locale] + if "zh-cn" in available_locales and matched_locale.lower() != "zh-cn": + locales_preference.append("zh-cn") + + return FluentLocalization( + locales_preference, merged_files, loader + ), available_locales + + def _update_available_locales(self) -> None: + if self.default_namespace in self.available_locales_by_namespace: + self.available_locales = self.available_locales_by_namespace[ + self.default_namespace + ] + return + + all_locales: set[str] = set() + for locales in self.available_locales_by_namespace.values(): + all_locales.update(locales) + self.available_locales = sorted(all_locales) + + def _refresh_namespace(self, namespace: str) -> None: + base_dir = self.namespace_paths[namespace] + ns_files = self.namespace_files.get(namespace, self.files) + l10n, available_locales = self._build_localization( + base_dir, self.locale, ns_files + ) + self._l10n_map[namespace] = l10n + self.available_locales_by_namespace[namespace] = available_locales + self._update_available_locales() + + def load_locale( + self, + locale: str = "zh-cn", + files: list[str] | None = None, + namespace_paths: dict[str, str | Path] | None = None, + namespace_files: dict[str, list[str]] | None = None, + ): + with self._lock: + if namespace_paths is not None: + self.namespace_paths = { + namespace: Path(path) for namespace, path in namespace_paths.items() + } + if self.default_namespace not in self.namespace_paths: + self.namespace_paths[self.default_namespace] = ( + self._get_core_locales_dir() + ) + if namespace_files is not None: + self.namespace_files = namespace_files + + self.locale = locale + if files is not None: + self.files = files + + l10n_map: dict[str, FluentLocalization] = {} + available_by_namespace: dict[str, list[str]] = {} + for namespace, base_dir in self.namespace_paths.items(): + ns_files = self.namespace_files.get(namespace, self.files) + l10n, available_locales = self._build_localization( + base_dir, locale, ns_files + ) + l10n_map[namespace] = l10n + available_by_namespace[namespace] = available_locales + + self._l10n_map = l10n_map + self.available_locales_by_namespace = available_by_namespace + self._update_available_locales() + + def register_namespace( + self, + namespace: str, + path: str | Path, + files: list[str] | None = None, + replace: bool = False, + ) -> None: + self._validate_namespace(namespace) + with self._lock: + if namespace in self.namespace_paths and not replace: + raise ValueError( + f"Namespace '{namespace}' already exists. Set replace=True to overwrite." + ) + + self.namespace_paths[namespace] = Path(path) + if files is None: + self.namespace_files.pop(namespace, None) + else: + self.namespace_files[namespace] = files + self._refresh_namespace(namespace) + + def unregister_namespace(self, namespace: str) -> None: + self._validate_namespace(namespace) + with self._lock: + if namespace == self.default_namespace: + raise ValueError("Default namespace cannot be unregistered.") + if namespace not in self.namespace_paths: + raise ValueError(f"Namespace '{namespace}' is not registered.") + + self.namespace_paths.pop(namespace, None) + self.namespace_files.pop(namespace, None) + self._l10n_map.pop(namespace, None) + self.available_locales_by_namespace.pop(namespace, None) + self._update_available_locales() + + def list_namespaces(self) -> list[str]: + with self._lock: + return sorted(self.namespace_paths.keys()) + + def get_namespace_meta(self) -> dict[str, dict[str, object]]: + with self._lock: + return { + namespace: { + "path": str(path), + "files": self.namespace_files.get(namespace), + "available_locales": self.available_locales_by_namespace.get( + namespace, [] + ), + } + for namespace, path in self.namespace_paths.items() + } + + def _resolve_key(self, key: str) -> tuple[str, str]: + if "." not in key: + return self.default_namespace, key + + namespace, real_key = key.split(".", 1) + if namespace in self._l10n_map and real_key: + return namespace, real_key + return self.default_namespace, key + + def __call__(self, key: str, **kwargs) -> str: + if not key: + return "" + with self._lock: + namespace, real_key = self._resolve_key(key) + l10n = ( + self._l10n_map.get(namespace) or self._l10n_map[self.default_namespace] + ) + return l10n.format_value(real_key, kwargs) + + +t = Lang(locale="zh-cn") diff --git a/astrbot/core/utils/t2i/local_strategy.py b/astrbot/core/utils/t2i/local_strategy.py index 2fa2351291..3d394dccc9 100644 --- a/astrbot/core/utils/t2i/local_strategy.py +++ b/astrbot/core/utils/t2i/local_strategy.py @@ -1,17 +1,18 @@ -import re import os -import aiohttp +import re import ssl -import certifi -from io import BytesIO -from typing import List, Tuple from abc import ABC, abstractmethod +from io import BytesIO + +import aiohttp +import certifi +from PIL import Image, ImageDraw, ImageFont + from astrbot.core.config import VERSION +from astrbot.core.utils.astrbot_path import get_astrbot_data_path +from astrbot.core.utils.io import save_temp_img from . import RenderStrategy -from PIL import ImageFont, Image, ImageDraw -from astrbot.core.utils.io import save_temp_img -from astrbot.core.utils.astrbot_path import get_astrbot_data_path class FontManager: @@ -20,7 +21,7 @@ class FontManager: _font_cache = {} @classmethod - def get_font(cls, size: int) -> ImageFont.FreeTypeFont|ImageFont.ImageFont: + def get_font(cls, size: int) -> ImageFont.FreeTypeFont | ImageFont.ImageFont: """获取指定大小的字体,优先从缓存获取""" if size in cls._font_cache: return cls._font_cache[size] @@ -66,7 +67,9 @@ class TextMeasurer: """测量文本尺寸的工具类""" @staticmethod - def get_text_size(text: str, font: ImageFont.FreeTypeFont|ImageFont.ImageFont) -> tuple[int, int]: + def get_text_size( + text: str, font: ImageFont.FreeTypeFont | ImageFont.ImageFont + ) -> tuple[int, int]: """获取文本的尺寸""" # 依赖库Pillow>=11.2.1,不再需要考虑<9.0.0 @@ -75,7 +78,7 @@ def get_text_size(text: str, font: ImageFont.FreeTypeFont|ImageFont.ImageFont) - @staticmethod def split_text_to_fit_width( - text: str, font: ImageFont.FreeTypeFont|ImageFont.ImageFont, max_width: int + text: str, font: ImageFont.FreeTypeFont | ImageFont.ImageFont, max_width: int ) -> list[str]: """将文本拆分为多行,确保每行不超过指定宽度""" lines = [] @@ -293,7 +296,10 @@ def render( # 倾斜变换,使用仿射变换实现斜体效果 # 变换矩阵: [1, 0.2, 0, 0, 1, 0] italic_img = text_img.transform( - text_img.size, Image.Transform.AFFINE, (1, 0.2, 0, 0, 1, 0), Image.Resampling.BICUBIC + text_img.size, + Image.Transform.AFFINE, + (1, 0.2, 0, 0, 1, 0), + Image.Resampling.BICUBIC, ) # 粘贴到原图像 diff --git a/astrbot/dashboard/routes/__init__.py b/astrbot/dashboard/routes/__init__.py index fbbd0c7a08..636016b937 100644 --- a/astrbot/dashboard/routes/__init__.py +++ b/astrbot/dashboard/routes/__init__.py @@ -21,6 +21,7 @@ from .subagent import SubAgentRoute from .tools import ToolsRoute from .update import UpdateRoute +from .lang_route import LangRoute __all__ = [ "ApiKeyRoute", @@ -46,4 +47,5 @@ "ToolsRoute", "SkillsRoute", "UpdateRoute", + "LangRoute", ] diff --git a/astrbot/dashboard/routes/lang_route.py b/astrbot/dashboard/routes/lang_route.py new file mode 100644 index 0000000000..822560495a --- /dev/null +++ b/astrbot/dashboard/routes/lang_route.py @@ -0,0 +1,27 @@ +from quart import request + +from astrbot.api import logger +from astrbot.core.lang import t +from astrbot.dashboard.routes.route import Response, Route, RouteContext + + +class LangRoute(Route): + def __init__(self, context: RouteContext) -> None: + super().__init__(context) + self.routes = { + "/setLang": ("POST", self.set_Lang), + } + self.register_routes() + + async def set_Lang(self): + data = await request.get_json() + lang = data.get("lang") + logger.debug(f"[LangRoute] lang:{lang}") + if lang is None: + return Response().error("lang 为必填参数。").__dict__ + try: + t.load_locale(locale=lang.lower(), files=None) + except ValueError as exc: + return Response().error(str(exc)).__dict__ + payload = {"lang": lang.lower(), "message": f"语言已设置为 {lang}"} + return Response().ok(payload).__dict__ diff --git a/astrbot/i18n/__init__.py b/astrbot/i18n/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/astrbot/i18n/automatic_i18n.py b/astrbot/i18n/automatic_i18n.py new file mode 100644 index 0000000000..11311c4168 --- /dev/null +++ b/astrbot/i18n/automatic_i18n.py @@ -0,0 +1,445 @@ +""" +从 Python 源文件中提取 logger / print / click.echo / raise XxxError 的消息, +转换为 FTL 格式,并将含变量的调用重写为 t("id", key=val) 形式。 +所有提取的条目统一输出到 astrbot/i18n/locales/zh-cn/i18n_messages.ftl。 +""" + +import ast +import hashlib +import re +from pathlib import Path + +# --------------------------------------------------------------------------- +# ID 生成:取消息内容的 MD5 前8位,相同内容永远生成同一个 id(幂等) +# --------------------------------------------------------------------------- + + +def make_id(ftl_value: str) -> str: + digest = hashlib.md5(ftl_value.encode()).hexdigest()[:8] + return f"msg-{digest}" + + +# --------------------------------------------------------------------------- +# 字符串表达式解析:提取 FTL 值 + 变量参数列表 +# 返回 (ftl_value, kwargs) 或 None +# ftl_value : FTL 格式字符串,如 "{$date}相反的你和我" +# kwargs : [(参数名, 源码表达式)] 列表,如 [("date", "date")] +# 纯字符串常量返回 ("原始字符串", []),kwargs 为空表示无需替换 +# --------------------------------------------------------------------------- + + +def flatten_str_concat(node): + """递归展开字符串拼接 "a" + "b" + ... → 合并后的字符串常量节点(仅当所有部分都是常量时)""" + if isinstance(node, ast.Constant) and isinstance(node.value, str): + return node.value + if isinstance(node, ast.BinOp) and isinstance(node.op, ast.Add): + left = flatten_str_concat(node.left) + right = flatten_str_concat(node.right) + if left is not None and right is not None: + return left + right + return None + + +def extract_string_expr(node): + # 纯字符串常量 + if isinstance(node, ast.Constant) and isinstance(node.value, str): + return node.value, [] + + # 多行字符串拼接:"aaa" "bbb" 或 "aaa" + "bbb"(全部为常量时合并处理) + if isinstance(node, ast.BinOp) and isinstance(node.op, ast.Add): + merged = flatten_str_concat(node) + if merged is not None: + return merged, [] + + # f-string + if isinstance(node, ast.JoinedStr): + return parse_fstring(node) + + # "..." % var 或 "..." % (var1, var2) + if isinstance(node, ast.BinOp) and isinstance(node.op, ast.Mod): + return parse_percent_format(node) + + # "...".format(...) + if ( + isinstance(node, ast.Call) + and isinstance(node.func, ast.Attribute) + and node.func.attr == "format" + and isinstance(node.func.value, ast.Constant) + and isinstance(node.func.value.value, str) + ): + return parse_str_format(node) + + # 裸变量:logger.info(var) → "{$var}" + if isinstance(node, ast.Name): + return "{$" + node.id + "}", [(node.id, node.id)] + + # 裸函数调用:logger.info(get_msg()) → "{$res}" + if isinstance(node, ast.Call): + return "{$res}", [("res", ast.unparse(node))] + + return None + + +def parse_fstring(node: ast.JoinedStr): + res_counter = [0] + parts = [] + kwargs = [] + + for value in node.values: + if isinstance(value, ast.Constant): + parts.append(str(value.value)) + elif isinstance(value, ast.FormattedValue): + param, src = get_param_and_src(value.value, res_counter) + parts.append("{$" + param + "}") + kwargs.append((param, src)) + + return "".join(parts), kwargs + + +def parse_percent_format(node: ast.BinOp): + if not (isinstance(node.left, ast.Constant) and isinstance(node.left.value, str)): + return None + + template = node.left.value + right = node.right + arg_nodes = list(right.elts) if isinstance(right, ast.Tuple) else [right] + + res_counter = [0] + kwargs = [] + + def replacer(m): + fmt_letter = m.group(0)[-1] + if fmt_letter == "%": + return "%" + if arg_nodes: + param, src = get_param_and_src(arg_nodes.pop(0), res_counter, fmt_letter) + kwargs.append((param, src)) + return "{$" + param + "}" + return m.group(0) + + ftl_value = re.sub(r"%(?:\(\w+\))?[-+0-9*.]*[sdfrx%]", replacer, template) + return ftl_value, kwargs + + +def parse_str_format(node: ast.Call): + template = node.func.value.value + res_counter = [0] + + # 命名占位符映射:占位符名 → (参数名, 源码表达式) + kw_map = {} + for kw in node.keywords: + if kw.arg: + kw_map[kw.arg] = (kw.arg, ast.unparse(kw.value)) + + # 位置参数列表 + pos_args = [get_param_and_src(a, res_counter, "val") for a in node.args] + + kwargs = [] + + def replacer(m): + field = m.group(1).split(":")[0].strip() + if field == "" or field.isdigit(): + idx = int(field) if field.isdigit() else 0 + param, src = pos_args[idx] if idx < len(pos_args) else ("arg", "arg") + else: + param, src = kw_map.get(field, (field, field)) + kwargs.append((param, src)) + return "{$" + param + "}" + + ftl_value = re.sub(r"\{([^{}]*)\}", replacer, template) + return ftl_value, kwargs + + +def get_param_and_src(node, res_counter: list, fmt_letter: str = "val"): + """返回 (参数名, 源码表达式字符串)""" + if isinstance(node, ast.Name): + return node.id, node.id + if isinstance(node, ast.Constant): + return fmt_letter, repr(node.value) + # 复杂表达式 / 函数调用 + res_counter[0] += 1 + count = res_counter[0] + param = "res_" + str(count) if count > 1 else "res" + return param, ast.unparse(node) + + +# --------------------------------------------------------------------------- +# 目标调用判断 +# --------------------------------------------------------------------------- + + +def is_logger_call(node: ast.Call) -> bool: + """判断是否为 logger.info / warning / warn / error / debug / critical / exception""" + func = node.func + return ( + isinstance(func, ast.Attribute) + and func.attr + in ("info", "warning", "warn", "error", "debug", "critical", "exception") + and isinstance(func.value, ast.Name) + ) + + +def is_print_call(node: ast.Call) -> bool: + """判断是否为 print(...)""" + return isinstance(node.func, ast.Name) and node.func.id == "print" + + +def is_click_echo_call(node: ast.Call) -> bool: + """判断是否为 click.echo(...)""" + func = node.func + return ( + isinstance(func, ast.Attribute) + and func.attr == "echo" + and isinstance(func.value, ast.Name) + and func.value.id == "click" + ) + + +def is_exception_call(node: ast.Call) -> bool: + """判断是否为 XxxError(...) 或 XxxException(...) 的实例化""" + func = node.func + # 支持 ValueError(...) 和 module.ValueError(...) 两种形式 + name = ( + func.id + if isinstance(func, ast.Name) + else (func.attr if isinstance(func, ast.Attribute) else "") + ) + return name.endswith("Error") or name.endswith("Exception") + + +def is_message_call(node: ast.Call) -> bool: + """判断是否为任意对象的 .message(...) 或 .error(...) 方法调用""" + func = node.func + if not isinstance(func, ast.Attribute): + return False + if func.attr not in ("message", "error"): + return False + # 第一个参数是函数调用结果(如 str(exc)、get_msg())时不匹配 + if node.args and isinstance(node.args[0], ast.Call): + return False + return True + + +def is_target_call(node: ast.Call) -> bool: + return ( + is_logger_call(node) + or is_print_call(node) + or is_click_echo_call(node) + or is_exception_call(node) + or is_message_call(node) + ) + + +# --------------------------------------------------------------------------- +# 核心:提取 + 重写 +# --------------------------------------------------------------------------- + + +def extract_and_rewrite(source: str): + """ + 解析源码,找出所有含变量的目标调用,返回: + ftl_entries : [(id, ftl_value), ...] + new_source : 将含变量的第一个参数替换为 t("id", key=val) 后的源码 + 纯字符串(无变量)的调用保持原样不动。 + """ + try: + tree = ast.parse(source) + except Exception as e: + print(f"Error parsing source: {e}") + return [], source + + # 收集替换信息:(起始偏移, 结束偏移, 新文本, msg_id, ftl_value) + replacements = [] + + # 预计算每行的字符偏移量 + line_offsets = [] + offset = 0 + for line in source.splitlines(keepends=True): + line_offsets.append(offset) + offset += len(line) + + for node in ast.walk(tree): + if not isinstance(node, ast.Call): + continue + if not is_target_call(node): + continue + if not node.args: + continue + + # 第一个参数已经是 t(...) 调用,说明已处理过,跳过 + first = node.args[0] + if ( + isinstance(first, ast.Call) + and isinstance(first.func, ast.Name) + and first.func.id == "t" + ): + continue + + result = extract_string_expr(node.args[0]) + if result is None: + continue + + ftl_value, kwargs = result + # 保留原样的 \n 而不是直接换行 + ftl_value = ftl_value.replace("\r", "\\r").replace("\n", "\\n") + + msg_id = make_id(ftl_value) + + # 构造新的第一个参数:t("id", key=val, ...) + kw_parts = ", ".join(f"{p}={s}" for p, s in kwargs) + t_call = f't("{msg_id}", {kw_parts})' if kw_parts else f't("{msg_id}")' + + # 用 get_source_segment 精确获取原始参数文本(正确处理中文字符偏移) + arg_node = node.args[0] + original_arg = ast.get_source_segment(source, arg_node) + if original_arg is None: + continue + + # 在源码中定位原始参数的精确位置 + approx = line_offsets[arg_node.lineno - 1] + arg_node.col_offset + window_start = max(0, approx - 4) + pos = source.find(original_arg, window_start) + if pos == -1: + continue + + replacements.append((pos, pos + len(original_arg), t_call, msg_id, ftl_value)) + + # 从后往前替换,保证偏移量不受影响 + replacements.sort(key=lambda x: x[0], reverse=True) + + new_source = source + ftl_entries_map = {} + for start, end, new_text, msg_id, ftl_value in replacements: + new_source = new_source[:start] + new_text + new_source[end:] + ftl_entries_map[msg_id] = ftl_value + + # 按出现顺序返回 FTL 条目(去重) + ordered_ftl = [] + seen = set() + for _, _, _, msg_id, ftl_value in sorted(replacements, key=lambda x: x[0]): + if msg_id not in seen: + ordered_ftl.append((msg_id, ftl_value)) + seen.add(msg_id) + + return ordered_ftl, new_source + + +# --------------------------------------------------------------------------- +# 命令行入口:遍历整个项目目录,批量提取并重写 +# --------------------------------------------------------------------------- + + +def main(): + import argparse + import os + + try: + from tqdm import tqdm + except ImportError: + + def tqdm(iterable, **kwargs): + return iterable + + parser = argparse.ArgumentParser(description="提取 i18n 消息并重写日志/异常调用") + parser.add_argument("--rewrite", action="store_true", help="原地重写源文件") + args = parser.parse_args() + + # 使用 get_astrbot_path 获取项目根目录 + root_dir = Path(".") + ftl_base_dir = Path(f"{root_dir}/astrbot/i18n/locales/zh-cn") + ftl_base_dir.mkdir(parents=True, exist_ok=True) + + ftl_file = ftl_base_dir / "i18n_messages.ftl" + + # 所有生成的 FTL 条目,按文件分组:rel_path -> [(msg_id, ftl_value)] + all_files_data = {} + + # 遍历时跳过的目录 + exclude_dirs = { + ".git", + "__pycache__", + ".venv", + "venv", + "tests", + ".pytest_cache", + ".ruff_cache", + ".idea", + ".vscode", + "data", + } + + all_files = [] + for root, dirs, files in os.walk(root_dir): + dirs[:] = [d for d in dirs if d not in exclude_dirs] + for file in files: + if not file.endswith(".py"): + continue + # 跳过本脚本自身及引导文件 + if file in ("automatic_i18n.py", "runtime_bootstrap.py"): + continue + all_files.append(Path(root) / file) + + pbar = tqdm(all_files, desc="Processing files") + for file_path in pbar: + try: + source = file_path.read_text(encoding="utf-8") + ftl_entries, new_source = extract_and_rewrite(source) + + if not ftl_entries: + continue + + if args.rewrite: + import_stmt = "from astrbot.core.lang import t" + if import_stmt not in new_source: + # 插入到模块 docstring 之后,否则插到文件开头 + if new_source.startswith('"""') or new_source.startswith("'''"): + quote = new_source[:3] + end_doc = new_source.find(quote, 3) + if end_doc != -1: + insert_pos = end_doc + 3 + new_source = ( + new_source[:insert_pos] + + "\n" + + import_stmt + + new_source[insert_pos:] + ) + else: + new_source = import_stmt + "\n" + new_source + else: + new_source = import_stmt + "\n" + new_source + file_path.write_text(new_source, encoding="utf-8") + tqdm.write(f" [已重写] {file_path}") + + rel_path = str(file_path.relative_to(root_dir)) + all_files_data[rel_path] = ftl_entries + + except Exception as e: + tqdm.write(f" [错误] 处理 {file_path} 失败:{e}") + + # 将 FTL 条目追加写入统一的文件(跳过已存在的 msg_id) + if all_files_data: + existing_content = ( + ftl_file.read_text(encoding="utf-8") if ftl_file.exists() else "" + ) + + new_ftl_lines = [] + for rel_path, entries in all_files_data.items(): + header = f"### {rel_path}" + section_lines = [] + for msg_id, ftl_value in entries: + if f"{msg_id} =" not in existing_content: + section_lines.append(f"{msg_id} = {ftl_value}") + + # 只有有新条目时才写入 header + if section_lines: + new_ftl_lines.append(f"\n{header}") + new_ftl_lines.extend(section_lines) + + if new_ftl_lines: + with open(ftl_file, "a", encoding="utf-8") as f: + f.write("\n".join(new_ftl_lines) + "\n") + print(f"[FTL] 已更新 {ftl_file},新增 {len(new_ftl_lines)} 行") + + +if __name__ == "__main__": + main() diff --git a/astrbot/i18n/ftl_translate.py b/astrbot/i18n/ftl_translate.py new file mode 100644 index 0000000000..2f76f61515 --- /dev/null +++ b/astrbot/i18n/ftl_translate.py @@ -0,0 +1,128 @@ +import argparse +import os +from concurrent.futures import ThreadPoolExecutor, as_completed +from pathlib import Path + +from fluent.syntax import ast, parse, serialize +from openai import OpenAI +from tqdm import tqdm + + +def translate_string(input_string: str, target_lang: str = "English") -> str: + """使用 DeepSeek API 翻译 i18n 字符串。""" + api_key = os.environ.get("DEEPSEEK_API_KEY") + if not api_key: + raise ValueError("未检测到环境变量 DEEPSEEK_API_KEY,请先设置。") + + client = OpenAI(api_key=api_key, base_url="https://api.deepseek.com") + + system_prompt = ( + f"你是一个专业的软件i18n翻译器。请将以下文本翻译为{target_lang},保持IT语境准确。\n\n" + "规则:\n\n" + "1. 必须原样保留所有代码占位符(如 {$var} 等)。\n\n" + "2. 只输出最终译文,绝对禁止包含任何解释、多余的引号或Markdown格式。" + "3. 如果原文为中文则直接返回原文" + ) + + try: + response = client.chat.completions.create( + model="deepseek-chat", + messages=[ + {"role": "system", "content": system_prompt}, + {"role": "user", "content": f"待翻译文本:{input_string}"}, + ], + temperature=1.3, + stream=False, + ) + return response.choices[0].message.content.strip() + except Exception as e: + print(f"\n[Error] API 调用失败: {e}") + return input_string + + +def translate_element(element: ast.TextElement, target_lang: str) -> str: + """翻译单个 TextElement,返回翻译结果(供线程池调用)。""" + original_text = element.value.strip() + if not original_text: + return element.value + return translate_string(original_text, target_lang) + + +def process_ftl(ftl_path: Path, target_lang: str = "English", max_workers: int = 10): + """读取、并发翻译并写回 FTL 文件。""" + if not ftl_path.exists(): + print(f"File not found: {ftl_path}") + return + + content = ftl_path.read_text(encoding="utf-8") + resource = parse(content) + + # 收集所有需要翻译的 TextElement(跳过空文本) + messages = [entry for entry in resource.body if isinstance(entry, ast.Message)] + if not messages: + print(f"No messages found in {ftl_path}") + return + + # 收集所有待翻译的 (element, ) 对,保留引用以便原地修改 + elements_to_translate = [] + for msg in messages: + if msg.value: + for element in msg.value.elements: + if isinstance(element, ast.TextElement) and element.value.strip(): + elements_to_translate.append(element) + + print( + f"共 {len(elements_to_translate)} 条文本,使用 {max_workers} 个并发线程翻译..." + ) + + # 并发翻译:future -> element 映射,翻译完成后原地写回 + with ThreadPoolExecutor(max_workers=max_workers) as executor: + future_to_element = { + executor.submit(translate_element, el, target_lang): el + for el in elements_to_translate + } + + pbar = tqdm( + as_completed(future_to_element), + total=len(future_to_element), + desc="翻译中", + unit="条", + ) + for future in pbar: + element = future_to_element[future] + try: + element.value = future.result() + except Exception as e: + print(f"\n[Error] 翻译失败,保留原文: {e}") + + # 序列化并写回 + translated_content = serialize(resource) + ftl_path.write_text(translated_content, encoding="utf-8") + print(f"\n翻译完成,已保存到 {ftl_path}") + + +def main(): + parser = argparse.ArgumentParser( + description="使用 DeepSeek 并发翻译 Fluent (FTL) 文件" + ) + parser.add_argument( + "--file", + default="astrbot/i18n/locales/en-us/i18n_messages.ftl", + help="待翻译的 FTL 文件路径", + ) + parser.add_argument("--lang", default="English", help="目标语言(默认: English)") + parser.add_argument( + "--workers", type=int, default=10, help="并发线程数(默认: 10)" + ) + args = parser.parse_args() + + if "DEEPSEEK_API_KEY" not in os.environ: + print("错误: 请先设置 DEEPSEEK_API_KEY 环境变量。") + print("例如: export DEEPSEEK_API_KEY='sk-xxxxxx'") + return + + process_ftl(Path(args.file), args.lang, args.workers) + + +if __name__ == "__main__": + main() diff --git a/astrbot/i18n/locales/en-us/i18n_messages.ftl b/astrbot/i18n/locales/en-us/i18n_messages.ftl new file mode 100644 index 0000000000..3eef348631 --- /dev/null +++ b/astrbot/i18n/locales/en-us/i18n_messages.ftl @@ -0,0 +1,2921 @@ + +### main.py +msg-5e25709f = 请使用 Python3.10+ 运行本项目。 +msg-afd0ab81 = 使用指定的 WebUI 目录: {$webui_dir} +msg-7765f00f = 指定的 WebUI 目录 {$webui_dir} 不存在,将使用默认逻辑。 +msg-9af20e37 = WebUI 版本已是最新。 +msg-9dd5c1d2 = 检测到 WebUI 版本 ({$v}) 与当前 AstrBot 版本 (v{$VERSION}) 不符。 +msg-ec714d4e = 开始下载管理面板文件...高峰期(晚上)可能导致较慢的速度。如多次下载失败,请前往 https://github.com/AstrBotDevs/AstrBot/releases/latest 下载 dist.zip,并将其中的 dist 文件夹解压至 data 目录下。 +msg-c5170c27 = 下载管理面板文件失败: {$e}。 +msg-e1592ad1 = 管理面板下载完成。 +msg-fe494da6 = {$logo_tmpl} + +### astrbot/core/lang.py +msg-d103bc8e = Namespace must not be empty. +msg-f66527da = Namespace must not contain '.'. +msg-b3665aee = Locale directory does not exist: {$base_dir} +msg-3fe89e6a = No locale directories found under: {$base_dir} +msg-c79b2c75 = Namespace '{$namespace}' already exists. Set replace=True to overwrite. +msg-7db3fccf = Default namespace cannot be unregistered. +msg-3d066f64 = Namespace '{$namespace}' is not registered. + +### astrbot/core/persona_mgr.py +msg-51a854e6 = 已加载 {$res} 个人格。 +msg-1ea88f45 = Persona with ID {$persona_id} does not exist. +msg-28104dff = Persona with ID {$persona_id} already exists. +msg-08ecfd42 = {$res} 人格情景预设对话格式不对,条数应该为偶数。 +msg-b6292b94 = 解析 Persona 配置失败:{$e} + +### astrbot/core/initial_loader.py +msg-78b9c276 = {$res} +msg-58525c23 = 😭 初始化 AstrBot 失败:{$e} !!! +msg-002cc3e8 = 🌈 正在关闭 AstrBot... + +### astrbot/core/log.py +msg-80a186b8 = Failed to add file sink: {$e} + +### astrbot/core/astrbot_config_mgr.py +msg-7875e5bd = Config file {$conf_path} for UUID {$uuid_} does not exist, skipping. +msg-39c4fd49 = 不能删除默认配置文件 +msg-cf7b8991 = 配置文件 {$conf_id} 不存在于映射中 +msg-2aad13a4 = 已删除配置文件: {$conf_path} +msg-94c359ef = 删除配置文件 {$conf_path} 失败: {$e} +msg-44f0b770 = 成功删除配置文件 {$conf_id} +msg-737da44e = 不能更新默认配置文件的信息 +msg-9d496709 = 成功更新配置文件 {$conf_id} 的信息 + +### astrbot/core/zip_updator.py +msg-24c90ff8 = 请求 {$url} 失败,状态码: {$res}, 内容: {$text} +msg-14726dd8 = 请求失败,状态码: {$res} +msg-fc3793c6 = 解析版本信息时发生异常: {$e} +msg-491135d9 = 解析版本信息失败 +msg-03a72cb5 = 未找到合适的发布版本 +msg-8bcbfcf0 = 正在下载更新 {$repo} ... +msg-ccc87294 = 正在从指定分支 {$branch} 下载 {$author}/{$repo} +msg-dfebcdc6 = 获取 {$author}/{$repo} 的 GitHub Releases 失败: {$e},将尝试下载默认分支 +msg-e327bc14 = 正在从默认分支下载 {$author}/{$repo} +msg-3cd3adfb = 检查到设置了镜像站,将使用镜像站下载 {$author}/{$repo} 仓库源码: {$release_url} +msg-1bffc0d7 = 无效的 GitHub URL +msg-0ba954db = 解压文件完成: {$zip_path} +msg-90ae0d15 = 删除临时更新文件: {$zip_path} 和 {$res} +msg-f8a43aa5 = 删除更新文件失败,可以手动删除 {$zip_path} 和 {$res} + +### astrbot/core/file_token_service.py +msg-0e444e51 = 文件不存在: {$local_path} (原始输入: {$file_path}) +msg-f61a5322 = 无效或过期的文件 token: {$file_token} +msg-73d3e179 = 文件不存在: {$file_path} + +### astrbot/core/subagent_orchestrator.py +msg-5d950986 = subagent_orchestrator.agents must be a list +msg-29e3b482 = SubAgent persona %s not found, fallback to inline prompt. +msg-f425c9f0 = Registered subagent handoff tool: {$res} + +### astrbot/core/astr_main_agent.py +msg-8dcf5caa = 未找到指定的提供商: %s。 +msg-61d46ee5 = 选择的提供商类型无效(%s),跳过 LLM 请求处理。 +msg-496864bc = Error occurred while selecting provider: %s +msg-507853eb = 无法创建新的对话。 +msg-66870b7e = Error occurred while retrieving knowledge base: %s +msg-36dc1409 = Moonshot AI API key for file extract is not set +msg-8534047e = Unsupported file extract provider: %s +msg-f2ea29f4 = Cannot get image caption because provider `{$provider_id}` is not exist. +msg-91a70615 = Cannot get image caption because provider `{$provider_id}` is not a valid Provider, it is {$res}. +msg-b1840df0 = Processing image caption with provider: %s +msg-089421fc = 处理图片描述失败: %s +msg-719d5e4d = No provider found for image captioning in quote. +msg-e16a974b = 处理引用图片失败: %s +msg-037dad2e = Group name display enabled but group object is None. Group ID: %s +msg-58b47bcd = 时区设置错误: %s, 使用本地时区 +msg-938af433 = Provider %s does not support image, using placeholder. +msg-83d739f8 = Provider %s does not support tool_use, clearing tools. +msg-3dbad2d9 = sanitize_context_by_modalities applied: removed_image_blocks=%s, removed_tool_messages=%s, removed_tool_calls=%s +msg-4214b760 = Generated chatui title for session %s: %s +msg-cb6db56e = Unsupported llm_safety_mode strategy: %s. +msg-7ea2c5d3 = Shipyard sandbox configuration is incomplete. +msg-9248b273 = 未找到指定的上下文压缩模型 %s,将跳过压缩。 +msg-16fe8ea5 = 指定的上下文压缩模型 %s 不是对话模型,将跳过压缩。 +msg-c6c9d989 = fallback_chat_models setting is not a list, skip fallback providers. +msg-614aebad = Fallback chat provider `%s` not found, skip. +msg-1a2e87dd = Fallback chat provider `%s` is invalid type: %s, skip. +msg-ee979399 = 未找到任何对话模型(提供商),跳过 LLM 请求处理。 +msg-7a7b4529 = Skip quoted fallback images due to limit=%d for umo=%s +msg-46bcda31 = Truncate quoted fallback images for umo=%s, reply_id=%s from %d to %d +msg-cbceb923 = Failed to resolve fallback quoted images for umo=%s, reply_id=%s: %s +msg-31483e80 = Error occurred while applying file extract: %s + +### astrbot/core/umop_config_router.py +msg-dedcfded = umop keys must be strings in the format [platform_id]:[message_type]:[session_id], with optional wildcards * or empty for all +msg-8e3a16f3 = umop must be a string in the format [platform_id]:[message_type]:[session_id], with optional wildcards * or empty for all + +### astrbot/core/event_bus.py +msg-da466871 = PipelineScheduler not found for id: {$res}, event ignored. +msg-7eccffa5 = [{$conf_name}] [{$res}({$res_2})] {$res_3}/{$res_4}: {$res_5} +msg-88bc26f2 = [{$conf_name}] [{$res}({$res_2})] {$res_3}: {$res_4} + +### astrbot/core/astr_agent_tool_exec.py +msg-e5f2fb34 = Background task {$task_id} failed: {$e} +msg-c54b2335 = Background handoff {$task_id} ({$res}) failed: {$e} +msg-8c2fe51d = Failed to build main agent for background task {$tool_name}. +msg-c6d4e4a6 = background task agent got no response +msg-0b3711f1 = Event must be provided for local function tools. +msg-8c19e27a = Tool must have a valid handler or override 'run' method. +msg-24053a5f = Tool 直接发送消息失败: {$e} +msg-f940b51e = tool {$res} execution timeout after {$res_2} seconds. +msg-7e22fc8e = 未知的方法名: {$method_name} +msg-c285315c = Tool execution ValueError: {$e} +msg-41366b74 = Tool handler parameter mismatch, please check the handler definition. Handler parameters: {$handler_param_str} +msg-e8cadf8e = Tool execution error: {$e}. Traceback: {$trace_} +msg-d7b4aa84 = Previous Error: {$trace_} + +### astrbot/core/astr_agent_run_util.py +msg-6b326889 = Agent reached max steps ({$max_step}), forcing a final response. +msg-bb15e9c7 = {$status_msg} +msg-78b9c276 = {$res} +msg-9c246298 = Error in on_agent_done hook +msg-34f164d4 = {$err_msg} +msg-6d9553b2 = [Live Agent] 使用流式 TTS(原生支持 get_audio_stream) +msg-becf71bf = [Live Agent] 使用 TTS({$res} 使用 get_audio,将按句子分块生成音频) +msg-21723afb = [Live Agent] 运行时发生错误: {$e} +msg-ca1bf0d7 = 发送 TTS 统计信息失败: {$e} +msg-5ace3d96 = [Live Agent Feeder] 分句: {$temp_buffer} +msg-bc1826ea = [Live Agent Feeder] Error: {$e} +msg-a92774c9 = [Live TTS Stream] Error: {$e} +msg-d7b3bbae = [Live TTS Simulated] Error processing text '{$res}...': {$e} +msg-035bca5f = [Live TTS Simulated] Critical Error: {$e} + +### astrbot/core/astr_main_agent_resources.py +msg-509829d8 = Downloaded file from sandbox: {$path} -> {$local_path} +msg-b462b60d = Failed to check/download file from sandbox: {$e} +msg-0b3144f1 = [知识库] 会话 {$umo} 已被配置为不使用知识库 +msg-97e13f98 = [知识库] 知识库不存在或未加载: {$kb_id} +msg-312d09c7 = [知识库] 会话 {$umo} 配置的以下知识库无效: {$invalid_kb_ids} +msg-42b0e9f8 = [知识库] 使用会话级配置,知识库数量: {$res} +msg-08167007 = [知识库] 使用全局配置,知识库数量: {$res} +msg-a00becc3 = [知识库] 开始检索知识库,数量: {$res}, top_k={$top_k} +msg-199e71b7 = [知识库] 为会话 {$umo} 注入了 {$res} 条相关知识块 + +### astrbot/core/conversation_mgr.py +msg-86f404dd = 会话删除回调执行失败 (session: {$unified_msg_origin}): {$e} +msg-57dcc41f = Conversation with id {$cid} not found + +### astrbot/core/updator.py +msg-e3d42a3b = 正在终止 {$res} 个子进程。 +msg-e7edc4a4 = 正在终止子进程 {$res} +msg-37bea42d = 子进程 {$res} 没有被正常终止, 正在强行杀死。 +msg-cc6d9588 = 重启失败({$executable}, {$e}),请尝试手动重启。 +msg-0e4439d8 = 不支持更新此方式启动的AstrBot +msg-3f39a942 = 当前已经是最新版本。 +msg-c7bdf215 = 未找到版本号为 {$version} 的更新文件。 +msg-92e46ecc = commit hash 长度不正确,应为 40 +msg-71c01b1c = 准备更新至指定版本的 AstrBot Core: {$version} +msg-d3a0e13d = 下载 AstrBot Core 更新文件完成,正在执行解压... + +### astrbot/core/core_lifecycle.py +msg-9967ec8b = Using proxy: {$proxy_config} +msg-5a29b73d = HTTP proxy cleared +msg-fafb87ce = Subagent orchestrator init failed: {$e} +msg-f7861f86 = AstrBot migration failed: {$e} +msg-78b9c276 = {$res} +msg-967606fd = ------- 任务 {$res} 发生错误: {$e} +msg-a2cd77f3 = | {$line} +msg-1f686eeb = ------- +msg-9556d279 = AstrBot 启动完成。 +msg-daaf690b = hook(on_astrbot_loaded) -> {$res} - {$res_2} +msg-4719cb33 = 插件 {$res} 未被正常终止 {$e}, 可能会导致资源泄露等问题。 +msg-c3bbfa1d = 任务 {$res} 发生错误: {$e} +msg-af06ccab = 配置文件 {$conf_id} 不存在 + +### astrbot/core/pipeline/context_utils.py +msg-49f260d3 = 处理函数参数不匹配,请检查 handler 的定义。 +msg-d7b4aa84 = Previous Error: {$trace_} +msg-eb8619cb = hook({$res}) -> {$res_2} - {$res_3} +msg-78b9c276 = {$res} +msg-add19f94 = {$res} - {$res_2} 终止了事件传播。 + +### astrbot/core/pipeline/__init__.py +msg-1c9fc93d = module {$__name__} has no attribute {$name} + +### astrbot/core/pipeline/scheduler.py +msg-c240d574 = 阶段 {$res} 已终止事件传播。 +msg-609a1ac5 = pipeline 执行完毕。 + +### astrbot/core/pipeline/rate_limit_check/stage.py +msg-18092978 = 会话 {$session_id} 被限流。根据限流策略,此会话处理将被暂停 {$stall_duration} 秒。 +msg-4962387a = 会话 {$session_id} 被限流。根据限流策略,此请求已被丢弃,直到限额于 {$stall_duration} 秒后重置。 + +### astrbot/core/pipeline/whitelist_check/stage.py +msg-8282c664 = 会话 ID {$res} 不在会话白名单中,已终止事件传播。请在配置文件中添加该会话 ID 到白名单。 + +### astrbot/core/pipeline/process_stage/follow_up.py +msg-df881b01 = Captured follow-up message for active agent run, umo=%s, order_seq=%s + +### astrbot/core/pipeline/process_stage/method/agent_request.py +msg-3267978a = 识别 LLM 聊天额外唤醒前缀 {$res} 以机器人唤醒前缀 {$bwp} 开头,已自动去除。 +msg-97a4d573 = This pipeline does not enable AI capability, skip processing. +msg-f1a11d2b = The session {$res} has disabled AI capability, skipping processing. + +### astrbot/core/pipeline/process_stage/method/star_request.py +msg-f0144031 = Cannot find plugin for given handler module path: {$res} +msg-1e8939dd = plugin -> {$res} - {$res_2} +msg-6be73b5e = {$traceback_text} +msg-d919bd27 = Star {$res} handle error: {$e} +msg-ed8dcc22 = {$ret} + +### astrbot/core/pipeline/process_stage/method/agent_sub_stages/internal.py +msg-60493581 = Unsupported tool_schema_mode: %s, fallback to skills_like +msg-9cdb2b6e = skip llm request: empty message and no provider_request +msg-e461e5af = ready to request llm provider +msg-be33dd11 = Follow-up ticket already consumed, stopping processing. umo=%s, seq=%s +msg-abd5ccbc = acquired session lock for llm request +msg-f9d617d7 = Provider API base %s is blocked due to security reasons. Please use another ai provider. +msg-3247374d = [Internal Agent] 检测到 Live Mode,启用 TTS 处理 +msg-dae92399 = [Live Mode] TTS Provider 未配置,将使用普通流式模式 +msg-1b1af61e = Error occurred while processing agent: {$e} +msg-ea02b899 = Error occurred while processing agent request: {$e} +msg-ee7e792b = LLM 响应为空,不保存记录。 + +### astrbot/core/pipeline/process_stage/method/agent_sub_stages/third_party.py +msg-5e551baf = Third party agent runner error: {$e} +msg-34f164d4 = {$err_msg} +msg-f9d76893 = 没有填写 Agent Runner 提供商 ID,请前往配置页面配置。 +msg-0f856470 = Agent Runner 提供商 {$res} 配置不存在,请前往配置页面修改配置。 +msg-b3f25c81 = Unsupported third party agent runner type: {$res} +msg-6c63eb68 = Agent Runner 未返回最终结果。 + +### astrbot/core/pipeline/result_decorate/stage.py +msg-7ec898fd = hook(on_decorating_result) -> {$res} - {$res_2} +msg-5e27dae6 = 启用流式输出时,依赖发送消息前事件钩子的插件可能无法正常工作 +msg-caaaec29 = hook(on_decorating_result) -> {$res} - {$res_2} 将消息结果清空。 +msg-78b9c276 = {$res} +msg-add19f94 = {$res} - {$res_2} 终止了事件传播。 +msg-813a44bb = 流式输出已启用,跳过结果装饰阶段 +msg-891aa43a = 分段回复正则表达式错误,使用默认分段方式: {$res} +msg-82bb9025 = 会话 {$res} 未配置文本转语音模型。 +msg-fb1c757a = TTS 请求: {$res} +msg-06341d25 = TTS 结果: {$audio_path} +msg-2057f670 = 由于 TTS 音频文件未找到,消息段转语音失败: {$res} +msg-f26725cf = 已注册:{$url} +msg-47716aec = TTS 失败,使用文本发送。 +msg-ffe054a9 = 文本转图片失败,使用文本发送。 +msg-06c1aedc = 文本转图片耗时超过了 3 秒,如果觉得很慢可以使用 /t2i 关闭文本转图片模式。 + +### astrbot/core/pipeline/waking_check/stage.py +msg-df815938 = enabled_plugins_name: {$enabled_plugins_name} +msg-51182733 = 插件 {$res}: {$e} +msg-e0dcf0b8 = 您(ID: {$res})的权限不足以使用此指令。通过 /sid 获取 ID 并请管理员添加。 +msg-a3c3706f = 触发 {$res} 时, 用户(ID={$res_2}) 权限不足。 + +### astrbot/core/pipeline/session_status_check/stage.py +msg-f9aba737 = 会话 {$res} 已被关闭,已终止事件传播。 + +### astrbot/core/pipeline/respond/stage.py +msg-59539c6e = 解析分段回复的间隔时间失败。{$e} +msg-4ddee754 = 分段回复间隔时间:{$res} +msg-5e2371a9 = Prepare to send - {$res}/{$res_2}: {$res_3} +msg-df92ac24 = async_stream 为空,跳过发送。 +msg-858b0e4f = 应用流式输出({$res}) +msg-22c7a672 = 消息为空,跳过发送阶段 +msg-e6ab7a25 = 空内容检查异常: {$e} +msg-b29b99c1 = 实际消息链为空, 跳过发送阶段。header_chain: {$header_comps}, actual_chain: {$res} +msg-842df577 = 发送消息链失败: chain = {$res}, error = {$e} +msg-f35465cf = 消息链全为 Reply 和 At 消息段, 跳过发送阶段。chain: {$res} +msg-784e8a67 = 发送消息链失败: chain = {$chain}, error = {$e} + +### astrbot/core/pipeline/content_safety_check/stage.py +msg-c733275f = 你的消息或者大模型的响应中包含不适当的内容,已被屏蔽。 +msg-46c80f28 = 内容安全检查不通过,原因:{$info} + +### astrbot/core/pipeline/content_safety_check/strategies/strategy.py +msg-27a700e0 = 使用百度内容审核应该先 pip install baidu-aip + +### astrbot/core/pipeline/preprocess_stage/stage.py +msg-7b9074fa = {$platform} 预回应表情发送失败: {$e} +msg-43f1b4ed = 路径映射: {$url} -> {$res} +msg-9549187d = 会话 {$res} 未配置语音转文本模型。 +msg-5bdf8f5c = {$e} +msg-ad90e19e = 重试中: {$res}/{$retry} +msg-78b9c276 = {$res} +msg-4f3245bf = 语音转文本失败: {$e} + +### astrbot/core/config/astrbot_config.py +msg-e0a69978 = 不受支持的配置类型 {$res}。支持的类型有:{$res_2} +msg-b9583fc9 = 检查到配置项 {$path_} 不存在,已插入默认值 {$value} +msg-ee26e40e = 检查到配置项 {$path_} 不存在,将从当前配置中删除 +msg-2d7497a5 = 检查到配置项 {$path} 的子项顺序不一致,已重新排序 +msg-5fdad937 = 检查到配置项顺序不一致,已重新排序 +msg-555373b0 = 没有找到 Key: '{$key}' + +### astrbot/core/platform/register.py +msg-eecf0aa8 = 平台适配器 {$adapter_name} 已经注册过了,可能发生了适配器命名冲突。 +msg-614a55eb = 平台适配器 {$adapter_name} 已注册 +msg-bb06a88d = 平台适配器 {$res} 已注销 (来自模块 {$res_2}) + +### astrbot/core/platform/platform.py +msg-30fc9871 = 平台 {$res} 未实现统一 Webhook 模式 + +### astrbot/core/platform/astr_message_event.py +msg-b593f13f = Failed to convert message type {$res} to MessageType. Falling back to FRIEND_MESSAGE. +msg-98bb33b7 = 清除 {$res} 的额外信息: {$res_2} +msg-0def44e2 = {$result} +msg-8e7dc862 = {$text} + +### astrbot/core/platform/manager.py +msg-464b7ab7 = 终止平台适配器失败: client_id=%s, error=%s +msg-78b9c276 = {$res} +msg-563a0a74 = 初始化 {$platform} 平台适配器失败: {$e} +msg-8432d24e = 平台 ID %r 包含非法字符 ':' 或 '!',已替换为 %r。 +msg-31361418 = 平台 ID {$platform_id} 不能为空,跳过加载该平台适配器。 +msg-e395bbcc = 载入 {$res}({$res_2}) 平台适配器 ... +msg-b4b29344 = 加载平台适配器 {$res} 失败,原因:{$e}。请检查依赖库是否安装。提示:可以在 管理面板->平台日志->安装Pip库 中安装依赖库。 +msg-18f0e1fe = 加载平台适配器 {$res} 失败,原因:{$e}。 +msg-2636a882 = 未找到适用于 {$res}({$res_2}) 平台适配器,请检查是否已经安装或者名称填写错误 +msg-c4a38b85 = hook(on_platform_loaded) -> {$res} - {$res_2} +msg-967606fd = ------- 任务 {$res} 发生错误: {$e} +msg-a2cd77f3 = | {$line} +msg-1f686eeb = ------- +msg-38723ea8 = 正在尝试终止 {$platform_id} 平台适配器 ... +msg-63f684c6 = 可能未完全移除 {$platform_id} 平台适配器 +msg-136a952f = 获取平台统计信息失败: {$e} + +### astrbot/core/platform/sources/dingtalk/dingtalk_adapter.py +msg-c81e728d = 2 +msg-d6371313 = dingtalk: {$res} +msg-a1c8b5b1 = 钉钉私聊会话缺少 staff_id 映射,回退使用 session_id 作为 userId 发送 +msg-2abb842f = 保存钉钉会话映射失败: {$e} +msg-46988861 = 下载钉钉文件失败: {$res}, {$res_2} +msg-ba9e1288 = 通过 dingtalk_stream 获取 access_token 失败: {$e} +msg-835b1ce6 = 获取钉钉机器人 access_token 失败: {$res}, {$res_2} +msg-331fcb1f = 读取钉钉 staff_id 映射失败: {$e} +msg-ba183a34 = 钉钉群消息发送失败: access_token 为空 +msg-b8aaa69b = 钉钉群消息发送失败: {$res}, {$res_2} +msg-cfb35bf5 = 钉钉私聊消息发送失败: access_token 为空 +msg-7553c219 = 钉钉私聊消息发送失败: {$res}, {$res_2} +msg-5ab2d58d = 清理临时文件失败: {$file_path}, {$e} +msg-c0c40912 = 钉钉语音转 OGG 失败,回退 AMR: {$e} +msg-21c73eca = 钉钉媒体上传失败: access_token 为空 +msg-24e3054f = 钉钉媒体上传失败: {$res}, {$res_2} +msg-34d0a11d = 钉钉媒体上传失败: {$data} +msg-3b0d4fb5 = 钉钉语音发送失败: {$e} +msg-7187f424 = 钉钉视频发送失败: {$e} +msg-e40cc45f = 钉钉私聊回复失败: 缺少 sender_staff_id +msg-be63618a = 钉钉适配器已被关闭 +msg-0ab22b13 = 钉钉机器人启动失败: {$e} + +### astrbot/core/platform/sources/dingtalk/dingtalk_event.py +msg-eaa1f3e4 = 钉钉消息发送失败: 缺少 adapter + +### astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_server.py +msg-41a3e59d = 正在登录到 QQ 官方机器人... +msg-66040e15 = 已登录 QQ 官方机器人账号: {$res} +msg-6ed59b60 = 收到 qq_official_webhook 回调: {$msg} +msg-ad355b59 = {$signed} +msg-1f6260e4 = _parser unknown event %s. +msg-cef08b17 = 将在 {$res}:{$res_2} 端口启动 QQ 官方机器人 webhook 适配器。 + +### astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_adapter.py +msg-3803e307 = [QQOfficialWebhook] No cached msg_id for session: %s, skip send_by_session +msg-08fd28cf = [QQOfficialWebhook] Unsupported message type for send_by_session: %s +msg-6fa95bb3 = Exception occurred during QQOfficialWebhook server shutdown: {$exc} +msg-6f83eea0 = QQ 机器人官方 API 适配器已经被优雅地关闭 + +### astrbot/core/platform/sources/discord/discord_platform_event.py +msg-0056366b = [Discord] 解析消息链时失败: {$e} +msg-fa0a9e40 = [Discord] 尝试发送空消息,已忽略。 +msg-5ccebf9a = [Discord] 频道 {$res} 不是可发送消息的类型 +msg-1550c1eb = [Discord] 发送消息时发生未知错误: {$e} +msg-7857133d = [Discord] 无法获取频道 {$res} +msg-050aa8d6 = [Discord] 开始处理 Image 组件: {$i} +msg-57c802ef = [Discord] Image 组件没有 file 属性: {$i} +msg-f2bea7ac = [Discord] 处理 URL 图片: {$file_content} +msg-c3eae1f1 = [Discord] 处理 File URI: {$file_content} +msg-6201da92 = [Discord] 图片文件不存在: {$path} +msg-2a6f0cd4 = [Discord] 处理 Base64 URI +msg-b589c643 = [Discord] 尝试作为裸 Base64 处理 +msg-41dd4b8f = [Discord] 裸 Base64 解码失败,作为本地路径处理: {$file_content} +msg-f59778a1 = [Discord] 处理图片时发生未知严重错误: {$file_info} +msg-85665612 = [Discord] 获取文件失败,路径不存在: {$file_path_str} +msg-e55956fb = [Discord] 获取文件失败: {$res} +msg-56cc0d48 = [Discord] 处理文件失败: {$res}, 错误: {$e} +msg-c0705d4e = [Discord] 忽略了不支持的消息组件: {$res} +msg-0417d127 = [Discord] 消息内容超过2000字符,将被截断。 +msg-6277510f = [Discord] 添加反应失败: {$e} + +### astrbot/core/platform/sources/discord/client.py +msg-940888cb = [Discord] 客户端未正确加载用户信息 (self.user is None) +msg-9a3c1925 = [Discord] 已作为 {$res} (ID: {$res_2}) 登录 +msg-30c1f1c8 = [Discord] 客户端已准备就绪。 +msg-d8c03bdf = [Discord] on_ready_once_callback 执行失败: {$e} +msg-c9601653 = Bot is not ready: self.user is None +msg-4b017a7c = Interaction received without a valid user +msg-3067bdce = [Discord] 收到原始消息 from {$res}: {$res_2} + +### astrbot/core/platform/sources/discord/discord_platform_adapter.py +msg-7ea23347 = [Discord] 客户端未就绪 (self.client.user is None),无法发送消息 +msg-ff6611ce = [Discord] Invalid channel ID format: {$channel_id_str} +msg-5e4e5d63 = [Discord] Can't get channel info for {$channel_id_str}, will guess message type. +msg-32d4751b = [Discord] 收到消息: {$message_data} +msg-8296c994 = [Discord] Bot Token 未配置。请在配置文件中正确设置 token。 +msg-170b31df = [Discord] 登录失败。请检查你的 Bot Token 是否正确。 +msg-6678fbd3 = [Discord] 与 Discord 的连接已关闭。 +msg-cd8c35d2 = [Discord] 适配器运行时发生意外错误: {$e} +msg-4df30f1d = [Discord] 客户端未就绪 (self.client.user is None),无法处理消息 +msg-f7803502 = [Discord] 收到非 Message 类型的消息: {$res},已忽略。 +msg-134e70e9 = [Discord] 正在终止适配器... (step 1: cancel polling task) +msg-5c01a092 = [Discord] polling_task 已取消。 +msg-77f8ca59 = [Discord] polling_task 取消异常: {$e} +msg-528b6618 = [Discord] 正在清理已注册的斜杠指令... (step 2) +msg-d0b832e6 = [Discord] 指令清理完成。 +msg-43383f5e = [Discord] 清理指令时发生错误: {$e} +msg-b960ed33 = [Discord] 正在关闭 Discord 客户端... (step 3) +msg-5e58f8a2 = [Discord] 客户端关闭异常: {$e} +msg-d1271bf1 = [Discord] 适配器已终止。 +msg-c374da7a = [Discord] 开始收集并注册斜杠指令... +msg-a6d37e4d = [Discord] 准备同步 {$res} 个指令: {$res_2} +msg-dbcaf095 = [Discord] 没有发现可注册的指令。 +msg-09209f2f = [Discord] 指令同步完成。 +msg-a95055fd = [Discord] 回调函数触发: {$cmd_name} +msg-55b13b1e = [Discord] 回调函数参数: {$ctx} +msg-79f72e4e = [Discord] 回调函数参数: {$params} +msg-22add467 = [Discord] 斜杠指令 '{$cmd_name}' 被触发。 原始参数: '{$params}'. 构建的指令字符串: '{$message_str_for_filter}' +msg-ccffc74a = [Discord] 指令 '{$cmd_name}' defer 失败: {$e} +msg-13402a28 = [Discord] 跳过不符合规范的指令: {$cmd_name} + +### astrbot/core/platform/sources/aiocqhttp/aiocqhttp_platform_adapter.py +msg-859d480d = Handle request message failed: {$e} +msg-6fb672e1 = Handle notice message failed: {$e} +msg-cf4687a3 = Handle group message failed: {$e} +msg-3a9853e3 = Handle private message failed: {$e} +msg-ec06dc3d = aiocqhttp(OneBot v11) 适配器已连接。 +msg-1304a54d = [aiocqhttp] RawMessage {$event} +msg-93cbb9fa = {$err} +msg-a4487a03 = 回复消息失败: {$e} +msg-48bc7bff = guessing lagrange +msg-6ab145a1 = 获取文件失败: {$ret} +msg-457454d7 = 获取文件失败: {$e},此消息段将被忽略。 +msg-7a299806 = 无法从回复消息数据构造 Event 对象: {$reply_event_data} +msg-e6633a51 = 获取引用消息失败: {$e}。 +msg-6e99cb8d = 获取 @ 用户信息失败: {$e},此消息段将被忽略。 +msg-cf15fd40 = 不支持的消息段类型,已忽略: {$t}, data={$res} +msg-45d126ad = 消息段解析失败: type={$t}, data={$res}. {$e} +msg-394a20ae = aiocqhttp: 未配置 ws_reverse_host 或 ws_reverse_port,将使用默认值:http://0.0.0.0:6199 +msg-7414707c = aiocqhttp 适配器已被关闭 + +### astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py +msg-0db8227d = 无法发送消息:缺少有效的数字 session_id({$session_id}) 或 event({$event}) + +### astrbot/core/platform/sources/lark/server.py +msg-2f3bccf1 = 未配置 encrypt_key,无法解密事件 +msg-e77104e2 = [Lark Webhook] 收到 challenge 验证请求: {$challenge} +msg-34b24fa1 = [Lark Webhook] 解析请求体失败: {$e} +msg-ec0fe13e = [Lark Webhook] 请求体为空 +msg-f69ebbdb = [Lark Webhook] 签名验证失败 +msg-7ece4036 = [Lark Webhook] 解密后的事件: {$event_data} +msg-f2cb4b46 = [Lark Webhook] 解密事件失败: {$e} +msg-ef9f8906 = [Lark Webhook] Verification Token 不匹配。 +msg-bedb2071 = [Lark Webhook] 处理事件回调失败: {$e} + +### astrbot/core/platform/sources/lark/lark_event.py +msg-eefbe737 = [Lark] API Client im 模块未初始化 +msg-a21f93fa = [Lark] 主动发送消息时,receive_id 和 receive_id_type 不能为空 +msg-f456e468 = [Lark] 发送飞书消息失败({$res}): {$res_2} +msg-1eb66d14 = [Lark] 文件不存在: {$path} +msg-1df39b24 = [Lark] API Client im 模块未初始化,无法上传文件 +msg-2ee721dd = [Lark] 无法上传文件({$res}): {$res_2} +msg-a04abf78 = [Lark] 上传文件成功但未返回数据(data is None) +msg-959e78a4 = [Lark] 文件上传成功: {$file_key} +msg-901a2f60 = [Lark] 无法打开或上传文件: {$e} +msg-13065327 = [Lark] 图片路径为空,无法上传 +msg-37245892 = [Lark] 无法打开图片文件: {$e} +msg-ad63bf53 = [Lark] API Client im 模块未初始化,无法上传图片 +msg-ef90038b = 无法上传飞书图片({$res}): {$res_2} +msg-d2065832 = [Lark] 上传图片成功但未返回数据(data is None) +msg-dbb635c2 = {$image_key} +msg-d4810504 = [Lark] 检测到文件组件,将单独发送 +msg-45556717 = [Lark] 检测到音频组件,将单独发送 +msg-959070b5 = [Lark] 检测到视频组件,将单独发送 +msg-4e2aa152 = 飞书 暂时不支持消息段: {$res} +msg-20d7c64b = [Lark] 无法获取音频文件路径: {$e} +msg-2f6f35e6 = [Lark] 音频文件不存在: {$original_audio_path} +msg-528b968d = [Lark] 音频格式转换失败,将尝试直接上传: {$e} +msg-fbc7efb9 = [Lark] 已删除转换后的音频文件: {$converted_audio_path} +msg-09840299 = [Lark] 删除转换后的音频文件失败: {$e} +msg-e073ff1c = [Lark] 无法获取视频文件路径: {$e} +msg-47e52913 = [Lark] 视频文件不存在: {$original_video_path} +msg-85ded1eb = [Lark] 视频格式转换失败,将尝试直接上传: {$e} +msg-b3bee05d = [Lark] 已删除转换后的视频文件: {$converted_video_path} +msg-775153f6 = [Lark] 删除转换后的视频文件失败: {$e} +msg-45038ba7 = [Lark] API Client im 模块未初始化,无法发送表情 +msg-8d475b01 = 发送飞书表情回应失败({$res}): {$res_2} + +### astrbot/core/platform/sources/lark/lark_adapter.py +msg-06ce76eb = 未设置飞书机器人名称,@ 机器人可能得不到回复。 +msg-eefbe737 = [Lark] API Client im 模块未初始化 +msg-236bcaad = [Lark] 下载消息资源失败 type={$resource_type}, key={$file_key}, code={$res}, msg={$res_2} +msg-ef9a61fe = [Lark] 消息资源响应中不包含文件流: {$file_key} +msg-7b69a8d4 = [Lark] 图片消息缺少 message_id +msg-59f1694d = [Lark] 富文本视频消息缺少 message_id +msg-af8f391d = [Lark] 文件消息缺少 message_id +msg-d4080b76 = [Lark] 文件消息缺少 file_key +msg-ab21318a = [Lark] 音频消息缺少 message_id +msg-9ec2c30a = [Lark] 音频消息缺少 file_key +msg-0fa9ed18 = [Lark] 视频消息缺少 message_id +msg-ae884c5c = [Lark] 视频消息缺少 file_key +msg-dac98a62 = [Lark] 获取引用消息失败 id={$parent_message_id}, code={$res}, msg={$res_2} +msg-7ee9f7dc = [Lark] 引用消息响应为空 id={$parent_message_id} +msg-2b3b2db9 = [Lark] 解析引用消息内容失败 id={$quoted_message_id} +msg-c5d54255 = [Lark] 收到空事件(event.event is None) +msg-82f041c4 = [Lark] 事件中没有消息体(message is None) +msg-206c3506 = [Lark] 消息内容为空 +msg-876aa1d2 = [Lark] 解析消息内容失败: {$res} +msg-514230f3 = [Lark] 消息内容不是 JSON Object: {$res} +msg-0898cf8b = [Lark] 解析消息内容: {$content_json_b} +msg-6a8bc661 = [Lark] 消息缺少 message_id +msg-26554571 = [Lark] 消息发送者信息不完整 +msg-007d863a = [Lark Webhook] 跳过重复事件: {$event_id} +msg-6ce17e71 = [Lark Webhook] 未处理的事件类型: {$event_type} +msg-8689a644 = [Lark Webhook] 处理事件失败: {$e} +msg-20688453 = [Lark] Webhook 模式已启用,但 webhook_server 未初始化 +msg-f46171bc = [Lark] Webhook 模式已启用,但未配置 webhook_uuid +msg-dd90a367 = 飞书(Lark) 适配器已关闭 + +### astrbot/core/platform/sources/wecom/wecom_event.py +msg-e164c137 = 未找到微信客服发送消息方法。 +msg-c114425e = 微信客服上传图片失败: {$e} +msg-a90bc15d = 微信客服上传图片返回: {$response} +msg-38298880 = 微信客服上传语音失败: {$e} +msg-3aee0caa = 微信客服上传语音返回: {$response} +msg-15e6381b = 删除临时音频文件失败: {$e} +msg-a79ae417 = 微信客服上传文件失败: {$e} +msg-374455ef = 微信客服上传文件返回: {$response} +msg-a2a133e4 = 微信客服上传视频失败: {$e} +msg-2732fffd = 微信客服上传视频返回: {$response} +msg-60815f02 = 还没实现这个消息类型的发送逻辑: {$res}。 +msg-9913aa52 = 企业微信上传图片失败: {$e} +msg-9e90ba91 = 企业微信上传图片返回: {$response} +msg-232af016 = 企业微信上传语音失败: {$e} +msg-e5b8829d = 企业微信上传语音返回: {$response} +msg-f68671d7 = 企业微信上传文件失败: {$e} +msg-8cdcc397 = 企业微信上传文件返回: {$response} +msg-4f3e15f5 = 企业微信上传视频失败: {$e} +msg-4e9aceea = 企业微信上传视频返回: {$response} + +### astrbot/core/platform/sources/wecom/wecom_adapter.py +msg-d4bbf9cb = 验证请求有效性: {$res} +msg-f8694a8a = 验证请求有效性成功。 +msg-8f4cda74 = 验证请求有效性失败,签名异常,请检查配置。 +msg-46d3feb9 = 解密失败,签名异常,请检查配置。 +msg-4d1dfce4 = 解析成功: {$msg} +msg-a98efa4b = 将在 {$res}:{$res_2} 端口启动 企业微信 适配器。 +msg-a616d9ce = 企业微信客服模式不支持 send_by_session 主动发送。 +msg-5d01d7b9 = send_by_session 失败:无法为会话 {$res} 推断 agent_id。 +msg-3f05613d = 获取到微信客服列表: {$acc_list} +msg-8fd19bd9 = 获取微信客服失败,open_kfid 为空。 +msg-5900d9b6 = Found open_kfid: {$open_kfid} +msg-391119b8 = 请打开以下链接,在微信扫码以获取客服微信: https://api.cl2wm.cn/api/qrcode/code?text={$kf_url} +msg-5bdf8f5c = {$e} +msg-93c9125e = 转换音频失败: {$e}。如果没有安装 ffmpeg 请先安装。 +msg-b2f7d1dc = 暂未实现的事件: {$res} +msg-61480a61 = abm: {$abm} +msg-42431e46 = 未实现的微信客服消息事件: {$msg} +msg-fbca491d = 企业微信 适配器已被关闭 + +### astrbot/core/platform/sources/weixin_official_account/weixin_offacc_event.py +msg-fa7f7afc = split plain into {$res} chunks for passive reply. Message not sent. +msg-59231e07 = 微信公众平台上传图片失败: {$e} +msg-d3968fc5 = 微信公众平台上传图片返回: {$response} +msg-7834b934 = 微信公众平台上传语音失败: {$e} +msg-4901d769 = 微信公众平台上传语音返回: {$response} +msg-15e6381b = 删除临时音频文件失败: {$e} +msg-60815f02 = 还没实现这个消息类型的发送逻辑: {$res}。 + +### astrbot/core/platform/sources/weixin_official_account/weixin_offacc_adapter.py +msg-d4bbf9cb = 验证请求有效性: {$res} +msg-b2edb1b2 = 未知的响应,请检查回调地址是否填写正确。 +msg-f8694a8a = 验证请求有效性成功。 +msg-8f4cda74 = 验证请求有效性失败,签名异常,请检查配置。 +msg-46d3feb9 = 解密失败,签名异常,请检查配置。 +msg-e23d8bff = 解析失败。msg为None。 +msg-4d1dfce4 = 解析成功: {$msg} +msg-193d9d7a = 用户消息缓冲状态: user={$from_user} state={$state} +msg-57a3c1b2 = wx buffer hit on trigger: user={$from_user} +msg-bed995d9 = wx buffer hit on retry window: user={$from_user} +msg-3a94b6ab = wx finished message sending in passive window: user={$from_user} msg_id={$msg_id} +msg-50c4b253 = wx finished message sending in passive window but not final: user={$from_user} msg_id={$msg_id} +msg-7d8b62e7 = wx finished in window but not final; return placeholder: user={$from_user} msg_id={$msg_id} +msg-2b9b8aed = wx task failed in passive window +msg-7bdf4941 = wx passive window timeout: user={$from_user} msg_id={$msg_id} +msg-98489949 = wx trigger while thinking: user={$from_user} +msg-01d0bbeb = wx new trigger: user={$from_user} msg_id={$msg_id} +msg-52bb36cd = wx start task: user={$from_user} msg_id={$msg_id} preview={$preview} +msg-ec9fd2ed = wx buffer hit immediately: user={$from_user} +msg-61c91fb9 = wx not finished in first window; return placeholder: user={$from_user} msg_id={$msg_id} +msg-35604bba = wx task failed in first window +msg-e56c4a28 = wx first window timeout: user={$from_user} msg_id={$msg_id} +msg-e163be40 = 将在 {$res}:{$res_2} 端口启动 微信公众平台 适配器。 +msg-c1740a04 = duplicate message id checked: {$res} +msg-04718b37 = Got future result: {$result} +msg-296e66c1 = callback 处理消息超时: message_id={$res} +msg-eb718c92 = 转换消息时出现异常: {$e} +msg-93c9125e = 转换音频失败: {$e}。如果没有安装 ffmpeg 请先安装。 +msg-b2f7d1dc = 暂未实现的事件: {$res} +msg-61480a61 = abm: {$abm} +msg-2e7e0187 = 用户消息未找到缓冲状态,无法处理消息: user={$res} message_id={$res_2} +msg-84312903 = 微信公众平台 适配器已被关闭 + +### astrbot/core/platform/sources/misskey/misskey_adapter.py +msg-7bacee77 = [Misskey] 配置不完整,无法启动 +msg-99cdf3d3 = [Misskey] 已连接用户: {$res} (ID: {$res_2}) +msg-5579c974 = [Misskey] 获取用户信息失败: {$e} +msg-d9547102 = [Misskey] API 客户端未初始化 +msg-341b0aa0 = [Misskey] WebSocket 已连接 (尝试 #{$connection_attempts}) +msg-c77d157b = [Misskey] 聊天频道已订阅 +msg-a0c5edc0 = [Misskey] WebSocket 连接失败 (尝试 #{$connection_attempts}) +msg-1958faa8 = [Misskey] WebSocket 异常 (尝试 #{$connection_attempts}): {$e} +msg-1b47382d = [Misskey] {$sleep_time}秒后重连 (下次尝试 #{$res}) +msg-a10a224d = [Misskey] 收到通知事件: type={$notification_type}, user_id={$res} +msg-7f0abf4a = [Misskey] 处理贴文提及: {$res}... +msg-2da7cdf5 = [Misskey] 处理通知失败: {$e} +msg-6c21d412 = [Misskey] 收到聊天事件: sender_id={$sender_id}, room_id={$room_id}, is_self={$res} +msg-68269731 = [Misskey] 检查群聊消息: '{$raw_text}', 机器人用户名: '{$res}' +msg-585aa62b = [Misskey] 处理群聊消息: {$res}... +msg-426c7874 = [Misskey] 处理私聊消息: {$res}... +msg-f5aff493 = [Misskey] 处理聊天消息失败: {$e} +msg-ea465183 = [Misskey] 收到未处理事件: type={$event_type}, channel={$res} +msg-8b69eb93 = [Misskey] 消息内容为空且无文件组件,跳过发送 +msg-9ba9c4e5 = [Misskey] 已清理临时文件: {$local_path} +msg-91af500e = [Misskey] 文件数量超过限制 ({$res} > {$MAX_FILE_UPLOAD_COUNT}),只上传前{$MAX_FILE_UPLOAD_COUNT}个文件 +msg-9746d7f5 = [Misskey] 并发上传过程中出现异常,继续发送文本 +msg-d6dc928c = [Misskey] 聊天消息只支持单个文件,忽略其余 {$res} 个文件 +msg-af584ae8 = [Misskey] 解析可见性: visibility={$visibility}, visible_user_ids={$visible_user_ids}, session_id={$session_id}, user_id_for_cache={$user_id_for_cache} +msg-1a176905 = [Misskey] 发送消息失败: {$e} + +### astrbot/core/platform/sources/misskey/misskey_api.py +msg-fab20f57 = aiohttp and websockets are required for Misskey API. Please install them with: pip install aiohttp websockets +msg-f2eea8e1 = [Misskey WebSocket] 已连接 +msg-5efd11a2 = [Misskey WebSocket] 重新订阅 {$channel_type} 失败: {$e} +msg-b70e2176 = [Misskey WebSocket] 连接失败: {$e} +msg-b9f3ee06 = [Misskey WebSocket] 连接已断开 +msg-7cd98e54 = WebSocket 未连接 +msg-43566304 = [Misskey WebSocket] 无法解析消息: {$e} +msg-e617e390 = [Misskey WebSocket] 处理消息失败: {$e} +msg-c60715cf = [Misskey WebSocket] 连接意外关闭: {$e} +msg-da9a2a17 = [Misskey WebSocket] 连接已关闭 (代码: {$res}, 原因: {$res_2}) +msg-bbf6a42e = [Misskey WebSocket] 握手失败: {$e} +msg-254f0237 = [Misskey WebSocket] 监听消息失败: {$e} +msg-49f7e90e = {$channel_summary} +msg-630a4832 = [Misskey WebSocket] 频道消息: {$channel_id}, 事件类型: {$event_type} +msg-0dc61a4d = [Misskey WebSocket] 使用处理器: {$handler_key} +msg-012666fc = [Misskey WebSocket] 使用事件处理器: {$event_type} +msg-e202168a = [Misskey WebSocket] 未找到处理器: {$handler_key} 或 {$event_type} +msg-a397eef1 = [Misskey WebSocket] 直接消息处理器: {$message_type} +msg-a5f12225 = [Misskey WebSocket] 未处理的消息类型: {$message_type} +msg-ad61d480 = [Misskey API] {$func_name} 重试 {$max_retries} 次后仍失败: {$e} +msg-7de2ca49 = [Misskey API] {$func_name} 第 {$attempt} 次重试失败: {$e},{$sleep_time}s后重试 +msg-f5aecf37 = [Misskey API] {$func_name} 遇到不可重试异常: {$e} +msg-e5852be5 = [Misskey API] 客户端已关闭 +msg-21fc185c = [Misskey API] 请求参数错误: {$endpoint} (HTTP {$status}) +msg-5b106def = Bad request for {$endpoint} +msg-28afff67 = [Misskey API] 未授权访问: {$endpoint} (HTTP {$status}) +msg-e12f2d28 = Unauthorized access for {$endpoint} +msg-beda662d = [Misskey API] 访问被禁止: {$endpoint} (HTTP {$status}) +msg-795ca227 = Forbidden access for {$endpoint} +msg-5c6ba873 = [Misskey API] 资源不存在: {$endpoint} (HTTP {$status}) +msg-74f2bac2 = Resource not found for {$endpoint} +msg-9ceafe4c = [Misskey API] 请求体过大: {$endpoint} (HTTP {$status}) +msg-3e336b73 = Request entity too large for {$endpoint} +msg-a47067de = [Misskey API] 请求频率限制: {$endpoint} (HTTP {$status}) +msg-901dc2da = Rate limit exceeded for {$endpoint} +msg-2bea8c2e = [Misskey API] 服务器内部错误: {$endpoint} (HTTP {$status}) +msg-ae8d3725 = Internal server error for {$endpoint} +msg-7b028462 = [Misskey API] 网关错误: {$endpoint} (HTTP {$status}) +msg-978414ef = Bad gateway for {$endpoint} +msg-50895a69 = [Misskey API] 服务不可用: {$endpoint} (HTTP {$status}) +msg-62adff89 = Service unavailable for {$endpoint} +msg-1cf15497 = [Misskey API] 网关超时: {$endpoint} (HTTP {$status}) +msg-a8a2578d = Gateway timeout for {$endpoint} +msg-c012110a = [Misskey API] 未知错误: {$endpoint} (HTTP {$status}) +msg-dc96bbb8 = HTTP {$status} for {$endpoint} +msg-4c7598b6 = [Misskey API] 获取到 {$res} 条新通知 +msg-851a2a54 = [Misskey API] 请求成功: {$endpoint} +msg-5f5609b6 = [Misskey API] 响应格式错误: {$e} +msg-c8f7bbeb = Invalid JSON response +msg-82748b31 = [Misskey API] 请求失败: {$endpoint} - HTTP {$res}, 响应: {$error_text} +msg-c6de3320 = [Misskey API] 请求失败: {$endpoint} - HTTP {$res} +msg-affb19a7 = [Misskey API] HTTP 请求错误: {$e} +msg-9f1286b3 = HTTP request failed: {$e} +msg-44f91be2 = [Misskey API] 发帖成功: {$note_id} +msg-fbafd3db = No file path provided for upload +msg-872d8419 = [Misskey API] 本地文件不存在: {$file_path} +msg-37186dea = File not found: {$file_path} +msg-65ef68e0 = [Misskey API] 本地文件上传成功: {$filename} -> {$file_id} +msg-0951db67 = [Misskey API] 文件上传网络错误: {$e} +msg-e3a322f5 = Upload failed: {$e} +msg-f28772b9 = No MD5 hash provided for find-by-hash +msg-25e566ef = [Misskey API] find-by-hash 请求: md5={$md5_hash} +msg-a036a942 = [Misskey API] find-by-hash 响应: 找到 {$res} 个文件 +msg-ea3581d5 = [Misskey API] 根据哈希查找文件失败: {$e} +msg-1d2a84ff = No name provided for find +msg-f25e28b4 = [Misskey API] find 请求: name={$name}, folder_id={$folder_id} +msg-cd43861a = [Misskey API] find 响应: 找到 {$res} 个文件 +msg-05cd55ef = [Misskey API] 根据名称查找文件失败: {$e} +msg-c01052a4 = [Misskey API] 列表文件请求: limit={$limit}, folder_id={$folder_id}, type={$type} +msg-7c81620d = [Misskey API] 列表文件响应: 找到 {$res} 个文件 +msg-a187a089 = [Misskey API] 列表文件失败: {$e} +msg-9e776259 = No existing session available +msg-de18c220 = URL不能为空 +msg-25b15b61 = [Misskey API] SSL 验证下载失败: {$ssl_error},重试不验证 SSL +msg-b6cbeef6 = [Misskey API] 本地上传成功: {$res} +msg-a4a898e2 = [Misskey API] 本地上传失败: {$e} +msg-46b7ea4b = [Misskey API] 聊天消息发送成功: {$message_id} +msg-32f71df4 = [Misskey API] 房间消息发送成功: {$message_id} +msg-7829f3b3 = [Misskey API] 聊天消息响应格式异常: {$res} +msg-d74c86a1 = [Misskey API] 提及通知响应格式异常: {$res} +msg-65ccb697 = 消息内容不能为空:需要文本或媒体文件 +msg-b6afb123 = [Misskey API] URL媒体上传成功: {$res} +msg-4e62bcdc = [Misskey API] URL媒体上传失败: {$url} +msg-71cc9d61 = [Misskey API] URL媒体处理失败 {$url}: {$e} +msg-75890c2b = [Misskey API] 本地文件上传成功: {$res} +msg-024d0ed5 = [Misskey API] 本地文件上传失败: {$file_path} +msg-f1fcb5e1 = [Misskey API] 本地文件处理失败 {$file_path}: {$e} +msg-1ee80a6b = 不支持的消息类型: {$message_type} + +### astrbot/core/platform/sources/misskey/misskey_event.py +msg-85cb7d49 = [MisskeyEvent] send 方法被调用,消息链包含 {$res} 个组件 +msg-252c2fca = [MisskeyEvent] 检查适配器方法: hasattr(self.client, 'send_by_session') = {$res} +msg-44d7a060 = [MisskeyEvent] 调用适配器的 send_by_session 方法 +msg-b6e08872 = [MisskeyEvent] 内容为空,跳过发送 +msg-8cfebc9c = [MisskeyEvent] 创建新帖子 +msg-ed0d2ed5 = [MisskeyEvent] 发送失败: {$e} + +### astrbot/core/platform/sources/wecom_ai_bot/wecomai_webhook.py +msg-a5c90267 = 消息推送 webhook URL 不能为空 +msg-76bfb25b = 消息推送 webhook URL 缺少 key 参数 +msg-3545eb07 = Webhook 请求失败: HTTP {$res}, {$text} +msg-758dfe0d = Webhook 返回错误: {$res} {$res_2} +msg-c056646b = 企业微信消息推送成功: %s +msg-73d3e179 = 文件不存在: {$file_path} +msg-774a1821 = 上传媒体失败: HTTP {$res}, {$text} +msg-6ff016a4 = 上传媒体失败: {$res} {$res_2} +msg-0e8252d1 = 上传媒体失败: 返回缺少 media_id +msg-9dbc2296 = 文件消息缺少有效文件路径,已跳过: %s +msg-2e567c36 = 清理临时语音文件失败 %s: %s +msg-e99c4df9 = 企业微信消息推送暂不支持组件类型 %s,已跳过 + +### astrbot/core/platform/sources/wecom_ai_bot/WXBizJsonMsgCrypt.py +msg-5bdf8f5c = {$e} +msg-fe69e232 = receiveid not match +msg-00b71c27 = signature not match +msg-5cfb5c20 = {$signature} + +### astrbot/core/platform/sources/wecom_ai_bot/wecomai_event.py +msg-e44e77b0 = 图片数据为空,跳过 +msg-30d116ed = 处理图片消息失败: %s +msg-31b11295 = [WecomAI] 不支持的消息组件类型: {$res}, 跳过 + +### astrbot/core/platform/sources/wecom_ai_bot/wecomai_adapter.py +msg-277cdd37 = 企业微信消息推送 webhook 配置无效: %s +msg-2102fede = 处理队列消息时发生异常: {$e} +msg-d4ea688d = 消息类型未知,忽略: {$message_data} +msg-15ba426f = 处理消息时发生异常: %s +msg-740911ab = Stream already finished, returning end message: {$stream_id} +msg-9fdbafe9 = Cannot find back queue for stream_id: {$stream_id} +msg-7a52ca2b = No new messages in back queue for stream_id: {$stream_id} +msg-9ffb59fb = Aggregated content: {$latest_plain_content}, image: {$res}, finish: {$finish} +msg-de9ff585 = Stream message sent successfully, stream_id: {$stream_id} +msg-558310b9 = 消息加密失败 +msg-251652f9 = 处理欢迎消息时发生异常: %s +msg-480c5dac = [WecomAI] 消息已入队: {$stream_id} +msg-f595dd6e = 处理加密图片失败: {$result} +msg-e8beeb3d = WecomAIAdapter: {$res} +msg-6f8ad811 = 主动消息发送失败: 未配置企业微信消息推送 Webhook URL,请前往配置添加。session_id=%s +msg-84439b09 = 企业微信消息推送失败(session=%s): %s +msg-f70f5008 = 启动企业微信智能机器人适配器,监听 %s:%d +msg-87616945 = 企业微信智能机器人适配器正在关闭... + +### astrbot/core/platform/sources/wecom_ai_bot/wecomai_api.py +msg-86f6ae9f = 消息解密失败,错误码: {$ret} +msg-45ad825c = 解密成功,消息内容: {$message_data} +msg-84c476a7 = JSON 解析失败: {$e}, 原始消息: {$decrypted_msg} +msg-c0d8c5f9 = 解密消息为空 +msg-a08bcfc7 = 解密过程发生异常: {$e} +msg-4dfaa613 = 消息加密失败,错误码: {$ret} +msg-6e566b12 = 消息加密成功 +msg-39bf8dba = 加密过程发生异常: {$e} +msg-fa5be7c5 = URL 验证失败,错误码: {$ret} +msg-813a4e4e = URL 验证成功 +msg-65ce0d23 = URL 验证发生异常: {$e} +msg-b1aa892f = 开始下载加密图片: {$image_url} +msg-10f72727 = {$error_msg} +msg-70123a82 = 图片下载成功,大小: {$res} 字节 +msg-85d2dba1 = AES 密钥不能为空 +msg-67c4fcea = 无效的 AES 密钥长度: 应为 32 字节 +msg-bde4bb57 = 无效的填充长度 (大于32字节) +msg-63c22912 = 图片解密成功,解密后大小: {$res} 字节 +msg-6ea489f0 = 文本消息解析失败 +msg-eb12d147 = 图片消息解析失败 +msg-ab1157ff = 流消息解析失败 +msg-e7e945d1 = 混合消息解析失败 +msg-06ada9dd = 事件消息解析失败 + +### astrbot/core/platform/sources/wecom_ai_bot/wecomai_server.py +msg-adaee66c = URL 验证参数缺失 +msg-742e0b43 = 收到企业微信智能机器人 WebHook URL 验证请求。 +msg-f86c030c = 消息回调参数缺失 +msg-cce4e44c = 收到消息回调,msg_signature={$msg_signature}, timestamp={$timestamp}, nonce={$nonce} +msg-7f018a3c = 消息解密失败,错误码: %d +msg-9d42e548 = 消息处理器执行异常: %s +msg-15ba426f = 处理消息时发生异常: %s +msg-5bf7dffa = 启动企业微信智能机器人服务器,监听 %s:%d +msg-445921d5 = 服务器运行异常: %s +msg-3269840c = 企业微信智能机器人服务器正在关闭... + +### astrbot/core/platform/sources/wecom_ai_bot/wecomai_queue_mgr.py +msg-8be03d44 = [WecomAI] 创建输入队列: {$session_id} +msg-9804296a = [WecomAI] 创建输出队列: {$session_id} +msg-bdf0fb78 = [WecomAI] 移除输出队列: {$session_id} +msg-40f6bb7b = [WecomAI] 移除待处理响应: {$session_id} +msg-fbb807cd = [WecomAI] 标记流已结束: {$session_id} +msg-9d7f5627 = [WecomAI] 移除输入队列: {$session_id} +msg-7637ed00 = [WecomAI] 设置待处理响应: {$session_id} +msg-5329c49b = [WecomAI] 清理过期响应及队列: {$session_id} +msg-09f098ea = [WecomAI] 为会话启动监听器: {$session_id} +msg-c55856d6 = 处理会话 {$session_id} 消息时发生错误: {$e} + +### astrbot/core/platform/sources/wecom_ai_bot/wecomai_utils.py +msg-14d01778 = JSON 解析失败: {$e}, 原始字符串: {$json_str} +msg-df346cf5 = 开始下载加密图片: %s +msg-cb266fb3 = 图片下载成功,大小: %d 字节 +msg-10f72727 = {$error_msg} +msg-1d91d2bb = AES密钥不能为空 +msg-bb32bedd = 无效的AES密钥长度: 应为32字节 +msg-bde4bb57 = 无效的填充长度 (大于32字节) +msg-3cf2120e = 图片解密成功,解密后大小: %d 字节 +msg-3f8ca8aa = 图片已转换为base64编码,编码后长度: %d + +### astrbot/core/platform/sources/line/line_api.py +msg-06e3f874 = [LINE] %s message failed: status=%s body=%s +msg-1478c917 = [LINE] %s message request failed: %s +msg-39941f06 = [LINE] get content retry failed: message_id=%s status=%s body=%s +msg-1fe70511 = [LINE] get content failed: message_id=%s status=%s body=%s + +### astrbot/core/platform/sources/line/line_event.py +msg-4068a191 = [LINE] resolve image url failed: %s +msg-2233b256 = [LINE] resolve record url failed: %s +msg-a7455817 = [LINE] resolve record duration failed: %s +msg-9d0fee66 = [LINE] resolve video url failed: %s +msg-3b8ea946 = [LINE] resolve video cover failed: %s +msg-aea2081a = [LINE] generate video preview failed: %s +msg-af426b7e = [LINE] resolve file url failed: %s +msg-fe44c12d = [LINE] resolve file size failed: %s +msg-d6443173 = [LINE] message count exceeds 5, extra segments will be dropped. + +### astrbot/core/platform/sources/line/line_adapter.py +msg-68539775 = LINE 适配器需要 channel_access_token 和 channel_secret。 +msg-30c67081 = [LINE] webhook_uuid 为空,统一 Webhook 可能无法接收消息。 +msg-64e92929 = [LINE] invalid webhook signature +msg-71bc0b77 = [LINE] invalid webhook body: %s +msg-8c7d9bab = [LINE] duplicate event skipped: %s + +### astrbot/core/platform/sources/telegram/tg_event.py +msg-7757f090 = [Telegram] 发送 chat action 失败: {$e} +msg-80b075a3 = User privacy settings prevent receiving voice messages, falling back to sending an audio file. To enable voice messages, go to Telegram Settings → Privacy and Security → Voice Messages → set to 'Everyone'. +msg-20665ad1 = MarkdownV2 send failed: {$e}. Using plain text instead. +msg-323cb67c = [Telegram] 添加反应失败: {$e} +msg-abe7fc3d = 编辑消息失败(streaming-break): {$e} +msg-f7d40103 = 不支持的消息类型: {$res} +msg-d4b50a96 = 编辑消息失败(streaming): {$e} +msg-2701a78f = 发送消息失败(streaming): {$e} +msg-2a8ecebd = Markdown转换失败,使用普通文本: {$e} + +### astrbot/core/platform/sources/telegram/tg_adapter.py +msg-cb53f79a = Telegram base url: {$res} +msg-e6b6040f = Telegram Updater is not initialized. Cannot start polling. +msg-2c4b186e = Telegram Platform Adapter is running. +msg-908d0414 = 向 Telegram 注册指令时发生错误: {$e} +msg-d2dfe45e = 命令名 '{$cmd_name}' 重复注册,将使用首次注册的定义: '{$res}' +msg-63bdfab8 = Received a start command without an effective chat, skipping /start reply. +msg-03a27b01 = Telegram message: {$res} +msg-e47b4bb4 = Received an update without a message. +msg-c97401c6 = [Telegram] Received a message without a from_user. +msg-f5c839ee = Telegram document file_path is None, cannot save the file {$file_name}. +msg-dca991a9 = Telegram video file_path is None, cannot save the file {$file_name}. +msg-56fb2950 = Create media group cache: {$media_group_id} +msg-0de2d4b5 = Add message to media group {$media_group_id}, currently has {$res} items. +msg-9e5069e9 = Media group {$media_group_id} has reached max wait time ({$elapsed}s >= {$res}s), processing immediately. +msg-9156b9d6 = Scheduled media group {$media_group_id} to be processed in {$delay} seconds (already waited {$elapsed}s) +msg-2849c882 = Media group {$media_group_id} not found in cache +msg-c75b2163 = Media group {$media_group_id} is empty +msg-0a3626c1 = Processing media group {$media_group_id}, total {$res} items +msg-2842e389 = Failed to convert the first message of media group {$media_group_id} +msg-32fbf7c1 = Added {$res} components to media group {$media_group_id} +msg-23bae28a = Telegram adapter has been closed. +msg-e46e7740 = Error occurred while closing Telegram adapter: {$e} + +### astrbot/core/platform/sources/slack/client.py +msg-1d6b68b9 = Slack request signature verification failed +msg-53ef18c3 = Received Slack event: {$event_data} +msg-58488af6 = 处理 Slack 事件时出错: {$e} +msg-477be979 = Slack Webhook 服务器启动中,监听 {$res}:{$res_2}{$res_3}... +msg-639fee6c = Slack Webhook 服务器已停止 +msg-a238d798 = Socket client is not initialized +msg-4e6de580 = 处理 Socket Mode 事件时出错: {$e} +msg-5bb71de9 = Slack Socket Mode 客户端启动中... +msg-f79ed37f = Slack Socket Mode 客户端已停止 + +### astrbot/core/platform/sources/slack/slack_adapter.py +msg-c34657ff = Slack bot_token 是必需的 +msg-64f8a45d = Socket Mode 需要 app_token +msg-a2aba1a7 = Webhook Mode 需要 signing_secret +msg-40e00bd4 = Slack 发送消息失败: {$e} +msg-56c1d0a3 = [slack] RawMessage {$event} +msg-855510b4 = Failed to download slack file: {$res} {$res_2} +msg-04ab2fae = 下载文件失败: {$res} +msg-79ed7e65 = Slack auth test OK. Bot ID: {$res} +msg-ec27746a = Slack 适配器 (Socket Mode) 启动中... +msg-34222d3a = Slack 适配器 (Webhook Mode) 启动中,监听 {$res}:{$res_2}{$res_3}... +msg-6d8110d2 = 不支持的连接模式: {$res},请使用 'socket' 或 'webhook' +msg-d71e7f36 = Slack 适配器已被关闭 + +### astrbot/core/platform/sources/slack/slack_event.py +msg-b233107c = Slack file upload failed: {$res} +msg-596945d1 = Slack file upload response: {$response} + +### astrbot/core/platform/sources/satori/satori_adapter.py +msg-ab7db6d9 = Satori WebSocket 连接关闭: {$e} +msg-4ef42cd1 = Satori WebSocket 连接失败: {$e} +msg-b50d159b = 达到最大重试次数 ({$max_retries}),停止重试 +msg-89de477c = Satori 适配器正在连接到 WebSocket: {$res} +msg-cfa5b059 = Satori 适配器 HTTP API 地址: {$res} +msg-d534864b = 无效的WebSocket URL: {$res} +msg-a110f9f7 = WebSocket URL必须以ws://或wss://开头: {$res} +msg-bf43ccb6 = Satori 处理消息异常: {$e} +msg-89081a1a = Satori WebSocket 连接异常: {$e} +msg-5c04bfcd = Satori WebSocket 关闭异常: {$e} +msg-b67bcee0 = WebSocket连接未建立 +msg-89ea8b76 = WebSocket连接已关闭 +msg-4c8a40e3 = 发送 IDENTIFY 信令时连接关闭: {$e} +msg-05a6b99d = 发送 IDENTIFY 信令失败: {$e} +msg-c9b1b774 = Satori WebSocket 发送心跳失败: {$e} +msg-61edb4f3 = 心跳任务异常: {$e} +msg-7db44899 = Satori 连接成功 - Bot {$res}: platform={$platform}, user_id={$user_id}, user_name={$user_name} +msg-01564612 = 解析 WebSocket 消息失败: {$e}, 消息内容: {$message} +msg-3a1657ea = 处理 WebSocket 消息异常: {$e} +msg-dc6b459c = 处理事件失败: {$e} +msg-6524f582 = 解析标签时发生错误: {$e}, 错误内容: {$content} +msg-3be535c3 = 转换 Satori 消息失败: {$e} +msg-be17caf1 = XML解析失败,使用正则提取: {$e} +msg-f6f41d74 = 提取标签时发生错误: {$e} +msg-ca6dca7f = 转换引用消息失败: {$e} +msg-cd3b067e = 解析 Satori 元素时发生解析错误: {$e}, 错误内容: {$content} +msg-03071274 = 解析 Satori 元素时发生未知错误: {$e} +msg-775cd5c0 = HTTP session 未初始化 +msg-e354c8d1 = Satori HTTP 请求异常: {$e} + +### astrbot/core/platform/sources/satori/satori_event.py +msg-c063ab8a = Satori 消息发送异常: {$e} +msg-9bc42a8d = Satori 消息发送失败 +msg-dbf77ca2 = 图片转换为base64失败: {$e} +msg-8b6100fb = Satori 流式消息发送异常: {$e} +msg-3c16c45c = 语音转换为base64失败: {$e} +msg-66994127 = 视频文件转换失败: {$e} +msg-30943570 = 转换消息组件失败: {$e} +msg-3e8181fc = 转换转发节点失败: {$e} +msg-d626f831 = 转换合并转发消息失败: {$e} + +### astrbot/core/platform/sources/webchat/webchat_queue_mgr.py +msg-4af4f885 = Started listener for conversation: {$conversation_id} +msg-10237240 = Error processing message from conversation {$conversation_id}: {$e} + +### astrbot/core/platform/sources/webchat/webchat_adapter.py +msg-9406158c = WebChatAdapter: {$res} + +### astrbot/core/platform/sources/webchat/webchat_event.py +msg-6b37adcd = webchat 忽略: {$res} + +### astrbot/core/platform/sources/qqofficial/qqofficial_platform_adapter.py +msg-8af45ba1 = QQ 机器人官方 API 适配器不支持 send_by_session +msg-8ebd1249 = Unknown message type: {$message_type} +msg-c165744d = QQ 官方机器人接口 适配器已被优雅地关闭 + +### astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py +msg-28a74d9d = [QQOfficial] Skip botpy FormData patch. +msg-c0b123f6 = 发送流式消息时出错: {$e} +msg-05d6bba5 = [QQOfficial] 不支持的消息源类型: {$res} +msg-e5339577 = [QQOfficial] GroupMessage 缺少 group_openid +msg-71275806 = Message sent to C2C: {$ret} +msg-040e7942 = [QQOfficial] markdown 发送被拒绝,回退到 content 模式重试。 +msg-9000f8f7 = Invalid upload parameters +msg-d72cffe7 = Failed to upload image, response is not dict: {$result} +msg-5944a27c = 上传文件响应格式错误: {$result} +msg-1e513ee5 = 上传请求错误: {$e} +msg-f1f1733c = Failed to post c2c message, response is not dict: {$result} +msg-9b8f9f70 = Unsupported image file format +msg-24eb302a = 转换音频格式时出错:音频时长不大于0 +msg-b49e55f9 = 处理语音时出错: {$e} +msg-6e716579 = qq_official 忽略 {$res} + +### astrbot/core/provider/provider.py +msg-e6f0c96f = Provider type {$provider_type_name} not registered +msg-c7953e3f = 批次 {$batch_idx} 处理失败,已重试 {$max_retries} 次: {$e} +msg-10f72727 = {$error_msg} +msg-7ff71721 = Rerank provider test failed, no results returned + +### astrbot/core/provider/register.py +msg-19ddffc0 = 检测到大模型提供商适配器 {$provider_type_name} 已经注册,可能发生了大模型提供商适配器类型命名冲突。 +msg-7e134b0d = 服务提供商 Provider {$provider_type_name} 已注册 + +### astrbot/core/provider/func_tool_manager.py +msg-0c42a4d9 = 添加函数调用工具: {$name} +msg-e8fdbb8c = 未找到 MCP 服务配置文件,已创建默认配置文件 {$mcp_json_file} +msg-cf8aed84 = 收到 MCP 客户端 {$name} 终止信号 +msg-3d7bcc64 = 初始化 MCP 客户端 {$name} 失败 +msg-1b190842 = MCP server {$name} list tools response: {$tools_res} +msg-6dc4f652 = 已连接 MCP 服务 {$name}, Tools: {$tool_names} +msg-a44aa4f2 = 清空 MCP 客户端资源 {$name}: {$e}。 +msg-e9c96c53 = 已关闭 MCP 服务 {$name} +msg-10f72727 = {$error_msg} +msg-85f156e0 = testing MCP server connection with config: {$config} +msg-93c54ce0 = Cleaning up MCP client after testing connection. +msg-368450ee = 此函数调用工具所属的插件 {$res} 已被禁用,请先在管理面板启用再激活此工具。 +msg-4ffa2135 = 加载 MCP 配置失败: {$e} +msg-a486ac39 = 保存 MCP 配置失败: {$e} +msg-58dfdfe7 = 从 ModelScope 同步了 {$synced_count} 个 MCP 服务器 +msg-75f1222f = 没有找到可用的 ModelScope MCP 服务器 +msg-c9f6cb1d = ModelScope API 请求失败: HTTP {$res} +msg-c8ebb4f7 = 网络连接错误: {$e} +msg-0ac6970f = 同步 ModelScope MCP 服务器时发生错误: {$e} + +### astrbot/core/provider/entities.py +msg-7fc6f623 = 图片 {$image_url} 得到的结果为空,将忽略。 + +### astrbot/core/provider/manager.py +msg-9e1a7f1f = 提供商 {$provider_id} 不存在,无法设置。 +msg-5fda2049 = Unknown provider type: {$provider_type} +msg-a5cb19c6 = 没有找到 ID 为 {$provider_id} 的提供商,这可能是由于您修改了提供商(模型)ID 导致的。 +msg-78b9c276 = {$res} +msg-5bdf8f5c = {$e} +msg-b734a1f4 = Provider {$provider_id} 配置项 key[{$idx}] 使用环境变量 {$env_key} 但未设置。 +msg-664b3329 = Provider {$res} is disabled, skipping +msg-f43f8022 = 载入 {$res}({$res_2}) 服务提供商 ... +msg-edd4aefe = 加载 {$res}({$res_2}) 提供商适配器失败:{$e}。可能是因为有未安装的依赖。 +msg-78e514a1 = 加载 {$res}({$res_2}) 提供商适配器失败:{$e}。未知原因 +msg-4636f83c = 未找到适用于 {$res}({$res_2}) 的提供商适配器,请检查是否已经安装或者名称填写错误。已跳过。 +msg-e9c6c4a2 = 无法找到 {$res} 的类 +msg-f705cf50 = Provider class {$cls_type} is not a subclass of STTProvider +msg-d20620aa = 已选择 {$res}({$res_2}) 作为当前语音转文本提供商适配器。 +msg-afbe5661 = Provider class {$cls_type} is not a subclass of TTSProvider +msg-74d437ed = 已选择 {$res}({$res_2}) 作为当前文本转语音提供商适配器。 +msg-08cd85c9 = Provider class {$cls_type} is not a subclass of Provider +msg-16a2b8e0 = 已选择 {$res}({$res_2}) 作为当前提供商适配器。 +msg-0e1707e7 = Provider class {$cls_type} is not a subclass of EmbeddingProvider +msg-821d06e0 = Provider class {$cls_type} is not a subclass of RerankProvider +msg-14c35664 = 未知的提供商类型:{$res} +msg-186fd5c6 = 实例化 {$res}({$res_2}) 提供商适配器失败:{$e} +msg-ede02a99 = providers in user's config: {$config_ids} +msg-95dc4227 = 自动选择 {$res} 作为当前提供商适配器。 +msg-a6187bac = 自动选择 {$res} 作为当前语音转文本提供商适配器。 +msg-bf28f7e2 = 自动选择 {$res} 作为当前文本转语音提供商适配器。 +msg-dba10c27 = 终止 {$provider_id} 提供商适配器({$res}, {$res_2}, {$res_3}) ... +msg-9d9d9765 = {$provider_id} 提供商适配器已终止({$res}, {$res_2}, {$res_3}) +msg-925bb70a = Provider {$target_prov_ids} 已从配置中删除。 +msg-a1657092 = New provider config must have an 'id' field +msg-1486c653 = Provider ID {$npid} already exists +msg-f9fc1545 = Provider ID {$origin_provider_id} not found +msg-4e2c657c = Error while disabling MCP servers + +### astrbot/core/provider/sources/gemini_embedding_source.py +msg-173efb0e = [Gemini Embedding] 使用代理: {$proxy} +msg-58a99789 = Gemini Embedding API请求失败: {$res} +msg-5c4ea38e = Gemini Embedding API批量请求失败: {$res} + +### astrbot/core/provider/sources/bailian_rerank_source.py +msg-dc1a9e6e = 阿里云百炼 API Key 不能为空。 +msg-f7079f37 = AstrBot 百炼 Rerank 初始化完成。模型: {$res} +msg-5b6d35ce = 百炼 API 错误: {$res} – {$res_2} +msg-d600c5e2 = 百炼 Rerank 返回空结果: {$data} +msg-d3312319 = 结果 {$idx} 缺少 relevance_score,使用默认值 0.0 +msg-2855fb44 = 解析结果 {$idx} 时出错: {$e}, result={$result} +msg-392f26e8 = 百炼 Rerank 消耗 Token: {$tokens} +msg-595e0cf9 = 百炼 Rerank 客户端会话已关闭,返回空结果 +msg-d0388210 = 文档列表为空,返回空结果 +msg-44d6cc76 = 查询文本为空,返回空结果 +msg-bd8b942a = 文档数量({$res})超过限制(500),将截断前500个文档 +msg-0dc3bca4 = 百炼 Rerank 请求: query='{$res}...', 文档数量={$res_2} +msg-4a9f4ee3 = 百炼 Rerank 成功返回 {$res} 个结果 +msg-fa301307 = 百炼 Rerank 网络请求失败: {$e} +msg-10f72727 = {$error_msg} +msg-9879e226 = 百炼 Rerank 处理失败: {$e} +msg-4f15074c = 关闭 百炼 Rerank 客户端会话 +msg-d01b1b0f = 关闭 百炼 Rerank 客户端时出错: {$e} + +### astrbot/core/provider/sources/edge_tts_source.py +msg-f4ab0713 = pyffmpeg 转换失败: {$e}, 尝试使用 ffmpeg 命令行进行转换 +msg-ddc3594a = [EdgeTTS] FFmpeg 标准输出: {$res} +msg-1b8c0a83 = FFmpeg错误输出: {$res} +msg-1e980a68 = [EdgeTTS] 返回值(0代表成功): {$res} +msg-c39d210c = 生成的WAV文件不存在或为空 +msg-57f60837 = FFmpeg 转换失败: {$res} +msg-ca94a42a = FFmpeg 转换失败: {$e} +msg-be660d63 = 音频生成失败: {$e} + +### astrbot/core/provider/sources/whisper_api_source.py +msg-28cbbf07 = 文件不存在: {$audio_url} +msg-b335b8db = Converting silk file to wav using tencent_silk_to_wav... +msg-68b5660f = Converting amr file to wav using convert_to_pcm_wav... +msg-cad3735e = Failed to remove temp file {$audio_url}: {$e} + +### astrbot/core/provider/sources/gemini_source.py +msg-1474947f = [Gemini] 使用代理: {$proxy} +msg-e2a81024 = 检测到 Key 异常({$res}),正在尝试更换 API Key 重试... 当前 Key: {$res_2}... +msg-0d388dae = 检测到 Key 异常({$res}),且已没有可用的 Key。 当前 Key: {$res_2}... +msg-1465290c = 达到了 Gemini 速率限制, 请稍后再试... +msg-7e9c01ca = 流式输出不支持图片模态,已自动降级为文本模态 +msg-89bac423 = 代码执行工具与搜索工具互斥,已忽略搜索工具 +msg-301cf76e = 代码执行工具与URL上下文工具互斥,已忽略URL上下文工具 +msg-356e7b28 = 当前 SDK 版本不支持 URL 上下文工具,已忽略该设置,请升级 google-genai 包 +msg-7d4e7d48 = gemini-2.0-lite 不支持代码执行、搜索工具和URL上下文,将忽略这些设置 +msg-cc5c666f = 已启用原生工具,函数工具将被忽略 +msg-aa7c77a5 = Invalid thinking level: {$thinking_level}, using HIGH +msg-59e1e769 = 文本内容为空,已添加空格占位 +msg-34c5c910 = Failed to decode google gemini thinking signature: {$e} +msg-a2357584 = assistant 角色的消息内容为空,已添加空格占位 +msg-f627f75d = 检测到启用Gemini原生工具,且上下文中存在函数调用,建议使用 /reset 重置上下文 +msg-cb743183 = 收到的 candidate.content 为空: {$candidate} +msg-34b367fc = API 返回的 candidate.content 为空。 +msg-73541852 = 模型生成内容未通过 Gemini 平台的安全检查 +msg-ae3cdcea = 模型生成内容违反 Gemini 平台政策 +msg-5d8f1711 = 收到的 candidate.content.parts 为空: {$candidate} +msg-57847bd5 = API 返回的 candidate.content.parts 为空。 +msg-a56c85e4 = genai result: {$result} +msg-42fc0767 = 请求失败, 返回的 candidates 为空: {$result} +msg-faf3a0dd = 请求失败, 返回的 candidates 为空。 +msg-cd690916 = 温度参数已超过最大值2,仍然发生recitation +msg-632e23d7 = 发生了recitation,正在提高温度至{$temperature}重试... +msg-41ff84bc = {$model} 不支持 system prompt,已自动去除(影响人格设置) +msg-ef9512f7 = {$model} 不支持函数调用,已自动去除 +msg-fde41b1d = {$model} 不支持多模态输出,降级为文本模态 +msg-4e168d67 = 收到的 chunk 中 candidates 为空: {$chunk} +msg-11af7d46 = 收到的 chunk 中 content 为空: {$chunk} +msg-8836d4a2 = 请求失败。 +msg-757d3828 = 获取模型列表失败: {$res} +msg-7fc6f623 = 图片 {$image_url} 得到的结果为空,将忽略。 +msg-0b041916 = 不支持的额外内容块类型: {$res} + +### astrbot/core/provider/sources/gsvi_tts_source.py +msg-520e410f = GSVI TTS API 请求失败,状态码: {$res},错误: {$error_text} + +### astrbot/core/provider/sources/anthropic_source.py +msg-d6b1df6e = Failed to parse image data URI: {$res}... +msg-6c2c0426 = Unsupported image URL format for Anthropic: {$res}... +msg-999f7680 = completion: {$completion} +msg-8d2c43ec = API 返回的 completion 为空。 +msg-26140afc = Anthropic API 返回的 completion 无法解析:{$completion}。 +msg-8e4c8c24 = 工具调用参数 JSON 解析失败: {$tool_info} +msg-7fc6f623 = 图片 {$image_url} 得到的结果为空,将忽略。 +msg-0b041916 = 不支持的额外内容块类型: {$res} + +### astrbot/core/provider/sources/openai_source.py +msg-bbb399f6 = 检测到图片请求失败(%s),已移除图片并重试(保留文本内容)。 +msg-d6f6a3c2 = 获取模型列表失败:{$e} +msg-1f850e09 = API 返回的 completion 类型错误:{$res}: {$completion}。 +msg-999f7680 = completion: {$completion} +msg-844635f7 = Unexpected dict format content: {$raw_content} +msg-8d2c43ec = API 返回的 completion 为空。 +msg-87d75331 = {$completion_text} +msg-0614efaf = 工具集未提供 +msg-c46f067a = API 返回的 completion 由于内容安全过滤被拒绝(非 AstrBot)。 +msg-647f0002 = API 返回的 completion 无法解析:{$completion}。 +msg-5cc50a15 = API 调用过于频繁,尝试使用其他 Key 重试。当前 Key: {$res} +msg-c4e639eb = 上下文长度超过限制。尝试弹出最早的记录然后重试。当前记录条数: {$res} +msg-5f8be4fb = {$res} 不支持函数工具调用,已自动去除,不影响使用。 +msg-45591836 = 疑似该模型不支持函数调用工具调用。请输入 /tool off_all +msg-6e47d22a = API 调用失败,重试 {$max_retries} 次仍然失败。 +msg-974e7484 = 未知错误 +msg-7fc6f623 = 图片 {$image_url} 得到的结果为空,将忽略。 +msg-0b041916 = 不支持的额外内容块类型: {$res} + +### astrbot/core/provider/sources/gemini_tts_source.py +msg-29fe386a = [Gemini TTS] 使用代理: {$proxy} +msg-012edfe1 = No audio content returned from Gemini TTS API. + +### astrbot/core/provider/sources/genie_tts.py +msg-583dd8a6 = Please install genie_tts first. +msg-935222b4 = Failed to load character {$res}: {$e} +msg-a6886f9e = Genie TTS did not save to file. +msg-e3587d60 = Genie TTS generation failed: {$e} +msg-3303e3a8 = Genie TTS failed to generate audio for: {$text} +msg-1cfe1af1 = Genie TTS stream error: {$e} + +### astrbot/core/provider/sources/dashscope_tts.py +msg-f23d2372 = Dashscope TTS model is not configured. +msg-74a7cc0a = Audio synthesis failed, returned empty content. The model may not be supported or the service is unavailable. +msg-bc8619d3 = dashscope SDK missing MultiModalConversation. Please upgrade the dashscope package to use Qwen TTS models. +msg-95bbf71e = No voice specified for Qwen TTS model, using default 'Cherry'. +msg-3c35d2d0 = Audio synthesis failed for model '{$model}'. {$response} +msg-16dc3b00 = Failed to decode base64 audio data. +msg-26603085 = Failed to download audio from URL {$url}: {$e} +msg-78b9c276 = {$res} + +### astrbot/core/provider/sources/whisper_selfhosted_source.py +msg-27fda50a = 下载或者加载 Whisper 模型中,这可能需要一些时间 ... +msg-4e70f563 = Whisper 模型加载完成。 +msg-28cbbf07 = 文件不存在: {$audio_url} +msg-d98780e5 = Converting silk file to wav ... +msg-e3e1215c = Whisper 模型未初始化 + +### astrbot/core/provider/sources/openai_tts_api_source.py +msg-d7084760 = [OpenAI TTS] 使用代理: {$proxy} + +### astrbot/core/provider/sources/xinference_rerank_source.py +msg-1ec1e6e4 = Xinference Rerank: Using API key for authentication. +msg-7bcb6e1b = Xinference Rerank: No API key provided. +msg-b0d1e564 = Model '{$res}' is already running with UID: {$uid} +msg-16965859 = Launching {$res} model... +msg-7b1dfdd3 = Model launched. +msg-3fc7310e = Model '{$res}' is not running and auto-launch is disabled. Provider will not be available. +msg-15f19a42 = Failed to initialize Xinference model: {$e} +msg-01af1651 = Xinference initialization failed with exception: {$e} +msg-2607cc7a = Xinference rerank model is not initialized. +msg-3d28173b = Rerank API response: {$response} +msg-4c63e1bd = Rerank API returned an empty list. Original response: {$response} +msg-cac71506 = Xinference rerank failed: {$e} +msg-4135cf72 = Xinference rerank failed with exception: {$e} +msg-ea2b36d0 = Closing Xinference rerank client... +msg-633a269f = Failed to close Xinference client: {$e} + +### astrbot/core/provider/sources/minimax_tts_api_source.py +msg-77c88c8a = Failed to parse JSON data from SSE message +msg-7873b87b = MiniMax TTS API请求失败: {$e} + +### astrbot/core/provider/sources/azure_tts_source.py +msg-93d9b5cf = [Azure TTS] 使用代理: {$res} +msg-9eea5bcb = Client not initialized. Please use 'async with' context. +msg-fd53d21d = 时间同步失败 +msg-77890ac4 = OTTS请求失败: {$e} +msg-c6ec6ec7 = OTTS未返回音频文件 +msg-5ad71900 = 无效的Azure订阅密钥 +msg-6416da27 = [Azure TTS Native] 使用代理: {$res} +msg-15c55ed8 = 无效的other[...]格式,应形如 other[{...}] +msg-90b31925 = 缺少OTTS参数: {$res} +msg-10f72727 = {$error_msg} +msg-60b044ea = 配置错误: 缺少必要参数 {$e} +msg-5c7dee08 = 订阅密钥格式无效,应为32位字母数字或other[...]格式 + +### astrbot/core/provider/sources/openai_embedding_source.py +msg-cecb2fbc = [OpenAI Embedding] 使用代理: {$proxy} + +### astrbot/core/provider/sources/vllm_rerank_source.py +msg-6f160342 = Rerank API 返回了空的列表数据。原始响应: {$response_data} + +### astrbot/core/provider/sources/xinference_stt_provider.py +msg-4e31e089 = Xinference STT: Using API key for authentication. +msg-e291704e = Xinference STT: No API key provided. +msg-b0d1e564 = Model '{$res}' is already running with UID: {$uid} +msg-16965859 = Launching {$res} model... +msg-7b1dfdd3 = Model launched. +msg-3fc7310e = Model '{$res}' is not running and auto-launch is disabled. Provider will not be available. +msg-15f19a42 = Failed to initialize Xinference model: {$e} +msg-01af1651 = Xinference initialization failed with exception: {$e} +msg-42ed8558 = Xinference STT model is not initialized. +msg-bbc43272 = Failed to download audio from {$audio_url}, status: {$res} +msg-f4e53d3d = File not found: {$audio_url} +msg-ebab7cac = Audio bytes are empty. +msg-7fd63838 = Audio requires conversion ({$conversion_type}), using temporary files... +msg-d03c4ede = Converting silk to wav ... +msg-79486689 = Converting amr to wav ... +msg-c4305a5b = Xinference STT result: {$text} +msg-d4241bd5 = Xinference STT transcription failed with status {$res}: {$error_text} +msg-8efe4ef1 = Xinference STT failed: {$e} +msg-b1554c7c = Xinference STT failed with exception: {$e} +msg-9d33941a = Removed temporary file: {$temp_file} +msg-7dc5bc44 = Failed to remove temporary file {$temp_file}: {$e} +msg-31904a1c = Closing Xinference STT client... +msg-633a269f = Failed to close Xinference client: {$e} + +### astrbot/core/provider/sources/fishaudio_tts_api_source.py +msg-c785baf0 = [FishAudio TTS] 使用代理: {$res} +msg-822bce1c = 无效的FishAudio参考模型ID: '{$res}'. 请确保ID是32位十六进制字符串(例如: 626bb6d3f3364c9cbc3aa6a67300a664)。您可以从 https://fish.audio/zh-CN/discovery 获取有效的模型ID。 +msg-5956263b = Fish Audio API请求失败: 状态码 {$res}, 响应内容: {$error_text} + +### astrbot/core/provider/sources/gsv_selfhosted_source.py +msg-5fb63f61 = [GSV TTS] 初始化完成 +msg-e0c38c5b = [GSV TTS] 初始化失败:{$e} +msg-4d57bc4f = [GSV TTS] Provider HTTP session is not ready or closed. +msg-2a4a0819 = [GSV TTS] 请求地址:{$endpoint},参数:{$params} +msg-5fdee1da = [GSV TTS] Request to {$endpoint} failed with status {$res}: {$error_text} +msg-3a51c2c5 = [GSV TTS] 请求 {$endpoint} 第 {$res} 次失败:{$e},重试中... +msg-49c1c17a = [GSV TTS] 请求 {$endpoint} 最终失败:{$e} +msg-1beb6249 = [GSV TTS] 成功设置 GPT 模型路径:{$res} +msg-17f1a087 = [GSV TTS] GPT 模型路径未配置,将使用内置 GPT 模型 +msg-ddeb915f = [GSV TTS] 成功设置 SoVITS 模型路径:{$res} +msg-bee5c961 = [GSV TTS] SoVITS 模型路径未配置,将使用内置 SoVITS 模型 +msg-423edb93 = [GSV TTS] 设置模型路径时发生网络错误:{$e} +msg-7d3c79cb = [GSV TTS] 设置模型路径时发生未知错误:{$e} +msg-d084916a = [GSV TTS] TTS 文本不能为空 +msg-fa20c883 = [GSV TTS] 正在调用语音合成接口,参数:{$params} +msg-a7fc38eb = [GSV TTS] 合成失败,输入文本:{$text},错误信息:{$result} +msg-a49cb96b = [GSV TTS] Session 已关闭 + +### astrbot/core/provider/sources/volcengine_tts.py +msg-4b55f021 = 请求头: {$headers} +msg-d252d96d = 请求 URL: {$res} +msg-72e07cfd = 请求体: {$res}... +msg-fb8cdd69 = 响应状态码: {$res} +msg-4c62e457 = 响应内容: {$res}... +msg-1477973b = 火山引擎 TTS API 返回错误: {$error_msg} +msg-75401c15 = 火山引擎 TTS API 请求失败: {$res}, {$response_text} +msg-a29cc73d = 火山引擎 TTS 异常详情: {$error_details} +msg-01433007 = 火山引擎 TTS 异常: {$e} + +### astrbot/core/provider/sources/sensevoice_selfhosted_source.py +msg-ee0daf96 = 下载或者加载 SenseVoice 模型中,这可能需要一些时间 ... +msg-cd6da7e9 = SenseVoice 模型加载完成。 +msg-28cbbf07 = 文件不存在: {$audio_url} +msg-d98780e5 = Converting silk file to wav ... +msg-4e8f1d05 = SenseVoice识别到的文案:{$res} +msg-55668aa2 = 未能提取到情绪信息 +msg-0cdbac9b = 处理音频文件时出错: {$e} + +### astrbot/core/message/components.py +msg-afb10076 = not a valid url +msg-fe4c33a0 = not a valid file: {$res} +msg-24d98e13 = 未配置 callback_api_base,文件服务不可用 +msg-a5c69cc9 = 已注册:{$callback_host}/api/file/{$token} +msg-3cddc5ef = download failed: {$url} +msg-1921aa47 = not a valid file: {$url} +msg-2ee3827c = Generated video file callback link: {$payload_file} +msg-32f4fc78 = No valid file or URL provided +msg-36375f4c = 不可以在异步上下文中同步等待下载! 这个警告通常发生于某些逻辑试图通过 .file 获取文件消息段的文件内容。请使用 await get_file() 代替直接获取 .file 字段 +msg-4a987754 = 文件下载失败: {$e} +msg-7c1935ee = Download failed: No URL provided in File component. +msg-35bb8d53 = Generated file callback link: {$payload_file} + +### astrbot/core/utils/metrics.py +msg-314258f2 = 保存指标到数据库失败: {$e} + +### astrbot/core/utils/trace.py +msg-fffce1b9 = [trace] {$payload} +msg-78b9c276 = {$res} + +### astrbot/core/utils/webhook_utils.py +msg-64c7ddcf = 获取 callback_api_base 失败: {$e} +msg-9b5d1bb1 = 获取 dashboard 端口失败: {$e} +msg-3db149ad = 获取 dashboard SSL 配置失败: {$e} +msg-3739eec9 = {$display_log} + +### astrbot/core/utils/path_util.py +msg-cf211d0f = 路径映射规则错误: {$mapping} +msg-ecea161e = 路径映射: {$url} -> {$srcPath} + +### astrbot/core/utils/media_utils.py +msg-2f697658 = [Media Utils] 获取媒体时长: {$duration_ms}ms +msg-52dfbc26 = [Media Utils] 无法获取媒体文件时长: {$file_path} +msg-486d493a = [Media Utils] ffprobe未安装或不在PATH中,无法获取媒体时长。请安装ffmpeg: https://ffmpeg.org/ +msg-0f9c647b = [Media Utils] 获取媒体时长时出错: {$e} +msg-aff4c5f8 = [Media Utils] 已清理失败的opus输出文件: {$output_path} +msg-82427384 = [Media Utils] 清理失败的opus输出文件时出错: {$e} +msg-215a0cfc = [Media Utils] ffmpeg转换音频失败: {$error_msg} +msg-8cce258e = ffmpeg conversion failed: {$error_msg} +msg-f0cfcb92 = [Media Utils] 音频转换成功: {$audio_path} -> {$output_path} +msg-ead1395b = [Media Utils] ffmpeg未安装或不在PATH中,无法转换音频格式。请安装ffmpeg: https://ffmpeg.org/ +msg-5df3a5ee = ffmpeg not found +msg-6322d4d2 = [Media Utils] 转换音频格式时出错: {$e} +msg-e125b1a5 = [Media Utils] 已清理失败的{$output_format}输出文件: {$output_path} +msg-5cf417e3 = [Media Utils] 清理失败的{$output_format}输出文件时出错: {$e} +msg-3766cbb8 = [Media Utils] ffmpeg转换视频失败: {$error_msg} +msg-77f68449 = [Media Utils] 视频转换成功: {$video_path} -> {$output_path} +msg-3fb20b91 = [Media Utils] ffmpeg未安装或不在PATH中,无法转换视频格式。请安装ffmpeg: https://ffmpeg.org/ +msg-696c4a46 = [Media Utils] 转换视频格式时出错: {$e} +msg-98cc8fb8 = [Media Utils] 清理失败的音频输出文件时出错: {$e} +msg-3c27d5e8 = [Media Utils] 清理失败的视频封面文件时出错: {$e} +msg-072774ab = ffmpeg extract cover failed: {$error_msg} + +### astrbot/core/utils/session_waiter.py +msg-0c977996 = 等待超时 +msg-ac406437 = session_filter 必须是 SessionFilter + +### astrbot/core/utils/history_saver.py +msg-fb7718cb = Failed to parse conversation history: %s + +### astrbot/core/utils/io.py +msg-665b0191 = SSL certificate verification failed for {$url}. Disabling SSL verification (CERT_NONE) as a fallback. This is insecure and exposes the application to man-in-the-middle attacks. Please investigate and resolve certificate issues. +msg-04ab2fae = 下载文件失败: {$res} +msg-63dacf99 = 文件大小: {$res} KB | 文件地址: {$url} +msg-14c3d0bb = \r下载进度: {$res} 速度: {$speed} KB/s +msg-4e4ee68e = SSL 证书验证失败,已关闭 SSL 验证(不安全,仅用于临时下载)。请检查目标服务器的证书配置。 +msg-5a3beefb = SSL certificate verification failed for {$url}. Falling back to unverified connection (CERT_NONE). This is insecure and exposes the application to man-in-the-middle attacks. Please investigate certificate issues with the remote server. +msg-315e5ed6 = 准备下载指定发行版本的 AstrBot WebUI 文件: {$dashboard_release_url} +msg-c709cf82 = 准备下载指定版本的 AstrBot WebUI: {$url} + +### astrbot/core/utils/shared_preferences.py +msg-9a1e6a9a = scope_id and key cannot be None when getting a specific preference. + +### astrbot/core/utils/migra_helper.py +msg-497ddf83 = Migration for third party agent runner configs failed: {$e} +msg-78b9c276 = {$res} +msg-e21f1509 = Migrating provider {$res} to new structure +msg-dd3339e6 = Provider-source structure migration completed +msg-1cb6c174 = Migration from version 4.5 to 4.6 failed: {$e} +msg-a899acc6 = Migration for webchat session failed: {$e} +msg-b9c52817 = Migration for token_usage column failed: {$e} +msg-d9660ff5 = Migration for provider-source structure failed: {$e} + +### astrbot/core/utils/temp_dir_cleaner.py +msg-752c7cc8 = Invalid {$res}={$configured}, fallback to {$res_2}MB. +msg-b1fc3643 = Skip temp file {$path} due to stat error: {$e} +msg-5e61f6b7 = Failed to delete temp file {$res}: {$e} +msg-391449f0 = Temp dir exceeded limit ({$total_size} > {$limit}). Removed {$removed_files} files, released {$released} bytes (target {$target_release} bytes). +msg-aaf1e12a = TempDirCleaner started. interval={$res}s cleanup_ratio={$res_2} +msg-e6170717 = TempDirCleaner run failed: {$e} +msg-0fc33fbc = TempDirCleaner stopped. + +### astrbot/core/utils/tencent_record_helper.py +msg-377ae139 = pilk 模块未安装,请前往管理面板->平台日志->安装pip库 安装 pilk 这个库 +msg-f4ab0713 = pyffmpeg 转换失败: {$e}, 尝试使用 ffmpeg 命令行进行转换 +msg-33c88889 = [FFmpeg] stdout: {$res} +msg-2470430c = [FFmpeg] stderr: {$res} +msg-1321d5f7 = [FFmpeg] return code: {$res} +msg-c39d210c = 生成的WAV文件不存在或为空 +msg-6e04bdb8 = 未安装 pilk: pip install pilk + +### astrbot/core/utils/pip_installer.py +msg-aa9e40b8 = pip module is unavailable (sys.executable={$res}, frozen={$res_2}, ASTRBOT_DESKTOP_CLIENT={$res_3}) +msg-560f11f2 = 读取依赖文件失败,跳过冲突检测: %s +msg-91ae1d17 = 读取 site-packages 元数据失败,使用回退模块名: %s +msg-c815b9dc = {$conflict_message} +msg-e8d4b617 = Loaded %s from plugin site-packages: %s +msg-4ef5d900 = Recovered dependency %s while preferring %s from plugin site-packages. +msg-0bf22754 = Module %s not found in plugin site-packages: %s +msg-76a41595 = Failed to prefer module %s from plugin site-packages: %s +msg-3d4de966 = Failed to patch pip distlib finder for loader %s (%s): %s +msg-117d9cf4 = Distlib finder patch did not take effect for loader %s (%s). +msg-b7975236 = Patched pip distlib finder for frozen loader: %s (%s) +msg-b1fa741c = Skip patching distlib finder because _finder_registry is unavailable. +msg-4ef0e609 = Skip patching distlib finder because register API is unavailable. +msg-b8c741dc = Pip 包管理器: pip {$res} +msg-6b72a960 = 安装失败,错误码:{$result_code} +msg-c8325399 = {$line} + +### astrbot/core/utils/llm_metadata.py +msg-d6535d03 = Successfully fetched metadata for {$res} LLMs. +msg-8cceaeb0 = Failed to fetch LLM metadata: {$e} + +### astrbot/core/utils/network_utils.py +msg-54b8fda8 = [{$provider_label}] 网络/代理连接失败 ({$error_type})。代理地址: {$effective_proxy},错误: {$error} +msg-ea7c80f1 = [{$provider_label}] 网络连接失败 ({$error_type})。错误: {$error} +msg-f8c8a73c = [{$provider_label}] 使用代理: {$proxy} + +### astrbot/core/utils/t2i/renderer.py +msg-4225607b = Failed to render image via AstrBot API: {$e}. Falling back to local rendering. + +### astrbot/core/utils/t2i/local_strategy.py +msg-94a58a1e = 无法加载任何字体 +msg-d5c7d255 = Failed to load image: HTTP {$res} +msg-7d59d0a0 = Failed to load image: {$e} + +### astrbot/core/utils/t2i/template_manager.py +msg-47d72ff5 = 模板名称包含非法字符。 +msg-d1b2131b = 模板不存在。 +msg-dde05b0f = 同名模板已存在。 +msg-0aa209bf = 用户模板不存在,无法删除。 + +### astrbot/core/utils/t2i/network_strategy.py +msg-be0eeaa7 = Successfully got {$res} official T2I endpoints. +msg-3bee02f4 = Failed to get official endpoints: {$e} +msg-829d3c71 = HTTP {$res} +msg-05fb621f = Endpoint {$endpoint} failed: {$e}, trying next... +msg-9a836926 = All endpoints failed: {$last_exception} + +### astrbot/core/utils/quoted_message/extractor.py +msg-24049c48 = quoted_message_parser: stop fetching nested forward messages after %d hops + +### astrbot/core/utils/quoted_message/onebot_client.py +msg-062923e6 = quoted_message_parser: action %s failed with params %s: %s +msg-f33f59d5 = quoted_message_parser: all attempts failed for action %s, last_params=%s, error=%s + +### astrbot/core/utils/quoted_message/image_resolver.py +msg-94224a01 = quoted_message_parser: skip non-image local path ref=%s +msg-3e6c0d14 = quoted_message_parser: failed to resolve quoted image ref=%s after %d actions + +### astrbot/core/agent/tool_image_cache.py +msg-45da4af7 = ToolImageCache initialized, cache dir: {$res} +msg-017bde96 = Saved tool image to: {$file_path} +msg-29398f55 = Failed to save tool image: {$e} +msg-128aa08a = Failed to read cached image {$file_path}: {$e} +msg-3c111d1f = Error during cache cleanup: {$e} +msg-eeb1b849 = Cleaned up {$cleaned} expired cached images + +### astrbot/core/agent/message.py +msg-d38656d7 = {$invalid_subclass_error_msg} +msg-42d5a315 = Cannot validate {$value} as ContentPart +msg-ffc376d0 = content is required unless role='assistant' and tool_calls is not None + +### astrbot/core/agent/mcp_client.py +msg-6a61ca88 = Warning: Missing 'mcp' dependency, MCP services will be unavailable. +msg-45995cdb = Warning: Missing 'mcp' dependency or MCP library version too old, Streamable HTTP connection unavailable. +msg-2866b896 = MCP connection config missing transport or type field +msg-3bf7776b = MCP Server {$name} Error: {$msg} +msg-10f72727 = {$error_msg} +msg-19c9b509 = MCP Client is not initialized +msg-5b9b4918 = MCP Client {$res} is already reconnecting, skipping +msg-c1008866 = Cannot reconnect: missing connection configuration +msg-7c3fe178 = Attempting to reconnect to MCP server {$res}... +msg-783f3b85 = Successfully reconnected to MCP server {$res} +msg-da7361ff = Failed to reconnect to MCP server {$res}: {$e} +msg-c0fd612e = MCP session is not available for MCP function tools. +msg-8236c58c = MCP tool {$tool_name} call failed (ClosedResourceError), attempting to reconnect... +msg-044046ec = Error closing current exit stack: {$e} + +### astrbot/core/agent/tool.py +msg-983bc802 = FunctionTool.call() must be implemented by subclasses or set a handler. + +### astrbot/core/agent/context/compressor.py +msg-6c75531b = Failed to generate summary: {$e} + +### astrbot/core/agent/context/manager.py +msg-59241964 = Error during context processing: {$e} +msg-a0d672dc = Compress triggered, starting compression... +msg-e6ef66f0 = Compress completed. {$prev_tokens} -> {$tokens_after_summary} tokens, compression rate: {$compress_rate}%. +msg-3fe644eb = Context still exceeds max tokens after compression, applying halving truncation... + +### astrbot/core/agent/runners/tool_loop_agent_runner.py +msg-960ef181 = Switched from %s to fallback chat provider: %s +msg-4f999913 = Chat Model %s returns error response, trying fallback to next provider. +msg-c042095f = Chat Model %s request error: %s +msg-81b2aeae = {$tag} RunCtx.messages -> [{$res}] {$res_2} +msg-55333301 = Request is not set. Please call reset() first. +msg-d3b77736 = Error in on_agent_begin hook: {$e} +msg-61de315c = Agent execution was requested to stop by user. +msg-8eb53be3 = Error in on_agent_done hook: {$e} +msg-508d6d17 = LLM 响应错误: {$res} +msg-ed80313d = LLM returned empty assistant message with no tool calls. +msg-970947ae = Appended {$res} cached image(s) to context for LLM review +msg-6b326889 = Agent reached max steps ({$max_step}), forcing a final response. +msg-948ea4b7 = Agent 使用工具: {$res} +msg-a27ad3d1 = 使用工具:{$func_tool_name},参数:{$func_tool_args} +msg-812ad241 = 未找到指定的工具: {$func_tool_name},将跳过。 +msg-20b4f143 = 工具 {$func_tool_name} 期望的参数: {$res} +msg-78f6833c = 工具 {$func_tool_name} 忽略非期望参数: {$ignored_params} +msg-2b523f8c = Error in on_tool_start hook: {$e} +msg-ec868b73 = {$func_tool_name} 没有返回值,或者已将结果直接发送给用户。 +msg-6b61e4f1 = Tool 返回了不支持的类型: {$res}。 +msg-34c13e02 = Error in on_tool_end hook: {$e} +msg-78b9c276 = {$res} +msg-a1493b6d = Tool `{$func_tool_name}` Result: {$last_tcr_content} + +### astrbot/core/agent/runners/base.py +msg-24eb2b08 = Agent state transition: {$res} -> {$new_state} + +### astrbot/core/agent/runners/dashscope/dashscope_agent_runner.py +msg-dc1a9e6e = 阿里云百炼 API Key 不能为空。 +msg-c492cbbc = 阿里云百炼 APP ID 不能为空。 +msg-bcc8e027 = 阿里云百炼 APP 类型不能为空。 +msg-55333301 = Request is not set. Please call reset() first. +msg-d3b77736 = Error in on_agent_begin hook: {$e} +msg-e3af4efd = 阿里云百炼请求失败:{$res} +msg-fccf5004 = dashscope stream chunk: {$chunk} +msg-100d7d7e = 阿里云百炼请求失败: request_id={$res}, code={$res_2}, message={$res_3}, 请参考文档:https://help.aliyun.com/zh/model-studio/developer-reference/error-code +msg-10f72727 = {$error_msg} +msg-e8615101 = {$chunk_text} +msg-dfb132c4 = {$ref_text} +msg-8eb53be3 = Error in on_agent_done hook: {$e} +msg-650b47e1 = 阿里云百炼暂不支持图片输入,将自动忽略图片内容。 + +### astrbot/core/agent/runners/coze/coze_agent_runner.py +msg-448549b0 = Coze API Key 不能为空。 +msg-b88724b0 = Coze Bot ID 不能为空。 +msg-ea5a135a = Coze API Base URL 格式不正确,必须以 http:// 或 https:// 开头。 +msg-55333301 = Request is not set. Please call reset() first. +msg-d3b77736 = Error in on_agent_begin hook: {$e} +msg-5aa3eb1c = Coze 请求失败:{$res} +msg-333354c6 = 处理上下文图片失败: {$e} +msg-2d9e1c08 = 处理图片失败 {$url}: {$e} +msg-1f50979d = {$content} +msg-6fe5588b = Coze message completed +msg-d2802f3b = Coze chat completed +msg-ba4afcda = Coze 出现错误: {$error_code} - {$error_msg} +msg-ee300f25 = Coze 未返回任何内容 +msg-8eb53be3 = Error in on_agent_done hook: {$e} +msg-034c1858 = [Coze] 使用缓存的 file_id: {$file_id} +msg-475d8a41 = [Coze] 图片上传成功并缓存,file_id: {$file_id} +msg-696dad99 = 处理图片失败 {$image_url}: {$e} +msg-7793a347 = 处理图片失败: {$e} + +### astrbot/core/agent/runners/coze/coze_api_client.py +msg-76f97104 = Coze API 认证失败,请检查 API Key 是否正确 +msg-3653b652 = 文件上传响应状态: {$res}, 内容: {$response_text} +msg-13fe060c = 文件上传失败,状态码: {$res}, 响应: {$response_text} +msg-5604b862 = 文件上传响应解析失败: {$response_text} +msg-c0373c50 = 文件上传失败: {$res} +msg-010e4299 = [Coze] 图片上传成功,file_id: {$file_id} +msg-719f13cb = 文件上传超时 +msg-121c11fb = 文件上传失败: {$e} +msg-f6101892 = 下载图片失败,状态码: {$res} +msg-c09c56c9 = 下载图片失败 {$image_url}: {$e} +msg-15211c7c = 下载图片失败: {$e} +msg-2245219f = Coze chat_messages payload: {$payload}, params: {$params} +msg-d8fd415c = Coze API 流式请求失败,状态码: {$res} +msg-f5cc7604 = Coze API 流式请求超时 ({$timeout}秒) +msg-30c0a9d6 = Coze API 流式请求失败: {$e} +msg-11509aba = Coze API 请求失败,状态码: {$res} +msg-002af11d = Coze API 返回非JSON格式 +msg-c0b8fc7c = Coze API 请求超时 +msg-a68a33fa = Coze API 请求失败: {$e} +msg-c26e068e = 获取Coze消息列表失败: {$e} +msg-5bc0a49d = Uploaded file_id: {$file_id} +msg-7c08bdaf = Event: {$event} + +### astrbot/core/agent/runners/dify/dify_api_client.py +msg-cd6cd7ac = Drop invalid dify json data: {$res} +msg-3654a12d = chat_messages payload: {$payload} +msg-8e865c52 = Dify /chat-messages 接口请求失败:{$res}. {$text} +msg-2d7534b8 = workflow_run payload: {$payload} +msg-89918ba5 = Dify /workflows/run 接口请求失败:{$res}. {$text} +msg-8bf17938 = file_path 和 file_data 不能同时为 None +msg-b6ee8f38 = Dify 文件上传失败:{$res}. {$text} + +### astrbot/core/agent/runners/dify/dify_agent_runner.py +msg-55333301 = Request is not set. Please call reset() first. +msg-d3b77736 = Error in on_agent_begin hook: {$e} +msg-0d493427 = Dify 请求失败:{$res} +msg-fe594f21 = Dify 上传图片响应:{$file_response} +msg-3534b306 = 上传图片后得到未知的 Dify 响应:{$file_response},图片将忽略。 +msg-08441fdf = 上传图片失败:{$e} +msg-3972f693 = dify resp chunk: {$chunk} +msg-6c74267b = Dify message end +msg-1ce260ba = Dify 出现错误:{$chunk} +msg-a12417dd = Dify 出现错误 status: {$res} message: {$res_2} +msg-f8530ee9 = dify workflow resp chunk: {$chunk} +msg-386a282e = Dify 工作流(ID: {$res})开始运行。 +msg-0bc1299b = Dify 工作流节点(ID: {$res} Title: {$res_2})运行结束。 +msg-5cf24248 = Dify 工作流(ID: {$res})运行结束 +msg-e2c2159f = Dify 工作流结果:{$chunk} +msg-4fa60ef1 = Dify 工作流出现错误:{$res} +msg-1f786836 = Dify 工作流的输出不包含指定的键名:{$res} +msg-c4a70ffb = 未知的 Dify API 类型:{$res} +msg-51d321fd = Dify 请求结果为空,请查看 Debug 日志。 +msg-8eb53be3 = Error in on_agent_done hook: {$e} + +### astrbot/core/star/session_plugin_manager.py +msg-16cc2a7a = 插件 {$res} 在会话 {$session_id} 中被禁用,跳过处理器 {$res_2} + +### astrbot/core/star/star_manager.py +msg-bfa28c02 = 未安装 watchfiles,无法实现插件的热重载。 +msg-f8e1c445 = 插件热重载监视任务异常: {$e} +msg-78b9c276 = {$res} +msg-28aeca68 = 检测到文件变化: {$changes} +msg-aeec7738 = 检测到插件 {$plugin_name} 文件变化,正在重载... +msg-4f989555 = 插件 {$d} 未找到 main.py 或者 {$d}.py,跳过。 +msg-74b32804 = 正在安装插件 {$p} 所需的依赖库: {$pth} +msg-936edfca = 更新插件 {$p} 的依赖失败。Code: {$e} +msg-ebd47311 = 插件 {$root_dir_name} 导入失败,尝试从已安装依赖恢复: {$import_exc} +msg-1b6e94f1 = 插件 {$root_dir_name} 已从 site-packages 恢复依赖,跳过重新安装。 +msg-81b7c9b9 = 插件 {$root_dir_name} 已安装依赖恢复失败,将重新安装依赖: {$recover_exc} +msg-22fde75d = 插件不存在。 +msg-3a307a9e = 插件元数据信息不完整。name, desc, version, author 是必须的字段。 +msg-55e089d5 = 删除模块 {$key} +msg-64de1322 = 删除模块 {$module_name} +msg-66823424 = 模块 {$module_name} 未载入 +msg-45c8df8d = 清除了插件{$dir_name}中的{$key}模块 +msg-f7d9aa9b = 清理处理器: {$res} +msg-3c492aa6 = 清理工具: {$res} +msg-e0002829 = 插件 {$res} 未被正常终止: {$e}, 可能会导致该插件运行不正常。 +msg-0fe27735 = 正在载入插件 {$root_dir_name} ... +msg-b2ec4801 = {$error_trace} +msg-db351291 = 插件 {$root_dir_name} 导入失败。原因:{$e} +msg-a3db5f45 = 失败插件依旧在插件列表中,正在清理... +msg-58c66a56 = 插件 {$root_dir_name} 元数据载入失败: {$e}。使用默认元数据。 +msg-da764b29 = {$metadata} +msg-17cd7b7d = 插件 {$res} 已被禁用。 +msg-4baf6814 = 插件 {$path} 未通过装饰器注册。尝试通过旧版本方式载入。 +msg-840994d1 = 无法找到插件 {$plugin_dir_path} 的元数据。 +msg-944ffff1 = 插入权限过滤器 {$cmd_type} 到 {$res} 的 {$res_2} 方法。 +msg-64edd12c = hook(on_plugin_loaded) -> {$res} - {$res_2} +msg-db49f7a1 = ----- 插件 {$root_dir_name} 载入失败 ----- +msg-26039659 = | {$line} +msg-4292f44d = ---------------------------------- +msg-d2048afe = 同步指令配置失败: {$e} +msg-df515dec = 已清理安装失败的插件目录: {$plugin_path} +msg-1f2aa1a9 = 清理安装失败插件目录失败: {$plugin_path},原因: {$e} +msg-1e947210 = 已清理安装失败插件配置: {$plugin_config_path} +msg-7374541f = 清理安装失败插件配置失败: {$plugin_config_path},原因: {$e} +msg-e871b08f = 读取插件 {$dir_name} 的 README.md 文件失败: {$e} +msg-70ca4592 = 该插件是 AstrBot 保留插件,无法卸载。 +msg-e247422b = 插件 {$plugin_name} 未被正常终止 {$e}, 可能会导致资源泄露等问题。 +msg-0c25dbf4 = 插件 {$plugin_name} 数据不完整,无法卸载。 +msg-d6f8142c = 移除插件成功,但是删除插件文件夹失败: {$e}。您可以手动删除该文件夹,位于 addons/plugins/ 下。 +msg-6313500c = 已删除插件 {$plugin_name} 的配置文件 +msg-f0f01b67 = 删除插件配置文件失败: {$e} +msg-c4008b30 = 已删除插件 {$plugin_name} 的持久化数据 (plugin_data) +msg-88d1ee05 = 删除插件持久化数据失败 (plugin_data): {$e} +msg-ba805469 = 已删除插件 {$plugin_name} 的持久化数据 (plugins_data) +msg-cf6eb821 = 删除插件持久化数据失败 (plugins_data): {$e} +msg-e1853811 = 移除了插件 {$plugin_name} 的处理函数 {$res} ({$res_2}) +msg-95b20050 = 移除了插件 {$plugin_name} 的平台适配器 {$adapter_name} +msg-9f248e88 = 该插件是 AstrBot 保留插件,无法更新。 +msg-ff435883 = 正在终止插件 {$res} ... +msg-355187b7 = 插件 {$res} 未被激活,不需要终止,跳过。 +msg-4369864f = hook(on_plugin_unloaded) -> {$res} - {$res_2} +msg-1b95e855 = 插件 {$plugin_name} 不存在。 +msg-c1bc6cd6 = 检测到插件 {$res} 已安装,正在终止旧插件... +msg-4f3271db = 检测到同名插件 {$res} 存在于不同目录 {$res_2},正在终止... +msg-d247fc54 = 读取新插件 metadata.yaml 失败,跳过同名检查: {$e} +msg-0f8947f8 = 删除插件压缩包失败: {$e} + +### astrbot/core/star/session_llm_manager.py +msg-7b90d0e9 = 会话 {$session_id} 的TTS状态已更新为: {$res} + +### astrbot/core/star/config.py +msg-c2189e8d = namespace 不能为空。 +msg-97f66907 = namespace 不能以 internal_ 开头。 +msg-09179604 = key 只支持 str 类型。 +msg-1163e4f1 = value 只支持 str, int, float, bool, list 类型。 +msg-ed0f93e4 = 配置文件 {$namespace}.json 不存在。 +msg-e3b5cdfb = 配置项 {$key} 不存在。 + +### astrbot/core/star/star_tools.py +msg-397b7bf9 = StarTools not initialized +msg-ca30e638 = 未找到适配器: AiocqhttpAdapter +msg-77ca0ccb = 不支持的平台: {$platform} +msg-3ed67eb2 = 无法获取调用者模块信息 +msg-e77ccce6 = 无法获取模块 {$res} 的元数据信息 +msg-76ac38ee = 无法获取插件名称 +msg-751bfd23 = 无法创建目录 {$data_dir}:权限不足 +msg-68979283 = 无法创建目录 {$data_dir}:{$e} + +### astrbot/core/star/context.py +msg-60eb9e43 = Provider {$chat_provider_id} not found +msg-da70a6fb = Agent did not produce a final LLM response +msg-141151fe = Provider not found +msg-a5cb19c6 = 没有找到 ID 为 {$provider_id} 的提供商,这可能是由于您修改了提供商(模型)ID 导致的。 +msg-2a44300b = 该会话来源的对话模型(提供商)的类型不正确: {$res} +msg-37c286ea = 返回的 Provider 不是 TTSProvider 类型 +msg-ff775f3b = 返回的 Provider 不是 STTProvider 类型 +msg-fd8c8295 = cannot find platform for session {$res}, message not sent +msg-2b806a28 = plugin(module_path {$module_path}) added LLM tool: {$res} + +### astrbot/core/star/updator.py +msg-66be72ec = 插件 {$res} 没有指定仓库地址。 +msg-7a29adea = 插件 {$res} 的根目录名未指定。 +msg-99a86f88 = 正在更新插件,路径: {$plugin_path},仓库地址: {$repo_url} +msg-df2c7e1b = 删除旧版本插件 {$plugin_path} 文件夹失败: {$e},使用覆盖安装。 +msg-b3471491 = 正在解压压缩包: {$zip_path} +msg-7197ad11 = 删除临时文件: {$zip_path} 和 {$res} +msg-f8a43aa5 = 删除更新文件失败,可以手动删除 {$zip_path} 和 {$res} + +### astrbot/core/star/command_management.py +msg-011581bb = 指定的处理函数不存在或不是指令。 +msg-a0c37004 = 指令名不能为空。 +msg-ae8b2307 = 指令名 '{$candidate_full}' 已被其他指令占用。 +msg-247926a7 = 别名 '{$alias_full}' 已被其他指令占用。 +msg-dbd19a23 = 权限类型必须为 admin 或 member。 +msg-9388ea1e = 未找到指令所属插件 +msg-0dd9b70d = 解析指令处理函数 {$res} 失败,跳过该指令。原因: {$e} + +### astrbot/core/star/base.py +msg-57019272 = get_config() failed: {$e} + +### astrbot/core/star/register/star.py +msg-64619f8e = The 'register_star' decorator is deprecated and will be removed in a future version. + +### astrbot/core/star/register/star_handler.py +msg-7ff2d46e = 注册指令{$command_name} 的子指令时未提供 sub_command 参数。 +msg-b68436e1 = 注册裸指令时未提供 command_name 参数。 +msg-1c183df2 = {$command_group_name} 指令组的子指令组 sub_command 未指定 +msg-9210c7e8 = 根指令组的名称未指定 +msg-678858e7 = 注册指令组失败。 +msg-6c3915e0 = LLM 函数工具 {$res}_{$llm_tool_name} 的参数 {$res_2} 缺少类型注释。 +msg-1255c964 = LLM 函数工具 {$res}_{$llm_tool_name} 不支持的参数类型:{$res_2} + +### astrbot/core/star/filter/command.py +msg-995944c2 = 参数 '{$param_name}' (GreedyStr) 必须是最后一个参数。 +msg-04dbdc3a = 必要参数缺失。该指令完整参数: {$res} +msg-bda71712 = 参数 {$param_name} 必须是布尔值(true/false, yes/no, 1/0)。 +msg-a9afddbf = 参数 {$param_name} 类型错误。完整参数: {$res} + +### astrbot/core/star/filter/custom_filter.py +msg-8f3eeb6e = Operands must be subclasses of CustomFilter. +msg-732ada95 = CustomFilter class can only operate with other CustomFilter. +msg-51c0c77d = CustomFilter lass can only operate with other CustomFilter. + +### astrbot/core/db/vec_db/faiss_impl/document_storage.py +msg-c2dc1d2b = Database connection is not initialized, returning empty result +msg-51fa7426 = Database connection is not initialized, skipping delete operation +msg-43d1f69f = Database connection is not initialized, returning 0 + +### astrbot/core/db/vec_db/faiss_impl/embedding_storage.py +msg-8e5fe535 = faiss 未安装。请使用 'pip install faiss-cpu' 或 'pip install faiss-gpu' 安装。 +msg-9aa7b941 = 向量维度不匹配, 期望: {$res}, 实际: {$res_2} + +### astrbot/core/db/vec_db/faiss_impl/vec_db.py +msg-9f9765dc = Generating embeddings for {$res} contents... +msg-385bc50a = Generated embeddings for {$res} contents in {$res_2} seconds. + +### astrbot/core/db/migration/migra_token_usage.py +msg-c3e53a4f = 开始执行数据库迁移(添加 conversations.token_usage 列)... +msg-ccbd0a41 = token_usage 列已存在,跳过迁移 +msg-39f60232 = token_usage 列添加成功 +msg-4f9d3876 = token_usage 迁移完成 +msg-91571aaf = 迁移过程中发生错误: {$e} + +### astrbot/core/db/migration/migra_3_to_4.py +msg-7805b529 = 迁移 {$total_cnt} 条旧的会话数据到新的表中... +msg-6f232b73 = 进度: {$progress}% ({$res}/{$total_cnt}) +msg-6b1def31 = 未找到该条旧会话对应的具体数据: {$conversation}, 跳过。 +msg-b008c93f = 迁移旧会话 {$res} 失败: {$e} +msg-6ac6313b = 成功迁移 {$total_cnt} 条旧的会话数据到新表。 +msg-6b72e89b = 迁移旧平台数据,offset_sec: {$offset_sec} 秒。 +msg-bdc90b84 = 迁移 {$res} 条旧的平台数据到新的表中... +msg-e6caca5c = 没有找到旧平台数据,跳过迁移。 +msg-1e824a79 = 进度: {$progress}% ({$res}/{$total_buckets}) +msg-813384e2 = 迁移平台统计数据失败: {$platform_id}, {$platform_type}, 时间戳: {$bucket_end} +msg-27ab191d = 成功迁移 {$res} 条旧的平台数据到新表。 +msg-8e6280ed = 迁移 {$total_cnt} 条旧的 WebChat 会话数据到新的表中... +msg-cad66fe1 = 迁移旧 WebChat 会话 {$res} 失败 +msg-63748a46 = 成功迁移 {$total_cnt} 条旧的 WebChat 会话数据到新表。 +msg-dfc93fa4 = 迁移 {$total_personas} 个 Persona 配置到新表中... +msg-ff85e45c = 进度: {$progress}% ({$res}/{$total_personas}) +msg-c346311e = 迁移 Persona {$res}({$res_2}...) 到新表成功。 +msg-b6292b94 = 解析 Persona 配置失败:{$e} +msg-90e5039e = 迁移全局偏好设置 {$key} 成功,值: {$value} +msg-d538da1c = 迁移会话 {$umo} 的对话数据到新表成功,平台 ID: {$platform_id} +msg-ee03c001 = 迁移会话 {$umo} 的对话数据失败: {$e} +msg-5c4339cd = 迁移会话 {$umo} 的服务配置到新表成功,平台 ID: {$platform_id} +msg-4ce2a0b2 = 迁移会话 {$umo} 的服务配置失败: {$e} +msg-2e62dab9 = 迁移会话 {$umo} 的变量失败: {$e} +msg-afbf819e = 迁移会话 {$umo} 的提供商偏好到新表成功,平台 ID: {$platform_id} +msg-959bb068 = 迁移会话 {$umo} 的提供商偏好失败: {$e} + +### astrbot/core/db/migration/helper.py +msg-a48f4752 = 开始执行数据库迁移... +msg-45e31e8e = 数据库迁移完成。 + +### astrbot/core/db/migration/migra_45_to_46.py +msg-782b01c1 = migrate_45_to_46: abconf_data is not a dict (type={$res}). Value: {$abconf_data} +msg-49e09620 = Starting migration from version 4.5 to 4.6 +msg-791b79f8 = Migration from version 45 to 46 completed successfully + +### astrbot/core/db/migration/migra_webchat_session.py +msg-53fad3d0 = 开始执行数据库迁移(WebChat 会话迁移)... +msg-7674efb0 = 没有找到需要迁移的 WebChat 数据 +msg-139e39ee = 找到 {$res} 个 WebChat 会话需要迁移 +msg-cf287e58 = 会话 {$session_id} 已存在,跳过 +msg-062c72fa = WebChat 会话迁移完成!成功迁移: {$res}, 跳过: {$skipped_count} +msg-a516cc9f = 没有新会话需要迁移 +msg-91571aaf = 迁移过程中发生错误: {$e} + +### astrbot/core/knowledge_base/kb_helper.py +msg-7b3dc642 = - LLM call failed on attempt {$res}/{$res_2}. Error: {$res_3} +msg-4ba9530f = - Failed to process chunk after {$res} attempts. Using original text. +msg-77670a3a = 知识库 {$res} 未配置 Embedding Provider +msg-8e9eb3f9 = 无法找到 ID 为 {$res} 的 Embedding Provider +msg-3e426806 = 无法找到 ID 为 {$res} 的 Rerank Provider +msg-6e780e1e = 使用预分块文本进行上传,共 {$res} 个块。 +msg-f4b82f18 = 当未提供 pre_chunked_text 时,file_content 不能为空。 +msg-975f06d7 = 上传文档失败: {$e} +msg-969b17ca = 清理多媒体文件失败 {$media_path}: {$me} +msg-18d25e55 = 无法找到 ID 为 {$doc_id} 的文档 +msg-f5d7c34c = Error: Tavily API key is not configured in provider_settings. +msg-975d88e0 = Failed to extract content from URL {$url}: {$e} +msg-cfe431b3 = No content extracted from URL: {$url} +msg-e7f5f836 = 内容清洗后未提取到有效文本。请尝试关闭内容清洗功能,或更换更高性能的LLM模型后重试。 +msg-693aa5c5 = 内容清洗未启用,使用指定参数进行分块: chunk_size={$chunk_size}, chunk_overlap={$chunk_overlap} +msg-947d8f46 = 启用了内容清洗,但未提供 cleaning_provider_id,跳过清洗并使用默认分块。 +msg-31963d3f = 无法找到 ID 为 {$cleaning_provider_id} 的 LLM Provider 或类型不正确 +msg-82728272 = 初步分块完成,生成 {$res} 个块用于修复。 +msg-6fa5fdca = 块 {$i} 处理异常: {$res}. 回退到原始块。 +msg-6780e950 = 文本修复完成: {$res} 个原始块 -> {$res_2} 个最终块。 +msg-79056c76 = 使用 Provider '{$cleaning_provider_id}' 清洗内容失败: {$e} + +### astrbot/core/knowledge_base/kb_mgr.py +msg-98bfa670 = 正在初始化知识库模块... +msg-7da7ae15 = 知识库模块导入失败: {$e} +msg-842a3c65 = 请确保已安装所需依赖: pypdf, aiofiles, Pillow, rank-bm25 +msg-c9e943f7 = 知识库模块初始化失败: {$e} +msg-78b9c276 = {$res} +msg-9349e112 = KnowledgeBase database initialized: {$DB_PATH} +msg-7605893e = 创建知识库时必须提供embedding_provider_id +msg-0b632cbd = 知识库名称 '{$kb_name}' 已存在 +msg-ca30330f = 关闭知识库 {$kb_id} 失败: {$e} +msg-00262e1f = 关闭知识库元数据数据库失败: {$e} +msg-3fc9ef0b = Knowledge base with id {$kb_id} not found. + +### astrbot/core/knowledge_base/kb_db_sqlite.py +msg-b850e5d8 = 知识库数据库已关闭: {$res} + +### astrbot/core/knowledge_base/parsers/util.py +msg-398b3580 = 暂时不支持的文件格式: {$ext} + +### astrbot/core/knowledge_base/parsers/url_parser.py +msg-2de85bf5 = Error: Tavily API keys are not configured. +msg-98ed69f4 = Error: url must be a non-empty string. +msg-7b14cdb7 = Tavily web extraction failed: {$reason}, status: {$res} +msg-cfe431b3 = No content extracted from URL: {$url} +msg-b0897365 = Failed to fetch URL {$url}: {$e} +msg-975d88e0 = Failed to extract content from URL {$url}: {$e} + +### astrbot/core/knowledge_base/parsers/text_parser.py +msg-70cbd40d = 无法解码文件: {$file_name} + +### astrbot/core/knowledge_base/chunking/recursive.py +msg-21db456a = chunk_size must be greater than 0 +msg-c0656f4e = chunk_overlap must be non-negative +msg-82bd199c = chunk_overlap must be less than chunk_size + +### astrbot/core/knowledge_base/retrieval/manager.py +msg-fcc0dde2 = 知识库 ID {$kb_id} 实例未找到, 已跳过该知识库的检索 +msg-320cfcff = Dense retrieval across {$res} bases took {$res_2}s and returned {$res_3} results. +msg-90ffcfc8 = Sparse retrieval across {$res} bases took {$res_2}s and returned {$res_3} results. +msg-12bcf404 = Rank fusion took {$res}s and returned {$res_2} results. +msg-28c084bc = vec_db for kb_id {$kb_id} is not FaissVecDB +msg-cc0230a3 = 知识库 {$kb_id} 稠密检索失败: {$e} + +### astrbot/core/skills/skill_manager.py +msg-ed9670ad = Zip file not found: {$zip_path} +msg-73f9cf65 = Uploaded file is not a valid zip archive. +msg-69eb5f95 = Zip archive is empty. +msg-9e9abb4c = {$top_dirs} +msg-20b8533f = Zip archive must contain a single top-level folder. +msg-1db1caf7 = Invalid skill folder name. +msg-d7814054 = Zip archive contains absolute paths. +msg-179bd10e = Zip archive contains invalid relative paths. +msg-90f2904e = Zip archive contains unexpected top-level entries. +msg-95775a4d = SKILL.md not found in the skill folder. +msg-a4117c0b = Skill folder not found after extraction. +msg-94041ef2 = Skill already exists. + +### astrbot/core/backup/importer.py +msg-c046b6e4 = {$msg} +msg-0e6f1f5d = 开始从 {$zip_path} 导入备份 +msg-2bf97ca0 = 备份导入完成: {$res} +msg-e67dda98 = 备份文件缺少版本信息 +msg-8f871d9f = 版本差异警告: {$res} +msg-2d6da12a = 已清空表 {$table_name} +msg-7d21b23a = 清空表 {$table_name} 失败: {$e} +msg-ab0f09db = 已清空知识库表 {$table_name} +msg-7bcdfaee = 清空知识库表 {$table_name} 失败: {$e} +msg-43f008f1 = 清理知识库 {$kb_id} 失败: {$e} +msg-985cae66 = 未知的表: {$table_name} +msg-dfa8b605 = 导入记录到 {$table_name} 失败: {$e} +msg-89a2120c = 导入表 {$table_name}: {$count} 条记录 +msg-f1dec753 = 导入知识库记录到 {$table_name} 失败: {$e} +msg-9807bcd8 = 导入文档块失败: {$e} +msg-98a66293 = 导入附件 {$name} 失败: {$e} +msg-39f2325f = 备份版本不支持目录备份,跳过目录导入 +msg-689050b6 = 已备份现有目录 {$target_dir} 到 {$backup_path} +msg-d51b3536 = 导入目录 {$dir_name}: {$file_count} 个文件 + +### astrbot/core/backup/exporter.py +msg-c7ed7177 = 开始导出备份到 {$zip_path} +msg-8099b694 = 备份导出完成: {$zip_path} +msg-75a4910d = 备份导出失败: {$e} +msg-2821fc92 = 导出表 {$table_name}: {$res} 条记录 +msg-52b7c242 = 导出表 {$table_name} 失败: {$e} +msg-56310830 = 导出知识库表 {$table_name}: {$res} 条记录 +msg-f4e8f57e = 导出知识库表 {$table_name} 失败: {$e} +msg-8e4ddd12 = 导出知识库文档失败: {$e} +msg-c1960618 = 导出 FAISS 索引: {$archive_path} +msg-314bf920 = 导出 FAISS 索引失败: {$e} +msg-528757b2 = 导出知识库媒体文件失败: {$e} +msg-d89d6dfe = 目录不存在,跳过: {$full_path} +msg-94527edd = 导出文件 {$file_path} 失败: {$e} +msg-cb773e24 = 导出目录 {$dir_name}: {$file_count} 个文件, {$total_size} 字节 +msg-ae929510 = 导出目录 {$dir_path} 失败: {$e} +msg-93e331d2 = 导出附件失败: {$e} + +### astrbot/core/computer/computer_client.py +msg-7cb974b8 = Uploading skills bundle to sandbox... +msg-130cf3e3 = Failed to upload skills bundle to sandbox. +msg-99188d69 = Failed to remove temp skills zip: {$zip_path} +msg-3f3c81da = Unknown booter type: {$booter_type} +msg-e20cc33a = Error booting sandbox for session {$session_id}: {$e} + +### astrbot/core/computer/tools/fs.py +msg-99ab0efe = Upload result: {$result} +msg-bca9d578 = File {$local_path} uploaded to sandbox at {$file_path} +msg-da21a6a5 = Error uploading file {$local_path}: {$e} +msg-93476abb = File {$remote_path} downloaded from sandbox to {$local_path} +msg-079c5972 = Error sending file message: {$e} +msg-ce35bb2c = Error downloading file {$remote_path}: {$e} + +### astrbot/core/computer/booters/local.py +msg-487d0c91 = Path is outside the allowed computer roots. +msg-e5eb5377 = Blocked unsafe shell command. +msg-9e1e117f = Local computer booter initialized for session: {$session_id} +msg-2d7f95de = Local computer booter shutdown complete. +msg-82a45196 = LocalBooter does not support upload_file operation. Use shell instead. +msg-0457524a = LocalBooter does not support download_file operation. Use shell instead. + +### astrbot/core/computer/booters/shipyard.py +msg-b03115b0 = Got sandbox ship: {$res} for session: {$session_id} +msg-c5ce8bde = Error checking Shipyard sandbox availability: {$e} + +### astrbot/core/computer/booters/boxlite.py +msg-019c4d18 = Failed to exec operation: {$res} {$error_text} +msg-b135b7bd = Failed to upload file: {$e} +msg-873ed1c8 = File not found: {$path} +msg-f58ceec6 = Unexpected error uploading file: {$e} +msg-900ab999 = Checking health for sandbox {$ship_id} on {$res}... +msg-2a50d6f3 = Sandbox {$ship_id} is healthy +msg-fbdbe32f = Booting(Boxlite) for session: {$session_id}, this may take a while... +msg-b1f13f5f = Boxlite booter started for session: {$session_id} +msg-e93d0c30 = Shutting down Boxlite booter for ship: {$res} +msg-6deea473 = Boxlite booter for ship: {$res} stopped + +### astrbot/core/cron/manager.py +msg-724e64a9 = Skip scheduling basic cron job %s due to missing handler. +msg-78ef135f = Invalid timezone %s for cron job %s, fallback to system. +msg-e71c28d3 = run_once job missing run_at timestamp +msg-dd46e69f = Failed to schedule cron job {$res}: {$e} +msg-aa2e4688 = Unknown cron job type: {$res} +msg-186627d9 = Cron job {$job_id} failed: {$e} +msg-cb955de0 = Basic cron job handler not found for {$res} +msg-2029c4b2 = ActiveAgentCronJob missing session. +msg-6babddc9 = Invalid session for cron job: {$e} +msg-865a2b07 = Failed to build main agent for cron job. +msg-27c9c6b3 = Cron job agent got no response + +### astrbot/utils/http_ssl_common.py +msg-7957c9b6 = Failed to load certifi CA bundle into SSL context; falling back to system trust store only: %s + +### astrbot/cli/__main__.py +msg-fe494da6 = {$logo_tmpl} +msg-c8b2ff67 = Welcome to AstrBot CLI! +msg-d79e1ff9 = AstrBot CLI version: {$__version__} +msg-78b9c276 = {$res} +msg-14dd710d = Unknown command: {$command_name} + +### astrbot/cli/utils/basic.py +msg-f4e0fd7b = 未安装管理面板 +msg-2d090cc3 = 正在安装管理面板... +msg-2eeb67e0 = 管理面板安装完成 +msg-9c727dca = 管理面板已是最新版本 +msg-11b49913 = 管理面板版本: {$version} +msg-f0b6145e = 下载管理面板失败: {$e} +msg-9504d173 = 初始化管理面板目录... +msg-699e2509 = 管理面板初始化完成 + +### astrbot/cli/utils/plugin.py +msg-e327bc14 = 正在从默认分支下载 {$author}/{$repo} +msg-c804f59f = 获取 release 信息失败: {$e},将直接使用提供的 URL +msg-aa398bd5 = master 分支不存在,尝试下载 main 分支 +msg-5587d9fb = 读取 {$yaml_path} 失败: {$e} +msg-8dbce791 = 获取在线插件列表失败: {$e} +msg-6999155d = 插件 {$plugin_name} 未安装,无法更新 +msg-fa5e129a = 正在从 {$repo_url} {$res}插件 {$plugin_name}... +msg-9ac1f4db = 插件 {$plugin_name} {$res}成功 +msg-b9c719ae = {$res}插件 {$plugin_name} 时出错: {$e} + +### astrbot/cli/commands/cmd_conf.py +msg-635b8763 = 日志级别必须是 DEBUG/INFO/WARNING/ERROR/CRITICAL 之一 +msg-ebc250dc = 端口必须在 1-65535 范围内 +msg-6ec400b6 = 端口必须是数字 +msg-0b62b5ce = 用户名不能为空 +msg-89b5d3d5 = 密码不能为空 +msg-92e7c8ad = 无效的时区: {$value},请使用有效的IANA时区名称 +msg-e470e37d = 回调接口基址必须以 http:// 或 https:// 开头 +msg-6b615721 = {$root}不是有效的 AstrBot 根目录,如需初始化请使用 astrbot init +msg-f74c517c = 配置文件解析失败: {$e} +msg-d7c58bcc = 配置路径冲突: {$res} 不是字典 +msg-e16816cc = 不支持的配置项: {$key} +msg-e9cce750 = 配置已更新: {$key} +msg-1ed565aa = 原值: ******** +msg-1bf9569a = 新值: ******** +msg-f2a20ab3 = 原值: {$old_value} +msg-0c104905 = 新值: {$validated_value} +msg-ea9b4e2c = 未知的配置项: {$key} +msg-4450e3b1 = 设置配置失败: {$e} +msg-ba464bee = {$key}: {$value} +msg-72aab576 = 获取配置失败: {$e} +msg-c1693d1d = 当前配置: +msg-50be9b74 = {$key}: {$value} + +### astrbot/cli/commands/cmd_init.py +msg-a90a250e = Current Directory: {$astrbot_root} +msg-4deda62e = 如果你确认这是 Astrbot root directory, 你需要在当前目录下创建一个 .astrbot 文件标记该目录为 AstrBot 的数据目录。 +msg-3319bf71 = Created {$dot_astrbot} +msg-7054f44f = {$res}: {$path} +msg-b19edc8a = Initializing AstrBot... +msg-eebc39e3 = 无法获取锁文件,请检查是否有其他实例正在运行 +msg-e16da80f = 初始化失败: {$e} + +### astrbot/cli/commands/cmd_run.py +msg-41ecc632 = {$astrbot_root}不是有效的 AstrBot 根目录,如需初始化请使用 astrbot init +msg-0ccaca23 = 启用插件自动重载 +msg-220914e7 = AstrBot 已关闭... +msg-eebc39e3 = 无法获取锁文件,请检查是否有其他实例正在运行 +msg-85f241d3 = 运行时出现错误: {$e}{"\u000A"}{$res} + +### astrbot/cli/commands/cmd_plug.py +msg-cbd8802b = {$base}不是有效的 AstrBot 根目录,如需初始化请使用 astrbot init +msg-78b9c276 = {$res} +msg-83664fcf = {$val} {$val} {$val} {$val} {$val} +msg-56f3f0bf = {$res} {$res_2} {$res_3} {$res_4} {$desc} +msg-1d802ff2 = 插件 {$name} 已存在 +msg-a7be9d23 = 版本号必须为 x.y 或 x.y.z 格式 +msg-4d81299b = 仓库地址必须以 http 开头 +msg-93289755 = 下载插件模板... +msg-b21682dd = 重写插件信息... +msg-bffc8bfa = 插件 {$name} 创建成功 +msg-08eae1e3 = 未安装任何插件 +msg-1a021bf4 = 未找到可安装的插件 {$name},可能是不存在或已安装 +msg-c120bafd = 插件 {$name} 不存在或未安装 +msg-63da4867 = 插件 {$name} 已卸载 +msg-e4925708 = 卸载插件 {$name} 失败: {$e} +msg-f4d15a87 = 插件 {$name} 不需要更新或无法更新 +msg-94b035f7 = 没有需要更新的插件 +msg-0766d599 = 发现 {$res} 个插件需要更新 +msg-bd5ab99c = 正在更新插件 {$plugin_name}... +msg-e32912b8 = 未找到匹配 '{$query}' 的插件 + +### astrbot/dashboard/server.py +msg-e88807e2 = 未找到该路由 +msg-06151c57 = Missing API key +msg-88dca3cc = Invalid API key +msg-fd267dc8 = Insufficient API key scope +msg-076fb3a3 = 未授权 +msg-6f214cc1 = Token 过期 +msg-5041dc95 = Token 无效 +msg-1241c883 = 检查端口 {$port} 时发生错误: {$e} +msg-7c3ba89d = Initialized random JWT secret for dashboard. +msg-a3adcb66 = WebUI 已被禁用 +msg-44832296 = 正在启动 WebUI, 监听地址: {$scheme}://{$host}:{$port} +msg-3eed4a73 = 提示: WebUI 将监听所有网络接口,请注意安全。(可在 data/cmd_config.json 中配置 dashboard.host 以修改 host) +msg-289a2fe8 = 错误:端口 {$port} 已被占用{"\u000A"}占用信息: {"\u000A"} {$process_info}{"\u000A"}请确保:{"\u000A"}1. 没有其他 AstrBot 实例正在运行{"\u000A"}2. 端口 {$port} 没有被其他程序占用{"\u000A"}3. 如需使用其他端口,请修改配置文件 +msg-6d1dfba8 = 端口 {$port} 已被占用 +msg-c0161c7c = {$display} +msg-ac4f2855 = dashboard.ssl.enable 为 true 时,必须配置 cert_file 和 key_file。 +msg-3e87aaf8 = SSL 证书文件不存在: {$cert_path} +msg-5ccf0a9f = SSL 私钥文件不存在: {$key_path} +msg-5e4aa3eb = SSL CA 证书文件不存在: {$ca_path} +msg-cb049eb2 = AstrBot WebUI 已经被优雅地关闭 + +### astrbot/dashboard/utils.py +msg-160bd44a = 缺少必要的库以生成 t-SNE 可视化。请安装 matplotlib 和 scikit-learn: {e} +msg-aa3a3dbf = 未找到知识库 +msg-0e404ea3 = FAISS 索引不存在: {$index_path} +msg-8d92420c = 索引为空 +msg-24c0450e = 提取 {$res} 个向量用于可视化... +msg-632d0acf = 开始 t-SNE 降维... +msg-61f0449f = 生成可视化图表... +msg-4436ad2b = 生成 t-SNE 可视化时出错: {$e} +msg-78b9c276 = {$res} + +### astrbot/dashboard/routes/update.py +msg-a3503781 = 迁移失败: {$res} +msg-543d8e4d = 迁移失败: {$e} +msg-251a5f4a = 检查更新失败: {$e} (不影响除项目更新外的正常使用) +msg-aa6bff26 = /api/update/releases: {$res} +msg-c5170c27 = 下载管理面板文件失败: {$e}。 +msg-db715c26 = 更新依赖中... +msg-9a00f940 = 更新依赖失败: {$e} +msg-6f96e3ba = /api/update_project: {$res} +msg-3217b509 = 下载管理面板文件失败: {$e} +msg-9cff28cf = /api/update_dashboard: {$res} +msg-1198c327 = You are not permitted to do this operation in demo mode +msg-38e60adf = 缺少参数 package 或不合法。 +msg-a1191473 = /api/update_pip: {$res} + +### astrbot/dashboard/routes/lang_route.py +msg-0d18aac8 = [LangRoute] lang:{$lang} +msg-bf610e68 = lang 为必填参数。 + +### astrbot/dashboard/routes/auth.py +msg-ee9cf260 = 为了保证安全,请尽快修改默认密码。 +msg-87f936b8 = 用户名或密码错误 +msg-1198c327 = You are not permitted to do this operation in demo mode +msg-25562cd3 = 原密码错误 +msg-d31087d2 = 新用户名和新密码不能同时为空 +msg-b512c27e = 两次输入的新密码不一致 +msg-7b947d8b = JWT secret is not set in the cmd_config. + +### astrbot/dashboard/routes/backup.py +msg-6920795d = 清理过期的上传会话: {$upload_id} +msg-3e96548d = 清理过期上传会话失败: {$e} +msg-259677a9 = 清理分片目录失败: {$e} +msg-d7263882 = 读取备份 manifest 失败: {$e} +msg-40f76598 = 跳过无效备份文件: {$filename} +msg-18a49bfc = 获取备份列表失败: {$e} +msg-78b9c276 = {$res} +msg-6e08b5a5 = 创建备份失败: {$e} +msg-9cce1032 = 后台导出任务 {$task_id} 失败: {$e} +msg-55927ac1 = 缺少备份文件 +msg-374cab8a = 请上传 ZIP 格式的备份文件 +msg-d53d6730 = 上传的备份文件已保存: {$unique_filename} (原始名称: {$res}) +msg-98e64c7f = 上传备份文件失败: {$e} +msg-49c3b432 = 缺少 filename 参数 +msg-df33d307 = 无效的文件大小 +msg-162ad779 = 初始化分片上传: upload_id={$upload_id}, filename={$unique_filename}, total_chunks={$total_chunks} +msg-de676924 = 初始化分片上传失败: {$e} +msg-eecf877c = 缺少必要参数 +msg-f175c633 = 无效的分片索引 +msg-ad865497 = 缺少分片数据 +msg-947c2d56 = 上传会话不存在或已过期 +msg-f3a464a5 = 分片索引超出范围 +msg-7060da1d = 接收分片: upload_id={$upload_id}, chunk={$res}/{$total_chunks} +msg-06c107c1 = 上传分片失败: {$e} +msg-f040b260 = 已标记备份为上传来源: {$zip_path} +msg-559c10a8 = 标记备份来源失败: {$e} +msg-d1d752ef = 缺少 upload_id 参数 +msg-390ed49a = 分片不完整,缺少: {$res}... +msg-8029086a = 分片上传完成: {$filename}, size={$file_size}, chunks={$total} +msg-4905dde5 = 完成分片上传失败: {$e} +msg-b63394b1 = 取消分片上传: {$upload_id} +msg-2b39da46 = 取消上传失败: {$e} +msg-f12b1f7a = 无效的文件名 +msg-44bb3b89 = 备份文件不存在: {$filename} +msg-b005980b = 预检查备份文件失败: {$e} +msg-65b7ede1 = 请先确认导入。导入将会清空并覆盖现有数据,此操作不可撤销。 +msg-b152e4bf = 导入备份失败: {$e} +msg-5e7f1683 = 后台导入任务 {$task_id} 失败: {$e} +msg-6906aa65 = 缺少参数 task_id +msg-5ea3d72c = 找不到该任务 +msg-f0901aef = 获取任务进度失败: {$e} +msg-8d23792b = 缺少参数 filename +msg-4188ede6 = 缺少参数 token +msg-0c708312 = 服务器配置错误 +msg-cc228d62 = Token 已过期,请刷新页面后重试 +msg-5041dc95 = Token 无效 +msg-96283fc5 = 备份文件不存在 +msg-00aacbf8 = 下载备份失败: {$e} +msg-3ea8e256 = 删除备份失败: {$e} +msg-e4a57714 = 缺少参数 new_name +msg-436724bb = 新文件名无效 +msg-9f9d8558 = 文件名 '{$new_filename}' 已存在 +msg-a5fda312 = 备份文件重命名: {$filename} -> {$new_filename} +msg-e7c82339 = 重命名备份失败: {$e} + +### astrbot/dashboard/routes/command.py +msg-1d47363b = handler_full_name 与 enabled 均为必填。 +msg-35374718 = handler_full_name 与 new_name 均为必填。 +msg-f879f2f4 = handler_full_name 与 permission 均为必填。 + +### astrbot/dashboard/routes/subagent.py +msg-78b9c276 = {$res} +msg-eda47201 = 获取 subagent 配置失败: {$e} +msg-3e5b1fe0 = 配置必须为 JSON 对象 +msg-9f285dd3 = 保存 subagent 配置失败: {$e} +msg-665f4751 = 获取可用工具失败: {$e} + +### astrbot/dashboard/routes/config.py +msg-680e7347 = 配置项 {$path}{$key} 没有类型定义, 跳过校验 +msg-ef2e5902 = Saving config, is_core={$is_core} +msg-78b9c276 = {$res} +msg-acef166d = 验证配置时出现异常: {$e} +msg-42f62db0 = 格式校验未通过: {$errors} +msg-3e668849 = 缺少配置数据 +msg-196b9b25 = 缺少 provider_source_id +msg-dbbbc375 = 未找到对应的 provider source +msg-a77f69f4 = 缺少 original_id +msg-96f154c4 = 缺少或错误的配置数据 +msg-c80b2c0f = Provider source ID '{$res}' exists already, please try another ID. +msg-537b700b = 缺少或错误的路由表数据 +msg-b5079e61 = 更新路由表失败: {$e} +msg-cf97d400 = 缺少 UMO 或配置文件 ID +msg-2a05bc8d = 缺少 UMO +msg-7098aa3f = 删除路由表项失败: {$e} +msg-902aedc3 = 缺少配置文件 ID +msg-b9026977 = abconf_id cannot be None +msg-acf0664a = 删除失败 +msg-59c93c1a = 删除配置文件失败: {$e} +msg-930442e2 = 更新失败 +msg-7375d4dc = 更新配置文件失败: {$e} +msg-53a8fdb2 = Attempting to check provider: {$res} (ID: {$res_2}, Type: {$res_3}, Model: {$res_4}) +msg-8b0a48ee = Provider {$res} (ID: {$res_2}) is available. +msg-7c7180a7 = Provider {$res} (ID: {$res_2}) is unavailable. Error: {$error_message} +msg-1298c229 = Traceback for {$res}:{"\u000A"}{$res_2} +msg-d7f9a42f = {$message} +msg-cd303a28 = API call: /config/provider/check_one id={$provider_id} +msg-55b8107a = Provider with id '{$provider_id}' not found in provider_manager. +msg-d1a98a9b = Provider with id '{$provider_id}' not found +msg-cb9c402c = 缺少参数 provider_type +msg-e092d4ee = 缺少参数 provider_id +msg-1ff28fed = 未找到 ID 为 {$provider_id} 的提供商 +msg-92347c35 = 提供商 {$provider_id} 类型不支持获取模型列表 +msg-d0845a10 = 缺少参数 provider_config +msg-5657fea4 = provider_config 缺少 type 字段 +msg-09ed9dc7 = 提供商适配器加载失败,请检查提供商类型配置或查看服务端日志 +msg-1cce1cd4 = 未找到适用于 {$provider_type} 的提供商适配器 +msg-8361e44d = 无法找到 {$provider_type} 的类 +msg-4325087c = 提供商不是 EmbeddingProvider 类型 +msg-a9873ea4 = 检测到 {$res} 的嵌入向量维度为 {$dim} +msg-d170e384 = 获取嵌入维度失败: {$e} +msg-abfeda72 = 缺少参数 source_id +msg-0384f4c9 = 未找到 ID 为 {$provider_source_id} 的 provider_source +msg-aec35bdb = provider_source 缺少 type 字段 +msg-cbb9d637 = 动态导入提供商适配器失败: {$e} +msg-468f64b3 = 提供商 {$provider_type} 不支持获取模型列表 +msg-cb07fc1c = 获取到 provider_source {$provider_source_id} 的模型列表: {$models} +msg-d2f6e16d = 获取模型列表失败: {$e} +msg-25ea8a96 = Unsupported scope: {$scope} +msg-23c8933f = Missing name or key parameter +msg-536e77ae = Plugin {$name} not found or has no config +msg-1b6bc453 = Config item not found or not file type +msg-fc0a457e = No files uploaded +msg-31c718d7 = Invalid name parameter +msg-e1edc16e = Missing name parameter +msg-8e634b35 = Invalid path parameter +msg-0b52a254 = Plugin {$name} not found +msg-bff0e837 = 参数错误 +msg-2f29d263 = 机器人名称不允许修改 +msg-1478800f = 未找到对应平台 +msg-ca6133f7 = 缺少参数 id +msg-1199c1f9 = Using cached logo token for platform {$res} +msg-889a7de5 = Platform class not found for {$res} +msg-317f359c = Logo token registered for platform {$res} +msg-323ec1e2 = Platform {$res} logo file not found: {$logo_file_path} +msg-bc6d0bcf = Failed to import required modules for platform {$res}: {$e} +msg-b02b538d = File system error for platform {$res} logo: {$e} +msg-31123607 = Unexpected error registering logo for platform {$res}: {$e} +msg-af06ccab = 配置文件 {$conf_id} 不存在 +msg-082a5585 = 插件 {$plugin_name} 不存在 +msg-ca334960 = 插件 {$plugin_name} 没有注册配置 + +### astrbot/dashboard/routes/knowledge_base.py +msg-ce669289 = 上传文档 {$res} 失败: {$e} +msg-87e99c2d = 后台上传任务 {$task_id} 失败: {$e} +msg-78b9c276 = {$res} +msg-d5355233 = 导入文档 {$file_name} 失败: {$e} +msg-5e7f1683 = 后台导入任务 {$task_id} 失败: {$e} +msg-e1949850 = 获取知识库列表失败: {$e} +msg-299af36d = 知识库名称不能为空 +msg-faf380ec = 缺少参数 embedding_provider_id +msg-9015b689 = 嵌入模型不存在或类型错误({$res}) +msg-a63b3aa9 = 嵌入向量维度不匹配,实际是 {$res},然而配置是 {$res_2} +msg-9b281e88 = 测试嵌入模型失败: {$e} +msg-d3fb6072 = 重排序模型不存在 +msg-fbec0dfd = 重排序模型返回结果异常 +msg-872feec8 = 测试重排序模型失败: {$e},请检查平台日志输出。 +msg-a4ac0b9e = 创建知识库失败: {$e} +msg-c8d487e9 = 缺少参数 kb_id +msg-978b3c73 = 知识库不存在 +msg-2137a3e6 = 获取知识库详情失败: {$e} +msg-e7cf9cfd = 至少需要提供一个更新字段 +msg-d3d82c22 = 更新知识库失败: {$e} +msg-5d5d4090 = 删除知识库失败: {$e} +msg-787a5dea = 获取知识库统计失败: {$e} +msg-97a2d918 = 获取文档列表失败: {$e} +msg-b170e0fa = Content-Type 须为 multipart/form-data +msg-5afbfa8e = 缺少文件 +msg-6636fd31 = 最多只能上传10个文件 +msg-975f06d7 = 上传文档失败: {$e} +msg-35bacf60 = 缺少参数 documents 或格式错误 +msg-6cc1edcd = 文档格式错误,必须包含 file_name 和 chunks +msg-376d7d5f = chunks 必须是列表 +msg-e7e2f311 = chunks 必须是非空字符串列表 +msg-42315b8d = 导入文档失败: {$e} +msg-6906aa65 = 缺少参数 task_id +msg-5ea3d72c = 找不到该任务 +msg-194def99 = 获取上传进度失败: {$e} +msg-df6ec98e = 缺少参数 doc_id +msg-7c3cfe22 = 文档不存在 +msg-b54ab822 = 获取文档详情失败: {$e} +msg-0ef7f633 = 删除文档失败: {$e} +msg-2fe40cbd = 缺少参数 chunk_id +msg-fc13d42a = 删除文本块失败: {$e} +msg-4ef8315b = 获取块列表失败: {$e} +msg-b70a1816 = 缺少参数 query +msg-82ee646e = 缺少参数 kb_names 或格式错误 +msg-07a61a9a = 生成 t-SNE 可视化失败: {$e} +msg-20a3b3f7 = 检索失败: {$e} +msg-1b76f5ab = 缺少参数 url +msg-5dc86dc6 = 从URL上传文档失败: {$e} +msg-890b3dee = 后台上传URL任务 {$task_id} 失败: {$e} + +### astrbot/dashboard/routes/skills.py +msg-78b9c276 = {$res} +msg-1198c327 = You are not permitted to do this operation in demo mode +msg-52430f2b = Missing file +msg-2ad598f3 = Only .zip files are supported +msg-a11f2e1c = Failed to remove temp skill file: {$temp_path} +msg-67367a6d = Missing skill name + +### astrbot/dashboard/routes/live_chat.py +msg-40f242d5 = [Live Chat] {$res} 开始说话 stamp={$stamp} +msg-a168d76d = [Live Chat] stamp 不匹配或未在说话状态: {$stamp} vs {$res} +msg-e01b2fea = [Live Chat] 没有音频帧数据 +msg-33856925 = [Live Chat] 音频文件已保存: {$audio_path}, 大小: {$res} bytes +msg-9e9b7e59 = [Live Chat] 组装 WAV 文件失败: {$e} +msg-21430f56 = [Live Chat] 已删除临时文件: {$res} +msg-6b4f88bc = [Live Chat] 删除临时文件失败: {$e} +msg-0849d043 = [Live Chat] WebSocket 连接建立: {$username} +msg-5477338a = [Live Chat] WebSocket 错误: {$e} +msg-fdbfdba8 = [Live Chat] WebSocket 连接关闭: {$username} +msg-7be90ac0 = [Live Chat] start_speaking 缺少 stamp +msg-8215062a = [Live Chat] 解码音频数据失败: {$e} +msg-438980ea = [Live Chat] end_speaking 缺少 stamp +msg-b35a375c = [Live Chat] 用户打断: {$res} +msg-2c3e7bbc = [Live Chat] STT Provider 未配置 +msg-0582c8ba = [Live Chat] STT 识别结果为空 +msg-57c2b539 = [Live Chat] STT 结果: {$user_text} +msg-6b7628c6 = [Live Chat] 检测到用户打断 +msg-2cab2269 = [Live Chat] 消息 ID 不匹配: {$result_message_id} != {$message_id} +msg-74c2470e = [Live Chat] 解析 AgentStats 失败: {$e} +msg-4738a2b3 = [Live Chat] 解析 TTSStats 失败: {$e} +msg-944d5022 = [Live Chat] 开始播放音频流 +msg-009104d8 = [Live Chat] Bot 回复完成: {$bot_text} +msg-0c4c3051 = [Live Chat] 处理音频失败: {$e} +msg-140caa36 = [Live Chat] 保存打断消息: {$interrupted_text} +msg-869f51ea = [Live Chat] 用户消息: {$user_text} (session: {$res}, ts: {$timestamp}) +msg-d26dee52 = [Live Chat] Bot 消息(打断): {$interrupted_text} (session: {$res}, ts: {$timestamp}) +msg-1377f378 = [Live Chat] 记录消息失败: {$e} + +### astrbot/dashboard/routes/log.py +msg-5bf500c1 = Log SSE 补发历史错误: {$e} +msg-e4368397 = Log SSE 连接错误: {$e} +msg-547abccb = 获取日志历史失败: {$e} +msg-cb5d4ebb = 获取 Trace 设置失败: {$e} +msg-7564d3b0 = 请求数据为空 +msg-d2a1cd76 = 更新 Trace 设置失败: {$e} + +### astrbot/dashboard/routes/conversation.py +msg-62392611 = 数据库查询出错: {$e}{"\u000A"}{$res} +msg-b21b052b = 数据库查询出错: {$e} +msg-10f72727 = {$error_msg} +msg-036e6190 = 获取对话列表失败: {$e} +msg-a16ba4b4 = 缺少必要参数: user_id 和 cid +msg-9a1fcec9 = 对话不存在 +msg-73a8a217 = 获取对话详情失败: {$e}{"\u000A"}{$res} +msg-976cd580 = 获取对话详情失败: {$e} +msg-c193b9c4 = 更新对话信息失败: {$e}{"\u000A"}{$res} +msg-9f96c4ee = 更新对话信息失败: {$e} +msg-e1cb0788 = 批量删除时conversations参数不能为空 +msg-38e3c4ba = 删除对话失败: {$e}{"\u000A"}{$res} +msg-ebf0371a = 删除对话失败: {$e} +msg-af54ee29 = 缺少必要参数: history +msg-b72552c8 = history 必须是有效的 JSON 字符串或数组 +msg-fdf757f3 = 更新对话历史失败: {$e}{"\u000A"}{$res} +msg-33762429 = 更新对话历史失败: {$e} +msg-498f11f8 = 导出列表不能为空 +msg-98aa3644 = 导出对话失败: user_id={$user_id}, cid={$cid}, error={$e} +msg-ed77aa37 = 没有成功导出任何对话 +msg-f07b18ee = 批量导出对话失败: {$e}{"\u000A"}{$res} +msg-85dc73fa = 批量导出对话失败: {$e} + +### astrbot/dashboard/routes/cron.py +msg-fb5b419b = Cron manager not initialized +msg-78b9c276 = {$res} +msg-112659e5 = Failed to list jobs: {$e} +msg-8bc87eb5 = Invalid payload +msg-29f616c2 = session is required +msg-ae7c99a4 = run_at is required when run_once=true +msg-4bb8c206 = cron_expression is required when run_once=false +msg-13fbf01e = run_at must be ISO datetime +msg-da14d97a = Failed to create job: {$e} +msg-804b6412 = Job not found +msg-94b2248d = Failed to update job: {$e} +msg-42c0ee7a = Failed to delete job: {$e} + +### astrbot/dashboard/routes/tools.py +msg-78b9c276 = {$res} +msg-977490be = 获取 MCP 服务器列表失败: {$e} +msg-50a07403 = 服务器名称不能为空 +msg-23d2bca3 = 必须提供有效的服务器配置 +msg-31252516 = 服务器 {$name} 已存在 +msg-20b8309f = 启用 MCP 服务器 {$name} 超时。 +msg-fff3d0c7 = 启用 MCP 服务器 {$name} 失败: {$e} +msg-7f1f7921 = 保存配置失败 +msg-a7f06648 = 添加 MCP 服务器失败: {$e} +msg-278dc41b = 服务器 {$old_name} 不存在 +msg-f0441f4b = 启用前停用 MCP 服务器时 {$old_name} 超时: {$e} +msg-7c468a83 = 启用前停用 MCP 服务器时 {$old_name} 失败: {$e} +msg-8a4c8128 = 停用 MCP 服务器 {$old_name} 超时。 +msg-9ac9b2fc = 停用 MCP 服务器 {$old_name} 失败: {$e} +msg-b988392d = 更新 MCP 服务器失败: {$e} +msg-c81030a7 = 服务器 {$name} 不存在 +msg-4cdbd30d = 停用 MCP 服务器 {$name} 超时。 +msg-1ed9a96e = 停用 MCP 服务器 {$name} 失败: {$e} +msg-a26f2c6a = 删除 MCP 服务器失败: {$e} +msg-bbc84cc5 = 无效的 MCP 服务器配置 +msg-aa0e3d0d = MCP 服务器配置不能为空 +msg-d69cbcf2 = 一次只能配置一个 MCP 服务器配置 +msg-bd43f610 = 测试 MCP 连接失败: {$e} +msg-057a3970 = 获取工具列表失败: {$e} +msg-29415636 = 缺少必要参数: name 或 action +msg-75d85dc1 = 启用工具失败: {$e} +msg-21a922b8 = 工具 {$tool_name} 不存在或操作失败。 +msg-20143f28 = 操作工具失败: {$e} +msg-295ab1fe = 未知: {$provider_name} +msg-fe38e872 = 同步失败: {$e} + +### astrbot/dashboard/routes/chatui_project.py +msg-04827ead = Missing key: title +msg-34fccfbb = Missing key: project_id +msg-a7c08aee = Project {$project_id} not found +msg-c52a1454 = Permission denied +msg-dbf41bfc = Missing key: session_id +msg-d922dfa3 = Session {$session_id} not found + +### astrbot/dashboard/routes/open_api.py +msg-e41d65d5 = Failed to create chat session %s: %s +msg-fc15cbcd = {$username_err} +msg-bc3b3977 = Invalid username +msg-2cd6e70f = {$ensure_session_err} +msg-53632573 = {$resolve_err} +msg-79b0c7cb = Failed to update chat config route for %s with %s: %s +msg-7c7a9f55 = Failed to update chat config route: {$e} +msg-74bff366 = page and page_size must be integers +msg-1507569c = Message is empty +msg-1389e46a = message must be a string or list +msg-697561eb = message part must be an object +msg-2c4bf283 = reply part missing message_id +msg-60ddb927 = unsupported message part type: {$part_type} +msg-cf310369 = attachment not found: {$attachment_id} +msg-58e0b84a = {$part_type} part missing attachment_id +msg-e565c4b5 = file not found: {$file_path} +msg-c6ec40ff = Message content is empty (reply only is not allowed) +msg-2b00f931 = Missing key: message +msg-a29d9adb = Missing key: umo +msg-4990e908 = Invalid umo: {$e} +msg-45ac857c = Bot not found or not running for platform: {$platform_id} +msg-ec0f0bd2 = Open API send_message failed: {$e} +msg-d04109ab = Failed to send message: {$e} + +### astrbot/dashboard/routes/session_management.py +msg-e1949850 = 获取知识库列表失败: {$e} +msg-3cd6eb8c = 获取规则列表失败: {$e} +msg-363174ae = 缺少必要参数: umo +msg-809e51d7 = 缺少必要参数: rule_key +msg-ce203e7e = 不支持的规则键: {$rule_key} +msg-2726ab30 = 更新会话规则失败: {$e} +msg-f021f9fb = 删除会话规则失败: {$e} +msg-6bfa1fe5 = 缺少必要参数: umos +msg-4ce0379e = 参数 umos 必须是数组 +msg-979c6e2f = 删除 umo {$umo} 的规则失败: {$e} +msg-77d2761d = 批量删除会话规则失败: {$e} +msg-6619322c = 获取 UMO 列表失败: {$e} +msg-b944697c = 获取会话状态列表失败: {$e} +msg-adba3c3b = 至少需要指定一个要修改的状态 +msg-4a8eb7a6 = 请指定分组 ID +msg-67f15ab7 = 分组 '{$group_id}' 不存在 +msg-50fbcccb = 没有找到符合条件的会话 +msg-59714ede = 更新 {$umo} 服务状态失败: {$e} +msg-31640917 = 批量更新服务状态失败: {$e} +msg-4d83eb92 = 缺少必要参数: provider_type, provider_id +msg-5f333041 = 不支持的 provider_type: {$provider_type} +msg-6fa017d7 = 更新 {$umo} Provider 失败: {$e} +msg-07416020 = 批量更新 Provider 失败: {$e} +msg-94c745e6 = 获取分组列表失败: {$e} +msg-fb7cf353 = 分组名称不能为空 +msg-ae3fce8a = 创建分组失败: {$e} +msg-07de5ff3 = 分组 ID 不能为空 +msg-35b8a74f = 更新分组失败: {$e} +msg-3d41a6fd = 删除分组失败: {$e} + +### astrbot/dashboard/routes/persona.py +msg-4a12aead = 获取人格列表失败: {$e}{"\u000A"}{$res} +msg-c168407f = 获取人格列表失败: {$e} +msg-63c6f414 = 缺少必要参数: persona_id +msg-ce7da6f3 = 人格不存在 +msg-9c07774d = 获取人格详情失败: {$e}{"\u000A"}{$res} +msg-ee3b44ad = 获取人格详情失败: {$e} +msg-ad455c14 = 人格ID不能为空 +msg-43037094 = 系统提示词不能为空 +msg-ec9dda44 = 预设对话数量必须为偶数(用户和助手轮流对话) +msg-26b214d5 = 创建人格失败: {$e}{"\u000A"}{$res} +msg-8913dfe6 = 创建人格失败: {$e} +msg-3d94d18d = 更新人格失败: {$e}{"\u000A"}{$res} +msg-f2cdfbb8 = 更新人格失败: {$e} +msg-51d84afc = 删除人格失败: {$e}{"\u000A"}{$res} +msg-8314a263 = 删除人格失败: {$e} +msg-b8ecb8f9 = 移动人格失败: {$e}{"\u000A"}{$res} +msg-ab0420e3 = 移动人格失败: {$e} +msg-e5604a24 = 获取文件夹列表失败: {$e}{"\u000A"}{$res} +msg-4d7c7f4a = 获取文件夹列表失败: {$e} +msg-cf0ee4aa = 获取文件夹树失败: {$e}{"\u000A"}{$res} +msg-bb515af0 = 获取文件夹树失败: {$e} +msg-c92b4863 = 缺少必要参数: folder_id +msg-77cdd6fa = 文件夹不存在 +msg-2d34652f = 获取文件夹详情失败: {$e}{"\u000A"}{$res} +msg-650ef096 = 获取文件夹详情失败: {$e} +msg-27c413df = 文件夹名称不能为空 +msg-b5866931 = 创建文件夹失败: {$e}{"\u000A"}{$res} +msg-5e57f3b5 = 创建文件夹失败: {$e} +msg-9bd8f820 = 更新文件夹失败: {$e}{"\u000A"}{$res} +msg-1eada044 = 更新文件夹失败: {$e} +msg-9cef0256 = 删除文件夹失败: {$e}{"\u000A"}{$res} +msg-22020727 = 删除文件夹失败: {$e} +msg-7a69fe08 = items 不能为空 +msg-e71ba5c2 = 每个 item 必须包含 id, type, sort_order 字段 +msg-dfeb8320 = type 字段必须是 'persona' 或 'folder' +msg-aec43ed3 = 更新排序失败: {$e}{"\u000A"}{$res} +msg-75ec4427 = 更新排序失败: {$e} + +### astrbot/dashboard/routes/platform.py +msg-bcc64513 = 未找到 webhook_uuid 为 {$webhook_uuid} 的平台 +msg-1478800f = 未找到对应平台 +msg-378cb077 = 平台 {$res} 未实现 webhook_callback 方法 +msg-2d797305 = 平台未支持统一 Webhook 模式 +msg-83f8dedf = 处理 webhook 回调时发生错误: {$e} +msg-af91bc78 = 处理回调失败 +msg-136a952f = 获取平台统计信息失败: {$e} +msg-60bb0722 = 获取统计信息失败: {$e} + +### astrbot/dashboard/routes/api_key.py +msg-8e0249fa = At least one valid scope is required +msg-1b79360d = Invalid scopes +msg-d6621696 = expires_in_days must be an integer +msg-33605d95 = expires_in_days must be greater than 0 +msg-209030fe = Missing key: key_id +msg-24513a81 = API key not found + +### astrbot/dashboard/routes/file.py +msg-78b9c276 = {$res} + +### astrbot/dashboard/routes/chat.py +msg-a4a521ff = Missing key: filename +msg-c9746528 = Invalid file path +msg-3c2f6dee = File access error +msg-e5b19b36 = Missing key: attachment_id +msg-cfa38c4d = Attachment not found +msg-377a7406 = Missing key: file +msg-bae87336 = Failed to create attachment +msg-5c531303 = Missing JSON body +msg-1c3efd8f = Missing key: message or files +msg-04588d0f = Missing key: session_id or conversation_id +msg-c6ec40ff = Message content is empty (reply only is not allowed) +msg-2c3fdeb9 = Message are both empty +msg-9bc95e22 = session_id is empty +msg-344a401b = [WebChat] 用户 {$username} 断开聊天长连接。 +msg-6b54abec = WebChat stream error: {$e} +msg-53509ecb = webchat stream message_id mismatch +msg-1211e857 = [WebChat] 用户 {$username} 断开聊天长连接。 {$e} +msg-be34e848 = Failed to extract web search refs: {$e} +msg-80bbd0ff = WebChat stream unexpected error: {$e} +msg-dbf41bfc = Missing key: session_id +msg-d922dfa3 = Session {$session_id} not found +msg-c52a1454 = Permission denied +msg-9d7a8094 = Failed to delete UMO route %s during session cleanup: %s +msg-44c45099 = Failed to delete attachment file {$res}: {$e} +msg-f033d8ea = Failed to get attachments: {$e} +msg-e6f655bd = Failed to delete attachments: {$e} +msg-a6ef3b67 = Missing key: display_name + +### astrbot/dashboard/routes/t2i.py +msg-76cc0933 = Error in get_active_template +msg-5350f35b = Template not found +msg-d7b101c5 = Name and content are required. +msg-e910b6f3 = Template with this name already exists. +msg-18cfb637 = Content is required. +msg-2480cf2f = Template not found. +msg-9fe026f1 = 模板名称(name)不能为空。 +msg-eeefe1dc = 模板 '{$name}' 不存在,无法应用。 +msg-0048e060 = Error in set_active_template +msg-8fde62dd = Error in reset_default_template + +### astrbot/dashboard/routes/stat.py +msg-1198c327 = You are not permitted to do this operation in demo mode +msg-78b9c276 = {$res} +msg-0e5bb0b1 = proxy_url is required +msg-f0e0983e = Failed. Status code: {$res} +msg-68e65093 = Error: {$e} +msg-b5979fe8 = version parameter is required +msg-b88a1887 = Invalid version format +msg-8cb9bb6b = Path traversal attempt detected: {$version} -> {$changelog_path} +msg-7616304c = Changelog for version {$version} not found + +### astrbot/dashboard/routes/plugin.py +msg-1198c327 = You are not permitted to do this operation in demo mode +msg-adce8d2f = 缺少插件目录名 +msg-2f1b67fd = 重载失败: {$err} +msg-71f9ea23 = /api/plugin/reload-failed: {$res} +msg-27286c23 = /api/plugin/reload: {$res} +msg-b33c0d61 = 缓存MD5匹配,使用缓存的插件市场数据 +msg-64b4a44c = 远程插件市场数据为空: {$url} +msg-fdbffdca = 成功获取远程插件市场数据,包含 {$res} 个插件 +msg-48c42bf8 = 请求 {$url} 失败,状态码:{$res} +msg-6ac25100 = 请求 {$url} 失败,错误:{$e} +msg-7e536821 = 远程插件市场数据获取失败,使用缓存数据 +msg-d4b4c53a = 获取插件列表失败,且没有可用的缓存数据 +msg-37f59b88 = 加载缓存MD5失败: {$e} +msg-8048aa4c = 获取远程MD5失败: {$e} +msg-593eacfd = 缓存文件中没有MD5信息 +msg-dedcd957 = 无法获取远程MD5,将使用缓存 +msg-21d7e754 = 插件数据MD5: 本地={$cached_md5}, 远程={$remote_md5}, 有效={$is_valid} +msg-0faf4275 = 检查缓存有效性失败: {$e} +msg-e26aa0a5 = 加载缓存文件: {$cache_file}, 缓存时间: {$res} +msg-23d627a1 = 加载插件市场缓存失败: {$e} +msg-22d12569 = 插件市场数据已缓存到: {$cache_file}, MD5: {$md5} +msg-478c99a9 = 保存插件市场缓存失败: {$e} +msg-3838d540 = 获取插件 Logo 失败: {$e} +msg-da442310 = 正在安装插件 {$repo_url} +msg-e0abd541 = 安装插件 {$repo_url} 成功。 +msg-78b9c276 = {$res} +msg-acfcd91e = 正在安装用户上传的插件 {$res} +msg-48e05870 = 安装插件 {$res} 成功 +msg-8af56756 = 正在卸载插件 {$plugin_name} +msg-6d1235b6 = 卸载插件 {$plugin_name} 成功 +msg-7055316c = 正在更新插件 {$plugin_name} +msg-d258c060 = 更新插件 {$plugin_name} 成功。 +msg-398370d5 = /api/plugin/update: {$res} +msg-2d225636 = 插件列表不能为空 +msg-32632e67 = 批量更新插件 {$name} +msg-08dd341c = /api/plugin/update-all: 更新插件 {$name} 失败: {$res} +msg-cb230226 = 停用插件 {$plugin_name} 。 +msg-abc710cd = /api/plugin/off: {$res} +msg-06e2a068 = 启用插件 {$plugin_name} 。 +msg-82c412e7 = /api/plugin/on: {$res} +msg-77e5d67e = 正在获取插件 {$plugin_name} 的README文件内容 +msg-baed1b72 = 插件名称为空 +msg-773cca0a = 插件名称不能为空 +msg-082a5585 = 插件 {$plugin_name} 不存在 +msg-ba106e58 = 插件 {$plugin_name} 目录不存在 +msg-e38e4370 = 无法找到插件目录: {$plugin_dir} +msg-df027f16 = 无法找到插件 {$plugin_name} 的目录 +msg-5f304f4b = 插件 {$plugin_name} 没有README文件 +msg-a3ed8739 = /api/plugin/readme: {$res} +msg-2f9e2c11 = 读取README文件失败: {$e} +msg-dcbd593f = 正在获取插件 {$plugin_name} 的更新日志 +msg-ea5482da = /api/plugin/changelog: {$res} +msg-8e27362e = 读取更新日志失败: {$e} +msg-0842bf8b = 插件 {$plugin_name} 没有更新日志文件 +msg-8e36313d = sources fields must be a list +msg-643e51e7 = /api/plugin/source/save: {$res} + +### astrbot/builtin_stars/session_controller/main.py +msg-b48bf3fe = LLM response failed: {$e} + +### astrbot/builtin_stars/builtin_commands/commands/setunset.py +msg-8b56b437 = 会话 {$uid} 变量 {$key} 存储成功。使用 /unset 移除。 +msg-dfd31d9d = 没有那个变量名。格式 /unset 变量名。 +msg-bf181241 = 会话 {$uid} 变量 {$key} 移除成功。 + +### astrbot/builtin_stars/builtin_commands/commands/provider.py +msg-b435fcdc = Provider reachability check failed: id=%s type=%s code=%s reason=%s +msg-f4cfd3ab = 正在进行提供商可达性测试,请稍候... +msg-ed8dcc22 = {$ret} +msg-f3d8988e = 请输入序号。 +msg-284759bb = 无效的提供商序号。 +msg-092d9956 = 成功切换到 {$id_}。 +msg-bf9eb668 = 无效的参数。 +msg-4cdd042d = 未找到任何 LLM 提供商。请先配置。 +msg-cb218e86 = 模型序号错误。 +msg-1756f199 = 切换模型成功。当前提供商: [{$res}] 当前模型: [{$res_2}] +msg-4d4f587f = 切换模型到 {$res}。 +msg-584ca956 = Key 序号错误。 +msg-f52481b8 = 切换 Key 未知错误: {$e} +msg-7a156524 = 切换 Key 成功。 + +### astrbot/builtin_stars/builtin_commands/commands/conversation.py +msg-63fe9607 = 在{$res}场景下,reset命令需要管理员权限,您 (ID {$res_2}) 不是管理员,无法执行此操作。 +msg-6f4bbe27 = 重置对话成功。 +msg-4cdd042d = 未找到任何 LLM 提供商。请先配置。 +msg-69ed45be = 当前未处于对话状态,请 /switch 切换或者 /new 创建。 +msg-ed8dcc22 = {$ret} +msg-772ec1fa = 已请求停止 {$stopped_count} 个运行中的任务。 +msg-8d42cd8a = 当前会话没有运行中的任务。 +msg-efdfbe3e = {$THIRD_PARTY_AGENT_RUNNER_STR} 对话列表功能暂不支持。 +msg-492c2c02 = 已创建新对话。 +msg-c7dc838d = 切换到新对话: 新对话({$res})。 +msg-6da01230 = 群聊 {$session} 已切换到新对话: 新对话({$res})。 +msg-f356d65a = 请输入群聊 ID。/groupnew 群聊ID。 +msg-7e442185 = 类型错误,请输入数字对话序号。 +msg-00dbe29c = 请输入对话序号。/switch 对话序号。/ls 查看对话 /new 新建对话 +msg-a848ccf6 = 对话序号错误,请使用 /ls 查看 +msg-1ec33cf6 = 切换到对话: {$title}({$res})。 +msg-68e5dd6c = 请输入新的对话名称。 +msg-c8dd6158 = 重命名对话成功。 +msg-1f1fa2f2 = 会话处于群聊,并且未开启独立会话,并且您 (ID {$res}) 不是管理员,因此没有权限删除当前对话。 +msg-6a1dc4b7 = 当前未处于对话状态,请 /switch 序号 切换或 /new 创建。 + +### astrbot/builtin_stars/builtin_commands/commands/tts.py +msg-ef1b2145 = {$status_text}当前会话的文本转语音。但 TTS 功能在配置中未启用,请前往 WebUI 开启。 +msg-deee9deb = {$status_text}当前会话的文本转语音。 + +### astrbot/builtin_stars/builtin_commands/commands/llm.py +msg-72cd5f57 = {$status} LLM 聊天功能。 + +### astrbot/builtin_stars/builtin_commands/commands/persona.py +msg-4f52d0dd = 当前对话不存在,请先使用 /new 新建一个对话。 +msg-e092b97c = [Persona]{"\u000A"}{"\u000A"}- 人格情景列表: `/persona list`{"\u000A"}- 设置人格情景: `/persona 人格`{"\u000A"}- 人格情景详细信息: `/persona view 人格`{"\u000A"}- 取消人格: `/persona unset`{"\u000A"}{"\u000A"}默认人格情景: {$res}{"\u000A"}当前对话 {$curr_cid_title} 的人格情景: {$curr_persona_name}{"\u000A"}{"\u000A"}配置人格情景请前往管理面板-配置页{"\u000A"} +msg-c046b6e4 = {$msg} +msg-99139ef8 = 请输入人格情景名 +msg-a44c7ec0 = 当前没有对话,无法取消人格。 +msg-a90c75d4 = 取消人格成功。 +msg-a712d71a = 当前没有对话,请先开始对话或使用 /new 创建一个对话。 +msg-4e4e746d = 设置成功。如果您正在切换到不同的人格,请注意使用 /reset 来清空上下文,防止原人格对话影响现人格。{$force_warn_msg} +msg-ab60a2e7 = 不存在该人格情景。使用 /persona list 查看所有。 + +### astrbot/builtin_stars/builtin_commands/commands/t2i.py +msg-855d5cf3 = 已关闭文本转图片模式。 +msg-64da24f4 = 已开启文本转图片模式。 + +### astrbot/builtin_stars/builtin_commands/commands/admin.py +msg-ad019976 = 使用方法: /op 授权管理员;/deop 取消管理员。可通过 /sid 获取 ID。 +msg-1235330f = 授权成功。 +msg-e78847e0 = 使用方法: /deop 取消管理员。可通过 /sid 获取 ID。 +msg-012152c1 = 取消授权成功。 +msg-5e076026 = 此用户 ID 不在管理员名单内。 +msg-7f8eedde = 使用方法: /wl 添加白名单;/dwl 删除白名单。可通过 /sid 获取 ID。 +msg-de1b0a87 = 添加白名单成功。 +msg-59d6fcbe = 使用方法: /dwl 删除白名单。可通过 /sid 获取 ID。 +msg-4638580f = 删除白名单成功。 +msg-278fb868 = 此 SID 不在白名单内。 +msg-1dee5007 = 正在尝试更新管理面板... +msg-76bea66c = 管理面板更新完成。 + +### astrbot/builtin_stars/builtin_commands/commands/sid.py +msg-ed8dcc22 = {$ret} + +### astrbot/builtin_stars/builtin_commands/commands/plugin.py +msg-9cae24f5 = {$plugin_list_info} +msg-3f3a6087 = 演示模式下无法禁用插件。 +msg-90e17cd4 = /plugin off <插件名> 禁用插件。 +msg-d29d6d57 = 插件 {$plugin_name} 已禁用。 +msg-f90bbe20 = 演示模式下无法启用插件。 +msg-b897048f = /plugin on <插件名> 启用插件。 +msg-ebfb93bb = 插件 {$plugin_name} 已启用。 +msg-9cd74a8d = 演示模式下无法安装插件。 +msg-d79ad78d = /plugin get <插件仓库地址> 安装插件 +msg-4f293fe1 = 准备从 {$plugin_repo} 安装插件。 +msg-d40e7065 = 安装插件成功。 +msg-feff82c6 = 安装插件失败: {$e} +msg-5bfe9d3d = /plugin help <插件名> 查看插件信息。 +msg-02627a9b = 未找到此插件。 +msg-ed8dcc22 = {$ret} + +### astrbot/builtin_stars/builtin_commands/commands/help.py +msg-c046b6e4 = {$msg} + +### astrbot/builtin_stars/builtin_commands/commands/alter_cmd.py +msg-d7a36c19 = 该指令用于设置指令或指令组的权限。{"\u000A"}格式: /alter_cmd {"\u000A"}例1: /alter_cmd c1 admin 将 c1 设为管理员指令{"\u000A"}例2: /alter_cmd g1 c1 admin 将 g1 指令组的 c1 子指令设为管理员指令{"\u000A"}/alter_cmd reset config 打开 reset 权限配置 +msg-afe0fa58 = {$config_menu} +msg-0c85d498 = 场景编号和权限类型不能为空 +msg-4e0afcd1 = 场景编号必须是 1-3 之间的数字 +msg-830d6eb8 = 权限类型错误,只能是 admin 或 member +msg-d1180ead = 已将 reset 命令在{$res}场景下的权限设为{$perm_type} +msg-8d9bc364 = 指令类型错误,可选类型有 admin, member +msg-1f2f65e0 = 未找到该指令 +msg-cd271581 = 已将「{$cmd_name}」{$cmd_group_str} 的权限级别调整为 {$cmd_type}。 + +### astrbot/builtin_stars/web_searcher/main.py +msg-7f5fd92b = 检测到旧版 websearch_tavily_key (字符串格式),自动迁移为列表格式并保存。 +msg-bed9def5 = web_searcher - scraping web: {$res} - {$res_2} +msg-8214760c = bing search error: {$e}, try the next one... +msg-8676b5aa = search bing failed +msg-3fb6d6ad = sogo search error: {$e} +msg-fe9b336f = search sogo failed +msg-c991b022 = 错误:Tavily API密钥未在AstrBot中配置。 +msg-b4fbb4a9 = Tavily web search failed: {$reason}, status: {$res} +msg-6769aba9 = Error: Tavily web searcher does not return any results. +msg-b4e7334e = 此指令已经被废弃,请在 WebUI 中开启或关闭网页搜索功能。 +msg-b1877974 = web_searcher - search_from_search_engine: {$query} +msg-2360df6b = Error processing search result: {$processed_result} +msg-359d0443 = Error: Baidu AI Search API key is not configured in AstrBot. +msg-94351632 = Successfully initialized Baidu AI Search MCP server. +msg-5a7207c1 = web_searcher - search_from_tavily: {$query} +msg-b36134c9 = Error: Tavily API key is not configured in AstrBot. +msg-98ed69f4 = Error: url must be a non-empty string. +msg-51edd9ee = 错误:BoCha API密钥未在AstrBot中配置。 +msg-73964067 = BoCha web search failed: {$reason}, status: {$res} +msg-34417720 = web_searcher - search_from_bocha: {$query} +msg-b798883b = Error: BoCha API key is not configured in AstrBot. +msg-22993708 = Cannot get Baidu AI Search MCP tool. +msg-6f8d62a4 = Cannot Initialize Baidu AI Search MCP Server: {$e} + +### astrbot/builtin_stars/web_searcher/engines/bing.py +msg-e3b4d1e9 = Bing search failed + +### astrbot/builtin_stars/astrbot/main.py +msg-3df554a1 = 聊天增强 err: {$e} +msg-5bdf8f5c = {$e} +msg-bb6ff036 = 未找到任何 LLM 提供商。请先配置。无法主动回复 +msg-afa050be = 当前未处于对话状态,无法主动回复,请确保 平台设置->会话隔离(unique_session) 未开启,并使用 /switch 序号 切换或者 /new 创建一个会话。 +msg-9a6a6b2e = 未找到对话,无法主动回复 +msg-78b9c276 = {$res} +msg-b177e640 = 主动回复失败: {$e} +msg-24d2f380 = ltm: {$e} + +### astrbot/builtin_stars/astrbot/long_term_memory.py +msg-5bdf8f5c = {$e} +msg-8e11fa57 = 没有找到 ID 为 {$image_caption_provider_id} 的提供商 +msg-8ebaa397 = 提供商类型错误({$res}),无法获取图片描述 +msg-30954f77 = 图片 URL 为空 +msg-62de0c3e = 获取图片描述失败: {$e} +msg-d0647999 = ltm | {$res} | {$final_message} +msg-133c1f1d = Recorded AI response: {$res} | {$final_message} + +### astrbot/i18n/ftl_translate.py +msg-547c9cc5 = 未检测到环境变量 DEEPSEEK_API_KEY,请先设置。 +msg-8654e4be = {"\u000A"}[Error] API 调用失败: {$e} +msg-75f207ed = File not found: {$ftl_path} +msg-dcfbbe82 = No messages found in {$ftl_path} +msg-ccd5a28f = 共 {$res} 条文本,使用 {$max_workers} 个并发线程翻译... +msg-00b24d69 = {"\u000A"}[Error] 翻译失败,保留原文: {$e} +msg-ebcdd595 = {"\u000A"}翻译完成,已保存到 {$ftl_path} +msg-d6c66497 = 错误: 请先设置 DEEPSEEK_API_KEY 环境变量。 +msg-09486085 = 例如: export DEEPSEEK_API_KEY='sk-xxxxxx' + +### scripts/generate_changelog.py +msg-a79937ef = Warning: openai package not installed. Install it with: pip install openai +msg-090bfd36 = Warning: Failed to call LLM API: {$e} +msg-a3ac9130 = Falling back to simple changelog generation... +msg-6f1011c5 = Latest tag: {$latest_tag} +msg-8c7f64d7 = Error: No tags found in repository +msg-a89fa0eb = No commits found since {$latest_tag} +msg-846ebecf = Found {$res} commits since {$latest_tag} +msg-9ad686af = Warning: Could not parse version from tag {$latest_tag} +msg-f5d43a54 = Generating changelog for {$version}... +msg-e54756e8 = {"\u000A"}✓ Changelog generated: {$changelog_file} +msg-82be6c98 = {"\u000A"}Preview: +msg-321ac5b1 = {$changelog_content} \ No newline at end of file diff --git a/astrbot/i18n/locales/zh-cn/i18n_messages.ftl b/astrbot/i18n/locales/zh-cn/i18n_messages.ftl new file mode 100644 index 0000000000..0d873f6669 --- /dev/null +++ b/astrbot/i18n/locales/zh-cn/i18n_messages.ftl @@ -0,0 +1,2921 @@ + +### main.py +msg-5e25709f = 请使用 Python3.10+ 运行本项目。 +msg-afd0ab81 = 使用指定的 WebUI 目录: {$webui_dir} +msg-7765f00f = 指定的 WebUI 目录 {$webui_dir} 不存在,将使用默认逻辑。 +msg-9af20e37 = WebUI 版本已是最新。 +msg-9dd5c1d2 = 检测到 WebUI 版本 ({$v}) 与当前 AstrBot 版本 (v{$VERSION}) 不符。 +msg-ec714d4e = 开始下载管理面板文件...高峰期(晚上)可能导致较慢的速度。如多次下载失败,请前往 https://github.com/AstrBotDevs/AstrBot/releases/latest 下载 dist.zip,并将其中的 dist 文件夹解压至 data 目录下。 +msg-c5170c27 = 下载管理面板文件失败: {$e}。 +msg-e1592ad1 = 管理面板下载完成。 +msg-fe494da6 = {$logo_tmpl} + +### astrbot/core/lang.py +msg-d103bc8e = Namespace must not be empty. +msg-f66527da = Namespace must not contain '.'. +msg-b3665aee = Locale directory does not exist: {$base_dir} +msg-3fe89e6a = No locale directories found under: {$base_dir} +msg-c79b2c75 = Namespace '{$namespace}' already exists. Set replace=True to overwrite. +msg-7db3fccf = Default namespace cannot be unregistered. +msg-3d066f64 = Namespace '{$namespace}' is not registered. + +### astrbot/core/persona_mgr.py +msg-51a854e6 = 已加载 {$res} 个人格。 +msg-1ea88f45 = Persona with ID {$persona_id} does not exist. +msg-28104dff = Persona with ID {$persona_id} already exists. +msg-08ecfd42 = {$res} 人格情景预设对话格式不对,条数应该为偶数。 +msg-b6292b94 = 解析 Persona 配置失败:{$e} + +### astrbot/core/initial_loader.py +msg-78b9c276 = {$res} +msg-58525c23 = 😭 初始化 AstrBot 失败:{$e} !!! +msg-002cc3e8 = 🌈 正在关闭 AstrBot... + +### astrbot/core/log.py +msg-80a186b8 = Failed to add file sink: {$e} + +### astrbot/core/astrbot_config_mgr.py +msg-7875e5bd = Config file {$conf_path} for UUID {$uuid_} does not exist, skipping. +msg-39c4fd49 = 不能删除默认配置文件 +msg-cf7b8991 = 配置文件 {$conf_id} 不存在于映射中 +msg-2aad13a4 = 已删除配置文件: {$conf_path} +msg-94c359ef = 删除配置文件 {$conf_path} 失败: {$e} +msg-44f0b770 = 成功删除配置文件 {$conf_id} +msg-737da44e = 不能更新默认配置文件的信息 +msg-9d496709 = 成功更新配置文件 {$conf_id} 的信息 + +### astrbot/core/zip_updator.py +msg-24c90ff8 = 请求 {$url} 失败,状态码: {$res}, 内容: {$text} +msg-14726dd8 = 请求失败,状态码: {$res} +msg-fc3793c6 = 解析版本信息时发生异常: {$e} +msg-491135d9 = 解析版本信息失败 +msg-03a72cb5 = 未找到合适的发布版本 +msg-8bcbfcf0 = 正在下载更新 {$repo} ... +msg-ccc87294 = 正在从指定分支 {$branch} 下载 {$author}/{$repo} +msg-dfebcdc6 = 获取 {$author}/{$repo} 的 GitHub Releases 失败: {$e},将尝试下载默认分支 +msg-e327bc14 = 正在从默认分支下载 {$author}/{$repo} +msg-3cd3adfb = 检查到设置了镜像站,将使用镜像站下载 {$author}/{$repo} 仓库源码: {$release_url} +msg-1bffc0d7 = 无效的 GitHub URL +msg-0ba954db = 解压文件完成: {$zip_path} +msg-90ae0d15 = 删除临时更新文件: {$zip_path} 和 {$res} +msg-f8a43aa5 = 删除更新文件失败,可以手动删除 {$zip_path} 和 {$res} + +### astrbot/core/file_token_service.py +msg-0e444e51 = 文件不存在: {$local_path} (原始输入: {$file_path}) +msg-f61a5322 = 无效或过期的文件 token: {$file_token} +msg-73d3e179 = 文件不存在: {$file_path} + +### astrbot/core/subagent_orchestrator.py +msg-5d950986 = subagent_orchestrator.agents must be a list +msg-29e3b482 = SubAgent persona %s not found, fallback to inline prompt. +msg-f425c9f0 = Registered subagent handoff tool: {$res} + +### astrbot/core/astr_main_agent.py +msg-8dcf5caa = 未找到指定的提供商: %s。 +msg-61d46ee5 = 选择的提供商类型无效(%s),跳过 LLM 请求处理。 +msg-496864bc = Error occurred while selecting provider: %s +msg-507853eb = 无法创建新的对话。 +msg-66870b7e = Error occurred while retrieving knowledge base: %s +msg-36dc1409 = Moonshot AI API key for file extract is not set +msg-8534047e = Unsupported file extract provider: %s +msg-f2ea29f4 = Cannot get image caption because provider `{$provider_id}` is not exist. +msg-91a70615 = Cannot get image caption because provider `{$provider_id}` is not a valid Provider, it is {$res}. +msg-b1840df0 = Processing image caption with provider: %s +msg-089421fc = 处理图片描述失败: %s +msg-719d5e4d = No provider found for image captioning in quote. +msg-e16a974b = 处理引用图片失败: %s +msg-037dad2e = Group name display enabled but group object is None. Group ID: %s +msg-58b47bcd = 时区设置错误: %s, 使用本地时区 +msg-938af433 = Provider %s does not support image, using placeholder. +msg-83d739f8 = Provider %s does not support tool_use, clearing tools. +msg-3dbad2d9 = sanitize_context_by_modalities applied: removed_image_blocks=%s, removed_tool_messages=%s, removed_tool_calls=%s +msg-4214b760 = Generated chatui title for session %s: %s +msg-cb6db56e = Unsupported llm_safety_mode strategy: %s. +msg-7ea2c5d3 = Shipyard sandbox configuration is incomplete. +msg-9248b273 = 未找到指定的上下文压缩模型 %s,将跳过压缩。 +msg-16fe8ea5 = 指定的上下文压缩模型 %s 不是对话模型,将跳过压缩。 +msg-c6c9d989 = fallback_chat_models setting is not a list, skip fallback providers. +msg-614aebad = Fallback chat provider `%s` not found, skip. +msg-1a2e87dd = Fallback chat provider `%s` is invalid type: %s, skip. +msg-ee979399 = 未找到任何对话模型(提供商),跳过 LLM 请求处理。 +msg-7a7b4529 = Skip quoted fallback images due to limit=%d for umo=%s +msg-46bcda31 = Truncate quoted fallback images for umo=%s, reply_id=%s from %d to %d +msg-cbceb923 = Failed to resolve fallback quoted images for umo=%s, reply_id=%s: %s +msg-31483e80 = Error occurred while applying file extract: %s + +### astrbot/core/umop_config_router.py +msg-dedcfded = umop keys must be strings in the format [platform_id]:[message_type]:[session_id], with optional wildcards * or empty for all +msg-8e3a16f3 = umop must be a string in the format [platform_id]:[message_type]:[session_id], with optional wildcards * or empty for all + +### astrbot/core/event_bus.py +msg-da466871 = PipelineScheduler not found for id: {$res}, event ignored. +msg-7eccffa5 = [{$conf_name}] [{$res}({$res_2})] {$res_3}/{$res_4}: {$res_5} +msg-88bc26f2 = [{$conf_name}] [{$res}({$res_2})] {$res_3}: {$res_4} + +### astrbot/core/astr_agent_tool_exec.py +msg-e5f2fb34 = Background task {$task_id} failed: {$e} +msg-c54b2335 = Background handoff {$task_id} ({$res}) failed: {$e} +msg-8c2fe51d = Failed to build main agent for background task {$tool_name}. +msg-c6d4e4a6 = background task agent got no response +msg-0b3711f1 = Event must be provided for local function tools. +msg-8c19e27a = Tool must have a valid handler or override 'run' method. +msg-24053a5f = Tool 直接发送消息失败: {$e} +msg-f940b51e = tool {$res} execution timeout after {$res_2} seconds. +msg-7e22fc8e = 未知的方法名: {$method_name} +msg-c285315c = Tool execution ValueError: {$e} +msg-41366b74 = Tool handler parameter mismatch, please check the handler definition. Handler parameters: {$handler_param_str} +msg-e8cadf8e = Tool execution error: {$e}. Traceback: {$trace_} +msg-d7b4aa84 = Previous Error: {$trace_} + +### astrbot/core/astr_agent_run_util.py +msg-6b326889 = Agent reached max steps ({$max_step}), forcing a final response. +msg-bb15e9c7 = {$status_msg} +msg-78b9c276 = {$res} +msg-9c246298 = Error in on_agent_done hook +msg-34f164d4 = {$err_msg} +msg-6d9553b2 = [Live Agent] 使用流式 TTS(原生支持 get_audio_stream) +msg-becf71bf = [Live Agent] 使用 TTS({$res} 使用 get_audio,将按句子分块生成音频) +msg-21723afb = [Live Agent] 运行时发生错误: {$e} +msg-ca1bf0d7 = 发送 TTS 统计信息失败: {$e} +msg-5ace3d96 = [Live Agent Feeder] 分句: {$temp_buffer} +msg-bc1826ea = [Live Agent Feeder] Error: {$e} +msg-a92774c9 = [Live TTS Stream] Error: {$e} +msg-d7b3bbae = [Live TTS Simulated] Error processing text '{$res}...': {$e} +msg-035bca5f = [Live TTS Simulated] Critical Error: {$e} + +### astrbot/core/astr_main_agent_resources.py +msg-509829d8 = Downloaded file from sandbox: {$path} -> {$local_path} +msg-b462b60d = Failed to check/download file from sandbox: {$e} +msg-0b3144f1 = [知识库] 会话 {$umo} 已被配置为不使用知识库 +msg-97e13f98 = [知识库] 知识库不存在或未加载: {$kb_id} +msg-312d09c7 = [知识库] 会话 {$umo} 配置的以下知识库无效: {$invalid_kb_ids} +msg-42b0e9f8 = [知识库] 使用会话级配置,知识库数量: {$res} +msg-08167007 = [知识库] 使用全局配置,知识库数量: {$res} +msg-a00becc3 = [知识库] 开始检索知识库,数量: {$res}, top_k={$top_k} +msg-199e71b7 = [知识库] 为会话 {$umo} 注入了 {$res} 条相关知识块 + +### astrbot/core/conversation_mgr.py +msg-86f404dd = 会话删除回调执行失败 (session: {$unified_msg_origin}): {$e} +msg-57dcc41f = Conversation with id {$cid} not found + +### astrbot/core/updator.py +msg-e3d42a3b = 正在终止 {$res} 个子进程。 +msg-e7edc4a4 = 正在终止子进程 {$res} +msg-37bea42d = 子进程 {$res} 没有被正常终止, 正在强行杀死。 +msg-cc6d9588 = 重启失败({$executable}, {$e}),请尝试手动重启。 +msg-0e4439d8 = 不支持更新此方式启动的AstrBot +msg-3f39a942 = 当前已经是最新版本。 +msg-c7bdf215 = 未找到版本号为 {$version} 的更新文件。 +msg-92e46ecc = commit hash 长度不正确,应为 40 +msg-71c01b1c = 准备更新至指定版本的 AstrBot Core: {$version} +msg-d3a0e13d = 下载 AstrBot Core 更新文件完成,正在执行解压... + +### astrbot/core/core_lifecycle.py +msg-9967ec8b = Using proxy: {$proxy_config} +msg-5a29b73d = HTTP proxy cleared +msg-fafb87ce = Subagent orchestrator init failed: {$e} +msg-f7861f86 = AstrBot migration failed: {$e} +msg-78b9c276 = {$res} +msg-967606fd = ------- 任务 {$res} 发生错误: {$e} +msg-a2cd77f3 = | {$line} +msg-1f686eeb = ------- +msg-9556d279 = AstrBot 启动完成。 +msg-daaf690b = hook(on_astrbot_loaded) -> {$res} - {$res_2} +msg-4719cb33 = 插件 {$res} 未被正常终止 {$e}, 可能会导致资源泄露等问题。 +msg-c3bbfa1d = 任务 {$res} 发生错误: {$e} +msg-af06ccab = 配置文件 {$conf_id} 不存在 + +### astrbot/core/pipeline/context_utils.py +msg-49f260d3 = 处理函数参数不匹配,请检查 handler 的定义。 +msg-d7b4aa84 = Previous Error: {$trace_} +msg-eb8619cb = hook({$res}) -> {$res_2} - {$res_3} +msg-78b9c276 = {$res} +msg-add19f94 = {$res} - {$res_2} 终止了事件传播。 + +### astrbot/core/pipeline/__init__.py +msg-1c9fc93d = module {$__name__} has no attribute {$name} + +### astrbot/core/pipeline/scheduler.py +msg-c240d574 = 阶段 {$res} 已终止事件传播。 +msg-609a1ac5 = pipeline 执行完毕。 + +### astrbot/core/pipeline/rate_limit_check/stage.py +msg-18092978 = 会话 {$session_id} 被限流。根据限流策略,此会话处理将被暂停 {$stall_duration} 秒。 +msg-4962387a = 会话 {$session_id} 被限流。根据限流策略,此请求已被丢弃,直到限额于 {$stall_duration} 秒后重置。 + +### astrbot/core/pipeline/whitelist_check/stage.py +msg-8282c664 = 会话 ID {$res} 不在会话白名单中,已终止事件传播。请在配置文件中添加该会话 ID 到白名单。 + +### astrbot/core/pipeline/process_stage/follow_up.py +msg-df881b01 = Captured follow-up message for active agent run, umo=%s, order_seq=%s + +### astrbot/core/pipeline/process_stage/method/agent_request.py +msg-3267978a = 识别 LLM 聊天额外唤醒前缀 {$res} 以机器人唤醒前缀 {$bwp} 开头,已自动去除。 +msg-97a4d573 = This pipeline does not enable AI capability, skip processing. +msg-f1a11d2b = The session {$res} has disabled AI capability, skipping processing. + +### astrbot/core/pipeline/process_stage/method/star_request.py +msg-f0144031 = Cannot find plugin for given handler module path: {$res} +msg-1e8939dd = plugin -> {$res} - {$res_2} +msg-6be73b5e = {$traceback_text} +msg-d919bd27 = Star {$res} handle error: {$e} +msg-ed8dcc22 = {$ret} + +### astrbot/core/pipeline/process_stage/method/agent_sub_stages/internal.py +msg-60493581 = Unsupported tool_schema_mode: %s, fallback to skills_like +msg-9cdb2b6e = skip llm request: empty message and no provider_request +msg-e461e5af = ready to request llm provider +msg-be33dd11 = Follow-up ticket already consumed, stopping processing. umo=%s, seq=%s +msg-abd5ccbc = acquired session lock for llm request +msg-f9d617d7 = Provider API base %s is blocked due to security reasons. Please use another ai provider. +msg-3247374d = [Internal Agent] 检测到 Live Mode,启用 TTS 处理 +msg-dae92399 = [Live Mode] TTS Provider 未配置,将使用普通流式模式 +msg-1b1af61e = Error occurred while processing agent: {$e} +msg-ea02b899 = Error occurred while processing agent request: {$e} +msg-ee7e792b = LLM 响应为空,不保存记录。 + +### astrbot/core/pipeline/process_stage/method/agent_sub_stages/third_party.py +msg-5e551baf = Third party agent runner error: {$e} +msg-34f164d4 = {$err_msg} +msg-f9d76893 = 没有填写 Agent Runner 提供商 ID,请前往配置页面配置。 +msg-0f856470 = Agent Runner 提供商 {$res} 配置不存在,请前往配置页面修改配置。 +msg-b3f25c81 = Unsupported third party agent runner type: {$res} +msg-6c63eb68 = Agent Runner 未返回最终结果。 + +### astrbot/core/pipeline/result_decorate/stage.py +msg-7ec898fd = hook(on_decorating_result) -> {$res} - {$res_2} +msg-5e27dae6 = 启用流式输出时,依赖发送消息前事件钩子的插件可能无法正常工作 +msg-caaaec29 = hook(on_decorating_result) -> {$res} - {$res_2} 将消息结果清空。 +msg-78b9c276 = {$res} +msg-add19f94 = {$res} - {$res_2} 终止了事件传播。 +msg-813a44bb = 流式输出已启用,跳过结果装饰阶段 +msg-891aa43a = 分段回复正则表达式错误,使用默认分段方式: {$res} +msg-82bb9025 = 会话 {$res} 未配置文本转语音模型。 +msg-fb1c757a = TTS 请求: {$res} +msg-06341d25 = TTS 结果: {$audio_path} +msg-2057f670 = 由于 TTS 音频文件未找到,消息段转语音失败: {$res} +msg-f26725cf = 已注册:{$url} +msg-47716aec = TTS 失败,使用文本发送。 +msg-ffe054a9 = 文本转图片失败,使用文本发送。 +msg-06c1aedc = 文本转图片耗时超过了 3 秒,如果觉得很慢可以使用 /t2i 关闭文本转图片模式。 + +### astrbot/core/pipeline/waking_check/stage.py +msg-df815938 = enabled_plugins_name: {$enabled_plugins_name} +msg-51182733 = 插件 {$res}: {$e} +msg-e0dcf0b8 = 您(ID: {$res})的权限不足以使用此指令。通过 /sid 获取 ID 并请管理员添加。 +msg-a3c3706f = 触发 {$res} 时, 用户(ID={$res_2}) 权限不足。 + +### astrbot/core/pipeline/session_status_check/stage.py +msg-f9aba737 = 会话 {$res} 已被关闭,已终止事件传播。 + +### astrbot/core/pipeline/respond/stage.py +msg-59539c6e = 解析分段回复的间隔时间失败。{$e} +msg-4ddee754 = 分段回复间隔时间:{$res} +msg-5e2371a9 = Prepare to send - {$res}/{$res_2}: {$res_3} +msg-df92ac24 = async_stream 为空,跳过发送。 +msg-858b0e4f = 应用流式输出({$res}) +msg-22c7a672 = 消息为空,跳过发送阶段 +msg-e6ab7a25 = 空内容检查异常: {$e} +msg-b29b99c1 = 实际消息链为空, 跳过发送阶段。header_chain: {$header_comps}, actual_chain: {$res} +msg-842df577 = 发送消息链失败: chain = {$res}, error = {$e} +msg-f35465cf = 消息链全为 Reply 和 At 消息段, 跳过发送阶段。chain: {$res} +msg-784e8a67 = 发送消息链失败: chain = {$chain}, error = {$e} + +### astrbot/core/pipeline/content_safety_check/stage.py +msg-c733275f = 你的消息或者大模型的响应中包含不适当的内容,已被屏蔽。 +msg-46c80f28 = 内容安全检查不通过,原因:{$info} + +### astrbot/core/pipeline/content_safety_check/strategies/strategy.py +msg-27a700e0 = 使用百度内容审核应该先 pip install baidu-aip + +### astrbot/core/pipeline/preprocess_stage/stage.py +msg-7b9074fa = {$platform} 预回应表情发送失败: {$e} +msg-43f1b4ed = 路径映射: {$url} -> {$res} +msg-9549187d = 会话 {$res} 未配置语音转文本模型。 +msg-5bdf8f5c = {$e} +msg-ad90e19e = 重试中: {$res}/{$retry} +msg-78b9c276 = {$res} +msg-4f3245bf = 语音转文本失败: {$e} + +### astrbot/core/config/astrbot_config.py +msg-e0a69978 = 不受支持的配置类型 {$res}。支持的类型有:{$res_2} +msg-b9583fc9 = 检查到配置项 {$path_} 不存在,已插入默认值 {$value} +msg-ee26e40e = 检查到配置项 {$path_} 不存在,将从当前配置中删除 +msg-2d7497a5 = 检查到配置项 {$path} 的子项顺序不一致,已重新排序 +msg-5fdad937 = 检查到配置项顺序不一致,已重新排序 +msg-555373b0 = 没有找到 Key: '{$key}' + +### astrbot/core/platform/register.py +msg-eecf0aa8 = 平台适配器 {$adapter_name} 已经注册过了,可能发生了适配器命名冲突。 +msg-614a55eb = 平台适配器 {$adapter_name} 已注册 +msg-bb06a88d = 平台适配器 {$res} 已注销 (来自模块 {$res_2}) + +### astrbot/core/platform/platform.py +msg-30fc9871 = 平台 {$res} 未实现统一 Webhook 模式 + +### astrbot/core/platform/astr_message_event.py +msg-b593f13f = Failed to convert message type {$res} to MessageType. Falling back to FRIEND_MESSAGE. +msg-98bb33b7 = 清除 {$res} 的额外信息: {$res_2} +msg-0def44e2 = {$result} +msg-8e7dc862 = {$text} + +### astrbot/core/platform/manager.py +msg-464b7ab7 = 终止平台适配器失败: client_id=%s, error=%s +msg-78b9c276 = {$res} +msg-563a0a74 = 初始化 {$platform} 平台适配器失败: {$e} +msg-8432d24e = 平台 ID %r 包含非法字符 ':' 或 '!',已替换为 %r。 +msg-31361418 = 平台 ID {$platform_id} 不能为空,跳过加载该平台适配器。 +msg-e395bbcc = 载入 {$res}({$res_2}) 平台适配器 ... +msg-b4b29344 = 加载平台适配器 {$res} 失败,原因:{$e}。请检查依赖库是否安装。提示:可以在 管理面板->平台日志->安装Pip库 中安装依赖库。 +msg-18f0e1fe = 加载平台适配器 {$res} 失败,原因:{$e}。 +msg-2636a882 = 未找到适用于 {$res}({$res_2}) 平台适配器,请检查是否已经安装或者名称填写错误 +msg-c4a38b85 = hook(on_platform_loaded) -> {$res} - {$res_2} +msg-967606fd = ------- 任务 {$res} 发生错误: {$e} +msg-a2cd77f3 = | {$line} +msg-1f686eeb = ------- +msg-38723ea8 = 正在尝试终止 {$platform_id} 平台适配器 ... +msg-63f684c6 = 可能未完全移除 {$platform_id} 平台适配器 +msg-136a952f = 获取平台统计信息失败: {$e} + +### astrbot/core/platform/sources/dingtalk/dingtalk_adapter.py +msg-c81e728d = 2 +msg-d6371313 = dingtalk: {$res} +msg-a1c8b5b1 = 钉钉私聊会话缺少 staff_id 映射,回退使用 session_id 作为 userId 发送 +msg-2abb842f = 保存钉钉会话映射失败: {$e} +msg-46988861 = 下载钉钉文件失败: {$res}, {$res_2} +msg-ba9e1288 = 通过 dingtalk_stream 获取 access_token 失败: {$e} +msg-835b1ce6 = 获取钉钉机器人 access_token 失败: {$res}, {$res_2} +msg-331fcb1f = 读取钉钉 staff_id 映射失败: {$e} +msg-ba183a34 = 钉钉群消息发送失败: access_token 为空 +msg-b8aaa69b = 钉钉群消息发送失败: {$res}, {$res_2} +msg-cfb35bf5 = 钉钉私聊消息发送失败: access_token 为空 +msg-7553c219 = 钉钉私聊消息发送失败: {$res}, {$res_2} +msg-5ab2d58d = 清理临时文件失败: {$file_path}, {$e} +msg-c0c40912 = 钉钉语音转 OGG 失败,回退 AMR: {$e} +msg-21c73eca = 钉钉媒体上传失败: access_token 为空 +msg-24e3054f = 钉钉媒体上传失败: {$res}, {$res_2} +msg-34d0a11d = 钉钉媒体上传失败: {$data} +msg-3b0d4fb5 = 钉钉语音发送失败: {$e} +msg-7187f424 = 钉钉视频发送失败: {$e} +msg-e40cc45f = 钉钉私聊回复失败: 缺少 sender_staff_id +msg-be63618a = 钉钉适配器已被关闭 +msg-0ab22b13 = 钉钉机器人启动失败: {$e} + +### astrbot/core/platform/sources/dingtalk/dingtalk_event.py +msg-eaa1f3e4 = 钉钉消息发送失败: 缺少 adapter + +### astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_server.py +msg-41a3e59d = 正在登录到 QQ 官方机器人... +msg-66040e15 = 已登录 QQ 官方机器人账号: {$res} +msg-6ed59b60 = 收到 qq_official_webhook 回调: {$msg} +msg-ad355b59 = {$signed} +msg-1f6260e4 = _parser unknown event %s. +msg-cef08b17 = 将在 {$res}:{$res_2} 端口启动 QQ 官方机器人 webhook 适配器。 + +### astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_adapter.py +msg-3803e307 = [QQOfficialWebhook] No cached msg_id for session: %s, skip send_by_session +msg-08fd28cf = [QQOfficialWebhook] Unsupported message type for send_by_session: %s +msg-6fa95bb3 = Exception occurred during QQOfficialWebhook server shutdown: {$exc} +msg-6f83eea0 = QQ 机器人官方 API 适配器已经被优雅地关闭 + +### astrbot/core/platform/sources/discord/discord_platform_event.py +msg-0056366b = [Discord] 解析消息链时失败: {$e} +msg-fa0a9e40 = [Discord] 尝试发送空消息,已忽略。 +msg-5ccebf9a = [Discord] 频道 {$res} 不是可发送消息的类型 +msg-1550c1eb = [Discord] 发送消息时发生未知错误: {$e} +msg-7857133d = [Discord] 无法获取频道 {$res} +msg-050aa8d6 = [Discord] 开始处理 Image 组件: {$i} +msg-57c802ef = [Discord] Image 组件没有 file 属性: {$i} +msg-f2bea7ac = [Discord] 处理 URL 图片: {$file_content} +msg-c3eae1f1 = [Discord] 处理 File URI: {$file_content} +msg-6201da92 = [Discord] 图片文件不存在: {$path} +msg-2a6f0cd4 = [Discord] 处理 Base64 URI +msg-b589c643 = [Discord] 尝试作为裸 Base64 处理 +msg-41dd4b8f = [Discord] 裸 Base64 解码失败,作为本地路径处理: {$file_content} +msg-f59778a1 = [Discord] 处理图片时发生未知严重错误: {$file_info} +msg-85665612 = [Discord] 获取文件失败,路径不存在: {$file_path_str} +msg-e55956fb = [Discord] 获取文件失败: {$res} +msg-56cc0d48 = [Discord] 处理文件失败: {$res}, 错误: {$e} +msg-c0705d4e = [Discord] 忽略了不支持的消息组件: {$res} +msg-0417d127 = [Discord] 消息内容超过2000字符,将被截断。 +msg-6277510f = [Discord] 添加反应失败: {$e} + +### astrbot/core/platform/sources/discord/client.py +msg-940888cb = [Discord] 客户端未正确加载用户信息 (self.user is None) +msg-9a3c1925 = [Discord] 已作为 {$res} (ID: {$res_2}) 登录 +msg-30c1f1c8 = [Discord] 客户端已准备就绪。 +msg-d8c03bdf = [Discord] on_ready_once_callback 执行失败: {$e} +msg-c9601653 = Bot is not ready: self.user is None +msg-4b017a7c = Interaction received without a valid user +msg-3067bdce = [Discord] 收到原始消息 from {$res}: {$res_2} + +### astrbot/core/platform/sources/discord/discord_platform_adapter.py +msg-7ea23347 = [Discord] 客户端未就绪 (self.client.user is None),无法发送消息 +msg-ff6611ce = [Discord] Invalid channel ID format: {$channel_id_str} +msg-5e4e5d63 = [Discord] Can't get channel info for {$channel_id_str}, will guess message type. +msg-32d4751b = [Discord] 收到消息: {$message_data} +msg-8296c994 = [Discord] Bot Token 未配置。请在配置文件中正确设置 token。 +msg-170b31df = [Discord] 登录失败。请检查你的 Bot Token 是否正确。 +msg-6678fbd3 = [Discord] 与 Discord 的连接已关闭。 +msg-cd8c35d2 = [Discord] 适配器运行时发生意外错误: {$e} +msg-4df30f1d = [Discord] 客户端未就绪 (self.client.user is None),无法处理消息 +msg-f7803502 = [Discord] 收到非 Message 类型的消息: {$res},已忽略。 +msg-134e70e9 = [Discord] 正在终止适配器... (step 1: cancel polling task) +msg-5c01a092 = [Discord] polling_task 已取消。 +msg-77f8ca59 = [Discord] polling_task 取消异常: {$e} +msg-528b6618 = [Discord] 正在清理已注册的斜杠指令... (step 2) +msg-d0b832e6 = [Discord] 指令清理完成。 +msg-43383f5e = [Discord] 清理指令时发生错误: {$e} +msg-b960ed33 = [Discord] 正在关闭 Discord 客户端... (step 3) +msg-5e58f8a2 = [Discord] 客户端关闭异常: {$e} +msg-d1271bf1 = [Discord] 适配器已终止。 +msg-c374da7a = [Discord] 开始收集并注册斜杠指令... +msg-a6d37e4d = [Discord] 准备同步 {$res} 个指令: {$res_2} +msg-dbcaf095 = [Discord] 没有发现可注册的指令。 +msg-09209f2f = [Discord] 指令同步完成。 +msg-a95055fd = [Discord] 回调函数触发: {$cmd_name} +msg-55b13b1e = [Discord] 回调函数参数: {$ctx} +msg-79f72e4e = [Discord] 回调函数参数: {$params} +msg-22add467 = [Discord] 斜杠指令 '{$cmd_name}' 被触发。 原始参数: '{$params}'. 构建的指令字符串: '{$message_str_for_filter}' +msg-ccffc74a = [Discord] 指令 '{$cmd_name}' defer 失败: {$e} +msg-13402a28 = [Discord] 跳过不符合规范的指令: {$cmd_name} + +### astrbot/core/platform/sources/aiocqhttp/aiocqhttp_platform_adapter.py +msg-859d480d = Handle request message failed: {$e} +msg-6fb672e1 = Handle notice message failed: {$e} +msg-cf4687a3 = Handle group message failed: {$e} +msg-3a9853e3 = Handle private message failed: {$e} +msg-ec06dc3d = aiocqhttp(OneBot v11) 适配器已连接。 +msg-1304a54d = [aiocqhttp] RawMessage {$event} +msg-93cbb9fa = {$err} +msg-a4487a03 = 回复消息失败: {$e} +msg-48bc7bff = guessing lagrange +msg-6ab145a1 = 获取文件失败: {$ret} +msg-457454d7 = 获取文件失败: {$e},此消息段将被忽略。 +msg-7a299806 = 无法从回复消息数据构造 Event 对象: {$reply_event_data} +msg-e6633a51 = 获取引用消息失败: {$e}。 +msg-6e99cb8d = 获取 @ 用户信息失败: {$e},此消息段将被忽略。 +msg-cf15fd40 = 不支持的消息段类型,已忽略: {$t}, data={$res} +msg-45d126ad = 消息段解析失败: type={$t}, data={$res}. {$e} +msg-394a20ae = aiocqhttp: 未配置 ws_reverse_host 或 ws_reverse_port,将使用默认值:http://0.0.0.0:6199 +msg-7414707c = aiocqhttp 适配器已被关闭 + +### astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py +msg-0db8227d = 无法发送消息:缺少有效的数字 session_id({$session_id}) 或 event({$event}) + +### astrbot/core/platform/sources/lark/server.py +msg-2f3bccf1 = 未配置 encrypt_key,无法解密事件 +msg-e77104e2 = [Lark Webhook] 收到 challenge 验证请求: {$challenge} +msg-34b24fa1 = [Lark Webhook] 解析请求体失败: {$e} +msg-ec0fe13e = [Lark Webhook] 请求体为空 +msg-f69ebbdb = [Lark Webhook] 签名验证失败 +msg-7ece4036 = [Lark Webhook] 解密后的事件: {$event_data} +msg-f2cb4b46 = [Lark Webhook] 解密事件失败: {$e} +msg-ef9f8906 = [Lark Webhook] Verification Token 不匹配。 +msg-bedb2071 = [Lark Webhook] 处理事件回调失败: {$e} + +### astrbot/core/platform/sources/lark/lark_event.py +msg-eefbe737 = [Lark] API Client im 模块未初始化 +msg-a21f93fa = [Lark] 主动发送消息时,receive_id 和 receive_id_type 不能为空 +msg-f456e468 = [Lark] 发送飞书消息失败({$res}): {$res_2} +msg-1eb66d14 = [Lark] 文件不存在: {$path} +msg-1df39b24 = [Lark] API Client im 模块未初始化,无法上传文件 +msg-2ee721dd = [Lark] 无法上传文件({$res}): {$res_2} +msg-a04abf78 = [Lark] 上传文件成功但未返回数据(data is None) +msg-959e78a4 = [Lark] 文件上传成功: {$file_key} +msg-901a2f60 = [Lark] 无法打开或上传文件: {$e} +msg-13065327 = [Lark] 图片路径为空,无法上传 +msg-37245892 = [Lark] 无法打开图片文件: {$e} +msg-ad63bf53 = [Lark] API Client im 模块未初始化,无法上传图片 +msg-ef90038b = 无法上传飞书图片({$res}): {$res_2} +msg-d2065832 = [Lark] 上传图片成功但未返回数据(data is None) +msg-dbb635c2 = {$image_key} +msg-d4810504 = [Lark] 检测到文件组件,将单独发送 +msg-45556717 = [Lark] 检测到音频组件,将单独发送 +msg-959070b5 = [Lark] 检测到视频组件,将单独发送 +msg-4e2aa152 = 飞书 暂时不支持消息段: {$res} +msg-20d7c64b = [Lark] 无法获取音频文件路径: {$e} +msg-2f6f35e6 = [Lark] 音频文件不存在: {$original_audio_path} +msg-528b968d = [Lark] 音频格式转换失败,将尝试直接上传: {$e} +msg-fbc7efb9 = [Lark] 已删除转换后的音频文件: {$converted_audio_path} +msg-09840299 = [Lark] 删除转换后的音频文件失败: {$e} +msg-e073ff1c = [Lark] 无法获取视频文件路径: {$e} +msg-47e52913 = [Lark] 视频文件不存在: {$original_video_path} +msg-85ded1eb = [Lark] 视频格式转换失败,将尝试直接上传: {$e} +msg-b3bee05d = [Lark] 已删除转换后的视频文件: {$converted_video_path} +msg-775153f6 = [Lark] 删除转换后的视频文件失败: {$e} +msg-45038ba7 = [Lark] API Client im 模块未初始化,无法发送表情 +msg-8d475b01 = 发送飞书表情回应失败({$res}): {$res_2} + +### astrbot/core/platform/sources/lark/lark_adapter.py +msg-06ce76eb = 未设置飞书机器人名称,@ 机器人可能得不到回复。 +msg-eefbe737 = [Lark] API Client im 模块未初始化 +msg-236bcaad = [Lark] 下载消息资源失败 type={$resource_type}, key={$file_key}, code={$res}, msg={$res_2} +msg-ef9a61fe = [Lark] 消息资源响应中不包含文件流: {$file_key} +msg-7b69a8d4 = [Lark] 图片消息缺少 message_id +msg-59f1694d = [Lark] 富文本视频消息缺少 message_id +msg-af8f391d = [Lark] 文件消息缺少 message_id +msg-d4080b76 = [Lark] 文件消息缺少 file_key +msg-ab21318a = [Lark] 音频消息缺少 message_id +msg-9ec2c30a = [Lark] 音频消息缺少 file_key +msg-0fa9ed18 = [Lark] 视频消息缺少 message_id +msg-ae884c5c = [Lark] 视频消息缺少 file_key +msg-dac98a62 = [Lark] 获取引用消息失败 id={$parent_message_id}, code={$res}, msg={$res_2} +msg-7ee9f7dc = [Lark] 引用消息响应为空 id={$parent_message_id} +msg-2b3b2db9 = [Lark] 解析引用消息内容失败 id={$quoted_message_id} +msg-c5d54255 = [Lark] 收到空事件(event.event is None) +msg-82f041c4 = [Lark] 事件中没有消息体(message is None) +msg-206c3506 = [Lark] 消息内容为空 +msg-876aa1d2 = [Lark] 解析消息内容失败: {$res} +msg-514230f3 = [Lark] 消息内容不是 JSON Object: {$res} +msg-0898cf8b = [Lark] 解析消息内容: {$content_json_b} +msg-6a8bc661 = [Lark] 消息缺少 message_id +msg-26554571 = [Lark] 消息发送者信息不完整 +msg-007d863a = [Lark Webhook] 跳过重复事件: {$event_id} +msg-6ce17e71 = [Lark Webhook] 未处理的事件类型: {$event_type} +msg-8689a644 = [Lark Webhook] 处理事件失败: {$e} +msg-20688453 = [Lark] Webhook 模式已启用,但 webhook_server 未初始化 +msg-f46171bc = [Lark] Webhook 模式已启用,但未配置 webhook_uuid +msg-dd90a367 = 飞书(Lark) 适配器已关闭 + +### astrbot/core/platform/sources/wecom/wecom_event.py +msg-e164c137 = 未找到微信客服发送消息方法。 +msg-c114425e = 微信客服上传图片失败: {$e} +msg-a90bc15d = 微信客服上传图片返回: {$response} +msg-38298880 = 微信客服上传语音失败: {$e} +msg-3aee0caa = 微信客服上传语音返回: {$response} +msg-15e6381b = 删除临时音频文件失败: {$e} +msg-a79ae417 = 微信客服上传文件失败: {$e} +msg-374455ef = 微信客服上传文件返回: {$response} +msg-a2a133e4 = 微信客服上传视频失败: {$e} +msg-2732fffd = 微信客服上传视频返回: {$response} +msg-60815f02 = 还没实现这个消息类型的发送逻辑: {$res}。 +msg-9913aa52 = 企业微信上传图片失败: {$e} +msg-9e90ba91 = 企业微信上传图片返回: {$response} +msg-232af016 = 企业微信上传语音失败: {$e} +msg-e5b8829d = 企业微信上传语音返回: {$response} +msg-f68671d7 = 企业微信上传文件失败: {$e} +msg-8cdcc397 = 企业微信上传文件返回: {$response} +msg-4f3e15f5 = 企业微信上传视频失败: {$e} +msg-4e9aceea = 企业微信上传视频返回: {$response} + +### astrbot/core/platform/sources/wecom/wecom_adapter.py +msg-d4bbf9cb = 验证请求有效性: {$res} +msg-f8694a8a = 验证请求有效性成功。 +msg-8f4cda74 = 验证请求有效性失败,签名异常,请检查配置。 +msg-46d3feb9 = 解密失败,签名异常,请检查配置。 +msg-4d1dfce4 = 解析成功: {$msg} +msg-a98efa4b = 将在 {$res}:{$res_2} 端口启动 企业微信 适配器。 +msg-a616d9ce = 企业微信客服模式不支持 send_by_session 主动发送。 +msg-5d01d7b9 = send_by_session 失败:无法为会话 {$res} 推断 agent_id。 +msg-3f05613d = 获取到微信客服列表: {$acc_list} +msg-8fd19bd9 = 获取微信客服失败,open_kfid 为空。 +msg-5900d9b6 = Found open_kfid: {$open_kfid} +msg-391119b8 = 请打开以下链接,在微信扫码以获取客服微信: https://api.cl2wm.cn/api/qrcode/code?text={$kf_url} +msg-5bdf8f5c = {$e} +msg-93c9125e = 转换音频失败: {$e}。如果没有安装 ffmpeg 请先安装。 +msg-b2f7d1dc = 暂未实现的事件: {$res} +msg-61480a61 = abm: {$abm} +msg-42431e46 = 未实现的微信客服消息事件: {$msg} +msg-fbca491d = 企业微信 适配器已被关闭 + +### astrbot/core/platform/sources/weixin_official_account/weixin_offacc_event.py +msg-fa7f7afc = split plain into {$res} chunks for passive reply. Message not sent. +msg-59231e07 = 微信公众平台上传图片失败: {$e} +msg-d3968fc5 = 微信公众平台上传图片返回: {$response} +msg-7834b934 = 微信公众平台上传语音失败: {$e} +msg-4901d769 = 微信公众平台上传语音返回: {$response} +msg-15e6381b = 删除临时音频文件失败: {$e} +msg-60815f02 = 还没实现这个消息类型的发送逻辑: {$res}。 + +### astrbot/core/platform/sources/weixin_official_account/weixin_offacc_adapter.py +msg-d4bbf9cb = 验证请求有效性: {$res} +msg-b2edb1b2 = 未知的响应,请检查回调地址是否填写正确。 +msg-f8694a8a = 验证请求有效性成功。 +msg-8f4cda74 = 验证请求有效性失败,签名异常,请检查配置。 +msg-46d3feb9 = 解密失败,签名异常,请检查配置。 +msg-e23d8bff = 解析失败。msg为None。 +msg-4d1dfce4 = 解析成功: {$msg} +msg-193d9d7a = 用户消息缓冲状态: user={$from_user} state={$state} +msg-57a3c1b2 = wx buffer hit on trigger: user={$from_user} +msg-bed995d9 = wx buffer hit on retry window: user={$from_user} +msg-3a94b6ab = wx finished message sending in passive window: user={$from_user} msg_id={$msg_id} +msg-50c4b253 = wx finished message sending in passive window but not final: user={$from_user} msg_id={$msg_id} +msg-7d8b62e7 = wx finished in window but not final; return placeholder: user={$from_user} msg_id={$msg_id} +msg-2b9b8aed = wx task failed in passive window +msg-7bdf4941 = wx passive window timeout: user={$from_user} msg_id={$msg_id} +msg-98489949 = wx trigger while thinking: user={$from_user} +msg-01d0bbeb = wx new trigger: user={$from_user} msg_id={$msg_id} +msg-52bb36cd = wx start task: user={$from_user} msg_id={$msg_id} preview={$preview} +msg-ec9fd2ed = wx buffer hit immediately: user={$from_user} +msg-61c91fb9 = wx not finished in first window; return placeholder: user={$from_user} msg_id={$msg_id} +msg-35604bba = wx task failed in first window +msg-e56c4a28 = wx first window timeout: user={$from_user} msg_id={$msg_id} +msg-e163be40 = 将在 {$res}:{$res_2} 端口启动 微信公众平台 适配器。 +msg-c1740a04 = duplicate message id checked: {$res} +msg-04718b37 = Got future result: {$result} +msg-296e66c1 = callback 处理消息超时: message_id={$res} +msg-eb718c92 = 转换消息时出现异常: {$e} +msg-93c9125e = 转换音频失败: {$e}。如果没有安装 ffmpeg 请先安装。 +msg-b2f7d1dc = 暂未实现的事件: {$res} +msg-61480a61 = abm: {$abm} +msg-2e7e0187 = 用户消息未找到缓冲状态,无法处理消息: user={$res} message_id={$res_2} +msg-84312903 = 微信公众平台 适配器已被关闭 + +### astrbot/core/platform/sources/misskey/misskey_adapter.py +msg-7bacee77 = [Misskey] 配置不完整,无法启动 +msg-99cdf3d3 = [Misskey] 已连接用户: {$res} (ID: {$res_2}) +msg-5579c974 = [Misskey] 获取用户信息失败: {$e} +msg-d9547102 = [Misskey] API 客户端未初始化 +msg-341b0aa0 = [Misskey] WebSocket 已连接 (尝试 #{$connection_attempts}) +msg-c77d157b = [Misskey] 聊天频道已订阅 +msg-a0c5edc0 = [Misskey] WebSocket 连接失败 (尝试 #{$connection_attempts}) +msg-1958faa8 = [Misskey] WebSocket 异常 (尝试 #{$connection_attempts}): {$e} +msg-1b47382d = [Misskey] {$sleep_time}秒后重连 (下次尝试 #{$res}) +msg-a10a224d = [Misskey] 收到通知事件: type={$notification_type}, user_id={$res} +msg-7f0abf4a = [Misskey] 处理贴文提及: {$res}... +msg-2da7cdf5 = [Misskey] 处理通知失败: {$e} +msg-6c21d412 = [Misskey] 收到聊天事件: sender_id={$sender_id}, room_id={$room_id}, is_self={$res} +msg-68269731 = [Misskey] 检查群聊消息: '{$raw_text}', 机器人用户名: '{$res}' +msg-585aa62b = [Misskey] 处理群聊消息: {$res}... +msg-426c7874 = [Misskey] 处理私聊消息: {$res}... +msg-f5aff493 = [Misskey] 处理聊天消息失败: {$e} +msg-ea465183 = [Misskey] 收到未处理事件: type={$event_type}, channel={$res} +msg-8b69eb93 = [Misskey] 消息内容为空且无文件组件,跳过发送 +msg-9ba9c4e5 = [Misskey] 已清理临时文件: {$local_path} +msg-91af500e = [Misskey] 文件数量超过限制 ({$res} > {$MAX_FILE_UPLOAD_COUNT}),只上传前{$MAX_FILE_UPLOAD_COUNT}个文件 +msg-9746d7f5 = [Misskey] 并发上传过程中出现异常,继续发送文本 +msg-d6dc928c = [Misskey] 聊天消息只支持单个文件,忽略其余 {$res} 个文件 +msg-af584ae8 = [Misskey] 解析可见性: visibility={$visibility}, visible_user_ids={$visible_user_ids}, session_id={$session_id}, user_id_for_cache={$user_id_for_cache} +msg-1a176905 = [Misskey] 发送消息失败: {$e} + +### astrbot/core/platform/sources/misskey/misskey_api.py +msg-fab20f57 = aiohttp and websockets are required for Misskey API. Please install them with: pip install aiohttp websockets +msg-f2eea8e1 = [Misskey WebSocket] 已连接 +msg-5efd11a2 = [Misskey WebSocket] 重新订阅 {$channel_type} 失败: {$e} +msg-b70e2176 = [Misskey WebSocket] 连接失败: {$e} +msg-b9f3ee06 = [Misskey WebSocket] 连接已断开 +msg-7cd98e54 = WebSocket 未连接 +msg-43566304 = [Misskey WebSocket] 无法解析消息: {$e} +msg-e617e390 = [Misskey WebSocket] 处理消息失败: {$e} +msg-c60715cf = [Misskey WebSocket] 连接意外关闭: {$e} +msg-da9a2a17 = [Misskey WebSocket] 连接已关闭 (代码: {$res}, 原因: {$res_2}) +msg-bbf6a42e = [Misskey WebSocket] 握手失败: {$e} +msg-254f0237 = [Misskey WebSocket] 监听消息失败: {$e} +msg-49f7e90e = {$channel_summary} +msg-630a4832 = [Misskey WebSocket] 频道消息: {$channel_id}, 事件类型: {$event_type} +msg-0dc61a4d = [Misskey WebSocket] 使用处理器: {$handler_key} +msg-012666fc = [Misskey WebSocket] 使用事件处理器: {$event_type} +msg-e202168a = [Misskey WebSocket] 未找到处理器: {$handler_key} 或 {$event_type} +msg-a397eef1 = [Misskey WebSocket] 直接消息处理器: {$message_type} +msg-a5f12225 = [Misskey WebSocket] 未处理的消息类型: {$message_type} +msg-ad61d480 = [Misskey API] {$func_name} 重试 {$max_retries} 次后仍失败: {$e} +msg-7de2ca49 = [Misskey API] {$func_name} 第 {$attempt} 次重试失败: {$e},{$sleep_time}s后重试 +msg-f5aecf37 = [Misskey API] {$func_name} 遇到不可重试异常: {$e} +msg-e5852be5 = [Misskey API] 客户端已关闭 +msg-21fc185c = [Misskey API] 请求参数错误: {$endpoint} (HTTP {$status}) +msg-5b106def = Bad request for {$endpoint} +msg-28afff67 = [Misskey API] 未授权访问: {$endpoint} (HTTP {$status}) +msg-e12f2d28 = Unauthorized access for {$endpoint} +msg-beda662d = [Misskey API] 访问被禁止: {$endpoint} (HTTP {$status}) +msg-795ca227 = Forbidden access for {$endpoint} +msg-5c6ba873 = [Misskey API] 资源不存在: {$endpoint} (HTTP {$status}) +msg-74f2bac2 = Resource not found for {$endpoint} +msg-9ceafe4c = [Misskey API] 请求体过大: {$endpoint} (HTTP {$status}) +msg-3e336b73 = Request entity too large for {$endpoint} +msg-a47067de = [Misskey API] 请求频率限制: {$endpoint} (HTTP {$status}) +msg-901dc2da = Rate limit exceeded for {$endpoint} +msg-2bea8c2e = [Misskey API] 服务器内部错误: {$endpoint} (HTTP {$status}) +msg-ae8d3725 = Internal server error for {$endpoint} +msg-7b028462 = [Misskey API] 网关错误: {$endpoint} (HTTP {$status}) +msg-978414ef = Bad gateway for {$endpoint} +msg-50895a69 = [Misskey API] 服务不可用: {$endpoint} (HTTP {$status}) +msg-62adff89 = Service unavailable for {$endpoint} +msg-1cf15497 = [Misskey API] 网关超时: {$endpoint} (HTTP {$status}) +msg-a8a2578d = Gateway timeout for {$endpoint} +msg-c012110a = [Misskey API] 未知错误: {$endpoint} (HTTP {$status}) +msg-dc96bbb8 = HTTP {$status} for {$endpoint} +msg-4c7598b6 = [Misskey API] 获取到 {$res} 条新通知 +msg-851a2a54 = [Misskey API] 请求成功: {$endpoint} +msg-5f5609b6 = [Misskey API] 响应格式错误: {$e} +msg-c8f7bbeb = Invalid JSON response +msg-82748b31 = [Misskey API] 请求失败: {$endpoint} - HTTP {$res}, 响应: {$error_text} +msg-c6de3320 = [Misskey API] 请求失败: {$endpoint} - HTTP {$res} +msg-affb19a7 = [Misskey API] HTTP 请求错误: {$e} +msg-9f1286b3 = HTTP request failed: {$e} +msg-44f91be2 = [Misskey API] 发帖成功: {$note_id} +msg-fbafd3db = No file path provided for upload +msg-872d8419 = [Misskey API] 本地文件不存在: {$file_path} +msg-37186dea = File not found: {$file_path} +msg-65ef68e0 = [Misskey API] 本地文件上传成功: {$filename} -> {$file_id} +msg-0951db67 = [Misskey API] 文件上传网络错误: {$e} +msg-e3a322f5 = Upload failed: {$e} +msg-f28772b9 = No MD5 hash provided for find-by-hash +msg-25e566ef = [Misskey API] find-by-hash 请求: md5={$md5_hash} +msg-a036a942 = [Misskey API] find-by-hash 响应: 找到 {$res} 个文件 +msg-ea3581d5 = [Misskey API] 根据哈希查找文件失败: {$e} +msg-1d2a84ff = No name provided for find +msg-f25e28b4 = [Misskey API] find 请求: name={$name}, folder_id={$folder_id} +msg-cd43861a = [Misskey API] find 响应: 找到 {$res} 个文件 +msg-05cd55ef = [Misskey API] 根据名称查找文件失败: {$e} +msg-c01052a4 = [Misskey API] 列表文件请求: limit={$limit}, folder_id={$folder_id}, type={$type} +msg-7c81620d = [Misskey API] 列表文件响应: 找到 {$res} 个文件 +msg-a187a089 = [Misskey API] 列表文件失败: {$e} +msg-9e776259 = No existing session available +msg-de18c220 = URL不能为空 +msg-25b15b61 = [Misskey API] SSL 验证下载失败: {$ssl_error},重试不验证 SSL +msg-b6cbeef6 = [Misskey API] 本地上传成功: {$res} +msg-a4a898e2 = [Misskey API] 本地上传失败: {$e} +msg-46b7ea4b = [Misskey API] 聊天消息发送成功: {$message_id} +msg-32f71df4 = [Misskey API] 房间消息发送成功: {$message_id} +msg-7829f3b3 = [Misskey API] 聊天消息响应格式异常: {$res} +msg-d74c86a1 = [Misskey API] 提及通知响应格式异常: {$res} +msg-65ccb697 = 消息内容不能为空:需要文本或媒体文件 +msg-b6afb123 = [Misskey API] URL媒体上传成功: {$res} +msg-4e62bcdc = [Misskey API] URL媒体上传失败: {$url} +msg-71cc9d61 = [Misskey API] URL媒体处理失败 {$url}: {$e} +msg-75890c2b = [Misskey API] 本地文件上传成功: {$res} +msg-024d0ed5 = [Misskey API] 本地文件上传失败: {$file_path} +msg-f1fcb5e1 = [Misskey API] 本地文件处理失败 {$file_path}: {$e} +msg-1ee80a6b = 不支持的消息类型: {$message_type} + +### astrbot/core/platform/sources/misskey/misskey_event.py +msg-85cb7d49 = [MisskeyEvent] send 方法被调用,消息链包含 {$res} 个组件 +msg-252c2fca = [MisskeyEvent] 检查适配器方法: hasattr(self.client, 'send_by_session') = {$res} +msg-44d7a060 = [MisskeyEvent] 调用适配器的 send_by_session 方法 +msg-b6e08872 = [MisskeyEvent] 内容为空,跳过发送 +msg-8cfebc9c = [MisskeyEvent] 创建新帖子 +msg-ed0d2ed5 = [MisskeyEvent] 发送失败: {$e} + +### astrbot/core/platform/sources/wecom_ai_bot/wecomai_webhook.py +msg-a5c90267 = 消息推送 webhook URL 不能为空 +msg-76bfb25b = 消息推送 webhook URL 缺少 key 参数 +msg-3545eb07 = Webhook 请求失败: HTTP {$res}, {$text} +msg-758dfe0d = Webhook 返回错误: {$res} {$res_2} +msg-c056646b = 企业微信消息推送成功: %s +msg-73d3e179 = 文件不存在: {$file_path} +msg-774a1821 = 上传媒体失败: HTTP {$res}, {$text} +msg-6ff016a4 = 上传媒体失败: {$res} {$res_2} +msg-0e8252d1 = 上传媒体失败: 返回缺少 media_id +msg-9dbc2296 = 文件消息缺少有效文件路径,已跳过: %s +msg-2e567c36 = 清理临时语音文件失败 %s: %s +msg-e99c4df9 = 企业微信消息推送暂不支持组件类型 %s,已跳过 + +### astrbot/core/platform/sources/wecom_ai_bot/WXBizJsonMsgCrypt.py +msg-5bdf8f5c = {$e} +msg-fe69e232 = receiveid not match +msg-00b71c27 = signature not match +msg-5cfb5c20 = {$signature} + +### astrbot/core/platform/sources/wecom_ai_bot/wecomai_event.py +msg-e44e77b0 = 图片数据为空,跳过 +msg-30d116ed = 处理图片消息失败: %s +msg-31b11295 = [WecomAI] 不支持的消息组件类型: {$res}, 跳过 + +### astrbot/core/platform/sources/wecom_ai_bot/wecomai_adapter.py +msg-277cdd37 = 企业微信消息推送 webhook 配置无效: %s +msg-2102fede = 处理队列消息时发生异常: {$e} +msg-d4ea688d = 消息类型未知,忽略: {$message_data} +msg-15ba426f = 处理消息时发生异常: %s +msg-740911ab = Stream already finished, returning end message: {$stream_id} +msg-9fdbafe9 = Cannot find back queue for stream_id: {$stream_id} +msg-7a52ca2b = No new messages in back queue for stream_id: {$stream_id} +msg-9ffb59fb = Aggregated content: {$latest_plain_content}, image: {$res}, finish: {$finish} +msg-de9ff585 = Stream message sent successfully, stream_id: {$stream_id} +msg-558310b9 = 消息加密失败 +msg-251652f9 = 处理欢迎消息时发生异常: %s +msg-480c5dac = [WecomAI] 消息已入队: {$stream_id} +msg-f595dd6e = 处理加密图片失败: {$result} +msg-e8beeb3d = WecomAIAdapter: {$res} +msg-6f8ad811 = 主动消息发送失败: 未配置企业微信消息推送 Webhook URL,请前往配置添加。session_id=%s +msg-84439b09 = 企业微信消息推送失败(session=%s): %s +msg-f70f5008 = 启动企业微信智能机器人适配器,监听 %s:%d +msg-87616945 = 企业微信智能机器人适配器正在关闭... + +### astrbot/core/platform/sources/wecom_ai_bot/wecomai_api.py +msg-86f6ae9f = 消息解密失败,错误码: {$ret} +msg-45ad825c = 解密成功,消息内容: {$message_data} +msg-84c476a7 = JSON 解析失败: {$e}, 原始消息: {$decrypted_msg} +msg-c0d8c5f9 = 解密消息为空 +msg-a08bcfc7 = 解密过程发生异常: {$e} +msg-4dfaa613 = 消息加密失败,错误码: {$ret} +msg-6e566b12 = 消息加密成功 +msg-39bf8dba = 加密过程发生异常: {$e} +msg-fa5be7c5 = URL 验证失败,错误码: {$ret} +msg-813a4e4e = URL 验证成功 +msg-65ce0d23 = URL 验证发生异常: {$e} +msg-b1aa892f = 开始下载加密图片: {$image_url} +msg-10f72727 = {$error_msg} +msg-70123a82 = 图片下载成功,大小: {$res} 字节 +msg-85d2dba1 = AES 密钥不能为空 +msg-67c4fcea = 无效的 AES 密钥长度: 应为 32 字节 +msg-bde4bb57 = 无效的填充长度 (大于32字节) +msg-63c22912 = 图片解密成功,解密后大小: {$res} 字节 +msg-6ea489f0 = 文本消息解析失败 +msg-eb12d147 = 图片消息解析失败 +msg-ab1157ff = 流消息解析失败 +msg-e7e945d1 = 混合消息解析失败 +msg-06ada9dd = 事件消息解析失败 + +### astrbot/core/platform/sources/wecom_ai_bot/wecomai_server.py +msg-adaee66c = URL 验证参数缺失 +msg-742e0b43 = 收到企业微信智能机器人 WebHook URL 验证请求。 +msg-f86c030c = 消息回调参数缺失 +msg-cce4e44c = 收到消息回调,msg_signature={$msg_signature}, timestamp={$timestamp}, nonce={$nonce} +msg-7f018a3c = 消息解密失败,错误码: %d +msg-9d42e548 = 消息处理器执行异常: %s +msg-15ba426f = 处理消息时发生异常: %s +msg-5bf7dffa = 启动企业微信智能机器人服务器,监听 %s:%d +msg-445921d5 = 服务器运行异常: %s +msg-3269840c = 企业微信智能机器人服务器正在关闭... + +### astrbot/core/platform/sources/wecom_ai_bot/wecomai_queue_mgr.py +msg-8be03d44 = [WecomAI] 创建输入队列: {$session_id} +msg-9804296a = [WecomAI] 创建输出队列: {$session_id} +msg-bdf0fb78 = [WecomAI] 移除输出队列: {$session_id} +msg-40f6bb7b = [WecomAI] 移除待处理响应: {$session_id} +msg-fbb807cd = [WecomAI] 标记流已结束: {$session_id} +msg-9d7f5627 = [WecomAI] 移除输入队列: {$session_id} +msg-7637ed00 = [WecomAI] 设置待处理响应: {$session_id} +msg-5329c49b = [WecomAI] 清理过期响应及队列: {$session_id} +msg-09f098ea = [WecomAI] 为会话启动监听器: {$session_id} +msg-c55856d6 = 处理会话 {$session_id} 消息时发生错误: {$e} + +### astrbot/core/platform/sources/wecom_ai_bot/wecomai_utils.py +msg-14d01778 = JSON 解析失败: {$e}, 原始字符串: {$json_str} +msg-df346cf5 = 开始下载加密图片: %s +msg-cb266fb3 = 图片下载成功,大小: %d 字节 +msg-10f72727 = {$error_msg} +msg-1d91d2bb = AES密钥不能为空 +msg-bb32bedd = 无效的AES密钥长度: 应为32字节 +msg-bde4bb57 = 无效的填充长度 (大于32字节) +msg-3cf2120e = 图片解密成功,解密后大小: %d 字节 +msg-3f8ca8aa = 图片已转换为base64编码,编码后长度: %d + +### astrbot/core/platform/sources/line/line_api.py +msg-06e3f874 = [LINE] %s message failed: status=%s body=%s +msg-1478c917 = [LINE] %s message request failed: %s +msg-39941f06 = [LINE] get content retry failed: message_id=%s status=%s body=%s +msg-1fe70511 = [LINE] get content failed: message_id=%s status=%s body=%s + +### astrbot/core/platform/sources/line/line_event.py +msg-4068a191 = [LINE] resolve image url failed: %s +msg-2233b256 = [LINE] resolve record url failed: %s +msg-a7455817 = [LINE] resolve record duration failed: %s +msg-9d0fee66 = [LINE] resolve video url failed: %s +msg-3b8ea946 = [LINE] resolve video cover failed: %s +msg-aea2081a = [LINE] generate video preview failed: %s +msg-af426b7e = [LINE] resolve file url failed: %s +msg-fe44c12d = [LINE] resolve file size failed: %s +msg-d6443173 = [LINE] message count exceeds 5, extra segments will be dropped. + +### astrbot/core/platform/sources/line/line_adapter.py +msg-68539775 = LINE 适配器需要 channel_access_token 和 channel_secret。 +msg-30c67081 = [LINE] webhook_uuid 为空,统一 Webhook 可能无法接收消息。 +msg-64e92929 = [LINE] invalid webhook signature +msg-71bc0b77 = [LINE] invalid webhook body: %s +msg-8c7d9bab = [LINE] duplicate event skipped: %s + +### astrbot/core/platform/sources/telegram/tg_event.py +msg-7757f090 = [Telegram] 发送 chat action 失败: {$e} +msg-80b075a3 = User privacy settings prevent receiving voice messages, falling back to sending an audio file. To enable voice messages, go to Telegram Settings → Privacy and Security → Voice Messages → set to 'Everyone'. +msg-20665ad1 = MarkdownV2 send failed: {$e}. Using plain text instead. +msg-323cb67c = [Telegram] 添加反应失败: {$e} +msg-abe7fc3d = 编辑消息失败(streaming-break): {$e} +msg-f7d40103 = 不支持的消息类型: {$res} +msg-d4b50a96 = 编辑消息失败(streaming): {$e} +msg-2701a78f = 发送消息失败(streaming): {$e} +msg-2a8ecebd = Markdown转换失败,使用普通文本: {$e} + +### astrbot/core/platform/sources/telegram/tg_adapter.py +msg-cb53f79a = Telegram base url: {$res} +msg-e6b6040f = Telegram Updater is not initialized. Cannot start polling. +msg-2c4b186e = Telegram Platform Adapter is running. +msg-908d0414 = 向 Telegram 注册指令时发生错误: {$e} +msg-d2dfe45e = 命令名 '{$cmd_name}' 重复注册,将使用首次注册的定义: '{$res}' +msg-63bdfab8 = Received a start command without an effective chat, skipping /start reply. +msg-03a27b01 = Telegram message: {$res} +msg-e47b4bb4 = Received an update without a message. +msg-c97401c6 = [Telegram] Received a message without a from_user. +msg-f5c839ee = Telegram document file_path is None, cannot save the file {$file_name}. +msg-dca991a9 = Telegram video file_path is None, cannot save the file {$file_name}. +msg-56fb2950 = Create media group cache: {$media_group_id} +msg-0de2d4b5 = Add message to media group {$media_group_id}, currently has {$res} items. +msg-9e5069e9 = Media group {$media_group_id} has reached max wait time ({$elapsed}s >= {$res}s), processing immediately. +msg-9156b9d6 = Scheduled media group {$media_group_id} to be processed in {$delay} seconds (already waited {$elapsed}s) +msg-2849c882 = Media group {$media_group_id} not found in cache +msg-c75b2163 = Media group {$media_group_id} is empty +msg-0a3626c1 = Processing media group {$media_group_id}, total {$res} items +msg-2842e389 = Failed to convert the first message of media group {$media_group_id} +msg-32fbf7c1 = Added {$res} components to media group {$media_group_id} +msg-23bae28a = Telegram adapter has been closed. +msg-e46e7740 = Error occurred while closing Telegram adapter: {$e} + +### astrbot/core/platform/sources/slack/client.py +msg-1d6b68b9 = Slack request signature verification failed +msg-53ef18c3 = Received Slack event: {$event_data} +msg-58488af6 = 处理 Slack 事件时出错: {$e} +msg-477be979 = Slack Webhook 服务器启动中,监听 {$res}:{$res_2}{$res_3}... +msg-639fee6c = Slack Webhook 服务器已停止 +msg-a238d798 = Socket client is not initialized +msg-4e6de580 = 处理 Socket Mode 事件时出错: {$e} +msg-5bb71de9 = Slack Socket Mode 客户端启动中... +msg-f79ed37f = Slack Socket Mode 客户端已停止 + +### astrbot/core/platform/sources/slack/slack_adapter.py +msg-c34657ff = Slack bot_token 是必需的 +msg-64f8a45d = Socket Mode 需要 app_token +msg-a2aba1a7 = Webhook Mode 需要 signing_secret +msg-40e00bd4 = Slack 发送消息失败: {$e} +msg-56c1d0a3 = [slack] RawMessage {$event} +msg-855510b4 = Failed to download slack file: {$res} {$res_2} +msg-04ab2fae = 下载文件失败: {$res} +msg-79ed7e65 = Slack auth test OK. Bot ID: {$res} +msg-ec27746a = Slack 适配器 (Socket Mode) 启动中... +msg-34222d3a = Slack 适配器 (Webhook Mode) 启动中,监听 {$res}:{$res_2}{$res_3}... +msg-6d8110d2 = 不支持的连接模式: {$res},请使用 'socket' 或 'webhook' +msg-d71e7f36 = Slack 适配器已被关闭 + +### astrbot/core/platform/sources/slack/slack_event.py +msg-b233107c = Slack file upload failed: {$res} +msg-596945d1 = Slack file upload response: {$response} + +### astrbot/core/platform/sources/satori/satori_adapter.py +msg-ab7db6d9 = Satori WebSocket 连接关闭: {$e} +msg-4ef42cd1 = Satori WebSocket 连接失败: {$e} +msg-b50d159b = 达到最大重试次数 ({$max_retries}),停止重试 +msg-89de477c = Satori 适配器正在连接到 WebSocket: {$res} +msg-cfa5b059 = Satori 适配器 HTTP API 地址: {$res} +msg-d534864b = 无效的WebSocket URL: {$res} +msg-a110f9f7 = WebSocket URL必须以ws://或wss://开头: {$res} +msg-bf43ccb6 = Satori 处理消息异常: {$e} +msg-89081a1a = Satori WebSocket 连接异常: {$e} +msg-5c04bfcd = Satori WebSocket 关闭异常: {$e} +msg-b67bcee0 = WebSocket连接未建立 +msg-89ea8b76 = WebSocket连接已关闭 +msg-4c8a40e3 = 发送 IDENTIFY 信令时连接关闭: {$e} +msg-05a6b99d = 发送 IDENTIFY 信令失败: {$e} +msg-c9b1b774 = Satori WebSocket 发送心跳失败: {$e} +msg-61edb4f3 = 心跳任务异常: {$e} +msg-7db44899 = Satori 连接成功 - Bot {$res}: platform={$platform}, user_id={$user_id}, user_name={$user_name} +msg-01564612 = 解析 WebSocket 消息失败: {$e}, 消息内容: {$message} +msg-3a1657ea = 处理 WebSocket 消息异常: {$e} +msg-dc6b459c = 处理事件失败: {$e} +msg-6524f582 = 解析标签时发生错误: {$e}, 错误内容: {$content} +msg-3be535c3 = 转换 Satori 消息失败: {$e} +msg-be17caf1 = XML解析失败,使用正则提取: {$e} +msg-f6f41d74 = 提取标签时发生错误: {$e} +msg-ca6dca7f = 转换引用消息失败: {$e} +msg-cd3b067e = 解析 Satori 元素时发生解析错误: {$e}, 错误内容: {$content} +msg-03071274 = 解析 Satori 元素时发生未知错误: {$e} +msg-775cd5c0 = HTTP session 未初始化 +msg-e354c8d1 = Satori HTTP 请求异常: {$e} + +### astrbot/core/platform/sources/satori/satori_event.py +msg-c063ab8a = Satori 消息发送异常: {$e} +msg-9bc42a8d = Satori 消息发送失败 +msg-dbf77ca2 = 图片转换为base64失败: {$e} +msg-8b6100fb = Satori 流式消息发送异常: {$e} +msg-3c16c45c = 语音转换为base64失败: {$e} +msg-66994127 = 视频文件转换失败: {$e} +msg-30943570 = 转换消息组件失败: {$e} +msg-3e8181fc = 转换转发节点失败: {$e} +msg-d626f831 = 转换合并转发消息失败: {$e} + +### astrbot/core/platform/sources/webchat/webchat_queue_mgr.py +msg-4af4f885 = Started listener for conversation: {$conversation_id} +msg-10237240 = Error processing message from conversation {$conversation_id}: {$e} + +### astrbot/core/platform/sources/webchat/webchat_adapter.py +msg-9406158c = WebChatAdapter: {$res} + +### astrbot/core/platform/sources/webchat/webchat_event.py +msg-6b37adcd = webchat 忽略: {$res} + +### astrbot/core/platform/sources/qqofficial/qqofficial_platform_adapter.py +msg-8af45ba1 = QQ 机器人官方 API 适配器不支持 send_by_session +msg-8ebd1249 = Unknown message type: {$message_type} +msg-c165744d = QQ 官方机器人接口 适配器已被优雅地关闭 + +### astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py +msg-28a74d9d = [QQOfficial] Skip botpy FormData patch. +msg-c0b123f6 = 发送流式消息时出错: {$e} +msg-05d6bba5 = [QQOfficial] 不支持的消息源类型: {$res} +msg-e5339577 = [QQOfficial] GroupMessage 缺少 group_openid +msg-71275806 = Message sent to C2C: {$ret} +msg-040e7942 = [QQOfficial] markdown 发送被拒绝,回退到 content 模式重试。 +msg-9000f8f7 = Invalid upload parameters +msg-d72cffe7 = Failed to upload image, response is not dict: {$result} +msg-5944a27c = 上传文件响应格式错误: {$result} +msg-1e513ee5 = 上传请求错误: {$e} +msg-f1f1733c = Failed to post c2c message, response is not dict: {$result} +msg-9b8f9f70 = Unsupported image file format +msg-24eb302a = 转换音频格式时出错:音频时长不大于0 +msg-b49e55f9 = 处理语音时出错: {$e} +msg-6e716579 = qq_official 忽略 {$res} + +### astrbot/core/provider/provider.py +msg-e6f0c96f = Provider type {$provider_type_name} not registered +msg-c7953e3f = 批次 {$batch_idx} 处理失败,已重试 {$max_retries} 次: {$e} +msg-10f72727 = {$error_msg} +msg-7ff71721 = Rerank provider test failed, no results returned + +### astrbot/core/provider/register.py +msg-19ddffc0 = 检测到大模型提供商适配器 {$provider_type_name} 已经注册,可能发生了大模型提供商适配器类型命名冲突。 +msg-7e134b0d = 服务提供商 Provider {$provider_type_name} 已注册 + +### astrbot/core/provider/func_tool_manager.py +msg-0c42a4d9 = 添加函数调用工具: {$name} +msg-e8fdbb8c = 未找到 MCP 服务配置文件,已创建默认配置文件 {$mcp_json_file} +msg-cf8aed84 = 收到 MCP 客户端 {$name} 终止信号 +msg-3d7bcc64 = 初始化 MCP 客户端 {$name} 失败 +msg-1b190842 = MCP server {$name} list tools response: {$tools_res} +msg-6dc4f652 = 已连接 MCP 服务 {$name}, Tools: {$tool_names} +msg-a44aa4f2 = 清空 MCP 客户端资源 {$name}: {$e}。 +msg-e9c96c53 = 已关闭 MCP 服务 {$name} +msg-10f72727 = {$error_msg} +msg-85f156e0 = testing MCP server connection with config: {$config} +msg-93c54ce0 = Cleaning up MCP client after testing connection. +msg-368450ee = 此函数调用工具所属的插件 {$res} 已被禁用,请先在管理面板启用再激活此工具。 +msg-4ffa2135 = 加载 MCP 配置失败: {$e} +msg-a486ac39 = 保存 MCP 配置失败: {$e} +msg-58dfdfe7 = 从 ModelScope 同步了 {$synced_count} 个 MCP 服务器 +msg-75f1222f = 没有找到可用的 ModelScope MCP 服务器 +msg-c9f6cb1d = ModelScope API 请求失败: HTTP {$res} +msg-c8ebb4f7 = 网络连接错误: {$e} +msg-0ac6970f = 同步 ModelScope MCP 服务器时发生错误: {$e} + +### astrbot/core/provider/entities.py +msg-7fc6f623 = 图片 {$image_url} 得到的结果为空,将忽略。 + +### astrbot/core/provider/manager.py +msg-9e1a7f1f = 提供商 {$provider_id} 不存在,无法设置。 +msg-5fda2049 = Unknown provider type: {$provider_type} +msg-a5cb19c6 = 没有找到 ID 为 {$provider_id} 的提供商,这可能是由于您修改了提供商(模型)ID 导致的。 +msg-78b9c276 = {$res} +msg-5bdf8f5c = {$e} +msg-b734a1f4 = Provider {$provider_id} 配置项 key[{$idx}] 使用环境变量 {$env_key} 但未设置。 +msg-664b3329 = Provider {$res} is disabled, skipping +msg-f43f8022 = 载入 {$res}({$res_2}) 服务提供商 ... +msg-edd4aefe = 加载 {$res}({$res_2}) 提供商适配器失败:{$e}。可能是因为有未安装的依赖。 +msg-78e514a1 = 加载 {$res}({$res_2}) 提供商适配器失败:{$e}。未知原因 +msg-4636f83c = 未找到适用于 {$res}({$res_2}) 的提供商适配器,请检查是否已经安装或者名称填写错误。已跳过。 +msg-e9c6c4a2 = 无法找到 {$res} 的类 +msg-f705cf50 = Provider class {$cls_type} is not a subclass of STTProvider +msg-d20620aa = 已选择 {$res}({$res_2}) 作为当前语音转文本提供商适配器。 +msg-afbe5661 = Provider class {$cls_type} is not a subclass of TTSProvider +msg-74d437ed = 已选择 {$res}({$res_2}) 作为当前文本转语音提供商适配器。 +msg-08cd85c9 = Provider class {$cls_type} is not a subclass of Provider +msg-16a2b8e0 = 已选择 {$res}({$res_2}) 作为当前提供商适配器。 +msg-0e1707e7 = Provider class {$cls_type} is not a subclass of EmbeddingProvider +msg-821d06e0 = Provider class {$cls_type} is not a subclass of RerankProvider +msg-14c35664 = 未知的提供商类型:{$res} +msg-186fd5c6 = 实例化 {$res}({$res_2}) 提供商适配器失败:{$e} +msg-ede02a99 = providers in user's config: {$config_ids} +msg-95dc4227 = 自动选择 {$res} 作为当前提供商适配器。 +msg-a6187bac = 自动选择 {$res} 作为当前语音转文本提供商适配器。 +msg-bf28f7e2 = 自动选择 {$res} 作为当前文本转语音提供商适配器。 +msg-dba10c27 = 终止 {$provider_id} 提供商适配器({$res}, {$res_2}, {$res_3}) ... +msg-9d9d9765 = {$provider_id} 提供商适配器已终止({$res}, {$res_2}, {$res_3}) +msg-925bb70a = Provider {$target_prov_ids} 已从配置中删除。 +msg-a1657092 = New provider config must have an 'id' field +msg-1486c653 = Provider ID {$npid} already exists +msg-f9fc1545 = Provider ID {$origin_provider_id} not found +msg-4e2c657c = Error while disabling MCP servers + +### astrbot/core/provider/sources/gemini_embedding_source.py +msg-173efb0e = [Gemini Embedding] 使用代理: {$proxy} +msg-58a99789 = Gemini Embedding API请求失败: {$res} +msg-5c4ea38e = Gemini Embedding API批量请求失败: {$res} + +### astrbot/core/provider/sources/bailian_rerank_source.py +msg-dc1a9e6e = 阿里云百炼 API Key 不能为空。 +msg-f7079f37 = AstrBot 百炼 Rerank 初始化完成。模型: {$res} +msg-5b6d35ce = 百炼 API 错误: {$res} – {$res_2} +msg-d600c5e2 = 百炼 Rerank 返回空结果: {$data} +msg-d3312319 = 结果 {$idx} 缺少 relevance_score,使用默认值 0.0 +msg-2855fb44 = 解析结果 {$idx} 时出错: {$e}, result={$result} +msg-392f26e8 = 百炼 Rerank 消耗 Token: {$tokens} +msg-595e0cf9 = 百炼 Rerank 客户端会话已关闭,返回空结果 +msg-d0388210 = 文档列表为空,返回空结果 +msg-44d6cc76 = 查询文本为空,返回空结果 +msg-bd8b942a = 文档数量({$res})超过限制(500),将截断前500个文档 +msg-0dc3bca4 = 百炼 Rerank 请求: query='{$res}...', 文档数量={$res_2} +msg-4a9f4ee3 = 百炼 Rerank 成功返回 {$res} 个结果 +msg-fa301307 = 百炼 Rerank 网络请求失败: {$e} +msg-10f72727 = {$error_msg} +msg-9879e226 = 百炼 Rerank 处理失败: {$e} +msg-4f15074c = 关闭 百炼 Rerank 客户端会话 +msg-d01b1b0f = 关闭 百炼 Rerank 客户端时出错: {$e} + +### astrbot/core/provider/sources/edge_tts_source.py +msg-f4ab0713 = pyffmpeg 转换失败: {$e}, 尝试使用 ffmpeg 命令行进行转换 +msg-ddc3594a = [EdgeTTS] FFmpeg 标准输出: {$res} +msg-1b8c0a83 = FFmpeg错误输出: {$res} +msg-1e980a68 = [EdgeTTS] 返回值(0代表成功): {$res} +msg-c39d210c = 生成的WAV文件不存在或为空 +msg-57f60837 = FFmpeg 转换失败: {$res} +msg-ca94a42a = FFmpeg 转换失败: {$e} +msg-be660d63 = 音频生成失败: {$e} + +### astrbot/core/provider/sources/whisper_api_source.py +msg-28cbbf07 = 文件不存在: {$audio_url} +msg-b335b8db = Converting silk file to wav using tencent_silk_to_wav... +msg-68b5660f = Converting amr file to wav using convert_to_pcm_wav... +msg-cad3735e = Failed to remove temp file {$audio_url}: {$e} + +### astrbot/core/provider/sources/gemini_source.py +msg-1474947f = [Gemini] 使用代理: {$proxy} +msg-e2a81024 = 检测到 Key 异常({$res}),正在尝试更换 API Key 重试... 当前 Key: {$res_2}... +msg-0d388dae = 检测到 Key 异常({$res}),且已没有可用的 Key。 当前 Key: {$res_2}... +msg-1465290c = 达到了 Gemini 速率限制, 请稍后再试... +msg-7e9c01ca = 流式输出不支持图片模态,已自动降级为文本模态 +msg-89bac423 = 代码执行工具与搜索工具互斥,已忽略搜索工具 +msg-301cf76e = 代码执行工具与URL上下文工具互斥,已忽略URL上下文工具 +msg-356e7b28 = 当前 SDK 版本不支持 URL 上下文工具,已忽略该设置,请升级 google-genai 包 +msg-7d4e7d48 = gemini-2.0-lite 不支持代码执行、搜索工具和URL上下文,将忽略这些设置 +msg-cc5c666f = 已启用原生工具,函数工具将被忽略 +msg-aa7c77a5 = Invalid thinking level: {$thinking_level}, using HIGH +msg-59e1e769 = 文本内容为空,已添加空格占位 +msg-34c5c910 = Failed to decode google gemini thinking signature: {$e} +msg-a2357584 = assistant 角色的消息内容为空,已添加空格占位 +msg-f627f75d = 检测到启用Gemini原生工具,且上下文中存在函数调用,建议使用 /reset 重置上下文 +msg-cb743183 = 收到的 candidate.content 为空: {$candidate} +msg-34b367fc = API 返回的 candidate.content 为空。 +msg-73541852 = 模型生成内容未通过 Gemini 平台的安全检查 +msg-ae3cdcea = 模型生成内容违反 Gemini 平台政策 +msg-5d8f1711 = 收到的 candidate.content.parts 为空: {$candidate} +msg-57847bd5 = API 返回的 candidate.content.parts 为空。 +msg-a56c85e4 = genai result: {$result} +msg-42fc0767 = 请求失败, 返回的 candidates 为空: {$result} +msg-faf3a0dd = 请求失败, 返回的 candidates 为空。 +msg-cd690916 = 温度参数已超过最大值2,仍然发生recitation +msg-632e23d7 = 发生了recitation,正在提高温度至{$temperature}重试... +msg-41ff84bc = {$model} 不支持 system prompt,已自动去除(影响人格设置) +msg-ef9512f7 = {$model} 不支持函数调用,已自动去除 +msg-fde41b1d = {$model} 不支持多模态输出,降级为文本模态 +msg-4e168d67 = 收到的 chunk 中 candidates 为空: {$chunk} +msg-11af7d46 = 收到的 chunk 中 content 为空: {$chunk} +msg-8836d4a2 = 请求失败。 +msg-757d3828 = 获取模型列表失败: {$res} +msg-7fc6f623 = 图片 {$image_url} 得到的结果为空,将忽略。 +msg-0b041916 = 不支持的额外内容块类型: {$res} + +### astrbot/core/provider/sources/gsvi_tts_source.py +msg-520e410f = GSVI TTS API 请求失败,状态码: {$res},错误: {$error_text} + +### astrbot/core/provider/sources/anthropic_source.py +msg-d6b1df6e = Failed to parse image data URI: {$res}... +msg-6c2c0426 = Unsupported image URL format for Anthropic: {$res}... +msg-999f7680 = completion: {$completion} +msg-8d2c43ec = API 返回的 completion 为空。 +msg-26140afc = Anthropic API 返回的 completion 无法解析:{$completion}。 +msg-8e4c8c24 = 工具调用参数 JSON 解析失败: {$tool_info} +msg-7fc6f623 = 图片 {$image_url} 得到的结果为空,将忽略。 +msg-0b041916 = 不支持的额外内容块类型: {$res} + +### astrbot/core/provider/sources/openai_source.py +msg-bbb399f6 = 检测到图片请求失败(%s),已移除图片并重试(保留文本内容)。 +msg-d6f6a3c2 = 获取模型列表失败:{$e} +msg-1f850e09 = API 返回的 completion 类型错误:{$res}: {$completion}。 +msg-999f7680 = completion: {$completion} +msg-844635f7 = Unexpected dict format content: {$raw_content} +msg-8d2c43ec = API 返回的 completion 为空。 +msg-87d75331 = {$completion_text} +msg-0614efaf = 工具集未提供 +msg-c46f067a = API 返回的 completion 由于内容安全过滤被拒绝(非 AstrBot)。 +msg-647f0002 = API 返回的 completion 无法解析:{$completion}。 +msg-5cc50a15 = API 调用过于频繁,尝试使用其他 Key 重试。当前 Key: {$res} +msg-c4e639eb = 上下文长度超过限制。尝试弹出最早的记录然后重试。当前记录条数: {$res} +msg-5f8be4fb = {$res} 不支持函数工具调用,已自动去除,不影响使用。 +msg-45591836 = 疑似该模型不支持函数调用工具调用。请输入 /tool off_all +msg-6e47d22a = API 调用失败,重试 {$max_retries} 次仍然失败。 +msg-974e7484 = 未知错误 +msg-7fc6f623 = 图片 {$image_url} 得到的结果为空,将忽略。 +msg-0b041916 = 不支持的额外内容块类型: {$res} + +### astrbot/core/provider/sources/gemini_tts_source.py +msg-29fe386a = [Gemini TTS] 使用代理: {$proxy} +msg-012edfe1 = No audio content returned from Gemini TTS API. + +### astrbot/core/provider/sources/genie_tts.py +msg-583dd8a6 = Please install genie_tts first. +msg-935222b4 = Failed to load character {$res}: {$e} +msg-a6886f9e = Genie TTS did not save to file. +msg-e3587d60 = Genie TTS generation failed: {$e} +msg-3303e3a8 = Genie TTS failed to generate audio for: {$text} +msg-1cfe1af1 = Genie TTS stream error: {$e} + +### astrbot/core/provider/sources/dashscope_tts.py +msg-f23d2372 = Dashscope TTS model is not configured. +msg-74a7cc0a = Audio synthesis failed, returned empty content. The model may not be supported or the service is unavailable. +msg-bc8619d3 = dashscope SDK missing MultiModalConversation. Please upgrade the dashscope package to use Qwen TTS models. +msg-95bbf71e = No voice specified for Qwen TTS model, using default 'Cherry'. +msg-3c35d2d0 = Audio synthesis failed for model '{$model}'. {$response} +msg-16dc3b00 = Failed to decode base64 audio data. +msg-26603085 = Failed to download audio from URL {$url}: {$e} +msg-78b9c276 = {$res} + +### astrbot/core/provider/sources/whisper_selfhosted_source.py +msg-27fda50a = 下载或者加载 Whisper 模型中,这可能需要一些时间 ... +msg-4e70f563 = Whisper 模型加载完成。 +msg-28cbbf07 = 文件不存在: {$audio_url} +msg-d98780e5 = Converting silk file to wav ... +msg-e3e1215c = Whisper 模型未初始化 + +### astrbot/core/provider/sources/openai_tts_api_source.py +msg-d7084760 = [OpenAI TTS] 使用代理: {$proxy} + +### astrbot/core/provider/sources/xinference_rerank_source.py +msg-1ec1e6e4 = Xinference Rerank: Using API key for authentication. +msg-7bcb6e1b = Xinference Rerank: No API key provided. +msg-b0d1e564 = Model '{$res}' is already running with UID: {$uid} +msg-16965859 = Launching {$res} model... +msg-7b1dfdd3 = Model launched. +msg-3fc7310e = Model '{$res}' is not running and auto-launch is disabled. Provider will not be available. +msg-15f19a42 = Failed to initialize Xinference model: {$e} +msg-01af1651 = Xinference initialization failed with exception: {$e} +msg-2607cc7a = Xinference rerank model is not initialized. +msg-3d28173b = Rerank API response: {$response} +msg-4c63e1bd = Rerank API returned an empty list. Original response: {$response} +msg-cac71506 = Xinference rerank failed: {$e} +msg-4135cf72 = Xinference rerank failed with exception: {$e} +msg-ea2b36d0 = Closing Xinference rerank client... +msg-633a269f = Failed to close Xinference client: {$e} + +### astrbot/core/provider/sources/minimax_tts_api_source.py +msg-77c88c8a = Failed to parse JSON data from SSE message +msg-7873b87b = MiniMax TTS API请求失败: {$e} + +### astrbot/core/provider/sources/azure_tts_source.py +msg-93d9b5cf = [Azure TTS] 使用代理: {$res} +msg-9eea5bcb = Client not initialized. Please use 'async with' context. +msg-fd53d21d = 时间同步失败 +msg-77890ac4 = OTTS请求失败: {$e} +msg-c6ec6ec7 = OTTS未返回音频文件 +msg-5ad71900 = 无效的Azure订阅密钥 +msg-6416da27 = [Azure TTS Native] 使用代理: {$res} +msg-15c55ed8 = 无效的other[...]格式,应形如 other[{...}] +msg-90b31925 = 缺少OTTS参数: {$res} +msg-10f72727 = {$error_msg} +msg-60b044ea = 配置错误: 缺少必要参数 {$e} +msg-5c7dee08 = 订阅密钥格式无效,应为32位字母数字或other[...]格式 + +### astrbot/core/provider/sources/openai_embedding_source.py +msg-cecb2fbc = [OpenAI Embedding] 使用代理: {$proxy} + +### astrbot/core/provider/sources/vllm_rerank_source.py +msg-6f160342 = Rerank API 返回了空的列表数据。原始响应: {$response_data} + +### astrbot/core/provider/sources/xinference_stt_provider.py +msg-4e31e089 = Xinference STT: Using API key for authentication. +msg-e291704e = Xinference STT: No API key provided. +msg-b0d1e564 = Model '{$res}' is already running with UID: {$uid} +msg-16965859 = Launching {$res} model... +msg-7b1dfdd3 = Model launched. +msg-3fc7310e = Model '{$res}' is not running and auto-launch is disabled. Provider will not be available. +msg-15f19a42 = Failed to initialize Xinference model: {$e} +msg-01af1651 = Xinference initialization failed with exception: {$e} +msg-42ed8558 = Xinference STT model is not initialized. +msg-bbc43272 = Failed to download audio from {$audio_url}, status: {$res} +msg-f4e53d3d = File not found: {$audio_url} +msg-ebab7cac = Audio bytes are empty. +msg-7fd63838 = Audio requires conversion ({$conversion_type}), using temporary files... +msg-d03c4ede = Converting silk to wav ... +msg-79486689 = Converting amr to wav ... +msg-c4305a5b = Xinference STT result: {$text} +msg-d4241bd5 = Xinference STT transcription failed with status {$res}: {$error_text} +msg-8efe4ef1 = Xinference STT failed: {$e} +msg-b1554c7c = Xinference STT failed with exception: {$e} +msg-9d33941a = Removed temporary file: {$temp_file} +msg-7dc5bc44 = Failed to remove temporary file {$temp_file}: {$e} +msg-31904a1c = Closing Xinference STT client... +msg-633a269f = Failed to close Xinference client: {$e} + +### astrbot/core/provider/sources/fishaudio_tts_api_source.py +msg-c785baf0 = [FishAudio TTS] 使用代理: {$res} +msg-822bce1c = 无效的FishAudio参考模型ID: '{$res}'. 请确保ID是32位十六进制字符串(例如: 626bb6d3f3364c9cbc3aa6a67300a664)。您可以从 https://fish.audio/zh-CN/discovery 获取有效的模型ID。 +msg-5956263b = Fish Audio API请求失败: 状态码 {$res}, 响应内容: {$error_text} + +### astrbot/core/provider/sources/gsv_selfhosted_source.py +msg-5fb63f61 = [GSV TTS] 初始化完成 +msg-e0c38c5b = [GSV TTS] 初始化失败:{$e} +msg-4d57bc4f = [GSV TTS] Provider HTTP session is not ready or closed. +msg-2a4a0819 = [GSV TTS] 请求地址:{$endpoint},参数:{$params} +msg-5fdee1da = [GSV TTS] Request to {$endpoint} failed with status {$res}: {$error_text} +msg-3a51c2c5 = [GSV TTS] 请求 {$endpoint} 第 {$res} 次失败:{$e},重试中... +msg-49c1c17a = [GSV TTS] 请求 {$endpoint} 最终失败:{$e} +msg-1beb6249 = [GSV TTS] 成功设置 GPT 模型路径:{$res} +msg-17f1a087 = [GSV TTS] GPT 模型路径未配置,将使用内置 GPT 模型 +msg-ddeb915f = [GSV TTS] 成功设置 SoVITS 模型路径:{$res} +msg-bee5c961 = [GSV TTS] SoVITS 模型路径未配置,将使用内置 SoVITS 模型 +msg-423edb93 = [GSV TTS] 设置模型路径时发生网络错误:{$e} +msg-7d3c79cb = [GSV TTS] 设置模型路径时发生未知错误:{$e} +msg-d084916a = [GSV TTS] TTS 文本不能为空 +msg-fa20c883 = [GSV TTS] 正在调用语音合成接口,参数:{$params} +msg-a7fc38eb = [GSV TTS] 合成失败,输入文本:{$text},错误信息:{$result} +msg-a49cb96b = [GSV TTS] Session 已关闭 + +### astrbot/core/provider/sources/volcengine_tts.py +msg-4b55f021 = 请求头: {$headers} +msg-d252d96d = 请求 URL: {$res} +msg-72e07cfd = 请求体: {$res}... +msg-fb8cdd69 = 响应状态码: {$res} +msg-4c62e457 = 响应内容: {$res}... +msg-1477973b = 火山引擎 TTS API 返回错误: {$error_msg} +msg-75401c15 = 火山引擎 TTS API 请求失败: {$res}, {$response_text} +msg-a29cc73d = 火山引擎 TTS 异常详情: {$error_details} +msg-01433007 = 火山引擎 TTS 异常: {$e} + +### astrbot/core/provider/sources/sensevoice_selfhosted_source.py +msg-ee0daf96 = 下载或者加载 SenseVoice 模型中,这可能需要一些时间 ... +msg-cd6da7e9 = SenseVoice 模型加载完成。 +msg-28cbbf07 = 文件不存在: {$audio_url} +msg-d98780e5 = Converting silk file to wav ... +msg-4e8f1d05 = SenseVoice识别到的文案:{$res} +msg-55668aa2 = 未能提取到情绪信息 +msg-0cdbac9b = 处理音频文件时出错: {$e} + +### astrbot/core/message/components.py +msg-afb10076 = not a valid url +msg-fe4c33a0 = not a valid file: {$res} +msg-24d98e13 = 未配置 callback_api_base,文件服务不可用 +msg-a5c69cc9 = 已注册:{$callback_host}/api/file/{$token} +msg-3cddc5ef = download failed: {$url} +msg-1921aa47 = not a valid file: {$url} +msg-2ee3827c = Generated video file callback link: {$payload_file} +msg-32f4fc78 = No valid file or URL provided +msg-36375f4c = 不可以在异步上下文中同步等待下载! 这个警告通常发生于某些逻辑试图通过 .file 获取文件消息段的文件内容。请使用 await get_file() 代替直接获取 .file 字段 +msg-4a987754 = 文件下载失败: {$e} +msg-7c1935ee = Download failed: No URL provided in File component. +msg-35bb8d53 = Generated file callback link: {$payload_file} + +### astrbot/core/utils/metrics.py +msg-314258f2 = 保存指标到数据库失败: {$e} + +### astrbot/core/utils/trace.py +msg-fffce1b9 = [trace] {$payload} +msg-78b9c276 = {$res} + +### astrbot/core/utils/webhook_utils.py +msg-64c7ddcf = 获取 callback_api_base 失败: {$e} +msg-9b5d1bb1 = 获取 dashboard 端口失败: {$e} +msg-3db149ad = 获取 dashboard SSL 配置失败: {$e} +msg-3739eec9 = {$display_log} + +### astrbot/core/utils/path_util.py +msg-cf211d0f = 路径映射规则错误: {$mapping} +msg-ecea161e = 路径映射: {$url} -> {$srcPath} + +### astrbot/core/utils/media_utils.py +msg-2f697658 = [Media Utils] 获取媒体时长: {$duration_ms}ms +msg-52dfbc26 = [Media Utils] 无法获取媒体文件时长: {$file_path} +msg-486d493a = [Media Utils] ffprobe未安装或不在PATH中,无法获取媒体时长。请安装ffmpeg: https://ffmpeg.org/ +msg-0f9c647b = [Media Utils] 获取媒体时长时出错: {$e} +msg-aff4c5f8 = [Media Utils] 已清理失败的opus输出文件: {$output_path} +msg-82427384 = [Media Utils] 清理失败的opus输出文件时出错: {$e} +msg-215a0cfc = [Media Utils] ffmpeg转换音频失败: {$error_msg} +msg-8cce258e = ffmpeg conversion failed: {$error_msg} +msg-f0cfcb92 = [Media Utils] 音频转换成功: {$audio_path} -> {$output_path} +msg-ead1395b = [Media Utils] ffmpeg未安装或不在PATH中,无法转换音频格式。请安装ffmpeg: https://ffmpeg.org/ +msg-5df3a5ee = ffmpeg not found +msg-6322d4d2 = [Media Utils] 转换音频格式时出错: {$e} +msg-e125b1a5 = [Media Utils] 已清理失败的{$output_format}输出文件: {$output_path} +msg-5cf417e3 = [Media Utils] 清理失败的{$output_format}输出文件时出错: {$e} +msg-3766cbb8 = [Media Utils] ffmpeg转换视频失败: {$error_msg} +msg-77f68449 = [Media Utils] 视频转换成功: {$video_path} -> {$output_path} +msg-3fb20b91 = [Media Utils] ffmpeg未安装或不在PATH中,无法转换视频格式。请安装ffmpeg: https://ffmpeg.org/ +msg-696c4a46 = [Media Utils] 转换视频格式时出错: {$e} +msg-98cc8fb8 = [Media Utils] 清理失败的音频输出文件时出错: {$e} +msg-3c27d5e8 = [Media Utils] 清理失败的视频封面文件时出错: {$e} +msg-072774ab = ffmpeg extract cover failed: {$error_msg} + +### astrbot/core/utils/session_waiter.py +msg-0c977996 = 等待超时 +msg-ac406437 = session_filter 必须是 SessionFilter + +### astrbot/core/utils/history_saver.py +msg-fb7718cb = Failed to parse conversation history: %s + +### astrbot/core/utils/io.py +msg-665b0191 = SSL certificate verification failed for {$url}. Disabling SSL verification (CERT_NONE) as a fallback. This is insecure and exposes the application to man-in-the-middle attacks. Please investigate and resolve certificate issues. +msg-04ab2fae = 下载文件失败: {$res} +msg-63dacf99 = 文件大小: {$res} KB | 文件地址: {$url} +msg-14c3d0bb = \r下载进度: {$res} 速度: {$speed} KB/s +msg-4e4ee68e = SSL 证书验证失败,已关闭 SSL 验证(不安全,仅用于临时下载)。请检查目标服务器的证书配置。 +msg-5a3beefb = SSL certificate verification failed for {$url}. Falling back to unverified connection (CERT_NONE). This is insecure and exposes the application to man-in-the-middle attacks. Please investigate certificate issues with the remote server. +msg-315e5ed6 = 准备下载指定发行版本的 AstrBot WebUI 文件: {$dashboard_release_url} +msg-c709cf82 = 准备下载指定版本的 AstrBot WebUI: {$url} + +### astrbot/core/utils/shared_preferences.py +msg-9a1e6a9a = scope_id and key cannot be None when getting a specific preference. + +### astrbot/core/utils/migra_helper.py +msg-497ddf83 = Migration for third party agent runner configs failed: {$e} +msg-78b9c276 = {$res} +msg-e21f1509 = Migrating provider {$res} to new structure +msg-dd3339e6 = Provider-source structure migration completed +msg-1cb6c174 = Migration from version 4.5 to 4.6 failed: {$e} +msg-a899acc6 = Migration for webchat session failed: {$e} +msg-b9c52817 = Migration for token_usage column failed: {$e} +msg-d9660ff5 = Migration for provider-source structure failed: {$e} + +### astrbot/core/utils/temp_dir_cleaner.py +msg-752c7cc8 = Invalid {$res}={$configured}, fallback to {$res_2}MB. +msg-b1fc3643 = Skip temp file {$path} due to stat error: {$e} +msg-5e61f6b7 = Failed to delete temp file {$res}: {$e} +msg-391449f0 = Temp dir exceeded limit ({$total_size} > {$limit}). Removed {$removed_files} files, released {$released} bytes (target {$target_release} bytes). +msg-aaf1e12a = TempDirCleaner started. interval={$res}s cleanup_ratio={$res_2} +msg-e6170717 = TempDirCleaner run failed: {$e} +msg-0fc33fbc = TempDirCleaner stopped. + +### astrbot/core/utils/tencent_record_helper.py +msg-377ae139 = pilk 模块未安装,请前往管理面板->平台日志->安装pip库 安装 pilk 这个库 +msg-f4ab0713 = pyffmpeg 转换失败: {$e}, 尝试使用 ffmpeg 命令行进行转换 +msg-33c88889 = [FFmpeg] stdout: {$res} +msg-2470430c = [FFmpeg] stderr: {$res} +msg-1321d5f7 = [FFmpeg] return code: {$res} +msg-c39d210c = 生成的WAV文件不存在或为空 +msg-6e04bdb8 = 未安装 pilk: pip install pilk + +### astrbot/core/utils/pip_installer.py +msg-aa9e40b8 = pip module is unavailable (sys.executable={$res}, frozen={$res_2}, ASTRBOT_DESKTOP_CLIENT={$res_3}) +msg-560f11f2 = 读取依赖文件失败,跳过冲突检测: %s +msg-91ae1d17 = 读取 site-packages 元数据失败,使用回退模块名: %s +msg-c815b9dc = {$conflict_message} +msg-e8d4b617 = Loaded %s from plugin site-packages: %s +msg-4ef5d900 = Recovered dependency %s while preferring %s from plugin site-packages. +msg-0bf22754 = Module %s not found in plugin site-packages: %s +msg-76a41595 = Failed to prefer module %s from plugin site-packages: %s +msg-3d4de966 = Failed to patch pip distlib finder for loader %s (%s): %s +msg-117d9cf4 = Distlib finder patch did not take effect for loader %s (%s). +msg-b7975236 = Patched pip distlib finder for frozen loader: %s (%s) +msg-b1fa741c = Skip patching distlib finder because _finder_registry is unavailable. +msg-4ef0e609 = Skip patching distlib finder because register API is unavailable. +msg-b8c741dc = Pip 包管理器: pip {$res} +msg-6b72a960 = 安装失败,错误码:{$result_code} +msg-c8325399 = {$line} + +### astrbot/core/utils/llm_metadata.py +msg-d6535d03 = Successfully fetched metadata for {$res} LLMs. +msg-8cceaeb0 = Failed to fetch LLM metadata: {$e} + +### astrbot/core/utils/network_utils.py +msg-54b8fda8 = [{$provider_label}] 网络/代理连接失败 ({$error_type})。代理地址: {$effective_proxy},错误: {$error} +msg-ea7c80f1 = [{$provider_label}] 网络连接失败 ({$error_type})。错误: {$error} +msg-f8c8a73c = [{$provider_label}] 使用代理: {$proxy} + +### astrbot/core/utils/t2i/renderer.py +msg-4225607b = Failed to render image via AstrBot API: {$e}. Falling back to local rendering. + +### astrbot/core/utils/t2i/local_strategy.py +msg-94a58a1e = 无法加载任何字体 +msg-d5c7d255 = Failed to load image: HTTP {$res} +msg-7d59d0a0 = Failed to load image: {$e} + +### astrbot/core/utils/t2i/template_manager.py +msg-47d72ff5 = 模板名称包含非法字符。 +msg-d1b2131b = 模板不存在。 +msg-dde05b0f = 同名模板已存在。 +msg-0aa209bf = 用户模板不存在,无法删除。 + +### astrbot/core/utils/t2i/network_strategy.py +msg-be0eeaa7 = Successfully got {$res} official T2I endpoints. +msg-3bee02f4 = Failed to get official endpoints: {$e} +msg-829d3c71 = HTTP {$res} +msg-05fb621f = Endpoint {$endpoint} failed: {$e}, trying next... +msg-9a836926 = All endpoints failed: {$last_exception} + +### astrbot/core/utils/quoted_message/extractor.py +msg-24049c48 = quoted_message_parser: stop fetching nested forward messages after %d hops + +### astrbot/core/utils/quoted_message/onebot_client.py +msg-062923e6 = quoted_message_parser: action %s failed with params %s: %s +msg-f33f59d5 = quoted_message_parser: all attempts failed for action %s, last_params=%s, error=%s + +### astrbot/core/utils/quoted_message/image_resolver.py +msg-94224a01 = quoted_message_parser: skip non-image local path ref=%s +msg-3e6c0d14 = quoted_message_parser: failed to resolve quoted image ref=%s after %d actions + +### astrbot/core/agent/tool_image_cache.py +msg-45da4af7 = ToolImageCache initialized, cache dir: {$res} +msg-017bde96 = Saved tool image to: {$file_path} +msg-29398f55 = Failed to save tool image: {$e} +msg-128aa08a = Failed to read cached image {$file_path}: {$e} +msg-3c111d1f = Error during cache cleanup: {$e} +msg-eeb1b849 = Cleaned up {$cleaned} expired cached images + +### astrbot/core/agent/message.py +msg-d38656d7 = {$invalid_subclass_error_msg} +msg-42d5a315 = Cannot validate {$value} as ContentPart +msg-ffc376d0 = content is required unless role='assistant' and tool_calls is not None + +### astrbot/core/agent/mcp_client.py +msg-6a61ca88 = Warning: Missing 'mcp' dependency, MCP services will be unavailable. +msg-45995cdb = Warning: Missing 'mcp' dependency or MCP library version too old, Streamable HTTP connection unavailable. +msg-2866b896 = MCP connection config missing transport or type field +msg-3bf7776b = MCP Server {$name} Error: {$msg} +msg-10f72727 = {$error_msg} +msg-19c9b509 = MCP Client is not initialized +msg-5b9b4918 = MCP Client {$res} is already reconnecting, skipping +msg-c1008866 = Cannot reconnect: missing connection configuration +msg-7c3fe178 = Attempting to reconnect to MCP server {$res}... +msg-783f3b85 = Successfully reconnected to MCP server {$res} +msg-da7361ff = Failed to reconnect to MCP server {$res}: {$e} +msg-c0fd612e = MCP session is not available for MCP function tools. +msg-8236c58c = MCP tool {$tool_name} call failed (ClosedResourceError), attempting to reconnect... +msg-044046ec = Error closing current exit stack: {$e} + +### astrbot/core/agent/tool.py +msg-983bc802 = FunctionTool.call() must be implemented by subclasses or set a handler. + +### astrbot/core/agent/context/compressor.py +msg-6c75531b = Failed to generate summary: {$e} + +### astrbot/core/agent/context/manager.py +msg-59241964 = Error during context processing: {$e} +msg-a0d672dc = Compress triggered, starting compression... +msg-e6ef66f0 = Compress completed. {$prev_tokens} -> {$tokens_after_summary} tokens, compression rate: {$compress_rate}%. +msg-3fe644eb = Context still exceeds max tokens after compression, applying halving truncation... + +### astrbot/core/agent/runners/tool_loop_agent_runner.py +msg-960ef181 = Switched from %s to fallback chat provider: %s +msg-4f999913 = Chat Model %s returns error response, trying fallback to next provider. +msg-c042095f = Chat Model %s request error: %s +msg-81b2aeae = {$tag} RunCtx.messages -> [{$res}] {$res_2} +msg-55333301 = Request is not set. Please call reset() first. +msg-d3b77736 = Error in on_agent_begin hook: {$e} +msg-61de315c = Agent execution was requested to stop by user. +msg-8eb53be3 = Error in on_agent_done hook: {$e} +msg-508d6d17 = LLM 响应错误: {$res} +msg-ed80313d = LLM returned empty assistant message with no tool calls. +msg-970947ae = Appended {$res} cached image(s) to context for LLM review +msg-6b326889 = Agent reached max steps ({$max_step}), forcing a final response. +msg-948ea4b7 = Agent 使用工具: {$res} +msg-a27ad3d1 = 使用工具:{$func_tool_name},参数:{$func_tool_args} +msg-812ad241 = 未找到指定的工具: {$func_tool_name},将跳过。 +msg-20b4f143 = 工具 {$func_tool_name} 期望的参数: {$res} +msg-78f6833c = 工具 {$func_tool_name} 忽略非期望参数: {$ignored_params} +msg-2b523f8c = Error in on_tool_start hook: {$e} +msg-ec868b73 = {$func_tool_name} 没有返回值,或者已将结果直接发送给用户。 +msg-6b61e4f1 = Tool 返回了不支持的类型: {$res}。 +msg-34c13e02 = Error in on_tool_end hook: {$e} +msg-78b9c276 = {$res} +msg-a1493b6d = Tool `{$func_tool_name}` Result: {$last_tcr_content} + +### astrbot/core/agent/runners/base.py +msg-24eb2b08 = Agent state transition: {$res} -> {$new_state} + +### astrbot/core/agent/runners/dashscope/dashscope_agent_runner.py +msg-dc1a9e6e = 阿里云百炼 API Key 不能为空。 +msg-c492cbbc = 阿里云百炼 APP ID 不能为空。 +msg-bcc8e027 = 阿里云百炼 APP 类型不能为空。 +msg-55333301 = Request is not set. Please call reset() first. +msg-d3b77736 = Error in on_agent_begin hook: {$e} +msg-e3af4efd = 阿里云百炼请求失败:{$res} +msg-fccf5004 = dashscope stream chunk: {$chunk} +msg-100d7d7e = 阿里云百炼请求失败: request_id={$res}, code={$res_2}, message={$res_3}, 请参考文档:https://help.aliyun.com/zh/model-studio/developer-reference/error-code +msg-10f72727 = {$error_msg} +msg-e8615101 = {$chunk_text} +msg-dfb132c4 = {$ref_text} +msg-8eb53be3 = Error in on_agent_done hook: {$e} +msg-650b47e1 = 阿里云百炼暂不支持图片输入,将自动忽略图片内容。 + +### astrbot/core/agent/runners/coze/coze_agent_runner.py +msg-448549b0 = Coze API Key 不能为空。 +msg-b88724b0 = Coze Bot ID 不能为空。 +msg-ea5a135a = Coze API Base URL 格式不正确,必须以 http:// 或 https:// 开头。 +msg-55333301 = Request is not set. Please call reset() first. +msg-d3b77736 = Error in on_agent_begin hook: {$e} +msg-5aa3eb1c = Coze 请求失败:{$res} +msg-333354c6 = 处理上下文图片失败: {$e} +msg-2d9e1c08 = 处理图片失败 {$url}: {$e} +msg-1f50979d = {$content} +msg-6fe5588b = Coze message completed +msg-d2802f3b = Coze chat completed +msg-ba4afcda = Coze 出现错误: {$error_code} - {$error_msg} +msg-ee300f25 = Coze 未返回任何内容 +msg-8eb53be3 = Error in on_agent_done hook: {$e} +msg-034c1858 = [Coze] 使用缓存的 file_id: {$file_id} +msg-475d8a41 = [Coze] 图片上传成功并缓存,file_id: {$file_id} +msg-696dad99 = 处理图片失败 {$image_url}: {$e} +msg-7793a347 = 处理图片失败: {$e} + +### astrbot/core/agent/runners/coze/coze_api_client.py +msg-76f97104 = Coze API 认证失败,请检查 API Key 是否正确 +msg-3653b652 = 文件上传响应状态: {$res}, 内容: {$response_text} +msg-13fe060c = 文件上传失败,状态码: {$res}, 响应: {$response_text} +msg-5604b862 = 文件上传响应解析失败: {$response_text} +msg-c0373c50 = 文件上传失败: {$res} +msg-010e4299 = [Coze] 图片上传成功,file_id: {$file_id} +msg-719f13cb = 文件上传超时 +msg-121c11fb = 文件上传失败: {$e} +msg-f6101892 = 下载图片失败,状态码: {$res} +msg-c09c56c9 = 下载图片失败 {$image_url}: {$e} +msg-15211c7c = 下载图片失败: {$e} +msg-2245219f = Coze chat_messages payload: {$payload}, params: {$params} +msg-d8fd415c = Coze API 流式请求失败,状态码: {$res} +msg-f5cc7604 = Coze API 流式请求超时 ({$timeout}秒) +msg-30c0a9d6 = Coze API 流式请求失败: {$e} +msg-11509aba = Coze API 请求失败,状态码: {$res} +msg-002af11d = Coze API 返回非JSON格式 +msg-c0b8fc7c = Coze API 请求超时 +msg-a68a33fa = Coze API 请求失败: {$e} +msg-c26e068e = 获取Coze消息列表失败: {$e} +msg-5bc0a49d = Uploaded file_id: {$file_id} +msg-7c08bdaf = Event: {$event} + +### astrbot/core/agent/runners/dify/dify_api_client.py +msg-cd6cd7ac = Drop invalid dify json data: {$res} +msg-3654a12d = chat_messages payload: {$payload} +msg-8e865c52 = Dify /chat-messages 接口请求失败:{$res}. {$text} +msg-2d7534b8 = workflow_run payload: {$payload} +msg-89918ba5 = Dify /workflows/run 接口请求失败:{$res}. {$text} +msg-8bf17938 = file_path 和 file_data 不能同时为 None +msg-b6ee8f38 = Dify 文件上传失败:{$res}. {$text} + +### astrbot/core/agent/runners/dify/dify_agent_runner.py +msg-55333301 = Request is not set. Please call reset() first. +msg-d3b77736 = Error in on_agent_begin hook: {$e} +msg-0d493427 = Dify 请求失败:{$res} +msg-fe594f21 = Dify 上传图片响应:{$file_response} +msg-3534b306 = 上传图片后得到未知的 Dify 响应:{$file_response},图片将忽略。 +msg-08441fdf = 上传图片失败:{$e} +msg-3972f693 = dify resp chunk: {$chunk} +msg-6c74267b = Dify message end +msg-1ce260ba = Dify 出现错误:{$chunk} +msg-a12417dd = Dify 出现错误 status: {$res} message: {$res_2} +msg-f8530ee9 = dify workflow resp chunk: {$chunk} +msg-386a282e = Dify 工作流(ID: {$res})开始运行。 +msg-0bc1299b = Dify 工作流节点(ID: {$res} Title: {$res_2})运行结束。 +msg-5cf24248 = Dify 工作流(ID: {$res})运行结束 +msg-e2c2159f = Dify 工作流结果:{$chunk} +msg-4fa60ef1 = Dify 工作流出现错误:{$res} +msg-1f786836 = Dify 工作流的输出不包含指定的键名:{$res} +msg-c4a70ffb = 未知的 Dify API 类型:{$res} +msg-51d321fd = Dify 请求结果为空,请查看 Debug 日志。 +msg-8eb53be3 = Error in on_agent_done hook: {$e} + +### astrbot/core/star/session_plugin_manager.py +msg-16cc2a7a = 插件 {$res} 在会话 {$session_id} 中被禁用,跳过处理器 {$res_2} + +### astrbot/core/star/star_manager.py +msg-bfa28c02 = 未安装 watchfiles,无法实现插件的热重载。 +msg-f8e1c445 = 插件热重载监视任务异常: {$e} +msg-78b9c276 = {$res} +msg-28aeca68 = 检测到文件变化: {$changes} +msg-aeec7738 = 检测到插件 {$plugin_name} 文件变化,正在重载... +msg-4f989555 = 插件 {$d} 未找到 main.py 或者 {$d}.py,跳过。 +msg-74b32804 = 正在安装插件 {$p} 所需的依赖库: {$pth} +msg-936edfca = 更新插件 {$p} 的依赖失败。Code: {$e} +msg-ebd47311 = 插件 {$root_dir_name} 导入失败,尝试从已安装依赖恢复: {$import_exc} +msg-1b6e94f1 = 插件 {$root_dir_name} 已从 site-packages 恢复依赖,跳过重新安装。 +msg-81b7c9b9 = 插件 {$root_dir_name} 已安装依赖恢复失败,将重新安装依赖: {$recover_exc} +msg-22fde75d = 插件不存在。 +msg-3a307a9e = 插件元数据信息不完整。name, desc, version, author 是必须的字段。 +msg-55e089d5 = 删除模块 {$key} +msg-64de1322 = 删除模块 {$module_name} +msg-66823424 = 模块 {$module_name} 未载入 +msg-45c8df8d = 清除了插件{$dir_name}中的{$key}模块 +msg-f7d9aa9b = 清理处理器: {$res} +msg-3c492aa6 = 清理工具: {$res} +msg-e0002829 = 插件 {$res} 未被正常终止: {$e}, 可能会导致该插件运行不正常。 +msg-0fe27735 = 正在载入插件 {$root_dir_name} ... +msg-b2ec4801 = {$error_trace} +msg-db351291 = 插件 {$root_dir_name} 导入失败。原因:{$e} +msg-a3db5f45 = 失败插件依旧在插件列表中,正在清理... +msg-58c66a56 = 插件 {$root_dir_name} 元数据载入失败: {$e}。使用默认元数据。 +msg-da764b29 = {$metadata} +msg-17cd7b7d = 插件 {$res} 已被禁用。 +msg-4baf6814 = 插件 {$path} 未通过装饰器注册。尝试通过旧版本方式载入。 +msg-840994d1 = 无法找到插件 {$plugin_dir_path} 的元数据。 +msg-944ffff1 = 插入权限过滤器 {$cmd_type} 到 {$res} 的 {$res_2} 方法。 +msg-64edd12c = hook(on_plugin_loaded) -> {$res} - {$res_2} +msg-db49f7a1 = ----- 插件 {$root_dir_name} 载入失败 ----- +msg-26039659 = | {$line} +msg-4292f44d = ---------------------------------- +msg-d2048afe = 同步指令配置失败: {$e} +msg-df515dec = 已清理安装失败的插件目录: {$plugin_path} +msg-1f2aa1a9 = 清理安装失败插件目录失败: {$plugin_path},原因: {$e} +msg-1e947210 = 已清理安装失败插件配置: {$plugin_config_path} +msg-7374541f = 清理安装失败插件配置失败: {$plugin_config_path},原因: {$e} +msg-e871b08f = 读取插件 {$dir_name} 的 README.md 文件失败: {$e} +msg-70ca4592 = 该插件是 AstrBot 保留插件,无法卸载。 +msg-e247422b = 插件 {$plugin_name} 未被正常终止 {$e}, 可能会导致资源泄露等问题。 +msg-0c25dbf4 = 插件 {$plugin_name} 数据不完整,无法卸载。 +msg-d6f8142c = 移除插件成功,但是删除插件文件夹失败: {$e}。您可以手动删除该文件夹,位于 addons/plugins/ 下。 +msg-6313500c = 已删除插件 {$plugin_name} 的配置文件 +msg-f0f01b67 = 删除插件配置文件失败: {$e} +msg-c4008b30 = 已删除插件 {$plugin_name} 的持久化数据 (plugin_data) +msg-88d1ee05 = 删除插件持久化数据失败 (plugin_data): {$e} +msg-ba805469 = 已删除插件 {$plugin_name} 的持久化数据 (plugins_data) +msg-cf6eb821 = 删除插件持久化数据失败 (plugins_data): {$e} +msg-e1853811 = 移除了插件 {$plugin_name} 的处理函数 {$res} ({$res_2}) +msg-95b20050 = 移除了插件 {$plugin_name} 的平台适配器 {$adapter_name} +msg-9f248e88 = 该插件是 AstrBot 保留插件,无法更新。 +msg-ff435883 = 正在终止插件 {$res} ... +msg-355187b7 = 插件 {$res} 未被激活,不需要终止,跳过。 +msg-4369864f = hook(on_plugin_unloaded) -> {$res} - {$res_2} +msg-1b95e855 = 插件 {$plugin_name} 不存在。 +msg-c1bc6cd6 = 检测到插件 {$res} 已安装,正在终止旧插件... +msg-4f3271db = 检测到同名插件 {$res} 存在于不同目录 {$res_2},正在终止... +msg-d247fc54 = 读取新插件 metadata.yaml 失败,跳过同名检查: {$e} +msg-0f8947f8 = 删除插件压缩包失败: {$e} + +### astrbot/core/star/session_llm_manager.py +msg-7b90d0e9 = 会话 {$session_id} 的TTS状态已更新为: {$res} + +### astrbot/core/star/config.py +msg-c2189e8d = namespace 不能为空。 +msg-97f66907 = namespace 不能以 internal_ 开头。 +msg-09179604 = key 只支持 str 类型。 +msg-1163e4f1 = value 只支持 str, int, float, bool, list 类型。 +msg-ed0f93e4 = 配置文件 {$namespace}.json 不存在。 +msg-e3b5cdfb = 配置项 {$key} 不存在。 + +### astrbot/core/star/star_tools.py +msg-397b7bf9 = StarTools not initialized +msg-ca30e638 = 未找到适配器: AiocqhttpAdapter +msg-77ca0ccb = 不支持的平台: {$platform} +msg-3ed67eb2 = 无法获取调用者模块信息 +msg-e77ccce6 = 无法获取模块 {$res} 的元数据信息 +msg-76ac38ee = 无法获取插件名称 +msg-751bfd23 = 无法创建目录 {$data_dir}:权限不足 +msg-68979283 = 无法创建目录 {$data_dir}:{$e} + +### astrbot/core/star/context.py +msg-60eb9e43 = Provider {$chat_provider_id} not found +msg-da70a6fb = Agent did not produce a final LLM response +msg-141151fe = Provider not found +msg-a5cb19c6 = 没有找到 ID 为 {$provider_id} 的提供商,这可能是由于您修改了提供商(模型)ID 导致的。 +msg-2a44300b = 该会话来源的对话模型(提供商)的类型不正确: {$res} +msg-37c286ea = 返回的 Provider 不是 TTSProvider 类型 +msg-ff775f3b = 返回的 Provider 不是 STTProvider 类型 +msg-fd8c8295 = cannot find platform for session {$res}, message not sent +msg-2b806a28 = plugin(module_path {$module_path}) added LLM tool: {$res} + +### astrbot/core/star/updator.py +msg-66be72ec = 插件 {$res} 没有指定仓库地址。 +msg-7a29adea = 插件 {$res} 的根目录名未指定。 +msg-99a86f88 = 正在更新插件,路径: {$plugin_path},仓库地址: {$repo_url} +msg-df2c7e1b = 删除旧版本插件 {$plugin_path} 文件夹失败: {$e},使用覆盖安装。 +msg-b3471491 = 正在解压压缩包: {$zip_path} +msg-7197ad11 = 删除临时文件: {$zip_path} 和 {$res} +msg-f8a43aa5 = 删除更新文件失败,可以手动删除 {$zip_path} 和 {$res} + +### astrbot/core/star/command_management.py +msg-011581bb = 指定的处理函数不存在或不是指令。 +msg-a0c37004 = 指令名不能为空。 +msg-ae8b2307 = 指令名 '{$candidate_full}' 已被其他指令占用。 +msg-247926a7 = 别名 '{$alias_full}' 已被其他指令占用。 +msg-dbd19a23 = 权限类型必须为 admin 或 member。 +msg-9388ea1e = 未找到指令所属插件 +msg-0dd9b70d = 解析指令处理函数 {$res} 失败,跳过该指令。原因: {$e} + +### astrbot/core/star/base.py +msg-57019272 = get_config() failed: {$e} + +### astrbot/core/star/register/star.py +msg-64619f8e = The 'register_star' decorator is deprecated and will be removed in a future version. + +### astrbot/core/star/register/star_handler.py +msg-7ff2d46e = 注册指令{$command_name} 的子指令时未提供 sub_command 参数。 +msg-b68436e1 = 注册裸指令时未提供 command_name 参数。 +msg-1c183df2 = {$command_group_name} 指令组的子指令组 sub_command 未指定 +msg-9210c7e8 = 根指令组的名称未指定 +msg-678858e7 = 注册指令组失败。 +msg-6c3915e0 = LLM 函数工具 {$res}_{$llm_tool_name} 的参数 {$res_2} 缺少类型注释。 +msg-1255c964 = LLM 函数工具 {$res}_{$llm_tool_name} 不支持的参数类型:{$res_2} + +### astrbot/core/star/filter/command.py +msg-995944c2 = 参数 '{$param_name}' (GreedyStr) 必须是最后一个参数。 +msg-04dbdc3a = 必要参数缺失。该指令完整参数: {$res} +msg-bda71712 = 参数 {$param_name} 必须是布尔值(true/false, yes/no, 1/0)。 +msg-a9afddbf = 参数 {$param_name} 类型错误。完整参数: {$res} + +### astrbot/core/star/filter/custom_filter.py +msg-8f3eeb6e = Operands must be subclasses of CustomFilter. +msg-732ada95 = CustomFilter class can only operate with other CustomFilter. +msg-51c0c77d = CustomFilter lass can only operate with other CustomFilter. + +### astrbot/core/db/vec_db/faiss_impl/document_storage.py +msg-c2dc1d2b = Database connection is not initialized, returning empty result +msg-51fa7426 = Database connection is not initialized, skipping delete operation +msg-43d1f69f = Database connection is not initialized, returning 0 + +### astrbot/core/db/vec_db/faiss_impl/embedding_storage.py +msg-8e5fe535 = faiss 未安装。请使用 'pip install faiss-cpu' 或 'pip install faiss-gpu' 安装。 +msg-9aa7b941 = 向量维度不匹配, 期望: {$res}, 实际: {$res_2} + +### astrbot/core/db/vec_db/faiss_impl/vec_db.py +msg-9f9765dc = Generating embeddings for {$res} contents... +msg-385bc50a = Generated embeddings for {$res} contents in {$res_2} seconds. + +### astrbot/core/db/migration/migra_token_usage.py +msg-c3e53a4f = 开始执行数据库迁移(添加 conversations.token_usage 列)... +msg-ccbd0a41 = token_usage 列已存在,跳过迁移 +msg-39f60232 = token_usage 列添加成功 +msg-4f9d3876 = token_usage 迁移完成 +msg-91571aaf = 迁移过程中发生错误: {$e} + +### astrbot/core/db/migration/migra_3_to_4.py +msg-7805b529 = 迁移 {$total_cnt} 条旧的会话数据到新的表中... +msg-6f232b73 = 进度: {$progress}% ({$res}/{$total_cnt}) +msg-6b1def31 = 未找到该条旧会话对应的具体数据: {$conversation}, 跳过。 +msg-b008c93f = 迁移旧会话 {$res} 失败: {$e} +msg-6ac6313b = 成功迁移 {$total_cnt} 条旧的会话数据到新表。 +msg-6b72e89b = 迁移旧平台数据,offset_sec: {$offset_sec} 秒。 +msg-bdc90b84 = 迁移 {$res} 条旧的平台数据到新的表中... +msg-e6caca5c = 没有找到旧平台数据,跳过迁移。 +msg-1e824a79 = 进度: {$progress}% ({$res}/{$total_buckets}) +msg-813384e2 = 迁移平台统计数据失败: {$platform_id}, {$platform_type}, 时间戳: {$bucket_end} +msg-27ab191d = 成功迁移 {$res} 条旧的平台数据到新表。 +msg-8e6280ed = 迁移 {$total_cnt} 条旧的 WebChat 会话数据到新的表中... +msg-cad66fe1 = 迁移旧 WebChat 会话 {$res} 失败 +msg-63748a46 = 成功迁移 {$total_cnt} 条旧的 WebChat 会话数据到新表。 +msg-dfc93fa4 = 迁移 {$total_personas} 个 Persona 配置到新表中... +msg-ff85e45c = 进度: {$progress}% ({$res}/{$total_personas}) +msg-c346311e = 迁移 Persona {$res}({$res_2}...) 到新表成功。 +msg-b6292b94 = 解析 Persona 配置失败:{$e} +msg-90e5039e = 迁移全局偏好设置 {$key} 成功,值: {$value} +msg-d538da1c = 迁移会话 {$umo} 的对话数据到新表成功,平台 ID: {$platform_id} +msg-ee03c001 = 迁移会话 {$umo} 的对话数据失败: {$e} +msg-5c4339cd = 迁移会话 {$umo} 的服务配置到新表成功,平台 ID: {$platform_id} +msg-4ce2a0b2 = 迁移会话 {$umo} 的服务配置失败: {$e} +msg-2e62dab9 = 迁移会话 {$umo} 的变量失败: {$e} +msg-afbf819e = 迁移会话 {$umo} 的提供商偏好到新表成功,平台 ID: {$platform_id} +msg-959bb068 = 迁移会话 {$umo} 的提供商偏好失败: {$e} + +### astrbot/core/db/migration/helper.py +msg-a48f4752 = 开始执行数据库迁移... +msg-45e31e8e = 数据库迁移完成。 + +### astrbot/core/db/migration/migra_45_to_46.py +msg-782b01c1 = migrate_45_to_46: abconf_data is not a dict (type={$res}). Value: {$abconf_data} +msg-49e09620 = Starting migration from version 4.5 to 4.6 +msg-791b79f8 = Migration from version 45 to 46 completed successfully + +### astrbot/core/db/migration/migra_webchat_session.py +msg-53fad3d0 = 开始执行数据库迁移(WebChat 会话迁移)... +msg-7674efb0 = 没有找到需要迁移的 WebChat 数据 +msg-139e39ee = 找到 {$res} 个 WebChat 会话需要迁移 +msg-cf287e58 = 会话 {$session_id} 已存在,跳过 +msg-062c72fa = WebChat 会话迁移完成!成功迁移: {$res}, 跳过: {$skipped_count} +msg-a516cc9f = 没有新会话需要迁移 +msg-91571aaf = 迁移过程中发生错误: {$e} + +### astrbot/core/knowledge_base/kb_helper.py +msg-7b3dc642 = - LLM call failed on attempt {$res}/{$res_2}. Error: {$res_3} +msg-4ba9530f = - Failed to process chunk after {$res} attempts. Using original text. +msg-77670a3a = 知识库 {$res} 未配置 Embedding Provider +msg-8e9eb3f9 = 无法找到 ID 为 {$res} 的 Embedding Provider +msg-3e426806 = 无法找到 ID 为 {$res} 的 Rerank Provider +msg-6e780e1e = 使用预分块文本进行上传,共 {$res} 个块。 +msg-f4b82f18 = 当未提供 pre_chunked_text 时,file_content 不能为空。 +msg-975f06d7 = 上传文档失败: {$e} +msg-969b17ca = 清理多媒体文件失败 {$media_path}: {$me} +msg-18d25e55 = 无法找到 ID 为 {$doc_id} 的文档 +msg-f5d7c34c = Error: Tavily API key is not configured in provider_settings. +msg-975d88e0 = Failed to extract content from URL {$url}: {$e} +msg-cfe431b3 = No content extracted from URL: {$url} +msg-e7f5f836 = 内容清洗后未提取到有效文本。请尝试关闭内容清洗功能,或更换更高性能的LLM模型后重试。 +msg-693aa5c5 = 内容清洗未启用,使用指定参数进行分块: chunk_size={$chunk_size}, chunk_overlap={$chunk_overlap} +msg-947d8f46 = 启用了内容清洗,但未提供 cleaning_provider_id,跳过清洗并使用默认分块。 +msg-31963d3f = 无法找到 ID 为 {$cleaning_provider_id} 的 LLM Provider 或类型不正确 +msg-82728272 = 初步分块完成,生成 {$res} 个块用于修复。 +msg-6fa5fdca = 块 {$i} 处理异常: {$res}. 回退到原始块。 +msg-6780e950 = 文本修复完成: {$res} 个原始块 -> {$res_2} 个最终块。 +msg-79056c76 = 使用 Provider '{$cleaning_provider_id}' 清洗内容失败: {$e} + +### astrbot/core/knowledge_base/kb_mgr.py +msg-98bfa670 = 正在初始化知识库模块... +msg-7da7ae15 = 知识库模块导入失败: {$e} +msg-842a3c65 = 请确保已安装所需依赖: pypdf, aiofiles, Pillow, rank-bm25 +msg-c9e943f7 = 知识库模块初始化失败: {$e} +msg-78b9c276 = {$res} +msg-9349e112 = KnowledgeBase database initialized: {$DB_PATH} +msg-7605893e = 创建知识库时必须提供embedding_provider_id +msg-0b632cbd = 知识库名称 '{$kb_name}' 已存在 +msg-ca30330f = 关闭知识库 {$kb_id} 失败: {$e} +msg-00262e1f = 关闭知识库元数据数据库失败: {$e} +msg-3fc9ef0b = Knowledge base with id {$kb_id} not found. + +### astrbot/core/knowledge_base/kb_db_sqlite.py +msg-b850e5d8 = 知识库数据库已关闭: {$res} + +### astrbot/core/knowledge_base/parsers/util.py +msg-398b3580 = 暂时不支持的文件格式: {$ext} + +### astrbot/core/knowledge_base/parsers/url_parser.py +msg-2de85bf5 = Error: Tavily API keys are not configured. +msg-98ed69f4 = Error: url must be a non-empty string. +msg-7b14cdb7 = Tavily web extraction failed: {$reason}, status: {$res} +msg-cfe431b3 = No content extracted from URL: {$url} +msg-b0897365 = Failed to fetch URL {$url}: {$e} +msg-975d88e0 = Failed to extract content from URL {$url}: {$e} + +### astrbot/core/knowledge_base/parsers/text_parser.py +msg-70cbd40d = 无法解码文件: {$file_name} + +### astrbot/core/knowledge_base/chunking/recursive.py +msg-21db456a = chunk_size must be greater than 0 +msg-c0656f4e = chunk_overlap must be non-negative +msg-82bd199c = chunk_overlap must be less than chunk_size + +### astrbot/core/knowledge_base/retrieval/manager.py +msg-fcc0dde2 = 知识库 ID {$kb_id} 实例未找到, 已跳过该知识库的检索 +msg-320cfcff = Dense retrieval across {$res} bases took {$res_2}s and returned {$res_3} results. +msg-90ffcfc8 = Sparse retrieval across {$res} bases took {$res_2}s and returned {$res_3} results. +msg-12bcf404 = Rank fusion took {$res}s and returned {$res_2} results. +msg-28c084bc = vec_db for kb_id {$kb_id} is not FaissVecDB +msg-cc0230a3 = 知识库 {$kb_id} 稠密检索失败: {$e} + +### astrbot/core/skills/skill_manager.py +msg-ed9670ad = Zip file not found: {$zip_path} +msg-73f9cf65 = Uploaded file is not a valid zip archive. +msg-69eb5f95 = Zip archive is empty. +msg-9e9abb4c = {$top_dirs} +msg-20b8533f = Zip archive must contain a single top-level folder. +msg-1db1caf7 = Invalid skill folder name. +msg-d7814054 = Zip archive contains absolute paths. +msg-179bd10e = Zip archive contains invalid relative paths. +msg-90f2904e = Zip archive contains unexpected top-level entries. +msg-95775a4d = SKILL.md not found in the skill folder. +msg-a4117c0b = Skill folder not found after extraction. +msg-94041ef2 = Skill already exists. + +### astrbot/core/backup/importer.py +msg-c046b6e4 = {$msg} +msg-0e6f1f5d = 开始从 {$zip_path} 导入备份 +msg-2bf97ca0 = 备份导入完成: {$res} +msg-e67dda98 = 备份文件缺少版本信息 +msg-8f871d9f = 版本差异警告: {$res} +msg-2d6da12a = 已清空表 {$table_name} +msg-7d21b23a = 清空表 {$table_name} 失败: {$e} +msg-ab0f09db = 已清空知识库表 {$table_name} +msg-7bcdfaee = 清空知识库表 {$table_name} 失败: {$e} +msg-43f008f1 = 清理知识库 {$kb_id} 失败: {$e} +msg-985cae66 = 未知的表: {$table_name} +msg-dfa8b605 = 导入记录到 {$table_name} 失败: {$e} +msg-89a2120c = 导入表 {$table_name}: {$count} 条记录 +msg-f1dec753 = 导入知识库记录到 {$table_name} 失败: {$e} +msg-9807bcd8 = 导入文档块失败: {$e} +msg-98a66293 = 导入附件 {$name} 失败: {$e} +msg-39f2325f = 备份版本不支持目录备份,跳过目录导入 +msg-689050b6 = 已备份现有目录 {$target_dir} 到 {$backup_path} +msg-d51b3536 = 导入目录 {$dir_name}: {$file_count} 个文件 + +### astrbot/core/backup/exporter.py +msg-c7ed7177 = 开始导出备份到 {$zip_path} +msg-8099b694 = 备份导出完成: {$zip_path} +msg-75a4910d = 备份导出失败: {$e} +msg-2821fc92 = 导出表 {$table_name}: {$res} 条记录 +msg-52b7c242 = 导出表 {$table_name} 失败: {$e} +msg-56310830 = 导出知识库表 {$table_name}: {$res} 条记录 +msg-f4e8f57e = 导出知识库表 {$table_name} 失败: {$e} +msg-8e4ddd12 = 导出知识库文档失败: {$e} +msg-c1960618 = 导出 FAISS 索引: {$archive_path} +msg-314bf920 = 导出 FAISS 索引失败: {$e} +msg-528757b2 = 导出知识库媒体文件失败: {$e} +msg-d89d6dfe = 目录不存在,跳过: {$full_path} +msg-94527edd = 导出文件 {$file_path} 失败: {$e} +msg-cb773e24 = 导出目录 {$dir_name}: {$file_count} 个文件, {$total_size} 字节 +msg-ae929510 = 导出目录 {$dir_path} 失败: {$e} +msg-93e331d2 = 导出附件失败: {$e} + +### astrbot/core/computer/computer_client.py +msg-7cb974b8 = Uploading skills bundle to sandbox... +msg-130cf3e3 = Failed to upload skills bundle to sandbox. +msg-99188d69 = Failed to remove temp skills zip: {$zip_path} +msg-3f3c81da = Unknown booter type: {$booter_type} +msg-e20cc33a = Error booting sandbox for session {$session_id}: {$e} + +### astrbot/core/computer/tools/fs.py +msg-99ab0efe = Upload result: {$result} +msg-bca9d578 = File {$local_path} uploaded to sandbox at {$file_path} +msg-da21a6a5 = Error uploading file {$local_path}: {$e} +msg-93476abb = File {$remote_path} downloaded from sandbox to {$local_path} +msg-079c5972 = Error sending file message: {$e} +msg-ce35bb2c = Error downloading file {$remote_path}: {$e} + +### astrbot/core/computer/booters/local.py +msg-487d0c91 = Path is outside the allowed computer roots. +msg-e5eb5377 = Blocked unsafe shell command. +msg-9e1e117f = Local computer booter initialized for session: {$session_id} +msg-2d7f95de = Local computer booter shutdown complete. +msg-82a45196 = LocalBooter does not support upload_file operation. Use shell instead. +msg-0457524a = LocalBooter does not support download_file operation. Use shell instead. + +### astrbot/core/computer/booters/shipyard.py +msg-b03115b0 = Got sandbox ship: {$res} for session: {$session_id} +msg-c5ce8bde = Error checking Shipyard sandbox availability: {$e} + +### astrbot/core/computer/booters/boxlite.py +msg-019c4d18 = Failed to exec operation: {$res} {$error_text} +msg-b135b7bd = Failed to upload file: {$e} +msg-873ed1c8 = File not found: {$path} +msg-f58ceec6 = Unexpected error uploading file: {$e} +msg-900ab999 = Checking health for sandbox {$ship_id} on {$res}... +msg-2a50d6f3 = Sandbox {$ship_id} is healthy +msg-fbdbe32f = Booting(Boxlite) for session: {$session_id}, this may take a while... +msg-b1f13f5f = Boxlite booter started for session: {$session_id} +msg-e93d0c30 = Shutting down Boxlite booter for ship: {$res} +msg-6deea473 = Boxlite booter for ship: {$res} stopped + +### astrbot/core/cron/manager.py +msg-724e64a9 = Skip scheduling basic cron job %s due to missing handler. +msg-78ef135f = Invalid timezone %s for cron job %s, fallback to system. +msg-e71c28d3 = run_once job missing run_at timestamp +msg-dd46e69f = Failed to schedule cron job {$res}: {$e} +msg-aa2e4688 = Unknown cron job type: {$res} +msg-186627d9 = Cron job {$job_id} failed: {$e} +msg-cb955de0 = Basic cron job handler not found for {$res} +msg-2029c4b2 = ActiveAgentCronJob missing session. +msg-6babddc9 = Invalid session for cron job: {$e} +msg-865a2b07 = Failed to build main agent for cron job. +msg-27c9c6b3 = Cron job agent got no response + +### astrbot/utils/http_ssl_common.py +msg-7957c9b6 = Failed to load certifi CA bundle into SSL context; falling back to system trust store only: %s + +### astrbot/cli/__main__.py +msg-fe494da6 = {$logo_tmpl} +msg-c8b2ff67 = Welcome to AstrBot CLI! +msg-d79e1ff9 = AstrBot CLI version: {$__version__} +msg-78b9c276 = {$res} +msg-14dd710d = Unknown command: {$command_name} + +### astrbot/cli/utils/basic.py +msg-f4e0fd7b = 未安装管理面板 +msg-2d090cc3 = 正在安装管理面板... +msg-2eeb67e0 = 管理面板安装完成 +msg-9c727dca = 管理面板已是最新版本 +msg-11b49913 = 管理面板版本: {$version} +msg-f0b6145e = 下载管理面板失败: {$e} +msg-9504d173 = 初始化管理面板目录... +msg-699e2509 = 管理面板初始化完成 + +### astrbot/cli/utils/plugin.py +msg-e327bc14 = 正在从默认分支下载 {$author}/{$repo} +msg-c804f59f = 获取 release 信息失败: {$e},将直接使用提供的 URL +msg-aa398bd5 = master 分支不存在,尝试下载 main 分支 +msg-5587d9fb = 读取 {$yaml_path} 失败: {$e} +msg-8dbce791 = 获取在线插件列表失败: {$e} +msg-6999155d = 插件 {$plugin_name} 未安装,无法更新 +msg-fa5e129a = 正在从 {$repo_url} {$res}插件 {$plugin_name}... +msg-9ac1f4db = 插件 {$plugin_name} {$res}成功 +msg-b9c719ae = {$res}插件 {$plugin_name} 时出错: {$e} + +### astrbot/cli/commands/cmd_conf.py +msg-635b8763 = 日志级别必须是 DEBUG/INFO/WARNING/ERROR/CRITICAL 之一 +msg-ebc250dc = 端口必须在 1-65535 范围内 +msg-6ec400b6 = 端口必须是数字 +msg-0b62b5ce = 用户名不能为空 +msg-89b5d3d5 = 密码不能为空 +msg-92e7c8ad = 无效的时区: {$value},请使用有效的IANA时区名称 +msg-e470e37d = 回调接口基址必须以 http:// 或 https:// 开头 +msg-6b615721 = {$root}不是有效的 AstrBot 根目录,如需初始化请使用 astrbot init +msg-f74c517c = 配置文件解析失败: {$e} +msg-d7c58bcc = 配置路径冲突: {$res} 不是字典 +msg-e16816cc = 不支持的配置项: {$key} +msg-e9cce750 = 配置已更新: {$key} +msg-1ed565aa = 原值: ******** +msg-1bf9569a = 新值: ******** +msg-f2a20ab3 = 原值: {$old_value} +msg-0c104905 = 新值: {$validated_value} +msg-ea9b4e2c = 未知的配置项: {$key} +msg-4450e3b1 = 设置配置失败: {$e} +msg-ba464bee = {$key}: {$value} +msg-72aab576 = 获取配置失败: {$e} +msg-c1693d1d = 当前配置: +msg-50be9b74 = {$key}: {$value} + +### astrbot/cli/commands/cmd_init.py +msg-a90a250e = Current Directory: {$astrbot_root} +msg-4deda62e = 如果你确认这是 Astrbot root directory, 你需要在当前目录下创建一个 .astrbot 文件标记该目录为 AstrBot 的数据目录。 +msg-3319bf71 = Created {$dot_astrbot} +msg-7054f44f = {$res}: {$path} +msg-b19edc8a = Initializing AstrBot... +msg-eebc39e3 = 无法获取锁文件,请检查是否有其他实例正在运行 +msg-e16da80f = 初始化失败: {$e} + +### astrbot/cli/commands/cmd_run.py +msg-41ecc632 = {$astrbot_root}不是有效的 AstrBot 根目录,如需初始化请使用 astrbot init +msg-0ccaca23 = 启用插件自动重载 +msg-220914e7 = AstrBot 已关闭... +msg-eebc39e3 = 无法获取锁文件,请检查是否有其他实例正在运行 +msg-85f241d3 = 运行时出现错误: {$e}{"\u000A"}{$res} + +### astrbot/cli/commands/cmd_plug.py +msg-cbd8802b = {$base}不是有效的 AstrBot 根目录,如需初始化请使用 astrbot init +msg-78b9c276 = {$res} +msg-83664fcf = {$val} {$val} {$val} {$val} {$val} +msg-56f3f0bf = {$res} {$res_2} {$res_3} {$res_4} {$desc} +msg-1d802ff2 = 插件 {$name} 已存在 +msg-a7be9d23 = 版本号必须为 x.y 或 x.y.z 格式 +msg-4d81299b = 仓库地址必须以 http 开头 +msg-93289755 = 下载插件模板... +msg-b21682dd = 重写插件信息... +msg-bffc8bfa = 插件 {$name} 创建成功 +msg-08eae1e3 = 未安装任何插件 +msg-1a021bf4 = 未找到可安装的插件 {$name},可能是不存在或已安装 +msg-c120bafd = 插件 {$name} 不存在或未安装 +msg-63da4867 = 插件 {$name} 已卸载 +msg-e4925708 = 卸载插件 {$name} 失败: {$e} +msg-f4d15a87 = 插件 {$name} 不需要更新或无法更新 +msg-94b035f7 = 没有需要更新的插件 +msg-0766d599 = 发现 {$res} 个插件需要更新 +msg-bd5ab99c = 正在更新插件 {$plugin_name}... +msg-e32912b8 = 未找到匹配 '{$query}' 的插件 + +### astrbot/dashboard/server.py +msg-e88807e2 = 未找到该路由 +msg-06151c57 = Missing API key +msg-88dca3cc = Invalid API key +msg-fd267dc8 = Insufficient API key scope +msg-076fb3a3 = 未授权 +msg-6f214cc1 = Token 过期 +msg-5041dc95 = Token 无效 +msg-1241c883 = 检查端口 {$port} 时发生错误: {$e} +msg-7c3ba89d = Initialized random JWT secret for dashboard. +msg-a3adcb66 = WebUI 已被禁用 +msg-44832296 = 正在启动 WebUI, 监听地址: {$scheme}://{$host}:{$port} +msg-3eed4a73 = 提示: WebUI 将监听所有网络接口,请注意安全。(可在 data/cmd_config.json 中配置 dashboard.host 以修改 host) +msg-289a2fe8 = 错误:端口 {$port} 已被占用{"\u000A"}占用信息: {"\u000A"} {$process_info}{"\u000A"}请确保:{"\u000A"}1. 没有其他 AstrBot 实例正在运行{"\u000A"}2. 端口 {$port} 没有被其他程序占用{"\u000A"}3. 如需使用其他端口,请修改配置文件 +msg-6d1dfba8 = 端口 {$port} 已被占用 +msg-c0161c7c = {$display} +msg-ac4f2855 = dashboard.ssl.enable 为 true 时,必须配置 cert_file 和 key_file。 +msg-3e87aaf8 = SSL 证书文件不存在: {$cert_path} +msg-5ccf0a9f = SSL 私钥文件不存在: {$key_path} +msg-5e4aa3eb = SSL CA 证书文件不存在: {$ca_path} +msg-cb049eb2 = AstrBot WebUI 已经被优雅地关闭 + +### astrbot/dashboard/utils.py +msg-160bd44a = 缺少必要的库以生成 t-SNE 可视化。请安装 matplotlib 和 scikit-learn: {e} +msg-aa3a3dbf = 未找到知识库 +msg-0e404ea3 = FAISS 索引不存在: {$index_path} +msg-8d92420c = 索引为空 +msg-24c0450e = 提取 {$res} 个向量用于可视化... +msg-632d0acf = 开始 t-SNE 降维... +msg-61f0449f = 生成可视化图表... +msg-4436ad2b = 生成 t-SNE 可视化时出错: {$e} +msg-78b9c276 = {$res} + +### astrbot/dashboard/routes/update.py +msg-a3503781 = 迁移失败: {$res} +msg-543d8e4d = 迁移失败: {$e} +msg-251a5f4a = 检查更新失败: {$e} (不影响除项目更新外的正常使用) +msg-aa6bff26 = /api/update/releases: {$res} +msg-c5170c27 = 下载管理面板文件失败: {$e}。 +msg-db715c26 = 更新依赖中... +msg-9a00f940 = 更新依赖失败: {$e} +msg-6f96e3ba = /api/update_project: {$res} +msg-3217b509 = 下载管理面板文件失败: {$e} +msg-9cff28cf = /api/update_dashboard: {$res} +msg-1198c327 = You are not permitted to do this operation in demo mode +msg-38e60adf = 缺少参数 package 或不合法。 +msg-a1191473 = /api/update_pip: {$res} + +### astrbot/dashboard/routes/lang_route.py +msg-0d18aac8 = [LangRoute] lang:{$lang} +msg-bf610e68 = lang 为必填参数。 + +### astrbot/dashboard/routes/auth.py +msg-ee9cf260 = 为了保证安全,请尽快修改默认密码。 +msg-87f936b8 = 用户名或密码错误 +msg-1198c327 = You are not permitted to do this operation in demo mode +msg-25562cd3 = 原密码错误 +msg-d31087d2 = 新用户名和新密码不能同时为空 +msg-b512c27e = 两次输入的新密码不一致 +msg-7b947d8b = JWT secret is not set in the cmd_config. + +### astrbot/dashboard/routes/backup.py +msg-6920795d = 清理过期的上传会话: {$upload_id} +msg-3e96548d = 清理过期上传会话失败: {$e} +msg-259677a9 = 清理分片目录失败: {$e} +msg-d7263882 = 读取备份 manifest 失败: {$e} +msg-40f76598 = 跳过无效备份文件: {$filename} +msg-18a49bfc = 获取备份列表失败: {$e} +msg-78b9c276 = {$res} +msg-6e08b5a5 = 创建备份失败: {$e} +msg-9cce1032 = 后台导出任务 {$task_id} 失败: {$e} +msg-55927ac1 = 缺少备份文件 +msg-374cab8a = 请上传 ZIP 格式的备份文件 +msg-d53d6730 = 上传的备份文件已保存: {$unique_filename} (原始名称: {$res}) +msg-98e64c7f = 上传备份文件失败: {$e} +msg-49c3b432 = 缺少 filename 参数 +msg-df33d307 = 无效的文件大小 +msg-162ad779 = 初始化分片上传: upload_id={$upload_id}, filename={$unique_filename}, total_chunks={$total_chunks} +msg-de676924 = 初始化分片上传失败: {$e} +msg-eecf877c = 缺少必要参数 +msg-f175c633 = 无效的分片索引 +msg-ad865497 = 缺少分片数据 +msg-947c2d56 = 上传会话不存在或已过期 +msg-f3a464a5 = 分片索引超出范围 +msg-7060da1d = 接收分片: upload_id={$upload_id}, chunk={$res}/{$total_chunks} +msg-06c107c1 = 上传分片失败: {$e} +msg-f040b260 = 已标记备份为上传来源: {$zip_path} +msg-559c10a8 = 标记备份来源失败: {$e} +msg-d1d752ef = 缺少 upload_id 参数 +msg-390ed49a = 分片不完整,缺少: {$res}... +msg-8029086a = 分片上传完成: {$filename}, size={$file_size}, chunks={$total} +msg-4905dde5 = 完成分片上传失败: {$e} +msg-b63394b1 = 取消分片上传: {$upload_id} +msg-2b39da46 = 取消上传失败: {$e} +msg-f12b1f7a = 无效的文件名 +msg-44bb3b89 = 备份文件不存在: {$filename} +msg-b005980b = 预检查备份文件失败: {$e} +msg-65b7ede1 = 请先确认导入。导入将会清空并覆盖现有数据,此操作不可撤销。 +msg-b152e4bf = 导入备份失败: {$e} +msg-5e7f1683 = 后台导入任务 {$task_id} 失败: {$e} +msg-6906aa65 = 缺少参数 task_id +msg-5ea3d72c = 找不到该任务 +msg-f0901aef = 获取任务进度失败: {$e} +msg-8d23792b = 缺少参数 filename +msg-4188ede6 = 缺少参数 token +msg-0c708312 = 服务器配置错误 +msg-cc228d62 = Token 已过期,请刷新页面后重试 +msg-5041dc95 = Token 无效 +msg-96283fc5 = 备份文件不存在 +msg-00aacbf8 = 下载备份失败: {$e} +msg-3ea8e256 = 删除备份失败: {$e} +msg-e4a57714 = 缺少参数 new_name +msg-436724bb = 新文件名无效 +msg-9f9d8558 = 文件名 '{$new_filename}' 已存在 +msg-a5fda312 = 备份文件重命名: {$filename} -> {$new_filename} +msg-e7c82339 = 重命名备份失败: {$e} + +### astrbot/dashboard/routes/command.py +msg-1d47363b = handler_full_name 与 enabled 均为必填。 +msg-35374718 = handler_full_name 与 new_name 均为必填。 +msg-f879f2f4 = handler_full_name 与 permission 均为必填。 + +### astrbot/dashboard/routes/subagent.py +msg-78b9c276 = {$res} +msg-eda47201 = 获取 subagent 配置失败: {$e} +msg-3e5b1fe0 = 配置必须为 JSON 对象 +msg-9f285dd3 = 保存 subagent 配置失败: {$e} +msg-665f4751 = 获取可用工具失败: {$e} + +### astrbot/dashboard/routes/config.py +msg-680e7347 = 配置项 {$path}{$key} 没有类型定义, 跳过校验 +msg-ef2e5902 = Saving config, is_core={$is_core} +msg-78b9c276 = {$res} +msg-acef166d = 验证配置时出现异常: {$e} +msg-42f62db0 = 格式校验未通过: {$errors} +msg-3e668849 = 缺少配置数据 +msg-196b9b25 = 缺少 provider_source_id +msg-dbbbc375 = 未找到对应的 provider source +msg-a77f69f4 = 缺少 original_id +msg-96f154c4 = 缺少或错误的配置数据 +msg-c80b2c0f = Provider source ID '{$res}' exists already, please try another ID. +msg-537b700b = 缺少或错误的路由表数据 +msg-b5079e61 = 更新路由表失败: {$e} +msg-cf97d400 = 缺少 UMO 或配置文件 ID +msg-2a05bc8d = 缺少 UMO +msg-7098aa3f = 删除路由表项失败: {$e} +msg-902aedc3 = 缺少配置文件 ID +msg-b9026977 = abconf_id cannot be None +msg-acf0664a = 删除失败 +msg-59c93c1a = 删除配置文件失败: {$e} +msg-930442e2 = 更新失败 +msg-7375d4dc = 更新配置文件失败: {$e} +msg-53a8fdb2 = Attempting to check provider: {$res} (ID: {$res_2}, Type: {$res_3}, Model: {$res_4}) +msg-8b0a48ee = Provider {$res} (ID: {$res_2}) is available. +msg-7c7180a7 = Provider {$res} (ID: {$res_2}) is unavailable. Error: {$error_message} +msg-1298c229 = Traceback for {$res}:{"\u000A"}{$res_2} +msg-d7f9a42f = {$message} +msg-cd303a28 = API call: /config/provider/check_one id={$provider_id} +msg-55b8107a = Provider with id '{$provider_id}' not found in provider_manager. +msg-d1a98a9b = Provider with id '{$provider_id}' not found +msg-cb9c402c = 缺少参数 provider_type +msg-e092d4ee = 缺少参数 provider_id +msg-1ff28fed = 未找到 ID 为 {$provider_id} 的提供商 +msg-92347c35 = 提供商 {$provider_id} 类型不支持获取模型列表 +msg-d0845a10 = 缺少参数 provider_config +msg-5657fea4 = provider_config 缺少 type 字段 +msg-09ed9dc7 = 提供商适配器加载失败,请检查提供商类型配置或查看服务端日志 +msg-1cce1cd4 = 未找到适用于 {$provider_type} 的提供商适配器 +msg-8361e44d = 无法找到 {$provider_type} 的类 +msg-4325087c = 提供商不是 EmbeddingProvider 类型 +msg-a9873ea4 = 检测到 {$res} 的嵌入向量维度为 {$dim} +msg-d170e384 = 获取嵌入维度失败: {$e} +msg-abfeda72 = 缺少参数 source_id +msg-0384f4c9 = 未找到 ID 为 {$provider_source_id} 的 provider_source +msg-aec35bdb = provider_source 缺少 type 字段 +msg-cbb9d637 = 动态导入提供商适配器失败: {$e} +msg-468f64b3 = 提供商 {$provider_type} 不支持获取模型列表 +msg-cb07fc1c = 获取到 provider_source {$provider_source_id} 的模型列表: {$models} +msg-d2f6e16d = 获取模型列表失败: {$e} +msg-25ea8a96 = Unsupported scope: {$scope} +msg-23c8933f = Missing name or key parameter +msg-536e77ae = Plugin {$name} not found or has no config +msg-1b6bc453 = Config item not found or not file type +msg-fc0a457e = No files uploaded +msg-31c718d7 = Invalid name parameter +msg-e1edc16e = Missing name parameter +msg-8e634b35 = Invalid path parameter +msg-0b52a254 = Plugin {$name} not found +msg-bff0e837 = 参数错误 +msg-2f29d263 = 机器人名称不允许修改 +msg-1478800f = 未找到对应平台 +msg-ca6133f7 = 缺少参数 id +msg-1199c1f9 = Using cached logo token for platform {$res} +msg-889a7de5 = Platform class not found for {$res} +msg-317f359c = Logo token registered for platform {$res} +msg-323ec1e2 = Platform {$res} logo file not found: {$logo_file_path} +msg-bc6d0bcf = Failed to import required modules for platform {$res}: {$e} +msg-b02b538d = File system error for platform {$res} logo: {$e} +msg-31123607 = Unexpected error registering logo for platform {$res}: {$e} +msg-af06ccab = 配置文件 {$conf_id} 不存在 +msg-082a5585 = 插件 {$plugin_name} 不存在 +msg-ca334960 = 插件 {$plugin_name} 没有注册配置 + +### astrbot/dashboard/routes/knowledge_base.py +msg-ce669289 = 上传文档 {$res} 失败: {$e} +msg-87e99c2d = 后台上传任务 {$task_id} 失败: {$e} +msg-78b9c276 = {$res} +msg-d5355233 = 导入文档 {$file_name} 失败: {$e} +msg-5e7f1683 = 后台导入任务 {$task_id} 失败: {$e} +msg-e1949850 = 获取知识库列表失败: {$e} +msg-299af36d = 知识库名称不能为空 +msg-faf380ec = 缺少参数 embedding_provider_id +msg-9015b689 = 嵌入模型不存在或类型错误({$res}) +msg-a63b3aa9 = 嵌入向量维度不匹配,实际是 {$res},然而配置是 {$res_2} +msg-9b281e88 = 测试嵌入模型失败: {$e} +msg-d3fb6072 = 重排序模型不存在 +msg-fbec0dfd = 重排序模型返回结果异常 +msg-872feec8 = 测试重排序模型失败: {$e},请检查平台日志输出。 +msg-a4ac0b9e = 创建知识库失败: {$e} +msg-c8d487e9 = 缺少参数 kb_id +msg-978b3c73 = 知识库不存在 +msg-2137a3e6 = 获取知识库详情失败: {$e} +msg-e7cf9cfd = 至少需要提供一个更新字段 +msg-d3d82c22 = 更新知识库失败: {$e} +msg-5d5d4090 = 删除知识库失败: {$e} +msg-787a5dea = 获取知识库统计失败: {$e} +msg-97a2d918 = 获取文档列表失败: {$e} +msg-b170e0fa = Content-Type 须为 multipart/form-data +msg-5afbfa8e = 缺少文件 +msg-6636fd31 = 最多只能上传10个文件 +msg-975f06d7 = 上传文档失败: {$e} +msg-35bacf60 = 缺少参数 documents 或格式错误 +msg-6cc1edcd = 文档格式错误,必须包含 file_name 和 chunks +msg-376d7d5f = chunks 必须是列表 +msg-e7e2f311 = chunks 必须是非空字符串列表 +msg-42315b8d = 导入文档失败: {$e} +msg-6906aa65 = 缺少参数 task_id +msg-5ea3d72c = 找不到该任务 +msg-194def99 = 获取上传进度失败: {$e} +msg-df6ec98e = 缺少参数 doc_id +msg-7c3cfe22 = 文档不存在 +msg-b54ab822 = 获取文档详情失败: {$e} +msg-0ef7f633 = 删除文档失败: {$e} +msg-2fe40cbd = 缺少参数 chunk_id +msg-fc13d42a = 删除文本块失败: {$e} +msg-4ef8315b = 获取块列表失败: {$e} +msg-b70a1816 = 缺少参数 query +msg-82ee646e = 缺少参数 kb_names 或格式错误 +msg-07a61a9a = 生成 t-SNE 可视化失败: {$e} +msg-20a3b3f7 = 检索失败: {$e} +msg-1b76f5ab = 缺少参数 url +msg-5dc86dc6 = 从URL上传文档失败: {$e} +msg-890b3dee = 后台上传URL任务 {$task_id} 失败: {$e} + +### astrbot/dashboard/routes/skills.py +msg-78b9c276 = {$res} +msg-1198c327 = You are not permitted to do this operation in demo mode +msg-52430f2b = Missing file +msg-2ad598f3 = Only .zip files are supported +msg-a11f2e1c = Failed to remove temp skill file: {$temp_path} +msg-67367a6d = Missing skill name + +### astrbot/dashboard/routes/live_chat.py +msg-40f242d5 = [Live Chat] {$res} 开始说话 stamp={$stamp} +msg-a168d76d = [Live Chat] stamp 不匹配或未在说话状态: {$stamp} vs {$res} +msg-e01b2fea = [Live Chat] 没有音频帧数据 +msg-33856925 = [Live Chat] 音频文件已保存: {$audio_path}, 大小: {$res} bytes +msg-9e9b7e59 = [Live Chat] 组装 WAV 文件失败: {$e} +msg-21430f56 = [Live Chat] 已删除临时文件: {$res} +msg-6b4f88bc = [Live Chat] 删除临时文件失败: {$e} +msg-0849d043 = [Live Chat] WebSocket 连接建立: {$username} +msg-5477338a = [Live Chat] WebSocket 错误: {$e} +msg-fdbfdba8 = [Live Chat] WebSocket 连接关闭: {$username} +msg-7be90ac0 = [Live Chat] start_speaking 缺少 stamp +msg-8215062a = [Live Chat] 解码音频数据失败: {$e} +msg-438980ea = [Live Chat] end_speaking 缺少 stamp +msg-b35a375c = [Live Chat] 用户打断: {$res} +msg-2c3e7bbc = [Live Chat] STT Provider 未配置 +msg-0582c8ba = [Live Chat] STT 识别结果为空 +msg-57c2b539 = [Live Chat] STT 结果: {$user_text} +msg-6b7628c6 = [Live Chat] 检测到用户打断 +msg-2cab2269 = [Live Chat] 消息 ID 不匹配: {$result_message_id} != {$message_id} +msg-74c2470e = [Live Chat] 解析 AgentStats 失败: {$e} +msg-4738a2b3 = [Live Chat] 解析 TTSStats 失败: {$e} +msg-944d5022 = [Live Chat] 开始播放音频流 +msg-009104d8 = [Live Chat] Bot 回复完成: {$bot_text} +msg-0c4c3051 = [Live Chat] 处理音频失败: {$e} +msg-140caa36 = [Live Chat] 保存打断消息: {$interrupted_text} +msg-869f51ea = [Live Chat] 用户消息: {$user_text} (session: {$res}, ts: {$timestamp}) +msg-d26dee52 = [Live Chat] Bot 消息(打断): {$interrupted_text} (session: {$res}, ts: {$timestamp}) +msg-1377f378 = [Live Chat] 记录消息失败: {$e} + +### astrbot/dashboard/routes/log.py +msg-5bf500c1 = Log SSE 补发历史错误: {$e} +msg-e4368397 = Log SSE 连接错误: {$e} +msg-547abccb = 获取日志历史失败: {$e} +msg-cb5d4ebb = 获取 Trace 设置失败: {$e} +msg-7564d3b0 = 请求数据为空 +msg-d2a1cd76 = 更新 Trace 设置失败: {$e} + +### astrbot/dashboard/routes/conversation.py +msg-62392611 = 数据库查询出错: {$e}{"\u000A"}{$res} +msg-b21b052b = 数据库查询出错: {$e} +msg-10f72727 = {$error_msg} +msg-036e6190 = 获取对话列表失败: {$e} +msg-a16ba4b4 = 缺少必要参数: user_id 和 cid +msg-9a1fcec9 = 对话不存在 +msg-73a8a217 = 获取对话详情失败: {$e}{"\u000A"}{$res} +msg-976cd580 = 获取对话详情失败: {$e} +msg-c193b9c4 = 更新对话信息失败: {$e}{"\u000A"}{$res} +msg-9f96c4ee = 更新对话信息失败: {$e} +msg-e1cb0788 = 批量删除时conversations参数不能为空 +msg-38e3c4ba = 删除对话失败: {$e}{"\u000A"}{$res} +msg-ebf0371a = 删除对话失败: {$e} +msg-af54ee29 = 缺少必要参数: history +msg-b72552c8 = history 必须是有效的 JSON 字符串或数组 +msg-fdf757f3 = 更新对话历史失败: {$e}{"\u000A"}{$res} +msg-33762429 = 更新对话历史失败: {$e} +msg-498f11f8 = 导出列表不能为空 +msg-98aa3644 = 导出对话失败: user_id={$user_id}, cid={$cid}, error={$e} +msg-ed77aa37 = 没有成功导出任何对话 +msg-f07b18ee = 批量导出对话失败: {$e}{"\u000A"}{$res} +msg-85dc73fa = 批量导出对话失败: {$e} + +### astrbot/dashboard/routes/cron.py +msg-fb5b419b = Cron manager not initialized +msg-78b9c276 = {$res} +msg-112659e5 = Failed to list jobs: {$e} +msg-8bc87eb5 = Invalid payload +msg-29f616c2 = session is required +msg-ae7c99a4 = run_at is required when run_once=true +msg-4bb8c206 = cron_expression is required when run_once=false +msg-13fbf01e = run_at must be ISO datetime +msg-da14d97a = Failed to create job: {$e} +msg-804b6412 = Job not found +msg-94b2248d = Failed to update job: {$e} +msg-42c0ee7a = Failed to delete job: {$e} + +### astrbot/dashboard/routes/tools.py +msg-78b9c276 = {$res} +msg-977490be = 获取 MCP 服务器列表失败: {$e} +msg-50a07403 = 服务器名称不能为空 +msg-23d2bca3 = 必须提供有效的服务器配置 +msg-31252516 = 服务器 {$name} 已存在 +msg-20b8309f = 启用 MCP 服务器 {$name} 超时。 +msg-fff3d0c7 = 启用 MCP 服务器 {$name} 失败: {$e} +msg-7f1f7921 = 保存配置失败 +msg-a7f06648 = 添加 MCP 服务器失败: {$e} +msg-278dc41b = 服务器 {$old_name} 不存在 +msg-f0441f4b = 启用前停用 MCP 服务器时 {$old_name} 超时: {$e} +msg-7c468a83 = 启用前停用 MCP 服务器时 {$old_name} 失败: {$e} +msg-8a4c8128 = 停用 MCP 服务器 {$old_name} 超时。 +msg-9ac9b2fc = 停用 MCP 服务器 {$old_name} 失败: {$e} +msg-b988392d = 更新 MCP 服务器失败: {$e} +msg-c81030a7 = 服务器 {$name} 不存在 +msg-4cdbd30d = 停用 MCP 服务器 {$name} 超时。 +msg-1ed9a96e = 停用 MCP 服务器 {$name} 失败: {$e} +msg-a26f2c6a = 删除 MCP 服务器失败: {$e} +msg-bbc84cc5 = 无效的 MCP 服务器配置 +msg-aa0e3d0d = MCP 服务器配置不能为空 +msg-d69cbcf2 = 一次只能配置一个 MCP 服务器配置 +msg-bd43f610 = 测试 MCP 连接失败: {$e} +msg-057a3970 = 获取工具列表失败: {$e} +msg-29415636 = 缺少必要参数: name 或 action +msg-75d85dc1 = 启用工具失败: {$e} +msg-21a922b8 = 工具 {$tool_name} 不存在或操作失败。 +msg-20143f28 = 操作工具失败: {$e} +msg-295ab1fe = 未知: {$provider_name} +msg-fe38e872 = 同步失败: {$e} + +### astrbot/dashboard/routes/chatui_project.py +msg-04827ead = Missing key: title +msg-34fccfbb = Missing key: project_id +msg-a7c08aee = Project {$project_id} not found +msg-c52a1454 = Permission denied +msg-dbf41bfc = Missing key: session_id +msg-d922dfa3 = Session {$session_id} not found + +### astrbot/dashboard/routes/open_api.py +msg-e41d65d5 = Failed to create chat session %s: %s +msg-fc15cbcd = {$username_err} +msg-bc3b3977 = Invalid username +msg-2cd6e70f = {$ensure_session_err} +msg-53632573 = {$resolve_err} +msg-79b0c7cb = Failed to update chat config route for %s with %s: %s +msg-7c7a9f55 = Failed to update chat config route: {$e} +msg-74bff366 = page and page_size must be integers +msg-1507569c = Message is empty +msg-1389e46a = message must be a string or list +msg-697561eb = message part must be an object +msg-2c4bf283 = reply part missing message_id +msg-60ddb927 = unsupported message part type: {$part_type} +msg-cf310369 = attachment not found: {$attachment_id} +msg-58e0b84a = {$part_type} part missing attachment_id +msg-e565c4b5 = file not found: {$file_path} +msg-c6ec40ff = Message content is empty (reply only is not allowed) +msg-2b00f931 = Missing key: message +msg-a29d9adb = Missing key: umo +msg-4990e908 = Invalid umo: {$e} +msg-45ac857c = Bot not found or not running for platform: {$platform_id} +msg-ec0f0bd2 = Open API send_message failed: {$e} +msg-d04109ab = Failed to send message: {$e} + +### astrbot/dashboard/routes/session_management.py +msg-e1949850 = 获取知识库列表失败: {$e} +msg-3cd6eb8c = 获取规则列表失败: {$e} +msg-363174ae = 缺少必要参数: umo +msg-809e51d7 = 缺少必要参数: rule_key +msg-ce203e7e = 不支持的规则键: {$rule_key} +msg-2726ab30 = 更新会话规则失败: {$e} +msg-f021f9fb = 删除会话规则失败: {$e} +msg-6bfa1fe5 = 缺少必要参数: umos +msg-4ce0379e = 参数 umos 必须是数组 +msg-979c6e2f = 删除 umo {$umo} 的规则失败: {$e} +msg-77d2761d = 批量删除会话规则失败: {$e} +msg-6619322c = 获取 UMO 列表失败: {$e} +msg-b944697c = 获取会话状态列表失败: {$e} +msg-adba3c3b = 至少需要指定一个要修改的状态 +msg-4a8eb7a6 = 请指定分组 ID +msg-67f15ab7 = 分组 '{$group_id}' 不存在 +msg-50fbcccb = 没有找到符合条件的会话 +msg-59714ede = 更新 {$umo} 服务状态失败: {$e} +msg-31640917 = 批量更新服务状态失败: {$e} +msg-4d83eb92 = 缺少必要参数: provider_type, provider_id +msg-5f333041 = 不支持的 provider_type: {$provider_type} +msg-6fa017d7 = 更新 {$umo} Provider 失败: {$e} +msg-07416020 = 批量更新 Provider 失败: {$e} +msg-94c745e6 = 获取分组列表失败: {$e} +msg-fb7cf353 = 分组名称不能为空 +msg-ae3fce8a = 创建分组失败: {$e} +msg-07de5ff3 = 分组 ID 不能为空 +msg-35b8a74f = 更新分组失败: {$e} +msg-3d41a6fd = 删除分组失败: {$e} + +### astrbot/dashboard/routes/persona.py +msg-4a12aead = 获取人格列表失败: {$e}{"\u000A"}{$res} +msg-c168407f = 获取人格列表失败: {$e} +msg-63c6f414 = 缺少必要参数: persona_id +msg-ce7da6f3 = 人格不存在 +msg-9c07774d = 获取人格详情失败: {$e}{"\u000A"}{$res} +msg-ee3b44ad = 获取人格详情失败: {$e} +msg-ad455c14 = 人格ID不能为空 +msg-43037094 = 系统提示词不能为空 +msg-ec9dda44 = 预设对话数量必须为偶数(用户和助手轮流对话) +msg-26b214d5 = 创建人格失败: {$e}{"\u000A"}{$res} +msg-8913dfe6 = 创建人格失败: {$e} +msg-3d94d18d = 更新人格失败: {$e}{"\u000A"}{$res} +msg-f2cdfbb8 = 更新人格失败: {$e} +msg-51d84afc = 删除人格失败: {$e}{"\u000A"}{$res} +msg-8314a263 = 删除人格失败: {$e} +msg-b8ecb8f9 = 移动人格失败: {$e}{"\u000A"}{$res} +msg-ab0420e3 = 移动人格失败: {$e} +msg-e5604a24 = 获取文件夹列表失败: {$e}{"\u000A"}{$res} +msg-4d7c7f4a = 获取文件夹列表失败: {$e} +msg-cf0ee4aa = 获取文件夹树失败: {$e}{"\u000A"}{$res} +msg-bb515af0 = 获取文件夹树失败: {$e} +msg-c92b4863 = 缺少必要参数: folder_id +msg-77cdd6fa = 文件夹不存在 +msg-2d34652f = 获取文件夹详情失败: {$e}{"\u000A"}{$res} +msg-650ef096 = 获取文件夹详情失败: {$e} +msg-27c413df = 文件夹名称不能为空 +msg-b5866931 = 创建文件夹失败: {$e}{"\u000A"}{$res} +msg-5e57f3b5 = 创建文件夹失败: {$e} +msg-9bd8f820 = 更新文件夹失败: {$e}{"\u000A"}{$res} +msg-1eada044 = 更新文件夹失败: {$e} +msg-9cef0256 = 删除文件夹失败: {$e}{"\u000A"}{$res} +msg-22020727 = 删除文件夹失败: {$e} +msg-7a69fe08 = items 不能为空 +msg-e71ba5c2 = 每个 item 必须包含 id, type, sort_order 字段 +msg-dfeb8320 = type 字段必须是 'persona' 或 'folder' +msg-aec43ed3 = 更新排序失败: {$e}{"\u000A"}{$res} +msg-75ec4427 = 更新排序失败: {$e} + +### astrbot/dashboard/routes/platform.py +msg-bcc64513 = 未找到 webhook_uuid 为 {$webhook_uuid} 的平台 +msg-1478800f = 未找到对应平台 +msg-378cb077 = 平台 {$res} 未实现 webhook_callback 方法 +msg-2d797305 = 平台未支持统一 Webhook 模式 +msg-83f8dedf = 处理 webhook 回调时发生错误: {$e} +msg-af91bc78 = 处理回调失败 +msg-136a952f = 获取平台统计信息失败: {$e} +msg-60bb0722 = 获取统计信息失败: {$e} + +### astrbot/dashboard/routes/api_key.py +msg-8e0249fa = At least one valid scope is required +msg-1b79360d = Invalid scopes +msg-d6621696 = expires_in_days must be an integer +msg-33605d95 = expires_in_days must be greater than 0 +msg-209030fe = Missing key: key_id +msg-24513a81 = API key not found + +### astrbot/dashboard/routes/file.py +msg-78b9c276 = {$res} + +### astrbot/dashboard/routes/chat.py +msg-a4a521ff = Missing key: filename +msg-c9746528 = Invalid file path +msg-3c2f6dee = File access error +msg-e5b19b36 = Missing key: attachment_id +msg-cfa38c4d = Attachment not found +msg-377a7406 = Missing key: file +msg-bae87336 = Failed to create attachment +msg-5c531303 = Missing JSON body +msg-1c3efd8f = Missing key: message or files +msg-04588d0f = Missing key: session_id or conversation_id +msg-c6ec40ff = Message content is empty (reply only is not allowed) +msg-2c3fdeb9 = Message are both empty +msg-9bc95e22 = session_id is empty +msg-344a401b = [WebChat] 用户 {$username} 断开聊天长连接。 +msg-6b54abec = WebChat stream error: {$e} +msg-53509ecb = webchat stream message_id mismatch +msg-1211e857 = [WebChat] 用户 {$username} 断开聊天长连接。 {$e} +msg-be34e848 = Failed to extract web search refs: {$e} +msg-80bbd0ff = WebChat stream unexpected error: {$e} +msg-dbf41bfc = Missing key: session_id +msg-d922dfa3 = Session {$session_id} not found +msg-c52a1454 = Permission denied +msg-9d7a8094 = Failed to delete UMO route %s during session cleanup: %s +msg-44c45099 = Failed to delete attachment file {$res}: {$e} +msg-f033d8ea = Failed to get attachments: {$e} +msg-e6f655bd = Failed to delete attachments: {$e} +msg-a6ef3b67 = Missing key: display_name + +### astrbot/dashboard/routes/t2i.py +msg-76cc0933 = Error in get_active_template +msg-5350f35b = Template not found +msg-d7b101c5 = Name and content are required. +msg-e910b6f3 = Template with this name already exists. +msg-18cfb637 = Content is required. +msg-2480cf2f = Template not found. +msg-9fe026f1 = 模板名称(name)不能为空。 +msg-eeefe1dc = 模板 '{$name}' 不存在,无法应用。 +msg-0048e060 = Error in set_active_template +msg-8fde62dd = Error in reset_default_template + +### astrbot/dashboard/routes/stat.py +msg-1198c327 = You are not permitted to do this operation in demo mode +msg-78b9c276 = {$res} +msg-0e5bb0b1 = proxy_url is required +msg-f0e0983e = Failed. Status code: {$res} +msg-68e65093 = Error: {$e} +msg-b5979fe8 = version parameter is required +msg-b88a1887 = Invalid version format +msg-8cb9bb6b = Path traversal attempt detected: {$version} -> {$changelog_path} +msg-7616304c = Changelog for version {$version} not found + +### astrbot/dashboard/routes/plugin.py +msg-1198c327 = You are not permitted to do this operation in demo mode +msg-adce8d2f = 缺少插件目录名 +msg-2f1b67fd = 重载失败: {$err} +msg-71f9ea23 = /api/plugin/reload-failed: {$res} +msg-27286c23 = /api/plugin/reload: {$res} +msg-b33c0d61 = 缓存MD5匹配,使用缓存的插件市场数据 +msg-64b4a44c = 远程插件市场数据为空: {$url} +msg-fdbffdca = 成功获取远程插件市场数据,包含 {$res} 个插件 +msg-48c42bf8 = 请求 {$url} 失败,状态码:{$res} +msg-6ac25100 = 请求 {$url} 失败,错误:{$e} +msg-7e536821 = 远程插件市场数据获取失败,使用缓存数据 +msg-d4b4c53a = 获取插件列表失败,且没有可用的缓存数据 +msg-37f59b88 = 加载缓存MD5失败: {$e} +msg-8048aa4c = 获取远程MD5失败: {$e} +msg-593eacfd = 缓存文件中没有MD5信息 +msg-dedcd957 = 无法获取远程MD5,将使用缓存 +msg-21d7e754 = 插件数据MD5: 本地={$cached_md5}, 远程={$remote_md5}, 有效={$is_valid} +msg-0faf4275 = 检查缓存有效性失败: {$e} +msg-e26aa0a5 = 加载缓存文件: {$cache_file}, 缓存时间: {$res} +msg-23d627a1 = 加载插件市场缓存失败: {$e} +msg-22d12569 = 插件市场数据已缓存到: {$cache_file}, MD5: {$md5} +msg-478c99a9 = 保存插件市场缓存失败: {$e} +msg-3838d540 = 获取插件 Logo 失败: {$e} +msg-da442310 = 正在安装插件 {$repo_url} +msg-e0abd541 = 安装插件 {$repo_url} 成功。 +msg-78b9c276 = {$res} +msg-acfcd91e = 正在安装用户上传的插件 {$res} +msg-48e05870 = 安装插件 {$res} 成功 +msg-8af56756 = 正在卸载插件 {$plugin_name} +msg-6d1235b6 = 卸载插件 {$plugin_name} 成功 +msg-7055316c = 正在更新插件 {$plugin_name} +msg-d258c060 = 更新插件 {$plugin_name} 成功。 +msg-398370d5 = /api/plugin/update: {$res} +msg-2d225636 = 插件列表不能为空 +msg-32632e67 = 批量更新插件 {$name} +msg-08dd341c = /api/plugin/update-all: 更新插件 {$name} 失败: {$res} +msg-cb230226 = 停用插件 {$plugin_name} 。 +msg-abc710cd = /api/plugin/off: {$res} +msg-06e2a068 = 启用插件 {$plugin_name} 。 +msg-82c412e7 = /api/plugin/on: {$res} +msg-77e5d67e = 正在获取插件 {$plugin_name} 的README文件内容 +msg-baed1b72 = 插件名称为空 +msg-773cca0a = 插件名称不能为空 +msg-082a5585 = 插件 {$plugin_name} 不存在 +msg-ba106e58 = 插件 {$plugin_name} 目录不存在 +msg-e38e4370 = 无法找到插件目录: {$plugin_dir} +msg-df027f16 = 无法找到插件 {$plugin_name} 的目录 +msg-5f304f4b = 插件 {$plugin_name} 没有README文件 +msg-a3ed8739 = /api/plugin/readme: {$res} +msg-2f9e2c11 = 读取README文件失败: {$e} +msg-dcbd593f = 正在获取插件 {$plugin_name} 的更新日志 +msg-ea5482da = /api/plugin/changelog: {$res} +msg-8e27362e = 读取更新日志失败: {$e} +msg-0842bf8b = 插件 {$plugin_name} 没有更新日志文件 +msg-8e36313d = sources fields must be a list +msg-643e51e7 = /api/plugin/source/save: {$res} + +### astrbot/builtin_stars/session_controller/main.py +msg-b48bf3fe = LLM response failed: {$e} + +### astrbot/builtin_stars/builtin_commands/commands/setunset.py +msg-8b56b437 = 会话 {$uid} 变量 {$key} 存储成功。使用 /unset 移除。 +msg-dfd31d9d = 没有那个变量名。格式 /unset 变量名。 +msg-bf181241 = 会话 {$uid} 变量 {$key} 移除成功。 + +### astrbot/builtin_stars/builtin_commands/commands/provider.py +msg-b435fcdc = Provider reachability check failed: id=%s type=%s code=%s reason=%s +msg-f4cfd3ab = 正在进行提供商可达性测试,请稍候... +msg-ed8dcc22 = {$ret} +msg-f3d8988e = 请输入序号。 +msg-284759bb = 无效的提供商序号。 +msg-092d9956 = 成功切换到 {$id_}。 +msg-bf9eb668 = 无效的参数。 +msg-4cdd042d = 未找到任何 LLM 提供商。请先配置。 +msg-cb218e86 = 模型序号错误。 +msg-1756f199 = 切换模型成功。当前提供商: [{$res}] 当前模型: [{$res_2}] +msg-4d4f587f = 切换模型到 {$res}。 +msg-584ca956 = Key 序号错误。 +msg-f52481b8 = 切换 Key 未知错误: {$e} +msg-7a156524 = 切换 Key 成功。 + +### astrbot/builtin_stars/builtin_commands/commands/conversation.py +msg-63fe9607 = 在{$res}场景下,reset命令需要管理员权限,您 (ID {$res_2}) 不是管理员,无法执行此操作。 +msg-6f4bbe27 = 重置对话成功。 +msg-4cdd042d = 未找到任何 LLM 提供商。请先配置。 +msg-69ed45be = 当前未处于对话状态,请 /switch 切换或者 /new 创建。 +msg-ed8dcc22 = {$ret} +msg-772ec1fa = 已请求停止 {$stopped_count} 个运行中的任务。 +msg-8d42cd8a = 当前会话没有运行中的任务。 +msg-efdfbe3e = {$THIRD_PARTY_AGENT_RUNNER_STR} 对话列表功能暂不支持。 +msg-492c2c02 = 已创建新对话。 +msg-c7dc838d = 切换到新对话: 新对话({$res})。 +msg-6da01230 = 群聊 {$session} 已切换到新对话: 新对话({$res})。 +msg-f356d65a = 请输入群聊 ID。/groupnew 群聊ID。 +msg-7e442185 = 类型错误,请输入数字对话序号。 +msg-00dbe29c = 请输入对话序号。/switch 对话序号。/ls 查看对话 /new 新建对话 +msg-a848ccf6 = 对话序号错误,请使用 /ls 查看 +msg-1ec33cf6 = 切换到对话: {$title}({$res})。 +msg-68e5dd6c = 请输入新的对话名称。 +msg-c8dd6158 = 重命名对话成功。 +msg-1f1fa2f2 = 会话处于群聊,并且未开启独立会话,并且您 (ID {$res}) 不是管理员,因此没有权限删除当前对话。 +msg-6a1dc4b7 = 当前未处于对话状态,请 /switch 序号 切换或 /new 创建。 + +### astrbot/builtin_stars/builtin_commands/commands/tts.py +msg-ef1b2145 = {$status_text}当前会话的文本转语音。但 TTS 功能在配置中未启用,请前往 WebUI 开启。 +msg-deee9deb = {$status_text}当前会话的文本转语音。 + +### astrbot/builtin_stars/builtin_commands/commands/llm.py +msg-72cd5f57 = {$status} LLM 聊天功能。 + +### astrbot/builtin_stars/builtin_commands/commands/persona.py +msg-4f52d0dd = 当前对话不存在,请先使用 /new 新建一个对话。 +msg-e092b97c = [Persona]{"\u000A"}{"\u000A"}- 人格情景列表: `/persona list`{"\u000A"}- 设置人格情景: `/persona 人格`{"\u000A"}- 人格情景详细信息: `/persona view 人格`{"\u000A"}- 取消人格: `/persona unset`{"\u000A"}{"\u000A"}默认人格情景: {$res}{"\u000A"}当前对话 {$curr_cid_title} 的人格情景: {$curr_persona_name}{"\u000A"}{"\u000A"}配置人格情景请前往管理面板-配置页{"\u000A"} +msg-c046b6e4 = {$msg} +msg-99139ef8 = 请输入人格情景名 +msg-a44c7ec0 = 当前没有对话,无法取消人格。 +msg-a90c75d4 = 取消人格成功。 +msg-a712d71a = 当前没有对话,请先开始对话或使用 /new 创建一个对话。 +msg-4e4e746d = 设置成功。如果您正在切换到不同的人格,请注意使用 /reset 来清空上下文,防止原人格对话影响现人格。{$force_warn_msg} +msg-ab60a2e7 = 不存在该人格情景。使用 /persona list 查看所有。 + +### astrbot/builtin_stars/builtin_commands/commands/t2i.py +msg-855d5cf3 = 已关闭文本转图片模式。 +msg-64da24f4 = 已开启文本转图片模式。 + +### astrbot/builtin_stars/builtin_commands/commands/admin.py +msg-ad019976 = 使用方法: /op 授权管理员;/deop 取消管理员。可通过 /sid 获取 ID。 +msg-1235330f = 授权成功。 +msg-e78847e0 = 使用方法: /deop 取消管理员。可通过 /sid 获取 ID。 +msg-012152c1 = 取消授权成功。 +msg-5e076026 = 此用户 ID 不在管理员名单内。 +msg-7f8eedde = 使用方法: /wl 添加白名单;/dwl 删除白名单。可通过 /sid 获取 ID。 +msg-de1b0a87 = 添加白名单成功。 +msg-59d6fcbe = 使用方法: /dwl 删除白名单。可通过 /sid 获取 ID。 +msg-4638580f = 删除白名单成功。 +msg-278fb868 = 此 SID 不在白名单内。 +msg-1dee5007 = 正在尝试更新管理面板... +msg-76bea66c = 管理面板更新完成。 + +### astrbot/builtin_stars/builtin_commands/commands/sid.py +msg-ed8dcc22 = {$ret} + +### astrbot/builtin_stars/builtin_commands/commands/plugin.py +msg-9cae24f5 = {$plugin_list_info} +msg-3f3a6087 = 演示模式下无法禁用插件。 +msg-90e17cd4 = /plugin off <插件名> 禁用插件。 +msg-d29d6d57 = 插件 {$plugin_name} 已禁用。 +msg-f90bbe20 = 演示模式下无法启用插件。 +msg-b897048f = /plugin on <插件名> 启用插件。 +msg-ebfb93bb = 插件 {$plugin_name} 已启用。 +msg-9cd74a8d = 演示模式下无法安装插件。 +msg-d79ad78d = /plugin get <插件仓库地址> 安装插件 +msg-4f293fe1 = 准备从 {$plugin_repo} 安装插件。 +msg-d40e7065 = 安装插件成功。 +msg-feff82c6 = 安装插件失败: {$e} +msg-5bfe9d3d = /plugin help <插件名> 查看插件信息。 +msg-02627a9b = 未找到此插件。 +msg-ed8dcc22 = {$ret} + +### astrbot/builtin_stars/builtin_commands/commands/help.py +msg-c046b6e4 = {$msg} + +### astrbot/builtin_stars/builtin_commands/commands/alter_cmd.py +msg-d7a36c19 = 该指令用于设置指令或指令组的权限。{"\u000A"}格式: /alter_cmd {"\u000A"}例1: /alter_cmd c1 admin 将 c1 设为管理员指令{"\u000A"}例2: /alter_cmd g1 c1 admin 将 g1 指令组的 c1 子指令设为管理员指令{"\u000A"}/alter_cmd reset config 打开 reset 权限配置 +msg-afe0fa58 = {$config_menu} +msg-0c85d498 = 场景编号和权限类型不能为空 +msg-4e0afcd1 = 场景编号必须是 1-3 之间的数字 +msg-830d6eb8 = 权限类型错误,只能是 admin 或 member +msg-d1180ead = 已将 reset 命令在{$res}场景下的权限设为{$perm_type} +msg-8d9bc364 = 指令类型错误,可选类型有 admin, member +msg-1f2f65e0 = 未找到该指令 +msg-cd271581 = 已将「{$cmd_name}」{$cmd_group_str} 的权限级别调整为 {$cmd_type}。 + +### astrbot/builtin_stars/web_searcher/main.py +msg-7f5fd92b = 检测到旧版 websearch_tavily_key (字符串格式),自动迁移为列表格式并保存。 +msg-bed9def5 = web_searcher - scraping web: {$res} - {$res_2} +msg-8214760c = bing search error: {$e}, try the next one... +msg-8676b5aa = search bing failed +msg-3fb6d6ad = sogo search error: {$e} +msg-fe9b336f = search sogo failed +msg-c991b022 = 错误:Tavily API密钥未在AstrBot中配置。 +msg-b4fbb4a9 = Tavily web search failed: {$reason}, status: {$res} +msg-6769aba9 = Error: Tavily web searcher does not return any results. +msg-b4e7334e = 此指令已经被废弃,请在 WebUI 中开启或关闭网页搜索功能。 +msg-b1877974 = web_searcher - search_from_search_engine: {$query} +msg-2360df6b = Error processing search result: {$processed_result} +msg-359d0443 = Error: Baidu AI Search API key is not configured in AstrBot. +msg-94351632 = Successfully initialized Baidu AI Search MCP server. +msg-5a7207c1 = web_searcher - search_from_tavily: {$query} +msg-b36134c9 = Error: Tavily API key is not configured in AstrBot. +msg-98ed69f4 = Error: url must be a non-empty string. +msg-51edd9ee = 错误:BoCha API密钥未在AstrBot中配置。 +msg-73964067 = BoCha web search failed: {$reason}, status: {$res} +msg-34417720 = web_searcher - search_from_bocha: {$query} +msg-b798883b = Error: BoCha API key is not configured in AstrBot. +msg-22993708 = Cannot get Baidu AI Search MCP tool. +msg-6f8d62a4 = Cannot Initialize Baidu AI Search MCP Server: {$e} + +### astrbot/builtin_stars/web_searcher/engines/bing.py +msg-e3b4d1e9 = Bing search failed + +### astrbot/builtin_stars/astrbot/main.py +msg-3df554a1 = 聊天增强 err: {$e} +msg-5bdf8f5c = {$e} +msg-bb6ff036 = 未找到任何 LLM 提供商。请先配置。无法主动回复 +msg-afa050be = 当前未处于对话状态,无法主动回复,请确保 平台设置->会话隔离(unique_session) 未开启,并使用 /switch 序号 切换或者 /new 创建一个会话。 +msg-9a6a6b2e = 未找到对话,无法主动回复 +msg-78b9c276 = {$res} +msg-b177e640 = 主动回复失败: {$e} +msg-24d2f380 = ltm: {$e} + +### astrbot/builtin_stars/astrbot/long_term_memory.py +msg-5bdf8f5c = {$e} +msg-8e11fa57 = 没有找到 ID 为 {$image_caption_provider_id} 的提供商 +msg-8ebaa397 = 提供商类型错误({$res}),无法获取图片描述 +msg-30954f77 = 图片 URL 为空 +msg-62de0c3e = 获取图片描述失败: {$e} +msg-d0647999 = ltm | {$res} | {$final_message} +msg-133c1f1d = Recorded AI response: {$res} | {$final_message} + +### astrbot/i18n/ftl_translate.py +msg-547c9cc5 = 未检测到环境变量 DEEPSEEK_API_KEY,请先设置。 +msg-8654e4be = {"\u000A"}[Error] API 调用失败: {$e} +msg-75f207ed = File not found: {$ftl_path} +msg-dcfbbe82 = No messages found in {$ftl_path} +msg-ccd5a28f = 共 {$res} 条文本,使用 {$max_workers} 个并发线程翻译... +msg-00b24d69 = {"\u000A"}[Error] 翻译失败,保留原文: {$e} +msg-ebcdd595 = {"\u000A"}翻译完成,已保存到 {$ftl_path} +msg-d6c66497 = 错误: 请先设置 DEEPSEEK_API_KEY 环境变量。 +msg-09486085 = 例如: export DEEPSEEK_API_KEY='sk-xxxxxx' + +### scripts/generate_changelog.py +msg-a79937ef = Warning: openai package not installed. Install it with: pip install openai +msg-090bfd36 = Warning: Failed to call LLM API: {$e} +msg-a3ac9130 = Falling back to simple changelog generation... +msg-6f1011c5 = Latest tag: {$latest_tag} +msg-8c7f64d7 = Error: No tags found in repository +msg-a89fa0eb = No commits found since {$latest_tag} +msg-846ebecf = Found {$res} commits since {$latest_tag} +msg-9ad686af = Warning: Could not parse version from tag {$latest_tag} +msg-f5d43a54 = Generating changelog for {$version}... +msg-e54756e8 = {"\u000A"}✓ Changelog generated: {$changelog_file} +msg-82be6c98 = {"\u000A"}Preview: +msg-321ac5b1 = {$changelog_content} diff --git a/dashboard/src/i18n/composables.ts b/dashboard/src/i18n/composables.ts index 131010bc39..36e419bedb 100644 --- a/dashboard/src/i18n/composables.ts +++ b/dashboard/src/i18n/composables.ts @@ -1,6 +1,7 @@ import { ref, computed } from 'vue'; import { translations as staticTranslations } from './translations'; import type { Locale } from './types'; +import axios from 'axios'; // 全局状态 const currentLocale = ref('zh-CN'); @@ -96,6 +97,16 @@ export function useI18n() { window.dispatchEvent(new CustomEvent('astrbot-locale-changed', { detail: { locale: newLocale } })); + + axios.post("/api/setLang", { lang: newLocale }) + .then(response => { + if (response.data.code !== 200) { + console.error('Failed to set language on server:', response.data.message); + } + }) + .catch(error => { + console.error('Error setting language on server:', error); + }); } }; @@ -225,4 +236,14 @@ export async function setupI18n() { : 'zh-CN'; await initI18n(initialLocale); + + axios.post("/api/setLang", { lang: initialLocale }) + .then(response => { + if (response.data.code !== 200) { + console.error('Failed to set language on server:', response.data.message); + } + }) + .catch(error => { + console.error('Error setting language on server:', error); + }); } \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index d0845cac86..4a88e8c350 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,6 +26,7 @@ dependencies = [ "docstring-parser>=0.16", "faiss-cpu>=1.12.0", "filelock>=3.18.0", + "fluent.runtime>=0.4.0", "google-genai>=1.56.0", "lark-oapi>=1.4.15", "lxml-html-clean>=0.4.2", diff --git a/requirements.txt b/requirements.txt index dd19a02c30..0c12cba7eb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,6 +19,7 @@ dingtalk-stream>=0.22.1 docstring-parser>=0.16 faiss-cpu>=1.12.0 filelock>=3.18.0 +fluent.runtime>=0.4.0 google-genai>=1.56.0 lark-oapi>=1.4.15 lxml-html-clean>=0.4.2 From 18df2814d49b88acd3f612c7c72712bdd8a6d439 Mon Sep 17 00:00:00 2001 From: united_pooh Date: Fri, 27 Feb 2026 17:17:00 +0800 Subject: [PATCH 02/36] feat(i18n): update ftl_translate defaults and sync translation files --- astrbot/i18n/ftl_translate.py | 8 +- astrbot/i18n/locales/en-us/i18n_messages.ftl | 4554 +++++++++--------- astrbot/i18n/locales/zh-cn/i18n_messages.ftl | 4224 ++++++++-------- 3 files changed, 4627 insertions(+), 4159 deletions(-) diff --git a/astrbot/i18n/ftl_translate.py b/astrbot/i18n/ftl_translate.py index 2f76f61515..fc9fc9d934 100644 --- a/astrbot/i18n/ftl_translate.py +++ b/astrbot/i18n/ftl_translate.py @@ -21,7 +21,7 @@ def translate_string(input_string: str, target_lang: str = "English") -> str: "规则:\n\n" "1. 必须原样保留所有代码占位符(如 {$var} 等)。\n\n" "2. 只输出最终译文,绝对禁止包含任何解释、多余的引号或Markdown格式。" - "3. 如果原文为中文则直接返回原文" + "3. 如果原文为目标语言则直接返回原文" ) try: @@ -107,12 +107,12 @@ def main(): ) parser.add_argument( "--file", - default="astrbot/i18n/locales/en-us/i18n_messages.ftl", + default="astrbot/i18n/locales/zh-cn/i18n_messages.ftl", help="待翻译的 FTL 文件路径", ) - parser.add_argument("--lang", default="English", help="目标语言(默认: English)") + parser.add_argument("--lang", default="Chinese", help="目标语言(默认: Chinese)") parser.add_argument( - "--workers", type=int, default=10, help="并发线程数(默认: 10)" + "--workers", type=int, default=28, help="并发线程数(默认: 10)" ) args = parser.parse_args() diff --git a/astrbot/i18n/locales/en-us/i18n_messages.ftl b/astrbot/i18n/locales/en-us/i18n_messages.ftl index 3eef348631..e8541eb20e 100644 --- a/astrbot/i18n/locales/en-us/i18n_messages.ftl +++ b/astrbot/i18n/locales/en-us/i18n_messages.ftl @@ -1,1448 +1,1569 @@ - ### main.py -msg-5e25709f = 请使用 Python3.10+ 运行本项目。 -msg-afd0ab81 = 使用指定的 WebUI 目录: {$webui_dir} -msg-7765f00f = 指定的 WebUI 目录 {$webui_dir} 不存在,将使用默认逻辑。 -msg-9af20e37 = WebUI 版本已是最新。 -msg-9dd5c1d2 = 检测到 WebUI 版本 ({$v}) 与当前 AstrBot 版本 (v{$VERSION}) 不符。 -msg-ec714d4e = 开始下载管理面板文件...高峰期(晚上)可能导致较慢的速度。如多次下载失败,请前往 https://github.com/AstrBotDevs/AstrBot/releases/latest 下载 dist.zip,并将其中的 dist 文件夹解压至 data 目录下。 -msg-c5170c27 = 下载管理面板文件失败: {$e}。 -msg-e1592ad1 = 管理面板下载完成。 -msg-fe494da6 = {$logo_tmpl} + +msg-5e25709f = Please use Python3.10+ to run this project. +msg-afd0ab81 = Use the specified WebUI directory:{ $webui_dir } +msg-7765f00f = Specified WebUI directory{ $webui_dir }Does not exist, default logic will be used. +msg-9af20e37 = The WebUI version is already up to date. +msg-9dd5c1d2 = Detected WebUI version ({ $v }) and the current AstrBot version (v{ $VERSION }) does not match. +msg-ec714d4e = Start downloading the management panel files...Peak hours (evening) may result in slower speeds. If the download fails multiple times, please go to https://github.com/AstrBotDevs/AstrBot/releases/latest to download dist.zip, and extract the dist folder into the data directory. +msg-c5170c27 = Failed to download the management panel file:{ $e }. +msg-e1592ad1 = Management panel download completed. +msg-fe494da6 = { $logo_tmpl } ### astrbot/core/lang.py + msg-d103bc8e = Namespace must not be empty. msg-f66527da = Namespace must not contain '.'. -msg-b3665aee = Locale directory does not exist: {$base_dir} -msg-3fe89e6a = No locale directories found under: {$base_dir} -msg-c79b2c75 = Namespace '{$namespace}' already exists. Set replace=True to overwrite. +msg-b3665aee = Locale directory does not exist:{ $base_dir } +msg-3fe89e6a = No locale directories found under:{ $base_dir } +msg-c79b2c75 = Namespace '{ $namespace }' already exists. Set replace=True to overwrite. msg-7db3fccf = Default namespace cannot be unregistered. -msg-3d066f64 = Namespace '{$namespace}' is not registered. +msg-3d066f64 = Namespace '{ $namespace }' is not registered. ### astrbot/core/persona_mgr.py -msg-51a854e6 = 已加载 {$res} 个人格。 -msg-1ea88f45 = Persona with ID {$persona_id} does not exist. -msg-28104dff = Persona with ID {$persona_id} already exists. -msg-08ecfd42 = {$res} 人格情景预设对话格式不对,条数应该为偶数。 -msg-b6292b94 = 解析 Persona 配置失败:{$e} + +msg-51a854e6 = Loaded{ $res }Personality. +msg-1ea88f45 = Persona with ID{ $persona_id }does not exist. +msg-28104dff = Persona with ID{ $persona_id }already exists. +msg-08ecfd42 = { $res }The personality scenario preset dialogue format is incorrect; the number of entries should be even. +msg-b6292b94 = Failed to parse Persona configuration:{ $e } ### astrbot/core/initial_loader.py -msg-78b9c276 = {$res} -msg-58525c23 = 😭 初始化 AstrBot 失败:{$e} !!! -msg-002cc3e8 = 🌈 正在关闭 AstrBot... + +msg-78b9c276 = { $res } +msg-58525c23 = 😭 Failed to initialize AstrBot:{ $e }!!! +msg-002cc3e8 = 🌈 Shutting down AstrBot... ### astrbot/core/log.py -msg-80a186b8 = Failed to add file sink: {$e} + +msg-80a186b8 = Failed to add file sink:{ $e } ### astrbot/core/astrbot_config_mgr.py -msg-7875e5bd = Config file {$conf_path} for UUID {$uuid_} does not exist, skipping. -msg-39c4fd49 = 不能删除默认配置文件 -msg-cf7b8991 = 配置文件 {$conf_id} 不存在于映射中 -msg-2aad13a4 = 已删除配置文件: {$conf_path} -msg-94c359ef = 删除配置文件 {$conf_path} 失败: {$e} -msg-44f0b770 = 成功删除配置文件 {$conf_id} -msg-737da44e = 不能更新默认配置文件的信息 -msg-9d496709 = 成功更新配置文件 {$conf_id} 的信息 + +msg-7875e5bd = Config file{ $conf_path }for UUID{ $uuid_ }does not exist, skipping. +msg-39c4fd49 = Cannot delete the default configuration file +msg-cf7b8991 = Configuration file{ $conf_id }Not present in the mapping +msg-2aad13a4 = Deleted configuration file:{ $conf_path } +msg-94c359ef = Delete configuration file{ $conf_path }Failure:{ $e } +msg-44f0b770 = Configuration file deleted successfully{ $conf_id } +msg-737da44e = Cannot update information in the default configuration file +msg-9d496709 = Configuration file updated successfully{ $conf_id }Information of ### astrbot/core/zip_updator.py -msg-24c90ff8 = 请求 {$url} 失败,状态码: {$res}, 内容: {$text} -msg-14726dd8 = 请求失败,状态码: {$res} -msg-fc3793c6 = 解析版本信息时发生异常: {$e} -msg-491135d9 = 解析版本信息失败 -msg-03a72cb5 = 未找到合适的发布版本 -msg-8bcbfcf0 = 正在下载更新 {$repo} ... -msg-ccc87294 = 正在从指定分支 {$branch} 下载 {$author}/{$repo} -msg-dfebcdc6 = 获取 {$author}/{$repo} 的 GitHub Releases 失败: {$e},将尝试下载默认分支 -msg-e327bc14 = 正在从默认分支下载 {$author}/{$repo} -msg-3cd3adfb = 检查到设置了镜像站,将使用镜像站下载 {$author}/{$repo} 仓库源码: {$release_url} -msg-1bffc0d7 = 无效的 GitHub URL -msg-0ba954db = 解压文件完成: {$zip_path} -msg-90ae0d15 = 删除临时更新文件: {$zip_path} 和 {$res} -msg-f8a43aa5 = 删除更新文件失败,可以手动删除 {$zip_path} 和 {$res} + +msg-24c90ff8 = Request{ $url }Failed, status code:{ $res }, Content:{ $text } +msg-14726dd8 = Request failed, status code:{ $res } +msg-fc3793c6 = Exception occurred while parsing version information:{ $e } +msg-491135d9 = Failed to parse version information +msg-03a72cb5 = No suitable release version found +msg-8bcbfcf0 = 正在下载更新{ $repo }... +msg-ccc87294 = Fetching from specified branch{ $branch }Download{ $author }/{ $repo } +msg-dfebcdc6 = Acquire{ $author }/{ $repo }GitHub Releases failed:{ $e }, will attempt to download the default branch +msg-e327bc14 = Downloading from the default branch{ $author }待翻译文本:{ $repo } +msg-3cd3adfb = Mirror site detected, will use mirror site for downloading.{ $author }Text to be translated:{ $repo }Repository Source Code:{ $release_url } +msg-1bffc0d7 = Invalid GitHub URL +msg-0ba954db = File decompression completed:{ $zip_path } +msg-90ae0d15 = Delete temporary update file:{ $zip_path }and{ $res } +msg-f8a43aa5 = Failed to delete the update file. You can delete it manually.{ $zip_path }and{ $res } ### astrbot/core/file_token_service.py -msg-0e444e51 = 文件不存在: {$local_path} (原始输入: {$file_path}) -msg-f61a5322 = 无效或过期的文件 token: {$file_token} -msg-73d3e179 = 文件不存在: {$file_path} + +msg-0e444e51 = File does not exist:{ $local_path }Text to be translated: (Original input:{ $file_path }Text to be translated: +msg-f61a5322 = Invalid or expired file token:{ $file_token } +msg-73d3e179 = File does not exist:{ $file_path } ### astrbot/core/subagent_orchestrator.py + msg-5d950986 = subagent_orchestrator.agents must be a list msg-29e3b482 = SubAgent persona %s not found, fallback to inline prompt. -msg-f425c9f0 = Registered subagent handoff tool: {$res} +msg-f425c9f0 = Registered subagent handoff tool:{ $res } ### astrbot/core/astr_main_agent.py -msg-8dcf5caa = 未找到指定的提供商: %s。 -msg-61d46ee5 = 选择的提供商类型无效(%s),跳过 LLM 请求处理。 + +msg-8dcf5caa = Specified provider not found: %s. +msg-61d46ee5 = Invalid provider type selected (%s), skipping LLM request processing. msg-496864bc = Error occurred while selecting provider: %s -msg-507853eb = 无法创建新的对话。 +msg-507853eb = Unable to create a new conversation. msg-66870b7e = Error occurred while retrieving knowledge base: %s -msg-36dc1409 = Moonshot AI API key for file extract is not set +msg-36dc1409 = Moonshot AI API key for file extraction is not set msg-8534047e = Unsupported file extract provider: %s -msg-f2ea29f4 = Cannot get image caption because provider `{$provider_id}` is not exist. -msg-91a70615 = Cannot get image caption because provider `{$provider_id}` is not a valid Provider, it is {$res}. +msg-f2ea29f4 = Cannot get image caption because provider `{ $provider_id }` does not exist. +msg-91a70615 = Cannot get image caption because provider `{ $provider_id }` is not a valid Provider, it is{ $res }. msg-b1840df0 = Processing image caption with provider: %s -msg-089421fc = 处理图片描述失败: %s +msg-089421fc = Failed to process image description: %s msg-719d5e4d = No provider found for image captioning in quote. -msg-e16a974b = 处理引用图片失败: %s +msg-e16a974b = Failed to process referenced image: %s msg-037dad2e = Group name display enabled but group object is None. Group ID: %s -msg-58b47bcd = 时区设置错误: %s, 使用本地时区 +msg-58b47bcd = Timezone setting error: %s, using local timezone msg-938af433 = Provider %s does not support image, using placeholder. msg-83d739f8 = Provider %s does not support tool_use, clearing tools. msg-3dbad2d9 = sanitize_context_by_modalities applied: removed_image_blocks=%s, removed_tool_messages=%s, removed_tool_calls=%s msg-4214b760 = Generated chatui title for session %s: %s msg-cb6db56e = Unsupported llm_safety_mode strategy: %s. msg-7ea2c5d3 = Shipyard sandbox configuration is incomplete. -msg-9248b273 = 未找到指定的上下文压缩模型 %s,将跳过压缩。 -msg-16fe8ea5 = 指定的上下文压缩模型 %s 不是对话模型,将跳过压缩。 -msg-c6c9d989 = fallback_chat_models setting is not a list, skip fallback providers. +msg-9248b273 = The specified context compression model %s was not found; compression will be skipped. +msg-16fe8ea5 = The specified context compression model %s is not a conversational model and will be skipped for compression. +msg-c6c9d989 = The fallback_chat_models setting is not a list, skipping fallback providers. msg-614aebad = Fallback chat provider `%s` not found, skip. -msg-1a2e87dd = Fallback chat provider `%s` is invalid type: %s, skip. -msg-ee979399 = 未找到任何对话模型(提供商),跳过 LLM 请求处理。 +msg-1a2e87dd = Fallback chat provider `%s` is of an invalid type: %s, skipping. +msg-ee979399 = No conversation models (providers) found, skipping LLM request processing. msg-7a7b4529 = Skip quoted fallback images due to limit=%d for umo=%s msg-46bcda31 = Truncate quoted fallback images for umo=%s, reply_id=%s from %d to %d msg-cbceb923 = Failed to resolve fallback quoted images for umo=%s, reply_id=%s: %s msg-31483e80 = Error occurred while applying file extract: %s ### astrbot/core/umop_config_router.py + msg-dedcfded = umop keys must be strings in the format [platform_id]:[message_type]:[session_id], with optional wildcards * or empty for all msg-8e3a16f3 = umop must be a string in the format [platform_id]:[message_type]:[session_id], with optional wildcards * or empty for all ### astrbot/core/event_bus.py -msg-da466871 = PipelineScheduler not found for id: {$res}, event ignored. -msg-7eccffa5 = [{$conf_name}] [{$res}({$res_2})] {$res_3}/{$res_4}: {$res_5} -msg-88bc26f2 = [{$conf_name}] [{$res}({$res_2})] {$res_3}: {$res_4} + +msg-da466871 = PipelineScheduler not found for id:{ $res }, event ignored. +msg-7eccffa5 = Text to be translated:{ $conf_name }] [{ $res }Text to translate: ({ $res_2 })]{ $res_3 }Text to be translated: /{ $res_4 }Text to be translated:{ $res_5 } +msg-88bc26f2 = Text to translate:{ $conf_name }] [{ $res }Text to be translated:{ $res_2 })]{ $res_3 }Text to be translated:{ $res_4 } ### astrbot/core/astr_agent_tool_exec.py -msg-e5f2fb34 = Background task {$task_id} failed: {$e} -msg-c54b2335 = Background handoff {$task_id} ({$res}) failed: {$e} -msg-8c2fe51d = Failed to build main agent for background task {$tool_name}. + +msg-e5f2fb34 = Background task{ $task_id }failed:{ $e } +msg-c54b2335 = Background handoff{ $task_id }Text to be translated:{ $res }) failed:{ $e } +msg-8c2fe51d = Failed to build main agent for background task{ $tool_name }. msg-c6d4e4a6 = background task agent got no response msg-0b3711f1 = Event must be provided for local function tools. msg-8c19e27a = Tool must have a valid handler or override 'run' method. -msg-24053a5f = Tool 直接发送消息失败: {$e} -msg-f940b51e = tool {$res} execution timeout after {$res_2} seconds. -msg-7e22fc8e = 未知的方法名: {$method_name} -msg-c285315c = Tool execution ValueError: {$e} -msg-41366b74 = Tool handler parameter mismatch, please check the handler definition. Handler parameters: {$handler_param_str} -msg-e8cadf8e = Tool execution error: {$e}. Traceback: {$trace_} -msg-d7b4aa84 = Previous Error: {$trace_} +msg-24053a5f = Tool failed to send message directly:{ $e } +msg-f940b51e = tool{ $res }execution timeout after{ $res_2 }seconds. +msg-7e22fc8e = Unknown method name:{ $method_name } +msg-c285315c = Tool execution ValueError:{ $e } +msg-41366b74 = Tool handler parameter mismatch, please check the handler definition. Handler parameters:{ $handler_param_str } +msg-e8cadf8e = Tool execution error:{ $e }. Traceback:{ $trace_ } +msg-d7b4aa84 = Previous Error:{ $trace_ } ### astrbot/core/astr_agent_run_util.py -msg-6b326889 = Agent reached max steps ({$max_step}), forcing a final response. -msg-bb15e9c7 = {$status_msg} -msg-78b9c276 = {$res} + +msg-6b326889 = Agent reached max steps ({ $max_step }), forcing a final response. +msg-bb15e9c7 = { $status_msg } +msg-78b9c276 = { $res } msg-9c246298 = Error in on_agent_done hook -msg-34f164d4 = {$err_msg} -msg-6d9553b2 = [Live Agent] 使用流式 TTS(原生支持 get_audio_stream) -msg-becf71bf = [Live Agent] 使用 TTS({$res} 使用 get_audio,将按句子分块生成音频) -msg-21723afb = [Live Agent] 运行时发生错误: {$e} -msg-ca1bf0d7 = 发送 TTS 统计信息失败: {$e} -msg-5ace3d96 = [Live Agent Feeder] 分句: {$temp_buffer} -msg-bc1826ea = [Live Agent Feeder] Error: {$e} -msg-a92774c9 = [Live TTS Stream] Error: {$e} -msg-d7b3bbae = [Live TTS Simulated] Error processing text '{$res}...': {$e} -msg-035bca5f = [Live TTS Simulated] Critical Error: {$e} +msg-34f164d4 = { $err_msg } +msg-6d9553b2 = [Live Agent] Using streaming TTS (natively supports get_audio_stream) +msg-becf71bf = [Live Agent] Using TTS ({ $res }Using get_audio, audio will be generated in sentence-based chunks +msg-21723afb = [Live Agent] Runtime error occurred:{ $e } +msg-ca1bf0d7 = Failed to send TTS statistics:{ $e } +msg-5ace3d96 = [Live Agent Feeder] Sentence segmentation:{ $temp_buffer } +msg-bc1826ea = [Live Agent Feeder] Error:{ $e } +msg-a92774c9 = [Live TTS Stream] Error:{ $e } +msg-d7b3bbae = [Live TTS Simulated] Error processing text '{ $res }'...':{ $e } +msg-035bca5f = [Live TTS Simulated] Critical Error:{ $e } ### astrbot/core/astr_main_agent_resources.py -msg-509829d8 = Downloaded file from sandbox: {$path} -> {$local_path} -msg-b462b60d = Failed to check/download file from sandbox: {$e} -msg-0b3144f1 = [知识库] 会话 {$umo} 已被配置为不使用知识库 -msg-97e13f98 = [知识库] 知识库不存在或未加载: {$kb_id} -msg-312d09c7 = [知识库] 会话 {$umo} 配置的以下知识库无效: {$invalid_kb_ids} -msg-42b0e9f8 = [知识库] 使用会话级配置,知识库数量: {$res} -msg-08167007 = [知识库] 使用全局配置,知识库数量: {$res} -msg-a00becc3 = [知识库] 开始检索知识库,数量: {$res}, top_k={$top_k} -msg-199e71b7 = [知识库] 为会话 {$umo} 注入了 {$res} 条相关知识块 + +msg-509829d8 = Downloaded file from sandbox:{ $path }->{ $local_path } +msg-b462b60d = Failed to check/download file from sandbox:{ $e } +msg-0b3144f1 = [Knowledge Base] Session{ $umo }It has been configured to not use the knowledge base. +msg-97e13f98 = [Knowledge Base] Knowledge base does not exist or is not loaded:{ $kb_id } +msg-312d09c7 = [Knowledge Base] Session{ $umo }The following configured knowledge base is invalid:{ $invalid_kb_ids } +msg-42b0e9f8 = [Knowledge Base] Using session-level configuration, number of knowledge bases:{ $res } +msg-08167007 = [Knowledge Base] Using global configuration, number of knowledge bases:{ $res } +msg-a00becc3 = [Knowledge Base] Start retrieving knowledge base, count:{ $res }, top_k={ $top_k } +msg-199e71b7 = [Knowledge Base] for Conversation{ $umo }Injected{ $res }knowledge blocks ### astrbot/core/conversation_mgr.py -msg-86f404dd = 会话删除回调执行失败 (session: {$unified_msg_origin}): {$e} -msg-57dcc41f = Conversation with id {$cid} not found + +msg-86f404dd = Session deletion callback execution failed (session:{ $unified_msg_origin }):{ $e } +msg-57dcc41f = Conversation with id{ $cid }not found ### astrbot/core/updator.py -msg-e3d42a3b = 正在终止 {$res} 个子进程。 -msg-e7edc4a4 = 正在终止子进程 {$res} -msg-37bea42d = 子进程 {$res} 没有被正常终止, 正在强行杀死。 -msg-cc6d9588 = 重启失败({$executable}, {$e}),请尝试手动重启。 -msg-0e4439d8 = 不支持更新此方式启动的AstrBot -msg-3f39a942 = 当前已经是最新版本。 -msg-c7bdf215 = 未找到版本号为 {$version} 的更新文件。 -msg-92e46ecc = commit hash 长度不正确,应为 40 -msg-71c01b1c = 准备更新至指定版本的 AstrBot Core: {$version} -msg-d3a0e13d = 下载 AstrBot Core 更新文件完成,正在执行解压... + +msg-e3d42a3b = Terminating{ $res }child processes. +msg-e7edc4a4 = 正在终止子进程{ $res } +msg-37bea42d = Child process{ $res }Not terminated normally, forcing a kill. +msg-cc6d9588 = Restart failed ({ $executable }{ $e }Please try to restart manually. +msg-0e4439d8 = Updating AstrBot started in this way is not supported. +msg-3f39a942 = Current version is already up to date. +msg-c7bdf215 = Version number not found{ $version }Update files. +msg-92e46ecc = The commit hash length is incorrect; it should be 40 characters. +msg-71c01b1c = Preparing to update AstrBot Core to the specified version:{ $version } +msg-d3a0e13d = Download of AstrBot Core update file completed, extracting now... ### astrbot/core/core_lifecycle.py -msg-9967ec8b = Using proxy: {$proxy_config} + +msg-9967ec8b = Using proxy:{ $proxy_config } msg-5a29b73d = HTTP proxy cleared -msg-fafb87ce = Subagent orchestrator init failed: {$e} -msg-f7861f86 = AstrBot migration failed: {$e} -msg-78b9c276 = {$res} -msg-967606fd = ------- 任务 {$res} 发生错误: {$e} -msg-a2cd77f3 = | {$line} -msg-1f686eeb = ------- -msg-9556d279 = AstrBot 启动完成。 -msg-daaf690b = hook(on_astrbot_loaded) -> {$res} - {$res_2} -msg-4719cb33 = 插件 {$res} 未被正常终止 {$e}, 可能会导致资源泄露等问题。 -msg-c3bbfa1d = 任务 {$res} 发生错误: {$e} -msg-af06ccab = 配置文件 {$conf_id} 不存在 +msg-fafb87ce = Subagent orchestrator init failed:{ $e } +msg-f7861f86 = AstrBot migration failed:{ $e } +msg-78b9c276 = { $res } +msg-967606fd = Task{ $res }An error occurred:{ $e } +msg-a2cd77f3 = Text to be translated:{ $line } +msg-1f686eeb = Text to be translated: +msg-9556d279 = AstrBot startup completed. +msg-daaf690b = hook(on_astrbot_loaded) ->{ $res }-{ $res_2 } +msg-4719cb33 = Plugin{ $res }Not properly terminated{ $e }, which may lead to resource leaks and other issues. +msg-c3bbfa1d = Task{ $res }An error occurred:{ $e } +msg-af06ccab = Configuration file{ $conf_id }不存在 ### astrbot/core/pipeline/context_utils.py -msg-49f260d3 = 处理函数参数不匹配,请检查 handler 的定义。 -msg-d7b4aa84 = Previous Error: {$trace_} -msg-eb8619cb = hook({$res}) -> {$res_2} - {$res_3} -msg-78b9c276 = {$res} -msg-add19f94 = {$res} - {$res_2} 终止了事件传播。 + +msg-49f260d3 = Handler function parameter mismatch, please check the handler definition. +msg-d7b4aa84 = Previous Error:{ $trace_ } +msg-eb8619cb = hook{ $res }) ->{ $res_2 }-{ $res_3 } +msg-78b9c276 = { $res } +msg-add19f94 = { $res }-{ $res_2 }Terminated event propagation. ### astrbot/core/pipeline/__init__.py -msg-1c9fc93d = module {$__name__} has no attribute {$name} + ### astrbot/core/pipeline/scheduler.py -msg-c240d574 = 阶段 {$res} 已终止事件传播。 -msg-609a1ac5 = pipeline 执行完毕。 + +msg-c240d574 = Stage{ $res }Event propagation has been terminated. +msg-609a1ac5 = The pipeline execution is complete. ### astrbot/core/pipeline/rate_limit_check/stage.py -msg-18092978 = 会话 {$session_id} 被限流。根据限流策略,此会话处理将被暂停 {$stall_duration} 秒。 -msg-4962387a = 会话 {$session_id} 被限流。根据限流策略,此请求已被丢弃,直到限额于 {$stall_duration} 秒后重置。 + +msg-18092978 = Session{ $session_id }Rate limited. According to the rate limiting policy, this session processing will be paused.{ $stall_duration }Second +msg-4962387a = Session{ $session_id }Rate limited. According to the rate limiting policy, this request has been discarded until the quota resets at{ $stall_duration }Reset in seconds. ### astrbot/core/pipeline/whitelist_check/stage.py -msg-8282c664 = 会话 ID {$res} 不在会话白名单中,已终止事件传播。请在配置文件中添加该会话 ID 到白名单。 + +msg-8282c664 = Session ID{ $res }Not in the conversation whitelist, event propagation has been terminated. Please add the conversation ID to the whitelist in the configuration file. ### astrbot/core/pipeline/process_stage/follow_up.py + msg-df881b01 = Captured follow-up message for active agent run, umo=%s, order_seq=%s ### astrbot/core/pipeline/process_stage/method/agent_request.py -msg-3267978a = 识别 LLM 聊天额外唤醒前缀 {$res} 以机器人唤醒前缀 {$bwp} 开头,已自动去除。 + +msg-3267978a = Identify additional wake-up prefixes for LLM chats{ $res }Wake-up prefix for the robot{ $bwp }Start, automatically removed. msg-97a4d573 = This pipeline does not enable AI capability, skip processing. -msg-f1a11d2b = The session {$res} has disabled AI capability, skipping processing. +msg-f1a11d2b = The session{ $res }AI capability has been disabled, skipping processing. ### astrbot/core/pipeline/process_stage/method/star_request.py -msg-f0144031 = Cannot find plugin for given handler module path: {$res} -msg-1e8939dd = plugin -> {$res} - {$res_2} -msg-6be73b5e = {$traceback_text} -msg-d919bd27 = Star {$res} handle error: {$e} -msg-ed8dcc22 = {$ret} + +msg-f0144031 = Cannot find plugin for given handler module path:{ $res } +msg-1e8939dd = plugin ->{ $res }-{ $res_2 } +msg-6be73b5e = { $traceback_text } +msg-d919bd27 = Star{ $res }handle error:{ $e } +msg-ed8dcc22 = { $ret } ### astrbot/core/pipeline/process_stage/method/agent_sub_stages/internal.py + msg-60493581 = Unsupported tool_schema_mode: %s, fallback to skills_like msg-9cdb2b6e = skip llm request: empty message and no provider_request msg-e461e5af = ready to request llm provider msg-be33dd11 = Follow-up ticket already consumed, stopping processing. umo=%s, seq=%s msg-abd5ccbc = acquired session lock for llm request -msg-f9d617d7 = Provider API base %s is blocked due to security reasons. Please use another ai provider. -msg-3247374d = [Internal Agent] 检测到 Live Mode,启用 TTS 处理 -msg-dae92399 = [Live Mode] TTS Provider 未配置,将使用普通流式模式 -msg-1b1af61e = Error occurred while processing agent: {$e} -msg-ea02b899 = Error occurred while processing agent request: {$e} -msg-ee7e792b = LLM 响应为空,不保存记录。 +msg-f9d617d7 = Provider API base %s is blocked due to security reasons. Please use another AI provider. +msg-3247374d = [Internal Agent] Live Mode detected, enabling TTS processing. +msg-dae92399 = [Live Mode] TTS Provider is not configured, will use normal streaming mode. +msg-1b1af61e = Error occurred while processing agent:{ $e } +msg-ea02b899 = Error occurred while processing agent request:{ $e } +msg-ee7e792b = LLM response is empty, no record saved. ### astrbot/core/pipeline/process_stage/method/agent_sub_stages/third_party.py -msg-5e551baf = Third party agent runner error: {$e} -msg-34f164d4 = {$err_msg} -msg-f9d76893 = 没有填写 Agent Runner 提供商 ID,请前往配置页面配置。 -msg-0f856470 = Agent Runner 提供商 {$res} 配置不存在,请前往配置页面修改配置。 -msg-b3f25c81 = Unsupported third party agent runner type: {$res} -msg-6c63eb68 = Agent Runner 未返回最终结果。 + +msg-5e551baf = Third party agent runner error:{ $e } +msg-34f164d4 = { $err_msg } +msg-f9d76893 = The Agent Runner provider ID is not filled in. Please go to the configuration page to configure it. +msg-0f856470 = Agent Runner Provider{ $res }Configuration does not exist. Please go to the configuration page to modify the configuration. +msg-b3f25c81 = Unsupported third party agent runner type:{ $res } +msg-6c63eb68 = Agent Runner did not return the final result. ### astrbot/core/pipeline/result_decorate/stage.py -msg-7ec898fd = hook(on_decorating_result) -> {$res} - {$res_2} -msg-5e27dae6 = 启用流式输出时,依赖发送消息前事件钩子的插件可能无法正常工作 -msg-caaaec29 = hook(on_decorating_result) -> {$res} - {$res_2} 将消息结果清空。 -msg-78b9c276 = {$res} -msg-add19f94 = {$res} - {$res_2} 终止了事件传播。 -msg-813a44bb = 流式输出已启用,跳过结果装饰阶段 -msg-891aa43a = 分段回复正则表达式错误,使用默认分段方式: {$res} -msg-82bb9025 = 会话 {$res} 未配置文本转语音模型。 -msg-fb1c757a = TTS 请求: {$res} -msg-06341d25 = TTS 结果: {$audio_path} -msg-2057f670 = 由于 TTS 音频文件未找到,消息段转语音失败: {$res} -msg-f26725cf = 已注册:{$url} -msg-47716aec = TTS 失败,使用文本发送。 -msg-ffe054a9 = 文本转图片失败,使用文本发送。 -msg-06c1aedc = 文本转图片耗时超过了 3 秒,如果觉得很慢可以使用 /t2i 关闭文本转图片模式。 + +msg-7ec898fd = hook(on_decorating_result) ->{ $res }-{ $res_2 } +msg-5e27dae6 = When streaming output is enabled, plugins that rely on the pre-message-send event hook may not function correctly. +msg-caaaec29 = hook(on_decorating_result) ->{ $res }-{ $res_2 }Clear message results. +msg-78b9c276 = { $res } +msg-add19f94 = { $res }-{ $res_2 }Terminated event propagation. +msg-813a44bb = Streaming output enabled, skipping result decoration phase +msg-891aa43a = Segmented reply regular expression error, using default segmentation method:{ $res } +msg-82bb9025 = Session{ $res }No text-to-speech model is configured. +msg-fb1c757a = TTS Request:{ $res } +msg-06341d25 = TTS Result:{ $audio_path } +msg-2057f670 = Failed to convert message segment to speech due to missing TTS audio file:{ $res } +msg-f26725cf = Registered:{ $url } +msg-47716aec = TTS failed, sending as text. +msg-ffe054a9 = Text to image conversion failed, sending as text. +msg-06c1aedc = Text-to-image conversion took more than 3 seconds. If it feels slow, you can use /t2i to turn off the text-to-image mode. ### astrbot/core/pipeline/waking_check/stage.py -msg-df815938 = enabled_plugins_name: {$enabled_plugins_name} -msg-51182733 = 插件 {$res}: {$e} -msg-e0dcf0b8 = 您(ID: {$res})的权限不足以使用此指令。通过 /sid 获取 ID 并请管理员添加。 -msg-a3c3706f = 触发 {$res} 时, 用户(ID={$res_2}) 权限不足。 + +msg-df815938 = enabled_plugins_name:{ $enabled_plugins_name } +msg-51182733 = Plugin{ $res }Text to be translated:{ $e } +msg-e0dcf0b8 = You (ID:{ $res }You do not have sufficient permissions to use this command. Obtain your ID via /sid and ask an administrator to add it. +msg-a3c3706f = Trigger{ $res }When, user(ID={ $res_2 }Insufficient permissions. ### astrbot/core/pipeline/session_status_check/stage.py -msg-f9aba737 = 会话 {$res} 已被关闭,已终止事件传播。 + +msg-f9aba737 = Session{ $res }Closed, event propagation terminated. ### astrbot/core/pipeline/respond/stage.py -msg-59539c6e = 解析分段回复的间隔时间失败。{$e} -msg-4ddee754 = 分段回复间隔时间:{$res} -msg-5e2371a9 = Prepare to send - {$res}/{$res_2}: {$res_3} -msg-df92ac24 = async_stream 为空,跳过发送。 -msg-858b0e4f = 应用流式输出({$res}) -msg-22c7a672 = 消息为空,跳过发送阶段 -msg-e6ab7a25 = 空内容检查异常: {$e} -msg-b29b99c1 = 实际消息链为空, 跳过发送阶段。header_chain: {$header_comps}, actual_chain: {$res} -msg-842df577 = 发送消息链失败: chain = {$res}, error = {$e} -msg-f35465cf = 消息链全为 Reply 和 At 消息段, 跳过发送阶段。chain: {$res} -msg-784e8a67 = 发送消息链失败: chain = {$chain}, error = {$e} + +msg-59539c6e = Failed to parse the interval time for segmented responses.{ $e } +msg-4ddee754 = Segment response interval:{ $res } +msg-5e2371a9 = Prepare to send -{ $res }Text to be translated:{ $res_2 }Text to translate:{ $res_3 } +msg-df92ac24 = async_stream is empty, skip sending. +msg-858b0e4f = Application streaming output({ $res }Text to be translated: ) +msg-22c7a672 = Message is empty, skipping sending phase. +msg-e6ab7a25 = Empty content check exception:{ $e } +msg-b29b99c1 = The actual message chain is empty, skipping the send phase. header_chain:{ $header_comps }, actual_chain:{ $res } +msg-842df577 = Failed to send message chain: chain ={ $res }, error ={ $e } +msg-f35465cf = The message chain consists entirely of Reply and At message segments, skipping the sending stage. chain:{ $res } +msg-784e8a67 = Failed to send message chain: chain ={ $chain }, error ={ $e } ### astrbot/core/pipeline/content_safety_check/stage.py -msg-c733275f = 你的消息或者大模型的响应中包含不适当的内容,已被屏蔽。 -msg-46c80f28 = 内容安全检查不通过,原因:{$info} + +msg-c733275f = Your message or the AI's response contains inappropriate content and has been blocked. +msg-46c80f28 = Content security check failed, reason:{ $info } ### astrbot/core/pipeline/content_safety_check/strategies/strategy.py -msg-27a700e0 = 使用百度内容审核应该先 pip install baidu-aip + +msg-27a700e0 = To use Baidu content moderation, you should first pip install baidu-aip. ### astrbot/core/pipeline/preprocess_stage/stage.py -msg-7b9074fa = {$platform} 预回应表情发送失败: {$e} -msg-43f1b4ed = 路径映射: {$url} -> {$res} -msg-9549187d = 会话 {$res} 未配置语音转文本模型。 -msg-5bdf8f5c = {$e} -msg-ad90e19e = 重试中: {$res}/{$retry} -msg-78b9c276 = {$res} -msg-4f3245bf = 语音转文本失败: {$e} + +msg-7b9074fa = { $platform }Pre-response emoji sending failed:{ $e } +msg-43f1b4ed = Path mapping:{ $url }->{ $res } +msg-9549187d = Session{ $res }Speech-to-text model not configured. +msg-5bdf8f5c = { $e } +msg-ad90e19e = Retrying:{ $res }Text to translate:{ $retry } +msg-78b9c276 = { $res } +msg-4f3245bf = Speech to text failed:{ $e } ### astrbot/core/config/astrbot_config.py -msg-e0a69978 = 不受支持的配置类型 {$res}。支持的类型有:{$res_2} -msg-b9583fc9 = 检查到配置项 {$path_} 不存在,已插入默认值 {$value} -msg-ee26e40e = 检查到配置项 {$path_} 不存在,将从当前配置中删除 -msg-2d7497a5 = 检查到配置项 {$path} 的子项顺序不一致,已重新排序 -msg-5fdad937 = 检查到配置项顺序不一致,已重新排序 -msg-555373b0 = 没有找到 Key: '{$key}' + +msg-e0a69978 = Unsupported configuration type{ $res }Supported types include:{ $res_2 } +msg-b9583fc9 = Configuration item detected{ $path_ }Not exist, default value inserted{ $value } +msg-ee26e40e = Configuration item detected{ $path_ }Does not exist, will be deleted from current configuration +msg-2d7497a5 = Configuration item detected{ $path }The order of sub-items is inconsistent and has been reordered. +msg-5fdad937 = Configuration item order inconsistency detected, order has been reset. +msg-555373b0 = Key not found: '{ $key }Text to be translated: ### astrbot/core/platform/register.py -msg-eecf0aa8 = 平台适配器 {$adapter_name} 已经注册过了,可能发生了适配器命名冲突。 -msg-614a55eb = 平台适配器 {$adapter_name} 已注册 -msg-bb06a88d = 平台适配器 {$res} 已注销 (来自模块 {$res_2}) + +msg-eecf0aa8 = Platform adapter{ $adapter_name }Already registered, possible adapter naming conflict. +msg-614a55eb = Platform Adapter{ $adapter_name }Registered +msg-bb06a88d = Platform Adapter{ $res }已注销 (来自模块{ $res_2 }) ### astrbot/core/platform/platform.py -msg-30fc9871 = 平台 {$res} 未实现统一 Webhook 模式 + +msg-30fc9871 = Platform{ $res }Unified Webhook mode not implemented ### astrbot/core/platform/astr_message_event.py -msg-b593f13f = Failed to convert message type {$res} to MessageType. Falling back to FRIEND_MESSAGE. -msg-98bb33b7 = 清除 {$res} 的额外信息: {$res_2} -msg-0def44e2 = {$result} -msg-8e7dc862 = {$text} + +msg-b593f13f = Failed to convert message type{ $res }to MessageType. Falling back to FRIEND_MESSAGE. +msg-98bb33b7 = Clear{ $res }Additional information:{ $res_2 } +msg-0def44e2 = { $result } +msg-8e7dc862 = { $text } ### astrbot/core/platform/manager.py -msg-464b7ab7 = 终止平台适配器失败: client_id=%s, error=%s -msg-78b9c276 = {$res} -msg-563a0a74 = 初始化 {$platform} 平台适配器失败: {$e} -msg-8432d24e = 平台 ID %r 包含非法字符 ':' 或 '!',已替换为 %r。 -msg-31361418 = 平台 ID {$platform_id} 不能为空,跳过加载该平台适配器。 -msg-e395bbcc = 载入 {$res}({$res_2}) 平台适配器 ... -msg-b4b29344 = 加载平台适配器 {$res} 失败,原因:{$e}。请检查依赖库是否安装。提示:可以在 管理面板->平台日志->安装Pip库 中安装依赖库。 -msg-18f0e1fe = 加载平台适配器 {$res} 失败,原因:{$e}。 -msg-2636a882 = 未找到适用于 {$res}({$res_2}) 平台适配器,请检查是否已经安装或者名称填写错误 -msg-c4a38b85 = hook(on_platform_loaded) -> {$res} - {$res_2} -msg-967606fd = ------- 任务 {$res} 发生错误: {$e} -msg-a2cd77f3 = | {$line} -msg-1f686eeb = ------- -msg-38723ea8 = 正在尝试终止 {$platform_id} 平台适配器 ... -msg-63f684c6 = 可能未完全移除 {$platform_id} 平台适配器 -msg-136a952f = 获取平台统计信息失败: {$e} + +msg-464b7ab7 = Failed to terminate platform adapter: client_id=%s, error=%s +msg-78b9c276 = { $res } +msg-563a0a74 = Initialization{ $platform }Platform adapter failed:{ $e } +msg-8432d24e = Platform ID %r contains illegal characters ':' or '!', replaced with %r. +msg-31361418 = Platform ID{ $platform_id }Cannot be empty, skip loading this platform adapter. +msg-e395bbcc = Loading{ $res }({ $res_2 }) Platform adapter ... +msg-b4b29344 = Loading platform adapters{ $res }Failed, reason:{ $e }Please check if the dependency library is installed. Tip: You can install dependency libraries in Admin Panel -> Platform Logs -> Install Pip Libraries. +msg-18f0e1fe = Loading platform adapter{ $res }Failed, reason:{ $e }. +msg-2636a882 = No applicable{ $res }Text to translate: ({ $res_2 }) Platform adapter, please check if it has been installed or the name is filled in incorrectly. +msg-c4a38b85 = hook(on_platform_loaded) ->{ $res }-{ $res_2 } +msg-967606fd = Task{ $res }An error has occurred:{ $e } +msg-a2cd77f3 = |{ $line } +msg-1f686eeb = Text to be translated: ------- +msg-38723ea8 = Attempting to terminate{ $platform_id }Platform adapter ... +msg-63f684c6 = Possibly not completely removed{ $platform_id }Platform Adapter +msg-136a952f = Failed to retrieve platform statistics:{ $e } ### astrbot/core/platform/sources/dingtalk/dingtalk_adapter.py + msg-c81e728d = 2 -msg-d6371313 = dingtalk: {$res} -msg-a1c8b5b1 = 钉钉私聊会话缺少 staff_id 映射,回退使用 session_id 作为 userId 发送 -msg-2abb842f = 保存钉钉会话映射失败: {$e} -msg-46988861 = 下载钉钉文件失败: {$res}, {$res_2} -msg-ba9e1288 = 通过 dingtalk_stream 获取 access_token 失败: {$e} -msg-835b1ce6 = 获取钉钉机器人 access_token 失败: {$res}, {$res_2} -msg-331fcb1f = 读取钉钉 staff_id 映射失败: {$e} -msg-ba183a34 = 钉钉群消息发送失败: access_token 为空 -msg-b8aaa69b = 钉钉群消息发送失败: {$res}, {$res_2} -msg-cfb35bf5 = 钉钉私聊消息发送失败: access_token 为空 -msg-7553c219 = 钉钉私聊消息发送失败: {$res}, {$res_2} -msg-5ab2d58d = 清理临时文件失败: {$file_path}, {$e} -msg-c0c40912 = 钉钉语音转 OGG 失败,回退 AMR: {$e} -msg-21c73eca = 钉钉媒体上传失败: access_token 为空 -msg-24e3054f = 钉钉媒体上传失败: {$res}, {$res_2} -msg-34d0a11d = 钉钉媒体上传失败: {$data} -msg-3b0d4fb5 = 钉钉语音发送失败: {$e} -msg-7187f424 = 钉钉视频发送失败: {$e} -msg-e40cc45f = 钉钉私聊回复失败: 缺少 sender_staff_id -msg-be63618a = 钉钉适配器已被关闭 -msg-0ab22b13 = 钉钉机器人启动失败: {$e} +msg-d6371313 = dingtalk:{ $res } +msg-a1c8b5b1 = DingTalk private chat session lacks staff_id mapping, falling back to using session_id as userId for sending. +msg-2abb842f = Failed to save DingTalk conversation mapping:{ $e } +msg-46988861 = Failed to download DingTalk file:{ $res }待翻译文本:,{ $res_2 } +msg-ba9e1288 = Failed to obtain access_token via dingtalk_stream:{ $e } +msg-835b1ce6 = Failed to get DingTalk robot access token:{ $res }{ $res_2 } +msg-331fcb1f = Failed to read DingTalk staff_id mapping:{ $e } +msg-ba183a34 = DingTalk group message sending failed: access_token is empty +msg-b8aaa69b = Failed to send DingTalk group message:{ $res },{ $res_2 } +msg-cfb35bf5 = DingTalk private message sending failed: access_token is empty +msg-7553c219 = DingTalk private chat message sending failed:{ $res }{ $res_2 } +msg-5ab2d58d = Failed to clean up temporary files:{ $file_path },{ $e } +msg-c0c40912 = DingTalk voice conversion to OGG failed, fallback to AMR:{ $e } +msg-21c73eca = DingTalk media upload failed: access_token is empty +msg-24e3054f = DingTalk media upload failed:{ $res },{ $res_2 } +msg-34d0a11d = DingTalk media upload failed:{ $data } +msg-3b0d4fb5 = DingTalk voice message sending failed:{ $e } +msg-7187f424 = DingTalk video sending failed:{ $e } +msg-e40cc45f = DingTalk private chat reply failed: missing sender_staff_id +msg-be63618a = DingTalk adapter has been disabled. +msg-0ab22b13 = DingTalk robot startup failed:{ $e } ### astrbot/core/platform/sources/dingtalk/dingtalk_event.py -msg-eaa1f3e4 = 钉钉消息发送失败: 缺少 adapter + +msg-eaa1f3e4 = DingTalk message sending failed: adapter missing ### astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_server.py -msg-41a3e59d = 正在登录到 QQ 官方机器人... -msg-66040e15 = 已登录 QQ 官方机器人账号: {$res} -msg-6ed59b60 = 收到 qq_official_webhook 回调: {$msg} -msg-ad355b59 = {$signed} + +msg-41a3e59d = Logging in to QQ Official Bot... +msg-66040e15 = Logged into the official QQ bot account:{ $res } +msg-6ed59b60 = Received qq_official_webhook callback:{ $msg } +msg-ad355b59 = { $signed } msg-1f6260e4 = _parser unknown event %s. -msg-cef08b17 = 将在 {$res}:{$res_2} 端口启动 QQ 官方机器人 webhook 适配器。 +msg-cef08b17 = Will be{ $res }Text to be translated:{ $res_2 }Port starts QQ official bot webhook adapter. ### astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_adapter.py + msg-3803e307 = [QQOfficialWebhook] No cached msg_id for session: %s, skip send_by_session msg-08fd28cf = [QQOfficialWebhook] Unsupported message type for send_by_session: %s -msg-6fa95bb3 = Exception occurred during QQOfficialWebhook server shutdown: {$exc} -msg-6f83eea0 = QQ 机器人官方 API 适配器已经被优雅地关闭 +msg-6fa95bb3 = Exception occurred during QQOfficialWebhook server shutdown:{ $exc } +msg-6f83eea0 = QQ bot official API adapter has been gracefully shut down ### astrbot/core/platform/sources/discord/discord_platform_event.py -msg-0056366b = [Discord] 解析消息链时失败: {$e} -msg-fa0a9e40 = [Discord] 尝试发送空消息,已忽略。 -msg-5ccebf9a = [Discord] 频道 {$res} 不是可发送消息的类型 -msg-1550c1eb = [Discord] 发送消息时发生未知错误: {$e} -msg-7857133d = [Discord] 无法获取频道 {$res} -msg-050aa8d6 = [Discord] 开始处理 Image 组件: {$i} -msg-57c802ef = [Discord] Image 组件没有 file 属性: {$i} -msg-f2bea7ac = [Discord] 处理 URL 图片: {$file_content} -msg-c3eae1f1 = [Discord] 处理 File URI: {$file_content} -msg-6201da92 = [Discord] 图片文件不存在: {$path} -msg-2a6f0cd4 = [Discord] 处理 Base64 URI -msg-b589c643 = [Discord] 尝试作为裸 Base64 处理 -msg-41dd4b8f = [Discord] 裸 Base64 解码失败,作为本地路径处理: {$file_content} -msg-f59778a1 = [Discord] 处理图片时发生未知严重错误: {$file_info} -msg-85665612 = [Discord] 获取文件失败,路径不存在: {$file_path_str} -msg-e55956fb = [Discord] 获取文件失败: {$res} -msg-56cc0d48 = [Discord] 处理文件失败: {$res}, 错误: {$e} -msg-c0705d4e = [Discord] 忽略了不支持的消息组件: {$res} -msg-0417d127 = [Discord] 消息内容超过2000字符,将被截断。 -msg-6277510f = [Discord] 添加反应失败: {$e} + +msg-0056366b = [Discord] Failed to parse message chain:{ $e } +msg-fa0a9e40 = [Discord] Attempted to send an empty message, ignored. +msg-5ccebf9a = [Discord] Channel{ $res }Not a type of message that can be sent +msg-1550c1eb = [Discord] An unknown error occurred while sending the message:{ $e } +msg-7857133d = [Discord] Failed to retrieve channel{ $res } +msg-050aa8d6 = [Discord] Start processing Image component:{ $i } +msg-57c802ef = [Discord] Image component does not have a file attribute:{ $i } +msg-f2bea7ac = [Discord] Processing URL image:{ $file_content } +msg-c3eae1f1 = [Discord] Processing File URI:{ $file_content } +msg-6201da92 = [Discord] Image file does not exist:{ $path } +msg-2a6f0cd4 = [Discord] Processing Base64 URI +msg-b589c643 = [Discord] Attempt to process as raw Base64 +msg-41dd4b8f = [Discord] Raw Base64 decoding failed, treating as local path:{ $file_content } +msg-f59778a1 = [Discord] An unknown critical error occurred while processing the image:{ $file_info } +msg-85665612 = [Discord] Failed to retrieve file, path does not exist:{ $file_path_str } +msg-e55956fb = [Discord] Failed to fetch file:{ $res } +msg-56cc0d48 = [Discord] Failed to process file:{ $res }, Error:{ $e } +msg-c0705d4e = [Discord] Ignored unsupported message component:{ $res } +msg-0417d127 = [Discord] Message content exceeds 2000 characters and will be truncated. +msg-6277510f = [Discord] Failed to add reaction:{ $e } ### astrbot/core/platform/sources/discord/client.py -msg-940888cb = [Discord] 客户端未正确加载用户信息 (self.user is None) -msg-9a3c1925 = [Discord] 已作为 {$res} (ID: {$res_2}) 登录 -msg-30c1f1c8 = [Discord] 客户端已准备就绪。 -msg-d8c03bdf = [Discord] on_ready_once_callback 执行失败: {$e} + +msg-940888cb = [Discord] Client failed to load user information properly (self.user is None) +msg-9a3c1925 = [Discord] has been added as{ $res }(ID:{ $res_2 }) Sign in +msg-30c1f1c8 = [Discord] Client is ready. +msg-d8c03bdf = [Discord] on_ready_once_callback execution failed:{ $e } msg-c9601653 = Bot is not ready: self.user is None msg-4b017a7c = Interaction received without a valid user -msg-3067bdce = [Discord] 收到原始消息 from {$res}: {$res_2} +msg-3067bdce = [Discord] Received original message from{ $res }Text to be translated:{ $res_2 } ### astrbot/core/platform/sources/discord/discord_platform_adapter.py -msg-7ea23347 = [Discord] 客户端未就绪 (self.client.user is None),无法发送消息 -msg-ff6611ce = [Discord] Invalid channel ID format: {$channel_id_str} -msg-5e4e5d63 = [Discord] Can't get channel info for {$channel_id_str}, will guess message type. -msg-32d4751b = [Discord] 收到消息: {$message_data} -msg-8296c994 = [Discord] Bot Token 未配置。请在配置文件中正确设置 token。 -msg-170b31df = [Discord] 登录失败。请检查你的 Bot Token 是否正确。 -msg-6678fbd3 = [Discord] 与 Discord 的连接已关闭。 -msg-cd8c35d2 = [Discord] 适配器运行时发生意外错误: {$e} -msg-4df30f1d = [Discord] 客户端未就绪 (self.client.user is None),无法处理消息 -msg-f7803502 = [Discord] 收到非 Message 类型的消息: {$res},已忽略。 -msg-134e70e9 = [Discord] 正在终止适配器... (step 1: cancel polling task) -msg-5c01a092 = [Discord] polling_task 已取消。 -msg-77f8ca59 = [Discord] polling_task 取消异常: {$e} -msg-528b6618 = [Discord] 正在清理已注册的斜杠指令... (step 2) -msg-d0b832e6 = [Discord] 指令清理完成。 -msg-43383f5e = [Discord] 清理指令时发生错误: {$e} -msg-b960ed33 = [Discord] 正在关闭 Discord 客户端... (step 3) -msg-5e58f8a2 = [Discord] 客户端关闭异常: {$e} -msg-d1271bf1 = [Discord] 适配器已终止。 -msg-c374da7a = [Discord] 开始收集并注册斜杠指令... -msg-a6d37e4d = [Discord] 准备同步 {$res} 个指令: {$res_2} -msg-dbcaf095 = [Discord] 没有发现可注册的指令。 -msg-09209f2f = [Discord] 指令同步完成。 -msg-a95055fd = [Discord] 回调函数触发: {$cmd_name} -msg-55b13b1e = [Discord] 回调函数参数: {$ctx} -msg-79f72e4e = [Discord] 回调函数参数: {$params} -msg-22add467 = [Discord] 斜杠指令 '{$cmd_name}' 被触发。 原始参数: '{$params}'. 构建的指令字符串: '{$message_str_for_filter}' -msg-ccffc74a = [Discord] 指令 '{$cmd_name}' defer 失败: {$e} -msg-13402a28 = [Discord] 跳过不符合规范的指令: {$cmd_name} + +msg-7ea23347 = [Discord] Client not ready (self.client.user is None), cannot send message +msg-ff6611ce = [Discord] Invalid channel ID format:{ $channel_id_str } +msg-5e4e5d63 = [Discord] Can't get channel info for{ $channel_id_str }, will guess message type. +msg-32d4751b = [Discord] Received message:{ $message_data } +msg-8296c994 = [Discord] Bot Token is not configured. Please set the token correctly in the configuration file. +msg-170b31df = [Discord] Login failed. Please check if your Bot Token is correct. +msg-6678fbd3 = [Discord] Connection to Discord has been closed. +msg-cd8c35d2 = [Discord] An unexpected error occurred in the adapter runtime:{ $e } +msg-4df30f1d = [Discord] Client not ready (self.client.user is None), unable to process messages +msg-f7803502 = [Discord] Received a non-Message type message:{ $res }, ignored. +msg-134e70e9 = [Discord] Terminating adapter... (step 1: cancel polling task) +msg-5c01a092 = [Discord] polling_task has been canceled. +msg-77f8ca59 = [Discord] polling_task cancellation exception:{ $e } +msg-528b6618 = [Discord] Cleaning up registered slash commands... (step 2) +msg-d0b832e6 = [Discord] Command cleanup completed. +msg-43383f5e = [Discord] An error occurred while clearing commands:{ $e } +msg-b960ed33 = [Discord] Shutting down Discord client... (step 3) +msg-5e58f8a2 = [Discord] Client closed abnormally:{ $e } +msg-d1271bf1 = [Discord] Adapter has terminated. +msg-c374da7a = [Discord] Starting to collect and register slash commands... +msg-a6d37e4d = [Discord] Preparing to sync{ $res }commands:{ $res_2 } +msg-dbcaf095 = [Discord] No registerable commands found. +msg-09209f2f = [Discord] Command synchronization completed. +msg-a95055fd = [Discord] Callback function triggered:{ $cmd_name } +msg-55b13b1e = [Discord] Callback function parameters:{ $ctx } +msg-79f72e4e = [Discord] Callback function parameters:{ $params } +msg-22add467 = [Discord] Slash command '{ $cmd_name }Triggered. Original parameters:{ $params }'. Built command string: '{ $message_str_for_filter }Text to be translated: +msg-ccffc74a = [Discord] Command '{ $cmd_name }defer failed:{ $e } +msg-13402a28 = [Discord] Skipping non-compliant commands:{ $cmd_name } ### astrbot/core/platform/sources/aiocqhttp/aiocqhttp_platform_adapter.py -msg-859d480d = Handle request message failed: {$e} -msg-6fb672e1 = Handle notice message failed: {$e} -msg-cf4687a3 = Handle group message failed: {$e} -msg-3a9853e3 = Handle private message failed: {$e} -msg-ec06dc3d = aiocqhttp(OneBot v11) 适配器已连接。 -msg-1304a54d = [aiocqhttp] RawMessage {$event} -msg-93cbb9fa = {$err} -msg-a4487a03 = 回复消息失败: {$e} + +msg-859d480d = Handle request message failed:{ $e } +msg-6fb672e1 = Failed to handle notification message:{ $e } +msg-cf4687a3 = Handle group message failed:{ $e } +msg-3a9853e3 = Handle private message failed:{ $e } +msg-ec06dc3d = aiocqhttp (OneBot v11) adapter is connected. +msg-1304a54d = [aiocqhttp] RawMessage{ $event } +msg-93cbb9fa = { $err } +msg-a4487a03 = Failed to reply to the message:{ $e } msg-48bc7bff = guessing lagrange -msg-6ab145a1 = 获取文件失败: {$ret} -msg-457454d7 = 获取文件失败: {$e},此消息段将被忽略。 -msg-7a299806 = 无法从回复消息数据构造 Event 对象: {$reply_event_data} -msg-e6633a51 = 获取引用消息失败: {$e}。 -msg-6e99cb8d = 获取 @ 用户信息失败: {$e},此消息段将被忽略。 -msg-cf15fd40 = 不支持的消息段类型,已忽略: {$t}, data={$res} -msg-45d126ad = 消息段解析失败: type={$t}, data={$res}. {$e} +msg-6ab145a1 = Failed to get file:{ $ret } +msg-457454d7 = Failed to retrieve file:{ $e }This message segment will be ignored. +msg-7a299806 = Unable to construct Event object from reply message data:{ $reply_event_data } +msg-e6633a51 = Failed to get referenced message:{ $e }. +msg-6e99cb8d = Failed to get user information:{ $e }This message segment will be ignored. +msg-cf15fd40 = Unsupported message segment type, ignored:{ $t }, data={ $res } +msg-45d126ad = Message segment parsing failed: type={ $t }, data={ $res }.{ $e } msg-394a20ae = aiocqhttp: 未配置 ws_reverse_host 或 ws_reverse_port,将使用默认值:http://0.0.0.0:6199 -msg-7414707c = aiocqhttp 适配器已被关闭 +msg-7414707c = The aiocqhttp adapter has been shut down. ### astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py -msg-0db8227d = 无法发送消息:缺少有效的数字 session_id({$session_id}) 或 event({$event}) + +msg-0db8227d = Unable to send message: Missing valid numeric session_id{ $session_id }) or event({ $event }待翻译文本: ### astrbot/core/platform/sources/lark/server.py -msg-2f3bccf1 = 未配置 encrypt_key,无法解密事件 -msg-e77104e2 = [Lark Webhook] 收到 challenge 验证请求: {$challenge} -msg-34b24fa1 = [Lark Webhook] 解析请求体失败: {$e} -msg-ec0fe13e = [Lark Webhook] 请求体为空 -msg-f69ebbdb = [Lark Webhook] 签名验证失败 -msg-7ece4036 = [Lark Webhook] 解密后的事件: {$event_data} -msg-f2cb4b46 = [Lark Webhook] 解密事件失败: {$e} -msg-ef9f8906 = [Lark Webhook] Verification Token 不匹配。 -msg-bedb2071 = [Lark Webhook] 处理事件回调失败: {$e} + +msg-2f3bccf1 = encrypt_key is not configured, unable to decrypt event +msg-e77104e2 = [Lark Webhook] Received challenge verification request:{ $challenge } +msg-34b24fa1 = [Lark Webhook] Failed to parse request body:{ $e } +msg-ec0fe13e = [Lark Webhook] The request body is empty +msg-f69ebbdb = [Lark Webhook] Signature verification failed +msg-7ece4036 = [Lark Webhook] Decrypted event:{ $event_data } +msg-f2cb4b46 = [Lark Webhook] Decrypt event failed:{ $e } +msg-ef9f8906 = [Lark Webhook] Verification Token does not match. +msg-bedb2071 = [Lark Webhook] Failed to process event callback:{ $e } ### astrbot/core/platform/sources/lark/lark_event.py -msg-eefbe737 = [Lark] API Client im 模块未初始化 -msg-a21f93fa = [Lark] 主动发送消息时,receive_id 和 receive_id_type 不能为空 -msg-f456e468 = [Lark] 发送飞书消息失败({$res}): {$res_2} -msg-1eb66d14 = [Lark] 文件不存在: {$path} -msg-1df39b24 = [Lark] API Client im 模块未初始化,无法上传文件 -msg-2ee721dd = [Lark] 无法上传文件({$res}): {$res_2} -msg-a04abf78 = [Lark] 上传文件成功但未返回数据(data is None) -msg-959e78a4 = [Lark] 文件上传成功: {$file_key} -msg-901a2f60 = [Lark] 无法打开或上传文件: {$e} -msg-13065327 = [Lark] 图片路径为空,无法上传 -msg-37245892 = [Lark] 无法打开图片文件: {$e} -msg-ad63bf53 = [Lark] API Client im 模块未初始化,无法上传图片 -msg-ef90038b = 无法上传飞书图片({$res}): {$res_2} -msg-d2065832 = [Lark] 上传图片成功但未返回数据(data is None) -msg-dbb635c2 = {$image_key} -msg-d4810504 = [Lark] 检测到文件组件,将单独发送 -msg-45556717 = [Lark] 检测到音频组件,将单独发送 -msg-959070b5 = [Lark] 检测到视频组件,将单独发送 -msg-4e2aa152 = 飞书 暂时不支持消息段: {$res} -msg-20d7c64b = [Lark] 无法获取音频文件路径: {$e} -msg-2f6f35e6 = [Lark] 音频文件不存在: {$original_audio_path} -msg-528b968d = [Lark] 音频格式转换失败,将尝试直接上传: {$e} -msg-fbc7efb9 = [Lark] 已删除转换后的音频文件: {$converted_audio_path} -msg-09840299 = [Lark] 删除转换后的音频文件失败: {$e} -msg-e073ff1c = [Lark] 无法获取视频文件路径: {$e} -msg-47e52913 = [Lark] 视频文件不存在: {$original_video_path} -msg-85ded1eb = [Lark] 视频格式转换失败,将尝试直接上传: {$e} -msg-b3bee05d = [Lark] 已删除转换后的视频文件: {$converted_video_path} -msg-775153f6 = [Lark] 删除转换后的视频文件失败: {$e} -msg-45038ba7 = [Lark] API Client im 模块未初始化,无法发送表情 -msg-8d475b01 = 发送飞书表情回应失败({$res}): {$res_2} + +msg-eefbe737 = [Lark] API Client im module not initialized +msg-a21f93fa = [Lark] When sending a message proactively, receive_id and receive_id_type cannot be empty. +msg-f456e468 = [Lark] Failed to send Lark message({ $res }):{ $res_2 } +msg-1eb66d14 = [Lark] File does not exist:{ $path } +msg-1df39b24 = [Lark] API Client IM module not initialized, unable to upload file +msg-2ee721dd = [Lark] Failed to upload file({ $res }):{ $res_2 } +msg-a04abf78 = [Lark] File uploaded successfully but no data returned (data is None) +msg-959e78a4 = [Lark] File upload successful:{ $file_key } +msg-901a2f60 = [Lark] Unable to open or upload file:{ $e } +msg-13065327 = [Lark] The image path is empty, unable to upload. +msg-37245892 = [Lark] Unable to open image file:{ $e } +msg-ad63bf53 = [Lark] API Client im module is not initialized, unable to upload image. +msg-ef90038b = Unable to upload Feishu images({ $res }):{ $res_2 } +msg-d2065832 = [Lark] Image uploaded successfully but no data returned (data is None) +msg-dbb635c2 = { $image_key } +msg-d4810504 = [Lark] File components detected, will be sent separately. +msg-45556717 = [Lark] Audio component detected, will send separately +msg-959070b5 = [Lark] Video component detected, will be sent separately. +msg-4e2aa152 = Feishu currently does not support message segments:{ $res } +msg-20d7c64b = [Lark] Failed to retrieve audio file path:{ $e } +msg-2f6f35e6 = [Lark] Audio file does not exist:{ $original_audio_path } +msg-528b968d = [Lark] Audio format conversion failed, will attempt direct upload:{ $e } +msg-fbc7efb9 = [Lark] Deleted converted audio file:{ $converted_audio_path } +msg-09840299 = [Lark] Failed to delete the converted audio file:{ $e } +msg-e073ff1c = [Lark] Unable to get video file path:{ $e } +msg-47e52913 = [Lark] The video file does not exist:{ $original_video_path } +msg-85ded1eb = [Lark] Video format conversion failed, will attempt direct upload:{ $e } +msg-b3bee05d = [Lark] Deleted converted video file:{ $converted_video_path } +msg-775153f6 = [Lark] Failed to delete the converted video file:{ $e } +msg-45038ba7 = [Lark] API Client im module not initialized, unable to send emoji +msg-8d475b01 = Failed to send Lark emoji reaction{ $res }):{ $res_2 } ### astrbot/core/platform/sources/lark/lark_adapter.py -msg-06ce76eb = 未设置飞书机器人名称,@ 机器人可能得不到回复。 -msg-eefbe737 = [Lark] API Client im 模块未初始化 -msg-236bcaad = [Lark] 下载消息资源失败 type={$resource_type}, key={$file_key}, code={$res}, msg={$res_2} -msg-ef9a61fe = [Lark] 消息资源响应中不包含文件流: {$file_key} -msg-7b69a8d4 = [Lark] 图片消息缺少 message_id -msg-59f1694d = [Lark] 富文本视频消息缺少 message_id -msg-af8f391d = [Lark] 文件消息缺少 message_id -msg-d4080b76 = [Lark] 文件消息缺少 file_key -msg-ab21318a = [Lark] 音频消息缺少 message_id -msg-9ec2c30a = [Lark] 音频消息缺少 file_key -msg-0fa9ed18 = [Lark] 视频消息缺少 message_id -msg-ae884c5c = [Lark] 视频消息缺少 file_key -msg-dac98a62 = [Lark] 获取引用消息失败 id={$parent_message_id}, code={$res}, msg={$res_2} -msg-7ee9f7dc = [Lark] 引用消息响应为空 id={$parent_message_id} -msg-2b3b2db9 = [Lark] 解析引用消息内容失败 id={$quoted_message_id} -msg-c5d54255 = [Lark] 收到空事件(event.event is None) -msg-82f041c4 = [Lark] 事件中没有消息体(message is None) -msg-206c3506 = [Lark] 消息内容为空 -msg-876aa1d2 = [Lark] 解析消息内容失败: {$res} -msg-514230f3 = [Lark] 消息内容不是 JSON Object: {$res} -msg-0898cf8b = [Lark] 解析消息内容: {$content_json_b} -msg-6a8bc661 = [Lark] 消息缺少 message_id -msg-26554571 = [Lark] 消息发送者信息不完整 -msg-007d863a = [Lark Webhook] 跳过重复事件: {$event_id} -msg-6ce17e71 = [Lark Webhook] 未处理的事件类型: {$event_type} -msg-8689a644 = [Lark Webhook] 处理事件失败: {$e} -msg-20688453 = [Lark] Webhook 模式已启用,但 webhook_server 未初始化 -msg-f46171bc = [Lark] Webhook 模式已启用,但未配置 webhook_uuid -msg-dd90a367 = 飞书(Lark) 适配器已关闭 + +msg-06ce76eb = No Feishu bot name set, @ bot may not get a reply. +msg-eefbe737 = [Lark] API Client im module not initialized +msg-236bcaad = [Lark] Failed to download message resource type={ $resource_type }, key={ $file_key }, code={ $res }, msg={ $res_2 } +msg-ef9a61fe = [Lark] No file stream included in the message resource response:{ $file_key } +msg-7b69a8d4 = [Lark] Image message missing message_id +msg-59f1694d = [Lark] Rich text video message is missing message_id +msg-af8f391d = [Lark] The file message is missing a message_id +msg-d4080b76 = [Lark] File message is missing file_key +msg-ab21318a = [Lark] Audio message is missing message_id +msg-9ec2c30a = [Lark] Audio message missing file_key +msg-0fa9ed18 = [Lark] Video message is missing message_id +msg-ae884c5c = [Lark] Video message missing file_key +msg-dac98a62 = [Lark] Failed to fetch quoted message id={ $parent_message_id }, code={ $res }, msg={ $res_2 } +msg-7ee9f7dc = [Lark] Quoted message response is empty id={ $parent_message_id } +msg-2b3b2db9 = [Lark] Failed to parse referenced message content id={ $quoted_message_id } +msg-c5d54255 = [Lark] Received empty event (event.event is None) +msg-82f041c4 = [Lark] No message body in the event (message is None) +msg-206c3506 = [Lark] The message content is empty +msg-876aa1d2 = [Lark] Failed to parse message content:{ $res } +msg-514230f3 = [Lark] The message content is not a JSON Object:{ $res } +msg-0898cf8b = [Lark] Parsing message content:{ $content_json_b } +msg-6a8bc661 = [Lark] Message missing message_id +msg-26554571 = [Lark] Incomplete sender information +msg-007d863a = [Lark Webhook] Skipped duplicate event:{ $event_id } +msg-6ce17e71 = [Lark Webhook] Unhandled event type:{ $event_type } +msg-8689a644 = [Lark Webhook] Failed to process event:{ $e } +msg-20688453 = [Lark] Webhook mode is enabled, but webhook_server is not initialized. +msg-f46171bc = [Lark] Webhook mode is enabled, but webhook_uuid is not configured. +msg-dd90a367 = Lark adapter is disabled. ### astrbot/core/platform/sources/wecom/wecom_event.py -msg-e164c137 = 未找到微信客服发送消息方法。 -msg-c114425e = 微信客服上传图片失败: {$e} -msg-a90bc15d = 微信客服上传图片返回: {$response} -msg-38298880 = 微信客服上传语音失败: {$e} -msg-3aee0caa = 微信客服上传语音返回: {$response} -msg-15e6381b = 删除临时音频文件失败: {$e} -msg-a79ae417 = 微信客服上传文件失败: {$e} -msg-374455ef = 微信客服上传文件返回: {$response} -msg-a2a133e4 = 微信客服上传视频失败: {$e} -msg-2732fffd = 微信客服上传视频返回: {$response} -msg-60815f02 = 还没实现这个消息类型的发送逻辑: {$res}。 -msg-9913aa52 = 企业微信上传图片失败: {$e} -msg-9e90ba91 = 企业微信上传图片返回: {$response} -msg-232af016 = 企业微信上传语音失败: {$e} -msg-e5b8829d = 企业微信上传语音返回: {$response} -msg-f68671d7 = 企业微信上传文件失败: {$e} -msg-8cdcc397 = 企业微信上传文件返回: {$response} -msg-4f3e15f5 = 企业微信上传视频失败: {$e} -msg-4e9aceea = 企业微信上传视频返回: {$response} + +msg-e164c137 = WeChat customer service message sending method not found. +msg-c114425e = WeChat customer service failed to upload the image:{ $e } +msg-a90bc15d = WeChat Customer Service Upload Image Return:{ $response } +msg-38298880 = WeChat customer service voice upload failed:{ $e } +msg-3aee0caa = WeChat customer service uploads voice and returns:{ $response } +msg-15e6381b = Failed to delete temporary audio file:{ $e } +msg-a79ae417 = WeChat customer service file upload failed:{ $e } +msg-374455ef = WeChat customer service file upload returns:{ $response } +msg-a2a133e4 = WeChat customer service failed to upload video:{ $e } +msg-2732fffd = WeChat customer service upload video returns:{ $response } +msg-60815f02 = Not yet implemented the sending logic for this message type:{ $res } +msg-9913aa52 = WeChat Work failed to upload the image:{ $e } +msg-9e90ba91 = WeChat Work upload image returns:{ $response } +msg-232af016 = Failed to upload voice message on WeChat Work:{ $e } +msg-e5b8829d = WeChat Work voice upload returns:{ $response } +msg-f68671d7 = Failed to upload file in WeCom:{ $e } +msg-8cdcc397 = WeChat Work upload file returns:{ $response } +msg-4f3e15f5 = Enterprise WeChat video upload failed:{ $e } +msg-4e9aceea = Enterprise WeChat upload video returns:{ $response } ### astrbot/core/platform/sources/wecom/wecom_adapter.py -msg-d4bbf9cb = 验证请求有效性: {$res} -msg-f8694a8a = 验证请求有效性成功。 -msg-8f4cda74 = 验证请求有效性失败,签名异常,请检查配置。 -msg-46d3feb9 = 解密失败,签名异常,请检查配置。 -msg-4d1dfce4 = 解析成功: {$msg} -msg-a98efa4b = 将在 {$res}:{$res_2} 端口启动 企业微信 适配器。 -msg-a616d9ce = 企业微信客服模式不支持 send_by_session 主动发送。 -msg-5d01d7b9 = send_by_session 失败:无法为会话 {$res} 推断 agent_id。 -msg-3f05613d = 获取到微信客服列表: {$acc_list} -msg-8fd19bd9 = 获取微信客服失败,open_kfid 为空。 -msg-5900d9b6 = Found open_kfid: {$open_kfid} -msg-391119b8 = 请打开以下链接,在微信扫码以获取客服微信: https://api.cl2wm.cn/api/qrcode/code?text={$kf_url} -msg-5bdf8f5c = {$e} -msg-93c9125e = 转换音频失败: {$e}。如果没有安装 ffmpeg 请先安装。 -msg-b2f7d1dc = 暂未实现的事件: {$res} -msg-61480a61 = abm: {$abm} -msg-42431e46 = 未实现的微信客服消息事件: {$msg} -msg-fbca491d = 企业微信 适配器已被关闭 + +msg-d4bbf9cb = Verify request validity:{ $res } +msg-f8694a8a = Verification of request validity successful. +msg-8f4cda74 = Verification of request validity failed, signature exception, please check configuration. +msg-46d3feb9 = Decryption failed, signature exception, please check the configuration. +msg-4d1dfce4 = Parse successful:{ $msg } +msg-a98efa4b = Will be{ $res }Text to translate:{ $res_2 }Port startup WeChat Work adapter. +msg-a616d9ce = WeChat Work customer service mode does not support sending messages actively via send_by_session. +msg-5d01d7b9 = send_by_session failed: Unable to send for session{ $res }Infer agent_id. +msg-3f05613d = Retrieved WeChat customer service list:{ $acc_list } +msg-8fd19bd9 = Failed to get WeChat customer service, open_kfid is empty. +msg-5900d9b6 = Found open_kfid:{ $open_kfid } +msg-391119b8 = Please open the following link and scan the QR code with WeChat to get the customer service WeChat account: https://api.cl2wm.cn/api/qrcode/code?text={ $kf_url } +msg-5bdf8f5c = { $e } +msg-93c9125e = Failed to convert audio:{ $e }If ffmpeg is not installed, please install it first. +msg-b2f7d1dc = Unimplemented events:{ $res } +msg-61480a61 = abm:{ $abm } +msg-42431e46 = Unimplemented WeChat customer service message event:{ $msg } +msg-fbca491d = WeChat Work Adapter has been disabled ### astrbot/core/platform/sources/weixin_official_account/weixin_offacc_event.py -msg-fa7f7afc = split plain into {$res} chunks for passive reply. Message not sent. -msg-59231e07 = 微信公众平台上传图片失败: {$e} -msg-d3968fc5 = 微信公众平台上传图片返回: {$response} -msg-7834b934 = 微信公众平台上传语音失败: {$e} -msg-4901d769 = 微信公众平台上传语音返回: {$response} -msg-15e6381b = 删除临时音频文件失败: {$e} -msg-60815f02 = 还没实现这个消息类型的发送逻辑: {$res}。 + +msg-fa7f7afc = split plain into{ $res }chunks for passive reply. Message not sent. +msg-59231e07 = WeChat Public Platform failed to upload image:{ $e } +msg-d3968fc5 = WeChat Public Platform upload image returns:{ $response } +msg-7834b934 = WeChat Official Account Platform upload voice failed:{ $e } +msg-4901d769 = WeChat Official Account Platform Upload Audio Return:{ $response } +msg-15e6381b = Failed to delete temporary audio file:{ $e } +msg-60815f02 = The sending logic for this message type has not been implemented yet:{ $res } ### astrbot/core/platform/sources/weixin_official_account/weixin_offacc_adapter.py -msg-d4bbf9cb = 验证请求有效性: {$res} -msg-b2edb1b2 = 未知的响应,请检查回调地址是否填写正确。 -msg-f8694a8a = 验证请求有效性成功。 -msg-8f4cda74 = 验证请求有效性失败,签名异常,请检查配置。 -msg-46d3feb9 = 解密失败,签名异常,请检查配置。 -msg-e23d8bff = 解析失败。msg为None。 -msg-4d1dfce4 = 解析成功: {$msg} -msg-193d9d7a = 用户消息缓冲状态: user={$from_user} state={$state} -msg-57a3c1b2 = wx buffer hit on trigger: user={$from_user} -msg-bed995d9 = wx buffer hit on retry window: user={$from_user} -msg-3a94b6ab = wx finished message sending in passive window: user={$from_user} msg_id={$msg_id} -msg-50c4b253 = wx finished message sending in passive window but not final: user={$from_user} msg_id={$msg_id} -msg-7d8b62e7 = wx finished in window but not final; return placeholder: user={$from_user} msg_id={$msg_id} + +msg-d4bbf9cb = Verify request validity:{ $res } +msg-b2edb1b2 = Unknown response, please check if the callback address is filled in correctly. +msg-f8694a8a = Request validation successful. +msg-8f4cda74 = Failed to validate request effectiveness, signature exception, please check configuration. +msg-46d3feb9 = Decryption failed, signature abnormal, please check the configuration. +msg-e23d8bff = Parsing failed. The msg is None. +msg-4d1dfce4 = Parse succeeded:{ $msg } +msg-193d9d7a = User message buffer status: user={ $from_user }state={ $state } +msg-57a3c1b2 = wx buffer hit on trigger: user={ $from_user } +msg-bed995d9 = wx buffer hit on retry window: user={ $from_user } +msg-3a94b6ab = wx finished message sending in passive window: user={ $from_user }msg_id={ $msg_id } +msg-50c4b253 = wx finished message sending in passive window but not final: user={ $from_user }msg_id={ $msg_id } +msg-7d8b62e7 = wx finished in window but not final; return placeholder: user={ $from_user }msg_id={ $msg_id } msg-2b9b8aed = wx task failed in passive window -msg-7bdf4941 = wx passive window timeout: user={$from_user} msg_id={$msg_id} -msg-98489949 = wx trigger while thinking: user={$from_user} -msg-01d0bbeb = wx new trigger: user={$from_user} msg_id={$msg_id} -msg-52bb36cd = wx start task: user={$from_user} msg_id={$msg_id} preview={$preview} -msg-ec9fd2ed = wx buffer hit immediately: user={$from_user} -msg-61c91fb9 = wx not finished in first window; return placeholder: user={$from_user} msg_id={$msg_id} +msg-7bdf4941 = wx passive window timeout: user={ $from_user }msg_id={ $msg_id } +msg-98489949 = wx trigger while thinking: user={ $from_user } +msg-01d0bbeb = wx new trigger: user={ $from_user }msg_id={ $msg_id } +msg-52bb36cd = wx start task: user={ $from_user }msg_id={ $msg_id }preview={ $preview } +msg-ec9fd2ed = wx buffer hit immediately: user={ $from_user } +msg-61c91fb9 = wx not finished in first window; return placeholder: user={ $from_user }msg_id={ $msg_id } msg-35604bba = wx task failed in first window -msg-e56c4a28 = wx first window timeout: user={$from_user} msg_id={$msg_id} -msg-e163be40 = 将在 {$res}:{$res_2} 端口启动 微信公众平台 适配器。 -msg-c1740a04 = duplicate message id checked: {$res} -msg-04718b37 = Got future result: {$result} -msg-296e66c1 = callback 处理消息超时: message_id={$res} -msg-eb718c92 = 转换消息时出现异常: {$e} -msg-93c9125e = 转换音频失败: {$e}。如果没有安装 ffmpeg 请先安装。 -msg-b2f7d1dc = 暂未实现的事件: {$res} -msg-61480a61 = abm: {$abm} -msg-2e7e0187 = 用户消息未找到缓冲状态,无法处理消息: user={$res} message_id={$res_2} -msg-84312903 = 微信公众平台 适配器已被关闭 +msg-e56c4a28 = wx first window timeout: user={ $from_user }msg_id={ $msg_id } +msg-e163be40 = Will be{ $res }Text to translate:{ $res_2 }Port startup WeChat public platform adapter. +msg-c1740a04 = duplicate message id checked:{ $res } +msg-04718b37 = Got future result:{ $result } +msg-296e66c1 = callback message processing timeout: message_id={ $res } +msg-eb718c92 = An exception occurred while converting the message:{ $e } +msg-93c9125e = Failed to convert audio:{ $e }If ffmpeg is not installed, please install it first. +msg-b2f7d1dc = Unimplemented events:{ $res } +msg-61480a61 = abm:{ $abm } +msg-2e7e0187 = User message buffering status not found, unable to process message: user={ $res }Message ID={ $res_2 } +msg-84312903 = WeChat Public Platform adapter has been disabled ### astrbot/core/platform/sources/misskey/misskey_adapter.py -msg-7bacee77 = [Misskey] 配置不完整,无法启动 -msg-99cdf3d3 = [Misskey] 已连接用户: {$res} (ID: {$res_2}) -msg-5579c974 = [Misskey] 获取用户信息失败: {$e} -msg-d9547102 = [Misskey] API 客户端未初始化 -msg-341b0aa0 = [Misskey] WebSocket 已连接 (尝试 #{$connection_attempts}) -msg-c77d157b = [Misskey] 聊天频道已订阅 -msg-a0c5edc0 = [Misskey] WebSocket 连接失败 (尝试 #{$connection_attempts}) -msg-1958faa8 = [Misskey] WebSocket 异常 (尝试 #{$connection_attempts}): {$e} -msg-1b47382d = [Misskey] {$sleep_time}秒后重连 (下次尝试 #{$res}) -msg-a10a224d = [Misskey] 收到通知事件: type={$notification_type}, user_id={$res} -msg-7f0abf4a = [Misskey] 处理贴文提及: {$res}... -msg-2da7cdf5 = [Misskey] 处理通知失败: {$e} -msg-6c21d412 = [Misskey] 收到聊天事件: sender_id={$sender_id}, room_id={$room_id}, is_self={$res} -msg-68269731 = [Misskey] 检查群聊消息: '{$raw_text}', 机器人用户名: '{$res}' -msg-585aa62b = [Misskey] 处理群聊消息: {$res}... -msg-426c7874 = [Misskey] 处理私聊消息: {$res}... -msg-f5aff493 = [Misskey] 处理聊天消息失败: {$e} -msg-ea465183 = [Misskey] 收到未处理事件: type={$event_type}, channel={$res} -msg-8b69eb93 = [Misskey] 消息内容为空且无文件组件,跳过发送 -msg-9ba9c4e5 = [Misskey] 已清理临时文件: {$local_path} -msg-91af500e = [Misskey] 文件数量超过限制 ({$res} > {$MAX_FILE_UPLOAD_COUNT}),只上传前{$MAX_FILE_UPLOAD_COUNT}个文件 -msg-9746d7f5 = [Misskey] 并发上传过程中出现异常,继续发送文本 -msg-d6dc928c = [Misskey] 聊天消息只支持单个文件,忽略其余 {$res} 个文件 -msg-af584ae8 = [Misskey] 解析可见性: visibility={$visibility}, visible_user_ids={$visible_user_ids}, session_id={$session_id}, user_id_for_cache={$user_id_for_cache} -msg-1a176905 = [Misskey] 发送消息失败: {$e} + +msg-7bacee77 = [Misskey] Configuration is incomplete, cannot start. +msg-99cdf3d3 = [Misskey] Connected users:{ $res }(ID:{ $res_2 }Text to be translated: ) +msg-5579c974 = [Misskey] Failed to retrieve user information:{ $e } +msg-d9547102 = [Misskey] API client not initialized +msg-341b0aa0 = [Misskey] WebSocket connected (Attempt #{ $connection_attempts }) +msg-c77d157b = [Misskey] Chat channel subscribed +msg-a0c5edc0 = [Misskey] WebSocket connection failed (attempt #{ $connection_attempts }) +msg-1958faa8 = [Misskey] WebSocket Exception (Attempt #{ $connection_attempts }):{ $e } +msg-1b47382d = [Misskey]{ $sleep_time }Reconnect in seconds (next attempt #{ $res }) +msg-a10a224d = [Misskey] Received notification event: type={ $notification_type }, user_id={ $res } +msg-7f0abf4a = [Misskey] Processing post mentions:{ $res }... +msg-2da7cdf5 = [Misskey] Failed to process notification:{ $e } +msg-6c21d412 = [Misskey] Received chat event: sender_id={ $sender_id }, room_id={ $room_id }, is_self={ $res } +msg-68269731 = [Misskey] Checking group chat messages: '{ $raw_text }', Bot username: '{ $res }Text to translate: +msg-585aa62b = [Misskey] Processing group chat message:{ $res }... +msg-426c7874 = [Misskey] Processing private message:{ $res }... +msg-f5aff493 = [Misskey] Failed to process chat message:{ $e } +msg-ea465183 = [Misskey] Unhandled event received: type={ $event_type }, channel={ $res } +msg-8b69eb93 = [Misskey] Message content is empty and no file components, skipping send. +msg-9ba9c4e5 = [Misskey] Temporary files cleaned:{ $local_path } +msg-91af500e = [Misskey] The number of files exceeds the limit{ $res }>{ $MAX_FILE_UPLOAD_COUNT }Only upload the first{ $MAX_FILE_UPLOAD_COUNT }file +msg-9746d7f5 = [Misskey] An exception occurred during concurrent uploads; continuing to send text. +msg-d6dc928c = [Misskey] Chat messages only support a single file, ignoring the rest{ $res }files +msg-af584ae8 = [Misskey] Parsing visibility: visibility={ $visibility }, visible_user_ids={ $visible_user_ids }, session_id={ $session_id }, user_id_for_cache={ $user_id_for_cache } +msg-1a176905 = [Misskey] Failed to send message:{ $e } ### astrbot/core/platform/sources/misskey/misskey_api.py + msg-fab20f57 = aiohttp and websockets are required for Misskey API. Please install them with: pip install aiohttp websockets -msg-f2eea8e1 = [Misskey WebSocket] 已连接 -msg-5efd11a2 = [Misskey WebSocket] 重新订阅 {$channel_type} 失败: {$e} -msg-b70e2176 = [Misskey WebSocket] 连接失败: {$e} -msg-b9f3ee06 = [Misskey WebSocket] 连接已断开 -msg-7cd98e54 = WebSocket 未连接 -msg-43566304 = [Misskey WebSocket] 无法解析消息: {$e} -msg-e617e390 = [Misskey WebSocket] 处理消息失败: {$e} -msg-c60715cf = [Misskey WebSocket] 连接意外关闭: {$e} -msg-da9a2a17 = [Misskey WebSocket] 连接已关闭 (代码: {$res}, 原因: {$res_2}) -msg-bbf6a42e = [Misskey WebSocket] 握手失败: {$e} -msg-254f0237 = [Misskey WebSocket] 监听消息失败: {$e} -msg-49f7e90e = {$channel_summary} -msg-630a4832 = [Misskey WebSocket] 频道消息: {$channel_id}, 事件类型: {$event_type} -msg-0dc61a4d = [Misskey WebSocket] 使用处理器: {$handler_key} -msg-012666fc = [Misskey WebSocket] 使用事件处理器: {$event_type} -msg-e202168a = [Misskey WebSocket] 未找到处理器: {$handler_key} 或 {$event_type} -msg-a397eef1 = [Misskey WebSocket] 直接消息处理器: {$message_type} -msg-a5f12225 = [Misskey WebSocket] 未处理的消息类型: {$message_type} -msg-ad61d480 = [Misskey API] {$func_name} 重试 {$max_retries} 次后仍失败: {$e} -msg-7de2ca49 = [Misskey API] {$func_name} 第 {$attempt} 次重试失败: {$e},{$sleep_time}s后重试 -msg-f5aecf37 = [Misskey API] {$func_name} 遇到不可重试异常: {$e} -msg-e5852be5 = [Misskey API] 客户端已关闭 -msg-21fc185c = [Misskey API] 请求参数错误: {$endpoint} (HTTP {$status}) -msg-5b106def = Bad request for {$endpoint} -msg-28afff67 = [Misskey API] 未授权访问: {$endpoint} (HTTP {$status}) -msg-e12f2d28 = Unauthorized access for {$endpoint} -msg-beda662d = [Misskey API] 访问被禁止: {$endpoint} (HTTP {$status}) -msg-795ca227 = Forbidden access for {$endpoint} -msg-5c6ba873 = [Misskey API] 资源不存在: {$endpoint} (HTTP {$status}) -msg-74f2bac2 = Resource not found for {$endpoint} -msg-9ceafe4c = [Misskey API] 请求体过大: {$endpoint} (HTTP {$status}) -msg-3e336b73 = Request entity too large for {$endpoint} -msg-a47067de = [Misskey API] 请求频率限制: {$endpoint} (HTTP {$status}) -msg-901dc2da = Rate limit exceeded for {$endpoint} -msg-2bea8c2e = [Misskey API] 服务器内部错误: {$endpoint} (HTTP {$status}) -msg-ae8d3725 = Internal server error for {$endpoint} -msg-7b028462 = [Misskey API] 网关错误: {$endpoint} (HTTP {$status}) -msg-978414ef = Bad gateway for {$endpoint} -msg-50895a69 = [Misskey API] 服务不可用: {$endpoint} (HTTP {$status}) -msg-62adff89 = Service unavailable for {$endpoint} -msg-1cf15497 = [Misskey API] 网关超时: {$endpoint} (HTTP {$status}) -msg-a8a2578d = Gateway timeout for {$endpoint} -msg-c012110a = [Misskey API] 未知错误: {$endpoint} (HTTP {$status}) -msg-dc96bbb8 = HTTP {$status} for {$endpoint} -msg-4c7598b6 = [Misskey API] 获取到 {$res} 条新通知 -msg-851a2a54 = [Misskey API] 请求成功: {$endpoint} -msg-5f5609b6 = [Misskey API] 响应格式错误: {$e} +msg-f2eea8e1 = [Misskey WebSocket] Connected +msg-5efd11a2 = [Misskey WebSocket] Resubscribe{ $channel_type }Failure:{ $e } +msg-b70e2176 = [Misskey WebSocket] Connection failed:{ $e } +msg-b9f3ee06 = [Misskey WebSocket] Connection disconnected +msg-7cd98e54 = WebSocket is not connected +msg-43566304 = [Misskey WebSocket] Failed to parse message:{ $e } +msg-e617e390 = [Misskey WebSocket] Failed to process message:{ $e } +msg-c60715cf = [Misskey WebSocket] Connection closed unexpectedly:{ $e } +msg-da9a2a17 = [Misskey WebSocket] Connection closed (Code:{ $res }, Reason:{ $res_2 }) +msg-bbf6a42e = [Misskey WebSocket] Handshake failed:{ $e } +msg-254f0237 = [Misskey WebSocket] Failed to listen to messages:{ $e } +msg-49f7e90e = { $channel_summary } +msg-630a4832 = [Misskey WebSocket] Channel Message:{ $channel_id }Event Type:{ $event_type } +msg-0dc61a4d = [Misskey WebSocket] Using handler:{ $handler_key } +msg-012666fc = [Misskey WebSocket] Using event handler:{ $event_type } +msg-e202168a = [Misskey WebSocket] Handler not found:{ $handler_key }Or{ $event_type } +msg-a397eef1 = [Misskey WebSocket] Direct Message Handler:{ $message_type } +msg-a5f12225 = [Misskey WebSocket] Unhandled message type:{ $message_type } +msg-ad61d480 = [Misskey API]{ $func_name }Retry{ $max_retries }Failed again after retry:{ $e } +msg-7de2ca49 = [Misskey API]{ $func_name }Page{ $attempt }Secondary retry failed:{ $e }Text to be translated:{ $sleep_time }Retry after s +msg-f5aecf37 = [Misskey API]{ $func_name }Encountered a non-retryable exception:{ $e } +msg-e5852be5 = [Misskey API] Client has closed +msg-21fc185c = [Misskey API] Request parameter error:{ $endpoint }(HTTP{ $status }) +msg-5b106def = Bad request for{ $endpoint } +msg-28afff67 = [Misskey API] Unauthorized access:{ $endpoint }(HTTP{ $status }) +msg-e12f2d28 = Unauthorized access for{ $endpoint } +msg-beda662d = [Misskey API] Access Denied:{ $endpoint }(HTTP{ $status }Text to be translated: +msg-795ca227 = Forbidden access for{ $endpoint } +msg-5c6ba873 = [Misskey API] Resource not found:{ $endpoint }(HTTP{ $status }) +msg-74f2bac2 = Resource not found for{ $endpoint } +msg-9ceafe4c = [Misskey API] Request body too large:{ $endpoint }(HTTP{ $status }Text to be translated: +msg-3e336b73 = Request entity too large{ $endpoint } +msg-a47067de = [Misskey API] Request rate limit:{ $endpoint }(HTTP{ $status }Text to be translated: +msg-901dc2da = Rate limit exceeded for{ $endpoint } +msg-2bea8c2e = [Misskey API] Server internal error:{ $endpoint }(HTTP{ $status }待翻译文本: +msg-ae8d3725 = Internal server error for{ $endpoint } +msg-7b028462 = [Misskey API] Gateway Error:{ $endpoint }(HTTP{ $status }) +msg-978414ef = Bad gateway for{ $endpoint } +msg-50895a69 = [Misskey API] Service Unavailable:{ $endpoint }(HTTP{ $status }) +msg-62adff89 = Service unavailable for{ $endpoint } +msg-1cf15497 = [Misskey API] Gateway Timeout:{ $endpoint }(HTTP{ $status }) +msg-a8a2578d = Gateway timeout for{ $endpoint } +msg-c012110a = [Misskey API] Unknown error:{ $endpoint }(HTTP{ $status }Text to be translated: +msg-dc96bbb8 = HTTP{ $status }for{ $endpoint } +msg-4c7598b6 = [Misskey API] Fetched{ $res }New notification +msg-851a2a54 = [Misskey API] Request successful:{ $endpoint } +msg-5f5609b6 = [Misskey API] Invalid response format:{ $e } msg-c8f7bbeb = Invalid JSON response -msg-82748b31 = [Misskey API] 请求失败: {$endpoint} - HTTP {$res}, 响应: {$error_text} -msg-c6de3320 = [Misskey API] 请求失败: {$endpoint} - HTTP {$res} -msg-affb19a7 = [Misskey API] HTTP 请求错误: {$e} -msg-9f1286b3 = HTTP request failed: {$e} -msg-44f91be2 = [Misskey API] 发帖成功: {$note_id} +msg-82748b31 = [Misskey API] Request failed:{ $endpoint }- HTTP{ $res }, Response:{ $error_text } +msg-c6de3320 = [Misskey API] Request failed:{ $endpoint }- HTTP{ $res } +msg-affb19a7 = [Misskey API] HTTP request error:{ $e } +msg-9f1286b3 = HTTP request failed:{ $e } +msg-44f91be2 = [Misskey API] Post successfully sent:{ $note_id } msg-fbafd3db = No file path provided for upload -msg-872d8419 = [Misskey API] 本地文件不存在: {$file_path} -msg-37186dea = File not found: {$file_path} -msg-65ef68e0 = [Misskey API] 本地文件上传成功: {$filename} -> {$file_id} -msg-0951db67 = [Misskey API] 文件上传网络错误: {$e} -msg-e3a322f5 = Upload failed: {$e} +msg-872d8419 = [Misskey API] Local file does not exist:{ $file_path } +msg-37186dea = File not found:{ $file_path } +msg-65ef68e0 = [Misskey API] Local file upload successful:{ $filename }->{ $file_id } +msg-0951db67 = [Misskey API] Network error in file upload:{ $e } +msg-e3a322f5 = Upload failed:{ $e } msg-f28772b9 = No MD5 hash provided for find-by-hash -msg-25e566ef = [Misskey API] find-by-hash 请求: md5={$md5_hash} -msg-a036a942 = [Misskey API] find-by-hash 响应: 找到 {$res} 个文件 -msg-ea3581d5 = [Misskey API] 根据哈希查找文件失败: {$e} +msg-25e566ef = [Misskey API] find-by-hash request: md5={ $md5_hash } +msg-a036a942 = [Misskey API] find-by-hash response: Found{ $res }files +msg-ea3581d5 = [Misskey API] Failed to find file by hash:{ $e } msg-1d2a84ff = No name provided for find -msg-f25e28b4 = [Misskey API] find 请求: name={$name}, folder_id={$folder_id} -msg-cd43861a = [Misskey API] find 响应: 找到 {$res} 个文件 -msg-05cd55ef = [Misskey API] 根据名称查找文件失败: {$e} -msg-c01052a4 = [Misskey API] 列表文件请求: limit={$limit}, folder_id={$folder_id}, type={$type} -msg-7c81620d = [Misskey API] 列表文件响应: 找到 {$res} 个文件 -msg-a187a089 = [Misskey API] 列表文件失败: {$e} +msg-f25e28b4 = [Misskey API] find request: name={ $name }, folder_id={ $folder_id } +msg-cd43861a = [Misskey API] find response: found{ $res }files +msg-05cd55ef = [Misskey API] Failed to find file by name:{ $e } +msg-c01052a4 = [Misskey API] List file request: limit={ $limit }, folder_id={ $folder_id }, type={ $type } +msg-7c81620d = [Misskey API] List files response: Found{ $res }files +msg-a187a089 = [Misskey API] Failed to list files:{ $e } msg-9e776259 = No existing session available -msg-de18c220 = URL不能为空 -msg-25b15b61 = [Misskey API] SSL 验证下载失败: {$ssl_error},重试不验证 SSL -msg-b6cbeef6 = [Misskey API] 本地上传成功: {$res} -msg-a4a898e2 = [Misskey API] 本地上传失败: {$e} -msg-46b7ea4b = [Misskey API] 聊天消息发送成功: {$message_id} -msg-32f71df4 = [Misskey API] 房间消息发送成功: {$message_id} -msg-7829f3b3 = [Misskey API] 聊天消息响应格式异常: {$res} -msg-d74c86a1 = [Misskey API] 提及通知响应格式异常: {$res} -msg-65ccb697 = 消息内容不能为空:需要文本或媒体文件 -msg-b6afb123 = [Misskey API] URL媒体上传成功: {$res} -msg-4e62bcdc = [Misskey API] URL媒体上传失败: {$url} -msg-71cc9d61 = [Misskey API] URL媒体处理失败 {$url}: {$e} -msg-75890c2b = [Misskey API] 本地文件上传成功: {$res} -msg-024d0ed5 = [Misskey API] 本地文件上传失败: {$file_path} -msg-f1fcb5e1 = [Misskey API] 本地文件处理失败 {$file_path}: {$e} -msg-1ee80a6b = 不支持的消息类型: {$message_type} +msg-de18c220 = URL cannot be empty +msg-25b15b61 = [Misskey API] SSL certificate download failed:{ $ssl_error }, retry without verifying SSL +msg-b6cbeef6 = [Misskey API] Local upload successful:{ $res } +msg-a4a898e2 = [Misskey API] Local upload failed:{ $e } +msg-46b7ea4b = [Misskey API] Chat message sent successfully:{ $message_id } +msg-32f71df4 = [Misskey API] Room message sent successfully:{ $message_id } +msg-7829f3b3 = [Misskey API] Chat message response format is abnormal:{ $res } +msg-d74c86a1 = [Misskey API] Mention notification response format is abnormal:{ $res } +msg-65ccb697 = Message content cannot be empty: text or media file is required. +msg-b6afb123 = [Misskey API] URL media upload succeeded:{ $res } +msg-4e62bcdc = [Misskey API] URL media upload failed:{ $url } +msg-71cc9d61 = [Misskey API] URL media processing failed{ $url }Text to be translated:{ $e } +msg-75890c2b = [Misskey API] Local file upload successful:{ $res } +msg-024d0ed5 = [Misskey API] Local file upload failed:{ $file_path } +msg-f1fcb5e1 = [Misskey API] Local file processing failed{ $file_path }Text to translate:{ $e } +msg-1ee80a6b = Unsupported message type:{ $message_type } ### astrbot/core/platform/sources/misskey/misskey_event.py -msg-85cb7d49 = [MisskeyEvent] send 方法被调用,消息链包含 {$res} 个组件 -msg-252c2fca = [MisskeyEvent] 检查适配器方法: hasattr(self.client, 'send_by_session') = {$res} -msg-44d7a060 = [MisskeyEvent] 调用适配器的 send_by_session 方法 -msg-b6e08872 = [MisskeyEvent] 内容为空,跳过发送 -msg-8cfebc9c = [MisskeyEvent] 创建新帖子 -msg-ed0d2ed5 = [MisskeyEvent] 发送失败: {$e} + +msg-85cb7d49 = [MisskeyEvent] send method was called, message chain contains{ $res }Components +msg-252c2fca = [MisskeyEvent] Check adapter method: hasattr(self.client, 'send_by_session') ={ $res } +msg-44d7a060 = [MisskeyEvent] Calling the adapter's send_by_session method +msg-b6e08872 = [MisskeyEvent] Content is empty, skipping send +msg-8cfebc9c = [MisskeyEvent] Create new post +msg-ed0d2ed5 = [MisskeyEvent] Sending failed:{ $e } ### astrbot/core/platform/sources/wecom_ai_bot/wecomai_webhook.py -msg-a5c90267 = 消息推送 webhook URL 不能为空 -msg-76bfb25b = 消息推送 webhook URL 缺少 key 参数 -msg-3545eb07 = Webhook 请求失败: HTTP {$res}, {$text} -msg-758dfe0d = Webhook 返回错误: {$res} {$res_2} -msg-c056646b = 企业微信消息推送成功: %s -msg-73d3e179 = 文件不存在: {$file_path} -msg-774a1821 = 上传媒体失败: HTTP {$res}, {$text} -msg-6ff016a4 = 上传媒体失败: {$res} {$res_2} -msg-0e8252d1 = 上传媒体失败: 返回缺少 media_id -msg-9dbc2296 = 文件消息缺少有效文件路径,已跳过: %s -msg-2e567c36 = 清理临时语音文件失败 %s: %s -msg-e99c4df9 = 企业微信消息推送暂不支持组件类型 %s,已跳过 + +msg-a5c90267 = Message push webhook URL cannot be empty +msg-76bfb25b = Message push webhook URL missing key parameter +msg-3545eb07 = Webhook request failed: HTTP{ $res }{ $text } +msg-758dfe0d = Webhook returned an error:{ $res } { $res_2 } +msg-c056646b = Enterprise WeChat message push successful: %s +msg-73d3e179 = File does not exist:{ $file_path } +msg-774a1821 = Upload media failed: HTTP{ $res }待翻译文本:,{ $text } +msg-6ff016a4 = Upload media failed:{ $res } { $res_2 } +msg-0e8252d1 = Upload media failed: Return missing media_id +msg-9dbc2296 = File message missing valid file path, skipped: %s +msg-2e567c36 = Failed to clean up temporary voice files %s: %s +msg-e99c4df9 = Enterprise WeChat message push does not currently support component type %s, skipped. ### astrbot/core/platform/sources/wecom_ai_bot/WXBizJsonMsgCrypt.py -msg-5bdf8f5c = {$e} + +msg-5bdf8f5c = { $e } msg-fe69e232 = receiveid not match msg-00b71c27 = signature not match -msg-5cfb5c20 = {$signature} +msg-5cfb5c20 = { $signature } ### astrbot/core/platform/sources/wecom_ai_bot/wecomai_event.py -msg-e44e77b0 = 图片数据为空,跳过 -msg-30d116ed = 处理图片消息失败: %s -msg-31b11295 = [WecomAI] 不支持的消息组件类型: {$res}, 跳过 + +msg-e44e77b0 = Image data is empty, skipping. +msg-30d116ed = Failed to process image message: %s +msg-31b11295 = [WecomAI] Unsupported message component type:{ $res }, skip ### astrbot/core/platform/sources/wecom_ai_bot/wecomai_adapter.py -msg-277cdd37 = 企业微信消息推送 webhook 配置无效: %s -msg-2102fede = 处理队列消息时发生异常: {$e} -msg-d4ea688d = 消息类型未知,忽略: {$message_data} -msg-15ba426f = 处理消息时发生异常: %s -msg-740911ab = Stream already finished, returning end message: {$stream_id} -msg-9fdbafe9 = Cannot find back queue for stream_id: {$stream_id} -msg-7a52ca2b = No new messages in back queue for stream_id: {$stream_id} -msg-9ffb59fb = Aggregated content: {$latest_plain_content}, image: {$res}, finish: {$finish} -msg-de9ff585 = Stream message sent successfully, stream_id: {$stream_id} -msg-558310b9 = 消息加密失败 -msg-251652f9 = 处理欢迎消息时发生异常: %s -msg-480c5dac = [WecomAI] 消息已入队: {$stream_id} -msg-f595dd6e = 处理加密图片失败: {$result} -msg-e8beeb3d = WecomAIAdapter: {$res} -msg-6f8ad811 = 主动消息发送失败: 未配置企业微信消息推送 Webhook URL,请前往配置添加。session_id=%s -msg-84439b09 = 企业微信消息推送失败(session=%s): %s -msg-f70f5008 = 启动企业微信智能机器人适配器,监听 %s:%d -msg-87616945 = 企业微信智能机器人适配器正在关闭... + +msg-277cdd37 = Enterprise WeChat message push webhook configuration invalid: %s +msg-2102fede = An exception occurred while processing the queue message:{ $e } +msg-d4ea688d = Message type unknown, ignored:{ $message_data } +msg-15ba426f = Exception occurred while processing message: %s +msg-740911ab = Stream already finished, returning end message:{ $stream_id } +msg-9fdbafe9 = Cannot find back queue for stream_id:{ $stream_id } +msg-7a52ca2b = No new messages in back queue for stream_id:{ $stream_id } +msg-9ffb59fb = Aggregated content:{ $latest_plain_content }, image:{ $res }finish:{ $finish } +msg-de9ff585 = Stream message sent successfully, stream_id:{ $stream_id } +msg-558310b9 = Message encryption failed +msg-251652f9 = An exception occurred while processing the welcome message: %s +msg-480c5dac = [WecomAI] Message enqueued:{ $stream_id } +msg-f595dd6e = Failed to process encrypted image:{ $result } +msg-e8beeb3d = WecomAIAdapter:{ $res } +msg-6f8ad811 = Active message sending failed: Enterprise WeChat message push Webhook URL not configured, please go to configuration to add. session_id=%s +msg-84439b09 = Enterprise WeChat message push failed (session=%s): %s +msg-f70f5008 = Start the WeChat Work smart robot adapter, listening on %s:%d +msg-87616945 = Enterprise WeChat intelligent robot adapter is shutting down... ### astrbot/core/platform/sources/wecom_ai_bot/wecomai_api.py -msg-86f6ae9f = 消息解密失败,错误码: {$ret} -msg-45ad825c = 解密成功,消息内容: {$message_data} -msg-84c476a7 = JSON 解析失败: {$e}, 原始消息: {$decrypted_msg} -msg-c0d8c5f9 = 解密消息为空 -msg-a08bcfc7 = 解密过程发生异常: {$e} -msg-4dfaa613 = 消息加密失败,错误码: {$ret} -msg-6e566b12 = 消息加密成功 -msg-39bf8dba = 加密过程发生异常: {$e} -msg-fa5be7c5 = URL 验证失败,错误码: {$ret} -msg-813a4e4e = URL 验证成功 -msg-65ce0d23 = URL 验证发生异常: {$e} -msg-b1aa892f = 开始下载加密图片: {$image_url} -msg-10f72727 = {$error_msg} -msg-70123a82 = 图片下载成功,大小: {$res} 字节 -msg-85d2dba1 = AES 密钥不能为空 -msg-67c4fcea = 无效的 AES 密钥长度: 应为 32 字节 -msg-bde4bb57 = 无效的填充长度 (大于32字节) -msg-63c22912 = 图片解密成功,解密后大小: {$res} 字节 -msg-6ea489f0 = 文本消息解析失败 -msg-eb12d147 = 图片消息解析失败 -msg-ab1157ff = 流消息解析失败 -msg-e7e945d1 = 混合消息解析失败 -msg-06ada9dd = 事件消息解析失败 + +msg-86f6ae9f = Message decryption failed, error code:{ $ret } +msg-45ad825c = Decryption successful, message content:{ $message_data } +msg-84c476a7 = JSON parsing failed:{ $e }Original message:{ $decrypted_msg } +msg-c0d8c5f9 = Decrypted message is empty +msg-a08bcfc7 = Decryption process exception occurred:{ $e } +msg-4dfaa613 = Message encryption failed, error code:{ $ret } +msg-6e566b12 = Message encrypted successfully +msg-39bf8dba = Encryption process exception occurred:{ $e } +msg-fa5be7c5 = URL verification failed, error code:{ $ret } +msg-813a4e4e = URL verification successful +msg-65ce0d23 = An exception occurred during URL validation:{ $e } +msg-b1aa892f = Start downloading encrypted image:{ $image_url } +msg-10f72727 = { $error_msg } +msg-70123a82 = Image downloaded successfully, size:{ $res }Byte +msg-85d2dba1 = AES key cannot be empty +msg-67c4fcea = Invalid AES key length: should be 32 bytes +msg-bde4bb57 = Invalid padding length (greater than 32 bytes) +msg-63c22912 = Image decryption successful, decrypted size:{ $res }Byte +msg-6ea489f0 = Text message parsing failed +msg-eb12d147 = Image message parsing failed +msg-ab1157ff = Stream message parsing failed +msg-e7e945d1 = Mixed message parsing failed +msg-06ada9dd = Event message parsing failed ### astrbot/core/platform/sources/wecom_ai_bot/wecomai_server.py -msg-adaee66c = URL 验证参数缺失 -msg-742e0b43 = 收到企业微信智能机器人 WebHook URL 验证请求。 -msg-f86c030c = 消息回调参数缺失 -msg-cce4e44c = 收到消息回调,msg_signature={$msg_signature}, timestamp={$timestamp}, nonce={$nonce} -msg-7f018a3c = 消息解密失败,错误码: %d -msg-9d42e548 = 消息处理器执行异常: %s -msg-15ba426f = 处理消息时发生异常: %s -msg-5bf7dffa = 启动企业微信智能机器人服务器,监听 %s:%d -msg-445921d5 = 服务器运行异常: %s -msg-3269840c = 企业微信智能机器人服务器正在关闭... + +msg-adaee66c = URL validation parameter missing +msg-742e0b43 = Received a verification request for the Enterprise WeChat Smart Bot WebHook URL. +msg-f86c030c = Message callback parameters are missing +msg-cce4e44c = Message received callback, msg_signature={ $msg_signature }, timestamp={ $timestamp }, nonce={ $nonce } +msg-7f018a3c = Message decryption failed, error code: %d +msg-9d42e548 = Message handler execution exception: %s +msg-15ba426f = An exception occurred while processing the message: %s +msg-5bf7dffa = Starting the enterprise WeChat intelligent robot server, listening on %s:%d +msg-445921d5 = Server running abnormally: %s +msg-3269840c = Enterprise WeChat intelligent robot server is shutting down... ### astrbot/core/platform/sources/wecom_ai_bot/wecomai_queue_mgr.py -msg-8be03d44 = [WecomAI] 创建输入队列: {$session_id} -msg-9804296a = [WecomAI] 创建输出队列: {$session_id} -msg-bdf0fb78 = [WecomAI] 移除输出队列: {$session_id} -msg-40f6bb7b = [WecomAI] 移除待处理响应: {$session_id} -msg-fbb807cd = [WecomAI] 标记流已结束: {$session_id} -msg-9d7f5627 = [WecomAI] 移除输入队列: {$session_id} -msg-7637ed00 = [WecomAI] 设置待处理响应: {$session_id} -msg-5329c49b = [WecomAI] 清理过期响应及队列: {$session_id} -msg-09f098ea = [WecomAI] 为会话启动监听器: {$session_id} -msg-c55856d6 = 处理会话 {$session_id} 消息时发生错误: {$e} + +msg-8be03d44 = [WecomAI] Creating input queue:{ $session_id } +msg-9804296a = [WecomAI] Creating output queue:{ $session_id } +msg-bdf0fb78 = [WecomAI] Remove Output Queue:{ $session_id } +msg-40f6bb7b = [WecomAI] Remove pending response:{ $session_id } +msg-fbb807cd = [WecomAI] Stream marking has ended:{ $session_id } +msg-9d7f5627 = [WecomAI] Remove from input queue:{ $session_id } +msg-7637ed00 = [WecomAI] Set pending response:{ $session_id } +msg-5329c49b = [WecomAI] Cleaning up expired responses and queues:{ $session_id } +msg-09f098ea = [WecomAI] Starting listener for conversation:{ $session_id } +msg-c55856d6 = Processing sessions{ $session_id }An error occurred while messaging:{ $e } ### astrbot/core/platform/sources/wecom_ai_bot/wecomai_utils.py -msg-14d01778 = JSON 解析失败: {$e}, 原始字符串: {$json_str} -msg-df346cf5 = 开始下载加密图片: %s -msg-cb266fb3 = 图片下载成功,大小: %d 字节 -msg-10f72727 = {$error_msg} -msg-1d91d2bb = AES密钥不能为空 -msg-bb32bedd = 无效的AES密钥长度: 应为32字节 -msg-bde4bb57 = 无效的填充长度 (大于32字节) -msg-3cf2120e = 图片解密成功,解密后大小: %d 字节 -msg-3f8ca8aa = 图片已转换为base64编码,编码后长度: %d + +msg-14d01778 = JSON parsing failed:{ $e }Original string:{ $json_str } +msg-df346cf5 = Start downloading encrypted image: %s +msg-cb266fb3 = Image downloaded successfully, size: %d bytes +msg-10f72727 = { $error_msg } +msg-1d91d2bb = AES key cannot be empty +msg-bb32bedd = Invalid AES key length: must be 32 bytes +msg-bde4bb57 = Invalid padding length (greater than 32 bytes) +msg-3cf2120e = Image decryption successful, decrypted size: %d bytes +msg-3f8ca8aa = Image has been converted to base64 encoding, encoded length: %d ### astrbot/core/platform/sources/line/line_api.py + msg-06e3f874 = [LINE] %s message failed: status=%s body=%s msg-1478c917 = [LINE] %s message request failed: %s msg-39941f06 = [LINE] get content retry failed: message_id=%s status=%s body=%s msg-1fe70511 = [LINE] get content failed: message_id=%s status=%s body=%s ### astrbot/core/platform/sources/line/line_event.py -msg-4068a191 = [LINE] resolve image url failed: %s -msg-2233b256 = [LINE] resolve record url failed: %s + +msg-4068a191 = [LINE] Failed to resolve image URL: %s +msg-2233b256 = [LINE] Failed to resolve record URL: %s msg-a7455817 = [LINE] resolve record duration failed: %s -msg-9d0fee66 = [LINE] resolve video url failed: %s +msg-9d0fee66 = [LINE] Failed to resolve video URL: %s msg-3b8ea946 = [LINE] resolve video cover failed: %s -msg-aea2081a = [LINE] generate video preview failed: %s +msg-aea2081a = [LINE] Failed to generate video preview: %s msg-af426b7e = [LINE] resolve file url failed: %s msg-fe44c12d = [LINE] resolve file size failed: %s msg-d6443173 = [LINE] message count exceeds 5, extra segments will be dropped. ### astrbot/core/platform/sources/line/line_adapter.py -msg-68539775 = LINE 适配器需要 channel_access_token 和 channel_secret。 -msg-30c67081 = [LINE] webhook_uuid 为空,统一 Webhook 可能无法接收消息。 + +msg-68539775 = The LINE adapter requires channel_access_token and channel_secret. +msg-30c67081 = [LINE] webhook_uuid is empty, the unified webhook may not be able to receive messages. msg-64e92929 = [LINE] invalid webhook signature msg-71bc0b77 = [LINE] invalid webhook body: %s msg-8c7d9bab = [LINE] duplicate event skipped: %s ### astrbot/core/platform/sources/telegram/tg_event.py -msg-7757f090 = [Telegram] 发送 chat action 失败: {$e} + +msg-7757f090 = [Telegram] Failed to send chat action:{ $e } msg-80b075a3 = User privacy settings prevent receiving voice messages, falling back to sending an audio file. To enable voice messages, go to Telegram Settings → Privacy and Security → Voice Messages → set to 'Everyone'. -msg-20665ad1 = MarkdownV2 send failed: {$e}. Using plain text instead. -msg-323cb67c = [Telegram] 添加反应失败: {$e} -msg-abe7fc3d = 编辑消息失败(streaming-break): {$e} -msg-f7d40103 = 不支持的消息类型: {$res} -msg-d4b50a96 = 编辑消息失败(streaming): {$e} -msg-2701a78f = 发送消息失败(streaming): {$e} -msg-2a8ecebd = Markdown转换失败,使用普通文本: {$e} +msg-20665ad1 = MarkdownV2 send failed:{ $e }. Using plain text instead. +msg-323cb67c = [Telegram] Failed to add reaction:{ $e } +msg-abe7fc3d = Edit message failed(streaming-break):{ $e } +msg-f7d40103 = Unsupported message type:{ $res } +msg-d4b50a96 = Edit message failed (streaming):{ $e } +msg-2701a78f = Failed to send message (streaming):{ $e } +msg-2a8ecebd = Markdown conversion failed, using plain text:{ $e } ### astrbot/core/platform/sources/telegram/tg_adapter.py -msg-cb53f79a = Telegram base url: {$res} + +msg-cb53f79a = Telegram base url:{ $res } msg-e6b6040f = Telegram Updater is not initialized. Cannot start polling. msg-2c4b186e = Telegram Platform Adapter is running. -msg-908d0414 = 向 Telegram 注册指令时发生错误: {$e} -msg-d2dfe45e = 命令名 '{$cmd_name}' 重复注册,将使用首次注册的定义: '{$res}' +msg-908d0414 = Error occurred while registering command to Telegram:{ $e } +msg-d2dfe45e = Command name '{ $cmd_name }Duplicate registration, will use the first registration definition:{ $res }Text to translate: msg-63bdfab8 = Received a start command without an effective chat, skipping /start reply. -msg-03a27b01 = Telegram message: {$res} +msg-03a27b01 = Telegram message:{ $res } msg-e47b4bb4 = Received an update without a message. msg-c97401c6 = [Telegram] Received a message without a from_user. -msg-f5c839ee = Telegram document file_path is None, cannot save the file {$file_name}. -msg-dca991a9 = Telegram video file_path is None, cannot save the file {$file_name}. -msg-56fb2950 = Create media group cache: {$media_group_id} -msg-0de2d4b5 = Add message to media group {$media_group_id}, currently has {$res} items. -msg-9e5069e9 = Media group {$media_group_id} has reached max wait time ({$elapsed}s >= {$res}s), processing immediately. -msg-9156b9d6 = Scheduled media group {$media_group_id} to be processed in {$delay} seconds (already waited {$elapsed}s) -msg-2849c882 = Media group {$media_group_id} not found in cache -msg-c75b2163 = Media group {$media_group_id} is empty -msg-0a3626c1 = Processing media group {$media_group_id}, total {$res} items -msg-2842e389 = Failed to convert the first message of media group {$media_group_id} -msg-32fbf7c1 = Added {$res} components to media group {$media_group_id} +msg-f5c839ee = Telegram document file_path is None, cannot save the file{ $file_name }. +msg-dca991a9 = Telegram video file_path is None, cannot save the file{ $file_name }. +msg-56fb2950 = Create media group cache:{ $media_group_id } +msg-0de2d4b5 = Add message to media group{ $media_group_id }currently has{ $res }items. +msg-9e5069e9 = Media group{ $media_group_id }has reached max wait time ({ $elapsed }s >={ $res }s), processing immediately. +msg-9156b9d6 = Scheduled media group{ $media_group_id }to be processed in{ $delay }seconds (already waited{ $elapsed }s) +msg-2849c882 = Media group{ $media_group_id }not found in cache +msg-c75b2163 = Media group{ $media_group_id }is empty +msg-0a3626c1 = Processing media group{ $media_group_id }, total{ $res }items +msg-2842e389 = Failed to convert the first message of media group{ $media_group_id } +msg-32fbf7c1 = Added{ $res }Components to media group{ $media_group_id } msg-23bae28a = Telegram adapter has been closed. -msg-e46e7740 = Error occurred while closing Telegram adapter: {$e} +msg-e46e7740 = Error occurred while closing Telegram adapter:{ $e } ### astrbot/core/platform/sources/slack/client.py + msg-1d6b68b9 = Slack request signature verification failed -msg-53ef18c3 = Received Slack event: {$event_data} -msg-58488af6 = 处理 Slack 事件时出错: {$e} -msg-477be979 = Slack Webhook 服务器启动中,监听 {$res}:{$res_2}{$res_3}... -msg-639fee6c = Slack Webhook 服务器已停止 +msg-53ef18c3 = Received Slack event:{ $event_data } +msg-58488af6 = Error processing Slack event:{ $e } +msg-477be979 = Slack Webhook server is starting, listening{ $res }Text to be translated:{ $res_2 }{ $res_3 }... +msg-639fee6c = Slack Webhook server has stopped msg-a238d798 = Socket client is not initialized -msg-4e6de580 = 处理 Socket Mode 事件时出错: {$e} -msg-5bb71de9 = Slack Socket Mode 客户端启动中... -msg-f79ed37f = Slack Socket Mode 客户端已停止 +msg-4e6de580 = Error occurred while handling Socket Mode event:{ $e } +msg-5bb71de9 = Slack Socket Mode client is starting... +msg-f79ed37f = Slack Socket Mode client has stopped ### astrbot/core/platform/sources/slack/slack_adapter.py -msg-c34657ff = Slack bot_token 是必需的 -msg-64f8a45d = Socket Mode 需要 app_token -msg-a2aba1a7 = Webhook Mode 需要 signing_secret -msg-40e00bd4 = Slack 发送消息失败: {$e} -msg-56c1d0a3 = [slack] RawMessage {$event} -msg-855510b4 = Failed to download slack file: {$res} {$res_2} -msg-04ab2fae = 下载文件失败: {$res} -msg-79ed7e65 = Slack auth test OK. Bot ID: {$res} -msg-ec27746a = Slack 适配器 (Socket Mode) 启动中... -msg-34222d3a = Slack 适配器 (Webhook Mode) 启动中,监听 {$res}:{$res_2}{$res_3}... -msg-6d8110d2 = 不支持的连接模式: {$res},请使用 'socket' 或 'webhook' -msg-d71e7f36 = Slack 适配器已被关闭 + +msg-c34657ff = The Slack bot_token is required. +msg-64f8a45d = Socket Mode requires an app_token +msg-a2aba1a7 = Webhook Mode requires signing_secret +msg-40e00bd4 = Failed to send Slack message:{ $e } +msg-56c1d0a3 = [slack] RawMessage{ $event } +msg-855510b4 = Failed to download Slack file:{ $res } { $res_2 } +msg-04ab2fae = Failed to download file:{ $res } +msg-79ed7e65 = Slack auth test OK. Bot ID:{ $res } +msg-ec27746a = Slack Adapter (Socket Mode) is starting... +msg-34222d3a = Slack Adapter (Webhook Mode) Starting, Listening{ $res }Text to be translated:{ $res_2 }{ $res_3 }... +msg-6d8110d2 = Unsupported connection mode:{ $res }, please use 'socket' or 'webhook' +msg-d71e7f36 = Slack adapter has been closed. ### astrbot/core/platform/sources/slack/slack_event.py -msg-b233107c = Slack file upload failed: {$res} -msg-596945d1 = Slack file upload response: {$response} + +msg-b233107c = Slack file upload failed:{ $res } +msg-596945d1 = Slack file upload response:{ $response } ### astrbot/core/platform/sources/satori/satori_adapter.py -msg-ab7db6d9 = Satori WebSocket 连接关闭: {$e} -msg-4ef42cd1 = Satori WebSocket 连接失败: {$e} -msg-b50d159b = 达到最大重试次数 ({$max_retries}),停止重试 -msg-89de477c = Satori 适配器正在连接到 WebSocket: {$res} -msg-cfa5b059 = Satori 适配器 HTTP API 地址: {$res} -msg-d534864b = 无效的WebSocket URL: {$res} -msg-a110f9f7 = WebSocket URL必须以ws://或wss://开头: {$res} -msg-bf43ccb6 = Satori 处理消息异常: {$e} -msg-89081a1a = Satori WebSocket 连接异常: {$e} -msg-5c04bfcd = Satori WebSocket 关闭异常: {$e} -msg-b67bcee0 = WebSocket连接未建立 -msg-89ea8b76 = WebSocket连接已关闭 -msg-4c8a40e3 = 发送 IDENTIFY 信令时连接关闭: {$e} -msg-05a6b99d = 发送 IDENTIFY 信令失败: {$e} -msg-c9b1b774 = Satori WebSocket 发送心跳失败: {$e} -msg-61edb4f3 = 心跳任务异常: {$e} -msg-7db44899 = Satori 连接成功 - Bot {$res}: platform={$platform}, user_id={$user_id}, user_name={$user_name} -msg-01564612 = 解析 WebSocket 消息失败: {$e}, 消息内容: {$message} -msg-3a1657ea = 处理 WebSocket 消息异常: {$e} -msg-dc6b459c = 处理事件失败: {$e} -msg-6524f582 = 解析标签时发生错误: {$e}, 错误内容: {$content} -msg-3be535c3 = 转换 Satori 消息失败: {$e} -msg-be17caf1 = XML解析失败,使用正则提取: {$e} -msg-f6f41d74 = 提取标签时发生错误: {$e} -msg-ca6dca7f = 转换引用消息失败: {$e} -msg-cd3b067e = 解析 Satori 元素时发生解析错误: {$e}, 错误内容: {$content} -msg-03071274 = 解析 Satori 元素时发生未知错误: {$e} -msg-775cd5c0 = HTTP session 未初始化 -msg-e354c8d1 = Satori HTTP 请求异常: {$e} + +msg-ab7db6d9 = Satori WebSocket connection closed:{ $e } +msg-4ef42cd1 = Satori WebSocket connection failed:{ $e } +msg-b50d159b = Maximum retry count reached ({ $max_retries }),stop retrying +msg-89de477c = Satori adapter is connecting to WebSocket:{ $res } +msg-cfa5b059 = Satori Adapter HTTP API Address:{ $res } +msg-d534864b = Invalid WebSocket URL:{ $res } +msg-a110f9f7 = WebSocket URL must start with ws:// or wss://{ $res } +msg-bf43ccb6 = Satori encountered an error while processing the message:{ $e } +msg-89081a1a = Satori WebSocket connection exception:{ $e } +msg-5c04bfcd = Satori WebSocket closed abnormally:{ $e } +msg-b67bcee0 = WebSocket connection not established +msg-89ea8b76 = WebSocket connection has been closed +msg-4c8a40e3 = Connection closed while sending IDENTIFY signal:{ $e } +msg-05a6b99d = Failed to send IDENTIFY signal:{ $e } +msg-c9b1b774 = Satori WebSocket heartbeat sending failed:{ $e } +msg-61edb4f3 = Heartbeat task exception:{ $e } +msg-7db44899 = Satori Connection Successful - Bot{ $res }platform={ $platform }, user_id={ $user_id }, user_name={ $user_name } +msg-01564612 = Failed to parse WebSocket message:{ $e }, Message content:{ $message } +msg-3a1657ea = Exception processing WebSocket message:{ $e } +msg-dc6b459c = Processing event failed:{ $e } +msg-6524f582 = Error occurred while parsing tag:{ $e }, Error content:{ $content } +msg-3be535c3 = Failed to convert Satori message:{ $e } +msg-be17caf1 = XML parsing failed, using regex extraction:{ $e } +msg-f6f41d74 = Error occurred when extracting tags:{ $e } +msg-ca6dca7f = Failed to convert reference message:{ $e } +msg-cd3b067e = Parsing error occurred while parsing Satori element:{ $e }, Error content:{ $content } +msg-03071274 = An unknown error occurred while parsing the Satori element:{ $e } +msg-775cd5c0 = HTTP session is not initialized +msg-e354c8d1 = Satori HTTP request exception:{ $e } ### astrbot/core/platform/sources/satori/satori_event.py -msg-c063ab8a = Satori 消息发送异常: {$e} -msg-9bc42a8d = Satori 消息发送失败 -msg-dbf77ca2 = 图片转换为base64失败: {$e} -msg-8b6100fb = Satori 流式消息发送异常: {$e} -msg-3c16c45c = 语音转换为base64失败: {$e} -msg-66994127 = 视频文件转换失败: {$e} -msg-30943570 = 转换消息组件失败: {$e} -msg-3e8181fc = 转换转发节点失败: {$e} -msg-d626f831 = 转换合并转发消息失败: {$e} + +msg-c063ab8a = Satori message sending exception:{ $e } +msg-9bc42a8d = Satori message sending failed +msg-dbf77ca2 = Failed to convert image to base64:{ $e } +msg-8b6100fb = Satori streaming message sending exception:{ $e } +msg-3c16c45c = Failed to convert voice to base64:{ $e } +msg-66994127 = Video file conversion failed:{ $e } +msg-30943570 = Failed to convert message component:{ $e } +msg-3e8181fc = Failed to convert forwarding node:{ $e } +msg-d626f831 = Failed to convert and forward the merged message:{ $e } ### astrbot/core/platform/sources/webchat/webchat_queue_mgr.py -msg-4af4f885 = Started listener for conversation: {$conversation_id} -msg-10237240 = Error processing message from conversation {$conversation_id}: {$e} + +msg-4af4f885 = Started listener for conversation:{ $conversation_id } +msg-10237240 = Error processing message from conversation{ $conversation_id }Text to be translated:{ $e } ### astrbot/core/platform/sources/webchat/webchat_adapter.py -msg-9406158c = WebChatAdapter: {$res} + +msg-9406158c = WebChatAdapter:{ $res } ### astrbot/core/platform/sources/webchat/webchat_event.py -msg-6b37adcd = webchat 忽略: {$res} + +msg-6b37adcd = webchat ignore:{ $res } ### astrbot/core/platform/sources/qqofficial/qqofficial_platform_adapter.py -msg-8af45ba1 = QQ 机器人官方 API 适配器不支持 send_by_session -msg-8ebd1249 = Unknown message type: {$message_type} -msg-c165744d = QQ 官方机器人接口 适配器已被优雅地关闭 + +msg-8af45ba1 = QQ Bot Official API Adapter does not support send_by_session +msg-8ebd1249 = Unknown message type:{ $message_type } +msg-c165744d = QQ Official Bot Interface Adapter has been gracefully shut down ### astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py + msg-28a74d9d = [QQOfficial] Skip botpy FormData patch. -msg-c0b123f6 = 发送流式消息时出错: {$e} -msg-05d6bba5 = [QQOfficial] 不支持的消息源类型: {$res} -msg-e5339577 = [QQOfficial] GroupMessage 缺少 group_openid -msg-71275806 = Message sent to C2C: {$ret} -msg-040e7942 = [QQOfficial] markdown 发送被拒绝,回退到 content 模式重试。 +msg-c0b123f6 = Error sending streaming message:{ $e } +msg-05d6bba5 = [QQOfficial] Unsupported message source type:{ $res } +msg-e5339577 = [QQOfficial] GroupMessage is missing group_openid +msg-71275806 = Message sent to C2C:{ $ret } +msg-040e7942 = [QQOfficial] markdown sending was rejected, falling back to content mode for retry. msg-9000f8f7 = Invalid upload parameters -msg-d72cffe7 = Failed to upload image, response is not dict: {$result} -msg-5944a27c = 上传文件响应格式错误: {$result} -msg-1e513ee5 = 上传请求错误: {$e} -msg-f1f1733c = Failed to post c2c message, response is not dict: {$result} +msg-d72cffe7 = Failed to upload image, response is not dict:{ $result } +msg-5944a27c = Upload file response format error:{ $result } +msg-1e513ee5 = Upload request error:{ $e } +msg-f1f1733c = Failed to post c2c message, response is not dict:{ $result } msg-9b8f9f70 = Unsupported image file format -msg-24eb302a = 转换音频格式时出错:音频时长不大于0 -msg-b49e55f9 = 处理语音时出错: {$e} -msg-6e716579 = qq_official 忽略 {$res} +msg-24eb302a = Error converting audio format: audio duration is not greater than 0 +msg-b49e55f9 = Error processing voice:{ $e } +msg-6e716579 = qq_official ignore{ $res } ### astrbot/core/provider/provider.py -msg-e6f0c96f = Provider type {$provider_type_name} not registered -msg-c7953e3f = 批次 {$batch_idx} 处理失败,已重试 {$max_retries} 次: {$e} -msg-10f72727 = {$error_msg} + +msg-e6f0c96f = Provider type{ $provider_type_name }not registered +msg-c7953e3f = Batch{ $batch_idx }Processing failed, retried{ $max_retries }Second:{ $e } +msg-10f72727 = { $error_msg } msg-7ff71721 = Rerank provider test failed, no results returned ### astrbot/core/provider/register.py -msg-19ddffc0 = 检测到大模型提供商适配器 {$provider_type_name} 已经注册,可能发生了大模型提供商适配器类型命名冲突。 -msg-7e134b0d = 服务提供商 Provider {$provider_type_name} 已注册 + +msg-19ddffc0 = Detected a large model provider adapter{ $provider_type_name }Already registered, possibly due to a naming conflict in the adapter type of the large model provider. +msg-7e134b0d = Service Provider{ $provider_type_name }Registered ### astrbot/core/provider/func_tool_manager.py -msg-0c42a4d9 = 添加函数调用工具: {$name} -msg-e8fdbb8c = 未找到 MCP 服务配置文件,已创建默认配置文件 {$mcp_json_file} -msg-cf8aed84 = 收到 MCP 客户端 {$name} 终止信号 -msg-3d7bcc64 = 初始化 MCP 客户端 {$name} 失败 -msg-1b190842 = MCP server {$name} list tools response: {$tools_res} -msg-6dc4f652 = 已连接 MCP 服务 {$name}, Tools: {$tool_names} -msg-a44aa4f2 = 清空 MCP 客户端资源 {$name}: {$e}。 -msg-e9c96c53 = 已关闭 MCP 服务 {$name} -msg-10f72727 = {$error_msg} -msg-85f156e0 = testing MCP server connection with config: {$config} + +msg-0c42a4d9 = Add function call tool:{ $name } +msg-e8fdbb8c = MCP service configuration file not found, a default configuration file has been created.{ $mcp_json_file } +msg-cf8aed84 = Received MCP client{ $name }Termination signal +msg-3d7bcc64 = Initializing MCP Client{ $name }Failed +msg-1b190842 = MCP server{ $name }list tools response:{ $tools_res } +msg-6dc4f652 = Connected to MCP service{ $name }, Tools:{ $tool_names } +msg-a44aa4f2 = Clear MCP client resources{ $name }Text to be translated:{ $e }. +msg-e9c96c53 = MCP service has been disabled.{ $name } +msg-10f72727 = { $error_msg } +msg-85f156e0 = Testing MCP server connection with config:{ $config } msg-93c54ce0 = Cleaning up MCP client after testing connection. -msg-368450ee = 此函数调用工具所属的插件 {$res} 已被禁用,请先在管理面板启用再激活此工具。 -msg-4ffa2135 = 加载 MCP 配置失败: {$e} -msg-a486ac39 = 保存 MCP 配置失败: {$e} -msg-58dfdfe7 = 从 ModelScope 同步了 {$synced_count} 个 MCP 服务器 -msg-75f1222f = 没有找到可用的 ModelScope MCP 服务器 -msg-c9f6cb1d = ModelScope API 请求失败: HTTP {$res} -msg-c8ebb4f7 = 网络连接错误: {$e} -msg-0ac6970f = 同步 ModelScope MCP 服务器时发生错误: {$e} +msg-368450ee = The plugin to which this function call tool belongs{ $res }Disabled. Please enable this tool in the admin panel first. +msg-4ffa2135 = Failed to load MCP configuration:{ $e } +msg-a486ac39 = Failed to save MCP configuration:{ $e } +msg-58dfdfe7 = Synchronized from ModelScope{ $synced_count }MCP Servers +msg-75f1222f = No available ModelScope MCP server found +msg-c9f6cb1d = ModelScope API request failed: HTTP{ $res } +msg-c8ebb4f7 = Network connection error:{ $e } +msg-0ac6970f = Error occurred while synchronizing ModelScope MCP server:{ $e } ### astrbot/core/provider/entities.py -msg-7fc6f623 = 图片 {$image_url} 得到的结果为空,将忽略。 + +msg-7fc6f623 = Image{ $image_url }The obtained result is empty and will be ignored. ### astrbot/core/provider/manager.py -msg-9e1a7f1f = 提供商 {$provider_id} 不存在,无法设置。 -msg-5fda2049 = Unknown provider type: {$provider_type} -msg-a5cb19c6 = 没有找到 ID 为 {$provider_id} 的提供商,这可能是由于您修改了提供商(模型)ID 导致的。 -msg-78b9c276 = {$res} -msg-5bdf8f5c = {$e} -msg-b734a1f4 = Provider {$provider_id} 配置项 key[{$idx}] 使用环境变量 {$env_key} 但未设置。 -msg-664b3329 = Provider {$res} is disabled, skipping -msg-f43f8022 = 载入 {$res}({$res_2}) 服务提供商 ... -msg-edd4aefe = 加载 {$res}({$res_2}) 提供商适配器失败:{$e}。可能是因为有未安装的依赖。 -msg-78e514a1 = 加载 {$res}({$res_2}) 提供商适配器失败:{$e}。未知原因 -msg-4636f83c = 未找到适用于 {$res}({$res_2}) 的提供商适配器,请检查是否已经安装或者名称填写错误。已跳过。 -msg-e9c6c4a2 = 无法找到 {$res} 的类 -msg-f705cf50 = Provider class {$cls_type} is not a subclass of STTProvider -msg-d20620aa = 已选择 {$res}({$res_2}) 作为当前语音转文本提供商适配器。 -msg-afbe5661 = Provider class {$cls_type} is not a subclass of TTSProvider -msg-74d437ed = 已选择 {$res}({$res_2}) 作为当前文本转语音提供商适配器。 -msg-08cd85c9 = Provider class {$cls_type} is not a subclass of Provider -msg-16a2b8e0 = 已选择 {$res}({$res_2}) 作为当前提供商适配器。 -msg-0e1707e7 = Provider class {$cls_type} is not a subclass of EmbeddingProvider -msg-821d06e0 = Provider class {$cls_type} is not a subclass of RerankProvider -msg-14c35664 = 未知的提供商类型:{$res} -msg-186fd5c6 = 实例化 {$res}({$res_2}) 提供商适配器失败:{$e} -msg-ede02a99 = providers in user's config: {$config_ids} -msg-95dc4227 = 自动选择 {$res} 作为当前提供商适配器。 -msg-a6187bac = 自动选择 {$res} 作为当前语音转文本提供商适配器。 -msg-bf28f7e2 = 自动选择 {$res} 作为当前文本转语音提供商适配器。 -msg-dba10c27 = 终止 {$provider_id} 提供商适配器({$res}, {$res_2}, {$res_3}) ... -msg-9d9d9765 = {$provider_id} 提供商适配器已终止({$res}, {$res_2}, {$res_3}) -msg-925bb70a = Provider {$target_prov_ids} 已从配置中删除。 + +msg-9e1a7f1f = Provider{ $provider_id }Does not exist, cannot be set. +msg-5fda2049 = Unknown provider type:{ $provider_type } +msg-a5cb19c6 = No ID found for{ $provider_id }The provider, which might be due to you having modified the provider (model) ID. +msg-78b9c276 = { $res } +msg-5bdf8f5c = { $e } +msg-b734a1f4 = Provider{ $provider_id }Configuration item key[{ $idx }] Use environment variables{ $env_key }but not set. +msg-664b3329 = Provider{ $res }is disabled, skipping +msg-f43f8022 = Loading{ $res }Text to translate: ({ $res_2 }Service Provider ... +msg-edd4aefe = Loading{ $res }({ $res_2 }) Provider adapter failed:{ $e }It might be due to uninstalled dependencies. +msg-78e514a1 = Loading{ $res }({ $res_2 }) Provider adapter failed:{ $e }Unknown reason +msg-4636f83c = No applicable{ $res }Text to translate:{ $res_2 }) provider adapter, please check if it is already installed or if the name is entered incorrectly. Skipped. +msg-e9c6c4a2 = Unable to find{ $res }class +msg-f705cf50 = Provider class{ $cls_type }is not a subclass of STTProvider +msg-d20620aa = Selected{ $res }Text to be translated:{ $res_2 }) as the current speech-to-text provider adapter. +msg-afbe5661 = Provider class{ $cls_type }is not a subclass of TTSProvider +msg-74d437ed = Selected{ $res }Text to translate:{ $res_2 }) as the current text-to-speech provider adapter. +msg-08cd85c9 = Provider class{ $cls_type }is not a subclass of Provider +msg-16a2b8e0 = Selected{ $res }({ $res_2 }) as the current provider adapter. +msg-0e1707e7 = Provider class{ $cls_type }is not a subclass of EmbeddingProvider +msg-821d06e0 = Provider class{ $cls_type }is not a subclass of RerankProvider +msg-14c35664 = Unknown provider type:{ $res } +msg-186fd5c6 = Instantiate{ $res }Text to translate: ({ $res_2 }) Provider adapter failed:{ $e } +msg-ede02a99 = providers in user's config:{ $config_ids } +msg-95dc4227 = Auto-select{ $res }As the current provider adapter. +msg-a6187bac = Auto-select{ $res }As the current speech-to-text provider adapter. +msg-bf28f7e2 = Auto-select{ $res }As the current text-to-speech provider adapter. +msg-dba10c27 = Terminate{ $provider_id }Provider adapter ({ $res }{ $res_2 }待翻译文本:{ $res_3 }) ... +msg-9d9d9765 = { $provider_id }Provider adapter has terminated ({ $res }{ $res_2 },{ $res_3 }) +msg-925bb70a = Provider{ $target_prov_ids }Removed from configuration. msg-a1657092 = New provider config must have an 'id' field -msg-1486c653 = Provider ID {$npid} already exists -msg-f9fc1545 = Provider ID {$origin_provider_id} not found +msg-1486c653 = Provider ID{ $npid }already exists +msg-f9fc1545 = Provider ID{ $origin_provider_id }not found msg-4e2c657c = Error while disabling MCP servers ### astrbot/core/provider/sources/gemini_embedding_source.py -msg-173efb0e = [Gemini Embedding] 使用代理: {$proxy} -msg-58a99789 = Gemini Embedding API请求失败: {$res} -msg-5c4ea38e = Gemini Embedding API批量请求失败: {$res} + +msg-173efb0e = [Gemini Embedding] Using proxy:{ $proxy } +msg-58a99789 = Gemini Embedding API request failed:{ $res } +msg-5c4ea38e = Gemini Embedding API batch request failed:{ $res } ### astrbot/core/provider/sources/bailian_rerank_source.py -msg-dc1a9e6e = 阿里云百炼 API Key 不能为空。 -msg-f7079f37 = AstrBot 百炼 Rerank 初始化完成。模型: {$res} -msg-5b6d35ce = 百炼 API 错误: {$res} – {$res_2} -msg-d600c5e2 = 百炼 Rerank 返回空结果: {$data} -msg-d3312319 = 结果 {$idx} 缺少 relevance_score,使用默认值 0.0 -msg-2855fb44 = 解析结果 {$idx} 时出错: {$e}, result={$result} -msg-392f26e8 = 百炼 Rerank 消耗 Token: {$tokens} -msg-595e0cf9 = 百炼 Rerank 客户端会话已关闭,返回空结果 -msg-d0388210 = 文档列表为空,返回空结果 -msg-44d6cc76 = 查询文本为空,返回空结果 -msg-bd8b942a = 文档数量({$res})超过限制(500),将截断前500个文档 -msg-0dc3bca4 = 百炼 Rerank 请求: query='{$res}...', 文档数量={$res_2} -msg-4a9f4ee3 = 百炼 Rerank 成功返回 {$res} 个结果 -msg-fa301307 = 百炼 Rerank 网络请求失败: {$e} -msg-10f72727 = {$error_msg} -msg-9879e226 = 百炼 Rerank 处理失败: {$e} -msg-4f15074c = 关闭 百炼 Rerank 客户端会话 -msg-d01b1b0f = 关闭 百炼 Rerank 客户端时出错: {$e} + +msg-dc1a9e6e = Alibaba Cloud Bailian API Key cannot be empty. +msg-f7079f37 = AstrBot Hundred Refinements Rerank initialization complete. Model:{ $res } +msg-5b6d35ce = Bailian API Error:{ $res }待翻译文本:{ $res_2 } +msg-d600c5e2 = Bailian Rerank returns empty results:{ $data } +msg-d3312319 = Result{ $idx }Missing relevance_score, using default value 0.0 +msg-2855fb44 = Analysis Result{ $idx }Error occurred:{ $e }, result={ $result } +msg-392f26e8 = Bailian Rerank Token Consumption:{ $tokens } +msg-595e0cf9 = Bailian Rerank client session has been closed, returning empty result. +msg-d0388210 = Document list is empty, returning empty result +msg-44d6cc76 = Query text is empty, returning empty results +msg-bd8b942a = Number of Documents({ $res }) exceeds limit (500), will truncate first 500 documents +msg-0dc3bca4 = Bailian Rerank request: query='{ $res }..., document count={ $res_2 } +msg-4a9f4ee3 = Bailian Rerank returned successfully{ $res }result +msg-fa301307 = Bailian Rerank network request failed:{ $e } +msg-10f72727 = { $error_msg } +msg-9879e226 = Bailian Rerank processing failed:{ $e } +msg-4f15074c = Close Baichuan Rerank client session +msg-d01b1b0f = Error closing the Baichuan Rerank client:{ $e } ### astrbot/core/provider/sources/edge_tts_source.py -msg-f4ab0713 = pyffmpeg 转换失败: {$e}, 尝试使用 ffmpeg 命令行进行转换 -msg-ddc3594a = [EdgeTTS] FFmpeg 标准输出: {$res} -msg-1b8c0a83 = FFmpeg错误输出: {$res} -msg-1e980a68 = [EdgeTTS] 返回值(0代表成功): {$res} -msg-c39d210c = 生成的WAV文件不存在或为空 -msg-57f60837 = FFmpeg 转换失败: {$res} -msg-ca94a42a = FFmpeg 转换失败: {$e} -msg-be660d63 = 音频生成失败: {$e} + +msg-f4ab0713 = pyffmpeg conversion failed:{ $e }, try using the ffmpeg command line for conversion +msg-ddc3594a = [EdgeTTS] FFmpeg standard output:{ $res } +msg-1b8c0a83 = FFmpeg error output:{ $res } +msg-1e980a68 = [EdgeTTS] Return value (0 for success):{ $res } +msg-c39d210c = The generated WAV file does not exist or is empty. +msg-57f60837 = FFmpeg conversion failed:{ $res } +msg-ca94a42a = FFmpeg conversion failed:{ $e } +msg-be660d63 = Audio generation failed:{ $e } ### astrbot/core/provider/sources/whisper_api_source.py -msg-28cbbf07 = 文件不存在: {$audio_url} + +msg-28cbbf07 = File does not exist:{ $audio_url } msg-b335b8db = Converting silk file to wav using tencent_silk_to_wav... msg-68b5660f = Converting amr file to wav using convert_to_pcm_wav... -msg-cad3735e = Failed to remove temp file {$audio_url}: {$e} +msg-cad3735e = Failed to remove temp file{ $audio_url }Text to be translated:{ $e } ### astrbot/core/provider/sources/gemini_source.py -msg-1474947f = [Gemini] 使用代理: {$proxy} -msg-e2a81024 = 检测到 Key 异常({$res}),正在尝试更换 API Key 重试... 当前 Key: {$res_2}... -msg-0d388dae = 检测到 Key 异常({$res}),且已没有可用的 Key。 当前 Key: {$res_2}... -msg-1465290c = 达到了 Gemini 速率限制, 请稍后再试... -msg-7e9c01ca = 流式输出不支持图片模态,已自动降级为文本模态 -msg-89bac423 = 代码执行工具与搜索工具互斥,已忽略搜索工具 -msg-301cf76e = 代码执行工具与URL上下文工具互斥,已忽略URL上下文工具 -msg-356e7b28 = 当前 SDK 版本不支持 URL 上下文工具,已忽略该设置,请升级 google-genai 包 -msg-7d4e7d48 = gemini-2.0-lite 不支持代码执行、搜索工具和URL上下文,将忽略这些设置 -msg-cc5c666f = 已启用原生工具,函数工具将被忽略 -msg-aa7c77a5 = Invalid thinking level: {$thinking_level}, using HIGH -msg-59e1e769 = 文本内容为空,已添加空格占位 -msg-34c5c910 = Failed to decode google gemini thinking signature: {$e} -msg-a2357584 = assistant 角色的消息内容为空,已添加空格占位 -msg-f627f75d = 检测到启用Gemini原生工具,且上下文中存在函数调用,建议使用 /reset 重置上下文 -msg-cb743183 = 收到的 candidate.content 为空: {$candidate} -msg-34b367fc = API 返回的 candidate.content 为空。 -msg-73541852 = 模型生成内容未通过 Gemini 平台的安全检查 -msg-ae3cdcea = 模型生成内容违反 Gemini 平台政策 -msg-5d8f1711 = 收到的 candidate.content.parts 为空: {$candidate} -msg-57847bd5 = API 返回的 candidate.content.parts 为空。 -msg-a56c85e4 = genai result: {$result} -msg-42fc0767 = 请求失败, 返回的 candidates 为空: {$result} -msg-faf3a0dd = 请求失败, 返回的 candidates 为空。 -msg-cd690916 = 温度参数已超过最大值2,仍然发生recitation -msg-632e23d7 = 发生了recitation,正在提高温度至{$temperature}重试... -msg-41ff84bc = {$model} 不支持 system prompt,已自动去除(影响人格设置) -msg-ef9512f7 = {$model} 不支持函数调用,已自动去除 -msg-fde41b1d = {$model} 不支持多模态输出,降级为文本模态 -msg-4e168d67 = 收到的 chunk 中 candidates 为空: {$chunk} -msg-11af7d46 = 收到的 chunk 中 content 为空: {$chunk} -msg-8836d4a2 = 请求失败。 -msg-757d3828 = 获取模型列表失败: {$res} -msg-7fc6f623 = 图片 {$image_url} 得到的结果为空,将忽略。 -msg-0b041916 = 不支持的额外内容块类型: {$res} + +msg-1474947f = [Gemini] Using Proxy:{ $proxy } +msg-e2a81024 = Key anomaly detected({ $res }),Trying to change API Key and retry... Current Key:{ $res_2 }... +msg-0d388dae = Detected Key anomaly({ $res }), and no more Keys are available. Current Key:{ $res_2 }... +msg-1465290c = Reached Gemini rate limit, please try again later... +msg-7e9c01ca = Streaming output does not support image modality and has been automatically downgraded to text modality. +msg-89bac423 = Code execution tool and search tool are mutually exclusive, search tool has been ignored. +msg-301cf76e = The code execution tool and the URL context tool are mutually exclusive. The URL context tool has been ignored. +msg-356e7b28 = Current SDK version does not support the URL context tool; this setting has been ignored. Please upgrade the google-genai package. +msg-7d4e7d48 = gemini-2.0-lite does not support code execution, search tools, and URL context; these settings will be ignored. +msg-cc5c666f = Native tools are enabled, function tools will be ignored. +msg-aa7c77a5 = Invalid thinking level:{ $thinking_level }, using HIGH +msg-59e1e769 = The text content is empty, placeholder space has been added +msg-34c5c910 = Failed to decode google gemini thinking signature:{ $e } +msg-a2357584 = The message content of the assistant role is empty; a space placeholder has been added. +msg-f627f75d = Detected that Gemini native tools are enabled and there are function calls in the context. It is recommended to use /reset to reset the context. +msg-cb743183 = Received candidate.content is empty:{ $candidate } +msg-34b367fc = The candidate.content returned by the API is empty. +msg-73541852 = The model-generated content failed the safety check on the Gemini platform. +msg-ae3cdcea = Model-generated content violates Gemini platform policies +msg-5d8f1711 = The received candidate.content.parts is empty:{ $candidate } +msg-57847bd5 = The candidate.content.parts returned by the API is empty. +msg-a56c85e4 = genai result:{ $result } +msg-42fc0767 = Request failed, returned candidates are empty:{ $result } +msg-faf3a0dd = Request failed, the returned candidates are empty. +msg-cd690916 = The temperature parameter has exceeded the maximum value of 2, yet recitation still occurred. +msg-632e23d7 = Recitation occurred, increasing temperature to{ $temperature }Retry... +msg-41ff84bc = { $model }System prompt not supported, automatically removed (affects persona settings). +msg-ef9512f7 = { $model }Function calls are not supported and have been automatically removed. +msg-fde41b1d = { $model }Multimodal output is not supported, downgraded to text mode. +msg-4e168d67 = Received chunk has empty candidates:{ $chunk } +msg-11af7d46 = Received chunk content is empty:{ $chunk } +msg-8836d4a2 = Request failed. +msg-757d3828 = Failed to get model list:{ $res } +msg-7fc6f623 = Image{ $image_url }The result obtained is empty and will be ignored. +msg-0b041916 = Unsupported additional content block type:{ $res } ### astrbot/core/provider/sources/gsvi_tts_source.py -msg-520e410f = GSVI TTS API 请求失败,状态码: {$res},错误: {$error_text} + +msg-520e410f = GSVI TTS API request failed, status code:{ $res }Error:{ $error_text } ### astrbot/core/provider/sources/anthropic_source.py -msg-d6b1df6e = Failed to parse image data URI: {$res}... -msg-6c2c0426 = Unsupported image URL format for Anthropic: {$res}... -msg-999f7680 = completion: {$completion} -msg-8d2c43ec = API 返回的 completion 为空。 -msg-26140afc = Anthropic API 返回的 completion 无法解析:{$completion}。 -msg-8e4c8c24 = 工具调用参数 JSON 解析失败: {$tool_info} -msg-7fc6f623 = 图片 {$image_url} 得到的结果为空,将忽略。 -msg-0b041916 = 不支持的额外内容块类型: {$res} + +msg-d6b1df6e = Failed to parse image data URI:{ $res }... +msg-6c2c0426 = Unsupported image URL format for Anthropic:{ $res }... +msg-999f7680 = completion:{ $completion } +msg-8d2c43ec = The API returned an empty completion. +msg-26140afc = Failed to parse the completion returned by the Anthropic API:{ $completion }Text to be translated: +msg-8e4c8c24 = Tool call parameter JSON parsing failed:{ $tool_info } +msg-7fc6f623 = Image{ $image_url }The obtained result is empty and will be ignored. +msg-0b041916 = Unsupported additional content block type:{ $res } ### astrbot/core/provider/sources/openai_source.py -msg-bbb399f6 = 检测到图片请求失败(%s),已移除图片并重试(保留文本内容)。 -msg-d6f6a3c2 = 获取模型列表失败:{$e} -msg-1f850e09 = API 返回的 completion 类型错误:{$res}: {$completion}。 -msg-999f7680 = completion: {$completion} -msg-844635f7 = Unexpected dict format content: {$raw_content} -msg-8d2c43ec = API 返回的 completion 为空。 -msg-87d75331 = {$completion_text} -msg-0614efaf = 工具集未提供 -msg-c46f067a = API 返回的 completion 由于内容安全过滤被拒绝(非 AstrBot)。 -msg-647f0002 = API 返回的 completion 无法解析:{$completion}。 -msg-5cc50a15 = API 调用过于频繁,尝试使用其他 Key 重试。当前 Key: {$res} -msg-c4e639eb = 上下文长度超过限制。尝试弹出最早的记录然后重试。当前记录条数: {$res} -msg-5f8be4fb = {$res} 不支持函数工具调用,已自动去除,不影响使用。 -msg-45591836 = 疑似该模型不支持函数调用工具调用。请输入 /tool off_all -msg-6e47d22a = API 调用失败,重试 {$max_retries} 次仍然失败。 -msg-974e7484 = 未知错误 -msg-7fc6f623 = 图片 {$image_url} 得到的结果为空,将忽略。 -msg-0b041916 = 不支持的额外内容块类型: {$res} + +msg-bbb399f6 = Image request failed (%s) detected, image removed and retried (text content preserved). +msg-d6f6a3c2 = Failed to retrieve model list:{ $e } +msg-1f850e09 = The API returned an incorrect completion type:{ $res }Text to translate:{ $completion }Text to be translated: . +msg-999f7680 = completion:{ $completion } +msg-844635f7 = Unexpected dict format content:{ $raw_content } +msg-8d2c43ec = The API returned an empty completion. +msg-87d75331 = { $completion_text } +msg-0614efaf = Toolset not provided +msg-c46f067a = The completion returned by the API was rejected due to content security filtering (not AstrBot). +msg-647f0002 = The completion returned by the API cannot be parsed:{ $completion }. +msg-5cc50a15 = API calls are too frequent, try using another key to retry. Current Key:{ $res } +msg-c4e639eb = Context length exceeds the limit. Try popping the earliest record and retry. Current record count:{ $res } +msg-5f8be4fb = { $res }Function tool calls are not supported; they have been automatically removed and will not affect usage. +msg-45591836 = The model does not seem to support function calls or tool invocation. Please enter /tool off_all +msg-6e47d22a = API call failed, retrying{ $max_retries }Failed again. +msg-974e7484 = Unknown error +msg-7fc6f623 = Image{ $image_url }The result is empty and will be ignored. +msg-0b041916 = Unsupported extra content block type:{ $res } ### astrbot/core/provider/sources/gemini_tts_source.py -msg-29fe386a = [Gemini TTS] 使用代理: {$proxy} + +msg-29fe386a = [Gemini TTS] Using proxy:{ $proxy } msg-012edfe1 = No audio content returned from Gemini TTS API. ### astrbot/core/provider/sources/genie_tts.py + msg-583dd8a6 = Please install genie_tts first. -msg-935222b4 = Failed to load character {$res}: {$e} +msg-935222b4 = Failed to load character{ $res }Text to be translated:{ $e } msg-a6886f9e = Genie TTS did not save to file. -msg-e3587d60 = Genie TTS generation failed: {$e} -msg-3303e3a8 = Genie TTS failed to generate audio for: {$text} -msg-1cfe1af1 = Genie TTS stream error: {$e} +msg-e3587d60 = Genie TTS generation failed:{ $e } +msg-3303e3a8 = Genie TTS failed to generate audio for:{ $text } +msg-1cfe1af1 = Genie TTS stream error:{ $e } ### astrbot/core/provider/sources/dashscope_tts.py + msg-f23d2372 = Dashscope TTS model is not configured. msg-74a7cc0a = Audio synthesis failed, returned empty content. The model may not be supported or the service is unavailable. -msg-bc8619d3 = dashscope SDK missing MultiModalConversation. Please upgrade the dashscope package to use Qwen TTS models. +msg-bc8619d3 = The dashscope SDK is missing MultiModalConversation. Please upgrade the dashscope package to use Qwen TTS models. msg-95bbf71e = No voice specified for Qwen TTS model, using default 'Cherry'. -msg-3c35d2d0 = Audio synthesis failed for model '{$model}'. {$response} +msg-3c35d2d0 = Audio synthesis failed for model '{ $model }'.{ $response } msg-16dc3b00 = Failed to decode base64 audio data. -msg-26603085 = Failed to download audio from URL {$url}: {$e} -msg-78b9c276 = {$res} +msg-26603085 = Failed to download audio from URL{ $url }Text to be translated:{ $e } +msg-78b9c276 = { $res } ### astrbot/core/provider/sources/whisper_selfhosted_source.py -msg-27fda50a = 下载或者加载 Whisper 模型中,这可能需要一些时间 ... -msg-4e70f563 = Whisper 模型加载完成。 -msg-28cbbf07 = 文件不存在: {$audio_url} + +msg-27fda50a = Downloading or loading the Whisper model, which may take some time... +msg-4e70f563 = Whisper model loading completed. +msg-28cbbf07 = File does not exist:{ $audio_url } msg-d98780e5 = Converting silk file to wav ... -msg-e3e1215c = Whisper 模型未初始化 +msg-e3e1215c = Whisper model not initialized ### astrbot/core/provider/sources/openai_tts_api_source.py -msg-d7084760 = [OpenAI TTS] 使用代理: {$proxy} + +msg-d7084760 = [OpenAI TTS] Using proxy:{ $proxy } ### astrbot/core/provider/sources/xinference_rerank_source.py + msg-1ec1e6e4 = Xinference Rerank: Using API key for authentication. msg-7bcb6e1b = Xinference Rerank: No API key provided. -msg-b0d1e564 = Model '{$res}' is already running with UID: {$uid} -msg-16965859 = Launching {$res} model... +msg-b0d1e564 = Model '{ $res }' is already running with UID:{ $uid } +msg-16965859 = Launching{ $res }model... msg-7b1dfdd3 = Model launched. -msg-3fc7310e = Model '{$res}' is not running and auto-launch is disabled. Provider will not be available. -msg-15f19a42 = Failed to initialize Xinference model: {$e} -msg-01af1651 = Xinference initialization failed with exception: {$e} +msg-3fc7310e = Model{ $res }' is not running and auto-launch is disabled. Provider will not be available. +msg-15f19a42 = Failed to initialize Xinference model:{ $e } +msg-01af1651 = Xinference initialization failed with exception:{ $e } msg-2607cc7a = Xinference rerank model is not initialized. -msg-3d28173b = Rerank API response: {$response} -msg-4c63e1bd = Rerank API returned an empty list. Original response: {$response} -msg-cac71506 = Xinference rerank failed: {$e} -msg-4135cf72 = Xinference rerank failed with exception: {$e} +msg-3d28173b = Rerank API response:{ $response } +msg-4c63e1bd = Rerank API returned an empty list. Original response:{ $response } +msg-cac71506 = Xinference rerank failed:{ $e } +msg-4135cf72 = Xinference rerank failed with exception:{ $e } msg-ea2b36d0 = Closing Xinference rerank client... -msg-633a269f = Failed to close Xinference client: {$e} +msg-633a269f = Failed to close Xinference client:{ $e } ### astrbot/core/provider/sources/minimax_tts_api_source.py + msg-77c88c8a = Failed to parse JSON data from SSE message -msg-7873b87b = MiniMax TTS API请求失败: {$e} +msg-7873b87b = MiniMax TTS API request failed:{ $e } ### astrbot/core/provider/sources/azure_tts_source.py -msg-93d9b5cf = [Azure TTS] 使用代理: {$res} + +msg-93d9b5cf = [Azure TTS] Using proxy:{ $res } msg-9eea5bcb = Client not initialized. Please use 'async with' context. -msg-fd53d21d = 时间同步失败 -msg-77890ac4 = OTTS请求失败: {$e} -msg-c6ec6ec7 = OTTS未返回音频文件 -msg-5ad71900 = 无效的Azure订阅密钥 -msg-6416da27 = [Azure TTS Native] 使用代理: {$res} -msg-15c55ed8 = 无效的other[...]格式,应形如 other[{...}] -msg-90b31925 = 缺少OTTS参数: {$res} -msg-10f72727 = {$error_msg} -msg-60b044ea = 配置错误: 缺少必要参数 {$e} -msg-5c7dee08 = 订阅密钥格式无效,应为32位字母数字或other[...]格式 +msg-fd53d21d = Time synchronization failed +msg-77890ac4 = OTTS request failed:{ $e } +msg-c6ec6ec7 = OTTS did not return an audio file +msg-5ad71900 = Invalid Azure subscription key +msg-6416da27 = [Azure TTS Native] Using proxy:{ $res } +msg-90b31925 = Missing OTTS parameter:{ $res } +msg-10f72727 = { $error_msg } +msg-60b044ea = Configuration error: Missing required parameters{ $e } +msg-5c7dee08 = The subscription key format is invalid, it should be a 32-character alphanumeric or other[...] format. ### astrbot/core/provider/sources/openai_embedding_source.py -msg-cecb2fbc = [OpenAI Embedding] 使用代理: {$proxy} + +msg-cecb2fbc = [OpenAI Embedding] Using proxy:{ $proxy } ### astrbot/core/provider/sources/vllm_rerank_source.py -msg-6f160342 = Rerank API 返回了空的列表数据。原始响应: {$response_data} + +msg-6f160342 = Rerank API returned an empty list data. Original response:{ $response_data } ### astrbot/core/provider/sources/xinference_stt_provider.py + msg-4e31e089 = Xinference STT: Using API key for authentication. msg-e291704e = Xinference STT: No API key provided. -msg-b0d1e564 = Model '{$res}' is already running with UID: {$uid} -msg-16965859 = Launching {$res} model... +msg-b0d1e564 = Model{ $res }' is already running with UID:{ $uid } +msg-16965859 = Launching{ $res }model... msg-7b1dfdd3 = Model launched. -msg-3fc7310e = Model '{$res}' is not running and auto-launch is disabled. Provider will not be available. -msg-15f19a42 = Failed to initialize Xinference model: {$e} -msg-01af1651 = Xinference initialization failed with exception: {$e} +msg-3fc7310e = Model{ $res }' is not running and auto-launch is disabled. Provider will not be available. +msg-15f19a42 = Failed to initialize Xinference model:{ $e } +msg-01af1651 = Xinference initialization failed with exception:{ $e } msg-42ed8558 = Xinference STT model is not initialized. -msg-bbc43272 = Failed to download audio from {$audio_url}, status: {$res} -msg-f4e53d3d = File not found: {$audio_url} +msg-bbc43272 = Failed to download audio from{ $audio_url }, status:{ $res } +msg-f4e53d3d = File not found:{ $audio_url } msg-ebab7cac = Audio bytes are empty. -msg-7fd63838 = Audio requires conversion ({$conversion_type}), using temporary files... +msg-7fd63838 = Audio requires conversion ({ $conversion_type }), using temporary files... msg-d03c4ede = Converting silk to wav ... msg-79486689 = Converting amr to wav ... -msg-c4305a5b = Xinference STT result: {$text} -msg-d4241bd5 = Xinference STT transcription failed with status {$res}: {$error_text} -msg-8efe4ef1 = Xinference STT failed: {$e} -msg-b1554c7c = Xinference STT failed with exception: {$e} -msg-9d33941a = Removed temporary file: {$temp_file} -msg-7dc5bc44 = Failed to remove temporary file {$temp_file}: {$e} +msg-c4305a5b = Xinference STT result:{ $text } +msg-d4241bd5 = Xinference STT transcription failed with status{ $res }Text to translate:{ $error_text } +msg-8efe4ef1 = Xinference STT failed:{ $e } +msg-b1554c7c = Xinference STT failed with exception:{ $e } +msg-9d33941a = Removed temporary file:{ $temp_file } +msg-7dc5bc44 = Failed to remove temporary file{ $temp_file }Text to be translated:{ $e } msg-31904a1c = Closing Xinference STT client... -msg-633a269f = Failed to close Xinference client: {$e} +msg-633a269f = Failed to close Xinference client:{ $e } ### astrbot/core/provider/sources/fishaudio_tts_api_source.py -msg-c785baf0 = [FishAudio TTS] 使用代理: {$res} -msg-822bce1c = 无效的FishAudio参考模型ID: '{$res}'. 请确保ID是32位十六进制字符串(例如: 626bb6d3f3364c9cbc3aa6a67300a664)。您可以从 https://fish.audio/zh-CN/discovery 获取有效的模型ID。 -msg-5956263b = Fish Audio API请求失败: 状态码 {$res}, 响应内容: {$error_text} + +msg-c785baf0 = [FishAudio TTS] Using Proxy:{ $res } +msg-822bce1c = Invalid FishAudio reference model ID: '{ $res }'. Please ensure the ID is a 32-digit hexadecimal string (e.g., 626bb6d3f3364c9cbc3aa6a67300a664). You can obtain a valid model ID from https://fish.audio/zh-CN/discovery. +msg-5956263b = Fish Audio API request failed: status code{ $res }, Response content:{ $error_text } ### astrbot/core/provider/sources/gsv_selfhosted_source.py -msg-5fb63f61 = [GSV TTS] 初始化完成 -msg-e0c38c5b = [GSV TTS] 初始化失败:{$e} + +msg-5fb63f61 = [GSV TTS] Initialization complete +msg-e0c38c5b = [GSV TTS] Initialization failed:{ $e } msg-4d57bc4f = [GSV TTS] Provider HTTP session is not ready or closed. -msg-2a4a0819 = [GSV TTS] 请求地址:{$endpoint},参数:{$params} -msg-5fdee1da = [GSV TTS] Request to {$endpoint} failed with status {$res}: {$error_text} -msg-3a51c2c5 = [GSV TTS] 请求 {$endpoint} 第 {$res} 次失败:{$e},重试中... -msg-49c1c17a = [GSV TTS] 请求 {$endpoint} 最终失败:{$e} -msg-1beb6249 = [GSV TTS] 成功设置 GPT 模型路径:{$res} -msg-17f1a087 = [GSV TTS] GPT 模型路径未配置,将使用内置 GPT 模型 -msg-ddeb915f = [GSV TTS] 成功设置 SoVITS 模型路径:{$res} -msg-bee5c961 = [GSV TTS] SoVITS 模型路径未配置,将使用内置 SoVITS 模型 -msg-423edb93 = [GSV TTS] 设置模型路径时发生网络错误:{$e} -msg-7d3c79cb = [GSV TTS] 设置模型路径时发生未知错误:{$e} -msg-d084916a = [GSV TTS] TTS 文本不能为空 -msg-fa20c883 = [GSV TTS] 正在调用语音合成接口,参数:{$params} -msg-a7fc38eb = [GSV TTS] 合成失败,输入文本:{$text},错误信息:{$result} -msg-a49cb96b = [GSV TTS] Session 已关闭 +msg-2a4a0819 = [GSV TTS] Request URL:{ $endpoint }, Parameters:{ $params } +msg-5fdee1da = [GSV TTS] Request to{ $endpoint }failed with status{ $res }Text to be translated:{ $error_text } +msg-3a51c2c5 = [GSV TTS] Request{ $endpoint }Page{ $res }Failed{ $e }, retrying... +msg-49c1c17a = [GSV TTS] Request{ $endpoint }Final failure:{ $e } +msg-1beb6249 = [GSV TTS] Successfully set GPT model path:{ $res } +msg-17f1a087 = [GSV TTS] GPT model path is not configured, will use the built-in GPT model. +msg-ddeb915f = [GSV TTS] Successfully set the SoVITS model path:{ $res } +msg-bee5c961 = [GSV TTS] SoVITS model path not configured, will use built-in SoVITS model. +msg-423edb93 = [GSV TTS] A network error occurred while setting the model path:{ $e } +msg-7d3c79cb = [GSV TTS] An unknown error occurred while setting the model path:{ $e } +msg-d084916a = [GSV TTS] TTS text cannot be empty +msg-fa20c883 = [GSV TTS] Calling the speech synthesis interface, parameters:{ $params } +msg-a7fc38eb = [GSV TTS] Synthesis failed, input text:{ $text }, Error message:{ $result } +msg-a49cb96b = [GSV TTS] Session has been closed ### astrbot/core/provider/sources/volcengine_tts.py -msg-4b55f021 = 请求头: {$headers} -msg-d252d96d = 请求 URL: {$res} -msg-72e07cfd = 请求体: {$res}... -msg-fb8cdd69 = 响应状态码: {$res} -msg-4c62e457 = 响应内容: {$res}... -msg-1477973b = 火山引擎 TTS API 返回错误: {$error_msg} -msg-75401c15 = 火山引擎 TTS API 请求失败: {$res}, {$response_text} -msg-a29cc73d = 火山引擎 TTS 异常详情: {$error_details} -msg-01433007 = 火山引擎 TTS 异常: {$e} + +msg-4b55f021 = Request header:{ $headers } +msg-d252d96d = Request URL:{ $res } +msg-72e07cfd = Request body:{ $res }... +msg-fb8cdd69 = Response status code:{ $res } +msg-4c62e457 = Response content:{ $res }... +msg-1477973b = Volcano Engine TTS API returned an error:{ $error_msg } +msg-75401c15 = Volcano Engine TTS API request failed:{ $res },{ $response_text } +msg-a29cc73d = Volcano Engine TTS Exception Details:{ $error_details } +msg-01433007 = Volcano Engine TTS Exception:{ $e } ### astrbot/core/provider/sources/sensevoice_selfhosted_source.py -msg-ee0daf96 = 下载或者加载 SenseVoice 模型中,这可能需要一些时间 ... -msg-cd6da7e9 = SenseVoice 模型加载完成。 -msg-28cbbf07 = 文件不存在: {$audio_url} + +msg-ee0daf96 = Downloading or loading the SenseVoice model, this may take some time... +msg-cd6da7e9 = SenseVoice model loading completed. +msg-28cbbf07 = File does not exist:{ $audio_url } msg-d98780e5 = Converting silk file to wav ... -msg-4e8f1d05 = SenseVoice识别到的文案:{$res} -msg-55668aa2 = 未能提取到情绪信息 -msg-0cdbac9b = 处理音频文件时出错: {$e} +msg-4e8f1d05 = Copy recognized by SenseVoice:{ $res } +msg-55668aa2 = Failed to extract emotion information +msg-0cdbac9b = Error processing audio file:{ $e } ### astrbot/core/message/components.py + msg-afb10076 = not a valid url -msg-fe4c33a0 = not a valid file: {$res} -msg-24d98e13 = 未配置 callback_api_base,文件服务不可用 -msg-a5c69cc9 = 已注册:{$callback_host}/api/file/{$token} -msg-3cddc5ef = download failed: {$url} -msg-1921aa47 = not a valid file: {$url} -msg-2ee3827c = Generated video file callback link: {$payload_file} +msg-fe4c33a0 = not a valid file:{ $res } +msg-24d98e13 = callback_api_base is not configured, file service is unavailable +msg-a5c69cc9 = Registered:{ $callback_host }/api/file/{ $token } +msg-3cddc5ef = download failed:{ $url } +msg-1921aa47 = not a valid file:{ $url } +msg-2ee3827c = Generated video file callback link:{ $payload_file } msg-32f4fc78 = No valid file or URL provided msg-36375f4c = 不可以在异步上下文中同步等待下载! 这个警告通常发生于某些逻辑试图通过 .file 获取文件消息段的文件内容。请使用 await get_file() 代替直接获取 .file 字段 -msg-4a987754 = 文件下载失败: {$e} +msg-4a987754 = File download failed:{ $e } msg-7c1935ee = Download failed: No URL provided in File component. -msg-35bb8d53 = Generated file callback link: {$payload_file} +msg-35bb8d53 = Generated file callback link:{ $payload_file } ### astrbot/core/utils/metrics.py -msg-314258f2 = 保存指标到数据库失败: {$e} + +msg-314258f2 = Failed to save indicator to database:{ $e } ### astrbot/core/utils/trace.py -msg-fffce1b9 = [trace] {$payload} -msg-78b9c276 = {$res} + +msg-fffce1b9 = [trace]{ $payload } +msg-78b9c276 = { $res } ### astrbot/core/utils/webhook_utils.py -msg-64c7ddcf = 获取 callback_api_base 失败: {$e} -msg-9b5d1bb1 = 获取 dashboard 端口失败: {$e} -msg-3db149ad = 获取 dashboard SSL 配置失败: {$e} -msg-3739eec9 = {$display_log} + +msg-64c7ddcf = Failed to get callback_api_base:{ $e } +msg-9b5d1bb1 = Failed to get dashboard port:{ $e } +msg-3db149ad = Failed to get dashboard SSL configuration:{ $e } +msg-3739eec9 = { $display_log } ### astrbot/core/utils/path_util.py -msg-cf211d0f = 路径映射规则错误: {$mapping} -msg-ecea161e = 路径映射: {$url} -> {$srcPath} + +msg-cf211d0f = Path mapping rule error:{ $mapping } +msg-ecea161e = Path mapping:{ $url }->{ $srcPath } ### astrbot/core/utils/media_utils.py -msg-2f697658 = [Media Utils] 获取媒体时长: {$duration_ms}ms -msg-52dfbc26 = [Media Utils] 无法获取媒体文件时长: {$file_path} + +msg-2f697658 = [Media Utils] Get media duration:{ $duration_ms }ms +msg-52dfbc26 = [Media Utils] Failed to get media file duration:{ $file_path } msg-486d493a = [Media Utils] ffprobe未安装或不在PATH中,无法获取媒体时长。请安装ffmpeg: https://ffmpeg.org/ -msg-0f9c647b = [Media Utils] 获取媒体时长时出错: {$e} -msg-aff4c5f8 = [Media Utils] 已清理失败的opus输出文件: {$output_path} -msg-82427384 = [Media Utils] 清理失败的opus输出文件时出错: {$e} -msg-215a0cfc = [Media Utils] ffmpeg转换音频失败: {$error_msg} -msg-8cce258e = ffmpeg conversion failed: {$error_msg} -msg-f0cfcb92 = [Media Utils] 音频转换成功: {$audio_path} -> {$output_path} -msg-ead1395b = [Media Utils] ffmpeg未安装或不在PATH中,无法转换音频格式。请安装ffmpeg: https://ffmpeg.org/ +msg-0f9c647b = [Media Utils] Failed to get media duration:{ $e } +msg-aff4c5f8 = [Media Utils] Cleaned up failed opus output files:{ $output_path } +msg-82427384 = [Media Utils] Error occurred while cleaning up failed opus output file:{ $e } +msg-215a0cfc = [Media Utils] ffmpeg audio conversion failed:{ $error_msg } +msg-8cce258e = ffmpeg conversion failed:{ $error_msg } +msg-f0cfcb92 = [Media Utils] Audio conversion successful:{ $audio_path }->{ $output_path } +msg-ead1395b = [Media Utils] ffmpeg is not installed or not in PATH, unable to convert audio format. Please install ffmpeg: https://ffmpeg.org/ msg-5df3a5ee = ffmpeg not found -msg-6322d4d2 = [Media Utils] 转换音频格式时出错: {$e} -msg-e125b1a5 = [Media Utils] 已清理失败的{$output_format}输出文件: {$output_path} -msg-5cf417e3 = [Media Utils] 清理失败的{$output_format}输出文件时出错: {$e} -msg-3766cbb8 = [Media Utils] ffmpeg转换视频失败: {$error_msg} -msg-77f68449 = [Media Utils] 视频转换成功: {$video_path} -> {$output_path} -msg-3fb20b91 = [Media Utils] ffmpeg未安装或不在PATH中,无法转换视频格式。请安装ffmpeg: https://ffmpeg.org/ -msg-696c4a46 = [Media Utils] 转换视频格式时出错: {$e} -msg-98cc8fb8 = [Media Utils] 清理失败的音频输出文件时出错: {$e} -msg-3c27d5e8 = [Media Utils] 清理失败的视频封面文件时出错: {$e} -msg-072774ab = ffmpeg extract cover failed: {$error_msg} +msg-6322d4d2 = [Media Utils] Error converting audio format:{ $e } +msg-e125b1a5 = [Media Utils] Failed cleanups have been cleared{ $output_format }Output file:{ $output_path } +msg-5cf417e3 = [Media Utils] Cleanup failed{ $output_format }Error when outputting file:{ $e } +msg-3766cbb8 = [Media Utils] ffmpeg video conversion failed:{ $error_msg } +msg-77f68449 = [Media Utils] Video conversion successful:{ $video_path }->{ $output_path } +msg-3fb20b91 = [Media Utils] ffmpeg is not installed or not in the PATH, unable to convert video format. Please install ffmpeg: https://ffmpeg.org/ +msg-696c4a46 = [Media Utils] Error converting video format:{ $e } +msg-98cc8fb8 = [Media Utils] Error occurred while cleaning up failed audio output files:{ $e } +msg-3c27d5e8 = [Media Utils] Error occurred while cleaning up failed video cover files:{ $e } +msg-072774ab = ffmpeg extract cover failed:{ $error_msg } ### astrbot/core/utils/session_waiter.py -msg-0c977996 = 等待超时 -msg-ac406437 = session_filter 必须是 SessionFilter + +msg-0c977996 = Wait timeout +msg-ac406437 = session_filter must be SessionFilter ### astrbot/core/utils/history_saver.py + msg-fb7718cb = Failed to parse conversation history: %s ### astrbot/core/utils/io.py -msg-665b0191 = SSL certificate verification failed for {$url}. Disabling SSL verification (CERT_NONE) as a fallback. This is insecure and exposes the application to man-in-the-middle attacks. Please investigate and resolve certificate issues. -msg-04ab2fae = 下载文件失败: {$res} -msg-63dacf99 = 文件大小: {$res} KB | 文件地址: {$url} -msg-14c3d0bb = \r下载进度: {$res} 速度: {$speed} KB/s -msg-4e4ee68e = SSL 证书验证失败,已关闭 SSL 验证(不安全,仅用于临时下载)。请检查目标服务器的证书配置。 -msg-5a3beefb = SSL certificate verification failed for {$url}. Falling back to unverified connection (CERT_NONE). This is insecure and exposes the application to man-in-the-middle attacks. Please investigate certificate issues with the remote server. -msg-315e5ed6 = 准备下载指定发行版本的 AstrBot WebUI 文件: {$dashboard_release_url} -msg-c709cf82 = 准备下载指定版本的 AstrBot WebUI: {$url} + +msg-665b0191 = SSL certificate verification failed for{ $url }. Disabling SSL verification (CERT_NONE) as a fallback. This is insecure and exposes the application to man-in-the-middle attacks. Please investigate and resolve certificate issues. +msg-04ab2fae = Download file failed:{ $res } +msg-63dacf99 = File size:{ $res }KB | File Address:{ $url } +msg-14c3d0bb = Download progress:{ $res }Speed:{ $speed }KB/s +msg-4e4ee68e = SSL certificate verification failed, SSL verification has been turned off (unsafe, for temporary download only). Please check the target server's certificate configuration. +msg-5a3beefb = SSL certificate verification failed for{ $url }. Falling back to unverified connection (CERT_NONE). This is insecure and exposes the application to man-in-the-middle attacks. Please investigate certificate issues with the remote server. +msg-315e5ed6 = Preparing to download the AstrBot WebUI files for the specified release version:{ $dashboard_release_url } +msg-c709cf82 = Preparing to download the specified version of AstrBot WebUI:{ $url } ### astrbot/core/utils/shared_preferences.py + msg-9a1e6a9a = scope_id and key cannot be None when getting a specific preference. ### astrbot/core/utils/migra_helper.py -msg-497ddf83 = Migration for third party agent runner configs failed: {$e} -msg-78b9c276 = {$res} -msg-e21f1509 = Migrating provider {$res} to new structure + +msg-497ddf83 = Migration for third party agent runner configs failed:{ $e } +msg-78b9c276 = { $res } +msg-e21f1509 = Migrating provider{ $res }to new structure msg-dd3339e6 = Provider-source structure migration completed -msg-1cb6c174 = Migration from version 4.5 to 4.6 failed: {$e} -msg-a899acc6 = Migration for webchat session failed: {$e} -msg-b9c52817 = Migration for token_usage column failed: {$e} -msg-d9660ff5 = Migration for provider-source structure failed: {$e} +msg-1cb6c174 = Migration from version 4.5 to 4.6 failed:{ $e } +msg-a899acc6 = Migration for webchat session failed:{ $e } +msg-b9c52817 = Migration for token_usage column failed:{ $e } +msg-d9660ff5 = Migration for provider-source structure failed:{ $e } ### astrbot/core/utils/temp_dir_cleaner.py -msg-752c7cc8 = Invalid {$res}={$configured}, fallback to {$res_2}MB. -msg-b1fc3643 = Skip temp file {$path} due to stat error: {$e} -msg-5e61f6b7 = Failed to delete temp file {$res}: {$e} -msg-391449f0 = Temp dir exceeded limit ({$total_size} > {$limit}). Removed {$removed_files} files, released {$released} bytes (target {$target_release} bytes). -msg-aaf1e12a = TempDirCleaner started. interval={$res}s cleanup_ratio={$res_2} -msg-e6170717 = TempDirCleaner run failed: {$e} + +msg-752c7cc8 = Invalid{ $res }={ $configured }, fallback to{ $res_2 }MB. +msg-b1fc3643 = Skip temp file{ $path }due to stat error:{ $e } +msg-5e61f6b7 = Failed to delete temp file{ $res }Text to be translated:{ $e } +msg-391449f0 = Temp dir exceeded limit ({ $total_size }Text to be translated:{ $limit }). Removed{ $removed_files }files, released{ $released }bytes (target{ $target_release }bytes). +msg-aaf1e12a = TempDirCleaner started. interval={ $res }cleanup_ratio={ $res_2 } +msg-e6170717 = TempDirCleaner run failed:{ $e } msg-0fc33fbc = TempDirCleaner stopped. ### astrbot/core/utils/tencent_record_helper.py -msg-377ae139 = pilk 模块未安装,请前往管理面板->平台日志->安装pip库 安装 pilk 这个库 -msg-f4ab0713 = pyffmpeg 转换失败: {$e}, 尝试使用 ffmpeg 命令行进行转换 -msg-33c88889 = [FFmpeg] stdout: {$res} -msg-2470430c = [FFmpeg] stderr: {$res} -msg-1321d5f7 = [FFmpeg] return code: {$res} -msg-c39d210c = 生成的WAV文件不存在或为空 -msg-6e04bdb8 = 未安装 pilk: pip install pilk + +msg-377ae139 = The pilk module is not installed. Please go to Admin Panel -> Platform Logs -> Install pip Libraries to install the pilk library. +msg-f4ab0713 = pyffmpeg conversion failed:{ $e }, try using the ffmpeg command line for conversion +msg-33c88889 = [FFmpeg] stdout:{ $res } +msg-2470430c = [FFmpeg] stderr:{ $res } +msg-1321d5f7 = [FFmpeg] return code:{ $res } +msg-c39d210c = The generated WAV file does not exist or is empty. +msg-6e04bdb8 = pilk not installed: pip install pilk ### astrbot/core/utils/pip_installer.py -msg-aa9e40b8 = pip module is unavailable (sys.executable={$res}, frozen={$res_2}, ASTRBOT_DESKTOP_CLIENT={$res_3}) -msg-560f11f2 = 读取依赖文件失败,跳过冲突检测: %s -msg-91ae1d17 = 读取 site-packages 元数据失败,使用回退模块名: %s -msg-c815b9dc = {$conflict_message} + +msg-aa9e40b8 = pip module is unavailable (sys.executable={ $res }, frozen={ $res_2 }, ASTRBOT_DESKTOP_CLIENT={ $res_3 }) +msg-560f11f2 = Failed to read dependency file, skipping conflict detection: %s +msg-91ae1d17 = Failed to read site-packages metadata, using fallback module name: %s +msg-c815b9dc = { $conflict_message } msg-e8d4b617 = Loaded %s from plugin site-packages: %s msg-4ef5d900 = Recovered dependency %s while preferring %s from plugin site-packages. msg-0bf22754 = Module %s not found in plugin site-packages: %s @@ -1452,489 +1573,541 @@ msg-117d9cf4 = Distlib finder patch did not take effect for loader %s (%s). msg-b7975236 = Patched pip distlib finder for frozen loader: %s (%s) msg-b1fa741c = Skip patching distlib finder because _finder_registry is unavailable. msg-4ef0e609 = Skip patching distlib finder because register API is unavailable. -msg-b8c741dc = Pip 包管理器: pip {$res} -msg-6b72a960 = 安装失败,错误码:{$result_code} -msg-c8325399 = {$line} +msg-b8c741dc = Pip Package Manager: pip{ $res } +msg-6b72a960 = Installation failed, error code:{ $result_code } +msg-c8325399 = { $line } ### astrbot/core/utils/llm_metadata.py -msg-d6535d03 = Successfully fetched metadata for {$res} LLMs. -msg-8cceaeb0 = Failed to fetch LLM metadata: {$e} + +msg-d6535d03 = Successfully fetched metadata for{ $res }LLMs. +msg-8cceaeb0 = Failed to fetch LLM metadata:{ $e } ### astrbot/core/utils/network_utils.py -msg-54b8fda8 = [{$provider_label}] 网络/代理连接失败 ({$error_type})。代理地址: {$effective_proxy},错误: {$error} -msg-ea7c80f1 = [{$provider_label}] 网络连接失败 ({$error_type})。错误: {$error} -msg-f8c8a73c = [{$provider_label}] 使用代理: {$proxy} + +msg-54b8fda8 = Text to translate:{ $provider_label }Network/Proxy Connection Failed{ $error_type }Proxy Address:{ $effective_proxy }, Error:{ $error } +msg-ea7c80f1 = 待翻译文本:{ $provider_label }Network connection failed{ $error_type })。 Error:{ $error } +msg-f8c8a73c = Text to be translated:{ $provider_label }] Use proxy:{ $proxy } ### astrbot/core/utils/t2i/renderer.py -msg-4225607b = Failed to render image via AstrBot API: {$e}. Falling back to local rendering. + +msg-4225607b = Failed to render image via AstrBot API:{ $e }. Falling back to local rendering. ### astrbot/core/utils/t2i/local_strategy.py -msg-94a58a1e = 无法加载任何字体 -msg-d5c7d255 = Failed to load image: HTTP {$res} -msg-7d59d0a0 = Failed to load image: {$e} + +msg-94a58a1e = Unable to load any fonts +msg-d5c7d255 = Failed to load image: HTTP{ $res } +msg-7d59d0a0 = Failed to load image:{ $e } ### astrbot/core/utils/t2i/template_manager.py -msg-47d72ff5 = 模板名称包含非法字符。 -msg-d1b2131b = 模板不存在。 -msg-dde05b0f = 同名模板已存在。 -msg-0aa209bf = 用户模板不存在,无法删除。 + +msg-47d72ff5 = Template name contains illegal characters. +msg-d1b2131b = Template does not exist. +msg-dde05b0f = A template with the same name already exists. +msg-0aa209bf = User template does not exist and cannot be deleted. ### astrbot/core/utils/t2i/network_strategy.py -msg-be0eeaa7 = Successfully got {$res} official T2I endpoints. -msg-3bee02f4 = Failed to get official endpoints: {$e} -msg-829d3c71 = HTTP {$res} -msg-05fb621f = Endpoint {$endpoint} failed: {$e}, trying next... -msg-9a836926 = All endpoints failed: {$last_exception} + +msg-be0eeaa7 = Successfully got{ $res }official T2I endpoints. +msg-3bee02f4 = Failed to get official endpoints:{ $e } +msg-829d3c71 = HTTP{ $res } +msg-05fb621f = Endpoint{ $endpoint }failed:{ $e }, trying next... +msg-9a836926 = All endpoints failed:{ $last_exception } ### astrbot/core/utils/quoted_message/extractor.py + msg-24049c48 = quoted_message_parser: stop fetching nested forward messages after %d hops ### astrbot/core/utils/quoted_message/onebot_client.py + msg-062923e6 = quoted_message_parser: action %s failed with params %s: %s msg-f33f59d5 = quoted_message_parser: all attempts failed for action %s, last_params=%s, error=%s ### astrbot/core/utils/quoted_message/image_resolver.py + msg-94224a01 = quoted_message_parser: skip non-image local path ref=%s msg-3e6c0d14 = quoted_message_parser: failed to resolve quoted image ref=%s after %d actions ### astrbot/core/agent/tool_image_cache.py -msg-45da4af7 = ToolImageCache initialized, cache dir: {$res} -msg-017bde96 = Saved tool image to: {$file_path} -msg-29398f55 = Failed to save tool image: {$e} -msg-128aa08a = Failed to read cached image {$file_path}: {$e} -msg-3c111d1f = Error during cache cleanup: {$e} -msg-eeb1b849 = Cleaned up {$cleaned} expired cached images + +msg-45da4af7 = ToolImageCache initialized, cache dir:{ $res } +msg-017bde96 = Saved tool image to:{ $file_path } +msg-29398f55 = Failed to save tool image:{ $e } +msg-128aa08a = Failed to read cached image{ $file_path }Text to be translated:{ $e } +msg-3c111d1f = Error during cache cleanup:{ $e } +msg-eeb1b849 = Cleaned up{ $cleaned }expired cached images ### astrbot/core/agent/message.py -msg-d38656d7 = {$invalid_subclass_error_msg} -msg-42d5a315 = Cannot validate {$value} as ContentPart + +msg-d38656d7 = { $invalid_subclass_error_msg } +msg-42d5a315 = Cannot validate{ $value }as ContentPart msg-ffc376d0 = content is required unless role='assistant' and tool_calls is not None ### astrbot/core/agent/mcp_client.py + msg-6a61ca88 = Warning: Missing 'mcp' dependency, MCP services will be unavailable. msg-45995cdb = Warning: Missing 'mcp' dependency or MCP library version too old, Streamable HTTP connection unavailable. msg-2866b896 = MCP connection config missing transport or type field -msg-3bf7776b = MCP Server {$name} Error: {$msg} -msg-10f72727 = {$error_msg} +msg-3bf7776b = MCP Server{ $name }Error:{ $msg } +msg-10f72727 = { $error_msg } msg-19c9b509 = MCP Client is not initialized -msg-5b9b4918 = MCP Client {$res} is already reconnecting, skipping +msg-5b9b4918 = MCP Client{ $res }is already reconnecting, skipping msg-c1008866 = Cannot reconnect: missing connection configuration -msg-7c3fe178 = Attempting to reconnect to MCP server {$res}... -msg-783f3b85 = Successfully reconnected to MCP server {$res} -msg-da7361ff = Failed to reconnect to MCP server {$res}: {$e} +msg-7c3fe178 = Attempting to reconnect to MCP server{ $res }... +msg-783f3b85 = Successfully reconnected to MCP server{ $res } +msg-da7361ff = Failed to reconnect to MCP server{ $res }Text to be translated:{ $e } msg-c0fd612e = MCP session is not available for MCP function tools. -msg-8236c58c = MCP tool {$tool_name} call failed (ClosedResourceError), attempting to reconnect... -msg-044046ec = Error closing current exit stack: {$e} +msg-8236c58c = MCP tool{ $tool_name }call failed (ClosedResourceError), attempting to reconnect... +msg-044046ec = Error closing current exit stack:{ $e } ### astrbot/core/agent/tool.py + msg-983bc802 = FunctionTool.call() must be implemented by subclasses or set a handler. ### astrbot/core/agent/context/compressor.py -msg-6c75531b = Failed to generate summary: {$e} + +msg-6c75531b = Failed to generate summary:{ $e } ### astrbot/core/agent/context/manager.py -msg-59241964 = Error during context processing: {$e} + +msg-59241964 = Error during context processing:{ $e } msg-a0d672dc = Compress triggered, starting compression... -msg-e6ef66f0 = Compress completed. {$prev_tokens} -> {$tokens_after_summary} tokens, compression rate: {$compress_rate}%. +msg-e6ef66f0 = Compress completed.{ $prev_tokens }->{ $tokens_after_summary }tokens, compression rate:{ $compress_rate }%. msg-3fe644eb = Context still exceeds max tokens after compression, applying halving truncation... ### astrbot/core/agent/runners/tool_loop_agent_runner.py + msg-960ef181 = Switched from %s to fallback chat provider: %s msg-4f999913 = Chat Model %s returns error response, trying fallback to next provider. msg-c042095f = Chat Model %s request error: %s -msg-81b2aeae = {$tag} RunCtx.messages -> [{$res}] {$res_2} +msg-81b2aeae = { $tag }RunCtx.messages -> [{ $res }Text to be translated: ]{ $res_2 } msg-55333301 = Request is not set. Please call reset() first. -msg-d3b77736 = Error in on_agent_begin hook: {$e} +msg-d3b77736 = Error in on_agent_begin hook:{ $e } msg-61de315c = Agent execution was requested to stop by user. -msg-8eb53be3 = Error in on_agent_done hook: {$e} -msg-508d6d17 = LLM 响应错误: {$res} +msg-8eb53be3 = Error in on_agent_done hook:{ $e } +msg-508d6d17 = LLM response error:{ $res } msg-ed80313d = LLM returned empty assistant message with no tool calls. -msg-970947ae = Appended {$res} cached image(s) to context for LLM review -msg-6b326889 = Agent reached max steps ({$max_step}), forcing a final response. -msg-948ea4b7 = Agent 使用工具: {$res} -msg-a27ad3d1 = 使用工具:{$func_tool_name},参数:{$func_tool_args} -msg-812ad241 = 未找到指定的工具: {$func_tool_name},将跳过。 -msg-20b4f143 = 工具 {$func_tool_name} 期望的参数: {$res} -msg-78f6833c = 工具 {$func_tool_name} 忽略非期望参数: {$ignored_params} -msg-2b523f8c = Error in on_tool_start hook: {$e} -msg-ec868b73 = {$func_tool_name} 没有返回值,或者已将结果直接发送给用户。 -msg-6b61e4f1 = Tool 返回了不支持的类型: {$res}。 -msg-34c13e02 = Error in on_tool_end hook: {$e} -msg-78b9c276 = {$res} -msg-a1493b6d = Tool `{$func_tool_name}` Result: {$last_tcr_content} +msg-970947ae = Appended{ $res }cached image(s) to context for LLM review +msg-6b326889 = Agent reached max steps ({ $max_step }), forcing a final response. +msg-948ea4b7 = Agent using tool:{ $res } +msg-a27ad3d1 = Using tool:{ $func_tool_name }Parameters:{ $func_tool_args } +msg-812ad241 = Specified tool not found:{ $func_tool_name }, will be skipped. +msg-20b4f143 = Tools{ $func_tool_name }Expected parameters:{ $res } +msg-78f6833c = Tools{ $func_tool_name }Ignore unexpected parameters:{ $ignored_params } +msg-2b523f8c = Error in on_tool_start hook:{ $e } +msg-ec868b73 = { $func_tool_name }No return value, or the result has been directly sent to the user. +msg-6b61e4f1 = Tool returned an unsupported type:{ $res }. +msg-34c13e02 = Error in on_tool_end hook:{ $e } +msg-78b9c276 = { $res } +msg-a1493b6d = Tool `{ $func_tool_name }Result:{ $last_tcr_content } ### astrbot/core/agent/runners/base.py -msg-24eb2b08 = Agent state transition: {$res} -> {$new_state} + +msg-24eb2b08 = Agent state transition:{ $res }->{ $new_state } ### astrbot/core/agent/runners/dashscope/dashscope_agent_runner.py -msg-dc1a9e6e = 阿里云百炼 API Key 不能为空。 -msg-c492cbbc = 阿里云百炼 APP ID 不能为空。 -msg-bcc8e027 = 阿里云百炼 APP 类型不能为空。 + +msg-dc1a9e6e = Alibaba Cloud Bailian API Key cannot be empty. +msg-c492cbbc = Alibaba Cloud Bailian APP ID cannot be empty. +msg-bcc8e027 = The Alibaba Cloud Bailian APP type cannot be empty. msg-55333301 = Request is not set. Please call reset() first. -msg-d3b77736 = Error in on_agent_begin hook: {$e} -msg-e3af4efd = 阿里云百炼请求失败:{$res} -msg-fccf5004 = dashscope stream chunk: {$chunk} -msg-100d7d7e = 阿里云百炼请求失败: request_id={$res}, code={$res_2}, message={$res_3}, 请参考文档:https://help.aliyun.com/zh/model-studio/developer-reference/error-code -msg-10f72727 = {$error_msg} -msg-e8615101 = {$chunk_text} -msg-dfb132c4 = {$ref_text} -msg-8eb53be3 = Error in on_agent_done hook: {$e} -msg-650b47e1 = 阿里云百炼暂不支持图片输入,将自动忽略图片内容。 +msg-d3b77736 = Error in on_agent_begin hook:{ $e } +msg-e3af4efd = Alibaba Cloud Bailian request failed:{ $res } +msg-fccf5004 = dashscope stream chunk:{ $chunk } +msg-100d7d7e = Alibaba Cloud Bailian request failed: request_id={ $res }, code={ $res_2 }, message={ $res_3 }, please refer to the documentation: https://help.aliyun.com/zh/model-studio/developer-reference/error-code +msg-10f72727 = { $error_msg } +msg-e8615101 = { $chunk_text } +msg-dfb132c4 = { $ref_text } +msg-8eb53be3 = Error in on_agent_done hook:{ $e } +msg-650b47e1 = Alibaba Cloud Bailian does not currently support image input and will automatically ignore image content. ### astrbot/core/agent/runners/coze/coze_agent_runner.py -msg-448549b0 = Coze API Key 不能为空。 -msg-b88724b0 = Coze Bot ID 不能为空。 -msg-ea5a135a = Coze API Base URL 格式不正确,必须以 http:// 或 https:// 开头。 + +msg-448549b0 = Coze API Key cannot be empty. +msg-b88724b0 = Coze Bot ID cannot be empty. +msg-ea5a135a = The Coze API Base URL format is incorrect; it must start with http:// or https://. msg-55333301 = Request is not set. Please call reset() first. -msg-d3b77736 = Error in on_agent_begin hook: {$e} -msg-5aa3eb1c = Coze 请求失败:{$res} -msg-333354c6 = 处理上下文图片失败: {$e} -msg-2d9e1c08 = 处理图片失败 {$url}: {$e} -msg-1f50979d = {$content} +msg-d3b77736 = Error in on_agent_begin hook:{ $e } +msg-5aa3eb1c = Coze request failed:{ $res } +msg-333354c6 = Failed to process context image:{ $e } +msg-2d9e1c08 = Failed to process image{ $url }Text to be translated:{ $e } +msg-1f50979d = { $content } msg-6fe5588b = Coze message completed msg-d2802f3b = Coze chat completed -msg-ba4afcda = Coze 出现错误: {$error_code} - {$error_msg} -msg-ee300f25 = Coze 未返回任何内容 -msg-8eb53be3 = Error in on_agent_done hook: {$e} -msg-034c1858 = [Coze] 使用缓存的 file_id: {$file_id} -msg-475d8a41 = [Coze] 图片上传成功并缓存,file_id: {$file_id} -msg-696dad99 = 处理图片失败 {$image_url}: {$e} -msg-7793a347 = 处理图片失败: {$e} +msg-ba4afcda = Coze error:{ $error_code }-{ $error_msg } +msg-ee300f25 = Coze did not return any content +msg-8eb53be3 = Error in on_agent_done hook:{ $e } +msg-034c1858 = [Coze] Using cached file_id:{ $file_id } +msg-475d8a41 = [Coze] Image uploaded successfully and cached, file_id:{ $file_id } +msg-696dad99 = Failed to process image{ $image_url }Text to translate:{ $e } +msg-7793a347 = Image processing failed:{ $e } ### astrbot/core/agent/runners/coze/coze_api_client.py -msg-76f97104 = Coze API 认证失败,请检查 API Key 是否正确 -msg-3653b652 = 文件上传响应状态: {$res}, 内容: {$response_text} -msg-13fe060c = 文件上传失败,状态码: {$res}, 响应: {$response_text} -msg-5604b862 = 文件上传响应解析失败: {$response_text} -msg-c0373c50 = 文件上传失败: {$res} -msg-010e4299 = [Coze] 图片上传成功,file_id: {$file_id} -msg-719f13cb = 文件上传超时 -msg-121c11fb = 文件上传失败: {$e} -msg-f6101892 = 下载图片失败,状态码: {$res} -msg-c09c56c9 = 下载图片失败 {$image_url}: {$e} -msg-15211c7c = 下载图片失败: {$e} -msg-2245219f = Coze chat_messages payload: {$payload}, params: {$params} -msg-d8fd415c = Coze API 流式请求失败,状态码: {$res} -msg-f5cc7604 = Coze API 流式请求超时 ({$timeout}秒) -msg-30c0a9d6 = Coze API 流式请求失败: {$e} -msg-11509aba = Coze API 请求失败,状态码: {$res} -msg-002af11d = Coze API 返回非JSON格式 -msg-c0b8fc7c = Coze API 请求超时 -msg-a68a33fa = Coze API 请求失败: {$e} -msg-c26e068e = 获取Coze消息列表失败: {$e} -msg-5bc0a49d = Uploaded file_id: {$file_id} -msg-7c08bdaf = Event: {$event} + +msg-76f97104 = Coze API authentication failed, please check if the API Key is correct +msg-3653b652 = File upload response status:{ $res }, content:{ $response_text } +msg-13fe060c = File upload failed, status code:{ $res }, response:{ $response_text } +msg-5604b862 = File upload response parsing failed:{ $response_text } +msg-c0373c50 = File upload failed:{ $res } +msg-010e4299 = [Coze] Image uploaded successfully, file_id:{ $file_id } +msg-719f13cb = File upload timeout +msg-121c11fb = File upload failed:{ $e } +msg-f6101892 = Failed to download image, status code:{ $res } +msg-c09c56c9 = Failed to download the image{ $image_url }Text to translate:{ $e } +msg-15211c7c = Failed to download image:{ $e } +msg-2245219f = Coze chat_messages payload:{ $payload }, params:{ $params } +msg-d8fd415c = Coze API streaming request failed, status code:{ $res } +msg-f5cc7604 = Coze API Streaming Request Timeout{ $timeout }second(s) +msg-30c0a9d6 = Coze API streaming request failed:{ $e } +msg-11509aba = Coze API request failed, status code:{ $res } +msg-002af11d = Coze API returns non-JSON format +msg-c0b8fc7c = Coze API request timeout +msg-a68a33fa = Coze API request failed:{ $e } +msg-c26e068e = Failed to get Coze message list:{ $e } +msg-5bc0a49d = Uploaded file_id:{ $file_id } +msg-7c08bdaf = Event:{ $event } ### astrbot/core/agent/runners/dify/dify_api_client.py -msg-cd6cd7ac = Drop invalid dify json data: {$res} -msg-3654a12d = chat_messages payload: {$payload} -msg-8e865c52 = Dify /chat-messages 接口请求失败:{$res}. {$text} -msg-2d7534b8 = workflow_run payload: {$payload} -msg-89918ba5 = Dify /workflows/run 接口请求失败:{$res}. {$text} -msg-8bf17938 = file_path 和 file_data 不能同时为 None -msg-b6ee8f38 = Dify 文件上传失败:{$res}. {$text} + +msg-cd6cd7ac = Drop invalid dify json data:{ $res } +msg-3654a12d = chat_messages payload:{ $payload } +msg-8e865c52 = Dify /chat-messages API request failed:{ $res }.{ $text } +msg-2d7534b8 = workflow_run payload:{ $payload } +msg-89918ba5 = Dify /workflows/run interface request failed:{ $res }.{ $text } +msg-8bf17938 = file_path and file_data cannot both be None +msg-b6ee8f38 = Dify file upload failed:{ $res }.{ $text } ### astrbot/core/agent/runners/dify/dify_agent_runner.py + msg-55333301 = Request is not set. Please call reset() first. -msg-d3b77736 = Error in on_agent_begin hook: {$e} -msg-0d493427 = Dify 请求失败:{$res} -msg-fe594f21 = Dify 上传图片响应:{$file_response} -msg-3534b306 = 上传图片后得到未知的 Dify 响应:{$file_response},图片将忽略。 -msg-08441fdf = 上传图片失败:{$e} -msg-3972f693 = dify resp chunk: {$chunk} +msg-d3b77736 = Error in on_agent_begin hook:{ $e } +msg-0d493427 = Dify request failed:{ $res } +msg-fe594f21 = Dify upload image response:{ $file_response } +msg-3534b306 = Received an unknown Dify response after uploading the image:{ $file_response }, images will be ignored. +msg-08441fdf = Upload image failed:{ $e } +msg-3972f693 = dify resp chunk:{ $chunk } msg-6c74267b = Dify message end -msg-1ce260ba = Dify 出现错误:{$chunk} -msg-a12417dd = Dify 出现错误 status: {$res} message: {$res_2} -msg-f8530ee9 = dify workflow resp chunk: {$chunk} -msg-386a282e = Dify 工作流(ID: {$res})开始运行。 -msg-0bc1299b = Dify 工作流节点(ID: {$res} Title: {$res_2})运行结束。 -msg-5cf24248 = Dify 工作流(ID: {$res})运行结束 -msg-e2c2159f = Dify 工作流结果:{$chunk} -msg-4fa60ef1 = Dify 工作流出现错误:{$res} -msg-1f786836 = Dify 工作流的输出不包含指定的键名:{$res} -msg-c4a70ffb = 未知的 Dify API 类型:{$res} -msg-51d321fd = Dify 请求结果为空,请查看 Debug 日志。 -msg-8eb53be3 = Error in on_agent_done hook: {$e} +msg-1ce260ba = Dify encountered an error:{ $chunk } +msg-a12417dd = Dify encountered an error status:{ $res }message:{ $res_2 } +msg-f8530ee9 = dify workflow resp chunk:{ $chunk } +msg-386a282e = Dify Workflow (ID:{ $res }Start running. +msg-0bc1299b = Dify workflow node (ID:{ $res }Title:{ $res_2 }) Running completed. +msg-5cf24248 = Dify workflow (ID:{ $res }) Run completed +msg-e2c2159f = Dify Workflow Result:{ $chunk } +msg-4fa60ef1 = Dify workflow error:{ $res } +msg-1f786836 = Dify workflow output does not contain the specified key name:{ $res } +msg-c4a70ffb = Unknown Dify API type:{ $res } +msg-51d321fd = Dify request result is empty, please check the Debug logs. +msg-8eb53be3 = Error in on_agent_done hook:{ $e } ### astrbot/core/star/session_plugin_manager.py -msg-16cc2a7a = 插件 {$res} 在会话 {$session_id} 中被禁用,跳过处理器 {$res_2} + +msg-16cc2a7a = Plugin{ $res }In session{ $session_id }Disabled in, skipping processor{ $res_2 } ### astrbot/core/star/star_manager.py -msg-bfa28c02 = 未安装 watchfiles,无法实现插件的热重载。 -msg-f8e1c445 = 插件热重载监视任务异常: {$e} -msg-78b9c276 = {$res} -msg-28aeca68 = 检测到文件变化: {$changes} -msg-aeec7738 = 检测到插件 {$plugin_name} 文件变化,正在重载... -msg-4f989555 = 插件 {$d} 未找到 main.py 或者 {$d}.py,跳过。 -msg-74b32804 = 正在安装插件 {$p} 所需的依赖库: {$pth} -msg-936edfca = 更新插件 {$p} 的依赖失败。Code: {$e} -msg-ebd47311 = 插件 {$root_dir_name} 导入失败,尝试从已安装依赖恢复: {$import_exc} -msg-1b6e94f1 = 插件 {$root_dir_name} 已从 site-packages 恢复依赖,跳过重新安装。 -msg-81b7c9b9 = 插件 {$root_dir_name} 已安装依赖恢复失败,将重新安装依赖: {$recover_exc} -msg-22fde75d = 插件不存在。 -msg-3a307a9e = 插件元数据信息不完整。name, desc, version, author 是必须的字段。 -msg-55e089d5 = 删除模块 {$key} -msg-64de1322 = 删除模块 {$module_name} -msg-66823424 = 模块 {$module_name} 未载入 -msg-45c8df8d = 清除了插件{$dir_name}中的{$key}模块 -msg-f7d9aa9b = 清理处理器: {$res} -msg-3c492aa6 = 清理工具: {$res} -msg-e0002829 = 插件 {$res} 未被正常终止: {$e}, 可能会导致该插件运行不正常。 -msg-0fe27735 = 正在载入插件 {$root_dir_name} ... -msg-b2ec4801 = {$error_trace} -msg-db351291 = 插件 {$root_dir_name} 导入失败。原因:{$e} -msg-a3db5f45 = 失败插件依旧在插件列表中,正在清理... -msg-58c66a56 = 插件 {$root_dir_name} 元数据载入失败: {$e}。使用默认元数据。 -msg-da764b29 = {$metadata} -msg-17cd7b7d = 插件 {$res} 已被禁用。 -msg-4baf6814 = 插件 {$path} 未通过装饰器注册。尝试通过旧版本方式载入。 -msg-840994d1 = 无法找到插件 {$plugin_dir_path} 的元数据。 -msg-944ffff1 = 插入权限过滤器 {$cmd_type} 到 {$res} 的 {$res_2} 方法。 -msg-64edd12c = hook(on_plugin_loaded) -> {$res} - {$res_2} -msg-db49f7a1 = ----- 插件 {$root_dir_name} 载入失败 ----- -msg-26039659 = | {$line} -msg-4292f44d = ---------------------------------- -msg-d2048afe = 同步指令配置失败: {$e} -msg-df515dec = 已清理安装失败的插件目录: {$plugin_path} -msg-1f2aa1a9 = 清理安装失败插件目录失败: {$plugin_path},原因: {$e} -msg-1e947210 = 已清理安装失败插件配置: {$plugin_config_path} -msg-7374541f = 清理安装失败插件配置失败: {$plugin_config_path},原因: {$e} -msg-e871b08f = 读取插件 {$dir_name} 的 README.md 文件失败: {$e} -msg-70ca4592 = 该插件是 AstrBot 保留插件,无法卸载。 -msg-e247422b = 插件 {$plugin_name} 未被正常终止 {$e}, 可能会导致资源泄露等问题。 -msg-0c25dbf4 = 插件 {$plugin_name} 数据不完整,无法卸载。 -msg-d6f8142c = 移除插件成功,但是删除插件文件夹失败: {$e}。您可以手动删除该文件夹,位于 addons/plugins/ 下。 -msg-6313500c = 已删除插件 {$plugin_name} 的配置文件 -msg-f0f01b67 = 删除插件配置文件失败: {$e} -msg-c4008b30 = 已删除插件 {$plugin_name} 的持久化数据 (plugin_data) -msg-88d1ee05 = 删除插件持久化数据失败 (plugin_data): {$e} -msg-ba805469 = 已删除插件 {$plugin_name} 的持久化数据 (plugins_data) -msg-cf6eb821 = 删除插件持久化数据失败 (plugins_data): {$e} -msg-e1853811 = 移除了插件 {$plugin_name} 的处理函数 {$res} ({$res_2}) -msg-95b20050 = 移除了插件 {$plugin_name} 的平台适配器 {$adapter_name} -msg-9f248e88 = 该插件是 AstrBot 保留插件,无法更新。 -msg-ff435883 = 正在终止插件 {$res} ... -msg-355187b7 = 插件 {$res} 未被激活,不需要终止,跳过。 -msg-4369864f = hook(on_plugin_unloaded) -> {$res} - {$res_2} -msg-1b95e855 = 插件 {$plugin_name} 不存在。 -msg-c1bc6cd6 = 检测到插件 {$res} 已安装,正在终止旧插件... -msg-4f3271db = 检测到同名插件 {$res} 存在于不同目录 {$res_2},正在终止... -msg-d247fc54 = 读取新插件 metadata.yaml 失败,跳过同名检查: {$e} -msg-0f8947f8 = 删除插件压缩包失败: {$e} + +msg-bfa28c02 = watchfiles is not installed, hot reloading of plugins cannot be achieved. +msg-f8e1c445 = Plugin hot reload monitoring task exception:{ $e } +msg-78b9c276 = { $res } +msg-28aeca68 = File change detected:{ $changes } +msg-aeec7738 = Plugin detected{ $plugin_name }File changed, reloading... +msg-4f989555 = Plugin{ $d }main.py not found{ $d }.py,跳过。 +msg-74b32804 = Installing plugin{ $p }Required dependencies:{ $pth } +msg-936edfca = Update plugin{ $p }Dependency failure. Code:{ $e } +msg-ebd47311 = Plugin{ $root_dir_name }Import failed, attempting to recover from installed dependencies:{ $import_exc } +msg-1b6e94f1 = Plugin{ $root_dir_name }Dependencies have been restored from site-packages, skipping reinstallation. +msg-81b7c9b9 = Plugin{ $root_dir_name }Failed to restore installed dependencies, will reinstall dependencies:{ $recover_exc } +msg-22fde75d = The plugin does not exist. +msg-3a307a9e = Plugin metadata information is incomplete. name, desc, version, and author are required fields. +msg-55e089d5 = Delete module{ $key } +msg-64de1322 = Delete Module{ $module_name } +msg-66823424 = Module{ $module_name }Not loaded +msg-45c8df8d = Cleared plugin{ $dir_name }In{ $key }Module +msg-f7d9aa9b = Cleanup Processor:{ $res } +msg-3c492aa6 = Cleanup Tool:{ $res } +msg-e0002829 = Plugin{ $res }Not properly terminated:{ $e }, may cause this plugin to malfunction. +msg-0fe27735 = Loading plugins{ $root_dir_name }... +msg-b2ec4801 = { $error_trace } +msg-db351291 = Plugin{ $root_dir_name }Import failed. Reason:{ $e } +msg-a3db5f45 = Failed plugins are still in the plugin list, cleaning up... +msg-58c66a56 = Plugin{ $root_dir_name }Metadata load failed:{ $e }Use default metadata. +msg-da764b29 = { $metadata } +msg-17cd7b7d = Plugin{ $res }It has been disabled. +msg-4baf6814 = Plugin{ $path }Not registered via decorator. Attempting to load using legacy method. +msg-840994d1 = Plugin not found{ $plugin_dir_path }metadata of +msg-944ffff1 = Insert permission filter{ $cmd_type }To{ $res }of{ $res_2 }Method. +msg-64edd12c = hook(on_plugin_loaded) ->{ $res }-{ $res_2 } +msg-db49f7a1 = ----- Plugin{ $root_dir_name }Failed to load +msg-26039659 = |{ $line } +msg-4292f44d = Text to be translated: ---------------------------------- +msg-d2048afe = Synchronization command configuration failed:{ $e } +msg-df515dec = Cleaned up installation failed plugin directory:{ $plugin_path } +msg-1f2aa1a9 = Failed to clean up the installation directory for the failed plugin:{ $plugin_path }Reason:{ $e } +msg-1e947210 = Cleaned up configuration for failed plugin installation:{ $plugin_config_path } +msg-7374541f = Failed to clean up configuration of unsuccessfully installed plugins:{ $plugin_config_path }, Reason:{ $e } +msg-e871b08f = Reading plugins{ $dir_name }Failed to read the README.md file:{ $e } +msg-70ca4592 = This plugin is a reserved plugin of AstrBot and cannot be uninstalled. +msg-e247422b = Plugin{ $plugin_name }Not normally terminated{ $e }, which may lead to resource leaks and other issues. +msg-0c25dbf4 = Plugin{ $plugin_name }Data is incomplete, cannot uninstall. +msg-d6f8142c = Plugin removed successfully, but failed to delete plugin folder:{ $e }You can manually delete this folder located under addons/plugins/. +msg-6313500c = Deleted plugin{ $plugin_name }configuration file +msg-f0f01b67 = Failed to delete plugin configuration file:{ $e } +msg-c4008b30 = Deleted plugin{ $plugin_name }Persistent data (plugin_data) +msg-88d1ee05 = Failed to delete plugin persistent data (plugin_data):{ $e } +msg-ba805469 = Deleted plugin{ $plugin_name }persistent data (plugins_data) +msg-cf6eb821 = Failed to delete plugin persistent data (plugins_data):{ $e } +msg-e1853811 = Removed plugin{ $plugin_name }Processing function{ $res }Text to translate: ({ $res_2 }) +msg-95b20050 = Removed plugin{ $plugin_name }Platform Adapter{ $adapter_name } +msg-9f248e88 = This plugin is a reserved plugin for AstrBot and cannot be updated. +msg-ff435883 = Terminating plugin{ $res }... +msg-355187b7 = Plugin{ $res }Not activated, no need to terminate, skip. +msg-4369864f = hook(on_plugin_unloaded) ->{ $res }-{ $res_2 } +msg-1b95e855 = Plugin{ $plugin_name }It does not exist. +msg-c1bc6cd6 = Plug-in detected{ $res }Installed, terminating old plugin... +msg-4f3271db = Duplicate plugin detected{ $res }Exists in different directories{ $res_2 }, terminating... +msg-d247fc54 = Failed to read new plugin metadata.yaml, skipping duplicate name check:{ $e } +msg-0f8947f8 = Failed to delete plugin archive:{ $e } ### astrbot/core/star/session_llm_manager.py -msg-7b90d0e9 = 会话 {$session_id} 的TTS状态已更新为: {$res} + +msg-7b90d0e9 = Session{ $session_id }The TTS status has been updated to:{ $res } ### astrbot/core/star/config.py -msg-c2189e8d = namespace 不能为空。 -msg-97f66907 = namespace 不能以 internal_ 开头。 -msg-09179604 = key 只支持 str 类型。 -msg-1163e4f1 = value 只支持 str, int, float, bool, list 类型。 -msg-ed0f93e4 = 配置文件 {$namespace}.json 不存在。 -msg-e3b5cdfb = 配置项 {$key} 不存在。 + +msg-c2189e8d = Namespace cannot be empty. +msg-97f66907 = Namespace cannot start with internal_. +msg-09179604 = key only supports str type. +msg-1163e4f1 = value only supports str, int, float, bool, list types. +msg-ed0f93e4 = Configuration file{ $namespace }.json does not exist. +msg-e3b5cdfb = Configuration item{ $key }Does not exist. ### astrbot/core/star/star_tools.py + msg-397b7bf9 = StarTools not initialized -msg-ca30e638 = 未找到适配器: AiocqhttpAdapter -msg-77ca0ccb = 不支持的平台: {$platform} -msg-3ed67eb2 = 无法获取调用者模块信息 -msg-e77ccce6 = 无法获取模块 {$res} 的元数据信息 -msg-76ac38ee = 无法获取插件名称 -msg-751bfd23 = 无法创建目录 {$data_dir}:权限不足 -msg-68979283 = 无法创建目录 {$data_dir}:{$e} +msg-ca30e638 = No adapter found: AiocqhttpAdapter +msg-77ca0ccb = Unsupported platform:{ $platform } +msg-3ed67eb2 = Unable to retrieve caller module information +msg-e77ccce6 = Unable to retrieve module{ $res }Metadata information +msg-76ac38ee = Unable to retrieve plugin name +msg-751bfd23 = Cannot create directory{ $data_dir }Insufficient permissions +msg-68979283 = Unable to create directory{ $data_dir }Text to be translated:{ $e } ### astrbot/core/star/context.py -msg-60eb9e43 = Provider {$chat_provider_id} not found + +msg-60eb9e43 = Provider{ $chat_provider_id }not found msg-da70a6fb = Agent did not produce a final LLM response msg-141151fe = Provider not found -msg-a5cb19c6 = 没有找到 ID 为 {$provider_id} 的提供商,这可能是由于您修改了提供商(模型)ID 导致的。 -msg-2a44300b = 该会话来源的对话模型(提供商)的类型不正确: {$res} -msg-37c286ea = 返回的 Provider 不是 TTSProvider 类型 -msg-ff775f3b = 返回的 Provider 不是 STTProvider 类型 -msg-fd8c8295 = cannot find platform for session {$res}, message not sent -msg-2b806a28 = plugin(module_path {$module_path}) added LLM tool: {$res} +msg-a5cb19c6 = ID not found for{ $provider_id }provider, which may be caused by you modifying the provider (model) ID. +msg-2a44300b = The conversation model (provider) type for the session source is incorrect:{ $res } +msg-37c286ea = The returned Provider is not of type TTSProvider. +msg-ff775f3b = The returned Provider is not of type STTProvider +msg-fd8c8295 = cannot find platform for session{ $res }, message not sent +msg-2b806a28 = plugin(module_path){ $module_path }) added LLM tool:{ $res } ### astrbot/core/star/updator.py -msg-66be72ec = 插件 {$res} 没有指定仓库地址。 -msg-7a29adea = 插件 {$res} 的根目录名未指定。 -msg-99a86f88 = 正在更新插件,路径: {$plugin_path},仓库地址: {$repo_url} -msg-df2c7e1b = 删除旧版本插件 {$plugin_path} 文件夹失败: {$e},使用覆盖安装。 -msg-b3471491 = 正在解压压缩包: {$zip_path} -msg-7197ad11 = 删除临时文件: {$zip_path} 和 {$res} -msg-f8a43aa5 = 删除更新文件失败,可以手动删除 {$zip_path} 和 {$res} + +msg-66be72ec = Plugin{ $res }No repository address specified. +msg-7a29adea = Plugin{ $res }The root directory name is not specified. +msg-99a86f88 = Updating plugin, path:{ $plugin_path }Repository address:{ $repo_url } +msg-df2c7e1b = Delete old version plugins{ $plugin_path }Folder failed:{ $e }, using the overwrite installation. +msg-b3471491 = Unzipping archive:{ $zip_path } +msg-7197ad11 = Delete temporary files:{ $zip_path }and{ $res } +msg-f8a43aa5 = Failed to delete the update file. You can delete it manually.{ $zip_path }and{ $res } ### astrbot/core/star/command_management.py -msg-011581bb = 指定的处理函数不存在或不是指令。 -msg-a0c37004 = 指令名不能为空。 -msg-ae8b2307 = 指令名 '{$candidate_full}' 已被其他指令占用。 -msg-247926a7 = 别名 '{$alias_full}' 已被其他指令占用。 -msg-dbd19a23 = 权限类型必须为 admin 或 member。 -msg-9388ea1e = 未找到指令所属插件 -msg-0dd9b70d = 解析指令处理函数 {$res} 失败,跳过该指令。原因: {$e} + +msg-011581bb = The specified handler function does not exist or is not an instruction. +msg-a0c37004 = Command name cannot be empty. +msg-ae8b2307 = Command name '{ $candidate_full }' is already occupied by another instruction. +msg-247926a7 = Alias{ $alias_full }It has been occupied by other instructions. +msg-dbd19a23 = Permission type must be admin or member. +msg-9388ea1e = Plugin for the command not found +msg-0dd9b70d = Parse instruction processing function{ $res }Failed, skipping this instruction. Reason:{ $e } ### astrbot/core/star/base.py -msg-57019272 = get_config() failed: {$e} + +msg-57019272 = get_config() failed:{ $e } ### astrbot/core/star/register/star.py + msg-64619f8e = The 'register_star' decorator is deprecated and will be removed in a future version. ### astrbot/core/star/register/star_handler.py -msg-7ff2d46e = 注册指令{$command_name} 的子指令时未提供 sub_command 参数。 -msg-b68436e1 = 注册裸指令时未提供 command_name 参数。 -msg-1c183df2 = {$command_group_name} 指令组的子指令组 sub_command 未指定 -msg-9210c7e8 = 根指令组的名称未指定 -msg-678858e7 = 注册指令组失败。 -msg-6c3915e0 = LLM 函数工具 {$res}_{$llm_tool_name} 的参数 {$res_2} 缺少类型注释。 -msg-1255c964 = LLM 函数工具 {$res}_{$llm_tool_name} 不支持的参数类型:{$res_2} + +msg-7ff2d46e = Registration instruction{ $command_name }The sub_command parameter was not provided when using the sub-command. +msg-b68436e1 = No command_name parameter provided when registering a bare instruction. +msg-1c183df2 = { $command_group_name }The sub_command of the command group is not specified. +msg-9210c7e8 = The name of the root command group is not specified. +msg-678858e7 = Registration of the instruction group failed. +msg-6c3915e0 = LLM Function Tools{ $res }_{ $llm_tool_name }'s parameters{ $res_2 }Missing type annotation. +msg-1255c964 = LLM function tools{ $res }_{ $llm_tool_name }Unsupported parameter type:{ $res_2 } ### astrbot/core/star/filter/command.py -msg-995944c2 = 参数 '{$param_name}' (GreedyStr) 必须是最后一个参数。 -msg-04dbdc3a = 必要参数缺失。该指令完整参数: {$res} -msg-bda71712 = 参数 {$param_name} 必须是布尔值(true/false, yes/no, 1/0)。 -msg-a9afddbf = 参数 {$param_name} 类型错误。完整参数: {$res} + +msg-995944c2 = Parameter '{ $param_name }(GreedyStr) must be the last argument. +msg-04dbdc3a = Required parameters missing. Full parameters for this command:{ $res } +msg-bda71712 = Parameter{ $param_name }Must be a boolean value (true/false, yes/no, 1/0). +msg-a9afddbf = Parameter{ $param_name }Type error. Full parameters:{ $res } ### astrbot/core/star/filter/custom_filter.py + msg-8f3eeb6e = Operands must be subclasses of CustomFilter. -msg-732ada95 = CustomFilter class can only operate with other CustomFilter. -msg-51c0c77d = CustomFilter lass can only operate with other CustomFilter. +msg-732ada95 = The CustomFilter class can only operate with other CustomFilter. +msg-51c0c77d = CustomFilter class can only operate with other CustomFilter. ### astrbot/core/db/vec_db/faiss_impl/document_storage.py + msg-c2dc1d2b = Database connection is not initialized, returning empty result msg-51fa7426 = Database connection is not initialized, skipping delete operation msg-43d1f69f = Database connection is not initialized, returning 0 ### astrbot/core/db/vec_db/faiss_impl/embedding_storage.py -msg-8e5fe535 = faiss 未安装。请使用 'pip install faiss-cpu' 或 'pip install faiss-gpu' 安装。 -msg-9aa7b941 = 向量维度不匹配, 期望: {$res}, 实际: {$res_2} + +msg-8e5fe535 = faiss is not installed. Please install it using 'pip install faiss-cpu' or 'pip install faiss-gpu'. +msg-9aa7b941 = Vector dimension mismatch, expected:{ $res }, actual:{ $res_2 } ### astrbot/core/db/vec_db/faiss_impl/vec_db.py -msg-9f9765dc = Generating embeddings for {$res} contents... -msg-385bc50a = Generated embeddings for {$res} contents in {$res_2} seconds. + +msg-9f9765dc = Generating embeddings for{ $res }contents... +msg-385bc50a = Generated embeddings for{ $res }contents in{ $res_2 }seconds. ### astrbot/core/db/migration/migra_token_usage.py -msg-c3e53a4f = 开始执行数据库迁移(添加 conversations.token_usage 列)... -msg-ccbd0a41 = token_usage 列已存在,跳过迁移 -msg-39f60232 = token_usage 列添加成功 -msg-4f9d3876 = token_usage 迁移完成 -msg-91571aaf = 迁移过程中发生错误: {$e} + +msg-c3e53a4f = Starting database migration (adding conversations.token_usage column)... +msg-ccbd0a41 = The token_usage column already exists, skipping migration +msg-39f60232 = token_usage column added successfully +msg-4f9d3876 = token_usage migration completed +msg-91571aaf = An error occurred during migration:{ $e } ### astrbot/core/db/migration/migra_3_to_4.py -msg-7805b529 = 迁移 {$total_cnt} 条旧的会话数据到新的表中... -msg-6f232b73 = 进度: {$progress}% ({$res}/{$total_cnt}) -msg-6b1def31 = 未找到该条旧会话对应的具体数据: {$conversation}, 跳过。 -msg-b008c93f = 迁移旧会话 {$res} 失败: {$e} -msg-6ac6313b = 成功迁移 {$total_cnt} 条旧的会话数据到新表。 -msg-6b72e89b = 迁移旧平台数据,offset_sec: {$offset_sec} 秒。 -msg-bdc90b84 = 迁移 {$res} 条旧的平台数据到新的表中... -msg-e6caca5c = 没有找到旧平台数据,跳过迁移。 -msg-1e824a79 = 进度: {$progress}% ({$res}/{$total_buckets}) -msg-813384e2 = 迁移平台统计数据失败: {$platform_id}, {$platform_type}, 时间戳: {$bucket_end} -msg-27ab191d = 成功迁移 {$res} 条旧的平台数据到新表。 -msg-8e6280ed = 迁移 {$total_cnt} 条旧的 WebChat 会话数据到新的表中... -msg-cad66fe1 = 迁移旧 WebChat 会话 {$res} 失败 -msg-63748a46 = 成功迁移 {$total_cnt} 条旧的 WebChat 会话数据到新表。 -msg-dfc93fa4 = 迁移 {$total_personas} 个 Persona 配置到新表中... -msg-ff85e45c = 进度: {$progress}% ({$res}/{$total_personas}) -msg-c346311e = 迁移 Persona {$res}({$res_2}...) 到新表成功。 -msg-b6292b94 = 解析 Persona 配置失败:{$e} -msg-90e5039e = 迁移全局偏好设置 {$key} 成功,值: {$value} -msg-d538da1c = 迁移会话 {$umo} 的对话数据到新表成功,平台 ID: {$platform_id} -msg-ee03c001 = 迁移会话 {$umo} 的对话数据失败: {$e} -msg-5c4339cd = 迁移会话 {$umo} 的服务配置到新表成功,平台 ID: {$platform_id} -msg-4ce2a0b2 = 迁移会话 {$umo} 的服务配置失败: {$e} -msg-2e62dab9 = 迁移会话 {$umo} 的变量失败: {$e} -msg-afbf819e = 迁移会话 {$umo} 的提供商偏好到新表成功,平台 ID: {$platform_id} -msg-959bb068 = 迁移会话 {$umo} 的提供商偏好失败: {$e} + +msg-7805b529 = Migration{ $total_cnt }Migrating old session data to the new table... +msg-6f232b73 = Progress:{ $progress }% ({ $res }Text to be translated:{ $total_cnt }) +msg-6b1def31 = No specific data found for this old session:{ $conversation }, skip. +msg-b008c93f = Migrate old sessions{ $res }Failed:{ $e } +msg-6ac6313b = Successfully migrated{ $total_cnt }Migrate old session data to the new table. +msg-6b72e89b = Migrate data from the old platform, offset_sec:{ $offset_sec }Seconds. +msg-bdc90b84 = Migration{ $res }Migrating old platform data to the new table... +msg-e6caca5c = No old platform data found, skipping migration. +msg-1e824a79 = Progress:{ $progress }% ({ $res }Text to translate:{ $total_buckets }) +msg-813384e2 = Migration platform statistics failed:{ $platform_id },{ $platform_type }, Timestamp:{ $bucket_end } +msg-27ab191d = Migration successful{ $res }Migrate old platform data to the new table. +msg-8e6280ed = Migration{ $total_cnt }Migrating old WebChat session data to the new table... +msg-cad66fe1 = Migrate old WebChat sessions{ $res }Failed +msg-63748a46 = Successfully migrated{ $total_cnt }Migrate old WebChat session data to the new table. +msg-dfc93fa4 = Migration{ $total_personas }Configuring Persona to new table... +msg-ff85e45c = Progress:{ $progress }% ({ $res }Text to be translated:{ $total_personas }) +msg-c346311e = Migrate Persona{ $res }Text to be translated:{ $res_2 }...) to new table succeeded. +msg-b6292b94 = Failed to parse Persona configuration:{ $e } +msg-90e5039e = Migrate global preference settings{ $key }Success, value:{ $value } +msg-d538da1c = Migrate Session{ $umo }Dialogue data successfully migrated to new table, Platform ID:{ $platform_id } +msg-ee03c001 = Migrate Session{ $umo }Failed to retrieve conversation data:{ $e } +msg-5c4339cd = Migrate Session{ $umo }Service configuration migrated to new table successfully, platform ID:{ $platform_id } +msg-4ce2a0b2 = Migration session{ $umo }Service configuration failed:{ $e } +msg-2e62dab9 = Migrate Session{ $umo }Failed to set variable:{ $e } +msg-afbf819e = Migration session{ $umo }Provider preferences migrated to new table successfully, platform ID:{ $platform_id } +msg-959bb068 = Migrate Session{ $umo }Provider preference failed:{ $e } ### astrbot/core/db/migration/helper.py -msg-a48f4752 = 开始执行数据库迁移... -msg-45e31e8e = 数据库迁移完成。 + +msg-a48f4752 = Starting database migration... +msg-45e31e8e = Database migration completed. ### astrbot/core/db/migration/migra_45_to_46.py -msg-782b01c1 = migrate_45_to_46: abconf_data is not a dict (type={$res}). Value: {$abconf_data} + +msg-782b01c1 = migrate_45_to_46: abconf_data is not a dict (type={ $res }). Value:{ $abconf_data } msg-49e09620 = Starting migration from version 4.5 to 4.6 msg-791b79f8 = Migration from version 45 to 46 completed successfully ### astrbot/core/db/migration/migra_webchat_session.py -msg-53fad3d0 = 开始执行数据库迁移(WebChat 会话迁移)... -msg-7674efb0 = 没有找到需要迁移的 WebChat 数据 -msg-139e39ee = 找到 {$res} 个 WebChat 会话需要迁移 -msg-cf287e58 = 会话 {$session_id} 已存在,跳过 -msg-062c72fa = WebChat 会话迁移完成!成功迁移: {$res}, 跳过: {$skipped_count} -msg-a516cc9f = 没有新会话需要迁移 -msg-91571aaf = 迁移过程中发生错误: {$e} + +msg-53fad3d0 = Start executing database migration (WebChat session migration)... +msg-7674efb0 = No WebChat data requiring migration was found. +msg-139e39ee = Find{ $res }A WebChat session requires migration +msg-cf287e58 = Session{ $session_id }Already exists, skipping +msg-062c72fa = WebChat session migration completed! Successfully migrated:{ $res }, skip:{ $skipped_count } +msg-a516cc9f = No new sessions need to be migrated. +msg-91571aaf = An error occurred during the migration:{ $e } ### astrbot/core/knowledge_base/kb_helper.py -msg-7b3dc642 = - LLM call failed on attempt {$res}/{$res_2}. Error: {$res_3} -msg-4ba9530f = - Failed to process chunk after {$res} attempts. Using original text. -msg-77670a3a = 知识库 {$res} 未配置 Embedding Provider -msg-8e9eb3f9 = 无法找到 ID 为 {$res} 的 Embedding Provider -msg-3e426806 = 无法找到 ID 为 {$res} 的 Rerank Provider -msg-6e780e1e = 使用预分块文本进行上传,共 {$res} 个块。 -msg-f4b82f18 = 当未提供 pre_chunked_text 时,file_content 不能为空。 -msg-975f06d7 = 上传文档失败: {$e} -msg-969b17ca = 清理多媒体文件失败 {$media_path}: {$me} -msg-18d25e55 = 无法找到 ID 为 {$doc_id} 的文档 + +msg-7b3dc642 = - LLM call failed on attempt{ $res }/{ $res_2 }. Error:{ $res_3 } +msg-4ba9530f = - Failed to process chunk after{ $res }attempts. Using original text. +msg-77670a3a = Knowledge Base{ $res }Embedding Provider is not configured +msg-8e9eb3f9 = Could not find ID{ $res }Embedding Provider +msg-3e426806 = Unable to find ID{ $res }Rerank Provider +msg-6e780e1e = Using pre-chunked text for upload, total{ $res }blocks. +msg-f4b82f18 = When pre_chunked_text is not provided, file_content cannot be empty. +msg-975f06d7 = Failed to upload document:{ $e } +msg-969b17ca = Failed to clean up multimedia files{ $media_path }Text to be translated:{ $me } +msg-18d25e55 = Unable to find ID{ $doc_id }Documentation msg-f5d7c34c = Error: Tavily API key is not configured in provider_settings. -msg-975d88e0 = Failed to extract content from URL {$url}: {$e} -msg-cfe431b3 = No content extracted from URL: {$url} -msg-e7f5f836 = 内容清洗后未提取到有效文本。请尝试关闭内容清洗功能,或更换更高性能的LLM模型后重试。 -msg-693aa5c5 = 内容清洗未启用,使用指定参数进行分块: chunk_size={$chunk_size}, chunk_overlap={$chunk_overlap} -msg-947d8f46 = 启用了内容清洗,但未提供 cleaning_provider_id,跳过清洗并使用默认分块。 -msg-31963d3f = 无法找到 ID 为 {$cleaning_provider_id} 的 LLM Provider 或类型不正确 -msg-82728272 = 初步分块完成,生成 {$res} 个块用于修复。 -msg-6fa5fdca = 块 {$i} 处理异常: {$res}. 回退到原始块。 -msg-6780e950 = 文本修复完成: {$res} 个原始块 -> {$res_2} 个最终块。 -msg-79056c76 = 使用 Provider '{$cleaning_provider_id}' 清洗内容失败: {$e} +msg-975d88e0 = Failed to extract content from URL{ $url }Text to be translated:{ $e } +msg-cfe431b3 = No content extracted from URL:{ $url } +msg-e7f5f836 = No valid text extracted after content cleaning. Please try disabling the content cleaning feature or retry with a higher-performance LLM model. +msg-693aa5c5 = Content cleaning is not enabled, using specified parameters for chunking: chunk_size={ $chunk_size }, chunk_overlap={ $chunk_overlap } +msg-947d8f46 = Content cleaning is enabled, but no cleaning_provider_id is provided, skipping cleaning and using default chunking. +msg-31963d3f = Unable to find ID{ $cleaning_provider_id }The LLM Provider or type is incorrect. +msg-82728272 = Initial chunking completed, generating{ $res }blocks to repair. +msg-6fa5fdca = Block{ $i }Handling exceptions:{ $res }Fallback to original block. +msg-6780e950 = Text repair completed:{ $res }original blocks{ $res_2 }Final block. +msg-79056c76 = Use Provider '{ $cleaning_provider_id }Failed to clean content:{ $e } ### astrbot/core/knowledge_base/kb_mgr.py -msg-98bfa670 = 正在初始化知识库模块... -msg-7da7ae15 = 知识库模块导入失败: {$e} -msg-842a3c65 = 请确保已安装所需依赖: pypdf, aiofiles, Pillow, rank-bm25 -msg-c9e943f7 = 知识库模块初始化失败: {$e} -msg-78b9c276 = {$res} -msg-9349e112 = KnowledgeBase database initialized: {$DB_PATH} -msg-7605893e = 创建知识库时必须提供embedding_provider_id -msg-0b632cbd = 知识库名称 '{$kb_name}' 已存在 -msg-ca30330f = 关闭知识库 {$kb_id} 失败: {$e} -msg-00262e1f = 关闭知识库元数据数据库失败: {$e} -msg-3fc9ef0b = Knowledge base with id {$kb_id} not found. + +msg-98bfa670 = Initializing the knowledge base module... +msg-7da7ae15 = Knowledge base module import failed:{ $e } +msg-842a3c65 = Please ensure the required dependencies are installed: pypdf, aiofiles, Pillow, rank-bm25 +msg-c9e943f7 = Knowledge base module initialization failed:{ $e } +msg-78b9c276 = { $res } +msg-9349e112 = KnowledgeBase database initialized:{ $DB_PATH } +msg-7605893e = You must provide an embedding_provider_id when creating a knowledge base. +msg-0b632cbd = Knowledge base name{ $kb_name }already exists +msg-ca30330f = Close Knowledge Base{ $kb_id }Failed:{ $e } +msg-00262e1f = Failed to close the knowledge base metadata database:{ $e } +msg-3fc9ef0b = Knowledge base with id{ $kb_id }not found. ### astrbot/core/knowledge_base/kb_db_sqlite.py -msg-b850e5d8 = 知识库数据库已关闭: {$res} + +msg-b850e5d8 = Knowledge base database is closed:{ $res } ### astrbot/core/knowledge_base/parsers/util.py -msg-398b3580 = 暂时不支持的文件格式: {$ext} + +msg-398b3580 = Temporarily unsupported file format:{ $ext } ### astrbot/core/knowledge_base/parsers/url_parser.py + msg-2de85bf5 = Error: Tavily API keys are not configured. msg-98ed69f4 = Error: url must be a non-empty string. -msg-7b14cdb7 = Tavily web extraction failed: {$reason}, status: {$res} -msg-cfe431b3 = No content extracted from URL: {$url} -msg-b0897365 = Failed to fetch URL {$url}: {$e} -msg-975d88e0 = Failed to extract content from URL {$url}: {$e} +msg-7b14cdb7 = Tavily web extraction failed:{ $reason }, status:{ $res } +msg-cfe431b3 = No content extracted from URL:{ $url } +msg-b0897365 = Failed to fetch URL{ $url }Text to be translated:{ $e } +msg-975d88e0 = Failed to extract content from URL{ $url }Text to be translated:{ $e } ### astrbot/core/knowledge_base/parsers/text_parser.py -msg-70cbd40d = 无法解码文件: {$file_name} + +msg-70cbd40d = Unable to decode file:{ $file_name } ### astrbot/core/knowledge_base/chunking/recursive.py + msg-21db456a = chunk_size must be greater than 0 msg-c0656f4e = chunk_overlap must be non-negative msg-82bd199c = chunk_overlap must be less than chunk_size ### astrbot/core/knowledge_base/retrieval/manager.py -msg-fcc0dde2 = 知识库 ID {$kb_id} 实例未找到, 已跳过该知识库的检索 -msg-320cfcff = Dense retrieval across {$res} bases took {$res_2}s and returned {$res_3} results. -msg-90ffcfc8 = Sparse retrieval across {$res} bases took {$res_2}s and returned {$res_3} results. -msg-12bcf404 = Rank fusion took {$res}s and returned {$res_2} results. -msg-28c084bc = vec_db for kb_id {$kb_id} is not FaissVecDB -msg-cc0230a3 = 知识库 {$kb_id} 稠密检索失败: {$e} + +msg-fcc0dde2 = Knowledge Base ID{ $kb_id }Instance not found, skipped retrieval for this knowledge base. +msg-320cfcff = Dense retrieval across{ $res }bases took{ $res_2 }s and returned{ $res_3 }Results. +msg-90ffcfc8 = Sparse retrieval across{ $res }bases took{ $res_2 }s and returned{ $res_3 }results. +msg-12bcf404 = Rank fusion took{ $res }s and returned{ $res_2 }results. +msg-28c084bc = vec_db for kb_id{ $kb_id }is not FaissVecDB +msg-cc0230a3 = Knowledge Base{ $kb_id }Dense retrieval failed:{ $e } ### astrbot/core/skills/skill_manager.py -msg-ed9670ad = Zip file not found: {$zip_path} + +msg-ed9670ad = Zip file not found:{ $zip_path } msg-73f9cf65 = Uploaded file is not a valid zip archive. msg-69eb5f95 = Zip archive is empty. -msg-9e9abb4c = {$top_dirs} +msg-9e9abb4c = { $top_dirs } msg-20b8533f = Zip archive must contain a single top-level folder. msg-1db1caf7 = Invalid skill folder name. msg-d7814054 = Zip archive contains absolute paths. @@ -1945,673 +2118,710 @@ msg-a4117c0b = Skill folder not found after extraction. msg-94041ef2 = Skill already exists. ### astrbot/core/backup/importer.py -msg-c046b6e4 = {$msg} -msg-0e6f1f5d = 开始从 {$zip_path} 导入备份 -msg-2bf97ca0 = 备份导入完成: {$res} -msg-e67dda98 = 备份文件缺少版本信息 -msg-8f871d9f = 版本差异警告: {$res} -msg-2d6da12a = 已清空表 {$table_name} -msg-7d21b23a = 清空表 {$table_name} 失败: {$e} -msg-ab0f09db = 已清空知识库表 {$table_name} -msg-7bcdfaee = 清空知识库表 {$table_name} 失败: {$e} -msg-43f008f1 = 清理知识库 {$kb_id} 失败: {$e} -msg-985cae66 = 未知的表: {$table_name} -msg-dfa8b605 = 导入记录到 {$table_name} 失败: {$e} -msg-89a2120c = 导入表 {$table_name}: {$count} 条记录 -msg-f1dec753 = 导入知识库记录到 {$table_name} 失败: {$e} -msg-9807bcd8 = 导入文档块失败: {$e} -msg-98a66293 = 导入附件 {$name} 失败: {$e} -msg-39f2325f = 备份版本不支持目录备份,跳过目录导入 -msg-689050b6 = 已备份现有目录 {$target_dir} 到 {$backup_path} -msg-d51b3536 = 导入目录 {$dir_name}: {$file_count} 个文件 + +msg-c046b6e4 = { $msg } +msg-0e6f1f5d = Start from{ $zip_path }Import Backup +msg-2bf97ca0 = Backup import completed:{ $res } +msg-e67dda98 = Backup file lacks version information +msg-8f871d9f = Version Difference Warning:{ $res } +msg-2d6da12a = Table cleared{ $table_name } +msg-7d21b23a = Clear Table{ $table_name }Failure:{ $e } +msg-ab0f09db = Knowledge base table has been cleared{ $table_name } +msg-7bcdfaee = Clear knowledge base table{ $table_name }Failed:{ $e } +msg-43f008f1 = Clean up knowledge base{ $kb_id }Failed:{ $e } +msg-985cae66 = Unknown table:{ $table_name } +msg-dfa8b605 = Import records to{ $table_name }Failed:{ $e } +msg-89a2120c = Import table{ $table_name }Text to translate:{ $count }records +msg-f1dec753 = Import knowledge base records to{ $table_name }Failed:{ $e } +msg-9807bcd8 = Failed to import document block:{ $e } +msg-98a66293 = Import attachment{ $name }Failed:{ $e } +msg-39f2325f = Backup version does not support directory backup, skipping directory import. +msg-689050b6 = Existing directory has been backed up{ $target_dir }To{ $backup_path } +msg-d51b3536 = Import Directory{ $dir_name }Text to be translated:{ $file_count }file ### astrbot/core/backup/exporter.py -msg-c7ed7177 = 开始导出备份到 {$zip_path} -msg-8099b694 = 备份导出完成: {$zip_path} -msg-75a4910d = 备份导出失败: {$e} -msg-2821fc92 = 导出表 {$table_name}: {$res} 条记录 -msg-52b7c242 = 导出表 {$table_name} 失败: {$e} -msg-56310830 = 导出知识库表 {$table_name}: {$res} 条记录 -msg-f4e8f57e = 导出知识库表 {$table_name} 失败: {$e} -msg-8e4ddd12 = 导出知识库文档失败: {$e} -msg-c1960618 = 导出 FAISS 索引: {$archive_path} -msg-314bf920 = 导出 FAISS 索引失败: {$e} -msg-528757b2 = 导出知识库媒体文件失败: {$e} -msg-d89d6dfe = 目录不存在,跳过: {$full_path} -msg-94527edd = 导出文件 {$file_path} 失败: {$e} -msg-cb773e24 = 导出目录 {$dir_name}: {$file_count} 个文件, {$total_size} 字节 -msg-ae929510 = 导出目录 {$dir_path} 失败: {$e} -msg-93e331d2 = 导出附件失败: {$e} + +msg-c7ed7177 = Start exporting backup to{ $zip_path } +msg-8099b694 = Backup export completed:{ $zip_path } +msg-75a4910d = Backup export failed:{ $e } +msg-2821fc92 = Export Table{ $table_name }Text to translate:{ $res }Records +msg-52b7c242 = Export Table{ $table_name }Failed:{ $e } +msg-56310830 = Export Knowledge Base Table{ $table_name }Text to be translated:{ $res }records +msg-f4e8f57e = Export knowledge base table{ $table_name }Failed:{ $e } +msg-8e4ddd12 = Failed to export knowledge base documents:{ $e } +msg-c1960618 = Export FAISS Index:{ $archive_path } +msg-314bf920 = Failed to export FAISS index:{ $e } +msg-528757b2 = Export knowledge base media files failed:{ $e } +msg-d89d6dfe = Directory does not exist, skipping:{ $full_path } +msg-94527edd = Export file{ $file_path }Failure:{ $e } +msg-cb773e24 = Export directory{ $dir_name }Text to be translated:{ $file_count }files,{ $total_size }Byte +msg-ae929510 = Export Directory{ $dir_path }Failed:{ $e } +msg-93e331d2 = Export attachment failed:{ $e } ### astrbot/core/computer/computer_client.py + msg-7cb974b8 = Uploading skills bundle to sandbox... msg-130cf3e3 = Failed to upload skills bundle to sandbox. -msg-99188d69 = Failed to remove temp skills zip: {$zip_path} -msg-3f3c81da = Unknown booter type: {$booter_type} -msg-e20cc33a = Error booting sandbox for session {$session_id}: {$e} +msg-99188d69 = Failed to remove temp skills zip:{ $zip_path } +msg-3f3c81da = Unknown booter type:{ $booter_type } +msg-e20cc33a = Error booting sandbox for session{ $session_id }Text to translate:{ $e } ### astrbot/core/computer/tools/fs.py -msg-99ab0efe = Upload result: {$result} -msg-bca9d578 = File {$local_path} uploaded to sandbox at {$file_path} -msg-da21a6a5 = Error uploading file {$local_path}: {$e} -msg-93476abb = File {$remote_path} downloaded from sandbox to {$local_path} -msg-079c5972 = Error sending file message: {$e} -msg-ce35bb2c = Error downloading file {$remote_path}: {$e} + +msg-99ab0efe = Upload result:{ $result } +msg-bca9d578 = File{ $local_path }uploaded to sandbox at{ $file_path } +msg-da21a6a5 = Error uploading file{ $local_path }Text to translate:{ $e } +msg-93476abb = File{ $remote_path }downloaded from sandbox to{ $local_path } +msg-079c5972 = Error sending file message:{ $e } +msg-ce35bb2c = Error downloading file{ $remote_path }Text to be translated:{ $e } ### astrbot/core/computer/booters/local.py + msg-487d0c91 = Path is outside the allowed computer roots. msg-e5eb5377 = Blocked unsafe shell command. -msg-9e1e117f = Local computer booter initialized for session: {$session_id} +msg-9e1e117f = Local computer booter initialized for session:{ $session_id } msg-2d7f95de = Local computer booter shutdown complete. msg-82a45196 = LocalBooter does not support upload_file operation. Use shell instead. msg-0457524a = LocalBooter does not support download_file operation. Use shell instead. ### astrbot/core/computer/booters/shipyard.py -msg-b03115b0 = Got sandbox ship: {$res} for session: {$session_id} -msg-c5ce8bde = Error checking Shipyard sandbox availability: {$e} + +msg-b03115b0 = Got sandbox ship:{ $res }for session:{ $session_id } +msg-c5ce8bde = Error checking Shipyard sandbox availability:{ $e } ### astrbot/core/computer/booters/boxlite.py -msg-019c4d18 = Failed to exec operation: {$res} {$error_text} -msg-b135b7bd = Failed to upload file: {$e} -msg-873ed1c8 = File not found: {$path} -msg-f58ceec6 = Unexpected error uploading file: {$e} -msg-900ab999 = Checking health for sandbox {$ship_id} on {$res}... -msg-2a50d6f3 = Sandbox {$ship_id} is healthy -msg-fbdbe32f = Booting(Boxlite) for session: {$session_id}, this may take a while... -msg-b1f13f5f = Boxlite booter started for session: {$session_id} -msg-e93d0c30 = Shutting down Boxlite booter for ship: {$res} -msg-6deea473 = Boxlite booter for ship: {$res} stopped + +msg-019c4d18 = Failed to exec operation:{ $res } { $error_text } +msg-b135b7bd = Failed to upload file:{ $e } +msg-873ed1c8 = File not found:{ $path } +msg-f58ceec6 = Unexpected error uploading file:{ $e } +msg-900ab999 = Checking health for sandbox{ $ship_id }on{ $res }... +msg-2a50d6f3 = Sandbox{ $ship_id }is healthy +msg-fbdbe32f = Booting(Boxlite) for session:{ $session_id }, this may take a while... +msg-b1f13f5f = Boxlite booter started for session:{ $session_id } +msg-e93d0c30 = Shutting down Boxlite booter for ship:{ $res } +msg-6deea473 = Boxlite booter for ship:{ $res }stopped ### astrbot/core/cron/manager.py + msg-724e64a9 = Skip scheduling basic cron job %s due to missing handler. msg-78ef135f = Invalid timezone %s for cron job %s, fallback to system. msg-e71c28d3 = run_once job missing run_at timestamp -msg-dd46e69f = Failed to schedule cron job {$res}: {$e} -msg-aa2e4688 = Unknown cron job type: {$res} -msg-186627d9 = Cron job {$job_id} failed: {$e} -msg-cb955de0 = Basic cron job handler not found for {$res} +msg-dd46e69f = Failed to schedule cron job{ $res }Text to be translated:{ $e } +msg-aa2e4688 = Unknown cron job type:{ $res } +msg-186627d9 = Cron job{ $job_id }failed:{ $e } +msg-cb955de0 = Basic cron job handler not found for{ $res } msg-2029c4b2 = ActiveAgentCronJob missing session. -msg-6babddc9 = Invalid session for cron job: {$e} +msg-6babddc9 = Invalid session for cron job:{ $e } msg-865a2b07 = Failed to build main agent for cron job. msg-27c9c6b3 = Cron job agent got no response ### astrbot/utils/http_ssl_common.py + msg-7957c9b6 = Failed to load certifi CA bundle into SSL context; falling back to system trust store only: %s ### astrbot/cli/__main__.py -msg-fe494da6 = {$logo_tmpl} + +msg-fe494da6 = { $logo_tmpl } msg-c8b2ff67 = Welcome to AstrBot CLI! -msg-d79e1ff9 = AstrBot CLI version: {$__version__} -msg-78b9c276 = {$res} -msg-14dd710d = Unknown command: {$command_name} +msg-78b9c276 = { $res } +msg-14dd710d = Unknown command:{ $command_name } ### astrbot/cli/utils/basic.py -msg-f4e0fd7b = 未安装管理面板 -msg-2d090cc3 = 正在安装管理面板... -msg-2eeb67e0 = 管理面板安装完成 -msg-9c727dca = 管理面板已是最新版本 -msg-11b49913 = 管理面板版本: {$version} -msg-f0b6145e = 下载管理面板失败: {$e} -msg-9504d173 = 初始化管理面板目录... -msg-699e2509 = 管理面板初始化完成 + +msg-f4e0fd7b = Management panel is not installed +msg-2d090cc3 = Installing management panel... +msg-2eeb67e0 = Management panel installation completed +msg-9c727dca = Management panel is already the latest version. +msg-11b49913 = Admin panel version:{ $version } +msg-f0b6145e = Download management panel failed:{ $e } +msg-9504d173 = Initializing admin panel directory... +msg-699e2509 = Admin panel initialization completed ### astrbot/cli/utils/plugin.py -msg-e327bc14 = 正在从默认分支下载 {$author}/{$repo} -msg-c804f59f = 获取 release 信息失败: {$e},将直接使用提供的 URL -msg-aa398bd5 = master 分支不存在,尝试下载 main 分支 -msg-5587d9fb = 读取 {$yaml_path} 失败: {$e} -msg-8dbce791 = 获取在线插件列表失败: {$e} -msg-6999155d = 插件 {$plugin_name} 未安装,无法更新 -msg-fa5e129a = 正在从 {$repo_url} {$res}插件 {$plugin_name}... -msg-9ac1f4db = 插件 {$plugin_name} {$res}成功 -msg-b9c719ae = {$res}插件 {$plugin_name} 时出错: {$e} + +msg-e327bc14 = Downloading from the default branch{ $author }/{ $repo } +msg-c804f59f = Failed to get release information:{ $e }, the provided URL will be used directly +msg-aa398bd5 = The master branch does not exist, attempting to download the main branch. +msg-5587d9fb = Read{ $yaml_path }Failed:{ $e } +msg-8dbce791 = Failed to retrieve online plugin list:{ $e } +msg-6999155d = Plugin{ $plugin_name }Not installed, cannot update +msg-fa5e129a = 正在从{ $repo_url } { $res }Plugin{ $plugin_name }... +msg-9ac1f4db = Plugin{ $plugin_name } { $res }Success +msg-b9c719ae = { $res }Plugin{ $plugin_name }Error occurred:{ $e } ### astrbot/cli/commands/cmd_conf.py -msg-635b8763 = 日志级别必须是 DEBUG/INFO/WARNING/ERROR/CRITICAL 之一 -msg-ebc250dc = 端口必须在 1-65535 范围内 -msg-6ec400b6 = 端口必须是数字 -msg-0b62b5ce = 用户名不能为空 -msg-89b5d3d5 = 密码不能为空 -msg-92e7c8ad = 无效的时区: {$value},请使用有效的IANA时区名称 -msg-e470e37d = 回调接口基址必须以 http:// 或 https:// 开头 -msg-6b615721 = {$root}不是有效的 AstrBot 根目录,如需初始化请使用 astrbot init -msg-f74c517c = 配置文件解析失败: {$e} -msg-d7c58bcc = 配置路径冲突: {$res} 不是字典 -msg-e16816cc = 不支持的配置项: {$key} -msg-e9cce750 = 配置已更新: {$key} -msg-1ed565aa = 原值: ******** -msg-1bf9569a = 新值: ******** -msg-f2a20ab3 = 原值: {$old_value} -msg-0c104905 = 新值: {$validated_value} -msg-ea9b4e2c = 未知的配置项: {$key} -msg-4450e3b1 = 设置配置失败: {$e} -msg-ba464bee = {$key}: {$value} -msg-72aab576 = 获取配置失败: {$e} -msg-c1693d1d = 当前配置: -msg-50be9b74 = {$key}: {$value} + +msg-635b8763 = Log level must be one of DEBUG/INFO/WARNING/ERROR/CRITICAL +msg-ebc250dc = Port must be within the range 1-65535 +msg-6ec400b6 = Port must be a number +msg-0b62b5ce = Username cannot be empty +msg-89b5d3d5 = Password cannot be empty +msg-92e7c8ad = Invalid timezone:{ $value }Please use a valid IANA timezone name +msg-e470e37d = Callback interface base address must start with http:// or https:// +msg-6b615721 = { $root }Not a valid AstrBot root directory. If you need to initialize, please use astrbot init +msg-f74c517c = Configuration file parsing failed:{ $e } +msg-d7c58bcc = Configuration path conflict:{ $res }Not a dictionary +msg-e16816cc = Unsupported configuration item:{ $key } +msg-e9cce750 = Configuration updated:{ $key } +msg-1ed565aa = Original value: ******** +msg-1bf9569a = New value: ******** +msg-f2a20ab3 = Original value:{ $old_value } +msg-0c104905 = New value:{ $validated_value } +msg-ea9b4e2c = Unknown configuration item:{ $key } +msg-4450e3b1 = Failed to set configuration:{ $e } +msg-ba464bee = { $key }Text to be translated:{ $value } +msg-72aab576 = Failed to get configuration:{ $e } +msg-c1693d1d = Current configuration: +msg-50be9b74 = { $key }Text to translate:{ $value } ### astrbot/cli/commands/cmd_init.py -msg-a90a250e = Current Directory: {$astrbot_root} -msg-4deda62e = 如果你确认这是 Astrbot root directory, 你需要在当前目录下创建一个 .astrbot 文件标记该目录为 AstrBot 的数据目录。 -msg-3319bf71 = Created {$dot_astrbot} -msg-7054f44f = {$res}: {$path} + +msg-a90a250e = Current Directory:{ $astrbot_root } +msg-4deda62e = If you confirm this is the AstrBot root directory, you need to create an .astrbot file in the current directory to mark it as the AstrBot data directory. +msg-3319bf71 = Created{ $dot_astrbot } +msg-7054f44f = { $res }Text to translate:{ $path } msg-b19edc8a = Initializing AstrBot... -msg-eebc39e3 = 无法获取锁文件,请检查是否有其他实例正在运行 -msg-e16da80f = 初始化失败: {$e} +msg-eebc39e3 = Unable to acquire the lock file. Please check if another instance is running. +msg-e16da80f = Initialization failed:{ $e } ### astrbot/cli/commands/cmd_run.py -msg-41ecc632 = {$astrbot_root}不是有效的 AstrBot 根目录,如需初始化请使用 astrbot init -msg-0ccaca23 = 启用插件自动重载 -msg-220914e7 = AstrBot 已关闭... -msg-eebc39e3 = 无法获取锁文件,请检查是否有其他实例正在运行 -msg-85f241d3 = 运行时出现错误: {$e}{"\u000A"}{$res} + +msg-41ecc632 = { $astrbot_root }Not a valid AstrBot root directory. Use 'astrbot init' to initialize if needed. +msg-0ccaca23 = Enable plugin auto-reload +msg-220914e7 = AstrBot is closed... +msg-eebc39e3 = Unable to acquire lock file, please check if another instance is running. +msg-85f241d3 = Runtime error occurred:{ $e }{ "\u000A" }{ $res } ### astrbot/cli/commands/cmd_plug.py -msg-cbd8802b = {$base}不是有效的 AstrBot 根目录,如需初始化请使用 astrbot init -msg-78b9c276 = {$res} -msg-83664fcf = {$val} {$val} {$val} {$val} {$val} -msg-56f3f0bf = {$res} {$res_2} {$res_3} {$res_4} {$desc} -msg-1d802ff2 = 插件 {$name} 已存在 -msg-a7be9d23 = 版本号必须为 x.y 或 x.y.z 格式 -msg-4d81299b = 仓库地址必须以 http 开头 -msg-93289755 = 下载插件模板... -msg-b21682dd = 重写插件信息... -msg-bffc8bfa = 插件 {$name} 创建成功 -msg-08eae1e3 = 未安装任何插件 -msg-1a021bf4 = 未找到可安装的插件 {$name},可能是不存在或已安装 -msg-c120bafd = 插件 {$name} 不存在或未安装 -msg-63da4867 = 插件 {$name} 已卸载 -msg-e4925708 = 卸载插件 {$name} 失败: {$e} -msg-f4d15a87 = 插件 {$name} 不需要更新或无法更新 -msg-94b035f7 = 没有需要更新的插件 -msg-0766d599 = 发现 {$res} 个插件需要更新 -msg-bd5ab99c = 正在更新插件 {$plugin_name}... -msg-e32912b8 = 未找到匹配 '{$query}' 的插件 + +msg-cbd8802b = { $base }Not a valid AstrBot root directory. Use astrbot init if you need to initialize. +msg-78b9c276 = { $res } +msg-83664fcf = { $val } { $val } { $val } { $val } { $val } +msg-56f3f0bf = { $res } { $res_2 } { $res_3 } { $res_4 } { $desc } +msg-1d802ff2 = Plugin{ $name }Already exists +msg-a7be9d23 = Version number must be in x.y or x.y.z format. +msg-4d81299b = The repository address must start with http +msg-93289755 = Downloading plugin template... +msg-b21682dd = Rewriting plugin information... +msg-bffc8bfa = Plugin{ $name }Creation successful +msg-08eae1e3 = No plugins installed +msg-1a021bf4 = No installable plugins found{ $name }, may not exist or has already been installed +msg-c120bafd = Plugin{ $name }Does not exist or is not installed +msg-63da4867 = Plugin{ $name }Uninstalled +msg-e4925708 = Uninstall plugin{ $name }Failed:{ $e } +msg-f4d15a87 = Plugin{ $name }No need to update or cannot be updated +msg-94b035f7 = No plugins need to be updated. +msg-0766d599 = Discover{ $res }plugins need to be updated +msg-bd5ab99c = Updating plugin{ $plugin_name }... +msg-e32912b8 = No matches found for '{ $query }'s plugin ### astrbot/dashboard/server.py -msg-e88807e2 = 未找到该路由 + +msg-e88807e2 = Route not found msg-06151c57 = Missing API key msg-88dca3cc = Invalid API key msg-fd267dc8 = Insufficient API key scope -msg-076fb3a3 = 未授权 -msg-6f214cc1 = Token 过期 -msg-5041dc95 = Token 无效 -msg-1241c883 = 检查端口 {$port} 时发生错误: {$e} +msg-076fb3a3 = Unauthorized +msg-6f214cc1 = Token expired +msg-5041dc95 = Token is invalid +msg-1241c883 = Check port{ $port }An error occurred:{ $e } msg-7c3ba89d = Initialized random JWT secret for dashboard. -msg-a3adcb66 = WebUI 已被禁用 -msg-44832296 = 正在启动 WebUI, 监听地址: {$scheme}://{$host}:{$port} -msg-3eed4a73 = 提示: WebUI 将监听所有网络接口,请注意安全。(可在 data/cmd_config.json 中配置 dashboard.host 以修改 host) -msg-289a2fe8 = 错误:端口 {$port} 已被占用{"\u000A"}占用信息: {"\u000A"} {$process_info}{"\u000A"}请确保:{"\u000A"}1. 没有其他 AstrBot 实例正在运行{"\u000A"}2. 端口 {$port} 没有被其他程序占用{"\u000A"}3. 如需使用其他端口,请修改配置文件 -msg-6d1dfba8 = 端口 {$port} 已被占用 -msg-c0161c7c = {$display} -msg-ac4f2855 = dashboard.ssl.enable 为 true 时,必须配置 cert_file 和 key_file。 -msg-3e87aaf8 = SSL 证书文件不存在: {$cert_path} -msg-5ccf0a9f = SSL 私钥文件不存在: {$key_path} -msg-5e4aa3eb = SSL CA 证书文件不存在: {$ca_path} -msg-cb049eb2 = AstrBot WebUI 已经被优雅地关闭 +msg-a3adcb66 = WebUI has been disabled +msg-44832296 = Starting WebUI, listening address:{ $scheme }://{ $host }Text to translate:{ $port } +msg-3eed4a73 = Hint: WebUI will listen on all network interfaces, please note security. (You can modify the host by configuring dashboard.host in data/cmd_config.json) +msg-289a2fe8 = Error: Port{ $port }Occupied{ "\u000A" }Usage Information:{ "\u000A" } { $process_info }{ "\u000A" }Please ensure:{ "\u000A" }1. No other AstrBot instances are currently running.{ "\u000A" }2. Port{ $port }Not occupied by other programs{ "\u000A" }3. To use other ports, please modify the configuration file. +msg-6d1dfba8 = Port{ $port }Occupied +msg-c0161c7c = { $display } +msg-ac4f2855 = dashboard.ssl.enable is true, cert_file and key_file must be configured. +msg-3e87aaf8 = SSL certificate file does not exist:{ $cert_path } +msg-5ccf0a9f = SSL private key file does not exist:{ $key_path } +msg-5e4aa3eb = SSL CA certificate file does not exist:{ $ca_path } +msg-cb049eb2 = AstrBot WebUI has been gracefully shut down. ### astrbot/dashboard/utils.py -msg-160bd44a = 缺少必要的库以生成 t-SNE 可视化。请安装 matplotlib 和 scikit-learn: {e} -msg-aa3a3dbf = 未找到知识库 -msg-0e404ea3 = FAISS 索引不存在: {$index_path} -msg-8d92420c = 索引为空 -msg-24c0450e = 提取 {$res} 个向量用于可视化... -msg-632d0acf = 开始 t-SNE 降维... -msg-61f0449f = 生成可视化图表... -msg-4436ad2b = 生成 t-SNE 可视化时出错: {$e} -msg-78b9c276 = {$res} + +msg-160bd44a = Missing required libraries for t-SNE visualization. Please install matplotlib and scikit-learn:{ e } +msg-aa3a3dbf = Knowledge base not found +msg-0e404ea3 = FAISS index does not exist:{ $index_path } +msg-8d92420c = Index is empty +msg-24c0450e = Extract{ $res }A vector for visualization... +msg-632d0acf = Starting t-SNE dimensionality reduction... +msg-61f0449f = Generating visual charts... +msg-4436ad2b = Error generating t-SNE visualization:{ $e } +msg-78b9c276 = { $res } ### astrbot/dashboard/routes/update.py -msg-a3503781 = 迁移失败: {$res} -msg-543d8e4d = 迁移失败: {$e} -msg-251a5f4a = 检查更新失败: {$e} (不影响除项目更新外的正常使用) -msg-aa6bff26 = /api/update/releases: {$res} -msg-c5170c27 = 下载管理面板文件失败: {$e}。 -msg-db715c26 = 更新依赖中... -msg-9a00f940 = 更新依赖失败: {$e} -msg-6f96e3ba = /api/update_project: {$res} -msg-3217b509 = 下载管理面板文件失败: {$e} -msg-9cff28cf = /api/update_dashboard: {$res} + +msg-a3503781 = Migration failed:{ $res } +msg-543d8e4d = Migration failed:{ $e } +msg-251a5f4a = Check for updates failed:{ $e }(Does not affect normal use except for project updates) +msg-aa6bff26 = /api/update/releases:{ $res } +msg-c5170c27 = Failed to download the management panel file:{ $e }. +msg-db715c26 = Updating dependencies... +msg-9a00f940 = Failed to update dependencies:{ $e } +msg-6f96e3ba = /api/update_project:{ $res } +msg-3217b509 = Failed to download management panel file:{ $e } +msg-9cff28cf = /api/update_dashboard:{ $res } msg-1198c327 = You are not permitted to do this operation in demo mode -msg-38e60adf = 缺少参数 package 或不合法。 -msg-a1191473 = /api/update_pip: {$res} +msg-38e60adf = Missing or invalid parameter package. +msg-a1191473 = /api/update_pip:{ $res } ### astrbot/dashboard/routes/lang_route.py -msg-0d18aac8 = [LangRoute] lang:{$lang} -msg-bf610e68 = lang 为必填参数。 + +msg-0d18aac8 = [LangRoute] lang:{ $lang } +msg-bf610e68 = lang is a required parameter. ### astrbot/dashboard/routes/auth.py -msg-ee9cf260 = 为了保证安全,请尽快修改默认密码。 -msg-87f936b8 = 用户名或密码错误 + +msg-ee9cf260 = For security purposes, please change the default password as soon as possible. +msg-87f936b8 = Username or password is incorrect msg-1198c327 = You are not permitted to do this operation in demo mode -msg-25562cd3 = 原密码错误 -msg-d31087d2 = 新用户名和新密码不能同时为空 -msg-b512c27e = 两次输入的新密码不一致 +msg-25562cd3 = Original password is incorrect +msg-d31087d2 = The new username and new password cannot both be empty. +msg-b512c27e = The new passwords entered twice do not match msg-7b947d8b = JWT secret is not set in the cmd_config. ### astrbot/dashboard/routes/backup.py -msg-6920795d = 清理过期的上传会话: {$upload_id} -msg-3e96548d = 清理过期上传会话失败: {$e} -msg-259677a9 = 清理分片目录失败: {$e} -msg-d7263882 = 读取备份 manifest 失败: {$e} -msg-40f76598 = 跳过无效备份文件: {$filename} -msg-18a49bfc = 获取备份列表失败: {$e} -msg-78b9c276 = {$res} -msg-6e08b5a5 = 创建备份失败: {$e} -msg-9cce1032 = 后台导出任务 {$task_id} 失败: {$e} -msg-55927ac1 = 缺少备份文件 -msg-374cab8a = 请上传 ZIP 格式的备份文件 -msg-d53d6730 = 上传的备份文件已保存: {$unique_filename} (原始名称: {$res}) -msg-98e64c7f = 上传备份文件失败: {$e} -msg-49c3b432 = 缺少 filename 参数 -msg-df33d307 = 无效的文件大小 -msg-162ad779 = 初始化分片上传: upload_id={$upload_id}, filename={$unique_filename}, total_chunks={$total_chunks} -msg-de676924 = 初始化分片上传失败: {$e} -msg-eecf877c = 缺少必要参数 -msg-f175c633 = 无效的分片索引 -msg-ad865497 = 缺少分片数据 -msg-947c2d56 = 上传会话不存在或已过期 -msg-f3a464a5 = 分片索引超出范围 -msg-7060da1d = 接收分片: upload_id={$upload_id}, chunk={$res}/{$total_chunks} -msg-06c107c1 = 上传分片失败: {$e} -msg-f040b260 = 已标记备份为上传来源: {$zip_path} -msg-559c10a8 = 标记备份来源失败: {$e} -msg-d1d752ef = 缺少 upload_id 参数 -msg-390ed49a = 分片不完整,缺少: {$res}... -msg-8029086a = 分片上传完成: {$filename}, size={$file_size}, chunks={$total} -msg-4905dde5 = 完成分片上传失败: {$e} -msg-b63394b1 = 取消分片上传: {$upload_id} -msg-2b39da46 = 取消上传失败: {$e} -msg-f12b1f7a = 无效的文件名 -msg-44bb3b89 = 备份文件不存在: {$filename} -msg-b005980b = 预检查备份文件失败: {$e} -msg-65b7ede1 = 请先确认导入。导入将会清空并覆盖现有数据,此操作不可撤销。 -msg-b152e4bf = 导入备份失败: {$e} -msg-5e7f1683 = 后台导入任务 {$task_id} 失败: {$e} -msg-6906aa65 = 缺少参数 task_id -msg-5ea3d72c = 找不到该任务 -msg-f0901aef = 获取任务进度失败: {$e} -msg-8d23792b = 缺少参数 filename -msg-4188ede6 = 缺少参数 token -msg-0c708312 = 服务器配置错误 -msg-cc228d62 = Token 已过期,请刷新页面后重试 -msg-5041dc95 = Token 无效 -msg-96283fc5 = 备份文件不存在 -msg-00aacbf8 = 下载备份失败: {$e} -msg-3ea8e256 = 删除备份失败: {$e} -msg-e4a57714 = 缺少参数 new_name -msg-436724bb = 新文件名无效 -msg-9f9d8558 = 文件名 '{$new_filename}' 已存在 -msg-a5fda312 = 备份文件重命名: {$filename} -> {$new_filename} -msg-e7c82339 = 重命名备份失败: {$e} + +msg-6920795d = Clean up expired upload sessions:{ $upload_id } +msg-3e96548d = Failed to clean up expired upload sessions:{ $e } +msg-259677a9 = Failed to clean up shard directory:{ $e } +msg-d7263882 = Failed to read backup manifest:{ $e } +msg-40f76598 = Skipping invalid backup file:{ $filename } +msg-18a49bfc = Failed to get backup list:{ $e } +msg-78b9c276 = { $res } +msg-6e08b5a5 = Failed to create backup:{ $e } +msg-9cce1032 = Background export task{ $task_id }Failed:{ $e } +msg-55927ac1 = Missing backup file +msg-374cab8a = Please upload a ZIP format backup file +msg-d53d6730 = Uploaded backup file saved:{ $unique_filename }(Original name:{ $res }) +msg-98e64c7f = Upload backup file failed:{ $e } +msg-49c3b432 = Missing filename parameter +msg-df33d307 = Invalid file size +msg-162ad779 = Initialize multipart upload: upload_id={ $upload_id }, filename={ $unique_filename }, total_chunks={ $total_chunks } +msg-de676924 = Initialize multipart upload failed:{ $e } +msg-eecf877c = Missing required parameters +msg-f175c633 = Invalid shard index +msg-ad865497 = Missing shard data +msg-947c2d56 = The upload session does not exist or has expired. +msg-f3a464a5 = Shard index out of range +msg-7060da1d = Receiving chunks: upload_id={ $upload_id }, chunk={ $res }Text to be translated:{ $total_chunks } +msg-06c107c1 = Upload chunk failed:{ $e } +msg-f040b260 = Marked backup as upload source:{ $zip_path } +msg-559c10a8 = Failed to mark backup source:{ $e } +msg-d1d752ef = Missing upload_id parameter +msg-390ed49a = Shard is incomplete, missing:{ $res }... +msg-8029086a = Shard upload completed:{ $filename }, size={ $file_size }, chunks={ $total } +msg-4905dde5 = Failed to complete multipart upload:{ $e } +msg-b63394b1 = Cancel multipart upload:{ $upload_id } +msg-2b39da46 = Cancel upload failed:{ $e } +msg-f12b1f7a = Invalid file name +msg-44bb3b89 = Backup file does not exist:{ $filename } +msg-b005980b = Pre-check backup file failed:{ $e } +msg-65b7ede1 = Please confirm the import first. The import will clear and overwrite existing data, and this operation cannot be undone. +msg-b152e4bf = Import backup failed:{ $e } +msg-5e7f1683 = Background Import Task{ $task_id }Failure:{ $e } +msg-6906aa65 = Missing parameter task_id +msg-5ea3d72c = Cannot find the task +msg-f0901aef = Failed to get task progress:{ $e } +msg-8d23792b = Missing parameter filename +msg-4188ede6 = Missing parameter token +msg-0c708312 = Server configuration error +msg-cc228d62 = Token has expired, please refresh the page and try again. +msg-5041dc95 = Invalid token +msg-96283fc5 = Backup file does not exist +msg-00aacbf8 = Download backup failed:{ $e } +msg-3ea8e256 = Failed to delete backup:{ $e } +msg-e4a57714 = Missing parameter new_name +msg-436724bb = The new file name is invalid +msg-9f9d8558 = File name '{ $new_filename }Already exists +msg-a5fda312 = Backup file rename:{ $filename }->{ $new_filename } +msg-e7c82339 = Rename backup failed:{ $e } ### astrbot/dashboard/routes/command.py -msg-1d47363b = handler_full_name 与 enabled 均为必填。 -msg-35374718 = handler_full_name 与 new_name 均为必填。 -msg-f879f2f4 = handler_full_name 与 permission 均为必填。 + +msg-1d47363b = handler_full_name and enabled are both required. +msg-35374718 = handler_full_name and new_name are both required. +msg-f879f2f4 = handler_full_name and permission are both required. ### astrbot/dashboard/routes/subagent.py -msg-78b9c276 = {$res} -msg-eda47201 = 获取 subagent 配置失败: {$e} -msg-3e5b1fe0 = 配置必须为 JSON 对象 -msg-9f285dd3 = 保存 subagent 配置失败: {$e} -msg-665f4751 = 获取可用工具失败: {$e} + +msg-78b9c276 = { $res } +msg-eda47201 = Failed to retrieve subagent configuration:{ $e } +msg-3e5b1fe0 = Configuration must be a JSON object +msg-9f285dd3 = Failed to save subagent configuration:{ $e } +msg-665f4751 = Failed to get available tools:{ $e } ### astrbot/dashboard/routes/config.py -msg-680e7347 = 配置项 {$path}{$key} 没有类型定义, 跳过校验 -msg-ef2e5902 = Saving config, is_core={$is_core} -msg-78b9c276 = {$res} -msg-acef166d = 验证配置时出现异常: {$e} -msg-42f62db0 = 格式校验未通过: {$errors} -msg-3e668849 = 缺少配置数据 -msg-196b9b25 = 缺少 provider_source_id -msg-dbbbc375 = 未找到对应的 provider source -msg-a77f69f4 = 缺少 original_id -msg-96f154c4 = 缺少或错误的配置数据 -msg-c80b2c0f = Provider source ID '{$res}' exists already, please try another ID. -msg-537b700b = 缺少或错误的路由表数据 -msg-b5079e61 = 更新路由表失败: {$e} -msg-cf97d400 = 缺少 UMO 或配置文件 ID -msg-2a05bc8d = 缺少 UMO -msg-7098aa3f = 删除路由表项失败: {$e} -msg-902aedc3 = 缺少配置文件 ID + +msg-680e7347 = Configuration items{ $path }{ $key }No type definition, skip validation +msg-ef2e5902 = Saving config, is_core={ $is_core } +msg-78b9c276 = { $res } +msg-acef166d = An exception occurred while validating the configuration:{ $e } +msg-42f62db0 = Format validation failed:{ $errors } +msg-3e668849 = Missing configuration data +msg-196b9b25 = Missing provider_source_id +msg-dbbbc375 = Provider source not found +msg-a77f69f4 = Missing original_id +msg-96f154c4 = Missing or incorrect configuration data +msg-c80b2c0f = Provider source ID '{ $res }' exists already, please try another ID. +msg-537b700b = Missing or incorrect routing table data +msg-b5079e61 = Failed to update routing table:{ $e } +msg-cf97d400 = Missing UMO or Configuration File ID +msg-2a05bc8d = Missing UMO +msg-7098aa3f = Failed to delete routing table entry:{ $e } +msg-902aedc3 = Missing configuration file ID msg-b9026977 = abconf_id cannot be None -msg-acf0664a = 删除失败 -msg-59c93c1a = 删除配置文件失败: {$e} -msg-930442e2 = 更新失败 -msg-7375d4dc = 更新配置文件失败: {$e} -msg-53a8fdb2 = Attempting to check provider: {$res} (ID: {$res_2}, Type: {$res_3}, Model: {$res_4}) -msg-8b0a48ee = Provider {$res} (ID: {$res_2}) is available. -msg-7c7180a7 = Provider {$res} (ID: {$res_2}) is unavailable. Error: {$error_message} -msg-1298c229 = Traceback for {$res}:{"\u000A"}{$res_2} -msg-d7f9a42f = {$message} -msg-cd303a28 = API call: /config/provider/check_one id={$provider_id} -msg-55b8107a = Provider with id '{$provider_id}' not found in provider_manager. -msg-d1a98a9b = Provider with id '{$provider_id}' not found -msg-cb9c402c = 缺少参数 provider_type -msg-e092d4ee = 缺少参数 provider_id -msg-1ff28fed = 未找到 ID 为 {$provider_id} 的提供商 -msg-92347c35 = 提供商 {$provider_id} 类型不支持获取模型列表 -msg-d0845a10 = 缺少参数 provider_config -msg-5657fea4 = provider_config 缺少 type 字段 -msg-09ed9dc7 = 提供商适配器加载失败,请检查提供商类型配置或查看服务端日志 -msg-1cce1cd4 = 未找到适用于 {$provider_type} 的提供商适配器 -msg-8361e44d = 无法找到 {$provider_type} 的类 -msg-4325087c = 提供商不是 EmbeddingProvider 类型 -msg-a9873ea4 = 检测到 {$res} 的嵌入向量维度为 {$dim} -msg-d170e384 = 获取嵌入维度失败: {$e} -msg-abfeda72 = 缺少参数 source_id -msg-0384f4c9 = 未找到 ID 为 {$provider_source_id} 的 provider_source -msg-aec35bdb = provider_source 缺少 type 字段 -msg-cbb9d637 = 动态导入提供商适配器失败: {$e} -msg-468f64b3 = 提供商 {$provider_type} 不支持获取模型列表 -msg-cb07fc1c = 获取到 provider_source {$provider_source_id} 的模型列表: {$models} -msg-d2f6e16d = 获取模型列表失败: {$e} -msg-25ea8a96 = Unsupported scope: {$scope} +msg-acf0664a = Deletion failed +msg-59c93c1a = Failed to delete configuration file:{ $e } +msg-930442e2 = Update failed +msg-7375d4dc = Failed to update configuration file:{ $e } +msg-53a8fdb2 = Attempting to check provider:{ $res }(ID:{ $res_2 }, Type:{ $res_3 }, Model:{ $res_4 }) +msg-8b0a48ee = Provider{ $res }(ID:{ $res_2 }) is available. +msg-7c7180a7 = Provider{ $res }(ID:{ $res_2 }) is unavailable. Error:{ $error_message } +msg-1298c229 = Traceback for{ $res }Text to be translated:{ "\u000A" }{ $res_2 } +msg-d7f9a42f = { $message } +msg-cd303a28 = API call: /config/provider/check_one id={ $provider_id } +msg-55b8107a = Provider with id '{ $provider_id }' not found in provider_manager. +msg-d1a98a9b = Provider with id '{ $provider_id }' not found +msg-cb9c402c = Missing parameter provider_type +msg-e092d4ee = Missing parameter provider_id +msg-1ff28fed = ID not found{ $provider_id }Provider +msg-92347c35 = Provider{ $provider_id }Type does not support retrieving model list +msg-d0845a10 = Missing parameter provider_config +msg-5657fea4 = provider_config is missing the type field +msg-09ed9dc7 = Provider adapter loading failed, please check provider type configuration or view server logs +msg-1cce1cd4 = Not applicable{ $provider_type }provider adapter +msg-8361e44d = Not found{ $provider_type }class +msg-4325087c = The provider is not of type EmbeddingProvider +msg-a9873ea4 = Detected{ $res }The embedding vector dimension is{ $dim } +msg-d170e384 = Failed to get embedding dimension:{ $e } +msg-abfeda72 = Missing parameter source_id +msg-0384f4c9 = ID not found for{ $provider_source_id }provider_source +msg-aec35bdb = provider_source is missing the type field +msg-cbb9d637 = Dynamic import of provider adapter failed:{ $e } +msg-468f64b3 = Provider{ $provider_type }Model list retrieval is not supported. +msg-cb07fc1c = Get provider_source{ $provider_source_id }Model List:{ $models } +msg-d2f6e16d = Failed to get model list:{ $e } +msg-25ea8a96 = Unsupported scope:{ $scope } msg-23c8933f = Missing name or key parameter -msg-536e77ae = Plugin {$name} not found or has no config -msg-1b6bc453 = Config item not found or not file type +msg-536e77ae = Plugin{ $name }not found or has no config +msg-1b6bc453 = Configuration item not found or not of file type msg-fc0a457e = No files uploaded msg-31c718d7 = Invalid name parameter msg-e1edc16e = Missing name parameter msg-8e634b35 = Invalid path parameter -msg-0b52a254 = Plugin {$name} not found -msg-bff0e837 = 参数错误 -msg-2f29d263 = 机器人名称不允许修改 -msg-1478800f = 未找到对应平台 -msg-ca6133f7 = 缺少参数 id -msg-1199c1f9 = Using cached logo token for platform {$res} -msg-889a7de5 = Platform class not found for {$res} -msg-317f359c = Logo token registered for platform {$res} -msg-323ec1e2 = Platform {$res} logo file not found: {$logo_file_path} -msg-bc6d0bcf = Failed to import required modules for platform {$res}: {$e} -msg-b02b538d = File system error for platform {$res} logo: {$e} -msg-31123607 = Unexpected error registering logo for platform {$res}: {$e} -msg-af06ccab = 配置文件 {$conf_id} 不存在 -msg-082a5585 = 插件 {$plugin_name} 不存在 -msg-ca334960 = 插件 {$plugin_name} 没有注册配置 +msg-0b52a254 = Plugin{ $name }not found +msg-bff0e837 = Parameter error +msg-2f29d263 = Robot name cannot be modified +msg-1478800f = No corresponding platform found +msg-ca6133f7 = Missing parameter id +msg-1199c1f9 = Using cached logo token for platform{ $res } +msg-889a7de5 = Platform class not found for{ $res } +msg-317f359c = Logo token registered for platform{ $res } +msg-323ec1e2 = Platform{ $res }logo file not found:{ $logo_file_path } +msg-bc6d0bcf = Failed to import required modules for platform{ $res }Text to be translated:{ $e } +msg-b02b538d = File system error for platform{ $res }logo:{ $e } +msg-31123607 = Unexpected error registering logo for platform{ $res }Text to be translated:{ $e } +msg-af06ccab = Configuration file{ $conf_id }Not exist +msg-082a5585 = Plugin{ $plugin_name }Does not exist +msg-ca334960 = Plugin{ $plugin_name }No registration configuration ### astrbot/dashboard/routes/knowledge_base.py -msg-ce669289 = 上传文档 {$res} 失败: {$e} -msg-87e99c2d = 后台上传任务 {$task_id} 失败: {$e} -msg-78b9c276 = {$res} -msg-d5355233 = 导入文档 {$file_name} 失败: {$e} -msg-5e7f1683 = 后台导入任务 {$task_id} 失败: {$e} -msg-e1949850 = 获取知识库列表失败: {$e} -msg-299af36d = 知识库名称不能为空 -msg-faf380ec = 缺少参数 embedding_provider_id -msg-9015b689 = 嵌入模型不存在或类型错误({$res}) -msg-a63b3aa9 = 嵌入向量维度不匹配,实际是 {$res},然而配置是 {$res_2} -msg-9b281e88 = 测试嵌入模型失败: {$e} -msg-d3fb6072 = 重排序模型不存在 -msg-fbec0dfd = 重排序模型返回结果异常 -msg-872feec8 = 测试重排序模型失败: {$e},请检查平台日志输出。 -msg-a4ac0b9e = 创建知识库失败: {$e} -msg-c8d487e9 = 缺少参数 kb_id -msg-978b3c73 = 知识库不存在 -msg-2137a3e6 = 获取知识库详情失败: {$e} -msg-e7cf9cfd = 至少需要提供一个更新字段 -msg-d3d82c22 = 更新知识库失败: {$e} -msg-5d5d4090 = 删除知识库失败: {$e} -msg-787a5dea = 获取知识库统计失败: {$e} -msg-97a2d918 = 获取文档列表失败: {$e} -msg-b170e0fa = Content-Type 须为 multipart/form-data -msg-5afbfa8e = 缺少文件 -msg-6636fd31 = 最多只能上传10个文件 -msg-975f06d7 = 上传文档失败: {$e} -msg-35bacf60 = 缺少参数 documents 或格式错误 -msg-6cc1edcd = 文档格式错误,必须包含 file_name 和 chunks -msg-376d7d5f = chunks 必须是列表 -msg-e7e2f311 = chunks 必须是非空字符串列表 -msg-42315b8d = 导入文档失败: {$e} -msg-6906aa65 = 缺少参数 task_id -msg-5ea3d72c = 找不到该任务 -msg-194def99 = 获取上传进度失败: {$e} -msg-df6ec98e = 缺少参数 doc_id -msg-7c3cfe22 = 文档不存在 -msg-b54ab822 = 获取文档详情失败: {$e} -msg-0ef7f633 = 删除文档失败: {$e} -msg-2fe40cbd = 缺少参数 chunk_id -msg-fc13d42a = 删除文本块失败: {$e} -msg-4ef8315b = 获取块列表失败: {$e} -msg-b70a1816 = 缺少参数 query -msg-82ee646e = 缺少参数 kb_names 或格式错误 -msg-07a61a9a = 生成 t-SNE 可视化失败: {$e} -msg-20a3b3f7 = 检索失败: {$e} -msg-1b76f5ab = 缺少参数 url -msg-5dc86dc6 = 从URL上传文档失败: {$e} -msg-890b3dee = 后台上传URL任务 {$task_id} 失败: {$e} + +msg-ce669289 = Upload document{ $res }Failed:{ $e } +msg-87e99c2d = Background upload task{ $task_id }Failed:{ $e } +msg-78b9c276 = { $res } +msg-d5355233 = Import documents{ $file_name }Failure:{ $e } +msg-5e7f1683 = Background import task{ $task_id }Failed:{ $e } +msg-e1949850 = Failed to retrieve knowledge base list:{ $e } +msg-299af36d = Knowledge base name cannot be empty +msg-faf380ec = Missing parameter embedding_provider_id +msg-9015b689 = Embedding model does not exist or is of the wrong type{ $res }Text to be translated: +msg-a63b3aa9 = Embedding vector dimensions do not match, actually{ $res }, however, the configuration is{ $res_2 } +msg-9b281e88 = Testing embedding model failed:{ $e } +msg-d3fb6072 = The reordering model does not exist. +msg-fbec0dfd = The reordering model returned an abnormal result. +msg-872feec8 = Test reordering model failed:{ $e }Please check the platform log output. +msg-a4ac0b9e = Failed to create knowledge base:{ $e } +msg-c8d487e9 = Missing parameter kb_id +msg-978b3c73 = Knowledge base does not exist +msg-2137a3e6 = Failed to retrieve knowledge base details:{ $e } +msg-e7cf9cfd = At least one update field must be provided +msg-d3d82c22 = Failed to update knowledge base:{ $e } +msg-5d5d4090 = Failed to delete knowledge base:{ $e } +msg-787a5dea = Failed to retrieve knowledge base statistics:{ $e } +msg-97a2d918 = Failed to get document list:{ $e } +msg-b170e0fa = Content-Type must be multipart/form-data +msg-5afbfa8e = Missing file +msg-6636fd31 = You can only upload up to 10 files. +msg-975f06d7 = Upload document failed:{ $e } +msg-35bacf60 = Missing parameter documents or format error +msg-6cc1edcd = Incorrect document format; must include file_name and chunks +msg-376d7d5f = chunks must be a list +msg-e7e2f311 = chunks must be a non-empty list of strings +msg-42315b8d = Failed to import document:{ $e } +msg-6906aa65 = Missing parameter task_id +msg-5ea3d72c = Task not found +msg-194def99 = Failed to get upload progress:{ $e } +msg-df6ec98e = Missing parameter doc_id +msg-7c3cfe22 = Document does not exist +msg-b54ab822 = Failed to retrieve document details:{ $e } +msg-0ef7f633 = Failed to delete document:{ $e } +msg-2fe40cbd = Missing parameter chunk_id +msg-fc13d42a = Failed to delete text block:{ $e } +msg-4ef8315b = Failed to retrieve block list:{ $e } +msg-b70a1816 = Missing parameter query +msg-82ee646e = Missing parameter kb_names or incorrect format +msg-07a61a9a = Failed to generate t-SNE visualization:{ $e } +msg-20a3b3f7 = Retrieval failed:{ $e } +msg-1b76f5ab = Missing parameter url +msg-5dc86dc6 = Failed to upload document from URL:{ $e } +msg-890b3dee = Background upload URL task{ $task_id }Failure:{ $e } ### astrbot/dashboard/routes/skills.py -msg-78b9c276 = {$res} + +msg-78b9c276 = { $res } msg-1198c327 = You are not permitted to do this operation in demo mode msg-52430f2b = Missing file msg-2ad598f3 = Only .zip files are supported -msg-a11f2e1c = Failed to remove temp skill file: {$temp_path} +msg-a11f2e1c = Failed to remove temporary skill file:{ $temp_path } msg-67367a6d = Missing skill name ### astrbot/dashboard/routes/live_chat.py -msg-40f242d5 = [Live Chat] {$res} 开始说话 stamp={$stamp} -msg-a168d76d = [Live Chat] stamp 不匹配或未在说话状态: {$stamp} vs {$res} -msg-e01b2fea = [Live Chat] 没有音频帧数据 -msg-33856925 = [Live Chat] 音频文件已保存: {$audio_path}, 大小: {$res} bytes -msg-9e9b7e59 = [Live Chat] 组装 WAV 文件失败: {$e} -msg-21430f56 = [Live Chat] 已删除临时文件: {$res} -msg-6b4f88bc = [Live Chat] 删除临时文件失败: {$e} -msg-0849d043 = [Live Chat] WebSocket 连接建立: {$username} -msg-5477338a = [Live Chat] WebSocket 错误: {$e} -msg-fdbfdba8 = [Live Chat] WebSocket 连接关闭: {$username} -msg-7be90ac0 = [Live Chat] start_speaking 缺少 stamp -msg-8215062a = [Live Chat] 解码音频数据失败: {$e} -msg-438980ea = [Live Chat] end_speaking 缺少 stamp -msg-b35a375c = [Live Chat] 用户打断: {$res} -msg-2c3e7bbc = [Live Chat] STT Provider 未配置 -msg-0582c8ba = [Live Chat] STT 识别结果为空 -msg-57c2b539 = [Live Chat] STT 结果: {$user_text} -msg-6b7628c6 = [Live Chat] 检测到用户打断 -msg-2cab2269 = [Live Chat] 消息 ID 不匹配: {$result_message_id} != {$message_id} -msg-74c2470e = [Live Chat] 解析 AgentStats 失败: {$e} -msg-4738a2b3 = [Live Chat] 解析 TTSStats 失败: {$e} -msg-944d5022 = [Live Chat] 开始播放音频流 -msg-009104d8 = [Live Chat] Bot 回复完成: {$bot_text} -msg-0c4c3051 = [Live Chat] 处理音频失败: {$e} -msg-140caa36 = [Live Chat] 保存打断消息: {$interrupted_text} -msg-869f51ea = [Live Chat] 用户消息: {$user_text} (session: {$res}, ts: {$timestamp}) -msg-d26dee52 = [Live Chat] Bot 消息(打断): {$interrupted_text} (session: {$res}, ts: {$timestamp}) -msg-1377f378 = [Live Chat] 记录消息失败: {$e} + +msg-40f242d5 = [Live Chat]{ $res }Start talking stamp={ $stamp } +msg-a168d76d = [Live Chat] stamp does not match or is not in speaking state:{ $stamp }vs{ $res } +msg-e01b2fea = [Live Chat] No audio frame data +msg-33856925 = [Live Chat] Audio file saved:{ $audio_path }, Size:{ $res }bytes +msg-9e9b7e59 = [Live Chat] Failed to assemble WAV file:{ $e } +msg-21430f56 = [Live Chat] Temporary files have been deleted:{ $res } +msg-6b4f88bc = [Live Chat] Failed to delete temporary files:{ $e } +msg-0849d043 = [Live Chat] WebSocket connection established:{ $username } +msg-5477338a = [Live Chat] WebSocket Error:{ $e } +msg-fdbfdba8 = [Live Chat] WebSocket connection closed:{ $username } +msg-7be90ac0 = [Live Chat] start_speaking missing stamp +msg-8215062a = [Live Chat] Failed to decode audio data:{ $e } +msg-438980ea = [Live Chat] end_speaking is missing stamp +msg-b35a375c = [Live Chat] User Interruption:{ $res } +msg-2c3e7bbc = [Live Chat] STT Provider Not Configured +msg-0582c8ba = [Live Chat] STT recognition result is empty +msg-57c2b539 = [Live Chat] STT result:{ $user_text } +msg-6b7628c6 = [Live Chat] User interruption detected +msg-2cab2269 = [Live Chat] Message ID mismatch:{ $result_message_id }!={ $message_id } +msg-74c2470e = [Live Chat] Failed to parse AgentStats:{ $e } +msg-4738a2b3 = [Live Chat] Failed to parse TTSStats:{ $e } +msg-944d5022 = [Live Chat] Starting audio stream playback +msg-009104d8 = [Live Chat] Bot reply completed:{ $bot_text } +msg-0c4c3051 = [Live Chat] Failed to process audio:{ $e } +msg-140caa36 = [Live Chat] Save Interrupted Messages:{ $interrupted_text } +msg-869f51ea = [Live Chat] User message:{ $user_text }(session:{ $res }, ts:{ $timestamp }Text to be translated: +msg-d26dee52 = [Live Chat] Bot Message (Interruption):{ $interrupted_text }(session:{ $res }, ts:{ $timestamp }Text to translate: ) +msg-1377f378 = [Live Chat] Failed to record message:{ $e } ### astrbot/dashboard/routes/log.py -msg-5bf500c1 = Log SSE 补发历史错误: {$e} -msg-e4368397 = Log SSE 连接错误: {$e} -msg-547abccb = 获取日志历史失败: {$e} -msg-cb5d4ebb = 获取 Trace 设置失败: {$e} -msg-7564d3b0 = 请求数据为空 -msg-d2a1cd76 = 更新 Trace 设置失败: {$e} + +msg-5bf500c1 = Log SSE resend history error:{ $e } +msg-e4368397 = Log SSE connection error:{ $e } +msg-547abccb = Failed to fetch log history:{ $e } +msg-cb5d4ebb = Failed to get Trace settings:{ $e } +msg-7564d3b0 = Request data is empty +msg-d2a1cd76 = Failed to update Trace settings:{ $e } ### astrbot/dashboard/routes/conversation.py -msg-62392611 = 数据库查询出错: {$e}{"\u000A"}{$res} -msg-b21b052b = 数据库查询出错: {$e} -msg-10f72727 = {$error_msg} -msg-036e6190 = 获取对话列表失败: {$e} -msg-a16ba4b4 = 缺少必要参数: user_id 和 cid -msg-9a1fcec9 = 对话不存在 -msg-73a8a217 = 获取对话详情失败: {$e}{"\u000A"}{$res} -msg-976cd580 = 获取对话详情失败: {$e} -msg-c193b9c4 = 更新对话信息失败: {$e}{"\u000A"}{$res} -msg-9f96c4ee = 更新对话信息失败: {$e} -msg-e1cb0788 = 批量删除时conversations参数不能为空 -msg-38e3c4ba = 删除对话失败: {$e}{"\u000A"}{$res} -msg-ebf0371a = 删除对话失败: {$e} -msg-af54ee29 = 缺少必要参数: history -msg-b72552c8 = history 必须是有效的 JSON 字符串或数组 -msg-fdf757f3 = 更新对话历史失败: {$e}{"\u000A"}{$res} -msg-33762429 = 更新对话历史失败: {$e} -msg-498f11f8 = 导出列表不能为空 -msg-98aa3644 = 导出对话失败: user_id={$user_id}, cid={$cid}, error={$e} -msg-ed77aa37 = 没有成功导出任何对话 -msg-f07b18ee = 批量导出对话失败: {$e}{"\u000A"}{$res} -msg-85dc73fa = 批量导出对话失败: {$e} + +msg-62392611 = Database query error:{ $e }{ "\u000A" }{ $res } +msg-b21b052b = Database query error:{ $e } +msg-10f72727 = { $error_msg } +msg-036e6190 = Failed to retrieve conversation list:{ $e } +msg-a16ba4b4 = Missing required parameters: user_id and cid +msg-9a1fcec9 = The conversation does not exist +msg-73a8a217 = Failed to retrieve conversation details:{ $e }{ "\u000A" }{ $res } +msg-976cd580 = Failed to retrieve conversation details:{ $e } +msg-c193b9c4 = Failed to update conversation information:{ $e }{ "\u000A" }{ $res } +msg-9f96c4ee = Failed to update conversation information:{ $e } +msg-e1cb0788 = The conversations parameter cannot be empty during batch deletion. +msg-38e3c4ba = Failed to delete conversation:{ $e }{ "\u000A" }{ $res } +msg-ebf0371a = Failed to delete conversation:{ $e } +msg-af54ee29 = Missing required parameter: history +msg-b72552c8 = history must be a valid JSON string or array +msg-fdf757f3 = Failed to update conversation history:{ $e }{ "\u000A" }{ $res } +msg-33762429 = Failed to update conversation history:{ $e } +msg-498f11f8 = Export list cannot be empty +msg-98aa3644 = Export conversation failed: user_id={ $user_id }, cid={ $cid }, error={ $e } +msg-ed77aa37 = No conversations were successfully exported. +msg-f07b18ee = Batch export conversations failed:{ $e }{ "\u000A" }{ $res } +msg-85dc73fa = Batch export conversations failed:{ $e } ### astrbot/dashboard/routes/cron.py + msg-fb5b419b = Cron manager not initialized -msg-78b9c276 = {$res} -msg-112659e5 = Failed to list jobs: {$e} +msg-78b9c276 = { $res } +msg-112659e5 = Failed to list jobs:{ $e } msg-8bc87eb5 = Invalid payload -msg-29f616c2 = session is required +msg-29f616c2 = Session is required msg-ae7c99a4 = run_at is required when run_once=true msg-4bb8c206 = cron_expression is required when run_once=false msg-13fbf01e = run_at must be ISO datetime -msg-da14d97a = Failed to create job: {$e} +msg-da14d97a = Failed to create job:{ $e } msg-804b6412 = Job not found -msg-94b2248d = Failed to update job: {$e} -msg-42c0ee7a = Failed to delete job: {$e} +msg-94b2248d = Failed to update job:{ $e } +msg-42c0ee7a = Failed to delete job:{ $e } ### astrbot/dashboard/routes/tools.py -msg-78b9c276 = {$res} -msg-977490be = 获取 MCP 服务器列表失败: {$e} -msg-50a07403 = 服务器名称不能为空 -msg-23d2bca3 = 必须提供有效的服务器配置 -msg-31252516 = 服务器 {$name} 已存在 -msg-20b8309f = 启用 MCP 服务器 {$name} 超时。 -msg-fff3d0c7 = 启用 MCP 服务器 {$name} 失败: {$e} -msg-7f1f7921 = 保存配置失败 -msg-a7f06648 = 添加 MCP 服务器失败: {$e} -msg-278dc41b = 服务器 {$old_name} 不存在 -msg-f0441f4b = 启用前停用 MCP 服务器时 {$old_name} 超时: {$e} -msg-7c468a83 = 启用前停用 MCP 服务器时 {$old_name} 失败: {$e} -msg-8a4c8128 = 停用 MCP 服务器 {$old_name} 超时。 -msg-9ac9b2fc = 停用 MCP 服务器 {$old_name} 失败: {$e} -msg-b988392d = 更新 MCP 服务器失败: {$e} -msg-c81030a7 = 服务器 {$name} 不存在 -msg-4cdbd30d = 停用 MCP 服务器 {$name} 超时。 -msg-1ed9a96e = 停用 MCP 服务器 {$name} 失败: {$e} -msg-a26f2c6a = 删除 MCP 服务器失败: {$e} -msg-bbc84cc5 = 无效的 MCP 服务器配置 -msg-aa0e3d0d = MCP 服务器配置不能为空 -msg-d69cbcf2 = 一次只能配置一个 MCP 服务器配置 -msg-bd43f610 = 测试 MCP 连接失败: {$e} -msg-057a3970 = 获取工具列表失败: {$e} -msg-29415636 = 缺少必要参数: name 或 action -msg-75d85dc1 = 启用工具失败: {$e} -msg-21a922b8 = 工具 {$tool_name} 不存在或操作失败。 -msg-20143f28 = 操作工具失败: {$e} -msg-295ab1fe = 未知: {$provider_name} -msg-fe38e872 = 同步失败: {$e} + +msg-78b9c276 = { $res } +msg-977490be = Failed to retrieve MCP server list:{ $e } +msg-50a07403 = Server name cannot be empty +msg-23d2bca3 = A valid server configuration must be provided +msg-31252516 = Server{ $name }Already exists +msg-20b8309f = Enable MCP Server{ $name }Timeout. +msg-fff3d0c7 = Enable MCP Server{ $name }Failed:{ $e } +msg-7f1f7921 = Failed to save configuration +msg-a7f06648 = Failed to add MCP server:{ $e } +msg-278dc41b = Server{ $old_name }Does not exist +msg-f0441f4b = Disable the MCP server before enabling{ $old_name }Timeout:{ $e } +msg-7c468a83 = Disable MCP server before enabling{ $old_name }Failed:{ $e } +msg-8a4c8128 = Stop the MCP server{ $old_name }Timeout. +msg-9ac9b2fc = Stop MCP Server{ $old_name }Failed:{ $e } +msg-b988392d = Failed to update MCP server:{ $e } +msg-c81030a7 = Server{ $name }Does not exist +msg-4cdbd30d = Deactivate MCP server{ $name }Timeout. +msg-1ed9a96e = Deactivate MCP Server{ $name }Failed:{ $e } +msg-a26f2c6a = Failed to delete MCP server:{ $e } +msg-bbc84cc5 = Invalid MCP server configuration +msg-aa0e3d0d = MCP server configuration cannot be empty +msg-d69cbcf2 = Only one MCP server configuration can be configured at a time. +msg-bd43f610 = Test MCP connection failed:{ $e } +msg-057a3970 = Failed to get tool list:{ $e } +msg-29415636 = Missing required parameters: name or action +msg-75d85dc1 = Failed to enable tool:{ $e } +msg-21a922b8 = Tools{ $tool_name }Does not exist or operation failed. +msg-20143f28 = Operation tool failed:{ $e } +msg-295ab1fe = Unknown:{ $provider_name } +msg-fe38e872 = Synchronization failed:{ $e } ### astrbot/dashboard/routes/chatui_project.py + msg-04827ead = Missing key: title msg-34fccfbb = Missing key: project_id -msg-a7c08aee = Project {$project_id} not found +msg-a7c08aee = Project{ $project_id }not found msg-c52a1454 = Permission denied msg-dbf41bfc = Missing key: session_id -msg-d922dfa3 = Session {$session_id} not found +msg-d922dfa3 = Session{ $session_id }not found ### astrbot/dashboard/routes/open_api.py + msg-e41d65d5 = Failed to create chat session %s: %s -msg-fc15cbcd = {$username_err} +msg-fc15cbcd = { $username_err } msg-bc3b3977 = Invalid username -msg-2cd6e70f = {$ensure_session_err} -msg-53632573 = {$resolve_err} +msg-2cd6e70f = { $ensure_session_err } +msg-53632573 = { $resolve_err } msg-79b0c7cb = Failed to update chat config route for %s with %s: %s -msg-7c7a9f55 = Failed to update chat config route: {$e} +msg-7c7a9f55 = Failed to update chat config route:{ $e } msg-74bff366 = page and page_size must be integers msg-1507569c = Message is empty msg-1389e46a = message must be a string or list msg-697561eb = message part must be an object msg-2c4bf283 = reply part missing message_id -msg-60ddb927 = unsupported message part type: {$part_type} -msg-cf310369 = attachment not found: {$attachment_id} -msg-58e0b84a = {$part_type} part missing attachment_id -msg-e565c4b5 = file not found: {$file_path} +msg-60ddb927 = unsupported message part type:{ $part_type } +msg-cf310369 = attachment not found:{ $attachment_id } +msg-58e0b84a = { $part_type }part missing attachment_id +msg-e565c4b5 = file not found:{ $file_path } msg-c6ec40ff = Message content is empty (reply only is not allowed) msg-2b00f931 = Missing key: message msg-a29d9adb = Missing key: umo -msg-4990e908 = Invalid umo: {$e} -msg-45ac857c = Bot not found or not running for platform: {$platform_id} -msg-ec0f0bd2 = Open API send_message failed: {$e} -msg-d04109ab = Failed to send message: {$e} +msg-4990e908 = Invalid umo:{ $e } +msg-45ac857c = Bot not found or not running for platform:{ $platform_id } +msg-ec0f0bd2 = Open API send_message failed:{ $e } +msg-d04109ab = Failed to send message:{ $e } ### astrbot/dashboard/routes/session_management.py -msg-e1949850 = 获取知识库列表失败: {$e} -msg-3cd6eb8c = 获取规则列表失败: {$e} -msg-363174ae = 缺少必要参数: umo -msg-809e51d7 = 缺少必要参数: rule_key -msg-ce203e7e = 不支持的规则键: {$rule_key} -msg-2726ab30 = 更新会话规则失败: {$e} -msg-f021f9fb = 删除会话规则失败: {$e} -msg-6bfa1fe5 = 缺少必要参数: umos -msg-4ce0379e = 参数 umos 必须是数组 -msg-979c6e2f = 删除 umo {$umo} 的规则失败: {$e} -msg-77d2761d = 批量删除会话规则失败: {$e} -msg-6619322c = 获取 UMO 列表失败: {$e} -msg-b944697c = 获取会话状态列表失败: {$e} -msg-adba3c3b = 至少需要指定一个要修改的状态 -msg-4a8eb7a6 = 请指定分组 ID -msg-67f15ab7 = 分组 '{$group_id}' 不存在 -msg-50fbcccb = 没有找到符合条件的会话 -msg-59714ede = 更新 {$umo} 服务状态失败: {$e} -msg-31640917 = 批量更新服务状态失败: {$e} -msg-4d83eb92 = 缺少必要参数: provider_type, provider_id -msg-5f333041 = 不支持的 provider_type: {$provider_type} -msg-6fa017d7 = 更新 {$umo} Provider 失败: {$e} -msg-07416020 = 批量更新 Provider 失败: {$e} -msg-94c745e6 = 获取分组列表失败: {$e} -msg-fb7cf353 = 分组名称不能为空 -msg-ae3fce8a = 创建分组失败: {$e} -msg-07de5ff3 = 分组 ID 不能为空 -msg-35b8a74f = 更新分组失败: {$e} -msg-3d41a6fd = 删除分组失败: {$e} + +msg-e1949850 = Failed to fetch knowledge base list:{ $e } +msg-3cd6eb8c = Failed to fetch rule list:{ $e } +msg-363174ae = Missing required parameter: umo +msg-809e51d7 = Missing required parameter: rule_key +msg-ce203e7e = Unsupported rule key:{ $rule_key } +msg-2726ab30 = Failed to update conversation rules:{ $e } +msg-f021f9fb = Failed to delete session rule:{ $e } +msg-6bfa1fe5 = Missing required parameter: umos +msg-4ce0379e = The parameter umos must be an array. +msg-979c6e2f = Delete umo{ $umo }The rule failed:{ $e } +msg-77d2761d = Batch deletion of session rules failed:{ $e } +msg-6619322c = Failed to retrieve UMO list:{ $e } +msg-b944697c = Failed to retrieve session status list:{ $e } +msg-adba3c3b = At least one status to be modified must be specified. +msg-4a8eb7a6 = Please specify the group ID +msg-67f15ab7 = Group{ $group_id }Does not exist +msg-50fbcccb = No matching conversations found +msg-59714ede = Update{ $umo }Service status failed:{ $e } +msg-31640917 = Batch update service status failed:{ $e } +msg-4d83eb92 = Missing required parameters: provider_type, provider_id +msg-5f333041 = Unsupported provider_type:{ $provider_type } +msg-6fa017d7 = Update{ $umo }Provider failed:{ $e } +msg-07416020 = Batch update Provider failed:{ $e } +msg-94c745e6 = Failed to get group list:{ $e } +msg-fb7cf353 = Group name cannot be empty +msg-ae3fce8a = Failed to create group:{ $e } +msg-07de5ff3 = Group ID cannot be empty +msg-35b8a74f = Update group failed:{ $e } +msg-3d41a6fd = Failed to delete group:{ $e } ### astrbot/dashboard/routes/persona.py -msg-4a12aead = 获取人格列表失败: {$e}{"\u000A"}{$res} -msg-c168407f = 获取人格列表失败: {$e} -msg-63c6f414 = 缺少必要参数: persona_id -msg-ce7da6f3 = 人格不存在 -msg-9c07774d = 获取人格详情失败: {$e}{"\u000A"}{$res} -msg-ee3b44ad = 获取人格详情失败: {$e} -msg-ad455c14 = 人格ID不能为空 -msg-43037094 = 系统提示词不能为空 -msg-ec9dda44 = 预设对话数量必须为偶数(用户和助手轮流对话) -msg-26b214d5 = 创建人格失败: {$e}{"\u000A"}{$res} -msg-8913dfe6 = 创建人格失败: {$e} -msg-3d94d18d = 更新人格失败: {$e}{"\u000A"}{$res} -msg-f2cdfbb8 = 更新人格失败: {$e} -msg-51d84afc = 删除人格失败: {$e}{"\u000A"}{$res} -msg-8314a263 = 删除人格失败: {$e} -msg-b8ecb8f9 = 移动人格失败: {$e}{"\u000A"}{$res} -msg-ab0420e3 = 移动人格失败: {$e} -msg-e5604a24 = 获取文件夹列表失败: {$e}{"\u000A"}{$res} -msg-4d7c7f4a = 获取文件夹列表失败: {$e} -msg-cf0ee4aa = 获取文件夹树失败: {$e}{"\u000A"}{$res} -msg-bb515af0 = 获取文件夹树失败: {$e} -msg-c92b4863 = 缺少必要参数: folder_id -msg-77cdd6fa = 文件夹不存在 -msg-2d34652f = 获取文件夹详情失败: {$e}{"\u000A"}{$res} -msg-650ef096 = 获取文件夹详情失败: {$e} -msg-27c413df = 文件夹名称不能为空 -msg-b5866931 = 创建文件夹失败: {$e}{"\u000A"}{$res} -msg-5e57f3b5 = 创建文件夹失败: {$e} -msg-9bd8f820 = 更新文件夹失败: {$e}{"\u000A"}{$res} -msg-1eada044 = 更新文件夹失败: {$e} -msg-9cef0256 = 删除文件夹失败: {$e}{"\u000A"}{$res} -msg-22020727 = 删除文件夹失败: {$e} -msg-7a69fe08 = items 不能为空 -msg-e71ba5c2 = 每个 item 必须包含 id, type, sort_order 字段 -msg-dfeb8320 = type 字段必须是 'persona' 或 'folder' -msg-aec43ed3 = 更新排序失败: {$e}{"\u000A"}{$res} -msg-75ec4427 = 更新排序失败: {$e} + +msg-4a12aead = Failed to retrieve personality list:{ $e }{ "\u000A" }{ $res } +msg-c168407f = Failed to retrieve personality list:{ $e } +msg-63c6f414 = Missing required parameter: persona_id +msg-ce7da6f3 = Personality does not exist +msg-9c07774d = Failed to retrieve personality details:{ $e }{ "\u000A" }{ $res } +msg-ee3b44ad = Failed to retrieve personality details:{ $e } +msg-ad455c14 = Personality ID cannot be empty +msg-43037094 = System prompt cannot be empty +msg-ec9dda44 = The number of preset dialogues must be an even number (alternating between user and assistant). +msg-26b214d5 = Failed to create persona:{ $e }{ "\u000A" }{ $res } +msg-8913dfe6 = Failed to create personality:{ $e } +msg-3d94d18d = Failed to update persona:{ $e }{ "\u000A" }{ $res } +msg-f2cdfbb8 = Failed to update personality:{ $e } +msg-51d84afc = Failed to delete persona:{ $e }{ "\u000A" }{ $res } +msg-8314a263 = Failed to delete persona:{ $e } +msg-b8ecb8f9 = Failed to move personality:{ $e }{ "\u000A" }{ $res } +msg-ab0420e3 = Failed to move persona:{ $e } +msg-e5604a24 = Failed to get folder list:{ $e }{ "\u000A" }{ $res } +msg-4d7c7f4a = Failed to get folder list:{ $e } +msg-cf0ee4aa = Failed to retrieve folder tree:{ $e }{ "\u000A" }{ $res } +msg-bb515af0 = Failed to retrieve folder tree:{ $e } +msg-c92b4863 = Missing required parameter: folder_id +msg-77cdd6fa = Folder does not exist +msg-2d34652f = Failed to get folder details:{ $e }{ "\u000A" }{ $res } +msg-650ef096 = Failed to get folder details:{ $e } +msg-27c413df = Folder name cannot be empty +msg-b5866931 = Failed to create folder:{ $e }{ "\u000A" }{ $res } +msg-5e57f3b5 = Failed to create folder:{ $e } +msg-9bd8f820 = Failed to update folder:{ $e }{ "\u000A" }{ $res } +msg-1eada044 = Failed to update folder:{ $e } +msg-9cef0256 = Failed to delete folder:{ $e }{ "\u000A" }{ $res } +msg-22020727 = Failed to delete folder:{ $e } +msg-7a69fe08 = items cannot be empty +msg-e71ba5c2 = Each item must contain the id, type, and sort_order fields +msg-dfeb8320 = The type field must be 'persona' or 'folder' +msg-aec43ed3 = Failed to update sorting:{ $e }{ "\u000A" }{ $res } +msg-75ec4427 = Failed to update sorting:{ $e } ### astrbot/dashboard/routes/platform.py -msg-bcc64513 = 未找到 webhook_uuid 为 {$webhook_uuid} 的平台 -msg-1478800f = 未找到对应平台 -msg-378cb077 = 平台 {$res} 未实现 webhook_callback 方法 -msg-2d797305 = 平台未支持统一 Webhook 模式 -msg-83f8dedf = 处理 webhook 回调时发生错误: {$e} -msg-af91bc78 = 处理回调失败 -msg-136a952f = 获取平台统计信息失败: {$e} -msg-60bb0722 = 获取统计信息失败: {$e} + +msg-bcc64513 = Webhook UUID not found for{ $webhook_uuid }platform +msg-1478800f = No corresponding platform found +msg-378cb077 = Platform{ $res }Method webhook_callback not implemented +msg-2d797305 = Platform does not support unified Webhook mode +msg-83f8dedf = An error occurred while processing the webhook callback:{ $e } +msg-af91bc78 = Failed to process callback +msg-136a952f = Failed to get platform statistics:{ $e } +msg-60bb0722 = Failed to retrieve statistics:{ $e } ### astrbot/dashboard/routes/api_key.py + msg-8e0249fa = At least one valid scope is required msg-1b79360d = Invalid scopes msg-d6621696 = expires_in_days must be an integer @@ -2620,9 +2830,11 @@ msg-209030fe = Missing key: key_id msg-24513a81 = API key not found ### astrbot/dashboard/routes/file.py -msg-78b9c276 = {$res} + +msg-78b9c276 = { $res } ### astrbot/dashboard/routes/chat.py + msg-a4a521ff = Missing key: filename msg-c9746528 = Invalid file path msg-3c2f6dee = File access error @@ -2634,288 +2846,310 @@ msg-5c531303 = Missing JSON body msg-1c3efd8f = Missing key: message or files msg-04588d0f = Missing key: session_id or conversation_id msg-c6ec40ff = Message content is empty (reply only is not allowed) -msg-2c3fdeb9 = Message are both empty +msg-2c3fdeb9 = Messages are both empty msg-9bc95e22 = session_id is empty -msg-344a401b = [WebChat] 用户 {$username} 断开聊天长连接。 -msg-6b54abec = WebChat stream error: {$e} +msg-344a401b = [WebChat] User{ $username }Disconnect chat long connection. +msg-6b54abec = WebChat stream error:{ $e } msg-53509ecb = webchat stream message_id mismatch -msg-1211e857 = [WebChat] 用户 {$username} 断开聊天长连接。 {$e} -msg-be34e848 = Failed to extract web search refs: {$e} -msg-80bbd0ff = WebChat stream unexpected error: {$e} +msg-1211e857 = [WebChat] User{ $username }Disconnect chat long connection.{ $e } +msg-be34e848 = Failed to extract web search refs:{ $e } +msg-80bbd0ff = WebChat stream unexpected error:{ $e } msg-dbf41bfc = Missing key: session_id -msg-d922dfa3 = Session {$session_id} not found +msg-d922dfa3 = Session{ $session_id }not found msg-c52a1454 = Permission denied msg-9d7a8094 = Failed to delete UMO route %s during session cleanup: %s -msg-44c45099 = Failed to delete attachment file {$res}: {$e} -msg-f033d8ea = Failed to get attachments: {$e} -msg-e6f655bd = Failed to delete attachments: {$e} +msg-44c45099 = Failed to delete attachment file{ $res }Text to translate:{ $e } +msg-f033d8ea = Failed to get attachments:{ $e } +msg-e6f655bd = Failed to delete attachments:{ $e } msg-a6ef3b67 = Missing key: display_name ### astrbot/dashboard/routes/t2i.py + msg-76cc0933 = Error in get_active_template msg-5350f35b = Template not found msg-d7b101c5 = Name and content are required. msg-e910b6f3 = Template with this name already exists. msg-18cfb637 = Content is required. msg-2480cf2f = Template not found. -msg-9fe026f1 = 模板名称(name)不能为空。 -msg-eeefe1dc = 模板 '{$name}' 不存在,无法应用。 +msg-9fe026f1 = Template name cannot be empty. +msg-eeefe1dc = Template '{ $name }does not exist, cannot be applied. msg-0048e060 = Error in set_active_template msg-8fde62dd = Error in reset_default_template ### astrbot/dashboard/routes/stat.py + msg-1198c327 = You are not permitted to do this operation in demo mode -msg-78b9c276 = {$res} +msg-78b9c276 = { $res } msg-0e5bb0b1 = proxy_url is required -msg-f0e0983e = Failed. Status code: {$res} -msg-68e65093 = Error: {$e} +msg-f0e0983e = Failed. Status code:{ $res } +msg-68e65093 = Error:{ $e } msg-b5979fe8 = version parameter is required msg-b88a1887 = Invalid version format -msg-8cb9bb6b = Path traversal attempt detected: {$version} -> {$changelog_path} -msg-7616304c = Changelog for version {$version} not found +msg-8cb9bb6b = Path traversal attempt detected:{ $version }->{ $changelog_path } +msg-7616304c = Changelog for version{ $version }not found ### astrbot/dashboard/routes/plugin.py + msg-1198c327 = You are not permitted to do this operation in demo mode -msg-adce8d2f = 缺少插件目录名 -msg-2f1b67fd = 重载失败: {$err} -msg-71f9ea23 = /api/plugin/reload-failed: {$res} -msg-27286c23 = /api/plugin/reload: {$res} -msg-b33c0d61 = 缓存MD5匹配,使用缓存的插件市场数据 -msg-64b4a44c = 远程插件市场数据为空: {$url} -msg-fdbffdca = 成功获取远程插件市场数据,包含 {$res} 个插件 -msg-48c42bf8 = 请求 {$url} 失败,状态码:{$res} -msg-6ac25100 = 请求 {$url} 失败,错误:{$e} -msg-7e536821 = 远程插件市场数据获取失败,使用缓存数据 -msg-d4b4c53a = 获取插件列表失败,且没有可用的缓存数据 -msg-37f59b88 = 加载缓存MD5失败: {$e} -msg-8048aa4c = 获取远程MD5失败: {$e} -msg-593eacfd = 缓存文件中没有MD5信息 -msg-dedcd957 = 无法获取远程MD5,将使用缓存 -msg-21d7e754 = 插件数据MD5: 本地={$cached_md5}, 远程={$remote_md5}, 有效={$is_valid} -msg-0faf4275 = 检查缓存有效性失败: {$e} -msg-e26aa0a5 = 加载缓存文件: {$cache_file}, 缓存时间: {$res} -msg-23d627a1 = 加载插件市场缓存失败: {$e} -msg-22d12569 = 插件市场数据已缓存到: {$cache_file}, MD5: {$md5} -msg-478c99a9 = 保存插件市场缓存失败: {$e} -msg-3838d540 = 获取插件 Logo 失败: {$e} -msg-da442310 = 正在安装插件 {$repo_url} -msg-e0abd541 = 安装插件 {$repo_url} 成功。 -msg-78b9c276 = {$res} -msg-acfcd91e = 正在安装用户上传的插件 {$res} -msg-48e05870 = 安装插件 {$res} 成功 -msg-8af56756 = 正在卸载插件 {$plugin_name} -msg-6d1235b6 = 卸载插件 {$plugin_name} 成功 -msg-7055316c = 正在更新插件 {$plugin_name} -msg-d258c060 = 更新插件 {$plugin_name} 成功。 -msg-398370d5 = /api/plugin/update: {$res} -msg-2d225636 = 插件列表不能为空 -msg-32632e67 = 批量更新插件 {$name} -msg-08dd341c = /api/plugin/update-all: 更新插件 {$name} 失败: {$res} -msg-cb230226 = 停用插件 {$plugin_name} 。 -msg-abc710cd = /api/plugin/off: {$res} -msg-06e2a068 = 启用插件 {$plugin_name} 。 -msg-82c412e7 = /api/plugin/on: {$res} -msg-77e5d67e = 正在获取插件 {$plugin_name} 的README文件内容 -msg-baed1b72 = 插件名称为空 -msg-773cca0a = 插件名称不能为空 -msg-082a5585 = 插件 {$plugin_name} 不存在 -msg-ba106e58 = 插件 {$plugin_name} 目录不存在 -msg-e38e4370 = 无法找到插件目录: {$plugin_dir} -msg-df027f16 = 无法找到插件 {$plugin_name} 的目录 -msg-5f304f4b = 插件 {$plugin_name} 没有README文件 -msg-a3ed8739 = /api/plugin/readme: {$res} -msg-2f9e2c11 = 读取README文件失败: {$e} -msg-dcbd593f = 正在获取插件 {$plugin_name} 的更新日志 -msg-ea5482da = /api/plugin/changelog: {$res} -msg-8e27362e = 读取更新日志失败: {$e} -msg-0842bf8b = 插件 {$plugin_name} 没有更新日志文件 +msg-adce8d2f = Missing plugin directory name +msg-2f1b67fd = Overload failed:{ $err } +msg-71f9ea23 = /api/plugin/reload-failed:{ $res } +msg-27286c23 = /api/plugin/reload:{ $res } +msg-b33c0d61 = Cache MD5 matches, using cached plugin marketplace data. +msg-64b4a44c = Remote plugin market data is empty:{ $url } +msg-fdbffdca = Successfully retrieved remote plugin market data, including{ $res }plugins +msg-48c42bf8 = Request{ $url }Failed, status code:{ $res } +msg-6ac25100 = Request{ $url }Failed, error:{ $e } +msg-7e536821 = Failed to fetch remote plugin market data, using cached data +msg-d4b4c53a = Failed to fetch the plugin list, and no cached data is available +msg-37f59b88 = Failed to load cache MD5:{ $e } +msg-8048aa4c = Failed to retrieve remote MD5:{ $e } +msg-593eacfd = The cache file does not contain MD5 information. +msg-dedcd957 = Unable to retrieve remote MD5, will use cache +msg-21d7e754 = Plugin data MD5: Local={ $cached_md5 }, Remote={ $remote_md5 }, valid={ $is_valid } +msg-0faf4275 = Failed to check cache validity:{ $e } +msg-e26aa0a5 = Loading cache file:{ $cache_file }, Cache Time:{ $res } +msg-23d627a1 = Failed to load plugin marketplace cache:{ $e } +msg-22d12569 = Plugin market data has been cached to:{ $cache_file }, MD5:{ $md5 } +msg-478c99a9 = Failed to save plugin marketplace cache:{ $e } +msg-3838d540 = Failed to get plugin logo:{ $e } +msg-da442310 = Installing plugin{ $repo_url } +msg-e0abd541 = Install plugin{ $repo_url }Successful. +msg-78b9c276 = { $res } +msg-acfcd91e = Installing user uploaded plugin{ $res } +msg-48e05870 = Install plugin{ $res }Success +msg-8af56756 = 正在卸载插件{ $plugin_name } +msg-6d1235b6 = Uninstall plugin{ $plugin_name }Success +msg-7055316c = Updating plugin{ $plugin_name } +msg-d258c060 = Update plugin{ $plugin_name }Success. +msg-398370d5 = /api/plugin/update:{ $res } +msg-2d225636 = Plugin list cannot be empty +msg-32632e67 = Batch Update Plugin{ $name } +msg-08dd341c = /api/plugin/update-all: Update plugin{ $name }Failed:{ $res } +msg-cb230226 = Deactivate plugin{ $plugin_name }待翻译文本: +msg-abc710cd = /api/plugin/off:{ $res } +msg-06e2a068 = Enable plugin{ $plugin_name }. +msg-82c412e7 = /api/plugin/on:{ $res } +msg-77e5d67e = 正在获取插件{ $plugin_name }The content of the README file +msg-baed1b72 = Plugin name is empty +msg-773cca0a = Plugin name cannot be empty +msg-082a5585 = Plugin{ $plugin_name }Does not exist +msg-ba106e58 = Plugin{ $plugin_name }Directory does not exist +msg-e38e4370 = Unable to find plugin directory:{ $plugin_dir } +msg-df027f16 = Plugin not found{ $plugin_name }Directory +msg-5f304f4b = Plugin{ $plugin_name }No README file +msg-a3ed8739 = /api/plugin/readme:{ $res } +msg-2f9e2c11 = Failed to read README file:{ $e } +msg-dcbd593f = Fetching plugins{ $plugin_name }Update log +msg-ea5482da = /api/plugin/changelog:{ $res } +msg-8e27362e = Failed to read changelog:{ $e } +msg-0842bf8b = Plugin{ $plugin_name }No changelog file msg-8e36313d = sources fields must be a list -msg-643e51e7 = /api/plugin/source/save: {$res} +msg-643e51e7 = /api/plugin/source/save:{ $res } ### astrbot/builtin_stars/session_controller/main.py -msg-b48bf3fe = LLM response failed: {$e} + +msg-b48bf3fe = LLM response failed:{ $e } ### astrbot/builtin_stars/builtin_commands/commands/setunset.py -msg-8b56b437 = 会话 {$uid} 变量 {$key} 存储成功。使用 /unset 移除。 -msg-dfd31d9d = 没有那个变量名。格式 /unset 变量名。 -msg-bf181241 = 会话 {$uid} 变量 {$key} 移除成功。 + +msg-8b56b437 = Session{ $uid }Variable{ $key }Storage successful. Use /unset to remove. +msg-dfd31d9d = There is no such variable name. Format: /unset variable name. +msg-bf181241 = Session{ $uid }Variable{ $key }Removed successfully. ### astrbot/builtin_stars/builtin_commands/commands/provider.py + msg-b435fcdc = Provider reachability check failed: id=%s type=%s code=%s reason=%s -msg-f4cfd3ab = 正在进行提供商可达性测试,请稍候... -msg-ed8dcc22 = {$ret} -msg-f3d8988e = 请输入序号。 -msg-284759bb = 无效的提供商序号。 -msg-092d9956 = 成功切换到 {$id_}。 -msg-bf9eb668 = 无效的参数。 -msg-4cdd042d = 未找到任何 LLM 提供商。请先配置。 -msg-cb218e86 = 模型序号错误。 -msg-1756f199 = 切换模型成功。当前提供商: [{$res}] 当前模型: [{$res_2}] -msg-4d4f587f = 切换模型到 {$res}。 -msg-584ca956 = Key 序号错误。 -msg-f52481b8 = 切换 Key 未知错误: {$e} -msg-7a156524 = 切换 Key 成功。 +msg-f4cfd3ab = Provider reachability test in progress, please wait... +msg-ed8dcc22 = { $ret } +msg-f3d8988e = Please enter the serial number. +msg-284759bb = Invalid provider number. +msg-092d9956 = Successfully switched to{ $id_ }Text to be translated: . +msg-bf9eb668 = Invalid parameter. +msg-4cdd042d = No LLM providers found. Please configure first. +msg-cb218e86 = Model serial number error. +msg-1756f199 = Switched model successfully. Current provider: [{ $res }Current model: [{ $res_2 }] +msg-4d4f587f = Switch model to{ $res }. +msg-584ca956 = Key sequence number is incorrect. +msg-f52481b8 = Switch Key Unknown Error:{ $e } +msg-7a156524 = Switching Key successful. ### astrbot/builtin_stars/builtin_commands/commands/conversation.py -msg-63fe9607 = 在{$res}场景下,reset命令需要管理员权限,您 (ID {$res_2}) 不是管理员,无法执行此操作。 -msg-6f4bbe27 = 重置对话成功。 -msg-4cdd042d = 未找到任何 LLM 提供商。请先配置。 -msg-69ed45be = 当前未处于对话状态,请 /switch 切换或者 /new 创建。 -msg-ed8dcc22 = {$ret} -msg-772ec1fa = 已请求停止 {$stopped_count} 个运行中的任务。 -msg-8d42cd8a = 当前会话没有运行中的任务。 -msg-efdfbe3e = {$THIRD_PARTY_AGENT_RUNNER_STR} 对话列表功能暂不支持。 -msg-492c2c02 = 已创建新对话。 -msg-c7dc838d = 切换到新对话: 新对话({$res})。 -msg-6da01230 = 群聊 {$session} 已切换到新对话: 新对话({$res})。 -msg-f356d65a = 请输入群聊 ID。/groupnew 群聊ID。 -msg-7e442185 = 类型错误,请输入数字对话序号。 -msg-00dbe29c = 请输入对话序号。/switch 对话序号。/ls 查看对话 /new 新建对话 -msg-a848ccf6 = 对话序号错误,请使用 /ls 查看 -msg-1ec33cf6 = 切换到对话: {$title}({$res})。 -msg-68e5dd6c = 请输入新的对话名称。 -msg-c8dd6158 = 重命名对话成功。 -msg-1f1fa2f2 = 会话处于群聊,并且未开启独立会话,并且您 (ID {$res}) 不是管理员,因此没有权限删除当前对话。 -msg-6a1dc4b7 = 当前未处于对话状态,请 /switch 序号 切换或 /new 创建。 + +msg-63fe9607 = In{ $res }In this scenario, the reset command requires administrator privileges, you (ID{ $res_2 }) Not an administrator, unable to perform this operation. +msg-6f4bbe27 = Conversation reset successfully. +msg-4cdd042d = No LLM provider found. Please configure it first. +msg-69ed45be = Not currently in a conversation state, please use /switch to switch or /new to create. +msg-ed8dcc22 = { $ret } +msg-772ec1fa = Stop requested{ $stopped_count }A running task. +msg-8d42cd8a = No tasks are currently running in this session. +msg-efdfbe3e = { $THIRD_PARTY_AGENT_RUNNER_STR }The conversation list feature is currently not supported. +msg-492c2c02 = A new conversation has been created. +msg-c7dc838d = Switch to New Conversation: New Conversation({ $res })。 +msg-6da01230 = Group Chat{ $session }Switched to new chat: New chat{ $res }). +msg-f356d65a = Please enter the group chat ID. /groupnew Group Chat ID. +msg-7e442185 = Type error, please enter a numeric conversation number. +msg-00dbe29c = Enter conversation number. /switch conversation number. /ls view conversations /new create conversation +msg-a848ccf6 = Dialog serial number error, please use /ls to view. +msg-1ec33cf6 = Switch to conversation:{ $title }Text to translate:{ $res })。 +msg-68e5dd6c = Please enter a new conversation name. +msg-c8dd6158 = Conversation renamed successfully. +msg-1f1fa2f2 = Session is in a group chat, and independent sessions are not enabled, and you (ID{ $res }) is not an administrator and therefore does not have permission to delete the current conversation. +msg-6a1dc4b7 = Currently not in a conversation state, please /switch number to switch or /new to create. ### astrbot/builtin_stars/builtin_commands/commands/tts.py -msg-ef1b2145 = {$status_text}当前会话的文本转语音。但 TTS 功能在配置中未启用,请前往 WebUI 开启。 -msg-deee9deb = {$status_text}当前会话的文本转语音。 + +msg-ef1b2145 = { $status_text }Text-to-speech for the current session. However, the TTS feature is not enabled in the configuration. Please go to the WebUI to enable it. +msg-deee9deb = { $status_text }Text-to-speech for the current session. ### astrbot/builtin_stars/builtin_commands/commands/llm.py -msg-72cd5f57 = {$status} LLM 聊天功能。 + +msg-72cd5f57 = { $status }LLM Chat Feature. ### astrbot/builtin_stars/builtin_commands/commands/persona.py -msg-4f52d0dd = 当前对话不存在,请先使用 /new 新建一个对话。 -msg-e092b97c = [Persona]{"\u000A"}{"\u000A"}- 人格情景列表: `/persona list`{"\u000A"}- 设置人格情景: `/persona 人格`{"\u000A"}- 人格情景详细信息: `/persona view 人格`{"\u000A"}- 取消人格: `/persona unset`{"\u000A"}{"\u000A"}默认人格情景: {$res}{"\u000A"}当前对话 {$curr_cid_title} 的人格情景: {$curr_persona_name}{"\u000A"}{"\u000A"}配置人格情景请前往管理面板-配置页{"\u000A"} -msg-c046b6e4 = {$msg} -msg-99139ef8 = 请输入人格情景名 -msg-a44c7ec0 = 当前没有对话,无法取消人格。 -msg-a90c75d4 = 取消人格成功。 -msg-a712d71a = 当前没有对话,请先开始对话或使用 /new 创建一个对话。 -msg-4e4e746d = 设置成功。如果您正在切换到不同的人格,请注意使用 /reset 来清空上下文,防止原人格对话影响现人格。{$force_warn_msg} -msg-ab60a2e7 = 不存在该人格情景。使用 /persona list 查看所有。 + +msg-4f52d0dd = The current conversation does not exist, please use /new to create a new conversation first. +msg-e092b97c = [Persona]{ "\u000A" }{ "\u000A" }- Persona Scenario List: `/persona list`{ "\u000A" }- Set personality scenario: `/persona personality`{ "\u000A" }- Persona scenario details: `/persona view persona`{ "\u000A" }- Cancel persona: `/persona unset`{ "\u000A" }{ "\u000A" }Default personality scenario:{ $res }{ "\u000A" }Current conversation{ $curr_cid_title }Personality scenario:{ $curr_persona_name }{ "\u000A" }{ "\u000A" }To configure persona scenarios, please go to the Admin Panel - Configuration page.{ "\u000A" } +msg-c046b6e4 = { $msg } +msg-99139ef8 = Please enter the personality scenario name +msg-a44c7ec0 = There is no conversation currently, unable to cancel persona. +msg-a90c75d4 = Personality cancellation successful. +msg-a712d71a = There is no conversation currently. Please start a conversation first or use /new to create one. +msg-4e4e746d = Settings successful. If you are switching to a different persona, please use /reset to clear the context to prevent the original persona's dialogue from affecting the current one.{ $force_warn_msg } +msg-ab60a2e7 = The persona scenario does not exist. Use /persona list to view all. ### astrbot/builtin_stars/builtin_commands/commands/t2i.py -msg-855d5cf3 = 已关闭文本转图片模式。 -msg-64da24f4 = 已开启文本转图片模式。 + +msg-855d5cf3 = Text-to-image mode has been disabled. +msg-64da24f4 = Text-to-image mode is enabled. ### astrbot/builtin_stars/builtin_commands/commands/admin.py -msg-ad019976 = 使用方法: /op 授权管理员;/deop 取消管理员。可通过 /sid 获取 ID。 -msg-1235330f = 授权成功。 -msg-e78847e0 = 使用方法: /deop 取消管理员。可通过 /sid 获取 ID。 -msg-012152c1 = 取消授权成功。 -msg-5e076026 = 此用户 ID 不在管理员名单内。 -msg-7f8eedde = 使用方法: /wl 添加白名单;/dwl 删除白名单。可通过 /sid 获取 ID。 -msg-de1b0a87 = 添加白名单成功。 -msg-59d6fcbe = 使用方法: /dwl 删除白名单。可通过 /sid 获取 ID。 -msg-4638580f = 删除白名单成功。 -msg-278fb868 = 此 SID 不在白名单内。 -msg-1dee5007 = 正在尝试更新管理面板... -msg-76bea66c = 管理面板更新完成。 + +msg-ad019976 = Usage: /op to authorize an administrator; /deop to remove administrator. Use /sid to get the ID. +msg-1235330f = Authorization successful. +msg-e78847e0 = Usage: /deop to remove admin. ID can be obtained via /sid. +msg-012152c1 = Authorization canceled successfully. +msg-5e076026 = This user ID is not in the administrator list. +msg-7f8eedde = Usage: /wl to add to the whitelist; /dwl to remove from the whitelist. Use /sid to get your ID. +msg-de1b0a87 = Whitelist added successfully. +msg-59d6fcbe = Usage: /dwl to remove from whitelist. Use /sid to get the ID. +msg-4638580f = Whitelist deletion successful. +msg-278fb868 = This SID is not in the whitelist. +msg-1dee5007 = Attempting to update the management panel... +msg-76bea66c = Management panel update completed. ### astrbot/builtin_stars/builtin_commands/commands/sid.py -msg-ed8dcc22 = {$ret} + +msg-ed8dcc22 = { $ret } ### astrbot/builtin_stars/builtin_commands/commands/plugin.py -msg-9cae24f5 = {$plugin_list_info} -msg-3f3a6087 = 演示模式下无法禁用插件。 -msg-90e17cd4 = /plugin off <插件名> 禁用插件。 -msg-d29d6d57 = 插件 {$plugin_name} 已禁用。 -msg-f90bbe20 = 演示模式下无法启用插件。 -msg-b897048f = /plugin on <插件名> 启用插件。 -msg-ebfb93bb = 插件 {$plugin_name} 已启用。 -msg-9cd74a8d = 演示模式下无法安装插件。 -msg-d79ad78d = /plugin get <插件仓库地址> 安装插件 -msg-4f293fe1 = 准备从 {$plugin_repo} 安装插件。 -msg-d40e7065 = 安装插件成功。 -msg-feff82c6 = 安装插件失败: {$e} -msg-5bfe9d3d = /plugin help <插件名> 查看插件信息。 -msg-02627a9b = 未找到此插件。 -msg-ed8dcc22 = {$ret} + +msg-9cae24f5 = { $plugin_list_info } +msg-3f3a6087 = Demo mode cannot disable plugins. +msg-90e17cd4 = /plugin off Disable plugin. +msg-d29d6d57 = Plugin{ $plugin_name }Disabled. +msg-f90bbe20 = Plugins cannot be enabled in demo mode. +msg-b897048f = /plugin on Enable plugin. +msg-ebfb93bb = Plugin{ $plugin_name }Enabled. +msg-9cd74a8d = Plugins cannot be installed in demo mode. +msg-d79ad78d = /plugin get install plugin +msg-4f293fe1 = Preparing to fetch from{ $plugin_repo }Install plugin. +msg-d40e7065 = Plugin installed successfully. +msg-feff82c6 = Plugin installation failed:{ $e } +msg-5bfe9d3d = /plugin help to view plugin information. +msg-02627a9b = Plugin not found. +msg-ed8dcc22 = { $ret } ### astrbot/builtin_stars/builtin_commands/commands/help.py -msg-c046b6e4 = {$msg} + +msg-c046b6e4 = { $msg } ### astrbot/builtin_stars/builtin_commands/commands/alter_cmd.py -msg-d7a36c19 = 该指令用于设置指令或指令组的权限。{"\u000A"}格式: /alter_cmd {"\u000A"}例1: /alter_cmd c1 admin 将 c1 设为管理员指令{"\u000A"}例2: /alter_cmd g1 c1 admin 将 g1 指令组的 c1 子指令设为管理员指令{"\u000A"}/alter_cmd reset config 打开 reset 权限配置 -msg-afe0fa58 = {$config_menu} -msg-0c85d498 = 场景编号和权限类型不能为空 -msg-4e0afcd1 = 场景编号必须是 1-3 之间的数字 -msg-830d6eb8 = 权限类型错误,只能是 admin 或 member -msg-d1180ead = 已将 reset 命令在{$res}场景下的权限设为{$perm_type} -msg-8d9bc364 = 指令类型错误,可选类型有 admin, member -msg-1f2f65e0 = 未找到该指令 -msg-cd271581 = 已将「{$cmd_name}」{$cmd_group_str} 的权限级别调整为 {$cmd_type}。 + +msg-d7a36c19 = This command is used to set permissions for a command or a group of commands.{ "\u000A" }Format: /alter_cmd { "\u000A" }Example 1: /alter_cmd c1 admin sets c1 as an admin command{ "\u000A" }Example 2: /alter_cmd g1 c1 admin sets the c1 sub-command of the g1 command group as an administrator command.{ "\u000A" }/alter_cmd reset config opens reset permission configuration +msg-afe0fa58 = { $config_menu } +msg-0c85d498 = Scene number and permission type cannot be empty +msg-4e0afcd1 = Scene number must be a number between 1 and 3 +msg-830d6eb8 = Permission type error, must be admin or member +msg-d1180ead = The reset command has been{ $res }Permissions set for the scenario{ $perm_type } +msg-8d9bc364 = Command type error, available types are admin, member +msg-1f2f65e0 = The command was not found +msg-cd271581 = 已将「{ $cmd_name }"{ $cmd_group_str }The permission level has been adjusted to{ $cmd_type }. ### astrbot/builtin_stars/web_searcher/main.py -msg-7f5fd92b = 检测到旧版 websearch_tavily_key (字符串格式),自动迁移为列表格式并保存。 -msg-bed9def5 = web_searcher - scraping web: {$res} - {$res_2} -msg-8214760c = bing search error: {$e}, try the next one... -msg-8676b5aa = search bing failed -msg-3fb6d6ad = sogo search error: {$e} + +msg-7f5fd92b = Detected legacy websearch_tavily_key (string format), automatically migrated to list format and saved. +msg-bed9def5 = web_searcher - scraping web:{ $res }To be translated text:{ $res_2 } +msg-8214760c = Bing search error:{ $e }, try the next one... +msg-8676b5aa = Search Bing failed +msg-3fb6d6ad = sogo search error:{ $e } msg-fe9b336f = search sogo failed -msg-c991b022 = 错误:Tavily API密钥未在AstrBot中配置。 -msg-b4fbb4a9 = Tavily web search failed: {$reason}, status: {$res} +msg-c991b022 = Error: Tavily API key is not configured in AstrBot. +msg-b4fbb4a9 = Tavily web search failed:{ $reason }, status:{ $res } msg-6769aba9 = Error: Tavily web searcher does not return any results. -msg-b4e7334e = 此指令已经被废弃,请在 WebUI 中开启或关闭网页搜索功能。 -msg-b1877974 = web_searcher - search_from_search_engine: {$query} -msg-2360df6b = Error processing search result: {$processed_result} +msg-b4e7334e = This command has been deprecated. Please enable or disable web search functionality in the WebUI. +msg-b1877974 = web_searcher - search_from_search_engine:{ $query } +msg-2360df6b = Error processing search result:{ $processed_result } msg-359d0443 = Error: Baidu AI Search API key is not configured in AstrBot. msg-94351632 = Successfully initialized Baidu AI Search MCP server. -msg-5a7207c1 = web_searcher - search_from_tavily: {$query} +msg-5a7207c1 = web_searcher - search_from_tavily:{ $query } msg-b36134c9 = Error: Tavily API key is not configured in AstrBot. msg-98ed69f4 = Error: url must be a non-empty string. -msg-51edd9ee = 错误:BoCha API密钥未在AstrBot中配置。 -msg-73964067 = BoCha web search failed: {$reason}, status: {$res} -msg-34417720 = web_searcher - search_from_bocha: {$query} +msg-51edd9ee = Error: BoCha API key is not configured in AstrBot. +msg-73964067 = BoCha web search failed:{ $reason }, status:{ $res } +msg-34417720 = web_searcher - search_from_bocha:{ $query } msg-b798883b = Error: BoCha API key is not configured in AstrBot. msg-22993708 = Cannot get Baidu AI Search MCP tool. -msg-6f8d62a4 = Cannot Initialize Baidu AI Search MCP Server: {$e} +msg-6f8d62a4 = Cannot Initialize Baidu AI Search MCP Server:{ $e } ### astrbot/builtin_stars/web_searcher/engines/bing.py + msg-e3b4d1e9 = Bing search failed ### astrbot/builtin_stars/astrbot/main.py -msg-3df554a1 = 聊天增强 err: {$e} -msg-5bdf8f5c = {$e} -msg-bb6ff036 = 未找到任何 LLM 提供商。请先配置。无法主动回复 + +msg-3df554a1 = Chat Enhancement err:{ $e } +msg-5bdf8f5c = { $e } +msg-bb6ff036 = No LLM provider found. Please configure first. Cannot actively reply. msg-afa050be = 当前未处于对话状态,无法主动回复,请确保 平台设置->会话隔离(unique_session) 未开启,并使用 /switch 序号 切换或者 /new 创建一个会话。 -msg-9a6a6b2e = 未找到对话,无法主动回复 -msg-78b9c276 = {$res} -msg-b177e640 = 主动回复失败: {$e} -msg-24d2f380 = ltm: {$e} +msg-9a6a6b2e = No conversation found, unable to initiate a reply. +msg-78b9c276 = { $res } +msg-b177e640 = Active reply failed:{ $e } +msg-24d2f380 = ltm:{ $e } ### astrbot/builtin_stars/astrbot/long_term_memory.py -msg-5bdf8f5c = {$e} -msg-8e11fa57 = 没有找到 ID 为 {$image_caption_provider_id} 的提供商 -msg-8ebaa397 = 提供商类型错误({$res}),无法获取图片描述 -msg-30954f77 = 图片 URL 为空 -msg-62de0c3e = 获取图片描述失败: {$e} -msg-d0647999 = ltm | {$res} | {$final_message} -msg-133c1f1d = Recorded AI response: {$res} | {$final_message} + +msg-5bdf8f5c = { $e } +msg-8e11fa57 = No ID found for{ $image_caption_provider_id }Provider +msg-8ebaa397 = Provider type error{ $res }), unable to get image description +msg-30954f77 = Image URL is empty +msg-62de0c3e = Failed to get image description:{ $e } +msg-d0647999 = ltm |{ $res }|{ $final_message } +msg-133c1f1d = Recorded AI response:{ $res }To be translated text:{ $final_message } ### astrbot/i18n/ftl_translate.py -msg-547c9cc5 = 未检测到环境变量 DEEPSEEK_API_KEY,请先设置。 -msg-8654e4be = {"\u000A"}[Error] API 调用失败: {$e} -msg-75f207ed = File not found: {$ftl_path} -msg-dcfbbe82 = No messages found in {$ftl_path} -msg-ccd5a28f = 共 {$res} 条文本,使用 {$max_workers} 个并发线程翻译... -msg-00b24d69 = {"\u000A"}[Error] 翻译失败,保留原文: {$e} -msg-ebcdd595 = {"\u000A"}翻译完成,已保存到 {$ftl_path} -msg-d6c66497 = 错误: 请先设置 DEEPSEEK_API_KEY 环境变量。 -msg-09486085 = 例如: export DEEPSEEK_API_KEY='sk-xxxxxx' + +msg-547c9cc5 = No environment variable DEEPSEEK_API_KEY detected, please set it first. +msg-8654e4be = { "\u000A" }[Error] API call failed:{ $e } +msg-75f207ed = File not found:{ $ftl_path } +msg-dcfbbe82 = No messages found in{ $ftl_path } +msg-ccd5a28f = Total{ $res }Text, use{ $max_workers }Concurrent threads translation... +msg-00b24d69 = { "\u000A" }[Error] Translation failed, original text retained:{ $e } +msg-ebcdd595 = { "\u000A" }Translation completed, saved to{ $ftl_path } +msg-d6c66497 = Error: Please set the DEEPSEEK_API_KEY environment variable first. +msg-09486085 = For example: export DEEPSEEK_API_KEY='sk-xxxxxx' ### scripts/generate_changelog.py + msg-a79937ef = Warning: openai package not installed. Install it with: pip install openai -msg-090bfd36 = Warning: Failed to call LLM API: {$e} +msg-090bfd36 = Warning: Failed to call LLM API:{ $e } msg-a3ac9130 = Falling back to simple changelog generation... -msg-6f1011c5 = Latest tag: {$latest_tag} +msg-6f1011c5 = Latest tag:{ $latest_tag } msg-8c7f64d7 = Error: No tags found in repository -msg-a89fa0eb = No commits found since {$latest_tag} -msg-846ebecf = Found {$res} commits since {$latest_tag} -msg-9ad686af = Warning: Could not parse version from tag {$latest_tag} -msg-f5d43a54 = Generating changelog for {$version}... -msg-e54756e8 = {"\u000A"}✓ Changelog generated: {$changelog_file} -msg-82be6c98 = {"\u000A"}Preview: -msg-321ac5b1 = {$changelog_content} \ No newline at end of file +msg-a89fa0eb = No commits found since{ $latest_tag } +msg-846ebecf = Found{ $res }commits since{ $latest_tag } +msg-9ad686af = Warning: Could not parse version from tag{ $latest_tag } +msg-f5d43a54 = Generating changelog for{ $version }... +msg-e54756e8 = { "\u000A" }✓ Changelog generated:{ $changelog_file } +msg-82be6c98 = { "\u000A" }Preview: +msg-321ac5b1 = { $changelog_content } diff --git a/astrbot/i18n/locales/zh-cn/i18n_messages.ftl b/astrbot/i18n/locales/zh-cn/i18n_messages.ftl index 0d873f6669..d086db6a25 100644 --- a/astrbot/i18n/locales/zh-cn/i18n_messages.ftl +++ b/astrbot/i18n/locales/zh-cn/i18n_messages.ftl @@ -1,517 +1,567 @@ - ### main.py + msg-5e25709f = 请使用 Python3.10+ 运行本项目。 -msg-afd0ab81 = 使用指定的 WebUI 目录: {$webui_dir} -msg-7765f00f = 指定的 WebUI 目录 {$webui_dir} 不存在,将使用默认逻辑。 +msg-afd0ab81 = 使用指定的 WebUI 目录:{ $webui_dir } +msg-7765f00f = 指定的 WebUI 目录{ $webui_dir }不存在,将使用默认逻辑。 msg-9af20e37 = WebUI 版本已是最新。 -msg-9dd5c1d2 = 检测到 WebUI 版本 ({$v}) 与当前 AstrBot 版本 (v{$VERSION}) 不符。 +msg-9dd5c1d2 = 检测到 WebUI 版本 ({ $v }) 与当前 AstrBot 版本 (v{ $VERSION }) 不符。 msg-ec714d4e = 开始下载管理面板文件...高峰期(晚上)可能导致较慢的速度。如多次下载失败,请前往 https://github.com/AstrBotDevs/AstrBot/releases/latest 下载 dist.zip,并将其中的 dist 文件夹解压至 data 目录下。 -msg-c5170c27 = 下载管理面板文件失败: {$e}。 +msg-c5170c27 = 下载管理面板文件失败:{ $e }。 msg-e1592ad1 = 管理面板下载完成。 -msg-fe494da6 = {$logo_tmpl} +msg-fe494da6 = { $logo_tmpl } ### astrbot/core/lang.py -msg-d103bc8e = Namespace must not be empty. -msg-f66527da = Namespace must not contain '.'. -msg-b3665aee = Locale directory does not exist: {$base_dir} -msg-3fe89e6a = No locale directories found under: {$base_dir} -msg-c79b2c75 = Namespace '{$namespace}' already exists. Set replace=True to overwrite. -msg-7db3fccf = Default namespace cannot be unregistered. -msg-3d066f64 = Namespace '{$namespace}' is not registered. + +msg-d103bc8e = 命名空间不能为空。 +msg-f66527da = 命名空间不能包含 '.'。 +msg-b3665aee = 区域设置目录不存在:{ $base_dir } +msg-3fe89e6a = 未找到区域设置目录位于:{ $base_dir } +msg-c79b2c75 = 命名空间 '{ $namespace }已存在。设置 replace=True 以覆盖。 +msg-7db3fccf = 默认命名空间无法注销。 +msg-3d066f64 = 命名空间 '{ $namespace }未注册。 ### astrbot/core/persona_mgr.py -msg-51a854e6 = 已加载 {$res} 个人格。 -msg-1ea88f45 = Persona with ID {$persona_id} does not exist. -msg-28104dff = Persona with ID {$persona_id} already exists. -msg-08ecfd42 = {$res} 人格情景预设对话格式不对,条数应该为偶数。 -msg-b6292b94 = 解析 Persona 配置失败:{$e} + +msg-51a854e6 = 已加载{ $res }Personality. +msg-1ea88f45 = ID 为 {$id} 的角色{ $persona_id }不存在。 +msg-28104dff = ID为{$id}的角色{ $persona_id }已存在。 +msg-08ecfd42 = { $res }The format for the personality scenario preset dialogue is incorrect; the number of entries must be even. +msg-b6292b94 = 解析 Persona 配置失败:{ $e } ### astrbot/core/initial_loader.py -msg-78b9c276 = {$res} -msg-58525c23 = 😭 初始化 AstrBot 失败:{$e} !!! + +msg-78b9c276 = { $res } +msg-58525c23 = 😭 初始化 AstrBot 失败:{ $e }!!! msg-002cc3e8 = 🌈 正在关闭 AstrBot... ### astrbot/core/log.py -msg-80a186b8 = Failed to add file sink: {$e} + +msg-80a186b8 = 添加文件接收器失败:{ $e } ### astrbot/core/astrbot_config_mgr.py -msg-7875e5bd = Config file {$conf_path} for UUID {$uuid_} does not exist, skipping. + +msg-7875e5bd = 配置文件{ $conf_path }用于 UUID{ $uuid_ }不存在,跳过。 msg-39c4fd49 = 不能删除默认配置文件 -msg-cf7b8991 = 配置文件 {$conf_id} 不存在于映射中 -msg-2aad13a4 = 已删除配置文件: {$conf_path} -msg-94c359ef = 删除配置文件 {$conf_path} 失败: {$e} -msg-44f0b770 = 成功删除配置文件 {$conf_id} -msg-737da44e = 不能更新默认配置文件的信息 -msg-9d496709 = 成功更新配置文件 {$conf_id} 的信息 +msg-cf7b8991 = Configuration File{ $conf_id }不存在于映射中 +msg-2aad13a4 = 已删除配置文件:{ $conf_path } +msg-94c359ef = 删除配置文件{ $conf_path }失败:{ $e } +msg-44f0b770 = 成功删除配置文件{ $conf_id } +msg-737da44e = 无法更新默认配置文件的信息 +msg-9d496709 = 成功更新配置文件{ $conf_id }的信息 ### astrbot/core/zip_updator.py -msg-24c90ff8 = 请求 {$url} 失败,状态码: {$res}, 内容: {$text} -msg-14726dd8 = 请求失败,状态码: {$res} -msg-fc3793c6 = 解析版本信息时发生异常: {$e} + +msg-24c90ff8 = Request{ $url }失败,状态码:{ $res }, 内容:{ $text } +msg-14726dd8 = Request failed, status code:{ $res } +msg-fc3793c6 = 解析版本信息时发生异常:{ $e } msg-491135d9 = 解析版本信息失败 -msg-03a72cb5 = 未找到合适的发布版本 -msg-8bcbfcf0 = 正在下载更新 {$repo} ... -msg-ccc87294 = 正在从指定分支 {$branch} 下载 {$author}/{$repo} -msg-dfebcdc6 = 获取 {$author}/{$repo} 的 GitHub Releases 失败: {$e},将尝试下载默认分支 -msg-e327bc14 = 正在从默认分支下载 {$author}/{$repo} -msg-3cd3adfb = 检查到设置了镜像站,将使用镜像站下载 {$author}/{$repo} 仓库源码: {$release_url} +msg-03a72cb5 = No suitable release version found +msg-8bcbfcf0 = 正在下载更新{ $repo }待翻译文本: +msg-ccc87294 = 正在从指定分支{ $branch }下载{ $author }待翻译文本:{ $repo } +msg-dfebcdc6 = 获取{ $author }待翻译文本:{ $repo }的 GitHub Releases 失败:{ $e },将尝试下载默认分支 +msg-e327bc14 = 正在从默认分支下载{ $author }待翻译文本:{ $repo } +msg-3cd3adfb = 检查到设置了镜像站,将使用镜像站下载{ $author }待翻译文本:{ $repo }仓库源码:{ $release_url } msg-1bffc0d7 = 无效的 GitHub URL -msg-0ba954db = 解压文件完成: {$zip_path} -msg-90ae0d15 = 删除临时更新文件: {$zip_path} 和 {$res} -msg-f8a43aa5 = 删除更新文件失败,可以手动删除 {$zip_path} 和 {$res} +msg-0ba954db = 文件解压完成:{ $zip_path } +msg-90ae0d15 = 删除临时更新文件:{ $zip_path }和{ $res } +msg-f8a43aa5 = 删除更新文件失败,可以手动删除{ $zip_path }and{ $res } ### astrbot/core/file_token_service.py -msg-0e444e51 = 文件不存在: {$local_path} (原始输入: {$file_path}) -msg-f61a5322 = 无效或过期的文件 token: {$file_token} -msg-73d3e179 = 文件不存在: {$file_path} + +msg-0e444e51 = 文件不存在:{ $local_path }原始输入:{ $file_path }) +msg-f61a5322 = 无效或过期的文件令牌:{ $file_token } +msg-73d3e179 = 文件不存在:{ $file_path } ### astrbot/core/subagent_orchestrator.py -msg-5d950986 = subagent_orchestrator.agents must be a list -msg-29e3b482 = SubAgent persona %s not found, fallback to inline prompt. -msg-f425c9f0 = Registered subagent handoff tool: {$res} + +msg-5d950986 = subagent_orchestrator.agents 必须是一个列表 +msg-29e3b482 = 子代理角色 %s 未找到,回退到内联提示。 +msg-f425c9f0 = 已注册的子代理转交工具:{ $res } ### astrbot/core/astr_main_agent.py + msg-8dcf5caa = 未找到指定的提供商: %s。 msg-61d46ee5 = 选择的提供商类型无效(%s),跳过 LLM 请求处理。 -msg-496864bc = Error occurred while selecting provider: %s +msg-496864bc = 选择提供商时发生错误:%s msg-507853eb = 无法创建新的对话。 -msg-66870b7e = Error occurred while retrieving knowledge base: %s -msg-36dc1409 = Moonshot AI API key for file extract is not set -msg-8534047e = Unsupported file extract provider: %s -msg-f2ea29f4 = Cannot get image caption because provider `{$provider_id}` is not exist. -msg-91a70615 = Cannot get image caption because provider `{$provider_id}` is not a valid Provider, it is {$res}. -msg-b1840df0 = Processing image caption with provider: %s +msg-66870b7e = 检索知识库时发生错误:%s +msg-36dc1409 = 文件提取的Moonshot AI API密钥未设置 +msg-8534047e = 不支持的文件提取提供程序:%s +msg-f2ea29f4 = 无法获取图片描述,因为提供商 `{ $provider_id }不存在。 +msg-91a70615 = 无法获取图片标题,因为提供者 `{ $provider_id }` 不是有效的 Provider,它是{ $res }. +msg-b1840df0 = 正在使用提供程序处理图片说明:%s msg-089421fc = 处理图片描述失败: %s -msg-719d5e4d = No provider found for image captioning in quote. +msg-719d5e4d = 引用中未找到图像说明提供程序。 msg-e16a974b = 处理引用图片失败: %s -msg-037dad2e = Group name display enabled but group object is None. Group ID: %s +msg-037dad2e = 组名显示已启用但组对象为空。组ID:%s msg-58b47bcd = 时区设置错误: %s, 使用本地时区 -msg-938af433 = Provider %s does not support image, using placeholder. -msg-83d739f8 = Provider %s does not support tool_use, clearing tools. -msg-3dbad2d9 = sanitize_context_by_modalities applied: removed_image_blocks=%s, removed_tool_messages=%s, removed_tool_calls=%s -msg-4214b760 = Generated chatui title for session %s: %s -msg-cb6db56e = Unsupported llm_safety_mode strategy: %s. -msg-7ea2c5d3 = Shipyard sandbox configuration is incomplete. +msg-938af433 = 提供者 %s 不支持图片,使用占位符。 +msg-83d739f8 = 提供商 %s 不支持工具使用,正在清除工具。 +msg-3dbad2d9 = sanitize_context_by_modalities 已应用:已移除图像块=%s,已移除工具消息=%s,已移除工具调用=%s +msg-4214b760 = 为会话 %s 生成的聊天界面标题:%s +msg-cb6db56e = 不支持的llm_safety_mode策略:%s。 +msg-7ea2c5d3 = Shipyard 沙箱配置不完整。 msg-9248b273 = 未找到指定的上下文压缩模型 %s,将跳过压缩。 msg-16fe8ea5 = 指定的上下文压缩模型 %s 不是对话模型,将跳过压缩。 -msg-c6c9d989 = fallback_chat_models setting is not a list, skip fallback providers. -msg-614aebad = Fallback chat provider `%s` not found, skip. -msg-1a2e87dd = Fallback chat provider `%s` is invalid type: %s, skip. +msg-c6c9d989 = fallback_chat_models 设置不是列表,跳过备用提供程序。 +msg-614aebad = 备用聊天提供商 `%s` 未找到,已跳过。 +msg-1a2e87dd = 备用聊天提供商 `%s` 的类型无效:%s,跳过。 msg-ee979399 = 未找到任何对话模型(提供商),跳过 LLM 请求处理。 -msg-7a7b4529 = Skip quoted fallback images due to limit=%d for umo=%s -msg-46bcda31 = Truncate quoted fallback images for umo=%s, reply_id=%s from %d to %d -msg-cbceb923 = Failed to resolve fallback quoted images for umo=%s, reply_id=%s: %s -msg-31483e80 = Error occurred while applying file extract: %s +msg-7a7b4529 = 由于限制=%d 对于umo=%s,跳过引用的备用图像 +msg-46bcda31 = 截断引用回退图片,用户消息对象=%s,回复ID=%s,从 %d 到 %d +msg-cbceb923 = 无法解析回退引用图片,用户消息对象=%s,回复ID=%s:%s +msg-31483e80 = 应用文件提取时发生错误:%s ### astrbot/core/umop_config_router.py -msg-dedcfded = umop keys must be strings in the format [platform_id]:[message_type]:[session_id], with optional wildcards * or empty for all -msg-8e3a16f3 = umop must be a string in the format [platform_id]:[message_type]:[session_id], with optional wildcards * or empty for all + +msg-dedcfded = umop 键必须是格式为 [platform_id]:[message_type]:[session_id] 的字符串,其中可选通配符 * 或留空表示全部 +msg-8e3a16f3 = umop 必须是格式为 [platform_id]:[message_type]:[session_id] 的字符串,其中可选通配符 * 或留空表示全部 ### astrbot/core/event_bus.py -msg-da466871 = PipelineScheduler not found for id: {$res}, event ignored. -msg-7eccffa5 = [{$conf_name}] [{$res}({$res_2})] {$res_3}/{$res_4}: {$res_5} -msg-88bc26f2 = [{$conf_name}] [{$res}({$res_2})] {$res_3}: {$res_4} + +msg-da466871 = 找不到ID为以下值的PipelineScheduler:{ $res },事件被忽略。 +msg-7eccffa5 = { $conf_name }] [{ $res }待翻译文本:{ $res_2 })]{ $res_3 }/{ $res_4 }待翻译文本:{ $res_5 } +msg-88bc26f2 = [{ $conf_name }] [{ $res }待翻译文本:{ $res_2 })]{ $res_3 }:{ $res_4 } ### astrbot/core/astr_agent_tool_exec.py -msg-e5f2fb34 = Background task {$task_id} failed: {$e} -msg-c54b2335 = Background handoff {$task_id} ({$res}) failed: {$e} -msg-8c2fe51d = Failed to build main agent for background task {$tool_name}. -msg-c6d4e4a6 = background task agent got no response -msg-0b3711f1 = Event must be provided for local function tools. -msg-8c19e27a = Tool must have a valid handler or override 'run' method. -msg-24053a5f = Tool 直接发送消息失败: {$e} -msg-f940b51e = tool {$res} execution timeout after {$res_2} seconds. -msg-7e22fc8e = 未知的方法名: {$method_name} -msg-c285315c = Tool execution ValueError: {$e} -msg-41366b74 = Tool handler parameter mismatch, please check the handler definition. Handler parameters: {$handler_param_str} -msg-e8cadf8e = Tool execution error: {$e}. Traceback: {$trace_} -msg-d7b4aa84 = Previous Error: {$trace_} + +msg-e5f2fb34 = 后台任务{ $task_id }失败:{ $e } +msg-c54b2335 = 后台交接{ $task_id }待翻译文本:{ $res }) 失败:{ $e } +msg-8c2fe51d = 构建后台任务主代理失败{ $tool_name }. +msg-c6d4e4a6 = 后台任务代理未收到响应 +msg-0b3711f1 = 必须为本地函数工具提供事件。 +msg-8c19e27a = 工具必须有一个有效的处理器或重写“运行”方法。 +msg-24053a5f = 工具直接发送消息失败:{ $e } +msg-f940b51e = 工具{ $res }执行超时后{ $res_2 }秒。 +msg-7e22fc8e = 未知的方法名:{ $method_name } +msg-c285315c = 工具执行值错误:{ $e } +msg-41366b74 = 工具处理器参数不匹配,请检查处理器定义。处理器参数:{ $handler_param_str } +msg-e8cadf8e = 工具执行错误:{ $e }. 回溯追踪:{ $trace_ } +msg-d7b4aa84 = 上一个错误:{ $trace_ } ### astrbot/core/astr_agent_run_util.py -msg-6b326889 = Agent reached max steps ({$max_step}), forcing a final response. -msg-bb15e9c7 = {$status_msg} -msg-78b9c276 = {$res} -msg-9c246298 = Error in on_agent_done hook -msg-34f164d4 = {$err_msg} + +msg-6b326889 = 代理达到最大步数限制({ $max_step }),强制最终响应。 +msg-bb15e9c7 = { $status_msg } +msg-78b9c276 = { $res } +msg-9c246298 = on_agent_done 钩子中的错误 +msg-34f164d4 = { $err_msg } msg-6d9553b2 = [Live Agent] 使用流式 TTS(原生支持 get_audio_stream) -msg-becf71bf = [Live Agent] 使用 TTS({$res} 使用 get_audio,将按句子分块生成音频) -msg-21723afb = [Live Agent] 运行时发生错误: {$e} -msg-ca1bf0d7 = 发送 TTS 统计信息失败: {$e} -msg-5ace3d96 = [Live Agent Feeder] 分句: {$temp_buffer} -msg-bc1826ea = [Live Agent Feeder] Error: {$e} -msg-a92774c9 = [Live TTS Stream] Error: {$e} -msg-d7b3bbae = [Live TTS Simulated] Error processing text '{$res}...': {$e} -msg-035bca5f = [Live TTS Simulated] Critical Error: {$e} +msg-becf71bf = [Live Agent] 使用 TTS({ $res }使用 get_audio,将按句子分块生成音频) +msg-21723afb = [Live Agent] 运行时发生错误:{ $e } +msg-ca1bf0d7 = Failed to send TTS statistics:{ $e } +msg-5ace3d96 = [实时客服信息推送] 分句:{ $temp_buffer } +msg-bc1826ea = [在线客服信息推送器] 错误:{ $e } +msg-a92774c9 = [实时TTS流] 错误:{ $e } +msg-d7b3bbae = [实时TTS模拟] 处理文本时出错 '{ $res }...'{ $e } +msg-035bca5f = [实时TTS模拟] 严重错误:{ $e } ### astrbot/core/astr_main_agent_resources.py -msg-509829d8 = Downloaded file from sandbox: {$path} -> {$local_path} -msg-b462b60d = Failed to check/download file from sandbox: {$e} -msg-0b3144f1 = [知识库] 会话 {$umo} 已被配置为不使用知识库 -msg-97e13f98 = [知识库] 知识库不存在或未加载: {$kb_id} -msg-312d09c7 = [知识库] 会话 {$umo} 配置的以下知识库无效: {$invalid_kb_ids} -msg-42b0e9f8 = [知识库] 使用会话级配置,知识库数量: {$res} -msg-08167007 = [知识库] 使用全局配置,知识库数量: {$res} -msg-a00becc3 = [知识库] 开始检索知识库,数量: {$res}, top_k={$top_k} -msg-199e71b7 = [知识库] 为会话 {$umo} 注入了 {$res} 条相关知识块 + +msg-509829d8 = 从沙盒下载的文件:{ $path }->{ $local_path } +msg-b462b60d = 无法从沙盒中检查/下载文件:{ $e } +msg-0b3144f1 = [知识库] 会话{ $umo }已被配置为不使用知识库 +msg-97e13f98 = [知识库] 知识库不存在或未加载:{ $kb_id } +msg-312d09c7 = [知识库] 会话{ $umo }配置的以下知识库无效:{ $invalid_kb_ids } +msg-42b0e9f8 = [知识库] 使用会话级配置,知识库数量:{ $res } +msg-08167007 = [知识库] 使用全局配置,知识库数量:{ $res } +msg-a00becc3 = [知识库] 开始检索知识库,数量:{ $res }top_k={ $top_k } +msg-199e71b7 = [知识库] 为会话{ $umo }已注入{ $res }条相关知识块 ### astrbot/core/conversation_mgr.py -msg-86f404dd = 会话删除回调执行失败 (session: {$unified_msg_origin}): {$e} -msg-57dcc41f = Conversation with id {$cid} not found + +msg-86f404dd = 会话删除回调执行失败 (session:{ $unified_msg_origin }):{ $e } +msg-57dcc41f = 对话 ID{ $cid }未找到 ### astrbot/core/updator.py -msg-e3d42a3b = 正在终止 {$res} 个子进程。 -msg-e7edc4a4 = 正在终止子进程 {$res} -msg-37bea42d = 子进程 {$res} 没有被正常终止, 正在强行杀死。 -msg-cc6d9588 = 重启失败({$executable}, {$e}),请尝试手动重启。 -msg-0e4439d8 = 不支持更新此方式启动的AstrBot + +msg-e3d42a3b = 正在终止{ $res }子进程。 +msg-e7edc4a4 = 正在终止子进程{ $res } +msg-37bea42d = Child process{ $res }没有被正常终止, 正在强行杀死。 +msg-cc6d9588 = Restart Failed{ $executable },{ $e }),请尝试手动重启。 +msg-0e4439d8 = Does not support updating AstrBot started in this manner. msg-3f39a942 = 当前已经是最新版本。 -msg-c7bdf215 = 未找到版本号为 {$version} 的更新文件。 +msg-c7bdf215 = 未找到版本号为{ $version }的更新文件。 msg-92e46ecc = commit hash 长度不正确,应为 40 -msg-71c01b1c = 准备更新至指定版本的 AstrBot Core: {$version} +msg-71c01b1c = 准备更新至指定版本的 AstrBot Core:{ $version } msg-d3a0e13d = 下载 AstrBot Core 更新文件完成,正在执行解压... ### astrbot/core/core_lifecycle.py -msg-9967ec8b = Using proxy: {$proxy_config} -msg-5a29b73d = HTTP proxy cleared -msg-fafb87ce = Subagent orchestrator init failed: {$e} -msg-f7861f86 = AstrBot migration failed: {$e} -msg-78b9c276 = {$res} -msg-967606fd = ------- 任务 {$res} 发生错误: {$e} -msg-a2cd77f3 = | {$line} -msg-1f686eeb = ------- + +msg-9967ec8b = 正在使用代理:{ $proxy_config } +msg-5a29b73d = HTTP 代理已清除 +msg-fafb87ce = 子代理编排器初始化失败:{ $e } +msg-f7861f86 = AstrBot 迁移失败:{ $e } +msg-78b9c276 = { $res } +msg-967606fd = 任务{ $res }发生错误:{ $e } +msg-a2cd77f3 = 待翻译文本:{ $line } +msg-1f686eeb = 待翻译文本: msg-9556d279 = AstrBot 启动完成。 -msg-daaf690b = hook(on_astrbot_loaded) -> {$res} - {$res_2} -msg-4719cb33 = 插件 {$res} 未被正常终止 {$e}, 可能会导致资源泄露等问题。 -msg-c3bbfa1d = 任务 {$res} 发生错误: {$e} -msg-af06ccab = 配置文件 {$conf_id} 不存在 +msg-daaf690b = 钩子(on_astrbot_已加载) ->{ $res }-{ $res_2 } +msg-4719cb33 = 插件{ $res }Not properly terminated{ $e }, 可能会导致资源泄露等问题。 +msg-c3bbfa1d = 任务{ $res }发生错误:{ $e } +msg-af06ccab = 配置文件{ $conf_id }不存在 ### astrbot/core/pipeline/context_utils.py + msg-49f260d3 = 处理函数参数不匹配,请检查 handler 的定义。 -msg-d7b4aa84 = Previous Error: {$trace_} -msg-eb8619cb = hook({$res}) -> {$res_2} - {$res_3} -msg-78b9c276 = {$res} -msg-add19f94 = {$res} - {$res_2} 终止了事件传播。 +msg-d7b4aa84 = Previous Error:{ $trace_ } +msg-eb8619cb = 挂钩{ $res }) ->{ $res_2 }-{ $res_3 } +msg-78b9c276 = { $res } +msg-add19f94 = { $res }-{ $res_2 }终止了事件传播。 ### astrbot/core/pipeline/__init__.py -msg-1c9fc93d = module {$__name__} has no attribute {$name} + ### astrbot/core/pipeline/scheduler.py -msg-c240d574 = 阶段 {$res} 已终止事件传播。 + +msg-c240d574 = 阶段{ $res }Event propagation has been terminated. msg-609a1ac5 = pipeline 执行完毕。 ### astrbot/core/pipeline/rate_limit_check/stage.py -msg-18092978 = 会话 {$session_id} 被限流。根据限流策略,此会话处理将被暂停 {$stall_duration} 秒。 -msg-4962387a = 会话 {$session_id} 被限流。根据限流策略,此请求已被丢弃,直到限额于 {$stall_duration} 秒后重置。 + +msg-18092978 = 会话{ $session_id }被限流。根据限流策略,此会话处理将被暂停{ $stall_duration }秒 +msg-4962387a = 会话{ $session_id }被限流。根据限流策略,此请求已被丢弃,直到限额于{ $stall_duration }秒后重置。 ### astrbot/core/pipeline/whitelist_check/stage.py -msg-8282c664 = 会话 ID {$res} 不在会话白名单中,已终止事件传播。请在配置文件中添加该会话 ID 到白名单。 + +msg-8282c664 = 会话 ID{ $res }不在会话白名单中,已终止事件传播。请在配置文件中添加该会话 ID 到白名单。 ### astrbot/core/pipeline/process_stage/follow_up.py -msg-df881b01 = Captured follow-up message for active agent run, umo=%s, order_seq=%s + +msg-df881b01 = 已捕获活动代理运行的后续消息,用户消息对象=%s,订单序列=%s ### astrbot/core/pipeline/process_stage/method/agent_request.py -msg-3267978a = 识别 LLM 聊天额外唤醒前缀 {$res} 以机器人唤醒前缀 {$bwp} 开头,已自动去除。 -msg-97a4d573 = This pipeline does not enable AI capability, skip processing. -msg-f1a11d2b = The session {$res} has disabled AI capability, skipping processing. + +msg-3267978a = 识别 LLM 聊天额外唤醒前缀{ $res }以机器人唤醒前缀{ $bwp }开头,已自动去除。 +msg-97a4d573 = 此流水线未启用AI功能,跳过处理。 +msg-f1a11d2b = 会话{ $res }已禁用AI功能,跳过处理。 ### astrbot/core/pipeline/process_stage/method/star_request.py -msg-f0144031 = Cannot find plugin for given handler module path: {$res} -msg-1e8939dd = plugin -> {$res} - {$res_2} -msg-6be73b5e = {$traceback_text} -msg-d919bd27 = Star {$res} handle error: {$e} -msg-ed8dcc22 = {$ret} + +msg-f0144031 = 无法找到给定处理器模块路径的插件:{ $res } +msg-1e8939dd = 插件 ->{ $res }-{ $res_2 } +msg-6be73b5e = { $traceback_text } +msg-d919bd27 = Star{ $res }处理错误:{ $e } +msg-ed8dcc22 = { $ret } ### astrbot/core/pipeline/process_stage/method/agent_sub_stages/internal.py -msg-60493581 = Unsupported tool_schema_mode: %s, fallback to skills_like -msg-9cdb2b6e = skip llm request: empty message and no provider_request -msg-e461e5af = ready to request llm provider -msg-be33dd11 = Follow-up ticket already consumed, stopping processing. umo=%s, seq=%s -msg-abd5ccbc = acquired session lock for llm request -msg-f9d617d7 = Provider API base %s is blocked due to security reasons. Please use another ai provider. -msg-3247374d = [Internal Agent] 检测到 Live Mode,启用 TTS 处理 + +msg-60493581 = 不支持的工具模式:%s,回退到类似技能模式 +msg-9cdb2b6e = 跳过 LLM 请求:消息为空且无 provider_request +msg-e461e5af = 准备请求LLM提供商 +msg-be33dd11 = 后续工单已被消耗,停止处理。umo=%s, seq=%s +msg-abd5ccbc = 已为LLM请求获取会话锁 +msg-f9d617d7 = 由于安全原因,提供者API基础%s已被阻止。请使用其他AI提供者。 +msg-3247374d = [内部代理] 检测到 Live Mode,启用 TTS 处理 msg-dae92399 = [Live Mode] TTS Provider 未配置,将使用普通流式模式 -msg-1b1af61e = Error occurred while processing agent: {$e} -msg-ea02b899 = Error occurred while processing agent request: {$e} +msg-1b1af61e = 处理代理时发生错误:{ $e } +msg-ea02b899 = 处理代理请求时发生错误:{ $e } msg-ee7e792b = LLM 响应为空,不保存记录。 ### astrbot/core/pipeline/process_stage/method/agent_sub_stages/third_party.py -msg-5e551baf = Third party agent runner error: {$e} -msg-34f164d4 = {$err_msg} + +msg-5e551baf = 第三方代理运行器错误:{ $e } +msg-34f164d4 = { $err_msg } msg-f9d76893 = 没有填写 Agent Runner 提供商 ID,请前往配置页面配置。 -msg-0f856470 = Agent Runner 提供商 {$res} 配置不存在,请前往配置页面修改配置。 -msg-b3f25c81 = Unsupported third party agent runner type: {$res} +msg-0f856470 = Agent Runner 提供商{ $res }配置不存在,请前往配置页面修改配置。 +msg-b3f25c81 = 不支持第三方代理运行器类型:{ $res } msg-6c63eb68 = Agent Runner 未返回最终结果。 ### astrbot/core/pipeline/result_decorate/stage.py -msg-7ec898fd = hook(on_decorating_result) -> {$res} - {$res_2} + +msg-7ec898fd = hook(on_decorating_result) ->{ $res }-{ $res_2 } msg-5e27dae6 = 启用流式输出时,依赖发送消息前事件钩子的插件可能无法正常工作 -msg-caaaec29 = hook(on_decorating_result) -> {$res} - {$res_2} 将消息结果清空。 -msg-78b9c276 = {$res} -msg-add19f94 = {$res} - {$res_2} 终止了事件传播。 -msg-813a44bb = 流式输出已启用,跳过结果装饰阶段 -msg-891aa43a = 分段回复正则表达式错误,使用默认分段方式: {$res} -msg-82bb9025 = 会话 {$res} 未配置文本转语音模型。 -msg-fb1c757a = TTS 请求: {$res} -msg-06341d25 = TTS 结果: {$audio_path} -msg-2057f670 = 由于 TTS 音频文件未找到,消息段转语音失败: {$res} -msg-f26725cf = 已注册:{$url} +msg-caaaec29 = hook(on_decorating_result) ->{ $res }-{ $res_2 }Clear message results. +msg-78b9c276 = { $res } +msg-add19f94 = { $res }-{ $res_2 }Stopped event propagation. +msg-813a44bb = Streaming output enabled, skipping result decoration stage. +msg-891aa43a = Segment reply regex error, using default segmentation method:{ $res } +msg-82bb9025 = Session{ $res }未配置文本转语音模型。 +msg-fb1c757a = TTS 请求:{ $res } +msg-06341d25 = TTS 结果:{ $audio_path } +msg-2057f670 = 由于 TTS 音频文件未找到,消息段转语音失败:{ $res } +msg-f26725cf = 已注册:{ $url } msg-47716aec = TTS 失败,使用文本发送。 msg-ffe054a9 = 文本转图片失败,使用文本发送。 msg-06c1aedc = 文本转图片耗时超过了 3 秒,如果觉得很慢可以使用 /t2i 关闭文本转图片模式。 ### astrbot/core/pipeline/waking_check/stage.py -msg-df815938 = enabled_plugins_name: {$enabled_plugins_name} -msg-51182733 = 插件 {$res}: {$e} -msg-e0dcf0b8 = 您(ID: {$res})的权限不足以使用此指令。通过 /sid 获取 ID 并请管理员添加。 -msg-a3c3706f = 触发 {$res} 时, 用户(ID={$res_2}) 权限不足。 + +msg-df815938 = 已启用插件名称:{ $enabled_plugins_name } +msg-51182733 = 插件{ $res }待翻译文本:{ $e } +msg-e0dcf0b8 = 您的ID:{ $res }) 的权限不足以使用此指令。通过 /sid 获取 ID 并请管理员添加。 +msg-a3c3706f = Trigger{ $res }当用户(ID={ $res_2 }权限不足。 ### astrbot/core/pipeline/session_status_check/stage.py -msg-f9aba737 = 会话 {$res} 已被关闭,已终止事件传播。 + +msg-f9aba737 = Session{ $res }已关闭,已停止事件传播。 ### astrbot/core/pipeline/respond/stage.py -msg-59539c6e = 解析分段回复的间隔时间失败。{$e} -msg-4ddee754 = 分段回复间隔时间:{$res} -msg-5e2371a9 = Prepare to send - {$res}/{$res_2}: {$res_3} + +msg-59539c6e = 解析分段回复的间隔时间失败。{ $e } +msg-4ddee754 = Segment response interval:{ $res } +msg-5e2371a9 = 准备发送 -{ $res }/{ $res_2 }待翻译文本:{ $res_3 } msg-df92ac24 = async_stream 为空,跳过发送。 -msg-858b0e4f = 应用流式输出({$res}) +msg-858b0e4f = 应用流式输出{ $res }) msg-22c7a672 = 消息为空,跳过发送阶段 -msg-e6ab7a25 = 空内容检查异常: {$e} -msg-b29b99c1 = 实际消息链为空, 跳过发送阶段。header_chain: {$header_comps}, actual_chain: {$res} -msg-842df577 = 发送消息链失败: chain = {$res}, error = {$e} -msg-f35465cf = 消息链全为 Reply 和 At 消息段, 跳过发送阶段。chain: {$res} -msg-784e8a67 = 发送消息链失败: chain = {$chain}, error = {$e} +msg-e6ab7a25 = 空内容检查异常:{ $e } +msg-b29b99c1 = 实际消息链为空,跳过发送阶段。header_chain:{ $header_comps },实际链:{ $res } +msg-842df577 = 发送消息链失败: chain ={ $res }, error ={ $e } +msg-f35465cf = 消息链全为Reply和At消息段,跳过发送阶段。chain:{ $res } +msg-784e8a67 = 发送消息链失败: chain ={ $chain },错误 ={ $e } ### astrbot/core/pipeline/content_safety_check/stage.py -msg-c733275f = 你的消息或者大模型的响应中包含不适当的内容,已被屏蔽。 -msg-46c80f28 = 内容安全检查不通过,原因:{$info} + +msg-c733275f = 您的消息或大模型的回复中包含不适当的内容,已被屏蔽。 +msg-46c80f28 = 内容安全检查不通过,原因:{ $info } ### astrbot/core/pipeline/content_safety_check/strategies/strategy.py + msg-27a700e0 = 使用百度内容审核应该先 pip install baidu-aip ### astrbot/core/pipeline/preprocess_stage/stage.py -msg-7b9074fa = {$platform} 预回应表情发送失败: {$e} -msg-43f1b4ed = 路径映射: {$url} -> {$res} -msg-9549187d = 会话 {$res} 未配置语音转文本模型。 -msg-5bdf8f5c = {$e} -msg-ad90e19e = 重试中: {$res}/{$retry} -msg-78b9c276 = {$res} -msg-4f3245bf = 语音转文本失败: {$e} + +msg-7b9074fa = { $platform }Pre-reply emoji sending failed:{ $e } +msg-43f1b4ed = Path mapping:{ $url }->{ $res } +msg-9549187d = 会话{ $res }未配置语音转文本模型。 +msg-5bdf8f5c = { $e } +msg-ad90e19e = 重试中:{ $res }/{ $retry } +msg-78b9c276 = { $res } +msg-4f3245bf = Speech-to-text conversion failed:{ $e } ### astrbot/core/config/astrbot_config.py -msg-e0a69978 = 不受支持的配置类型 {$res}。支持的类型有:{$res_2} -msg-b9583fc9 = 检查到配置项 {$path_} 不存在,已插入默认值 {$value} -msg-ee26e40e = 检查到配置项 {$path_} 不存在,将从当前配置中删除 -msg-2d7497a5 = 检查到配置项 {$path} 的子项顺序不一致,已重新排序 + +msg-e0a69978 = Unsupported configuration type{ $res }支持的类型有:{ $res_2 } +msg-b9583fc9 = 检查到配置项{ $path_ }不存在,已插入默认值{ $value } +msg-ee26e40e = 检查到配置项{ $path_ }不存在,将从当前配置中删除 +msg-2d7497a5 = 检查到配置项{ $path }Child item order inconsistent, reordered. msg-5fdad937 = 检查到配置项顺序不一致,已重新排序 -msg-555373b0 = 没有找到 Key: '{$key}' +msg-555373b0 = 未找到 Key: '{ $key }待翻译文本: ### astrbot/core/platform/register.py -msg-eecf0aa8 = 平台适配器 {$adapter_name} 已经注册过了,可能发生了适配器命名冲突。 -msg-614a55eb = 平台适配器 {$adapter_name} 已注册 -msg-bb06a88d = 平台适配器 {$res} 已注销 (来自模块 {$res_2}) + +msg-eecf0aa8 = 平台适配器{ $adapter_name }已经注册过了,可能发生了适配器命名冲突。 +msg-614a55eb = Platform Adapter{ $adapter_name }已注册 +msg-bb06a88d = Platform Adapter{ $res }已注销 (来自模块{ $res_2 }) ### astrbot/core/platform/platform.py -msg-30fc9871 = 平台 {$res} 未实现统一 Webhook 模式 + +msg-30fc9871 = 平台{ $res }未实现统一 Webhook 模式 ### astrbot/core/platform/astr_message_event.py -msg-b593f13f = Failed to convert message type {$res} to MessageType. Falling back to FRIEND_MESSAGE. -msg-98bb33b7 = 清除 {$res} 的额外信息: {$res_2} -msg-0def44e2 = {$result} -msg-8e7dc862 = {$text} + +msg-b593f13f = 无法转换消息类型{ $res }回退到FRIEND_MESSAGE。 +msg-98bb33b7 = 清除{ $res }Additional information:{ $res_2 } +msg-0def44e2 = { $result } +msg-8e7dc862 = { $text } ### astrbot/core/platform/manager.py + msg-464b7ab7 = 终止平台适配器失败: client_id=%s, error=%s -msg-78b9c276 = {$res} -msg-563a0a74 = 初始化 {$platform} 平台适配器失败: {$e} +msg-78b9c276 = { $res } +msg-563a0a74 = 初始化{ $platform }Platform adapter failed:{ $e } msg-8432d24e = 平台 ID %r 包含非法字符 ':' 或 '!',已替换为 %r。 -msg-31361418 = 平台 ID {$platform_id} 不能为空,跳过加载该平台适配器。 -msg-e395bbcc = 载入 {$res}({$res_2}) 平台适配器 ... -msg-b4b29344 = 加载平台适配器 {$res} 失败,原因:{$e}。请检查依赖库是否安装。提示:可以在 管理面板->平台日志->安装Pip库 中安装依赖库。 -msg-18f0e1fe = 加载平台适配器 {$res} 失败,原因:{$e}。 -msg-2636a882 = 未找到适用于 {$res}({$res_2}) 平台适配器,请检查是否已经安装或者名称填写错误 -msg-c4a38b85 = hook(on_platform_loaded) -> {$res} - {$res_2} -msg-967606fd = ------- 任务 {$res} 发生错误: {$e} -msg-a2cd77f3 = | {$line} +msg-31361418 = 平台 ID{ $platform_id }不能为空,跳过加载该平台适配器。 +msg-e395bbcc = Loading{ $res }待翻译文本:{ $res_2 }) 平台适配器 ... +msg-b4b29344 = 加载平台适配器{ $res }失败,原因:{ $e }请检查依赖库是否安装。提示:可以在 管理面板->平台日志->安装Pip库 中安装依赖库。 +msg-18f0e1fe = Loading platform adapters{ $res }Failed, reason:{ $e }待翻译文本: +msg-2636a882 = 未找到适用于{ $res }待翻译文本:{ $res_2 }) 平台适配器,请检查是否已经安装或者名称填写错误 +msg-c4a38b85 = 钩子(平台加载后) ->{ $res }-{ $res_2 } +msg-967606fd = 任务{ $res }发生错误:{ $e } +msg-a2cd77f3 = |{ $line } msg-1f686eeb = ------- -msg-38723ea8 = 正在尝试终止 {$platform_id} 平台适配器 ... -msg-63f684c6 = 可能未完全移除 {$platform_id} 平台适配器 -msg-136a952f = 获取平台统计信息失败: {$e} +msg-38723ea8 = 正在尝试终止{ $platform_id }平台适配器 ... +msg-63f684c6 = 可能未完全移除{ $platform_id }Platform Adapter +msg-136a952f = Failed to retrieve platform statistics:{ $e } ### astrbot/core/platform/sources/dingtalk/dingtalk_adapter.py + msg-c81e728d = 2 -msg-d6371313 = dingtalk: {$res} -msg-a1c8b5b1 = 钉钉私聊会话缺少 staff_id 映射,回退使用 session_id 作为 userId 发送 -msg-2abb842f = 保存钉钉会话映射失败: {$e} -msg-46988861 = 下载钉钉文件失败: {$res}, {$res_2} -msg-ba9e1288 = 通过 dingtalk_stream 获取 access_token 失败: {$e} -msg-835b1ce6 = 获取钉钉机器人 access_token 失败: {$res}, {$res_2} -msg-331fcb1f = 读取钉钉 staff_id 映射失败: {$e} +msg-d6371313 = 钉钉:{ $res } +msg-a1c8b5b1 = The DingTalk private chat session lacks staff_id mapping, falling back to using session_id as userId for sending. +msg-2abb842f = 保存钉钉会话映射失败:{ $e } +msg-46988861 = 下载钉钉文件失败:{ $res },{ $res_2 } +msg-ba9e1288 = Failed to obtain access_token via dingtalk_stream:{ $e } +msg-835b1ce6 = Failed to get DingTalk robot access token:{ $res },{ $res_2 } +msg-331fcb1f = 读取钉钉 staff_id 映射失败:{ $e } msg-ba183a34 = 钉钉群消息发送失败: access_token 为空 -msg-b8aaa69b = 钉钉群消息发送失败: {$res}, {$res_2} +msg-b8aaa69b = Failed to send DingTalk group message:{ $res },{ $res_2 } msg-cfb35bf5 = 钉钉私聊消息发送失败: access_token 为空 -msg-7553c219 = 钉钉私聊消息发送失败: {$res}, {$res_2} -msg-5ab2d58d = 清理临时文件失败: {$file_path}, {$e} -msg-c0c40912 = 钉钉语音转 OGG 失败,回退 AMR: {$e} +msg-7553c219 = 钉钉私聊消息发送失败:{ $res },{ $res_2 } +msg-5ab2d58d = Failed to clean temporary files:{ $file_path },{ $e } +msg-c0c40912 = 钉钉语音转OGG失败,回退至AMR格式:{ $e } msg-21c73eca = 钉钉媒体上传失败: access_token 为空 -msg-24e3054f = 钉钉媒体上传失败: {$res}, {$res_2} -msg-34d0a11d = 钉钉媒体上传失败: {$data} -msg-3b0d4fb5 = 钉钉语音发送失败: {$e} -msg-7187f424 = 钉钉视频发送失败: {$e} +msg-24e3054f = 钉钉媒体上传失败:{ $res }{ $res_2 } +msg-34d0a11d = 钉钉媒体上传失败:{ $data } +msg-3b0d4fb5 = 钉钉语音发送失败:{ $e } +msg-7187f424 = 钉钉视频发送失败:{ $e } msg-e40cc45f = 钉钉私聊回复失败: 缺少 sender_staff_id -msg-be63618a = 钉钉适配器已被关闭 -msg-0ab22b13 = 钉钉机器人启动失败: {$e} +msg-be63618a = The DingTalk adapter has been disabled. +msg-0ab22b13 = 钉钉机器人启动失败:{ $e } ### astrbot/core/platform/sources/dingtalk/dingtalk_event.py -msg-eaa1f3e4 = 钉钉消息发送失败: 缺少 adapter + +msg-eaa1f3e4 = 钉钉消息发送失败:缺少适配器 ### astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_server.py + msg-41a3e59d = 正在登录到 QQ 官方机器人... -msg-66040e15 = 已登录 QQ 官方机器人账号: {$res} -msg-6ed59b60 = 收到 qq_official_webhook 回调: {$msg} -msg-ad355b59 = {$signed} -msg-1f6260e4 = _parser unknown event %s. -msg-cef08b17 = 将在 {$res}:{$res_2} 端口启动 QQ 官方机器人 webhook 适配器。 +msg-66040e15 = 已登录 QQ 官方机器人账号:{ $res } +msg-6ed59b60 = 收到 qq_official_webhook 回调:{ $msg } +msg-ad355b59 = { $signed } +msg-1f6260e4 = _解析器未知事件 %s。 +msg-cef08b17 = 将在{ $res }待翻译文本:{ $res_2 }端口启动 QQ 官方机器人 webhook 适配器。 ### astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_adapter.py -msg-3803e307 = [QQOfficialWebhook] No cached msg_id for session: %s, skip send_by_session -msg-08fd28cf = [QQOfficialWebhook] Unsupported message type for send_by_session: %s -msg-6fa95bb3 = Exception occurred during QQOfficialWebhook server shutdown: {$exc} + +msg-3803e307 = [QQOfficialWebhook] 会话 %s 没有缓存的 msg_id,跳过 send_by_session +msg-08fd28cf = [QQOfficialWebhook] 通过会话发送消息时遇到不支持的消息类型:%s +msg-6fa95bb3 = QQ官方Web钩子服务器关闭期间发生异常:{ $exc } msg-6f83eea0 = QQ 机器人官方 API 适配器已经被优雅地关闭 ### astrbot/core/platform/sources/discord/discord_platform_event.py -msg-0056366b = [Discord] 解析消息链时失败: {$e} + +msg-0056366b = [Discord] 解析消息链时失败:{ $e } msg-fa0a9e40 = [Discord] 尝试发送空消息,已忽略。 -msg-5ccebf9a = [Discord] 频道 {$res} 不是可发送消息的类型 -msg-1550c1eb = [Discord] 发送消息时发生未知错误: {$e} -msg-7857133d = [Discord] 无法获取频道 {$res} -msg-050aa8d6 = [Discord] 开始处理 Image 组件: {$i} -msg-57c802ef = [Discord] Image 组件没有 file 属性: {$i} -msg-f2bea7ac = [Discord] 处理 URL 图片: {$file_content} -msg-c3eae1f1 = [Discord] 处理 File URI: {$file_content} -msg-6201da92 = [Discord] 图片文件不存在: {$path} +msg-5ccebf9a = [Discord] 频道{ $res }不是可发送消息的类型 +msg-1550c1eb = [Discord] 发送消息时发生未知错误:{ $e } +msg-7857133d = [Discord] 无法获取频道{ $res } +msg-050aa8d6 = [Discord] 开始处理 Image 组件:{ $i } +msg-57c802ef = [Discord] Image 组件缺少 file 属性:{ $i } +msg-f2bea7ac = [Discord] 处理 URL 图片:{ $file_content } +msg-c3eae1f1 = [Discord] 处理 File URI:{ $file_content } +msg-6201da92 = [Discord] 图片文件不存在:{ $path } msg-2a6f0cd4 = [Discord] 处理 Base64 URI msg-b589c643 = [Discord] 尝试作为裸 Base64 处理 -msg-41dd4b8f = [Discord] 裸 Base64 解码失败,作为本地路径处理: {$file_content} -msg-f59778a1 = [Discord] 处理图片时发生未知严重错误: {$file_info} -msg-85665612 = [Discord] 获取文件失败,路径不存在: {$file_path_str} -msg-e55956fb = [Discord] 获取文件失败: {$res} -msg-56cc0d48 = [Discord] 处理文件失败: {$res}, 错误: {$e} -msg-c0705d4e = [Discord] 忽略了不支持的消息组件: {$res} +msg-41dd4b8f = [Discord] 原始 Base64 解码失败,已作为本地路径处理:{ $file_content } +msg-f59778a1 = [Discord] 处理图片时发生未知严重错误:{ $file_info } +msg-85665612 = [Discord] 获取文件失败,路径不存在:{ $file_path_str } +msg-e55956fb = [Discord] 获取文件失败:{ $res } +msg-56cc0d48 = [Discord] 处理文件失败:{ $res }, 错误:{ $e } +msg-c0705d4e = [Discord] 忽略了不支持的消息组件:{ $res } msg-0417d127 = [Discord] 消息内容超过2000字符,将被截断。 -msg-6277510f = [Discord] 添加反应失败: {$e} +msg-6277510f = [Discord] 添加反应失败:{ $e } ### astrbot/core/platform/sources/discord/client.py + msg-940888cb = [Discord] 客户端未正确加载用户信息 (self.user is None) -msg-9a3c1925 = [Discord] 已作为 {$res} (ID: {$res_2}) 登录 +msg-9a3c1925 = [Discord] 已作为{ $res }(ID:{ $res_2 }) 登录 msg-30c1f1c8 = [Discord] 客户端已准备就绪。 -msg-d8c03bdf = [Discord] on_ready_once_callback 执行失败: {$e} -msg-c9601653 = Bot is not ready: self.user is None -msg-4b017a7c = Interaction received without a valid user -msg-3067bdce = [Discord] 收到原始消息 from {$res}: {$res_2} +msg-d8c03bdf = [Discord] on_ready_once_callback 执行失败:{ $e } +msg-c9601653 = Bot 未就绪:self.user 为 None +msg-4b017a7c = 收到无有效用户的交互 +msg-3067bdce = [Discord] 收到来自原始消息{ $res }待翻译文本:{ $res_2 } ### astrbot/core/platform/sources/discord/discord_platform_adapter.py + msg-7ea23347 = [Discord] 客户端未就绪 (self.client.user is None),无法发送消息 -msg-ff6611ce = [Discord] Invalid channel ID format: {$channel_id_str} -msg-5e4e5d63 = [Discord] Can't get channel info for {$channel_id_str}, will guess message type. -msg-32d4751b = [Discord] 收到消息: {$message_data} +msg-ff6611ce = [Discord] 频道ID格式无效:{ $channel_id_str } +msg-5e4e5d63 = [Discord] 无法获取频道信息{ $channel_id_str },将猜测消息类型。 +msg-32d4751b = [Discord] 收到消息:{ $message_data } msg-8296c994 = [Discord] Bot Token 未配置。请在配置文件中正确设置 token。 msg-170b31df = [Discord] 登录失败。请检查你的 Bot Token 是否正确。 msg-6678fbd3 = [Discord] 与 Discord 的连接已关闭。 -msg-cd8c35d2 = [Discord] 适配器运行时发生意外错误: {$e} -msg-4df30f1d = [Discord] 客户端未就绪 (self.client.user is None),无法处理消息 -msg-f7803502 = [Discord] 收到非 Message 类型的消息: {$res},已忽略。 -msg-134e70e9 = [Discord] 正在终止适配器... (step 1: cancel polling task) +msg-cd8c35d2 = [Discord] 适配器运行时发生意外错误:{ $e } +msg-4df30f1d = [Discord] 客户端未就绪 (self.client.user 为 None),无法处理消息 +msg-f7803502 = [Discord] 收到非 Message 类型的消息:{ $res }已忽略。 +msg-134e70e9 = [Discord] 正在终止适配器... (步骤 1:取消轮询任务) msg-5c01a092 = [Discord] polling_task 已取消。 -msg-77f8ca59 = [Discord] polling_task 取消异常: {$e} -msg-528b6618 = [Discord] 正在清理已注册的斜杠指令... (step 2) +msg-77f8ca59 = [Discord] 轮询任务取消异常:{ $e } +msg-528b6618 = [Discord] 正在清理已注册的斜杠指令... (步骤 2) msg-d0b832e6 = [Discord] 指令清理完成。 -msg-43383f5e = [Discord] 清理指令时发生错误: {$e} -msg-b960ed33 = [Discord] 正在关闭 Discord 客户端... (step 3) -msg-5e58f8a2 = [Discord] 客户端关闭异常: {$e} +msg-43383f5e = [Discord] 清理指令时发生错误:{ $e } +msg-b960ed33 = [Discord] 正在关闭 Discord 客户端... (步骤 3) +msg-5e58f8a2 = [Discord] 客户端关闭异常:{ $e } msg-d1271bf1 = [Discord] 适配器已终止。 msg-c374da7a = [Discord] 开始收集并注册斜杠指令... -msg-a6d37e4d = [Discord] 准备同步 {$res} 个指令: {$res_2} -msg-dbcaf095 = [Discord] 没有发现可注册的指令。 +msg-a6d37e4d = [Discord] 准备同步{ $res }个指令:{ $res_2 } +msg-dbcaf095 = [Discord] 未发现可注册的指令。 msg-09209f2f = [Discord] 指令同步完成。 -msg-a95055fd = [Discord] 回调函数触发: {$cmd_name} -msg-55b13b1e = [Discord] 回调函数参数: {$ctx} -msg-79f72e4e = [Discord] 回调函数参数: {$params} -msg-22add467 = [Discord] 斜杠指令 '{$cmd_name}' 被触发。 原始参数: '{$params}'. 构建的指令字符串: '{$message_str_for_filter}' -msg-ccffc74a = [Discord] 指令 '{$cmd_name}' defer 失败: {$e} -msg-13402a28 = [Discord] 跳过不符合规范的指令: {$cmd_name} +msg-a95055fd = [Discord] 回调函数触发:{ $cmd_name } +msg-55b13b1e = [Discord] 回调函数参数:{ $ctx } +msg-79f72e4e = [Discord] 回调函数参数:{ $params } +msg-22add467 = [Discord] 斜杠命令 '{ $cmd_name }被触发。 原始参数:{ $params }'. 构建的指令字符串: '{ $message_str_for_filter }待翻译文本: +msg-ccffc74a = [Discord] 指令 '{ $cmd_name }defer 失败:{ $e } +msg-13402a28 = [Discord] 跳过不符合规范的指令:{ $cmd_name } ### astrbot/core/platform/sources/aiocqhttp/aiocqhttp_platform_adapter.py -msg-859d480d = Handle request message failed: {$e} -msg-6fb672e1 = Handle notice message failed: {$e} -msg-cf4687a3 = Handle group message failed: {$e} -msg-3a9853e3 = Handle private message failed: {$e} + +msg-859d480d = 处理请求消息失败:{ $e } +msg-6fb672e1 = 处理通知消息失败:{ $e } +msg-cf4687a3 = 处理群组消息失败:{ $e } +msg-3a9853e3 = 处理私信失败:{ $e } msg-ec06dc3d = aiocqhttp(OneBot v11) 适配器已连接。 -msg-1304a54d = [aiocqhttp] RawMessage {$event} -msg-93cbb9fa = {$err} -msg-a4487a03 = 回复消息失败: {$e} -msg-48bc7bff = guessing lagrange -msg-6ab145a1 = 获取文件失败: {$ret} -msg-457454d7 = 获取文件失败: {$e},此消息段将被忽略。 -msg-7a299806 = 无法从回复消息数据构造 Event 对象: {$reply_event_data} -msg-e6633a51 = 获取引用消息失败: {$e}。 -msg-6e99cb8d = 获取 @ 用户信息失败: {$e},此消息段将被忽略。 -msg-cf15fd40 = 不支持的消息段类型,已忽略: {$t}, data={$res} -msg-45d126ad = 消息段解析失败: type={$t}, data={$res}. {$e} +msg-1304a54d = [aiocqhttp] 原始消息{ $event } +msg-93cbb9fa = { $err } +msg-a4487a03 = Failed to reply to message:{ $e } +msg-48bc7bff = 猜测拉格朗日 +msg-6ab145a1 = 获取文件失败:{ $ret } +msg-457454d7 = Failed to retrieve file:{ $e }此消息段将被忽略。 +msg-7a299806 = 无法从回复消息数据构造 Event 对象:{ $reply_event_data } +msg-e6633a51 = 获取引用消息失败:{ $e } +msg-6e99cb8d = 获取 @ 用户信息失败:{ $e }此消息段将被忽略。 +msg-cf15fd40 = 不支持的消息段类型,已忽略。{ $t }, data={ $res } +msg-45d126ad = 消息段解析失败: type={ $t }, data={ $res }.{ $e } msg-394a20ae = aiocqhttp: 未配置 ws_reverse_host 或 ws_reverse_port,将使用默认值:http://0.0.0.0:6199 msg-7414707c = aiocqhttp 适配器已被关闭 ### astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py -msg-0db8227d = 无法发送消息:缺少有效的数字 session_id({$session_id}) 或 event({$event}) + +msg-0db8227d = 无法发送消息:缺少有效的数字 session_id{ $session_id }) 或 event({ $event }) ### astrbot/core/platform/sources/lark/server.py + msg-2f3bccf1 = 未配置 encrypt_key,无法解密事件 -msg-e77104e2 = [Lark Webhook] 收到 challenge 验证请求: {$challenge} -msg-34b24fa1 = [Lark Webhook] 解析请求体失败: {$e} +msg-e77104e2 = [Lark Webhook] 收到 challenge 验证请求:{ $challenge } +msg-34b24fa1 = [Lark Webhook] 解析请求体失败:{ $e } msg-ec0fe13e = [Lark Webhook] 请求体为空 msg-f69ebbdb = [Lark Webhook] 签名验证失败 -msg-7ece4036 = [Lark Webhook] 解密后的事件: {$event_data} -msg-f2cb4b46 = [Lark Webhook] 解密事件失败: {$e} -msg-ef9f8906 = [Lark Webhook] Verification Token 不匹配。 -msg-bedb2071 = [Lark Webhook] 处理事件回调失败: {$e} +msg-7ece4036 = [Lark Webhook] 解密后的事件:{ $event_data } +msg-f2cb4b46 = [Lark Webhook] 解密事件失败:{ $e } +msg-ef9f8906 = [Lark Webhook] 验证令牌不匹配。 +msg-bedb2071 = [Lark Webhook] 处理事件回调失败:{ $e } ### astrbot/core/platform/sources/lark/lark_event.py -msg-eefbe737 = [Lark] API Client im 模块未初始化 + +msg-eefbe737 = [Lark] API 客户端 im 模块未初始化 msg-a21f93fa = [Lark] 主动发送消息时,receive_id 和 receive_id_type 不能为空 -msg-f456e468 = [Lark] 发送飞书消息失败({$res}): {$res_2} -msg-1eb66d14 = [Lark] 文件不存在: {$path} +msg-f456e468 = [Lark] 发送飞书消息失败({ $res }):{ $res_2 } +msg-1eb66d14 = [Lark] 文件不存在:{ $path } msg-1df39b24 = [Lark] API Client im 模块未初始化,无法上传文件 -msg-2ee721dd = [Lark] 无法上传文件({$res}): {$res_2} -msg-a04abf78 = [Lark] 上传文件成功但未返回数据(data is None) -msg-959e78a4 = [Lark] 文件上传成功: {$file_key} -msg-901a2f60 = [Lark] 无法打开或上传文件: {$e} +msg-2ee721dd = [Lark] 无法上传文件({ $res }):{ $res_2 } +msg-a04abf78 = [Lark] 文件上传成功但未返回数据(data 为 None) +msg-959e78a4 = [Lark] 文件上传成功:{ $file_key } +msg-901a2f60 = [Lark] 无法打开或上传文件:{ $e } msg-13065327 = [Lark] 图片路径为空,无法上传 -msg-37245892 = [Lark] 无法打开图片文件: {$e} +msg-37245892 = [Lark] 无法打开图片文件:{ $e } msg-ad63bf53 = [Lark] API Client im 模块未初始化,无法上传图片 -msg-ef90038b = 无法上传飞书图片({$res}): {$res_2} -msg-d2065832 = [Lark] 上传图片成功但未返回数据(data is None) -msg-dbb635c2 = {$image_key} +msg-ef90038b = Cannot upload Lark image ({ $res }):{ $res_2 } +msg-d2065832 = [Lark] 图片上传成功但未返回数据(data is None) +msg-dbb635c2 = { $image_key } msg-d4810504 = [Lark] 检测到文件组件,将单独发送 msg-45556717 = [Lark] 检测到音频组件,将单独发送 msg-959070b5 = [Lark] 检测到视频组件,将单独发送 -msg-4e2aa152 = 飞书 暂时不支持消息段: {$res} -msg-20d7c64b = [Lark] 无法获取音频文件路径: {$e} -msg-2f6f35e6 = [Lark] 音频文件不存在: {$original_audio_path} -msg-528b968d = [Lark] 音频格式转换失败,将尝试直接上传: {$e} -msg-fbc7efb9 = [Lark] 已删除转换后的音频文件: {$converted_audio_path} -msg-09840299 = [Lark] 删除转换后的音频文件失败: {$e} -msg-e073ff1c = [Lark] 无法获取视频文件路径: {$e} -msg-47e52913 = [Lark] 视频文件不存在: {$original_video_path} -msg-85ded1eb = [Lark] 视频格式转换失败,将尝试直接上传: {$e} -msg-b3bee05d = [Lark] 已删除转换后的视频文件: {$converted_video_path} -msg-775153f6 = [Lark] 删除转换后的视频文件失败: {$e} +msg-4e2aa152 = Feishu does not currently support message segments.{ $res } +msg-20d7c64b = [Lark] 无法获取音频文件路径:{ $e } +msg-2f6f35e6 = [Lark] 音频文件不存在:{ $original_audio_path } +msg-528b968d = [Lark] 音频格式转换失败,将尝试直接上传:{ $e } +msg-fbc7efb9 = [Lark] 已删除转换后的音频文件:{ $converted_audio_path } +msg-09840299 = [Lark] 删除转换后的音频文件失败:{ $e } +msg-e073ff1c = [Lark] 无法获取视频文件路径:{ $e } +msg-47e52913 = [Lark] 视频文件不存在:{ $original_video_path } +msg-85ded1eb = [Lark] 视频格式转换失败,将尝试直接上传:{ $e } +msg-b3bee05d = [Lark] 已删除转换后的视频文件:{ $converted_video_path } +msg-775153f6 = [Lark] 删除转换后的视频文件失败:{ $e } msg-45038ba7 = [Lark] API Client im 模块未初始化,无法发送表情 -msg-8d475b01 = 发送飞书表情回应失败({$res}): {$res_2} +msg-8d475b01 = Failed to send Lark emoji reaction{ $res }):{ $res_2 } ### astrbot/core/platform/sources/lark/lark_adapter.py + msg-06ce76eb = 未设置飞书机器人名称,@ 机器人可能得不到回复。 msg-eefbe737 = [Lark] API Client im 模块未初始化 -msg-236bcaad = [Lark] 下载消息资源失败 type={$resource_type}, key={$file_key}, code={$res}, msg={$res_2} -msg-ef9a61fe = [Lark] 消息资源响应中不包含文件流: {$file_key} +msg-236bcaad = [Lark] 下载消息资源失败 type={ $resource_type }, 键={ $file_key }, 代码={ $res },消息={ $res_2 } +msg-ef9a61fe = [Lark] 消息资源响应中不包含文件流{ $file_key } msg-7b69a8d4 = [Lark] 图片消息缺少 message_id msg-59f1694d = [Lark] 富文本视频消息缺少 message_id msg-af8f391d = [Lark] 文件消息缺少 message_id @@ -520,308 +570,321 @@ msg-ab21318a = [Lark] 音频消息缺少 message_id msg-9ec2c30a = [Lark] 音频消息缺少 file_key msg-0fa9ed18 = [Lark] 视频消息缺少 message_id msg-ae884c5c = [Lark] 视频消息缺少 file_key -msg-dac98a62 = [Lark] 获取引用消息失败 id={$parent_message_id}, code={$res}, msg={$res_2} -msg-7ee9f7dc = [Lark] 引用消息响应为空 id={$parent_message_id} -msg-2b3b2db9 = [Lark] 解析引用消息内容失败 id={$quoted_message_id} +msg-dac98a62 = [Lark] 获取引用消息失败 id={ $parent_message_id },代码={ $res }, 消息={ $res_2 } +msg-7ee9f7dc = [Lark] 引用消息响应为空 id={ $parent_message_id } +msg-2b3b2db9 = [Lark] 解析引用消息内容失败 id={ $quoted_message_id } msg-c5d54255 = [Lark] 收到空事件(event.event is None) msg-82f041c4 = [Lark] 事件中没有消息体(message is None) msg-206c3506 = [Lark] 消息内容为空 -msg-876aa1d2 = [Lark] 解析消息内容失败: {$res} -msg-514230f3 = [Lark] 消息内容不是 JSON Object: {$res} -msg-0898cf8b = [Lark] 解析消息内容: {$content_json_b} +msg-876aa1d2 = [Lark] 解析消息内容失败:{ $res } +msg-514230f3 = [Lark] 消息内容不是 JSON Object:{ $res } +msg-0898cf8b = [Lark] 解析消息内容:{ $content_json_b } msg-6a8bc661 = [Lark] 消息缺少 message_id msg-26554571 = [Lark] 消息发送者信息不完整 -msg-007d863a = [Lark Webhook] 跳过重复事件: {$event_id} -msg-6ce17e71 = [Lark Webhook] 未处理的事件类型: {$event_type} -msg-8689a644 = [Lark Webhook] 处理事件失败: {$e} +msg-007d863a = [Lark Webhook] 跳过重复事件:{ $event_id } +msg-6ce17e71 = [Lark Webhook] 未处理的事件类型:{ $event_type } +msg-8689a644 = [Lark Webhook] 处理事件失败:{ $e } msg-20688453 = [Lark] Webhook 模式已启用,但 webhook_server 未初始化 msg-f46171bc = [Lark] Webhook 模式已启用,但未配置 webhook_uuid msg-dd90a367 = 飞书(Lark) 适配器已关闭 ### astrbot/core/platform/sources/wecom/wecom_event.py -msg-e164c137 = 未找到微信客服发送消息方法。 -msg-c114425e = 微信客服上传图片失败: {$e} -msg-a90bc15d = 微信客服上传图片返回: {$response} -msg-38298880 = 微信客服上传语音失败: {$e} -msg-3aee0caa = 微信客服上传语音返回: {$response} -msg-15e6381b = 删除临时音频文件失败: {$e} -msg-a79ae417 = 微信客服上传文件失败: {$e} -msg-374455ef = 微信客服上传文件返回: {$response} -msg-a2a133e4 = 微信客服上传视频失败: {$e} -msg-2732fffd = 微信客服上传视频返回: {$response} -msg-60815f02 = 还没实现这个消息类型的发送逻辑: {$res}。 -msg-9913aa52 = 企业微信上传图片失败: {$e} -msg-9e90ba91 = 企业微信上传图片返回: {$response} -msg-232af016 = 企业微信上传语音失败: {$e} -msg-e5b8829d = 企业微信上传语音返回: {$response} -msg-f68671d7 = 企业微信上传文件失败: {$e} -msg-8cdcc397 = 企业微信上传文件返回: {$response} -msg-4f3e15f5 = 企业微信上传视频失败: {$e} -msg-4e9aceea = 企业微信上传视频返回: {$response} + +msg-e164c137 = WeChat customer service message sending method not found. +msg-c114425e = WeChat客服上传图片失败:{ $e } +msg-a90bc15d = 微信客服上传图片返回:{ $response } +msg-38298880 = WeChat客服上传语音失败:{ $e } +msg-3aee0caa = 微信客服上传语音返回:{ $response } +msg-15e6381b = Failed to delete temporary audio file:{ $e } +msg-a79ae417 = 微信客服上传文件失败:{ $e } +msg-374455ef = 微信客服上传文件返回:{ $response } +msg-a2a133e4 = 微信客服上传视频失败:{ $e } +msg-2732fffd = 微信客服上传视频返回:{ $response } +msg-60815f02 = 还没实现这个消息类型的发送逻辑:{ $res }。 +msg-9913aa52 = 企业微信上传图片失败:{ $e } +msg-9e90ba91 = 企业微信上传图片返回:{ $response } +msg-232af016 = 企业微信上传语音失败:{ $e } +msg-e5b8829d = 企业微信语音上传返回:{ $response } +msg-f68671d7 = 企业微信上传文件失败:{ $e } +msg-8cdcc397 = 企业微信上传文件返回:{ $response } +msg-4f3e15f5 = 企业微信上传视频失败:{ $e } +msg-4e9aceea = 企业微信上传视频返回:{ $response } ### astrbot/core/platform/sources/wecom/wecom_adapter.py -msg-d4bbf9cb = 验证请求有效性: {$res} -msg-f8694a8a = 验证请求有效性成功。 + +msg-d4bbf9cb = 验证请求有效性:{ $res } +msg-f8694a8a = Request validation successful. msg-8f4cda74 = 验证请求有效性失败,签名异常,请检查配置。 -msg-46d3feb9 = 解密失败,签名异常,请检查配置。 -msg-4d1dfce4 = 解析成功: {$msg} -msg-a98efa4b = 将在 {$res}:{$res_2} 端口启动 企业微信 适配器。 +msg-46d3feb9 = Decryption failed, signature exception, please check the configuration. +msg-4d1dfce4 = 解析成功:{ $msg } +msg-a98efa4b = 将在{ $res }待翻译文本:{ $res_2 }端口启动 企业微信 适配器。 msg-a616d9ce = 企业微信客服模式不支持 send_by_session 主动发送。 -msg-5d01d7b9 = send_by_session 失败:无法为会话 {$res} 推断 agent_id。 -msg-3f05613d = 获取到微信客服列表: {$acc_list} -msg-8fd19bd9 = 获取微信客服失败,open_kfid 为空。 -msg-5900d9b6 = Found open_kfid: {$open_kfid} -msg-391119b8 = 请打开以下链接,在微信扫码以获取客服微信: https://api.cl2wm.cn/api/qrcode/code?text={$kf_url} -msg-5bdf8f5c = {$e} -msg-93c9125e = 转换音频失败: {$e}。如果没有安装 ffmpeg 请先安装。 -msg-b2f7d1dc = 暂未实现的事件: {$res} -msg-61480a61 = abm: {$abm} -msg-42431e46 = 未实现的微信客服消息事件: {$msg} +msg-5d01d7b9 = send_by_session 失败:无法为会话{ $res }推断 agent_id。 +msg-3f05613d = 获取到微信客服列表:{ $acc_list } +msg-8fd19bd9 = Failed to fetch WeChat customer service, open_kfid is empty. +msg-5900d9b6 = 找到 open_kfid:{ $open_kfid } +msg-391119b8 = 请打开以下链接,在微信扫码以获取客服微信: https://api.cl2wm.cn/api/qrcode/code?text={ $kf_url } +msg-5bdf8f5c = { $e } +msg-93c9125e = 转换音频失败:{ $e }如果没有安装 ffmpeg 请先安装。 +msg-b2f7d1dc = 暂未实现的事件:{ $res } +msg-61480a61 = abm:{ $abm } +msg-42431e46 = Unimplemented WeChat customer service message event:{ $msg } msg-fbca491d = 企业微信 适配器已被关闭 ### astrbot/core/platform/sources/weixin_official_account/weixin_offacc_event.py -msg-fa7f7afc = split plain into {$res} chunks for passive reply. Message not sent. -msg-59231e07 = 微信公众平台上传图片失败: {$e} -msg-d3968fc5 = 微信公众平台上传图片返回: {$response} -msg-7834b934 = 微信公众平台上传语音失败: {$e} -msg-4901d769 = 微信公众平台上传语音返回: {$response} -msg-15e6381b = 删除临时音频文件失败: {$e} -msg-60815f02 = 还没实现这个消息类型的发送逻辑: {$res}。 + +msg-fa7f7afc = 拆分纯文本为{ $res }用于被动回复的区块。消息未发送。 +msg-59231e07 = 微信公众平台上传图片失败:{ $e } +msg-d3968fc5 = 微信公众平台上传图片返回:{ $response } +msg-7834b934 = 微信公众平台上传语音失败:{ $e } +msg-4901d769 = 微信公众平台语音上传返回结果:{ $response } +msg-15e6381b = Failed to delete temporary audio file:{ $e } +msg-60815f02 = 还没实现这个消息类型的发送逻辑:{ $res }。 ### astrbot/core/platform/sources/weixin_official_account/weixin_offacc_adapter.py -msg-d4bbf9cb = 验证请求有效性: {$res} + +msg-d4bbf9cb = 验证请求有效性:{ $res } msg-b2edb1b2 = 未知的响应,请检查回调地址是否填写正确。 -msg-f8694a8a = 验证请求有效性成功。 +msg-f8694a8a = Verification request validity succeeded. msg-8f4cda74 = 验证请求有效性失败,签名异常,请检查配置。 msg-46d3feb9 = 解密失败,签名异常,请检查配置。 msg-e23d8bff = 解析失败。msg为None。 -msg-4d1dfce4 = 解析成功: {$msg} -msg-193d9d7a = 用户消息缓冲状态: user={$from_user} state={$state} -msg-57a3c1b2 = wx buffer hit on trigger: user={$from_user} -msg-bed995d9 = wx buffer hit on retry window: user={$from_user} -msg-3a94b6ab = wx finished message sending in passive window: user={$from_user} msg_id={$msg_id} -msg-50c4b253 = wx finished message sending in passive window but not final: user={$from_user} msg_id={$msg_id} -msg-7d8b62e7 = wx finished in window but not final; return placeholder: user={$from_user} msg_id={$msg_id} -msg-2b9b8aed = wx task failed in passive window -msg-7bdf4941 = wx passive window timeout: user={$from_user} msg_id={$msg_id} -msg-98489949 = wx trigger while thinking: user={$from_user} -msg-01d0bbeb = wx new trigger: user={$from_user} msg_id={$msg_id} -msg-52bb36cd = wx start task: user={$from_user} msg_id={$msg_id} preview={$preview} -msg-ec9fd2ed = wx buffer hit immediately: user={$from_user} -msg-61c91fb9 = wx not finished in first window; return placeholder: user={$from_user} msg_id={$msg_id} -msg-35604bba = wx task failed in first window -msg-e56c4a28 = wx first window timeout: user={$from_user} msg_id={$msg_id} -msg-e163be40 = 将在 {$res}:{$res_2} 端口启动 微信公众平台 适配器。 -msg-c1740a04 = duplicate message id checked: {$res} -msg-04718b37 = Got future result: {$result} -msg-296e66c1 = callback 处理消息超时: message_id={$res} -msg-eb718c92 = 转换消息时出现异常: {$e} -msg-93c9125e = 转换音频失败: {$e}。如果没有安装 ffmpeg 请先安装。 -msg-b2f7d1dc = 暂未实现的事件: {$res} -msg-61480a61 = abm: {$abm} -msg-2e7e0187 = 用户消息未找到缓冲状态,无法处理消息: user={$res} message_id={$res_2} -msg-84312903 = 微信公众平台 适配器已被关闭 +msg-4d1dfce4 = 解析成功:{ $msg } +msg-193d9d7a = 用户消息缓冲状态: user={ $from_user }状态={ $state } +msg-57a3c1b2 = wx buffer hit on trigger: user={ $from_user } +msg-bed995d9 = 重试窗口缓冲区命中:用户={ $from_user } +msg-3a94b6ab = 被动窗口中的微信已完成消息发送:用户={ $from_user }消息ID={ $msg_id } +msg-50c4b253 = 微信在被动窗口完成消息发送但非最终状态:用户={ $from_user }消息ID={ $msg_id } +msg-7d8b62e7 = wx在窗口中完成但非最终状态;返回占位符:user={ $from_user }消息ID={ $msg_id } +msg-2b9b8aed = 在被动窗口中微信任务失败 +msg-7bdf4941 = 微信被动窗口超时时间:用户={ $from_user }消息ID={ $msg_id } +msg-98489949 = wx 触发思考时:用户={ $from_user } +msg-01d0bbeb = wx new trigger: user={ $from_user }消息ID={ $msg_id } +msg-52bb36cd = wx 开始任务:用户={ $from_user }消息标识符={ $msg_id }preview={ $preview } +msg-ec9fd2ed = wx buffer 立即命中: user={ $from_user } +msg-61c91fb9 = 第一个窗口中wx未完成;返回占位符:user={ $from_user }msg_id={ $msg_id } +msg-35604bba = 首窗口微信任务失败 +msg-e56c4a28 = wx 第一个窗口超时:用户={ $from_user }消息ID={ $msg_id } +msg-e163be40 = 将在{ $res }待翻译文本:{ $res_2 }端口启动 微信公众平台 适配器。 +msg-c1740a04 = 重复消息ID已检查:{ $res } +msg-04718b37 = 已获取未来结果:{ $result } +msg-296e66c1 = callback 处理消息超时: message_id={ $res } +msg-eb718c92 = 转换消息时出现异常:{ $e } +msg-93c9125e = 转换音频失败:{ $e }如果没有安装 ffmpeg 请先安装。 +msg-b2f7d1dc = 暂未实现的事件:{ $res } +msg-61480a61 = abm:{ $abm } +msg-2e7e0187 = 用户消息未找到缓冲状态,无法处理消息: user={ $res }消息ID={ $res_2 } +msg-84312903 = WeChat Official Account Platform adapter has been disabled ### astrbot/core/platform/sources/misskey/misskey_adapter.py + msg-7bacee77 = [Misskey] 配置不完整,无法启动 -msg-99cdf3d3 = [Misskey] 已连接用户: {$res} (ID: {$res_2}) -msg-5579c974 = [Misskey] 获取用户信息失败: {$e} +msg-99cdf3d3 = [Misskey] 已连接用户:{ $res }(ID:{ $res_2 }) +msg-5579c974 = [Misskey] 获取用户信息失败:{ $e } msg-d9547102 = [Misskey] API 客户端未初始化 -msg-341b0aa0 = [Misskey] WebSocket 已连接 (尝试 #{$connection_attempts}) +msg-341b0aa0 = [Misskey] WebSocket 已连接 (尝试 #{ $connection_attempts }) msg-c77d157b = [Misskey] 聊天频道已订阅 -msg-a0c5edc0 = [Misskey] WebSocket 连接失败 (尝试 #{$connection_attempts}) -msg-1958faa8 = [Misskey] WebSocket 异常 (尝试 #{$connection_attempts}): {$e} -msg-1b47382d = [Misskey] {$sleep_time}秒后重连 (下次尝试 #{$res}) -msg-a10a224d = [Misskey] 收到通知事件: type={$notification_type}, user_id={$res} -msg-7f0abf4a = [Misskey] 处理贴文提及: {$res}... -msg-2da7cdf5 = [Misskey] 处理通知失败: {$e} -msg-6c21d412 = [Misskey] 收到聊天事件: sender_id={$sender_id}, room_id={$room_id}, is_self={$res} -msg-68269731 = [Misskey] 检查群聊消息: '{$raw_text}', 机器人用户名: '{$res}' -msg-585aa62b = [Misskey] 处理群聊消息: {$res}... -msg-426c7874 = [Misskey] 处理私聊消息: {$res}... -msg-f5aff493 = [Misskey] 处理聊天消息失败: {$e} -msg-ea465183 = [Misskey] 收到未处理事件: type={$event_type}, channel={$res} +msg-a0c5edc0 = [Misskey] WebSocket 连接失败 (尝试 #{ $connection_attempts }) +msg-1958faa8 = [Misskey] WebSocket 异常 (尝试{ $connection_attempts }):{ $e } +msg-1b47382d = [Misskey]{ $sleep_time }秒后重连 (下次尝试 #{ $res }) +msg-a10a224d = [Misskey] 收到通知事件: type={ $notification_type }用户ID={ $res } +msg-7f0abf4a = [Misskey] 处理贴文提及:{ $res }... +msg-2da7cdf5 = [Misskey] 处理通知失败:{ $e } +msg-6c21d412 = [Misskey] 收到聊天事件: sender_id={ $sender_id }, room_id={ $room_id }, is_self={ $res } +msg-68269731 = [Misskey] 检查群聊消息: '{ $raw_text }', 机器人用户名: '{ $res }' +msg-585aa62b = [Misskey] 处理群聊消息:{ $res }... +msg-426c7874 = [Misskey] 处理私聊消息:{ $res }... +msg-f5aff493 = [Misskey] 处理聊天消息失败:{ $e } +msg-ea465183 = [Misskey] 收到未处理事件: type={ $event_type },频道={ $res } msg-8b69eb93 = [Misskey] 消息内容为空且无文件组件,跳过发送 -msg-9ba9c4e5 = [Misskey] 已清理临时文件: {$local_path} -msg-91af500e = [Misskey] 文件数量超过限制 ({$res} > {$MAX_FILE_UPLOAD_COUNT}),只上传前{$MAX_FILE_UPLOAD_COUNT}个文件 +msg-9ba9c4e5 = [Misskey] 已清理临时文件:{ $local_path } +msg-91af500e = [Misskey] 文件数量超过限制 ({ $res }>{ $MAX_FILE_UPLOAD_COUNT }),只上传前{ $MAX_FILE_UPLOAD_COUNT }个文件 msg-9746d7f5 = [Misskey] 并发上传过程中出现异常,继续发送文本 -msg-d6dc928c = [Misskey] 聊天消息只支持单个文件,忽略其余 {$res} 个文件 -msg-af584ae8 = [Misskey] 解析可见性: visibility={$visibility}, visible_user_ids={$visible_user_ids}, session_id={$session_id}, user_id_for_cache={$user_id_for_cache} -msg-1a176905 = [Misskey] 发送消息失败: {$e} +msg-d6dc928c = [Misskey] 聊天消息只支持单个文件,忽略其余{ $res }个文件 +msg-af584ae8 = [Misskey] 解析可见性: visibility={ $visibility }, visible_user_ids={ $visible_user_ids },session_id={ $session_id }用户ID用于缓存={ $user_id_for_cache } +msg-1a176905 = [Misskey] 发送消息失败:{ $e } ### astrbot/core/platform/sources/misskey/misskey_api.py -msg-fab20f57 = aiohttp and websockets are required for Misskey API. Please install them with: pip install aiohttp websockets + +msg-fab20f57 = Misskey API 需要 aiohttp 和 websockets 库。请通过以下命令安装:pip install aiohttp websockets msg-f2eea8e1 = [Misskey WebSocket] 已连接 -msg-5efd11a2 = [Misskey WebSocket] 重新订阅 {$channel_type} 失败: {$e} -msg-b70e2176 = [Misskey WebSocket] 连接失败: {$e} +msg-5efd11a2 = [Misskey WebSocket] 重新订阅{ $channel_type }失败:{ $e } +msg-b70e2176 = [Misskey WebSocket] 连接失败:{ $e } msg-b9f3ee06 = [Misskey WebSocket] 连接已断开 msg-7cd98e54 = WebSocket 未连接 -msg-43566304 = [Misskey WebSocket] 无法解析消息: {$e} -msg-e617e390 = [Misskey WebSocket] 处理消息失败: {$e} -msg-c60715cf = [Misskey WebSocket] 连接意外关闭: {$e} -msg-da9a2a17 = [Misskey WebSocket] 连接已关闭 (代码: {$res}, 原因: {$res_2}) -msg-bbf6a42e = [Misskey WebSocket] 握手失败: {$e} -msg-254f0237 = [Misskey WebSocket] 监听消息失败: {$e} -msg-49f7e90e = {$channel_summary} -msg-630a4832 = [Misskey WebSocket] 频道消息: {$channel_id}, 事件类型: {$event_type} -msg-0dc61a4d = [Misskey WebSocket] 使用处理器: {$handler_key} -msg-012666fc = [Misskey WebSocket] 使用事件处理器: {$event_type} -msg-e202168a = [Misskey WebSocket] 未找到处理器: {$handler_key} 或 {$event_type} -msg-a397eef1 = [Misskey WebSocket] 直接消息处理器: {$message_type} -msg-a5f12225 = [Misskey WebSocket] 未处理的消息类型: {$message_type} -msg-ad61d480 = [Misskey API] {$func_name} 重试 {$max_retries} 次后仍失败: {$e} -msg-7de2ca49 = [Misskey API] {$func_name} 第 {$attempt} 次重试失败: {$e},{$sleep_time}s后重试 -msg-f5aecf37 = [Misskey API] {$func_name} 遇到不可重试异常: {$e} +msg-43566304 = [Misskey WebSocket] 无法解析消息:{ $e } +msg-e617e390 = [Misskey WebSocket] 处理消息失败:{ $e } +msg-c60715cf = [Misskey WebSocket] 连接意外关闭:{ $e } +msg-da9a2a17 = [Misskey WebSocket] 连接已关闭 (代码:{ $res }, 原因:{ $res_2 }) +msg-bbf6a42e = [Misskey WebSocket] 握手失败:{ $e } +msg-254f0237 = [Misskey WebSocket] 监听消息失败:{ $e } +msg-49f7e90e = { $channel_summary } +msg-630a4832 = [Misskey WebSocket] 频道消息:{ $channel_id }, 事件类型:{ $event_type } +msg-0dc61a4d = [Misskey WebSocket] 使用处理器:{ $handler_key } +msg-012666fc = [Misskey WebSocket] 使用事件处理器:{ $event_type } +msg-e202168a = [Misskey WebSocket] 未找到处理器:{ $handler_key }Or{ $event_type } +msg-a397eef1 = [Misskey WebSocket] 直接消息处理器:{ $message_type } +msg-a5f12225 = [Misskey WebSocket] 未处理的消息类型:{ $message_type } +msg-ad61d480 = [Misskey API]{ $func_name }重试{ $max_retries }次后仍失败:{ $e } +msg-7de2ca49 = [Misskey API]{ $func_name }第{ $attempt }Secondary retry failure:{ $e },{ $sleep_time }s后重试 +msg-f5aecf37 = [Misskey API]{ $func_name }遇到不可重试异常:{ $e } msg-e5852be5 = [Misskey API] 客户端已关闭 -msg-21fc185c = [Misskey API] 请求参数错误: {$endpoint} (HTTP {$status}) -msg-5b106def = Bad request for {$endpoint} -msg-28afff67 = [Misskey API] 未授权访问: {$endpoint} (HTTP {$status}) -msg-e12f2d28 = Unauthorized access for {$endpoint} -msg-beda662d = [Misskey API] 访问被禁止: {$endpoint} (HTTP {$status}) -msg-795ca227 = Forbidden access for {$endpoint} -msg-5c6ba873 = [Misskey API] 资源不存在: {$endpoint} (HTTP {$status}) -msg-74f2bac2 = Resource not found for {$endpoint} -msg-9ceafe4c = [Misskey API] 请求体过大: {$endpoint} (HTTP {$status}) -msg-3e336b73 = Request entity too large for {$endpoint} -msg-a47067de = [Misskey API] 请求频率限制: {$endpoint} (HTTP {$status}) -msg-901dc2da = Rate limit exceeded for {$endpoint} -msg-2bea8c2e = [Misskey API] 服务器内部错误: {$endpoint} (HTTP {$status}) -msg-ae8d3725 = Internal server error for {$endpoint} -msg-7b028462 = [Misskey API] 网关错误: {$endpoint} (HTTP {$status}) -msg-978414ef = Bad gateway for {$endpoint} -msg-50895a69 = [Misskey API] 服务不可用: {$endpoint} (HTTP {$status}) -msg-62adff89 = Service unavailable for {$endpoint} -msg-1cf15497 = [Misskey API] 网关超时: {$endpoint} (HTTP {$status}) -msg-a8a2578d = Gateway timeout for {$endpoint} -msg-c012110a = [Misskey API] 未知错误: {$endpoint} (HTTP {$status}) -msg-dc96bbb8 = HTTP {$status} for {$endpoint} -msg-4c7598b6 = [Misskey API] 获取到 {$res} 条新通知 -msg-851a2a54 = [Misskey API] 请求成功: {$endpoint} -msg-5f5609b6 = [Misskey API] 响应格式错误: {$e} -msg-c8f7bbeb = Invalid JSON response -msg-82748b31 = [Misskey API] 请求失败: {$endpoint} - HTTP {$res}, 响应: {$error_text} -msg-c6de3320 = [Misskey API] 请求失败: {$endpoint} - HTTP {$res} -msg-affb19a7 = [Misskey API] HTTP 请求错误: {$e} -msg-9f1286b3 = HTTP request failed: {$e} -msg-44f91be2 = [Misskey API] 发帖成功: {$note_id} -msg-fbafd3db = No file path provided for upload -msg-872d8419 = [Misskey API] 本地文件不存在: {$file_path} -msg-37186dea = File not found: {$file_path} -msg-65ef68e0 = [Misskey API] 本地文件上传成功: {$filename} -> {$file_id} -msg-0951db67 = [Misskey API] 文件上传网络错误: {$e} -msg-e3a322f5 = Upload failed: {$e} -msg-f28772b9 = No MD5 hash provided for find-by-hash -msg-25e566ef = [Misskey API] find-by-hash 请求: md5={$md5_hash} -msg-a036a942 = [Misskey API] find-by-hash 响应: 找到 {$res} 个文件 -msg-ea3581d5 = [Misskey API] 根据哈希查找文件失败: {$e} -msg-1d2a84ff = No name provided for find -msg-f25e28b4 = [Misskey API] find 请求: name={$name}, folder_id={$folder_id} -msg-cd43861a = [Misskey API] find 响应: 找到 {$res} 个文件 -msg-05cd55ef = [Misskey API] 根据名称查找文件失败: {$e} -msg-c01052a4 = [Misskey API] 列表文件请求: limit={$limit}, folder_id={$folder_id}, type={$type} -msg-7c81620d = [Misskey API] 列表文件响应: 找到 {$res} 个文件 -msg-a187a089 = [Misskey API] 列表文件失败: {$e} -msg-9e776259 = No existing session available -msg-de18c220 = URL不能为空 -msg-25b15b61 = [Misskey API] SSL 验证下载失败: {$ssl_error},重试不验证 SSL -msg-b6cbeef6 = [Misskey API] 本地上传成功: {$res} -msg-a4a898e2 = [Misskey API] 本地上传失败: {$e} -msg-46b7ea4b = [Misskey API] 聊天消息发送成功: {$message_id} -msg-32f71df4 = [Misskey API] 房间消息发送成功: {$message_id} -msg-7829f3b3 = [Misskey API] 聊天消息响应格式异常: {$res} -msg-d74c86a1 = [Misskey API] 提及通知响应格式异常: {$res} -msg-65ccb697 = 消息内容不能为空:需要文本或媒体文件 -msg-b6afb123 = [Misskey API] URL媒体上传成功: {$res} -msg-4e62bcdc = [Misskey API] URL媒体上传失败: {$url} -msg-71cc9d61 = [Misskey API] URL媒体处理失败 {$url}: {$e} -msg-75890c2b = [Misskey API] 本地文件上传成功: {$res} -msg-024d0ed5 = [Misskey API] 本地文件上传失败: {$file_path} -msg-f1fcb5e1 = [Misskey API] 本地文件处理失败 {$file_path}: {$e} -msg-1ee80a6b = 不支持的消息类型: {$message_type} +msg-21fc185c = [Misskey API] 请求参数错误:{ $endpoint }(HTTP{ $status }) +msg-5b106def = 请求错误{ $endpoint } +msg-28afff67 = [Misskey API] 未授权访问:{ $endpoint }(HTTP{ $status }) +msg-e12f2d28 = 未经授权的访问{ $endpoint } +msg-beda662d = [Misskey API] 访问被禁止:{ $endpoint }(HTTP{ $status }) +msg-795ca227 = 禁止访问{ $endpoint } +msg-5c6ba873 = [Misskey API] 资源不存在:{ $endpoint }(HTTP{ $status }) +msg-74f2bac2 = 找不到资源用于{ $endpoint } +msg-9ceafe4c = [Misskey API] 请求体过大:{ $endpoint }(HTTP{ $status }) +msg-3e336b73 = 请求实体过大{ $endpoint } +msg-a47067de = [Misskey API] 请求频率限制:{ $endpoint }(HTTP{ $status }) +msg-901dc2da = 超出速率限制{ $endpoint } +msg-2bea8c2e = [Misskey API] 服务器内部错误:{ $endpoint }待翻译文本:(HTTP{ $status }) +msg-ae8d3725 = 内部服务器错误{ $endpoint } +msg-7b028462 = [Misskey API] 网关错误:{ $endpoint }(HTTP{ $status }) +msg-978414ef = 网关错误{ $endpoint } +msg-50895a69 = [Misskey API] 服务不可用:{ $endpoint }(HTTP{ $status }) +msg-62adff89 = 服务不可用{ $endpoint } +msg-1cf15497 = [Misskey API] 网关超时:{ $endpoint }(HTTP{ $status }) +msg-a8a2578d = 网关超时{ $endpoint } +msg-c012110a = [Misskey API] 未知错误:{ $endpoint }(HTTP{ $status }) +msg-dc96bbb8 = HTTP{ $status }为{ $endpoint } +msg-4c7598b6 = [Misskey API] 已获取到{ $res }1 new notification +msg-851a2a54 = [Misskey API] 请求成功:{ $endpoint } +msg-5f5609b6 = [Misskey API] 响应格式错误:{ $e } +msg-c8f7bbeb = 无效的JSON响应 +msg-82748b31 = [Misskey API] 请求失败:{ $endpoint }- HTTP{ $res }, 响应:{ $error_text } +msg-c6de3320 = [Misskey API] 请求失败:{ $endpoint }- HTTP{ $res } +msg-affb19a7 = [Misskey API] HTTP 请求错误:{ $e } +msg-9f1286b3 = HTTP请求失败:{ $e } +msg-44f91be2 = [Misskey API] 发帖成功:{ $note_id } +msg-fbafd3db = 未提供上传文件路径 +msg-872d8419 = [Misskey API] 本地文件不存在:{ $file_path } +msg-37186dea = 文件未找到:{ $file_path } +msg-65ef68e0 = [Misskey API] 本地文件上传成功:{ $filename }->{ $file_id } +msg-0951db67 = [Misskey API] 文件上传网络错误:{ $e } +msg-e3a322f5 = 上传失败:{ $e } +msg-f28772b9 = 未提供MD5哈希用于按哈希查找 +msg-25e566ef = [Misskey API] find-by-hash 请求: md5={ $md5_hash } +msg-a036a942 = [Misskey API] find-by-hash 响应:找到{ $res }个文件 +msg-ea3581d5 = [Misskey API] 根据哈希查找文件失败:{ $e } +msg-1d2a84ff = 未提供查找名称 +msg-f25e28b4 = [Misskey API] find 请求: name={ $name },folder_id={ $folder_id } +msg-cd43861a = [Misskey API] find 响应: 找到{ $res }1 file +msg-05cd55ef = [Misskey API] 根据名称查找文件失败:{ $e } +msg-c01052a4 = [Misskey API] 列表文件请求: limit={ $limit }文件夹ID={ $folder_id }, type={ $type } +msg-7c81620d = [Misskey API] 列表文件响应:已找到{ $res }个文件 +msg-a187a089 = [Misskey API] 列表文件失败:{ $e } +msg-9e776259 = 无可用会话 +msg-de18c220 = URL cannot be empty +msg-25b15b61 = [Misskey API] SSL 验证下载失败:{ $ssl_error },重试不验证 SSL +msg-b6cbeef6 = [Misskey API] 本地上传成功:{ $res } +msg-a4a898e2 = [Misskey API] 本地上传失败:{ $e } +msg-46b7ea4b = [Misskey API] 聊天消息发送成功:{ $message_id } +msg-32f71df4 = [Misskey API] 房间消息发送成功:{ $message_id } +msg-7829f3b3 = [Misskey API] 聊天消息响应格式异常:{ $res } +msg-d74c86a1 = [Misskey API] 提及通知响应格式异常:{ $res } +msg-65ccb697 = Message content cannot be empty: text or media file required +msg-b6afb123 = [Misskey API] URL媒体上传成功:{ $res } +msg-4e62bcdc = [Misskey API] URL媒体上传失败:{ $url } +msg-71cc9d61 = [Misskey API] URL媒体处理失败{ $url }待翻译文本:{ $e } +msg-75890c2b = [Misskey API] 本地文件上传成功:{ $res } +msg-024d0ed5 = [Misskey API] 本地文件上传失败:{ $file_path } +msg-f1fcb5e1 = [Misskey API] 本地文件处理失败{ $file_path }待翻译文本:{ $e } +msg-1ee80a6b = 不支持的消息类型:{ $message_type } ### astrbot/core/platform/sources/misskey/misskey_event.py -msg-85cb7d49 = [MisskeyEvent] send 方法被调用,消息链包含 {$res} 个组件 -msg-252c2fca = [MisskeyEvent] 检查适配器方法: hasattr(self.client, 'send_by_session') = {$res} + +msg-85cb7d49 = [MisskeyEvent] send 方法被调用,消息链包含{ $res }个组件 +msg-252c2fca = [MisskeyEvent] 检查适配器方法: hasattr(self.client, 'send_by_session') ={ $res } msg-44d7a060 = [MisskeyEvent] 调用适配器的 send_by_session 方法 msg-b6e08872 = [MisskeyEvent] 内容为空,跳过发送 msg-8cfebc9c = [MisskeyEvent] 创建新帖子 -msg-ed0d2ed5 = [MisskeyEvent] 发送失败: {$e} +msg-ed0d2ed5 = [MisskeyEvent] 发送失败:{ $e } ### astrbot/core/platform/sources/wecom_ai_bot/wecomai_webhook.py + msg-a5c90267 = 消息推送 webhook URL 不能为空 msg-76bfb25b = 消息推送 webhook URL 缺少 key 参数 -msg-3545eb07 = Webhook 请求失败: HTTP {$res}, {$text} -msg-758dfe0d = Webhook 返回错误: {$res} {$res_2} +msg-3545eb07 = Webhook 请求失败: HTTP{ $res },{ $text } +msg-758dfe0d = Webhook 返回错误:{ $res } { $res_2 } msg-c056646b = 企业微信消息推送成功: %s -msg-73d3e179 = 文件不存在: {$file_path} -msg-774a1821 = 上传媒体失败: HTTP {$res}, {$text} -msg-6ff016a4 = 上传媒体失败: {$res} {$res_2} +msg-73d3e179 = 文件不存在:{ $file_path } +msg-774a1821 = 上传媒体失败: HTTP{ $res },{ $text } +msg-6ff016a4 = Failed to upload media:{ $res } { $res_2 } msg-0e8252d1 = 上传媒体失败: 返回缺少 media_id msg-9dbc2296 = 文件消息缺少有效文件路径,已跳过: %s msg-2e567c36 = 清理临时语音文件失败 %s: %s msg-e99c4df9 = 企业微信消息推送暂不支持组件类型 %s,已跳过 ### astrbot/core/platform/sources/wecom_ai_bot/WXBizJsonMsgCrypt.py -msg-5bdf8f5c = {$e} -msg-fe69e232 = receiveid not match -msg-00b71c27 = signature not match -msg-5cfb5c20 = {$signature} + +msg-5bdf8f5c = { $e } +msg-fe69e232 = 接收ID不匹配 +msg-00b71c27 = 签名不匹配 +msg-5cfb5c20 = { $signature } ### astrbot/core/platform/sources/wecom_ai_bot/wecomai_event.py -msg-e44e77b0 = 图片数据为空,跳过 + +msg-e44e77b0 = Image data is empty, skipping msg-30d116ed = 处理图片消息失败: %s -msg-31b11295 = [WecomAI] 不支持的消息组件类型: {$res}, 跳过 +msg-31b11295 = [WecomAI] 不支持的消息组件类型:{ $res }, 跳过 ### astrbot/core/platform/sources/wecom_ai_bot/wecomai_adapter.py + msg-277cdd37 = 企业微信消息推送 webhook 配置无效: %s -msg-2102fede = 处理队列消息时发生异常: {$e} -msg-d4ea688d = 消息类型未知,忽略: {$message_data} +msg-2102fede = 处理队列消息时发生异常:{ $e } +msg-d4ea688d = 消息类型未知,忽略:{ $message_data } msg-15ba426f = 处理消息时发生异常: %s -msg-740911ab = Stream already finished, returning end message: {$stream_id} -msg-9fdbafe9 = Cannot find back queue for stream_id: {$stream_id} -msg-7a52ca2b = No new messages in back queue for stream_id: {$stream_id} -msg-9ffb59fb = Aggregated content: {$latest_plain_content}, image: {$res}, finish: {$finish} -msg-de9ff585 = Stream message sent successfully, stream_id: {$stream_id} +msg-740911ab = 流已结束,返回结束消息:{ $stream_id } +msg-9fdbafe9 = 无法为stream_id找到对应的回退队列:{ $stream_id } +msg-7a52ca2b = stream_id 对应的待处理队列中没有新消息。{ $stream_id } +msg-9ffb59fb = 聚合内容:{ $latest_plain_content }, 图片:{ $res }, 完成:{ $finish } +msg-de9ff585 = 流消息发送成功,流ID:{ $stream_id } msg-558310b9 = 消息加密失败 msg-251652f9 = 处理欢迎消息时发生异常: %s -msg-480c5dac = [WecomAI] 消息已入队: {$stream_id} -msg-f595dd6e = 处理加密图片失败: {$result} -msg-e8beeb3d = WecomAIAdapter: {$res} +msg-480c5dac = [WecomAI] 消息已入队:{ $stream_id } +msg-f595dd6e = 处理加密图片失败:{ $result } +msg-e8beeb3d = WecomAIAdapter:{ $res } msg-6f8ad811 = 主动消息发送失败: 未配置企业微信消息推送 Webhook URL,请前往配置添加。session_id=%s msg-84439b09 = 企业微信消息推送失败(session=%s): %s msg-f70f5008 = 启动企业微信智能机器人适配器,监听 %s:%d msg-87616945 = 企业微信智能机器人适配器正在关闭... ### astrbot/core/platform/sources/wecom_ai_bot/wecomai_api.py -msg-86f6ae9f = 消息解密失败,错误码: {$ret} -msg-45ad825c = 解密成功,消息内容: {$message_data} -msg-84c476a7 = JSON 解析失败: {$e}, 原始消息: {$decrypted_msg} -msg-c0d8c5f9 = 解密消息为空 -msg-a08bcfc7 = 解密过程发生异常: {$e} -msg-4dfaa613 = 消息加密失败,错误码: {$ret} -msg-6e566b12 = 消息加密成功 -msg-39bf8dba = 加密过程发生异常: {$e} -msg-fa5be7c5 = URL 验证失败,错误码: {$ret} + +msg-86f6ae9f = 消息解密失败,错误码:{ $ret } +msg-45ad825c = Decryption successful, message content:{ $message_data } +msg-84c476a7 = JSON 解析失败:{ $e }, 原始消息:{ $decrypted_msg } +msg-c0d8c5f9 = Decrypted message is empty +msg-a08bcfc7 = 解密过程发生异常:{ $e } +msg-4dfaa613 = Message encryption failed, error code:{ $ret } +msg-6e566b12 = Message encrypted successfully +msg-39bf8dba = 加密过程发生异常:{ $e } +msg-fa5be7c5 = URL 验证失败,错误码:{ $ret } msg-813a4e4e = URL 验证成功 -msg-65ce0d23 = URL 验证发生异常: {$e} -msg-b1aa892f = 开始下载加密图片: {$image_url} -msg-10f72727 = {$error_msg} -msg-70123a82 = 图片下载成功,大小: {$res} 字节 +msg-65ce0d23 = URL validation encountered an exception:{ $e } +msg-b1aa892f = 开始下载加密图片:{ $image_url } +msg-10f72727 = { $error_msg } +msg-70123a82 = 图片下载成功,大小:{ $res }字节 msg-85d2dba1 = AES 密钥不能为空 msg-67c4fcea = 无效的 AES 密钥长度: 应为 32 字节 msg-bde4bb57 = 无效的填充长度 (大于32字节) -msg-63c22912 = 图片解密成功,解密后大小: {$res} 字节 +msg-63c22912 = 图片解密成功,解密后大小:{ $res }字节 msg-6ea489f0 = 文本消息解析失败 msg-eb12d147 = 图片消息解析失败 -msg-ab1157ff = 流消息解析失败 +msg-ab1157ff = Stream message parsing failed msg-e7e945d1 = 混合消息解析失败 msg-06ada9dd = 事件消息解析失败 ### astrbot/core/platform/sources/wecom_ai_bot/wecomai_server.py -msg-adaee66c = URL 验证参数缺失 -msg-742e0b43 = 收到企业微信智能机器人 WebHook URL 验证请求。 + +msg-adaee66c = URL validation parameters missing +msg-742e0b43 = Received enterprise WeChat smart robot WebHook URL verification request. msg-f86c030c = 消息回调参数缺失 -msg-cce4e44c = 收到消息回调,msg_signature={$msg_signature}, timestamp={$timestamp}, nonce={$nonce} +msg-cce4e44c = 收到消息回调,msg_signature={ $msg_signature }时间戳={ $timestamp }, nonce={ $nonce } msg-7f018a3c = 消息解密失败,错误码: %d msg-9d42e548 = 消息处理器执行异常: %s msg-15ba426f = 处理消息时发生异常: %s @@ -830,1979 +893,2140 @@ msg-445921d5 = 服务器运行异常: %s msg-3269840c = 企业微信智能机器人服务器正在关闭... ### astrbot/core/platform/sources/wecom_ai_bot/wecomai_queue_mgr.py -msg-8be03d44 = [WecomAI] 创建输入队列: {$session_id} -msg-9804296a = [WecomAI] 创建输出队列: {$session_id} -msg-bdf0fb78 = [WecomAI] 移除输出队列: {$session_id} -msg-40f6bb7b = [WecomAI] 移除待处理响应: {$session_id} -msg-fbb807cd = [WecomAI] 标记流已结束: {$session_id} -msg-9d7f5627 = [WecomAI] 移除输入队列: {$session_id} -msg-7637ed00 = [WecomAI] 设置待处理响应: {$session_id} -msg-5329c49b = [WecomAI] 清理过期响应及队列: {$session_id} -msg-09f098ea = [WecomAI] 为会话启动监听器: {$session_id} -msg-c55856d6 = 处理会话 {$session_id} 消息时发生错误: {$e} + +msg-8be03d44 = [WecomAI] 创建输入队列:{ $session_id } +msg-9804296a = [WecomAI] 创建输出队列:{ $session_id } +msg-bdf0fb78 = [WecomAI] 移除输出队列:{ $session_id } +msg-40f6bb7b = [WecomAI] 移除待处理响应:{ $session_id } +msg-fbb807cd = [WecomAI] 标记流已结束{ $session_id } +msg-9d7f5627 = [WecomAI] 移除输入队列:{ $session_id } +msg-7637ed00 = [WecomAI] 设置待处理响应:{ $session_id } +msg-5329c49b = [WecomAI] 清理过期响应及队列:{ $session_id } +msg-09f098ea = [WecomAI] 为会话启动监听器:{ $session_id } +msg-c55856d6 = 处理会话{ $session_id }Error occurred while messaging:{ $e } ### astrbot/core/platform/sources/wecom_ai_bot/wecomai_utils.py -msg-14d01778 = JSON 解析失败: {$e}, 原始字符串: {$json_str} + +msg-14d01778 = JSON 解析失败:{ $e }, 原始字符串:{ $json_str } msg-df346cf5 = 开始下载加密图片: %s msg-cb266fb3 = 图片下载成功,大小: %d 字节 -msg-10f72727 = {$error_msg} +msg-10f72727 = { $error_msg } msg-1d91d2bb = AES密钥不能为空 -msg-bb32bedd = 无效的AES密钥长度: 应为32字节 -msg-bde4bb57 = 无效的填充长度 (大于32字节) +msg-bb32bedd = 无效的AES密钥长度:应为32字节 +msg-bde4bb57 = Invalid padding length (greater than 32 bytes) msg-3cf2120e = 图片解密成功,解密后大小: %d 字节 msg-3f8ca8aa = 图片已转换为base64编码,编码后长度: %d ### astrbot/core/platform/sources/line/line_api.py -msg-06e3f874 = [LINE] %s message failed: status=%s body=%s -msg-1478c917 = [LINE] %s message request failed: %s -msg-39941f06 = [LINE] get content retry failed: message_id=%s status=%s body=%s -msg-1fe70511 = [LINE] get content failed: message_id=%s status=%s body=%s + +msg-06e3f874 = [LINE] %s 消息发送失败:状态码=%s 响应体=%s +msg-1478c917 = [LINE] %s 消息请求失败: %s +msg-39941f06 = [LINE] 获取内容重试失败:消息ID=%s 状态=%s 正文=%s +msg-1fe70511 = [LINE] 获取内容失败:message_id=%s status=%s body=%s ### astrbot/core/platform/sources/line/line_event.py -msg-4068a191 = [LINE] resolve image url failed: %s -msg-2233b256 = [LINE] resolve record url failed: %s -msg-a7455817 = [LINE] resolve record duration failed: %s -msg-9d0fee66 = [LINE] resolve video url failed: %s -msg-3b8ea946 = [LINE] resolve video cover failed: %s -msg-aea2081a = [LINE] generate video preview failed: %s -msg-af426b7e = [LINE] resolve file url failed: %s -msg-fe44c12d = [LINE] resolve file size failed: %s -msg-d6443173 = [LINE] message count exceeds 5, extra segments will be dropped. + +msg-4068a191 = [LINE] 解析图片URL失败: %s +msg-2233b256 = [LINE] 解析记录URL失败:%s +msg-a7455817 = [LINE] 解析记录时长失败:%s +msg-9d0fee66 = [LINE] 解析视频链接失败:%s +msg-3b8ea946 = [LINE] 解析视频封面失败:%s +msg-aea2081a = [LINE] 生成视频预览失败:%s +msg-af426b7e = [LINE] 解析文件URL失败:%s +msg-fe44c12d = [LINE] 解析文件大小失败:%s +msg-d6443173 = [LINE] 消息数量超过5条,超出部分将被丢弃。 ### astrbot/core/platform/sources/line/line_adapter.py -msg-68539775 = LINE 适配器需要 channel_access_token 和 channel_secret。 + +msg-68539775 = LINE adapter requires channel_access_token and channel_secret. msg-30c67081 = [LINE] webhook_uuid 为空,统一 Webhook 可能无法接收消息。 -msg-64e92929 = [LINE] invalid webhook signature -msg-71bc0b77 = [LINE] invalid webhook body: %s -msg-8c7d9bab = [LINE] duplicate event skipped: %s +msg-64e92929 = [LINE] 无效的Webhook签名 +msg-71bc0b77 = [LINE] webhook 内容无效:%s +msg-8c7d9bab = [LINE] 重复事件已跳过: %s ### astrbot/core/platform/sources/telegram/tg_event.py -msg-7757f090 = [Telegram] 发送 chat action 失败: {$e} -msg-80b075a3 = User privacy settings prevent receiving voice messages, falling back to sending an audio file. To enable voice messages, go to Telegram Settings → Privacy and Security → Voice Messages → set to 'Everyone'. -msg-20665ad1 = MarkdownV2 send failed: {$e}. Using plain text instead. -msg-323cb67c = [Telegram] 添加反应失败: {$e} -msg-abe7fc3d = 编辑消息失败(streaming-break): {$e} -msg-f7d40103 = 不支持的消息类型: {$res} -msg-d4b50a96 = 编辑消息失败(streaming): {$e} -msg-2701a78f = 发送消息失败(streaming): {$e} -msg-2a8ecebd = Markdown转换失败,使用普通文本: {$e} + +msg-7757f090 = [Telegram] 发送聊天动作失败:{ $e } +msg-80b075a3 = 用户隐私设置阻止接收语音消息,已回退为发送音频文件。要启用语音消息功能,请前往 Telegram 设置 → 隐私与安全 → 语音消息 → 设置为“所有人”。 +msg-20665ad1 = MarkdownV2 发送失败:{ $e }使用纯文本替代。 +msg-323cb67c = [Telegram] 添加反应失败:{ $e } +msg-abe7fc3d = 编辑消息失败(streaming-break):{ $e } +msg-f7d40103 = 不支持的消息类型:{ $res } +msg-d4b50a96 = 编辑消息失败(streaming):{ $e } +msg-2701a78f = 发送消息失败(流式传输):{ $e } +msg-2a8ecebd = Markdown转换失败,使用普通文本:{ $e } ### astrbot/core/platform/sources/telegram/tg_adapter.py -msg-cb53f79a = Telegram base url: {$res} -msg-e6b6040f = Telegram Updater is not initialized. Cannot start polling. -msg-2c4b186e = Telegram Platform Adapter is running. -msg-908d0414 = 向 Telegram 注册指令时发生错误: {$e} -msg-d2dfe45e = 命令名 '{$cmd_name}' 重复注册,将使用首次注册的定义: '{$res}' -msg-63bdfab8 = Received a start command without an effective chat, skipping /start reply. -msg-03a27b01 = Telegram message: {$res} -msg-e47b4bb4 = Received an update without a message. -msg-c97401c6 = [Telegram] Received a message without a from_user. -msg-f5c839ee = Telegram document file_path is None, cannot save the file {$file_name}. -msg-dca991a9 = Telegram video file_path is None, cannot save the file {$file_name}. -msg-56fb2950 = Create media group cache: {$media_group_id} -msg-0de2d4b5 = Add message to media group {$media_group_id}, currently has {$res} items. -msg-9e5069e9 = Media group {$media_group_id} has reached max wait time ({$elapsed}s >= {$res}s), processing immediately. -msg-9156b9d6 = Scheduled media group {$media_group_id} to be processed in {$delay} seconds (already waited {$elapsed}s) -msg-2849c882 = Media group {$media_group_id} not found in cache -msg-c75b2163 = Media group {$media_group_id} is empty -msg-0a3626c1 = Processing media group {$media_group_id}, total {$res} items -msg-2842e389 = Failed to convert the first message of media group {$media_group_id} -msg-32fbf7c1 = Added {$res} components to media group {$media_group_id} -msg-23bae28a = Telegram adapter has been closed. -msg-e46e7740 = Error occurred while closing Telegram adapter: {$e} + +msg-cb53f79a = Telegram 基础网址:{ $res } +msg-e6b6040f = Telegram Updater 未初始化。无法启动轮询。 +msg-2c4b186e = Telegram 平台适配器正在运行。 +msg-908d0414 = An error occurred while registering the command to Telegram:{ $e } +msg-d2dfe45e = Command name{ $cmd_name }重复注册,将使用首次注册的定义:{ $res }待翻译文本: +msg-63bdfab8 = 收到启动命令但没有有效的聊天会话,跳过 /start 回复。 +msg-03a27b01 = Telegram 消息:{ $res } +msg-e47b4bb4 = 收到一条没有消息内容的更新。 +msg-c97401c6 = [Telegram] 收到一条未包含发件人信息的消息。 +msg-f5c839ee = Telegram文档文件路径为空,无法保存文件。{ $file_name }. +msg-dca991a9 = Telegram 视频文件路径为空,无法保存文件。{ $file_name }待翻译文本: +msg-56fb2950 = 创建媒体组缓存:{ $media_group_id } +msg-0de2d4b5 = 向媒体组添加消息{ $media_group_id }当前拥有{ $res }items. +msg-9e5069e9 = 媒体组{ $media_group_id }已达到最大等待时间({ $elapsed }s >={ $res }s), 立即处理。 +msg-9156b9d6 = 已安排的媒体组{ $media_group_id }待处理{ $delay }秒 (已等待{ $elapsed }s) +msg-2849c882 = 媒体组{ $media_group_id }未在缓存中找到 +msg-c75b2163 = 媒体组{ $media_group_id }为空 +msg-0a3626c1 = 正在处理媒体组{ $media_group_id },总计{ $res }项目 +msg-2842e389 = 媒体群组的首条消息转换失败{ $media_group_id } +msg-32fbf7c1 = 已添加{ $res }组件到媒体群组{ $media_group_id } +msg-23bae28a = Telegram 适配器已关闭。 +msg-e46e7740 = 关闭Telegram适配器时发生错误:{ $e } ### astrbot/core/platform/sources/slack/client.py -msg-1d6b68b9 = Slack request signature verification failed -msg-53ef18c3 = Received Slack event: {$event_data} -msg-58488af6 = 处理 Slack 事件时出错: {$e} -msg-477be979 = Slack Webhook 服务器启动中,监听 {$res}:{$res_2}{$res_3}... + +msg-1d6b68b9 = Slack请求签名验证失败 +msg-53ef18c3 = 已收到Slack事件:{ $event_data } +msg-58488af6 = 处理 Slack 事件时出错:{ $e } +msg-477be979 = Slack Webhook 服务器启动中,监听{ $res }待翻译文本:{ $res_2 }{ $res_3 }待翻译文本: msg-639fee6c = Slack Webhook 服务器已停止 -msg-a238d798 = Socket client is not initialized -msg-4e6de580 = 处理 Socket Mode 事件时出错: {$e} +msg-a238d798 = 套接字客户端未初始化 +msg-4e6de580 = 处理 Socket Mode 事件时出错:{ $e } msg-5bb71de9 = Slack Socket Mode 客户端启动中... msg-f79ed37f = Slack Socket Mode 客户端已停止 ### astrbot/core/platform/sources/slack/slack_adapter.py + msg-c34657ff = Slack bot_token 是必需的 msg-64f8a45d = Socket Mode 需要 app_token -msg-a2aba1a7 = Webhook Mode 需要 signing_secret -msg-40e00bd4 = Slack 发送消息失败: {$e} -msg-56c1d0a3 = [slack] RawMessage {$event} -msg-855510b4 = Failed to download slack file: {$res} {$res_2} -msg-04ab2fae = 下载文件失败: {$res} -msg-79ed7e65 = Slack auth test OK. Bot ID: {$res} +msg-a2aba1a7 = Webhook 模式需要签名密钥 +msg-40e00bd4 = Slack 发送消息失败:{ $e } +msg-56c1d0a3 = [slack] 原始消息{ $event } +msg-855510b4 = 下载Slack文件失败:{ $res } { $res_2 } +msg-04ab2fae = 下载文件失败:{ $res } +msg-79ed7e65 = Slack 认证测试通过。机器人 ID:{ $res } msg-ec27746a = Slack 适配器 (Socket Mode) 启动中... -msg-34222d3a = Slack 适配器 (Webhook Mode) 启动中,监听 {$res}:{$res_2}{$res_3}... -msg-6d8110d2 = 不支持的连接模式: {$res},请使用 'socket' 或 'webhook' +msg-34222d3a = Slack 适配器 (Webhook 模式) 启动中,监听{ $res }:{ $res_2 }{ $res_3 }... +msg-6d8110d2 = 不支持的连接模式:{ $res }请使用 'socket' 或 'webhook' msg-d71e7f36 = Slack 适配器已被关闭 ### astrbot/core/platform/sources/slack/slack_event.py -msg-b233107c = Slack file upload failed: {$res} -msg-596945d1 = Slack file upload response: {$response} + +msg-b233107c = Slack 文件上传失败:{ $res } +msg-596945d1 = Slack 文件上传响应:{ $response } ### astrbot/core/platform/sources/satori/satori_adapter.py -msg-ab7db6d9 = Satori WebSocket 连接关闭: {$e} -msg-4ef42cd1 = Satori WebSocket 连接失败: {$e} -msg-b50d159b = 达到最大重试次数 ({$max_retries}),停止重试 -msg-89de477c = Satori 适配器正在连接到 WebSocket: {$res} -msg-cfa5b059 = Satori 适配器 HTTP API 地址: {$res} -msg-d534864b = 无效的WebSocket URL: {$res} -msg-a110f9f7 = WebSocket URL必须以ws://或wss://开头: {$res} -msg-bf43ccb6 = Satori 处理消息异常: {$e} -msg-89081a1a = Satori WebSocket 连接异常: {$e} -msg-5c04bfcd = Satori WebSocket 关闭异常: {$e} -msg-b67bcee0 = WebSocket连接未建立 + +msg-ab7db6d9 = Satori WebSocket 连接关闭:{ $e } +msg-4ef42cd1 = Satori WebSocket 连接失败:{ $e } +msg-b50d159b = 达到最大重试次数 ({ $max_retries }),停止重试 +msg-89de477c = Satori 适配器正在连接到 WebSocket:{ $res } +msg-cfa5b059 = Satori 适配器 HTTP API 地址:{ $res } +msg-d534864b = 无效的WebSocket URL:{ $res } +msg-a110f9f7 = WebSocket URL必须以ws://或wss://开头{ $res } +msg-bf43ccb6 = Satori 处理消息异常:{ $e } +msg-89081a1a = Satori WebSocket 连接异常:{ $e } +msg-5c04bfcd = Satori WebSocket 关闭异常:{ $e } +msg-b67bcee0 = WebSocket connection is not established msg-89ea8b76 = WebSocket连接已关闭 -msg-4c8a40e3 = 发送 IDENTIFY 信令时连接关闭: {$e} -msg-05a6b99d = 发送 IDENTIFY 信令失败: {$e} -msg-c9b1b774 = Satori WebSocket 发送心跳失败: {$e} -msg-61edb4f3 = 心跳任务异常: {$e} -msg-7db44899 = Satori 连接成功 - Bot {$res}: platform={$platform}, user_id={$user_id}, user_name={$user_name} -msg-01564612 = 解析 WebSocket 消息失败: {$e}, 消息内容: {$message} -msg-3a1657ea = 处理 WebSocket 消息异常: {$e} -msg-dc6b459c = 处理事件失败: {$e} -msg-6524f582 = 解析标签时发生错误: {$e}, 错误内容: {$content} -msg-3be535c3 = 转换 Satori 消息失败: {$e} -msg-be17caf1 = XML解析失败,使用正则提取: {$e} -msg-f6f41d74 = 提取标签时发生错误: {$e} -msg-ca6dca7f = 转换引用消息失败: {$e} -msg-cd3b067e = 解析 Satori 元素时发生解析错误: {$e}, 错误内容: {$content} -msg-03071274 = 解析 Satori 元素时发生未知错误: {$e} -msg-775cd5c0 = HTTP session 未初始化 -msg-e354c8d1 = Satori HTTP 请求异常: {$e} +msg-4c8a40e3 = Connection closed while sending IDENTIFY signal.{ $e } +msg-05a6b99d = Failed to send IDENTIFY signal:{ $e } +msg-c9b1b774 = Satori WebSocket 发送心跳失败:{ $e } +msg-61edb4f3 = 心跳任务异常:{ $e } +msg-7db44899 = Satori 连接成功 - 机器人{ $res }: platform={ $platform }用户ID={ $user_id }用户名={ $user_name } +msg-01564612 = 解析 WebSocket 消息失败:{ $e }消息内容:{ $message } +msg-3a1657ea = 处理 WebSocket 消息异常:{ $e } +msg-dc6b459c = Failed to process event:{ $e } +msg-6524f582 = 解析标签时发生错误:{ $e }, 错误内容:{ $content } +msg-3be535c3 = 转换 Satori 消息失败:{ $e } +msg-be17caf1 = XML解析失败,使用正则提取:{ $e } +msg-f6f41d74 = 提取标签时发生错误:{ $e } +msg-ca6dca7f = Failed to convert referenced message:{ $e } +msg-cd3b067e = 解析 Satori 元素时发生解析错误:{ $e }, 错误内容:{ $content } +msg-03071274 = 解析 Satori 元素时发生未知错误:{ $e } +msg-775cd5c0 = HTTP 会话未初始化 +msg-e354c8d1 = Satori HTTP 请求异常:{ $e } ### astrbot/core/platform/sources/satori/satori_event.py -msg-c063ab8a = Satori 消息发送异常: {$e} + +msg-c063ab8a = Satori 消息发送异常:{ $e } msg-9bc42a8d = Satori 消息发送失败 -msg-dbf77ca2 = 图片转换为base64失败: {$e} -msg-8b6100fb = Satori 流式消息发送异常: {$e} -msg-3c16c45c = 语音转换为base64失败: {$e} -msg-66994127 = 视频文件转换失败: {$e} -msg-30943570 = 转换消息组件失败: {$e} -msg-3e8181fc = 转换转发节点失败: {$e} -msg-d626f831 = 转换合并转发消息失败: {$e} +msg-dbf77ca2 = 图片转换为base64失败:{ $e } +msg-8b6100fb = Satori 流式消息发送异常:{ $e } +msg-3c16c45c = 语音转换为base64失败:{ $e } +msg-66994127 = 视频文件转换失败:{ $e } +msg-30943570 = Failed to convert message component:{ $e } +msg-3e8181fc = 转换转发节点失败:{ $e } +msg-d626f831 = 转换合并转发消息失败:{ $e } ### astrbot/core/platform/sources/webchat/webchat_queue_mgr.py -msg-4af4f885 = Started listener for conversation: {$conversation_id} -msg-10237240 = Error processing message from conversation {$conversation_id}: {$e} + +msg-4af4f885 = 已启动对话监听器:{ $conversation_id } +msg-10237240 = 处理来自对话的消息时出错{ $conversation_id }待翻译文本:{ $e } ### astrbot/core/platform/sources/webchat/webchat_adapter.py -msg-9406158c = WebChatAdapter: {$res} + +msg-9406158c = WebChatAdapter:{ $res } ### astrbot/core/platform/sources/webchat/webchat_event.py -msg-6b37adcd = webchat 忽略: {$res} + +msg-6b37adcd = webchat 忽略:{ $res } ### astrbot/core/platform/sources/qqofficial/qqofficial_platform_adapter.py + msg-8af45ba1 = QQ 机器人官方 API 适配器不支持 send_by_session -msg-8ebd1249 = Unknown message type: {$message_type} -msg-c165744d = QQ 官方机器人接口 适配器已被优雅地关闭 +msg-8ebd1249 = 未知消息类型:{ $message_type } +msg-c165744d = QQ官方机器人接口适配器已被优雅地关闭 ### astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py -msg-28a74d9d = [QQOfficial] Skip botpy FormData patch. -msg-c0b123f6 = 发送流式消息时出错: {$e} -msg-05d6bba5 = [QQOfficial] 不支持的消息源类型: {$res} + +msg-28a74d9d = [QQ官方] 跳过 botpy FormData 补丁。 +msg-c0b123f6 = 发送流式消息时出错:{ $e } +msg-05d6bba5 = [QQOfficial] 不支持的消息源类型:{ $res } msg-e5339577 = [QQOfficial] GroupMessage 缺少 group_openid -msg-71275806 = Message sent to C2C: {$ret} -msg-040e7942 = [QQOfficial] markdown 发送被拒绝,回退到 content 模式重试。 -msg-9000f8f7 = Invalid upload parameters -msg-d72cffe7 = Failed to upload image, response is not dict: {$result} -msg-5944a27c = 上传文件响应格式错误: {$result} -msg-1e513ee5 = 上传请求错误: {$e} -msg-f1f1733c = Failed to post c2c message, response is not dict: {$result} -msg-9b8f9f70 = Unsupported image file format +msg-71275806 = 消息已发送至C2C:{ $ret } +msg-040e7942 = [QQOfficial] Markdown 发送被拒绝,已回退到内容模式重试。 +msg-9000f8f7 = 无效的上传参数 +msg-d72cffe7 = 上传图片失败,响应不是字典类型:{ $result } +msg-5944a27c = 上传文件响应格式错误:{ $result } +msg-1e513ee5 = 上传请求错误:{ $e } +msg-f1f1733c = 发布C2C消息失败,响应不是字典类型:{ $result } +msg-9b8f9f70 = 不支持的图像文件格式 msg-24eb302a = 转换音频格式时出错:音频时长不大于0 -msg-b49e55f9 = 处理语音时出错: {$e} -msg-6e716579 = qq_official 忽略 {$res} +msg-b49e55f9 = 处理语音时出错:{ $e } +msg-6e716579 = qq_official 忽略{ $res } ### astrbot/core/provider/provider.py -msg-e6f0c96f = Provider type {$provider_type_name} not registered -msg-c7953e3f = 批次 {$batch_idx} 处理失败,已重试 {$max_retries} 次: {$e} -msg-10f72727 = {$error_msg} -msg-7ff71721 = Rerank provider test failed, no results returned + +msg-e6f0c96f = 提供者类型{ $provider_type_name }未注册 +msg-c7953e3f = 批次{ $batch_idx }处理失败,已重试{ $max_retries }次:{ $e } +msg-10f72727 = { $error_msg } +msg-7ff71721 = 重排服务提供者测试失败,未返回任何结果 ### astrbot/core/provider/register.py -msg-19ddffc0 = 检测到大模型提供商适配器 {$provider_type_name} 已经注册,可能发生了大模型提供商适配器类型命名冲突。 -msg-7e134b0d = 服务提供商 Provider {$provider_type_name} 已注册 + +msg-19ddffc0 = 检测到大模型提供商适配器{ $provider_type_name }已经注册,可能发生了大模型提供商适配器类型命名冲突。 +msg-7e134b0d = 服务提供商 Provider{ $provider_type_name }已注册 ### astrbot/core/provider/func_tool_manager.py -msg-0c42a4d9 = 添加函数调用工具: {$name} -msg-e8fdbb8c = 未找到 MCP 服务配置文件,已创建默认配置文件 {$mcp_json_file} -msg-cf8aed84 = 收到 MCP 客户端 {$name} 终止信号 -msg-3d7bcc64 = 初始化 MCP 客户端 {$name} 失败 -msg-1b190842 = MCP server {$name} list tools response: {$tools_res} -msg-6dc4f652 = 已连接 MCP 服务 {$name}, Tools: {$tool_names} -msg-a44aa4f2 = 清空 MCP 客户端资源 {$name}: {$e}。 -msg-e9c96c53 = 已关闭 MCP 服务 {$name} -msg-10f72727 = {$error_msg} -msg-85f156e0 = testing MCP server connection with config: {$config} -msg-93c54ce0 = Cleaning up MCP client after testing connection. -msg-368450ee = 此函数调用工具所属的插件 {$res} 已被禁用,请先在管理面板启用再激活此工具。 -msg-4ffa2135 = 加载 MCP 配置失败: {$e} -msg-a486ac39 = 保存 MCP 配置失败: {$e} -msg-58dfdfe7 = 从 ModelScope 同步了 {$synced_count} 个 MCP 服务器 + +msg-0c42a4d9 = 添加函数调用工具:{ $name } +msg-e8fdbb8c = 未找到 MCP 服务配置文件,已创建默认配置文件{ $mcp_json_file } +msg-cf8aed84 = 收到 MCP 客户端{ $name }终止信号 +msg-3d7bcc64 = 初始化 MCP 客户端{ $name }失败 +msg-1b190842 = MCP 服务器{ $name }列出工具响应:{ $tools_res } +msg-6dc4f652 = 已连接 MCP 服务{ $name }工具:{ $tool_names } +msg-a44aa4f2 = 清空 MCP 客户端资源{ $name }:{ $e }。 +msg-e9c96c53 = 已关闭 MCP 服务{ $name } +msg-10f72727 = { $error_msg } +msg-85f156e0 = 正在使用配置测试 MCP 服务器连接:{ $config } +msg-93c54ce0 = 测试连接后正在清理MCP客户端。 +msg-368450ee = 此函数调用工具所属的插件{ $res }此功能已被禁用,请在管理面板中启用后再激活此工具。 +msg-4ffa2135 = Loading MCP configuration failed:{ $e } +msg-a486ac39 = Failed to save MCP configuration:{ $e } +msg-58dfdfe7 = 从 ModelScope 同步了{ $synced_count }MCP 服务器 msg-75f1222f = 没有找到可用的 ModelScope MCP 服务器 -msg-c9f6cb1d = ModelScope API 请求失败: HTTP {$res} -msg-c8ebb4f7 = 网络连接错误: {$e} -msg-0ac6970f = 同步 ModelScope MCP 服务器时发生错误: {$e} +msg-c9f6cb1d = ModelScope API 请求失败: HTTP{ $res } +msg-c8ebb4f7 = 网络连接错误:{ $e } +msg-0ac6970f = 同步 ModelScope MCP 服务器时发生错误:{ $e } ### astrbot/core/provider/entities.py -msg-7fc6f623 = 图片 {$image_url} 得到的结果为空,将忽略。 + +msg-7fc6f623 = 图片{ $image_url }The result is empty and will be ignored. ### astrbot/core/provider/manager.py -msg-9e1a7f1f = 提供商 {$provider_id} 不存在,无法设置。 -msg-5fda2049 = Unknown provider type: {$provider_type} -msg-a5cb19c6 = 没有找到 ID 为 {$provider_id} 的提供商,这可能是由于您修改了提供商(模型)ID 导致的。 -msg-78b9c276 = {$res} -msg-5bdf8f5c = {$e} -msg-b734a1f4 = Provider {$provider_id} 配置项 key[{$idx}] 使用环境变量 {$env_key} 但未设置。 -msg-664b3329 = Provider {$res} is disabled, skipping -msg-f43f8022 = 载入 {$res}({$res_2}) 服务提供商 ... -msg-edd4aefe = 加载 {$res}({$res_2}) 提供商适配器失败:{$e}。可能是因为有未安装的依赖。 -msg-78e514a1 = 加载 {$res}({$res_2}) 提供商适配器失败:{$e}。未知原因 -msg-4636f83c = 未找到适用于 {$res}({$res_2}) 的提供商适配器,请检查是否已经安装或者名称填写错误。已跳过。 -msg-e9c6c4a2 = 无法找到 {$res} 的类 -msg-f705cf50 = Provider class {$cls_type} is not a subclass of STTProvider -msg-d20620aa = 已选择 {$res}({$res_2}) 作为当前语音转文本提供商适配器。 -msg-afbe5661 = Provider class {$cls_type} is not a subclass of TTSProvider -msg-74d437ed = 已选择 {$res}({$res_2}) 作为当前文本转语音提供商适配器。 -msg-08cd85c9 = Provider class {$cls_type} is not a subclass of Provider -msg-16a2b8e0 = 已选择 {$res}({$res_2}) 作为当前提供商适配器。 -msg-0e1707e7 = Provider class {$cls_type} is not a subclass of EmbeddingProvider -msg-821d06e0 = Provider class {$cls_type} is not a subclass of RerankProvider -msg-14c35664 = 未知的提供商类型:{$res} -msg-186fd5c6 = 实例化 {$res}({$res_2}) 提供商适配器失败:{$e} -msg-ede02a99 = providers in user's config: {$config_ids} -msg-95dc4227 = 自动选择 {$res} 作为当前提供商适配器。 -msg-a6187bac = 自动选择 {$res} 作为当前语音转文本提供商适配器。 -msg-bf28f7e2 = 自动选择 {$res} 作为当前文本转语音提供商适配器。 -msg-dba10c27 = 终止 {$provider_id} 提供商适配器({$res}, {$res_2}, {$res_3}) ... -msg-9d9d9765 = {$provider_id} 提供商适配器已终止({$res}, {$res_2}, {$res_3}) -msg-925bb70a = Provider {$target_prov_ids} 已从配置中删除。 -msg-a1657092 = New provider config must have an 'id' field -msg-1486c653 = Provider ID {$npid} already exists -msg-f9fc1545 = Provider ID {$origin_provider_id} not found -msg-4e2c657c = Error while disabling MCP servers + +msg-9e1a7f1f = Provider{ $provider_id }不存在,无法设置。 +msg-5fda2049 = 未知的提供者类型:{ $provider_type } +msg-a5cb19c6 = 没有找到 ID 为{ $provider_id }的提供商,这可能是由于您修改了提供商(模型)ID 导致的。 +msg-78b9c276 = { $res } +msg-5bdf8f5c = { $e } +msg-b734a1f4 = 提供程序{ $provider_id }配置项 key{ $idx }使用环境变量{ $env_key }但未设置。 +msg-664b3329 = 提供者{ $res }已禁用,正在跳过 +msg-f43f8022 = 载入{ $res }待翻译文本:({ $res_2 }) 服务提供商 ... +msg-edd4aefe = 加载{ $res }待翻译文本:{ $res_2 }) 提供商适配器失败:{ $e }。可能是因为有未安装的依赖。 +msg-78e514a1 = 加载{ $res }({ $res_2 }) 提供商适配器失败:{ $e }。未知原因 +msg-4636f83c = No applicable found{ $res }待翻译文本:{ $res_2 }) 的提供商适配器,请检查是否已经安装或者名称填写错误。已跳过。 +msg-e9c6c4a2 = 无法找到{ $res }的类 +msg-f705cf50 = Provider 类{ $cls_type }不是STTProvider的子类 +msg-d20620aa = 已选择{ $res }待翻译文本:{ $res_2 }) 作为当前语音转文本提供商适配器。 +msg-afbe5661 = 提供者类{ $cls_type }不是 TTSProvider 的子类 +msg-74d437ed = 已选择{ $res }待翻译文本:{ $res_2 }) 作为当前文本转语音提供商适配器。 +msg-08cd85c9 = 提供者类{ $cls_type }不是 Provider 的子类 +msg-16a2b8e0 = 已选择{ $res }待翻译文本:{ $res_2 }) 作为当前提供商适配器。 +msg-0e1707e7 = 提供者类{ $cls_type }不是EmbeddingProvider的子类 +msg-821d06e0 = 提供者类{ $cls_type }不是 RerankProvider 的子类 +msg-14c35664 = 未知的提供商类型:{ $res } +msg-186fd5c6 = 实例化{ $res }待翻译文本:{ $res_2 }) 提供商适配器失败:{ $e } +msg-ede02a99 = 用户配置中的提供者:{ $config_ids } +msg-95dc4227 = 自动选择{ $res }作为当前提供商适配器。 +msg-a6187bac = 自动选择{ $res }作为当前语音转文本提供商适配器。 +msg-bf28f7e2 = 自动选择{ $res }作为当前文本转语音提供商适配器。 +msg-dba10c27 = 终止{ $provider_id }Provider Adapter{ $res },{ $res_2 },{ $res_3 }) ... +msg-9d9d9765 = { $provider_id }Provider adapter has been terminated({ $res },{ $res_2 },{ $res_3 }) +msg-925bb70a = 提供者{ $target_prov_ids }已从配置中删除。 +msg-a1657092 = 新提供程序配置必须包含一个'id'字段。 +msg-1486c653 = 提供商ID{ $npid }已存在 +msg-f9fc1545 = 提供商 ID{ $origin_provider_id }未找到 +msg-4e2c657c = 禁用 MCP 服务器时出错 ### astrbot/core/provider/sources/gemini_embedding_source.py -msg-173efb0e = [Gemini Embedding] 使用代理: {$proxy} -msg-58a99789 = Gemini Embedding API请求失败: {$res} -msg-5c4ea38e = Gemini Embedding API批量请求失败: {$res} + +msg-173efb0e = [Gemini Embedding] 使用代理:{ $proxy } +msg-58a99789 = Gemini Embedding API请求失败:{ $res } +msg-5c4ea38e = Gemini Embedding API批量请求失败:{ $res } ### astrbot/core/provider/sources/bailian_rerank_source.py + msg-dc1a9e6e = 阿里云百炼 API Key 不能为空。 -msg-f7079f37 = AstrBot 百炼 Rerank 初始化完成。模型: {$res} -msg-5b6d35ce = 百炼 API 错误: {$res} – {$res_2} -msg-d600c5e2 = 百炼 Rerank 返回空结果: {$data} -msg-d3312319 = 结果 {$idx} 缺少 relevance_score,使用默认值 0.0 -msg-2855fb44 = 解析结果 {$idx} 时出错: {$e}, result={$result} -msg-392f26e8 = 百炼 Rerank 消耗 Token: {$tokens} +msg-f7079f37 = AstrBot 百炼 Rerank 初始化完成。模型:{ $res } +msg-5b6d35ce = 百炼 API 错误:{ $res }–{ $res_2 } +msg-d600c5e2 = 百炼 Rerank 返回空结果:{ $data } +msg-d3312319 = Result{ $idx }缺少 relevance_score,使用默认值 0.0 +msg-2855fb44 = 解析结果{ $idx }时出错:{ $e }, result={ $result } +msg-392f26e8 = 百炼 Rerank 消耗 Token:{ $tokens } msg-595e0cf9 = 百炼 Rerank 客户端会话已关闭,返回空结果 msg-d0388210 = 文档列表为空,返回空结果 msg-44d6cc76 = 查询文本为空,返回空结果 -msg-bd8b942a = 文档数量({$res})超过限制(500),将截断前500个文档 -msg-0dc3bca4 = 百炼 Rerank 请求: query='{$res}...', 文档数量={$res_2} -msg-4a9f4ee3 = 百炼 Rerank 成功返回 {$res} 个结果 -msg-fa301307 = 百炼 Rerank 网络请求失败: {$e} -msg-10f72727 = {$error_msg} -msg-9879e226 = 百炼 Rerank 处理失败: {$e} +msg-bd8b942a = 文档数量({ $res })超过限制(500),将截断前500个文档 +msg-0dc3bca4 = 百炼 Rerank 请求: query='{ $res }...', 文档数量={ $res_2 } +msg-4a9f4ee3 = 百炼 Rerank 成功返回{ $res }个结果 +msg-fa301307 = 百炼 Rerank 网络请求失败:{ $e } +msg-10f72727 = { $error_msg } +msg-9879e226 = 百炼 Rerank 处理失败:{ $e } msg-4f15074c = 关闭 百炼 Rerank 客户端会话 -msg-d01b1b0f = 关闭 百炼 Rerank 客户端时出错: {$e} +msg-d01b1b0f = 关闭 百炼 Rerank 客户端时出错:{ $e } ### astrbot/core/provider/sources/edge_tts_source.py -msg-f4ab0713 = pyffmpeg 转换失败: {$e}, 尝试使用 ffmpeg 命令行进行转换 -msg-ddc3594a = [EdgeTTS] FFmpeg 标准输出: {$res} -msg-1b8c0a83 = FFmpeg错误输出: {$res} -msg-1e980a68 = [EdgeTTS] 返回值(0代表成功): {$res} + +msg-f4ab0713 = pyffmpeg 转换失败:{ $e }尝试使用 ffmpeg 命令行进行转换 +msg-ddc3594a = [EdgeTTS] FFmpeg 标准输出:{ $res } +msg-1b8c0a83 = FFmpeg错误输出:{ $res } +msg-1e980a68 = [EdgeTTS] 返回值(0代表成功):{ $res } msg-c39d210c = 生成的WAV文件不存在或为空 -msg-57f60837 = FFmpeg 转换失败: {$res} -msg-ca94a42a = FFmpeg 转换失败: {$e} -msg-be660d63 = 音频生成失败: {$e} +msg-57f60837 = FFmpeg 转换失败:{ $res } +msg-ca94a42a = FFmpeg 转换失败:{ $e } +msg-be660d63 = Audio generation failed:{ $e } ### astrbot/core/provider/sources/whisper_api_source.py -msg-28cbbf07 = 文件不存在: {$audio_url} -msg-b335b8db = Converting silk file to wav using tencent_silk_to_wav... -msg-68b5660f = Converting amr file to wav using convert_to_pcm_wav... -msg-cad3735e = Failed to remove temp file {$audio_url}: {$e} + +msg-28cbbf07 = 文件不存在:{ $audio_url } +msg-b335b8db = 正在使用tencent_silk_to_wav将silk文件转换为wav... +msg-68b5660f = 正在使用convert_to_pcm_wav将amr文件转换为wav... +msg-cad3735e = 无法删除临时文件{ $audio_url }待翻译文本:{ $e } ### astrbot/core/provider/sources/gemini_source.py -msg-1474947f = [Gemini] 使用代理: {$proxy} -msg-e2a81024 = 检测到 Key 异常({$res}),正在尝试更换 API Key 重试... 当前 Key: {$res_2}... -msg-0d388dae = 检测到 Key 异常({$res}),且已没有可用的 Key。 当前 Key: {$res_2}... -msg-1465290c = 达到了 Gemini 速率限制, 请稍后再试... -msg-7e9c01ca = 流式输出不支持图片模态,已自动降级为文本模态 + +msg-1474947f = [Gemini] 使用代理:{ $proxy } +msg-e2a81024 = 检测到 Key 异常{ $res }),正在尝试更换 API Key 重试... 当前 Key:{ $res_2 }... +msg-0d388dae = 检测到 Key 异常{ $res }),且已没有可用的 Key。 当前 Key:{ $res_2 }... +msg-1465290c = 已达到 Gemini 速率限制,请稍后再试... +msg-7e9c01ca = Streaming output does not support image modality and has been automatically downgraded to text modality. msg-89bac423 = 代码执行工具与搜索工具互斥,已忽略搜索工具 msg-301cf76e = 代码执行工具与URL上下文工具互斥,已忽略URL上下文工具 msg-356e7b28 = 当前 SDK 版本不支持 URL 上下文工具,已忽略该设置,请升级 google-genai 包 msg-7d4e7d48 = gemini-2.0-lite 不支持代码执行、搜索工具和URL上下文,将忽略这些设置 msg-cc5c666f = 已启用原生工具,函数工具将被忽略 -msg-aa7c77a5 = Invalid thinking level: {$thinking_level}, using HIGH +msg-aa7c77a5 = 无效的思考级别:{ $thinking_level }使用 HIGH msg-59e1e769 = 文本内容为空,已添加空格占位 -msg-34c5c910 = Failed to decode google gemini thinking signature: {$e} +msg-34c5c910 = 无法解码谷歌双子座思维签名:{ $e } msg-a2357584 = assistant 角色的消息内容为空,已添加空格占位 msg-f627f75d = 检测到启用Gemini原生工具,且上下文中存在函数调用,建议使用 /reset 重置上下文 -msg-cb743183 = 收到的 candidate.content 为空: {$candidate} +msg-cb743183 = 收到的 candidate.content 为空:{ $candidate } msg-34b367fc = API 返回的 candidate.content 为空。 -msg-73541852 = 模型生成内容未通过 Gemini 平台的安全检查 +msg-73541852 = Model-generated content failed Gemini platform security checks msg-ae3cdcea = 模型生成内容违反 Gemini 平台政策 -msg-5d8f1711 = 收到的 candidate.content.parts 为空: {$candidate} +msg-5d8f1711 = 收到的 candidate.content.parts 为空:{ $candidate } msg-57847bd5 = API 返回的 candidate.content.parts 为空。 -msg-a56c85e4 = genai result: {$result} -msg-42fc0767 = 请求失败, 返回的 candidates 为空: {$result} -msg-faf3a0dd = 请求失败, 返回的 candidates 为空。 -msg-cd690916 = 温度参数已超过最大值2,仍然发生recitation -msg-632e23d7 = 发生了recitation,正在提高温度至{$temperature}重试... -msg-41ff84bc = {$model} 不支持 system prompt,已自动去除(影响人格设置) -msg-ef9512f7 = {$model} 不支持函数调用,已自动去除 -msg-fde41b1d = {$model} 不支持多模态输出,降级为文本模态 -msg-4e168d67 = 收到的 chunk 中 candidates 为空: {$chunk} -msg-11af7d46 = 收到的 chunk 中 content 为空: {$chunk} -msg-8836d4a2 = 请求失败。 -msg-757d3828 = 获取模型列表失败: {$res} -msg-7fc6f623 = 图片 {$image_url} 得到的结果为空,将忽略。 -msg-0b041916 = 不支持的额外内容块类型: {$res} +msg-a56c85e4 = 生成式AI结果:{ $result } +msg-42fc0767 = 请求失败,返回的 candidates 为空:{ $result } +msg-faf3a0dd = 请求失败,返回的 candidates 为空。 +msg-cd690916 = 温度参数已超过最大值2,仍然发生重复读取 +msg-632e23d7 = 发生了重算,正在提高温度至{ $temperature }重试... +msg-41ff84bc = { $model }不支持系统提示,已自动移除(影响角色设定) +msg-ef9512f7 = { $model }不支持函数调用,已自动去除 +msg-fde41b1d = { $model }不支持多模态输出,降级为文本模态 +msg-4e168d67 = 收到的 chunk 中 candidates 为空:{ $chunk } +msg-11af7d46 = 收到的 chunk 中 content 为空:{ $chunk } +msg-8836d4a2 = Request failed. +msg-757d3828 = 获取模型列表失败:{ $res } +msg-7fc6f623 = Image{ $image_url }得到的结果为空,将忽略。 +msg-0b041916 = Unsupported extra content block type:{ $res } ### astrbot/core/provider/sources/gsvi_tts_source.py -msg-520e410f = GSVI TTS API 请求失败,状态码: {$res},错误: {$error_text} + +msg-520e410f = GSVI TTS API 请求失败,状态码:{ $res }错误:{ $error_text } ### astrbot/core/provider/sources/anthropic_source.py -msg-d6b1df6e = Failed to parse image data URI: {$res}... -msg-6c2c0426 = Unsupported image URL format for Anthropic: {$res}... -msg-999f7680 = completion: {$completion} + +msg-d6b1df6e = 无法解析图像数据URI:{ $res }... +msg-6c2c0426 = Anthropic不支持的图片URL格式:{ $res }... +msg-999f7680 = completion:{ $completion } msg-8d2c43ec = API 返回的 completion 为空。 -msg-26140afc = Anthropic API 返回的 completion 无法解析:{$completion}。 -msg-8e4c8c24 = 工具调用参数 JSON 解析失败: {$tool_info} -msg-7fc6f623 = 图片 {$image_url} 得到的结果为空,将忽略。 -msg-0b041916 = 不支持的额外内容块类型: {$res} +msg-26140afc = Anthropic API 返回的 completion 无法解析:{ $completion }。 +msg-8e4c8c24 = 工具调用参数 JSON 解析失败:{ $tool_info } +msg-7fc6f623 = 图片{ $image_url }结果为空,将忽略。 +msg-0b041916 = 不支持的额外内容块类型:{ $res } ### astrbot/core/provider/sources/openai_source.py + msg-bbb399f6 = 检测到图片请求失败(%s),已移除图片并重试(保留文本内容)。 -msg-d6f6a3c2 = 获取模型列表失败:{$e} -msg-1f850e09 = API 返回的 completion 类型错误:{$res}: {$completion}。 -msg-999f7680 = completion: {$completion} -msg-844635f7 = Unexpected dict format content: {$raw_content} +msg-d6f6a3c2 = 获取模型列表失败:{ $e } +msg-1f850e09 = API 返回的 completion 类型错误:{ $res }:{ $completion }。 +msg-999f7680 = 完成:{ $completion } +msg-844635f7 = 意外的字典格式内容:{ $raw_content } msg-8d2c43ec = API 返回的 completion 为空。 -msg-87d75331 = {$completion_text} +msg-87d75331 = { $completion_text } msg-0614efaf = 工具集未提供 msg-c46f067a = API 返回的 completion 由于内容安全过滤被拒绝(非 AstrBot)。 -msg-647f0002 = API 返回的 completion 无法解析:{$completion}。 -msg-5cc50a15 = API 调用过于频繁,尝试使用其他 Key 重试。当前 Key: {$res} -msg-c4e639eb = 上下文长度超过限制。尝试弹出最早的记录然后重试。当前记录条数: {$res} -msg-5f8be4fb = {$res} 不支持函数工具调用,已自动去除,不影响使用。 +msg-647f0002 = API 返回的 completion 无法解析:{ $completion }。 +msg-5cc50a15 = API 调用过于频繁,尝试使用其他 Key 重试。当前 Key:{ $res } +msg-c4e639eb = 上下文长度超过限制。尝试弹出最早的记录然后重试。当前记录条数:{ $res } +msg-5f8be4fb = { $res }不支持函数工具调用,已自动去除,不影响使用。 msg-45591836 = 疑似该模型不支持函数调用工具调用。请输入 /tool off_all -msg-6e47d22a = API 调用失败,重试 {$max_retries} 次仍然失败。 +msg-6e47d22a = API 调用失败,重试{ $max_retries }It still fails. msg-974e7484 = 未知错误 -msg-7fc6f623 = 图片 {$image_url} 得到的结果为空,将忽略。 -msg-0b041916 = 不支持的额外内容块类型: {$res} +msg-7fc6f623 = Image{ $image_url }得到的结果为空,将忽略。 +msg-0b041916 = 不支持的额外内容块类型:{ $res } ### astrbot/core/provider/sources/gemini_tts_source.py -msg-29fe386a = [Gemini TTS] 使用代理: {$proxy} -msg-012edfe1 = No audio content returned from Gemini TTS API. + +msg-29fe386a = [Gemini TTS] 使用代理:{ $proxy } +msg-012edfe1 = Gemini TTS API 未返回任何音频内容。 ### astrbot/core/provider/sources/genie_tts.py -msg-583dd8a6 = Please install genie_tts first. -msg-935222b4 = Failed to load character {$res}: {$e} -msg-a6886f9e = Genie TTS did not save to file. -msg-e3587d60 = Genie TTS generation failed: {$e} -msg-3303e3a8 = Genie TTS failed to generate audio for: {$text} -msg-1cfe1af1 = Genie TTS stream error: {$e} + +msg-583dd8a6 = 请先安装 genie_tts。 +msg-935222b4 = 加载角色失败{ $res }:{ $e } +msg-a6886f9e = Genie TTS 未保存到文件。 +msg-e3587d60 = Genie TTS 生成失败:{ $e } +msg-3303e3a8 = Genie TTS 未能为以下内容生成音频:{ $text } +msg-1cfe1af1 = Genie TTS 流错误:{ $e } ### astrbot/core/provider/sources/dashscope_tts.py -msg-f23d2372 = Dashscope TTS model is not configured. -msg-74a7cc0a = Audio synthesis failed, returned empty content. The model may not be supported or the service is unavailable. -msg-bc8619d3 = dashscope SDK missing MultiModalConversation. Please upgrade the dashscope package to use Qwen TTS models. -msg-95bbf71e = No voice specified for Qwen TTS model, using default 'Cherry'. -msg-3c35d2d0 = Audio synthesis failed for model '{$model}'. {$response} -msg-16dc3b00 = Failed to decode base64 audio data. -msg-26603085 = Failed to download audio from URL {$url}: {$e} -msg-78b9c276 = {$res} + +msg-f23d2372 = Dashscope TTS 模型未配置。 +msg-74a7cc0a = 音频合成失败,返回空内容。可能是模型不受支持或服务不可用。 +msg-bc8619d3 = dashscope SDK缺少MultiModalConversation模块。请升级dashscope包以使用Qwen TTS模型。 +msg-95bbf71e = 未为Qwen TTS模型指定语音,将使用默认语音'Cherry'。 +msg-3c35d2d0 = 模型 '{$modelName}' 的音频合成失败{ $model }'.'{ $response } +msg-16dc3b00 = 无法解码Base64音频数据。 +msg-26603085 = 无法从URL下载音频{ $url }:{ $e } +msg-78b9c276 = { $res } ### astrbot/core/provider/sources/whisper_selfhosted_source.py + msg-27fda50a = 下载或者加载 Whisper 模型中,这可能需要一些时间 ... msg-4e70f563 = Whisper 模型加载完成。 -msg-28cbbf07 = 文件不存在: {$audio_url} -msg-d98780e5 = Converting silk file to wav ... +msg-28cbbf07 = 文件不存在:{ $audio_url } +msg-d98780e5 = 正在将 silk 文件转换为 wav ... msg-e3e1215c = Whisper 模型未初始化 ### astrbot/core/provider/sources/openai_tts_api_source.py -msg-d7084760 = [OpenAI TTS] 使用代理: {$proxy} + +msg-d7084760 = [OpenAI TTS] 使用代理:{ $proxy } ### astrbot/core/provider/sources/xinference_rerank_source.py -msg-1ec1e6e4 = Xinference Rerank: Using API key for authentication. -msg-7bcb6e1b = Xinference Rerank: No API key provided. -msg-b0d1e564 = Model '{$res}' is already running with UID: {$uid} -msg-16965859 = Launching {$res} model... -msg-7b1dfdd3 = Model launched. -msg-3fc7310e = Model '{$res}' is not running and auto-launch is disabled. Provider will not be available. -msg-15f19a42 = Failed to initialize Xinference model: {$e} -msg-01af1651 = Xinference initialization failed with exception: {$e} -msg-2607cc7a = Xinference rerank model is not initialized. -msg-3d28173b = Rerank API response: {$response} -msg-4c63e1bd = Rerank API returned an empty list. Original response: {$response} -msg-cac71506 = Xinference rerank failed: {$e} -msg-4135cf72 = Xinference rerank failed with exception: {$e} -msg-ea2b36d0 = Closing Xinference rerank client... -msg-633a269f = Failed to close Xinference client: {$e} + +msg-1ec1e6e4 = Xinference Rerank:使用 API 密钥进行身份验证。 +msg-7bcb6e1b = Xinference Rerank: 未提供API密钥。 +msg-b0d1e564 = 模型{ $res }' 已经在以 UID: 运行{ $uid } +msg-16965859 = 启动中{ $res }模型... +msg-7b1dfdd3 = 模型已启动。 +msg-3fc7310e = 模型{ $res }未在运行,且自动启动功能已禁用。提供商将不可用。 +msg-15f19a42 = 初始化Xinference模型失败:{ $e } +msg-01af1651 = Xinference初始化失败,异常信息:{ $e } +msg-2607cc7a = Xinference重排序模型尚未初始化。 +msg-3d28173b = 重排API响应:{ $response } +msg-4c63e1bd = Rerank API 返回了空列表。原始响应:{ $response } +msg-cac71506 = Xinference 重新排序失败:{ $e } +msg-4135cf72 = Xinference 重排失败,异常信息:{ $e } +msg-ea2b36d0 = 正在关闭Xinference重排客户端... +msg-633a269f = 关闭 Xinference 客户端失败:{ $e } ### astrbot/core/provider/sources/minimax_tts_api_source.py -msg-77c88c8a = Failed to parse JSON data from SSE message -msg-7873b87b = MiniMax TTS API请求失败: {$e} + +msg-77c88c8a = 解析SSE消息中的JSON数据失败 +msg-7873b87b = MiniMax TTS API请求失败:{ $e } ### astrbot/core/provider/sources/azure_tts_source.py -msg-93d9b5cf = [Azure TTS] 使用代理: {$res} -msg-9eea5bcb = Client not initialized. Please use 'async with' context. + +msg-93d9b5cf = [Azure TTS] 使用代理:{ $res } +msg-9eea5bcb = 客户端未初始化。请使用'async with'上下文。 msg-fd53d21d = 时间同步失败 -msg-77890ac4 = OTTS请求失败: {$e} +msg-77890ac4 = OTTS请求失败:{ $e } msg-c6ec6ec7 = OTTS未返回音频文件 msg-5ad71900 = 无效的Azure订阅密钥 -msg-6416da27 = [Azure TTS Native] 使用代理: {$res} -msg-15c55ed8 = 无效的other[...]格式,应形如 other[{...}] -msg-90b31925 = 缺少OTTS参数: {$res} -msg-10f72727 = {$error_msg} -msg-60b044ea = 配置错误: 缺少必要参数 {$e} -msg-5c7dee08 = 订阅密钥格式无效,应为32位字母数字或other[...]格式 +msg-6416da27 = [Azure TTS Native] 使用代理:{ $res } +msg-90b31925 = 缺少OTTS参数:{ $res } +msg-10f72727 = { $error_msg } +msg-60b044ea = 配置错误: 缺少必要参数{ $e } +msg-5c7dee08 = 订阅密钥格式无效,应为32位字母数字或其他[...]格式 ### astrbot/core/provider/sources/openai_embedding_source.py -msg-cecb2fbc = [OpenAI Embedding] 使用代理: {$proxy} + +msg-cecb2fbc = [OpenAI Embedding] 使用代理:{ $proxy } ### astrbot/core/provider/sources/vllm_rerank_source.py -msg-6f160342 = Rerank API 返回了空的列表数据。原始响应: {$response_data} + +msg-6f160342 = Rerank API 返回了空的列表数据。原始响应:{ $response_data } ### astrbot/core/provider/sources/xinference_stt_provider.py -msg-4e31e089 = Xinference STT: Using API key for authentication. -msg-e291704e = Xinference STT: No API key provided. -msg-b0d1e564 = Model '{$res}' is already running with UID: {$uid} -msg-16965859 = Launching {$res} model... -msg-7b1dfdd3 = Model launched. -msg-3fc7310e = Model '{$res}' is not running and auto-launch is disabled. Provider will not be available. -msg-15f19a42 = Failed to initialize Xinference model: {$e} -msg-01af1651 = Xinference initialization failed with exception: {$e} -msg-42ed8558 = Xinference STT model is not initialized. -msg-bbc43272 = Failed to download audio from {$audio_url}, status: {$res} -msg-f4e53d3d = File not found: {$audio_url} -msg-ebab7cac = Audio bytes are empty. -msg-7fd63838 = Audio requires conversion ({$conversion_type}), using temporary files... -msg-d03c4ede = Converting silk to wav ... -msg-79486689 = Converting amr to wav ... -msg-c4305a5b = Xinference STT result: {$text} -msg-d4241bd5 = Xinference STT transcription failed with status {$res}: {$error_text} -msg-8efe4ef1 = Xinference STT failed: {$e} -msg-b1554c7c = Xinference STT failed with exception: {$e} -msg-9d33941a = Removed temporary file: {$temp_file} -msg-7dc5bc44 = Failed to remove temporary file {$temp_file}: {$e} -msg-31904a1c = Closing Xinference STT client... -msg-633a269f = Failed to close Xinference client: {$e} + +msg-4e31e089 = Xinference STT: 正在使用API密钥进行身份验证。 +msg-e291704e = Xinference STT:未提供API密钥。 +msg-b0d1e564 = 模型{ $res }正在以UID运行的进程:{ $uid } +msg-16965859 = 正在启动{ $res }模型... +msg-7b1dfdd3 = 模型已启动。 +msg-3fc7310e = 模型{ $res }未在运行且自动启动已禁用。提供程序将不可用。 +msg-15f19a42 = 初始化Xinference模型失败:{ $e } +msg-01af1651 = Xinference 初始化失败,异常信息:{ $e } +msg-42ed8558 = Xinference STT 模型未初始化。 +msg-bbc43272 = 音频下载失败{ $audio_url }, 状态:{ $res } +msg-f4e53d3d = 文件未找到:{ $audio_url } +msg-ebab7cac = 音频字节为空。 +msg-7fd63838 = 音频需要转换({ $conversion_type }正在使用临时文件... +msg-d03c4ede = 正在将丝绸转换为WAV格式... +msg-79486689 = 正在将amr转换为wav ... +msg-c4305a5b = Xinference STT 结果:{ $text } +msg-d4241bd5 = Xinference STT 转写失败,状态为{ $res }待翻译文本:{ $error_text } +msg-8efe4ef1 = Xinference STT 失败:{ $e } +msg-b1554c7c = Xinference STT 出现异常:{ $e } +msg-9d33941a = 已删除临时文件:{ $temp_file } +msg-7dc5bc44 = 未能移除临时文件{ $temp_file }待翻译文本:{ $e } +msg-31904a1c = 正在关闭 Xinference STT 客户端... +msg-633a269f = 无法关闭Xinference客户端:{ $e } ### astrbot/core/provider/sources/fishaudio_tts_api_source.py -msg-c785baf0 = [FishAudio TTS] 使用代理: {$res} -msg-822bce1c = 无效的FishAudio参考模型ID: '{$res}'. 请确保ID是32位十六进制字符串(例如: 626bb6d3f3364c9cbc3aa6a67300a664)。您可以从 https://fish.audio/zh-CN/discovery 获取有效的模型ID。 -msg-5956263b = Fish Audio API请求失败: 状态码 {$res}, 响应内容: {$error_text} + +msg-c785baf0 = [FishAudio TTS] 使用代理:{ $res } +msg-822bce1c = 无效的FishAudio参考模型ID:'{ $res }'. 请确保ID是32位十六进制字符串(例如: 626bb6d3f3364c9cbc3aa6a67300a664)。您可以从 https://fish.audio/zh-CN/discovery 获取有效的模型ID。 +msg-5956263b = Fish Audio API请求失败: 状态码{ $res }, 响应内容:{ $error_text } ### astrbot/core/provider/sources/gsv_selfhosted_source.py + msg-5fb63f61 = [GSV TTS] 初始化完成 -msg-e0c38c5b = [GSV TTS] 初始化失败:{$e} -msg-4d57bc4f = [GSV TTS] Provider HTTP session is not ready or closed. -msg-2a4a0819 = [GSV TTS] 请求地址:{$endpoint},参数:{$params} -msg-5fdee1da = [GSV TTS] Request to {$endpoint} failed with status {$res}: {$error_text} -msg-3a51c2c5 = [GSV TTS] 请求 {$endpoint} 第 {$res} 次失败:{$e},重试中... -msg-49c1c17a = [GSV TTS] 请求 {$endpoint} 最终失败:{$e} -msg-1beb6249 = [GSV TTS] 成功设置 GPT 模型路径:{$res} +msg-e0c38c5b = [GSV TTS] 初始化失败:{ $e } +msg-4d57bc4f = [GSV TTS] 提供者HTTP会话未就绪或已关闭。 +msg-2a4a0819 = [GSV TTS] 请求地址:{ $endpoint }参数:{ $params } +msg-5fdee1da = [GSV TTS] 请求发送至{ $endpoint }执行失败,状态异常{ $res }待翻译文本:{ $error_text } +msg-3a51c2c5 = [GSV TTS] 请求{ $endpoint }第{ $res }次失败:{ $e },重试中... +msg-49c1c17a = [GSV TTS] 请求{ $endpoint }最终失败:{ $e } +msg-1beb6249 = [GSV TTS] 成功设置 GPT 模型路径:{ $res } msg-17f1a087 = [GSV TTS] GPT 模型路径未配置,将使用内置 GPT 模型 -msg-ddeb915f = [GSV TTS] 成功设置 SoVITS 模型路径:{$res} +msg-ddeb915f = [GSV TTS] 成功设置 SoVITS 模型路径:{ $res } msg-bee5c961 = [GSV TTS] SoVITS 模型路径未配置,将使用内置 SoVITS 模型 -msg-423edb93 = [GSV TTS] 设置模型路径时发生网络错误:{$e} -msg-7d3c79cb = [GSV TTS] 设置模型路径时发生未知错误:{$e} +msg-423edb93 = [GSV TTS] 设置模型路径时发生网络错误:{ $e } +msg-7d3c79cb = [GSV TTS] 设置模型路径时发生未知错误:{ $e } msg-d084916a = [GSV TTS] TTS 文本不能为空 -msg-fa20c883 = [GSV TTS] 正在调用语音合成接口,参数:{$params} -msg-a7fc38eb = [GSV TTS] 合成失败,输入文本:{$text},错误信息:{$result} -msg-a49cb96b = [GSV TTS] Session 已关闭 +msg-fa20c883 = [GSV TTS] 正在调用语音合成接口,参数:{ $params } +msg-a7fc38eb = [GSV TTS] 合成失败,输入文本:{ $text },错误信息:{ $result } +msg-a49cb96b = [GSV TTS] 会话已关闭 ### astrbot/core/provider/sources/volcengine_tts.py -msg-4b55f021 = 请求头: {$headers} -msg-d252d96d = 请求 URL: {$res} -msg-72e07cfd = 请求体: {$res}... -msg-fb8cdd69 = 响应状态码: {$res} -msg-4c62e457 = 响应内容: {$res}... -msg-1477973b = 火山引擎 TTS API 返回错误: {$error_msg} -msg-75401c15 = 火山引擎 TTS API 请求失败: {$res}, {$response_text} -msg-a29cc73d = 火山引擎 TTS 异常详情: {$error_details} -msg-01433007 = 火山引擎 TTS 异常: {$e} + +msg-4b55f021 = 请求头:{ $headers } +msg-d252d96d = 请求 URL:{ $res } +msg-72e07cfd = 请求体:{ $res }... +msg-fb8cdd69 = Response Status Code:{ $res } +msg-4c62e457 = 响应内容:{ $res }... +msg-1477973b = 火山引擎 TTS API 返回错误:{ $error_msg } +msg-75401c15 = 火山引擎 TTS API 请求失败:{ $res },{ $response_text } +msg-a29cc73d = 火山引擎 TTS 异常详情:{ $error_details } +msg-01433007 = 火山引擎 TTS 异常:{ $e } ### astrbot/core/provider/sources/sensevoice_selfhosted_source.py -msg-ee0daf96 = 下载或者加载 SenseVoice 模型中,这可能需要一些时间 ... + +msg-ee0daf96 = 正在下载或加载 SenseVoice 模型,这可能需要一些时间 ... msg-cd6da7e9 = SenseVoice 模型加载完成。 -msg-28cbbf07 = 文件不存在: {$audio_url} -msg-d98780e5 = Converting silk file to wav ... -msg-4e8f1d05 = SenseVoice识别到的文案:{$res} +msg-28cbbf07 = 文件不存在:{ $audio_url } +msg-d98780e5 = 正在将silk文件转换为wav ... +msg-4e8f1d05 = SenseVoice识别到的文案:{ $res } msg-55668aa2 = 未能提取到情绪信息 -msg-0cdbac9b = 处理音频文件时出错: {$e} +msg-0cdbac9b = 处理音频文件时出错:{ $e } ### astrbot/core/message/components.py -msg-afb10076 = not a valid url -msg-fe4c33a0 = not a valid file: {$res} + +msg-afb10076 = 不是有效的网址 +msg-fe4c33a0 = 不是有效的文件:{ $res } msg-24d98e13 = 未配置 callback_api_base,文件服务不可用 -msg-a5c69cc9 = 已注册:{$callback_host}/api/file/{$token} -msg-3cddc5ef = download failed: {$url} -msg-1921aa47 = not a valid file: {$url} -msg-2ee3827c = Generated video file callback link: {$payload_file} -msg-32f4fc78 = No valid file or URL provided -msg-36375f4c = 不可以在异步上下文中同步等待下载! 这个警告通常发生于某些逻辑试图通过 .file 获取文件消息段的文件内容。请使用 await get_file() 代替直接获取 .file 字段 -msg-4a987754 = 文件下载失败: {$e} -msg-7c1935ee = Download failed: No URL provided in File component. -msg-35bb8d53 = Generated file callback link: {$payload_file} +msg-a5c69cc9 = 已注册:{ $callback_host }/api/file/{ $token } +msg-3cddc5ef = 下载失败:{ $url } +msg-1921aa47 = 不是一个有效的文件:{ $url } +msg-2ee3827c = 生成的视频文件回调链接:{ $payload_file } +msg-32f4fc78 = 未提供有效的文件或 URL +msg-36375f4c = Do not synchronously await downloads in asynchronous contexts! This warning usually occurs when certain logic attempts to retrieve the file content of a file message segment via .file. Please use await get_file() instead of directly accessing the .file field. +msg-4a987754 = 文件下载失败:{ $e } +msg-7c1935ee = 下载失败:文件组件中未提供URL。 +msg-35bb8d53 = 生成文件回调链接:{ $payload_file } ### astrbot/core/utils/metrics.py -msg-314258f2 = 保存指标到数据库失败: {$e} + +msg-314258f2 = Failed to save metric to database:{ $e } ### astrbot/core/utils/trace.py -msg-fffce1b9 = [trace] {$payload} -msg-78b9c276 = {$res} + +msg-fffce1b9 = [trace]{ $payload } +msg-78b9c276 = { $res } ### astrbot/core/utils/webhook_utils.py -msg-64c7ddcf = 获取 callback_api_base 失败: {$e} -msg-9b5d1bb1 = 获取 dashboard 端口失败: {$e} -msg-3db149ad = 获取 dashboard SSL 配置失败: {$e} -msg-3739eec9 = {$display_log} + +msg-64c7ddcf = 获取 callback_api_base 失败:{ $e } +msg-9b5d1bb1 = 获取 dashboard 端口失败:{ $e } +msg-3db149ad = 获取仪表板 SSL 配置失败:{ $e } +msg-3739eec9 = { $display_log } ### astrbot/core/utils/path_util.py -msg-cf211d0f = 路径映射规则错误: {$mapping} -msg-ecea161e = 路径映射: {$url} -> {$srcPath} + +msg-cf211d0f = 路径映射规则错误:{ $mapping } +msg-ecea161e = Path Mapping:{ $url }->{ $srcPath } ### astrbot/core/utils/media_utils.py -msg-2f697658 = [Media Utils] 获取媒体时长: {$duration_ms}ms -msg-52dfbc26 = [Media Utils] 无法获取媒体文件时长: {$file_path} -msg-486d493a = [Media Utils] ffprobe未安装或不在PATH中,无法获取媒体时长。请安装ffmpeg: https://ffmpeg.org/ -msg-0f9c647b = [Media Utils] 获取媒体时长时出错: {$e} -msg-aff4c5f8 = [Media Utils] 已清理失败的opus输出文件: {$output_path} -msg-82427384 = [Media Utils] 清理失败的opus输出文件时出错: {$e} -msg-215a0cfc = [Media Utils] ffmpeg转换音频失败: {$error_msg} -msg-8cce258e = ffmpeg conversion failed: {$error_msg} -msg-f0cfcb92 = [Media Utils] 音频转换成功: {$audio_path} -> {$output_path} -msg-ead1395b = [Media Utils] ffmpeg未安装或不在PATH中,无法转换音频格式。请安装ffmpeg: https://ffmpeg.org/ -msg-5df3a5ee = ffmpeg not found -msg-6322d4d2 = [Media Utils] 转换音频格式时出错: {$e} -msg-e125b1a5 = [Media Utils] 已清理失败的{$output_format}输出文件: {$output_path} -msg-5cf417e3 = [Media Utils] 清理失败的{$output_format}输出文件时出错: {$e} -msg-3766cbb8 = [Media Utils] ffmpeg转换视频失败: {$error_msg} -msg-77f68449 = [Media Utils] 视频转换成功: {$video_path} -> {$output_path} -msg-3fb20b91 = [Media Utils] ffmpeg未安装或不在PATH中,无法转换视频格式。请安装ffmpeg: https://ffmpeg.org/ -msg-696c4a46 = [Media Utils] 转换视频格式时出错: {$e} -msg-98cc8fb8 = [Media Utils] 清理失败的音频输出文件时出错: {$e} -msg-3c27d5e8 = [Media Utils] 清理失败的视频封面文件时出错: {$e} -msg-072774ab = ffmpeg extract cover failed: {$error_msg} + +msg-2f697658 = [Media Utils] 获取媒体时长:{ $duration_ms }毫秒 +msg-52dfbc26 = [媒体工具] 无法获取媒体文件时长:{ $file_path } +msg-486d493a = [媒体工具] ffprobe未安装或不在PATH环境变量中,无法获取媒体时长。请安装ffmpeg: https://ffmpeg.org/ +msg-0f9c647b = [媒体工具] 获取媒体时长时出错:{ $e } +msg-aff4c5f8 = [Media Utils] 已清理失败的opus输出文件:{ $output_path } +msg-82427384 = [Media Utils] 清理失败的opus输出文件时出错:{ $e } +msg-215a0cfc = [媒体工具] ffmpeg音频转换失败:{ $error_msg } +msg-8cce258e = ffmpeg 转换失败:{ $error_msg } +msg-f0cfcb92 = [媒体工具] 音频转换成功:{ $audio_path }->{ $output_path } +msg-ead1395b = [媒体工具] ffmpeg未安装或不在PATH环境变量中,无法转换音频格式。请安装ffmpeg: https://ffmpeg.org/ +msg-5df3a5ee = 未找到 ffmpeg +msg-6322d4d2 = [Media Utils] 转换音频格式时出错:{ $e } +msg-e125b1a5 = [媒体工具] 已清理失败的{ $output_format }Output file:{ $output_path } +msg-5cf417e3 = [媒体工具] 清理失败的{ $output_format }输出文件时出错:{ $e } +msg-3766cbb8 = [媒体工具] ffmpeg视频转换失败:{ $error_msg } +msg-77f68449 = [Media Utils] 视频转换成功:{ $video_path }->{ $output_path } +msg-3fb20b91 = [媒体工具] ffmpeg未安装或不在PATH环境变量中,无法转换视频格式。请安装ffmpeg: https://ffmpeg.org/ +msg-696c4a46 = [媒体工具] 转换视频格式时出错:{ $e } +msg-98cc8fb8 = [媒体工具] 清理失败的音频输出文件时出错:{ $e } +msg-3c27d5e8 = [媒体工具] 清理失败的视频封面文件时出错:{ $e } +msg-072774ab = ffmpeg 提取封面失败:{ $error_msg } ### astrbot/core/utils/session_waiter.py + msg-0c977996 = 等待超时 msg-ac406437 = session_filter 必须是 SessionFilter ### astrbot/core/utils/history_saver.py -msg-fb7718cb = Failed to parse conversation history: %s + +msg-fb7718cb = 解析对话历史失败:%s ### astrbot/core/utils/io.py -msg-665b0191 = SSL certificate verification failed for {$url}. Disabling SSL verification (CERT_NONE) as a fallback. This is insecure and exposes the application to man-in-the-middle attacks. Please investigate and resolve certificate issues. -msg-04ab2fae = 下载文件失败: {$res} -msg-63dacf99 = 文件大小: {$res} KB | 文件地址: {$url} -msg-14c3d0bb = \r下载进度: {$res} 速度: {$speed} KB/s + +msg-665b0191 = SSL证书验证失败{ $url }正在禁用SSL验证(CERT_NONE)作为备用方案。这种做法不安全,会使应用程序暴露于中间人攻击的风险中。请检查并解决证书问题。 +msg-04ab2fae = 下载文件失败:{ $res } +msg-63dacf99 = 文件大小:{ $res }KB | 文件地址:{ $url } +msg-14c3d0bb = 下载进度:{ $res }速度:{ $speed }千字节/秒 msg-4e4ee68e = SSL 证书验证失败,已关闭 SSL 验证(不安全,仅用于临时下载)。请检查目标服务器的证书配置。 -msg-5a3beefb = SSL certificate verification failed for {$url}. Falling back to unverified connection (CERT_NONE). This is insecure and exposes the application to man-in-the-middle attacks. Please investigate certificate issues with the remote server. -msg-315e5ed6 = 准备下载指定发行版本的 AstrBot WebUI 文件: {$dashboard_release_url} -msg-c709cf82 = 准备下载指定版本的 AstrBot WebUI: {$url} +msg-5a3beefb = SSL证书验证失败{ $url }正在回退到未验证的连接(CERT_NONE)。此操作不安全,会使应用程序面临中间人攻击的风险。请检查远程服务器的证书问题。 +msg-315e5ed6 = 准备下载指定发行版本的 AstrBot WebUI 文件:{ $dashboard_release_url } +msg-c709cf82 = 准备下载指定版本的 AstrBot WebUI:{ $url } ### astrbot/core/utils/shared_preferences.py -msg-9a1e6a9a = scope_id and key cannot be None when getting a specific preference. + +msg-9a1e6a9a = 获取特定偏好设置时,scope_id 和 key 不能为 None。 ### astrbot/core/utils/migra_helper.py -msg-497ddf83 = Migration for third party agent runner configs failed: {$e} -msg-78b9c276 = {$res} -msg-e21f1509 = Migrating provider {$res} to new structure -msg-dd3339e6 = Provider-source structure migration completed -msg-1cb6c174 = Migration from version 4.5 to 4.6 failed: {$e} -msg-a899acc6 = Migration for webchat session failed: {$e} -msg-b9c52817 = Migration for token_usage column failed: {$e} -msg-d9660ff5 = Migration for provider-source structure failed: {$e} + +msg-497ddf83 = 第三方代理运行器配置迁移失败:{ $e } +msg-78b9c276 = { $res } +msg-e21f1509 = 迁移供应商{ $res }到新结构 +msg-dd3339e6 = 提供商-源结构迁移完成 +msg-1cb6c174 = 从版本 4.5 迁移至 4.6 失败:{ $e } +msg-a899acc6 = Webchat 会话迁移失败:{ $e } +msg-b9c52817 = token_usage 列的迁移失败:{ $e } +msg-d9660ff5 = 迁移提供者源结构失败:{ $e } ### astrbot/core/utils/temp_dir_cleaner.py -msg-752c7cc8 = Invalid {$res}={$configured}, fallback to {$res_2}MB. -msg-b1fc3643 = Skip temp file {$path} due to stat error: {$e} -msg-5e61f6b7 = Failed to delete temp file {$res}: {$e} -msg-391449f0 = Temp dir exceeded limit ({$total_size} > {$limit}). Removed {$removed_files} files, released {$released} bytes (target {$target_release} bytes). -msg-aaf1e12a = TempDirCleaner started. interval={$res}s cleanup_ratio={$res_2} -msg-e6170717 = TempDirCleaner run failed: {$e} -msg-0fc33fbc = TempDirCleaner stopped. + +msg-752c7cc8 = 无效{ $res }={ $configured },回退至{ $res_2 }MB +msg-b1fc3643 = 跳过临时文件{ $path }由于统计错误:{ $e } +msg-5e61f6b7 = 无法删除临时文件{ $res }:{ $e } +msg-391449f0 = 临时目录超出限制 ({ $total_size }待翻译文本:{ $limit }已移除{ $removed_files }文件,已发布{ $released }字节数(目标{ $target_release }字节数。 +msg-aaf1e12a = 临时目录清理器已启动。interval={ $res }清理比例={ $res_2 } +msg-e6170717 = TempDirCleaner 运行失败:{ $e } +msg-0fc33fbc = 临时目录清理器已停止。 ### astrbot/core/utils/tencent_record_helper.py + msg-377ae139 = pilk 模块未安装,请前往管理面板->平台日志->安装pip库 安装 pilk 这个库 -msg-f4ab0713 = pyffmpeg 转换失败: {$e}, 尝试使用 ffmpeg 命令行进行转换 -msg-33c88889 = [FFmpeg] stdout: {$res} -msg-2470430c = [FFmpeg] stderr: {$res} -msg-1321d5f7 = [FFmpeg] return code: {$res} -msg-c39d210c = 生成的WAV文件不存在或为空 +msg-f4ab0713 = pyffmpeg 转换失败:{ $e }尝试使用 ffmpeg 命令行进行转换 +msg-33c88889 = [FFmpeg] 标准输出:{ $res } +msg-2470430c = [FFmpeg] 标准错误输出:{ $res } +msg-1321d5f7 = [FFmpeg] 返回代码:{ $res } +msg-c39d210c = The generated WAV file does not exist or is empty. msg-6e04bdb8 = 未安装 pilk: pip install pilk ### astrbot/core/utils/pip_installer.py -msg-aa9e40b8 = pip module is unavailable (sys.executable={$res}, frozen={$res_2}, ASTRBOT_DESKTOP_CLIENT={$res_3}) + +msg-aa9e40b8 = pip模块不可用 (sys.executable={ $res }, frozen={ $res_2 }ASTRBOT_DESKTOP_CLIENT={ $res_3 }) msg-560f11f2 = 读取依赖文件失败,跳过冲突检测: %s msg-91ae1d17 = 读取 site-packages 元数据失败,使用回退模块名: %s -msg-c815b9dc = {$conflict_message} -msg-e8d4b617 = Loaded %s from plugin site-packages: %s -msg-4ef5d900 = Recovered dependency %s while preferring %s from plugin site-packages. -msg-0bf22754 = Module %s not found in plugin site-packages: %s -msg-76a41595 = Failed to prefer module %s from plugin site-packages: %s -msg-3d4de966 = Failed to patch pip distlib finder for loader %s (%s): %s -msg-117d9cf4 = Distlib finder patch did not take effect for loader %s (%s). -msg-b7975236 = Patched pip distlib finder for frozen loader: %s (%s) -msg-b1fa741c = Skip patching distlib finder because _finder_registry is unavailable. -msg-4ef0e609 = Skip patching distlib finder because register API is unavailable. -msg-b8c741dc = Pip 包管理器: pip {$res} -msg-6b72a960 = 安装失败,错误码:{$result_code} -msg-c8325399 = {$line} +msg-c815b9dc = { $conflict_message } +msg-e8d4b617 = 已从插件 site-packages 加载 %s:%s +msg-4ef5d900 = 从插件站点包中恢复依赖项 %s,同时首选 %s。 +msg-0bf22754 = 插件site-packages中未找到模块%s:%s +msg-76a41595 = 无法从插件站点包中首选模块 %s:%s +msg-3d4de966 = 无法为加载器 %s (%s) 修补 pip distlib 查找器:%s +msg-117d9cf4 = Distlib查找器补丁未对加载器%s (%s)生效。 +msg-b7975236 = 已修补用于冻结加载器的 pip distlib 查找器:%s (%s) +msg-b1fa741c = 跳过修补分发库查找器,因为_finder_registry不可用。 +msg-4ef0e609 = 跳过修补distlib查找器,因为注册API不可用。 +msg-b8c741dc = Pip 包管理器: pip{ $res } +msg-6b72a960 = 安装失败,错误码:{ $result_code } +msg-c8325399 = { $line } ### astrbot/core/utils/llm_metadata.py -msg-d6535d03 = Successfully fetched metadata for {$res} LLMs. -msg-8cceaeb0 = Failed to fetch LLM metadata: {$e} + +msg-d6535d03 = 成功获取元数据{ $res }LLMs +msg-8cceaeb0 = 获取LLM元数据失败:{ $e } ### astrbot/core/utils/network_utils.py -msg-54b8fda8 = [{$provider_label}] 网络/代理连接失败 ({$error_type})。代理地址: {$effective_proxy},错误: {$error} -msg-ea7c80f1 = [{$provider_label}] 网络连接失败 ({$error_type})。错误: {$error} -msg-f8c8a73c = [{$provider_label}] 使用代理: {$proxy} + +msg-54b8fda8 = [{ $provider_label }] 网络/代理连接失败{ $error_type }代理地址:{ $effective_proxy },错误:{ $error } +msg-ea7c80f1 = 原文:{ $provider_label }网络连接失败{ $error_type })。错误:{ $error } +msg-f8c8a73c = 待翻译文本:{ $provider_label }使用代理:{ $proxy } ### astrbot/core/utils/t2i/renderer.py -msg-4225607b = Failed to render image via AstrBot API: {$e}. Falling back to local rendering. + +msg-4225607b = 通过AstrBot API渲染图像失败:{ $e }正在回退到本地渲染。 ### astrbot/core/utils/t2i/local_strategy.py + msg-94a58a1e = 无法加载任何字体 -msg-d5c7d255 = Failed to load image: HTTP {$res} -msg-7d59d0a0 = Failed to load image: {$e} +msg-d5c7d255 = 加载图片失败:HTTP{ $res } +msg-7d59d0a0 = 加载图像失败:{ $e } ### astrbot/core/utils/t2i/template_manager.py + msg-47d72ff5 = 模板名称包含非法字符。 -msg-d1b2131b = 模板不存在。 -msg-dde05b0f = 同名模板已存在。 +msg-d1b2131b = Template does not exist. +msg-dde05b0f = A template with the same name already exists. msg-0aa209bf = 用户模板不存在,无法删除。 ### astrbot/core/utils/t2i/network_strategy.py -msg-be0eeaa7 = Successfully got {$res} official T2I endpoints. -msg-3bee02f4 = Failed to get official endpoints: {$e} -msg-829d3c71 = HTTP {$res} -msg-05fb621f = Endpoint {$endpoint} failed: {$e}, trying next... -msg-9a836926 = All endpoints failed: {$last_exception} + +msg-be0eeaa7 = 成功获取{ $res }官方T2I端点。 +msg-3bee02f4 = 获取官方端点失败:{ $e } +msg-829d3c71 = HTTP{ $res } +msg-05fb621f = 端点{ $endpoint }失败:{ $e },正在尝试下一个... +msg-9a836926 = 所有端点均失败:{ $last_exception } ### astrbot/core/utils/quoted_message/extractor.py -msg-24049c48 = quoted_message_parser: stop fetching nested forward messages after %d hops + +msg-24049c48 = quoted_message_parser:在%d次跳转后停止获取嵌套转发消息 ### astrbot/core/utils/quoted_message/onebot_client.py -msg-062923e6 = quoted_message_parser: action %s failed with params %s: %s -msg-f33f59d5 = quoted_message_parser: all attempts failed for action %s, last_params=%s, error=%s + +msg-062923e6 = quoted_message_parser: 操作 %s 失败,参数 %s: %s +msg-f33f59d5 = quoted_message_parser: 操作 %s 的所有尝试均失败,last_params=%s,错误=%s ### astrbot/core/utils/quoted_message/image_resolver.py -msg-94224a01 = quoted_message_parser: skip non-image local path ref=%s -msg-3e6c0d14 = quoted_message_parser: failed to resolve quoted image ref=%s after %d actions + +msg-94224a01 = quoted_message_parser: 跳过非图像本地路径 ref=%s +msg-3e6c0d14 = quoted_message_parser: 在 %d 次操作后未能解析引用的图片 ref=%s ### astrbot/core/agent/tool_image_cache.py -msg-45da4af7 = ToolImageCache initialized, cache dir: {$res} -msg-017bde96 = Saved tool image to: {$file_path} -msg-29398f55 = Failed to save tool image: {$e} -msg-128aa08a = Failed to read cached image {$file_path}: {$e} -msg-3c111d1f = Error during cache cleanup: {$e} -msg-eeb1b849 = Cleaned up {$cleaned} expired cached images + +msg-45da4af7 = ToolImageCache 已初始化,缓存目录:{ $res } +msg-017bde96 = 已保存工具镜像至:{ $file_path } +msg-29398f55 = 保存工具镜像失败:{ $e } +msg-128aa08a = 读取缓存图片失败{ $file_path }待翻译文本:{ $e } +msg-3c111d1f = 缓存清理过程中出错:{ $e } +msg-eeb1b849 = 已清理{ $cleaned }已过期的缓存图像 ### astrbot/core/agent/message.py -msg-d38656d7 = {$invalid_subclass_error_msg} -msg-42d5a315 = Cannot validate {$value} as ContentPart -msg-ffc376d0 = content is required unless role='assistant' and tool_calls is not None + +msg-d38656d7 = { $invalid_subclass_error_msg } +msg-42d5a315 = 无法验证{ $value }作为内容部件 +msg-ffc376d0 = 除非角色为'assistant'且tool_calls不为None,否则内容为必填项。 ### astrbot/core/agent/mcp_client.py -msg-6a61ca88 = Warning: Missing 'mcp' dependency, MCP services will be unavailable. -msg-45995cdb = Warning: Missing 'mcp' dependency or MCP library version too old, Streamable HTTP connection unavailable. -msg-2866b896 = MCP connection config missing transport or type field -msg-3bf7776b = MCP Server {$name} Error: {$msg} -msg-10f72727 = {$error_msg} -msg-19c9b509 = MCP Client is not initialized -msg-5b9b4918 = MCP Client {$res} is already reconnecting, skipping -msg-c1008866 = Cannot reconnect: missing connection configuration -msg-7c3fe178 = Attempting to reconnect to MCP server {$res}... -msg-783f3b85 = Successfully reconnected to MCP server {$res} -msg-da7361ff = Failed to reconnect to MCP server {$res}: {$e} -msg-c0fd612e = MCP session is not available for MCP function tools. -msg-8236c58c = MCP tool {$tool_name} call failed (ClosedResourceError), attempting to reconnect... -msg-044046ec = Error closing current exit stack: {$e} + +msg-6a61ca88 = 警告:缺少 'mcp' 依赖项,MCP 服务将不可用。 +msg-45995cdb = 警告:缺少 'mcp' 依赖项或MCP库版本过旧,可流式传输的HTTP连接不可用。 +msg-2866b896 = MCP 连接配置缺少传输或类型字段 +msg-3bf7776b = MCP 服务器{ $name }错误:{ $msg } +msg-10f72727 = { $error_msg } +msg-19c9b509 = MCP客户端未初始化 +msg-5b9b4918 = MCP 客户端{ $res }已处于重新连接状态,跳过 +msg-c1008866 = 无法重新连接:缺少连接配置 +msg-7c3fe178 = 正在尝试重新连接到 MCP 服务器{ $res }... +msg-783f3b85 = 已成功重新连接到MCP服务器{ $res } +msg-da7361ff = 无法重新连接到 MCP 服务器{ $res }:{ $e } +msg-c0fd612e = MCP会话不可用于MCP功能工具。 +msg-8236c58c = MCP工具{ $tool_name }调用失败(ClosedResourceError),正在尝试重新连接... +msg-044046ec = 错误关闭当前退出堆栈:{ $e } ### astrbot/core/agent/tool.py -msg-983bc802 = FunctionTool.call() must be implemented by subclasses or set a handler. + +msg-983bc802 = FunctionTool.call() 必须由子类实现或设置处理程序。 ### astrbot/core/agent/context/compressor.py -msg-6c75531b = Failed to generate summary: {$e} + +msg-6c75531b = 生成摘要失败:{ $e } ### astrbot/core/agent/context/manager.py -msg-59241964 = Error during context processing: {$e} -msg-a0d672dc = Compress triggered, starting compression... -msg-e6ef66f0 = Compress completed. {$prev_tokens} -> {$tokens_after_summary} tokens, compression rate: {$compress_rate}%. -msg-3fe644eb = Context still exceeds max tokens after compression, applying halving truncation... + +msg-59241964 = 上下文处理期间发生错误:{ $e } +msg-a0d672dc = 压缩已触发,开始压缩... +msg-e6ef66f0 = 压缩完成。{ $prev_tokens }->{ $tokens_after_summary }令牌,压缩率:{ $compress_rate }%. +msg-3fe644eb = 上下文在压缩后仍然超过最大令牌数,正在应用折半截断处理... ### astrbot/core/agent/runners/tool_loop_agent_runner.py -msg-960ef181 = Switched from %s to fallback chat provider: %s -msg-4f999913 = Chat Model %s returns error response, trying fallback to next provider. -msg-c042095f = Chat Model %s request error: %s -msg-81b2aeae = {$tag} RunCtx.messages -> [{$res}] {$res_2} -msg-55333301 = Request is not set. Please call reset() first. -msg-d3b77736 = Error in on_agent_begin hook: {$e} -msg-61de315c = Agent execution was requested to stop by user. -msg-8eb53be3 = Error in on_agent_done hook: {$e} -msg-508d6d17 = LLM 响应错误: {$res} -msg-ed80313d = LLM returned empty assistant message with no tool calls. -msg-970947ae = Appended {$res} cached image(s) to context for LLM review -msg-6b326889 = Agent reached max steps ({$max_step}), forcing a final response. -msg-948ea4b7 = Agent 使用工具: {$res} -msg-a27ad3d1 = 使用工具:{$func_tool_name},参数:{$func_tool_args} -msg-812ad241 = 未找到指定的工具: {$func_tool_name},将跳过。 -msg-20b4f143 = 工具 {$func_tool_name} 期望的参数: {$res} -msg-78f6833c = 工具 {$func_tool_name} 忽略非期望参数: {$ignored_params} -msg-2b523f8c = Error in on_tool_start hook: {$e} -msg-ec868b73 = {$func_tool_name} 没有返回值,或者已将结果直接发送给用户。 -msg-6b61e4f1 = Tool 返回了不支持的类型: {$res}。 -msg-34c13e02 = Error in on_tool_end hook: {$e} -msg-78b9c276 = {$res} -msg-a1493b6d = Tool `{$func_tool_name}` Result: {$last_tcr_content} + +msg-960ef181 = 已从 %s 切换到备用聊天服务提供商:%s +msg-4f999913 = 聊天模型 %s 返回错误响应,尝试降级到下一个提供程序。 +msg-c042095f = 聊天模型 %s 请求错误: %s +msg-81b2aeae = { $tag }RunCtx.messages -> [{ $res }]{ $res_2 } +msg-55333301 = 请求未设置。请先调用 reset()。 +msg-d3b77736 = on_agent_begin 钩子函数出错:{ $e } +msg-61de315c = 用户请求停止代理执行。 +msg-8eb53be3 = on_agent_done 钩子中发生错误:{ $e } +msg-508d6d17 = LLM 响应错误:{ $res } +msg-ed80313d = LLM返回了空的助手消息,且未调用任何工具。 +msg-970947ae = 已添加{ $res }已缓存的图像已发送至上下文以供LLM审核 +msg-6b326889 = 代理已达到最大步数限制 ({ $max_step }),强制进行最终响应。 +msg-948ea4b7 = Agent 使用工具:{ $res } +msg-a27ad3d1 = 使用工具:{ $func_tool_name }参数:{ $func_tool_args } +msg-812ad241 = 未找到指定的工具:{ $func_tool_name },将跳过。 +msg-20b4f143 = 工具{ $func_tool_name }期望的参数:{ $res } +msg-78f6833c = 工具{ $func_tool_name }忽略非期望参数:{ $ignored_params } +msg-2b523f8c = on_tool_start 钩子中的错误:{ $e } +msg-ec868b73 = { $func_tool_name }没有返回值,或者已将结果直接发送给用户。 +msg-6b61e4f1 = 工具返回了不支持的类型:{ $res }。 +msg-34c13e02 = on_tool_end 钩子中出现错误:{ $e } +msg-78b9c276 = { $res } +msg-a1493b6d = 工具{ $func_tool_name }`结果:`{ $last_tcr_content } ### astrbot/core/agent/runners/base.py -msg-24eb2b08 = Agent state transition: {$res} -> {$new_state} + +msg-24eb2b08 = 代理状态转换:{ $res }->{ $new_state } ### astrbot/core/agent/runners/dashscope/dashscope_agent_runner.py + msg-dc1a9e6e = 阿里云百炼 API Key 不能为空。 msg-c492cbbc = 阿里云百炼 APP ID 不能为空。 msg-bcc8e027 = 阿里云百炼 APP 类型不能为空。 -msg-55333301 = Request is not set. Please call reset() first. -msg-d3b77736 = Error in on_agent_begin hook: {$e} -msg-e3af4efd = 阿里云百炼请求失败:{$res} -msg-fccf5004 = dashscope stream chunk: {$chunk} -msg-100d7d7e = 阿里云百炼请求失败: request_id={$res}, code={$res_2}, message={$res_3}, 请参考文档:https://help.aliyun.com/zh/model-studio/developer-reference/error-code -msg-10f72727 = {$error_msg} -msg-e8615101 = {$chunk_text} -msg-dfb132c4 = {$ref_text} -msg-8eb53be3 = Error in on_agent_done hook: {$e} +msg-55333301 = 请求未设置。请先调用 reset()。 +msg-d3b77736 = on_agent_begin 钩子中出现错误:{ $e } +msg-e3af4efd = 阿里云百炼请求失败:{ $res } +msg-fccf5004 = dashscope 流式数据块:{ $chunk } +msg-100d7d7e = 阿里云百炼请求失败: request_id={ $res }待翻译文本:, 代码={ $res_2 },消息={ $res_3 }, 请参考文档:https://help.aliyun.com/zh/model-studio/developer-reference/error-code +msg-10f72727 = { $error_msg } +msg-e8615101 = { $chunk_text } +msg-dfb132c4 = { $ref_text } +msg-8eb53be3 = on_agent_done 钩子中的错误:{ $e } msg-650b47e1 = 阿里云百炼暂不支持图片输入,将自动忽略图片内容。 ### astrbot/core/agent/runners/coze/coze_agent_runner.py + msg-448549b0 = Coze API Key 不能为空。 msg-b88724b0 = Coze Bot ID 不能为空。 -msg-ea5a135a = Coze API Base URL 格式不正确,必须以 http:// 或 https:// 开头。 -msg-55333301 = Request is not set. Please call reset() first. -msg-d3b77736 = Error in on_agent_begin hook: {$e} -msg-5aa3eb1c = Coze 请求失败:{$res} -msg-333354c6 = 处理上下文图片失败: {$e} -msg-2d9e1c08 = 处理图片失败 {$url}: {$e} -msg-1f50979d = {$content} -msg-6fe5588b = Coze message completed -msg-d2802f3b = Coze chat completed -msg-ba4afcda = Coze 出现错误: {$error_code} - {$error_msg} +msg-ea5a135a = Coze API 基础 URL 格式不正确,必须以 http:// 或 https:// 开头。 +msg-55333301 = 请求未设置。请先调用 reset()。 +msg-d3b77736 = on_agent_begin 钩子中的错误:{ $e } +msg-5aa3eb1c = Coze 请求失败:{ $res } +msg-333354c6 = Failed to process context image:{ $e } +msg-2d9e1c08 = Failed to process image{ $url }待翻译文本:{ $e } +msg-1f50979d = { $content } +msg-6fe5588b = Coze消息已处理完成 +msg-d2802f3b = Coze 聊天完成 +msg-ba4afcda = Coze 出现错误:{ $error_code }-{ $error_msg } msg-ee300f25 = Coze 未返回任何内容 -msg-8eb53be3 = Error in on_agent_done hook: {$e} -msg-034c1858 = [Coze] 使用缓存的 file_id: {$file_id} -msg-475d8a41 = [Coze] 图片上传成功并缓存,file_id: {$file_id} -msg-696dad99 = 处理图片失败 {$image_url}: {$e} -msg-7793a347 = 处理图片失败: {$e} +msg-8eb53be3 = on_agent_done 钩子中出错:{ $e } +msg-034c1858 = [Coze] 使用缓存的 file_id:{ $file_id } +msg-475d8a41 = [Coze] 图片上传成功并缓存,file_id:{ $file_id } +msg-696dad99 = Failed to process image{ $image_url }:{ $e } +msg-7793a347 = 图片处理失败:{ $e } ### astrbot/core/agent/runners/coze/coze_api_client.py + msg-76f97104 = Coze API 认证失败,请检查 API Key 是否正确 -msg-3653b652 = 文件上传响应状态: {$res}, 内容: {$response_text} -msg-13fe060c = 文件上传失败,状态码: {$res}, 响应: {$response_text} -msg-5604b862 = 文件上传响应解析失败: {$response_text} -msg-c0373c50 = 文件上传失败: {$res} -msg-010e4299 = [Coze] 图片上传成功,file_id: {$file_id} +msg-3653b652 = 文件上传响应状态:{ $res }内容:{ $response_text } +msg-13fe060c = 文件上传失败,状态码:{ $res }, 响应:{ $response_text } +msg-5604b862 = 文件上传响应解析失败:{ $response_text } +msg-c0373c50 = 文件上传失败:{ $res } +msg-010e4299 = [Coze] 图片上传成功,file_id:{ $file_id } msg-719f13cb = 文件上传超时 -msg-121c11fb = 文件上传失败: {$e} -msg-f6101892 = 下载图片失败,状态码: {$res} -msg-c09c56c9 = 下载图片失败 {$image_url}: {$e} -msg-15211c7c = 下载图片失败: {$e} -msg-2245219f = Coze chat_messages payload: {$payload}, params: {$params} -msg-d8fd415c = Coze API 流式请求失败,状态码: {$res} -msg-f5cc7604 = Coze API 流式请求超时 ({$timeout}秒) -msg-30c0a9d6 = Coze API 流式请求失败: {$e} -msg-11509aba = Coze API 请求失败,状态码: {$res} +msg-121c11fb = File upload failed:{ $e } +msg-f6101892 = Failed to download image, status code:{ $res } +msg-c09c56c9 = 下载图片失败{ $image_url }:{ $e } +msg-15211c7c = 下载图片失败:{ $e } +msg-2245219f = Coze 聊天消息负载:{ $payload }, 参数:{ $params } +msg-d8fd415c = Coze API 流式请求失败,状态码:{ $res } +msg-f5cc7604 = Coze API 流式请求超时{ $timeout }秒) +msg-30c0a9d6 = Coze API 流式请求失败:{ $e } +msg-11509aba = Coze API 请求失败,状态码:{ $res } msg-002af11d = Coze API 返回非JSON格式 msg-c0b8fc7c = Coze API 请求超时 -msg-a68a33fa = Coze API 请求失败: {$e} -msg-c26e068e = 获取Coze消息列表失败: {$e} -msg-5bc0a49d = Uploaded file_id: {$file_id} -msg-7c08bdaf = Event: {$event} +msg-a68a33fa = Coze API 请求失败:{ $e } +msg-c26e068e = 获取Coze消息列表失败:{ $e } +msg-5bc0a49d = 上传的文件 ID:{ $file_id } +msg-7c08bdaf = 事件:{ $event } ### astrbot/core/agent/runners/dify/dify_api_client.py -msg-cd6cd7ac = Drop invalid dify json data: {$res} -msg-3654a12d = chat_messages payload: {$payload} -msg-8e865c52 = Dify /chat-messages 接口请求失败:{$res}. {$text} -msg-2d7534b8 = workflow_run payload: {$payload} -msg-89918ba5 = Dify /workflows/run 接口请求失败:{$res}. {$text} + +msg-cd6cd7ac = 丢弃无效的 dify json 数据:{ $res } +msg-3654a12d = 聊天消息负载:{ $payload } +msg-8e865c52 = Dify /chat-messages 接口请求失败:{ $res }.{ $text } +msg-2d7534b8 = workflow_run 负载:{ $payload } +msg-89918ba5 = Dify /workflows/run 接口请求失败:{ $res }.{ $text } msg-8bf17938 = file_path 和 file_data 不能同时为 None -msg-b6ee8f38 = Dify 文件上传失败:{$res}. {$text} +msg-b6ee8f38 = Dify 文件上传失败:{ $res }.{ $text } ### astrbot/core/agent/runners/dify/dify_agent_runner.py -msg-55333301 = Request is not set. Please call reset() first. -msg-d3b77736 = Error in on_agent_begin hook: {$e} -msg-0d493427 = Dify 请求失败:{$res} -msg-fe594f21 = Dify 上传图片响应:{$file_response} -msg-3534b306 = 上传图片后得到未知的 Dify 响应:{$file_response},图片将忽略。 -msg-08441fdf = 上传图片失败:{$e} -msg-3972f693 = dify resp chunk: {$chunk} -msg-6c74267b = Dify message end -msg-1ce260ba = Dify 出现错误:{$chunk} -msg-a12417dd = Dify 出现错误 status: {$res} message: {$res_2} -msg-f8530ee9 = dify workflow resp chunk: {$chunk} -msg-386a282e = Dify 工作流(ID: {$res})开始运行。 -msg-0bc1299b = Dify 工作流节点(ID: {$res} Title: {$res_2})运行结束。 -msg-5cf24248 = Dify 工作流(ID: {$res})运行结束 -msg-e2c2159f = Dify 工作流结果:{$chunk} -msg-4fa60ef1 = Dify 工作流出现错误:{$res} -msg-1f786836 = Dify 工作流的输出不包含指定的键名:{$res} -msg-c4a70ffb = 未知的 Dify API 类型:{$res} + +msg-55333301 = 请求未设置。请先调用 reset()。 +msg-d3b77736 = 代理开始钩子中出错:{ $e } +msg-0d493427 = Dify 请求失败:{ $res } +msg-fe594f21 = Dify 上传图片响应:{ $file_response } +msg-3534b306 = 上传图片后得到未知的 Dify 响应:{ $file_response },图片将忽略。 +msg-08441fdf = Failed to upload image:{ $e } +msg-3972f693 = dify 响应分块:{ $chunk } +msg-6c74267b = Dify 消息结束 +msg-1ce260ba = Dify 出现错误:{ $chunk } +msg-a12417dd = Dify 出现错误 status:{ $res }消息:{ $res_2 } +msg-f8530ee9 = dify工作流响应块:{ $chunk } +msg-386a282e = Dify 工作流(ID:{ $res })开始运行。 +msg-0bc1299b = Dify 工作流节点(ID:{ $res }标题:{ $res_2 })运行结束。 +msg-5cf24248 = Dify 工作流(ID:{ $res })运行结束 +msg-e2c2159f = Dify 工作流结果:{ $chunk } +msg-4fa60ef1 = Dify 工作流出现错误:{ $res } +msg-1f786836 = Dify 工作流的输出不包含指定的键名:{ $res } +msg-c4a70ffb = 未知的 Dify API 类型:{ $res } msg-51d321fd = Dify 请求结果为空,请查看 Debug 日志。 -msg-8eb53be3 = Error in on_agent_done hook: {$e} +msg-8eb53be3 = on_agent_done 钩子中的错误:{ $e } ### astrbot/core/star/session_plugin_manager.py -msg-16cc2a7a = 插件 {$res} 在会话 {$session_id} 中被禁用,跳过处理器 {$res_2} + +msg-16cc2a7a = 插件{ $res }In Session{ $session_id }Disabled in, skipping processor{ $res_2 } ### astrbot/core/star/star_manager.py -msg-bfa28c02 = 未安装 watchfiles,无法实现插件的热重载。 -msg-f8e1c445 = 插件热重载监视任务异常: {$e} -msg-78b9c276 = {$res} -msg-28aeca68 = 检测到文件变化: {$changes} -msg-aeec7738 = 检测到插件 {$plugin_name} 文件变化,正在重载... -msg-4f989555 = 插件 {$d} 未找到 main.py 或者 {$d}.py,跳过。 -msg-74b32804 = 正在安装插件 {$p} 所需的依赖库: {$pth} -msg-936edfca = 更新插件 {$p} 的依赖失败。Code: {$e} -msg-ebd47311 = 插件 {$root_dir_name} 导入失败,尝试从已安装依赖恢复: {$import_exc} -msg-1b6e94f1 = 插件 {$root_dir_name} 已从 site-packages 恢复依赖,跳过重新安装。 -msg-81b7c9b9 = 插件 {$root_dir_name} 已安装依赖恢复失败,将重新安装依赖: {$recover_exc} + +msg-bfa28c02 = watchfiles is not installed, hot reload of plugins cannot be implemented. +msg-f8e1c445 = 插件热重载监视任务异常:{ $e } +msg-78b9c276 = { $res } +msg-28aeca68 = Detected file changes:{ $changes } +msg-aeec7738 = 检测到插件{ $plugin_name }文件变化,正在重载... +msg-4f989555 = 插件{ $d }未找到 main.py 或者{ $d }.py,跳过。 +msg-74b32804 = 正在安装插件{ $p }所需的依赖库:{ $pth } +msg-936edfca = Update plugin{ $p }Dependency failed. Code:{ $e } +msg-ebd47311 = 插件{ $root_dir_name }Import failed, attempting to recover from installed dependencies:{ $import_exc } +msg-1b6e94f1 = 插件{ $root_dir_name }已从 site-packages 恢复依赖,跳过重新安装。 +msg-81b7c9b9 = 插件{ $root_dir_name }已安装依赖恢复失败,将重新安装依赖:{ $recover_exc } msg-22fde75d = 插件不存在。 -msg-3a307a9e = 插件元数据信息不完整。name, desc, version, author 是必须的字段。 -msg-55e089d5 = 删除模块 {$key} -msg-64de1322 = 删除模块 {$module_name} -msg-66823424 = 模块 {$module_name} 未载入 -msg-45c8df8d = 清除了插件{$dir_name}中的{$key}模块 -msg-f7d9aa9b = 清理处理器: {$res} -msg-3c492aa6 = 清理工具: {$res} -msg-e0002829 = 插件 {$res} 未被正常终止: {$e}, 可能会导致该插件运行不正常。 -msg-0fe27735 = 正在载入插件 {$root_dir_name} ... -msg-b2ec4801 = {$error_trace} -msg-db351291 = 插件 {$root_dir_name} 导入失败。原因:{$e} -msg-a3db5f45 = 失败插件依旧在插件列表中,正在清理... -msg-58c66a56 = 插件 {$root_dir_name} 元数据载入失败: {$e}。使用默认元数据。 -msg-da764b29 = {$metadata} -msg-17cd7b7d = 插件 {$res} 已被禁用。 -msg-4baf6814 = 插件 {$path} 未通过装饰器注册。尝试通过旧版本方式载入。 -msg-840994d1 = 无法找到插件 {$plugin_dir_path} 的元数据。 -msg-944ffff1 = 插入权限过滤器 {$cmd_type} 到 {$res} 的 {$res_2} 方法。 -msg-64edd12c = hook(on_plugin_loaded) -> {$res} - {$res_2} -msg-db49f7a1 = ----- 插件 {$root_dir_name} 载入失败 ----- -msg-26039659 = | {$line} -msg-4292f44d = ---------------------------------- -msg-d2048afe = 同步指令配置失败: {$e} -msg-df515dec = 已清理安装失败的插件目录: {$plugin_path} -msg-1f2aa1a9 = 清理安装失败插件目录失败: {$plugin_path},原因: {$e} -msg-1e947210 = 已清理安装失败插件配置: {$plugin_config_path} -msg-7374541f = 清理安装失败插件配置失败: {$plugin_config_path},原因: {$e} -msg-e871b08f = 读取插件 {$dir_name} 的 README.md 文件失败: {$e} +msg-3a307a9e = 插件元数据信息不完整。name、desc、version、author 是必须的字段。 +msg-55e089d5 = 删除模块{ $key } +msg-64de1322 = 删除模块{ $module_name } +msg-66823424 = 模块{ $module_name }未载入 +msg-45c8df8d = Cleared plugin{ $dir_name }中的{ $key }模块 +msg-f7d9aa9b = 清理处理器:{ $res } +msg-3c492aa6 = Cleanup Tool:{ $res } +msg-e0002829 = 插件{ $res }Not properly terminated:{ $e }, 可能会导致该插件运行不正常。 +msg-0fe27735 = 正在载入插件{ $root_dir_name }... +msg-b2ec4801 = { $error_trace } +msg-db351291 = 插件{ $root_dir_name }Import failed. Reason:{ $e } +msg-a3db5f45 = Failed plugins are still in the plugin list, cleaning up... +msg-58c66a56 = 插件{ $root_dir_name }Metadata loading failed:{ $e }使用默认元数据。 +msg-da764b29 = { $metadata } +msg-17cd7b7d = 插件{ $res }已被禁用。 +msg-4baf6814 = 插件{ $path }未通过装饰器注册。尝试通过旧版本方式载入。 +msg-840994d1 = Plugin not found{ $plugin_dir_path }的元数据。 +msg-944ffff1 = 插入权限过滤器{ $cmd_type }到{ $res }的{ $res_2 }方法。 +msg-64edd12c = 钩子函数(on_plugin_loaded){ $res }-{ $res_2 } +msg-db49f7a1 = ----- 插件{ $root_dir_name }载入失败 +msg-26039659 = 待翻译文本:{ $line } +msg-4292f44d = 待翻译文本:---------------------------------- +msg-d2048afe = 同步指令配置失败:{ $e } +msg-df515dec = 已清理安装失败的插件目录:{ $plugin_path } +msg-1f2aa1a9 = Failed to clean up the installation directory for the failed plugin:{ $plugin_path },原因:{ $e } +msg-1e947210 = 已清理安装失败插件配置:{ $plugin_config_path } +msg-7374541f = 清理安装失败插件配置失败:{ $plugin_config_path },原因:{ $e } +msg-e871b08f = 读取插件{ $dir_name }的 README.md 文件失败:{ $e } msg-70ca4592 = 该插件是 AstrBot 保留插件,无法卸载。 -msg-e247422b = 插件 {$plugin_name} 未被正常终止 {$e}, 可能会导致资源泄露等问题。 -msg-0c25dbf4 = 插件 {$plugin_name} 数据不完整,无法卸载。 -msg-d6f8142c = 移除插件成功,但是删除插件文件夹失败: {$e}。您可以手动删除该文件夹,位于 addons/plugins/ 下。 -msg-6313500c = 已删除插件 {$plugin_name} 的配置文件 -msg-f0f01b67 = 删除插件配置文件失败: {$e} -msg-c4008b30 = 已删除插件 {$plugin_name} 的持久化数据 (plugin_data) -msg-88d1ee05 = 删除插件持久化数据失败 (plugin_data): {$e} -msg-ba805469 = 已删除插件 {$plugin_name} 的持久化数据 (plugins_data) -msg-cf6eb821 = 删除插件持久化数据失败 (plugins_data): {$e} -msg-e1853811 = 移除了插件 {$plugin_name} 的处理函数 {$res} ({$res_2}) -msg-95b20050 = 移除了插件 {$plugin_name} 的平台适配器 {$adapter_name} +msg-e247422b = 插件{ $plugin_name }Not properly terminated{ $e }, 可能导致资源泄漏等问题。 +msg-0c25dbf4 = 插件{ $plugin_name }数据不完整,无法卸载。 +msg-d6f8142c = 插件已成功移除,但删除插件文件夹失败:{ $e }您可以手动删除该文件夹,位于 addons/plugins/ 下。 +msg-6313500c = 已删除插件{ $plugin_name }的配置文件 +msg-f0f01b67 = 删除插件配置文件失败:{ $e } +msg-c4008b30 = 已删除插件{ $plugin_name }持久化数据 (plugin_data) +msg-88d1ee05 = 删除插件持久化数据失败 (plugin_data):{ $e } +msg-ba805469 = 已删除插件{ $plugin_name }的持久化数据 (plugins_data) +msg-cf6eb821 = Failed to delete plugin persistent data (plugins_data):{ $e } +msg-e1853811 = 移除了插件{ $plugin_name }的处理函数{ $res }待翻译文本:({ $res_2 }) +msg-95b20050 = Removed plugin{ $plugin_name }的平台适配器{ $adapter_name } msg-9f248e88 = 该插件是 AstrBot 保留插件,无法更新。 -msg-ff435883 = 正在终止插件 {$res} ... -msg-355187b7 = 插件 {$res} 未被激活,不需要终止,跳过。 -msg-4369864f = hook(on_plugin_unloaded) -> {$res} - {$res_2} -msg-1b95e855 = 插件 {$plugin_name} 不存在。 -msg-c1bc6cd6 = 检测到插件 {$res} 已安装,正在终止旧插件... -msg-4f3271db = 检测到同名插件 {$res} 存在于不同目录 {$res_2},正在终止... -msg-d247fc54 = 读取新插件 metadata.yaml 失败,跳过同名检查: {$e} -msg-0f8947f8 = 删除插件压缩包失败: {$e} +msg-ff435883 = 正在终止插件{ $res }... +msg-355187b7 = 插件{ $res }Not activated, no termination required, skipping. +msg-4369864f = hook(on_plugin_unloaded) ->{ $res }-{ $res_2 } +msg-1b95e855 = 插件{ $plugin_name }不存在。 +msg-c1bc6cd6 = 检测到插件{ $res }已安装,正在终止旧插件... +msg-4f3271db = 检测到同名插件{ $res }存在于不同目录{ $res_2 },正在终止... +msg-d247fc54 = Failed to read new plugin metadata.yaml, skipping duplicate name check:{ $e } +msg-0f8947f8 = Failed to delete plugin archive:{ $e } ### astrbot/core/star/session_llm_manager.py -msg-7b90d0e9 = 会话 {$session_id} 的TTS状态已更新为: {$res} + +msg-7b90d0e9 = 会话{ $session_id }TTS状态已更新为:{ $res } ### astrbot/core/star/config.py + msg-c2189e8d = namespace 不能为空。 msg-97f66907 = namespace 不能以 internal_ 开头。 -msg-09179604 = key 只支持 str 类型。 -msg-1163e4f1 = value 只支持 str, int, float, bool, list 类型。 -msg-ed0f93e4 = 配置文件 {$namespace}.json 不存在。 -msg-e3b5cdfb = 配置项 {$key} 不存在。 +msg-09179604 = key 仅支持 str 类型。 +msg-1163e4f1 = value 仅支持 str、int、float、bool、list 类型。 +msg-ed0f93e4 = 配置文件{ $namespace }.json 不存在。 +msg-e3b5cdfb = Configuration item{ $key }不存在。 ### astrbot/core/star/star_tools.py -msg-397b7bf9 = StarTools not initialized + +msg-397b7bf9 = StarTools 未初始化 msg-ca30e638 = 未找到适配器: AiocqhttpAdapter -msg-77ca0ccb = 不支持的平台: {$platform} +msg-77ca0ccb = Unsupported platform:{ $platform } msg-3ed67eb2 = 无法获取调用者模块信息 -msg-e77ccce6 = 无法获取模块 {$res} 的元数据信息 -msg-76ac38ee = 无法获取插件名称 -msg-751bfd23 = 无法创建目录 {$data_dir}:权限不足 -msg-68979283 = 无法创建目录 {$data_dir}:{$e} +msg-e77ccce6 = Unable to retrieve module{ $res }Metadata information of +msg-76ac38ee = Unable to get plugin name +msg-751bfd23 = Unable to create directory{ $data_dir }权限不足 +msg-68979283 = 无法创建目录{ $data_dir }待翻译文本:{ $e } ### astrbot/core/star/context.py -msg-60eb9e43 = Provider {$chat_provider_id} not found -msg-da70a6fb = Agent did not produce a final LLM response -msg-141151fe = Provider not found -msg-a5cb19c6 = 没有找到 ID 为 {$provider_id} 的提供商,这可能是由于您修改了提供商(模型)ID 导致的。 -msg-2a44300b = 该会话来源的对话模型(提供商)的类型不正确: {$res} + +msg-60eb9e43 = 提供方{ $chat_provider_id }未找到 +msg-da70a6fb = 代理未生成最终LLM响应 +msg-141151fe = 未找到提供商 +msg-a5cb19c6 = 未找到 ID 为{ $provider_id }的提供商,这可能是由于您修改了提供商(模型)ID 导致的。 +msg-2a44300b = The type of the conversation model (provider) for this session source is incorrect:{ $res } msg-37c286ea = 返回的 Provider 不是 TTSProvider 类型 msg-ff775f3b = 返回的 Provider 不是 STTProvider 类型 -msg-fd8c8295 = cannot find platform for session {$res}, message not sent -msg-2b806a28 = plugin(module_path {$module_path}) added LLM tool: {$res} +msg-fd8c8295 = 无法找到会话的平台{ $res }消息未发送 +msg-2b806a28 = 插件(模块路径{ $module_path }) 已添加LLM工具:{ $res } ### astrbot/core/star/updator.py -msg-66be72ec = 插件 {$res} 没有指定仓库地址。 -msg-7a29adea = 插件 {$res} 的根目录名未指定。 -msg-99a86f88 = 正在更新插件,路径: {$plugin_path},仓库地址: {$repo_url} -msg-df2c7e1b = 删除旧版本插件 {$plugin_path} 文件夹失败: {$e},使用覆盖安装。 -msg-b3471491 = 正在解压压缩包: {$zip_path} -msg-7197ad11 = 删除临时文件: {$zip_path} 和 {$res} -msg-f8a43aa5 = 删除更新文件失败,可以手动删除 {$zip_path} 和 {$res} + +msg-66be72ec = 插件{ $res }未指定仓库地址。 +msg-7a29adea = 插件{ $res }的根目录名未指定。 +msg-99a86f88 = 正在更新插件,路径:{ $plugin_path }仓库地址:{ $repo_url } +msg-df2c7e1b = 删除旧版本插件{ $plugin_path }Folder failed:{ $e }使用覆盖安装。 +msg-b3471491 = 正在解压压缩包:{ $zip_path } +msg-7197ad11 = 删除临时文件:{ $zip_path }和{ $res } +msg-f8a43aa5 = 删除更新文件失败,可以手动删除{ $zip_path }和{ $res } ### astrbot/core/star/command_management.py + msg-011581bb = 指定的处理函数不存在或不是指令。 msg-a0c37004 = 指令名不能为空。 -msg-ae8b2307 = 指令名 '{$candidate_full}' 已被其他指令占用。 -msg-247926a7 = 别名 '{$alias_full}' 已被其他指令占用。 +msg-ae8b2307 = Command name '{ $candidate_full }' 已被其他指令占用。 +msg-247926a7 = 别名{ $alias_full }已被其他指令占用。 msg-dbd19a23 = 权限类型必须为 admin 或 member。 msg-9388ea1e = 未找到指令所属插件 -msg-0dd9b70d = 解析指令处理函数 {$res} 失败,跳过该指令。原因: {$e} +msg-0dd9b70d = Parse instruction processing function{ $res }失败,跳过该指令。原因:{ $e } ### astrbot/core/star/base.py -msg-57019272 = get_config() failed: {$e} + +msg-57019272 = get_config() 失败:{ $e } ### astrbot/core/star/register/star.py -msg-64619f8e = The 'register_star' decorator is deprecated and will be removed in a future version. + +msg-64619f8e = 'register_star' 装饰器已被弃用,将在未来版本中移除。 ### astrbot/core/star/register/star_handler.py -msg-7ff2d46e = 注册指令{$command_name} 的子指令时未提供 sub_command 参数。 + +msg-7ff2d46e = 注册指令{ $command_name }The sub-command parameter was not provided when executing the sub-command. msg-b68436e1 = 注册裸指令时未提供 command_name 参数。 -msg-1c183df2 = {$command_group_name} 指令组的子指令组 sub_command 未指定 +msg-1c183df2 = { $command_group_name }指令组的子指令组 sub_command 未指定 msg-9210c7e8 = 根指令组的名称未指定 -msg-678858e7 = 注册指令组失败。 -msg-6c3915e0 = LLM 函数工具 {$res}_{$llm_tool_name} 的参数 {$res_2} 缺少类型注释。 -msg-1255c964 = LLM 函数工具 {$res}_{$llm_tool_name} 不支持的参数类型:{$res_2} +msg-678858e7 = Failed to register the command group. +msg-6c3915e0 = LLM 函数工具{ $res }_{ $llm_tool_name }的参数{ $res_2 }缺少类型注释。 +msg-1255c964 = LLM 函数工具{ $res }_{ $llm_tool_name }不支持的参数类型:{ $res_2 } ### astrbot/core/star/filter/command.py -msg-995944c2 = 参数 '{$param_name}' (GreedyStr) 必须是最后一个参数。 -msg-04dbdc3a = 必要参数缺失。该指令完整参数: {$res} -msg-bda71712 = 参数 {$param_name} 必须是布尔值(true/false, yes/no, 1/0)。 -msg-a9afddbf = 参数 {$param_name} 类型错误。完整参数: {$res} + +msg-995944c2 = 参数 '{ $param_name }(GreedyStr) 必须是最后一个参数。 +msg-04dbdc3a = Required parameters are missing. The complete parameters for this command are:{ $res } +msg-bda71712 = 参数{ $param_name }必须是布尔值(true/false, yes/no, 1/0)。 +msg-a9afddbf = 参数{ $param_name }类型错误。完整参数:{ $res } ### astrbot/core/star/filter/custom_filter.py -msg-8f3eeb6e = Operands must be subclasses of CustomFilter. -msg-732ada95 = CustomFilter class can only operate with other CustomFilter. -msg-51c0c77d = CustomFilter lass can only operate with other CustomFilter. + +msg-8f3eeb6e = 操作数必须是CustomFilter的子类。 +msg-732ada95 = CustomFilter类只能与其他CustomFilter类一起操作。 +msg-51c0c77d = CustomFilter 类只能与其他 CustomFilter 类共同操作。 ### astrbot/core/db/vec_db/faiss_impl/document_storage.py -msg-c2dc1d2b = Database connection is not initialized, returning empty result -msg-51fa7426 = Database connection is not initialized, skipping delete operation -msg-43d1f69f = Database connection is not initialized, returning 0 + +msg-c2dc1d2b = 数据库连接未初始化,返回空结果 +msg-51fa7426 = 数据库连接未初始化,跳过删除操作 +msg-43d1f69f = 数据库连接未初始化,返回0 ### astrbot/core/db/vec_db/faiss_impl/embedding_storage.py + msg-8e5fe535 = faiss 未安装。请使用 'pip install faiss-cpu' 或 'pip install faiss-gpu' 安装。 -msg-9aa7b941 = 向量维度不匹配, 期望: {$res}, 实际: {$res_2} +msg-9aa7b941 = 向量维度不匹配,期望:{ $res }实际:{ $res_2 } ### astrbot/core/db/vec_db/faiss_impl/vec_db.py -msg-9f9765dc = Generating embeddings for {$res} contents... -msg-385bc50a = Generated embeddings for {$res} contents in {$res_2} seconds. + +msg-9f9765dc = 正在生成嵌入向量{ $res }内容... +msg-385bc50a = 已生成嵌入{ $res }内容在{ $res_2 }秒。 ### astrbot/core/db/migration/migra_token_usage.py + msg-c3e53a4f = 开始执行数据库迁移(添加 conversations.token_usage 列)... msg-ccbd0a41 = token_usage 列已存在,跳过迁移 msg-39f60232 = token_usage 列添加成功 msg-4f9d3876 = token_usage 迁移完成 -msg-91571aaf = 迁移过程中发生错误: {$e} +msg-91571aaf = 迁移过程中发生错误:{ $e } ### astrbot/core/db/migration/migra_3_to_4.py -msg-7805b529 = 迁移 {$total_cnt} 条旧的会话数据到新的表中... -msg-6f232b73 = 进度: {$progress}% ({$res}/{$total_cnt}) -msg-6b1def31 = 未找到该条旧会话对应的具体数据: {$conversation}, 跳过。 -msg-b008c93f = 迁移旧会话 {$res} 失败: {$e} -msg-6ac6313b = 成功迁移 {$total_cnt} 条旧的会话数据到新表。 -msg-6b72e89b = 迁移旧平台数据,offset_sec: {$offset_sec} 秒。 -msg-bdc90b84 = 迁移 {$res} 条旧的平台数据到新的表中... -msg-e6caca5c = 没有找到旧平台数据,跳过迁移。 -msg-1e824a79 = 进度: {$progress}% ({$res}/{$total_buckets}) -msg-813384e2 = 迁移平台统计数据失败: {$platform_id}, {$platform_type}, 时间戳: {$bucket_end} -msg-27ab191d = 成功迁移 {$res} 条旧的平台数据到新表。 -msg-8e6280ed = 迁移 {$total_cnt} 条旧的 WebChat 会话数据到新的表中... -msg-cad66fe1 = 迁移旧 WebChat 会话 {$res} 失败 -msg-63748a46 = 成功迁移 {$total_cnt} 条旧的 WebChat 会话数据到新表。 -msg-dfc93fa4 = 迁移 {$total_personas} 个 Persona 配置到新表中... -msg-ff85e45c = 进度: {$progress}% ({$res}/{$total_personas}) -msg-c346311e = 迁移 Persona {$res}({$res_2}...) 到新表成功。 -msg-b6292b94 = 解析 Persona 配置失败:{$e} -msg-90e5039e = 迁移全局偏好设置 {$key} 成功,值: {$value} -msg-d538da1c = 迁移会话 {$umo} 的对话数据到新表成功,平台 ID: {$platform_id} -msg-ee03c001 = 迁移会话 {$umo} 的对话数据失败: {$e} -msg-5c4339cd = 迁移会话 {$umo} 的服务配置到新表成功,平台 ID: {$platform_id} -msg-4ce2a0b2 = 迁移会话 {$umo} 的服务配置失败: {$e} -msg-2e62dab9 = 迁移会话 {$umo} 的变量失败: {$e} -msg-afbf819e = 迁移会话 {$umo} 的提供商偏好到新表成功,平台 ID: {$platform_id} -msg-959bb068 = 迁移会话 {$umo} 的提供商偏好失败: {$e} + +msg-7805b529 = 迁移{ $total_cnt }迁移旧的会话数据到新的表中... +msg-6f232b73 = 进度:{ $progress }% ({ $res }待翻译文本:{ $total_cnt }) +msg-6b1def31 = 未找到该条旧会话对应的具体数据:{ $conversation }跳过。 +msg-b008c93f = 迁移旧会话{ $res }失败:{ $e } +msg-6ac6313b = 成功迁移{ $total_cnt }Migrate old session data to the new table. +msg-6b72e89b = 迁移旧平台数据,offset_sec:{ $offset_sec }秒。 +msg-bdc90b84 = 迁移{ $res }正在将旧的平台数据迁移到新的表中... +msg-e6caca5c = 未找到旧平台数据,跳过迁移。 +msg-1e824a79 = 进度:{ $progress }% ({ $res }待翻译文本:{ $total_buckets }) +msg-813384e2 = 迁移平台统计数据失败:{ $platform_id },{ $platform_type }, 时间戳:{ $bucket_end } +msg-27ab191d = 成功迁移{ $res }迁移旧的平台数据到新表。 +msg-8e6280ed = 迁移{ $total_cnt }正在迁移旧的 WebChat 会话数据到新的表中... +msg-cad66fe1 = 迁移旧 WebChat 会话{ $res }失败 +msg-63748a46 = 成功迁移{ $total_cnt }Migrate old WebChat session data to the new table. +msg-dfc93fa4 = 迁移{ $total_personas }正在将 Persona 配置迁移到新表... +msg-ff85e45c = 进度:{ $progress }% ({ $res }/{ $total_personas }) +msg-c346311e = 迁移 Persona{ $res }待翻译文本:({ $res_2 }...) 到新表成功。 +msg-b6292b94 = 解析 Persona 配置失败:{ $e } +msg-90e5039e = 迁移全局偏好设置{ $key }成功,值:{ $value } +msg-d538da1c = 迁移会话{ $umo }的对话数据到新表成功,平台 ID:{ $platform_id } +msg-ee03c001 = 迁移会话{ $umo }Failed to get conversation data:{ $e } +msg-5c4339cd = 迁移会话{ $umo }的服务配置到新表成功,平台 ID:{ $platform_id } +msg-4ce2a0b2 = 迁移会话{ $umo }服务配置失败:{ $e } +msg-2e62dab9 = 迁移会话{ $umo }变量失败:{ $e } +msg-afbf819e = 迁移会话{ $umo }Provider preference successfully migrated to new table, platform ID:{ $platform_id } +msg-959bb068 = 迁移会话{ $umo }Provider preference failed:{ $e } ### astrbot/core/db/migration/helper.py + msg-a48f4752 = 开始执行数据库迁移... msg-45e31e8e = 数据库迁移完成。 ### astrbot/core/db/migration/migra_45_to_46.py -msg-782b01c1 = migrate_45_to_46: abconf_data is not a dict (type={$res}). Value: {$abconf_data} -msg-49e09620 = Starting migration from version 4.5 to 4.6 -msg-791b79f8 = Migration from version 45 to 46 completed successfully + +msg-782b01c1 = migrate_45_to_46:abconf_data 不是字典类型(type={ $res }). 值:{ $abconf_data } +msg-49e09620 = 开始从版本 4.5 迁移到 4.6 +msg-791b79f8 = 从版本45到46的迁移已成功完成 ### astrbot/core/db/migration/migra_webchat_session.py + msg-53fad3d0 = 开始执行数据库迁移(WebChat 会话迁移)... msg-7674efb0 = 没有找到需要迁移的 WebChat 数据 -msg-139e39ee = 找到 {$res} 个 WebChat 会话需要迁移 -msg-cf287e58 = 会话 {$session_id} 已存在,跳过 -msg-062c72fa = WebChat 会话迁移完成!成功迁移: {$res}, 跳过: {$skipped_count} +msg-139e39ee = 找到{ $res }个 WebChat 会话需要迁移 +msg-cf287e58 = Session{ $session_id }已存在,跳过 +msg-062c72fa = WebChat 会话迁移完成!成功迁移:{ $res }, 跳过:{ $skipped_count } msg-a516cc9f = 没有新会话需要迁移 -msg-91571aaf = 迁移过程中发生错误: {$e} +msg-91571aaf = 迁移过程中发生错误:{ $e } ### astrbot/core/knowledge_base/kb_helper.py -msg-7b3dc642 = - LLM call failed on attempt {$res}/{$res_2}. Error: {$res_3} -msg-4ba9530f = - Failed to process chunk after {$res} attempts. Using original text. -msg-77670a3a = 知识库 {$res} 未配置 Embedding Provider -msg-8e9eb3f9 = 无法找到 ID 为 {$res} 的 Embedding Provider -msg-3e426806 = 无法找到 ID 为 {$res} 的 Rerank Provider -msg-6e780e1e = 使用预分块文本进行上传,共 {$res} 个块。 + +msg-7b3dc642 = - 第 {$attempt} 次尝试时 LLM 调用失败{ $res }待翻译文本:{ $res_2 }错误:{ $res_3 } +msg-4ba9530f = - 处理块后失败{ $res }尝试次数。使用原文。 +msg-77670a3a = 知识库{ $res }未配置 Embedding Provider +msg-8e9eb3f9 = Cannot find ID{ $res }的嵌入提供程序 +msg-3e426806 = Cannot find the ID{ $res }的重新排序提供商 +msg-6e780e1e = 使用预分块文本进行上传,共{ $res }个块。 msg-f4b82f18 = 当未提供 pre_chunked_text 时,file_content 不能为空。 -msg-975f06d7 = 上传文档失败: {$e} -msg-969b17ca = 清理多媒体文件失败 {$media_path}: {$me} -msg-18d25e55 = 无法找到 ID 为 {$doc_id} 的文档 -msg-f5d7c34c = Error: Tavily API key is not configured in provider_settings. -msg-975d88e0 = Failed to extract content from URL {$url}: {$e} -msg-cfe431b3 = No content extracted from URL: {$url} -msg-e7f5f836 = 内容清洗后未提取到有效文本。请尝试关闭内容清洗功能,或更换更高性能的LLM模型后重试。 -msg-693aa5c5 = 内容清洗未启用,使用指定参数进行分块: chunk_size={$chunk_size}, chunk_overlap={$chunk_overlap} +msg-975f06d7 = Failed to upload document:{ $e } +msg-969b17ca = Failed to clean up multimedia files{ $media_path }待翻译文本:{ $me } +msg-18d25e55 = 无法找到 ID 为{ $doc_id }Documentation +msg-f5d7c34c = 错误:Tavily API 密钥未在 provider_settings 中配置。 +msg-975d88e0 = 无法从URL提取内容{ $url }:{ $e } +msg-cfe431b3 = 未从URL提取到内容:{ $url } +msg-e7f5f836 = Content cleaning did not extract valid text. Please try turning off the content cleaning feature or retry after switching to a higher-performance LLM model. +msg-693aa5c5 = 内容清洗未启用,使用指定参数进行分块: chunk_size={ $chunk_size }, 块重叠={ $chunk_overlap } msg-947d8f46 = 启用了内容清洗,但未提供 cleaning_provider_id,跳过清洗并使用默认分块。 -msg-31963d3f = 无法找到 ID 为 {$cleaning_provider_id} 的 LLM Provider 或类型不正确 -msg-82728272 = 初步分块完成,生成 {$res} 个块用于修复。 -msg-6fa5fdca = 块 {$i} 处理异常: {$res}. 回退到原始块。 -msg-6780e950 = 文本修复完成: {$res} 个原始块 -> {$res_2} 个最终块。 -msg-79056c76 = 使用 Provider '{$cleaning_provider_id}' 清洗内容失败: {$e} +msg-31963d3f = 无法找到 ID 为{ $cleaning_provider_id }LLM Provider 或类型不正确 +msg-82728272 = 初步分块完成,生成{ $res }个块用于修复。 +msg-6fa5fdca = 块{ $i }处理异常:{ $res }. 回退到原始块。 +msg-6780e950 = Text restoration completed:{ $res }个原始块 ->{ $res_2 }个最终块。 +msg-79056c76 = 使用 Provider{ $cleaning_provider_id }清洗内容失败:{ $e } ### astrbot/core/knowledge_base/kb_mgr.py + msg-98bfa670 = 正在初始化知识库模块... -msg-7da7ae15 = 知识库模块导入失败: {$e} -msg-842a3c65 = 请确保已安装所需依赖: pypdf, aiofiles, Pillow, rank-bm25 -msg-c9e943f7 = 知识库模块初始化失败: {$e} -msg-78b9c276 = {$res} -msg-9349e112 = KnowledgeBase database initialized: {$DB_PATH} +msg-7da7ae15 = 知识库模块导入失败:{ $e } +msg-842a3c65 = 请确保已安装所需依赖:pypdf、aiofiles、Pillow、rank-bm25 +msg-c9e943f7 = 知识库模块初始化失败:{ $e } +msg-78b9c276 = { $res } +msg-9349e112 = KnowledgeBase数据库已初始化:{ $DB_PATH } msg-7605893e = 创建知识库时必须提供embedding_provider_id -msg-0b632cbd = 知识库名称 '{$kb_name}' 已存在 -msg-ca30330f = 关闭知识库 {$kb_id} 失败: {$e} -msg-00262e1f = 关闭知识库元数据数据库失败: {$e} -msg-3fc9ef0b = Knowledge base with id {$kb_id} not found. +msg-0b632cbd = 知识库名称{ $kb_name }已存在 +msg-ca30330f = 关闭知识库{ $kb_id }失败:{ $e } +msg-00262e1f = Failed to close knowledge base metadata database:{ $e } +msg-3fc9ef0b = ID为的知识库{ $kb_id }未找到。 ### astrbot/core/knowledge_base/kb_db_sqlite.py -msg-b850e5d8 = 知识库数据库已关闭: {$res} + +msg-b850e5d8 = 知识库数据库已关闭:{ $res } ### astrbot/core/knowledge_base/parsers/util.py -msg-398b3580 = 暂时不支持的文件格式: {$ext} + +msg-398b3580 = Temporarily unsupported file format:{ $ext } ### astrbot/core/knowledge_base/parsers/url_parser.py -msg-2de85bf5 = Error: Tavily API keys are not configured. -msg-98ed69f4 = Error: url must be a non-empty string. -msg-7b14cdb7 = Tavily web extraction failed: {$reason}, status: {$res} -msg-cfe431b3 = No content extracted from URL: {$url} -msg-b0897365 = Failed to fetch URL {$url}: {$e} -msg-975d88e0 = Failed to extract content from URL {$url}: {$e} + +msg-2de85bf5 = 错误:未配置Tavily API密钥。 +msg-98ed69f4 = 错误:URL 必须为非空字符串。 +msg-7b14cdb7 = Tavily网页提取失败:{ $reason },状态:{ $res } +msg-cfe431b3 = 未从URL中提取到任何内容:{ $url } +msg-b0897365 = 获取URL失败{ $url }:{ $e } +msg-975d88e0 = 未能从URL提取内容{ $url }待翻译文本:{ $e } ### astrbot/core/knowledge_base/parsers/text_parser.py -msg-70cbd40d = 无法解码文件: {$file_name} + +msg-70cbd40d = 无法解码文件:{ $file_name } ### astrbot/core/knowledge_base/chunking/recursive.py -msg-21db456a = chunk_size must be greater than 0 -msg-c0656f4e = chunk_overlap must be non-negative -msg-82bd199c = chunk_overlap must be less than chunk_size + +msg-21db456a = 块大小必须大于0 +msg-c0656f4e = 块重叠必须为非负值 +msg-82bd199c = chunk_overlap 必须小于 chunk_size ### astrbot/core/knowledge_base/retrieval/manager.py -msg-fcc0dde2 = 知识库 ID {$kb_id} 实例未找到, 已跳过该知识库的检索 -msg-320cfcff = Dense retrieval across {$res} bases took {$res_2}s and returned {$res_3} results. -msg-90ffcfc8 = Sparse retrieval across {$res} bases took {$res_2}s and returned {$res_3} results. -msg-12bcf404 = Rank fusion took {$res}s and returned {$res_2} results. -msg-28c084bc = vec_db for kb_id {$kb_id} is not FaissVecDB -msg-cc0230a3 = 知识库 {$kb_id} 稠密检索失败: {$e} + +msg-fcc0dde2 = 知识库 ID{ $kb_id }Instance not found, skipped retrieval for this knowledge base. +msg-320cfcff = 密集检索跨域{ $res }基地遭受攻击{ $res_2 }s 并返回{ $res_3 }结果。 +msg-90ffcfc8 = 稀疏检索跨{ $res }基地占领{ $res_2 }已发送并返回{ $res_3 }结果。 +msg-12bcf404 = 排名融合耗时{ $res }和返回{ $res_2 }结果。 +msg-28c084bc = vec_db for kb_id{ $kb_id }不是 FaissVecDB +msg-cc0230a3 = Knowledge base{ $kb_id }Dense retrieval failed:{ $e } ### astrbot/core/skills/skill_manager.py -msg-ed9670ad = Zip file not found: {$zip_path} -msg-73f9cf65 = Uploaded file is not a valid zip archive. -msg-69eb5f95 = Zip archive is empty. -msg-9e9abb4c = {$top_dirs} -msg-20b8533f = Zip archive must contain a single top-level folder. -msg-1db1caf7 = Invalid skill folder name. -msg-d7814054 = Zip archive contains absolute paths. -msg-179bd10e = Zip archive contains invalid relative paths. -msg-90f2904e = Zip archive contains unexpected top-level entries. -msg-95775a4d = SKILL.md not found in the skill folder. -msg-a4117c0b = Skill folder not found after extraction. -msg-94041ef2 = Skill already exists. + +msg-ed9670ad = 未找到 Zip 文件:{ $zip_path } +msg-73f9cf65 = 上传的文件不是有效的zip归档文件。 +msg-69eb5f95 = 压缩文件为空。 +msg-9e9abb4c = { $top_dirs } +msg-20b8533f = ZIP归档必须包含一个顶级文件夹。 +msg-1db1caf7 = 技能文件夹名称无效。 +msg-d7814054 = 压缩包包含绝对路径。 +msg-179bd10e = ZIP 压缩包包含无效的相对路径。 +msg-90f2904e = 压缩归档包含意外的顶级条目。 +msg-95775a4d = 技能文件夹中未找到 SKILL.md 文件。 +msg-a4117c0b = 解压后未找到技能文件夹。 +msg-94041ef2 = 技能已存在。 ### astrbot/core/backup/importer.py -msg-c046b6e4 = {$msg} -msg-0e6f1f5d = 开始从 {$zip_path} 导入备份 -msg-2bf97ca0 = 备份导入完成: {$res} + +msg-c046b6e4 = { $msg } +msg-0e6f1f5d = 开始从{ $zip_path }Import Backup +msg-2bf97ca0 = 备份导入完成:{ $res } msg-e67dda98 = 备份文件缺少版本信息 -msg-8f871d9f = 版本差异警告: {$res} -msg-2d6da12a = 已清空表 {$table_name} -msg-7d21b23a = 清空表 {$table_name} 失败: {$e} -msg-ab0f09db = 已清空知识库表 {$table_name} -msg-7bcdfaee = 清空知识库表 {$table_name} 失败: {$e} -msg-43f008f1 = 清理知识库 {$kb_id} 失败: {$e} -msg-985cae66 = 未知的表: {$table_name} -msg-dfa8b605 = 导入记录到 {$table_name} 失败: {$e} -msg-89a2120c = 导入表 {$table_name}: {$count} 条记录 -msg-f1dec753 = 导入知识库记录到 {$table_name} 失败: {$e} -msg-9807bcd8 = 导入文档块失败: {$e} -msg-98a66293 = 导入附件 {$name} 失败: {$e} +msg-8f871d9f = 版本差异警告:{ $res } +msg-2d6da12a = 已清空表{ $table_name } +msg-7d21b23a = 清空表{ $table_name }失败:{ $e } +msg-ab0f09db = 已清空知识库表{ $table_name } +msg-7bcdfaee = Clear Knowledge Base Table{ $table_name }失败:{ $e } +msg-43f008f1 = 清理知识库{ $kb_id }失败:{ $e } +msg-985cae66 = Unknown table:{ $table_name } +msg-dfa8b605 = 导入记录到{ $table_name }失败:{ $e } +msg-89a2120c = Import Table{ $table_name }待翻译文本:{ $count }条记录 +msg-f1dec753 = Import knowledge base records into{ $table_name }失败:{ $e } +msg-9807bcd8 = Failed to import document blocks:{ $e } +msg-98a66293 = Import attachment{ $name }失败:{ $e } msg-39f2325f = 备份版本不支持目录备份,跳过目录导入 -msg-689050b6 = 已备份现有目录 {$target_dir} 到 {$backup_path} -msg-d51b3536 = 导入目录 {$dir_name}: {$file_count} 个文件 +msg-689050b6 = 已备份现有目录{ $target_dir }To{ $backup_path } +msg-d51b3536 = Import Directory{ $dir_name }待翻译文本:{ $file_count }个文件 ### astrbot/core/backup/exporter.py -msg-c7ed7177 = 开始导出备份到 {$zip_path} -msg-8099b694 = 备份导出完成: {$zip_path} -msg-75a4910d = 备份导出失败: {$e} -msg-2821fc92 = 导出表 {$table_name}: {$res} 条记录 -msg-52b7c242 = 导出表 {$table_name} 失败: {$e} -msg-56310830 = 导出知识库表 {$table_name}: {$res} 条记录 -msg-f4e8f57e = 导出知识库表 {$table_name} 失败: {$e} -msg-8e4ddd12 = 导出知识库文档失败: {$e} -msg-c1960618 = 导出 FAISS 索引: {$archive_path} -msg-314bf920 = 导出 FAISS 索引失败: {$e} -msg-528757b2 = 导出知识库媒体文件失败: {$e} -msg-d89d6dfe = 目录不存在,跳过: {$full_path} -msg-94527edd = 导出文件 {$file_path} 失败: {$e} -msg-cb773e24 = 导出目录 {$dir_name}: {$file_count} 个文件, {$total_size} 字节 -msg-ae929510 = 导出目录 {$dir_path} 失败: {$e} -msg-93e331d2 = 导出附件失败: {$e} + +msg-c7ed7177 = 开始导出备份到{ $zip_path } +msg-8099b694 = 备份导出完成:{ $zip_path } +msg-75a4910d = Backup export failed:{ $e } +msg-2821fc92 = Export Table{ $table_name }待翻译文本:{ $res }条记录 +msg-52b7c242 = 导出表{ $table_name }失败:{ $e } +msg-56310830 = 导出知识库表{ $table_name }待翻译文本:{ $res }条记录 +msg-f4e8f57e = Export Knowledge Base Table{ $table_name }失败:{ $e } +msg-8e4ddd12 = Exporting knowledge base documents failed:{ $e } +msg-c1960618 = Export FAISS Index:{ $archive_path } +msg-314bf920 = Failed to export FAISS index:{ $e } +msg-528757b2 = 导出知识库媒体文件失败:{ $e } +msg-d89d6dfe = Directory does not exist, skipping:{ $full_path } +msg-94527edd = Export file{ $file_path }失败:{ $e } +msg-cb773e24 = 导出目录{ $dir_name }待翻译文本:{ $file_count }个文件,{ $total_size }字节 +msg-ae929510 = Export Directory{ $dir_path }失败:{ $e } +msg-93e331d2 = Export attachment failed:{ $e } ### astrbot/core/computer/computer_client.py -msg-7cb974b8 = Uploading skills bundle to sandbox... -msg-130cf3e3 = Failed to upload skills bundle to sandbox. -msg-99188d69 = Failed to remove temp skills zip: {$zip_path} -msg-3f3c81da = Unknown booter type: {$booter_type} -msg-e20cc33a = Error booting sandbox for session {$session_id}: {$e} + +msg-7cb974b8 = 正在将技能包上传到沙箱环境... +msg-130cf3e3 = 无法将技能包上传到沙盒。 +msg-99188d69 = 无法删除临时技能压缩文件:{ $zip_path } +msg-3f3c81da = 未知启动器类型:{ $booter_type } +msg-e20cc33a = 启动会话沙箱时出错{ $session_id }待翻译文本:{ $e } ### astrbot/core/computer/tools/fs.py -msg-99ab0efe = Upload result: {$result} -msg-bca9d578 = File {$local_path} uploaded to sandbox at {$file_path} -msg-da21a6a5 = Error uploading file {$local_path}: {$e} -msg-93476abb = File {$remote_path} downloaded from sandbox to {$local_path} -msg-079c5972 = Error sending file message: {$e} -msg-ce35bb2c = Error downloading file {$remote_path}: {$e} + +msg-99ab0efe = 上传结果:{ $result } +msg-bca9d578 = 文件{ $local_path }已上传至沙盒环境{ $file_path } +msg-da21a6a5 = 文件上传错误{ $local_path }:{ $e } +msg-93476abb = 文件{ $remote_path }从沙箱下载到{ $local_path } +msg-079c5972 = 发送文件消息时出错:{ $e } +msg-ce35bb2c = 下载文件时出错{ $remote_path }待翻译文本:{ $e } ### astrbot/core/computer/booters/local.py -msg-487d0c91 = Path is outside the allowed computer roots. -msg-e5eb5377 = Blocked unsafe shell command. -msg-9e1e117f = Local computer booter initialized for session: {$session_id} -msg-2d7f95de = Local computer booter shutdown complete. -msg-82a45196 = LocalBooter does not support upload_file operation. Use shell instead. -msg-0457524a = LocalBooter does not support download_file operation. Use shell instead. + +msg-487d0c91 = 路径超出了允许的计算机根目录范围。 +msg-e5eb5377 = 已阻止不安全Shell命令。 +msg-9e1e117f = 本地计算机启动器已为会话初始化:{ $session_id } +msg-2d7f95de = 本地计算机引导程序关闭完成。 +msg-82a45196 = LocalBooter 不支持 upload_file 操作。请改用 shell。 +msg-0457524a = LocalBooter 不支持 download_file 操作。请改用 shell。 ### astrbot/core/computer/booters/shipyard.py -msg-b03115b0 = Got sandbox ship: {$res} for session: {$session_id} -msg-c5ce8bde = Error checking Shipyard sandbox availability: {$e} + +msg-b03115b0 = 沙盒船只已就绪:{ $res }对于会话:{ $session_id } +msg-c5ce8bde = 检查 Shipyard 沙箱可用性时出错:{ $e } ### astrbot/core/computer/booters/boxlite.py -msg-019c4d18 = Failed to exec operation: {$res} {$error_text} -msg-b135b7bd = Failed to upload file: {$e} -msg-873ed1c8 = File not found: {$path} -msg-f58ceec6 = Unexpected error uploading file: {$e} -msg-900ab999 = Checking health for sandbox {$ship_id} on {$res}... -msg-2a50d6f3 = Sandbox {$ship_id} is healthy -msg-fbdbe32f = Booting(Boxlite) for session: {$session_id}, this may take a while... -msg-b1f13f5f = Boxlite booter started for session: {$session_id} -msg-e93d0c30 = Shutting down Boxlite booter for ship: {$res} -msg-6deea473 = Boxlite booter for ship: {$res} stopped + +msg-019c4d18 = 执行操作失败:{ $res } { $error_text } +msg-b135b7bd = 文件上传失败:{ $e } +msg-873ed1c8 = 文件未找到:{ $path } +msg-f58ceec6 = 上传文件时发生意外错误:{ $e } +msg-900ab999 = 正在检查沙箱健康状况{ $ship_id }开启{ $res }... +msg-2a50d6f3 = 沙盒{ $ship_id }健康 +msg-fbdbe32f = 正在为会话启动(Boxlite):{ $session_id },这可能需要一些时间... +msg-b1f13f5f = Boxlite启动器已为会话启动:{ $session_id } +msg-e93d0c30 = 正在为飞船关闭Boxlite启动程序:{ $res } +msg-6deea473 = 船舶用Boxlite启动器:{ $res }已停止 ### astrbot/core/cron/manager.py -msg-724e64a9 = Skip scheduling basic cron job %s due to missing handler. -msg-78ef135f = Invalid timezone %s for cron job %s, fallback to system. -msg-e71c28d3 = run_once job missing run_at timestamp -msg-dd46e69f = Failed to schedule cron job {$res}: {$e} -msg-aa2e4688 = Unknown cron job type: {$res} -msg-186627d9 = Cron job {$job_id} failed: {$e} -msg-cb955de0 = Basic cron job handler not found for {$res} -msg-2029c4b2 = ActiveAgentCronJob missing session. -msg-6babddc9 = Invalid session for cron job: {$e} -msg-865a2b07 = Failed to build main agent for cron job. -msg-27c9c6b3 = Cron job agent got no response + +msg-724e64a9 = 跳过调度基本cron任务 %s,因为缺少处理器。 +msg-78ef135f = cron 作业 %s 的时区 %s 无效,已回退至系统时区。 +msg-e71c28d3 = run_once 作业缺少 run_at 时间戳 +msg-dd46e69f = 计划定时任务失败{ $res }待翻译文本:{ $e } +msg-aa2e4688 = 未知的定时任务类型:{ $res } +msg-186627d9 = 定时任务{ $job_id }失败:{ $e } +msg-cb955de0 = 未找到基础cron任务处理程序{ $res } +msg-2029c4b2 = ActiveAgentCronJob 缺少会话。 +msg-6babddc9 = 定时任务会话无效:{ $e } +msg-865a2b07 = 构建 cron 作业的主代理失败。 +msg-27c9c6b3 = Cron任务代理未收到响应 ### astrbot/utils/http_ssl_common.py -msg-7957c9b6 = Failed to load certifi CA bundle into SSL context; falling back to system trust store only: %s + +msg-7957c9b6 = 无法将certifi CA证书包加载到SSL上下文中;仅回退到系统信任存储:%s ### astrbot/cli/__main__.py -msg-fe494da6 = {$logo_tmpl} -msg-c8b2ff67 = Welcome to AstrBot CLI! -msg-d79e1ff9 = AstrBot CLI version: {$__version__} -msg-78b9c276 = {$res} -msg-14dd710d = Unknown command: {$command_name} + +msg-fe494da6 = { $logo_tmpl } +msg-c8b2ff67 = 欢迎使用 AstrBot CLI! +msg-78b9c276 = { $res } +msg-14dd710d = 未知命令:{ $command_name } ### astrbot/cli/utils/basic.py + msg-f4e0fd7b = 未安装管理面板 msg-2d090cc3 = 正在安装管理面板... msg-2eeb67e0 = 管理面板安装完成 msg-9c727dca = 管理面板已是最新版本 -msg-11b49913 = 管理面板版本: {$version} -msg-f0b6145e = 下载管理面板失败: {$e} -msg-9504d173 = 初始化管理面板目录... +msg-11b49913 = 管理面板版本:{ $version } +msg-f0b6145e = Failed to download management panel:{ $e } +msg-9504d173 = Initializing management panel directory... msg-699e2509 = 管理面板初始化完成 ### astrbot/cli/utils/plugin.py -msg-e327bc14 = 正在从默认分支下载 {$author}/{$repo} -msg-c804f59f = 获取 release 信息失败: {$e},将直接使用提供的 URL + +msg-e327bc14 = 正在从默认分支下载{ $author }待翻译文本:{ $repo } +msg-c804f59f = 获取 release 信息失败:{ $e }将直接使用提供的 URL msg-aa398bd5 = master 分支不存在,尝试下载 main 分支 -msg-5587d9fb = 读取 {$yaml_path} 失败: {$e} -msg-8dbce791 = 获取在线插件列表失败: {$e} -msg-6999155d = 插件 {$plugin_name} 未安装,无法更新 -msg-fa5e129a = 正在从 {$repo_url} {$res}插件 {$plugin_name}... -msg-9ac1f4db = 插件 {$plugin_name} {$res}成功 -msg-b9c719ae = {$res}插件 {$plugin_name} 时出错: {$e} +msg-5587d9fb = 读取{ $yaml_path }失败:{ $e } +msg-8dbce791 = 获取在线插件列表失败:{ $e } +msg-6999155d = 插件{ $plugin_name }Not installed, cannot update +msg-fa5e129a = 正在从{ $repo_url } { $res }插件{ $plugin_name }... +msg-9ac1f4db = 插件{ $plugin_name } { $res }成功 +msg-b9c719ae = { $res }插件{ $plugin_name }时出错:{ $e } ### astrbot/cli/commands/cmd_conf.py + msg-635b8763 = 日志级别必须是 DEBUG/INFO/WARNING/ERROR/CRITICAL 之一 msg-ebc250dc = 端口必须在 1-65535 范围内 msg-6ec400b6 = 端口必须是数字 msg-0b62b5ce = 用户名不能为空 -msg-89b5d3d5 = 密码不能为空 -msg-92e7c8ad = 无效的时区: {$value},请使用有效的IANA时区名称 +msg-89b5d3d5 = Password cannot be empty +msg-92e7c8ad = 无效的时区:{ $value }请使用有效的IANA时区名称 msg-e470e37d = 回调接口基址必须以 http:// 或 https:// 开头 -msg-6b615721 = {$root}不是有效的 AstrBot 根目录,如需初始化请使用 astrbot init -msg-f74c517c = 配置文件解析失败: {$e} -msg-d7c58bcc = 配置路径冲突: {$res} 不是字典 -msg-e16816cc = 不支持的配置项: {$key} -msg-e9cce750 = 配置已更新: {$key} -msg-1ed565aa = 原值: ******** -msg-1bf9569a = 新值: ******** -msg-f2a20ab3 = 原值: {$old_value} -msg-0c104905 = 新值: {$validated_value} -msg-ea9b4e2c = 未知的配置项: {$key} -msg-4450e3b1 = 设置配置失败: {$e} -msg-ba464bee = {$key}: {$value} -msg-72aab576 = 获取配置失败: {$e} -msg-c1693d1d = 当前配置: -msg-50be9b74 = {$key}: {$value} +msg-6b615721 = { $root }不是有效的 AstrBot 根目录,如需初始化请使用 astrbot init +msg-f74c517c = Configuration file parsing failed:{ $e } +msg-d7c58bcc = 配置路径冲突:{ $res }不是字典 +msg-e16816cc = Unsupported configuration item:{ $key } +msg-e9cce750 = Configuration updated:{ $key } +msg-1ed565aa = 原值: ******** +msg-1bf9569a = 新值: ******** +msg-f2a20ab3 = 原值:{ $old_value } +msg-0c104905 = 新值:{ $validated_value } +msg-ea9b4e2c = 未知的配置项:{ $key } +msg-4450e3b1 = 设置配置失败:{ $e } +msg-ba464bee = { $key }待翻译文本:{ $value } +msg-72aab576 = Failed to get configuration:{ $e } +msg-c1693d1d = Current Configuration: +msg-50be9b74 = { $key }待翻译文本:{ $value } ### astrbot/cli/commands/cmd_init.py -msg-a90a250e = Current Directory: {$astrbot_root} -msg-4deda62e = 如果你确认这是 Astrbot root directory, 你需要在当前目录下创建一个 .astrbot 文件标记该目录为 AstrBot 的数据目录。 -msg-3319bf71 = Created {$dot_astrbot} -msg-7054f44f = {$res}: {$path} -msg-b19edc8a = Initializing AstrBot... + +msg-a90a250e = 当前目录:{ $astrbot_root } +msg-4deda62e = 如果你确认这是 AstrBot 根目录,你需要在当前目录下创建一个 .astrbot 文件来标记该目录为 AstrBot 的数据目录。 +msg-3319bf71 = 已创建{ $dot_astrbot } +msg-7054f44f = { $res }待翻译文本:{ $path } +msg-b19edc8a = 正在初始化 AstrBot... msg-eebc39e3 = 无法获取锁文件,请检查是否有其他实例正在运行 -msg-e16da80f = 初始化失败: {$e} +msg-e16da80f = 初始化失败:{ $e } ### astrbot/cli/commands/cmd_run.py -msg-41ecc632 = {$astrbot_root}不是有效的 AstrBot 根目录,如需初始化请使用 astrbot init -msg-0ccaca23 = 启用插件自动重载 + +msg-41ecc632 = { $astrbot_root }不是有效的 AstrBot 根目录,如需初始化请使用 astrbot init +msg-0ccaca23 = Enable plugin auto reload msg-220914e7 = AstrBot 已关闭... msg-eebc39e3 = 无法获取锁文件,请检查是否有其他实例正在运行 -msg-85f241d3 = 运行时出现错误: {$e}{"\u000A"}{$res} +msg-85f241d3 = 运行时出现错误:{ $e }{ "\u000A" }{ $res } ### astrbot/cli/commands/cmd_plug.py -msg-cbd8802b = {$base}不是有效的 AstrBot 根目录,如需初始化请使用 astrbot init -msg-78b9c276 = {$res} -msg-83664fcf = {$val} {$val} {$val} {$val} {$val} -msg-56f3f0bf = {$res} {$res_2} {$res_3} {$res_4} {$desc} -msg-1d802ff2 = 插件 {$name} 已存在 + +msg-cbd8802b = { $base }不是有效的 AstrBot 根目录,如需初始化请使用 astrbot init +msg-78b9c276 = { $res } +msg-83664fcf = { $val } { $val } { $val } { $val } { $val } +msg-56f3f0bf = { $res } { $res_2 } { $res_3 } { $res_4 } { $desc } +msg-1d802ff2 = 插件{ $name }已存在 msg-a7be9d23 = 版本号必须为 x.y 或 x.y.z 格式 msg-4d81299b = 仓库地址必须以 http 开头 msg-93289755 = 下载插件模板... -msg-b21682dd = 重写插件信息... -msg-bffc8bfa = 插件 {$name} 创建成功 +msg-b21682dd = Rewriting plugin information... +msg-bffc8bfa = 插件{ $name }Created successfully msg-08eae1e3 = 未安装任何插件 -msg-1a021bf4 = 未找到可安装的插件 {$name},可能是不存在或已安装 -msg-c120bafd = 插件 {$name} 不存在或未安装 -msg-63da4867 = 插件 {$name} 已卸载 -msg-e4925708 = 卸载插件 {$name} 失败: {$e} -msg-f4d15a87 = 插件 {$name} 不需要更新或无法更新 +msg-1a021bf4 = No installable plugins found{ $name },可能是不存在或已安装 +msg-c120bafd = 插件{ $name }不存在或未安装 +msg-63da4867 = 插件{ $name }已卸载 +msg-e4925708 = 卸载插件{ $name }失败:{ $e } +msg-f4d15a87 = 插件{ $name }不需要更新或无法更新 msg-94b035f7 = 没有需要更新的插件 -msg-0766d599 = 发现 {$res} 个插件需要更新 -msg-bd5ab99c = 正在更新插件 {$plugin_name}... -msg-e32912b8 = 未找到匹配 '{$query}' 的插件 +msg-0766d599 = 发现{ $res }个插件需要更新 +msg-bd5ab99c = 正在更新插件{ $plugin_name }... +msg-e32912b8 = 未找到匹配 '{ $query }的插件 ### astrbot/dashboard/server.py + msg-e88807e2 = 未找到该路由 -msg-06151c57 = Missing API key -msg-88dca3cc = Invalid API key -msg-fd267dc8 = Insufficient API key scope +msg-06151c57 = 缺少 API 密钥 +msg-88dca3cc = 无效的API密钥 +msg-fd267dc8 = API密钥权限不足 msg-076fb3a3 = 未授权 msg-6f214cc1 = Token 过期 msg-5041dc95 = Token 无效 -msg-1241c883 = 检查端口 {$port} 时发生错误: {$e} -msg-7c3ba89d = Initialized random JWT secret for dashboard. +msg-1241c883 = 检查端口{ $port }时发生错误:{ $e } +msg-7c3ba89d = 仪表盘已初始化随机JWT密钥。 msg-a3adcb66 = WebUI 已被禁用 -msg-44832296 = 正在启动 WebUI, 监听地址: {$scheme}://{$host}:{$port} +msg-44832296 = 正在启动 WebUI, 监听地址:{ $scheme }://{ $host }待翻译文本:{ $port } msg-3eed4a73 = 提示: WebUI 将监听所有网络接口,请注意安全。(可在 data/cmd_config.json 中配置 dashboard.host 以修改 host) -msg-289a2fe8 = 错误:端口 {$port} 已被占用{"\u000A"}占用信息: {"\u000A"} {$process_info}{"\u000A"}请确保:{"\u000A"}1. 没有其他 AstrBot 实例正在运行{"\u000A"}2. 端口 {$port} 没有被其他程序占用{"\u000A"}3. 如需使用其他端口,请修改配置文件 -msg-6d1dfba8 = 端口 {$port} 已被占用 -msg-c0161c7c = {$display} -msg-ac4f2855 = dashboard.ssl.enable 为 true 时,必须配置 cert_file 和 key_file。 -msg-3e87aaf8 = SSL 证书文件不存在: {$cert_path} -msg-5ccf0a9f = SSL 私钥文件不存在: {$key_path} -msg-5e4aa3eb = SSL CA 证书文件不存在: {$ca_path} -msg-cb049eb2 = AstrBot WebUI 已经被优雅地关闭 +msg-289a2fe8 = 错误:端口{ $port }已被占用{ "\u000A" }占用信息:{ "\u000A" } { $process_info }{ "\u000A" }请确保:{ "\u000A" }1. 没有其他 AstrBot 实例正在运行{ "\u000A" }2. 端口{ $port }Not occupied by other programs{ "\u000A" }3. 如需使用其他端口,请修改配置文件 +msg-6d1dfba8 = 端口{ $port }已被占用 +msg-c0161c7c = { $display } +msg-ac4f2855 = 当 dashboard.ssl.enable 为 true 时,必须配置 cert_file 和 key_file。 +msg-3e87aaf8 = SSL certificate file does not exist:{ $cert_path } +msg-5ccf0a9f = SSL 私钥文件不存在:{ $key_path } +msg-5e4aa3eb = SSL CA 证书文件不存在:{ $ca_path } +msg-cb049eb2 = AstrBot WebUI 已经优雅地关闭 ### astrbot/dashboard/utils.py -msg-160bd44a = 缺少必要的库以生成 t-SNE 可视化。请安装 matplotlib 和 scikit-learn: {e} + +msg-160bd44a = 缺少必要的库以生成 t-SNE 可视化。请安装 matplotlib 和 scikit-learn:{ e } msg-aa3a3dbf = 未找到知识库 -msg-0e404ea3 = FAISS 索引不存在: {$index_path} +msg-0e404ea3 = FAISS index does not exist:{ $index_path } msg-8d92420c = 索引为空 -msg-24c0450e = 提取 {$res} 个向量用于可视化... +msg-24c0450e = Extract{ $res }个向量用于可视化... msg-632d0acf = 开始 t-SNE 降维... msg-61f0449f = 生成可视化图表... -msg-4436ad2b = 生成 t-SNE 可视化时出错: {$e} -msg-78b9c276 = {$res} +msg-4436ad2b = 生成 t-SNE 可视化时出错:{ $e } +msg-78b9c276 = { $res } ### astrbot/dashboard/routes/update.py -msg-a3503781 = 迁移失败: {$res} -msg-543d8e4d = 迁移失败: {$e} -msg-251a5f4a = 检查更新失败: {$e} (不影响除项目更新外的正常使用) -msg-aa6bff26 = /api/update/releases: {$res} -msg-c5170c27 = 下载管理面板文件失败: {$e}。 -msg-db715c26 = 更新依赖中... -msg-9a00f940 = 更新依赖失败: {$e} -msg-6f96e3ba = /api/update_project: {$res} -msg-3217b509 = 下载管理面板文件失败: {$e} -msg-9cff28cf = /api/update_dashboard: {$res} -msg-1198c327 = You are not permitted to do this operation in demo mode + +msg-a3503781 = 迁移失败:{ $res } +msg-543d8e4d = 迁移失败:{ $e } +msg-251a5f4a = 检查更新失败:{ $e }(不影响除项目更新外的正常使用) +msg-aa6bff26 = /api/update/releases:{ $res } +msg-c5170c27 = Download management panel file failed:{ $e } +msg-db715c26 = Updating dependencies... +msg-9a00f940 = 更新依赖失败:{ $e } +msg-6f96e3ba = /api/update_project:{ $res } +msg-3217b509 = Failed to download management panel file:{ $e } +msg-9cff28cf = /api/update_dashboard:{ $res } +msg-1198c327 = 在演示模式下,您无权执行此操作。 msg-38e60adf = 缺少参数 package 或不合法。 -msg-a1191473 = /api/update_pip: {$res} +msg-a1191473 = /api/update_pip:{ $res } ### astrbot/dashboard/routes/lang_route.py -msg-0d18aac8 = [LangRoute] lang:{$lang} + +msg-0d18aac8 = [LangRoute] 语言:{ $lang } msg-bf610e68 = lang 为必填参数。 ### astrbot/dashboard/routes/auth.py + msg-ee9cf260 = 为了保证安全,请尽快修改默认密码。 msg-87f936b8 = 用户名或密码错误 -msg-1198c327 = You are not permitted to do this operation in demo mode +msg-1198c327 = 您无权在演示模式下执行此操作。 msg-25562cd3 = 原密码错误 -msg-d31087d2 = 新用户名和新密码不能同时为空 +msg-d31087d2 = New username and new password cannot both be empty. msg-b512c27e = 两次输入的新密码不一致 -msg-7b947d8b = JWT secret is not set in the cmd_config. +msg-7b947d8b = cmd_config 中未设置 JWT 密钥。 ### astrbot/dashboard/routes/backup.py -msg-6920795d = 清理过期的上传会话: {$upload_id} -msg-3e96548d = 清理过期上传会话失败: {$e} -msg-259677a9 = 清理分片目录失败: {$e} -msg-d7263882 = 读取备份 manifest 失败: {$e} -msg-40f76598 = 跳过无效备份文件: {$filename} -msg-18a49bfc = 获取备份列表失败: {$e} -msg-78b9c276 = {$res} -msg-6e08b5a5 = 创建备份失败: {$e} -msg-9cce1032 = 后台导出任务 {$task_id} 失败: {$e} + +msg-6920795d = 清理过期的上传会话:{ $upload_id } +msg-3e96548d = 清理过期上传会话失败:{ $e } +msg-259677a9 = Failed to clean up the shard directory:{ $e } +msg-d7263882 = 读取备份 manifest 失败:{ $e } +msg-40f76598 = 跳过无效备份文件:{ $filename } +msg-18a49bfc = 获取备份列表失败:{ $e } +msg-78b9c276 = { $res } +msg-6e08b5a5 = 创建备份失败:{ $e } +msg-9cce1032 = Background export tasks{ $task_id }失败:{ $e } msg-55927ac1 = 缺少备份文件 msg-374cab8a = 请上传 ZIP 格式的备份文件 -msg-d53d6730 = 上传的备份文件已保存: {$unique_filename} (原始名称: {$res}) -msg-98e64c7f = 上传备份文件失败: {$e} +msg-d53d6730 = 上传的备份文件已保存:{ $unique_filename }(原始名称:{ $res }) +msg-98e64c7f = Upload backup file failed:{ $e } msg-49c3b432 = 缺少 filename 参数 msg-df33d307 = 无效的文件大小 -msg-162ad779 = 初始化分片上传: upload_id={$upload_id}, filename={$unique_filename}, total_chunks={$total_chunks} -msg-de676924 = 初始化分片上传失败: {$e} +msg-162ad779 = 初始化分片上传: upload_id={ $upload_id }文件名={ $unique_filename }总块数={ $total_chunks } +msg-de676924 = 初始化分片上传失败:{ $e } msg-eecf877c = 缺少必要参数 -msg-f175c633 = 无效的分片索引 +msg-f175c633 = Invalid shard index msg-ad865497 = 缺少分片数据 -msg-947c2d56 = 上传会话不存在或已过期 -msg-f3a464a5 = 分片索引超出范围 -msg-7060da1d = 接收分片: upload_id={$upload_id}, chunk={$res}/{$total_chunks} -msg-06c107c1 = 上传分片失败: {$e} -msg-f040b260 = 已标记备份为上传来源: {$zip_path} -msg-559c10a8 = 标记备份来源失败: {$e} +msg-947c2d56 = Upload session does not exist or has expired +msg-f3a464a5 = Shard index out of range +msg-7060da1d = 接收分片: upload_id={ $upload_id }, chunk={ $res }待翻译文本:{ $total_chunks } +msg-06c107c1 = Upload chunk failed:{ $e } +msg-f040b260 = Marked backup as upload source:{ $zip_path } +msg-559c10a8 = 标记备份来源失败:{ $e } msg-d1d752ef = 缺少 upload_id 参数 -msg-390ed49a = 分片不完整,缺少: {$res}... -msg-8029086a = 分片上传完成: {$filename}, size={$file_size}, chunks={$total} -msg-4905dde5 = 完成分片上传失败: {$e} -msg-b63394b1 = 取消分片上传: {$upload_id} -msg-2b39da46 = 取消上传失败: {$e} +msg-390ed49a = 分片不完整,缺少:{ $res }... +msg-8029086a = 分片上传完成:{ $filename }, 大小={ $file_size }, chunks={ $total } +msg-4905dde5 = 完成分片上传失败:{ $e } +msg-b63394b1 = 取消分片上传:{ $upload_id } +msg-2b39da46 = 取消上传失败:{ $e } msg-f12b1f7a = 无效的文件名 -msg-44bb3b89 = 备份文件不存在: {$filename} -msg-b005980b = 预检查备份文件失败: {$e} +msg-44bb3b89 = Backup file does not exist:{ $filename } +msg-b005980b = Pre-check backup file failed:{ $e } msg-65b7ede1 = 请先确认导入。导入将会清空并覆盖现有数据,此操作不可撤销。 -msg-b152e4bf = 导入备份失败: {$e} -msg-5e7f1683 = 后台导入任务 {$task_id} 失败: {$e} +msg-b152e4bf = 导入备份失败:{ $e } +msg-5e7f1683 = 后台导入任务{ $task_id }失败:{ $e } msg-6906aa65 = 缺少参数 task_id msg-5ea3d72c = 找不到该任务 -msg-f0901aef = 获取任务进度失败: {$e} +msg-f0901aef = Failed to fetch task progress:{ $e } msg-8d23792b = 缺少参数 filename msg-4188ede6 = 缺少参数 token msg-0c708312 = 服务器配置错误 msg-cc228d62 = Token 已过期,请刷新页面后重试 msg-5041dc95 = Token 无效 -msg-96283fc5 = 备份文件不存在 -msg-00aacbf8 = 下载备份失败: {$e} -msg-3ea8e256 = 删除备份失败: {$e} +msg-96283fc5 = Backup file does not exist +msg-00aacbf8 = Download backup failed:{ $e } +msg-3ea8e256 = 删除备份失败:{ $e } msg-e4a57714 = 缺少参数 new_name msg-436724bb = 新文件名无效 -msg-9f9d8558 = 文件名 '{$new_filename}' 已存在 -msg-a5fda312 = 备份文件重命名: {$filename} -> {$new_filename} -msg-e7c82339 = 重命名备份失败: {$e} +msg-9f9d8558 = 文件名{ $new_filename }已存在 +msg-a5fda312 = Backup file rename:{ $filename }->{ $new_filename } +msg-e7c82339 = Rename backup failed:{ $e } ### astrbot/dashboard/routes/command.py + msg-1d47363b = handler_full_name 与 enabled 均为必填。 msg-35374718 = handler_full_name 与 new_name 均为必填。 msg-f879f2f4 = handler_full_name 与 permission 均为必填。 ### astrbot/dashboard/routes/subagent.py -msg-78b9c276 = {$res} -msg-eda47201 = 获取 subagent 配置失败: {$e} + +msg-78b9c276 = { $res } +msg-eda47201 = 获取 subagent 配置失败:{ $e } msg-3e5b1fe0 = 配置必须为 JSON 对象 -msg-9f285dd3 = 保存 subagent 配置失败: {$e} -msg-665f4751 = 获取可用工具失败: {$e} +msg-9f285dd3 = 保存 subagent 配置失败:{ $e } +msg-665f4751 = Failed to retrieve available tools:{ $e } ### astrbot/dashboard/routes/config.py -msg-680e7347 = 配置项 {$path}{$key} 没有类型定义, 跳过校验 -msg-ef2e5902 = Saving config, is_core={$is_core} -msg-78b9c276 = {$res} -msg-acef166d = 验证配置时出现异常: {$e} -msg-42f62db0 = 格式校验未通过: {$errors} + +msg-680e7347 = 配置项{ $path }{ $key }没有类型定义, 跳过校验 +msg-ef2e5902 = 正在保存配置,is_core={ $is_core } +msg-78b9c276 = { $res } +msg-acef166d = 验证配置时出现异常:{ $e } +msg-42f62db0 = 格式校验未通过:{ $errors } msg-3e668849 = 缺少配置数据 msg-196b9b25 = 缺少 provider_source_id msg-dbbbc375 = 未找到对应的 provider source msg-a77f69f4 = 缺少 original_id msg-96f154c4 = 缺少或错误的配置数据 -msg-c80b2c0f = Provider source ID '{$res}' exists already, please try another ID. +msg-c80b2c0f = 提供商源ID '{ $res }已存在,请尝试其他ID。 msg-537b700b = 缺少或错误的路由表数据 -msg-b5079e61 = 更新路由表失败: {$e} +msg-b5079e61 = Failed to update routing table:{ $e } msg-cf97d400 = 缺少 UMO 或配置文件 ID msg-2a05bc8d = 缺少 UMO -msg-7098aa3f = 删除路由表项失败: {$e} +msg-7098aa3f = 删除路由表项失败:{ $e } msg-902aedc3 = 缺少配置文件 ID -msg-b9026977 = abconf_id cannot be None +msg-b9026977 = abconf_id 不能为空 msg-acf0664a = 删除失败 -msg-59c93c1a = 删除配置文件失败: {$e} +msg-59c93c1a = 删除配置文件失败:{ $e } msg-930442e2 = 更新失败 -msg-7375d4dc = 更新配置文件失败: {$e} -msg-53a8fdb2 = Attempting to check provider: {$res} (ID: {$res_2}, Type: {$res_3}, Model: {$res_4}) -msg-8b0a48ee = Provider {$res} (ID: {$res_2}) is available. -msg-7c7180a7 = Provider {$res} (ID: {$res_2}) is unavailable. Error: {$error_message} -msg-1298c229 = Traceback for {$res}:{"\u000A"}{$res_2} -msg-d7f9a42f = {$message} -msg-cd303a28 = API call: /config/provider/check_one id={$provider_id} -msg-55b8107a = Provider with id '{$provider_id}' not found in provider_manager. -msg-d1a98a9b = Provider with id '{$provider_id}' not found +msg-7375d4dc = Failed to update configuration file:{ $e } +msg-53a8fdb2 = 正在尝试检查提供商:{ $res }(ID:{ $res_2 },类型:{ $res_3 }, 模型:{ $res_4 }) +msg-8b0a48ee = 提供商{ $res }(ID:{ $res_2 }) 已就绪。 +msg-7c7180a7 = 提供商{ $res }(ID:{ $res_2 }) 不可用。错误:{ $error_message } +msg-1298c229 = 回溯追踪{ $res }待翻译文本:{ "\u000A" }{ $res_2 } +msg-d7f9a42f = { $message } +msg-cd303a28 = API调用:/config/provider/check_one id={ $provider_id } +msg-55b8107a = ID为'{ $provider_id }在provider_manager中未找到。 +msg-d1a98a9b = ID为'{ $provider_id }'未找到' msg-cb9c402c = 缺少参数 provider_type msg-e092d4ee = 缺少参数 provider_id -msg-1ff28fed = 未找到 ID 为 {$provider_id} 的提供商 -msg-92347c35 = 提供商 {$provider_id} 类型不支持获取模型列表 +msg-1ff28fed = 未找到 ID 为{ $provider_id }的提供商 +msg-92347c35 = Provider{ $provider_id }Type does not support fetching model list msg-d0845a10 = 缺少参数 provider_config msg-5657fea4 = provider_config 缺少 type 字段 -msg-09ed9dc7 = 提供商适配器加载失败,请检查提供商类型配置或查看服务端日志 -msg-1cce1cd4 = 未找到适用于 {$provider_type} 的提供商适配器 -msg-8361e44d = 无法找到 {$provider_type} 的类 +msg-09ed9dc7 = Provider adapter failed to load. Please check the provider type configuration or review the server logs. +msg-1cce1cd4 = 未找到适用于{ $provider_type }的提供商适配器 +msg-8361e44d = Not found{ $provider_type }的类 msg-4325087c = 提供商不是 EmbeddingProvider 类型 -msg-a9873ea4 = 检测到 {$res} 的嵌入向量维度为 {$dim} -msg-d170e384 = 获取嵌入维度失败: {$e} +msg-a9873ea4 = 检测到{ $res }Embedding vector dimension is{ $dim } +msg-d170e384 = 获取嵌入维度失败:{ $e } msg-abfeda72 = 缺少参数 source_id -msg-0384f4c9 = 未找到 ID 为 {$provider_source_id} 的 provider_source +msg-0384f4c9 = ID not found{ $provider_source_id }的 provider_source msg-aec35bdb = provider_source 缺少 type 字段 -msg-cbb9d637 = 动态导入提供商适配器失败: {$e} -msg-468f64b3 = 提供商 {$provider_type} 不支持获取模型列表 -msg-cb07fc1c = 获取到 provider_source {$provider_source_id} 的模型列表: {$models} -msg-d2f6e16d = 获取模型列表失败: {$e} -msg-25ea8a96 = Unsupported scope: {$scope} -msg-23c8933f = Missing name or key parameter -msg-536e77ae = Plugin {$name} not found or has no config -msg-1b6bc453 = Config item not found or not file type -msg-fc0a457e = No files uploaded -msg-31c718d7 = Invalid name parameter -msg-e1edc16e = Missing name parameter -msg-8e634b35 = Invalid path parameter -msg-0b52a254 = Plugin {$name} not found +msg-cbb9d637 = Failed to dynamically import provider adapter:{ $e } +msg-468f64b3 = Provider{ $provider_type }不支持获取模型列表 +msg-cb07fc1c = 获取到 provider_source{ $provider_source_id }的模型列表:{ $models } +msg-d2f6e16d = 获取模型列表失败:{ $e } +msg-25ea8a96 = 不支持的scope:{ $scope } +msg-23c8933f = 缺少名称或键参数 +msg-536e77ae = 插件{ $name }未找到或没有配置 +msg-1b6bc453 = 配置项未找到或不是文件类型 +msg-fc0a457e = 未上传任何文件 +msg-31c718d7 = 无效的名称参数 +msg-e1edc16e = 缺少名称参数 +msg-8e634b35 = 无效的路径参数 +msg-0b52a254 = 插件{ $name }未找到 msg-bff0e837 = 参数错误 msg-2f29d263 = 机器人名称不允许修改 msg-1478800f = 未找到对应平台 msg-ca6133f7 = 缺少参数 id -msg-1199c1f9 = Using cached logo token for platform {$res} -msg-889a7de5 = Platform class not found for {$res} -msg-317f359c = Logo token registered for platform {$res} -msg-323ec1e2 = Platform {$res} logo file not found: {$logo_file_path} -msg-bc6d0bcf = Failed to import required modules for platform {$res}: {$e} -msg-b02b538d = File system error for platform {$res} logo: {$e} -msg-31123607 = Unexpected error registering logo for platform {$res}: {$e} -msg-af06ccab = 配置文件 {$conf_id} 不存在 -msg-082a5585 = 插件 {$plugin_name} 不存在 -msg-ca334960 = 插件 {$plugin_name} 没有注册配置 +msg-1199c1f9 = 使用平台缓存的徽标令牌{ $res } +msg-889a7de5 = 平台类未找到{ $res } +msg-317f359c = 平台注册的Logo代币{ $res } +msg-323ec1e2 = 平台{ $res }logo文件未找到:{ $logo_file_path } +msg-bc6d0bcf = 导入平台所需的模块失败{ $res }待翻译文本:{ $e } +msg-b02b538d = 平台文件系统错误{ $res }logo:{ $e } +msg-31123607 = 注册平台徽标时出现意外错误{ $res }待翻译文本:{ $e } +msg-af06ccab = 配置文件{ $conf_id }不存在 +msg-082a5585 = 插件{ $plugin_name }不存在 +msg-ca334960 = 插件{ $plugin_name }No registration configuration ### astrbot/dashboard/routes/knowledge_base.py -msg-ce669289 = 上传文档 {$res} 失败: {$e} -msg-87e99c2d = 后台上传任务 {$task_id} 失败: {$e} -msg-78b9c276 = {$res} -msg-d5355233 = 导入文档 {$file_name} 失败: {$e} -msg-5e7f1683 = 后台导入任务 {$task_id} 失败: {$e} -msg-e1949850 = 获取知识库列表失败: {$e} + +msg-ce669289 = Upload document{ $res }失败:{ $e } +msg-87e99c2d = 后台上传任务{ $task_id }失败:{ $e } +msg-78b9c276 = { $res } +msg-d5355233 = Import Documents{ $file_name }失败:{ $e } +msg-5e7f1683 = 后台导入任务{ $task_id }失败:{ $e } +msg-e1949850 = 获取知识库列表失败:{ $e } msg-299af36d = 知识库名称不能为空 msg-faf380ec = 缺少参数 embedding_provider_id -msg-9015b689 = 嵌入模型不存在或类型错误({$res}) -msg-a63b3aa9 = 嵌入向量维度不匹配,实际是 {$res},然而配置是 {$res_2} -msg-9b281e88 = 测试嵌入模型失败: {$e} +msg-9015b689 = Embedding model does not exist or type is incorrect({ $res }) +msg-a63b3aa9 = 嵌入向量维度不匹配,实际是{ $res }然而配置是{ $res_2 } +msg-9b281e88 = 测试嵌入模型失败:{ $e } msg-d3fb6072 = 重排序模型不存在 msg-fbec0dfd = 重排序模型返回结果异常 -msg-872feec8 = 测试重排序模型失败: {$e},请检查平台日志输出。 -msg-a4ac0b9e = 创建知识库失败: {$e} +msg-872feec8 = 测试重排序模型失败:{ $e }请检查平台日志输出。 +msg-a4ac0b9e = 创建知识库失败:{ $e } msg-c8d487e9 = 缺少参数 kb_id msg-978b3c73 = 知识库不存在 -msg-2137a3e6 = 获取知识库详情失败: {$e} -msg-e7cf9cfd = 至少需要提供一个更新字段 -msg-d3d82c22 = 更新知识库失败: {$e} -msg-5d5d4090 = 删除知识库失败: {$e} -msg-787a5dea = 获取知识库统计失败: {$e} -msg-97a2d918 = 获取文档列表失败: {$e} +msg-2137a3e6 = 获取知识库详情失败:{ $e } +msg-e7cf9cfd = At least one update field must be provided +msg-d3d82c22 = 更新知识库失败:{ $e } +msg-5d5d4090 = 删除知识库失败:{ $e } +msg-787a5dea = Failed to fetch knowledge base statistics:{ $e } +msg-97a2d918 = Failed to retrieve document list:{ $e } msg-b170e0fa = Content-Type 须为 multipart/form-data msg-5afbfa8e = 缺少文件 msg-6636fd31 = 最多只能上传10个文件 -msg-975f06d7 = 上传文档失败: {$e} +msg-975f06d7 = Failed to upload document:{ $e } msg-35bacf60 = 缺少参数 documents 或格式错误 msg-6cc1edcd = 文档格式错误,必须包含 file_name 和 chunks msg-376d7d5f = chunks 必须是列表 msg-e7e2f311 = chunks 必须是非空字符串列表 -msg-42315b8d = 导入文档失败: {$e} +msg-42315b8d = 导入文档失败:{ $e } msg-6906aa65 = 缺少参数 task_id msg-5ea3d72c = 找不到该任务 -msg-194def99 = 获取上传进度失败: {$e} +msg-194def99 = Failed to get upload progress:{ $e } msg-df6ec98e = 缺少参数 doc_id msg-7c3cfe22 = 文档不存在 -msg-b54ab822 = 获取文档详情失败: {$e} -msg-0ef7f633 = 删除文档失败: {$e} +msg-b54ab822 = Failed to retrieve document details:{ $e } +msg-0ef7f633 = 删除文档失败:{ $e } msg-2fe40cbd = 缺少参数 chunk_id -msg-fc13d42a = 删除文本块失败: {$e} -msg-4ef8315b = 获取块列表失败: {$e} +msg-fc13d42a = Failed to delete text block:{ $e } +msg-4ef8315b = 获取块列表失败:{ $e } msg-b70a1816 = 缺少参数 query msg-82ee646e = 缺少参数 kb_names 或格式错误 -msg-07a61a9a = 生成 t-SNE 可视化失败: {$e} -msg-20a3b3f7 = 检索失败: {$e} +msg-07a61a9a = Failed to generate t-SNE visualization:{ $e } +msg-20a3b3f7 = Search failed:{ $e } msg-1b76f5ab = 缺少参数 url -msg-5dc86dc6 = 从URL上传文档失败: {$e} -msg-890b3dee = 后台上传URL任务 {$task_id} 失败: {$e} +msg-5dc86dc6 = Failed to upload document from URL:{ $e } +msg-890b3dee = 后台上传URL任务{ $task_id }失败:{ $e } ### astrbot/dashboard/routes/skills.py -msg-78b9c276 = {$res} -msg-1198c327 = You are not permitted to do this operation in demo mode -msg-52430f2b = Missing file -msg-2ad598f3 = Only .zip files are supported -msg-a11f2e1c = Failed to remove temp skill file: {$temp_path} -msg-67367a6d = Missing skill name + +msg-78b9c276 = { $res } +msg-1198c327 = 您不能在演示模式下执行此操作 +msg-52430f2b = 文件丢失 +msg-2ad598f3 = 仅支持 .zip 文件 +msg-a11f2e1c = 无法删除临时技能文件:{ $temp_path } +msg-67367a6d = 缺少技能名称 ### astrbot/dashboard/routes/live_chat.py -msg-40f242d5 = [Live Chat] {$res} 开始说话 stamp={$stamp} -msg-a168d76d = [Live Chat] stamp 不匹配或未在说话状态: {$stamp} vs {$res} + +msg-40f242d5 = [在线聊天]{ $res }开始说话 stamp={ $stamp } +msg-a168d76d = [实时聊天] 时间戳不匹配或未处于发言状态:{ $stamp }vs{ $res } msg-e01b2fea = [Live Chat] 没有音频帧数据 -msg-33856925 = [Live Chat] 音频文件已保存: {$audio_path}, 大小: {$res} bytes -msg-9e9b7e59 = [Live Chat] 组装 WAV 文件失败: {$e} -msg-21430f56 = [Live Chat] 已删除临时文件: {$res} -msg-6b4f88bc = [Live Chat] 删除临时文件失败: {$e} -msg-0849d043 = [Live Chat] WebSocket 连接建立: {$username} -msg-5477338a = [Live Chat] WebSocket 错误: {$e} -msg-fdbfdba8 = [Live Chat] WebSocket 连接关闭: {$username} +msg-33856925 = [Live Chat] 音频文件已保存:{ $audio_path }, 大小:{ $res }字节 +msg-9e9b7e59 = [Live Chat] 组装 WAV 文件失败:{ $e } +msg-21430f56 = [Live Chat] 已删除临时文件:{ $res } +msg-6b4f88bc = [Live Chat] 删除临时文件失败:{ $e } +msg-0849d043 = [Live Chat] WebSocket 连接建立:{ $username } +msg-5477338a = [在线聊天] WebSocket 错误:{ $e } +msg-fdbfdba8 = [Live Chat] WebSocket 连接关闭:{ $username } msg-7be90ac0 = [Live Chat] start_speaking 缺少 stamp -msg-8215062a = [Live Chat] 解码音频数据失败: {$e} +msg-8215062a = [Live Chat] 解码音频数据失败:{ $e } msg-438980ea = [Live Chat] end_speaking 缺少 stamp -msg-b35a375c = [Live Chat] 用户打断: {$res} -msg-2c3e7bbc = [Live Chat] STT Provider 未配置 +msg-b35a375c = [实时聊天] 用户打断:{ $res } +msg-2c3e7bbc = [Live Chat] STT 提供商未配置 msg-0582c8ba = [Live Chat] STT 识别结果为空 -msg-57c2b539 = [Live Chat] STT 结果: {$user_text} -msg-6b7628c6 = [Live Chat] 检测到用户打断 -msg-2cab2269 = [Live Chat] 消息 ID 不匹配: {$result_message_id} != {$message_id} -msg-74c2470e = [Live Chat] 解析 AgentStats 失败: {$e} -msg-4738a2b3 = [Live Chat] 解析 TTSStats 失败: {$e} +msg-57c2b539 = [Live Chat] STT 结果:{ $user_text } +msg-6b7628c6 = [在线聊天] 检测到用户打断 +msg-2cab2269 = [Live Chat] 消息 ID 不匹配:{ $result_message_id }不等于{ $message_id } +msg-74c2470e = [Live Chat] 解析 AgentStats 失败:{ $e } +msg-4738a2b3 = [Live Chat] 解析 TTSStats 失败:{ $e } msg-944d5022 = [Live Chat] 开始播放音频流 -msg-009104d8 = [Live Chat] Bot 回复完成: {$bot_text} -msg-0c4c3051 = [Live Chat] 处理音频失败: {$e} -msg-140caa36 = [Live Chat] 保存打断消息: {$interrupted_text} -msg-869f51ea = [Live Chat] 用户消息: {$user_text} (session: {$res}, ts: {$timestamp}) -msg-d26dee52 = [Live Chat] Bot 消息(打断): {$interrupted_text} (session: {$res}, ts: {$timestamp}) -msg-1377f378 = [Live Chat] 记录消息失败: {$e} +msg-009104d8 = [在线聊天] 机器人回复完成:{ $bot_text } +msg-0c4c3051 = [Live Chat] 处理音频失败:{ $e } +msg-140caa36 = [在线聊天] 保存中断消息:{ $interrupted_text } +msg-869f51ea = [在线聊天] 用户消息:{ $user_text }(session:{ $res }, ts:{ $timestamp }) +msg-d26dee52 = [Live Chat] Bot 消息(打断):{ $interrupted_text }(session:{ $res }, ts:{ $timestamp }) +msg-1377f378 = [Live Chat] 记录消息失败:{ $e } ### astrbot/dashboard/routes/log.py -msg-5bf500c1 = Log SSE 补发历史错误: {$e} -msg-e4368397 = Log SSE 连接错误: {$e} -msg-547abccb = 获取日志历史失败: {$e} -msg-cb5d4ebb = 获取 Trace 设置失败: {$e} + +msg-5bf500c1 = Log SSE 补发历史错误:{ $e } +msg-e4368397 = 记录SSE连接错误:{ $e } +msg-547abccb = 获取日志历史失败:{ $e } +msg-cb5d4ebb = Failed to get Trace settings:{ $e } msg-7564d3b0 = 请求数据为空 -msg-d2a1cd76 = 更新 Trace 设置失败: {$e} +msg-d2a1cd76 = 更新 Trace 设置失败:{ $e } ### astrbot/dashboard/routes/conversation.py -msg-62392611 = 数据库查询出错: {$e}{"\u000A"}{$res} -msg-b21b052b = 数据库查询出错: {$e} -msg-10f72727 = {$error_msg} -msg-036e6190 = 获取对话列表失败: {$e} + +msg-62392611 = Database query error:{ $e }{ "\u000A" }{ $res } +msg-b21b052b = Database query error:{ $e } +msg-10f72727 = { $error_msg } +msg-036e6190 = 获取对话列表失败:{ $e } msg-a16ba4b4 = 缺少必要参数: user_id 和 cid msg-9a1fcec9 = 对话不存在 -msg-73a8a217 = 获取对话详情失败: {$e}{"\u000A"}{$res} -msg-976cd580 = 获取对话详情失败: {$e} -msg-c193b9c4 = 更新对话信息失败: {$e}{"\u000A"}{$res} -msg-9f96c4ee = 更新对话信息失败: {$e} +msg-73a8a217 = Failed to retrieve conversation details:{ $e }{ "\u000A" }{ $res } +msg-976cd580 = Failed to retrieve conversation details:{ $e } +msg-c193b9c4 = 更新对话信息失败:{ $e }{ "\u000A" }{ $res } +msg-9f96c4ee = 更新对话信息失败:{ $e } msg-e1cb0788 = 批量删除时conversations参数不能为空 -msg-38e3c4ba = 删除对话失败: {$e}{"\u000A"}{$res} -msg-ebf0371a = 删除对话失败: {$e} -msg-af54ee29 = 缺少必要参数: history +msg-38e3c4ba = 删除对话失败:{ $e }{ "\u000A" }{ $res } +msg-ebf0371a = Failed to delete conversation:{ $e } +msg-af54ee29 = 缺少必要参数:历史记录 msg-b72552c8 = history 必须是有效的 JSON 字符串或数组 -msg-fdf757f3 = 更新对话历史失败: {$e}{"\u000A"}{$res} -msg-33762429 = 更新对话历史失败: {$e} -msg-498f11f8 = 导出列表不能为空 -msg-98aa3644 = 导出对话失败: user_id={$user_id}, cid={$cid}, error={$e} -msg-ed77aa37 = 没有成功导出任何对话 -msg-f07b18ee = 批量导出对话失败: {$e}{"\u000A"}{$res} -msg-85dc73fa = 批量导出对话失败: {$e} +msg-fdf757f3 = 更新对话历史失败:{ $e }{ "\u000A" }{ $res } +msg-33762429 = Failed to update conversation history:{ $e } +msg-498f11f8 = Export list cannot be empty +msg-98aa3644 = 导出对话失败: user_id={ $user_id }, 会话ID={ $cid },错误={ $e } +msg-ed77aa37 = No conversations were successfully exported. +msg-f07b18ee = 批量导出对话失败:{ $e }{ "\u000A" }{ $res } +msg-85dc73fa = 批量导出对话失败:{ $e } ### astrbot/dashboard/routes/cron.py -msg-fb5b419b = Cron manager not initialized -msg-78b9c276 = {$res} -msg-112659e5 = Failed to list jobs: {$e} -msg-8bc87eb5 = Invalid payload -msg-29f616c2 = session is required -msg-ae7c99a4 = run_at is required when run_once=true -msg-4bb8c206 = cron_expression is required when run_once=false -msg-13fbf01e = run_at must be ISO datetime -msg-da14d97a = Failed to create job: {$e} -msg-804b6412 = Job not found -msg-94b2248d = Failed to update job: {$e} -msg-42c0ee7a = Failed to delete job: {$e} + +msg-fb5b419b = Cron管理器未初始化 +msg-78b9c276 = { $res } +msg-112659e5 = 无法列出作业:{ $e } +msg-8bc87eb5 = 无效载荷 +msg-29f616c2 = 需要会话 +msg-ae7c99a4 = 当 run_once=true 时,run_at 是必需的。 +msg-4bb8c206 = cron_expression 在 run_once=false 时必须提供 +msg-13fbf01e = run_at 必须为 ISO 日期时间格式 +msg-da14d97a = 创建作业失败:{ $e } +msg-804b6412 = 作业未找到 +msg-94b2248d = 更新作业失败:{ $e } +msg-42c0ee7a = 删除作业失败:{ $e } ### astrbot/dashboard/routes/tools.py -msg-78b9c276 = {$res} -msg-977490be = 获取 MCP 服务器列表失败: {$e} + +msg-78b9c276 = { $res } +msg-977490be = Failed to fetch MCP server list:{ $e } msg-50a07403 = 服务器名称不能为空 msg-23d2bca3 = 必须提供有效的服务器配置 -msg-31252516 = 服务器 {$name} 已存在 -msg-20b8309f = 启用 MCP 服务器 {$name} 超时。 -msg-fff3d0c7 = 启用 MCP 服务器 {$name} 失败: {$e} +msg-31252516 = 服务器{ $name }已存在 +msg-20b8309f = Enable MCP Server{ $name }超时。 +msg-fff3d0c7 = 启用 MCP 服务器{ $name }失败:{ $e } msg-7f1f7921 = 保存配置失败 -msg-a7f06648 = 添加 MCP 服务器失败: {$e} -msg-278dc41b = 服务器 {$old_name} 不存在 -msg-f0441f4b = 启用前停用 MCP 服务器时 {$old_name} 超时: {$e} -msg-7c468a83 = 启用前停用 MCP 服务器时 {$old_name} 失败: {$e} -msg-8a4c8128 = 停用 MCP 服务器 {$old_name} 超时。 -msg-9ac9b2fc = 停用 MCP 服务器 {$old_name} 失败: {$e} -msg-b988392d = 更新 MCP 服务器失败: {$e} -msg-c81030a7 = 服务器 {$name} 不存在 -msg-4cdbd30d = 停用 MCP 服务器 {$name} 超时。 -msg-1ed9a96e = 停用 MCP 服务器 {$name} 失败: {$e} -msg-a26f2c6a = 删除 MCP 服务器失败: {$e} +msg-a7f06648 = 添加 MCP 服务器失败:{ $e } +msg-278dc41b = 服务器{ $old_name }不存在 +msg-f0441f4b = 停用 MCP 服务器前启用时{ $old_name }超时:{ $e } +msg-7c468a83 = 启用前停用 MCP 服务器时{ $old_name }失败:{ $e } +msg-8a4c8128 = 停用 MCP 服务器{ $old_name }超时。 +msg-9ac9b2fc = 停用 MCP 服务器{ $old_name }失败:{ $e } +msg-b988392d = Update MCP server failed:{ $e } +msg-c81030a7 = 服务器{ $name }不存在 +msg-4cdbd30d = 停用 MCP 服务器{ $name }Timeout. +msg-1ed9a96e = 停用 MCP 服务器{ $name }失败:{ $e } +msg-a26f2c6a = 删除 MCP 服务器失败:{ $e } msg-bbc84cc5 = 无效的 MCP 服务器配置 msg-aa0e3d0d = MCP 服务器配置不能为空 msg-d69cbcf2 = 一次只能配置一个 MCP 服务器配置 -msg-bd43f610 = 测试 MCP 连接失败: {$e} -msg-057a3970 = 获取工具列表失败: {$e} +msg-bd43f610 = 测试 MCP 连接失败:{ $e } +msg-057a3970 = 获取工具列表失败:{ $e } msg-29415636 = 缺少必要参数: name 或 action -msg-75d85dc1 = 启用工具失败: {$e} -msg-21a922b8 = 工具 {$tool_name} 不存在或操作失败。 -msg-20143f28 = 操作工具失败: {$e} -msg-295ab1fe = 未知: {$provider_name} -msg-fe38e872 = 同步失败: {$e} +msg-75d85dc1 = 启用工具失败:{ $e } +msg-21a922b8 = 工具{ $tool_name }不存在或操作失败。 +msg-20143f28 = Operation tool failed:{ $e } +msg-295ab1fe = 未知:{ $provider_name } +msg-fe38e872 = 同步失败:{ $e } ### astrbot/dashboard/routes/chatui_project.py -msg-04827ead = Missing key: title -msg-34fccfbb = Missing key: project_id -msg-a7c08aee = Project {$project_id} not found -msg-c52a1454 = Permission denied -msg-dbf41bfc = Missing key: session_id -msg-d922dfa3 = Session {$session_id} not found + +msg-04827ead = 缺少键值:title +msg-34fccfbb = 缺少密钥:project_id +msg-a7c08aee = 项目{ $project_id }未找到 +msg-c52a1454 = 权限被拒绝 +msg-dbf41bfc = 缺少键值: session_id +msg-d922dfa3 = 会话{ $session_id }未找到 ### astrbot/dashboard/routes/open_api.py -msg-e41d65d5 = Failed to create chat session %s: %s -msg-fc15cbcd = {$username_err} -msg-bc3b3977 = Invalid username -msg-2cd6e70f = {$ensure_session_err} -msg-53632573 = {$resolve_err} -msg-79b0c7cb = Failed to update chat config route for %s with %s: %s -msg-7c7a9f55 = Failed to update chat config route: {$e} -msg-74bff366 = page and page_size must be integers -msg-1507569c = Message is empty -msg-1389e46a = message must be a string or list -msg-697561eb = message part must be an object -msg-2c4bf283 = reply part missing message_id -msg-60ddb927 = unsupported message part type: {$part_type} -msg-cf310369 = attachment not found: {$attachment_id} -msg-58e0b84a = {$part_type} part missing attachment_id -msg-e565c4b5 = file not found: {$file_path} -msg-c6ec40ff = Message content is empty (reply only is not allowed) -msg-2b00f931 = Missing key: message -msg-a29d9adb = Missing key: umo -msg-4990e908 = Invalid umo: {$e} -msg-45ac857c = Bot not found or not running for platform: {$platform_id} -msg-ec0f0bd2 = Open API send_message failed: {$e} -msg-d04109ab = Failed to send message: {$e} + +msg-e41d65d5 = 创建聊天会话 %s 失败:%s +msg-fc15cbcd = { $username_err } +msg-bc3b3977 = 无效用户名 +msg-2cd6e70f = { $ensure_session_err } +msg-53632573 = { $resolve_err } +msg-79b0c7cb = 更新聊天配置路由失败,目标:%s,使用配置:%s,错误原因:%s +msg-7c7a9f55 = 更新聊天配置路由失败:{ $e } +msg-74bff366 = page和page_size必须是整数 +msg-1507569c = 消息为空 +msg-1389e46a = 消息必须为字符串或列表 +msg-697561eb = 消息部分必须是一个对象 +msg-2c4bf283 = 回复部分缺少消息ID +msg-60ddb927 = 不支持的消息部件类型:{ $part_type } +msg-cf310369 = 附件未找到:{ $attachment_id } +msg-58e0b84a = { $part_type }部件缺少附件ID +msg-e565c4b5 = 文件未找到:{ $file_path } +msg-c6ec40ff = 消息内容为空(不允许仅回复) +msg-2b00f931 = 缺少键值:消息 +msg-a29d9adb = 缺少键值:umo +msg-4990e908 = 无效的umo:{ $e } +msg-45ac857c = 机器人未找到或未在平台上运行:{ $platform_id } +msg-ec0f0bd2 = Open API 发送消息失败:{ $e } +msg-d04109ab = 消息发送失败:{ $e } ### astrbot/dashboard/routes/session_management.py -msg-e1949850 = 获取知识库列表失败: {$e} -msg-3cd6eb8c = 获取规则列表失败: {$e} + +msg-e1949850 = 获取知识库列表失败:{ $e } +msg-3cd6eb8c = 获取规则列表失败:{ $e } msg-363174ae = 缺少必要参数: umo msg-809e51d7 = 缺少必要参数: rule_key -msg-ce203e7e = 不支持的规则键: {$rule_key} -msg-2726ab30 = 更新会话规则失败: {$e} -msg-f021f9fb = 删除会话规则失败: {$e} +msg-ce203e7e = 不支持的规则键:{ $rule_key } +msg-2726ab30 = 更新会话规则失败:{ $e } +msg-f021f9fb = 删除会话规则失败:{ $e } msg-6bfa1fe5 = 缺少必要参数: umos msg-4ce0379e = 参数 umos 必须是数组 -msg-979c6e2f = 删除 umo {$umo} 的规则失败: {$e} -msg-77d2761d = 批量删除会话规则失败: {$e} -msg-6619322c = 获取 UMO 列表失败: {$e} -msg-b944697c = 获取会话状态列表失败: {$e} +msg-979c6e2f = 删除 umo{ $umo }The rule failed:{ $e } +msg-77d2761d = 批量删除会话规则失败:{ $e } +msg-6619322c = Failed to get UMO list:{ $e } +msg-b944697c = 获取会话状态列表失败:{ $e } msg-adba3c3b = 至少需要指定一个要修改的状态 msg-4a8eb7a6 = 请指定分组 ID -msg-67f15ab7 = 分组 '{$group_id}' 不存在 -msg-50fbcccb = 没有找到符合条件的会话 -msg-59714ede = 更新 {$umo} 服务状态失败: {$e} -msg-31640917 = 批量更新服务状态失败: {$e} +msg-67f15ab7 = 分组 '{ $group_id }不存在 +msg-50fbcccb = No matching conversations found +msg-59714ede = 更新{ $umo }服务状态失败:{ $e } +msg-31640917 = 批量更新服务状态失败:{ $e } msg-4d83eb92 = 缺少必要参数: provider_type, provider_id -msg-5f333041 = 不支持的 provider_type: {$provider_type} -msg-6fa017d7 = 更新 {$umo} Provider 失败: {$e} -msg-07416020 = 批量更新 Provider 失败: {$e} -msg-94c745e6 = 获取分组列表失败: {$e} -msg-fb7cf353 = 分组名称不能为空 -msg-ae3fce8a = 创建分组失败: {$e} +msg-5f333041 = 不支持的 provider_type:{ $provider_type } +msg-6fa017d7 = 更新{ $umo }提供商失败:{ $e } +msg-07416020 = 批量更新 Provider 失败:{ $e } +msg-94c745e6 = 获取分组列表失败:{ $e } +msg-fb7cf353 = Group name cannot be empty +msg-ae3fce8a = Failed to create group:{ $e } msg-07de5ff3 = 分组 ID 不能为空 -msg-35b8a74f = 更新分组失败: {$e} -msg-3d41a6fd = 删除分组失败: {$e} +msg-35b8a74f = Failed to update group:{ $e } +msg-3d41a6fd = Failed to delete group:{ $e } ### astrbot/dashboard/routes/persona.py -msg-4a12aead = 获取人格列表失败: {$e}{"\u000A"}{$res} -msg-c168407f = 获取人格列表失败: {$e} + +msg-4a12aead = Failed to retrieve personality list:{ $e }{ "\u000A" }{ $res } +msg-c168407f = 获取人格列表失败:{ $e } msg-63c6f414 = 缺少必要参数: persona_id -msg-ce7da6f3 = 人格不存在 -msg-9c07774d = 获取人格详情失败: {$e}{"\u000A"}{$res} -msg-ee3b44ad = 获取人格详情失败: {$e} -msg-ad455c14 = 人格ID不能为空 +msg-ce7da6f3 = Personality does not exist +msg-9c07774d = Failed to retrieve personality details:{ $e }{ "\u000A" }{ $res } +msg-ee3b44ad = 获取人格详情失败:{ $e } +msg-ad455c14 = Person ID cannot be empty msg-43037094 = 系统提示词不能为空 msg-ec9dda44 = 预设对话数量必须为偶数(用户和助手轮流对话) -msg-26b214d5 = 创建人格失败: {$e}{"\u000A"}{$res} -msg-8913dfe6 = 创建人格失败: {$e} -msg-3d94d18d = 更新人格失败: {$e}{"\u000A"}{$res} -msg-f2cdfbb8 = 更新人格失败: {$e} -msg-51d84afc = 删除人格失败: {$e}{"\u000A"}{$res} -msg-8314a263 = 删除人格失败: {$e} -msg-b8ecb8f9 = 移动人格失败: {$e}{"\u000A"}{$res} -msg-ab0420e3 = 移动人格失败: {$e} -msg-e5604a24 = 获取文件夹列表失败: {$e}{"\u000A"}{$res} -msg-4d7c7f4a = 获取文件夹列表失败: {$e} -msg-cf0ee4aa = 获取文件夹树失败: {$e}{"\u000A"}{$res} -msg-bb515af0 = 获取文件夹树失败: {$e} +msg-26b214d5 = 创建人格失败:{ $e }{ "\u000A" }{ $res } +msg-8913dfe6 = 创建人格失败:{ $e } +msg-3d94d18d = 更新人格失败:{ $e }{ "\u000A" }{ $res } +msg-f2cdfbb8 = 更新人格失败:{ $e } +msg-51d84afc = Delete personality failed:{ $e }{ "\u000A" }{ $res } +msg-8314a263 = 删除人格失败:{ $e } +msg-b8ecb8f9 = Failed to move personality:{ $e }{ "\u000A" }{ $res } +msg-ab0420e3 = 移动人格失败:{ $e } +msg-e5604a24 = Failed to get folder list:{ $e }{ "\u000A" }{ $res } +msg-4d7c7f4a = Failed to retrieve folder list:{ $e } +msg-cf0ee4aa = 获取文件夹树失败:{ $e }{ "\u000A" }{ $res } +msg-bb515af0 = Failed to retrieve folder tree:{ $e } msg-c92b4863 = 缺少必要参数: folder_id -msg-77cdd6fa = 文件夹不存在 -msg-2d34652f = 获取文件夹详情失败: {$e}{"\u000A"}{$res} -msg-650ef096 = 获取文件夹详情失败: {$e} +msg-77cdd6fa = Folder does not exist +msg-2d34652f = Failed to get folder details:{ $e }{ "\u000A" }{ $res } +msg-650ef096 = Failed to retrieve folder details:{ $e } msg-27c413df = 文件夹名称不能为空 -msg-b5866931 = 创建文件夹失败: {$e}{"\u000A"}{$res} -msg-5e57f3b5 = 创建文件夹失败: {$e} -msg-9bd8f820 = 更新文件夹失败: {$e}{"\u000A"}{$res} -msg-1eada044 = 更新文件夹失败: {$e} -msg-9cef0256 = 删除文件夹失败: {$e}{"\u000A"}{$res} -msg-22020727 = 删除文件夹失败: {$e} +msg-b5866931 = 创建文件夹失败:{ $e }{ "\u000A" }{ $res } +msg-5e57f3b5 = 创建文件夹失败:{ $e } +msg-9bd8f820 = Failed to update folder:{ $e }{ "\u000A" }{ $res } +msg-1eada044 = Failed to update folder:{ $e } +msg-9cef0256 = 删除文件夹失败:{ $e }{ "\u000A" }{ $res } +msg-22020727 = Failed to delete the folder:{ $e } msg-7a69fe08 = items 不能为空 -msg-e71ba5c2 = 每个 item 必须包含 id, type, sort_order 字段 +msg-e71ba5c2 = 每个项目必须包含 id、type 和 sort_order 字段 msg-dfeb8320 = type 字段必须是 'persona' 或 'folder' -msg-aec43ed3 = 更新排序失败: {$e}{"\u000A"}{$res} -msg-75ec4427 = 更新排序失败: {$e} +msg-aec43ed3 = 更新排序失败:{ $e }{ "\u000A" }{ $res } +msg-75ec4427 = Update ordering failed:{ $e } ### astrbot/dashboard/routes/platform.py -msg-bcc64513 = 未找到 webhook_uuid 为 {$webhook_uuid} 的平台 + +msg-bcc64513 = 未找到 webhook_uuid 为{ $webhook_uuid }的平台 msg-1478800f = 未找到对应平台 -msg-378cb077 = 平台 {$res} 未实现 webhook_callback 方法 +msg-378cb077 = 平台{ $res }未实现 webhook_callback 方法 msg-2d797305 = 平台未支持统一 Webhook 模式 -msg-83f8dedf = 处理 webhook 回调时发生错误: {$e} -msg-af91bc78 = 处理回调失败 -msg-136a952f = 获取平台统计信息失败: {$e} -msg-60bb0722 = 获取统计信息失败: {$e} +msg-83f8dedf = 处理 webhook 回调时发生错误:{ $e } +msg-af91bc78 = Failed to process callback +msg-136a952f = Failed to retrieve platform statistics:{ $e } +msg-60bb0722 = 获取统计信息失败:{ $e } ### astrbot/dashboard/routes/api_key.py -msg-8e0249fa = At least one valid scope is required -msg-1b79360d = Invalid scopes -msg-d6621696 = expires_in_days must be an integer -msg-33605d95 = expires_in_days must be greater than 0 -msg-209030fe = Missing key: key_id -msg-24513a81 = API key not found + +msg-8e0249fa = 至少需要一个有效的作用域 +msg-1b79360d = 无效的作用域 +msg-d6621696 = expires_in_days必须为整数 +msg-33605d95 = expires_in_days 必须大于 0 +msg-209030fe = 缺少键:key_id +msg-24513a81 = API密钥未找到 ### astrbot/dashboard/routes/file.py -msg-78b9c276 = {$res} + +msg-78b9c276 = { $res } ### astrbot/dashboard/routes/chat.py -msg-a4a521ff = Missing key: filename -msg-c9746528 = Invalid file path -msg-3c2f6dee = File access error -msg-e5b19b36 = Missing key: attachment_id -msg-cfa38c4d = Attachment not found -msg-377a7406 = Missing key: file -msg-bae87336 = Failed to create attachment -msg-5c531303 = Missing JSON body -msg-1c3efd8f = Missing key: message or files -msg-04588d0f = Missing key: session_id or conversation_id -msg-c6ec40ff = Message content is empty (reply only is not allowed) -msg-2c3fdeb9 = Message are both empty -msg-9bc95e22 = session_id is empty -msg-344a401b = [WebChat] 用户 {$username} 断开聊天长连接。 -msg-6b54abec = WebChat stream error: {$e} -msg-53509ecb = webchat stream message_id mismatch -msg-1211e857 = [WebChat] 用户 {$username} 断开聊天长连接。 {$e} -msg-be34e848 = Failed to extract web search refs: {$e} -msg-80bbd0ff = WebChat stream unexpected error: {$e} -msg-dbf41bfc = Missing key: session_id -msg-d922dfa3 = Session {$session_id} not found -msg-c52a1454 = Permission denied -msg-9d7a8094 = Failed to delete UMO route %s during session cleanup: %s -msg-44c45099 = Failed to delete attachment file {$res}: {$e} -msg-f033d8ea = Failed to get attachments: {$e} -msg-e6f655bd = Failed to delete attachments: {$e} -msg-a6ef3b67 = Missing key: display_name + +msg-a4a521ff = 缺少键:文件名 +msg-c9746528 = 无效的文件路径 +msg-3c2f6dee = 文件访问错误 +msg-e5b19b36 = 缺少键值:attachment_id +msg-cfa38c4d = 附件未找到 +msg-377a7406 = 缺少键:文件 +msg-bae87336 = 创建附件失败 +msg-5c531303 = 缺少JSON请求体 +msg-1c3efd8f = 缺少键:消息或文件 +msg-04588d0f = 缺少键:session_id 或 conversation_id +msg-c6ec40ff = 消息内容为空(仅回复不被允许) +msg-2c3fdeb9 = 消息均为空 +msg-9bc95e22 = session_id为空 +msg-344a401b = [WebChat] 用户{ $username }断开聊天长连接。 +msg-6b54abec = WebChat 流错误:{ $e } +msg-53509ecb = webchat 流消息 ID 不匹配 +msg-1211e857 = [WebChat] 用户{ $username }断开聊天长连接。{ $e } +msg-be34e848 = 提取网页搜索引用失败:{ $e } +msg-80bbd0ff = WebChat 流式传输意外错误:{ $e } +msg-dbf41bfc = 缺少键值: session_id +msg-d922dfa3 = 会话{ $session_id }未找到 +msg-c52a1454 = 权限被拒绝 +msg-9d7a8094 = 在会话清理期间删除UMO路由 %s 失败:%s +msg-44c45099 = 无法删除附件文件{ $res }:{ $e } +msg-f033d8ea = 获取附件失败:{ $e } +msg-e6f655bd = 删除附件失败:{ $e } +msg-a6ef3b67 = 缺少键:display_name ### astrbot/dashboard/routes/t2i.py -msg-76cc0933 = Error in get_active_template -msg-5350f35b = Template not found -msg-d7b101c5 = Name and content are required. -msg-e910b6f3 = Template with this name already exists. -msg-18cfb637 = Content is required. -msg-2480cf2f = Template not found. + +msg-76cc0933 = 获取活动模板时出错 +msg-5350f35b = 模板未找到 +msg-d7b101c5 = 名称和内容为必填项。 +msg-e910b6f3 = 已存在同名的模板。 +msg-18cfb637 = 内容为必填项。 +msg-2480cf2f = 模板未找到。 msg-9fe026f1 = 模板名称(name)不能为空。 -msg-eeefe1dc = 模板 '{$name}' 不存在,无法应用。 -msg-0048e060 = Error in set_active_template -msg-8fde62dd = Error in reset_default_template +msg-eeefe1dc = 模板{ $name }不存在,无法应用。 +msg-0048e060 = 设置活动模板时出错 +msg-8fde62dd = 重置默认模板时出错 ### astrbot/dashboard/routes/stat.py -msg-1198c327 = You are not permitted to do this operation in demo mode -msg-78b9c276 = {$res} -msg-0e5bb0b1 = proxy_url is required -msg-f0e0983e = Failed. Status code: {$res} -msg-68e65093 = Error: {$e} -msg-b5979fe8 = version parameter is required -msg-b88a1887 = Invalid version format -msg-8cb9bb6b = Path traversal attempt detected: {$version} -> {$changelog_path} -msg-7616304c = Changelog for version {$version} not found + +msg-1198c327 = 演示模式下不允许进行此操作 +msg-78b9c276 = { $res } +msg-0e5bb0b1 = proxy_url 为必填项 +msg-f0e0983e = 失败。状态码:{ $res } +msg-68e65093 = 错误:{ $e } +msg-b5979fe8 = 版本参数是必需的 +msg-b88a1887 = 无效的版本格式 +msg-8cb9bb6b = 检测到路径遍历尝试:{ $version }->{ $changelog_path } +msg-7616304c = 版本更新日志{ $version }未找到 ### astrbot/dashboard/routes/plugin.py -msg-1198c327 = You are not permitted to do this operation in demo mode + +msg-1198c327 = 您不能在演示模式下执行此操作。 msg-adce8d2f = 缺少插件目录名 -msg-2f1b67fd = 重载失败: {$err} -msg-71f9ea23 = /api/plugin/reload-failed: {$res} -msg-27286c23 = /api/plugin/reload: {$res} +msg-2f1b67fd = 重载失败:{ $err } +msg-71f9ea23 = /api/plugin/reload-failed:{ $res } +msg-27286c23 = /api/plugin/reload:{ $res } msg-b33c0d61 = 缓存MD5匹配,使用缓存的插件市场数据 -msg-64b4a44c = 远程插件市场数据为空: {$url} -msg-fdbffdca = 成功获取远程插件市场数据,包含 {$res} 个插件 -msg-48c42bf8 = 请求 {$url} 失败,状态码:{$res} -msg-6ac25100 = 请求 {$url} 失败,错误:{$e} +msg-64b4a44c = 远程插件市场数据为空:{ $url } +msg-fdbffdca = 成功获取远程插件市场数据,包含{ $res }个插件 +msg-48c42bf8 = 请求{ $url }失败,状态码:{ $res } +msg-6ac25100 = Request{ $url }失败,错误:{ $e } msg-7e536821 = 远程插件市场数据获取失败,使用缓存数据 msg-d4b4c53a = 获取插件列表失败,且没有可用的缓存数据 -msg-37f59b88 = 加载缓存MD5失败: {$e} -msg-8048aa4c = 获取远程MD5失败: {$e} +msg-37f59b88 = Failed to load cache MD5:{ $e } +msg-8048aa4c = Failed to retrieve remote MD5:{ $e } msg-593eacfd = 缓存文件中没有MD5信息 -msg-dedcd957 = 无法获取远程MD5,将使用缓存 -msg-21d7e754 = 插件数据MD5: 本地={$cached_md5}, 远程={$remote_md5}, 有效={$is_valid} -msg-0faf4275 = 检查缓存有效性失败: {$e} -msg-e26aa0a5 = 加载缓存文件: {$cache_file}, 缓存时间: {$res} -msg-23d627a1 = 加载插件市场缓存失败: {$e} -msg-22d12569 = 插件市场数据已缓存到: {$cache_file}, MD5: {$md5} -msg-478c99a9 = 保存插件市场缓存失败: {$e} -msg-3838d540 = 获取插件 Logo 失败: {$e} -msg-da442310 = 正在安装插件 {$repo_url} -msg-e0abd541 = 安装插件 {$repo_url} 成功。 -msg-78b9c276 = {$res} -msg-acfcd91e = 正在安装用户上传的插件 {$res} -msg-48e05870 = 安装插件 {$res} 成功 -msg-8af56756 = 正在卸载插件 {$plugin_name} -msg-6d1235b6 = 卸载插件 {$plugin_name} 成功 -msg-7055316c = 正在更新插件 {$plugin_name} -msg-d258c060 = 更新插件 {$plugin_name} 成功。 -msg-398370d5 = /api/plugin/update: {$res} +msg-dedcd957 = Unable to retrieve remote MD5, using cache. +msg-21d7e754 = 插件数据MD5: 本地={ $cached_md5 }, 远程={ $remote_md5 }, 有效={ $is_valid } +msg-0faf4275 = 检查缓存有效性失败:{ $e } +msg-e26aa0a5 = Loading cache file:{ $cache_file }, 缓存时间:{ $res } +msg-23d627a1 = Failed to load plugin marketplace cache:{ $e } +msg-22d12569 = Plugin market data has been cached to:{ $cache_file }, MD5:{ $md5 } +msg-478c99a9 = 保存插件市场缓存失败:{ $e } +msg-3838d540 = 获取插件 Logo 失败:{ $e } +msg-da442310 = 正在安装插件{ $repo_url } +msg-e0abd541 = 安装插件{ $repo_url }成功。 +msg-78b9c276 = { $res } +msg-acfcd91e = 正在安装用户上传的插件{ $res } +msg-48e05870 = 安装插件{ $res }成功 +msg-8af56756 = 正在卸载插件{ $plugin_name } +msg-6d1235b6 = Uninstall plugin{ $plugin_name }成功 +msg-7055316c = Updating plugin{ $plugin_name } +msg-d258c060 = Update Plugin{ $plugin_name }成功。 +msg-398370d5 = /api/plugin/update:{ $res } msg-2d225636 = 插件列表不能为空 -msg-32632e67 = 批量更新插件 {$name} -msg-08dd341c = /api/plugin/update-all: 更新插件 {$name} 失败: {$res} -msg-cb230226 = 停用插件 {$plugin_name} 。 -msg-abc710cd = /api/plugin/off: {$res} -msg-06e2a068 = 启用插件 {$plugin_name} 。 -msg-82c412e7 = /api/plugin/on: {$res} -msg-77e5d67e = 正在获取插件 {$plugin_name} 的README文件内容 +msg-32632e67 = Batch Update Plugins{ $name } +msg-08dd341c = /api/plugin/update-all: 更新插件{ $name }失败:{ $res } +msg-cb230226 = 停用插件{ $plugin_name }待翻译文本: +msg-abc710cd = /api/plugin/off:{ $res } +msg-06e2a068 = Enable Plugin{ $plugin_name }待翻译文本: +msg-82c412e7 = /api/plugin/on:{ $res } +msg-77e5d67e = 正在获取插件{ $plugin_name }README文件内容 msg-baed1b72 = 插件名称为空 -msg-773cca0a = 插件名称不能为空 -msg-082a5585 = 插件 {$plugin_name} 不存在 -msg-ba106e58 = 插件 {$plugin_name} 目录不存在 -msg-e38e4370 = 无法找到插件目录: {$plugin_dir} -msg-df027f16 = 无法找到插件 {$plugin_name} 的目录 -msg-5f304f4b = 插件 {$plugin_name} 没有README文件 -msg-a3ed8739 = /api/plugin/readme: {$res} -msg-2f9e2c11 = 读取README文件失败: {$e} -msg-dcbd593f = 正在获取插件 {$plugin_name} 的更新日志 -msg-ea5482da = /api/plugin/changelog: {$res} -msg-8e27362e = 读取更新日志失败: {$e} -msg-0842bf8b = 插件 {$plugin_name} 没有更新日志文件 -msg-8e36313d = sources fields must be a list -msg-643e51e7 = /api/plugin/source/save: {$res} +msg-773cca0a = Plugin name cannot be empty +msg-082a5585 = 插件{ $plugin_name }不存在 +msg-ba106e58 = 插件{ $plugin_name }Directory does not exist +msg-e38e4370 = Cannot find plugin directory:{ $plugin_dir } +msg-df027f16 = Plugin not found{ $plugin_name }的目录 +msg-5f304f4b = 插件{ $plugin_name }没有README文件 +msg-a3ed8739 = /api/plugin/readme:{ $res } +msg-2f9e2c11 = Failed to read README file:{ $e } +msg-dcbd593f = 正在获取插件{ $plugin_name }更新日志 +msg-ea5482da = /api/plugin/changelog:{ $res } +msg-8e27362e = 读取更新日志失败:{ $e } +msg-0842bf8b = 插件{ $plugin_name }No changelog file available +msg-8e36313d = sources 字段必须是一个列表 +msg-643e51e7 = /api/plugin/source/save:{ $res } ### astrbot/builtin_stars/session_controller/main.py -msg-b48bf3fe = LLM response failed: {$e} + +msg-b48bf3fe = LLM响应失败:{ $e } ### astrbot/builtin_stars/builtin_commands/commands/setunset.py -msg-8b56b437 = 会话 {$uid} 变量 {$key} 存储成功。使用 /unset 移除。 + +msg-8b56b437 = Session{ $uid }变量{ $key }存储成功。使用 /unset 移除。 msg-dfd31d9d = 没有那个变量名。格式 /unset 变量名。 -msg-bf181241 = 会话 {$uid} 变量 {$key} 移除成功。 +msg-bf181241 = 会话{ $uid }变量{ $key }移除成功。 ### astrbot/builtin_stars/builtin_commands/commands/provider.py -msg-b435fcdc = Provider reachability check failed: id=%s type=%s code=%s reason=%s + +msg-b435fcdc = 提供程序可达性检查失败:id=%s type=%s code=%s reason=%s msg-f4cfd3ab = 正在进行提供商可达性测试,请稍候... -msg-ed8dcc22 = {$ret} +msg-ed8dcc22 = { $ret } msg-f3d8988e = 请输入序号。 -msg-284759bb = 无效的提供商序号。 -msg-092d9956 = 成功切换到 {$id_}。 +msg-284759bb = Invalid provider number. +msg-092d9956 = 成功切换到{ $id_ } msg-bf9eb668 = 无效的参数。 msg-4cdd042d = 未找到任何 LLM 提供商。请先配置。 msg-cb218e86 = 模型序号错误。 -msg-1756f199 = 切换模型成功。当前提供商: [{$res}] 当前模型: [{$res_2}] -msg-4d4f587f = 切换模型到 {$res}。 +msg-1756f199 = 切换模型成功。当前提供商: [{ $res }当前模型: [{ $res_2 }] +msg-4d4f587f = Switch model to{ $res }待翻译文本: msg-584ca956 = Key 序号错误。 -msg-f52481b8 = 切换 Key 未知错误: {$e} +msg-f52481b8 = 切换 Key 未知错误:{ $e } msg-7a156524 = 切换 Key 成功。 ### astrbot/builtin_stars/builtin_commands/commands/conversation.py -msg-63fe9607 = 在{$res}场景下,reset命令需要管理员权限,您 (ID {$res_2}) 不是管理员,无法执行此操作。 + +msg-63fe9607 = In{ $res }场景下,reset命令需要管理员权限,您 (ID{ $res_2 }) 不是管理员,无法执行此操作。 msg-6f4bbe27 = 重置对话成功。 msg-4cdd042d = 未找到任何 LLM 提供商。请先配置。 -msg-69ed45be = 当前未处于对话状态,请 /switch 切换或者 /new 创建。 -msg-ed8dcc22 = {$ret} -msg-772ec1fa = 已请求停止 {$stopped_count} 个运行中的任务。 +msg-69ed45be = 当前未处于对话状态,请使用 /switch 切换或 /new 创建。 +msg-ed8dcc22 = { $ret } +msg-772ec1fa = 已请求停止{ $stopped_count }A running task. msg-8d42cd8a = 当前会话没有运行中的任务。 -msg-efdfbe3e = {$THIRD_PARTY_AGENT_RUNNER_STR} 对话列表功能暂不支持。 +msg-efdfbe3e = { $THIRD_PARTY_AGENT_RUNNER_STR }对话列表功能暂不支持。 msg-492c2c02 = 已创建新对话。 -msg-c7dc838d = 切换到新对话: 新对话({$res})。 -msg-6da01230 = 群聊 {$session} 已切换到新对话: 新对话({$res})。 +msg-c7dc838d = 切换到新对话: 新对话({ $res })。 +msg-6da01230 = Group Chat{ $session }已切换到新对话: 新对话{ $res })。 msg-f356d65a = 请输入群聊 ID。/groupnew 群聊ID。 msg-7e442185 = 类型错误,请输入数字对话序号。 msg-00dbe29c = 请输入对话序号。/switch 对话序号。/ls 查看对话 /new 新建对话 msg-a848ccf6 = 对话序号错误,请使用 /ls 查看 -msg-1ec33cf6 = 切换到对话: {$title}({$res})。 +msg-1ec33cf6 = 切换到对话:{ $title }待翻译文本:{ $res })。 msg-68e5dd6c = 请输入新的对话名称。 msg-c8dd6158 = 重命名对话成功。 -msg-1f1fa2f2 = 会话处于群聊,并且未开启独立会话,并且您 (ID {$res}) 不是管理员,因此没有权限删除当前对话。 +msg-1f1fa2f2 = 会话处于群聊,并且未开启独立会话,并且您 (ID{ $res }) 不是管理员,因此没有权限删除当前对话。 msg-6a1dc4b7 = 当前未处于对话状态,请 /switch 序号 切换或 /new 创建。 ### astrbot/builtin_stars/builtin_commands/commands/tts.py -msg-ef1b2145 = {$status_text}当前会话的文本转语音。但 TTS 功能在配置中未启用,请前往 WebUI 开启。 -msg-deee9deb = {$status_text}当前会话的文本转语音。 + +msg-ef1b2145 = { $status_text }当前会话的文本转语音。但 TTS 功能在配置中未启用,请前往 WebUI 开启。 +msg-deee9deb = { $status_text }当前会话的文本转语音。 ### astrbot/builtin_stars/builtin_commands/commands/llm.py -msg-72cd5f57 = {$status} LLM 聊天功能。 + +msg-72cd5f57 = { $status }LLM 聊天功能。 ### astrbot/builtin_stars/builtin_commands/commands/persona.py + msg-4f52d0dd = 当前对话不存在,请先使用 /new 新建一个对话。 -msg-e092b97c = [Persona]{"\u000A"}{"\u000A"}- 人格情景列表: `/persona list`{"\u000A"}- 设置人格情景: `/persona 人格`{"\u000A"}- 人格情景详细信息: `/persona view 人格`{"\u000A"}- 取消人格: `/persona unset`{"\u000A"}{"\u000A"}默认人格情景: {$res}{"\u000A"}当前对话 {$curr_cid_title} 的人格情景: {$curr_persona_name}{"\u000A"}{"\u000A"}配置人格情景请前往管理面板-配置页{"\u000A"} -msg-c046b6e4 = {$msg} +msg-e092b97c = [角色]{ "\u000A" }{ "\u000A" }- 人格情景列表: `/persona list`{ "\u000A" }- 设置人格情景: `/persona 人格`{ "\u000A" }- 人格情景详细信息: `/persona view 人格`{ "\u000A" }- 取消人格: `/persona unset`{ "\u000A" }{ "\u000A" }Default Personality Scenario:{ $res }{ "\u000A" }当前对话{ $curr_cid_title }Personality scenario:{ $curr_persona_name }{ "\u000A" }{ "\u000A" }Configure personality scenarios, please go to the management panel - configuration page.{ "\u000A" } +msg-c046b6e4 = { $msg } msg-99139ef8 = 请输入人格情景名 msg-a44c7ec0 = 当前没有对话,无法取消人格。 -msg-a90c75d4 = 取消人格成功。 +msg-a90c75d4 = Cancel Personality Successful. msg-a712d71a = 当前没有对话,请先开始对话或使用 /new 创建一个对话。 -msg-4e4e746d = 设置成功。如果您正在切换到不同的人格,请注意使用 /reset 来清空上下文,防止原人格对话影响现人格。{$force_warn_msg} +msg-4e4e746d = 设置成功。如果您正在切换到不同的人格,请注意使用 /reset 来清空上下文,防止原人格对话影响现人格。{ $force_warn_msg } msg-ab60a2e7 = 不存在该人格情景。使用 /persona list 查看所有。 ### astrbot/builtin_stars/builtin_commands/commands/t2i.py + msg-855d5cf3 = 已关闭文本转图片模式。 -msg-64da24f4 = 已开启文本转图片模式。 +msg-64da24f4 = Text-to-image mode is enabled. ### astrbot/builtin_stars/builtin_commands/commands/admin.py + msg-ad019976 = 使用方法: /op 授权管理员;/deop 取消管理员。可通过 /sid 获取 ID。 -msg-1235330f = 授权成功。 +msg-1235330f = Authorization successful. msg-e78847e0 = 使用方法: /deop 取消管理员。可通过 /sid 获取 ID。 msg-012152c1 = 取消授权成功。 msg-5e076026 = 此用户 ID 不在管理员名单内。 @@ -2815,107 +3039,117 @@ msg-1dee5007 = 正在尝试更新管理面板... msg-76bea66c = 管理面板更新完成。 ### astrbot/builtin_stars/builtin_commands/commands/sid.py -msg-ed8dcc22 = {$ret} + +msg-ed8dcc22 = { $ret } ### astrbot/builtin_stars/builtin_commands/commands/plugin.py -msg-9cae24f5 = {$plugin_list_info} + +msg-9cae24f5 = { $plugin_list_info } msg-3f3a6087 = 演示模式下无法禁用插件。 msg-90e17cd4 = /plugin off <插件名> 禁用插件。 -msg-d29d6d57 = 插件 {$plugin_name} 已禁用。 +msg-d29d6d57 = 插件{ $plugin_name }已禁用。 msg-f90bbe20 = 演示模式下无法启用插件。 msg-b897048f = /plugin on <插件名> 启用插件。 -msg-ebfb93bb = 插件 {$plugin_name} 已启用。 +msg-ebfb93bb = 插件{ $plugin_name }已启用。 msg-9cd74a8d = 演示模式下无法安装插件。 msg-d79ad78d = /plugin get <插件仓库地址> 安装插件 -msg-4f293fe1 = 准备从 {$plugin_repo} 安装插件。 +msg-4f293fe1 = 准备从{ $plugin_repo }安装插件。 msg-d40e7065 = 安装插件成功。 -msg-feff82c6 = 安装插件失败: {$e} +msg-feff82c6 = 安装插件失败:{ $e } msg-5bfe9d3d = /plugin help <插件名> 查看插件信息。 msg-02627a9b = 未找到此插件。 -msg-ed8dcc22 = {$ret} +msg-ed8dcc22 = { $ret } ### astrbot/builtin_stars/builtin_commands/commands/help.py -msg-c046b6e4 = {$msg} + +msg-c046b6e4 = { $msg } ### astrbot/builtin_stars/builtin_commands/commands/alter_cmd.py -msg-d7a36c19 = 该指令用于设置指令或指令组的权限。{"\u000A"}格式: /alter_cmd {"\u000A"}例1: /alter_cmd c1 admin 将 c1 设为管理员指令{"\u000A"}例2: /alter_cmd g1 c1 admin 将 g1 指令组的 c1 子指令设为管理员指令{"\u000A"}/alter_cmd reset config 打开 reset 权限配置 -msg-afe0fa58 = {$config_menu} + +msg-d7a36c19 = 该指令用于设置指令或指令组的权限。{ "\u000A" }格式: /alter_cmd { "\u000A" }例1: /alter_cmd c1 admin 将 c1 设为管理员指令{ "\u000A" }例2: /alter_cmd g1 c1 admin 将 g1 指令组的 c1 子指令设为管理员指令{ "\u000A" }/alter_cmd reset config 打开 reset 权限配置 +msg-afe0fa58 = { $config_menu } msg-0c85d498 = 场景编号和权限类型不能为空 msg-4e0afcd1 = 场景编号必须是 1-3 之间的数字 msg-830d6eb8 = 权限类型错误,只能是 admin 或 member -msg-d1180ead = 已将 reset 命令在{$res}场景下的权限设为{$perm_type} +msg-d1180ead = 已将 reset 命令在{ $res }场景下的权限设为{ $perm_type } msg-8d9bc364 = 指令类型错误,可选类型有 admin, member msg-1f2f65e0 = 未找到该指令 -msg-cd271581 = 已将「{$cmd_name}」{$cmd_group_str} 的权限级别调整为 {$cmd_type}。 +msg-cd271581 = 已将「{ $cmd_name }"{ $cmd_group_str }The permission level has been adjusted to{ $cmd_type }。 ### astrbot/builtin_stars/web_searcher/main.py -msg-7f5fd92b = 检测到旧版 websearch_tavily_key (字符串格式),自动迁移为列表格式并保存。 -msg-bed9def5 = web_searcher - scraping web: {$res} - {$res_2} -msg-8214760c = bing search error: {$e}, try the next one... -msg-8676b5aa = search bing failed -msg-3fb6d6ad = sogo search error: {$e} -msg-fe9b336f = search sogo failed -msg-c991b022 = 错误:Tavily API密钥未在AstrBot中配置。 -msg-b4fbb4a9 = Tavily web search failed: {$reason}, status: {$res} -msg-6769aba9 = Error: Tavily web searcher does not return any results. -msg-b4e7334e = 此指令已经被废弃,请在 WebUI 中开启或关闭网页搜索功能。 -msg-b1877974 = web_searcher - search_from_search_engine: {$query} -msg-2360df6b = Error processing search result: {$processed_result} -msg-359d0443 = Error: Baidu AI Search API key is not configured in AstrBot. -msg-94351632 = Successfully initialized Baidu AI Search MCP server. -msg-5a7207c1 = web_searcher - search_from_tavily: {$query} -msg-b36134c9 = Error: Tavily API key is not configured in AstrBot. -msg-98ed69f4 = Error: url must be a non-empty string. + +msg-7f5fd92b = 检测到旧版 websearch_tavily_key(字符串格式),已自动迁移为列表格式并保存。 +msg-bed9def5 = web_searcher - 网页抓取中:{ $res }-{ $res_2 } +msg-8214760c = 必应搜索错误:{ $e },试试下一个... +msg-8676b5aa = 搜索必应失败 +msg-3fb6d6ad = sogo 搜索错误:{ $e } +msg-fe9b336f = 搜索搜狗失败 +msg-c991b022 = 错误:AstrBot中未配置Tavily API密钥。 +msg-b4fbb4a9 = Tavily 网页搜索失败:{ $reason }状态:{ $res } +msg-6769aba9 = 错误:Tavily 网络搜索器未返回任何结果。 +msg-b4e7334e = 此指令已被弃用,请在 WebUI 中开启或关闭网页搜索功能。 +msg-b1877974 = web_searcher - search_from_search_engine:{ $query } +msg-2360df6b = 处理搜索结果时出错:{ $processed_result } +msg-359d0443 = 错误:AstrBot 中未配置百度AI搜索API密钥。 +msg-94351632 = 成功初始化百度AI搜索MCP服务器。 +msg-5a7207c1 = web_searcher - search_from_tavily:{ $query } +msg-b36134c9 = 错误:Tavily API 密钥未在 AstrBot 中配置。 +msg-98ed69f4 = 错误:网址必须是非空字符串。 msg-51edd9ee = 错误:BoCha API密钥未在AstrBot中配置。 -msg-73964067 = BoCha web search failed: {$reason}, status: {$res} -msg-34417720 = web_searcher - search_from_bocha: {$query} -msg-b798883b = Error: BoCha API key is not configured in AstrBot. -msg-22993708 = Cannot get Baidu AI Search MCP tool. -msg-6f8d62a4 = Cannot Initialize Baidu AI Search MCP Server: {$e} +msg-73964067 = BoCha 网络搜索失败:{ $reason }, 状态:{ $res } +msg-34417720 = web_searcher - search_from_bocha:{ $query } +msg-b798883b = 错误:AstrBot中未配置BoCha API密钥。 +msg-22993708 = 无法获取百度AI搜索MCP工具。 +msg-6f8d62a4 = 无法初始化百度AI搜索MCP服务器:{ $e } ### astrbot/builtin_stars/web_searcher/engines/bing.py -msg-e3b4d1e9 = Bing search failed + +msg-e3b4d1e9 = Bing搜索失败 ### astrbot/builtin_stars/astrbot/main.py -msg-3df554a1 = 聊天增强 err: {$e} -msg-5bdf8f5c = {$e} -msg-bb6ff036 = 未找到任何 LLM 提供商。请先配置。无法主动回复 -msg-afa050be = 当前未处于对话状态,无法主动回复,请确保 平台设置->会话隔离(unique_session) 未开启,并使用 /switch 序号 切换或者 /new 创建一个会话。 + +msg-3df554a1 = 聊天增强错误:{ $e } +msg-5bdf8f5c = { $e } +msg-bb6ff036 = No LLM provider found. Please configure it first. Unable to reply actively. +msg-afa050be = 当前未处于对话状态,无法主动回复,请确保平台设置->会话隔离(unique_session)未开启,并使用 /switch 序号 切换或者 /new 创建一个会话。 msg-9a6a6b2e = 未找到对话,无法主动回复 -msg-78b9c276 = {$res} -msg-b177e640 = 主动回复失败: {$e} -msg-24d2f380 = ltm: {$e} +msg-78b9c276 = { $res } +msg-b177e640 = 主动回复失败:{ $e } +msg-24d2f380 = ltm:{ $e } ### astrbot/builtin_stars/astrbot/long_term_memory.py -msg-5bdf8f5c = {$e} -msg-8e11fa57 = 没有找到 ID 为 {$image_caption_provider_id} 的提供商 -msg-8ebaa397 = 提供商类型错误({$res}),无法获取图片描述 + +msg-5bdf8f5c = { $e } +msg-8e11fa57 = 没有找到 ID 为{ $image_caption_provider_id }Provider of +msg-8ebaa397 = Provider type error{ $res }),无法获取图片描述 msg-30954f77 = 图片 URL 为空 -msg-62de0c3e = 获取图片描述失败: {$e} -msg-d0647999 = ltm | {$res} | {$final_message} -msg-133c1f1d = Recorded AI response: {$res} | {$final_message} +msg-62de0c3e = 获取图片描述失败:{ $e } +msg-d0647999 = 负载均衡器{ $res }|{ $final_message } +msg-133c1f1d = 已记录的AI响应:{ $res }|{ $final_message } ### astrbot/i18n/ftl_translate.py + msg-547c9cc5 = 未检测到环境变量 DEEPSEEK_API_KEY,请先设置。 -msg-8654e4be = {"\u000A"}[Error] API 调用失败: {$e} -msg-75f207ed = File not found: {$ftl_path} -msg-dcfbbe82 = No messages found in {$ftl_path} -msg-ccd5a28f = 共 {$res} 条文本,使用 {$max_workers} 个并发线程翻译... -msg-00b24d69 = {"\u000A"}[Error] 翻译失败,保留原文: {$e} -msg-ebcdd595 = {"\u000A"}翻译完成,已保存到 {$ftl_path} +msg-8654e4be = { "\u000A" }[错误] API 调用失败:{ $e } +msg-75f207ed = 文件未找到:{ $ftl_path } +msg-dcfbbe82 = 未找到消息{ $ftl_path } +msg-ccd5a28f = Total{ $res }条文本,使用{ $max_workers }Processing concurrent threads for translation... +msg-00b24d69 = { "\u000A" }[Error] 翻译失败,保留原文:{ $e } +msg-ebcdd595 = { "\u000A" }翻译完成,已保存到{ $ftl_path } msg-d6c66497 = 错误: 请先设置 DEEPSEEK_API_KEY 环境变量。 msg-09486085 = 例如: export DEEPSEEK_API_KEY='sk-xxxxxx' ### scripts/generate_changelog.py -msg-a79937ef = Warning: openai package not installed. Install it with: pip install openai -msg-090bfd36 = Warning: Failed to call LLM API: {$e} -msg-a3ac9130 = Falling back to simple changelog generation... -msg-6f1011c5 = Latest tag: {$latest_tag} -msg-8c7f64d7 = Error: No tags found in repository -msg-a89fa0eb = No commits found since {$latest_tag} -msg-846ebecf = Found {$res} commits since {$latest_tag} -msg-9ad686af = Warning: Could not parse version from tag {$latest_tag} -msg-f5d43a54 = Generating changelog for {$version}... -msg-e54756e8 = {"\u000A"}✓ Changelog generated: {$changelog_file} -msg-82be6c98 = {"\u000A"}Preview: -msg-321ac5b1 = {$changelog_content} + +msg-a79937ef = 警告:未安装 openai 包。请通过以下命令安装:pip install openai +msg-090bfd36 = 警告:调用LLM API失败:{ $e } +msg-a3ac9130 = 回退至简单变更日志生成... +msg-6f1011c5 = 最新标签:{ $latest_tag } +msg-8c7f64d7 = 错误:仓库中未找到标签 +msg-a89fa0eb = 自上次提交以来未找到任何提交{ $latest_tag } +msg-846ebecf = 已找到{ $res }自上次提交以来的提交数{ $latest_tag } +msg-9ad686af = 警告:无法从标签解析版本{ $latest_tag } +msg-f5d43a54 = 正在为生成变更日志{ $version }... +msg-e54756e8 = { "\u000A" }✓ 变更日志已生成:{ $changelog_file } +msg-82be6c98 = { "\u000A" }预览: +msg-321ac5b1 = { $changelog_content } From 8347fcdc0d749c75a8c6c49404bbe4dce2509804 Mon Sep 17 00:00:00 2001 From: united_pooh Date: Fri, 27 Feb 2026 20:28:29 +0800 Subject: [PATCH 03/36] refactor(i18n): update error messages to use translation function --- .../builtin_stars/astrbot/long_term_memory.py | 15 +- astrbot/builtin_stars/astrbot/main.py | 21 +- .../builtin_commands/commands/admin.py | 25 +- .../builtin_commands/commands/alter_cmd.py | 23 +- .../builtin_commands/commands/conversation.py | 52 +- .../builtin_commands/commands/help.py | 3 +- .../builtin_commands/commands/llm.py | 3 +- .../builtin_commands/commands/persona.py | 32 +- .../builtin_commands/commands/plugin.py | 33 +- .../builtin_commands/commands/provider.py | 45 +- .../builtin_commands/commands/setunset.py | 7 +- .../builtin_commands/commands/sid.py | 3 +- .../builtin_commands/commands/t2i.py | 5 +- .../builtin_commands/commands/tts.py | 5 +- .../builtin_stars/session_controller/main.py | 3 +- .../web_searcher/engines/bing.py | 3 +- astrbot/builtin_stars/web_searcher/main.py | 51 +- astrbot/cli/__main__.py | 13 +- astrbot/cli/commands/cmd_conf.py | 49 +- astrbot/cli/commands/cmd_init.py | 15 +- astrbot/cli/commands/cmd_plug.py | 42 +- astrbot/cli/commands/cmd_run.py | 11 +- astrbot/cli/utils/basic.py | 19 +- astrbot/cli/utils/plugin.py | 19 +- astrbot/core/agent/context/compressor.py | 3 +- astrbot/core/agent/context/manager.py | 11 +- astrbot/core/agent/mcp_client.py | 31 +- astrbot/core/agent/message.py | 9 +- astrbot/core/agent/runners/base.py | 3 +- .../agent/runners/coze/coze_agent_runner.py | 41 +- .../agent/runners/coze/coze_api_client.py | 55 +- .../dashscope/dashscope_agent_runner.py | 31 +- .../agent/runners/dify/dify_agent_runner.py | 45 +- .../agent/runners/dify/dify_api_client.py | 17 +- .../agent/runners/tool_loop_agent_runner.py | 49 +- astrbot/core/agent/tool.py | 3 +- astrbot/core/agent/tool_image_cache.py | 13 +- astrbot/core/astr_agent_run_util.py | 32 +- astrbot/core/astr_agent_tool_exec.py | 29 +- astrbot/core/astr_main_agent.py | 64 +- astrbot/core/astr_main_agent_resources.py | 19 +- astrbot/core/astrbot_config_mgr.py | 19 +- astrbot/core/backup/exporter.py | 33 +- astrbot/core/backup/importer.py | 41 +- astrbot/core/computer/booters/boxlite.py | 21 +- astrbot/core/computer/booters/local.py | 13 +- astrbot/core/computer/booters/shipyard.py | 5 +- astrbot/core/computer/computer_client.py | 11 +- astrbot/core/computer/tools/fs.py | 13 +- astrbot/core/config/astrbot_config.py | 13 +- astrbot/core/conversation_mgr.py | 5 +- astrbot/core/core_lifecycle.py | 31 +- astrbot/core/cron/manager.py | 23 +- astrbot/core/db/migration/helper.py | 5 +- astrbot/core/db/migration/migra_3_to_4.py | 57 +- astrbot/core/db/migration/migra_45_to_46.py | 7 +- .../core/db/migration/migra_token_usage.py | 11 +- .../db/migration/migra_webchat_session.py | 15 +- .../db/vec_db/faiss_impl/document_storage.py | 7 +- .../db/vec_db/faiss_impl/embedding_storage.py | 7 +- astrbot/core/db/vec_db/faiss_impl/vec_db.py | 5 +- astrbot/core/event_bus.py | 7 +- astrbot/core/file_token_service.py | 7 +- astrbot/core/initial_loader.py | 7 +- .../core/knowledge_base/chunking/recursive.py | 7 +- astrbot/core/knowledge_base/kb_db_sqlite.py | 3 +- astrbot/core/knowledge_base/kb_helper.py | 47 +- astrbot/core/knowledge_base/kb_mgr.py | 23 +- .../knowledge_base/parsers/text_parser.py | 3 +- .../core/knowledge_base/parsers/url_parser.py | 13 +- astrbot/core/knowledge_base/parsers/util.py | 3 +- .../core/knowledge_base/retrieval/manager.py | 13 +- astrbot/core/lang.py | 16 +- astrbot/core/log.py | 3 +- astrbot/core/message/components.py | 55 +- astrbot/core/persona_mgr.py | 15 +- astrbot/core/pipeline/__init__.py | 3 +- .../pipeline/content_safety_check/stage.py | 5 +- .../strategies/strategy.py | 3 +- astrbot/core/pipeline/context_utils.py | 11 +- .../core/pipeline/preprocess_stage/stage.py | 15 +- .../core/pipeline/process_stage/follow_up.py | 3 +- .../process_stage/method/agent_request.py | 7 +- .../method/agent_sub_stages/internal.py | 23 +- .../method/agent_sub_stages/third_party.py | 13 +- .../process_stage/method/star_request.py | 11 +- .../core/pipeline/rate_limit_check/stage.py | 5 +- astrbot/core/pipeline/respond/stage.py | 25 +- .../core/pipeline/result_decorate/stage.py | 35 +- astrbot/core/pipeline/scheduler.py | 9 +- .../pipeline/session_status_check/stage.py | 3 +- astrbot/core/pipeline/waking_check/stage.py | 9 +- .../core/pipeline/whitelist_check/stage.py | 3 +- astrbot/core/platform/astr_message_event.py | 10 +- astrbot/core/platform/manager.py | 35 +- astrbot/core/platform/platform.py | 3 +- astrbot/core/platform/register.py | 7 +- .../aiocqhttp/aiocqhttp_message_event.py | 3 +- .../aiocqhttp/aiocqhttp_platform_adapter.py | 43 +- .../sources/dingtalk/dingtalk_adapter.py | 45 +- .../sources/dingtalk/dingtalk_event.py | 3 +- .../core/platform/sources/discord/client.py | 17 +- .../discord/discord_platform_adapter.py | 61 +- .../sources/discord/discord_platform_event.py | 43 +- .../platform/sources/lark/lark_adapter.py | 63 +- .../core/platform/sources/lark/lark_event.py | 65 +- astrbot/core/platform/sources/lark/server.py | 19 +- .../platform/sources/line/line_adapter.py | 11 +- .../core/platform/sources/line/line_api.py | 9 +- .../core/platform/sources/line/line_event.py | 19 +- .../sources/misskey/misskey_adapter.py | 53 +- .../platform/sources/misskey/misskey_api.py | 180 +++--- .../platform/sources/misskey/misskey_event.py | 13 +- .../qqofficial/qqofficial_message_event.py | 31 +- .../qqofficial/qqofficial_platform_adapter.py | 7 +- .../qqofficial_webhook/qo_webhook_adapter.py | 9 +- .../qqofficial_webhook/qo_webhook_server.py | 13 +- .../platform/sources/satori/satori_adapter.py | 65 +- .../platform/sources/satori/satori_event.py | 35 +- astrbot/core/platform/sources/slack/client.py | 19 +- .../platform/sources/slack/slack_adapter.py | 29 +- .../platform/sources/slack/slack_event.py | 7 +- .../platform/sources/telegram/tg_adapter.py | 49 +- .../platform/sources/telegram/tg_event.py | 22 +- .../sources/webchat/webchat_adapter.py | 3 +- .../platform/sources/webchat/webchat_event.py | 3 +- .../sources/webchat/webchat_queue_mgr.py | 5 +- .../platform/sources/wecom/wecom_adapter.py | 39 +- .../platform/sources/wecom/wecom_event.py | 59 +- .../sources/wecom_ai_bot/WXBizJsonMsgCrypt.py | 597 +++++++++--------- .../sources/wecom_ai_bot/wecomai_adapter.py | 39 +- .../sources/wecom_ai_bot/wecomai_api.py | 53 +- .../sources/wecom_ai_bot/wecomai_event.py | 7 +- .../sources/wecom_ai_bot/wecomai_queue_mgr.py | 21 +- .../sources/wecom_ai_bot/wecomai_server.py | 21 +- .../sources/wecom_ai_bot/wecomai_utils.py | 19 +- .../sources/wecom_ai_bot/wecomai_webhook.py | 25 +- .../weixin_offacc_adapter.py | 65 +- .../weixin_offacc_event.py | 19 +- astrbot/core/provider/entities.py | 3 +- astrbot/core/provider/func_tool_manager.py | 39 +- astrbot/core/provider/manager.py | 73 +-- astrbot/core/provider/provider.py | 9 +- astrbot/core/provider/register.py | 5 +- .../core/provider/sources/anthropic_source.py | 17 +- .../core/provider/sources/azure_tts_source.py | 27 +- .../provider/sources/bailian_rerank_source.py | 39 +- .../core/provider/sources/dashscope_tts.py | 17 +- .../core/provider/sources/edge_tts_source.py | 253 ++++---- .../sources/fishaudio_tts_api_source.py | 9 +- .../sources/gemini_embedding_source.py | 7 +- .../core/provider/sources/gemini_source.py | 81 +-- .../provider/sources/gemini_tts_source.py | 5 +- astrbot/core/provider/sources/genie_tts.py | 13 +- .../provider/sources/gsv_selfhosted_source.py | 35 +- .../core/provider/sources/gsvi_tts_source.py | 119 ++-- .../sources/minimax_tts_api_source.py | 5 +- .../sources/openai_embedding_source.py | 3 +- .../core/provider/sources/openai_source.py | 43 +- .../provider/sources/openai_tts_api_source.py | 3 +- .../sources/sensevoice_selfhosted_source.py | 15 +- .../provider/sources/vllm_rerank_source.py | 3 +- .../core/provider/sources/volcengine_tts.py | 19 +- .../provider/sources/whisper_api_source.py | 9 +- .../sources/whisper_selfhosted_source.py | 11 +- .../sources/xinference_rerank_source.py | 31 +- .../sources/xinference_stt_provider.py | 47 +- astrbot/core/skills/skill_manager.py | 25 +- astrbot/core/star/base.py | 3 +- astrbot/core/star/command_management.py | 19 +- astrbot/core/star/config.py | 13 +- astrbot/core/star/context.py | 21 +- astrbot/core/star/filter/command.py | 9 +- astrbot/core/star/filter/custom_filter.py | 9 +- astrbot/core/star/register/star.py | 3 +- astrbot/core/star/register/star_handler.py | 15 +- astrbot/core/star/session_llm_manager.py | 3 +- astrbot/core/star/session_plugin_manager.py | 3 +- astrbot/core/star/star_manager.py | 155 ++--- astrbot/core/star/star_tools.py | 33 +- astrbot/core/star/updator.py | 15 +- astrbot/core/subagent_orchestrator.py | 7 +- astrbot/core/umop_config_router.py | 7 +- astrbot/core/updator.py | 21 +- astrbot/core/utils/history_saver.py | 3 +- astrbot/core/utils/io.py | 27 +- astrbot/core/utils/llm_metadata.py | 5 +- astrbot/core/utils/media_utils.py | 55 +- astrbot/core/utils/metrics.py | 3 +- astrbot/core/utils/migra_helper.py | 25 +- astrbot/core/utils/network_utils.py | 8 +- astrbot/core/utils/path_util.py | 7 +- astrbot/core/utils/pip_installer.py | 36 +- .../core/utils/quoted_message/extractor.py | 3 +- .../utils/quoted_message/image_resolver.py | 5 +- .../utils/quoted_message/onebot_client.py | 6 +- astrbot/core/utils/session_waiter.py | 5 +- astrbot/core/utils/shared_preferences.py | 3 +- astrbot/core/utils/t2i/local_strategy.py | 7 +- astrbot/core/utils/t2i/network_strategy.py | 13 +- astrbot/core/utils/t2i/renderer.py | 3 +- astrbot/core/utils/t2i/template_manager.py | 9 +- astrbot/core/utils/temp_dir_cleaner.py | 18 +- astrbot/core/utils/tencent_record_helper.py | 15 +- astrbot/core/utils/trace.py | 5 +- astrbot/core/utils/webhook_utils.py | 9 +- astrbot/core/zip_updator.py | 29 +- astrbot/dashboard/routes/api_key.py | 17 +- astrbot/dashboard/routes/auth.py | 15 +- astrbot/dashboard/routes/backup.py | 193 +++--- astrbot/dashboard/routes/chat.py | 75 +-- astrbot/dashboard/routes/chatui_project.py | 45 +- astrbot/dashboard/routes/command.py | 7 +- astrbot/dashboard/routes/config.py | 217 +++---- astrbot/dashboard/routes/conversation.py | 55 +- astrbot/dashboard/routes/cron.py | 39 +- astrbot/dashboard/routes/file.py | 3 +- astrbot/dashboard/routes/knowledge_base.py | 219 +++---- astrbot/dashboard/routes/lang_route.py | 4 +- astrbot/dashboard/routes/live_chat.py | 57 +- astrbot/dashboard/routes/log.py | 19 +- astrbot/dashboard/routes/open_api.py | 49 +- astrbot/dashboard/routes/persona.py | 87 +-- astrbot/dashboard/routes/platform.py | 17 +- astrbot/dashboard/routes/plugin.py | 155 ++--- .../dashboard/routes/session_management.py | 99 +-- astrbot/dashboard/routes/skills.py | 25 +- astrbot/dashboard/routes/stat.py | 39 +- astrbot/dashboard/routes/subagent.py | 15 +- astrbot/dashboard/routes/t2i.py | 21 +- astrbot/dashboard/routes/tools.py | 101 +-- astrbot/dashboard/routes/update.py | 29 +- astrbot/dashboard/server.py | 58 +- astrbot/dashboard/utils.py | 19 +- astrbot/i18n/automatic_i18n.py | 81 ++- astrbot/i18n/ftl_translate.py | 19 +- astrbot/i18n/locales/en-us/i18n_messages.ftl | 5 + astrbot/i18n/locales/zh-cn/i18n_messages.ftl | 14 + astrbot/utils/http_ssl_common.py | 4 +- main.py | 19 +- scripts/generate_changelog.py | 25 +- 241 files changed, 3662 insertions(+), 3446 deletions(-) diff --git a/astrbot/builtin_stars/astrbot/long_term_memory.py b/astrbot/builtin_stars/astrbot/long_term_memory.py index e08cdc5157..d5e5935bca 100644 --- a/astrbot/builtin_stars/astrbot/long_term_memory.py +++ b/astrbot/builtin_stars/astrbot/long_term_memory.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import datetime import random import uuid @@ -28,7 +29,7 @@ def cfg(self, event: AstrMessageEvent): try: max_cnt = int(cfg["provider_ltm_settings"]["group_message_max_cnt"]) except BaseException as e: - logger.error(e) + logger.error(t("msg-5bdf8f5c", e=e)) max_cnt = 300 image_caption_prompt = cfg["provider_settings"]["image_caption_prompt"] image_caption_provider_id = cfg["provider_ltm_settings"].get( @@ -74,9 +75,9 @@ async def get_image_caption( else: provider = self.context.get_provider_by_id(image_caption_provider_id) if not provider: - raise Exception(f"没有找到 ID 为 {image_caption_provider_id} 的提供商") + raise Exception(t("msg-8e11fa57", image_caption_provider_id=image_caption_provider_id)) if not isinstance(provider, Provider): - raise Exception(f"提供商类型错误({type(provider)}),无法获取图片描述") + raise Exception(t("msg-8ebaa397", res=type(provider))) response = await provider.text_chat( prompt=image_caption_prompt, session_id=uuid.uuid4().hex, @@ -128,7 +129,7 @@ async def handle_message(self, event: AstrMessageEvent) -> None: try: url = comp.url if comp.url else comp.file if not url: - raise Exception("图片 URL 为空") + raise Exception(t("msg-30954f77")) caption = await self.get_image_caption( url, cfg["image_caption_provider_id"], @@ -136,14 +137,14 @@ async def handle_message(self, event: AstrMessageEvent) -> None: ) parts.append(f" [Image: {caption}]") except Exception as e: - logger.error(f"获取图片描述失败: {e}") + logger.error(t("msg-62de0c3e", e=e)) else: parts.append(" [Image]") elif isinstance(comp, At): parts.append(f" [At: {comp.name}]") final_message = "".join(parts) - logger.debug(f"ltm | {event.unified_msg_origin} | {final_message}") + logger.debug(t("msg-d0647999", res=event.unified_msg_origin, final_message=final_message)) self.session_chats[event.unified_msg_origin].append(final_message) if len(self.session_chats[event.unified_msg_origin]) > cfg["max_cnt"]: self.session_chats[event.unified_msg_origin].pop(0) @@ -180,7 +181,7 @@ async def after_req_llm( if llm_resp.completion_text: final_message = f"[You/{datetime.datetime.now().strftime('%H:%M:%S')}]: {llm_resp.completion_text}" logger.debug( - f"Recorded AI response: {event.unified_msg_origin} | {final_message}" + t("msg-133c1f1d", res=event.unified_msg_origin, final_message=final_message) ) self.session_chats[event.unified_msg_origin].append(final_message) cfg = self.cfg(event) diff --git a/astrbot/builtin_stars/astrbot/main.py b/astrbot/builtin_stars/astrbot/main.py index da2a008354..b1c887a52a 100644 --- a/astrbot/builtin_stars/astrbot/main.py +++ b/astrbot/builtin_stars/astrbot/main.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import traceback from astrbot.api import star @@ -16,7 +17,7 @@ def __init__(self, context: star.Context) -> None: try: self.ltm = LongTermMemory(self.context.astrbot_config_mgr, self.context) except BaseException as e: - logger.error(f"聊天增强 err: {e}") + logger.error(t("msg-3df554a1", e=e)) def ltm_enabled(self, event: AstrMessageEvent): ltmse = self.context.get_config(umo=event.unified_msg_origin)[ @@ -44,13 +45,13 @@ async def on_message(self, event: AstrMessageEvent): try: await self.ltm.handle_message(event) except BaseException as e: - logger.error(e) + logger.error(t("msg-5bdf8f5c", e=e)) if need_active: """主动回复""" provider = self.context.get_using_provider(event.unified_msg_origin) if not provider: - logger.error("未找到任何 LLM 提供商。请先配置。无法主动回复") + logger.error(t("msg-bb6ff036")) return try: conv = None @@ -60,7 +61,7 @@ async def on_message(self, event: AstrMessageEvent): if not session_curr_cid: logger.error( - "当前未处于对话状态,无法主动回复,请确保 平台设置->会话隔离(unique_session) 未开启,并使用 /switch 序号 切换或者 /new 创建一个会话。", + t("msg-afa050be"), ) return @@ -72,7 +73,7 @@ async def on_message(self, event: AstrMessageEvent): prompt = event.message_str if not conv: - logger.error("未找到对话,无法主动回复") + logger.error(t("msg-9a6a6b2e")) return yield event.request_llm( @@ -81,8 +82,8 @@ async def on_message(self, event: AstrMessageEvent): conversation=conv, ) except BaseException as e: - logger.error(traceback.format_exc()) - logger.error(f"主动回复失败: {e}") + logger.error(t("msg-78b9c276", res=traceback.format_exc())) + logger.error(t("msg-b177e640", e=e)) @filter.on_llm_request() async def decorate_llm_req( @@ -93,7 +94,7 @@ async def decorate_llm_req( try: await self.ltm.on_req_llm(event, req) except BaseException as e: - logger.error(f"ltm: {e}") + logger.error(t("msg-24d2f380", e=e)) @filter.on_llm_response() async def record_llm_resp_to_ltm( @@ -104,7 +105,7 @@ async def record_llm_resp_to_ltm( try: await self.ltm.after_req_llm(event, resp) except Exception as e: - logger.error(f"ltm: {e}") + logger.error(t("msg-24d2f380", e=e)) @filter.after_message_sent() async def after_message_sent(self, event: AstrMessageEvent) -> None: @@ -115,4 +116,4 @@ async def after_message_sent(self, event: AstrMessageEvent) -> None: if clean_session: await self.ltm.remove_session(event) except Exception as e: - logger.error(f"ltm: {e}") + logger.error(t("msg-24d2f380", e=e)) diff --git a/astrbot/builtin_stars/builtin_commands/commands/admin.py b/astrbot/builtin_stars/builtin_commands/commands/admin.py index a4f46b6036..75a94aca11 100644 --- a/astrbot/builtin_stars/builtin_commands/commands/admin.py +++ b/astrbot/builtin_stars/builtin_commands/commands/admin.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t from astrbot.api import star from astrbot.api.event import AstrMessageEvent, MessageChain, MessageEventResult from astrbot.core.config.default import VERSION @@ -13,30 +14,30 @@ async def op(self, event: AstrMessageEvent, admin_id: str = "") -> None: if not admin_id: event.set_result( MessageEventResult().message( - "使用方法: /op 授权管理员;/deop 取消管理员。可通过 /sid 获取 ID。", + t("msg-ad019976"), ), ) return self.context.get_config()["admins_id"].append(str(admin_id)) self.context.get_config().save_config() - event.set_result(MessageEventResult().message("授权成功。")) + event.set_result(MessageEventResult().message(t("msg-1235330f"))) async def deop(self, event: AstrMessageEvent, admin_id: str = "") -> None: """取消授权管理员。deop """ if not admin_id: event.set_result( MessageEventResult().message( - "使用方法: /deop 取消管理员。可通过 /sid 获取 ID。", + t("msg-e78847e0"), ), ) return try: self.context.get_config()["admins_id"].remove(str(admin_id)) self.context.get_config().save_config() - event.set_result(MessageEventResult().message("取消授权成功。")) + event.set_result(MessageEventResult().message(t("msg-012152c1"))) except ValueError: event.set_result( - MessageEventResult().message("此用户 ID 不在管理员名单内。"), + MessageEventResult().message(t("msg-5e076026")), ) async def wl(self, event: AstrMessageEvent, sid: str = "") -> None: @@ -44,21 +45,21 @@ async def wl(self, event: AstrMessageEvent, sid: str = "") -> None: if not sid: event.set_result( MessageEventResult().message( - "使用方法: /wl 添加白名单;/dwl 删除白名单。可通过 /sid 获取 ID。", + t("msg-7f8eedde"), ), ) return cfg = self.context.get_config(umo=event.unified_msg_origin) cfg["platform_settings"]["id_whitelist"].append(str(sid)) cfg.save_config() - event.set_result(MessageEventResult().message("添加白名单成功。")) + event.set_result(MessageEventResult().message(t("msg-de1b0a87"))) async def dwl(self, event: AstrMessageEvent, sid: str = "") -> None: """删除白名单。dwl """ if not sid: event.set_result( MessageEventResult().message( - "使用方法: /dwl 删除白名单。可通过 /sid 获取 ID。", + t("msg-59d6fcbe"), ), ) return @@ -66,12 +67,12 @@ async def dwl(self, event: AstrMessageEvent, sid: str = "") -> None: cfg = self.context.get_config(umo=event.unified_msg_origin) cfg["platform_settings"]["id_whitelist"].remove(str(sid)) cfg.save_config() - event.set_result(MessageEventResult().message("删除白名单成功。")) + event.set_result(MessageEventResult().message(t("msg-4638580f"))) except ValueError: - event.set_result(MessageEventResult().message("此 SID 不在白名单内。")) + event.set_result(MessageEventResult().message(t("msg-278fb868"))) async def update_dashboard(self, event: AstrMessageEvent) -> None: """更新管理面板""" - await event.send(MessageChain().message("正在尝试更新管理面板...")) + await event.send(MessageChain().message(t("msg-1dee5007"))) await download_dashboard(version=f"v{VERSION}", latest=False) - await event.send(MessageChain().message("管理面板更新完成。")) + await event.send(MessageChain().message(t("msg-76bea66c"))) diff --git a/astrbot/builtin_stars/builtin_commands/commands/alter_cmd.py b/astrbot/builtin_stars/builtin_commands/commands/alter_cmd.py index ba31c3326c..87c4dc6152 100644 --- a/astrbot/builtin_stars/builtin_commands/commands/alter_cmd.py +++ b/astrbot/builtin_stars/builtin_commands/commands/alter_cmd.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t from astrbot.api import star from astrbot.api.event import AstrMessageEvent, MessageChain from astrbot.core.star.filter.command import CommandFilter @@ -31,11 +32,7 @@ async def alter_cmd(self, event: AstrMessageEvent) -> None: if token.len < 3: await event.send( MessageChain().message( - "该指令用于设置指令或指令组的权限。\n" - "格式: /alter_cmd \n" - "例1: /alter_cmd c1 admin 将 c1 设为管理员指令\n" - "例2: /alter_cmd g1 c1 admin 将 g1 指令组的 c1 子指令设为管理员指令\n" - "/alter_cmd reset config 打开 reset 权限配置", + t("msg-d7a36c19"), ), ) return @@ -63,7 +60,7 @@ async def alter_cmd(self, event: AstrMessageEvent) -> None: 修改指令格式: /alter_cmd reset scene <场景编号> 例如: /alter_cmd reset scene 2 member""" - await event.send(MessageChain().message(config_menu)) + await event.send(MessageChain().message(t("msg-afe0fa58", config_menu=config_menu))) return if cmd_name == "reset" and cmd_type == "scene" and token.len >= 4: @@ -71,18 +68,18 @@ async def alter_cmd(self, event: AstrMessageEvent) -> None: perm_type = token.get(4) if scene_num is None or perm_type is None: - await event.send(MessageChain().message("场景编号和权限类型不能为空")) + await event.send(MessageChain().message(t("msg-0c85d498"))) return if not scene_num.isdigit() or int(scene_num) < 1 or int(scene_num) > 3: await event.send( - MessageChain().message("场景编号必须是 1-3 之间的数字"), + MessageChain().message(t("msg-4e0afcd1")), ) return if perm_type not in ["admin", "member"]: await event.send( - MessageChain().message("权限类型错误,只能是 admin 或 member"), + MessageChain().message(t("msg-830d6eb8")), ) return @@ -94,14 +91,14 @@ async def alter_cmd(self, event: AstrMessageEvent) -> None: await event.send( MessageChain().message( - f"已将 reset 命令在{scene.name}场景下的权限设为{perm_type}", + t("msg-d1180ead", res=scene.name, perm_type=perm_type), ), ) return if cmd_type not in ["admin", "member"]: await event.send( - MessageChain().message("指令类型错误,可选类型有 admin, member"), + MessageChain().message(t("msg-8d9bc364")), ) return @@ -124,7 +121,7 @@ async def alter_cmd(self, event: AstrMessageEvent) -> None: break if not found_command: - await event.send(MessageChain().message("未找到该指令")) + await event.send(MessageChain().message(t("msg-1f2f65e0"))) return found_plugin = star_map[found_command.handler_module_path] @@ -168,6 +165,6 @@ async def alter_cmd(self, event: AstrMessageEvent) -> None: cmd_group_str = "指令组" if cmd_group else "指令" await event.send( MessageChain().message( - f"已将「{cmd_name}」{cmd_group_str} 的权限级别调整为 {cmd_type}。", + t("msg-cd271581", cmd_name=cmd_name, cmd_group_str=cmd_group_str, cmd_type=cmd_type), ), ) diff --git a/astrbot/builtin_stars/builtin_commands/commands/conversation.py b/astrbot/builtin_stars/builtin_commands/commands/conversation.py index 55b75cb1bd..ee9a06e97e 100644 --- a/astrbot/builtin_stars/builtin_commands/commands/conversation.py +++ b/astrbot/builtin_stars/builtin_commands/commands/conversation.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import datetime from astrbot.api import sp, star @@ -55,8 +56,7 @@ async def reset(self, message: AstrMessageEvent) -> None: if required_perm == "admin" and message.role != "admin": message.set_result( MessageEventResult().message( - f"在{scene.name}场景下,reset命令需要管理员权限," - f"您 (ID {message.get_sender_id()}) 不是管理员,无法执行此操作。", + t("msg-63fe9607", res=scene.name, res_2=message.get_sender_id()), ), ) return @@ -69,12 +69,12 @@ async def reset(self, message: AstrMessageEvent) -> None: scope_id=umo, key=THIRD_PARTY_AGENT_RUNNER_KEY[agent_runner_type], ) - message.set_result(MessageEventResult().message("重置对话成功。")) + message.set_result(MessageEventResult().message(t("msg-6f4bbe27"))) return if not self.context.get_using_provider(umo): message.set_result( - MessageEventResult().message("未找到任何 LLM 提供商。请先配置。"), + MessageEventResult().message(t("msg-4cdd042d")), ) return @@ -83,7 +83,7 @@ async def reset(self, message: AstrMessageEvent) -> None: if not cid: message.set_result( MessageEventResult().message( - "当前未处于对话状态,请 /switch 切换或者 /new 创建。", + t("msg-69ed45be"), ), ) return @@ -100,7 +100,7 @@ async def reset(self, message: AstrMessageEvent) -> None: message.set_extra("_clean_ltm_session", True) - message.set_result(MessageEventResult().message(ret)) + message.set_result(MessageEventResult().message(t("msg-ed8dcc22", ret=ret))) async def stop(self, message: AstrMessageEvent) -> None: """停止当前会话正在运行的 Agent""" @@ -119,18 +119,18 @@ async def stop(self, message: AstrMessageEvent) -> None: if stopped_count > 0: message.set_result( MessageEventResult().message( - f"已请求停止 {stopped_count} 个运行中的任务。" + t("msg-772ec1fa", stopped_count=stopped_count) ) ) return - message.set_result(MessageEventResult().message("当前会话没有运行中的任务。")) + message.set_result(MessageEventResult().message(t("msg-8d42cd8a"))) async def his(self, message: AstrMessageEvent, page: int = 1) -> None: """查看对话记录""" if not self.context.get_using_provider(message.unified_msg_origin): message.set_result( - MessageEventResult().message("未找到任何 LLM 提供商。请先配置。"), + MessageEventResult().message(t("msg-4cdd042d")), ) return @@ -167,7 +167,7 @@ async def his(self, message: AstrMessageEvent, page: int = 1) -> None: f"*输入 /history 2 跳转到第 2 页" ) - message.set_result(MessageEventResult().message(ret).use_t2i(False)) + message.set_result(MessageEventResult().message(t("msg-ed8dcc22", ret=ret)).use_t2i(False)) async def convs(self, message: AstrMessageEvent, page: int = 1) -> None: """查看对话列表""" @@ -176,7 +176,7 @@ async def convs(self, message: AstrMessageEvent, page: int = 1) -> None: if agent_runner_type in THIRD_PARTY_AGENT_RUNNER_KEY: message.set_result( MessageEventResult().message( - f"{THIRD_PARTY_AGENT_RUNNER_STR} 对话列表功能暂不支持。", + t("msg-efdfbe3e", THIRD_PARTY_AGENT_RUNNER_STR=THIRD_PARTY_AGENT_RUNNER_STR), ), ) return @@ -258,7 +258,7 @@ async def convs(self, message: AstrMessageEvent, page: int = 1) -> None: ret += f"\n第 {page} 页 | 共 {total_pages} 页" ret += "\n*输入 /ls 2 跳转到第 2 页" - message.set_result(MessageEventResult().message(ret).use_t2i(False)) + message.set_result(MessageEventResult().message(t("msg-ed8dcc22", ret=ret)).use_t2i(False)) return async def new_conv(self, message: AstrMessageEvent) -> None: @@ -272,7 +272,7 @@ async def new_conv(self, message: AstrMessageEvent) -> None: scope_id=message.unified_msg_origin, key=THIRD_PARTY_AGENT_RUNNER_KEY[agent_runner_type], ) - message.set_result(MessageEventResult().message("已创建新对话。")) + message.set_result(MessageEventResult().message(t("msg-492c2c02"))) return active_event_registry.stop_all(message.unified_msg_origin, exclude=message) @@ -286,7 +286,7 @@ async def new_conv(self, message: AstrMessageEvent) -> None: message.set_extra("_clean_ltm_session", True) message.set_result( - MessageEventResult().message(f"切换到新对话: 新对话({cid[:4]})。"), + MessageEventResult().message(t("msg-c7dc838d", res=cid[:4])), ) async def groupnew_conv(self, message: AstrMessageEvent, sid: str = "") -> None: @@ -308,12 +308,12 @@ async def groupnew_conv(self, message: AstrMessageEvent, sid: str = "") -> None: ) message.set_result( MessageEventResult().message( - f"群聊 {session} 已切换到新对话: 新对话({cid[:4]})。", + t("msg-6da01230", session=session, res=cid[:4]), ), ) else: message.set_result( - MessageEventResult().message("请输入群聊 ID。/groupnew 群聊ID。"), + MessageEventResult().message(t("msg-f356d65a")), ) async def switch_conv( @@ -324,14 +324,14 @@ async def switch_conv( """通过 /ls 前面的序号切换对话""" if not isinstance(index, int): message.set_result( - MessageEventResult().message("类型错误,请输入数字对话序号。"), + MessageEventResult().message(t("msg-7e442185")), ) return if index is None: message.set_result( MessageEventResult().message( - "请输入对话序号。/switch 对话序号。/ls 查看对话 /new 新建对话", + t("msg-00dbe29c"), ), ) return @@ -340,7 +340,7 @@ async def switch_conv( ) if index > len(conversations) or index < 1: message.set_result( - MessageEventResult().message("对话序号错误,请使用 /ls 查看"), + MessageEventResult().message(t("msg-a848ccf6")), ) else: conversation = conversations[index - 1] @@ -351,20 +351,20 @@ async def switch_conv( ) message.set_result( MessageEventResult().message( - f"切换到对话: {title}({conversation.cid[:4]})。", + t("msg-1ec33cf6", title=title, res=conversation.cid[:4]), ), ) async def rename_conv(self, message: AstrMessageEvent, new_name: str = "") -> None: """重命名对话""" if not new_name: - message.set_result(MessageEventResult().message("请输入新的对话名称。")) + message.set_result(MessageEventResult().message(t("msg-68e5dd6c"))) return await self.context.conversation_manager.update_conversation_title( message.unified_msg_origin, new_name, ) - message.set_result(MessageEventResult().message("重命名对话成功。")) + message.set_result(MessageEventResult().message(t("msg-c8dd6158"))) async def del_conv(self, message: AstrMessageEvent) -> None: """删除当前对话""" @@ -375,7 +375,7 @@ async def del_conv(self, message: AstrMessageEvent) -> None: # 群聊,没开独立会话,发送人不是管理员 message.set_result( MessageEventResult().message( - f"会话处于群聊,并且未开启独立会话,并且您 (ID {message.get_sender_id()}) 不是管理员,因此没有权限删除当前对话。", + t("msg-1f1fa2f2", res=message.get_sender_id()), ), ) return @@ -388,7 +388,7 @@ async def del_conv(self, message: AstrMessageEvent) -> None: scope_id=umo, key=THIRD_PARTY_AGENT_RUNNER_KEY[agent_runner_type], ) - message.set_result(MessageEventResult().message("重置对话成功。")) + message.set_result(MessageEventResult().message(t("msg-6f4bbe27"))) return session_curr_cid = ( @@ -398,7 +398,7 @@ async def del_conv(self, message: AstrMessageEvent) -> None: if not session_curr_cid: message.set_result( MessageEventResult().message( - "当前未处于对话状态,请 /switch 序号 切换或 /new 创建。", + t("msg-6a1dc4b7"), ), ) return @@ -412,4 +412,4 @@ async def del_conv(self, message: AstrMessageEvent) -> None: ret = "删除当前对话成功。不再处于对话状态,使用 /switch 序号 切换到其他对话或 /new 创建。" message.set_extra("_clean_ltm_session", True) - message.set_result(MessageEventResult().message(ret)) + message.set_result(MessageEventResult().message(t("msg-ed8dcc22", ret=ret))) diff --git a/astrbot/builtin_stars/builtin_commands/commands/help.py b/astrbot/builtin_stars/builtin_commands/commands/help.py index ae2f4c787e..afa2451191 100644 --- a/astrbot/builtin_stars/builtin_commands/commands/help.py +++ b/astrbot/builtin_stars/builtin_commands/commands/help.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import aiohttp from astrbot.api import star @@ -85,4 +86,4 @@ async def help(self, event: AstrMessageEvent) -> None: msg_parts.append(notice) msg = "\n".join(msg_parts) - event.set_result(MessageEventResult().message(msg).use_t2i(False)) + event.set_result(MessageEventResult().message(t("msg-c046b6e4", msg=msg)).use_t2i(False)) diff --git a/astrbot/builtin_stars/builtin_commands/commands/llm.py b/astrbot/builtin_stars/builtin_commands/commands/llm.py index ba9ba5c9b2..bbfcd1a2c1 100644 --- a/astrbot/builtin_stars/builtin_commands/commands/llm.py +++ b/astrbot/builtin_stars/builtin_commands/commands/llm.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t from astrbot.api import star from astrbot.api.event import AstrMessageEvent, MessageChain @@ -17,4 +18,4 @@ async def llm(self, event: AstrMessageEvent) -> None: cfg["provider_settings"]["enable"] = True status = "开启" cfg.save_config() - await event.send(MessageChain().message(f"{status} LLM 聊天功能。")) + await event.send(MessageChain().message(t("msg-72cd5f57", status=status))) diff --git a/astrbot/builtin_stars/builtin_commands/commands/persona.py b/astrbot/builtin_stars/builtin_commands/commands/persona.py index 7a7416bbaf..31f889c483 100644 --- a/astrbot/builtin_stars/builtin_commands/commands/persona.py +++ b/astrbot/builtin_stars/builtin_commands/commands/persona.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import builtins from typing import TYPE_CHECKING @@ -71,7 +72,7 @@ async def persona(self, message: AstrMessageEvent) -> None: if conv is None: message.set_result( MessageEventResult().message( - "当前对话不存在,请先使用 /new 新建一个对话。", + t("msg-4f52d0dd"), ), ) return @@ -107,18 +108,7 @@ async def persona(self, message: AstrMessageEvent) -> None: message.set_result( MessageEventResult() .message( - f"""[Persona] - -- 人格情景列表: `/persona list` -- 设置人格情景: `/persona 人格` -- 人格情景详细信息: `/persona view 人格` -- 取消人格: `/persona unset` - -默认人格情景: {default_persona["name"]} -当前对话 {curr_cid_title} 的人格情景: {curr_persona_name} - -配置人格情景请前往管理面板-配置页 -""", + t("msg-e092b97c", res=default_persona['name'], curr_cid_title=curr_cid_title, curr_persona_name=curr_persona_name), ) .use_t2i(False), ) @@ -148,10 +138,10 @@ async def persona(self, message: AstrMessageEvent) -> None: lines.append("*使用 `/persona view <人格名>` 查看详细信息") msg = "\n".join(lines) - message.set_result(MessageEventResult().message(msg).use_t2i(False)) + message.set_result(MessageEventResult().message(t("msg-c046b6e4", msg=msg)).use_t2i(False)) elif l[1] == "view": if len(l) == 2: - message.set_result(MessageEventResult().message("请输入人格情景名")) + message.set_result(MessageEventResult().message(t("msg-99139ef8"))) return ps = l[2].strip() if persona := next( @@ -165,24 +155,24 @@ async def persona(self, message: AstrMessageEvent) -> None: msg += f"{persona['prompt']}\n" else: msg = f"人格{ps}不存在" - message.set_result(MessageEventResult().message(msg)) + message.set_result(MessageEventResult().message(t("msg-c046b6e4", msg=msg))) elif l[1] == "unset": if not cid: message.set_result( - MessageEventResult().message("当前没有对话,无法取消人格。"), + MessageEventResult().message(t("msg-a44c7ec0")), ) return await self.context.conversation_manager.update_conversation_persona_id( message.unified_msg_origin, "[%None]", ) - message.set_result(MessageEventResult().message("取消人格成功。")) + message.set_result(MessageEventResult().message(t("msg-a90c75d4"))) else: ps = "".join(l[1:]).strip() if not cid: message.set_result( MessageEventResult().message( - "当前没有对话,请先开始对话或使用 /new 创建一个对话。", + t("msg-a712d71a"), ), ) return @@ -205,12 +195,12 @@ async def persona(self, message: AstrMessageEvent) -> None: message.set_result( MessageEventResult().message( - f"设置成功。如果您正在切换到不同的人格,请注意使用 /reset 来清空上下文,防止原人格对话影响现人格。{force_warn_msg}", + t("msg-4e4e746d", force_warn_msg=force_warn_msg), ), ) else: message.set_result( MessageEventResult().message( - "不存在该人格情景。使用 /persona list 查看所有。", + t("msg-ab60a2e7"), ), ) diff --git a/astrbot/builtin_stars/builtin_commands/commands/plugin.py b/astrbot/builtin_stars/builtin_commands/commands/plugin.py index 49bee94627..6b1a169fad 100644 --- a/astrbot/builtin_stars/builtin_commands/commands/plugin.py +++ b/astrbot/builtin_stars/builtin_commands/commands/plugin.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t from astrbot.api import star from astrbot.api.event import AstrMessageEvent, MessageEventResult from astrbot.core import DEMO_MODE, logger @@ -27,66 +28,66 @@ async def plugin_ls(self, event: AstrMessageEvent) -> None: plugin_list_info += "\n使用 /plugin help <插件名> 查看插件帮助和加载的指令。\n使用 /plugin on/off <插件名> 启用或者禁用插件。" event.set_result( - MessageEventResult().message(f"{plugin_list_info}").use_t2i(False), + MessageEventResult().message(t("msg-9cae24f5", plugin_list_info=plugin_list_info)).use_t2i(False), ) async def plugin_off(self, event: AstrMessageEvent, plugin_name: str = "") -> None: """禁用插件""" if DEMO_MODE: - event.set_result(MessageEventResult().message("演示模式下无法禁用插件。")) + event.set_result(MessageEventResult().message(t("msg-3f3a6087"))) return if not plugin_name: event.set_result( - MessageEventResult().message("/plugin off <插件名> 禁用插件。"), + MessageEventResult().message(t("msg-90e17cd4")), ) return await self.context._star_manager.turn_off_plugin(plugin_name) # type: ignore - event.set_result(MessageEventResult().message(f"插件 {plugin_name} 已禁用。")) + event.set_result(MessageEventResult().message(t("msg-d29d6d57", plugin_name=plugin_name))) async def plugin_on(self, event: AstrMessageEvent, plugin_name: str = "") -> None: """启用插件""" if DEMO_MODE: - event.set_result(MessageEventResult().message("演示模式下无法启用插件。")) + event.set_result(MessageEventResult().message(t("msg-f90bbe20"))) return if not plugin_name: event.set_result( - MessageEventResult().message("/plugin on <插件名> 启用插件。"), + MessageEventResult().message(t("msg-b897048f")), ) return await self.context._star_manager.turn_on_plugin(plugin_name) # type: ignore - event.set_result(MessageEventResult().message(f"插件 {plugin_name} 已启用。")) + event.set_result(MessageEventResult().message(t("msg-ebfb93bb", plugin_name=plugin_name))) async def plugin_get(self, event: AstrMessageEvent, plugin_repo: str = "") -> None: """安装插件""" if DEMO_MODE: - event.set_result(MessageEventResult().message("演示模式下无法安装插件。")) + event.set_result(MessageEventResult().message(t("msg-9cd74a8d"))) return if not plugin_repo: event.set_result( - MessageEventResult().message("/plugin get <插件仓库地址> 安装插件"), + MessageEventResult().message(t("msg-d79ad78d")), ) return - logger.info(f"准备从 {plugin_repo} 安装插件。") + logger.info(t("msg-4f293fe1", plugin_repo=plugin_repo)) if self.context._star_manager: star_mgr: PluginManager = self.context._star_manager try: await star_mgr.install_plugin(plugin_repo) # type: ignore - event.set_result(MessageEventResult().message("安装插件成功。")) + event.set_result(MessageEventResult().message(t("msg-d40e7065"))) except Exception as e: - logger.error(f"安装插件失败: {e}") - event.set_result(MessageEventResult().message(f"安装插件失败: {e}")) + logger.error(t("msg-feff82c6", e=e)) + event.set_result(MessageEventResult().message(t("msg-feff82c6", e=e))) return async def plugin_help(self, event: AstrMessageEvent, plugin_name: str = "") -> None: """获取插件帮助""" if not plugin_name: event.set_result( - MessageEventResult().message("/plugin help <插件名> 查看插件信息。"), + MessageEventResult().message(t("msg-5bfe9d3d")), ) return plugin = self.context.get_registered_star(plugin_name) if plugin is None: - event.set_result(MessageEventResult().message("未找到此插件。")) + event.set_result(MessageEventResult().message(t("msg-02627a9b"))) return help_msg = "" help_msg += f"\n\n✨ 作者: {plugin.author}\n✨ 版本: {plugin.version}" @@ -117,4 +118,4 @@ async def plugin_help(self, event: AstrMessageEvent, plugin_name: str = "") -> N ret = f"🧩 插件 {plugin_name} 帮助信息:\n" + help_msg ret += "更多帮助信息请查看插件仓库 README。" - event.set_result(MessageEventResult().message(ret).use_t2i(False)) + event.set_result(MessageEventResult().message(t("msg-ed8dcc22", ret=ret)).use_t2i(False)) diff --git a/astrbot/builtin_stars/builtin_commands/commands/provider.py b/astrbot/builtin_stars/builtin_commands/commands/provider.py index ae20eb8e1c..d2f9e7ab38 100644 --- a/astrbot/builtin_stars/builtin_commands/commands/provider.py +++ b/astrbot/builtin_stars/builtin_commands/commands/provider.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import re @@ -21,7 +22,7 @@ def _log_reachability_failure( """记录不可达原因到日志。""" meta = provider.meta() logger.warning( - "Provider reachability check failed: id=%s type=%s code=%s reason=%s", + t("msg-b435fcdc"), meta.id, provider_capability_type.name if provider_capability_type else "unknown", err_code, @@ -74,7 +75,7 @@ async def provider( if all_providers: await event.send( MessageEventResult().message( - "正在进行提供商可达性测试,请稍候..." + t("msg-f4cfd3ab") ) ) check_results = await asyncio.gather( @@ -178,13 +179,13 @@ async def provider( if not reachability_check_enabled: ret += "\n已跳过提供商可达性检测,如需检测请在配置文件中开启。" - event.set_result(MessageEventResult().message(ret)) + event.set_result(MessageEventResult().message(t("msg-ed8dcc22", ret=ret))) elif idx == "tts": if idx2 is None: - event.set_result(MessageEventResult().message("请输入序号。")) + event.set_result(MessageEventResult().message(t("msg-f3d8988e"))) return if idx2 > len(self.context.get_all_tts_providers()) or idx2 < 1: - event.set_result(MessageEventResult().message("无效的提供商序号。")) + event.set_result(MessageEventResult().message(t("msg-284759bb"))) return provider = self.context.get_all_tts_providers()[idx2 - 1] id_ = provider.meta().id @@ -193,13 +194,13 @@ async def provider( provider_type=ProviderType.TEXT_TO_SPEECH, umo=umo, ) - event.set_result(MessageEventResult().message(f"成功切换到 {id_}。")) + event.set_result(MessageEventResult().message(t("msg-092d9956", id_=id_))) elif idx == "stt": if idx2 is None: - event.set_result(MessageEventResult().message("请输入序号。")) + event.set_result(MessageEventResult().message(t("msg-f3d8988e"))) return if idx2 > len(self.context.get_all_stt_providers()) or idx2 < 1: - event.set_result(MessageEventResult().message("无效的提供商序号。")) + event.set_result(MessageEventResult().message(t("msg-284759bb"))) return provider = self.context.get_all_stt_providers()[idx2 - 1] id_ = provider.meta().id @@ -208,10 +209,10 @@ async def provider( provider_type=ProviderType.SPEECH_TO_TEXT, umo=umo, ) - event.set_result(MessageEventResult().message(f"成功切换到 {id_}。")) + event.set_result(MessageEventResult().message(t("msg-092d9956", id_=id_))) elif isinstance(idx, int): if idx > len(self.context.get_all_providers()) or idx < 1: - event.set_result(MessageEventResult().message("无效的提供商序号。")) + event.set_result(MessageEventResult().message(t("msg-284759bb"))) return provider = self.context.get_all_providers()[idx - 1] id_ = provider.meta().id @@ -220,9 +221,9 @@ async def provider( provider_type=ProviderType.CHAT_COMPLETION, umo=umo, ) - event.set_result(MessageEventResult().message(f"成功切换到 {id_}。")) + event.set_result(MessageEventResult().message(t("msg-092d9956", id_=id_))) else: - event.set_result(MessageEventResult().message("无效的参数。")) + event.set_result(MessageEventResult().message(t("msg-bf9eb668"))) async def model_ls( self, @@ -233,7 +234,7 @@ async def model_ls( prov = self.context.get_using_provider(message.unified_msg_origin) if not prov: message.set_result( - MessageEventResult().message("未找到任何 LLM 提供商。请先配置。"), + MessageEventResult().message(t("msg-4cdd042d")), ) return # 定义正则表达式匹配 API 密钥 @@ -262,7 +263,7 @@ async def model_ls( ) ret = "".join(parts) - message.set_result(MessageEventResult().message(ret).use_t2i(False)) + message.set_result(MessageEventResult().message(t("msg-ed8dcc22", ret=ret)).use_t2i(False)) elif isinstance(idx_or_name, int): models = [] try: @@ -273,7 +274,7 @@ async def model_ls( ) return if idx_or_name > len(models) or idx_or_name < 1: - message.set_result(MessageEventResult().message("模型序号错误。")) + message.set_result(MessageEventResult().message(t("msg-cb218e86"))) else: try: new_model = models[idx_or_name - 1] @@ -284,20 +285,20 @@ async def model_ls( ) message.set_result( MessageEventResult().message( - f"切换模型成功。当前提供商: [{prov.meta().id}] 当前模型: [{prov.get_model()}]", + t("msg-1756f199", res=prov.meta().id, res_2=prov.get_model()), ), ) else: prov.set_model(idx_or_name) message.set_result( - MessageEventResult().message(f"切换模型到 {prov.get_model()}。"), + MessageEventResult().message(t("msg-4d4f587f", res=prov.get_model())), ) async def key(self, message: AstrMessageEvent, index: int | None = None) -> None: prov = self.context.get_using_provider(message.unified_msg_origin) if not prov: message.set_result( - MessageEventResult().message("未找到任何 LLM 提供商。请先配置。"), + MessageEventResult().message(t("msg-4cdd042d")), ) return @@ -313,17 +314,17 @@ async def key(self, message: AstrMessageEvent, index: int | None = None) -> None parts.append("\n使用 /key 切换 Key。") ret = "".join(parts) - message.set_result(MessageEventResult().message(ret).use_t2i(False)) + message.set_result(MessageEventResult().message(t("msg-ed8dcc22", ret=ret)).use_t2i(False)) else: keys_data = prov.get_keys() if index > len(keys_data) or index < 1: - message.set_result(MessageEventResult().message("Key 序号错误。")) + message.set_result(MessageEventResult().message(t("msg-584ca956"))) else: try: new_key = keys_data[index - 1] prov.set_key(new_key) except BaseException as e: message.set_result( - MessageEventResult().message(f"切换 Key 未知错误: {e!s}"), + MessageEventResult().message(t("msg-f52481b8", e=e)), ) - message.set_result(MessageEventResult().message("切换 Key 成功。")) + message.set_result(MessageEventResult().message(t("msg-7a156524"))) diff --git a/astrbot/builtin_stars/builtin_commands/commands/setunset.py b/astrbot/builtin_stars/builtin_commands/commands/setunset.py index 096698844d..8942c8de16 100644 --- a/astrbot/builtin_stars/builtin_commands/commands/setunset.py +++ b/astrbot/builtin_stars/builtin_commands/commands/setunset.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t from astrbot.api import sp, star from astrbot.api.event import AstrMessageEvent, MessageEventResult @@ -15,7 +16,7 @@ async def set_variable(self, event: AstrMessageEvent, key: str, value: str) -> N event.set_result( MessageEventResult().message( - f"会话 {uid} 变量 {key} 存储成功。使用 /unset 移除。", + t("msg-8b56b437", uid=uid, key=key), ), ) @@ -26,11 +27,11 @@ async def unset_variable(self, event: AstrMessageEvent, key: str) -> None: if key not in session_var: event.set_result( - MessageEventResult().message("没有那个变量名。格式 /unset 变量名。"), + MessageEventResult().message(t("msg-dfd31d9d")), ) else: del session_var[key] await sp.session_put(uid, "session_variables", session_var) event.set_result( - MessageEventResult().message(f"会话 {uid} 变量 {key} 移除成功。"), + MessageEventResult().message(t("msg-bf181241", uid=uid, key=key)), ) diff --git a/astrbot/builtin_stars/builtin_commands/commands/sid.py b/astrbot/builtin_stars/builtin_commands/commands/sid.py index e8bdbffb19..7797359df3 100644 --- a/astrbot/builtin_stars/builtin_commands/commands/sid.py +++ b/astrbot/builtin_stars/builtin_commands/commands/sid.py @@ -1,4 +1,5 @@ """会话ID命令""" +from astrbot.core.lang import t from astrbot.api import star from astrbot.api.event import AstrMessageEvent, MessageEventResult @@ -33,4 +34,4 @@ async def sid(self, event: AstrMessageEvent) -> None: ): ret += f"\n\n当前处于独立会话模式, 此群 ID: 「{event.get_group_id()}」, 也可将此 ID 加入白名单来放行整个群聊。" - event.set_result(MessageEventResult().message(ret).use_t2i(False)) + event.set_result(MessageEventResult().message(t("msg-ed8dcc22", ret=ret)).use_t2i(False)) diff --git a/astrbot/builtin_stars/builtin_commands/commands/t2i.py b/astrbot/builtin_stars/builtin_commands/commands/t2i.py index 78d6b0df7b..b9a12224ce 100644 --- a/astrbot/builtin_stars/builtin_commands/commands/t2i.py +++ b/astrbot/builtin_stars/builtin_commands/commands/t2i.py @@ -1,4 +1,5 @@ """文本转图片命令""" +from astrbot.core.lang import t from astrbot.api import star from astrbot.api.event import AstrMessageEvent, MessageEventResult @@ -16,8 +17,8 @@ async def t2i(self, event: AstrMessageEvent) -> None: if config["t2i"]: config["t2i"] = False config.save_config() - event.set_result(MessageEventResult().message("已关闭文本转图片模式。")) + event.set_result(MessageEventResult().message(t("msg-855d5cf3"))) return config["t2i"] = True config.save_config() - event.set_result(MessageEventResult().message("已开启文本转图片模式。")) + event.set_result(MessageEventResult().message(t("msg-64da24f4"))) diff --git a/astrbot/builtin_stars/builtin_commands/commands/tts.py b/astrbot/builtin_stars/builtin_commands/commands/tts.py index 13049ac22e..193fe8022e 100644 --- a/astrbot/builtin_stars/builtin_commands/commands/tts.py +++ b/astrbot/builtin_stars/builtin_commands/commands/tts.py @@ -1,4 +1,5 @@ """文本转语音命令""" +from astrbot.core.lang import t from astrbot.api import star from astrbot.api.event import AstrMessageEvent, MessageEventResult @@ -27,10 +28,10 @@ async def tts(self, event: AstrMessageEvent) -> None: if new_status and not tts_enable: event.set_result( MessageEventResult().message( - f"{status_text}当前会话的文本转语音。但 TTS 功能在配置中未启用,请前往 WebUI 开启。", + t("msg-ef1b2145", status_text=status_text), ), ) else: event.set_result( - MessageEventResult().message(f"{status_text}当前会话的文本转语音。"), + MessageEventResult().message(t("msg-deee9deb", status_text=status_text)), ) diff --git a/astrbot/builtin_stars/session_controller/main.py b/astrbot/builtin_stars/session_controller/main.py index 70081e03a6..e522fbb09b 100644 --- a/astrbot/builtin_stars/session_controller/main.py +++ b/astrbot/builtin_stars/session_controller/main.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import copy from sys import maxsize @@ -82,7 +83,7 @@ async def handle_empty_mention(self, event: AstrMessageEvent): conversation=conversation, ) except Exception as e: - logger.error(f"LLM response failed: {e!s}") + logger.error(t("msg-b48bf3fe", e=e)) # LLM 回复失败,使用原始预设回复 yield event.plain_result("想要问什么呢?😄") diff --git a/astrbot/builtin_stars/web_searcher/engines/bing.py b/astrbot/builtin_stars/web_searcher/engines/bing.py index 7565e5df36..9087599648 100644 --- a/astrbot/builtin_stars/web_searcher/engines/bing.py +++ b/astrbot/builtin_stars/web_searcher/engines/bing.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t from . import USER_AGENT_BING, SearchEngine @@ -27,4 +28,4 @@ async def _get_next_page(self, query) -> str: except Exception as _: self.base_url = base_url continue - raise Exception("Bing search failed") + raise Exception(t("msg-e3b4d1e9")) diff --git a/astrbot/builtin_stars/web_searcher/main.py b/astrbot/builtin_stars/web_searcher/main.py index d2c171a925..ccce8958b6 100644 --- a/astrbot/builtin_stars/web_searcher/main.py +++ b/astrbot/builtin_stars/web_searcher/main.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import json import random @@ -41,7 +42,7 @@ def __init__(self, context: star.Context) -> None: tavily_key = provider_settings.get("websearch_tavily_key") if isinstance(tavily_key, str): logger.info( - "检测到旧版 websearch_tavily_key (字符串格式),自动迁移为列表格式并保存。", + t("msg-7f5fd92b"), ) if tavily_key: provider_settings["websearch_tavily_key"] = [tavily_key] @@ -85,7 +86,7 @@ async def _process_search_result( websearch_link: bool, ) -> str: """处理单个搜索结果""" - logger.info(f"web_searcher - scraping web: {result.title} - {result.url}") + logger.info(t("msg-bed9def5", res=result.title, res_2=result.url)) try: site_result = await self._get_from_url(result.url) except BaseException: @@ -110,15 +111,15 @@ async def _web_search_default( try: results = await self.bing_search.search(query, num_results) except Exception as e: - logger.error(f"bing search error: {e}, try the next one...") + logger.error(t("msg-8214760c", e=e)) if len(results) == 0: - logger.debug("search bing failed") + logger.debug(t("msg-8676b5aa")) try: results = await self.sogo_search.search(query, num_results) except Exception as e: - logger.error(f"sogo search error: {e}") + logger.error(t("msg-3fb6d6ad", e=e)) if len(results) == 0: - logger.debug("search sogo failed") + logger.debug(t("msg-fe9b336f")) return [] return results @@ -127,7 +128,7 @@ async def _get_tavily_key(self, cfg: AstrBotConfig) -> str: """并发安全的从列表中获取并轮换Tavily API密钥。""" tavily_keys = cfg.get("provider_settings", {}).get("websearch_tavily_key", []) if not tavily_keys: - raise ValueError("错误:Tavily API密钥未在AstrBot中配置。") + raise ValueError(t("msg-c991b022")) async with self.tavily_key_lock: key = tavily_keys[self.tavily_key_index] @@ -155,7 +156,7 @@ async def _web_search_tavily( if response.status != 200: reason = await response.text() raise Exception( - f"Tavily web search failed: {reason}, status: {response.status}", + t("msg-b4fbb4a9", reason=reason, res=response.status), ) data = await response.json() results = [] @@ -186,13 +187,13 @@ async def _extract_tavily(self, cfg: AstrBotConfig, payload: dict) -> list[dict] if response.status != 200: reason = await response.text() raise Exception( - f"Tavily web search failed: {reason}, status: {response.status}", + t("msg-b4fbb4a9", reason=reason, res=response.status), ) data = await response.json() results: list[dict] = data.get("results", []) if not results: raise ValueError( - "Error: Tavily web searcher does not return any results.", + t("msg-6769aba9"), ) return results @@ -201,7 +202,7 @@ async def websearch(self, event: AstrMessageEvent, oper: str | None = None) -> N """网页搜索指令(已废弃)""" event.set_result( MessageEventResult().message( - "此指令已经被废弃,请在 WebUI 中开启或关闭网页搜索功能。", + t("msg-b4e7334e"), ), ) @@ -219,7 +220,7 @@ async def search_from_search_engine( max_results(number): 返回的最大搜索结果数量,默认为 5。 """ - logger.info(f"web_searcher - search_from_search_engine: {query}") + logger.info(t("msg-b1877974", query=query)) cfg = self.context.get_config(umo=event.unified_msg_origin) websearch_link = cfg["provider_settings"].get("web_search_link", False) @@ -235,7 +236,7 @@ async def search_from_search_engine( ret = "" for processed_result in processed_results: if isinstance(processed_result, BaseException): - logger.error(f"Error processing search result: {processed_result}") + logger.error(t("msg-2360df6b", processed_result=processed_result)) continue ret += processed_result @@ -254,7 +255,7 @@ async def ensure_baidu_ai_search_mcp(self, umo: str | None = None) -> None: ) if not key: raise ValueError( - "Error: Baidu AI Search API key is not configured in AstrBot.", + t("msg-359d0443"), ) func_tool_mgr = self.context.get_llm_tool_manager() await func_tool_mgr.enable_mcp_server( @@ -267,7 +268,7 @@ async def ensure_baidu_ai_search_mcp(self, umo: str | None = None) -> None: }, ) self.baidu_initialized = True - logger.info("Successfully initialized Baidu AI Search MCP server.") + logger.info(t("msg-94351632")) @llm_tool(name="fetch_url") async def fetch_website_content(self, event: AstrMessageEvent, url: str) -> str: @@ -307,11 +308,11 @@ async def search_from_tavily( end_date(string): Optional. The end date for the search results in the format 'YYYY-MM-DD'. """ - logger.info(f"web_searcher - search_from_tavily: {query}") + logger.info(t("msg-5a7207c1", query=query)) cfg = self.context.get_config(umo=event.unified_msg_origin) # websearch_link = cfg["provider_settings"].get("web_search_link", False) if not cfg.get("provider_settings", {}).get("websearch_tavily_key", []): - raise ValueError("Error: Tavily API key is not configured in AstrBot.") + raise ValueError(t("msg-b36134c9")) # build payload payload = {"query": query, "max_results": max_results, "include_favicon": True} @@ -372,10 +373,10 @@ async def tavily_extract_web_page( """ cfg = self.context.get_config(umo=event.unified_msg_origin) if not cfg.get("provider_settings", {}).get("websearch_tavily_key", []): - raise ValueError("Error: Tavily API key is not configured in AstrBot.") + raise ValueError(t("msg-b36134c9")) if not url: - raise ValueError("Error: url must be a non-empty string.") + raise ValueError(t("msg-98ed69f4")) if extract_depth not in ["basic", "advanced"]: extract_depth = "basic" payload = { @@ -396,7 +397,7 @@ async def _get_bocha_key(self, cfg: AstrBotConfig) -> str: """并发安全的从列表中获取并轮换BoCha API密钥。""" bocha_keys = cfg.get("provider_settings", {}).get("websearch_bocha_key", []) if not bocha_keys: - raise ValueError("错误:BoCha API密钥未在AstrBot中配置。") + raise ValueError(t("msg-51edd9ee")) async with self.bocha_key_lock: key = bocha_keys[self.bocha_key_index] @@ -424,7 +425,7 @@ async def _web_search_bocha( if response.status != 200: reason = await response.text() raise Exception( - f"BoCha web search failed: {reason}, status: {response.status}", + t("msg-73964067", reason=reason, res=response.status), ) data = await response.json() data = data["data"]["webPages"]["value"] @@ -497,11 +498,11 @@ async def search_from_bocha( The actual number of returned results may be less than the specified count. """ - logger.info(f"web_searcher - search_from_bocha: {query}") + logger.info(t("msg-34417720", query=query)) cfg = self.context.get_config(umo=event.unified_msg_origin) # websearch_link = cfg["provider_settings"].get("web_search_link", False) if not cfg.get("provider_settings", {}).get("websearch_bocha_key", []): - raise ValueError("Error: BoCha API key is not configured in AstrBot.") + raise ValueError(t("msg-b798883b")) # build payload payload = { @@ -600,7 +601,7 @@ async def edit_web_search_tools( await self.ensure_baidu_ai_search_mcp(event.unified_msg_origin) aisearch_tool = func_tool_mgr.get_func("AIsearch") if not aisearch_tool: - raise ValueError("Cannot get Baidu AI Search MCP tool.") + raise ValueError(t("msg-22993708")) tool_set.add_tool(aisearch_tool) tool_set.remove_tool("web_search") tool_set.remove_tool("fetch_url") @@ -608,7 +609,7 @@ async def edit_web_search_tools( tool_set.remove_tool("tavily_extract_web_page") tool_set.remove_tool("web_search_bocha") except Exception as e: - logger.error(f"Cannot Initialize Baidu AI Search MCP Server: {e}") + logger.error(t("msg-6f8d62a4", e=e)) elif provider == "bocha": web_search_bocha = func_tool_mgr.get_func("web_search_bocha") if web_search_bocha: diff --git a/astrbot/cli/__main__.py b/astrbot/cli/__main__.py index 40c46de79d..21ac1b562b 100644 --- a/astrbot/cli/__main__.py +++ b/astrbot/cli/__main__.py @@ -1,4 +1,5 @@ """AstrBot CLI入口""" +from astrbot.core.lang import t import sys @@ -21,9 +22,9 @@ @click.version_option(__version__, prog_name="AstrBot") def cli() -> None: """The AstrBot CLI""" - click.echo(logo_tmpl) - click.echo("Welcome to AstrBot CLI!") - click.echo(f"AstrBot CLI version: {__version__}") + click.echo(t("msg-fe494da6", logo_tmpl=logo_tmpl)) + click.echo(t("msg-c8b2ff67")) + click.echo(t("msg-d79e1ff9", __version__=__version__)) @click.command() @@ -40,13 +41,13 @@ def help(command_name: str | None) -> None: command = cli.get_command(ctx, command_name) if command: # 显示特定命令的帮助信息 - click.echo(command.get_help(ctx)) + click.echo(t("msg-78b9c276", res=command.get_help(ctx))) else: - click.echo(f"Unknown command: {command_name}") + click.echo(t("msg-14dd710d", command_name=command_name)) sys.exit(1) else: # 显示通用帮助信息 - click.echo(cli.get_help(ctx)) + click.echo(t("msg-78b9c276", res=cli.get_help(ctx))) cli.add_command(init) diff --git a/astrbot/cli/commands/cmd_conf.py b/astrbot/cli/commands/cmd_conf.py index 703c9b8995..46ada7241c 100644 --- a/astrbot/cli/commands/cmd_conf.py +++ b/astrbot/cli/commands/cmd_conf.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import hashlib import json import zoneinfo @@ -14,7 +15,7 @@ def _validate_log_level(value: str) -> str: value = value.upper() if value not in ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]: raise click.ClickException( - "日志级别必须是 DEBUG/INFO/WARNING/ERROR/CRITICAL 之一", + t("msg-635b8763"), ) return value @@ -24,23 +25,23 @@ def _validate_dashboard_port(value: str) -> int: try: port = int(value) if port < 1 or port > 65535: - raise click.ClickException("端口必须在 1-65535 范围内") + raise click.ClickException(t("msg-ebc250dc")) return port except ValueError: - raise click.ClickException("端口必须是数字") + raise click.ClickException(t("msg-6ec400b6")) def _validate_dashboard_username(value: str) -> str: """验证 Dashboard 用户名""" if not value: - raise click.ClickException("用户名不能为空") + raise click.ClickException(t("msg-0b62b5ce")) return value def _validate_dashboard_password(value: str) -> str: """验证 Dashboard 密码""" if not value: - raise click.ClickException("密码不能为空") + raise click.ClickException(t("msg-89b5d3d5")) return hashlib.md5(value.encode()).hexdigest() @@ -49,14 +50,14 @@ def _validate_timezone(value: str) -> str: try: zoneinfo.ZoneInfo(value) except Exception: - raise click.ClickException(f"无效的时区: {value},请使用有效的IANA时区名称") + raise click.ClickException(t("msg-92e7c8ad", value=value)) return value def _validate_callback_api_base(value: str) -> str: """验证回调接口基址""" if not value.startswith("http://") and not value.startswith("https://"): - raise click.ClickException("回调接口基址必须以 http:// 或 https:// 开头") + raise click.ClickException(t("msg-e470e37d")) return value @@ -76,7 +77,7 @@ def _load_config() -> dict[str, Any]: root = get_astrbot_root() if not check_astrbot_root(root): raise click.ClickException( - f"{root}不是有效的 AstrBot 根目录,如需初始化请使用 astrbot init", + t("msg-6b615721", root=root), ) config_path = root / "data" / "cmd_config.json" @@ -91,7 +92,7 @@ def _load_config() -> dict[str, Any]: try: return json.loads(config_path.read_text(encoding="utf-8-sig")) except json.JSONDecodeError as e: - raise click.ClickException(f"配置文件解析失败: {e!s}") + raise click.ClickException(t("msg-f74c517c", e=e)) def _save_config(config: dict[str, Any]) -> None: @@ -112,7 +113,7 @@ def _set_nested_item(obj: dict[str, Any], path: str, value: Any) -> None: obj[part] = {} elif not isinstance(obj[part], dict): raise click.ClickException( - f"配置路径冲突: {'.'.join(parts[: parts.index(part) + 1])} 不是字典", + t("msg-d7c58bcc", res='.'.join(parts[:parts.index(part) + 1])), ) obj = obj[part] obj[parts[-1]] = value @@ -152,7 +153,7 @@ def conf() -> None: def set_config(key: str, value: str) -> None: """设置配置项的值""" if key not in CONFIG_VALIDATORS: - raise click.ClickException(f"不支持的配置项: {key}") + raise click.ClickException(t("msg-e16816cc", key=key)) config = _load_config() @@ -162,18 +163,18 @@ def set_config(key: str, value: str) -> None: _set_nested_item(config, key, validated_value) _save_config(config) - click.echo(f"配置已更新: {key}") + click.echo(t("msg-e9cce750", key=key)) if key == "dashboard.password": - click.echo(" 原值: ********") - click.echo(" 新值: ********") + click.echo(t("msg-1ed565aa")) + click.echo(t("msg-1bf9569a")) else: - click.echo(f" 原值: {old_value}") - click.echo(f" 新值: {validated_value}") + click.echo(t("msg-f2a20ab3", old_value=old_value)) + click.echo(t("msg-0c104905", validated_value=validated_value)) except KeyError: - raise click.ClickException(f"未知的配置项: {key}") + raise click.ClickException(t("msg-ea9b4e2c", key=key)) except Exception as e: - raise click.UsageError(f"设置配置失败: {e!s}") + raise click.UsageError(t("msg-4450e3b1", e=e)) @conf.command(name="get") @@ -184,19 +185,19 @@ def get_config(key: str | None = None) -> None: if key: if key not in CONFIG_VALIDATORS: - raise click.ClickException(f"不支持的配置项: {key}") + raise click.ClickException(t("msg-e16816cc", key=key)) try: value = _get_nested_item(config, key) if key == "dashboard.password": value = "********" - click.echo(f"{key}: {value}") + click.echo(t("msg-ba464bee", key=key, value=value)) except KeyError: - raise click.ClickException(f"未知的配置项: {key}") + raise click.ClickException(t("msg-ea9b4e2c", key=key)) except Exception as e: - raise click.UsageError(f"获取配置失败: {e!s}") + raise click.UsageError(t("msg-72aab576", e=e)) else: - click.echo("当前配置:") + click.echo(t("msg-c1693d1d")) for key in CONFIG_VALIDATORS: try: value = ( @@ -204,6 +205,6 @@ def get_config(key: str | None = None) -> None: if key == "dashboard.password" else _get_nested_item(config, key) ) - click.echo(f" {key}: {value}") + click.echo(t("msg-50be9b74", key=key, value=value)) except (KeyError, TypeError): pass diff --git a/astrbot/cli/commands/cmd_init.py b/astrbot/cli/commands/cmd_init.py index 6c0c34b99c..d4bbc92ab1 100644 --- a/astrbot/cli/commands/cmd_init.py +++ b/astrbot/cli/commands/cmd_init.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio from pathlib import Path @@ -12,9 +13,9 @@ async def initialize_astrbot(astrbot_root: Path) -> None: dot_astrbot = astrbot_root / ".astrbot" if not dot_astrbot.exists(): - click.echo(f"Current Directory: {astrbot_root}") + click.echo(t("msg-a90a250e", astrbot_root=astrbot_root)) click.echo( - "如果你确认这是 Astrbot root directory, 你需要在当前目录下创建一个 .astrbot 文件标记该目录为 AstrBot 的数据目录。", + t("msg-4deda62e"), ) if click.confirm( f"请检查当前目录是否正确,确认正确请回车: {astrbot_root}", @@ -22,7 +23,7 @@ async def initialize_astrbot(astrbot_root: Path) -> None: abort=True, ): dot_astrbot.touch() - click.echo(f"Created {dot_astrbot}") + click.echo(t("msg-3319bf71", dot_astrbot=dot_astrbot)) paths = { "data": astrbot_root / "data", @@ -33,7 +34,7 @@ async def initialize_astrbot(astrbot_root: Path) -> None: for name, path in paths.items(): path.mkdir(parents=True, exist_ok=True) - click.echo(f"{'Created' if not path.exists() else 'Directory exists'}: {path}") + click.echo(t("msg-7054f44f", res='Created' if not path.exists() else 'Directory exists', path=path)) await check_dashboard(astrbot_root / "data") @@ -41,7 +42,7 @@ async def initialize_astrbot(astrbot_root: Path) -> None: @click.command() def init() -> None: """初始化 AstrBot""" - click.echo("Initializing AstrBot...") + click.echo(t("msg-b19edc8a")) astrbot_root = get_astrbot_root() lock_file = astrbot_root / "astrbot.lock" lock = FileLock(lock_file, timeout=5) @@ -50,7 +51,7 @@ def init() -> None: with lock.acquire(): asyncio.run(initialize_astrbot(astrbot_root)) except Timeout: - raise click.ClickException("无法获取锁文件,请检查是否有其他实例正在运行") + raise click.ClickException(t("msg-eebc39e3")) except Exception as e: - raise click.ClickException(f"初始化失败: {e!s}") + raise click.ClickException(t("msg-e16da80f", e=e)) diff --git a/astrbot/cli/commands/cmd_plug.py b/astrbot/cli/commands/cmd_plug.py index 9cf94365af..d8e497360a 100644 --- a/astrbot/cli/commands/cmd_plug.py +++ b/astrbot/cli/commands/cmd_plug.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import re import shutil from pathlib import Path @@ -23,23 +24,22 @@ def _get_data_path() -> Path: base = get_astrbot_root() if not check_astrbot_root(base): raise click.ClickException( - f"{base}不是有效的 AstrBot 根目录,如需初始化请使用 astrbot init", + t("msg-cbd8802b", base=base), ) return (base / "data").resolve() def display_plugins(plugins, title=None, color=None) -> None: if title: - click.echo(click.style(title, fg=color, bold=True)) + click.echo(t("msg-78b9c276", res=click.style(title, fg=color, bold=True))) - click.echo(f"{'名称':<20} {'版本':<10} {'状态':<10} {'作者':<15} {'描述':<30}") + click.echo(t("msg-83664fcf", val='名称')) click.echo("-" * 85) for p in plugins: desc = p["desc"][:30] + ("..." if len(p["desc"]) > 30 else "") click.echo( - f"{p['name']:<20} {p['version']:<10} {p['status']:<10} " - f"{p['author']:<15} {desc:<30}", + t("msg-56f3f0bf", res=p['name'], res_2=p['version'], res_3=p['status'], res_4=p['author'], desc=desc), ) @@ -51,24 +51,24 @@ def new(name: str) -> None: plug_path = base_path / "plugins" / name if plug_path.exists(): - raise click.ClickException(f"插件 {name} 已存在") + raise click.ClickException(t("msg-1d802ff2", name=name)) author = click.prompt("请输入插件作者", type=str) desc = click.prompt("请输入插件描述", type=str) version = click.prompt("请输入插件版本", type=str) if not re.match(r"^\d+\.\d+(\.\d+)?$", version.lower().lstrip("v")): - raise click.ClickException("版本号必须为 x.y 或 x.y.z 格式") + raise click.ClickException(t("msg-a7be9d23")) repo = click.prompt("请输入插件仓库:", type=str) if not repo.startswith("http"): - raise click.ClickException("仓库地址必须以 http 开头") + raise click.ClickException(t("msg-4d81299b")) - click.echo("下载插件模板...") + click.echo(t("msg-93289755")) get_git_repo( "https://github.com/Soulter/helloworld", plug_path, ) - click.echo("重写插件信息...") + click.echo(t("msg-b21682dd")) # 重写 metadata.yaml with open(plug_path / "metadata.yaml", "w", encoding="utf-8") as f: f.write( @@ -95,7 +95,7 @@ def new(name: str) -> None: with open(plug_path / "main.py", "w", encoding="utf-8") as f: f.write(new_content) - click.echo(f"插件 {name} 创建成功") + click.echo(t("msg-bffc8bfa", name=name)) @plug.command() @@ -135,7 +135,7 @@ def list(all: bool) -> None: not any([not_published_plugins, need_update_plugins, installed_plugins]) and not all ): - click.echo("未安装任何插件") + click.echo(t("msg-08eae1e3")) @plug.command() @@ -157,7 +157,7 @@ def install(name: str, proxy: str | None) -> None: ) if not plugin: - raise click.ClickException(f"未找到可安装的插件 {name},可能是不存在或已安装") + raise click.ClickException(t("msg-1a021bf4", name=name)) manage_plugin(plugin, plug_path, is_update=False, proxy=proxy) @@ -171,7 +171,7 @@ def remove(name: str) -> None: plugin = next((p for p in plugins if p["name"] == name), None) if not plugin or not plugin.get("local_path"): - raise click.ClickException(f"插件 {name} 不存在或未安装") + raise click.ClickException(t("msg-c120bafd", name=name)) plugin_path = plugin["local_path"] @@ -179,9 +179,9 @@ def remove(name: str) -> None: try: shutil.rmtree(plugin_path) - click.echo(f"插件 {name} 已卸载") + click.echo(t("msg-63da4867", name=name)) except Exception as e: - raise click.ClickException(f"卸载插件 {name} 失败: {e}") + raise click.ClickException(t("msg-e4925708", name=name, e=e)) @plug.command() @@ -204,7 +204,7 @@ def update(name: str, proxy: str | None) -> None: ) if not plugin: - raise click.ClickException(f"插件 {name} 不需要更新或无法更新") + raise click.ClickException(t("msg-f4d15a87", name=name)) manage_plugin(plugin, plug_path, is_update=True, proxy=proxy) else: @@ -213,13 +213,13 @@ def update(name: str, proxy: str | None) -> None: ] if not need_update_plugins: - click.echo("没有需要更新的插件") + click.echo(t("msg-94b035f7")) return - click.echo(f"发现 {len(need_update_plugins)} 个插件需要更新") + click.echo(t("msg-0766d599", res=len(need_update_plugins))) for plugin in need_update_plugins: plugin_name = plugin["name"] - click.echo(f"正在更新插件 {plugin_name}...") + click.echo(t("msg-bd5ab99c", plugin_name=plugin_name)) manage_plugin(plugin, plug_path, is_update=True, proxy=proxy) @@ -239,7 +239,7 @@ def search(query: str) -> None: ] if not matched_plugins: - click.echo(f"未找到匹配 '{query}' 的插件") + click.echo(t("msg-e32912b8", query=query)) return display_plugins(matched_plugins, f"搜索结果: '{query}'", "cyan") diff --git a/astrbot/cli/commands/cmd_run.py b/astrbot/cli/commands/cmd_run.py index 23665dff3d..68a5a7262f 100644 --- a/astrbot/cli/commands/cmd_run.py +++ b/astrbot/cli/commands/cmd_run.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import os import sys @@ -37,7 +38,7 @@ def run(reload: bool, port: str) -> None: if not check_astrbot_root(astrbot_root): raise click.ClickException( - f"{astrbot_root}不是有效的 AstrBot 根目录,如需初始化请使用 astrbot init", + t("msg-41ecc632", astrbot_root=astrbot_root), ) os.environ["ASTRBOT_ROOT"] = str(astrbot_root) @@ -47,7 +48,7 @@ def run(reload: bool, port: str) -> None: os.environ["DASHBOARD_PORT"] = port if reload: - click.echo("启用插件自动重载") + click.echo(t("msg-0ccaca23")) os.environ["ASTRBOT_RELOAD"] = "1" lock_file = astrbot_root / "astrbot.lock" @@ -55,8 +56,8 @@ def run(reload: bool, port: str) -> None: with lock.acquire(): asyncio.run(run_astrbot(astrbot_root)) except KeyboardInterrupt: - click.echo("AstrBot 已关闭...") + click.echo(t("msg-220914e7")) except Timeout: - raise click.ClickException("无法获取锁文件,请检查是否有其他实例正在运行") + raise click.ClickException(t("msg-eebc39e3")) except Exception as e: - raise click.ClickException(f"运行时出现错误: {e}\n{traceback.format_exc()}") + raise click.ClickException(t("msg-85f241d3", e=e, res=traceback.format_exc())) diff --git a/astrbot/cli/utils/basic.py b/astrbot/cli/utils/basic.py index 5dbe290065..048a8d8cb5 100644 --- a/astrbot/cli/utils/basic.py +++ b/astrbot/cli/utils/basic.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t from pathlib import Path import click @@ -30,28 +31,28 @@ async def check_dashboard(astrbot_root: Path) -> None: dashboard_version = await get_dashboard_version() match dashboard_version: case None: - click.echo("未安装管理面板") + click.echo(t("msg-f4e0fd7b")) if click.confirm( "是否安装管理面板?", default=True, abort=True, ): - click.echo("正在安装管理面板...") + click.echo(t("msg-2d090cc3")) await download_dashboard( path="data/dashboard.zip", extract_path=str(astrbot_root), version=f"v{VERSION}", latest=False, ) - click.echo("管理面板安装完成") + click.echo(t("msg-2eeb67e0")) case str(): if VersionComparator.compare_version(VERSION, dashboard_version) <= 0: - click.echo("管理面板已是最新版本") + click.echo(t("msg-9c727dca")) return try: version = dashboard_version.split("v")[1] - click.echo(f"管理面板版本: {version}") + click.echo(t("msg-11b49913", version=version)) await download_dashboard( path="data/dashboard.zip", extract_path=str(astrbot_root), @@ -59,10 +60,10 @@ async def check_dashboard(astrbot_root: Path) -> None: latest=False, ) except Exception as e: - click.echo(f"下载管理面板失败: {e}") + click.echo(t("msg-f0b6145e", e=e)) return except FileNotFoundError: - click.echo("初始化管理面板目录...") + click.echo(t("msg-9504d173")) try: await download_dashboard( path=str(astrbot_root / "dashboard.zip"), @@ -70,7 +71,7 @@ async def check_dashboard(astrbot_root: Path) -> None: version=f"v{VERSION}", latest=False, ) - click.echo("管理面板初始化完成") + click.echo(t("msg-699e2509")) except Exception as e: - click.echo(f"下载管理面板失败: {e}") + click.echo(t("msg-f0b6145e", e=e)) return diff --git a/astrbot/cli/utils/plugin.py b/astrbot/cli/utils/plugin.py index 81f59e0bfc..9809a40c99 100644 --- a/astrbot/cli/utils/plugin.py +++ b/astrbot/cli/utils/plugin.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import shutil import tempfile from enum import Enum @@ -44,10 +45,10 @@ def get_git_repo(url: str, target_path: Path, proxy: str | None = None) -> None: download_url = releases[0]["zipball_url"] else: # 没有 release,使用默认分支 - click.echo(f"正在从默认分支下载 {author}/{repo}") + click.echo(t("msg-e327bc14", author=author, repo=repo)) download_url = f"https://github.com/{author}/{repo}/archive/refs/heads/master.zip" except Exception as e: - click.echo(f"获取 release 信息失败: {e},将直接使用提供的 URL") + click.echo(t("msg-c804f59f", e=e)) download_url = url # 应用代理 @@ -65,7 +66,7 @@ def get_git_repo(url: str, target_path: Path, proxy: str | None = None) -> None: and "archive/refs/heads/master.zip" in download_url ): alt_url = download_url.replace("master.zip", "main.zip") - click.echo("master 分支不存在,尝试下载 main 分支") + click.echo(t("msg-aa398bd5")) resp = client.get(alt_url) resp.raise_for_status() else: @@ -98,7 +99,7 @@ def load_yaml_metadata(plugin_dir: Path) -> dict: try: return yaml.safe_load(yaml_path.read_text(encoding="utf-8")) or {} except Exception as e: - click.echo(f"读取 {yaml_path} 失败: {e}", err=True) + click.echo(t("msg-5587d9fb", yaml_path=yaml_path, e=e), err=True) return {} @@ -160,7 +161,7 @@ def build_plug_list(plugins_dir: Path) -> list: }, ) except Exception as e: - click.echo(f"获取在线插件列表失败: {e}", err=True) + click.echo(t("msg-8dbce791", e=e), err=True) # 与在线插件比对,更新状态 online_plugin_names = {plugin["name"] for plugin in online_plugins} @@ -218,7 +219,7 @@ def manage_plugin( # 检查插件是否存在 if is_update and not target_path.exists(): - raise click.ClickException(f"插件 {plugin_name} 未安装,无法更新") + raise click.ClickException(t("msg-6999155d", plugin_name=plugin_name)) # 备份现有插件 if is_update and backup_path is not None and backup_path.exists(): @@ -228,19 +229,19 @@ def manage_plugin( try: click.echo( - f"正在从 {repo_url} {'更新' if is_update else '下载'}插件 {plugin_name}...", + t("msg-fa5e129a", repo_url=repo_url, res='更新' if is_update else '下载', plugin_name=plugin_name), ) get_git_repo(repo_url, target_path, proxy) # 更新成功,删除备份 if is_update and backup_path is not None and backup_path.exists(): shutil.rmtree(backup_path) - click.echo(f"插件 {plugin_name} {'更新' if is_update else '安装'}成功") + click.echo(t("msg-9ac1f4db", plugin_name=plugin_name, res='更新' if is_update else '安装')) except Exception as e: if target_path.exists(): shutil.rmtree(target_path, ignore_errors=True) if is_update and backup_path is not None and backup_path.exists(): shutil.move(backup_path, target_path) raise click.ClickException( - f"{'更新' if is_update else '安装'}插件 {plugin_name} 时出错: {e}", + t("msg-b9c719ae", res='更新' if is_update else '安装', plugin_name=plugin_name, e=e), ) diff --git a/astrbot/core/agent/context/compressor.py b/astrbot/core/agent/context/compressor.py index 31a0b0b48d..c07da26a44 100644 --- a/astrbot/core/agent/context/compressor.py +++ b/astrbot/core/agent/context/compressor.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t from typing import TYPE_CHECKING, Protocol, runtime_checkable from ..message import Message @@ -220,7 +221,7 @@ async def __call__(self, messages: list[Message]) -> list[Message]: response = await self.provider.text_chat(contexts=llm_payload) summary_content = response.completion_text except Exception as e: - logger.error(f"Failed to generate summary: {e}") + logger.error(t("msg-6c75531b", e=e)) return messages # build result diff --git a/astrbot/core/agent/context/manager.py b/astrbot/core/agent/context/manager.py index 216a3e7e15..30cc5434de 100644 --- a/astrbot/core/agent/context/manager.py +++ b/astrbot/core/agent/context/manager.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t from astrbot import logger from ..message import Message @@ -76,7 +77,7 @@ async def process( return result except Exception as e: - logger.error(f"Error during context processing: {e}", exc_info=True) + logger.error(t("msg-59241964", e=e), exc_info=True) return messages async def _run_compression( @@ -92,7 +93,7 @@ async def _run_compression( Returns: The compressed/truncated message list. """ - logger.debug("Compress triggered, starting compression...") + logger.debug(t("msg-a0d672dc")) messages = await self.compressor(messages) @@ -102,9 +103,7 @@ async def _run_compression( # calculate compress rate compress_rate = (tokens_after_summary / self.config.max_context_tokens) * 100 logger.info( - f"Compress completed." - f" {prev_tokens} -> {tokens_after_summary} tokens," - f" compression rate: {compress_rate:.2f}%.", + t("msg-e6ef66f0", prev_tokens=prev_tokens, tokens_after_summary=tokens_after_summary, compress_rate=compress_rate), ) # last check @@ -112,7 +111,7 @@ async def _run_compression( messages, tokens_after_summary, self.config.max_context_tokens ): logger.info( - "Context still exceeds max tokens after compression, applying halving truncation..." + t("msg-3fe644eb") ) # still need compress, truncate by half messages = self.truncator.truncate_by_halving(messages) diff --git a/astrbot/core/agent/mcp_client.py b/astrbot/core/agent/mcp_client.py index 18f4d47e04..7ba6c2b60a 100644 --- a/astrbot/core/agent/mcp_client.py +++ b/astrbot/core/agent/mcp_client.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import logging from contextlib import AsyncExitStack @@ -25,14 +26,14 @@ from mcp.client.sse import sse_client except (ModuleNotFoundError, ImportError): logger.warning( - "Warning: Missing 'mcp' dependency, MCP services will be unavailable." + t("msg-6a61ca88") ) try: from mcp.client.streamable_http import streamablehttp_client except (ModuleNotFoundError, ImportError): logger.warning( - "Warning: Missing 'mcp' dependency or MCP library version too old, Streamable HTTP connection unavailable.", + t("msg-45995cdb"), ) @@ -61,7 +62,7 @@ async def _quick_test_mcp_connection(config: dict) -> tuple[bool, str]: elif "type" in cfg: transport_type = cfg["type"] else: - raise Exception("MCP connection config missing transport or type field") + raise Exception(t("msg-2866b896")) async with aiohttp.ClientSession() as session: if transport_type == "streamable_http": @@ -146,20 +147,20 @@ async def connect_to_server(self, mcp_server_config: dict, name: str) -> None: def logging_callback(msg: str) -> None: # Handle MCP service error logs - print(f"MCP Server {name} Error: {msg}") + print(t("msg-3bf7776b", name=name, msg=msg)) self.server_errlogs.append(msg) if "url" in cfg: success, error_msg = await _quick_test_mcp_connection(cfg) if not success: - raise Exception(error_msg) + raise Exception(t("msg-10f72727", error_msg=error_msg)) if "transport" in cfg: transport_type = cfg["transport"] elif "type" in cfg: transport_type = cfg["type"] else: - raise Exception("MCP connection config missing transport or type field") + raise Exception(t("msg-2866b896")) if transport_type != "streamable_http": # SSE transport method @@ -239,7 +240,7 @@ def callback(msg: str) -> None: async def list_tools_and_save(self) -> mcp.ListToolsResult: """List all tools from the server and save them to self.tools""" if not self.session: - raise Exception("MCP Client is not initialized") + raise Exception(t("msg-19c9b509")) response = await self.session.list_tools() self.tools = response.tools return response @@ -256,17 +257,17 @@ async def _reconnect(self) -> None: # Check if already reconnecting (useful for logging) if self._reconnecting: logger.debug( - f"MCP Client {self._server_name} is already reconnecting, skipping" + t("msg-5b9b4918", res=self._server_name) ) return if not self._mcp_server_config or not self._server_name: - raise Exception("Cannot reconnect: missing connection configuration") + raise Exception(t("msg-c1008866")) self._reconnecting = True try: logger.info( - f"Attempting to reconnect to MCP server {self._server_name}..." + t("msg-7c3fe178", res=self._server_name) ) # Save old exit_stack for later cleanup (don't close it now to avoid cancel scope issues) @@ -284,11 +285,11 @@ async def _reconnect(self) -> None: await self.list_tools_and_save() logger.info( - f"Successfully reconnected to MCP server {self._server_name}" + t("msg-783f3b85", res=self._server_name) ) except Exception as e: logger.error( - f"Failed to reconnect to MCP server {self._server_name}: {e}" + t("msg-da7361ff", res=self._server_name, e=e) ) raise finally: @@ -324,7 +325,7 @@ async def call_tool_with_reconnect( ) async def _call_with_retry(): if not self.session: - raise ValueError("MCP session is not available for MCP function tools.") + raise ValueError(t("msg-c0fd612e")) try: return await self.session.call_tool( @@ -334,7 +335,7 @@ async def _call_with_retry(): ) except anyio.ClosedResourceError: logger.warning( - f"MCP tool {tool_name} call failed (ClosedResourceError), attempting to reconnect..." + t("msg-8236c58c", tool_name=tool_name) ) # Attempt to reconnect await self._reconnect() @@ -349,7 +350,7 @@ async def cleanup(self) -> None: try: await self.exit_stack.aclose() except Exception as e: - logger.debug(f"Error closing current exit stack: {e}") + logger.debug(t("msg-044046ec", e=e)) # Don't close old exit stacks as they may be in different task contexts # They will be garbage collected naturally diff --git a/astrbot/core/agent/message.py b/astrbot/core/agent/message.py index bde6353ff3..3ec4495a32 100644 --- a/astrbot/core/agent/message.py +++ b/astrbot/core/agent/message.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t # Inspired by MoonshotAI/kosong, credits to MoonshotAI/kosong authors for the original implementation. # License: Apache License 2.0 @@ -27,7 +28,7 @@ def __init_subclass__(cls, **kwargs: Any) -> None: type_value = getattr(cls, "type", None) if type_value is None or not isinstance(type_value, str): - raise ValueError(invalid_subclass_error_msg) + raise ValueError(t("msg-d38656d7", invalid_subclass_error_msg=invalid_subclass_error_msg)) cls.__content_part_registry[type_value] = cls @@ -47,11 +48,11 @@ def validate_content_part(value: Any) -> Any: if isinstance(value, dict) and "type" in value: type_value: Any | None = cast(dict[str, Any], value).get("type") if not isinstance(type_value, str): - raise ValueError(f"Cannot validate {value} as ContentPart") + raise ValueError(t("msg-42d5a315", value=value)) target_class = cls.__content_part_registry[type_value] return target_class.model_validate(value) - raise ValueError(f"Cannot validate {value} as ContentPart") + raise ValueError(t("msg-42d5a315", value=value)) return core_schema.no_info_plain_validator_function(validate_content_part) @@ -195,7 +196,7 @@ def check_content_required(self): # other all cases: content is required if self.content is None: raise ValueError( - "content is required unless role='assistant' and tool_calls is not None" + t("msg-ffc376d0") ) return self diff --git a/astrbot/core/agent/runners/base.py b/astrbot/core/agent/runners/base.py index 21e7964335..384f299585 100644 --- a/astrbot/core/agent/runners/base.py +++ b/astrbot/core/agent/runners/base.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import abc import typing as T from enum import Enum, auto @@ -61,5 +62,5 @@ def get_final_llm_resp(self) -> LLMResponse | None: def _transition_state(self, new_state: AgentState) -> None: """Transition the agent state.""" if self._state != new_state: - logger.debug(f"Agent state transition: {self._state} -> {new_state}") + logger.debug(t("msg-24eb2b08", res=self._state, new_state=new_state)) self._state = new_state diff --git a/astrbot/core/agent/runners/coze/coze_agent_runner.py b/astrbot/core/agent/runners/coze/coze_agent_runner.py index a8300bb711..7164a1a440 100644 --- a/astrbot/core/agent/runners/coze/coze_agent_runner.py +++ b/astrbot/core/agent/runners/coze/coze_agent_runner.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import base64 import json import sys @@ -45,17 +46,17 @@ async def reset( self.api_key = provider_config.get("coze_api_key", "") if not self.api_key: - raise Exception("Coze API Key 不能为空。") + raise Exception(t("msg-448549b0")) self.bot_id = provider_config.get("bot_id", "") if not self.bot_id: - raise Exception("Coze Bot ID 不能为空。") + raise Exception(t("msg-b88724b0")) self.api_base: str = provider_config.get("coze_api_base", "https://api.coze.cn") if not isinstance(self.api_base, str) or not self.api_base.startswith( ("http://", "https://"), ): raise Exception( - "Coze API Base URL 格式不正确,必须以 http:// 或 https:// 开头。", + t("msg-ea5a135a"), ) self.timeout = provider_config.get("timeout", 120) @@ -75,13 +76,13 @@ async def step(self): 执行 Coze Agent 的一个步骤 """ if not self.req: - raise ValueError("Request is not set. Please call reset() first.") + raise ValueError(t("msg-55333301")) if self._state == AgentState.IDLE: try: await self.agent_hooks.on_agent_begin(self.run_context) except Exception as e: - logger.error(f"Error in on_agent_begin hook: {e}", exc_info=True) + logger.error(t("msg-d3b77736", e=e), exc_info=True) # 开始处理,转换到运行状态 self._transition_state(AgentState.RUNNING) @@ -91,7 +92,7 @@ async def step(self): async for response in self._execute_coze_request(): yield response except Exception as e: - logger.error(f"Coze 请求失败:{str(e)}") + logger.error(t("msg-5aa3eb1c", res=str(e))) self._transition_state(AgentState.ERROR) self.final_llm_resp = LLMResponse( role="err", completion_text=f"Coze 请求失败:{str(e)}" @@ -99,7 +100,7 @@ async def step(self): yield AgentResponse( type="err", data=AgentResponseData( - chain=MessageChain().message(f"Coze 请求失败:{str(e)}") + chain=MessageChain().message(t("msg-5aa3eb1c", res=str(e))) ), ) finally: @@ -177,7 +178,7 @@ async def _execute_coze_request(self): } ) except Exception as e: - logger.warning(f"处理上下文图片失败: {e}") + logger.warning(t("msg-333354c6", e=e)) continue if processed_content: @@ -218,7 +219,7 @@ async def _execute_coze_request(self): } ) except Exception as e: - logger.warning(f"处理图片失败 {url}: {e}") + logger.warning(t("msg-2d9e1c08", url=url, e=e)) continue if object_string_content: @@ -282,29 +283,29 @@ async def _execute_coze_request(self): yield AgentResponse( type="streaming_delta", data=AgentResponseData( - chain=MessageChain().message(content) + chain=MessageChain().message(t("msg-1f50979d", content=content)) ), ) elif event_type == "conversation.message.completed": # 消息完成 - logger.debug("Coze message completed") + logger.debug(t("msg-6fe5588b")) message_started = True elif event_type == "conversation.chat.completed": # 对话完成 - logger.debug("Coze chat completed") + logger.debug(t("msg-d2802f3b")) break elif event_type == "error": # 错误处理 error_msg = data.get("msg", "未知错误") error_code = data.get("code", "UNKNOWN") - logger.error(f"Coze 出现错误: {error_code} - {error_msg}") - raise Exception(f"Coze 出现错误: {error_code} - {error_msg}") + logger.error(t("msg-ba4afcda", error_code=error_code, error_msg=error_msg)) + raise Exception(t("msg-ba4afcda", error_code=error_code, error_msg=error_msg)) if not message_started and not accumulated_content: - logger.warning("Coze 未返回任何内容") + logger.warning(t("msg-ee300f25")) accumulated_content = "" # 创建最终响应 @@ -315,7 +316,7 @@ async def _execute_coze_request(self): try: await self.agent_hooks.on_agent_done(self.run_context, self.final_llm_resp) except Exception as e: - logger.error(f"Error in on_agent_done hook: {e}", exc_info=True) + logger.error(t("msg-8eb53be3", e=e), exc_info=True) # 返回最终结果 yield AgentResponse( @@ -340,7 +341,7 @@ async def _download_and_upload_image( if cache_key in self.file_id_cache[session_id]: file_id = self.file_id_cache[session_id][cache_key] - logger.debug(f"[Coze] 使用缓存的 file_id: {file_id}") + logger.debug(t("msg-034c1858", file_id=file_id)) return file_id try: @@ -349,13 +350,13 @@ async def _download_and_upload_image( if session_id: self.file_id_cache[session_id][cache_key] = file_id - logger.debug(f"[Coze] 图片上传成功并缓存,file_id: {file_id}") + logger.debug(t("msg-475d8a41", file_id=file_id)) return file_id except Exception as e: - logger.error(f"处理图片失败 {image_url}: {e!s}") - raise Exception(f"处理图片失败: {e!s}") + logger.error(t("msg-696dad99", image_url=image_url, e=e)) + raise Exception(t("msg-7793a347", e=e)) @override def done(self) -> bool: diff --git a/astrbot/core/agent/runners/coze/coze_api_client.py b/astrbot/core/agent/runners/coze/coze_api_client.py index f5799dfbb7..4281531b79 100644 --- a/astrbot/core/agent/runners/coze/coze_api_client.py +++ b/astrbot/core/agent/runners/coze/coze_api_client.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import io import json @@ -66,36 +67,36 @@ async def upload_file( timeout=aiohttp.ClientTimeout(total=60), ) as response: if response.status == 401: - raise Exception("Coze API 认证失败,请检查 API Key 是否正确") + raise Exception(t("msg-76f97104")) response_text = await response.text() logger.debug( - f"文件上传响应状态: {response.status}, 内容: {response_text}", + t("msg-3653b652", res=response.status, response_text=response_text), ) if response.status != 200: raise Exception( - f"文件上传失败,状态码: {response.status}, 响应: {response_text}", + t("msg-13fe060c", res=response.status, response_text=response_text), ) try: result = await response.json() except json.JSONDecodeError: - raise Exception(f"文件上传响应解析失败: {response_text}") + raise Exception(t("msg-5604b862", response_text=response_text)) if result.get("code") != 0: - raise Exception(f"文件上传失败: {result.get('msg', '未知错误')}") + raise Exception(t("msg-c0373c50", res=result.get('msg', '未知错误'))) file_id = result["data"]["id"] - logger.debug(f"[Coze] 图片上传成功,file_id: {file_id}") + logger.debug(t("msg-010e4299", file_id=file_id)) return file_id except asyncio.TimeoutError: - logger.error("文件上传超时") - raise Exception("文件上传超时") + logger.error(t("msg-719f13cb")) + raise Exception(t("msg-719f13cb")) except Exception as e: - logger.error(f"文件上传失败: {e!s}") - raise Exception(f"文件上传失败: {e!s}") + logger.error(t("msg-121c11fb", e=e)) + raise Exception(t("msg-121c11fb", e=e)) async def download_image(self, image_url: str) -> bytes: """下载图片并返回字节数据 @@ -111,14 +112,14 @@ async def download_image(self, image_url: str) -> bytes: try: async with session.get(image_url) as response: if response.status != 200: - raise Exception(f"下载图片失败,状态码: {response.status}") + raise Exception(t("msg-f6101892", res=response.status)) image_data = await response.read() return image_data except Exception as e: - logger.error(f"下载图片失败 {image_url}: {e!s}") - raise Exception(f"下载图片失败: {e!s}") + logger.error(t("msg-c09c56c9", image_url=image_url, e=e)) + raise Exception(t("msg-15211c7c", e=e)) async def chat_messages( self, @@ -159,7 +160,7 @@ async def chat_messages( if conversation_id: params["conversation_id"] = conversation_id - logger.debug(f"Coze chat_messages payload: {payload}, params: {params}") + logger.debug(t("msg-2245219f", payload=payload, params=params)) try: async with session.post( @@ -169,10 +170,10 @@ async def chat_messages( timeout=aiohttp.ClientTimeout(total=timeout), ) as response: if response.status == 401: - raise Exception("Coze API 认证失败,请检查 API Key 是否正确") + raise Exception(t("msg-76f97104")) if response.status != 200: - raise Exception(f"Coze API 流式请求失败,状态码: {response.status}") + raise Exception(t("msg-d8fd415c", res=response.status)) # SSE buffer = "" @@ -204,9 +205,9 @@ async def chat_messages( event_data = {"content": data_str} except asyncio.TimeoutError: - raise Exception(f"Coze API 流式请求超时 ({timeout}秒)") + raise Exception(t("msg-f5cc7604", timeout=timeout)) except Exception as e: - raise Exception(f"Coze API 流式请求失败: {e!s}") + raise Exception(t("msg-30c0a9d6", e=e)) async def clear_context(self, conversation_id: str): """清空会话上下文 @@ -226,20 +227,20 @@ async def clear_context(self, conversation_id: str): response_text = await response.text() if response.status == 401: - raise Exception("Coze API 认证失败,请检查 API Key 是否正确") + raise Exception(t("msg-76f97104")) if response.status != 200: - raise Exception(f"Coze API 请求失败,状态码: {response.status}") + raise Exception(t("msg-11509aba", res=response.status)) try: return json.loads(response_text) except json.JSONDecodeError: - raise Exception("Coze API 返回非JSON格式") + raise Exception(t("msg-002af11d")) except asyncio.TimeoutError: - raise Exception("Coze API 请求超时") + raise Exception(t("msg-c0b8fc7c")) except aiohttp.ClientError as e: - raise Exception(f"Coze API 请求失败: {e!s}") + raise Exception(t("msg-a68a33fa", e=e)) async def get_message_list( self, @@ -274,8 +275,8 @@ async def get_message_list( return await response.json() except Exception as e: - logger.error(f"获取Coze消息列表失败: {e!s}") - raise Exception(f"获取Coze消息列表失败: {e!s}") + logger.error(t("msg-c26e068e", e=e)) + raise Exception(t("msg-c26e068e", e=e)) async def close(self) -> None: """关闭会话""" @@ -297,7 +298,7 @@ async def test_coze_api_client() -> None: with open("README.md", "rb") as f: file_data = f.read() file_id = await client.upload_file(file_data) - print(f"Uploaded file_id: {file_id}") + print(t("msg-5bc0a49d", file_id=file_id)) async for event in client.chat_messages( bot_id=bot_id, user_id="test_user", @@ -316,7 +317,7 @@ async def test_coze_api_client() -> None: ], stream=True, ): - print(f"Event: {event}") + print(t("msg-7c08bdaf", event=event)) finally: await client.close() diff --git a/astrbot/core/agent/runners/dashscope/dashscope_agent_runner.py b/astrbot/core/agent/runners/dashscope/dashscope_agent_runner.py index 1aaf6e3b9c..a9b190afd2 100644 --- a/astrbot/core/agent/runners/dashscope/dashscope_agent_runner.py +++ b/astrbot/core/agent/runners/dashscope/dashscope_agent_runner.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import functools import queue @@ -49,13 +50,13 @@ async def reset( self.api_key = provider_config.get("dashscope_api_key", "") if not self.api_key: - raise Exception("阿里云百炼 API Key 不能为空。") + raise Exception(t("msg-dc1a9e6e")) self.app_id = provider_config.get("dashscope_app_id", "") if not self.app_id: - raise Exception("阿里云百炼 APP ID 不能为空。") + raise Exception(t("msg-c492cbbc")) self.dashscope_app_type = provider_config.get("dashscope_app_type", "") if not self.dashscope_app_type: - raise Exception("阿里云百炼 APP 类型不能为空。") + raise Exception(t("msg-bcc8e027")) self.variables: dict = provider_config.get("variables", {}) or {} self.rag_options: dict = provider_config.get("rag_options", {}) @@ -87,13 +88,13 @@ async def step(self): 执行 Dashscope Agent 的一个步骤 """ if not self.req: - raise ValueError("Request is not set. Please call reset() first.") + raise ValueError(t("msg-55333301")) if self._state == AgentState.IDLE: try: await self.agent_hooks.on_agent_begin(self.run_context) except Exception as e: - logger.error(f"Error in on_agent_begin hook: {e}", exc_info=True) + logger.error(t("msg-d3b77736", e=e), exc_info=True) # 开始处理,转换到运行状态 self._transition_state(AgentState.RUNNING) @@ -103,7 +104,7 @@ async def step(self): async for response in self._execute_dashscope_request(): yield response except Exception as e: - logger.error(f"阿里云百炼请求失败:{str(e)}") + logger.error(t("msg-e3af4efd", res=str(e))) self._transition_state(AgentState.ERROR) self.final_llm_resp = LLMResponse( role="err", completion_text=f"阿里云百炼请求失败:{str(e)}" @@ -111,7 +112,7 @@ async def step(self): yield AgentResponse( type="err", data=AgentResponseData( - chain=MessageChain().message(f"阿里云百炼请求失败:{str(e)}") + chain=MessageChain().message(t("msg-e3af4efd", res=str(e))) ), ) @@ -157,11 +158,11 @@ async def _process_stream_chunk( (更新后的output_text, doc_references, AgentResponse或None) """ - logger.debug(f"dashscope stream chunk: {chunk}") + logger.debug(t("msg-fccf5004", chunk=chunk)) if chunk.status_code != 200: logger.error( - f"阿里云百炼请求失败: request_id={chunk.request_id}, code={chunk.status_code}, message={chunk.message}, 请参考文档:https://help.aliyun.com/zh/model-studio/developer-reference/error-code", + t("msg-100d7d7e", res=chunk.request_id, res_2=chunk.status_code, res_3=chunk.message), ) self._transition_state(AgentState.ERROR) error_msg = ( @@ -169,14 +170,14 @@ async def _process_stream_chunk( ) self.final_llm_resp = LLMResponse( role="err", - result_chain=MessageChain().message(error_msg), + result_chain=MessageChain().message(t("msg-10f72727", error_msg=error_msg)), ) return ( output_text, None, AgentResponse( type="err", - data=AgentResponseData(chain=MessageChain().message(error_msg)), + data=AgentResponseData(chain=MessageChain().message(t("msg-10f72727", error_msg=error_msg))), ), ) @@ -189,7 +190,7 @@ async def _process_stream_chunk( output_text += chunk_text response = AgentResponse( type="streaming_delta", - data=AgentResponseData(chain=MessageChain().message(chunk_text)), + data=AgentResponseData(chain=MessageChain().message(t("msg-e8615101", chunk_text=chunk_text))), ) # 获取文档引用 @@ -347,7 +348,7 @@ async def _handle_streaming_response( if self.streaming: yield AgentResponse( type="streaming_delta", - data=AgentResponseData(chain=MessageChain().message(ref_text)), + data=AgentResponseData(chain=MessageChain().message(t("msg-dfb132c4", ref_text=ref_text))), ) # 创建最终响应 @@ -358,7 +359,7 @@ async def _handle_streaming_response( try: await self.agent_hooks.on_agent_done(self.run_context, self.final_llm_resp) except Exception as e: - logger.error(f"Error in on_agent_done hook: {e}", exc_info=True) + logger.error(t("msg-8eb53be3", e=e), exc_info=True) # 返回最终结果 yield AgentResponse( @@ -376,7 +377,7 @@ async def _execute_dashscope_request(self): # 检查图片输入 if image_urls: - logger.warning("阿里云百炼暂不支持图片输入,将自动忽略图片内容。") + logger.warning(t("msg-650b47e1")) # 构建请求payload payload = await self._build_request_payload( diff --git a/astrbot/core/agent/runners/dify/dify_agent_runner.py b/astrbot/core/agent/runners/dify/dify_agent_runner.py index 93f8d3570d..461ee32205 100644 --- a/astrbot/core/agent/runners/dify/dify_agent_runner.py +++ b/astrbot/core/agent/runners/dify/dify_agent_runner.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import base64 import os import sys @@ -68,13 +69,13 @@ async def step(self): 执行 Dify Agent 的一个步骤 """ if not self.req: - raise ValueError("Request is not set. Please call reset() first.") + raise ValueError(t("msg-55333301")) if self._state == AgentState.IDLE: try: await self.agent_hooks.on_agent_begin(self.run_context) except Exception as e: - logger.error(f"Error in on_agent_begin hook: {e}", exc_info=True) + logger.error(t("msg-d3b77736", e=e), exc_info=True) # 开始处理,转换到运行状态 self._transition_state(AgentState.RUNNING) @@ -84,7 +85,7 @@ async def step(self): async for response in self._execute_dify_request(): yield response except Exception as e: - logger.error(f"Dify 请求失败:{str(e)}") + logger.error(t("msg-0d493427", res=str(e))) self._transition_state(AgentState.ERROR) self.final_llm_resp = LLMResponse( role="err", completion_text=f"Dify 请求失败:{str(e)}" @@ -92,7 +93,7 @@ async def step(self): yield AgentResponse( type="err", data=AgentResponseData( - chain=MessageChain().message(f"Dify 请求失败:{str(e)}") + chain=MessageChain().message(t("msg-0d493427", res=str(e))) ), ) finally: @@ -133,10 +134,10 @@ async def _execute_dify_request(self): mime_type="image/png", file_name="image.png", ) - logger.debug(f"Dify 上传图片响应:{file_response}") + logger.debug(t("msg-fe594f21", file_response=file_response)) if "id" not in file_response: logger.warning( - f"上传图片后得到未知的 Dify 响应:{file_response},图片将忽略。" + t("msg-3534b306", file_response=file_response) ) continue files_payload.append( @@ -147,7 +148,7 @@ async def _execute_dify_request(self): } ) except Exception as e: - logger.warning(f"上传图片失败:{e}") + logger.warning(t("msg-08441fdf", e=e)) continue # 获得会话变量 @@ -178,7 +179,7 @@ async def _execute_dify_request(self): files=files_payload, timeout=self.timeout, ): - logger.debug(f"dify resp chunk: {chunk}") + logger.debug(t("msg-3972f693", chunk=chunk)) if chunk["event"] == "message" or chunk["event"] == "agent_message": result += chunk["answer"] if not conversation_id: @@ -199,12 +200,12 @@ async def _execute_dify_request(self): ), ) elif chunk["event"] == "message_end": - logger.debug("Dify message end") + logger.debug(t("msg-6c74267b")) break elif chunk["event"] == "error": - logger.error(f"Dify 出现错误:{chunk}") + logger.error(t("msg-1ce260ba", chunk=chunk)) raise Exception( - f"Dify 出现错误 status: {chunk['status']} message: {chunk['message']}" + t("msg-a12417dd", res=chunk['status'], res_2=chunk['message']) ) case "workflow": @@ -218,15 +219,15 @@ async def _execute_dify_request(self): files=files_payload, timeout=self.timeout, ): - logger.debug(f"dify workflow resp chunk: {chunk}") + logger.debug(t("msg-f8530ee9", chunk=chunk)) match chunk["event"]: case "workflow_started": logger.info( - f"Dify 工作流(ID: {chunk['workflow_run_id']})开始运行。" + t("msg-386a282e", res=chunk['workflow_run_id']) ) case "node_finished": logger.debug( - f"Dify 工作流节点(ID: {chunk['data']['node_id']} Title: {chunk['data'].get('title', '')})运行结束。" + t("msg-0bc1299b", res=chunk['data']['node_id'], res_2=chunk['data'].get('title', '')) ) case "text_chunk": if self.streaming and chunk["data"]["text"]: @@ -240,26 +241,26 @@ async def _execute_dify_request(self): ) case "workflow_finished": logger.info( - f"Dify 工作流(ID: {chunk['workflow_run_id']})运行结束" + t("msg-5cf24248", res=chunk['workflow_run_id']) ) - logger.debug(f"Dify 工作流结果:{chunk}") + logger.debug(t("msg-e2c2159f", chunk=chunk)) if chunk["data"]["error"]: logger.error( - f"Dify 工作流出现错误:{chunk['data']['error']}" + t("msg-4fa60ef1", res=chunk['data']['error']) ) raise Exception( - f"Dify 工作流出现错误:{chunk['data']['error']}" + t("msg-4fa60ef1", res=chunk['data']['error']) ) if self.workflow_output_key not in chunk["data"]["outputs"]: raise Exception( - f"Dify 工作流的输出不包含指定的键名:{self.workflow_output_key}" + t("msg-1f786836", res=self.workflow_output_key) ) result = chunk case _: - raise Exception(f"未知的 Dify API 类型:{self.api_type}") + raise Exception(t("msg-c4a70ffb", res=self.api_type)) if not result: - logger.warning("Dify 请求结果为空,请查看 Debug 日志。") + logger.warning(t("msg-51d321fd")) # 解析结果 chain = await self.parse_dify_result(result) @@ -271,7 +272,7 @@ async def _execute_dify_request(self): try: await self.agent_hooks.on_agent_done(self.run_context, self.final_llm_resp) except Exception as e: - logger.error(f"Error in on_agent_done hook: {e}", exc_info=True) + logger.error(t("msg-8eb53be3", e=e), exc_info=True) # 返回最终结果 yield AgentResponse( diff --git a/astrbot/core/agent/runners/dify/dify_api_client.py b/astrbot/core/agent/runners/dify/dify_api_client.py index 26da6dfe9a..403432f732 100644 --- a/astrbot/core/agent/runners/dify/dify_api_client.py +++ b/astrbot/core/agent/runners/dify/dify_api_client.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import codecs import json from collections.abc import AsyncGenerator @@ -19,7 +20,7 @@ async def _stream_sse(resp: ClientResponse) -> AsyncGenerator[dict, None]: try: yield json.loads(block[5:]) except json.JSONDecodeError: - logger.warning(f"Drop invalid dify json data: {block[5:]}") + logger.warning(t("msg-cd6cd7ac", res=block[5:])) continue # flush any remaining text buffer += decoder.decode(b"", final=True) @@ -27,7 +28,7 @@ async def _stream_sse(resp: ClientResponse) -> AsyncGenerator[dict, None]: try: yield json.loads(buffer[5:]) except json.JSONDecodeError: - logger.warning(f"Drop invalid dify json data: {buffer[5:]}") + logger.warning(t("msg-cd6cd7ac", res=buffer[5:])) class DifyAPIClient: @@ -55,7 +56,7 @@ async def chat_messages( payload = locals() payload.pop("self") payload.pop("timeout") - logger.info(f"chat_messages payload: {payload}") + logger.info(t("msg-3654a12d", payload=payload)) async with self.session.post( url, json=payload, @@ -65,7 +66,7 @@ async def chat_messages( if resp.status != 200: text = await resp.text() raise Exception( - f"Dify /chat-messages 接口请求失败:{resp.status}. {text}", + t("msg-8e865c52", res=resp.status, text=text), ) async for event in _stream_sse(resp): yield event @@ -84,7 +85,7 @@ async def workflow_run( payload = locals() payload.pop("self") payload.pop("timeout") - logger.info(f"workflow_run payload: {payload}") + logger.info(t("msg-2d7534b8", payload=payload)) async with self.session.post( url, json=payload, @@ -94,7 +95,7 @@ async def workflow_run( if resp.status != 200: text = await resp.text() raise Exception( - f"Dify /workflows/run 接口请求失败:{resp.status}. {text}", + t("msg-89918ba5", res=resp.status, text=text), ) async for event in _stream_sse(resp): yield event @@ -143,7 +144,7 @@ async def file_upload( content_type=mime_type or "application/octet-stream", ) else: - raise ValueError("file_path 和 file_data 不能同时为 None") + raise ValueError(t("msg-8bf17938")) async with self.session.post( url, @@ -152,7 +153,7 @@ async def file_upload( ) as resp: if resp.status != 200 and resp.status != 201: text = await resp.text() - raise Exception(f"Dify 文件上传失败:{resp.status}. {text}") + raise Exception(t("msg-b6ee8f38", res=resp.status, text=text)) return await resp.json() # {"id": "xxx", ...} async def close(self) -> None: diff --git a/astrbot/core/agent/runners/tool_loop_agent_runner.py b/astrbot/core/agent/runners/tool_loop_agent_runner.py index 94069089d9..621e192390 100644 --- a/astrbot/core/agent/runners/tool_loop_agent_runner.py +++ b/astrbot/core/agent/runners/tool_loop_agent_runner.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import copy import sys @@ -225,7 +226,7 @@ async def _iter_llm_responses_with_fallback( is_last_candidate = idx == total_candidates - 1 if idx > 0: logger.warning( - "Switched from %s to fallback chat provider: %s", + t("msg-960ef181"), self.provider.provider_config.get("id", ""), candidate_id, ) @@ -245,7 +246,7 @@ async def _iter_llm_responses_with_fallback( ): last_err_response = resp logger.warning( - "Chat Model %s returns error response, trying fallback to next provider.", + t("msg-4f999913"), candidate_id, ) break @@ -258,7 +259,7 @@ async def _iter_llm_responses_with_fallback( except Exception as exc: # noqa: BLE001 last_exception = exc logger.warning( - "Chat Model %s request error: %s", + t("msg-c042095f"), candidate_id, exc, exc_info=True, @@ -286,7 +287,7 @@ def _simple_print_message_role(self, tag: str = ""): roles = [] for message in self.run_context.messages: roles.append(message.role) - logger.debug(f"{tag} RunCtx.messages -> [{len(roles)}] {','.join(roles)}") + logger.debug(t("msg-81b2aeae", tag=tag, res=len(roles), res_2=','.join(roles))) def follow_up( self, @@ -343,13 +344,13 @@ async def step(self): This method should return the result of the step. """ if not self.req: - raise ValueError("Request is not set. Please call reset() first.") + raise ValueError(t("msg-55333301")) if self._state == AgentState.IDLE: try: await self.agent_hooks.on_agent_begin(self.run_context) except Exception as e: - logger.error(f"Error in on_agent_begin hook: {e}", exc_info=True) + logger.error(t("msg-d3b77736", e=e), exc_info=True) # 开始处理,转换到运行状态 self._transition_state(AgentState.RUNNING) @@ -415,7 +416,7 @@ async def step(self): return if self._stop_requested: - logger.info("Agent execution was requested to stop by user.") + logger.info(t("msg-61de315c")) llm_resp = llm_resp_result if llm_resp.role != "assistant": llm_resp = LLMResponse( @@ -445,7 +446,7 @@ async def step(self): try: await self.agent_hooks.on_agent_done(self.run_context, llm_resp) except Exception as e: - logger.error(f"Error in on_agent_done hook: {e}", exc_info=True) + logger.error(t("msg-8eb53be3", e=e), exc_info=True) yield AgentResponse( type="aborted", @@ -467,7 +468,7 @@ async def step(self): type="err", data=AgentResponseData( chain=MessageChain().message( - f"LLM 响应错误: {llm_resp.completion_text or '未知错误'}", + t("msg-508d6d17", res=llm_resp.completion_text or '未知错误'), ), ), ) @@ -492,7 +493,7 @@ async def step(self): parts.append(TextPart(text=llm_resp.completion_text)) if len(parts) == 0: logger.warning( - "LLM returned empty assistant message with no tool calls." + t("msg-ed80313d") ) self.run_context.messages.append(Message(role="assistant", content=parts)) @@ -500,7 +501,7 @@ async def step(self): try: await self.agent_hooks.on_agent_done(self.run_context, llm_resp) except Exception as e: - logger.error(f"Error in on_agent_done hook: {e}", exc_info=True) + logger.error(t("msg-8eb53be3", e=e), exc_info=True) self._resolve_unconsumed_follow_ups() # 返回 LLM 结果 @@ -603,7 +604,7 @@ async def step(self): Message(role="user", content=image_parts) ) logger.debug( - f"Appended {len(cached_images)} cached image(s) to context for LLM review" + t("msg-970947ae", res=len(cached_images)) ) self.req.append_tool_calls_result(tool_calls_result) @@ -621,7 +622,7 @@ async def step_until_done( # 如果循环结束了但是 agent 还没有完成,说明是达到了 max_step if not self.done(): logger.warning( - f"Agent reached max steps ({max_step}), forcing a final response." + t("msg-6b326889", max_step=max_step) ) # 拔掉所有工具 if self.req: @@ -644,7 +645,7 @@ async def _handle_function_tools( ) -> T.AsyncGenerator[_HandleFunctionToolsResult, None]: """处理函数工具调用。""" tool_call_result_blocks: list[ToolCallMessageSegment] = [] - logger.info(f"Agent 使用工具: {llm_response.tools_call_name}") + logger.info(t("msg-948ea4b7", res=llm_response.tools_call_name)) def _append_tool_call_result(tool_call_id: str, content: str) -> None: tool_call_result_blocks.append( @@ -690,10 +691,10 @@ def _append_tool_call_result(tool_call_id: str, content: str) -> None: else: func_tool = req.func_tool.get_tool(func_tool_name) - logger.info(f"使用工具:{func_tool_name},参数:{func_tool_args}") + logger.info(t("msg-a27ad3d1", func_tool_name=func_tool_name, func_tool_args=func_tool_args)) if not func_tool: - logger.warning(f"未找到指定的工具: {func_tool_name},将跳过。") + logger.warning(t("msg-812ad241", func_tool_name=func_tool_name)) _append_tool_call_result( func_tool_id, f"error: Tool {func_tool_name} not found.", @@ -705,7 +706,7 @@ def _append_tool_call_result(tool_call_id: str, content: str) -> None: # 获取实际的 handler 函数 if func_tool.handler: logger.debug( - f"工具 {func_tool_name} 期望的参数: {func_tool.parameters}", + t("msg-20b4f143", func_tool_name=func_tool_name, res=func_tool.parameters), ) if func_tool.parameters and func_tool.parameters.get("properties"): expected_params = set(func_tool.parameters["properties"].keys()) @@ -722,7 +723,7 @@ def _append_tool_call_result(tool_call_id: str, content: str) -> None: ) if ignored_params: logger.warning( - f"工具 {func_tool_name} 忽略非期望参数: {ignored_params}", + t("msg-78f6833c", func_tool_name=func_tool_name, ignored_params=ignored_params), ) else: # 如果没有 handler(如 MCP 工具),使用所有参数 @@ -735,7 +736,7 @@ def _append_tool_call_result(tool_call_id: str, content: str) -> None: valid_params, ) except Exception as e: - logger.error(f"Error in on_tool_start hook: {e}", exc_info=True) + logger.error(t("msg-2b523f8c", e=e), exc_info=True) executor = self.tool_executor.execute( tool=func_tool, @@ -817,7 +818,7 @@ def _append_tool_call_result(tool_call_id: str, content: str) -> None: # 这里我们将直接结束 Agent Loop # 发送消息逻辑在 ToolExecutor 中处理了 logger.warning( - f"{func_tool_name} 没有返回值,或者已将结果直接发送给用户。" + t("msg-ec868b73", func_tool_name=func_tool_name) ) self._transition_state(AgentState.DONE) self.stats.end_time = time.time() @@ -828,7 +829,7 @@ def _append_tool_call_result(tool_call_id: str, content: str) -> None: else: # 不应该出现其他类型 logger.warning( - f"Tool 返回了不支持的类型: {type(resp)}。", + t("msg-6b61e4f1", res=type(resp)), ) _append_tool_call_result( func_tool_id, @@ -843,9 +844,9 @@ def _append_tool_call_result(tool_call_id: str, content: str) -> None: _final_resp, ) except Exception as e: - logger.error(f"Error in on_tool_end hook: {e}", exc_info=True) + logger.error(t("msg-34c13e02", e=e), exc_info=True) except Exception as e: - logger.warning(traceback.format_exc()) + logger.warning(t("msg-78b9c276", res=traceback.format_exc())) _append_tool_call_result( func_tool_id, f"error: {e!s}", @@ -868,7 +869,7 @@ def _append_tool_call_result(tool_call_id: str, content: str) -> None: ], ) ) - logger.info(f"Tool `{func_tool_name}` Result: {last_tcr_content}") + logger.info(t("msg-a1493b6d", func_tool_name=func_tool_name, last_tcr_content=last_tcr_content)) # 处理函数调用响应 if tool_call_result_blocks: diff --git a/astrbot/core/agent/tool.py b/astrbot/core/agent/tool.py index c2536708e6..69475b7ad4 100644 --- a/astrbot/core/agent/tool.py +++ b/astrbot/core/agent/tool.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import copy from collections.abc import AsyncGenerator, Awaitable, Callable from typing import Any, Generic @@ -70,7 +71,7 @@ def __repr__(self) -> str: async def call(self, context: ContextWrapper[TContext], **kwargs) -> ToolExecResult: """Run the tool with the given arguments. The handler field has priority.""" raise NotImplementedError( - "FunctionTool.call() must be implemented by subclasses or set a handler." + t("msg-983bc802") ) diff --git a/astrbot/core/agent/tool_image_cache.py b/astrbot/core/agent/tool_image_cache.py index 72e22dd52e..f091e8f748 100644 --- a/astrbot/core/agent/tool_image_cache.py +++ b/astrbot/core/agent/tool_image_cache.py @@ -2,6 +2,7 @@ This module allows LLM to review images before deciding whether to send them to users. """ +from astrbot.core.lang import t import base64 import os @@ -52,7 +53,7 @@ def __init__(self) -> None: self._initialized = True self._cache_dir = os.path.join(get_astrbot_temp_path(), self.CACHE_DIR_NAME) os.makedirs(self._cache_dir, exist_ok=True) - logger.debug(f"ToolImageCache initialized, cache dir: {self._cache_dir}") + logger.debug(t("msg-45da4af7", res=self._cache_dir)) def _get_file_extension(self, mime_type: str) -> str: """Get file extension from MIME type.""" @@ -96,9 +97,9 @@ def save_image( image_bytes = base64.b64decode(base64_data) with open(file_path, "wb") as f: f.write(image_bytes) - logger.debug(f"Saved tool image to: {file_path}") + logger.debug(t("msg-017bde96", file_path=file_path)) except Exception as e: - logger.error(f"Failed to save tool image: {e}") + logger.error(t("msg-29398f55", e=e)) raise return CachedImage( @@ -129,7 +130,7 @@ def get_image_base64_by_path( base64_data = base64.b64encode(image_bytes).decode("utf-8") return base64_data, mime_type except Exception as e: - logger.error(f"Failed to read cached image {file_path}: {e}") + logger.error(t("msg-128aa08a", file_path=file_path, e=e)) return None def cleanup_expired(self) -> int: @@ -150,10 +151,10 @@ def cleanup_expired(self) -> int: os.remove(file_path) cleaned += 1 except Exception as e: - logger.warning(f"Error during cache cleanup: {e}") + logger.warning(t("msg-3c111d1f", e=e)) if cleaned: - logger.info(f"Cleaned up {cleaned} expired cached images") + logger.info(t("msg-eeb1b849", cleaned=cleaned)) return cleaned diff --git a/astrbot/core/astr_agent_run_util.py b/astrbot/core/astr_agent_run_util.py index 017f2cea24..647d911931 100644 --- a/astrbot/core/astr_agent_run_util.py +++ b/astrbot/core/astr_agent_run_util.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import re import time @@ -100,7 +101,7 @@ async def run_agent( if step_idx == max_step + 1: logger.warning( - f"Agent reached max steps ({max_step}), forcing a final response." + t("msg-6b326889", max_step=max_step) ) if not agent_runner.done(): # 拔掉所有工具 @@ -157,7 +158,7 @@ async def run_agent( msg_chain, tool_name_by_call_id ) await astr_event.send( - MessageChain(type="tool_call").message(status_msg) + MessageChain(type="tool_call").message(t("msg-bb15e9c7", status_msg=status_msg)) ) # 对于其他情况,暂时先不处理 continue @@ -233,7 +234,7 @@ async def run_agent( await stop_watcher except asyncio.CancelledError: pass - logger.error(traceback.format_exc()) + logger.error(t("msg-78b9c276", res=traceback.format_exc())) err_msg = f"\n\nAstrBot 请求失败。\n错误类型: {type(e).__name__}\n错误信息: {e!s}\n\n请在平台日志查看和分享错误详情。\n" @@ -246,12 +247,12 @@ async def run_agent( agent_runner.run_context, error_llm_response ) except Exception: - logger.exception("Error in on_agent_done hook") + logger.exception(t("msg-9c246298")) if agent_runner.streaming: - yield MessageChain().message(err_msg) + yield MessageChain().message(t("msg-34f164d4", err_msg=err_msg)) else: - astr_event.set_result(MessageEventResult().message(err_msg)) + astr_event.set_result(MessageEventResult().message(t("msg-34f164d4", err_msg=err_msg))) return @@ -299,11 +300,10 @@ async def run_live_agent( support_stream = tts_provider.support_stream() if support_stream: - logger.info("[Live Agent] 使用流式 TTS(原生支持 get_audio_stream)") + logger.info(t("msg-6d9553b2")) else: logger.info( - f"[Live Agent] 使用 TTS({tts_provider.meta().type} " - "使用 get_audio,将按句子分块生成音频)" + t("msg-becf71bf", res=tts_provider.meta().type) ) # 统计数据初始化 @@ -368,7 +368,7 @@ async def run_live_agent( yield chain except Exception as e: - logger.error(f"[Live Agent] 运行时发生错误: {e}", exc_info=True) + logger.error(t("msg-21723afb", e=e), exc_info=True) finally: # 清理任务 if not feeder_task.done(): @@ -402,7 +402,7 @@ async def run_live_agent( ) ) except Exception as e: - logger.error(f"发送 TTS 统计信息失败: {e}") + logger.error(t("msg-ca1bf0d7", e=e)) async def _run_agent_feeder( @@ -448,7 +448,7 @@ async def _run_agent_feeder( if len(temp_buffer) >= 10: if temp_buffer.strip(): - logger.info(f"[Live Agent Feeder] 分句: {temp_buffer}") + logger.info(t("msg-5ace3d96", temp_buffer=temp_buffer)) await text_queue.put(temp_buffer) temp_buffer = "" @@ -460,7 +460,7 @@ async def _run_agent_feeder( await text_queue.put(buffer) except Exception as e: - logger.error(f"[Live Agent Feeder] Error: {e}", exc_info=True) + logger.error(t("msg-bc1826ea", e=e), exc_info=True) finally: # 发送结束信号 await text_queue.put(None) @@ -475,7 +475,7 @@ async def _safe_tts_stream_wrapper( try: await tts_provider.get_audio_stream(text_queue, audio_queue) except Exception as e: - logger.error(f"[Live TTS Stream] Error: {e}", exc_info=True) + logger.error(t("msg-a92774c9", e=e), exc_info=True) finally: await audio_queue.put(None) @@ -501,11 +501,11 @@ async def _simulated_stream_tts( await audio_queue.put((text, audio_data)) except Exception as e: logger.error( - f"[Live TTS Simulated] Error processing text '{text[:20]}...': {e}" + t("msg-d7b3bbae", res=text[:20], e=e) ) # 继续处理下一句 except Exception as e: - logger.error(f"[Live TTS Simulated] Critical Error: {e}", exc_info=True) + logger.error(t("msg-035bca5f", e=e), exc_info=True) finally: await audio_queue.put(None) diff --git a/astrbot/core/astr_agent_tool_exec.py b/astrbot/core/astr_agent_tool_exec.py index 46ec4346b3..baf3c05444 100644 --- a/astrbot/core/astr_agent_tool_exec.py +++ b/astrbot/core/astr_agent_tool_exec.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import inspect import json @@ -80,7 +81,7 @@ async def _run_in_background() -> None: ) except Exception as e: # noqa: BLE001 logger.error( - f"Background task {task_id} failed: {e!s}", + t("msg-e5f2fb34", task_id=task_id, e=e), exc_info=True, ) @@ -237,7 +238,7 @@ async def _run_handoff_in_background() -> None: ) except Exception as e: # noqa: BLE001 logger.error( - f"Background handoff {task_id} ({tool.name}) failed: {e!s}", + t("msg-c54b2335", task_id=task_id, res=tool.name, e=e), exc_info=True, ) @@ -411,7 +412,7 @@ async def _wake_main_agent_for_background_result( event=cron_event, plugin_context=ctx, config=config, req=req ) if not result: - logger.error(f"Failed to build main agent for background task {tool_name}.") + logger.error(t("msg-8c2fe51d", tool_name=tool_name)) return runner = result.agent_runner @@ -436,7 +437,7 @@ async def _wake_main_agent_for_background_result( summary_note=summary_note, ) if not llm_resp: - logger.warning("background task agent got no response") + logger.warning(t("msg-c6d4e4a6")) return @classmethod @@ -450,7 +451,7 @@ async def _execute_local( ): event = run_context.context.event if not event: - raise ValueError("Event must be provided for local function tools.") + raise ValueError(t("msg-0b3711f1")) is_override_call = False for ty in type(tool).mro(): @@ -460,7 +461,7 @@ async def _execute_local( # 检查 tool 下有没有 run 方法 if not tool.handler and not hasattr(tool, "run") and not is_override_call: - raise ValueError("Tool must have a valid handler or override 'run' method.") + raise ValueError(t("msg-8c19e27a")) awaitable = None method_name = "" @@ -474,7 +475,7 @@ async def _execute_local( awaitable = getattr(tool, "run") method_name = "run" if awaitable is None: - raise ValueError("Tool must have a valid handler or override 'run' method.") + raise ValueError(t("msg-8c19e27a")) wrapper = call_local_llm_tool( context=run_context, @@ -512,13 +513,13 @@ async def _execute_local( ) except Exception as e: logger.error( - f"Tool 直接发送消息失败: {e}", + t("msg-24053a5f", e=e), exc_info=True, ) yield None except asyncio.TimeoutError: raise Exception( - f"tool {tool.name} execution timeout after {tool_call_timeout or run_context.tool_call_timeout} seconds.", + t("msg-f940b51e", res=tool.name, res_2=tool_call_timeout or run_context.tool_call_timeout), ) except StopAsyncIteration: break @@ -560,9 +561,9 @@ async def call_local_llm_tool( elif method_name == "call": ready_to_call = handler(context, *args, **kwargs) else: - raise ValueError(f"未知的方法名: {method_name}") + raise ValueError(t("msg-7e22fc8e", method_name=method_name)) except ValueError as e: - raise Exception(f"Tool execution ValueError: {e}") from e + raise Exception(t("msg-c285315c", e=e)) from e except TypeError as e: # 获取函数的签名(包括类型),除了第一个 event/context 参数。 try: @@ -593,11 +594,11 @@ async def call_local_llm_tool( handler_param_str = "(unable to inspect signature)" raise Exception( - f"Tool handler parameter mismatch, please check the handler definition. Handler parameters: {handler_param_str}" + t("msg-41366b74", handler_param_str=handler_param_str) ) from e except Exception as e: trace_ = traceback.format_exc() - raise Exception(f"Tool execution error: {e}. Traceback: {trace_}") from e + raise Exception(t("msg-e8cadf8e", e=e, trace_=trace_)) from e if not ready_to_call: return @@ -621,7 +622,7 @@ async def call_local_llm_tool( # 如果这个异步生成器没有执行到 yield 分支 yield except Exception as e: - logger.error(f"Previous Error: {trace_}") + logger.error(t("msg-d7b4aa84", trace_=trace_)) raise e elif inspect.iscoroutine(ready_to_call): # 如果只是一个协程, 直接执行 diff --git a/astrbot/core/astr_main_agent.py b/astrbot/core/astr_main_agent.py index 6c1242f61b..126e688949 100644 --- a/astrbot/core/astr_main_agent.py +++ b/astrbot/core/astr_main_agent.py @@ -1,4 +1,5 @@ from __future__ import annotations +from astrbot.core.lang import t import asyncio import copy @@ -137,17 +138,17 @@ def _select_provider( if sel_provider and isinstance(sel_provider, str): provider = plugin_context.get_provider_by_id(sel_provider) if not provider: - logger.error("未找到指定的提供商: %s。", sel_provider) + logger.error(t("msg-8dcf5caa"), sel_provider) if not isinstance(provider, Provider): logger.error( - "选择的提供商类型无效(%s),跳过 LLM 请求处理。", type(provider) + t("msg-61d46ee5"), type(provider) ) return None return provider try: return plugin_context.get_using_provider(umo=event.unified_msg_origin) except ValueError as exc: - logger.error("Error occurred while selecting provider: %s", exc) + logger.error(t("msg-496864bc"), exc) return None @@ -164,7 +165,7 @@ async def _get_session_conv( cid = await conv_mgr.new_conversation(umo, event.get_platform_id()) conversation = await conv_mgr.get_conversation(umo, cid) if not conversation: - raise RuntimeError("无法创建新的对话。") + raise RuntimeError(t("msg-507853eb")) return conversation @@ -190,7 +191,7 @@ async def _apply_kb( f"\n\n[Related Knowledge Base Results]:\n{kb_result}" ) except Exception as exc: # noqa: BLE001 - logger.error("Error occurred while retrieving knowledge base: %s", exc) + logger.error(t("msg-66870b7e"), exc) else: if req.func_tool is None: req.func_tool = ToolSet() @@ -219,7 +220,7 @@ async def _apply_file_extract( req.prompt = "总结一下文件里面讲了什么?" if config.file_extract_prov == "moonshotai": if not config.file_extract_msh_api_key: - logger.error("Moonshot AI API key for file extract is not set") + logger.error(t("msg-36dc1409")) return file_contents = await asyncio.gather( *[ @@ -231,7 +232,7 @@ async def _apply_file_extract( ] ) else: - logger.error("Unsupported file extract provider: %s", config.file_extract_prov) + logger.error(t("msg-8534047e"), config.file_extract_prov) return for file_content, file_name in zip(file_contents, file_names): @@ -419,18 +420,18 @@ async def _request_img_caption( prov = plugin_context.get_provider_by_id(provider_id) if prov is None: raise ValueError( - f"Cannot get image caption because provider `{provider_id}` is not exist.", + t("msg-f2ea29f4", provider_id=provider_id), ) if not isinstance(prov, Provider): raise ValueError( - f"Cannot get image caption because provider `{provider_id}` is not a valid Provider, it is {type(prov)}.", + t("msg-91a70615", provider_id=provider_id, res=type(prov)), ) img_cap_prompt = cfg.get( "image_caption_prompt", "Please describe the image.", ) - logger.debug("Processing image caption with provider: %s", provider_id) + logger.debug(t("msg-b1840df0"), provider_id) llm_resp = await prov.text_chat( prompt=img_cap_prompt, image_urls=image_urls, @@ -457,7 +458,7 @@ async def _ensure_img_caption( ) req.image_urls = [] except Exception as exc: # noqa: BLE001 - logger.error("处理图片描述失败: %s", exc) + logger.error(t("msg-089421fc"), exc) def _append_quoted_image_attachment(req: ProviderRequest, image_path: str) -> None: @@ -530,9 +531,9 @@ async def _process_quote_message( f"[Image Caption in quoted message]: {llm_resp.completion_text}" ) else: - logger.warning("No provider found for image captioning in quote.") + logger.warning(t("msg-719d5e4d")) except BaseException as exc: - logger.error("处理引用图片失败: %s", exc) + logger.error(t("msg-e16a974b"), exc) quoted_content = "\n".join(content_parts) quoted_text = f"\n{quoted_content}\n" @@ -554,7 +555,7 @@ def _append_system_reminders( if cfg.get("group_name_display") and event.message_obj.group_id: if not event.message_obj.group: logger.error( - "Group name display enabled but group object is None. Group ID: %s", + t("msg-037dad2e"), event.message_obj.group_id, ) else: @@ -569,7 +570,7 @@ def _append_system_reminders( now = datetime.datetime.now(zoneinfo.ZoneInfo(timezone)) current_time = now.strftime("%Y-%m-%d %H:%M (%Z)") except Exception as exc: # noqa: BLE001 - logger.error("时区设置错误: %s, 使用本地时区", exc) + logger.error(t("msg-58b47bcd"), exc) if not current_time: current_time = ( datetime.datetime.now().astimezone().strftime("%Y-%m-%d %H:%M (%Z)") @@ -628,7 +629,7 @@ def _modalities_fix(provider: Provider, req: ProviderRequest) -> None: provider_cfg = provider.provider_config.get("modalities", ["image"]) if "image" not in provider_cfg: logger.debug( - "Provider %s does not support image, using placeholder.", provider + t("msg-938af433"), provider ) image_count = len(req.image_urls) placeholder = " ".join(["[图片]"] * image_count) @@ -641,7 +642,7 @@ def _modalities_fix(provider: Provider, req: ProviderRequest) -> None: provider_cfg = provider.provider_config.get("modalities", ["tool_use"]) if "tool_use" not in provider_cfg: logger.debug( - "Provider %s does not support tool_use, clearing tools.", provider + t("msg-83d739f8"), provider ) req.func_tool = None @@ -715,8 +716,7 @@ def _sanitize_context_by_modalities( if removed_image_blocks or removed_tool_messages or removed_tool_calls: logger.debug( - "sanitize_context_by_modalities applied: " - "removed_image_blocks=%s, removed_tool_messages=%s, removed_tool_calls=%s", + t("msg-3dbad2d9"), removed_image_blocks, removed_tool_messages, removed_tool_calls, @@ -776,7 +776,7 @@ async def _handle_webchat( if not title or "" in title: return logger.info( - "Generated chatui title for session %s: %s", chatui_session_id, title + t("msg-4214b760"), chatui_session_id, title ) await db_helper.update_platform_session( session_id=chatui_session_id, @@ -791,7 +791,7 @@ def _apply_llm_safety_mode(config: MainAgentBuildConfig, req: ProviderRequest) - ) else: logger.warning( - "Unsupported llm_safety_mode strategy: %s.", + t("msg-cb6db56e"), config.safety_mode_strategy, ) @@ -805,7 +805,7 @@ def _apply_sandbox_tools( ep = config.sandbox_cfg.get("shipyard_endpoint", "") at = config.sandbox_cfg.get("shipyard_access_token", "") if not ep or not at: - logger.error("Shipyard sandbox configuration is incomplete.") + logger.error(t("msg-7ea2c5d3")) return os.environ["SHIPYARD_ENDPOINT"] = ep os.environ["SHIPYARD_ACCESS_TOKEN"] = at @@ -834,13 +834,13 @@ def _get_compress_provider( provider = plugin_context.get_provider_by_id(config.llm_compress_provider_id) if provider is None: logger.warning( - "未找到指定的上下文压缩模型 %s,将跳过压缩。", + t("msg-9248b273"), config.llm_compress_provider_id, ) return None if not isinstance(provider, Provider): logger.warning( - "指定的上下文压缩模型 %s 不是对话模型,将跳过压缩。", + t("msg-16fe8ea5"), config.llm_compress_provider_id, ) return None @@ -853,7 +853,7 @@ def _get_fallback_chat_providers( fallback_ids = provider_settings.get("fallback_chat_models", []) if not isinstance(fallback_ids, list): logger.warning( - "fallback_chat_models setting is not a list, skip fallback providers." + t("msg-c6c9d989") ) return [] @@ -868,11 +868,11 @@ def _get_fallback_chat_providers( continue fallback_provider = plugin_context.get_provider_by_id(fallback_id) if fallback_provider is None: - logger.warning("Fallback chat provider `%s` not found, skip.", fallback_id) + logger.warning(t("msg-614aebad"), fallback_id) continue if not isinstance(fallback_provider, Provider): logger.warning( - "Fallback chat provider `%s` is invalid type: %s, skip.", + t("msg-1a2e87dd"), fallback_id, type(fallback_provider), ) @@ -897,7 +897,7 @@ async def build_main_agent( """ provider = provider or _select_provider(event, plugin_context) if provider is None: - logger.info("未找到任何对话模型(提供商),跳过 LLM 请求处理。") + logger.info(t("msg-ee979399")) return None if req is None: @@ -984,14 +984,14 @@ async def build_main_agent( ) if remaining_limit <= 0 and fallback_images: logger.warning( - "Skip quoted fallback images due to limit=%d for umo=%s", + t("msg-7a7b4529"), config.max_quoted_fallback_images, event.unified_msg_origin, ) continue if len(fallback_images) > remaining_limit: logger.warning( - "Truncate quoted fallback images for umo=%s, reply_id=%s from %d to %d", + t("msg-46bcda31"), event.unified_msg_origin, getattr(comp, "id", None), len(fallback_images), @@ -1006,7 +1006,7 @@ async def build_main_agent( _append_quoted_image_attachment(req, image_ref) except Exception as exc: # noqa: BLE001 logger.warning( - "Failed to resolve fallback quoted images for umo=%s, reply_id=%s: %s", + t("msg-cbceb923"), event.unified_msg_origin, getattr(comp, "id", None), exc, @@ -1026,7 +1026,7 @@ async def build_main_agent( try: await _apply_file_extract(event, req, config) except Exception as exc: # noqa: BLE001 - logger.error("Error occurred while applying file extract: %s", exc) + logger.error(t("msg-31483e80"), exc) if not req.prompt and not req.image_urls: if not event.get_group_id() and req.extra_user_content_parts: diff --git a/astrbot/core/astr_main_agent_resources.py b/astrbot/core/astr_main_agent_resources.py index 634647e7a7..d092a0ca5f 100644 --- a/astrbot/core/astr_main_agent_resources.py +++ b/astrbot/core/astr_main_agent_resources.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import base64 import json import os @@ -245,10 +246,10 @@ async def _resolve_path_from_sandbox( get_astrbot_temp_path(), f"sandbox_{uuid.uuid4().hex[:4]}_{name}" ) await sb.download_file(path, local_path) - logger.info(f"Downloaded file from sandbox: {path} -> {local_path}") + logger.info(t("msg-509829d8", path=path, local_path=local_path)) return local_path, True except Exception as e: - logger.warning(f"Failed to check/download file from sandbox: {e}") + logger.warning(t("msg-b462b60d", e=e)) # Return the original path (will likely fail later, but that's expected) return path, False @@ -387,7 +388,7 @@ async def retrieve_knowledge_base( # 如果配置为空列表,明确表示不使用知识库 if not kb_ids: - logger.info(f"[知识库] 会话 {umo} 已被配置为不使用知识库") + logger.info(t("msg-0b3144f1", umo=umo)) return top_k = session_config.get("top_k", 5) @@ -400,29 +401,29 @@ async def retrieve_knowledge_base( if kb_helper: kb_names.append(kb_helper.kb.kb_name) else: - logger.warning(f"[知识库] 知识库不存在或未加载: {kb_id}") + logger.warning(t("msg-97e13f98", kb_id=kb_id)) invalid_kb_ids.append(kb_id) if invalid_kb_ids: logger.warning( - f"[知识库] 会话 {umo} 配置的以下知识库无效: {invalid_kb_ids}", + t("msg-312d09c7", umo=umo, invalid_kb_ids=invalid_kb_ids), ) if not kb_names: return - logger.debug(f"[知识库] 使用会话级配置,知识库数量: {len(kb_names)}") + logger.debug(t("msg-42b0e9f8", res=len(kb_names))) else: kb_names = config.get("kb_names", []) top_k = config.get("kb_final_top_k", 5) - logger.debug(f"[知识库] 使用全局配置,知识库数量: {len(kb_names)}") + logger.debug(t("msg-08167007", res=len(kb_names))) top_k_fusion = config.get("kb_fusion_top_k", 20) if not kb_names: return - logger.debug(f"[知识库] 开始检索知识库,数量: {len(kb_names)}, top_k={top_k}") + logger.debug(t("msg-a00becc3", res=len(kb_names), top_k=top_k)) kb_context = await kb_mgr.retrieve( query=query, kb_names=kb_names, @@ -436,7 +437,7 @@ async def retrieve_knowledge_base( formatted = kb_context.get("context_text", "") if formatted: results = kb_context.get("results", []) - logger.debug(f"[知识库] 为会话 {umo} 注入了 {len(results)} 条相关知识块") + logger.debug(t("msg-199e71b7", umo=umo, res=len(results))) return formatted diff --git a/astrbot/core/astrbot_config_mgr.py b/astrbot/core/astrbot_config_mgr.py index c2bfb1c37b..248b754753 100644 --- a/astrbot/core/astrbot_config_mgr.py +++ b/astrbot/core/astrbot_config_mgr.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import os import uuid from typing import TypedDict, TypeVar @@ -68,7 +69,7 @@ def _load_all_configs(self) -> None: self.confs[uuid_] = conf else: logger.warning( - f"Config file {conf_path} for UUID {uuid_} does not exist, skipping.", + t("msg-7875e5bd", conf_path=conf_path, uuid_=uuid_), ) continue @@ -188,7 +189,7 @@ def delete_conf(self, conf_id: str) -> bool: """ if conf_id == "default": - raise ValueError("不能删除默认配置文件") + raise ValueError(t("msg-39c4fd49")) # 从映射中移除 abconf_data = self.sp.get( @@ -198,7 +199,7 @@ def delete_conf(self, conf_id: str) -> bool: scope_id="global", ) if conf_id not in abconf_data: - logger.warning(f"配置文件 {conf_id} 不存在于映射中") + logger.warning(t("msg-cf7b8991", conf_id=conf_id)) return False # 获取配置文件路径 @@ -211,9 +212,9 @@ def delete_conf(self, conf_id: str) -> bool: try: if os.path.exists(conf_path): os.remove(conf_path) - logger.info(f"已删除配置文件: {conf_path}") + logger.info(t("msg-2aad13a4", conf_path=conf_path)) except Exception as e: - logger.error(f"删除配置文件 {conf_path} 失败: {e}") + logger.error(t("msg-94c359ef", conf_path=conf_path, e=e)) return False # 从内存中移除 @@ -225,7 +226,7 @@ def delete_conf(self, conf_id: str) -> bool: self.sp.put("abconf_mapping", abconf_data, scope="global", scope_id="global") self.abconf_data = abconf_data - logger.info(f"成功删除配置文件 {conf_id}") + logger.info(t("msg-44f0b770", conf_id=conf_id)) return True def update_conf_info(self, conf_id: str, name: str | None = None) -> bool: @@ -240,7 +241,7 @@ def update_conf_info(self, conf_id: str, name: str | None = None) -> bool: """ if conf_id == "default": - raise ValueError("不能更新默认配置文件的信息") + raise ValueError(t("msg-737da44e")) abconf_data = self.sp.get( "abconf_mapping", @@ -249,7 +250,7 @@ def update_conf_info(self, conf_id: str, name: str | None = None) -> bool: scope_id="global", ) if conf_id not in abconf_data: - logger.warning(f"配置文件 {conf_id} 不存在于映射中") + logger.warning(t("msg-cf7b8991", conf_id=conf_id)) return False # 更新名称 @@ -259,7 +260,7 @@ def update_conf_info(self, conf_id: str, name: str | None = None) -> bool: # 保存更新 self.sp.put("abconf_mapping", abconf_data, scope="global", scope_id="global") self.abconf_data = abconf_data - logger.info(f"成功更新配置文件 {conf_id} 的信息") + logger.info(t("msg-9d496709", conf_id=conf_id)) return True def g( diff --git a/astrbot/core/backup/exporter.py b/astrbot/core/backup/exporter.py index a922375998..804175c148 100644 --- a/astrbot/core/backup/exporter.py +++ b/astrbot/core/backup/exporter.py @@ -3,6 +3,7 @@ 负责将所有数据导出为 ZIP 备份文件。 导出格式为 JSON,这是数据库无关的方案,支持未来向 MySQL/PostgreSQL 迁移。 """ +from astrbot.core.lang import t import hashlib import json @@ -89,7 +90,7 @@ async def export_all( zip_filename = f"astrbot_backup_{timestamp}.zip" zip_path = os.path.join(output_dir, zip_filename) - logger.info(f"开始导出备份到 {zip_path}") + logger.info(t("msg-c7ed7177", zip_path=zip_path)) try: with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as zf: @@ -193,11 +194,11 @@ async def export_all( if progress_callback: await progress_callback("manifest", 100, 100, "清单生成完成") - logger.info(f"备份导出完成: {zip_path}") + logger.info(t("msg-8099b694", zip_path=zip_path)) return zip_path except Exception as e: - logger.error(f"备份导出失败: {e}") + logger.error(t("msg-75a4910d", e=e)) # 清理失败的文件 if os.path.exists(zip_path): os.remove(zip_path) @@ -216,10 +217,10 @@ async def _export_main_database(self) -> dict[str, list[dict]]: self._model_to_dict(record) for record in records ] logger.debug( - f"导出表 {table_name}: {len(export_data[table_name])} 条记录" + t("msg-2821fc92", table_name=table_name, res=len(export_data[table_name])) ) except Exception as e: - logger.warning(f"导出表 {table_name} 失败: {e}") + logger.warning(t("msg-52b7c242", table_name=table_name, e=e)) export_data[table_name] = [] return export_data @@ -240,10 +241,10 @@ async def _export_kb_metadata(self) -> dict[str, list[dict]]: self._model_to_dict(record) for record in records ] logger.debug( - f"导出知识库表 {table_name}: {len(export_data[table_name])} 条记录" + t("msg-56310830", table_name=table_name, res=len(export_data[table_name])) ) except Exception as e: - logger.warning(f"导出知识库表 {table_name} 失败: {e}") + logger.warning(t("msg-f4e8f57e", table_name=table_name, e=e)) export_data[table_name] = [] return export_data @@ -266,7 +267,7 @@ async def _export_kb_documents(self, kb_helper: Any) -> dict[str, Any]: return {"documents": docs} except Exception as e: - logger.warning(f"导出知识库文档失败: {e}") + logger.warning(t("msg-8e4ddd12", e=e)) return {"documents": []} async def _export_faiss_index( @@ -281,9 +282,9 @@ async def _export_faiss_index( if index_path.exists(): archive_path = f"databases/kb_{kb_id}/index.faiss" zf.write(str(index_path), archive_path) - logger.debug(f"导出 FAISS 索引: {archive_path}") + logger.debug(t("msg-c1960618", archive_path=archive_path)) except Exception as e: - logger.warning(f"导出 FAISS 索引失败: {e}") + logger.warning(t("msg-314bf920", e=e)) async def _export_kb_media_files( self, zf: zipfile.ZipFile, kb_helper: Any, kb_id: str @@ -302,7 +303,7 @@ async def _export_kb_media_files( archive_path = f"files/kb_media/{kb_id}/{rel_path}" zf.write(str(file_path), archive_path) except Exception as e: - logger.warning(f"导出知识库媒体文件失败: {e}") + logger.warning(t("msg-528757b2", e=e)) async def _export_directories( self, zf: zipfile.ZipFile @@ -318,7 +319,7 @@ async def _export_directories( for dir_name, dir_path in backup_directories.items(): full_path = Path(dir_path) if not full_path.exists(): - logger.debug(f"目录不存在,跳过: {full_path}") + logger.debug(t("msg-d89d6dfe", full_path=full_path)) continue file_count = 0 @@ -343,14 +344,14 @@ async def _export_directories( file_count += 1 total_size += file_path.stat().st_size except Exception as e: - logger.warning(f"导出文件 {file_path} 失败: {e}") + logger.warning(t("msg-94527edd", file_path=file_path, e=e)) stats[dir_name] = {"files": file_count, "size": total_size} logger.debug( - f"导出目录 {dir_name}: {file_count} 个文件, {total_size} 字节" + t("msg-cb773e24", dir_name=dir_name, file_count=file_count, total_size=total_size) ) except Exception as e: - logger.warning(f"导出目录 {dir_path} 失败: {e}") + logger.warning(t("msg-ae929510", dir_path=dir_path, e=e)) stats[dir_name] = {"files": 0, "size": 0} return stats @@ -369,7 +370,7 @@ async def _export_attachments( archive_path = f"files/attachments/{attachment_id}{ext}" zf.write(file_path, archive_path) except Exception as e: - logger.warning(f"导出附件失败: {e}") + logger.warning(t("msg-93e331d2", e=e)) def _model_to_dict(self, record: Any) -> dict: """将 SQLModel 实例转换为字典 diff --git a/astrbot/core/backup/importer.py b/astrbot/core/backup/importer.py index 2e67f85e5c..a316468145 100644 --- a/astrbot/core/backup/importer.py +++ b/astrbot/core/backup/importer.py @@ -6,6 +6,7 @@ - 小版本(第三位)不同时提示警告,用户可选择强制导入 - 版本匹配时也需要用户确认 """ +from astrbot.core.lang import t import json import os @@ -120,12 +121,12 @@ def __init__(self) -> None: def add_warning(self, msg: str) -> None: self.warnings.append(msg) - logger.warning(msg) + logger.warning(t("msg-c046b6e4", msg=msg)) def add_error(self, msg: str) -> None: self.errors.append(msg) self.success = False - logger.error(msg) + logger.error(t("msg-c046b6e4", msg=msg)) def to_dict(self) -> dict: return { @@ -301,7 +302,7 @@ async def import_all( result.add_error(f"备份文件不存在: {zip_path}") return result - logger.info(f"开始从 {zip_path} 导入备份") + logger.info(t("msg-0e6f1f5d", zip_path=zip_path)) try: with zipfile.ZipFile(zip_path, "r") as zf: @@ -413,7 +414,7 @@ async def import_all( if progress_callback: await progress_callback("directories", 100, 100, "目录导入完成") - logger.info(f"备份导入完成: {result.to_dict()}") + logger.info(t("msg-2bf97ca0", res=result.to_dict())) return result except zipfile.BadZipFile: @@ -431,7 +432,7 @@ def _validate_version(self, manifest: dict) -> None: """ backup_version = manifest.get("astrbot_version") if not backup_version: - raise ValueError("备份文件缺少版本信息") + raise ValueError(t("msg-e67dda98")) # 使用新的版本兼容性检查 version_check = self._check_version_compatibility(backup_version) @@ -441,7 +442,7 @@ def _validate_version(self, manifest: dict) -> None: # minor_diff 和 match 都允许导入 if version_check["status"] == "minor_diff": - logger.warning(f"版本差异警告: {version_check['message']}") + logger.warning(t("msg-8f871d9f", res=version_check['message'])) async def _clear_main_db(self) -> None: """清空主数据库所有表""" @@ -450,9 +451,9 @@ async def _clear_main_db(self) -> None: for table_name, model_class in MAIN_DB_MODELS.items(): try: await session.execute(delete(model_class)) - logger.debug(f"已清空表 {table_name}") + logger.debug(t("msg-2d6da12a", table_name=table_name)) except Exception as e: - logger.warning(f"清空表 {table_name} 失败: {e}") + logger.warning(t("msg-7d21b23a", table_name=table_name, e=e)) async def _clear_kb_data(self) -> None: """清空知识库数据""" @@ -465,9 +466,9 @@ async def _clear_kb_data(self) -> None: for table_name, model_class in KB_METADATA_MODELS.items(): try: await session.execute(delete(model_class)) - logger.debug(f"已清空知识库表 {table_name}") + logger.debug(t("msg-ab0f09db", table_name=table_name)) except Exception as e: - logger.warning(f"清空知识库表 {table_name} 失败: {e}") + logger.warning(t("msg-7bcdfaee", table_name=table_name, e=e)) # 删除知识库文件目录 for kb_id in list(self.kb_manager.kb_insts.keys()): @@ -477,7 +478,7 @@ async def _clear_kb_data(self) -> None: if kb_helper.kb_dir.exists(): shutil.rmtree(kb_helper.kb_dir) except Exception as e: - logger.warning(f"清理知识库 {kb_id} 失败: {e}") + logger.warning(t("msg-43f008f1", kb_id=kb_id, e=e)) self.kb_manager.kb_insts.clear() @@ -492,7 +493,7 @@ async def _import_main_database( for table_name, rows in data.items(): model_class = MAIN_DB_MODELS.get(table_name) if not model_class: - logger.warning(f"未知的表: {table_name}") + logger.warning(t("msg-985cae66", table_name=table_name)) continue count = 0 @@ -504,10 +505,10 @@ async def _import_main_database( session.add(obj) count += 1 except Exception as e: - logger.warning(f"导入记录到 {table_name} 失败: {e}") + logger.warning(t("msg-dfa8b605", table_name=table_name, e=e)) imported[table_name] = count - logger.debug(f"导入表 {table_name}: {count} 条记录") + logger.debug(t("msg-89a2120c", table_name=table_name, count=count)) return imported @@ -537,7 +538,7 @@ async def _import_knowledge_bases( session.add(obj) count += 1 except Exception as e: - logger.warning(f"导入知识库记录到 {table_name} 失败: {e}") + logger.warning(t("msg-f1dec753", table_name=table_name, e=e)) result.imported_tables[f"kb_{table_name}"] = count @@ -610,7 +611,7 @@ async def _import_kb_documents(self, kb_id: str, doc_data: dict) -> None: metadata=json.loads(doc.get("metadata", "{}")), ) except Exception as e: - logger.warning(f"导入文档块失败: {e}") + logger.warning(t("msg-9807bcd8", e=e)) finally: await doc_storage.close() @@ -647,7 +648,7 @@ async def _import_attachments( dst.write(src.read()) count += 1 except Exception as e: - logger.warning(f"导入附件 {name} 失败: {e}") + logger.warning(t("msg-98a66293", name=name, e=e)) return count @@ -672,7 +673,7 @@ async def _import_directories( # 检查备份版本是否支持目录备份(需要版本 >= 1.1) backup_version = manifest.get("version", "1.0") if VersionComparator.compare_version(backup_version, "1.1") < 0: - logger.info("备份版本不支持目录备份,跳过目录导入") + logger.info(t("msg-39f2325f")) return dir_stats backed_up_dirs = manifest.get("directories", []) @@ -705,7 +706,7 @@ async def _import_directories( if backup_path.exists(): shutil.rmtree(backup_path) shutil.move(str(target_dir), str(backup_path)) - logger.debug(f"已备份现有目录 {target_dir} 到 {backup_path}") + logger.debug(t("msg-689050b6", target_dir=target_dir, backup_path=backup_path)) # 创建目标目录 target_dir.mkdir(parents=True, exist_ok=True) @@ -728,7 +729,7 @@ async def _import_directories( result.add_warning(f"导入文件 {name} 失败: {e}") dir_stats[dir_name] = file_count - logger.debug(f"导入目录 {dir_name}: {file_count} 个文件") + logger.debug(t("msg-d51b3536", dir_name=dir_name, file_count=file_count)) except Exception as e: result.add_warning(f"导入目录 {dir_name} 失败: {e}") diff --git a/astrbot/core/computer/booters/boxlite.py b/astrbot/core/computer/booters/boxlite.py index 373f6cee04..f08f3ed46d 100644 --- a/astrbot/core/computer/booters/boxlite.py +++ b/astrbot/core/computer/booters/boxlite.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import random from typing import Any @@ -37,7 +38,7 @@ async def _exec_operation( else: error_text = await response.text() raise Exception( - f"Failed to exec operation: {response.status} {error_text}" + t("msg-019c4d18", res=response.status, error_text=error_text) ) async def upload_file(self, path: str, remote_path: str) -> dict: @@ -78,7 +79,7 @@ async def upload_file(self, path: str, remote_path: str) -> dict: } except aiohttp.ClientError as e: - logger.error(f"Failed to upload file: {e}") + logger.error(t("msg-b135b7bd", e=e)) return { "success": False, "error": f"Connection error: {str(e)}", @@ -91,14 +92,14 @@ async def upload_file(self, path: str, remote_path: str) -> dict: "message": "File upload failed", } except FileNotFoundError: - logger.error(f"File not found: {path}") + logger.error(t("msg-873ed1c8", path=path)) return { "success": False, "error": f"File not found: {path}", "message": "File upload failed", } except Exception as e: - logger.error(f"Unexpected error uploading file: {e}") + logger.error(t("msg-f58ceec6", e=e)) return { "success": False, "error": f"Internal error: {str(e)}", @@ -111,13 +112,13 @@ async def wait_healthy(self, ship_id: str, session_id: str) -> None: while loop > 0: try: logger.info( - f"Checking health for sandbox {ship_id} on {self.sb_url}..." + t("msg-900ab999", ship_id=ship_id, res=self.sb_url) ) url = f"{self.sb_url}/health" async with aiohttp.ClientSession() as session: async with session.get(url) as response: if response.status == 200: - logger.info(f"Sandbox {ship_id} is healthy") + logger.info(t("msg-2a50d6f3", ship_id=ship_id)) return except Exception: await asyncio.sleep(1) @@ -127,7 +128,7 @@ async def wait_healthy(self, ship_id: str, session_id: str) -> None: class BoxliteBooter(ComputerBooter): async def boot(self, session_id: str) -> None: logger.info( - f"Booting(Boxlite) for session: {session_id}, this may take a while..." + t("msg-fbdbe32f", session_id=session_id) ) random_port = random.randint(20000, 30000) self.box = boxlite.SimpleBox( @@ -142,7 +143,7 @@ async def boot(self, session_id: str) -> None: ], ) await self.box.start() - logger.info(f"Boxlite booter started for session: {session_id}") + logger.info(t("msg-b1f13f5f", session_id=session_id)) self.mocked = MockShipyardSandboxClient( sb_url=f"http://127.0.0.1:{random_port}" ) @@ -165,9 +166,9 @@ async def boot(self, session_id: str) -> None: await self.mocked.wait_healthy(self.box.id, session_id) async def shutdown(self) -> None: - logger.info(f"Shutting down Boxlite booter for ship: {self.box.id}") + logger.info(t("msg-e93d0c30", res=self.box.id)) self.box.shutdown() - logger.info(f"Boxlite booter for ship: {self.box.id} stopped") + logger.info(t("msg-6deea473", res=self.box.id)) @property def fs(self) -> FileSystemComponent: diff --git a/astrbot/core/computer/booters/local.py b/astrbot/core/computer/booters/local.py index a80ef0da28..27eea1829c 100644 --- a/astrbot/core/computer/booters/local.py +++ b/astrbot/core/computer/booters/local.py @@ -1,4 +1,5 @@ from __future__ import annotations +from astrbot.core.lang import t import asyncio import os @@ -48,7 +49,7 @@ def _ensure_safe_path(path: str) -> str: os.path.abspath(get_astrbot_temp_path()), ] if not any(abs_path.startswith(root) for root in allowed_roots): - raise PermissionError("Path is outside the allowed computer roots.") + raise PermissionError(t("msg-487d0c91")) return abs_path @@ -64,7 +65,7 @@ async def exec( background: bool = False, ) -> dict[str, Any]: if not _is_safe_command(command): - raise PermissionError("Blocked unsafe shell command.") + raise PermissionError(t("msg-e5eb5377")) def _run() -> dict[str, Any]: run_env = os.environ.copy() @@ -203,10 +204,10 @@ def __init__(self) -> None: self._shell = LocalShellComponent() async def boot(self, session_id: str) -> None: - logger.info(f"Local computer booter initialized for session: {session_id}") + logger.info(t("msg-9e1e117f", session_id=session_id)) async def shutdown(self) -> None: - logger.info("Local computer booter shutdown complete.") + logger.info(t("msg-2d7f95de")) @property def fs(self) -> FileSystemComponent: @@ -222,12 +223,12 @@ def shell(self) -> ShellComponent: async def upload_file(self, path: str, file_name: str) -> dict: raise NotImplementedError( - "LocalBooter does not support upload_file operation. Use shell instead." + t("msg-82a45196") ) async def download_file(self, remote_path: str, local_path: str) -> None: raise NotImplementedError( - "LocalBooter does not support download_file operation. Use shell instead." + t("msg-0457524a") ) async def available(self) -> bool: diff --git a/astrbot/core/computer/booters/shipyard.py b/astrbot/core/computer/booters/shipyard.py index b13503431c..317b325a52 100644 --- a/astrbot/core/computer/booters/shipyard.py +++ b/astrbot/core/computer/booters/shipyard.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t from shipyard import ShipyardClient, Spec from astrbot.api import logger @@ -27,7 +28,7 @@ async def boot(self, session_id: str) -> None: max_session_num=self._session_num, session_id=session_id, ) - logger.info(f"Got sandbox ship: {ship.id} for session: {session_id}") + logger.info(t("msg-b03115b0", res=ship.id, session_id=session_id)) self._ship = ship async def shutdown(self) -> None: @@ -63,5 +64,5 @@ async def available(self) -> bool: health = bool(data.get("status", 0) == 1) return health except Exception as e: - logger.error(f"Error checking Shipyard sandbox availability: {e}") + logger.error(t("msg-c5ce8bde", e=e)) return False diff --git a/astrbot/core/computer/computer_client.py b/astrbot/core/computer/computer_client.py index 9750e7b642..58bcd153d5 100644 --- a/astrbot/core/computer/computer_client.py +++ b/astrbot/core/computer/computer_client.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import os import shutil import uuid @@ -35,11 +36,11 @@ async def _sync_skills_to_sandbox(booter: ComputerBooter) -> None: os.remove(zip_path) shutil.make_archive(zip_base, "zip", skills_root) remote_zip = Path(SANDBOX_SKILLS_ROOT) / "skills.zip" - logger.info("Uploading skills bundle to sandbox...") + logger.info(t("msg-7cb974b8")) await booter.shell.exec(f"mkdir -p {SANDBOX_SKILLS_ROOT}") upload_result = await booter.upload_file(zip_path, str(remote_zip)) if not upload_result.get("success", False): - raise RuntimeError("Failed to upload skills bundle to sandbox.") + raise RuntimeError(t("msg-130cf3e3")) # Use -n flag to never overwrite existing files, fallback to Python if unzip unavailable await booter.shell.exec( f"unzip -n {remote_zip} -d {SANDBOX_SKILLS_ROOT} || " @@ -56,7 +57,7 @@ async def _sync_skills_to_sandbox(booter: ComputerBooter) -> None: try: os.remove(zip_path) except Exception: - logger.warning(f"Failed to remove temp skills zip: {zip_path}") + logger.warning(t("msg-99188d69", zip_path=zip_path)) async def get_booter( @@ -91,13 +92,13 @@ async def get_booter( client = BoxliteBooter() else: - raise ValueError(f"Unknown booter type: {booter_type}") + raise ValueError(t("msg-3f3c81da", booter_type=booter_type)) try: await client.boot(uuid_str) await _sync_skills_to_sandbox(client) except Exception as e: - logger.error(f"Error booting sandbox for session {session_id}: {e}") + logger.error(t("msg-e20cc33a", session_id=session_id, e=e)) raise e session_booter[session_id] = client diff --git a/astrbot/core/computer/tools/fs.py b/astrbot/core/computer/tools/fs.py index 31b7f3f513..8fc7feff0d 100644 --- a/astrbot/core/computer/tools/fs.py +++ b/astrbot/core/computer/tools/fs.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import os import uuid from dataclasses import dataclass, field @@ -122,18 +123,18 @@ async def call( # Upload file to sandbox result = await sb.upload_file(local_path, remote_path) - logger.debug(f"Upload result: {result}") + logger.debug(t("msg-99ab0efe", result=result)) success = result.get("success", False) if not success: return f"Error uploading file: {result.get('message', 'Unknown error')}" file_path = result.get("file_path", "") - logger.info(f"File {local_path} uploaded to sandbox at {file_path}") + logger.info(t("msg-bca9d578", local_path=local_path, file_path=file_path)) return f"File uploaded successfully to {file_path}" except Exception as e: - logger.error(f"Error uploading file {local_path}: {e}") + logger.error(t("msg-da21a6a5", local_path=local_path, e=e)) return f"Error uploading file: {str(e)}" @@ -179,7 +180,7 @@ async def call( # Download file from sandbox await sb.download_file(remote_path, local_path) - logger.info(f"File {remote_path} downloaded from sandbox to {local_path}") + logger.info(t("msg-93476abb", remote_path=remote_path, local_path=local_path)) if also_send_to_user: try: @@ -188,7 +189,7 @@ async def call( MessageChain(chain=[File(name=name, file=local_path)]) ) except Exception as e: - logger.error(f"Error sending file message: {e}") + logger.error(t("msg-079c5972", e=e)) # remove # try: @@ -200,5 +201,5 @@ async def call( return f"File downloaded successfully to {local_path}" except Exception as e: - logger.error(f"Error downloading file {remote_path}: {e}") + logger.error(t("msg-ce35bb2c", remote_path=remote_path, e=e)) return f"Error downloading file: {str(e)}" diff --git a/astrbot/core/config/astrbot_config.py b/astrbot/core/config/astrbot_config.py index 6a415e56c9..8cfa5f4b01 100644 --- a/astrbot/core/config/astrbot_config.py +++ b/astrbot/core/config/astrbot_config.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import enum import json import logging @@ -73,7 +74,7 @@ def _parse_schema(schema: dict, conf: dict) -> None: for k, v in schema.items(): if v["type"] not in DEFAULT_VALUE_MAP: raise TypeError( - f"不受支持的配置类型 {v['type']}。支持的类型有:{DEFAULT_VALUE_MAP.keys()}", + t("msg-e0a69978", res=v['type'], res_2=DEFAULT_VALUE_MAP.keys()), ) if "default" in v: default = v["default"] @@ -104,7 +105,7 @@ def check_config_integrity(self, refer_conf: dict, conf: dict, path=""): if key not in conf: # 配置项不存在,插入默认值 path_ = path + "." + key if path else key - logger.info(f"检查到配置项 {path_} 不存在,已插入默认值 {value}") + logger.info(t("msg-b9583fc9", path_=path_, value=value)) new_conf[key] = value has_new = True elif conf[key] is None: @@ -134,15 +135,15 @@ def check_config_integrity(self, refer_conf: dict, conf: dict, path=""): for key in list(conf.keys()): if key not in refer_conf: path_ = path + "." + key if path else key - logger.info(f"检查到配置项 {path_} 不存在,将从当前配置中删除") + logger.info(t("msg-ee26e40e", path_=path_)) has_new = True # 顺序不一致也算作变更 if list(conf.keys()) != list(new_conf.keys()): if path: - logger.info(f"检查到配置项 {path} 的子项顺序不一致,已重新排序") + logger.info(t("msg-2d7497a5", path=path)) else: - logger.info("检查到配置项顺序不一致,已重新排序") + logger.info(t("msg-5fdad937")) has_new = True # 更新原始配置 @@ -172,7 +173,7 @@ def __delattr__(self, key) -> None: del self[key] self.save_config() except KeyError: - raise AttributeError(f"没有找到 Key: '{key}'") + raise AttributeError(t("msg-555373b0", key=key)) def __setattr__(self, key, value) -> None: self[key] = value diff --git a/astrbot/core/conversation_mgr.py b/astrbot/core/conversation_mgr.py index 6fcb3608c3..3c5b0109fd 100644 --- a/astrbot/core/conversation_mgr.py +++ b/astrbot/core/conversation_mgr.py @@ -3,6 +3,7 @@ 在 AstrBot 中, 会话和对话是独立的, 会话用于标记对话窗口, 例如群聊"123456789"可以建立一个会话, 在一个会话中可以建立多个对话, 并且支持对话的切换和删除 """ +from astrbot.core.lang import t import json from collections.abc import Awaitable, Callable @@ -53,7 +54,7 @@ async def _trigger_session_deleted(self, unified_msg_origin: str) -> None: from astrbot.core import logger logger.error( - f"会话删除回调执行失败 (session: {unified_msg_origin}): {e}", + t("msg-86f404dd", unified_msg_origin=unified_msg_origin, e=e), ) def _convert_conv_from_v2_to_v1(self, conv_v2: ConversationV2) -> Conversation: @@ -344,7 +345,7 @@ async def add_message_pair( """ conv = await self.db.get_conversation_by_id(cid=cid) if not conv: - raise Exception(f"Conversation with id {cid} not found") + raise Exception(t("msg-57dcc41f", cid=cid)) history = conv.content or [] if isinstance(user_message, UserMessageSegment): user_msg_dict = user_message.model_dump() diff --git a/astrbot/core/core_lifecycle.py b/astrbot/core/core_lifecycle.py index 758cf1ccd0..1c85b19262 100644 --- a/astrbot/core/core_lifecycle.py +++ b/astrbot/core/core_lifecycle.py @@ -8,6 +8,7 @@ 2. 启动事件总线和任务, 所有任务都在这里运行 3. 执行启动完成事件钩子 """ +from astrbot.core.lang import t import asyncio import os @@ -65,7 +66,7 @@ def __init__(self, log_broker: LogBroker, db: BaseDatabase) -> None: if proxy_config != "": os.environ["https_proxy"] = proxy_config os.environ["http_proxy"] = proxy_config - logger.debug(f"Using proxy: {proxy_config}") + logger.debug(t("msg-9967ec8b", proxy_config=proxy_config)) # 设置 no_proxy no_proxy_list = self.astrbot_config.get("no_proxy", []) os.environ["no_proxy"] = ",".join(no_proxy_list) @@ -77,7 +78,7 @@ def __init__(self, log_broker: LogBroker, db: BaseDatabase) -> None: del os.environ["http_proxy"] if "no_proxy" in os.environ: del os.environ["no_proxy"] - logger.debug("HTTP proxy cleared") + logger.debug(t("msg-5a29b73d")) async def _init_or_reload_subagent_orchestrator(self) -> None: """Create (if needed) and reload the subagent orchestrator from config. @@ -95,7 +96,7 @@ async def _init_or_reload_subagent_orchestrator(self) -> None: self.astrbot_config.get("subagent_orchestrator", {}), ) except Exception as e: - logger.error(f"Subagent orchestrator init failed: {e}", exc_info=True) + logger.error(t("msg-fafb87ce", e=e), exc_info=True) async def initialize(self) -> None: """初始化 AstrBot 核心生命周期管理类. @@ -143,8 +144,8 @@ async def initialize(self) -> None: self.astrbot_config_mgr, ) except Exception as e: - logger.error(f"AstrBot migration failed: {e!s}") - logger.error(traceback.format_exc()) + logger.error(t("msg-f7861f86", e=e)) + logger.error(t("msg-78b9c276", res=traceback.format_exc())) # 初始化事件队列 self.event_queue = Queue() @@ -283,10 +284,10 @@ async def _task_wrapper(self, task: asyncio.Task) -> None: pass # 任务被取消, 静默处理 except Exception as e: # 获取完整的异常堆栈信息, 按行分割并记录到日志中 - logger.error(f"------- 任务 {task.get_name()} 发生错误: {e}") + logger.error(t("msg-967606fd", res=task.get_name(), e=e)) for line in traceback.format_exc().split("\n"): - logger.error(f"| {line}") - logger.error("-------") + logger.error(t("msg-a2cd77f3", line=line)) + logger.error(t("msg-1f686eeb")) async def start(self) -> None: """启动 AstrBot 核心生命周期管理类. @@ -294,7 +295,7 @@ async def start(self) -> None: 用load加载事件总线和任务并初始化, 执行启动完成事件钩子 """ self._load() - logger.info("AstrBot 启动完成。") + logger.info(t("msg-9556d279")) # 执行启动完成事件钩子 handlers = star_handlers_registry.get_handlers_by_event_type( @@ -303,11 +304,11 @@ async def start(self) -> None: for handler in handlers: try: logger.info( - f"hook(on_astrbot_loaded) -> {star_map[handler.handler_module_path].name} - {handler.handler_name}", + t("msg-daaf690b", res=star_map[handler.handler_module_path].name, res_2=handler.handler_name), ) await handler.handler() except BaseException: - logger.error(traceback.format_exc()) + logger.error(t("msg-78b9c276", res=traceback.format_exc())) # 同时运行curr_tasks中的所有任务 await asyncio.gather(*self.curr_tasks, return_exceptions=True) @@ -328,9 +329,9 @@ async def stop(self) -> None: try: await self.plugin_manager._terminate_plugin(plugin) except Exception as e: - logger.warning(traceback.format_exc()) + logger.warning(t("msg-78b9c276", res=traceback.format_exc())) logger.warning( - f"插件 {plugin.name} 未被正常终止 {e!s}, 可能会导致资源泄露等问题。", + t("msg-4719cb33", res=plugin.name, e=e), ) await self.provider_manager.terminate() @@ -345,7 +346,7 @@ async def stop(self) -> None: except asyncio.CancelledError: pass except Exception as e: - logger.error(f"任务 {task.get_name()} 发生错误: {e}") + logger.error(t("msg-c3bbfa1d", res=task.get_name(), e=e)) async def restart(self) -> None: """重启 AstrBot 核心生命周期管理类, 终止各个管理器并重新加载平台实例""" @@ -397,7 +398,7 @@ async def reload_pipeline_scheduler(self, conf_id: str) -> None: """ ab_config = self.astrbot_config_mgr.confs.get(conf_id) if not ab_config: - raise ValueError(f"配置文件 {conf_id} 不存在") + raise ValueError(t("msg-af06ccab", conf_id=conf_id)) scheduler = PipelineScheduler( PipelineContext(ab_config, self.plugin_manager, conf_id), ) diff --git a/astrbot/core/cron/manager.py b/astrbot/core/cron/manager.py index d12878be3e..8fa0603f10 100644 --- a/astrbot/core/cron/manager.py +++ b/astrbot/core/cron/manager.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import json from collections.abc import Awaitable, Callable @@ -55,7 +56,7 @@ async def sync_from_db(self) -> None: continue if job.job_type == "basic" and job.job_id not in self._basic_handlers: logger.warning( - "Skip scheduling basic cron job %s due to missing handler.", + t("msg-724e64a9"), job.job_id, ) continue @@ -151,7 +152,7 @@ def _schedule_job(self, job: CronJob) -> None: tzinfo = ZoneInfo(job.timezone) except Exception: logger.warning( - "Invalid timezone %s for cron job %s, fallback to system.", + t("msg-78ef135f"), job.timezone, job.job_id, ) @@ -161,7 +162,7 @@ def _schedule_job(self, job: CronJob) -> None: run_at_str = job.payload.get("run_at") run_at_str = run_at_str or job.cron_expression if not run_at_str: - raise ValueError("run_once job missing run_at timestamp") + raise ValueError(t("msg-e71c28d3")) run_at = datetime.fromisoformat(run_at_str) if run_at.tzinfo is None and tzinfo is not None: run_at = run_at.replace(tzinfo=tzinfo) @@ -182,7 +183,7 @@ def _schedule_job(self, job: CronJob) -> None: ) ) except Exception as e: - logger.error(f"Failed to schedule cron job {job.job_id}: {e!s}") + logger.error(t("msg-dd46e69f", res=job.job_id, e=e)) def _get_next_run_time(self, job_id: str): aps_job = self.scheduler.get_job(job_id) @@ -204,11 +205,11 @@ async def _run_job(self, job_id: str) -> None: elif job.job_type == "active_agent": await self._run_active_agent_job(job, start_time=start_time) else: - raise ValueError(f"Unknown cron job type: {job.job_type}") + raise ValueError(t("msg-aa2e4688", res=job.job_type)) except Exception as e: # noqa: BLE001 status = "failed" last_error = str(e) - logger.error(f"Cron job {job_id} failed: {e!s}", exc_info=True) + logger.error(t("msg-186627d9", job_id=job_id, e=e), exc_info=True) finally: next_run = self._get_next_run_time(job_id) await self.db.update_cron_job( @@ -225,7 +226,7 @@ async def _run_job(self, job_id: str) -> None: async def _run_basic_job(self, job: CronJob) -> None: handler = self._basic_handlers.get(job.job_id) if not handler: - raise RuntimeError(f"Basic cron job handler not found for {job.job_id}") + raise RuntimeError(t("msg-cb955de0", res=job.job_id)) payload = job.payload or {} result = handler(**payload) if payload else handler() if asyncio.iscoroutine(result): @@ -235,7 +236,7 @@ async def _run_active_agent_job(self, job: CronJob, start_time: datetime) -> Non payload = job.payload or {} session_str = payload.get("session") if not session_str: - raise ValueError("ActiveAgentCronJob missing session.") + raise ValueError(t("msg-2029c4b2")) note = payload.get("note") or job.description or job.name extras = { @@ -285,7 +286,7 @@ async def _woke_main_agent( else MessageSession.from_str(session_str) ) except Exception as e: # noqa: BLE001 - logger.error(f"Invalid session for cron job: {e}") + logger.error(t("msg-6babddc9", e=e)) return cron_event = CronMessageEvent( @@ -345,7 +346,7 @@ async def _woke_main_agent( event=cron_event, plugin_context=self.ctx, config=config, req=req ) if not result: - logger.error("Failed to build main agent for cron job.") + logger.error(t("msg-865a2b07")) return runner = result.agent_runner @@ -370,7 +371,7 @@ async def _woke_main_agent( summary_note=summary_note, ) if not llm_resp: - logger.warning("Cron job agent got no response") + logger.warning(t("msg-27c9c6b3")) return diff --git a/astrbot/core/db/migration/helper.py b/astrbot/core/db/migration/helper.py index d7bca30678..4de9d20dad 100644 --- a/astrbot/core/db/migration/helper.py +++ b/astrbot/core/db/migration/helper.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import os from astrbot.api import logger, sp @@ -46,7 +47,7 @@ async def do_migration_v4( if not await check_migration_needed_v4(db_helper): return - logger.info("开始执行数据库迁移...") + logger.info(t("msg-a48f4752")) # 执行会话表迁移 await migration_conversation_table(db_helper, platform_id_map) @@ -66,4 +67,4 @@ async def do_migration_v4( # 标记迁移完成 await sp.put_async("global", "global", "migration_done_v4", True) - logger.info("数据库迁移完成。") + logger.info(t("msg-45e31e8e")) diff --git a/astrbot/core/db/migration/migra_3_to_4.py b/astrbot/core/db/migration/migra_3_to_4.py index 727d97b29b..9dd66be675 100644 --- a/astrbot/core/db/migration/migra_3_to_4.py +++ b/astrbot/core/db/migration/migra_3_to_4.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import datetime import json @@ -51,7 +52,7 @@ async def migration_conversation_table( page=1, page_size=10000000, ) - logger.info(f"迁移 {total_cnt} 条旧的会话数据到新的表中...") + logger.info(t("msg-7805b529", total_cnt=total_cnt)) async with db_helper.get_db() as dbsession: dbsession: AsyncSession @@ -60,7 +61,7 @@ async def migration_conversation_table( if total_cnt > 0 and (idx + 1) % max(1, total_cnt // 10) == 0: progress = int((idx + 1) / total_cnt * 100) if progress % 10 == 0: - logger.info(f"进度: {progress}% ({idx + 1}/{total_cnt})") + logger.info(t("msg-6f232b73", progress=progress, res=idx + 1, total_cnt=total_cnt)) try: conv = db_helper_v3.get_conversation_by_user_id( user_id=conversation.get("user_id", "unknown"), @@ -68,7 +69,7 @@ async def migration_conversation_table( ) if not conv: logger.info( - f"未找到该条旧会话对应的具体数据: {conversation}, 跳过。", + t("msg-6b1def31", conversation=conversation), ) continue if ":" not in conv.user_id: @@ -92,10 +93,10 @@ async def migration_conversation_table( dbsession.add(conv_v2) except Exception as e: logger.error( - f"迁移旧会话 {conversation.get('cid', 'unknown')} 失败: {e}", + t("msg-b008c93f", res=conversation.get('cid', 'unknown'), e=e), exc_info=True, ) - logger.info(f"成功迁移 {total_cnt} 条旧的会话数据到新表。") + logger.info(t("msg-6ac6313b", total_cnt=total_cnt)) async def migration_platform_table( @@ -110,13 +111,13 @@ async def migration_platform_table( - datetime.datetime(2023, 4, 10, tzinfo=datetime.timezone.utc) ).total_seconds() offset_sec = int(secs_from_2023_4_10_to_now) - logger.info(f"迁移旧平台数据,offset_sec: {offset_sec} 秒。") + logger.info(t("msg-6b72e89b", offset_sec=offset_sec)) stats = db_helper_v3.get_base_stats(offset_sec=offset_sec) - logger.info(f"迁移 {len(stats.platform)} 条旧的平台数据到新的表中...") + logger.info(t("msg-bdc90b84", res=len(stats.platform))) platform_stats_v3 = stats.platform if not platform_stats_v3: - logger.info("没有找到旧平台数据,跳过迁移。") + logger.info(t("msg-e6caca5c")) return first_time_stamp = platform_stats_v3[0].timestamp @@ -133,7 +134,7 @@ async def migration_platform_table( for bucket_idx, bucket_end in enumerate(range(start_time, end_time, 3600)): if bucket_idx % 500 == 0: progress = int((bucket_idx + 1) / total_buckets * 100) - logger.info(f"进度: {progress}% ({bucket_idx + 1}/{total_buckets})") + logger.info(t("msg-1e824a79", progress=progress, res=bucket_idx + 1, total_buckets=total_buckets)) cnt = 0 while ( idx < len(platform_stats_v3) @@ -171,10 +172,10 @@ async def migration_platform_table( ) except Exception: logger.error( - f"迁移平台统计数据失败: {platform_id}, {platform_type}, 时间戳: {bucket_end}", + t("msg-813384e2", platform_id=platform_id, platform_type=platform_type, bucket_end=bucket_end), exc_info=True, ) - logger.info(f"成功迁移 {len(platform_stats_v3)} 条旧的平台数据到新表。") + logger.info(t("msg-27ab191d", res=len(platform_stats_v3))) async def migration_webchat_data( @@ -189,7 +190,7 @@ async def migration_webchat_data( page=1, page_size=10000000, ) - logger.info(f"迁移 {total_cnt} 条旧的 WebChat 会话数据到新的表中...") + logger.info(t("msg-8e6280ed", total_cnt=total_cnt)) async with db_helper.get_db() as dbsession: dbsession: AsyncSession @@ -198,7 +199,7 @@ async def migration_webchat_data( if total_cnt > 0 and (idx + 1) % max(1, total_cnt // 10) == 0: progress = int((idx + 1) / total_cnt * 100) if progress % 10 == 0: - logger.info(f"进度: {progress}% ({idx + 1}/{total_cnt})") + logger.info(t("msg-6f232b73", progress=progress, res=idx + 1, total_cnt=total_cnt)) try: conv = db_helper_v3.get_conversation_by_user_id( user_id=conversation.get("user_id", "unknown"), @@ -206,7 +207,7 @@ async def migration_webchat_data( ) if not conv: logger.info( - f"未找到该条旧会话对应的具体数据: {conversation}, 跳过。", + t("msg-6b1def31", conversation=conversation), ) continue if ":" in conv.user_id: @@ -226,11 +227,11 @@ async def migration_webchat_data( except Exception: logger.error( - f"迁移旧 WebChat 会话 {conversation.get('cid', 'unknown')} 失败", + t("msg-cad66fe1", res=conversation.get('cid', 'unknown')), exc_info=True, ) - logger.info(f"成功迁移 {total_cnt} 条旧的 WebChat 会话数据到新表。") + logger.info(t("msg-63748a46", total_cnt=total_cnt)) async def migration_persona_data( @@ -242,13 +243,13 @@ async def migration_persona_data( """ v3_persona_config: list[dict] = astrbot_config.get("persona", []) total_personas = len(v3_persona_config) - logger.info(f"迁移 {total_personas} 个 Persona 配置到新表中...") + logger.info(t("msg-dfc93fa4", total_personas=total_personas)) for idx, persona in enumerate(v3_persona_config): if total_personas > 0 and (idx + 1) % max(1, total_personas // 10) == 0: progress = int((idx + 1) / total_personas * 100) if progress % 10 == 0: - logger.info(f"进度: {progress}% ({idx + 1}/{total_personas})") + logger.info(t("msg-ff85e45c", progress=progress, res=idx + 1, total_personas=total_personas)) try: begin_dialogs = persona.get("begin_dialogs", []) mood_imitation_dialogs = persona.get("mood_imitation_dialogs", []) @@ -270,10 +271,10 @@ async def migration_persona_data( begin_dialogs=begin_dialogs, ) logger.info( - f"迁移 Persona {persona['name']}({persona_new.system_prompt[:30]}...) 到新表成功。", + t("msg-c346311e", res=persona['name'], res_2=persona_new.system_prompt[:30]), ) except Exception as e: - logger.error(f"解析 Persona 配置失败:{e}") + logger.error(t("msg-b6292b94", e=e)) async def migration_preferences( @@ -293,7 +294,7 @@ async def migration_preferences( value = sp_v3.get(key) if value is not None: await sp.put_async("global", "global", key, value) - logger.info(f"迁移全局偏好设置 {key} 成功,值: {value}") + logger.info(t("msg-90e5039e", key=key, value=value)) # 2. umo scope migration session_conversation = sp_v3.get("session_conversation", default={}) @@ -305,9 +306,9 @@ async def migration_preferences( platform_id = get_platform_id(platform_id_map, session.platform_name) session.platform_id = platform_id await sp.put_async("umo", str(session), "sel_conv_id", conversation_id) - logger.info(f"迁移会话 {umo} 的对话数据到新表成功,平台 ID: {platform_id}") + logger.info(t("msg-d538da1c", umo=umo, platform_id=platform_id)) except Exception as e: - logger.error(f"迁移会话 {umo} 的对话数据失败: {e}", exc_info=True) + logger.error(t("msg-ee03c001", umo=umo, e=e), exc_info=True) session_service_config = sp_v3.get("session_service_config", default={}) for umo, config in session_service_config.items(): @@ -320,9 +321,9 @@ async def migration_preferences( await sp.put_async("umo", str(session), "session_service_config", config) - logger.info(f"迁移会话 {umo} 的服务配置到新表成功,平台 ID: {platform_id}") + logger.info(t("msg-5c4339cd", umo=umo, platform_id=platform_id)) except Exception as e: - logger.error(f"迁移会话 {umo} 的服务配置失败: {e}", exc_info=True) + logger.error(t("msg-4ce2a0b2", umo=umo, e=e), exc_info=True) session_variables = sp_v3.get("session_variables", default={}) for umo, variables in session_variables.items(): @@ -334,7 +335,7 @@ async def migration_preferences( session.platform_id = platform_id await sp.put_async("umo", str(session), "session_variables", variables) except Exception as e: - logger.error(f"迁移会话 {umo} 的变量失败: {e}", exc_info=True) + logger.error(t("msg-2e62dab9", umo=umo, e=e), exc_info=True) session_provider_perf = sp_v3.get("session_provider_perf", default={}) for umo, perf in session_provider_perf.items(): @@ -353,7 +354,7 @@ async def migration_preferences( provider_id, ) logger.info( - f"迁移会话 {umo} 的提供商偏好到新表成功,平台 ID: {platform_id}", + t("msg-afbf819e", umo=umo, platform_id=platform_id), ) except Exception as e: - logger.error(f"迁移会话 {umo} 的提供商偏好失败: {e}", exc_info=True) + logger.error(t("msg-959bb068", umo=umo, e=e), exc_info=True) diff --git a/astrbot/core/db/migration/migra_45_to_46.py b/astrbot/core/db/migration/migra_45_to_46.py index 58736ab51f..d8629e8c76 100644 --- a/astrbot/core/db/migration/migra_45_to_46.py +++ b/astrbot/core/db/migration/migra_45_to_46.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t from astrbot.api import logger, sp from astrbot.core.astrbot_config_mgr import AstrBotConfigManager from astrbot.core.umop_config_router import UmopConfigRouter @@ -9,7 +10,7 @@ async def migrate_45_to_46(acm: AstrBotConfigManager, ucr: UmopConfigRouter) -> if not isinstance(abconf_data, dict): # should be unreachable logger.warning( - f"migrate_45_to_46: abconf_data is not a dict (type={type(abconf_data)}). Value: {abconf_data!r}", + t("msg-782b01c1", res=type(abconf_data), abconf_data=abconf_data), ) return @@ -23,7 +24,7 @@ async def migrate_45_to_46(acm: AstrBotConfigManager, ucr: UmopConfigRouter) -> if not need_migration: return - logger.info("Starting migration from version 4.5 to 4.6") + logger.info(t("msg-49e09620")) # extract umo->conf_id mapping umo_to_conf_id = {} @@ -41,4 +42,4 @@ async def migrate_45_to_46(acm: AstrBotConfigManager, ucr: UmopConfigRouter) -> # update the umop config router await ucr.update_routing_data(umo_to_conf_id) - logger.info("Migration from version 45 to 46 completed successfully") + logger.info(t("msg-791b79f8")) diff --git a/astrbot/core/db/migration/migra_token_usage.py b/astrbot/core/db/migration/migra_token_usage.py index 76bf8ce01c..d3ddc003e5 100644 --- a/astrbot/core/db/migration/migra_token_usage.py +++ b/astrbot/core/db/migration/migra_token_usage.py @@ -5,6 +5,7 @@ Changes: - Adds token_usage column to conversations table (default: 0) """ +from astrbot.core.lang import t from sqlalchemy import text @@ -24,7 +25,7 @@ async def migrate_token_usage(db_helper: BaseDatabase) -> None: if migration_done: return - logger.info("开始执行数据库迁移(添加 conversations.token_usage 列)...") + logger.info(t("msg-c3e53a4f")) # 这里只适配了 SQLite。因为截止至这一版本,AstrBot 仅支持 SQLite。 @@ -36,7 +37,7 @@ async def migrate_token_usage(db_helper: BaseDatabase) -> None: column_names = [col[1] for col in columns] if "token_usage" in column_names: - logger.info("token_usage 列已存在,跳过迁移") + logger.info(t("msg-ccbd0a41")) await sp.put_async( "global", "global", "migration_done_token_usage_1", True ) @@ -50,12 +51,12 @@ async def migrate_token_usage(db_helper: BaseDatabase) -> None: ) await session.commit() - logger.info("token_usage 列添加成功") + logger.info(t("msg-39f60232")) # 标记迁移完成 await sp.put_async("global", "global", "migration_done_token_usage_1", True) - logger.info("token_usage 迁移完成") + logger.info(t("msg-4f9d3876")) except Exception as e: - logger.error(f"迁移过程中发生错误: {e}", exc_info=True) + logger.error(t("msg-91571aaf", e=e), exc_info=True) raise diff --git a/astrbot/core/db/migration/migra_webchat_session.py b/astrbot/core/db/migration/migra_webchat_session.py index 46025fc646..3e39935cd9 100644 --- a/astrbot/core/db/migration/migra_webchat_session.py +++ b/astrbot/core/db/migration/migra_webchat_session.py @@ -8,6 +8,7 @@ - Adds display_name field - Session_id format: {platform_id}_{uuid} """ +from astrbot.core.lang import t from sqlalchemy import func, select from sqlmodel import col @@ -30,7 +31,7 @@ async def migrate_webchat_session(db_helper: BaseDatabase) -> None: if migration_done: return - logger.info("开始执行数据库迁移(WebChat 会话迁移)...") + logger.info(t("msg-53fad3d0")) try: async with db_helper.get_db() as session: @@ -51,13 +52,13 @@ async def migrate_webchat_session(db_helper: BaseDatabase) -> None: webchat_users = result.all() if not webchat_users: - logger.info("没有找到需要迁移的 WebChat 数据") + logger.info(t("msg-7674efb0")) await sp.put_async( "global", "global", "migration_done_webchat_session_1", True ) return - logger.info(f"找到 {len(webchat_users)} 个 WebChat 会话需要迁移") + logger.info(t("msg-139e39ee", res=len(webchat_users))) # 检查已存在的会话 existing_query = select(col(PlatformSession.session_id)) @@ -93,7 +94,7 @@ async def migrate_webchat_session(db_helper: BaseDatabase) -> None: # 检查是否已经存在该会话 if session_id in existing_session_ids: - logger.debug(f"会话 {session_id} 已存在,跳过") + logger.debug(t("msg-cf287e58", session_id=session_id)) skipped_count += 1 continue @@ -118,14 +119,14 @@ async def migrate_webchat_session(db_helper: BaseDatabase) -> None: await session.commit() logger.info( - f"WebChat 会话迁移完成!成功迁移: {len(sessions_to_add)}, 跳过: {skipped_count}", + t("msg-062c72fa", res=len(sessions_to_add), skipped_count=skipped_count), ) else: - logger.info("没有新会话需要迁移") + logger.info(t("msg-a516cc9f")) # 标记迁移完成 await sp.put_async("global", "global", "migration_done_webchat_session_1", True) except Exception as e: - logger.error(f"迁移过程中发生错误: {e}", exc_info=True) + logger.error(t("msg-91571aaf", e=e), exc_info=True) raise diff --git a/astrbot/core/db/vec_db/faiss_impl/document_storage.py b/astrbot/core/db/vec_db/faiss_impl/document_storage.py index 2adae69ccc..5de921c18b 100644 --- a/astrbot/core/db/vec_db/faiss_impl/document_storage.py +++ b/astrbot/core/db/vec_db/faiss_impl/document_storage.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import json import os from contextlib import asynccontextmanager @@ -121,7 +122,7 @@ async def get_documents( """ if self.engine is None: logger.warning( - "Database connection is not initialized, returning empty result", + t("msg-c2dc1d2b"), ) return [] @@ -278,7 +279,7 @@ async def delete_documents(self, metadata_filters: dict) -> None: """ if self.engine is None: logger.warning( - "Database connection is not initialized, skipping delete operation", + t("msg-51fa7426"), ) return @@ -307,7 +308,7 @@ async def count_documents(self, metadata_filters: dict | None = None) -> int: """ if self.engine is None: - logger.warning("Database connection is not initialized, returning 0") + logger.warning(t("msg-43d1f69f")) return 0 async with self.get_session() as session: diff --git a/astrbot/core/db/vec_db/faiss_impl/embedding_storage.py b/astrbot/core/db/vec_db/faiss_impl/embedding_storage.py index dc6977cf8a..296e55d92c 100644 --- a/astrbot/core/db/vec_db/faiss_impl/embedding_storage.py +++ b/astrbot/core/db/vec_db/faiss_impl/embedding_storage.py @@ -1,8 +1,9 @@ +from astrbot.core.lang import t try: import faiss except ModuleNotFoundError: raise ImportError( - "faiss 未安装。请使用 'pip install faiss-cpu' 或 'pip install faiss-gpu' 安装。", + t("msg-8e5fe535"), ) import os @@ -33,7 +34,7 @@ async def insert(self, vector: np.ndarray, id: int) -> None: assert self.index is not None, "FAISS index is not initialized." if vector.shape[0] != self.dimension: raise ValueError( - f"向量维度不匹配, 期望: {self.dimension}, 实际: {vector.shape[0]}", + t("msg-9aa7b941", res=self.dimension, res_2=vector.shape[0]), ) self.index.add_with_ids(vector.reshape(1, -1), np.array([id])) await self.save_index() @@ -51,7 +52,7 @@ async def insert_batch(self, vectors: np.ndarray, ids: list[int]) -> None: assert self.index is not None, "FAISS index is not initialized." if vectors.shape[1] != self.dimension: raise ValueError( - f"向量维度不匹配, 期望: {self.dimension}, 实际: {vectors.shape[1]}", + t("msg-9aa7b941", res=self.dimension, res_2=vectors.shape[1]), ) self.index.add_with_ids(vectors, np.array(ids)) await self.save_index() diff --git a/astrbot/core/db/vec_db/faiss_impl/vec_db.py b/astrbot/core/db/vec_db/faiss_impl/vec_db.py index 3fca246ef5..2229833be0 100644 --- a/astrbot/core/db/vec_db/faiss_impl/vec_db.py +++ b/astrbot/core/db/vec_db/faiss_impl/vec_db.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import time import uuid @@ -75,7 +76,7 @@ async def insert_batch( ids = ids or [str(uuid.uuid4()) for _ in contents] start = time.time() - logger.debug(f"Generating embeddings for {len(contents)} contents...") + logger.debug(t("msg-9f9765dc", res=len(contents))) vectors = await self.embedding_provider.get_embeddings_batch( contents, batch_size=batch_size, @@ -85,7 +86,7 @@ async def insert_batch( ) end = time.time() logger.debug( - f"Generated embeddings for {len(contents)} contents in {end - start:.2f} seconds.", + t("msg-385bc50a", res=len(contents), res_2=end - start), ) # 使用 DocumentStorage 的批量插入方法 diff --git a/astrbot/core/event_bus.py b/astrbot/core/event_bus.py index 44cdccb83a..fd448ead8b 100644 --- a/astrbot/core/event_bus.py +++ b/astrbot/core/event_bus.py @@ -9,6 +9,7 @@ 1. 维护一个异步队列, 来接受各种消息事件 2. 无限循环的调度函数, 从事件队列中获取新的事件, 打印日志并创建一个新的异步任务来执行管道调度器的处理逻辑 """ +from astrbot.core.lang import t import asyncio from asyncio import Queue @@ -42,7 +43,7 @@ async def dispatch(self) -> None: scheduler = self.pipeline_scheduler_mapping.get(conf_info["id"]) if not scheduler: logger.error( - f"PipelineScheduler not found for id: {conf_info['id']}, event ignored." + t("msg-da466871", res=conf_info['id']) ) continue asyncio.create_task(scheduler.execute(event)) @@ -57,10 +58,10 @@ def _print_event(self, event: AstrMessageEvent, conf_name: str) -> None: # 如果有发送者名称: [平台名] 发送者名称/发送者ID: 消息概要 if event.get_sender_name(): logger.info( - f"[{conf_name}] [{event.get_platform_id()}({event.get_platform_name()})] {event.get_sender_name()}/{event.get_sender_id()}: {event.get_message_outline()}", + t("msg-7eccffa5", conf_name=conf_name, res=event.get_platform_id(), res_2=event.get_platform_name(), res_3=event.get_sender_name(), res_4=event.get_sender_id(), res_5=event.get_message_outline()), ) # 没有发送者名称: [平台名] 发送者ID: 消息概要 else: logger.info( - f"[{conf_name}] [{event.get_platform_id()}({event.get_platform_name()})] {event.get_sender_id()}: {event.get_message_outline()}", + t("msg-88bc26f2", conf_name=conf_name, res=event.get_platform_id(), res_2=event.get_platform_name(), res_3=event.get_sender_id(), res_4=event.get_message_outline()), ) diff --git a/astrbot/core/file_token_service.py b/astrbot/core/file_token_service.py index 42fbd23dfe..90bb41b30d 100644 --- a/astrbot/core/file_token_service.py +++ b/astrbot/core/file_token_service.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import os import platform @@ -61,7 +62,7 @@ async def register_file(self, file_path: str, timeout: float | None = None) -> s if not os.path.exists(local_path): raise FileNotFoundError( - f"文件不存在: {local_path} (原始输入: {file_path})", + t("msg-0e444e51", local_path=local_path, file_path=file_path), ) file_token = str(uuid.uuid4()) @@ -90,9 +91,9 @@ async def handle_file(self, file_token: str) -> str: await self._cleanup_expired_tokens() if file_token not in self.staged_files: - raise KeyError(f"无效或过期的文件 token: {file_token}") + raise KeyError(t("msg-f61a5322", file_token=file_token)) file_path, _ = self.staged_files.pop(file_token) if not os.path.exists(file_path): - raise FileNotFoundError(f"文件不存在: {file_path}") + raise FileNotFoundError(t("msg-73d3e179", file_path=file_path)) return file_path diff --git a/astrbot/core/initial_loader.py b/astrbot/core/initial_loader.py index 3f836a4c42..c156c28755 100644 --- a/astrbot/core/initial_loader.py +++ b/astrbot/core/initial_loader.py @@ -4,6 +4,7 @@ 1. 初始化核心生命周期, 传递数据库和日志代理实例到核心生命周期 2. 运行核心生命周期任务和仪表板服务器 """ +from astrbot.core.lang import t import asyncio import traceback @@ -29,8 +30,8 @@ async def start(self) -> None: try: await core_lifecycle.initialize() except Exception as e: - logger.critical(traceback.format_exc()) - logger.critical(f"😭 初始化 AstrBot 失败:{e} !!!") + logger.critical(t("msg-78b9c276", res=traceback.format_exc())) + logger.critical(t("msg-58525c23", e=e)) return core_task = core_lifecycle.start() @@ -53,5 +54,5 @@ async def start(self) -> None: try: await task # 整个AstrBot在这里运行 except asyncio.CancelledError: - logger.info("🌈 正在关闭 AstrBot...") + logger.info(t("msg-002cc3e8")) await core_lifecycle.stop() diff --git a/astrbot/core/knowledge_base/chunking/recursive.py b/astrbot/core/knowledge_base/chunking/recursive.py index e27ffbd1b7..9208b8b4ab 100644 --- a/astrbot/core/knowledge_base/chunking/recursive.py +++ b/astrbot/core/knowledge_base/chunking/recursive.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t from collections.abc import Callable from .base import BaseChunker @@ -154,11 +155,11 @@ def _split_by_character( if overlap is None: overlap = self.chunk_overlap if chunk_size <= 0: - raise ValueError("chunk_size must be greater than 0") + raise ValueError(t("msg-21db456a")) if overlap < 0: - raise ValueError("chunk_overlap must be non-negative") + raise ValueError(t("msg-c0656f4e")) if overlap >= chunk_size: - raise ValueError("chunk_overlap must be less than chunk_size") + raise ValueError(t("msg-82bd199c")) result = [] for i in range(0, len(text), chunk_size - overlap): end = min(i + chunk_size, len(text)) diff --git a/astrbot/core/knowledge_base/kb_db_sqlite.py b/astrbot/core/knowledge_base/kb_db_sqlite.py index 4b9dcf7dd0..792c3e3a22 100644 --- a/astrbot/core/knowledge_base/kb_db_sqlite.py +++ b/astrbot/core/knowledge_base/kb_db_sqlite.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t from contextlib import asynccontextmanager from pathlib import Path @@ -167,7 +168,7 @@ async def migrate_to_v1(self) -> None: async def close(self) -> None: """关闭数据库连接""" await self.engine.dispose() - logger.info(f"知识库数据库已关闭: {self.db_path}") + logger.info(t("msg-b850e5d8", res=self.db_path)) async def get_kb_by_id(self, kb_id: str) -> KnowledgeBase | None: """根据 ID 获取知识库""" diff --git a/astrbot/core/knowledge_base/kb_helper.py b/astrbot/core/knowledge_base/kb_helper.py index 1e9127d72a..2daa211282 100644 --- a/astrbot/core/knowledge_base/kb_helper.py +++ b/astrbot/core/knowledge_base/kb_helper.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import json import re @@ -96,11 +97,11 @@ async def _repair_and_translate_chunk_with_retry( return [] except Exception as e: logger.warning( - f" - LLM call failed on attempt {attempt + 1}/{max_retries + 1}. Error: {str(e)}" + t("msg-7b3dc642", res=attempt + 1, res_2=max_retries + 1, res_3=str(e)) ) logger.error( - f" - Failed to process chunk after {max_retries + 1} attempts. Using original text." + t("msg-4ba9530f", res=max_retries + 1) ) return [chunk] @@ -135,13 +136,13 @@ async def initialize(self) -> None: async def get_ep(self) -> EmbeddingProvider: if not self.kb.embedding_provider_id: - raise ValueError(f"知识库 {self.kb.kb_name} 未配置 Embedding Provider") + raise ValueError(t("msg-77670a3a", res=self.kb.kb_name)) ep: EmbeddingProvider = await self.prov_mgr.get_provider_by_id( self.kb.embedding_provider_id, ) # type: ignore if not ep: raise ValueError( - f"无法找到 ID 为 {self.kb.embedding_provider_id} 的 Embedding Provider", + t("msg-8e9eb3f9", res=self.kb.embedding_provider_id), ) return ep @@ -153,13 +154,13 @@ async def get_rp(self) -> RerankProvider | None: ) # type: ignore if not rp: raise ValueError( - f"无法找到 ID 为 {self.kb.rerank_provider_id} 的 Rerank Provider", + t("msg-3e426806", res=self.kb.rerank_provider_id), ) return rp async def _ensure_vec_db(self) -> FaissVecDB: if not self.kb.embedding_provider_id: - raise ValueError(f"知识库 {self.kb.kb_name} 未配置 Embedding Provider") + raise ValueError(t("msg-77670a3a", res=self.kb.kb_name)) ep = await self.get_ep() rp = await self.get_rp() @@ -234,12 +235,12 @@ async def upload_document( # 如果提供了预分块文本,直接使用 chunks_text = pre_chunked_text file_size = sum(len(chunk) for chunk in chunks_text) - logger.info(f"使用预分块文本进行上传,共 {len(chunks_text)} 个块。") + logger.info(t("msg-6e780e1e", res=len(chunks_text))) else: # 否则,执行标准的文件解析和分块流程 if file_content is None: raise ValueError( - "当未提供 pre_chunked_text 时,file_content 不能为空。" + t("msg-f4b82f18") ) file_size = len(file_content) @@ -333,7 +334,7 @@ async def embedding_progress_callback(current, total) -> None: await self.refresh_document(doc_id) return doc except Exception as e: - logger.error(f"上传文档失败: {e}") + logger.error(t("msg-975f06d7", e=e)) # if file_path.exists(): # file_path.unlink() @@ -342,7 +343,7 @@ async def embedding_progress_callback(current, total) -> None: if media_path.exists(): media_path.unlink() except Exception as me: - logger.warning(f"清理多媒体文件失败 {media_path}: {me}") + logger.warning(t("msg-969b17ca", media_path=media_path, me=me)) raise e @@ -393,7 +394,7 @@ async def refresh_document(self, doc_id: str) -> None: """更新文档的元数据""" doc = await self.get_document(doc_id) if not doc: - raise ValueError(f"无法找到 ID 为 {doc_id} 的文档") + raise ValueError(t("msg-18d25e55", doc_id=doc_id)) chunk_count = await self.get_chunk_count_by_doc_id(doc_id) doc.chunk_count = chunk_count async with self.kb_db.get_db() as session: @@ -504,7 +505,7 @@ async def upload_from_url( ) if not tavily_keys: raise ValueError( - "Error: Tavily API key is not configured in provider_settings." + t("msg-f5d7c34c") ) # 阶段1: 从 URL 提取内容 @@ -514,11 +515,11 @@ async def upload_from_url( try: text_content = await extract_text_from_url(url, tavily_keys) except Exception as e: - logger.error(f"Failed to extract content from URL {url}: {e}") - raise OSError(f"Failed to extract content from URL {url}: {e}") from e + logger.error(t("msg-975d88e0", url=url, e=e)) + raise OSError(t("msg-975d88e0", url=url, e=e)) from e if not text_content: - raise ValueError(f"No content extracted from URL: {url}") + raise ValueError(t("msg-cfe431b3", url=url)) if progress_callback: await progress_callback("extracting", 100, 100) @@ -536,7 +537,7 @@ async def upload_from_url( if enable_cleaning and not final_chunks: raise ValueError( - "内容清洗后未提取到有效文本。请尝试关闭内容清洗功能,或更换更高性能的LLM模型后重试。" + t("msg-e7f5f836") ) # 创建一个虚拟文件名 @@ -575,7 +576,7 @@ async def _clean_and_rechunk_content( if not enable_cleaning: # 如果不启用清洗,则使用从前端传递的参数进行分块 logger.info( - f"内容清洗未启用,使用指定参数进行分块: chunk_size={chunk_size}, chunk_overlap={chunk_overlap}" + t("msg-693aa5c5", chunk_size=chunk_size, chunk_overlap=chunk_overlap) ) return await self.chunker.chunk( content, chunk_size=chunk_size, chunk_overlap=chunk_overlap @@ -583,7 +584,7 @@ async def _clean_and_rechunk_content( if not cleaning_provider_id: logger.warning( - "启用了内容清洗,但未提供 cleaning_provider_id,跳过清洗并使用默认分块。" + t("msg-947d8f46") ) return await self.chunker.chunk(content) @@ -595,7 +596,7 @@ async def _clean_and_rechunk_content( llm_provider = await self.prov_mgr.get_provider_by_id(cleaning_provider_id) if not llm_provider or not isinstance(llm_provider, LLMProvider): raise ValueError( - f"无法找到 ID 为 {cleaning_provider_id} 的 LLM Provider 或类型不正确" + t("msg-31963d3f", cleaning_provider_id=cleaning_provider_id) ) # 初步分块 @@ -606,7 +607,7 @@ async def _clean_and_rechunk_content( separators=["\n\n", "\n", " "], # 优先使用段落分隔符 ) initial_chunks = await text_splitter.chunk(content) - logger.info(f"初步分块完成,生成 {len(initial_chunks)} 个块用于修复。") + logger.info(t("msg-82728272", res=len(initial_chunks))) # 并发处理所有块 rate_limiter = RateLimiter(repair_max_rpm) @@ -622,13 +623,13 @@ async def _clean_and_rechunk_content( final_chunks = [] for i, result in enumerate(repaired_results): if isinstance(result, Exception): - logger.warning(f"块 {i} 处理异常: {str(result)}. 回退到原始块。") + logger.warning(t("msg-6fa5fdca", i=i, res=str(result))) final_chunks.append(initial_chunks[i]) elif isinstance(result, list): final_chunks.extend(result) logger.info( - f"文本修复完成: {len(initial_chunks)} 个原始块 -> {len(final_chunks)} 个最终块。" + t("msg-6780e950", res=len(initial_chunks), res_2=len(final_chunks)) ) if progress_callback: @@ -637,6 +638,6 @@ async def _clean_and_rechunk_content( return final_chunks except Exception as e: - logger.error(f"使用 Provider '{cleaning_provider_id}' 清洗内容失败: {e}") + logger.error(t("msg-79056c76", cleaning_provider_id=cleaning_provider_id, e=e)) # 清洗失败,返回默认分块结果,保证流程不中断 return await self.chunker.chunk(content) diff --git a/astrbot/core/knowledge_base/kb_mgr.py b/astrbot/core/knowledge_base/kb_mgr.py index f26409e56e..9eb0b9e64d 100644 --- a/astrbot/core/knowledge_base/kb_mgr.py +++ b/astrbot/core/knowledge_base/kb_mgr.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import traceback from pathlib import Path @@ -37,7 +38,7 @@ def __init__( async def initialize(self) -> None: """初始化知识库模块""" try: - logger.info("正在初始化知识库模块...") + logger.info(t("msg-98bfa670")) # 初始化数据库 await self._init_kb_database() @@ -53,17 +54,17 @@ async def initialize(self) -> None: await self.load_kbs() except ImportError as e: - logger.error(f"知识库模块导入失败: {e}") - logger.warning("请确保已安装所需依赖: pypdf, aiofiles, Pillow, rank-bm25") + logger.error(t("msg-7da7ae15", e=e)) + logger.warning(t("msg-842a3c65")) except Exception as e: - logger.error(f"知识库模块初始化失败: {e}") - logger.error(traceback.format_exc()) + logger.error(t("msg-c9e943f7", e=e)) + logger.error(t("msg-78b9c276", res=traceback.format_exc())) async def _init_kb_database(self) -> None: self.kb_db = KBSQLiteDatabase(DB_PATH.as_posix()) await self.kb_db.initialize() await self.kb_db.migrate_to_v1() - logger.info(f"KnowledgeBase database initialized: {DB_PATH}") + logger.info(t("msg-9349e112", DB_PATH=DB_PATH)) async def load_kbs(self) -> None: """加载所有知识库实例""" @@ -94,7 +95,7 @@ async def create_kb( ) -> KBHelper: """创建新的知识库实例""" if embedding_provider_id is None: - raise ValueError("创建知识库时必须提供embedding_provider_id") + raise ValueError(t("msg-7605893e")) kb = KnowledgeBase( kb_name=kb_name, description=description, @@ -125,7 +126,7 @@ async def create_kb( return kb_helper except Exception as e: if "kb_name" in str(e): - raise ValueError(f"知识库名称 '{kb_name}' 已存在") + raise ValueError(t("msg-0b632cbd", kb_name=kb_name)) raise async def get_kb(self, kb_id: str) -> KBHelper | None: @@ -282,7 +283,7 @@ async def terminate(self) -> None: try: await kb_helper.terminate() except Exception as e: - logger.error(f"关闭知识库 {kb_id} 失败: {e}") + logger.error(t("msg-ca30330f", kb_id=kb_id, e=e)) self.kb_insts.clear() @@ -291,7 +292,7 @@ async def terminate(self) -> None: try: await self.kb_db.close() except Exception as e: - logger.error(f"关闭知识库元数据数据库失败: {e}") + logger.error(t("msg-00262e1f", e=e)) async def upload_from_url( self, @@ -325,7 +326,7 @@ async def upload_from_url( """ kb_helper = await self.get_kb(kb_id) if not kb_helper: - raise ValueError(f"Knowledge base with id {kb_id} not found.") + raise ValueError(t("msg-3fc9ef0b", kb_id=kb_id)) return await kb_helper.upload_from_url( url=url, diff --git a/astrbot/core/knowledge_base/parsers/text_parser.py b/astrbot/core/knowledge_base/parsers/text_parser.py index bed2d09b8b..3d46e48dd3 100644 --- a/astrbot/core/knowledge_base/parsers/text_parser.py +++ b/astrbot/core/knowledge_base/parsers/text_parser.py @@ -2,6 +2,7 @@ 支持解析 TXT 和 Markdown 文件。 """ +from astrbot.core.lang import t from astrbot.core.knowledge_base.parsers.base import BaseParser, ParseResult @@ -36,7 +37,7 @@ async def parse(self, file_content: bytes, file_name: str) -> ParseResult: except UnicodeDecodeError: continue else: - raise ValueError(f"无法解码文件: {file_name}") + raise ValueError(t("msg-70cbd40d", file_name=file_name)) # 文本文件无多媒体资源 return ParseResult(text=text, media=[]) diff --git a/astrbot/core/knowledge_base/parsers/url_parser.py b/astrbot/core/knowledge_base/parsers/url_parser.py index 2867164a96..8990dde592 100644 --- a/astrbot/core/knowledge_base/parsers/url_parser.py +++ b/astrbot/core/knowledge_base/parsers/url_parser.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import aiohttp @@ -14,7 +15,7 @@ def __init__(self, tavily_keys: list[str]) -> None: tavily_keys: Tavily API 密钥列表 """ if not tavily_keys: - raise ValueError("Error: Tavily API keys are not configured.") + raise ValueError(t("msg-2de85bf5")) self.tavily_keys = tavily_keys self.tavily_key_index = 0 @@ -44,7 +45,7 @@ async def extract_text_from_url(self, url: str) -> str: IOError: 如果请求失败或返回错误 """ if not url: - raise ValueError("Error: url must be a non-empty string.") + raise ValueError(t("msg-98ed69f4")) tavily_key = await self._get_tavily_key() api_url = "https://api.tavily.com/extract" @@ -69,22 +70,22 @@ async def extract_text_from_url(self, url: str) -> str: if response.status != 200: reason = await response.text() raise OSError( - f"Tavily web extraction failed: {reason}, status: {response.status}" + t("msg-7b14cdb7", reason=reason, res=response.status) ) data = await response.json() results = data.get("results", []) if not results: - raise ValueError(f"No content extracted from URL: {url}") + raise ValueError(t("msg-cfe431b3", url=url)) # 返回第一个结果的内容 return results[0].get("raw_content", "") except aiohttp.ClientError as e: - raise OSError(f"Failed to fetch URL {url}: {e}") from e + raise OSError(t("msg-b0897365", url=url, e=e)) from e except Exception as e: - raise OSError(f"Failed to extract content from URL {url}: {e}") from e + raise OSError(t("msg-975d88e0", url=url, e=e)) from e # 为了向后兼容,提供一个简单的函数接口 diff --git a/astrbot/core/knowledge_base/parsers/util.py b/astrbot/core/knowledge_base/parsers/util.py index 7a44632022..0d99c93b9b 100644 --- a/astrbot/core/knowledge_base/parsers/util.py +++ b/astrbot/core/knowledge_base/parsers/util.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t from .base import BaseParser @@ -10,4 +11,4 @@ async def select_parser(ext: str) -> BaseParser: from .pdf_parser import PDFParser return PDFParser() - raise ValueError(f"暂时不支持的文件格式: {ext}") + raise ValueError(t("msg-398b3580", ext=ext)) diff --git a/astrbot/core/knowledge_base/retrieval/manager.py b/astrbot/core/knowledge_base/retrieval/manager.py index 1244e18af1..d023f690c8 100644 --- a/astrbot/core/knowledge_base/retrieval/manager.py +++ b/astrbot/core/knowledge_base/retrieval/manager.py @@ -2,6 +2,7 @@ 协调稠密检索、稀疏检索和 Rerank,提供统一的检索接口 """ +from astrbot.core.lang import t import time from dataclasses import dataclass @@ -102,7 +103,7 @@ async def retrieve( } new_kb_ids.append(kb_id) else: - logger.warning(f"知识库 ID {kb_id} 实例未找到, 已跳过该知识库的检索") + logger.warning(t("msg-fcc0dde2", kb_id=kb_id)) kb_ids = new_kb_ids @@ -115,7 +116,7 @@ async def retrieve( ) time_end = time.time() logger.debug( - f"Dense retrieval across {len(kb_ids)} bases took {time_end - time_start:.2f}s and returned {len(dense_results)} results.", + t("msg-320cfcff", res=len(kb_ids), res_2=time_end - time_start, res_3=len(dense_results)), ) # 2. 稀疏检索 @@ -127,7 +128,7 @@ async def retrieve( ) time_end = time.time() logger.debug( - f"Sparse retrieval across {len(kb_ids)} bases took {time_end - time_start:.2f}s and returned {len(sparse_results)} results.", + t("msg-90ffcfc8", res=len(kb_ids), res_2=time_end - time_start, res_3=len(sparse_results)), ) # 3. 结果融合 @@ -139,7 +140,7 @@ async def retrieve( ) time_end = time.time() logger.debug( - f"Rank fusion took {time_end - time_start:.2f}s and returned {len(fused_results)} results.", + t("msg-12bcf404", res=time_end - time_start, res_2=len(fused_results)), ) # 4. 转换为 RetrievalResult (批量获取元数据) @@ -171,7 +172,7 @@ async def retrieve( for kb_id in kb_ids: vec_db = kb_options[kb_id]["vec_db"] if not isinstance(vec_db, FaissVecDB): - logger.warning(f"vec_db for kb_id {kb_id} is not FaissVecDB") + logger.warning(t("msg-28c084bc", kb_id=kb_id)) continue rerank_pi = kb_options[kb_id]["rerank_provider_id"] @@ -231,7 +232,7 @@ async def _dense_retrieve( except Exception as e: from astrbot.core import logger - logger.warning(f"知识库 {kb_id} 稠密检索失败: {e}") + logger.warning(t("msg-cc0230a3", kb_id=kb_id, e=e)) continue # 按相似度排序并返回 top_k diff --git a/astrbot/core/lang.py b/astrbot/core/lang.py index 26bbba2add..5c84cb1f09 100644 --- a/astrbot/core/lang.py +++ b/astrbot/core/lang.py @@ -44,9 +44,9 @@ def _get_core_locales_dir() -> Path: @staticmethod def _validate_namespace(namespace: str) -> None: if not namespace: - raise ValueError("Namespace must not be empty.") + raise ValueError(t("msg-d103bc8e")) if "." in namespace: - raise ValueError("Namespace must not contain '.'.") + raise ValueError(t("msg-f66527da")) @staticmethod def _collect_files(base_dir: Path, files: list[str] | None) -> list[str]: @@ -74,11 +74,11 @@ def _build_localization( self, base_dir: Path, locale: str, files: list[str] | None ) -> tuple[FluentLocalization, list[str]]: if not base_dir.exists() or not base_dir.is_dir(): - raise ValueError(f"Locale directory does not exist: {base_dir}") + raise ValueError(t("msg-b3665aee", base_dir=base_dir)) available_locales = [d.name for d in base_dir.iterdir() if d.is_dir()] if not available_locales: - raise ValueError(f"No locale directories found under: {base_dir}") + raise ValueError(t("msg-3fe89e6a", base_dir=base_dir)) matched_locale = self._match_locale(available_locales, locale) merged_files = self._collect_files(base_dir, files) @@ -161,9 +161,7 @@ def register_namespace( self._validate_namespace(namespace) with self._lock: if namespace in self.namespace_paths and not replace: - raise ValueError( - f"Namespace '{namespace}' already exists. Set replace=True to overwrite." - ) + raise ValueError(t("msg-c79b2c75", namespace=namespace)) self.namespace_paths[namespace] = Path(path) if files is None: @@ -176,9 +174,9 @@ def unregister_namespace(self, namespace: str) -> None: self._validate_namespace(namespace) with self._lock: if namespace == self.default_namespace: - raise ValueError("Default namespace cannot be unregistered.") + raise ValueError(t("msg-7db3fccf")) if namespace not in self.namespace_paths: - raise ValueError(f"Namespace '{namespace}' is not registered.") + raise ValueError(t("msg-3d066f64", namespace=namespace)) self.namespace_paths.pop(namespace, None) self.namespace_files.pop(namespace, None) diff --git a/astrbot/core/log.py b/astrbot/core/log.py index 66a2f31543..a4f5e2a1cf 100644 --- a/astrbot/core/log.py +++ b/astrbot/core/log.py @@ -1,4 +1,5 @@ """日志系统,统一将标准 logging 输出转发到 loguru。""" +from astrbot.core.lang import t import asyncio import logging @@ -374,7 +375,7 @@ def configure_logger( trace=False, ) except Exception as e: - logger.error(f"Failed to add file sink: {e}") + logger.error(t("msg-80a186b8", e=e)) @classmethod def configure_trace_logger(cls, config: dict | None) -> None: diff --git a/astrbot/core/message/components.py b/astrbot/core/message/components.py index 15265c38d1..5c3af65f37 100644 --- a/astrbot/core/message/components.py +++ b/astrbot/core/message/components.py @@ -20,6 +20,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ +from astrbot.core.lang import t import asyncio import base64 @@ -139,7 +140,7 @@ def fromFileSystem(path, **_): def fromURL(url: str, **_): if url.startswith("http://") or url.startswith("https://"): return Record(file=url, **_) - raise Exception("not a valid url") + raise Exception(t("msg-afb10076")) @staticmethod def fromBase64(bs64_data: str, **_): @@ -153,7 +154,7 @@ async def convert_to_file_path(self) -> str: """ if not self.file: - raise Exception(f"not a valid file: {self.file}") + raise Exception(t("msg-fe4c33a0", res=self.file)) if self.file.startswith("file:///"): return self.file[8:] if self.file.startswith("http"): @@ -170,7 +171,7 @@ async def convert_to_file_path(self) -> str: return os.path.abspath(file_path) if os.path.exists(self.file): return os.path.abspath(self.file) - raise Exception(f"not a valid file: {self.file}") + raise Exception(t("msg-fe4c33a0", res=self.file)) async def convert_to_base64(self) -> str: """将语音统一转换为 base64 编码。这个方法避免了手动判断语音数据类型,直接返回语音数据的 base64 编码。 @@ -181,7 +182,7 @@ async def convert_to_base64(self) -> str: """ # convert to base64 if not self.file: - raise Exception(f"not a valid file: {self.file}") + raise Exception(t("msg-fe4c33a0", res=self.file)) if self.file.startswith("file:///"): bs64_data = file_to_base64(self.file[8:]) elif self.file.startswith("http"): @@ -192,7 +193,7 @@ async def convert_to_base64(self) -> str: elif os.path.exists(self.file): bs64_data = file_to_base64(self.file) else: - raise Exception(f"not a valid file: {self.file}") + raise Exception(t("msg-fe4c33a0", res=self.file)) bs64_data = bs64_data.removeprefix("base64://") return bs64_data @@ -209,13 +210,13 @@ async def register_to_file_service(self) -> str: callback_host = astrbot_config.get("callback_api_base") if not callback_host: - raise Exception("未配置 callback_api_base,文件服务不可用") + raise Exception(t("msg-24d98e13")) file_path = await self.convert_to_file_path() token = await file_token_service.register_file(file_path) - logger.debug(f"已注册:{callback_host}/api/file/{token}") + logger.debug(t("msg-a5c69cc9", callback_host=callback_host, token=token)) return f"{callback_host}/api/file/{token}" @@ -239,7 +240,7 @@ def fromFileSystem(path, **_): def fromURL(url: str, **_): if url.startswith("http://") or url.startswith("https://"): return Video(file=url, **_) - raise Exception("not a valid url") + raise Exception(t("msg-afb10076")) async def convert_to_file_path(self) -> str: """将这个视频统一转换为本地文件路径。这个方法避免了手动判断视频数据类型,直接返回视频数据的本地路径(如果是网络 URL,则会自动进行下载)。 @@ -258,10 +259,10 @@ async def convert_to_file_path(self) -> str: await download_file(url, video_file_path) if os.path.exists(video_file_path): return os.path.abspath(video_file_path) - raise Exception(f"download failed: {url}") + raise Exception(t("msg-3cddc5ef", url=url)) if os.path.exists(url): return os.path.abspath(url) - raise Exception(f"not a valid file: {url}") + raise Exception(t("msg-1921aa47", url=url)) async def register_to_file_service(self) -> str: """将视频注册到文件服务。 @@ -276,13 +277,13 @@ async def register_to_file_service(self) -> str: callback_host = astrbot_config.get("callback_api_base") if not callback_host: - raise Exception("未配置 callback_api_base,文件服务不可用") + raise Exception(t("msg-24d98e13")) file_path = await self.convert_to_file_path() token = await file_token_service.register_file(file_path) - logger.debug(f"已注册:{callback_host}/api/file/{token}") + logger.debug(t("msg-a5c69cc9", callback_host=callback_host, token=token)) return f"{callback_host}/api/file/{token}" @@ -295,7 +296,7 @@ async def to_dict(self): callback_host = str(callback_host).removesuffix("/") token = await file_token_service.register_file(url_or_path) payload_file = f"{callback_host}/api/file/{token}" - logger.debug(f"Generated video file callback link: {payload_file}") + logger.debug(t("msg-2ee3827c", payload_file=payload_file)) else: payload_file = url_or_path return { @@ -417,7 +418,7 @@ def __init__(self, file: str | None, **_) -> None: def fromURL(url: str, **_): if url.startswith("http://") or url.startswith("https://"): return Image(file=url, **_) - raise Exception("not a valid url") + raise Exception(t("msg-afb10076")) @staticmethod def fromFileSystem(path, **_): @@ -444,7 +445,7 @@ async def convert_to_file_path(self) -> str: """ url = self.url or self.file if not url: - raise ValueError("No valid file or URL provided") + raise ValueError(t("msg-32f4fc78")) if url.startswith("file:///"): return url[8:] if url.startswith("http"): @@ -461,7 +462,7 @@ async def convert_to_file_path(self) -> str: return os.path.abspath(image_file_path) if os.path.exists(url): return os.path.abspath(url) - raise Exception(f"not a valid file: {url}") + raise Exception(t("msg-1921aa47", url=url)) async def convert_to_base64(self) -> str: """将这个图片统一转换为 base64 编码。这个方法避免了手动判断图片数据类型,直接返回图片数据的 base64 编码。 @@ -473,7 +474,7 @@ async def convert_to_base64(self) -> str: # convert to base64 url = self.url or self.file if not url: - raise ValueError("No valid file or URL provided") + raise ValueError(t("msg-32f4fc78")) if url.startswith("file:///"): bs64_data = file_to_base64(url[8:]) elif url.startswith("http"): @@ -484,7 +485,7 @@ async def convert_to_base64(self) -> str: elif os.path.exists(url): bs64_data = file_to_base64(url) else: - raise Exception(f"not a valid file: {url}") + raise Exception(t("msg-1921aa47", url=url)) bs64_data = bs64_data.removeprefix("base64://") return bs64_data @@ -501,13 +502,13 @@ async def register_to_file_service(self) -> str: callback_host = astrbot_config.get("callback_api_base") if not callback_host: - raise Exception("未配置 callback_api_base,文件服务不可用") + raise Exception(t("msg-24d98e13")) file_path = await self.convert_to_file_path() token = await file_token_service.register_file(file_path) - logger.debug(f"已注册:{callback_host}/api/file/{token}") + logger.debug(t("msg-a5c69cc9", callback_host=callback_host, token=token)) return f"{callback_host}/api/file/{token}" @@ -679,9 +680,7 @@ def file(self) -> str: loop = asyncio.get_event_loop() if loop.is_running(): logger.warning( - "不可以在异步上下文中同步等待下载! " - "这个警告通常发生于某些逻辑试图通过 .file 获取文件消息段的文件内容。" - "请使用 await get_file() 代替直接获取 .file 字段", + t("msg-36375f4c"), ) return "" # 等待下载完成 @@ -690,7 +689,7 @@ def file(self) -> str: if self.file_ and os.path.exists(self.file_): return os.path.abspath(self.file_) except Exception as e: - logger.error(f"文件下载失败: {e}") + logger.error(t("msg-4a987754", e=e)) return "" @@ -758,7 +757,7 @@ async def get_file(self, allow_return_url: bool = False) -> str: async def _download_file(self) -> None: """下载文件""" if not self.url: - raise ValueError("Download failed: No URL provided in File component.") + raise ValueError(t("msg-7c1935ee")) download_dir = get_astrbot_temp_path() if self.name: name, ext = os.path.splitext(self.name) @@ -782,13 +781,13 @@ async def register_to_file_service(self) -> str: callback_host = astrbot_config.get("callback_api_base") if not callback_host: - raise Exception("未配置 callback_api_base,文件服务不可用") + raise Exception(t("msg-24d98e13")) file_path = await self.get_file() token = await file_token_service.register_file(file_path) - logger.debug(f"已注册:{callback_host}/api/file/{token}") + logger.debug(t("msg-a5c69cc9", callback_host=callback_host, token=token)) return f"{callback_host}/api/file/{token}" @@ -801,7 +800,7 @@ async def to_dict(self): callback_host = str(callback_host).removesuffix("/") token = await file_token_service.register_file(url_or_path) payload_file = f"{callback_host}/api/file/{token}" - logger.debug(f"Generated file callback link: {payload_file}") + logger.debug(t("msg-35bb8d53", payload_file=payload_file)) else: payload_file = url_or_path return { diff --git a/astrbot/core/persona_mgr.py b/astrbot/core/persona_mgr.py index 66002b2bd5..8a693b7825 100644 --- a/astrbot/core/persona_mgr.py +++ b/astrbot/core/persona_mgr.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t from astrbot import logger from astrbot.api import sp from astrbot.core.astrbot_config_mgr import AstrBotConfigManager @@ -33,13 +34,13 @@ def __init__(self, db_helper: BaseDatabase, acm: AstrBotConfigManager) -> None: async def initialize(self) -> None: self.personas = await self.get_all_personas() self.get_v3_persona_data() - logger.info(f"已加载 {len(self.personas)} 个人格。") + logger.info(t("msg-51a854e6", res=len(self.personas))) async def get_persona(self, persona_id: str): """获取指定 persona 的信息""" persona = await self.db.get_persona_by_id(persona_id) if not persona: - raise ValueError(f"Persona with ID {persona_id} does not exist.") + raise ValueError(t("msg-1ea88f45", persona_id=persona_id)) return persona async def get_default_persona_v3( @@ -116,7 +117,7 @@ async def resolve_selected_persona( async def delete_persona(self, persona_id: str) -> None: """删除指定 persona""" if not await self.db.get_persona_by_id(persona_id): - raise ValueError(f"Persona with ID {persona_id} does not exist.") + raise ValueError(t("msg-1ea88f45", persona_id=persona_id)) await self.db.delete_persona(persona_id) self.personas = [p for p in self.personas if p.persona_id != persona_id] self.get_v3_persona_data() @@ -132,7 +133,7 @@ async def update_persona( """更新指定 persona 的信息。tools 参数为 None 时表示使用所有工具,空列表表示不使用任何工具""" existing_persona = await self.db.get_persona_by_id(persona_id) if not existing_persona: - raise ValueError(f"Persona with ID {persona_id} does not exist.") + raise ValueError(t("msg-1ea88f45", persona_id=persona_id)) persona = await self.db.update_persona( persona_id, system_prompt, @@ -313,7 +314,7 @@ async def create_persona( sort_order: 排序顺序 """ if await self.db.get_persona_by_id(persona_id): - raise ValueError(f"Persona with ID {persona_id} already exists.") + raise ValueError(t("msg-28104dff", persona_id=persona_id)) new_persona = await self.db.insert_persona( persona_id, system_prompt, @@ -359,7 +360,7 @@ def get_v3_persona_data( if begin_dialogs: if len(begin_dialogs) % 2 != 0: logger.error( - f"{persona_cfg['name']} 人格情景预设对话格式不对,条数应该为偶数。", + t("msg-08ecfd42", res=persona_cfg['name']), ) begin_dialogs = [] user_turn = True @@ -383,7 +384,7 @@ def get_v3_persona_data( selected_default_persona = persona personas_v3.append(persona) except Exception as e: - logger.error(f"解析 Persona 配置失败:{e}") + logger.error(t("msg-b6292b94", e=e)) if not selected_default_persona and len(personas_v3) > 0: # 默认选择第一个 diff --git a/astrbot/core/pipeline/__init__.py b/astrbot/core/pipeline/__init__.py index 2fced806d8..1d8bd89b93 100644 --- a/astrbot/core/pipeline/__init__.py +++ b/astrbot/core/pipeline/__init__.py @@ -6,6 +6,7 @@ """ from __future__ import annotations +from astrbot.core.lang import t from importlib import import_module from typing import TYPE_CHECKING, Any @@ -85,7 +86,7 @@ def __getattr__(name: str) -> Any: if name not in _LAZY_EXPORTS: - raise AttributeError(f"module {__name__!r} has no attribute {name!r}") + raise AttributeError(t("msg-1c9fc93d", __name__=__name__, name=name)) module_path, attr_name = _LAZY_EXPORTS[name] module = import_module(module_path) value = getattr(module, attr_name) diff --git a/astrbot/core/pipeline/content_safety_check/stage.py b/astrbot/core/pipeline/content_safety_check/stage.py index 19037eb081..2f719278da 100644 --- a/astrbot/core/pipeline/content_safety_check/stage.py +++ b/astrbot/core/pipeline/content_safety_check/stage.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t from collections.abc import AsyncGenerator from astrbot.core import logger @@ -32,10 +33,10 @@ async def process( if event.is_at_or_wake_command: event.set_result( MessageEventResult().message( - "你的消息或者大模型的响应中包含不适当的内容,已被屏蔽。", + t("msg-c733275f"), ), ) yield event.stop_event() - logger.info(f"内容安全检查不通过,原因:{info}") + logger.info(t("msg-46c80f28", info=info)) return diff --git a/astrbot/core/pipeline/content_safety_check/strategies/strategy.py b/astrbot/core/pipeline/content_safety_check/strategies/strategy.py index c971ef26ff..2d66a1685e 100644 --- a/astrbot/core/pipeline/content_safety_check/strategies/strategy.py +++ b/astrbot/core/pipeline/content_safety_check/strategies/strategy.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t from astrbot import logger from . import ContentSafetyStrategy @@ -16,7 +17,7 @@ def __init__(self, config: dict) -> None: try: from .baidu_aip import BaiduAipStrategy except ImportError: - logger.warning("使用百度内容审核应该先 pip install baidu-aip") + logger.warning(t("msg-27a700e0")) return self.enabled_strategies.append( BaiduAipStrategy( diff --git a/astrbot/core/pipeline/context_utils.py b/astrbot/core/pipeline/context_utils.py index 9402ce3e62..1450a2e5e0 100644 --- a/astrbot/core/pipeline/context_utils.py +++ b/astrbot/core/pipeline/context_utils.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import inspect import traceback import typing as T @@ -36,7 +37,7 @@ async def call_handler( try: ready_to_call = handler(event, *args, **kwargs) except TypeError: - logger.error("处理函数参数不匹配,请检查 handler 的定义。", exc_info=True) + logger.error(t("msg-49f260d3"), exc_info=True) if not ready_to_call: return @@ -60,7 +61,7 @@ async def call_handler( # 如果这个异步生成器没有执行到 yield 分支 yield except Exception as e: - logger.error(f"Previous Error: {trace_}") + logger.error(t("msg-d7b4aa84", trace_=trace_)) raise e elif inspect.iscoroutine(ready_to_call): # 如果只是一个协程, 直接执行 @@ -93,15 +94,15 @@ async def call_event_hook( try: assert inspect.iscoroutinefunction(handler.handler) logger.debug( - f"hook({hook_type.name}) -> {star_map[handler.handler_module_path].name} - {handler.handler_name}", + t("msg-eb8619cb", res=hook_type.name, res_2=star_map[handler.handler_module_path].name, res_3=handler.handler_name), ) await handler.handler(event, *args, **kwargs) except BaseException: - logger.error(traceback.format_exc()) + logger.error(t("msg-78b9c276", res=traceback.format_exc())) if event.is_stopped(): logger.info( - f"{star_map[handler.handler_module_path].name} - {handler.handler_name} 终止了事件传播。", + t("msg-add19f94", res=star_map[handler.handler_module_path].name, res_2=handler.handler_name), ) return True diff --git a/astrbot/core/pipeline/preprocess_stage/stage.py b/astrbot/core/pipeline/preprocess_stage/stage.py index 6544f85c11..b9c302e796 100644 --- a/astrbot/core/pipeline/preprocess_stage/stage.py +++ b/astrbot/core/pipeline/preprocess_stage/stage.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import random import traceback @@ -44,7 +45,7 @@ async def process( try: await event.react(random.choice(emojis)) except Exception as e: - logger.warning(f"{platform} 预回应表情发送失败: {e}") + logger.warning(t("msg-7b9074fa", platform=platform, e=e)) # 路径映射 if mappings := self.platform_settings.get("path_mapping", []): @@ -61,7 +62,7 @@ async def process( url = component.url.removeprefix("file://") if url.startswith(from_): component.url = url.replace(from_, to_, 1) - logger.debug(f"路径映射: {url} -> {component.url}") + logger.debug(t("msg-43f1b4ed", url=url, res=component.url)) message_chain[idx] = component # STT @@ -71,7 +72,7 @@ async def process( stt_provider = ctx.get_using_stt_provider(event.unified_msg_origin) if not stt_provider: logger.warning( - f"会话 {event.unified_msg_origin} 未配置语音转文本模型。", + t("msg-9549187d", res=event.unified_msg_origin), ) return message_chain = event.get_messages() @@ -90,11 +91,11 @@ async def process( break except FileNotFoundError as e: # napcat workaround - logger.warning(e) - logger.warning(f"重试中: {i + 1}/{retry}") + logger.warning(t("msg-5bdf8f5c", e=e)) + logger.warning(t("msg-ad90e19e", res=i + 1, retry=retry)) await asyncio.sleep(0.5) continue except BaseException as e: - logger.error(traceback.format_exc()) - logger.error(f"语音转文本失败: {e}") + logger.error(t("msg-78b9c276", res=traceback.format_exc())) + logger.error(t("msg-4f3245bf", e=e)) break diff --git a/astrbot/core/pipeline/process_stage/follow_up.py b/astrbot/core/pipeline/process_stage/follow_up.py index 6c1a4fa06b..78a819f124 100644 --- a/astrbot/core/pipeline/process_stage/follow_up.py +++ b/astrbot/core/pipeline/process_stage/follow_up.py @@ -1,4 +1,5 @@ from __future__ import annotations +from astrbot.core.lang import t import asyncio from dataclasses import dataclass @@ -185,7 +186,7 @@ def try_capture_follow_up(event: AstrMessageEvent) -> FollowUpCapture | None: ) ) logger.info( - "Captured follow-up message for active agent run, umo=%s, order_seq=%s", + t("msg-df881b01"), event.unified_msg_origin, order_seq, ) diff --git a/astrbot/core/pipeline/process_stage/method/agent_request.py b/astrbot/core/pipeline/process_stage/method/agent_request.py index 9efe538146..d83b447601 100644 --- a/astrbot/core/pipeline/process_stage/method/agent_request.py +++ b/astrbot/core/pipeline/process_stage/method/agent_request.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t from collections.abc import AsyncGenerator from astrbot.core import logger @@ -20,7 +21,7 @@ async def initialize(self, ctx: PipelineContext) -> None: for bwp in self.bot_wake_prefixs: if self.prov_wake_prefix.startswith(bwp): logger.info( - f"识别 LLM 聊天额外唤醒前缀 {self.prov_wake_prefix} 以机器人唤醒前缀 {bwp} 开头,已自动去除。", + t("msg-3267978a", res=self.prov_wake_prefix, bwp=bwp), ) self.prov_wake_prefix = self.prov_wake_prefix[len(bwp) :] @@ -34,13 +35,13 @@ async def initialize(self, ctx: PipelineContext) -> None: async def process(self, event: AstrMessageEvent) -> AsyncGenerator[None, None]: if not self.ctx.astrbot_config["provider_settings"]["enable"]: logger.debug( - "This pipeline does not enable AI capability, skip processing." + t("msg-97a4d573") ) return if not await SessionServiceManager.should_process_llm_request(event): logger.debug( - f"The session {event.unified_msg_origin} has disabled AI capability, skipping processing." + t("msg-f1a11d2b", res=event.unified_msg_origin) ) return diff --git a/astrbot/core/pipeline/process_stage/method/agent_sub_stages/internal.py b/astrbot/core/pipeline/process_stage/method/agent_sub_stages/internal.py index d95f7f86cc..425b4913ac 100644 --- a/astrbot/core/pipeline/process_stage/method/agent_sub_stages/internal.py +++ b/astrbot/core/pipeline/process_stage/method/agent_sub_stages/internal.py @@ -1,4 +1,5 @@ """本地 Agent 模式的 LLM 调用 Stage""" +from astrbot.core.lang import t import asyncio import base64 @@ -55,7 +56,7 @@ async def initialize(self, ctx: PipelineContext) -> None: self.tool_schema_mode: str = settings.get("tool_schema_mode", "full") if self.tool_schema_mode not in ("skills_like", "full"): logger.warning( - "Unsupported tool_schema_mode: %s, fallback to skills_like", + t("msg-60493581"), self.tool_schema_mode, ) self.tool_schema_mode = "full" @@ -157,10 +158,10 @@ async def process( and not has_valid_message and not has_media_content ): - logger.debug("skip llm request: empty message and no provider_request") + logger.debug(t("msg-9cdb2b6e")) return - logger.debug("ready to request llm provider") + logger.debug(t("msg-e461e5af")) follow_up_capture = try_capture_follow_up(event) if follow_up_capture: ( @@ -169,7 +170,7 @@ async def process( ) = await prepare_follow_up_capture(follow_up_capture) if follow_up_consumed_marked: logger.info( - "Follow-up ticket already consumed, stopping processing. umo=%s, seq=%s", + t("msg-be33dd11"), event.unified_msg_origin, follow_up_capture.ticket.seq, ) @@ -179,7 +180,7 @@ async def process( await call_event_hook(event, EventType.OnWaitingLLMRequestEvent) async with session_lock_manager.acquire_lock(event.unified_msg_origin): - logger.debug("acquired session lock for llm request") + logger.debug(t("msg-abd5ccbc")) agent_runner: AgentRunner | None = None runner_registered = False try: @@ -208,7 +209,7 @@ async def process( for host in decoded_blocked: if host in api_base: logger.error( - "Provider API base %s is blocked due to security reasons. Please use another ai provider.", + t("msg-f9d617d7"), api_base, ) return @@ -245,7 +246,7 @@ async def process( # 检测 Live Mode if action_type == "live": # Live Mode: 使用 run_live_agent - logger.info("[Internal Agent] 检测到 Live Mode,启用 TTS 处理") + logger.info(t("msg-3247374d")) # 获取 TTS Provider tts_provider = ( @@ -256,7 +257,7 @@ async def process( if not tts_provider: logger.warning( - "[Live Mode] TTS Provider 未配置,将使用普通流式模式" + t("msg-dae92399") ) # 使用 run_live_agent,总是使用流式响应 @@ -365,10 +366,10 @@ async def process( unregister_active_runner(event.unified_msg_origin, agent_runner) except Exception as e: - logger.error(f"Error occurred while processing agent: {e}") + logger.error(t("msg-1b1af61e", e=e)) await event.send( MessageChain().message( - f"Error occurred while processing agent request: {e}" + t("msg-ea02b899", e=e) ) ) finally: @@ -409,7 +410,7 @@ async def _save_to_history( and not req.tool_calls_result and not user_aborted ): - logger.debug("LLM 响应为空,不保存记录。") + logger.debug(t("msg-ee7e792b")) return message_to_save = [] diff --git a/astrbot/core/pipeline/process_stage/method/agent_sub_stages/third_party.py b/astrbot/core/pipeline/process_stage/method/agent_sub_stages/third_party.py index 7fb5cee82b..23125a45da 100644 --- a/astrbot/core/pipeline/process_stage/method/agent_sub_stages/third_party.py +++ b/astrbot/core/pipeline/process_stage/method/agent_sub_stages/third_party.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio from collections.abc import AsyncGenerator from typing import TYPE_CHECKING @@ -54,12 +55,12 @@ async def run_third_party_agent( if stream_to_general: yield resp.data["chain"] except Exception as e: - logger.error(f"Third party agent runner error: {e}") + logger.error(t("msg-5e551baf", e=e)) err_msg = ( f"\nAstrBot 请求失败。\n错误类型: {type(e).__name__}\n" f"错误信息: {e!s}\n\n请在平台日志查看和分享错误详情。\n" ) - yield MessageChain().message(err_msg) + yield MessageChain().message(t("msg-34f164d4", err_msg=err_msg)) class ThirdPartyAgentSubStage(Stage): @@ -92,11 +93,11 @@ async def process( {}, ) if not self.prov_id: - logger.error("没有填写 Agent Runner 提供商 ID,请前往配置页面配置。") + logger.error(t("msg-f9d76893")) return if not self.prov_cfg: logger.error( - f"Agent Runner 提供商 {self.prov_id} 配置不存在,请前往配置页面修改配置。" + t("msg-0f856470", res=self.prov_id) ) return @@ -124,7 +125,7 @@ async def process( runner = DashscopeAgentRunner[AstrAgentContext]() else: raise ValueError( - f"Unsupported third party agent runner type: {self.runner_type}", + t("msg-b3f25c81", res=self.runner_type), ) astr_agent_ctx = AstrAgentContext( @@ -185,7 +186,7 @@ async def process( final_resp = runner.get_final_llm_resp() if not final_resp or not final_resp.result_chain: - logger.warning("Agent Runner 未返回最终结果。") + logger.warning(t("msg-6c63eb68")) return event.set_result( diff --git a/astrbot/core/pipeline/process_stage/method/star_request.py b/astrbot/core/pipeline/process_stage/method/star_request.py index 9422d6317a..a523ec2483 100644 --- a/astrbot/core/pipeline/process_stage/method/star_request.py +++ b/astrbot/core/pipeline/process_stage/method/star_request.py @@ -1,4 +1,5 @@ """本地 Agent 模式的 AstrBot 插件调用 Stage""" +from astrbot.core.lang import t import traceback from collections.abc import AsyncGenerator @@ -38,10 +39,10 @@ async def process( md = star_map.get(handler.handler_module_path) if not md: logger.warning( - f"Cannot find plugin for given handler module path: {handler.handler_module_path}", + t("msg-f0144031", res=handler.handler_module_path), ) continue - logger.debug(f"plugin -> {md.name} - {handler.handler_name}") + logger.debug(t("msg-1e8939dd", res=md.name, res_2=handler.handler_name)) try: wrapper = call_handler(event, handler.handler, **params) async for ret in wrapper: @@ -49,8 +50,8 @@ async def process( event.clear_result() # 清除上一个 handler 的结果 except Exception as e: traceback_text = traceback.format_exc() - logger.error(traceback_text) - logger.error(f"Star {handler.handler_full_name} handle error: {e}") + logger.error(t("msg-6be73b5e", traceback_text=traceback_text)) + logger.error(t("msg-d919bd27", res=handler.handler_full_name, e=e)) await call_event_hook( event, @@ -63,7 +64,7 @@ async def process( if not event.is_stopped() and event.is_at_or_wake_command: ret = f":(\n\n在调用插件 {md.name} 的处理函数 {handler.handler_name} 时出现异常:{e}" - event.set_result(MessageEventResult().message(ret)) + event.set_result(MessageEventResult().message(t("msg-ed8dcc22", ret=ret))) yield event.clear_result() diff --git a/astrbot/core/pipeline/rate_limit_check/stage.py b/astrbot/core/pipeline/rate_limit_check/stage.py index 392bceff30..1a4a7b1cf9 100644 --- a/astrbot/core/pipeline/rate_limit_check/stage.py +++ b/astrbot/core/pipeline/rate_limit_check/stage.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio from collections import defaultdict, deque from collections.abc import AsyncGenerator @@ -72,13 +73,13 @@ async def process( match self.rl_strategy: case RateLimitStrategy.STALL.value: logger.info( - f"会话 {session_id} 被限流。根据限流策略,此会话处理将被暂停 {stall_duration:.2f} 秒。", + t("msg-18092978", session_id=session_id, stall_duration=stall_duration), ) await asyncio.sleep(stall_duration) now = datetime.now() case RateLimitStrategy.DISCARD.value: logger.info( - f"会话 {session_id} 被限流。根据限流策略,此请求已被丢弃,直到限额于 {stall_duration:.2f} 秒后重置。", + t("msg-4962387a", session_id=session_id, stall_duration=stall_duration), ) return event.stop_event() diff --git a/astrbot/core/pipeline/respond/stage.py b/astrbot/core/pipeline/respond/stage.py index 72e853ffcc..9382b11db1 100644 --- a/astrbot/core/pipeline/respond/stage.py +++ b/astrbot/core/pipeline/respond/stage.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import math import random @@ -85,8 +86,8 @@ async def initialize(self, ctx: PipelineContext) -> None: try: self.interval = [float(t) for t in interval_str_ls] except BaseException as e: - logger.error(f"解析分段回复的间隔时间失败。{e}") - logger.info(f"分段回复间隔时间:{self.interval}") + logger.error(t("msg-59539c6e", e=e)) + logger.info(t("msg-4ddee754", res=self.interval)) async def _word_cnt(self, text: str) -> int: """分段回复 统计字数""" @@ -182,12 +183,12 @@ async def process( return logger.info( - f"Prepare to send - {event.get_sender_name()}/{event.get_sender_id()}: {event._outline_chain(result.chain)}", + t("msg-5e2371a9", res=event.get_sender_name(), res_2=event.get_sender_id(), res_3=event._outline_chain(result.chain)), ) if result.result_content_type == ResultContentType.STREAMING_RESULT: if result.async_stream is None: - logger.warning("async_stream 为空,跳过发送。") + logger.warning(t("msg-df92ac24")) return # 流式结果直接交付平台适配器处理 realtime_segmenting = ( @@ -197,7 +198,7 @@ async def process( ) == "realtime_segmenting" ) - logger.info(f"应用流式输出({event.get_platform_id()})") + logger.info(t("msg-858b0e4f", res=event.get_platform_id())) await event.send_streaming(result.async_stream, realtime_segmenting) return if len(result.chain) > 0: @@ -212,10 +213,10 @@ async def process( # 检查消息链是否为空 try: if await self._is_empty_message_chain(result.chain): - logger.info("消息为空,跳过发送阶段") + logger.info(t("msg-22c7a672")) return except Exception as e: - logger.warning(f"空内容检查异常: {e}") + logger.warning(t("msg-e6ab7a25", e=e)) # 将 Plain 为空的消息段移除 result.chain = [ @@ -239,7 +240,7 @@ async def process( if not result.chain or len(result.chain) == 0: # may fix #2670 logger.warning( - f"实际消息链为空, 跳过发送阶段。header_chain: {header_comps}, actual_chain: {result.chain}", + t("msg-b29b99c1", header_comps=header_comps, res=result.chain), ) return for comp in result.chain: @@ -253,7 +254,7 @@ async def process( header_comps.clear() except Exception as e: logger.error( - f"发送消息链失败: chain = {MessageChain([comp])}, error = {e}", + t("msg-842df577", res=MessageChain([comp]), e=e), exc_info=True, ) else: @@ -263,7 +264,7 @@ async def process( ): # may fix #2670 logger.warning( - f"消息链全为 Reply 和 At 消息段, 跳过发送阶段。chain: {result.chain}", + t("msg-f35465cf", res=result.chain), ) return sep_comps = self._extract_comp( @@ -277,7 +278,7 @@ async def process( await event.send(chain) except Exception as e: logger.error( - f"发送消息链失败: chain = {chain}, error = {e}", + t("msg-784e8a67", chain=chain, e=e), exc_info=True, ) chain = MessageChain(result.chain) @@ -286,7 +287,7 @@ async def process( await event.send(chain) except Exception as e: logger.error( - f"发送消息链失败: chain = {chain}, error = {e}", + t("msg-784e8a67", chain=chain, e=e), exc_info=True, ) diff --git a/astrbot/core/pipeline/result_decorate/stage.py b/astrbot/core/pipeline/result_decorate/stage.py index 15d68fb22e..ab718788e8 100644 --- a/astrbot/core/pipeline/result_decorate/stage.py +++ b/astrbot/core/pipeline/result_decorate/stage.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import random import re import time @@ -163,30 +164,30 @@ async def process( for handler in handlers: try: logger.debug( - f"hook(on_decorating_result) -> {star_map[handler.handler_module_path].name} - {handler.handler_name}", + t("msg-7ec898fd", res=star_map[handler.handler_module_path].name, res_2=handler.handler_name), ) if is_stream: logger.warning( - "启用流式输出时,依赖发送消息前事件钩子的插件可能无法正常工作", + t("msg-5e27dae6"), ) await handler.handler(event) if (result := event.get_result()) is None or not result.chain: logger.debug( - f"hook(on_decorating_result) -> {star_map[handler.handler_module_path].name} - {handler.handler_name} 将消息结果清空。", + t("msg-caaaec29", res=star_map[handler.handler_module_path].name, res_2=handler.handler_name), ) except BaseException: - logger.error(traceback.format_exc()) + logger.error(t("msg-78b9c276", res=traceback.format_exc())) if event.is_stopped(): logger.info( - f"{star_map[handler.handler_module_path].name} - {handler.handler_name} 终止了事件传播。", + t("msg-add19f94", res=star_map[handler.handler_module_path].name, res_2=handler.handler_name), ) return # 流式输出不执行下面的逻辑 if is_stream: - logger.info("流式输出已启用,跳过结果装饰阶段") + logger.info(t("msg-813a44bb")) return # 需要再获取一次。插件可能直接对 chain 进行了替换。 @@ -231,7 +232,7 @@ async def process( ) except re.error: logger.error( - f"分段回复正则表达式错误,使用默认分段方式: {traceback.format_exc()}", + t("msg-891aa43a", res=traceback.format_exc()), ) split_response = re.findall( r".*?[。?!~…]+|.+$", @@ -266,7 +267,7 @@ async def process( ) if should_tts and not tts_provider: logger.warning( - f"会话 {event.unified_msg_origin} 未配置文本转语音模型。", + t("msg-82bb9025", res=event.unified_msg_origin), ) if ( @@ -283,12 +284,12 @@ async def process( for comp in result.chain: if isinstance(comp, Plain) and len(comp.text) > 1: try: - logger.info(f"TTS 请求: {comp.text}") + logger.info(t("msg-fb1c757a", res=comp.text)) audio_path = await tts_provider.get_audio(comp.text) - logger.info(f"TTS 结果: {audio_path}") + logger.info(t("msg-06341d25", audio_path=audio_path)) if not audio_path: logger.error( - f"由于 TTS 音频文件未找到,消息段转语音失败: {comp.text}", + t("msg-2057f670", res=comp.text), ) new_chain.append(comp) continue @@ -309,7 +310,7 @@ async def process( audio_path, ) url = f"{callback_api_base}/api/file/{token}" - logger.debug(f"已注册:{url}") + logger.debug(t("msg-f26725cf", url=url)) new_chain.append( Record( @@ -321,8 +322,8 @@ async def process( if dual_output: new_chain.append(comp) except Exception: - logger.error(traceback.format_exc()) - logger.error("TTS 失败,使用文本发送。") + logger.error(t("msg-78b9c276", res=traceback.format_exc())) + logger.error(t("msg-47716aec")) new_chain.append(comp) else: new_chain.append(comp) @@ -349,11 +350,11 @@ async def process( template_name=self.t2i_active_template, ) except BaseException: - logger.error("文本转图片失败,使用文本发送。") + logger.error(t("msg-ffe054a9")) return if time.time() - render_start > 3: logger.warning( - "文本转图片耗时超过了 3 秒,如果觉得很慢可以使用 /t2i 关闭文本转图片模式。", + t("msg-06c1aedc"), ) if url: if url.startswith("http"): @@ -364,7 +365,7 @@ async def process( ): token = await file_token_service.register_file(url) url = f"{self.ctx.astrbot_config['callback_api_base']}/api/file/{token}" - logger.debug(f"已注册:{url}") + logger.debug(t("msg-f26725cf", url=url)) result.chain = [Image.fromURL(url)] else: result.chain = [Image.fromFileSystem(url)] diff --git a/astrbot/core/pipeline/scheduler.py b/astrbot/core/pipeline/scheduler.py index ffb9c5c99c..d4d2f130d0 100644 --- a/astrbot/core/pipeline/scheduler.py +++ b/astrbot/core/pipeline/scheduler.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t from collections.abc import AsyncGenerator from astrbot.core import logger @@ -53,7 +54,7 @@ async def _process_stages(self, event: AstrMessageEvent, from_stage=0) -> None: # 此处是前置处理完成后的暂停点(yield), 下面开始执行后续阶段 if event.is_stopped(): logger.debug( - f"阶段 {stage.__class__.__name__} 已终止事件传播。", + t("msg-c240d574", res=stage.__class__.__name__), ) break @@ -63,7 +64,7 @@ async def _process_stages(self, event: AstrMessageEvent, from_stage=0) -> None: # 此处是后续所有阶段处理完毕后返回的点, 执行后置处理 if event.is_stopped(): logger.debug( - f"阶段 {stage.__class__.__name__} 已终止事件传播。", + t("msg-c240d574", res=stage.__class__.__name__), ) break else: @@ -72,7 +73,7 @@ async def _process_stages(self, event: AstrMessageEvent, from_stage=0) -> None: await coroutine if event.is_stopped(): - logger.debug(f"阶段 {stage.__class__.__name__} 已终止事件传播。") + logger.debug(t("msg-c240d574", res=stage.__class__.__name__)) break async def execute(self, event: AstrMessageEvent) -> None: @@ -90,6 +91,6 @@ async def execute(self, event: AstrMessageEvent) -> None: if isinstance(event, WebChatMessageEvent | WecomAIBotMessageEvent): await event.send(None) - logger.debug("pipeline 执行完毕。") + logger.debug(t("msg-609a1ac5")) finally: active_event_registry.unregister(event) diff --git a/astrbot/core/pipeline/session_status_check/stage.py b/astrbot/core/pipeline/session_status_check/stage.py index 26c3c235a3..f97da430b8 100644 --- a/astrbot/core/pipeline/session_status_check/stage.py +++ b/astrbot/core/pipeline/session_status_check/stage.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t from collections.abc import AsyncGenerator from astrbot.core import logger @@ -22,7 +23,7 @@ async def process( ) -> None | AsyncGenerator[None, None]: # 检查会话是否整体启用 if not await SessionServiceManager.is_session_enabled(event.unified_msg_origin): - logger.debug(f"会话 {event.unified_msg_origin} 已被关闭,已终止事件传播。") + logger.debug(t("msg-f9aba737", res=event.unified_msg_origin)) # workaround for #2309 conv_id = await self.conv_mgr.get_curr_conversation_id( diff --git a/astrbot/core/pipeline/waking_check/stage.py b/astrbot/core/pipeline/waking_check/stage.py index 2dcb840e91..64d7efcbbf 100644 --- a/astrbot/core/pipeline/waking_check/stage.py +++ b/astrbot/core/pipeline/waking_check/stage.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t from collections.abc import AsyncGenerator, Callable from astrbot import logger @@ -154,7 +155,7 @@ async def process( event.plugins_name = None else: event.plugins_name = enabled_plugins_name - logger.debug(f"enabled_plugins_name: {enabled_plugins_name}") + logger.debug(t("msg-df815938", enabled_plugins_name=enabled_plugins_name)) for handler in star_handlers_registry.get_handlers_by_event_type( EventType.AdapterMessageEvent, @@ -186,7 +187,7 @@ async def process( except Exception as e: await event.send( MessageEventResult().message( - f"插件 {star_map[handler.handler_module_path].name}: {e}", + t("msg-51182733", res=star_map[handler.handler_module_path].name, e=e), ), ) event.stop_event() @@ -200,11 +201,11 @@ async def process( if self.no_permission_reply: await event.send( MessageChain().message( - f"您(ID: {event.get_sender_id()})的权限不足以使用此指令。通过 /sid 获取 ID 并请管理员添加。", + t("msg-e0dcf0b8", res=event.get_sender_id()), ), ) logger.info( - f"触发 {star_map[handler.handler_module_path].name} 时, 用户(ID={event.get_sender_id()}) 权限不足。", + t("msg-a3c3706f", res=star_map[handler.handler_module_path].name, res_2=event.get_sender_id()), ) event.stop_event() return diff --git a/astrbot/core/pipeline/whitelist_check/stage.py b/astrbot/core/pipeline/whitelist_check/stage.py index ea9c55228e..e85ee53aa6 100644 --- a/astrbot/core/pipeline/whitelist_check/stage.py +++ b/astrbot/core/pipeline/whitelist_check/stage.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t from collections.abc import AsyncGenerator from astrbot.core import logger @@ -63,6 +64,6 @@ async def process( ): if self.wl_log: logger.info( - f"会话 ID {event.unified_msg_origin} 不在会话白名单中,已终止事件传播。请在配置文件中添加该会话 ID 到白名单。", + t("msg-8282c664", res=event.unified_msg_origin), ) event.stop_event() diff --git a/astrbot/core/platform/astr_message_event.py b/astrbot/core/platform/astr_message_event.py index 021a4bff7c..66fe396571 100644 --- a/astrbot/core/platform/astr_message_event.py +++ b/astrbot/core/platform/astr_message_event.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import abc import asyncio import hashlib @@ -58,8 +59,7 @@ def __init__( message_type = MessageType(str(message_type)) except (ValueError, TypeError, AttributeError): logger.warning( - f"Failed to convert message type {message_obj.type!r} to MessageType. " - f"Falling back to FRIEND_MESSAGE." + t("msg-b593f13f", res=message_obj.type) ) message_type = MessageType.FRIEND_MESSAGE self.session = MessageSession( @@ -225,7 +225,7 @@ def get_extra(self, key: str | None = None, default=None) -> Any: def clear_extra(self) -> None: """清除额外的信息。""" - logger.info(f"清除 {self.get_platform_name()} 的额外信息: {self._extras}") + logger.info(t("msg-98bb33b7", res=self.get_platform_name(), res_2=self._extras)) self._extras.clear() def is_private_chat(self) -> bool: @@ -301,7 +301,7 @@ async def check_count(self, event: AstrMessageEvent): """ if isinstance(result, str): - result = MessageEventResult().message(result) + result = MessageEventResult().message(t("msg-0def44e2", result=result)) # 兼容外部插件或调用方传入的 chain=None 的情况,确保为可迭代列表 if isinstance(result, MessageEventResult) and result.chain is None: result.chain = [] @@ -361,7 +361,7 @@ def make_result(self) -> MessageEventResult: def plain_result(self, text: str) -> MessageEventResult: """创建一个空的消息事件结果,只包含一条文本消息。""" - return MessageEventResult().message(text) + return MessageEventResult().message(t("msg-8e7dc862", text=text)) def image_result(self, url_or_path: str) -> MessageEventResult: """创建一个空的消息事件结果,只包含一条图片消息。 diff --git a/astrbot/core/platform/manager.py b/astrbot/core/platform/manager.py index 0238779dad..db5a484380 100644 --- a/astrbot/core/platform/manager.py +++ b/astrbot/core/platform/manager.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import traceback from asyncio import Queue @@ -76,11 +77,11 @@ async def _terminate_inst_and_tasks(self, inst: Platform) -> None: raise except Exception as e: logger.error( - "终止平台适配器失败: client_id=%s, error=%s", + t("msg-464b7ab7"), client_id, e, ) - logger.error(traceback.format_exc()) + logger.error(t("msg-78b9c276", res=traceback.format_exc())) finally: await self._stop_platform_task(client_id) @@ -92,7 +93,7 @@ async def initialize(self) -> None: self.astrbot_config.save_config() await self.load_platform(platform) except Exception as e: - logger.error(f"初始化 {platform} 平台适配器失败: {e}") + logger.error(t("msg-563a0a74", platform=platform, e=e)) # 网页聊天 webchat_inst = WebChatAdapter({}, self.settings, self.event_queue) @@ -110,7 +111,7 @@ async def load_platform(self, platform_config: dict) -> None: sanitized_id, changed = self._sanitize_platform_id(platform_id) if sanitized_id and changed: logger.warning( - "平台 ID %r 包含非法字符 ':' 或 '!',已替换为 %r。", + t("msg-8432d24e"), platform_id, sanitized_id, ) @@ -118,12 +119,12 @@ async def load_platform(self, platform_config: dict) -> None: self.astrbot_config.save_config() else: logger.error( - f"平台 ID {platform_id!r} 不能为空,跳过加载该平台适配器。", + t("msg-31361418", platform_id=platform_id), ) return logger.info( - f"载入 {platform_config['type']}({platform_config['id']}) 平台适配器 ...", + t("msg-e395bbcc", res=platform_config['type'], res_2=platform_config['id']), ) match platform_config["type"]: case "aiocqhttp": @@ -182,14 +183,14 @@ async def load_platform(self, platform_config: dict) -> None: ) except (ImportError, ModuleNotFoundError) as e: logger.error( - f"加载平台适配器 {platform_config['type']} 失败,原因:{e}。请检查依赖库是否安装。提示:可以在 管理面板->平台日志->安装Pip库 中安装依赖库。", + t("msg-b4b29344", res=platform_config['type'], e=e), ) except Exception as e: - logger.error(f"加载平台适配器 {platform_config['type']} 失败,原因:{e}。") + logger.error(t("msg-18f0e1fe", res=platform_config['type'], e=e)) if platform_config["type"] not in platform_cls_map: logger.error( - f"未找到适用于 {platform_config['type']}({platform_config['id']}) 平台适配器,请检查是否已经安装或者名称填写错误", + t("msg-2636a882", res=platform_config['type'], res_2=platform_config['id']), ) return cls_type = platform_cls_map[platform_config["type"]] @@ -209,11 +210,11 @@ async def load_platform(self, platform_config: dict) -> None: for handler in handlers: try: logger.info( - f"hook(on_platform_loaded) -> {star_map[handler.handler_module_path].name} - {handler.handler_name}", + t("msg-c4a38b85", res=star_map[handler.handler_module_path].name, res_2=handler.handler_name), ) await handler.handler() except Exception: - logger.error(traceback.format_exc()) + logger.error(t("msg-78b9c276", res=traceback.format_exc())) async def _task_wrapper( self, task: asyncio.Task, platform: Platform | None = None @@ -230,10 +231,10 @@ async def _task_wrapper( except Exception as e: error_msg = str(e) tb_str = traceback.format_exc() - logger.error(f"------- 任务 {task.get_name()} 发生错误: {e}") + logger.error(t("msg-967606fd", res=task.get_name(), e=e)) for line in tb_str.split("\n"): - logger.error(f"| {line}") - logger.error("-------") + logger.error(t("msg-a2cd77f3", line=line)) + logger.error(t("msg-1f686eeb")) # 记录错误到平台实例 if platform: @@ -252,7 +253,7 @@ async def reload(self, platform_config: dict) -> None: async def terminate_platform(self, platform_id: str) -> None: if platform_id in self._inst_map: - logger.info(f"正在尝试终止 {platform_id} 平台适配器 ...") + logger.info(t("msg-38723ea8", platform_id=platform_id)) # client_id = self._inst_map.pop(platform_id, None) info = self._inst_map.pop(platform_id) @@ -267,7 +268,7 @@ async def terminate_platform(self, platform_id: str) -> None: ), ) except Exception: - logger.warning(f"可能未完全移除 {platform_id} 平台适配器") + logger.warning(t("msg-63f684c6", platform_id=platform_id)) await self._terminate_inst_and_tasks(inst) @@ -314,7 +315,7 @@ def get_all_stats(self) -> dict: error_count += 1 except Exception as e: # 如果获取统计信息失败,记录基本信息 - logger.warning(f"获取平台统计信息失败: {e}") + logger.warning(t("msg-136a952f", e=e)) stats_list.append( { "id": getattr(inst, "config", {}).get("id", "unknown"), diff --git a/astrbot/core/platform/platform.py b/astrbot/core/platform/platform.py index a7c181217d..07ed242f43 100644 --- a/astrbot/core/platform/platform.py +++ b/astrbot/core/platform/platform.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import abc import uuid from asyncio import Queue @@ -162,4 +163,4 @@ async def webhook_callback(self, request: Any) -> Any: Raises: NotImplementedError: 平台未实现统一 Webhook 模式 """ - raise NotImplementedError(f"平台 {self.meta().name} 未实现统一 Webhook 模式") + raise NotImplementedError(t("msg-30fc9871", res=self.meta().name)) diff --git a/astrbot/core/platform/register.py b/astrbot/core/platform/register.py index 62ec5070ab..84cd0198bf 100644 --- a/astrbot/core/platform/register.py +++ b/astrbot/core/platform/register.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t from astrbot.core import logger from .platform_metadata import PlatformMetadata @@ -28,7 +29,7 @@ def register_platform_adapter( def decorator(cls): if adapter_name in platform_cls_map: raise ValueError( - f"平台适配器 {adapter_name} 已经注册过了,可能发生了适配器命名冲突。", + t("msg-eecf0aa8", adapter_name=adapter_name), ) # 添加必备选项 @@ -57,7 +58,7 @@ def decorator(cls): ) platform_registry.append(pm) platform_cls_map[adapter_name] = cls - logger.debug(f"平台适配器 {adapter_name} 已注册") + logger.debug(t("msg-614a55eb", adapter_name=adapter_name)) return cls return decorator @@ -86,6 +87,6 @@ def unregister_platform_adapters_by_module(module_path_prefix: str) -> list[str] platform_registry.remove(pm) if pm.name in platform_cls_map: del platform_cls_map[pm.name] - logger.debug(f"平台适配器 {pm.name} 已注销 (来自模块 {pm.module_path})") + logger.debug(t("msg-bb06a88d", res=pm.name, res_2=pm.module_path)) return unregistered diff --git a/astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py b/astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py index 7e42a0fd86..bb6191bb94 100644 --- a/astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py +++ b/astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import re from collections.abc import AsyncGenerator @@ -99,7 +100,7 @@ async def _dispatch_send( await bot.send(event=event, message=messages) else: raise ValueError( - f"无法发送消息:缺少有效的数字 session_id({session_id}) 或 event({event})", + t("msg-0db8227d", session_id=session_id, event=event), ) @classmethod diff --git a/astrbot/core/platform/sources/aiocqhttp/aiocqhttp_platform_adapter.py b/astrbot/core/platform/sources/aiocqhttp/aiocqhttp_platform_adapter.py index 45114382fa..cf0a063248 100644 --- a/astrbot/core/platform/sources/aiocqhttp/aiocqhttp_platform_adapter.py +++ b/astrbot/core/platform/sources/aiocqhttp/aiocqhttp_platform_adapter.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import inspect import itertools @@ -69,7 +70,7 @@ async def request(event: Event) -> None: return await self.handle_msg(abm) except Exception as e: - logger.exception(f"Handle request message failed: {e}") + logger.exception(t("msg-859d480d", e=e)) return @self.bot.on_notice() @@ -79,7 +80,7 @@ async def notice(event: Event) -> None: if abm: await self.handle_msg(abm) except Exception as e: - logger.exception(f"Handle notice message failed: {e}") + logger.exception(t("msg-6fb672e1", e=e)) return @self.bot.on_message("group") @@ -89,7 +90,7 @@ async def group(event: Event) -> None: if abm: await self.handle_msg(abm) except Exception as e: - logger.exception(f"Handle group message failed: {e}") + logger.exception(t("msg-cf4687a3", e=e)) return @self.bot.on_message("private") @@ -99,12 +100,12 @@ async def private(event: Event) -> None: if abm: await self.handle_msg(abm) except Exception as e: - logger.exception(f"Handle private message failed: {e}") + logger.exception(t("msg-3a9853e3", e=e)) return @self.bot.on_websocket_connection def on_websocket_connection(_) -> None: - logger.info("aiocqhttp(OneBot v11) 适配器已连接。") + logger.info(t("msg-ec06dc3d")) async def send_by_session( self, @@ -126,7 +127,7 @@ async def send_by_session( await super().send_by_session(session, message_chain) async def convert_message(self, event: Event) -> AstrBotMessage | None: - logger.debug(f"[aiocqhttp] RawMessage {event}") + logger.debug(t("msg-1304a54d", event=event)) if event["post_type"] == "message": abm = await self._convert_handle_message_event(event) @@ -231,12 +232,12 @@ async def _convert_handle_message_event( message_str = "" if not isinstance(event.message, list): err = f"aiocqhttp: 无法识别的消息类型: {event.message!s},此条消息将被忽略。如果您在使用 go-cqhttp,请将其配置文件中的 message.post-format 更改为 array。" - logger.critical(err) + logger.critical(t("msg-93cbb9fa", err=err)) try: await self.bot.send(event, err) except BaseException as e: - logger.error(f"回复消息失败: {e}") - raise ValueError(err) + logger.error(t("msg-a4487a03", e=e)) + raise ValueError(t("msg-93cbb9fa", err=err)) # 按消息段类型类型适配 for t, m_group in itertools.groupby(event.message, key=lambda x: x["type"]): @@ -254,7 +255,7 @@ async def _convert_handle_message_event( for m in m_group: if m["data"].get("url") and m["data"].get("url").startswith("http"): # Lagrange - logger.info("guessing lagrange") + logger.info(t("msg-48bc7bff")) # 检查多个可能的文件名字段 file_name = ( m["data"].get("file_name", "") @@ -290,12 +291,12 @@ async def _convert_handle_message_event( a = File(name=file_name, url=file_url) abm.message.append(a) else: - logger.error(f"获取文件失败: {ret}") + logger.error(t("msg-6ab145a1", ret=ret)) except ActionFailed as e: - logger.error(f"获取文件失败: {e},此消息段将被忽略。") + logger.error(t("msg-457454d7", e=e)) except BaseException as e: - logger.error(f"获取文件失败: {e},此消息段将被忽略。") + logger.error(t("msg-457454d7", e=e)) elif t == "reply": for m in m_group: @@ -313,7 +314,7 @@ async def _convert_handle_message_event( new_event = Event.from_payload(reply_event_data) if not new_event: logger.error( - f"无法从回复消息数据构造 Event 对象: {reply_event_data}", + t("msg-7a299806", reply_event_data=reply_event_data), ) continue abm_reply = await self._convert_handle_message_event( @@ -334,7 +335,7 @@ async def _convert_handle_message_event( abm.message.append(reply_seg) except BaseException as e: - logger.error(f"获取引用消息失败: {e}。") + logger.error(t("msg-e6633a51", e=e)) a = ComponentTypes[t](**m["data"]) abm.message.append(a) elif t == "at": @@ -384,9 +385,9 @@ async def _convert_handle_message_event( else: abm.message.append(At(qq=str(m["data"]["qq"]), name="")) except ActionFailed as e: - logger.error(f"获取 @ 用户信息失败: {e},此消息段将被忽略。") + logger.error(t("msg-6e99cb8d", e=e)) except BaseException as e: - logger.error(f"获取 @ 用户信息失败: {e},此消息段将被忽略。") + logger.error(t("msg-6e99cb8d", e=e)) message_str += "".join(at_parts) elif t == "markdown": @@ -399,14 +400,14 @@ async def _convert_handle_message_event( try: if t not in ComponentTypes: logger.warning( - f"不支持的消息段类型,已忽略: {t}, data={m['data']}" + t("msg-cf15fd40", t=t, res=m['data']) ) continue a = ComponentTypes[t](**m["data"]) abm.message.append(a) except Exception as e: logger.exception( - f"消息段解析失败: type={t}, data={m['data']}. {e}" + t("msg-45d126ad", t=t, res=m['data'], e=e) ) continue @@ -419,7 +420,7 @@ async def _convert_handle_message_event( def run(self) -> Awaitable[Any]: if not self.host or not self.port: logger.warning( - "aiocqhttp: 未配置 ws_reverse_host 或 ws_reverse_port,将使用默认值:http://0.0.0.0:6199", + t("msg-394a20ae"), ) self.host = "0.0.0.0" self.port = 6199 @@ -476,7 +477,7 @@ async def _close_reverse_ws_connections(self) -> None: async def shutdown_trigger_placeholder(self) -> None: await self.shutdown_event.wait() - logger.info("aiocqhttp 适配器已被关闭") + logger.info(t("msg-7414707c")) def meta(self) -> PlatformMetadata: return self.metadata diff --git a/astrbot/core/platform/sources/dingtalk/dingtalk_adapter.py b/astrbot/core/platform/sources/dingtalk/dingtalk_adapter.py index 2d9b45cc19..59c9610920 100644 --- a/astrbot/core/platform/sources/dingtalk/dingtalk_adapter.py +++ b/astrbot/core/platform/sources/dingtalk/dingtalk_adapter.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import json import threading @@ -37,7 +38,7 @@ class MyEventHandler(dingtalk_stream.EventHandler): async def process(self, event: dingtalk_stream.EventMessage): print( - "2", + t("msg-c81e728d"), event.headers.event_type, event.headers.event_id, event.headers.event_born_time, @@ -65,7 +66,7 @@ def __init__( class AstrCallbackClient(dingtalk_stream.ChatbotHandler): async def process(self, message: dingtalk_stream.CallbackMessage): - logger.debug(f"dingtalk: {message.data}") + logger.debug(t("msg-d6371313", res=message.data)) im = dingtalk_stream.ChatbotMessage.from_dict(message.data) abm = await outer_self.convert_msg(im) await outer_self.handle_msg(abm) @@ -110,7 +111,7 @@ async def send_by_session( staff_id = await self._get_sender_staff_id(session) if not staff_id: logger.warning( - "钉钉私聊会话缺少 staff_id 映射,回退使用 session_id 作为 userId 发送", + t("msg-a1c8b5b1"), ) staff_id = session.session_id await self.send_message_chain_to_user( @@ -229,7 +230,7 @@ async def _remember_sender_binding( sender_staff_id, ) except Exception as e: - logger.warning(f"保存钉钉会话映射失败: {e}") + logger.warning(t("msg-2abb842f", e=e)) async def download_ding_file( self, @@ -266,7 +267,7 @@ async def download_ding_file( ): if resp.status != 200: logger.error( - f"下载钉钉文件失败: {resp.status}, {await resp.text()}", + t("msg-46988861", res=resp.status, res_2=await resp.text()), ) return "" resp_data = await resp.json() @@ -283,7 +284,7 @@ async def get_access_token(self) -> str: if access_token: return access_token except Exception as e: - logger.warning(f"通过 dingtalk_stream 获取 access_token 失败: {e}") + logger.warning(t("msg-ba9e1288", e=e)) payload = {"appKey": self.client_id, "appSecret": self.client_secret} async with aiohttp.ClientSession() as session: @@ -293,7 +294,7 @@ async def get_access_token(self) -> str: ) as resp: if resp.status != 200: logger.error( - f"获取钉钉机器人 access_token 失败: {resp.status}, {await resp.text()}", + t("msg-835b1ce6", res=resp.status, res_2=await resp.text()), ) return "" data = await resp.json() @@ -309,7 +310,7 @@ async def _get_sender_staff_id(self, session: MessageSesion) -> str: ) return cast(str, staff_id or "") except Exception as e: - logger.warning(f"读取钉钉 staff_id 映射失败: {e}") + logger.warning(t("msg-331fcb1f", e=e)) return "" async def _send_group_message( @@ -321,7 +322,7 @@ async def _send_group_message( ) -> None: access_token = await self.get_access_token() if not access_token: - logger.error("钉钉群消息发送失败: access_token 为空") + logger.error(t("msg-ba183a34")) return payload = { @@ -342,7 +343,7 @@ async def _send_group_message( ) as resp: if resp.status != 200: logger.error( - f"钉钉群消息发送失败: {resp.status}, {await resp.text()}", + t("msg-b8aaa69b", res=resp.status, res_2=await resp.text()), ) async def _send_private_message( @@ -354,7 +355,7 @@ async def _send_private_message( ) -> None: access_token = await self.get_access_token() if not access_token: - logger.error("钉钉私聊消息发送失败: access_token 为空") + logger.error(t("msg-cfb35bf5")) return payload = { @@ -375,7 +376,7 @@ async def _send_private_message( ) as resp: if resp.status != 200: logger.error( - f"钉钉私聊消息发送失败: {resp.status}, {await resp.text()}", + t("msg-7553c219", res=resp.status, res_2=await resp.text()), ) def _safe_remove_file(self, file_path: str | None) -> None: @@ -386,7 +387,7 @@ def _safe_remove_file(self, file_path: str | None) -> None: if p.exists() and p.is_file(): p.unlink() except Exception as e: - logger.warning(f"清理临时文件失败: {file_path}, {e}") + logger.warning(t("msg-5ab2d58d", file_path=file_path, e=e)) async def _prepare_voice_for_dingtalk(self, input_path: str) -> tuple[str, bool]: """优先转换为 OGG(Opus),不可用时回退 AMR。""" @@ -398,7 +399,7 @@ async def _prepare_voice_for_dingtalk(self, input_path: str) -> tuple[str, bool] converted = await convert_audio_format(input_path, "ogg") return converted, converted != input_path except Exception as e: - logger.warning(f"钉钉语音转 OGG 失败,回退 AMR: {e}") + logger.warning(t("msg-c0c40912", e=e)) converted = await convert_audio_format(input_path, "amr") return converted, converted != input_path @@ -406,7 +407,7 @@ async def upload_media(self, file_path: str, media_type: str) -> str: media_file_path = Path(file_path) access_token = await self.get_access_token() if not access_token: - logger.error("钉钉媒体上传失败: access_token 为空") + logger.error(t("msg-21c73eca")) return "" form = aiohttp.FormData() @@ -423,12 +424,12 @@ async def upload_media(self, file_path: str, media_type: str) -> str: ) as resp: if resp.status != 200: logger.error( - f"钉钉媒体上传失败: {resp.status}, {await resp.text()}" + t("msg-24e3054f", res=resp.status, res_2=await resp.text()) ) return "" data = await resp.json() if data.get("errcode") != 0: - logger.error(f"钉钉媒体上传失败: {data}") + logger.error(t("msg-34d0a11d", data=data)) return "" return cast(str, data.get("media_id", "")) @@ -504,7 +505,7 @@ async def send_message(msg_key: str, msg_param: dict) -> None: }, ) except Exception as e: - logger.warning(f"钉钉语音发送失败: {e}") + logger.warning(t("msg-3b0d4fb5", e=e)) continue finally: if converted_audio: @@ -535,7 +536,7 @@ async def send_message(msg_key: str, msg_param: dict) -> None: }, ) except Exception as e: - logger.warning(f"钉钉视频发送失败: {e}") + logger.warning(t("msg-7187f424", e=e)) continue finally: self._safe_remove_file(cover_path) @@ -610,7 +611,7 @@ async def send_message_chain_with_incoming( ) staff_id = sender_staff_id or await self._get_sender_staff_id(session) if not staff_id: - logger.error("钉钉私聊回复失败: 缺少 sender_staff_id") + logger.error(t("msg-e40cc45f")) return await self.send_message_chain_to_user( staff_id=staff_id, @@ -643,9 +644,9 @@ def start_client(loop: asyncio.AbstractEventLoop) -> None: task.result() except Exception as e: if "Graceful shutdown" in str(e): - logger.info("钉钉适配器已被关闭") + logger.info(t("msg-be63618a")) return - logger.error(f"钉钉机器人启动失败: {e}") + logger.error(t("msg-0ab22b13", e=e)) loop = asyncio.get_event_loop() await loop.run_in_executor(None, start_client, loop) diff --git a/astrbot/core/platform/sources/dingtalk/dingtalk_event.py b/astrbot/core/platform/sources/dingtalk/dingtalk_event.py index 3331c51476..558b75d474 100644 --- a/astrbot/core/platform/sources/dingtalk/dingtalk_event.py +++ b/astrbot/core/platform/sources/dingtalk/dingtalk_event.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t from typing import Any from astrbot import logger @@ -20,7 +21,7 @@ def __init__( async def send(self, message: MessageChain) -> None: if not self.adapter: - logger.error("钉钉消息发送失败: 缺少 adapter") + logger.error(t("msg-eaa1f3e4")) return await self.adapter.send_message_chain_with_incoming( incoming_message=self.message_obj.raw_message, diff --git a/astrbot/core/platform/sources/discord/client.py b/astrbot/core/platform/sources/discord/client.py index ebd32c471a..eb0dd198c7 100644 --- a/astrbot/core/platform/sources/discord/client.py +++ b/astrbot/core/platform/sources/discord/client.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import sys from collections.abc import Awaitable, Callable @@ -35,11 +36,11 @@ def __init__(self, token: str, proxy: str | None = None) -> None: async def on_ready(self) -> None: """当机器人成功连接并准备就绪时触发""" if self.user is None: - logger.error("[Discord] 客户端未正确加载用户信息 (self.user is None)") + logger.error(t("msg-940888cb")) return - logger.info(f"[Discord] 已作为 {self.user} (ID: {self.user.id}) 登录") - logger.info("[Discord] 客户端已准备就绪。") + logger.info(t("msg-9a3c1925", res=self.user, res_2=self.user.id)) + logger.info(t("msg-30c1f1c8")) if self.on_ready_once_callback and not self._ready_once_fired: self._ready_once_fired = True @@ -47,14 +48,14 @@ async def on_ready(self) -> None: await self.on_ready_once_callback() except Exception as e: logger.error( - f"[Discord] on_ready_once_callback 执行失败: {e}", + t("msg-d8c03bdf", e=e), exc_info=True, ) def _create_message_data(self, message: discord.Message) -> dict: """从 discord.Message 创建数据字典""" if self.user is None: - raise RuntimeError("Bot is not ready: self.user is None") + raise RuntimeError(t("msg-c9601653")) is_mentioned = self.user in message.mentions return { @@ -74,10 +75,10 @@ def _create_message_data(self, message: discord.Message) -> dict: def _create_interaction_data(self, interaction: discord.Interaction) -> dict: """从 discord.Interaction 创建数据字典""" if self.user is None: - raise RuntimeError("Bot is not ready: self.user is None") + raise RuntimeError(t("msg-c9601653")) if interaction.user is None: - raise ValueError("Interaction received without a valid user") + raise ValueError(t("msg-4b017a7c")) return { "interaction": interaction, @@ -99,7 +100,7 @@ async def on_message(self, message: discord.Message) -> None: return logger.debug( - f"[Discord] 收到原始消息 from {message.author.name}: {message.content}", + t("msg-3067bdce", res=message.author.name, res_2=message.content), ) if self.on_message_received: diff --git a/astrbot/core/platform/sources/discord/discord_platform_adapter.py b/astrbot/core/platform/sources/discord/discord_platform_adapter.py index 7657962a11..50014e055c 100644 --- a/astrbot/core/platform/sources/discord/discord_platform_adapter.py +++ b/astrbot/core/platform/sources/discord/discord_platform_adapter.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import re import sys @@ -64,7 +65,7 @@ async def send_by_session( """通过会话发送消息""" if self.client.user is None: logger.error( - "[Discord] 客户端未就绪 (self.client.user is None),无法发送消息" + t("msg-7ea23347") ) return @@ -78,14 +79,14 @@ async def send_by_session( channel_id = int(channel_id_str) channel = self.client.get_channel(channel_id) except (ValueError, TypeError): - logger.warning(f"[Discord] Invalid channel ID format: {channel_id_str}") + logger.warning(t("msg-ff6611ce", channel_id_str=channel_id_str)) if channel: message_obj.type = self._get_message_type(channel) message_obj.group_id = self._get_channel_id(channel) else: logger.warning( - f"[Discord] Can't get channel info for {channel_id_str}, will guess message type.", + t("msg-5e4e5d63", channel_id_str=channel_id_str), ) message_obj.type = MessageType.GROUP_MESSAGE message_obj.group_id = session.session_id @@ -127,7 +128,7 @@ async def run(self) -> None: # 初始化回调函数 async def on_received(message_data) -> None: - logger.debug(f"[Discord] 收到消息: {message_data}") + logger.debug(t("msg-32d4751b", message_data=message_data)) if self.client_self_id is None: self.client_self_id = message_data.get("bot_id") abm = await self.convert_message(data=message_data) @@ -136,7 +137,7 @@ async def on_received(message_data) -> None: # 初始化 Discord 客户端 token = str(self.config.get("discord_token")) if not token: - logger.error("[Discord] Bot Token 未配置。请在配置文件中正确设置 token。") + logger.error(t("msg-8296c994")) return proxy = self.config.get("discord_proxy") or None @@ -158,11 +159,11 @@ async def callback() -> None: self._polling_task = asyncio.create_task(self.client.start_polling()) await self.shutdown_event.wait() except discord.errors.LoginFailure: - logger.error("[Discord] 登录失败。请检查你的 Bot Token 是否正确。") + logger.error(t("msg-170b31df")) except discord.errors.ConnectionClosed: - logger.warning("[Discord] 与 Discord 的连接已关闭。") + logger.warning(t("msg-6678fbd3")) except Exception as e: - logger.error(f"[Discord] 适配器运行时发生意外错误: {e}", exc_info=True) + logger.error(t("msg-cd8c35d2", e=e), exc_info=True) def _get_message_type( self, @@ -264,7 +265,7 @@ async def handle_msg(self, message: AstrBotMessage, followup_webhook=None) -> No if self.client.user is None: logger.error( - "[Discord] 客户端未就绪 (self.client.user is None),无法处理消息" + t("msg-4df30f1d") ) return @@ -283,7 +284,7 @@ async def handle_msg(self, message: AstrBotMessage, followup_webhook=None) -> No raw_message = message.raw_message if not isinstance(raw_message, discord.Message): logger.warning( - f"[Discord] 收到非 Message 类型的消息: {type(raw_message)},已忽略。" + t("msg-f7803502", res=type(raw_message)) ) return @@ -325,7 +326,7 @@ async def handle_msg(self, message: AstrBotMessage, followup_webhook=None) -> No @override async def terminate(self) -> None: """终止适配器""" - logger.info("[Discord] 正在终止适配器... (step 1: cancel polling task)") + logger.info(t("msg-134e70e9")) self.shutdown_event.set() # 优先 cancel polling_task if self._polling_task: @@ -333,10 +334,10 @@ async def terminate(self) -> None: try: await asyncio.wait_for(self._polling_task, timeout=10) except asyncio.CancelledError: - logger.info("[Discord] polling_task 已取消。") + logger.info(t("msg-5c01a092")) except Exception as e: - logger.warning(f"[Discord] polling_task 取消异常: {e}") - logger.info("[Discord] 正在清理已注册的斜杠指令... (step 2)") + logger.warning(t("msg-77f8ca59", e=e)) + logger.info(t("msg-528b6618")) # 清理指令 if self.enable_command_register and self.client: try: @@ -347,16 +348,16 @@ async def terminate(self) -> None: ), timeout=10, ) - logger.info("[Discord] 指令清理完成。") + logger.info(t("msg-d0b832e6")) except Exception as e: - logger.error(f"[Discord] 清理指令时发生错误: {e}", exc_info=True) - logger.info("[Discord] 正在关闭 Discord 客户端... (step 3)") + logger.error(t("msg-43383f5e", e=e), exc_info=True) + logger.info(t("msg-b960ed33")) if self.client and hasattr(self.client, "close"): try: await asyncio.wait_for(self.client.close(), timeout=10) except Exception as e: - logger.warning(f"[Discord] 客户端关闭异常: {e}") - logger.info("[Discord] 适配器已终止。") + logger.warning(t("msg-5e58f8a2", e=e)) + logger.info(t("msg-d1271bf1")) def register_handler(self, handler_info) -> None: """注册处理器信息""" @@ -364,7 +365,7 @@ def register_handler(self, handler_info) -> None: async def _collect_and_register_commands(self) -> None: """收集所有指令并注册到Discord""" - logger.info("[Discord] 开始收集并注册斜杠指令...") + logger.info(t("msg-c374da7a")) registered_commands = [] for handler_md in star_handlers_registry: @@ -405,15 +406,15 @@ async def _collect_and_register_commands(self) -> None: if registered_commands: logger.info( - f"[Discord] 准备同步 {len(registered_commands)} 个指令: {', '.join(registered_commands)}", + t("msg-a6d37e4d", res=len(registered_commands), res_2=', '.join(registered_commands)), ) else: - logger.info("[Discord] 没有发现可注册的指令。") + logger.info(t("msg-dbcaf095")) # 使用 Pycord 的方法同步指令 # 注意:这可能需要一些时间,并且有频率限制 await self.client.sync_commands() - logger.info("[Discord] 指令同步完成。") + logger.info(t("msg-09209f2f")) def _create_dynamic_callback(self, cmd_name: str): """为每个指令动态创建一个异步回调函数""" @@ -422,17 +423,15 @@ async def dynamic_callback( ctx: discord.ApplicationContext, params: str | None = None ) -> None: # 将平台特定的前缀'/'剥离,以适配通用的CommandFilter - logger.debug(f"[Discord] 回调函数触发: {cmd_name}") - logger.debug(f"[Discord] 回调函数参数: {ctx}") - logger.debug(f"[Discord] 回调函数参数: {params}") + logger.debug(t("msg-a95055fd", cmd_name=cmd_name)) + logger.debug(t("msg-55b13b1e", ctx=ctx)) + logger.debug(t("msg-79f72e4e", params=params)) message_str_for_filter = cmd_name if params: message_str_for_filter += f" {params}" logger.debug( - f"[Discord] 斜杠指令 '{cmd_name}' 被触发。 " - f"原始参数: '{params}'. " - f"构建的指令字符串: '{message_str_for_filter}'", + t("msg-22add467", cmd_name=cmd_name, params=params, message_str_for_filter=message_str_for_filter), ) # 尝试立即响应,防止超时 @@ -441,7 +440,7 @@ async def dynamic_callback( await ctx.defer() followup_webhook = ctx.followup except Exception as e: - logger.warning(f"[Discord] 指令 '{cmd_name}' defer 失败: {e}") + logger.warning(t("msg-ccffc74a", cmd_name=cmd_name, e=e)) # 2. 构建 AstrBotMessage channel = ctx.channel @@ -503,7 +502,7 @@ def _extract_command_info( # Discord 斜杠指令名称规范 if not re.match(r"^[a-z0-9_-]{1,32}$", cmd_name): - logger.debug(f"[Discord] 跳过不符合规范的指令: {cmd_name}") + logger.debug(t("msg-13402a28", cmd_name=cmd_name)) return None description = handler_metadata.desc or f"指令: {cmd_name}" diff --git a/astrbot/core/platform/sources/discord/discord_platform_event.py b/astrbot/core/platform/sources/discord/discord_platform_event.py index 02d4dae868..faa8f50306 100644 --- a/astrbot/core/platform/sources/discord/discord_platform_event.py +++ b/astrbot/core/platform/sources/discord/discord_platform_event.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import base64 import binascii @@ -58,7 +59,7 @@ async def send(self, message: MessageChain) -> None: reference_message_id, ) = await self._parse_to_discord(message) except Exception as e: - logger.error(f"[Discord] 解析消息链时失败: {e}", exc_info=True) + logger.error(t("msg-0056366b", e=e), exc_info=True) return kwargs = {} @@ -73,7 +74,7 @@ async def send(self, message: MessageChain) -> None: if reference_message_id and not self.interaction_followup_webhook: kwargs["reference"] = self.client.get_message(int(reference_message_id)) if not kwargs: - logger.debug("[Discord] 尝试发送空消息,已忽略。") + logger.debug(t("msg-fa0a9e40")) return # 根据上下文执行发送/回复操作 @@ -88,12 +89,12 @@ async def send(self, message: MessageChain) -> None: if not channel: return if not isinstance(channel, discord.abc.Messageable): - logger.error(f"[Discord] 频道 {channel.id} 不是可发送消息的类型") + logger.error(t("msg-5ccebf9a", res=channel.id)) return await channel.send(**kwargs) except Exception as e: - logger.error(f"[Discord] 发送消息时发生未知错误: {e}", exc_info=True) + logger.error(t("msg-1550c1eb", e=e), exc_info=True) await super().send(message) @@ -122,7 +123,7 @@ async def _get_channel( channel_id, ) or await self.client.fetch_channel(channel_id) except (ValueError, discord.errors.NotFound, discord.errors.Forbidden): - logger.error(f"[Discord] 无法获取频道 {self.session_id}") + logger.error(t("msg-7857133d", res=self.session_id)) return None async def _parse_to_discord( @@ -149,27 +150,27 @@ async def _parse_to_discord( elif isinstance(i, At): content_parts.append(f"<@{i.qq}>") elif isinstance(i, Image): - logger.debug(f"[Discord] 开始处理 Image 组件: {i}") + logger.debug(t("msg-050aa8d6", i=i)) try: filename = getattr(i, "filename", None) file_content = getattr(i, "file", None) if not file_content: - logger.warning(f"[Discord] Image 组件没有 file 属性: {i}") + logger.warning(t("msg-57c802ef", i=i)) continue discord_file = None # 1. URL if file_content.startswith("http"): - logger.debug(f"[Discord] 处理 URL 图片: {file_content}") + logger.debug(t("msg-f2bea7ac", file_content=file_content)) embed = discord.Embed().set_image(url=file_content) embeds.append(embed) continue # 2. File URI if file_content.startswith("file:///"): - logger.debug(f"[Discord] 处理 File URI: {file_content}") + logger.debug(t("msg-c3eae1f1", file_content=file_content)) path = Path(file_content[8:]) if await asyncio.to_thread(path.exists): file_bytes = await asyncio.to_thread(path.read_bytes) @@ -178,11 +179,11 @@ async def _parse_to_discord( filename=filename or path.name, ) else: - logger.warning(f"[Discord] 图片文件不存在: {path}") + logger.warning(t("msg-6201da92", path=path)) # 3. Base64 URI elif file_content.startswith("base64://"): - logger.debug("[Discord] 处理 Base64 URI") + logger.debug(t("msg-2a6f0cd4")) b64_data = file_content.split("base64://", 1)[1] missing_padding = len(b64_data) % 4 if missing_padding: @@ -196,7 +197,7 @@ async def _parse_to_discord( # 4. 裸 Base64 或本地路径 else: try: - logger.debug("[Discord] 尝试作为裸 Base64 处理") + logger.debug(t("msg-b589c643")) b64_data = file_content missing_padding = len(b64_data) % 4 if missing_padding: @@ -208,7 +209,7 @@ async def _parse_to_discord( ) except (ValueError, TypeError, binascii.Error): logger.debug( - f"[Discord] 裸 Base64 解码失败,作为本地路径处理: {file_content}", + t("msg-41dd4b8f", file_content=file_content), ) path = Path(file_content) if await asyncio.to_thread(path.exists): @@ -218,7 +219,7 @@ async def _parse_to_discord( filename=filename or path.name, ) else: - logger.warning(f"[Discord] 图片文件不存在: {path}") + logger.warning(t("msg-6201da92", path=path)) if discord_file: files.append(discord_file) @@ -227,7 +228,7 @@ async def _parse_to_discord( # 使用 getattr 来安全地访问 i.file,以防 i 本身就是问题 file_info = getattr(i, "file", "未知") logger.error( - f"[Discord] 处理图片时发生未知严重错误: {file_info}", + t("msg-f59778a1", file_info=file_info), exc_info=True, ) elif isinstance(i, File): @@ -242,12 +243,12 @@ async def _parse_to_discord( ) else: logger.warning( - f"[Discord] 获取文件失败,路径不存在: {file_path_str}", + t("msg-85665612", file_path_str=file_path_str), ) else: - logger.warning(f"[Discord] 获取文件失败: {i.name}") + logger.warning(t("msg-e55956fb", res=i.name)) except Exception as e: - logger.warning(f"[Discord] 处理文件失败: {i.name}, 错误: {e}") + logger.warning(t("msg-56cc0d48", res=i.name, e=e)) elif isinstance(i, DiscordEmbed): # Discord Embed消息 embeds.append(i.to_discord_embed()) @@ -259,11 +260,11 @@ async def _parse_to_discord( if isinstance(i.view, discord.ui.View): view = i.view else: - logger.debug(f"[Discord] 忽略了不支持的消息组件: {i.type}") + logger.debug(t("msg-c0705d4e", res=i.type)) content = "".join(content_parts) if len(content) > 2000: - logger.warning("[Discord] 消息内容超过2000字符,将被截断。") + logger.warning(t("msg-0417d127")) content = content[:2000] return content, files, view, embeds, reference_message_id @@ -278,7 +279,7 @@ async def react(self, emoji: str) -> None: emoji ) except Exception as e: - logger.error(f"[Discord] 添加反应失败: {e}") + logger.error(t("msg-6277510f", e=e)) def is_slash_command(self) -> bool: """判断是否为斜杠命令""" diff --git a/astrbot/core/platform/sources/lark/lark_adapter.py b/astrbot/core/platform/sources/lark/lark_adapter.py index be1c81c26e..27eb695063 100644 --- a/astrbot/core/platform/sources/lark/lark_adapter.py +++ b/astrbot/core/platform/sources/lark/lark_adapter.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import base64 import json @@ -54,7 +55,7 @@ def __init__( self.connection_mode = platform_config.get("lark_connection_mode", "socket") if not self.bot_name: - logger.warning("未设置飞书机器人名称,@ 机器人可能得不到回复。") + logger.warning(t("msg-06ce76eb")) # 初始化 WebSocket 长连接相关配置 async def on_msg_event_recv(event: lark.im.v1.P2ImMessageReceiveV1) -> None: @@ -103,7 +104,7 @@ async def _download_message_resource( resource_type: str, ) -> bytes | None: if self.lark_api.im is None: - logger.error("[Lark] API Client im 模块未初始化") + logger.error(t("msg-eefbe737")) return None request = ( @@ -116,13 +117,12 @@ async def _download_message_resource( response = await self.lark_api.im.v1.message_resource.aget(request) if not response.success(): logger.error( - f"[Lark] 下载消息资源失败 type={resource_type}, key={file_key}, " - f"code={response.code}, msg={response.msg}", + t("msg-236bcaad", resource_type=resource_type, file_key=file_key, res=response.code, res_2=response.msg), ) return None if response.file is None: - logger.error(f"[Lark] 消息资源响应中不包含文件流: {file_key}") + logger.error(t("msg-ef9a61fe", file_key=file_key)) return None return response.file.read() @@ -245,7 +245,7 @@ async def _parse_message_components( if not image_key: continue if not message_id: - logger.error("[Lark] 图片消息缺少 message_id") + logger.error(t("msg-7b69a8d4")) continue image_bytes = await self._download_message_resource( message_id=message_id, @@ -264,7 +264,7 @@ async def _parse_message_components( if not file_key: continue if not message_id: - logger.error("[Lark] 富文本视频消息缺少 message_id") + logger.error(t("msg-59f1694d")) continue file_path = await self._download_file_resource_to_temp( message_id=message_id, @@ -282,10 +282,10 @@ async def _parse_message_components( file_key = str(content.get("file_key", "")).strip() file_name = str(content.get("file_name", "")).strip() or "lark_file" if not message_id: - logger.error("[Lark] 文件消息缺少 message_id") + logger.error(t("msg-af8f391d")) return components if not file_key: - logger.error("[Lark] 文件消息缺少 file_key") + logger.error(t("msg-d4080b76")) return components file_path = await self._download_file_resource_to_temp( message_id=message_id, @@ -300,10 +300,10 @@ async def _parse_message_components( if message_type == "audio": file_key = str(content.get("file_key", "")).strip() if not message_id: - logger.error("[Lark] 音频消息缺少 message_id") + logger.error(t("msg-ab21318a")) return components if not file_key: - logger.error("[Lark] 音频消息缺少 file_key") + logger.error(t("msg-9ec2c30a")) return components file_path = await self._download_file_resource_to_temp( message_id=message_id, @@ -319,10 +319,10 @@ async def _parse_message_components( file_key = str(content.get("file_key", "")).strip() file_name = str(content.get("file_name", "")).strip() or "lark_media.mp4" if not message_id: - logger.error("[Lark] 视频消息缺少 message_id") + logger.error(t("msg-0fa9ed18")) return components if not file_key: - logger.error("[Lark] 视频消息缺少 file_key") + logger.error(t("msg-ae884c5c")) return components file_path = await self._download_file_resource_to_temp( message_id=message_id, @@ -342,21 +342,20 @@ async def _build_reply_from_parent_id( parent_message_id: str, ) -> Comp.Reply | None: if self.lark_api.im is None: - logger.error("[Lark] API Client im 模块未初始化") + logger.error(t("msg-eefbe737")) return None request = GetMessageRequest.builder().message_id(parent_message_id).build() response = await self.lark_api.im.v1.message.aget(request) if not response.success(): logger.error( - f"[Lark] 获取引用消息失败 id={parent_message_id}, " - f"code={response.code}, msg={response.msg}", + t("msg-dac98a62", parent_message_id=parent_message_id, res=response.code, res_2=response.msg), ) return None if response.data is None or not response.data.items: logger.error( - f"[Lark] 引用消息响应为空 id={parent_message_id}", + t("msg-7ee9f7dc", parent_message_id=parent_message_id), ) return None @@ -385,7 +384,7 @@ async def _build_reply_from_parent_id( quoted_content_json = parsed except json.JSONDecodeError: logger.warning( - f"[Lark] 解析引用消息内容失败 id={quoted_message_id}", + t("msg-2b3b2db9", quoted_message_id=quoted_message_id), ) quoted_at_map = self._build_at_map(parent_message.mentions) @@ -496,11 +495,11 @@ def meta(self) -> PlatformMetadata: async def convert_msg(self, event: lark.im.v1.P2ImMessageReceiveV1) -> None: if event.event is None: - logger.debug("[Lark] 收到空事件(event.event is None)") + logger.debug(t("msg-c5d54255")) return message = event.event.message if message is None: - logger.debug("[Lark] 事件中没有消息体(message is None)") + logger.debug(t("msg-82f041c4")) return abm = AstrBotMessage() @@ -539,20 +538,20 @@ async def convert_msg(self, event: lark.im.v1.P2ImMessageReceiveV1) -> None: abm.self_id = m.id.open_id if message.content is None: - logger.warning("[Lark] 消息内容为空") + logger.warning(t("msg-206c3506")) return try: content_json_b = json.loads(message.content) except json.JSONDecodeError: - logger.error(f"[Lark] 解析消息内容失败: {message.content}") + logger.error(t("msg-876aa1d2", res=message.content)) return if not isinstance(content_json_b, dict): - logger.error(f"[Lark] 消息内容不是 JSON Object: {message.content}") + logger.error(t("msg-514230f3", res=message.content)) return - logger.debug(f"[Lark] 解析消息内容: {content_json_b}") + logger.debug(t("msg-0898cf8b", content_json_b=content_json_b)) parsed_components = await self._parse_message_components( message_id=message.message_id, message_type=message.message_type or "unknown", @@ -563,7 +562,7 @@ async def convert_msg(self, event: lark.im.v1.P2ImMessageReceiveV1) -> None: abm.message_str = self._build_message_str_from_components(parsed_components) if message.message_id is None: - logger.error("[Lark] 消息缺少 message_id") + logger.error(t("msg-6a8bc661")) return if ( @@ -571,7 +570,7 @@ async def convert_msg(self, event: lark.im.v1.P2ImMessageReceiveV1) -> None: or event.event.sender.sender_id is None or event.event.sender.sender_id.open_id is None ): - logger.error("[Lark] 消息发送者信息不完整") + logger.error(t("msg-26554571")) return abm.message_id = message.message_id @@ -608,7 +607,7 @@ async def handle_webhook_event(self, event_data: dict) -> None: header = event_data.get("header", {}) event_id = header.get("event_id", "") if event_id and self._is_duplicate_event(event_id): - logger.debug(f"[Lark Webhook] 跳过重复事件: {event_id}") + logger.debug(t("msg-007d863a", event_id=event_id)) return event_type = header.get("event_type", "") if event_type == "im.message.receive_v1": @@ -616,22 +615,22 @@ async def handle_webhook_event(self, event_data: dict) -> None: data = (processor.type())(event_data) processor.do(data) else: - logger.debug(f"[Lark Webhook] 未处理的事件类型: {event_type}") + logger.debug(t("msg-6ce17e71", event_type=event_type)) except Exception as e: - logger.error(f"[Lark Webhook] 处理事件失败: {e}", exc_info=True) + logger.error(t("msg-8689a644", e=e), exc_info=True) async def run(self) -> None: if self.connection_mode == "webhook": # Webhook 模式 if self.webhook_server is None: - logger.error("[Lark] Webhook 模式已启用,但 webhook_server 未初始化") + logger.error(t("msg-20688453")) return webhook_uuid = self.config.get("webhook_uuid") if webhook_uuid: log_webhook_info(f"{self.meta().id}(飞书 Webhook)", webhook_uuid) else: - logger.warning("[Lark] Webhook 模式已启用,但未配置 webhook_uuid") + logger.warning(t("msg-f46171bc")) else: # 长连接模式 await self.client._connect() @@ -646,7 +645,7 @@ async def webhook_callback(self, request: Any) -> Any: async def terminate(self) -> None: if self.connection_mode == "socket": await self.client._disconnect() - logger.info("飞书(Lark) 适配器已关闭") + logger.info(t("msg-dd90a367")) def get_client(self) -> lark.ws.Client: return self.client diff --git a/astrbot/core/platform/sources/lark/lark_event.py b/astrbot/core/platform/sources/lark/lark_event.py index 92e3a32b9e..6432ea3d69 100644 --- a/astrbot/core/platform/sources/lark/lark_event.py +++ b/astrbot/core/platform/sources/lark/lark_event.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import base64 import json import os @@ -66,7 +67,7 @@ async def _send_im_message( 是否发送成功 """ if lark_client.im is None: - logger.error("[Lark] API Client im 模块未初始化") + logger.error(t("msg-eefbe737")) return False if reply_message_id: @@ -92,7 +93,7 @@ async def _send_im_message( if receive_id_type is None or receive_id is None: logger.error( - "[Lark] 主动发送消息时,receive_id 和 receive_id_type 不能为空", + t("msg-a21f93fa"), ) return False @@ -112,7 +113,7 @@ async def _send_im_message( response = await lark_client.im.v1.message.acreate(request) if not response.success(): - logger.error(f"[Lark] 发送飞书消息失败({response.code}): {response.msg}") + logger.error(t("msg-f456e468", res=response.code, res_2=response.msg)) return False return True @@ -137,11 +138,11 @@ async def _upload_lark_file( 成功返回file_key,失败返回None """ if not path or not os.path.exists(path): - logger.error(f"[Lark] 文件不存在: {path}") + logger.error(t("msg-1eb66d14", path=path)) return None if lark_client.im is None: - logger.error("[Lark] API Client im 模块未初始化,无法上传文件") + logger.error(t("msg-1df39b24")) return None try: @@ -164,20 +165,20 @@ async def _upload_lark_file( if not response.success(): logger.error( - f"[Lark] 无法上传文件({response.code}): {response.msg}" + t("msg-2ee721dd", res=response.code, res_2=response.msg) ) return None if response.data is None: - logger.error("[Lark] 上传文件成功但未返回数据(data is None)") + logger.error(t("msg-a04abf78")) return None file_key = response.data.file_key - logger.debug(f"[Lark] 文件上传成功: {file_key}") + logger.debug(t("msg-959e78a4", file_key=file_key)) return file_key except Exception as e: - logger.error(f"[Lark] 无法打开或上传文件: {e}") + logger.error(t("msg-901a2f60", e=e)) return None @staticmethod @@ -214,12 +215,12 @@ async def _convert_to_lark(message: MessageChain, lark_client: lark.Client) -> l if image_file is None: if not file_path: - logger.error("[Lark] 图片路径为空,无法上传") + logger.error(t("msg-13065327")) continue try: image_file = open(file_path, "rb") except Exception as e: - logger.error(f"[Lark] 无法打开图片文件: {e}") + logger.error(t("msg-37245892", e=e)) continue request = ( @@ -234,37 +235,37 @@ async def _convert_to_lark(message: MessageChain, lark_client: lark.Client) -> l ) if lark_client.im is None: - logger.error("[Lark] API Client im 模块未初始化,无法上传图片") + logger.error(t("msg-ad63bf53")) continue response = await lark_client.im.v1.image.acreate(request) if not response.success(): - logger.error(f"无法上传飞书图片({response.code}): {response.msg}") + logger.error(t("msg-ef90038b", res=response.code, res_2=response.msg)) continue if response.data is None: - logger.error("[Lark] 上传图片成功但未返回数据(data is None)") + logger.error(t("msg-d2065832")) continue image_key = response.data.image_key - logger.debug(image_key) + logger.debug(t("msg-dbb635c2", image_key=image_key)) ret.append(_stage) ret.append([{"tag": "img", "image_key": image_key}]) _stage.clear() elif isinstance(comp, File): # 文件将通过 _send_file_message 方法单独发送,这里跳过 - logger.debug("[Lark] 检测到文件组件,将单独发送") + logger.debug(t("msg-d4810504")) continue elif isinstance(comp, Record): # 音频将通过 _send_audio_message 方法单独发送,这里跳过 - logger.debug("[Lark] 检测到音频组件,将单独发送") + logger.debug(t("msg-45556717")) continue elif isinstance(comp, Video): # 视频将通过 _send_media_message 方法单独发送,这里跳过 - logger.debug("[Lark] 检测到视频组件,将单独发送") + logger.debug(t("msg-959070b5")) continue else: - logger.warning(f"飞书 暂时不支持消息段: {comp.type}") + logger.warning(t("msg-4e2aa152", res=comp.type)) if _stage: ret.append(_stage) @@ -288,7 +289,7 @@ async def send_message_chain( receive_id_type: 接收者ID类型,如 'open_id', 'chat_id'(用于主动发送) """ if lark_client.im is None: - logger.error("[Lark] API Client im 模块未初始化") + logger.error(t("msg-eefbe737")) return # 分离文件、音频、视频组件和其他组件 @@ -409,11 +410,11 @@ async def _send_audio_message( try: original_audio_path = await audio_comp.convert_to_file_path() except Exception as e: - logger.error(f"[Lark] 无法获取音频文件路径: {e}") + logger.error(t("msg-20d7c64b", e=e)) return if not original_audio_path or not os.path.exists(original_audio_path): - logger.error(f"[Lark] 音频文件不存在: {original_audio_path}") + logger.error(t("msg-2f6f35e6", original_audio_path=original_audio_path)) return # 转换为opus格式 @@ -426,7 +427,7 @@ async def _send_audio_message( else: audio_path = original_audio_path except Exception as e: - logger.error(f"[Lark] 音频格式转换失败,将尝试直接上传: {e}") + logger.error(t("msg-528b968d", e=e)) # 如果转换失败,继续尝试直接上传原始文件 audio_path = original_audio_path @@ -445,9 +446,9 @@ async def _send_audio_message( if converted_audio_path and os.path.exists(converted_audio_path): try: os.remove(converted_audio_path) - logger.debug(f"[Lark] 已删除转换后的音频文件: {converted_audio_path}") + logger.debug(t("msg-fbc7efb9", converted_audio_path=converted_audio_path)) except Exception as e: - logger.warning(f"[Lark] 删除转换后的音频文件失败: {e}") + logger.warning(t("msg-09840299", e=e)) if not file_key: return @@ -482,11 +483,11 @@ async def _send_media_message( try: original_video_path = await media_comp.convert_to_file_path() except Exception as e: - logger.error(f"[Lark] 无法获取视频文件路径: {e}") + logger.error(t("msg-e073ff1c", e=e)) return if not original_video_path or not os.path.exists(original_video_path): - logger.error(f"[Lark] 视频文件不存在: {original_video_path}") + logger.error(t("msg-47e52913", original_video_path=original_video_path)) return # 转换为mp4格式 @@ -499,7 +500,7 @@ async def _send_media_message( else: video_path = original_video_path except Exception as e: - logger.error(f"[Lark] 视频格式转换失败,将尝试直接上传: {e}") + logger.error(t("msg-85ded1eb", e=e)) # 如果转换失败,继续尝试直接上传原始文件 video_path = original_video_path @@ -518,9 +519,9 @@ async def _send_media_message( if converted_video_path and os.path.exists(converted_video_path): try: os.remove(converted_video_path) - logger.debug(f"[Lark] 已删除转换后的视频文件: {converted_video_path}") + logger.debug(t("msg-b3bee05d", converted_video_path=converted_video_path)) except Exception as e: - logger.warning(f"[Lark] 删除转换后的视频文件失败: {e}") + logger.warning(t("msg-775153f6", e=e)) if not file_key: return @@ -536,7 +537,7 @@ async def _send_media_message( async def react(self, emoji: str) -> None: if self.bot.im is None: - logger.error("[Lark] API Client im 模块未初始化,无法发送表情") + logger.error(t("msg-45038ba7")) return request = ( @@ -552,7 +553,7 @@ async def react(self, emoji: str) -> None: response = await self.bot.im.v1.message_reaction.acreate(request) if not response.success(): - logger.error(f"发送飞书表情回应失败({response.code}): {response.msg}") + logger.error(t("msg-8d475b01", res=response.code, res_2=response.msg)) return async def send_streaming(self, generator, use_fallback: bool = False): diff --git a/astrbot/core/platform/sources/lark/server.py b/astrbot/core/platform/sources/lark/server.py index 52177ebb0c..9f6d6ef55b 100644 --- a/astrbot/core/platform/sources/lark/server.py +++ b/astrbot/core/platform/sources/lark/server.py @@ -6,6 +6,7 @@ 3. 签名校验 (SHA256) 4. 事件接收和处理 """ +from astrbot.core.lang import t import asyncio import base64 @@ -109,7 +110,7 @@ def decrypt_event(self, encrypted_data: str) -> dict: 解密后的事件字典 """ if not self.cipher: - raise ValueError("未配置 encrypt_key,无法解密事件") + raise ValueError(t("msg-2f3bccf1")) decrypted_str = self.cipher.decrypt_string(encrypted_data) return json.loads(decrypted_str) @@ -124,7 +125,7 @@ async def handle_challenge(self, event_data: dict) -> dict: 包含 challenge 的响应 """ challenge = event_data.get("challenge", "") - logger.info(f"[Lark Webhook] 收到 challenge 验证请求: {challenge}") + logger.info(t("msg-e77104e2", challenge=challenge)) return {"challenge": challenge} @@ -143,11 +144,11 @@ async def handle_callback(self, request) -> tuple[dict, int] | dict: try: event_data = await request.json except Exception as e: - logger.error(f"[Lark Webhook] 解析请求体失败: {e}") + logger.error(t("msg-34b24fa1", e=e)) return {"error": "Invalid JSON"}, 400 if not event_data: - logger.error("[Lark Webhook] 请求体为空") + logger.error(t("msg-ec0fe13e")) return {"error": "Empty request body"}, 400 # 如果配置了 encrypt_key,进行签名验证 @@ -160,16 +161,16 @@ async def handle_callback(self, request) -> tuple[dict, int] | dict: if not self.verify_signature( timestamp, nonce, self.encrypt_key, body, signature ): - logger.error("[Lark Webhook] 签名验证失败") + logger.error(t("msg-f69ebbdb")) return {"error": "Invalid signature"}, 401 # 检查是否是加密事件 if "encrypt" in event_data: try: event_data = self.decrypt_event(event_data["encrypt"]) - logger.debug(f"[Lark Webhook] 解密后的事件: {event_data}") + logger.debug(t("msg-7ece4036", event_data=event_data)) except Exception as e: - logger.error(f"[Lark Webhook] 解密事件失败: {e}") + logger.error(t("msg-f2cb4b46", e=e)) return {"error": "Decryption failed"}, 400 # 验证 token @@ -180,7 +181,7 @@ async def handle_callback(self, request) -> tuple[dict, int] | dict: else: token = event_data.get("token", "") if token != self.verification_token: - logger.error("[Lark Webhook] Verification Token 不匹配。") + logger.error(t("msg-ef9f8906")) return {"error": "Invalid verification token"}, 401 # 处理 URL 验证 (challenge) @@ -192,7 +193,7 @@ async def handle_callback(self, request) -> tuple[dict, int] | dict: try: await self.callback(event_data) except Exception as e: - logger.error(f"[Lark Webhook] 处理事件回调失败: {e}", exc_info=True) + logger.error(t("msg-bedb2071", e=e), exc_info=True) return {"error": "Event processing failed"}, 500 return {} diff --git a/astrbot/core/platform/sources/line/line_adapter.py b/astrbot/core/platform/sources/line/line_adapter.py index c13677b13b..c7821b7aaa 100644 --- a/astrbot/core/platform/sources/line/line_adapter.py +++ b/astrbot/core/platform/sources/line/line_adapter.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import mimetypes import time @@ -86,7 +87,7 @@ def __init__( channel_secret = str(platform_config.get("channel_secret", "")) if not channel_access_token or not channel_secret: raise ValueError( - "LINE 适配器需要 channel_access_token 和 channel_secret。", + t("msg-68539775"), ) self.line_api = LineAPIClient( @@ -117,7 +118,7 @@ async def run(self) -> None: if webhook_uuid: log_webhook_info(f"{self.meta().id}(LINE)", webhook_uuid) else: - logger.warning("[LINE] webhook_uuid 为空,统一 Webhook 可能无法接收消息。") + logger.warning(t("msg-30c67081")) await self.shutdown_event.wait() async def terminate(self) -> None: @@ -128,13 +129,13 @@ async def webhook_callback(self, request: Any) -> Any: raw_body = await request.get_data() signature = request.headers.get("x-line-signature") if not self.line_api.verify_signature(raw_body, signature): - logger.warning("[LINE] invalid webhook signature") + logger.warning(t("msg-64e92929")) return "invalid signature", 400 try: payload = await request.get_json(force=True, silent=False) except Exception as e: - logger.warning("[LINE] invalid webhook body: %s", e) + logger.warning(t("msg-71bc0b77"), e) return "bad request", 400 if not isinstance(payload, dict): @@ -158,7 +159,7 @@ async def handle_webhook_event(self, payload: dict[str, Any]) -> None: event_id = str(event.get("webhookEventId", "")) if event_id and self._is_duplicate_event(event_id): - logger.debug("[LINE] duplicate event skipped: %s", event_id) + logger.debug(t("msg-8c7d9bab"), event_id) continue abm = await self.convert_message(event) diff --git a/astrbot/core/platform/sources/line/line_api.py b/astrbot/core/platform/sources/line/line_api.py index 32204bd6ee..a65842a210 100644 --- a/astrbot/core/platform/sources/line/line_api.py +++ b/astrbot/core/platform/sources/line/line_api.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import base64 import hmac @@ -102,14 +103,14 @@ async def _post_json( return True body = await resp.text() logger.error( - "[LINE] %s message failed: status=%s body=%s", + t("msg-06e3f874"), op_name, resp.status, body, ) return False except Exception as e: - logger.error("[LINE] %s message request failed: %s", op_name, e) + logger.error(t("msg-1478c917"), op_name, e) return False async def get_message_content( @@ -128,7 +129,7 @@ async def get_message_content( if retry_resp.status != 200: body = await retry_resp.text() logger.warning( - "[LINE] get content retry failed: message_id=%s status=%s body=%s", + t("msg-39941f06"), message_id, retry_resp.status, body, @@ -139,7 +140,7 @@ async def get_message_content( if resp.status != 200: body = await resp.text() logger.warning( - "[LINE] get content failed: message_id=%s status=%s body=%s", + t("msg-1fe70511"), message_id, resp.status, body, diff --git a/astrbot/core/platform/sources/line/line_event.py b/astrbot/core/platform/sources/line/line_event.py index 04be53922b..e582d6b720 100644 --- a/astrbot/core/platform/sources/line/line_event.py +++ b/astrbot/core/platform/sources/line/line_event.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import os import re @@ -109,7 +110,7 @@ async def _resolve_image_url(segment: Image) -> str: try: return await segment.register_to_file_service() except Exception as e: - logger.debug("[LINE] resolve image url failed: %s", e) + logger.debug(t("msg-4068a191"), e) return "" @staticmethod @@ -120,7 +121,7 @@ async def _resolve_record_url(segment: Record) -> str: try: return await segment.register_to_file_service() except Exception as e: - logger.debug("[LINE] resolve record url failed: %s", e) + logger.debug(t("msg-2233b256"), e) return "" @staticmethod @@ -131,7 +132,7 @@ async def _resolve_record_duration(segment: Record) -> int: if isinstance(duration_ms, int) and duration_ms > 0: return duration_ms except Exception as e: - logger.debug("[LINE] resolve record duration failed: %s", e) + logger.debug(t("msg-a7455817"), e) return 1000 @staticmethod @@ -142,7 +143,7 @@ async def _resolve_video_url(segment: Video) -> str: try: return await segment.register_to_file_service() except Exception as e: - logger.debug("[LINE] resolve video url failed: %s", e) + logger.debug(t("msg-9d0fee66"), e) return "" @staticmethod @@ -158,7 +159,7 @@ async def _resolve_video_preview_url(segment: Video) -> str: cover_seg = Image(file=cover_candidate) return await cover_seg.register_to_file_service() except Exception as e: - logger.debug("[LINE] resolve video cover failed: %s", e) + logger.debug(t("msg-3b8ea946"), e) try: video_path = await segment.convert_to_file_path() @@ -186,7 +187,7 @@ async def _resolve_video_preview_url(segment: Video) -> str: cover_seg = Image.fromFileSystem(str(thumb_path)) return await cover_seg.register_to_file_service() except Exception as e: - logger.debug("[LINE] generate video preview failed: %s", e) + logger.debug(t("msg-aea2081a"), e) return "" @staticmethod @@ -196,7 +197,7 @@ async def _resolve_file_url(segment: File) -> str: try: return await segment.register_to_file_service() except Exception as e: - logger.debug("[LINE] resolve file url failed: %s", e) + logger.debug(t("msg-af426b7e"), e) return "" @staticmethod @@ -206,7 +207,7 @@ async def _resolve_file_size(segment: File) -> int: if file_path and os.path.exists(file_path): return int(os.path.getsize(file_path)) except Exception as e: - logger.debug("[LINE] resolve file size failed: %s", e) + logger.debug(t("msg-fe44c12d"), e) return 0 @classmethod @@ -222,7 +223,7 @@ async def build_line_messages(cls, message_chain: MessageChain) -> list[dict]: if len(messages) > 5: logger.warning( - "[LINE] message count exceeds 5, extra segments will be dropped." + t("msg-d6443173") ) messages = messages[:5] return messages diff --git a/astrbot/core/platform/sources/misskey/misskey_adapter.py b/astrbot/core/platform/sources/misskey/misskey_adapter.py index fd61c3e506..a67e10cd61 100644 --- a/astrbot/core/platform/sources/misskey/misskey_adapter.py +++ b/astrbot/core/platform/sources/misskey/misskey_adapter.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import os import random @@ -123,7 +124,7 @@ def meta(self) -> PlatformMetadata: async def run(self) -> None: if not self.instance_url or not self.access_token: - logger.error("[Misskey] 配置不完整,无法启动") + logger.error(t("msg-7bacee77")) return self.api = MisskeyAPI( @@ -141,10 +142,10 @@ async def run(self) -> None: self.client_self_id = str(user_info.get("id", "")) self._bot_username = user_info.get("username", "") logger.info( - f"[Misskey] 已连接用户: {self._bot_username} (ID: {self.client_self_id})", + t("msg-99cdf3d3", res=self._bot_username, res_2=self.client_self_id), ) except Exception as e: - logger.error(f"[Misskey] 获取用户信息失败: {e}") + logger.error(t("msg-5579c974", e=e)) self._running = False return @@ -243,7 +244,7 @@ async def _start_websocket_connection(self) -> None: try: connection_attempts += 1 if not self.api: - logger.error("[Misskey] API 客户端未初始化") + logger.error(t("msg-d9547102")) break streaming = self.api.get_streaming_client() @@ -251,32 +252,32 @@ async def _start_websocket_connection(self) -> None: if await streaming.connect(): logger.info( - f"[Misskey] WebSocket 已连接 (尝试 #{connection_attempts})", + t("msg-341b0aa0", connection_attempts=connection_attempts), ) connection_attempts = 0 await streaming.subscribe_channel("main") if self.enable_chat: await streaming.subscribe_channel("messaging") await streaming.subscribe_channel("messagingIndex") - logger.info("[Misskey] 聊天频道已订阅") + logger.info(t("msg-c77d157b")) backoff_delay = 1.0 await streaming.listen() else: logger.error( - f"[Misskey] WebSocket 连接失败 (尝试 #{connection_attempts})", + t("msg-a0c5edc0", connection_attempts=connection_attempts), ) except Exception as e: logger.error( - f"[Misskey] WebSocket 异常 (尝试 #{connection_attempts}): {e}", + t("msg-1958faa8", connection_attempts=connection_attempts, e=e), ) if self._running: jitter = random.uniform(0, 1.0) sleep_time = backoff_delay + jitter logger.info( - f"[Misskey] {sleep_time:.1f}秒后重连 (下次尝试 #{connection_attempts + 1})", + t("msg-1b47382d", sleep_time=sleep_time, res=connection_attempts + 1), ) await asyncio.sleep(sleep_time) backoff_delay = min(backoff_delay * backoff_multiplier, max_backoff) @@ -285,13 +286,13 @@ async def _handle_notification(self, data: dict[str, Any]) -> None: try: notification_type = data.get("type") logger.debug( - f"[Misskey] 收到通知事件: type={notification_type}, user_id={data.get('userId', 'unknown')}", + t("msg-a10a224d", notification_type=notification_type, res=data.get('userId', 'unknown')), ) if notification_type in ["mention", "reply", "quote"]: note = data.get("note") if note and self._is_bot_mentioned(note): logger.info( - f"[Misskey] 处理贴文提及: {note.get('text', '')[:50]}...", + t("msg-7f0abf4a", res=note.get('text', '')[:50]), ) message = await self.convert_message(note) event = MisskeyPlatformEvent( @@ -303,7 +304,7 @@ async def _handle_notification(self, data: dict[str, Any]) -> None: ) self.commit_event(event) except Exception as e: - logger.error(f"[Misskey] 处理通知失败: {e}") + logger.error(t("msg-2da7cdf5", e=e)) async def _handle_chat_message(self, data: dict[str, Any]) -> None: try: @@ -312,7 +313,7 @@ async def _handle_chat_message(self, data: dict[str, Any]) -> None: ) room_id = data.get("toRoomId") logger.debug( - f"[Misskey] 收到聊天事件: sender_id={sender_id}, room_id={room_id}, is_self={sender_id == self.client_self_id}", + t("msg-6c21d412", sender_id=sender_id, room_id=room_id, res=sender_id == self.client_self_id), ) if sender_id == self.client_self_id: return @@ -320,14 +321,14 @@ async def _handle_chat_message(self, data: dict[str, Any]) -> None: if room_id: raw_text = data.get("text", "") logger.debug( - f"[Misskey] 检查群聊消息: '{raw_text}', 机器人用户名: '{self._bot_username}'", + t("msg-68269731", raw_text=raw_text, res=self._bot_username), ) message = await self.convert_room_message(data) - logger.info(f"[Misskey] 处理群聊消息: {message.message_str[:50]}...") + logger.info(t("msg-585aa62b", res=message.message_str[:50])) else: message = await self.convert_chat_message(data) - logger.info(f"[Misskey] 处理私聊消息: {message.message_str[:50]}...") + logger.info(t("msg-426c7874", res=message.message_str[:50])) event = MisskeyPlatformEvent( message_str=message.message_str, @@ -338,12 +339,12 @@ async def _handle_chat_message(self, data: dict[str, Any]) -> None: ) self.commit_event(event) except Exception as e: - logger.error(f"[Misskey] 处理聊天消息失败: {e}") + logger.error(t("msg-f5aff493", e=e)) async def _debug_handler(self, data: dict[str, Any]) -> None: event_type = data.get("type", "unknown") logger.debug( - f"[Misskey] 收到未处理事件: type={event_type}, channel={data.get('channel', 'unknown')}", + t("msg-ea465183", event_type=event_type, res=data.get('channel', 'unknown')), ) def _is_bot_mentioned(self, note: dict[str, Any]) -> bool: @@ -371,7 +372,7 @@ async def send_by_session( message_chain: MessageChain, ) -> None: if not self.api: - logger.error("[Misskey] API 客户端未初始化") + logger.error(t("msg-d9547102")) return await super().send_by_session(session, message_chain) try: @@ -408,7 +409,7 @@ async def send_by_session( if not text or not text.strip(): if not has_file_components: - logger.warning("[Misskey] 消息内容为空且无文件组件,跳过发送") + logger.warning(t("msg-8b69eb93")) return await super().send_by_session(session, message_chain) text = "" @@ -504,7 +505,7 @@ async def _upload_comp(comp) -> object | None: ): try: os.remove(local_path) - logger.debug(f"[Misskey] 已清理临时文件: {local_path}") + logger.debug(t("msg-9ba9c4e5", local_path=local_path)) except Exception: pass @@ -529,7 +530,7 @@ async def _upload_comp(comp) -> object | None: if len(file_components) > MAX_FILE_UPLOAD_COUNT: logger.warning( - f"[Misskey] 文件数量超过限制 ({len(file_components)} > {MAX_FILE_UPLOAD_COUNT}),只上传前{MAX_FILE_UPLOAD_COUNT}个文件", + t("msg-91af500e", res=len(file_components), MAX_FILE_UPLOAD_COUNT=MAX_FILE_UPLOAD_COUNT), ) file_components = file_components[:MAX_FILE_UPLOAD_COUNT] @@ -552,7 +553,7 @@ async def _upload_comp(comp) -> object | None: except Exception: pass except Exception: - logger.debug("[Misskey] 并发上传过程中出现异常,继续发送文本") + logger.debug(t("msg-9746d7f5")) if session_id and is_valid_room_session_id(session_id): from .misskey_utils import extract_room_id_from_session_id @@ -582,7 +583,7 @@ async def _upload_comp(comp) -> object | None: payload["fileId"] = file_ids[0] if len(file_ids) > 1: logger.warning( - f"[Misskey] 聊天消息只支持单个文件,忽略其余 {len(file_ids) - 1} 个文件", + t("msg-d6dc928c", res=len(file_ids) - 1), ) await self.api.send_message(payload) else: @@ -602,7 +603,7 @@ async def _upload_comp(comp) -> object | None: default_visibility=self.default_visibility, ) logger.debug( - f"[Misskey] 解析可见性: visibility={visibility}, visible_user_ids={visible_user_ids}, session_id={session_id}, user_id_for_cache={user_id_for_cache}", + t("msg-af584ae8", visibility=visibility, visible_user_ids=visible_user_ids, session_id=session_id, user_id_for_cache=user_id_for_cache), ) fields = self._extract_additional_fields(session, message_chain) @@ -627,7 +628,7 @@ async def _upload_comp(comp) -> object | None: ) except Exception as e: - logger.error(f"[Misskey] 发送消息失败: {e}") + logger.error(t("msg-1a176905", e=e)) return await super().send_by_session(session, message_chain) diff --git a/astrbot/core/platform/sources/misskey/misskey_api.py b/astrbot/core/platform/sources/misskey/misskey_api.py index 3e5eb9a90e..73295fb806 100644 --- a/astrbot/core/platform/sources/misskey/misskey_api.py +++ b/astrbot/core/platform/sources/misskey/misskey_api.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import json import random @@ -10,7 +11,7 @@ import websockets except ImportError as e: raise ImportError( - "aiohttp and websockets are required for Misskey API. Please install them with: pip install aiohttp websockets", + t("msg-fab20f57"), ) from e from astrbot.api import logger @@ -70,7 +71,7 @@ async def connect(self) -> bool: self.is_connected = True self._running = True - logger.info("[Misskey WebSocket] 已连接") + logger.info(t("msg-f2eea8e1")) if self.desired_channels: try: desired = list(self.desired_channels.items()) @@ -79,14 +80,14 @@ async def connect(self) -> bool: await self.subscribe_channel(channel_type, params) except Exception as e: logger.warning( - f"[Misskey WebSocket] 重新订阅 {channel_type} 失败: {e}", + t("msg-5efd11a2", channel_type=channel_type, e=e), ) except Exception: pass return True except Exception as e: - logger.error(f"[Misskey WebSocket] 连接失败: {e}") + logger.error(t("msg-b70e2176", e=e)) self.is_connected = False return False @@ -96,7 +97,7 @@ async def disconnect(self) -> None: await self.websocket.close() self.websocket = None self.is_connected = False - logger.info("[Misskey WebSocket] 连接已断开") + logger.info(t("msg-b9f3ee06")) async def subscribe_channel( self, @@ -104,7 +105,7 @@ async def subscribe_channel( params: dict | None = None, ) -> str: if not self.is_connected or not self.websocket: - raise WebSocketError("WebSocket 未连接") + raise WebSocketError(t("msg-7cd98e54")) channel_id = str(uuid.uuid4()) message = { @@ -141,7 +142,7 @@ def add_message_handler( async def listen(self) -> None: if not self.is_connected or not self.websocket: - raise WebSocketError("WebSocket 未连接") + raise WebSocketError(t("msg-7cd98e54")) try: async for message in self.websocket: @@ -152,12 +153,12 @@ async def listen(self) -> None: data = json.loads(message) await self._handle_message(data) except json.JSONDecodeError as e: - logger.warning(f"[Misskey WebSocket] 无法解析消息: {e}") + logger.warning(t("msg-43566304", e=e)) except Exception as e: - logger.error(f"[Misskey WebSocket] 处理消息失败: {e}") + logger.error(t("msg-e617e390", e=e)) except websockets.exceptions.ConnectionClosedError as e: - logger.warning(f"[Misskey WebSocket] 连接意外关闭: {e}") + logger.warning(t("msg-c60715cf", e=e)) self.is_connected = False try: await self.disconnect() @@ -165,7 +166,7 @@ async def listen(self) -> None: pass except websockets.exceptions.ConnectionClosed as e: logger.warning( - f"[Misskey WebSocket] 连接已关闭 (代码: {e.code}, 原因: {e.reason})", + t("msg-da9a2a17", res=e.code, res_2=e.reason), ) self.is_connected = False try: @@ -173,14 +174,14 @@ async def listen(self) -> None: except Exception: pass except websockets.exceptions.InvalidHandshake as e: - logger.error(f"[Misskey WebSocket] 握手失败: {e}") + logger.error(t("msg-bbf6a42e", e=e)) self.is_connected = False try: await self.disconnect() except Exception: pass except Exception as e: - logger.error(f"[Misskey WebSocket] 监听消息失败: {e}") + logger.error(t("msg-254f0237", e=e)) self.is_connected = False try: await self.disconnect() @@ -219,7 +220,7 @@ def _build_channel_summary(message_type: str | None, body: Any) -> str: return f"[Misskey WebSocket] 收到消息类型: {message_type}" channel_summary = _build_channel_summary(message_type, body) - logger.info(channel_summary) + logger.info(t("msg-49f7e90e", channel_summary=channel_summary)) if message_type == "channel": channel_id = body.get("id") @@ -227,7 +228,7 @@ def _build_channel_summary(message_type: str | None, body: Any) -> str: event_body = body.get("body", {}) logger.debug( - f"[Misskey WebSocket] 频道消息: {channel_id}, 事件类型: {event_type}", + t("msg-630a4832", channel_id=channel_id, event_type=event_type), ) if channel_id in self.channels: @@ -235,14 +236,14 @@ def _build_channel_summary(message_type: str | None, body: Any) -> str: handler_key = f"{channel_type}:{event_type}" if handler_key in self.message_handlers: - logger.debug(f"[Misskey WebSocket] 使用处理器: {handler_key}") + logger.debug(t("msg-0dc61a4d", handler_key=handler_key)) await self.message_handlers[handler_key](event_body) elif event_type in self.message_handlers: - logger.debug(f"[Misskey WebSocket] 使用事件处理器: {event_type}") + logger.debug(t("msg-012666fc", event_type=event_type)) await self.message_handlers[event_type](event_body) else: logger.debug( - f"[Misskey WebSocket] 未找到处理器: {handler_key} 或 {event_type}", + t("msg-e202168a", handler_key=handler_key, event_type=event_type), ) if "_debug" in self.message_handlers: await self.message_handlers["_debug"]( @@ -254,10 +255,10 @@ def _build_channel_summary(message_type: str | None, body: Any) -> str: ) elif message_type in self.message_handlers: - logger.debug(f"[Misskey WebSocket] 直接消息处理器: {message_type}") + logger.debug(t("msg-a397eef1", message_type=message_type)) await self.message_handlers[message_type](body) else: - logger.debug(f"[Misskey WebSocket] 未处理的消息类型: {message_type}") + logger.debug(t("msg-a5f12225", message_type=message_type)) if "_debug" in self.message_handlers: await self.message_handlers["_debug"](data) @@ -290,7 +291,7 @@ async def wrapper(*args, **kwargs): last_exc = e if attempt == max_retries: logger.error( - f"[Misskey API] {func_name} 重试 {max_retries} 次后仍失败: {e}", + t("msg-ad61d480", func_name=func_name, max_retries=max_retries, e=e), ) break @@ -306,14 +307,13 @@ async def wrapper(*args, **kwargs): sleep_time = backoff + jitter logger.warning( - f"[Misskey API] {func_name} 第 {attempt} 次重试失败: {e}," - f"{sleep_time:.1f}s后重试", + t("msg-7de2ca49", func_name=func_name, attempt=attempt, e=e, sleep_time=sleep_time), ) await asyncio.sleep(sleep_time) continue except Exception as e: # 非可重试异常直接抛出 - logger.error(f"[Misskey API] {func_name} 遇到不可重试异常: {e}") + logger.error(t("msg-f5aecf37", func_name=func_name, e=e)) raise if last_exc: @@ -361,7 +361,7 @@ async def close(self) -> None: if self._session: await self._session.close() self._session = None - logger.debug("[Misskey API] 客户端已关闭") + logger.debug(t("msg-e5852be5")) def get_streaming_client(self) -> StreamingClient: if not self.streaming: @@ -378,37 +378,37 @@ def session(self) -> aiohttp.ClientSession: def _handle_response_status(self, status: int, endpoint: str) -> NoReturn: """处理 HTTP 响应状态码""" if status == 400: - logger.error(f"[Misskey API] 请求参数错误: {endpoint} (HTTP {status})") - raise APIError(f"Bad request for {endpoint}") + logger.error(t("msg-21fc185c", endpoint=endpoint, status=status)) + raise APIError(t("msg-5b106def", endpoint=endpoint)) if status == 401: - logger.error(f"[Misskey API] 未授权访问: {endpoint} (HTTP {status})") - raise AuthenticationError(f"Unauthorized access for {endpoint}") + logger.error(t("msg-28afff67", endpoint=endpoint, status=status)) + raise AuthenticationError(t("msg-e12f2d28", endpoint=endpoint)) if status == 403: - logger.error(f"[Misskey API] 访问被禁止: {endpoint} (HTTP {status})") - raise AuthenticationError(f"Forbidden access for {endpoint}") + logger.error(t("msg-beda662d", endpoint=endpoint, status=status)) + raise AuthenticationError(t("msg-795ca227", endpoint=endpoint)) if status == 404: - logger.error(f"[Misskey API] 资源不存在: {endpoint} (HTTP {status})") - raise APIError(f"Resource not found for {endpoint}") + logger.error(t("msg-5c6ba873", endpoint=endpoint, status=status)) + raise APIError(t("msg-74f2bac2", endpoint=endpoint)) if status == 413: - logger.error(f"[Misskey API] 请求体过大: {endpoint} (HTTP {status})") - raise APIError(f"Request entity too large for {endpoint}") + logger.error(t("msg-9ceafe4c", endpoint=endpoint, status=status)) + raise APIError(t("msg-3e336b73", endpoint=endpoint)) if status == 429: - logger.warning(f"[Misskey API] 请求频率限制: {endpoint} (HTTP {status})") - raise APIRateLimitError(f"Rate limit exceeded for {endpoint}") + logger.warning(t("msg-a47067de", endpoint=endpoint, status=status)) + raise APIRateLimitError(t("msg-901dc2da", endpoint=endpoint)) if status == 500: - logger.error(f"[Misskey API] 服务器内部错误: {endpoint} (HTTP {status})") - raise APIConnectionError(f"Internal server error for {endpoint}") + logger.error(t("msg-2bea8c2e", endpoint=endpoint, status=status)) + raise APIConnectionError(t("msg-ae8d3725", endpoint=endpoint)) if status == 502: - logger.error(f"[Misskey API] 网关错误: {endpoint} (HTTP {status})") - raise APIConnectionError(f"Bad gateway for {endpoint}") + logger.error(t("msg-7b028462", endpoint=endpoint, status=status)) + raise APIConnectionError(t("msg-978414ef", endpoint=endpoint)) if status == 503: - logger.error(f"[Misskey API] 服务不可用: {endpoint} (HTTP {status})") - raise APIConnectionError(f"Service unavailable for {endpoint}") + logger.error(t("msg-50895a69", endpoint=endpoint, status=status)) + raise APIConnectionError(t("msg-62adff89", endpoint=endpoint)) if status == 504: - logger.error(f"[Misskey API] 网关超时: {endpoint} (HTTP {status})") - raise APIConnectionError(f"Gateway timeout for {endpoint}") - logger.error(f"[Misskey API] 未知错误: {endpoint} (HTTP {status})") - raise APIConnectionError(f"HTTP {status} for {endpoint}") + logger.error(t("msg-1cf15497", endpoint=endpoint, status=status)) + raise APIConnectionError(t("msg-a8a2578d", endpoint=endpoint)) + logger.error(t("msg-c012110a", endpoint=endpoint, status=status)) + raise APIConnectionError(t("msg-dc96bbb8", status=status, endpoint=endpoint)) async def _process_response( self, @@ -429,23 +429,23 @@ async def _process_response( ) if notifications_data: logger.debug( - f"[Misskey API] 获取到 {len(notifications_data)} 条新通知", + t("msg-4c7598b6", res=len(notifications_data)), ) else: - logger.debug(f"[Misskey API] 请求成功: {endpoint}") + logger.debug(t("msg-851a2a54", endpoint=endpoint)) return result except json.JSONDecodeError as e: - logger.error(f"[Misskey API] 响应格式错误: {e}") - raise APIConnectionError("Invalid JSON response") from e + logger.error(t("msg-5f5609b6", e=e)) + raise APIConnectionError(t("msg-c8f7bbeb")) from e else: try: error_text = await response.text() logger.error( - f"[Misskey API] 请求失败: {endpoint} - HTTP {response.status}, 响应: {error_text}", + t("msg-82748b31", endpoint=endpoint, res=response.status, error_text=error_text), ) except Exception: logger.error( - f"[Misskey API] 请求失败: {endpoint} - HTTP {response.status}", + t("msg-c6de3320", endpoint=endpoint, res=response.status), ) self._handle_response_status(response.status, endpoint) @@ -468,8 +468,8 @@ async def _make_request( async with self.session.post(url, json=payload) as response: return await self._process_response(response, endpoint) except aiohttp.ClientError as e: - logger.error(f"[Misskey API] HTTP 请求错误: {e}") - raise APIConnectionError(f"HTTP request failed: {e}") from e + logger.error(t("msg-affb19a7", e=e)) + raise APIConnectionError(t("msg-9f1286b3", e=e)) from e async def create_note( self, @@ -532,7 +532,7 @@ async def create_note( if isinstance(result, dict) else "unknown" ) - logger.debug(f"[Misskey API] 发帖成功: {note_id}") + logger.debug(t("msg-44f91be2", note_id=note_id)) return result async def upload_file( @@ -543,7 +543,7 @@ async def upload_file( ) -> dict[str, Any]: """Upload a file to Misskey drive/files/create and return a dict containing id and raw result.""" if not file_path: - raise APIError("No file path provided for upload") + raise APIError(t("msg-fbafd3db")) url = f"{self.instance_url}/api/drive/files/create" form = aiohttp.FormData() @@ -557,8 +557,8 @@ async def upload_file( try: f = open(file_path, "rb") except FileNotFoundError as e: - logger.error(f"[Misskey API] 本地文件不存在: {file_path}") - raise APIError(f"File not found: {file_path}") from e + logger.error(t("msg-872d8419", file_path=file_path)) + raise APIError(t("msg-37186dea", file_path=file_path)) from e try: form.add_field("file", f, filename=filename) @@ -566,31 +566,31 @@ async def upload_file( result = await self._process_response(resp, "drive/files/create") file_id = FileIDExtractor.extract_file_id(result) logger.debug( - f"[Misskey API] 本地文件上传成功: {filename} -> {file_id}", + t("msg-65ef68e0", filename=filename, file_id=file_id), ) return {"id": file_id, "raw": result} finally: f.close() except aiohttp.ClientError as e: - logger.error(f"[Misskey API] 文件上传网络错误: {e}") - raise APIConnectionError(f"Upload failed: {e}") from e + logger.error(t("msg-0951db67", e=e)) + raise APIConnectionError(t("msg-e3a322f5", e=e)) from e async def find_files_by_hash(self, md5_hash: str) -> list[dict[str, Any]]: """Find files by MD5 hash""" if not md5_hash: - raise APIError("No MD5 hash provided for find-by-hash") + raise APIError(t("msg-f28772b9")) data = {"md5": md5_hash} try: - logger.debug(f"[Misskey API] find-by-hash 请求: md5={md5_hash}") + logger.debug(t("msg-25e566ef", md5_hash=md5_hash)) result = await self._make_request("drive/files/find-by-hash", data) logger.debug( - f"[Misskey API] find-by-hash 响应: 找到 {len(result) if isinstance(result, list) else 0} 个文件", + t("msg-a036a942", res=len(result) if isinstance(result, list) else 0), ) return result if isinstance(result, list) else [] except Exception as e: - logger.error(f"[Misskey API] 根据哈希查找文件失败: {e}") + logger.error(t("msg-ea3581d5", e=e)) raise async def find_files_by_name( @@ -600,21 +600,21 @@ async def find_files_by_name( ) -> list[dict[str, Any]]: """Find files by name""" if not name: - raise APIError("No name provided for find") + raise APIError(t("msg-1d2a84ff")) data: dict[str, Any] = {"name": name} if folder_id: data["folderId"] = folder_id try: - logger.debug(f"[Misskey API] find 请求: name={name}, folder_id={folder_id}") + logger.debug(t("msg-f25e28b4", name=name, folder_id=folder_id)) result = await self._make_request("drive/files/find", data) logger.debug( - f"[Misskey API] find 响应: 找到 {len(result) if isinstance(result, list) else 0} 个文件", + t("msg-cd43861a", res=len(result) if isinstance(result, list) else 0), ) return result if isinstance(result, list) else [] except Exception as e: - logger.error(f"[Misskey API] 根据名称查找文件失败: {e}") + logger.error(t("msg-05cd55ef", e=e)) raise async def find_files( @@ -632,15 +632,15 @@ async def find_files( try: logger.debug( - f"[Misskey API] 列表文件请求: limit={limit}, folder_id={folder_id}, type={type}", + t("msg-c01052a4", limit=limit, folder_id=folder_id, type=type), ) result = await self._make_request("drive/files", data) logger.debug( - f"[Misskey API] 列表文件响应: 找到 {len(result) if isinstance(result, list) else 0} 个文件", + t("msg-7c81620d", res=len(result) if isinstance(result, list) else 0), ) return result if isinstance(result, list) else [] except Exception as e: - logger.error(f"[Misskey API] 列表文件失败: {e}") + logger.error(t("msg-a187a089", e=e)) raise async def _download_with_existing_session( @@ -650,7 +650,7 @@ async def _download_with_existing_session( ) -> bytes | None: """使用现有会话下载文件""" if not (hasattr(self, "session") and self.session): - raise APIConnectionError("No existing session available") + raise APIConnectionError(t("msg-9e776259")) async with self.session.get( url, @@ -699,7 +699,7 @@ async def upload_and_find_file( """ if not url: - raise APIError("URL不能为空") + raise APIError(t("msg-de18c220")) # 通过本地上传获取即时文件 ID(下载文件 → 上传 → 返回 ID) try: @@ -715,7 +715,7 @@ async def upload_and_find_file( ) or await self._download_with_temp_session(url, ssl_verify=True) except Exception as ssl_error: logger.debug( - f"[Misskey API] SSL 验证下载失败: {ssl_error},重试不验证 SSL", + t("msg-25b15b61", ssl_error=ssl_error), ) try: tmp_bytes = await self._download_with_existing_session( @@ -732,7 +732,7 @@ async def upload_and_find_file( try: result = await self.upload_file(tmp_path, name, folder_id) - logger.debug(f"[Misskey API] 本地上传成功: {result.get('id')}") + logger.debug(t("msg-b6cbeef6", res=result.get('id'))) return result finally: try: @@ -740,7 +740,7 @@ async def upload_and_find_file( except Exception: pass except Exception as e: - logger.error(f"[Misskey API] 本地上传失败: {e}") + logger.error(t("msg-a4a898e2", e=e)) return None @@ -764,7 +764,7 @@ async def send_message( result = await self._make_request("chat/messages/create-to-user", data) message_id = result.get("id", "unknown") - logger.debug(f"[Misskey API] 聊天消息发送成功: {message_id}") + logger.debug(t("msg-46b7ea4b", message_id=message_id)) return result async def send_room_message( @@ -783,7 +783,7 @@ async def send_room_message( result = await self._make_request("chat/messages/create-to-room", data) message_id = result.get("id", "unknown") - logger.debug(f"[Misskey API] 房间消息发送成功: {message_id}") + logger.debug(t("msg-32f71df4", message_id=message_id)) return result async def get_messages( @@ -800,7 +800,7 @@ async def get_messages( result = await self._make_request("chat/messages/user-timeline", data) if isinstance(result, list): return result - logger.warning(f"[Misskey API] 聊天消息响应格式异常: {type(result)}") + logger.warning(t("msg-7829f3b3", res=type(result))) return [] async def get_mentions( @@ -819,7 +819,7 @@ async def get_mentions( return result if isinstance(result, dict) and "notifications" in result: return result["notifications"] - logger.warning(f"[Misskey API] 提及通知响应格式异常: {type(result)}") + logger.warning(t("msg-d74c86a1", res=type(result))) return [] async def send_message_with_media( @@ -849,7 +849,7 @@ async def send_message_with_media( """ if not text and not media_urls and not local_files: - raise APIError("消息内容不能为空:需要文本或媒体文件") + raise APIError(t("msg-65ccb697")) file_ids = [] @@ -878,11 +878,11 @@ async def _process_media_urls(self, urls: list[str]) -> list[str]: result = await self.upload_and_find_file(url) if result and result.get("id"): file_ids.append(result["id"]) - logger.debug(f"[Misskey API] URL媒体上传成功: {result['id']}") + logger.debug(t("msg-b6afb123", res=result['id'])) else: - logger.error(f"[Misskey API] URL媒体上传失败: {url}") + logger.error(t("msg-4e62bcdc", url=url)) except Exception as e: - logger.error(f"[Misskey API] URL媒体处理失败 {url}: {e}") + logger.error(t("msg-71cc9d61", url=url, e=e)) # 继续处理其他文件,不中断整个流程 continue return file_ids @@ -895,11 +895,11 @@ async def _process_local_files(self, file_paths: list[str]) -> list[str]: result = await self.upload_file(file_path) if result and result.get("id"): file_ids.append(result["id"]) - logger.debug(f"[Misskey API] 本地文件上传成功: {result['id']}") + logger.debug(t("msg-75890c2b", res=result['id'])) else: - logger.error(f"[Misskey API] 本地文件上传失败: {file_path}") + logger.error(t("msg-024d0ed5", file_path=file_path)) except Exception as e: - logger.error(f"[Misskey API] 本地文件处理失败 {file_path}: {e}") + logger.error(t("msg-f1fcb5e1", file_path=file_path, e=e)) continue return file_ids @@ -960,4 +960,4 @@ async def _dispatch_message( note_kwargs.update(kwargs) return await self.create_note(**note_kwargs) - raise APIError(f"不支持的消息类型: {message_type}") + raise APIError(t("msg-1ee80a6b", message_type=message_type)) diff --git a/astrbot/core/platform/sources/misskey/misskey_event.py b/astrbot/core/platform/sources/misskey/misskey_event.py index 068f7e7a28..93d1170e1b 100644 --- a/astrbot/core/platform/sources/misskey/misskey_event.py +++ b/astrbot/core/platform/sources/misskey/misskey_event.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import re from collections.abc import AsyncGenerator @@ -44,7 +45,7 @@ async def send(self, message: MessageChain) -> None: """发送消息,使用适配器的完整上传和发送逻辑""" try: logger.debug( - f"[MisskeyEvent] send 方法被调用,消息链包含 {len(message.chain)} 个组件", + t("msg-85cb7d49", res=len(message.chain)), ) # 使用适配器的 send_by_session 方法,它包含文件上传逻辑 @@ -66,19 +67,19 @@ async def send(self, message: MessageChain) -> None: ) logger.debug( - f"[MisskeyEvent] 检查适配器方法: hasattr(self.client, 'send_by_session') = {hasattr(self.client, 'send_by_session')}", + t("msg-252c2fca", res=hasattr(self.client, 'send_by_session')), ) # 调用适配器的 send_by_session 方法 if hasattr(self.client, "send_by_session"): - logger.debug("[MisskeyEvent] 调用适配器的 send_by_session 方法") + logger.debug(t("msg-44d7a060")) await self.client.send_by_session(session, message) else: # 回退到原来的简化发送逻辑 content, has_at = serialize_message_chain(message.chain) if not content: - logger.debug("[MisskeyEvent] 内容为空,跳过发送") + logger.debug(t("msg-b6e08872")) return original_message_id = getattr(self.message_obj, "message_id", None) @@ -118,13 +119,13 @@ async def send(self, message: MessageChain) -> None: visible_user_ids=visible_user_ids, ) elif hasattr(self.client, "create_note"): - logger.debug("[MisskeyEvent] 创建新帖子") + logger.debug(t("msg-8cfebc9c")) await self.client.create_note(content) await super().send(message) except Exception as e: - logger.error(f"[MisskeyEvent] 发送失败: {e}") + logger.error(t("msg-ed0d2ed5", e=e)) async def send_streaming( self, diff --git a/astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py b/astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py index 868ec8a657..538b2d986c 100644 --- a/astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py +++ b/astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import base64 import os @@ -39,7 +40,7 @@ def _patch_qq_botpy_formdata() -> None: if not hasattr(_FormData, "_is_processed"): setattr(_FormData, "_is_processed", False) except Exception: - logger.debug("[QQOfficial] Skip botpy FormData patch.") + logger.debug(t("msg-28a74d9d")) _patch_qq_botpy_formdata() @@ -100,7 +101,7 @@ async def send_streaming(self, generator, use_fallback: bool = False): ret = await self._post_send() except Exception as e: - logger.error(f"发送流式消息时出错: {e}", exc_info=True) + logger.error(t("msg-c0b123f6", e=e), exc_info=True) self.send_buffer = None return await super().send_streaming(generator, use_fallback) @@ -118,7 +119,7 @@ async def _post_send(self, stream: dict | None = None): | botpy.message.DirectMessage | botpy.message.C2CMessage, ): - logger.warning(f"[QQOfficial] 不支持的消息源类型: {type(source)}") + logger.warning(t("msg-05d6bba5", res=type(source))) return None ( @@ -151,7 +152,7 @@ async def _post_send(self, stream: dict | None = None): match source: case botpy.message.GroupMessage(): if not source.group_openid: - logger.error("[QQOfficial] GroupMessage 缺少 group_openid") + logger.error(t("msg-e5339577")) return None if image_base64: @@ -223,7 +224,7 @@ async def _post_send(self, stream: dict | None = None): payload=payload, plain_text=plain_text, ) - logger.debug(f"Message sent to C2C: {ret}") + logger.debug(t("msg-71275806", ret=ret)) case botpy.message.Message(): if image_path: @@ -279,7 +280,7 @@ async def _send_with_markdown_fallback( raise logger.warning( - "[QQOfficial] markdown 发送被拒绝,回退到 content 模式重试。" + t("msg-040e7942") ) fallback_payload = payload.copy() fallback_payload["markdown"] = None @@ -314,11 +315,11 @@ async def upload_group_and_c2c_image( ) result = await self.bot.api._http.request(route, json=payload) else: - raise ValueError("Invalid upload parameters") + raise ValueError(t("msg-9000f8f7")) if not isinstance(result, dict): raise RuntimeError( - f"Failed to upload image, response is not dict: {result}" + t("msg-d72cffe7", result=result) ) return Media( @@ -369,7 +370,7 @@ async def upload_group_and_c2c_record( if result: if not isinstance(result, dict): - logger.error(f"上传文件响应格式错误: {result}") + logger.error(t("msg-5944a27c", result=result)) return None return Media( @@ -378,7 +379,7 @@ async def upload_group_and_c2c_record( ttl=result.get("ttl", 0), ) except Exception as e: - logger.error(f"上传请求错误: {e}") + logger.error(t("msg-1e513ee5", e=e)) return None @@ -405,7 +406,7 @@ async def post_c2c_message( if not isinstance(result, dict): raise RuntimeError( - f"Failed to post c2c message, response is not dict: {result}" + t("msg-f1f1733c", result=result) ) return message.Message(**result) @@ -431,7 +432,7 @@ async def _parse_to_qqofficial(message: MessageChain): elif i.file: image_base64 = file_to_base64(i.file) else: - raise ValueError("Unsupported image file format") + raise ValueError(t("msg-9b8f9f70")) image_base64 = image_base64.removeprefix("base64://") elif isinstance(i, Record): if i.file: @@ -450,10 +451,10 @@ async def _parse_to_qqofficial(message: MessageChain): record_file_path = record_tecent_silk_path else: record_file_path = None - logger.error("转换音频格式时出错:音频时长不大于0") + logger.error(t("msg-24eb302a")) except Exception as e: - logger.error(f"处理语音时出错: {e}") + logger.error(t("msg-b49e55f9", e=e)) record_file_path = None else: - logger.debug(f"qq_official 忽略 {i.type}") + logger.debug(t("msg-6e716579", res=i.type)) return plain_text, image_base64, image_file_path, record_file_path diff --git a/astrbot/core/platform/sources/qqofficial/qqofficial_platform_adapter.py b/astrbot/core/platform/sources/qqofficial/qqofficial_platform_adapter.py index 603bc8f58b..f35757c783 100644 --- a/astrbot/core/platform/sources/qqofficial/qqofficial_platform_adapter.py +++ b/astrbot/core/platform/sources/qqofficial/qqofficial_platform_adapter.py @@ -1,4 +1,5 @@ from __future__ import annotations +from astrbot.core.lang import t import asyncio import logging @@ -131,7 +132,7 @@ async def send_by_session( session: MessageSesion, message_chain: MessageChain, ) -> None: - raise NotImplementedError("QQ 机器人官方 API 适配器不支持 send_by_session") + raise NotImplementedError(t("msg-8af45ba1")) def meta(self) -> PlatformMetadata: return PlatformMetadata( @@ -235,7 +236,7 @@ def _parse_from_qqofficial( if isinstance(message, botpy.message.Message): abm.group_id = message.channel_id else: - raise ValueError(f"Unknown message type: {message_type}") + raise ValueError(t("msg-8ebd1249", message_type=message_type)) abm.self_id = "qq_official" return abm @@ -247,4 +248,4 @@ def get_client(self) -> botClient: async def terminate(self) -> None: await self.client.close() - logger.info("QQ 官方机器人接口 适配器已被优雅地关闭") + logger.info(t("msg-c165744d")) diff --git a/astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_adapter.py b/astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_adapter.py index 6aae6b9ce0..baef016f76 100644 --- a/astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_adapter.py +++ b/astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_adapter.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import logging import random @@ -135,7 +136,7 @@ async def send_by_session( msg_id = self._session_last_message_id.get(session.session_id) if not msg_id: logger.warning( - "[QQOfficialWebhook] No cached msg_id for session: %s, skip send_by_session", + t("msg-3803e307"), session.session_id, ) return @@ -203,7 +204,7 @@ async def send_by_session( ) else: logger.warning( - "[QQOfficialWebhook] Unsupported message type for send_by_session: %s", + t("msg-08fd28cf"), session.message_type, ) return @@ -277,7 +278,7 @@ async def terminate(self) -> None: await self.webhook_helper.server.shutdown() except Exception as exc: logger.warning( - f"Exception occurred during QQOfficialWebhook server shutdown: {exc}", + t("msg-6fa95bb3", exc=exc), exc_info=True, ) - logger.info("QQ 机器人官方 API 适配器已经被优雅地关闭") + logger.info(t("msg-6f83eea0")) diff --git a/astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_server.py b/astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_server.py index 5f35471eea..01e61af2de 100644 --- a/astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_server.py +++ b/astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_server.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import logging from typing import cast @@ -41,9 +42,9 @@ def __init__( self.shutdown_event = asyncio.Event() async def initialize(self) -> None: - logger.info("正在登录到 QQ 官方机器人...") + logger.info(t("msg-41a3e59d")) self.user = await self.http.login(self.token) - logger.info(f"已登录 QQ 官方机器人账号: {self.user}") + logger.info(t("msg-66040e15", res=self.user)) # 直接注入到 botpy 的 Client,移花接木! self.client.api = self.api self.client.http = self.http @@ -94,7 +95,7 @@ async def handle_callback(self, request) -> dict: 响应数据 """ msg: dict = await request.json - logger.debug(f"收到 qq_official_webhook 回调: {msg}") + logger.debug(t("msg-6ed59b60", msg=msg)) event = msg.get("t") opcode = msg.get("op") @@ -103,7 +104,7 @@ async def handle_callback(self, request) -> dict: if opcode == 13: # validation signed = await self.webhook_validation(cast(dict, data)) - print(signed) + print(t("msg-ad355b59", signed=signed)) return signed if event and opcode == BotWebSocket.WS_DISPATCH_EVENT: @@ -111,7 +112,7 @@ async def handle_callback(self, request) -> dict: try: func = self._connection.parser[event] except KeyError: - logger.error("_parser unknown event %s.", event) + logger.error(t("msg-1f6260e4"), event) else: func(msg) @@ -119,7 +120,7 @@ async def handle_callback(self, request) -> dict: async def start_polling(self) -> None: logger.info( - f"将在 {self.callback_server_host}:{self.port} 端口启动 QQ 官方机器人 webhook 适配器。", + t("msg-cef08b17", res=self.callback_server_host, res_2=self.port), ) await self.server.run_task( host=self.callback_server_host, diff --git a/astrbot/core/platform/sources/satori/satori_adapter.py b/astrbot/core/platform/sources/satori/satori_adapter.py index 5c2f7a37f3..462a294d35 100644 --- a/astrbot/core/platform/sources/satori/satori_adapter.py +++ b/astrbot/core/platform/sources/satori/satori_adapter.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t import asyncio import json import time @@ -111,17 +112,17 @@ async def run(self) -> None: await self.connect_websocket() retry_count = 0 except websockets.exceptions.ConnectionClosed as e: - logger.warning(f"Satori WebSocket 连接关闭: {e}") + logger.warning(t("msg-ab7db6d9", e=e)) retry_count += 1 except Exception as e: - logger.error(f"Satori WebSocket 连接失败: {e}") + logger.error(t("msg-4ef42cd1", e=e)) retry_count += 1 if not self.running: break if retry_count >= max_retries: - logger.error(f"达到最大重试次数 ({max_retries}),停止重试") + logger.error(t("msg-b50d159b", max_retries=max_retries)) break if not self.auto_reconnect: @@ -134,12 +135,12 @@ async def run(self) -> None: await self.session.close() async def connect_websocket(self) -> None: - logger.info(f"Satori 适配器正在连接到 WebSocket: {self.endpoint}") - logger.info(f"Satori 适配器 HTTP API 地址: {self.api_base_url}") + logger.info(t("msg-89de477c", res=self.endpoint)) + logger.info(t("msg-cfa5b059", res=self.api_base_url)) if not self.endpoint.startswith(("ws://", "wss://")): - logger.error(f"无效的WebSocket URL: {self.endpoint}") - raise ValueError(f"WebSocket URL必须以ws://或wss://开头: {self.endpoint}") + logger.error(t("msg-d534864b", res=self.endpoint)) + raise ValueError(t("msg-a110f9f7", res=self.endpoint)) try: websocket = await connect( @@ -160,13 +161,13 @@ async def connect_websocket(self) -> None: try: await self.handle_message(message) # type: ignore except Exception as e: - logger.error(f"Satori 处理消息异常: {e}") + logger.error(t("msg-bf43ccb6", e=e)) except websockets.exceptions.ConnectionClosed as e: - logger.warning(f"Satori WebSocket 连接关闭: {e}") + logger.warning(t("msg-ab7db6d9", e=e)) raise except Exception as e: - logger.error(f"Satori WebSocket 连接异常: {e}") + logger.error(t("msg-89081a1a", e=e)) raise finally: if self.heartbeat_task: @@ -179,14 +180,14 @@ async def connect_websocket(self) -> None: try: await self.ws.close() except Exception as e: - logger.error(f"Satori WebSocket 关闭异常: {e}") + logger.error(t("msg-5c04bfcd", e=e)) async def send_identify(self) -> None: if not self.ws: - raise Exception("WebSocket连接未建立") + raise Exception(t("msg-b67bcee0")) if self._is_websocket_closed(self.ws): - raise Exception("WebSocket连接已关闭") + raise Exception(t("msg-89ea8b76")) identify_payload = { "op": 3, # IDENTIFY @@ -203,10 +204,10 @@ async def send_identify(self) -> None: message_str = json.dumps(identify_payload, ensure_ascii=False) await self.ws.send(message_str) except websockets.exceptions.ConnectionClosed as e: - logger.error(f"发送 IDENTIFY 信令时连接关闭: {e}") + logger.error(t("msg-4c8a40e3", e=e)) raise except Exception as e: - logger.error(f"发送 IDENTIFY 信令失败: {e}") + logger.error(t("msg-05a6b99d", e=e)) raise async def heartbeat_loop(self) -> None: @@ -222,17 +223,17 @@ async def heartbeat_loop(self) -> None: } await self.ws.send(json.dumps(ping_payload, ensure_ascii=False)) except websockets.exceptions.ConnectionClosed as e: - logger.error(f"Satori WebSocket 连接关闭: {e}") + logger.error(t("msg-ab7db6d9", e=e)) break except Exception as e: - logger.error(f"Satori WebSocket 发送心跳失败: {e}") + logger.error(t("msg-c9b1b774", e=e)) break else: break except asyncio.CancelledError: pass except Exception as e: - logger.error(f"心跳任务异常: {e}") + logger.error(t("msg-61edb4f3", e=e)) async def handle_message(self, message: str) -> None: try: @@ -252,7 +253,7 @@ async def handle_message(self, message: str) -> None: user_id = user.get("id", "") user_name = user.get("name", "") logger.info( - f"Satori 连接成功 - Bot {i + 1}: platform={platform}, user_id={user_id}, user_name={user_name}", + t("msg-7db44899", res=i + 1, platform=platform, user_id=user_id, user_name=user_name), ) if "sn" in body: @@ -271,9 +272,9 @@ async def handle_message(self, message: str) -> None: self.sequence = body["sn"] except json.JSONDecodeError as e: - logger.error(f"解析 WebSocket 消息失败: {e}, 消息内容: {message}") + logger.error(t("msg-01564612", e=e, message=message)) except Exception as e: - logger.error(f"处理 WebSocket 消息异常: {e}") + logger.error(t("msg-3a1657ea", e=e)) async def handle_event(self, event_data: dict) -> None: try: @@ -305,7 +306,7 @@ async def handle_event(self, event_data: dict) -> None: await self.handle_msg(abm) except Exception as e: - logger.error(f"处理事件失败: {e}") + logger.error(t("msg-dc6b459c", e=e)) async def convert_satori_message( self, @@ -358,7 +359,7 @@ async def convert_satori_message( quote = quote_info["quote"] content_for_parsing = quote_info["content_without_quote"] except Exception as e: - logger.error(f"解析标签时发生错误: {e}, 错误内容: {content}") + logger.error(t("msg-6524f582", e=e, content=content)) if quote: # 引用消息 @@ -400,7 +401,7 @@ async def convert_satori_message( return abm except Exception as e: - logger.error(f"转换 Satori 消息失败: {e}") + logger.error(t("msg-3be535c3", e=e)) return None def _extract_namespace_prefixes(self, content: str) -> set: @@ -520,10 +521,10 @@ async def _extract_quote_element(self, content: str) -> dict | None: return None except ET.ParseError as e: - logger.warning(f"XML解析失败,使用正则提取: {e}") + logger.warning(t("msg-be17caf1", e=e)) return await self._extract_quote_with_regex(content) except Exception as e: - logger.error(f"提取标签时发生错误: {e}") + logger.error(t("msg-f6f41d74", e=e)) return None async def _extract_quote_with_regex(self, content: str) -> dict | None: @@ -586,7 +587,7 @@ async def _convert_quote_message(self, quote: dict) -> AstrBotMessage | None: return quote_abm except Exception as e: - logger.error(f"转换引用消息失败: {e}") + logger.error(t("msg-ca6dca7f", e=e)) return None async def parse_satori_elements(self, content: str) -> list: @@ -620,12 +621,12 @@ async def parse_satori_elements(self, content: str) -> list: root = ET.fromstring(processed_content) await self._parse_xml_node(root, elements) except ET.ParseError as e: - logger.warning(f"解析 Satori 元素时发生解析错误: {e}, 错误内容: {content}") + logger.warning(t("msg-cd3b067e", e=e, content=content)) # 如果解析失败,将整个内容当作纯文本 if content.strip(): elements.append(Plain(text=content)) except Exception as e: - logger.error(f"解析 Satori 元素时发生未知错误: {e}") + logger.error(t("msg-03071274", e=e)) raise e # 如果没有解析到任何元素,将整个内容当作纯文本 @@ -741,7 +742,7 @@ async def send_http_request( user_id: str | None = None, ) -> dict: if not self.session: - raise Exception("HTTP session 未初始化") + raise Exception(t("msg-775cd5c0")) headers = { "Content-Type": "application/json", @@ -777,7 +778,7 @@ async def send_http_request( return result return {} except Exception as e: - logger.error(f"Satori HTTP 请求异常: {e}") + logger.error(t("msg-e354c8d1", e=e)) return {} async def terminate(self) -> None: @@ -790,7 +791,7 @@ async def terminate(self) -> None: try: await self.ws.close() except Exception as e: - logger.error(f"Satori WebSocket 关闭异常: {e}") + logger.error(t("msg-5c04bfcd", e=e)) if self.session: await self.session.close() diff --git a/astrbot/core/platform/sources/satori/satori_event.py b/astrbot/core/platform/sources/satori/satori_event.py index 0214222837..c24f65d592 100644 --- a/astrbot/core/platform/sources/satori/satori_event.py +++ b/astrbot/core/platform/sources/satori/satori_event.py @@ -1,3 +1,4 @@ +from astrbot.core.lang import t from typing import TYPE_CHECKING from astrbot.api import logger @@ -107,7 +108,7 @@ async def send_with_adapter( return None except Exception as e: - logger.error(f"Satori 消息发送异常: {e}") + logger.error(t("msg-c063ab8a", e=e)) return None async def send(self, message: MessageChain) -> None: @@ -154,9 +155,9 @@ async def send(self, message: MessageChain) -> None: user_id, ) if not result: - logger.error("Satori 消息发送失败") + logger.error(t("msg-9bc42a8d")) except Exception as e: - logger.error(f"Satori 消息发送异常: {e}") + logger.error(t("msg-c063ab8a", e=e)) await super().send(message) @@ -195,7 +196,7 @@ async def send_streaming(self, generator, use_fallback: bool = False): ) await self.send(img_chain) except Exception as e: - logger.error(f"图片转换为base64失败: {e}") + logger.error(t("msg-dbf77ca2", e=e)) else: content_parts.append(str(component)) @@ -205,7 +206,7 @@ async def send_streaming(self, generator, use_fallback: bool = False): await self.send(temp_chain) except Exception as e: - logger.error(f"Satori 流式消息发送异常: {e}") + logger.error(t("msg-8b6100fb", e=e)) return await super().send_streaming(generator, use_fallback) @@ -232,7 +233,7 @@ async def _convert_component_to_satori(self, component) -> str: if image_base64: return f'' except Exception as e: - logger.error(f"图片转换为base64失败: {e}") + logger.error(t("msg-dbf77ca2", e=e)) elif isinstance(component, File): return ( @@ -245,7 +246,7 @@ async def _convert_component_to_satori(self, component) -> str: if record_base64: return f'