From ab677ea100981f65a8d102ea3b59f133fef28193 Mon Sep 17 00:00:00 2001 From: chenpeng <115522593@qq.com> Date: Wed, 2 Jul 2025 17:30:37 +0800 Subject: [PATCH 01/31] =?UTF-8?q?=E4=BF=AE=E6=AD=A3pilk=E4=BE=9D=E8=B5=96?= =?UTF-8?q?=E6=8F=90=E7=A4=BA=E6=96=87=E6=A1=88=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E7=9B=91=E5=90=ACwechatpadpro=E6=B6=88=E6=81=AF=E5=B9=B3?= =?UTF-8?q?=E5=8F=B0=E7=9A=84=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- astrbot/core/star/filter/platform_adapter_type.py | 4 +++- astrbot/core/utils/tencent_record_helper.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/astrbot/core/star/filter/platform_adapter_type.py b/astrbot/core/star/filter/platform_adapter_type.py index 0926cc337..4252aa1af 100644 --- a/astrbot/core/star/filter/platform_adapter_type.py +++ b/astrbot/core/star/filter/platform_adapter_type.py @@ -13,7 +13,8 @@ class PlatformAdapterType(enum.Flag): TELEGRAM = enum.auto() WECOM = enum.auto() LARK = enum.auto() - ALL = AIOCQHTTP | QQOFFICIAL | VCHAT | GEWECHAT | TELEGRAM | WECOM | LARK + WECHATPADPRO = enum.auto() + ALL = AIOCQHTTP | QQOFFICIAL | VCHAT | GEWECHAT | TELEGRAM | WECOM | LARK | WECHATPADPRO ADAPTER_NAME_2_TYPE = { @@ -24,6 +25,7 @@ ADAPTER_NAME_2_TYPE = { "telegram": PlatformAdapterType.TELEGRAM, "wecom": PlatformAdapterType.WECOM, "lark": PlatformAdapterType.LARK, + "wechatpadpro": PlatformAdapterType.WECHATPADPRO, } diff --git a/astrbot/core/utils/tencent_record_helper.py b/astrbot/core/utils/tencent_record_helper.py index 9d0552c1e..2c97a01ed 100644 --- a/astrbot/core/utils/tencent_record_helper.py +++ b/astrbot/core/utils/tencent_record_helper.py @@ -117,7 +117,7 @@ async def audio_to_tencent_silk_base64(audio_path: str) -> tuple[str, float]: try: import pilk except ImportError as e: - raise Exception("未安装 pysilk,请执行: pip install pysilk") from e + raise Exception("未安装 pilk: pip install pilk") from e temp_dir = os.path.join(get_astrbot_data_path(), "temp") os.makedirs(temp_dir, exist_ok=True) From 1a8a171f8b692961f63f9638b676bcce1fe9a10e Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Thu, 3 Jul 2025 08:46:42 +0200 Subject: [PATCH 02/31] Keep GitHub Actions up to date with GitHub's Dependabot * [Keeping your software supply chain secure with Dependabot](https://docs.github.com/en/code-security/dependabot) * [Keeping your actions up to date with Dependabot](https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot) * [Configuration options for the `dependabot.yml` file - package-ecosystem](https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#package-ecosystem) --- .github/dependabot.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..be006de9a --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,13 @@ +# Keep GitHub Actions up to date with GitHub's Dependabot... +# https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot +# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#package-ecosystem +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + groups: + github-actions: + patterns: + - "*" # Group all Actions updates into a single larger pull request + schedule: + interval: weekly From a4e999c47f9eeec3732aa91f4a53161080ee2273 Mon Sep 17 00:00:00 2001 From: Raven95676 Date: Thu, 3 Jul 2025 22:13:13 +0800 Subject: [PATCH 03/31] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E9=A3=8E?= =?UTF-8?q?=E9=99=A9=E6=8F=92=E4=BB=B6=E5=AE=89=E8=A3=85=E7=A1=AE=E8=AE=A4?= =?UTF-8?q?=E5=AF=B9=E8=AF=9D=E6=A1=86=E4=BB=A5=E5=8F=8A=E9=A3=8E=E9=99=A9?= =?UTF-8?q?=E6=8F=92=E4=BB=B6=E6=A0=87=E7=AD=BE=E7=89=B9=E6=AE=8A=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/shared/ExtensionCard.vue | 12 +++- .../locales/en-US/features/extension.json | 11 +++- .../locales/zh-CN/features/extension.json | 11 +++- dashboard/src/views/ExtensionPage.vue | 65 +++++++++++++++++-- 4 files changed, 91 insertions(+), 8 deletions(-) diff --git a/dashboard/src/components/shared/ExtensionCard.vue b/dashboard/src/components/shared/ExtensionCard.vue index 35666b740..8a0075173 100644 --- a/dashboard/src/components/shared/ExtensionCard.vue +++ b/dashboard/src/components/shared/ExtensionCard.vue @@ -49,6 +49,11 @@ const reloadExtension = () => { }; const $confirm = inject("$confirm"); + +const installExtension = async () => { + emit('install', props.extension); +}; + const uninstallExtension = async () => { if (typeof $confirm !== "function") { console.error(tm("card.errors.confirmNotRegistered")); @@ -117,6 +122,10 @@ const viewReadme = () => { {{ extension.handlers?.length }}{{ tm("card.status.handlersCount") }} + + {{ tag === 'danger' ? tm('tags.danger') : tag }} +
@@ -139,7 +148,7 @@ const viewReadme = () => { + @click="installExtension"> @@ -200,6 +209,7 @@ const viewReadme = () => { + \ No newline at end of file From 225db6673823a6ca82cb8368a8d6c7ec32d796c8 Mon Sep 17 00:00:00 2001 From: Soulter <905617992@qq.com> Date: Fri, 4 Jul 2025 16:59:49 +0800 Subject: [PATCH 06/31] fix: refine streaming logic in chat response handling --- astrbot/dashboard/routes/chat.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/astrbot/dashboard/routes/chat.py b/astrbot/dashboard/routes/chat.py index e7b086cd1..b704a8888 100644 --- a/astrbot/dashboard/routes/chat.py +++ b/astrbot/dashboard/routes/chat.py @@ -166,13 +166,12 @@ class ChatRoute(Route): type = result.get("type") cid = result.get("cid") streaming = result.get("streaming", False) + chain_type = result.get("chain_type") yield f"data: {json.dumps(result, ensure_ascii=False)}\n\n" await asyncio.sleep(0.05) if streaming and type != "end": - continue - - if type == "update_title": + # If the result is still streaming, we continue to wait for more data continue if result_text: @@ -189,7 +188,11 @@ class ChatRoute(Route): self.db.update_conversation( username, cid, history=json.dumps(history) ) - break + if chain_type not in ["tool_call", "tool_call_result"]: + # If the result is not a tool call or tool call result, + # we can break the loop and end the stream + break + except BaseException as _: logger.debug(f"用户 {username} 断开聊天长连接。") return From 3df5e7b9b901225b6a864a51f7d405a981780d6c Mon Sep 17 00:00:00 2001 From: IGCrystal Date: Fri, 4 Jul 2025 17:28:39 +0800 Subject: [PATCH 07/31] =?UTF-8?q?=F0=9F=90=9E=20fix:=20=E6=B7=BB=E5=8A=A0t?= =?UTF-8?q?ags.danger=E7=9A=84=E7=BF=BB=E8=AF=91=E9=94=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dashboard/src/i18n/locales/en-US/features/extension.json | 3 +++ dashboard/src/i18n/locales/zh-CN/features/extension.json | 3 +++ 2 files changed, 6 insertions(+) diff --git a/dashboard/src/i18n/locales/en-US/features/extension.json b/dashboard/src/i18n/locales/en-US/features/extension.json index 40929054e..a9d0d1b2f 100644 --- a/dashboard/src/i18n/locales/en-US/features/extension.json +++ b/dashboard/src/i18n/locales/en-US/features/extension.json @@ -79,6 +79,9 @@ "devDocs": "Extension Development Docs", "submitRepo": "Submit Extension Repository" }, + "tags": { + "danger": "Danger" + }, "dialogs": { "error": { "title": "Error Information", diff --git a/dashboard/src/i18n/locales/zh-CN/features/extension.json b/dashboard/src/i18n/locales/zh-CN/features/extension.json index 1e8eb849a..a8e4559eb 100644 --- a/dashboard/src/i18n/locales/zh-CN/features/extension.json +++ b/dashboard/src/i18n/locales/zh-CN/features/extension.json @@ -79,6 +79,9 @@ "devDocs": "插件开发文档", "submitRepo": "提交插件仓库" }, + "tags": { + "danger": "危险" + }, "dialogs": { "error": { "title": "错误信息", From 3f5210c587927e48a980d591c70b1ba0ebca85de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=B8=A6=E7=BE=BD?= Date: Fri, 4 Jul 2025 22:28:00 +0800 Subject: [PATCH 08/31] chore: update plugin publish template --- .github/ISSUE_TEMPLATE/PLUGIN_PUBLISH.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/ISSUE_TEMPLATE/PLUGIN_PUBLISH.md b/.github/ISSUE_TEMPLATE/PLUGIN_PUBLISH.md index 73f5009ca..0358a5b27 100644 --- a/.github/ISSUE_TEMPLATE/PLUGIN_PUBLISH.md +++ b/.github/ISSUE_TEMPLATE/PLUGIN_PUBLISH.md @@ -17,6 +17,7 @@ assignees: '' { "name": "插件名", "desc": "插件介绍", + "author": "作者名", "repo": "插件仓库链接", "tags": [], "social_link": "" From ff63134c147dde33f378cea74d172e8eee574dab Mon Sep 17 00:00:00 2001 From: JOJO <41473909@qq.com> Date: Sat, 5 Jul 2025 12:30:50 +0800 Subject: [PATCH 09/31] =?UTF-8?q?fix:=20=E5=A2=9E=E5=8A=A0=E6=BC=94?= =?UTF-8?q?=E7=A4=BA=E6=A8=A1=E5=BC=8F=E4=B8=8B=E6=A0=A1=E9=AA=8C=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=E5=BC=80=E5=90=AF/=E5=85=B3=E9=97=AD/=E5=AE=89?= =?UTF-8?q?=E8=A3=85=E6=8C=87=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/astrbot/main.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/packages/astrbot/main.py b/packages/astrbot/main.py index 0a3f8ba6c..d2a78d609 100644 --- a/packages/astrbot/main.py +++ b/packages/astrbot/main.py @@ -10,6 +10,7 @@ import astrbot.api.event.filter as filter from astrbot.api.event import AstrMessageEvent, MessageEventResult from astrbot.api import sp from astrbot.api.provider import ProviderRequest +from astrbot.core import DEMO_MODE from astrbot.core.platform.astr_message_event import MessageSesion from astrbot.core.platform.message_type import MessageType from astrbot.core.provider.entities import ProviderType @@ -59,7 +60,7 @@ class RstScene(Enum): name="astrbot", desc="AstrBot 基础指令结合 + 拓展功能", author="Soulter", - version="4.0.0", + version="4.0.1", ) class Main(star.Star): def __init__(self, context: star.Context) -> None: @@ -233,6 +234,11 @@ class Main(star.Star): @plugin.command("off") async def plugin_off(self, event: AstrMessageEvent, plugin_name: str = None): """禁用插件""" + if DEMO_MODE: + event.set_result( + MessageEventResult().message("演示模式下无法禁用插件。") + ) + return if not plugin_name: event.set_result( MessageEventResult().message("/plugin off <插件名> 禁用插件。") @@ -245,6 +251,11 @@ class Main(star.Star): @plugin.command("on") async def plugin_on(self, event: AstrMessageEvent, plugin_name: str = None): """启用插件""" + if DEMO_MODE: + event.set_result( + MessageEventResult().message("演示模式下无法启用插件。") + ) + return if not plugin_name: event.set_result( MessageEventResult().message("/plugin on <插件名> 启用插件。") @@ -257,6 +268,11 @@ class Main(star.Star): @plugin.command("get") async def plugin_get(self, event: AstrMessageEvent, plugin_repo: str = None): """安装插件""" + if DEMO_MODE: + event.set_result( + MessageEventResult().message("演示模式下无法安装插件。") + ) + return if not plugin_repo: event.set_result( MessageEventResult().message("/plugin get <插件仓库地址> 安装插件") From 24958377913b41d9da33cd9a6c192312807ac937 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 5 Jul 2025 11:20:25 +0000 Subject: [PATCH 10/31] chore(deps): bump the github-actions group with 4 updates Bumps the github-actions group with 4 updates: [actions/checkout](https://github.com/actions/checkout), [actions/setup-python](https://github.com/actions/setup-python), [codecov/codecov-action](https://github.com/codecov/codecov-action) and [actions/stale](https://github.com/actions/stale). Updates `actions/checkout` from 3 to 4 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) Updates `actions/setup-python` from 4 to 5 - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v4...v5) Updates `codecov/codecov-action` from 4 to 5 - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v4...v5) Updates `actions/stale` from 5 to 9 - [Release notes](https://github.com/actions/stale/releases) - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/stale/compare/v5...v9) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions - dependency-name: actions/setup-python dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions - dependency-name: codecov/codecov-action dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions - dependency-name: actions/stale dependency-version: '9' dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions ... Signed-off-by: dependabot[bot] --- .github/workflows/auto_release.yml | 2 +- .github/workflows/coverage_test.yml | 4 ++-- .github/workflows/docker-image.yml | 2 +- .github/workflows/stale.yml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/auto_release.yml b/.github/workflows/auto_release.yml index 854a69f16..46d914a9a 100644 --- a/.github/workflows/auto_release.yml +++ b/.github/workflows/auto_release.yml @@ -73,7 +73,7 @@ jobs: uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.10' diff --git a/.github/workflows/coverage_test.yml b/.github/workflows/coverage_test.yml index 30e9237ed..a62efa5d2 100644 --- a/.github/workflows/coverage_test.yml +++ b/.github/workflows/coverage_test.yml @@ -21,7 +21,7 @@ jobs: fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 - name: Install dependencies run: | @@ -40,6 +40,6 @@ jobs: PYTHONPATH=./ pytest --cov=. tests/ -v -o log_cli=true -o log_level=DEBUG - name: Upload results to Codecov - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index e0e235c09..c0610a3c1 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Pull The Codes - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 # Must be 0 so we can fetch tags diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 310e250b6..283e99989 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -18,7 +18,7 @@ jobs: pull-requests: write steps: - - uses: actions/stale@v5 + - uses: actions/stale@v9 with: repo-token: ${{ secrets.GITHUB_TOKEN }} stale-issue-message: 'Stale issue message' From 9f31df7f3a9dac47a7e6a5b567cde4e1065c5fab Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sat, 5 Jul 2025 13:52:28 +0200 Subject: [PATCH 11/31] pytest recommendation: `pip install --editable .` https://docs.pytest.org/en/stable/how-to/existingtestsuite.html This makes setting `PYTHONPATH` unnecessary and will pull requirements from `pyproject.toml` instead of `requirements.txt`, so it is similar to end-user installations. `makedir -p data/plugins` will do both `mkdir data` and `mkdir data/plugins`. The `$CI` environment variable might be better to use than `$TESTING` because it is preset to `true` in GitHub Actions. * https://docs.github.com/en/actions/reference/variables-reference#default-environment-variables * https://docs.pytest.org/en/stable/explanation/ci.html --- .github/workflows/coverage_test.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/coverage_test.yml b/.github/workflows/coverage_test.yml index a62efa5d2..3f219121c 100644 --- a/.github/workflows/coverage_test.yml +++ b/.github/workflows/coverage_test.yml @@ -26,20 +26,19 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install -r requirements.txt - pip install pytest pytest-cov pytest-asyncio + pip install pytest pytest-asyncio pytest-cov + pip install --editable . - name: Run tests run: | - mkdir data - mkdir data/plugins - mkdir data/config - mkdir data/temp + mkdir -p data/plugins + mkdir -p data/config + mkdir -p data/temp export TESTING=true export ZHIPU_API_KEY=${{ secrets.OPENAI_API_KEY }} - PYTHONPATH=./ pytest --cov=. tests/ -v -o log_cli=true -o log_level=DEBUG + pytest --cov=. tests/ -v -o log_cli=true -o log_level=DEBUG - name: Upload results to Codecov uses: codecov/codecov-action@v5 with: - token: ${{ secrets.CODECOV_TOKEN }} \ No newline at end of file + token: ${{ secrets.CODECOV_TOKEN }} From d2f7e55bf5bd34c20ab6d06dc76d922b0d37e6ea Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sat, 5 Jul 2025 13:57:58 +0200 Subject: [PATCH 12/31] Run the tests on pull requests --- .github/workflows/coverage_test.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/coverage_test.yml b/.github/workflows/coverage_test.yml index 3f219121c..e9c94d679 100644 --- a/.github/workflows/coverage_test.yml +++ b/.github/workflows/coverage_test.yml @@ -1,6 +1,6 @@ name: Run tests and upload coverage -on: +on: push: branches: - master @@ -8,6 +8,7 @@ on: - 'README.md' - 'changelogs/**' - 'dashboard/**' + pull_request: workflow_dispatch: jobs: @@ -36,7 +37,7 @@ jobs: mkdir -p data/temp export TESTING=true export ZHIPU_API_KEY=${{ secrets.OPENAI_API_KEY }} - pytest --cov=. tests/ -v -o log_cli=true -o log_level=DEBUG + pytest --cov=. -v -o log_cli=true -o log_level=DEBUG - name: Upload results to Codecov uses: codecov/codecov-action@v5 From 1674653a42f9c56ef58d404bcd3aa5b19feee6d4 Mon Sep 17 00:00:00 2001 From: Zhenyi Wang Date: Sun, 6 Jul 2025 16:18:31 +0800 Subject: [PATCH 13/31] =?UTF-8?q?fix(wechatpadpro):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=8E=88=E6=9D=83=E7=A0=81=E6=8F=90=E5=8F=96=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E4=BB=A5=E5=85=BC=E5=AE=B9=E6=96=B0=E6=97=A7=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新接口返回多了一层authKeys字段,同时兼容二者 --- .../wechatpadpro/wechatpadpro_adapter.py | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/astrbot/core/platform/sources/wechatpadpro/wechatpadpro_adapter.py b/astrbot/core/platform/sources/wechatpadpro/wechatpadpro_adapter.py index 58e3c9b19..786c769bf 100644 --- a/astrbot/core/platform/sources/wechatpadpro/wechatpadpro_adapter.py +++ b/astrbot/core/platform/sources/wechatpadpro/wechatpadpro_adapter.py @@ -225,21 +225,23 @@ class WeChatPadProAdapter(Platform): # 修正成功判断条件和授权码提取路径 if response.status == 200 and response_data.get("Code") == 200: # 授权码在 Data 字段的列表中 - if ( - response_data.get("Data") - and isinstance(response_data["Data"], list) - and len(response_data["Data"]) > 0 - ): - self.auth_key = response_data["Data"][0] - logger.info(f"成功获取授权码 {self.auth_key[:8]}...") + data = response_data.get("Data") + if data: + # 新返回格式 + if isinstance(data.get("authKeys"), list) and data["authKeys"]: + self.auth_key = data["authKeys"][0] + # 兼容旧版接口 + elif isinstance(data, list) and data: + self.auth_key = data[0] + + if self.auth_key: + logger.info(f"成功获取授权码 {self.auth_key[:8]}...") + else: + logger.error(f"生成授权码成功但未找到授权码: {response_data}") else: - logger.error( - f"生成授权码成功但未找到授权码: {response_data}" - ) + logger.error(f"生成授权码成功但未找到授权码: {response_data}") else: - logger.error( - f"生成授权码失败: {response.status}, {response_data}" - ) + logger.error(f"生成授权码失败: {response.status}, {response_data}") except aiohttp.ClientConnectorError as e: logger.error(f"连接到 WeChatPadPro 服务失败: {e}") except Exception as e: From 3e4917f0a10ba6e2556573e6a9fa0fd31eaa9364 Mon Sep 17 00:00:00 2001 From: Zhenyi Wang Date: Sun, 6 Jul 2025 16:34:55 +0800 Subject: [PATCH 14/31] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=20wechatpa?= =?UTF-8?q?dpro=20=E6=8E=88=E6=9D=83=E7=A0=81=E7=94=9F=E6=88=90=E5=B9=B6?= =?UTF-8?q?=E5=A2=9E=E5=BC=BA=E5=AE=89=E5=85=A8=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 generate_auth_key 方法中的授权码提取逻辑重构为新的辅助方法 _extract_auth_key ,以提高代码的可读性和可测试性。 - 在访问 data.get('authKeys') 之前添加 isinstance(data, dict) 检查,以防止潜在的 AttributeError 。 - 移除了 auth_key 的明文日志记录,以避免敏感信息泄露。 - 在生成新密钥之前,将 self.auth_key 初始化为 None ,以避免在失败时保留旧值。 --- .../wechatpadpro/wechatpadpro_adapter.py | 40 +++++++++++-------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/astrbot/core/platform/sources/wechatpadpro/wechatpadpro_adapter.py b/astrbot/core/platform/sources/wechatpadpro/wechatpadpro_adapter.py index 786c769bf..7d5984416 100644 --- a/astrbot/core/platform/sources/wechatpadpro/wechatpadpro_adapter.py +++ b/astrbot/core/platform/sources/wechatpadpro/wechatpadpro_adapter.py @@ -210,6 +210,16 @@ class WeChatPadProAdapter(Platform): logger.error(traceback.format_exc()) return False + def _extract_auth_key(self, data): + """Helper method to extract auth_key from response data.""" + if isinstance(data, dict): + auth_keys = data.get("authKeys") # 新接口 + if isinstance(auth_keys, list) and auth_keys: + return auth_keys[0] + elif isinstance(data, list) and data: # 旧接口 + return data[0] + return None + async def generate_auth_key(self): """ 生成授权码。 @@ -218,30 +228,26 @@ class WeChatPadProAdapter(Platform): params = {"key": self.admin_key} payload = {"Count": 1, "Days": 365} # 生成一个有效期365天的授权码 + self.auth_key = None # Reset auth_key before generating a new one + async with aiohttp.ClientSession() as session: try: async with session.post(url, params=params, json=payload) as response: + if response.status != 200: + logger.error(f"生成授权码失败: {response.status}, {await response.text()}") + return + response_data = await response.json() - # 修正成功判断条件和授权码提取路径 - if response.status == 200 and response_data.get("Code") == 200: - # 授权码在 Data 字段的列表中 - data = response_data.get("Data") - if data: - # 新返回格式 - if isinstance(data.get("authKeys"), list) and data["authKeys"]: - self.auth_key = data["authKeys"][0] - # 兼容旧版接口 - elif isinstance(data, list) and data: - self.auth_key = data[0] - - if self.auth_key: - logger.info(f"成功获取授权码 {self.auth_key[:8]}...") - else: - logger.error(f"生成授权码成功但未找到授权码: {response_data}") + if response_data.get("Code") == 200: + if data := response_data.get("Data"): + self.auth_key = self._extract_auth_key(data) + + if self.auth_key: + logger.info("成功获取授权码") else: logger.error(f"生成授权码成功但未找到授权码: {response_data}") else: - logger.error(f"生成授权码失败: {response.status}, {response_data}") + logger.error(f"生成授权码失败: {response_data}") except aiohttp.ClientConnectorError as e: logger.error(f"连接到 WeChatPadPro 服务失败: {e}") except Exception as e: From 20f49890ad6d7a615db2acda8e6adb95ebb6f07f Mon Sep 17 00:00:00 2001 From: Soulter <905617992@qq.com> Date: Fri, 4 Jul 2025 16:59:49 +0800 Subject: [PATCH 15/31] fix: provider selection for updating webchat title --- astrbot/core/pipeline/process_stage/method/llm_request.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/astrbot/core/pipeline/process_stage/method/llm_request.py b/astrbot/core/pipeline/process_stage/method/llm_request.py index 5923e8246..4027dcd7e 100644 --- a/astrbot/core/pipeline/process_stage/method/llm_request.py +++ b/astrbot/core/pipeline/process_stage/method/llm_request.py @@ -254,11 +254,11 @@ class LLMRequestSubStage(Stage): # 异步处理 WebChat 特殊情况 if event.get_platform_name() == "webchat": - asyncio.create_task(self._handle_webchat(event, req)) + asyncio.create_task(self._handle_webchat(event, req, provider)) await self._save_to_history(event, req, tool_loop_agent.get_final_llm_resp()) - async def _handle_webchat(self, event: AstrMessageEvent, req: ProviderRequest): + async def _handle_webchat(self, event: AstrMessageEvent, req: ProviderRequest, prov: Provider): """处理 WebChat 平台的特殊情况,包括第一次 LLM 对话时总结对话内容生成 title""" conversation = await self.conv_manager.get_conversation( event.unified_msg_origin, req.conversation.cid @@ -268,10 +268,9 @@ class LLMRequestSubStage(Stage): latest_pair = messages[-2:] if not latest_pair: return - provider = self.ctx.plugin_manager.context.get_using_provider() cleaned_text = "User: " + latest_pair[0].get("content", "").strip() logger.debug(f"WebChat 对话标题生成请求,清理后的文本: {cleaned_text}") - llm_resp = await provider.text_chat( + llm_resp = await prov.text_chat( system_prompt="You are expert in summarizing user's query.", prompt=( f"Please summarize the following query of user:\n" From 67ef993d617162a0c660bebf87858b033494ad4e Mon Sep 17 00:00:00 2001 From: Soulter <905617992@qq.com> Date: Sun, 6 Jul 2025 17:21:57 +0800 Subject: [PATCH 16/31] fix: webchat message bubble style --- dashboard/src/views/ChatPage.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/dashboard/src/views/ChatPage.vue b/dashboard/src/views/ChatPage.vue index 1aa8bb9e0..fedb86b3e 100644 --- a/dashboard/src/views/ChatPage.vue +++ b/dashboard/src/views/ChatPage.vue @@ -1473,7 +1473,6 @@ export default { .message-bubble { padding: 8px 16px; border-radius: 12px; - max-width: 80%; } .user-bubble { From 69d3ae709c23771f16212ef3e25463cc12aed0cb Mon Sep 17 00:00:00 2001 From: Raven95676 Date: Sat, 5 Jul 2025 22:08:17 +0800 Subject: [PATCH 17/31] fix: direct send tool_call_result --- .../agent_runner/tool_loop_agent.py | 1 - .../process_stage/method/llm_request.py | 13 +++++++------ dashboard/src/views/ChatPage.vue | 1 - packages/astrbot/main.py | 18 +++++++++++++++++- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/astrbot/core/pipeline/process_stage/agent_runner/tool_loop_agent.py b/astrbot/core/pipeline/process_stage/agent_runner/tool_loop_agent.py index dcb390b2f..3f97c189c 100644 --- a/astrbot/core/pipeline/process_stage/agent_runner/tool_loop_agent.py +++ b/astrbot/core/pipeline/process_stage/agent_runner/tool_loop_agent.py @@ -106,7 +106,6 @@ class ToolLoopAgent(BaseAgentRunner): # 处理 LLM 响应 llm_resp = llm_resp_result - logger.debug(f"LLMResp: {llm_resp}") if llm_resp.role == "err": # 如果 LLM 响应错误,转换到错误状态 diff --git a/astrbot/core/pipeline/process_stage/method/llm_request.py b/astrbot/core/pipeline/process_stage/method/llm_request.py index 5923e8246..000369326 100644 --- a/astrbot/core/pipeline/process_stage/method/llm_request.py +++ b/astrbot/core/pipeline/process_stage/method/llm_request.py @@ -177,7 +177,10 @@ class LLMRequestSubStage(Stage): if event.is_stopped(): return if resp.type == "tool_call_result": - continue # 跳过工具调用结果 + # 处理工具调用结果,直接发送给用户 + resp.data["chain"].type = "tool_call_result" + await event.send(resp.data["chain"]) + continue if resp.type == "tool_call": if self.streaming_response: # 用来标记流式响应需要分节 @@ -254,11 +257,11 @@ class LLMRequestSubStage(Stage): # 异步处理 WebChat 特殊情况 if event.get_platform_name() == "webchat": - asyncio.create_task(self._handle_webchat(event, req)) + asyncio.create_task(self._handle_webchat(event, req, provider)) await self._save_to_history(event, req, tool_loop_agent.get_final_llm_resp()) - async def _handle_webchat(self, event: AstrMessageEvent, req: ProviderRequest): + async def _handle_webchat(self, event: AstrMessageEvent, req: ProviderRequest, prov: Provider): """处理 WebChat 平台的特殊情况,包括第一次 LLM 对话时总结对话内容生成 title""" conversation = await self.conv_manager.get_conversation( event.unified_msg_origin, req.conversation.cid @@ -268,10 +271,9 @@ class LLMRequestSubStage(Stage): latest_pair = messages[-2:] if not latest_pair: return - provider = self.ctx.plugin_manager.context.get_using_provider() cleaned_text = "User: " + latest_pair[0].get("content", "").strip() logger.debug(f"WebChat 对话标题生成请求,清理后的文本: {cleaned_text}") - llm_resp = await provider.text_chat( + llm_resp = await prov.text_chat( system_prompt="You are expert in summarizing user's query.", prompt=( f"Please summarize the following query of user:\n" @@ -333,7 +335,6 @@ class LLMRequestSubStage(Stage): await self.conv_manager.update_conversation( event.unified_msg_origin, req.conversation.cid, history=messages ) - logger.debug(f"messages persisted: {messages}") def fix_messages(self, messages: list[dict]) -> list[dict]: """验证并且修复上下文""" diff --git a/dashboard/src/views/ChatPage.vue b/dashboard/src/views/ChatPage.vue index 1aa8bb9e0..fedb86b3e 100644 --- a/dashboard/src/views/ChatPage.vue +++ b/dashboard/src/views/ChatPage.vue @@ -1473,7 +1473,6 @@ export default { .message-bubble { padding: 8px 16px; border-radius: 12px; - max-width: 80%; } .user-bubble { diff --git a/packages/astrbot/main.py b/packages/astrbot/main.py index 0a3f8ba6c..d2a78d609 100644 --- a/packages/astrbot/main.py +++ b/packages/astrbot/main.py @@ -10,6 +10,7 @@ import astrbot.api.event.filter as filter from astrbot.api.event import AstrMessageEvent, MessageEventResult from astrbot.api import sp from astrbot.api.provider import ProviderRequest +from astrbot.core import DEMO_MODE from astrbot.core.platform.astr_message_event import MessageSesion from astrbot.core.platform.message_type import MessageType from astrbot.core.provider.entities import ProviderType @@ -59,7 +60,7 @@ class RstScene(Enum): name="astrbot", desc="AstrBot 基础指令结合 + 拓展功能", author="Soulter", - version="4.0.0", + version="4.0.1", ) class Main(star.Star): def __init__(self, context: star.Context) -> None: @@ -233,6 +234,11 @@ class Main(star.Star): @plugin.command("off") async def plugin_off(self, event: AstrMessageEvent, plugin_name: str = None): """禁用插件""" + if DEMO_MODE: + event.set_result( + MessageEventResult().message("演示模式下无法禁用插件。") + ) + return if not plugin_name: event.set_result( MessageEventResult().message("/plugin off <插件名> 禁用插件。") @@ -245,6 +251,11 @@ class Main(star.Star): @plugin.command("on") async def plugin_on(self, event: AstrMessageEvent, plugin_name: str = None): """启用插件""" + if DEMO_MODE: + event.set_result( + MessageEventResult().message("演示模式下无法启用插件。") + ) + return if not plugin_name: event.set_result( MessageEventResult().message("/plugin on <插件名> 启用插件。") @@ -257,6 +268,11 @@ class Main(star.Star): @plugin.command("get") async def plugin_get(self, event: AstrMessageEvent, plugin_repo: str = None): """安装插件""" + if DEMO_MODE: + event.set_result( + MessageEventResult().message("演示模式下无法安装插件。") + ) + return if not plugin_repo: event.set_result( MessageEventResult().message("/plugin get <插件仓库地址> 安装插件") From cd722a0e39b4ca2aa83332f79dc986f7d213f616 Mon Sep 17 00:00:00 2001 From: Soulter <905617992@qq.com> Date: Sun, 6 Jul 2025 18:04:46 +0800 Subject: [PATCH 18/31] fix: handle direct tool call results --- .../process_stage/agent_runner/tool_loop_agent.py | 12 +++++++++--- .../pipeline/process_stage/method/llm_request.py | 15 ++++++++++----- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/astrbot/core/pipeline/process_stage/agent_runner/tool_loop_agent.py b/astrbot/core/pipeline/process_stage/agent_runner/tool_loop_agent.py index 3f97c189c..c2961ded5 100644 --- a/astrbot/core/pipeline/process_stage/agent_runner/tool_loop_agent.py +++ b/astrbot/core/pipeline/process_stage/agent_runner/tool_loop_agent.py @@ -218,7 +218,9 @@ class ToolLoopAgent(BaseAgentRunner): content="返回了图片(已直接发送给用户)", ) ) - yield MessageChain().base64_image(res.content[0].data) + yield MessageChain(type="tool_direct_result").base64_image( + res.content[0].data + ) elif isinstance(res.content[0], EmbeddedResource): resource = res.content[0].resource if isinstance(resource, TextResourceContents): @@ -242,7 +244,9 @@ class ToolLoopAgent(BaseAgentRunner): content="返回了图片(已直接发送给用户)", ) ) - yield MessageChain().base64_image(res.content[0].data) + yield MessageChain(type="tool_direct_result").base64_image( + res.content[0].data + ) else: tool_call_result_blocks.append( ToolCallMessageSegment( @@ -275,7 +279,9 @@ class ToolLoopAgent(BaseAgentRunner): self._transition_state(AgentState.DONE) if res := self.event.get_result(): if res.chain: - yield MessageChain(chain=res.chain) + yield MessageChain( + chain=res.chain, type="tool_direct_result" + ) self.event.clear_result() except Exception as e: diff --git a/astrbot/core/pipeline/process_stage/method/llm_request.py b/astrbot/core/pipeline/process_stage/method/llm_request.py index 000369326..b1d9310c6 100644 --- a/astrbot/core/pipeline/process_stage/method/llm_request.py +++ b/astrbot/core/pipeline/process_stage/method/llm_request.py @@ -177,10 +177,13 @@ class LLMRequestSubStage(Stage): if event.is_stopped(): return if resp.type == "tool_call_result": - # 处理工具调用结果,直接发送给用户 - resp.data["chain"].type = "tool_call_result" - await event.send(resp.data["chain"]) - continue + msg_chain = resp.data["chain"] + if msg_chain.type == "tool_direct_result": + # tool_direct_result 用于标记 llm tool 需要直接发送给用户的内容 + resp.data["chain"].type = "tool_call_result" + await event.send(resp.data["chain"]) + continue + # 对于其他情况,暂时先不处理 if resp.type == "tool_call": if self.streaming_response: # 用来标记流式响应需要分节 @@ -261,7 +264,9 @@ class LLMRequestSubStage(Stage): await self._save_to_history(event, req, tool_loop_agent.get_final_llm_resp()) - async def _handle_webchat(self, event: AstrMessageEvent, req: ProviderRequest, prov: Provider): + async def _handle_webchat( + self, event: AstrMessageEvent, req: ProviderRequest, prov: Provider + ): """处理 WebChat 平台的特殊情况,包括第一次 LLM 对话时总结对话内容生成 title""" conversation = await self.conv_manager.get_conversation( event.unified_msg_origin, req.conversation.cid From 7512bfc7107f3e60b6d62c88bbf7214990f3ded4 Mon Sep 17 00:00:00 2001 From: Soulter <905617992@qq.com> Date: Sun, 6 Jul 2025 18:06:25 +0800 Subject: [PATCH 19/31] fix: update user message bubble styling for improved appearance --- dashboard/src/views/ChatPage.vue | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dashboard/src/views/ChatPage.vue b/dashboard/src/views/ChatPage.vue index fedb86b3e..2a17473f1 100644 --- a/dashboard/src/views/ChatPage.vue +++ b/dashboard/src/views/ChatPage.vue @@ -1477,8 +1477,10 @@ export default { .user-bubble { color: var(--v-theme-primaryText); - padding: 12px 16px; + padding: 18px 20px; font-size: 16px; + max-width: 60%; + border-radius: 1.5rem; } .bot-bubble { From 14a8bb57df5e7085489a3f8939515534b595fec0 Mon Sep 17 00:00:00 2001 From: IGCrystal Date: Fri, 4 Jul 2025 22:39:32 +0800 Subject: [PATCH 20/31] =?UTF-8?q?=F0=9F=90=9E=20fix(WebUI):=20=E8=A7=A3?= =?UTF-8?q?=E5=86=B3XSS=E6=B3=A8=E5=85=A5=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dashboard/package.json | 1 + .../src/components/shared/ReadmeDialog.vue | 41 +++++++++---------- .../full/vertical-header/VerticalHeader.vue | 12 +++++- dashboard/src/views/ChatPage.vue | 13 +++--- dashboard/src/views/ConversationPage.vue | 15 ++++--- 5 files changed, 49 insertions(+), 33 deletions(-) diff --git a/dashboard/package.json b/dashboard/package.json index 7a5dd44a5..4f7ca6753 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -26,6 +26,7 @@ "js-md5": "^0.8.3", "lodash": "4.17.21", "marked": "^15.0.7", + "markdown-it": "^14.1.0", "pinia": "2.1.6", "remixicon": "3.5.0", "vee-validate": "4.11.3", diff --git a/dashboard/src/components/shared/ReadmeDialog.vue b/dashboard/src/components/shared/ReadmeDialog.vue index 739b9a4dd..4d1a7a258 100644 --- a/dashboard/src/components/shared/ReadmeDialog.vue +++ b/dashboard/src/components/shared/ReadmeDialog.vue @@ -1,7 +1,7 @@ + + diff --git a/dashboard/src/components/shared/ItemCardGrid.vue b/dashboard/src/components/shared/ItemCardGrid.vue index 71841d2ab..5176c186b 100644 --- a/dashboard/src/components/shared/ItemCardGrid.vue +++ b/dashboard/src/components/shared/ItemCardGrid.vue @@ -9,10 +9,10 @@ - +
- {{ getItemTitle(item) }} + {{ getItemTitle(item) }}