diff --git a/astrbot/builtin_stars/astrbot/long_term_memory.py b/astrbot/builtin_stars/astrbot/long_term_memory.py index 610995db2..469d7ca63 100644 --- a/astrbot/builtin_stars/astrbot/long_term_memory.py +++ b/astrbot/builtin_stars/astrbot/long_term_memory.py @@ -70,7 +70,7 @@ async def get_image_caption( image_caption_prompt: str, ) -> str: if not image_caption_provider_id: - provider = self.context.get_using_provider() + provider = await self.context.get_using_provider() else: provider = self.context.get_provider_by_id(image_caption_provider_id) if not provider: @@ -164,7 +164,9 @@ async def on_req_llm(self, event: AstrMessageEvent, req: ProviderRequest): "Please react to it. Only output your response and do not output any other information. " "You MUST use the SAME language as the chatroom is using." ) - req.contexts = [] # 清空上下文,当使用了主动回复,所有聊天记录都在一个prompt中。 + req.contexts = ( + [] + ) # 清空上下文,当使用了主动回复,所有聊天记录都在一个prompt中。 else: req.system_prompt += ( "You are now in a chatroom. The chat history is as follows: \n" diff --git a/astrbot/builtin_stars/astrbot/main.py b/astrbot/builtin_stars/astrbot/main.py index 773d03939..6491cb199 100644 --- a/astrbot/builtin_stars/astrbot/main.py +++ b/astrbot/builtin_stars/astrbot/main.py @@ -48,7 +48,9 @@ async def on_message(self, event: AstrMessageEvent): if need_active: """主动回复""" - provider = self.context.get_using_provider(event.unified_msg_origin) + provider = await self.context.get_using_provider( + event.unified_msg_origin + ) if not provider: logger.error("未找到任何 LLM 提供商。请先配置。无法主动回复") return diff --git a/astrbot/builtin_stars/builtin_commands/commands/conversation.py b/astrbot/builtin_stars/builtin_commands/commands/conversation.py index de3d11ac8..07f5dc92a 100644 --- a/astrbot/builtin_stars/builtin_commands/commands/conversation.py +++ b/astrbot/builtin_stars/builtin_commands/commands/conversation.py @@ -70,7 +70,7 @@ async def reset(self, message: AstrMessageEvent): message.set_result(MessageEventResult().message("重置对话成功。")) return - if not self.context.get_using_provider(umo): + if not await self.context.get_using_provider(umo): message.set_result( MessageEventResult().message("未找到任何 LLM 提供商。请先配置。"), ) @@ -100,7 +100,7 @@ async def reset(self, message: AstrMessageEvent): async def his(self, message: AstrMessageEvent, page: int = 1): """查看对话记录""" - if not self.context.get_using_provider(message.unified_msg_origin): + if not await self.context.get_using_provider(message.unified_msg_origin): message.set_result( MessageEventResult().message("未找到任何 LLM 提供商。请先配置。"), ) diff --git a/astrbot/builtin_stars/builtin_commands/commands/provider.py b/astrbot/builtin_stars/builtin_commands/commands/provider.py index 60b81ebe5..77fb24123 100644 --- a/astrbot/builtin_stars/builtin_commands/commands/provider.py +++ b/astrbot/builtin_stars/builtin_commands/commands/provider.py @@ -138,7 +138,7 @@ async def provider( llm_data = [d for d in display_data if d["type"] == "llm"] for i, d in enumerate(llm_data): line = f"{i + 1}. {d['info']}{d['mark']}" - provider_using = self.context.get_using_provider(umo=umo) + provider_using = await self.context.get_using_provider(umo=umo) if ( provider_using and provider_using.meta().id == d["provider"].meta().id @@ -152,7 +152,7 @@ async def provider( parts.append("\n## 载入的 TTS 提供商\n") for i, d in enumerate(tts_data): line = f"{i + 1}. {d['info']}{d['mark']}" - tts_using = self.context.get_using_tts_provider(umo=umo) + tts_using = await self.context.get_using_tts_provider(umo=umo) if tts_using and tts_using.meta().id == d["provider"].meta().id: line += " (当前使用)" parts.append(line + "\n") @@ -163,7 +163,7 @@ async def provider( parts.append("\n## 载入的 STT 提供商\n") for i, d in enumerate(stt_data): line = f"{i + 1}. {d['info']}{d['mark']}" - stt_using = self.context.get_using_stt_provider(umo=umo) + stt_using = await self.context.get_using_stt_provider(umo=umo) if stt_using and stt_using.meta().id == d["provider"].meta().id: line += " (当前使用)" parts.append(line + "\n") @@ -230,7 +230,7 @@ async def model_ls( idx_or_name: int | str | None = None, ): """查看或者切换模型""" - prov = self.context.get_using_provider(message.unified_msg_origin) + prov = await self.context.get_using_provider(message.unified_msg_origin) if not prov: message.set_result( MessageEventResult().message("未找到任何 LLM 提供商。请先配置。"), @@ -294,7 +294,7 @@ async def model_ls( ) async def key(self, message: AstrMessageEvent, index: int | None = None): - prov = self.context.get_using_provider(message.unified_msg_origin) + prov = await self.context.get_using_provider(message.unified_msg_origin) if not prov: message.set_result( MessageEventResult().message("未找到任何 LLM 提供商。请先配置。"), diff --git a/astrbot/cli/__init__.py b/astrbot/cli/__init__.py index f13ee1d85..9ea60ffe2 100644 --- a/astrbot/cli/__init__.py +++ b/astrbot/cli/__init__.py @@ -1 +1 @@ -__version__ = "4.14.7" +__version__ = "4.14.8" diff --git a/astrbot/core/astr_main_agent.py b/astrbot/core/astr_main_agent.py index 690a6404c..e81fcf48c 100644 --- a/astrbot/core/astr_main_agent.py +++ b/astrbot/core/astr_main_agent.py @@ -118,7 +118,7 @@ class MainAgentBuildResult: reset_coro: Coroutine | None = None -def _select_provider( +async def _select_provider( event: AstrMessageEvent, plugin_context: Context ) -> Provider | None: """Select chat provider for the event.""" @@ -134,7 +134,7 @@ def _select_provider( return None return provider try: - return plugin_context.get_using_provider(umo=event.unified_msg_origin) + return await plugin_context.get_using_provider(umo=event.unified_msg_origin) except ValueError as exc: logger.error("Error occurred while selecting provider: %s", exc) return None @@ -505,7 +505,7 @@ async def _process_quote_message( if img_cap_prov_id: prov = plugin_context.get_provider_by_id(img_cap_prov_id) if prov is None: - prov = plugin_context.get_using_provider(event.unified_msg_origin) + prov = await plugin_context.get_using_provider(event.unified_msg_origin) if prov and isinstance(prov, Provider): llm_resp = await prov.text_chat( @@ -845,7 +845,7 @@ async def build_main_agent( If apply_reset is False, will not call reset on the agent runner. """ - provider = provider or _select_provider(event, plugin_context) + provider = provider or await _select_provider(event, plugin_context) if provider is None: logger.info("未找到任何对话模型(提供商),跳过 LLM 请求处理。") return None diff --git a/astrbot/core/config/default.py b/astrbot/core/config/default.py index 3606cd2fc..076c95ce8 100644 --- a/astrbot/core/config/default.py +++ b/astrbot/core/config/default.py @@ -5,7 +5,7 @@ from astrbot.core.utils.astrbot_path import get_astrbot_data_path -VERSION = "4.14.7" +VERSION = "4.14.8" DB_PATH = os.path.join(get_astrbot_data_path(), "data_v4.db") WEBHOOK_SUPPORTED_PLATFORMS = [ diff --git a/astrbot/core/pipeline/preprocess_stage/stage.py b/astrbot/core/pipeline/preprocess_stage/stage.py index 6544f85c1..73b22adba 100644 --- a/astrbot/core/pipeline/preprocess_stage/stage.py +++ b/astrbot/core/pipeline/preprocess_stage/stage.py @@ -68,7 +68,7 @@ async def process( if self.stt_settings.get("enable", False): # TODO: 独立 ctx = self.plugin_manager.context - stt_provider = ctx.get_using_stt_provider(event.unified_msg_origin) + stt_provider = await ctx.get_using_stt_provider(event.unified_msg_origin) if not stt_provider: logger.warning( f"会话 {event.unified_msg_origin} 未配置语音转文本模型。", 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 b095a7cbb..0e4120964 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 @@ -216,7 +216,7 @@ async def process( # 获取 TTS Provider tts_provider = ( - self.ctx.plugin_manager.context.get_using_tts_provider( + await self.ctx.plugin_manager.context.get_using_tts_provider( event.unified_msg_origin ) ) diff --git a/astrbot/core/pipeline/result_decorate/stage.py b/astrbot/core/pipeline/result_decorate/stage.py index e0bcd5ac9..0e400baf1 100644 --- a/astrbot/core/pipeline/result_decorate/stage.py +++ b/astrbot/core/pipeline/result_decorate/stage.py @@ -253,7 +253,7 @@ async def process( result.chain = new_chain # TTS - tts_provider = self.ctx.plugin_manager.context.get_using_tts_provider( + tts_provider = await self.ctx.plugin_manager.context.get_using_tts_provider( event.unified_msg_origin, ) diff --git a/astrbot/core/provider/manager.py b/astrbot/core/provider/manager.py index 7ec8c36ff..bd78a53ce 100644 --- a/astrbot/core/provider/manager.py +++ b/astrbot/core/provider/manager.py @@ -153,7 +153,7 @@ async def get_provider_by_id(self, provider_id: str) -> Providers | None: """根据提供商 ID 获取提供商实例""" return self.inst_map.get(provider_id) - def get_using_provider( + async def get_using_provider( self, provider_type: ProviderType, umo=None ) -> Providers | None: """获取正在使用的提供商实例。 @@ -169,11 +169,11 @@ def get_using_provider( provider = None provider_id = None if umo: - provider_id = sp.get( - f"provider_perf_{provider_type.value}", - None, - scope="umo", - scope_id=umo, + provider_id = await sp.get_async( + scope="umo", + scope_id=umo, + key=f"provider_perf_{provider_type.value}", + default=None, ) if provider_id: provider = self.inst_map.get(provider_id) diff --git a/astrbot/core/star/context.py b/astrbot/core/star/context.py index c7438baf2..93ef178a7 100644 --- a/astrbot/core/star/context.py +++ b/astrbot/core/star/context.py @@ -251,7 +251,7 @@ async def get_current_chat_provider_id(self, umo: str) -> str: Raises: ProviderNotFoundError: 未找到。 """ - prov = self.get_using_provider(umo) + prov = await self.get_using_provider(umo) if not prov: raise ProviderNotFoundError("Provider not found") return prov.meta().id @@ -335,7 +335,7 @@ def get_all_embedding_providers(self) -> list[EmbeddingProvider]: """获取所有用于 Embedding 任务的 Provider。""" return self.provider_manager.embedding_provider_insts - def get_using_provider(self, umo: str | None = None) -> Provider | None: + async def get_using_provider(self, umo: str | None = None) -> Provider | None: """获取当前使用的用于文本生成任务的 LLM Provider(Chat_Completion 类型)。 Args: @@ -348,7 +348,7 @@ def get_using_provider(self, umo: str | None = None) -> Provider | None: Raises: ValueError: 该会话来源配置的的对话模型(提供商)的类型不正确。 """ - prov = self.provider_manager.get_using_provider( + prov = await self.provider_manager.get_using_provider( provider_type=ProviderType.CHAT_COMPLETION, umo=umo, ) @@ -360,7 +360,7 @@ def get_using_provider(self, umo: str | None = None) -> Provider | None: ) return prov - def get_using_tts_provider(self, umo: str | None = None) -> TTSProvider | None: + async def get_using_tts_provider(self, umo: str | None = None) -> TTSProvider | None: """获取当前使用的用于 TTS 任务的 Provider。 Args: @@ -372,7 +372,7 @@ def get_using_tts_provider(self, umo: str | None = None) -> TTSProvider | None: Raises: ValueError: 返回的提供者不是 TTSProvider 类型。 """ - prov = self.provider_manager.get_using_provider( + prov = await self.provider_manager.get_using_provider( provider_type=ProviderType.TEXT_TO_SPEECH, umo=umo, ) @@ -380,7 +380,7 @@ def get_using_tts_provider(self, umo: str | None = None) -> TTSProvider | None: raise ValueError("返回的 Provider 不是 TTSProvider 类型") return prov - def get_using_stt_provider(self, umo: str | None = None) -> STTProvider | None: + async def get_using_stt_provider(self, umo: str | None = None) -> STTProvider | None: """获取当前使用的用于 STT 任务的 Provider。 Args: @@ -392,7 +392,7 @@ def get_using_stt_provider(self, umo: str | None = None) -> STTProvider | None: Raises: ValueError: 返回的提供者不是 STTProvider 类型。 """ - prov = self.provider_manager.get_using_provider( + prov = await self.provider_manager.get_using_provider( provider_type=ProviderType.SPEECH_TO_TEXT, umo=umo, ) diff --git a/changelogs/v4.14.8.md b/changelogs/v4.14.8.md new file mode 100644 index 000000000..595a75355 --- /dev/null +++ b/changelogs/v4.14.8.md @@ -0,0 +1,35 @@ +## What's Changed + +hotfix of 4.14.7 + +- 为 AstrBot Electron App 增加特殊的更新处理。 + +### 修复 +- 人格预设对话可能会重复添加到上下文 ([#4961](https://github.com/AstrBotDevs/AstrBot/issues/4961)) + +### 新增 +- 增加提供商级别的代理支持 ([#4949](https://github.com/AstrBotDevs/AstrBot/issues/4949)) +- WebUI 管理行为增加插件指令权限管理功能 ([#4887](https://github.com/AstrBotDevs/AstrBot/issues/4887)) +- 允许 LLM 预览工具返回的图片并自主决定是否发送 ([#4895](https://github.com/AstrBotDevs/AstrBot/issues/4895)) +- Telegram 平台添加媒体组(相册)支持 ([#4893](https://github.com/AstrBotDevs/AstrBot/issues/4893)) +- 增加欢迎功能,支持本地化内容和新手引导步骤 +- 支持 Electron 桌面应用部署 ([#4952](https://github.com/AstrBotDevs/AstrBot/issues/4952)) + +### 注意 +- 更新 AstrBot Python 版本要求至 3.12 ([#4963](https://github.com/AstrBotDevs/AstrBot/issues/4963)) + +## What's Changed + +### Fixes +- Fixed issue where persona preset conversations could be duplicated in context ([#4961](https://github.com/AstrBotDevs/AstrBot/issues/4961)) + +### Features +- Added provider-level proxy support ([#4949](https://github.com/AstrBotDevs/AstrBot/issues/4949)) +- Added plugin command permission management to WebUI management behavior ([#4887](https://github.com/AstrBotDevs/AstrBot/issues/4887)) +- Allowed LLMs to preview images returned by tools and autonomously decide whether to send them ([#4895](https://github.com/AstrBotDevs/AstrBot/issues/4895)) +- Added media group (album) support for Telegram platform ([#4893](https://github.com/AstrBotDevs/AstrBot/issues/4893)) +- Added welcome feature with support for localized content and onboarding steps +- Supported Electron desktop application deployment ([#4952](https://github.com/AstrBotDevs/AstrBot/issues/4952)) + +### Notice +- Updated AstrBot Python version requirement to 3.12 ([#4963](https://github.com/AstrBotDevs/AstrBot/issues/4963)) \ No newline at end of file diff --git a/desktop/package.json b/desktop/package.json index 74a6fda5a..3cda11c5a 100644 --- a/desktop/package.json +++ b/desktop/package.json @@ -1,6 +1,6 @@ { "name": "astrbot-desktop", - "version": "4.14.6", + "version": "4.14.7", "description": "AstrBot desktop wrapper", "private": true, "main": "main.js", diff --git a/pyproject.toml b/pyproject.toml index 8628167ad..9cc4a3767 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "AstrBot" -version = "4.14.7" +version = "4.14.8" description = "Easy-to-use multi-platform LLM chatbot and development framework" readme = "README.md" requires-python = ">=3.12"