AstrBot 4.5.0__py3-none-any.whl → 4.5.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- astrbot/api/__init__.py +10 -11
- astrbot/api/event/__init__.py +5 -6
- astrbot/api/event/filter/__init__.py +37 -36
- astrbot/api/platform/__init__.py +7 -8
- astrbot/api/provider/__init__.py +7 -7
- astrbot/api/star/__init__.py +3 -4
- astrbot/api/util/__init__.py +2 -2
- astrbot/cli/__main__.py +5 -5
- astrbot/cli/commands/__init__.py +3 -3
- astrbot/cli/commands/cmd_conf.py +19 -16
- astrbot/cli/commands/cmd_init.py +3 -2
- astrbot/cli/commands/cmd_plug.py +8 -10
- astrbot/cli/commands/cmd_run.py +5 -6
- astrbot/cli/utils/__init__.py +6 -6
- astrbot/cli/utils/basic.py +14 -14
- astrbot/cli/utils/plugin.py +24 -15
- astrbot/cli/utils/version_comparator.py +10 -12
- astrbot/core/__init__.py +8 -6
- astrbot/core/agent/agent.py +3 -2
- astrbot/core/agent/handoff.py +6 -2
- astrbot/core/agent/hooks.py +9 -6
- astrbot/core/agent/mcp_client.py +50 -15
- astrbot/core/agent/message.py +168 -0
- astrbot/core/agent/response.py +2 -1
- astrbot/core/agent/run_context.py +2 -3
- astrbot/core/agent/runners/base.py +10 -13
- astrbot/core/agent/runners/tool_loop_agent_runner.py +52 -51
- astrbot/core/agent/tool.py +60 -41
- astrbot/core/agent/tool_executor.py +9 -3
- astrbot/core/astr_agent_context.py +3 -1
- astrbot/core/astrbot_config_mgr.py +29 -9
- astrbot/core/config/__init__.py +2 -2
- astrbot/core/config/astrbot_config.py +28 -26
- astrbot/core/config/default.py +44 -6
- astrbot/core/conversation_mgr.py +105 -36
- astrbot/core/core_lifecycle.py +68 -54
- astrbot/core/db/__init__.py +33 -18
- astrbot/core/db/migration/helper.py +18 -13
- astrbot/core/db/migration/migra_3_to_4.py +53 -34
- astrbot/core/db/migration/migra_45_to_46.py +1 -1
- astrbot/core/db/migration/shared_preferences_v3.py +2 -1
- astrbot/core/db/migration/sqlite_v3.py +26 -23
- astrbot/core/db/po.py +27 -18
- astrbot/core/db/sqlite.py +74 -45
- astrbot/core/db/vec_db/base.py +10 -14
- astrbot/core/db/vec_db/faiss_impl/document_storage.py +90 -77
- astrbot/core/db/vec_db/faiss_impl/embedding_storage.py +9 -3
- astrbot/core/db/vec_db/faiss_impl/vec_db.py +36 -31
- astrbot/core/event_bus.py +8 -6
- astrbot/core/file_token_service.py +6 -5
- astrbot/core/initial_loader.py +7 -5
- astrbot/core/knowledge_base/chunking/__init__.py +1 -3
- astrbot/core/knowledge_base/chunking/base.py +1 -0
- astrbot/core/knowledge_base/chunking/fixed_size.py +2 -0
- astrbot/core/knowledge_base/chunking/recursive.py +16 -10
- astrbot/core/knowledge_base/kb_db_sqlite.py +50 -48
- astrbot/core/knowledge_base/kb_helper.py +30 -17
- astrbot/core/knowledge_base/kb_mgr.py +6 -7
- astrbot/core/knowledge_base/models.py +10 -4
- astrbot/core/knowledge_base/parsers/__init__.py +3 -5
- astrbot/core/knowledge_base/parsers/base.py +1 -0
- astrbot/core/knowledge_base/parsers/markitdown_parser.py +2 -1
- astrbot/core/knowledge_base/parsers/pdf_parser.py +2 -1
- astrbot/core/knowledge_base/parsers/text_parser.py +1 -0
- astrbot/core/knowledge_base/parsers/util.py +1 -1
- astrbot/core/knowledge_base/retrieval/__init__.py +6 -8
- astrbot/core/knowledge_base/retrieval/manager.py +17 -14
- astrbot/core/knowledge_base/retrieval/rank_fusion.py +7 -3
- astrbot/core/knowledge_base/retrieval/sparse_retriever.py +11 -5
- astrbot/core/log.py +21 -13
- astrbot/core/message/components.py +123 -217
- astrbot/core/message/message_event_result.py +24 -24
- astrbot/core/persona_mgr.py +20 -11
- astrbot/core/pipeline/__init__.py +7 -7
- astrbot/core/pipeline/content_safety_check/stage.py +13 -9
- astrbot/core/pipeline/content_safety_check/strategies/__init__.py +1 -2
- astrbot/core/pipeline/content_safety_check/strategies/baidu_aip.py +12 -13
- astrbot/core/pipeline/content_safety_check/strategies/keywords.py +1 -0
- astrbot/core/pipeline/content_safety_check/strategies/strategy.py +6 -6
- astrbot/core/pipeline/context.py +4 -1
- astrbot/core/pipeline/context_utils.py +77 -7
- astrbot/core/pipeline/preprocess_stage/stage.py +12 -9
- astrbot/core/pipeline/process_stage/method/llm_request.py +125 -72
- astrbot/core/pipeline/process_stage/method/star_request.py +19 -17
- astrbot/core/pipeline/process_stage/stage.py +13 -10
- astrbot/core/pipeline/process_stage/utils.py +6 -5
- astrbot/core/pipeline/rate_limit_check/stage.py +37 -36
- astrbot/core/pipeline/respond/stage.py +23 -20
- astrbot/core/pipeline/result_decorate/stage.py +31 -23
- astrbot/core/pipeline/scheduler.py +12 -8
- astrbot/core/pipeline/session_status_check/stage.py +12 -8
- astrbot/core/pipeline/stage.py +10 -4
- astrbot/core/pipeline/waking_check/stage.py +24 -18
- astrbot/core/pipeline/whitelist_check/stage.py +10 -7
- astrbot/core/platform/__init__.py +6 -6
- astrbot/core/platform/astr_message_event.py +76 -110
- astrbot/core/platform/astrbot_message.py +11 -13
- astrbot/core/platform/manager.py +16 -15
- astrbot/core/platform/message_session.py +5 -3
- astrbot/core/platform/platform.py +16 -24
- astrbot/core/platform/platform_metadata.py +4 -4
- astrbot/core/platform/register.py +8 -8
- astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py +23 -15
- astrbot/core/platform/sources/aiocqhttp/aiocqhttp_platform_adapter.py +51 -33
- astrbot/core/platform/sources/dingtalk/dingtalk_adapter.py +47 -29
- astrbot/core/platform/sources/dingtalk/dingtalk_event.py +7 -3
- astrbot/core/platform/sources/discord/client.py +9 -6
- astrbot/core/platform/sources/discord/components.py +18 -14
- astrbot/core/platform/sources/discord/discord_platform_adapter.py +45 -30
- astrbot/core/platform/sources/discord/discord_platform_event.py +38 -30
- astrbot/core/platform/sources/lark/lark_adapter.py +23 -17
- astrbot/core/platform/sources/lark/lark_event.py +21 -14
- astrbot/core/platform/sources/misskey/misskey_adapter.py +107 -67
- astrbot/core/platform/sources/misskey/misskey_api.py +153 -129
- astrbot/core/platform/sources/misskey/misskey_event.py +20 -15
- astrbot/core/platform/sources/misskey/misskey_utils.py +74 -62
- astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py +63 -44
- astrbot/core/platform/sources/qqofficial/qqofficial_platform_adapter.py +41 -26
- astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_adapter.py +36 -17
- astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_event.py +3 -1
- astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_server.py +12 -7
- astrbot/core/platform/sources/satori/satori_adapter.py +56 -38
- astrbot/core/platform/sources/satori/satori_event.py +34 -25
- astrbot/core/platform/sources/slack/client.py +11 -9
- astrbot/core/platform/sources/slack/slack_adapter.py +52 -36
- astrbot/core/platform/sources/slack/slack_event.py +34 -24
- astrbot/core/platform/sources/telegram/tg_adapter.py +38 -18
- astrbot/core/platform/sources/telegram/tg_event.py +32 -18
- astrbot/core/platform/sources/webchat/webchat_adapter.py +27 -17
- astrbot/core/platform/sources/webchat/webchat_event.py +14 -10
- astrbot/core/platform/sources/wechatpadpro/wechatpadpro_adapter.py +115 -120
- astrbot/core/platform/sources/wechatpadpro/wechatpadpro_message_event.py +9 -8
- astrbot/core/platform/sources/wechatpadpro/xml_data_parser.py +15 -16
- astrbot/core/platform/sources/wecom/wecom_adapter.py +35 -18
- astrbot/core/platform/sources/wecom/wecom_event.py +55 -48
- astrbot/core/platform/sources/wecom/wecom_kf.py +34 -44
- astrbot/core/platform/sources/wecom/wecom_kf_message.py +26 -10
- astrbot/core/platform/sources/wecom_ai_bot/WXBizJsonMsgCrypt.py +18 -10
- astrbot/core/platform/sources/wecom_ai_bot/__init__.py +3 -5
- astrbot/core/platform/sources/wecom_ai_bot/ierror.py +0 -1
- astrbot/core/platform/sources/wecom_ai_bot/wecomai_adapter.py +61 -37
- astrbot/core/platform/sources/wecom_ai_bot/wecomai_api.py +67 -28
- astrbot/core/platform/sources/wecom_ai_bot/wecomai_event.py +8 -9
- astrbot/core/platform/sources/wecom_ai_bot/wecomai_queue_mgr.py +18 -9
- astrbot/core/platform/sources/wecom_ai_bot/wecomai_server.py +14 -12
- astrbot/core/platform/sources/wecom_ai_bot/wecomai_utils.py +22 -12
- astrbot/core/platform/sources/weixin_official_account/weixin_offacc_adapter.py +40 -26
- astrbot/core/platform/sources/weixin_official_account/weixin_offacc_event.py +47 -45
- astrbot/core/platform_message_history_mgr.py +5 -3
- astrbot/core/provider/__init__.py +2 -3
- astrbot/core/provider/entites.py +8 -8
- astrbot/core/provider/entities.py +61 -75
- astrbot/core/provider/func_tool_manager.py +59 -55
- astrbot/core/provider/manager.py +40 -22
- astrbot/core/provider/provider.py +72 -46
- astrbot/core/provider/register.py +7 -7
- astrbot/core/provider/sources/anthropic_source.py +48 -30
- astrbot/core/provider/sources/azure_tts_source.py +17 -13
- astrbot/core/provider/sources/coze_api_client.py +27 -17
- astrbot/core/provider/sources/coze_source.py +104 -87
- astrbot/core/provider/sources/dashscope_source.py +18 -11
- astrbot/core/provider/sources/dashscope_tts.py +36 -23
- astrbot/core/provider/sources/dify_source.py +25 -20
- astrbot/core/provider/sources/edge_tts_source.py +21 -17
- astrbot/core/provider/sources/fishaudio_tts_api_source.py +22 -14
- astrbot/core/provider/sources/gemini_embedding_source.py +12 -13
- astrbot/core/provider/sources/gemini_source.py +72 -58
- astrbot/core/provider/sources/gemini_tts_source.py +8 -6
- astrbot/core/provider/sources/gsv_selfhosted_source.py +17 -14
- astrbot/core/provider/sources/gsvi_tts_source.py +11 -7
- astrbot/core/provider/sources/minimax_tts_api_source.py +50 -40
- astrbot/core/provider/sources/openai_embedding_source.py +6 -8
- astrbot/core/provider/sources/openai_source.py +102 -69
- astrbot/core/provider/sources/openai_tts_api_source.py +14 -6
- astrbot/core/provider/sources/sensevoice_selfhosted_source.py +13 -11
- astrbot/core/provider/sources/vllm_rerank_source.py +10 -4
- astrbot/core/provider/sources/volcengine_tts.py +38 -31
- astrbot/core/provider/sources/whisper_api_source.py +14 -12
- astrbot/core/provider/sources/whisper_selfhosted_source.py +15 -11
- astrbot/core/provider/sources/xinference_rerank_source.py +116 -0
- astrbot/core/provider/sources/xinference_stt_provider.py +197 -0
- astrbot/core/star/__init__.py +16 -11
- astrbot/core/star/config.py +10 -15
- astrbot/core/star/context.py +109 -84
- astrbot/core/star/filter/__init__.py +4 -3
- astrbot/core/star/filter/command.py +30 -28
- astrbot/core/star/filter/command_group.py +27 -24
- astrbot/core/star/filter/custom_filter.py +6 -5
- astrbot/core/star/filter/event_message_type.py +4 -2
- astrbot/core/star/filter/permission.py +4 -2
- astrbot/core/star/filter/platform_adapter_type.py +4 -2
- astrbot/core/star/filter/regex.py +4 -2
- astrbot/core/star/register/__init__.py +19 -19
- astrbot/core/star/register/star.py +6 -2
- astrbot/core/star/register/star_handler.py +96 -73
- astrbot/core/star/session_llm_manager.py +48 -14
- astrbot/core/star/session_plugin_manager.py +29 -15
- astrbot/core/star/star.py +1 -2
- astrbot/core/star/star_handler.py +13 -8
- astrbot/core/star/star_manager.py +151 -59
- astrbot/core/star/star_tools.py +44 -37
- astrbot/core/star/updator.py +10 -10
- astrbot/core/umop_config_router.py +10 -4
- astrbot/core/updator.py +13 -5
- astrbot/core/utils/astrbot_path.py +3 -5
- astrbot/core/utils/dify_api_client.py +33 -15
- astrbot/core/utils/io.py +66 -42
- astrbot/core/utils/log_pipe.py +1 -1
- astrbot/core/utils/metrics.py +7 -7
- astrbot/core/utils/path_util.py +15 -16
- astrbot/core/utils/pip_installer.py +5 -5
- astrbot/core/utils/session_waiter.py +19 -20
- astrbot/core/utils/shared_preferences.py +45 -20
- astrbot/core/utils/t2i/__init__.py +4 -1
- astrbot/core/utils/t2i/network_strategy.py +35 -26
- astrbot/core/utils/t2i/renderer.py +11 -5
- astrbot/core/utils/t2i/template_manager.py +14 -15
- astrbot/core/utils/tencent_record_helper.py +19 -13
- astrbot/core/utils/version_comparator.py +10 -13
- astrbot/core/zip_updator.py +43 -40
- astrbot/dashboard/routes/__init__.py +18 -18
- astrbot/dashboard/routes/auth.py +10 -8
- astrbot/dashboard/routes/chat.py +30 -21
- astrbot/dashboard/routes/config.py +92 -75
- astrbot/dashboard/routes/conversation.py +46 -39
- astrbot/dashboard/routes/file.py +4 -2
- astrbot/dashboard/routes/knowledge_base.py +47 -40
- astrbot/dashboard/routes/log.py +9 -4
- astrbot/dashboard/routes/persona.py +19 -16
- astrbot/dashboard/routes/plugin.py +69 -55
- astrbot/dashboard/routes/route.py +3 -1
- astrbot/dashboard/routes/session_management.py +130 -116
- astrbot/dashboard/routes/stat.py +34 -34
- astrbot/dashboard/routes/t2i.py +15 -12
- astrbot/dashboard/routes/tools.py +47 -52
- astrbot/dashboard/routes/update.py +32 -28
- astrbot/dashboard/server.py +30 -26
- astrbot/dashboard/utils.py +8 -4
- {astrbot-4.5.0.dist-info → astrbot-4.5.2.dist-info}/METADATA +4 -2
- astrbot-4.5.2.dist-info/RECORD +261 -0
- astrbot-4.5.0.dist-info/RECORD +0 -258
- {astrbot-4.5.0.dist-info → astrbot-4.5.2.dist-info}/WHEEL +0 -0
- {astrbot-4.5.0.dist-info → astrbot-4.5.2.dist-info}/entry_points.txt +0 -0
- {astrbot-4.5.0.dist-info → astrbot-4.5.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -37,7 +37,10 @@ else:
|
|
|
37
37
|
@register_platform_adapter("telegram", "telegram 适配器")
|
|
38
38
|
class TelegramPlatformAdapter(Platform):
|
|
39
39
|
def __init__(
|
|
40
|
-
self,
|
|
40
|
+
self,
|
|
41
|
+
platform_config: dict,
|
|
42
|
+
platform_settings: dict,
|
|
43
|
+
event_queue: asyncio.Queue,
|
|
41
44
|
) -> None:
|
|
42
45
|
super().__init__(event_queue)
|
|
43
46
|
self.config = platform_config
|
|
@@ -45,13 +48,15 @@ class TelegramPlatformAdapter(Platform):
|
|
|
45
48
|
self.client_self_id = uuid.uuid4().hex[:8]
|
|
46
49
|
|
|
47
50
|
base_url = self.config.get(
|
|
48
|
-
"telegram_api_base_url",
|
|
51
|
+
"telegram_api_base_url",
|
|
52
|
+
"https://api.telegram.org/bot",
|
|
49
53
|
)
|
|
50
54
|
if not base_url:
|
|
51
55
|
base_url = "https://api.telegram.org/bot"
|
|
52
56
|
|
|
53
57
|
file_base_url = self.config.get(
|
|
54
|
-
"telegram_file_base_url",
|
|
58
|
+
"telegram_file_base_url",
|
|
59
|
+
"https://api.telegram.org/file/bot",
|
|
55
60
|
)
|
|
56
61
|
if not file_base_url:
|
|
57
62
|
file_base_url = "https://api.telegram.org/file/bot"
|
|
@@ -59,10 +64,12 @@ class TelegramPlatformAdapter(Platform):
|
|
|
59
64
|
self.base_url = base_url
|
|
60
65
|
|
|
61
66
|
self.enable_command_register = self.config.get(
|
|
62
|
-
"telegram_command_register",
|
|
67
|
+
"telegram_command_register",
|
|
68
|
+
True,
|
|
63
69
|
)
|
|
64
70
|
self.enable_command_refresh = self.config.get(
|
|
65
|
-
"telegram_command_auto_refresh",
|
|
71
|
+
"telegram_command_auto_refresh",
|
|
72
|
+
True,
|
|
66
73
|
)
|
|
67
74
|
self.last_command_hash = None
|
|
68
75
|
|
|
@@ -85,11 +92,15 @@ class TelegramPlatformAdapter(Platform):
|
|
|
85
92
|
|
|
86
93
|
@override
|
|
87
94
|
async def send_by_session(
|
|
88
|
-
self,
|
|
95
|
+
self,
|
|
96
|
+
session: MessageSesion,
|
|
97
|
+
message_chain: MessageChain,
|
|
89
98
|
):
|
|
90
99
|
from_username = session.session_id
|
|
91
100
|
await TelegramPlatformEvent.send_with_client(
|
|
92
|
-
self.client,
|
|
101
|
+
self.client,
|
|
102
|
+
message_chain,
|
|
103
|
+
from_username,
|
|
93
104
|
)
|
|
94
105
|
await super().send_by_session(session, message_chain)
|
|
95
106
|
|
|
@@ -131,7 +142,7 @@ class TelegramPlatformAdapter(Platform):
|
|
|
131
142
|
|
|
132
143
|
if commands:
|
|
133
144
|
current_hash = hash(
|
|
134
|
-
tuple((cmd.command, cmd.description) for cmd in commands)
|
|
145
|
+
tuple((cmd.command, cmd.description) for cmd in commands),
|
|
135
146
|
)
|
|
136
147
|
if current_hash == self.last_command_hash:
|
|
137
148
|
return
|
|
@@ -153,7 +164,9 @@ class TelegramPlatformAdapter(Platform):
|
|
|
153
164
|
continue
|
|
154
165
|
for event_filter in handler_metadata.event_filters:
|
|
155
166
|
cmd_info = self._extract_command_info(
|
|
156
|
-
event_filter,
|
|
167
|
+
event_filter,
|
|
168
|
+
handler_metadata,
|
|
169
|
+
skip_commands,
|
|
157
170
|
)
|
|
158
171
|
if cmd_info:
|
|
159
172
|
cmd_name, description = cmd_info
|
|
@@ -164,7 +177,9 @@ class TelegramPlatformAdapter(Platform):
|
|
|
164
177
|
|
|
165
178
|
@staticmethod
|
|
166
179
|
def _extract_command_info(
|
|
167
|
-
event_filter,
|
|
180
|
+
event_filter,
|
|
181
|
+
handler_metadata,
|
|
182
|
+
skip_commands: set,
|
|
168
183
|
) -> tuple[str, str] | None:
|
|
169
184
|
"""从事件过滤器中提取指令信息"""
|
|
170
185
|
cmd_name = None
|
|
@@ -199,11 +214,12 @@ class TelegramPlatformAdapter(Platform):
|
|
|
199
214
|
async def start(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
|
|
200
215
|
if not update.effective_chat:
|
|
201
216
|
logger.warning(
|
|
202
|
-
"Received a start command without an effective chat, skipping /start reply."
|
|
217
|
+
"Received a start command without an effective chat, skipping /start reply.",
|
|
203
218
|
)
|
|
204
219
|
return
|
|
205
220
|
await context.bot.send_message(
|
|
206
|
-
chat_id=update.effective_chat.id,
|
|
221
|
+
chat_id=update.effective_chat.id,
|
|
222
|
+
text=self.config["start_message"],
|
|
207
223
|
)
|
|
208
224
|
|
|
209
225
|
async def message_handler(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
|
|
@@ -213,7 +229,10 @@ class TelegramPlatformAdapter(Platform):
|
|
|
213
229
|
await self.handle_msg(abm)
|
|
214
230
|
|
|
215
231
|
async def convert_message(
|
|
216
|
-
self,
|
|
232
|
+
self,
|
|
233
|
+
update: Update,
|
|
234
|
+
context: ContextTypes.DEFAULT_TYPE,
|
|
235
|
+
get_reply=True,
|
|
217
236
|
) -> AstrBotMessage | None:
|
|
218
237
|
"""转换 Telegram 的消息对象为 AstrBotMessage 对象。
|
|
219
238
|
|
|
@@ -244,7 +263,8 @@ class TelegramPlatformAdapter(Platform):
|
|
|
244
263
|
logger.warning("[Telegram] Received a message without a from_user.")
|
|
245
264
|
return None
|
|
246
265
|
message.sender = MessageMember(
|
|
247
|
-
str(_from_user.id),
|
|
266
|
+
str(_from_user.id),
|
|
267
|
+
_from_user.username or "Unknown",
|
|
248
268
|
)
|
|
249
269
|
message.self_id = str(context.bot.username)
|
|
250
270
|
message.raw_message = update
|
|
@@ -274,7 +294,7 @@ class TelegramPlatformAdapter(Platform):
|
|
|
274
294
|
message_str=reply_abm.message_str,
|
|
275
295
|
text=reply_abm.message_str,
|
|
276
296
|
qq=reply_abm.sender.user_id,
|
|
277
|
-
)
|
|
297
|
+
),
|
|
278
298
|
)
|
|
279
299
|
|
|
280
300
|
if update.message.text:
|
|
@@ -320,7 +340,7 @@ class TelegramPlatformAdapter(Platform):
|
|
|
320
340
|
|
|
321
341
|
if message.message_str.strip() == "/start":
|
|
322
342
|
await self.start(update, context)
|
|
323
|
-
return
|
|
343
|
+
return None
|
|
324
344
|
|
|
325
345
|
elif update.message.voice:
|
|
326
346
|
file = await update.message.voice.get_file()
|
|
@@ -358,7 +378,7 @@ class TelegramPlatformAdapter(Platform):
|
|
|
358
378
|
file_path = file.file_path
|
|
359
379
|
if file_path is None:
|
|
360
380
|
logger.warning(
|
|
361
|
-
f"Telegram document file_path is None, cannot save the file {file_name}."
|
|
381
|
+
f"Telegram document file_path is None, cannot save the file {file_name}.",
|
|
362
382
|
)
|
|
363
383
|
else:
|
|
364
384
|
message.message.append(Comp.File(file=file_path, name=file_name))
|
|
@@ -369,7 +389,7 @@ class TelegramPlatformAdapter(Platform):
|
|
|
369
389
|
file_path = file.file_path
|
|
370
390
|
if file_path is None:
|
|
371
391
|
logger.warning(
|
|
372
|
-
f"Telegram video file_path is None, cannot save the file {file_name}."
|
|
392
|
+
f"Telegram video file_path is None, cannot save the file {file_name}.",
|
|
373
393
|
)
|
|
374
394
|
else:
|
|
375
395
|
message.message.append(Comp.Video(file=file_path, path=file.file_path))
|
|
@@ -1,22 +1,24 @@
|
|
|
1
|
+
import asyncio
|
|
1
2
|
import os
|
|
2
3
|
import re
|
|
3
|
-
|
|
4
|
+
|
|
4
5
|
import telegramify_markdown
|
|
6
|
+
from telegram import ReactionTypeCustomEmoji, ReactionTypeEmoji
|
|
7
|
+
from telegram.ext import ExtBot
|
|
8
|
+
|
|
9
|
+
from astrbot import logger
|
|
5
10
|
from astrbot.api.event import AstrMessageEvent, MessageChain
|
|
6
|
-
from astrbot.api.platform import AstrBotMessage, PlatformMetadata, MessageType
|
|
7
11
|
from astrbot.api.message_components import (
|
|
8
|
-
Plain,
|
|
9
|
-
Image,
|
|
10
|
-
Reply,
|
|
11
12
|
At,
|
|
12
13
|
File,
|
|
14
|
+
Image,
|
|
15
|
+
Plain,
|
|
13
16
|
Record,
|
|
17
|
+
Reply,
|
|
14
18
|
)
|
|
15
|
-
from
|
|
16
|
-
from astrbot.core.utils.io import download_file
|
|
17
|
-
from astrbot import logger
|
|
19
|
+
from astrbot.api.platform import AstrBotMessage, MessageType, PlatformMetadata
|
|
18
20
|
from astrbot.core.utils.astrbot_path import get_astrbot_data_path
|
|
19
|
-
from
|
|
21
|
+
from astrbot.core.utils.io import download_file
|
|
20
22
|
|
|
21
23
|
|
|
22
24
|
class TelegramPlatformEvent(AstrMessageEvent):
|
|
@@ -68,7 +70,10 @@ class TelegramPlatformEvent(AstrMessageEvent):
|
|
|
68
70
|
|
|
69
71
|
@classmethod
|
|
70
72
|
async def send_with_client(
|
|
71
|
-
cls,
|
|
73
|
+
cls,
|
|
74
|
+
client: ExtBot,
|
|
75
|
+
message: MessageChain,
|
|
76
|
+
user_name: str,
|
|
72
77
|
):
|
|
73
78
|
image_path = None
|
|
74
79
|
|
|
@@ -104,14 +109,18 @@ class TelegramPlatformEvent(AstrMessageEvent):
|
|
|
104
109
|
for chunk in chunks:
|
|
105
110
|
try:
|
|
106
111
|
md_text = telegramify_markdown.markdownify(
|
|
107
|
-
chunk,
|
|
112
|
+
chunk,
|
|
113
|
+
max_line_length=None,
|
|
114
|
+
normalize_whitespace=False,
|
|
108
115
|
)
|
|
109
116
|
await client.send_message(
|
|
110
|
-
text=md_text,
|
|
117
|
+
text=md_text,
|
|
118
|
+
parse_mode="MarkdownV2",
|
|
119
|
+
**payload,
|
|
111
120
|
)
|
|
112
121
|
except Exception as e:
|
|
113
122
|
logger.warning(
|
|
114
|
-
f"MarkdownV2 send failed: {e}. Using plain text instead."
|
|
123
|
+
f"MarkdownV2 send failed: {e}. Using plain text instead.",
|
|
115
124
|
)
|
|
116
125
|
await client.send_message(text=chunk, **payload)
|
|
117
126
|
elif isinstance(i, Image):
|
|
@@ -137,8 +146,7 @@ class TelegramPlatformEvent(AstrMessageEvent):
|
|
|
137
146
|
await super().send(message)
|
|
138
147
|
|
|
139
148
|
async def react(self, emoji: str | None, big: bool = False):
|
|
140
|
-
"""
|
|
141
|
-
给原消息添加 Telegram 反应:
|
|
149
|
+
"""给原消息添加 Telegram 反应:
|
|
142
150
|
- 普通 emoji:传入 '👍'、'😂' 等
|
|
143
151
|
- 自定义表情:传入其 custom_emoji_id(纯数字字符串)
|
|
144
152
|
- 取消本机器人的反应:传入 None 或空字符串
|
|
@@ -216,7 +224,9 @@ class TelegramPlatformEvent(AstrMessageEvent):
|
|
|
216
224
|
i.file = path
|
|
217
225
|
|
|
218
226
|
await self.client.send_document(
|
|
219
|
-
document=i.file,
|
|
227
|
+
document=i.file,
|
|
228
|
+
filename=i.name,
|
|
229
|
+
**payload,
|
|
220
230
|
)
|
|
221
231
|
continue
|
|
222
232
|
elif isinstance(i, Record):
|
|
@@ -263,7 +273,9 @@ class TelegramPlatformEvent(AstrMessageEvent):
|
|
|
263
273
|
if delta and current_content != delta:
|
|
264
274
|
try:
|
|
265
275
|
markdown_text = telegramify_markdown.markdownify(
|
|
266
|
-
delta,
|
|
276
|
+
delta,
|
|
277
|
+
max_line_length=None,
|
|
278
|
+
normalize_whitespace=False,
|
|
267
279
|
)
|
|
268
280
|
await self.client.edit_message_text(
|
|
269
281
|
text=markdown_text,
|
|
@@ -274,7 +286,9 @@ class TelegramPlatformEvent(AstrMessageEvent):
|
|
|
274
286
|
except Exception as e:
|
|
275
287
|
logger.warning(f"Markdown转换失败,使用普通文本: {e!s}")
|
|
276
288
|
await self.client.edit_message_text(
|
|
277
|
-
text=delta,
|
|
289
|
+
text=delta,
|
|
290
|
+
chat_id=payload["chat_id"],
|
|
291
|
+
message_id=message_id,
|
|
278
292
|
)
|
|
279
293
|
except Exception as e:
|
|
280
294
|
logger.warning(f"编辑消息失败(streaming): {e!s}")
|
|
@@ -1,24 +1,27 @@
|
|
|
1
|
-
import time
|
|
2
1
|
import asyncio
|
|
3
|
-
import uuid
|
|
4
2
|
import os
|
|
5
|
-
|
|
3
|
+
import time
|
|
4
|
+
import uuid
|
|
5
|
+
from collections.abc import Awaitable, Callable
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
from astrbot import logger
|
|
9
|
+
from astrbot.core.message.components import Image, Plain, Record
|
|
10
|
+
from astrbot.core.message.message_event_result import MessageChain
|
|
6
11
|
from astrbot.core.platform import (
|
|
7
|
-
Platform,
|
|
8
12
|
AstrBotMessage,
|
|
9
13
|
MessageMember,
|
|
10
14
|
MessageType,
|
|
15
|
+
Platform,
|
|
11
16
|
PlatformMetadata,
|
|
12
17
|
)
|
|
13
|
-
from astrbot.core.message.message_event_result import MessageChain
|
|
14
|
-
from astrbot.core.message.components import Plain, Image, Record # noqa: F403
|
|
15
|
-
from astrbot import logger
|
|
16
|
-
from .webchat_queue_mgr import webchat_queue_mgr, WebChatQueueMgr
|
|
17
|
-
from .webchat_event import WebChatMessageEvent
|
|
18
18
|
from astrbot.core.platform.astr_message_event import MessageSesion
|
|
19
|
-
from ...register import register_platform_adapter
|
|
20
19
|
from astrbot.core.utils.astrbot_path import get_astrbot_data_path
|
|
21
20
|
|
|
21
|
+
from ...register import register_platform_adapter
|
|
22
|
+
from .webchat_event import WebChatMessageEvent
|
|
23
|
+
from .webchat_queue_mgr import WebChatQueueMgr, webchat_queue_mgr
|
|
24
|
+
|
|
22
25
|
|
|
23
26
|
class QueueListener:
|
|
24
27
|
def __init__(self, webchat_queue_mgr: WebChatQueueMgr, callback: Callable) -> None:
|
|
@@ -35,7 +38,7 @@ class QueueListener:
|
|
|
35
38
|
await self.callback(data)
|
|
36
39
|
except Exception as e:
|
|
37
40
|
logger.error(
|
|
38
|
-
f"Error processing message from conversation {conversation_id}: {e}"
|
|
41
|
+
f"Error processing message from conversation {conversation_id}: {e}",
|
|
39
42
|
)
|
|
40
43
|
break
|
|
41
44
|
|
|
@@ -66,7 +69,10 @@ class QueueListener:
|
|
|
66
69
|
@register_platform_adapter("webchat", "webchat")
|
|
67
70
|
class WebChatAdapter(Platform):
|
|
68
71
|
def __init__(
|
|
69
|
-
self,
|
|
72
|
+
self,
|
|
73
|
+
platform_config: dict,
|
|
74
|
+
platform_settings: dict,
|
|
75
|
+
event_queue: asyncio.Queue,
|
|
70
76
|
) -> None:
|
|
71
77
|
super().__init__(event_queue)
|
|
72
78
|
|
|
@@ -77,11 +83,15 @@ class WebChatAdapter(Platform):
|
|
|
77
83
|
os.makedirs(self.imgs_dir, exist_ok=True)
|
|
78
84
|
|
|
79
85
|
self.metadata = PlatformMetadata(
|
|
80
|
-
name="webchat",
|
|
86
|
+
name="webchat",
|
|
87
|
+
description="webchat",
|
|
88
|
+
id="webchat",
|
|
81
89
|
)
|
|
82
90
|
|
|
83
91
|
async def send_by_session(
|
|
84
|
-
self,
|
|
92
|
+
self,
|
|
93
|
+
session: MessageSesion,
|
|
94
|
+
message_chain: MessageChain,
|
|
85
95
|
):
|
|
86
96
|
await WebChatMessageEvent._send(message_chain, session.session_id)
|
|
87
97
|
await super().send_by_session(session, message_chain)
|
|
@@ -106,13 +116,13 @@ class WebChatAdapter(Platform):
|
|
|
106
116
|
if isinstance(payload["image_url"], list):
|
|
107
117
|
for img in payload["image_url"]:
|
|
108
118
|
abm.message.append(
|
|
109
|
-
Image.fromFileSystem(os.path.join(self.imgs_dir, img))
|
|
119
|
+
Image.fromFileSystem(os.path.join(self.imgs_dir, img)),
|
|
110
120
|
)
|
|
111
121
|
else:
|
|
112
122
|
abm.message.append(
|
|
113
123
|
Image.fromFileSystem(
|
|
114
|
-
os.path.join(self.imgs_dir, payload["image_url"])
|
|
115
|
-
)
|
|
124
|
+
os.path.join(self.imgs_dir, payload["image_url"]),
|
|
125
|
+
),
|
|
116
126
|
)
|
|
117
127
|
if payload["audio_url"]:
|
|
118
128
|
if isinstance(payload["audio_url"], list):
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
import base64
|
|
1
2
|
import os
|
|
2
3
|
import uuid
|
|
3
|
-
|
|
4
|
+
|
|
4
5
|
from astrbot.api import logger
|
|
5
6
|
from astrbot.api.event import AstrMessageEvent, MessageChain
|
|
6
|
-
from astrbot.api.message_components import
|
|
7
|
-
from astrbot.core.utils.io import download_image_by_url
|
|
7
|
+
from astrbot.api.message_components import Image, Plain, Record
|
|
8
8
|
from astrbot.core.utils.astrbot_path import get_astrbot_data_path
|
|
9
|
+
from astrbot.core.utils.io import download_image_by_url
|
|
10
|
+
|
|
9
11
|
from .webchat_queue_mgr import webchat_queue_mgr
|
|
10
12
|
|
|
11
13
|
imgs_dir = os.path.join(get_astrbot_data_path(), "webchat", "imgs")
|
|
@@ -26,7 +28,7 @@ class WebChatMessageEvent(AstrMessageEvent):
|
|
|
26
28
|
"type": "end",
|
|
27
29
|
"data": "",
|
|
28
30
|
"streaming": False,
|
|
29
|
-
} # end means this request is finished
|
|
31
|
+
}, # end means this request is finished
|
|
30
32
|
)
|
|
31
33
|
return ""
|
|
32
34
|
|
|
@@ -41,7 +43,7 @@ class WebChatMessageEvent(AstrMessageEvent):
|
|
|
41
43
|
"data": data,
|
|
42
44
|
"streaming": streaming,
|
|
43
45
|
"chain_type": message.type,
|
|
44
|
-
}
|
|
46
|
+
},
|
|
45
47
|
)
|
|
46
48
|
elif isinstance(comp, Image):
|
|
47
49
|
# save image to local
|
|
@@ -70,7 +72,7 @@ class WebChatMessageEvent(AstrMessageEvent):
|
|
|
70
72
|
"cid": cid,
|
|
71
73
|
"data": data,
|
|
72
74
|
"streaming": streaming,
|
|
73
|
-
}
|
|
75
|
+
},
|
|
74
76
|
)
|
|
75
77
|
elif isinstance(comp, Record):
|
|
76
78
|
# save record to local
|
|
@@ -94,7 +96,7 @@ class WebChatMessageEvent(AstrMessageEvent):
|
|
|
94
96
|
"cid": cid,
|
|
95
97
|
"data": data,
|
|
96
98
|
"streaming": streaming,
|
|
97
|
-
}
|
|
99
|
+
},
|
|
98
100
|
)
|
|
99
101
|
else:
|
|
100
102
|
logger.debug(f"webchat 忽略: {comp.type}")
|
|
@@ -118,12 +120,14 @@ class WebChatMessageEvent(AstrMessageEvent):
|
|
|
118
120
|
"data": final_data,
|
|
119
121
|
"streaming": True,
|
|
120
122
|
"cid": cid,
|
|
121
|
-
}
|
|
123
|
+
},
|
|
122
124
|
)
|
|
123
125
|
final_data = ""
|
|
124
126
|
continue
|
|
125
127
|
final_data += await WebChatMessageEvent._send(
|
|
126
|
-
chain,
|
|
128
|
+
chain,
|
|
129
|
+
session_id=self.session_id,
|
|
130
|
+
streaming=True,
|
|
127
131
|
)
|
|
128
132
|
|
|
129
133
|
await web_chat_back_queue.put(
|
|
@@ -132,6 +136,6 @@ class WebChatMessageEvent(AstrMessageEvent):
|
|
|
132
136
|
"data": final_data,
|
|
133
137
|
"streaming": True,
|
|
134
138
|
"cid": cid,
|
|
135
|
-
}
|
|
139
|
+
},
|
|
136
140
|
)
|
|
137
141
|
await super().send_streaming(generator, use_fallback)
|