mirror of
https://github.com/AstrBotDevs/AstrBot
synced 2026-07-03 19:20:16 +08:00
Compare commits
4 Commits
fix/llm_to
...
v4.26.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
00c50b3b92 | ||
|
|
090f9008b6 | ||
|
|
473377f340 | ||
|
|
9daf8f0a84 |
@@ -1,4 +1,4 @@
|
||||
import logging
|
||||
|
||||
__version__ = "4.26.0"
|
||||
__version__ = "4.26.1"
|
||||
logger = logging.getLogger("astrbot")
|
||||
|
||||
@@ -210,7 +210,8 @@ class InternalAgentSubStage(Stage):
|
||||
await event.send_typing()
|
||||
except Exception:
|
||||
logger.warning("send_typing failed", exc_info=True)
|
||||
await call_event_hook(event, EventType.OnWaitingLLMRequestEvent)
|
||||
if await call_event_hook(event, EventType.OnWaitingLLMRequestEvent):
|
||||
return
|
||||
|
||||
async with session_lock_manager.acquire_lock(event.unified_msg_origin):
|
||||
logger.debug("acquired session lock for llm request")
|
||||
|
||||
@@ -25,7 +25,7 @@ from tenacity import (
|
||||
|
||||
from astrbot.api import logger
|
||||
from astrbot.api.event import AstrMessageEvent, MessageChain
|
||||
from astrbot.api.message_components import At, File, Image, Plain, Record, Video
|
||||
from astrbot.api.message_components import File, Image, Plain, Record, Video
|
||||
from astrbot.api.platform import AstrBotMessage, PlatformMetadata
|
||||
from astrbot.core.utils.media_utils import MediaResolver, file_uri_to_path, is_file_uri
|
||||
|
||||
@@ -747,10 +747,6 @@ class QQOfficialMessageEvent(AstrMessageEvent):
|
||||
file_source = file_path
|
||||
elif i.url:
|
||||
file_source = i.url
|
||||
elif isinstance(i, At):
|
||||
qq_id = getattr(i, "qq", "")
|
||||
if qq_id and qq_id != "all":
|
||||
plain_text += f"<@{qq_id}>"
|
||||
else:
|
||||
logger.debug(f"qq_official 忽略 {i.type}")
|
||||
return (
|
||||
|
||||
@@ -249,9 +249,10 @@ class _PermissionGuardedTool(FunctionTool):
|
||||
if error is not None:
|
||||
return error
|
||||
|
||||
# Delegate to handler first (plugin tools).
|
||||
# @filter.llm_tool decorated tools have a handler attribute, which is the actual callable.
|
||||
if self._wrapped.handler is not None:
|
||||
result = self._wrapped.handler(context, **kwargs)
|
||||
event = context.context.event
|
||||
result = self._wrapped.handler(event, **kwargs)
|
||||
if _inspect.isasyncgen(result):
|
||||
last: Any = None
|
||||
async for item in result:
|
||||
@@ -261,11 +262,12 @@ class _PermissionGuardedTool(FunctionTool):
|
||||
return await result
|
||||
return result
|
||||
|
||||
# Fall back to overridden call() on subclasses (e.g. MCPTool).
|
||||
# If the tool has a "call" method that is not the default FunctionTool.call, invoke it.
|
||||
call_override = getattr(type(self._wrapped), "call", None)
|
||||
if call_override is not None and call_override is not FunctionTool.call:
|
||||
return await self._wrapped.call(context, **kwargs)
|
||||
|
||||
# Compatibility fallback: if the tool has a "run" method, invoke it. This is for legacy tools that don't use the new handler/call interface.
|
||||
run = getattr(self._wrapped, "run", None)
|
||||
if run is not None:
|
||||
event = context.context.event
|
||||
|
||||
30
changelogs/v4.26.1.md
Normal file
30
changelogs/v4.26.1.md
Normal file
@@ -0,0 +1,30 @@
|
||||
- [更新日志(简体中文)](#chinese)
|
||||
- [Changelog(English)](#english)
|
||||
|
||||
<a id="chinese"></a>
|
||||
|
||||
## What's Changed
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复插件注册的 LLM Tool 在受保护工具权限处理场景下可能无法正常调用的问题。([#9001](https://github.com/AstrBotDevs/AstrBot/pull/9001))
|
||||
- 修复等待 LLM 请求事件在获取会话锁前未及时处理停止信号的问题。([#8935](https://github.com/AstrBotDevs/AstrBot/pull/8935))
|
||||
- 回滚 QQ 官方平台发送消息时保留 At 组件的相关变更,避免引入兼容性问题。([#9004](https://github.com/AstrBotDevs/AstrBot/pull/9004))
|
||||
|
||||
### 其他
|
||||
|
||||
- 补充 Cloudflare Workers 静态资源相关配置。([commit](https://github.com/AstrBotDevs/AstrBot/commit/44df70d2e), [commit](https://github.com/AstrBotDevs/AstrBot/commit/348fe8172))
|
||||
|
||||
<a id="english"></a>
|
||||
|
||||
## What's Changed (EN)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Fixed a case where plugin-registered LLM tools could fail to invoke when guarded tool permission handling was applied. ([#9001](https://github.com/AstrBotDevs/AstrBot/pull/9001))
|
||||
- Fixed waiting LLM request events so stop signals are checked before acquiring the session lock. ([#8935](https://github.com/AstrBotDevs/AstrBot/pull/8935))
|
||||
- Reverted the QQ Official platform At component preservation change to avoid compatibility regressions. ([#9004](https://github.com/AstrBotDevs/AstrBot/pull/9004))
|
||||
|
||||
### Other
|
||||
|
||||
- Added Cloudflare Workers static asset configuration. ([commit](https://github.com/AstrBotDevs/AstrBot/commit/44df70d2e), [commit](https://github.com/AstrBotDevs/AstrBot/commit/348fe8172))
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "AstrBot"
|
||||
version = "4.26.0"
|
||||
version = "4.26.1"
|
||||
description = "Easy-to-use multi-platform LLM chatbot and development framework"
|
||||
readme = "README.md"
|
||||
license = { text = "AGPL-3.0-or-later" }
|
||||
|
||||
@@ -174,16 +174,19 @@ async def test_check_permission_passes_for_member_when_configured_member():
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_guarded_tool_delegates_when_permission_passes():
|
||||
async def test_guarded_tool_delegates_handler_with_event_when_permission_passes():
|
||||
_clear_tool_permissions()
|
||||
mgr = FunctionToolManager()
|
||||
|
||||
called = False
|
||||
received_event = None
|
||||
|
||||
async def handler(ctx, **kw):
|
||||
async def handler(event, **kw):
|
||||
nonlocal called
|
||||
nonlocal received_event
|
||||
called = True
|
||||
return "ok"
|
||||
received_event = event
|
||||
return f"ok:{event.get_sender_id()}:{kw['value']}"
|
||||
|
||||
wrapped = FunctionTool(
|
||||
name="delegated",
|
||||
@@ -194,9 +197,10 @@ async def test_guarded_tool_delegates_when_permission_passes():
|
||||
guarded = _PermissionGuardedTool(wrapped, mgr)
|
||||
context = _make_context(role="member")
|
||||
|
||||
result = await guarded.call(context)
|
||||
result = await guarded.call(context, value="sentinel")
|
||||
assert called
|
||||
assert result == "ok"
|
||||
assert received_event is context.context.event
|
||||
assert result == "ok:user_123:sentinel"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@@ -280,7 +284,8 @@ async def test_guarded_tool_handles_async_generator_handler():
|
||||
_clear_tool_permissions()
|
||||
mgr = FunctionToolManager()
|
||||
|
||||
async def gen_handler(ctx, **kw): # type: ignore[misc]
|
||||
async def gen_handler(event, **kw): # type: ignore[misc]
|
||||
assert event is context.context.event
|
||||
yield "A"
|
||||
yield "B"
|
||||
yield "C"
|
||||
|
||||
Reference in New Issue
Block a user