AstrBot 4.10.2__py3-none-any.whl → 4.10.4__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/builtin_stars/astrbot/long_term_memory.py +186 -0
- astrbot/builtin_stars/astrbot/main.py +120 -0
- astrbot/builtin_stars/astrbot/metadata.yaml +4 -0
- astrbot/builtin_stars/astrbot/process_llm_request.py +245 -0
- astrbot/builtin_stars/builtin_commands/commands/__init__.py +31 -0
- astrbot/builtin_stars/builtin_commands/commands/admin.py +77 -0
- astrbot/builtin_stars/builtin_commands/commands/alter_cmd.py +173 -0
- astrbot/builtin_stars/builtin_commands/commands/conversation.py +366 -0
- astrbot/builtin_stars/builtin_commands/commands/help.py +88 -0
- astrbot/builtin_stars/builtin_commands/commands/llm.py +20 -0
- astrbot/builtin_stars/builtin_commands/commands/persona.py +142 -0
- astrbot/builtin_stars/builtin_commands/commands/plugin.py +120 -0
- astrbot/builtin_stars/builtin_commands/commands/provider.py +329 -0
- astrbot/builtin_stars/builtin_commands/commands/setunset.py +36 -0
- astrbot/builtin_stars/builtin_commands/commands/sid.py +36 -0
- astrbot/builtin_stars/builtin_commands/commands/t2i.py +23 -0
- astrbot/builtin_stars/builtin_commands/commands/tool.py +31 -0
- astrbot/builtin_stars/builtin_commands/commands/tts.py +36 -0
- astrbot/builtin_stars/builtin_commands/commands/utils/rst_scene.py +26 -0
- astrbot/builtin_stars/builtin_commands/main.py +237 -0
- astrbot/builtin_stars/builtin_commands/metadata.yaml +4 -0
- astrbot/builtin_stars/python_interpreter/main.py +536 -0
- astrbot/builtin_stars/python_interpreter/metadata.yaml +4 -0
- astrbot/builtin_stars/python_interpreter/requirements.txt +1 -0
- astrbot/builtin_stars/python_interpreter/shared/api.py +22 -0
- astrbot/builtin_stars/reminder/main.py +266 -0
- astrbot/builtin_stars/reminder/metadata.yaml +4 -0
- astrbot/builtin_stars/session_controller/main.py +114 -0
- astrbot/builtin_stars/session_controller/metadata.yaml +5 -0
- astrbot/builtin_stars/web_searcher/engines/__init__.py +111 -0
- astrbot/builtin_stars/web_searcher/engines/bing.py +30 -0
- astrbot/builtin_stars/web_searcher/engines/sogo.py +52 -0
- astrbot/builtin_stars/web_searcher/main.py +436 -0
- astrbot/builtin_stars/web_searcher/metadata.yaml +4 -0
- astrbot/cli/__init__.py +1 -1
- astrbot/core/agent/message.py +32 -1
- astrbot/core/agent/runners/tool_loop_agent_runner.py +26 -8
- astrbot/core/astr_agent_hooks.py +6 -0
- astrbot/core/backup/__init__.py +26 -0
- astrbot/core/backup/constants.py +77 -0
- astrbot/core/backup/exporter.py +477 -0
- astrbot/core/backup/importer.py +761 -0
- astrbot/core/config/astrbot_config.py +2 -0
- astrbot/core/config/default.py +47 -6
- astrbot/core/knowledge_base/chunking/recursive.py +10 -2
- astrbot/core/log.py +1 -1
- astrbot/core/pipeline/process_stage/method/agent_sub_stages/internal.py +184 -174
- astrbot/core/pipeline/result_decorate/stage.py +65 -57
- astrbot/core/pipeline/waking_check/stage.py +31 -3
- astrbot/core/platform/sources/aiocqhttp/aiocqhttp_platform_adapter.py +15 -29
- astrbot/core/platform/sources/dingtalk/dingtalk_adapter.py +1 -6
- astrbot/core/platform/sources/dingtalk/dingtalk_event.py +15 -1
- astrbot/core/platform/sources/lark/lark_adapter.py +2 -10
- astrbot/core/platform/sources/misskey/misskey_adapter.py +0 -5
- astrbot/core/platform/sources/misskey/misskey_utils.py +0 -3
- astrbot/core/platform/sources/qqofficial/qqofficial_platform_adapter.py +4 -9
- astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_adapter.py +4 -9
- astrbot/core/platform/sources/satori/satori_adapter.py +6 -1
- astrbot/core/platform/sources/slack/slack_adapter.py +3 -6
- astrbot/core/platform/sources/webchat/webchat_adapter.py +0 -1
- astrbot/core/platform/sources/wechatpadpro/wechatpadpro_adapter.py +3 -5
- astrbot/core/provider/entities.py +41 -10
- astrbot/core/provider/provider.py +3 -1
- astrbot/core/provider/sources/anthropic_source.py +140 -30
- astrbot/core/provider/sources/fishaudio_tts_api_source.py +14 -6
- astrbot/core/provider/sources/gemini_source.py +112 -29
- astrbot/core/provider/sources/minimax_tts_api_source.py +4 -1
- astrbot/core/provider/sources/openai_source.py +93 -56
- astrbot/core/provider/sources/xai_source.py +29 -0
- astrbot/core/provider/sources/xinference_stt_provider.py +24 -12
- astrbot/core/star/context.py +1 -1
- astrbot/core/star/star_manager.py +52 -13
- astrbot/core/utils/astrbot_path.py +34 -0
- astrbot/core/utils/pip_installer.py +20 -1
- astrbot/dashboard/routes/__init__.py +2 -0
- astrbot/dashboard/routes/backup.py +1093 -0
- astrbot/dashboard/routes/config.py +45 -0
- astrbot/dashboard/routes/log.py +44 -10
- astrbot/dashboard/server.py +9 -1
- {astrbot-4.10.2.dist-info → astrbot-4.10.4.dist-info}/METADATA +1 -1
- {astrbot-4.10.2.dist-info → astrbot-4.10.4.dist-info}/RECORD +84 -44
- {astrbot-4.10.2.dist-info → astrbot-4.10.4.dist-info}/WHEEL +0 -0
- {astrbot-4.10.2.dist-info → astrbot-4.10.4.dist-info}/entry_points.txt +0 -0
- {astrbot-4.10.2.dist-info → astrbot-4.10.4.dist-info}/licenses/LICENSE +0 -0
|
@@ -98,6 +98,9 @@ class ResultDecorateStage(Stage):
|
|
|
98
98
|
self.content_safe_check_stage = stage_cls()
|
|
99
99
|
await self.content_safe_check_stage.initialize(ctx)
|
|
100
100
|
|
|
101
|
+
provider_cfg = ctx.astrbot_config.get("provider_settings", {})
|
|
102
|
+
self.show_reasoning = provider_cfg.get("display_reasoning_text", False)
|
|
103
|
+
|
|
101
104
|
def _split_text_by_words(self, text: str) -> list[str]:
|
|
102
105
|
"""使用分段词列表分段文本"""
|
|
103
106
|
if not self.split_words_pattern:
|
|
@@ -254,70 +257,75 @@ class ResultDecorateStage(Stage):
|
|
|
254
257
|
event.unified_msg_origin,
|
|
255
258
|
)
|
|
256
259
|
|
|
257
|
-
|
|
258
|
-
self.ctx.astrbot_config["provider_tts_settings"]["enable"]
|
|
260
|
+
should_tts = (
|
|
261
|
+
bool(self.ctx.astrbot_config["provider_tts_settings"]["enable"])
|
|
259
262
|
and result.is_llm_result()
|
|
260
263
|
and SessionServiceManager.should_process_tts_request(event)
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
264
|
+
and random.random() <= self.tts_trigger_probability
|
|
265
|
+
and tts_provider
|
|
266
|
+
)
|
|
267
|
+
if should_tts and not tts_provider:
|
|
268
|
+
logger.warning(
|
|
269
|
+
f"会话 {event.unified_msg_origin} 未配置文本转语音模型。",
|
|
265
270
|
)
|
|
266
271
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
use_file_service = self.ctx.astrbot_config[
|
|
289
|
-
"provider_tts_settings"
|
|
290
|
-
]["use_file_service"]
|
|
291
|
-
callback_api_base = self.ctx.astrbot_config[
|
|
292
|
-
"callback_api_base"
|
|
293
|
-
]
|
|
294
|
-
dual_output = self.ctx.astrbot_config[
|
|
295
|
-
"provider_tts_settings"
|
|
296
|
-
]["dual_output"]
|
|
297
|
-
|
|
298
|
-
url = None
|
|
299
|
-
if use_file_service and callback_api_base:
|
|
300
|
-
token = await file_token_service.register_file(
|
|
301
|
-
audio_path,
|
|
302
|
-
)
|
|
303
|
-
url = f"{callback_api_base}/api/file/{token}"
|
|
304
|
-
logger.debug(f"已注册:{url}")
|
|
305
|
-
|
|
306
|
-
new_chain.append(
|
|
307
|
-
Record(
|
|
308
|
-
file=url or audio_path,
|
|
309
|
-
url=url or audio_path,
|
|
310
|
-
),
|
|
272
|
+
if (
|
|
273
|
+
not should_tts
|
|
274
|
+
and self.show_reasoning
|
|
275
|
+
and event.get_extra("_llm_reasoning_content")
|
|
276
|
+
):
|
|
277
|
+
# inject reasoning content to chain
|
|
278
|
+
reasoning_content = event.get_extra("_llm_reasoning_content")
|
|
279
|
+
result.chain.insert(0, Plain(f"🤔 思考: {reasoning_content}\n"))
|
|
280
|
+
|
|
281
|
+
if should_tts and tts_provider:
|
|
282
|
+
new_chain = []
|
|
283
|
+
for comp in result.chain:
|
|
284
|
+
if isinstance(comp, Plain) and len(comp.text) > 1:
|
|
285
|
+
try:
|
|
286
|
+
logger.info(f"TTS 请求: {comp.text}")
|
|
287
|
+
audio_path = await tts_provider.get_audio(comp.text)
|
|
288
|
+
logger.info(f"TTS 结果: {audio_path}")
|
|
289
|
+
if not audio_path:
|
|
290
|
+
logger.error(
|
|
291
|
+
f"由于 TTS 音频文件未找到,消息段转语音失败: {comp.text}",
|
|
311
292
|
)
|
|
312
|
-
if dual_output:
|
|
313
|
-
new_chain.append(comp)
|
|
314
|
-
except Exception:
|
|
315
|
-
logger.error(traceback.format_exc())
|
|
316
|
-
logger.error("TTS 失败,使用文本发送。")
|
|
317
293
|
new_chain.append(comp)
|
|
318
|
-
|
|
294
|
+
continue
|
|
295
|
+
|
|
296
|
+
use_file_service = self.ctx.astrbot_config[
|
|
297
|
+
"provider_tts_settings"
|
|
298
|
+
]["use_file_service"]
|
|
299
|
+
callback_api_base = self.ctx.astrbot_config[
|
|
300
|
+
"callback_api_base"
|
|
301
|
+
]
|
|
302
|
+
dual_output = self.ctx.astrbot_config[
|
|
303
|
+
"provider_tts_settings"
|
|
304
|
+
]["dual_output"]
|
|
305
|
+
|
|
306
|
+
url = None
|
|
307
|
+
if use_file_service and callback_api_base:
|
|
308
|
+
token = await file_token_service.register_file(
|
|
309
|
+
audio_path,
|
|
310
|
+
)
|
|
311
|
+
url = f"{callback_api_base}/api/file/{token}"
|
|
312
|
+
logger.debug(f"已注册:{url}")
|
|
313
|
+
|
|
314
|
+
new_chain.append(
|
|
315
|
+
Record(
|
|
316
|
+
file=url or audio_path,
|
|
317
|
+
url=url or audio_path,
|
|
318
|
+
),
|
|
319
|
+
)
|
|
320
|
+
if dual_output:
|
|
321
|
+
new_chain.append(comp)
|
|
322
|
+
except Exception:
|
|
323
|
+
logger.error(traceback.format_exc())
|
|
324
|
+
logger.error("TTS 失败,使用文本发送。")
|
|
319
325
|
new_chain.append(comp)
|
|
320
|
-
|
|
326
|
+
else:
|
|
327
|
+
new_chain.append(comp)
|
|
328
|
+
result.chain = new_chain
|
|
321
329
|
|
|
322
330
|
# 文本转图片
|
|
323
331
|
elif (
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
from collections.abc import AsyncGenerator
|
|
1
|
+
from collections.abc import AsyncGenerator, Callable
|
|
2
2
|
|
|
3
3
|
from astrbot import logger
|
|
4
4
|
from astrbot.core.message.components import At, AtAll, Reply
|
|
5
5
|
from astrbot.core.message.message_event_result import MessageChain, MessageEventResult
|
|
6
6
|
from astrbot.core.platform.astr_message_event import AstrMessageEvent
|
|
7
|
+
from astrbot.core.platform.message_type import MessageType
|
|
7
8
|
from astrbot.core.star.filter.command_group import CommandGroupFilter
|
|
8
9
|
from astrbot.core.star.filter.permission import PermissionTypeFilter
|
|
9
10
|
from astrbot.core.star.session_plugin_manager import SessionPluginManager
|
|
@@ -13,6 +14,23 @@ from astrbot.core.star.star_handler import EventType, star_handlers_registry
|
|
|
13
14
|
from ..context import PipelineContext
|
|
14
15
|
from ..stage import Stage, register_stage
|
|
15
16
|
|
|
17
|
+
UNIQUE_SESSION_ID_BUILDERS: dict[str, Callable[[AstrMessageEvent], str | None]] = {
|
|
18
|
+
"aiocqhttp": lambda e: f"{e.get_sender_id()}_{e.get_group_id()}",
|
|
19
|
+
"slack": lambda e: f"{e.get_sender_id()}_{e.get_group_id()}",
|
|
20
|
+
"dingtalk": lambda e: e.get_sender_id(),
|
|
21
|
+
"qq_official": lambda e: e.get_sender_id(),
|
|
22
|
+
"qq_official_webhook": lambda e: e.get_sender_id(),
|
|
23
|
+
"lark": lambda e: f"{e.get_sender_id()}%{e.get_group_id()}",
|
|
24
|
+
"misskey": lambda e: f"{e.get_session_id()}_{e.get_sender_id()}",
|
|
25
|
+
"wechatpadpro": lambda e: f"{e.get_group_id()}#{e.get_sender_id()}",
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def build_unique_session_id(event: AstrMessageEvent) -> str | None:
|
|
30
|
+
platform = event.get_platform_name()
|
|
31
|
+
builder = UNIQUE_SESSION_ID_BUILDERS.get(platform)
|
|
32
|
+
return builder(event) if builder else None
|
|
33
|
+
|
|
16
34
|
|
|
17
35
|
@register_stage
|
|
18
36
|
class WakingCheckStage(Stage):
|
|
@@ -53,18 +71,27 @@ class WakingCheckStage(Stage):
|
|
|
53
71
|
self.disable_builtin_commands = self.ctx.astrbot_config.get(
|
|
54
72
|
"disable_builtin_commands", False
|
|
55
73
|
)
|
|
74
|
+
platform_settings = self.ctx.astrbot_config.get("platform_settings", {})
|
|
75
|
+
self.unique_session = platform_settings.get("unique_session", False)
|
|
56
76
|
|
|
57
77
|
async def process(
|
|
58
78
|
self,
|
|
59
79
|
event: AstrMessageEvent,
|
|
60
80
|
) -> None | AsyncGenerator[None, None]:
|
|
81
|
+
# apply unique session
|
|
82
|
+
if self.unique_session and event.message_obj.type == MessageType.GROUP_MESSAGE:
|
|
83
|
+
sid = build_unique_session_id(event)
|
|
84
|
+
if sid:
|
|
85
|
+
event.session_id = sid
|
|
86
|
+
|
|
87
|
+
# ignore bot self message
|
|
61
88
|
if (
|
|
62
89
|
self.ignore_bot_self_message
|
|
63
90
|
and event.get_self_id() == event.get_sender_id()
|
|
64
91
|
):
|
|
65
|
-
# 忽略机器人自己发送的消息
|
|
66
92
|
event.stop_event()
|
|
67
93
|
return
|
|
94
|
+
|
|
68
95
|
# 设置 sender 身份
|
|
69
96
|
event.message_str = event.message_str.strip()
|
|
70
97
|
for admin_id in self.ctx.astrbot_config["admins_id"]:
|
|
@@ -136,7 +163,8 @@ class WakingCheckStage(Stage):
|
|
|
136
163
|
):
|
|
137
164
|
if (
|
|
138
165
|
self.disable_builtin_commands
|
|
139
|
-
and handler.handler_module_path
|
|
166
|
+
and handler.handler_module_path
|
|
167
|
+
== "astrbot.builtin_stars.builtin_commands.main"
|
|
140
168
|
):
|
|
141
169
|
logger.debug("skipping builtin command")
|
|
142
170
|
continue
|
|
@@ -41,7 +41,6 @@ class AiocqhttpAdapter(Platform):
|
|
|
41
41
|
super().__init__(platform_config, event_queue)
|
|
42
42
|
|
|
43
43
|
self.settings = platform_settings
|
|
44
|
-
self.unique_session = platform_settings["unique_session"]
|
|
45
44
|
self.host = platform_config["ws_reverse_host"]
|
|
46
45
|
self.port = platform_config["ws_reverse_port"]
|
|
47
46
|
|
|
@@ -136,14 +135,11 @@ class AiocqhttpAdapter(Platform):
|
|
|
136
135
|
abm.group_id = str(event.group_id)
|
|
137
136
|
else:
|
|
138
137
|
abm.type = MessageType.FRIEND_MESSAGE
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
abm.
|
|
143
|
-
|
|
144
|
-
if abm.type == MessageType.GROUP_MESSAGE
|
|
145
|
-
else abm.sender.user_id
|
|
146
|
-
)
|
|
138
|
+
abm.session_id = (
|
|
139
|
+
str(event.group_id)
|
|
140
|
+
if abm.type == MessageType.GROUP_MESSAGE
|
|
141
|
+
else abm.sender.user_id
|
|
142
|
+
)
|
|
147
143
|
abm.message_str = ""
|
|
148
144
|
abm.message = []
|
|
149
145
|
abm.timestamp = int(time.time())
|
|
@@ -164,16 +160,11 @@ class AiocqhttpAdapter(Platform):
|
|
|
164
160
|
abm.type = MessageType.GROUP_MESSAGE
|
|
165
161
|
else:
|
|
166
162
|
abm.type = MessageType.FRIEND_MESSAGE
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
abm.session_id = (
|
|
173
|
-
str(event.group_id)
|
|
174
|
-
if abm.type == MessageType.GROUP_MESSAGE
|
|
175
|
-
else abm.sender.user_id
|
|
176
|
-
)
|
|
163
|
+
abm.session_id = (
|
|
164
|
+
str(event.group_id)
|
|
165
|
+
if abm.type == MessageType.GROUP_MESSAGE
|
|
166
|
+
else abm.sender.user_id
|
|
167
|
+
)
|
|
177
168
|
abm.message_str = ""
|
|
178
169
|
abm.message = []
|
|
179
170
|
abm.raw_message = event
|
|
@@ -210,16 +201,11 @@ class AiocqhttpAdapter(Platform):
|
|
|
210
201
|
abm.group.group_name = event.get("group_name", "N/A")
|
|
211
202
|
elif event["message_type"] == "private":
|
|
212
203
|
abm.type = MessageType.FRIEND_MESSAGE
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
abm.session_id = (
|
|
219
|
-
str(event.group_id)
|
|
220
|
-
if abm.type == MessageType.GROUP_MESSAGE
|
|
221
|
-
else abm.sender.user_id
|
|
222
|
-
)
|
|
204
|
+
abm.session_id = (
|
|
205
|
+
str(event.group_id)
|
|
206
|
+
if abm.type == MessageType.GROUP_MESSAGE
|
|
207
|
+
else abm.sender.user_id
|
|
208
|
+
)
|
|
223
209
|
|
|
224
210
|
abm.message_id = str(event.message_id)
|
|
225
211
|
abm.message = []
|
|
@@ -50,8 +50,6 @@ class DingtalkPlatformAdapter(Platform):
|
|
|
50
50
|
) -> None:
|
|
51
51
|
super().__init__(platform_config, event_queue)
|
|
52
52
|
|
|
53
|
-
self.unique_session = platform_settings["unique_session"]
|
|
54
|
-
|
|
55
53
|
self.client_id = platform_config["client_id"]
|
|
56
54
|
self.client_secret = platform_config["client_secret"]
|
|
57
55
|
|
|
@@ -129,10 +127,7 @@ class DingtalkPlatformAdapter(Platform):
|
|
|
129
127
|
if id := self._id_to_sid(user.dingtalk_id):
|
|
130
128
|
abm.message.append(At(qq=id))
|
|
131
129
|
abm.group_id = message.conversation_id
|
|
132
|
-
|
|
133
|
-
abm.session_id = abm.sender.user_id
|
|
134
|
-
else:
|
|
135
|
-
abm.session_id = abm.group_id
|
|
130
|
+
abm.session_id = abm.group_id
|
|
136
131
|
else:
|
|
137
132
|
abm.session_id = abm.sender.user_id
|
|
138
133
|
|
|
@@ -25,6 +25,20 @@ class DingtalkMessageEvent(AstrMessageEvent):
|
|
|
25
25
|
client: dingtalk_stream.ChatbotHandler,
|
|
26
26
|
message: MessageChain,
|
|
27
27
|
):
|
|
28
|
+
icm = cast(dingtalk_stream.ChatbotMessage, self.message_obj.raw_message)
|
|
29
|
+
ats = []
|
|
30
|
+
# fixes: #4218
|
|
31
|
+
# 钉钉 at 机器人需要使用 sender_staff_id 而不是 sender_id
|
|
32
|
+
for i in message.chain:
|
|
33
|
+
if isinstance(i, Comp.At):
|
|
34
|
+
print(i.qq, icm.sender_id, icm.sender_staff_id)
|
|
35
|
+
if str(i.qq) in str(icm.sender_id or ""):
|
|
36
|
+
# 适配器会将开头的 $:LWCP_v1:$ 去掉,因此我们用 in 判断
|
|
37
|
+
ats.append(f"@{icm.sender_staff_id}")
|
|
38
|
+
else:
|
|
39
|
+
ats.append(f"@{i.qq}")
|
|
40
|
+
at_str = " ".join(ats)
|
|
41
|
+
|
|
28
42
|
for segment in message.chain:
|
|
29
43
|
if isinstance(segment, Comp.Plain):
|
|
30
44
|
segment.text = segment.text.strip()
|
|
@@ -32,7 +46,7 @@ class DingtalkMessageEvent(AstrMessageEvent):
|
|
|
32
46
|
None,
|
|
33
47
|
client.reply_markdown,
|
|
34
48
|
segment.text,
|
|
35
|
-
segment.text,
|
|
49
|
+
f"{at_str} {segment.text}".strip(),
|
|
36
50
|
cast(dingtalk_stream.ChatbotMessage, self.message_obj.raw_message),
|
|
37
51
|
)
|
|
38
52
|
elif isinstance(segment, Comp.Image):
|
|
@@ -44,8 +44,6 @@ class LarkPlatformAdapter(Platform):
|
|
|
44
44
|
) -> None:
|
|
45
45
|
super().__init__(platform_config, event_queue)
|
|
46
46
|
|
|
47
|
-
self.unique_session = platform_settings["unique_session"]
|
|
48
|
-
|
|
49
47
|
self.appid = platform_config["app_id"]
|
|
50
48
|
self.appsecret = platform_config["app_secret"]
|
|
51
49
|
self.domain = platform_config.get("domain", lark.FEISHU_DOMAIN)
|
|
@@ -317,14 +315,8 @@ class LarkPlatformAdapter(Platform):
|
|
|
317
315
|
user_id=event.event.sender.sender_id.open_id,
|
|
318
316
|
nickname=event.event.sender.sender_id.open_id[:8],
|
|
319
317
|
)
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
if abm.type == MessageType.GROUP_MESSAGE:
|
|
323
|
-
abm.session_id = abm.group_id
|
|
324
|
-
else:
|
|
325
|
-
abm.session_id = abm.sender.user_id
|
|
326
|
-
elif abm.type == MessageType.GROUP_MESSAGE:
|
|
327
|
-
abm.session_id = f"{abm.sender.user_id}%{abm.group_id}" # 也保留群组id
|
|
318
|
+
if abm.type == MessageType.GROUP_MESSAGE:
|
|
319
|
+
abm.session_id = abm.group_id
|
|
328
320
|
else:
|
|
329
321
|
abm.session_id = abm.sender.user_id
|
|
330
322
|
|
|
@@ -91,8 +91,6 @@ class MisskeyPlatformAdapter(Platform):
|
|
|
91
91
|
except Exception:
|
|
92
92
|
self.max_download_bytes = None
|
|
93
93
|
|
|
94
|
-
self.unique_session = platform_settings["unique_session"]
|
|
95
|
-
|
|
96
94
|
self.api: MisskeyAPI | None = None
|
|
97
95
|
self._running = False
|
|
98
96
|
self.client_self_id = ""
|
|
@@ -641,7 +639,6 @@ class MisskeyPlatformAdapter(Platform):
|
|
|
641
639
|
sender_info,
|
|
642
640
|
self.client_self_id,
|
|
643
641
|
is_chat=False,
|
|
644
|
-
unique_session=self.unique_session,
|
|
645
642
|
)
|
|
646
643
|
cache_user_info(
|
|
647
644
|
self._user_cache,
|
|
@@ -690,7 +687,6 @@ class MisskeyPlatformAdapter(Platform):
|
|
|
690
687
|
sender_info,
|
|
691
688
|
self.client_self_id,
|
|
692
689
|
is_chat=True,
|
|
693
|
-
unique_session=self.unique_session,
|
|
694
690
|
)
|
|
695
691
|
cache_user_info(
|
|
696
692
|
self._user_cache,
|
|
@@ -720,7 +716,6 @@ class MisskeyPlatformAdapter(Platform):
|
|
|
720
716
|
self.client_self_id,
|
|
721
717
|
is_chat=False,
|
|
722
718
|
room_id=room_id,
|
|
723
|
-
unique_session=self.unique_session,
|
|
724
719
|
)
|
|
725
720
|
|
|
726
721
|
cache_user_info(
|
|
@@ -338,7 +338,6 @@ def create_base_message(
|
|
|
338
338
|
client_self_id: str,
|
|
339
339
|
is_chat: bool = False,
|
|
340
340
|
room_id: str | None = None,
|
|
341
|
-
unique_session: bool = False,
|
|
342
341
|
) -> AstrBotMessage:
|
|
343
342
|
"""创建基础消息对象"""
|
|
344
343
|
message = AstrBotMessage()
|
|
@@ -353,8 +352,6 @@ def create_base_message(
|
|
|
353
352
|
if room_id:
|
|
354
353
|
session_prefix = "room"
|
|
355
354
|
session_id = f"{session_prefix}%{room_id}"
|
|
356
|
-
if unique_session:
|
|
357
|
-
session_id += f"_{sender_info['sender_id']}"
|
|
358
355
|
message.type = MessageType.GROUP_MESSAGE
|
|
359
356
|
message.group_id = room_id
|
|
360
357
|
elif is_chat:
|
|
@@ -44,11 +44,8 @@ class botClient(Client):
|
|
|
44
44
|
message,
|
|
45
45
|
MessageType.GROUP_MESSAGE,
|
|
46
46
|
)
|
|
47
|
-
abm.
|
|
48
|
-
|
|
49
|
-
if self.platform.unique_session
|
|
50
|
-
else cast(str, message.group_openid)
|
|
51
|
-
)
|
|
47
|
+
abm.group_id = cast(str, message.group_openid)
|
|
48
|
+
abm.session_id = abm.group_id
|
|
52
49
|
self._commit(abm)
|
|
53
50
|
|
|
54
51
|
# 收到频道消息
|
|
@@ -57,9 +54,8 @@ class botClient(Client):
|
|
|
57
54
|
message,
|
|
58
55
|
MessageType.GROUP_MESSAGE,
|
|
59
56
|
)
|
|
60
|
-
abm.
|
|
61
|
-
|
|
62
|
-
)
|
|
57
|
+
abm.group_id = message.channel_id
|
|
58
|
+
abm.session_id = abm.group_id
|
|
63
59
|
self._commit(abm)
|
|
64
60
|
|
|
65
61
|
# 收到私聊消息
|
|
@@ -104,7 +100,6 @@ class QQOfficialPlatformAdapter(Platform):
|
|
|
104
100
|
|
|
105
101
|
self.appid = platform_config["appid"]
|
|
106
102
|
self.secret = platform_config["secret"]
|
|
107
|
-
self.unique_session: bool = platform_settings["unique_session"]
|
|
108
103
|
qq_group = platform_config["enable_group_c2c"]
|
|
109
104
|
guild_dm = platform_config["enable_guild_direct_message"]
|
|
110
105
|
|
|
@@ -35,11 +35,8 @@ class botClient(Client):
|
|
|
35
35
|
message,
|
|
36
36
|
MessageType.GROUP_MESSAGE,
|
|
37
37
|
)
|
|
38
|
-
abm.
|
|
39
|
-
|
|
40
|
-
if self.platform.unique_session
|
|
41
|
-
else cast(str, message.group_openid)
|
|
42
|
-
)
|
|
38
|
+
abm.group_id = cast(str, message.group_openid)
|
|
39
|
+
abm.session_id = abm.group_id
|
|
43
40
|
self._commit(abm)
|
|
44
41
|
|
|
45
42
|
# 收到频道消息
|
|
@@ -48,9 +45,8 @@ class botClient(Client):
|
|
|
48
45
|
message,
|
|
49
46
|
MessageType.GROUP_MESSAGE,
|
|
50
47
|
)
|
|
51
|
-
abm.
|
|
52
|
-
|
|
53
|
-
)
|
|
48
|
+
abm.group_id = message.channel_id
|
|
49
|
+
abm.session_id = abm.group_id
|
|
54
50
|
self._commit(abm)
|
|
55
51
|
|
|
56
52
|
# 收到私聊消息
|
|
@@ -95,7 +91,6 @@ class QQOfficialWebhookPlatformAdapter(Platform):
|
|
|
95
91
|
|
|
96
92
|
self.appid = platform_config["appid"]
|
|
97
93
|
self.secret = platform_config["secret"]
|
|
98
|
-
self.unique_session = platform_settings["unique_session"]
|
|
99
94
|
self.unified_webhook_mode = platform_config.get("unified_webhook_mode", False)
|
|
100
95
|
|
|
101
96
|
intents = botpy.Intents(
|
|
@@ -142,7 +142,12 @@ class SatoriPlatformAdapter(Platform):
|
|
|
142
142
|
raise ValueError(f"WebSocket URL必须以ws://或wss://开头: {self.endpoint}")
|
|
143
143
|
|
|
144
144
|
try:
|
|
145
|
-
websocket = await connect(
|
|
145
|
+
websocket = await connect(
|
|
146
|
+
self.endpoint,
|
|
147
|
+
additional_headers={},
|
|
148
|
+
max_size=10 * 1024 * 1024, # 10MB
|
|
149
|
+
)
|
|
150
|
+
|
|
146
151
|
self.ws = websocket
|
|
147
152
|
|
|
148
153
|
await asyncio.sleep(0.1)
|
|
@@ -41,7 +41,6 @@ class SlackAdapter(Platform):
|
|
|
41
41
|
) -> None:
|
|
42
42
|
super().__init__(platform_config, event_queue)
|
|
43
43
|
self.settings = platform_settings
|
|
44
|
-
self.unique_session = platform_settings.get("unique_session", False)
|
|
45
44
|
|
|
46
45
|
self.bot_token = platform_config.get("bot_token")
|
|
47
46
|
self.app_token = platform_config.get("app_token")
|
|
@@ -147,12 +146,10 @@ class SlackAdapter(Platform):
|
|
|
147
146
|
abm.group_id = channel_id
|
|
148
147
|
|
|
149
148
|
# 设置会话ID
|
|
150
|
-
if
|
|
151
|
-
abm.session_id =
|
|
149
|
+
if abm.type == MessageType.GROUP_MESSAGE:
|
|
150
|
+
abm.session_id = abm.group_id
|
|
152
151
|
else:
|
|
153
|
-
abm.session_id =
|
|
154
|
-
channel_id if abm.type == MessageType.GROUP_MESSAGE else user_id
|
|
155
|
-
)
|
|
152
|
+
abm.session_id = user_id
|
|
156
153
|
|
|
157
154
|
abm.message_id = event.get("client_msg_id", uuid.uuid4().hex)
|
|
158
155
|
abm.timestamp = int(float(event.get("ts", time.time())))
|
|
@@ -79,7 +79,6 @@ class WebChatAdapter(Platform):
|
|
|
79
79
|
super().__init__(platform_config, event_queue)
|
|
80
80
|
|
|
81
81
|
self.settings = platform_settings
|
|
82
|
-
self.unique_session = platform_settings["unique_session"]
|
|
83
82
|
self.imgs_dir = os.path.join(get_astrbot_data_path(), "webchat", "imgs")
|
|
84
83
|
os.makedirs(self.imgs_dir, exist_ok=True)
|
|
85
84
|
|
|
@@ -47,7 +47,6 @@ class WeChatPadProAdapter(Platform):
|
|
|
47
47
|
self._shutdown_event = None
|
|
48
48
|
self.wxnewpass = None
|
|
49
49
|
self.settings = platform_settings
|
|
50
|
-
self.unique_session = platform_settings.get("unique_session", False)
|
|
51
50
|
|
|
52
51
|
self.metadata = PlatformMetadata(
|
|
53
52
|
name="wechatpadpro",
|
|
@@ -509,11 +508,10 @@ class WeChatPadProAdapter(Platform):
|
|
|
509
508
|
if accurate_nickname:
|
|
510
509
|
abm.sender.nickname = accurate_nickname
|
|
511
510
|
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
abm.session_id = f"{from_user_name}#{abm.sender.user_id}"
|
|
511
|
+
if abm.type == MessageType.GROUP_MESSAGE:
|
|
512
|
+
abm.session_id = abm.group_id
|
|
515
513
|
else:
|
|
516
|
-
abm.session_id =
|
|
514
|
+
abm.session_id = abm.sender.user_id
|
|
517
515
|
|
|
518
516
|
msg_source = raw_message.get("msg_source", "")
|
|
519
517
|
if self.wxid in msg_source:
|