AstrBot 4.5.8__py3-none-any.whl → 4.6.0__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.
Files changed (28) hide show
  1. astrbot/core/agent/mcp_client.py +152 -26
  2. astrbot/core/agent/message.py +7 -0
  3. astrbot/core/config/default.py +8 -1
  4. astrbot/core/core_lifecycle.py +8 -0
  5. astrbot/core/db/__init__.py +50 -1
  6. astrbot/core/db/migration/migra_webchat_session.py +131 -0
  7. astrbot/core/db/po.py +49 -13
  8. astrbot/core/db/sqlite.py +102 -3
  9. astrbot/core/knowledge_base/kb_helper.py +314 -33
  10. astrbot/core/knowledge_base/kb_mgr.py +45 -1
  11. astrbot/core/knowledge_base/parsers/url_parser.py +103 -0
  12. astrbot/core/knowledge_base/prompts.py +65 -0
  13. astrbot/core/pipeline/process_stage/method/llm_request.py +28 -14
  14. astrbot/core/pipeline/process_stage/utils.py +60 -16
  15. astrbot/core/platform/sources/wecom_ai_bot/wecomai_adapter.py +13 -10
  16. astrbot/core/platform/sources/wecom_ai_bot/wecomai_event.py +8 -4
  17. astrbot/core/platform/sources/wecom_ai_bot/wecomai_queue_mgr.py +0 -4
  18. astrbot/core/provider/entities.py +22 -9
  19. astrbot/core/provider/func_tool_manager.py +12 -9
  20. astrbot/core/provider/sources/gemini_source.py +25 -8
  21. astrbot/core/provider/sources/openai_source.py +9 -16
  22. astrbot/dashboard/routes/chat.py +134 -77
  23. astrbot/dashboard/routes/knowledge_base.py +172 -0
  24. {astrbot-4.5.8.dist-info → astrbot-4.6.0.dist-info}/METADATA +4 -3
  25. {astrbot-4.5.8.dist-info → astrbot-4.6.0.dist-info}/RECORD +28 -25
  26. {astrbot-4.5.8.dist-info → astrbot-4.6.0.dist-info}/WHEEL +0 -0
  27. {astrbot-4.5.8.dist-info → astrbot-4.6.0.dist-info}/entry_points.txt +0 -0
  28. {astrbot-4.5.8.dist-info → astrbot-4.6.0.dist-info}/licenses/LICENSE +0 -0
@@ -10,7 +10,6 @@ from quart import g, make_response, request
10
10
  from astrbot.core import logger
11
11
  from astrbot.core.core_lifecycle import AstrBotCoreLifecycle
12
12
  from astrbot.core.db import BaseDatabase
13
- from astrbot.core.platform.astr_message_event import MessageSession
14
13
  from astrbot.core.platform.sources.webchat.webchat_queue_mgr import webchat_queue_mgr
15
14
  from astrbot.core.utils.astrbot_path import get_astrbot_data_path
16
15
 
@@ -36,11 +35,14 @@ class ChatRoute(Route):
36
35
  super().__init__(context)
37
36
  self.routes = {
38
37
  "/chat/send": ("POST", self.chat),
39
- "/chat/new_conversation": ("GET", self.new_conversation),
40
- "/chat/conversations": ("GET", self.get_conversations),
41
- "/chat/get_conversation": ("GET", self.get_conversation),
42
- "/chat/delete_conversation": ("GET", self.delete_conversation),
43
- "/chat/rename_conversation": ("POST", self.rename_conversation),
38
+ "/chat/new_session": ("GET", self.new_session),
39
+ "/chat/sessions": ("GET", self.get_sessions),
40
+ "/chat/get_session": ("GET", self.get_session),
41
+ "/chat/delete_session": ("GET", self.delete_webchat_session),
42
+ "/chat/update_session_display_name": (
43
+ "POST",
44
+ self.update_session_display_name,
45
+ ),
44
46
  "/chat/get_file": ("GET", self.get_file),
45
47
  "/chat/post_image": ("POST", self.post_image),
46
48
  "/chat/post_file": ("POST", self.post_file),
@@ -53,6 +55,7 @@ class ChatRoute(Route):
53
55
  self.supported_imgs = ["jpg", "jpeg", "png", "gif", "webp"]
54
56
  self.conv_mgr = core_lifecycle.conversation_manager
55
57
  self.platform_history_mgr = core_lifecycle.platform_message_history_manager
58
+ self.db = db
56
59
 
57
60
  self.running_convs: dict[str, bool] = {}
58
61
 
@@ -116,11 +119,14 @@ class ChatRoute(Route):
116
119
  if "message" not in post_data and "image_url" not in post_data:
117
120
  return Response().error("Missing key: message or image_url").__dict__
118
121
 
119
- if "conversation_id" not in post_data:
120
- return Response().error("Missing key: conversation_id").__dict__
122
+ if "session_id" not in post_data and "conversation_id" not in post_data:
123
+ return (
124
+ Response().error("Missing key: session_id or conversation_id").__dict__
125
+ )
121
126
 
122
127
  message = post_data["message"]
123
- conversation_id = post_data["conversation_id"]
128
+ # conversation_id = post_data["conversation_id"]
129
+ session_id = post_data.get("session_id", post_data.get("conversation_id"))
124
130
  image_url = post_data.get("image_url")
125
131
  audio_url = post_data.get("audio_url")
126
132
  selected_provider = post_data.get("selected_provider")
@@ -133,11 +139,11 @@ class ChatRoute(Route):
133
139
  .error("Message and image_url and audio_url are empty")
134
140
  .__dict__
135
141
  )
136
- if not conversation_id:
137
- return Response().error("conversation_id is empty").__dict__
142
+ if not session_id:
143
+ return Response().error("session_id is empty").__dict__
138
144
 
139
145
  # 追加用户消息
140
- webchat_conv_id = await self._get_webchat_conv_id_from_conv_id(conversation_id)
146
+ webchat_conv_id = session_id
141
147
 
142
148
  # 获取会话特定的队列
143
149
  back_queue = webchat_queue_mgr.get_or_create_back_queue(webchat_conv_id)
@@ -245,88 +251,110 @@ class ChatRoute(Route):
245
251
  response.timeout = None # fix SSE auto disconnect issue
246
252
  return response
247
253
 
248
- async def _get_webchat_conv_id_from_conv_id(self, conversation_id: str) -> str:
249
- """从对话 ID 中提取 WebChat 会话 ID
250
-
251
- NOTE: 关于这里为什么要单独做一个 WebChat 的 Conversation ID 出来,这个是为了向前兼容。
252
- """
253
- conversation = await self.conv_mgr.get_conversation(
254
- unified_msg_origin="webchat",
255
- conversation_id=conversation_id,
256
- )
257
- if not conversation:
258
- raise ValueError(f"Conversation with ID {conversation_id} not found.")
259
- conv_user_id = conversation.user_id
260
- webchat_session_id = MessageSession.from_str(conv_user_id).session_id
261
- if "!" not in webchat_session_id:
262
- raise ValueError(f"Invalid conv user ID: {conv_user_id}")
263
- return webchat_session_id.split("!")[-1]
264
-
265
- async def delete_conversation(self):
266
- conversation_id = request.args.get("conversation_id")
267
- if not conversation_id:
268
- return Response().error("Missing key: conversation_id").__dict__
254
+ async def delete_webchat_session(self):
255
+ """Delete a Platform session and all its related data."""
256
+ session_id = request.args.get("session_id")
257
+ if not session_id:
258
+ return Response().error("Missing key: session_id").__dict__
269
259
  username = g.get("username", "guest")
270
260
 
271
- # Clean up queues when deleting conversation
272
- webchat_queue_mgr.remove_queues(conversation_id)
273
- webchat_conv_id = await self._get_webchat_conv_id_from_conv_id(conversation_id)
274
- await self.conv_mgr.delete_conversation(
275
- unified_msg_origin=f"webchat:FriendMessage:webchat!{username}!{webchat_conv_id}",
276
- conversation_id=conversation_id,
277
- )
261
+ # 验证会话是否存在且属于当前用户
262
+ session = await self.db.get_platform_session_by_id(session_id)
263
+ if not session:
264
+ return Response().error(f"Session {session_id} not found").__dict__
265
+ if session.creator != username:
266
+ return Response().error("Permission denied").__dict__
267
+
268
+ # 删除该会话下的所有对话
269
+ unified_msg_origin = f"{session.platform_id}:FriendMessage:{session.platform_id}!{username}!{session_id}"
270
+ await self.conv_mgr.delete_conversations_by_user_id(unified_msg_origin)
271
+
272
+ # 删除消息历史
278
273
  await self.platform_history_mgr.delete(
279
- platform_id="webchat",
280
- user_id=webchat_conv_id,
274
+ platform_id=session.platform_id,
275
+ user_id=session_id,
281
276
  offset_sec=99999999,
282
277
  )
278
+
279
+ # 清理队列(仅对 webchat)
280
+ if session.platform_id == "webchat":
281
+ webchat_queue_mgr.remove_queues(session_id)
282
+
283
+ # 删除会话
284
+ await self.db.delete_platform_session(session_id)
285
+
283
286
  return Response().ok().__dict__
284
287
 
285
- async def new_conversation(self):
288
+ async def new_session(self):
289
+ """Create a new Platform session (default: webchat)."""
286
290
  username = g.get("username", "guest")
287
- webchat_conv_id = str(uuid.uuid4())
288
- conv_id = await self.conv_mgr.new_conversation(
289
- unified_msg_origin=f"webchat:FriendMessage:webchat!{username}!{webchat_conv_id}",
290
- platform_id="webchat",
291
- content=[],
291
+
292
+ # 获取可选的 platform_id 参数,默认为 webchat
293
+ platform_id = request.args.get("platform_id", "webchat")
294
+
295
+ # 创建新会话
296
+ session = await self.db.create_platform_session(
297
+ creator=username,
298
+ platform_id=platform_id,
299
+ is_group=0,
292
300
  )
293
- return Response().ok(data={"conversation_id": conv_id}).__dict__
294
301
 
295
- async def rename_conversation(self):
296
- post_data = await request.json
297
- if "conversation_id" not in post_data or "title" not in post_data:
298
- return Response().error("Missing key: conversation_id or title").__dict__
302
+ return (
303
+ Response()
304
+ .ok(
305
+ data={
306
+ "session_id": session.session_id,
307
+ "platform_id": session.platform_id,
308
+ }
309
+ )
310
+ .__dict__
311
+ )
299
312
 
300
- conversation_id = post_data["conversation_id"]
301
- title = post_data["title"]
313
+ async def get_sessions(self):
314
+ """Get all Platform sessions for the current user."""
315
+ username = g.get("username", "guest")
316
+
317
+ # 获取可选的 platform_id 参数
318
+ platform_id = request.args.get("platform_id")
302
319
 
303
- await self.conv_mgr.update_conversation(
304
- unified_msg_origin="webchat", # fake
305
- conversation_id=conversation_id,
306
- title=title,
320
+ sessions = await self.db.get_platform_sessions_by_creator(
321
+ creator=username,
322
+ platform_id=platform_id,
323
+ page=1,
324
+ page_size=100, # 暂时返回前100个
307
325
  )
308
- return Response().ok(message="重命名成功!").__dict__
309
326
 
310
- async def get_conversations(self):
311
- conversations = await self.conv_mgr.get_conversations(platform_id="webchat")
312
- # remove content
313
- conversations_ = []
314
- for conv in conversations:
315
- conv.history = None
316
- conversations_.append(conv)
317
- return Response().ok(data=conversations_).__dict__
327
+ # 转换为字典格式,并添加额外信息
328
+ sessions_data = []
329
+ for session in sessions:
330
+ sessions_data.append(
331
+ {
332
+ "session_id": session.session_id,
333
+ "platform_id": session.platform_id,
334
+ "creator": session.creator,
335
+ "display_name": session.display_name,
336
+ "is_group": session.is_group,
337
+ "created_at": session.created_at.astimezone().isoformat(),
338
+ "updated_at": session.updated_at.astimezone().isoformat(),
339
+ }
340
+ )
341
+
342
+ return Response().ok(data=sessions_data).__dict__
318
343
 
319
- async def get_conversation(self):
320
- conversation_id = request.args.get("conversation_id")
321
- if not conversation_id:
322
- return Response().error("Missing key: conversation_id").__dict__
344
+ async def get_session(self):
345
+ """Get session information and message history by session_id."""
346
+ session_id = request.args.get("session_id")
347
+ if not session_id:
348
+ return Response().error("Missing key: session_id").__dict__
323
349
 
324
- webchat_conv_id = await self._get_webchat_conv_id_from_conv_id(conversation_id)
350
+ # 获取会话信息以确定 platform_id
351
+ session = await self.db.get_platform_session_by_id(session_id)
352
+ platform_id = session.platform_id if session else "webchat"
325
353
 
326
- # Get platform message history
354
+ # Get platform message history using session_id
327
355
  history_ls = await self.platform_history_mgr.get(
328
- platform_id="webchat",
329
- user_id=webchat_conv_id,
356
+ platform_id=platform_id,
357
+ user_id=session_id,
330
358
  page=1,
331
359
  page_size=1000,
332
360
  )
@@ -338,8 +366,37 @@ class ChatRoute(Route):
338
366
  .ok(
339
367
  data={
340
368
  "history": history_res,
341
- "is_running": self.running_convs.get(webchat_conv_id, False),
369
+ "is_running": self.running_convs.get(session_id, False),
342
370
  },
343
371
  )
344
372
  .__dict__
345
373
  )
374
+
375
+ async def update_session_display_name(self):
376
+ """Update a Platform session's display name."""
377
+ post_data = await request.json
378
+
379
+ session_id = post_data.get("session_id")
380
+ display_name = post_data.get("display_name")
381
+
382
+ if not session_id:
383
+ return Response().error("Missing key: session_id").__dict__
384
+ if display_name is None:
385
+ return Response().error("Missing key: display_name").__dict__
386
+
387
+ username = g.get("username", "guest")
388
+
389
+ # 验证会话是否存在且属于当前用户
390
+ session = await self.db.get_platform_session_by_id(session_id)
391
+ if not session:
392
+ return Response().error(f"Session {session_id} not found").__dict__
393
+ if session.creator != username:
394
+ return Response().error("Permission denied").__dict__
395
+
396
+ # 更新 display_name
397
+ await self.db.update_platform_session(
398
+ session_id=session_id,
399
+ display_name=display_name,
400
+ )
401
+
402
+ return Response().ok().__dict__
@@ -48,6 +48,7 @@ class KnowledgeBaseRoute(Route):
48
48
  # 文档管理
49
49
  "/kb/document/list": ("GET", self.list_documents),
50
50
  "/kb/document/upload": ("POST", self.upload_document),
51
+ "/kb/document/upload/url": ("POST", self.upload_document_from_url),
51
52
  "/kb/document/upload/progress": ("GET", self.get_upload_progress),
52
53
  "/kb/document/get": ("GET", self.get_document),
53
54
  "/kb/document/delete": ("POST", self.delete_document),
@@ -1070,3 +1071,174 @@ class KnowledgeBaseRoute(Route):
1070
1071
  logger.error(f"删除会话知识库配置失败: {e}")
1071
1072
  logger.error(traceback.format_exc())
1072
1073
  return Response().error(f"删除会话知识库配置失败: {e!s}").__dict__
1074
+
1075
+ async def upload_document_from_url(self):
1076
+ """从 URL 上传文档
1077
+
1078
+ Body:
1079
+ - kb_id: 知识库 ID (必填)
1080
+ - url: 要提取内容的网页 URL (必填)
1081
+ - chunk_size: 分块大小 (可选, 默认512)
1082
+ - chunk_overlap: 块重叠大小 (可选, 默认50)
1083
+ - batch_size: 批处理大小 (可选, 默认32)
1084
+ - tasks_limit: 并发任务限制 (可选, 默认3)
1085
+ - max_retries: 最大重试次数 (可选, 默认3)
1086
+
1087
+ 返回:
1088
+ - task_id: 任务ID,用于查询上传进度和结果
1089
+ """
1090
+ try:
1091
+ kb_manager = self._get_kb_manager()
1092
+ data = await request.json
1093
+
1094
+ kb_id = data.get("kb_id")
1095
+ if not kb_id:
1096
+ return Response().error("缺少参数 kb_id").__dict__
1097
+
1098
+ url = data.get("url")
1099
+ if not url:
1100
+ return Response().error("缺少参数 url").__dict__
1101
+
1102
+ chunk_size = data.get("chunk_size", 512)
1103
+ chunk_overlap = data.get("chunk_overlap", 50)
1104
+ batch_size = data.get("batch_size", 32)
1105
+ tasks_limit = data.get("tasks_limit", 3)
1106
+ max_retries = data.get("max_retries", 3)
1107
+ enable_cleaning = data.get("enable_cleaning", False)
1108
+ cleaning_provider_id = data.get("cleaning_provider_id")
1109
+
1110
+ # 获取知识库
1111
+ kb_helper = await kb_manager.get_kb(kb_id)
1112
+ if not kb_helper:
1113
+ return Response().error("知识库不存在").__dict__
1114
+
1115
+ # 生成任务ID
1116
+ task_id = str(uuid.uuid4())
1117
+
1118
+ # 初始化任务状态
1119
+ self.upload_tasks[task_id] = {
1120
+ "status": "pending",
1121
+ "result": None,
1122
+ "error": None,
1123
+ }
1124
+
1125
+ # 启动后台任务
1126
+ asyncio.create_task(
1127
+ self._background_upload_from_url_task(
1128
+ task_id=task_id,
1129
+ kb_helper=kb_helper,
1130
+ url=url,
1131
+ chunk_size=chunk_size,
1132
+ chunk_overlap=chunk_overlap,
1133
+ batch_size=batch_size,
1134
+ tasks_limit=tasks_limit,
1135
+ max_retries=max_retries,
1136
+ enable_cleaning=enable_cleaning,
1137
+ cleaning_provider_id=cleaning_provider_id,
1138
+ ),
1139
+ )
1140
+
1141
+ return (
1142
+ Response()
1143
+ .ok(
1144
+ {
1145
+ "task_id": task_id,
1146
+ "url": url,
1147
+ "message": "URL upload task created, processing in background",
1148
+ },
1149
+ )
1150
+ .__dict__
1151
+ )
1152
+
1153
+ except ValueError as e:
1154
+ return Response().error(str(e)).__dict__
1155
+ except Exception as e:
1156
+ logger.error(f"从URL上传文档失败: {e}")
1157
+ logger.error(traceback.format_exc())
1158
+ return Response().error(f"从URL上传文档失败: {e!s}").__dict__
1159
+
1160
+ async def _background_upload_from_url_task(
1161
+ self,
1162
+ task_id: str,
1163
+ kb_helper,
1164
+ url: str,
1165
+ chunk_size: int,
1166
+ chunk_overlap: int,
1167
+ batch_size: int,
1168
+ tasks_limit: int,
1169
+ max_retries: int,
1170
+ enable_cleaning: bool,
1171
+ cleaning_provider_id: str | None,
1172
+ ):
1173
+ """后台上传URL任务"""
1174
+ try:
1175
+ # 初始化任务状态
1176
+ self.upload_tasks[task_id] = {
1177
+ "status": "processing",
1178
+ "result": None,
1179
+ "error": None,
1180
+ }
1181
+ self.upload_progress[task_id] = {
1182
+ "status": "processing",
1183
+ "file_index": 0,
1184
+ "file_total": 1,
1185
+ "file_name": f"URL: {url}",
1186
+ "stage": "extracting",
1187
+ "current": 0,
1188
+ "total": 100,
1189
+ }
1190
+
1191
+ # 创建进度回调函数
1192
+ async def progress_callback(stage, current, total):
1193
+ if task_id in self.upload_progress:
1194
+ self.upload_progress[task_id].update(
1195
+ {
1196
+ "status": "processing",
1197
+ "file_index": 0,
1198
+ "file_name": f"URL: {url}",
1199
+ "stage": stage,
1200
+ "current": current,
1201
+ "total": total,
1202
+ },
1203
+ )
1204
+
1205
+ # 上传文档
1206
+ doc = await kb_helper.upload_from_url(
1207
+ url=url,
1208
+ chunk_size=chunk_size,
1209
+ chunk_overlap=chunk_overlap,
1210
+ batch_size=batch_size,
1211
+ tasks_limit=tasks_limit,
1212
+ max_retries=max_retries,
1213
+ progress_callback=progress_callback,
1214
+ enable_cleaning=enable_cleaning,
1215
+ cleaning_provider_id=cleaning_provider_id,
1216
+ )
1217
+
1218
+ # 更新任务完成状态
1219
+ result = {
1220
+ "task_id": task_id,
1221
+ "uploaded": [doc.model_dump()],
1222
+ "failed": [],
1223
+ "total": 1,
1224
+ "success_count": 1,
1225
+ "failed_count": 0,
1226
+ }
1227
+
1228
+ self.upload_tasks[task_id] = {
1229
+ "status": "completed",
1230
+ "result": result,
1231
+ "error": None,
1232
+ }
1233
+ self.upload_progress[task_id]["status"] = "completed"
1234
+
1235
+ except Exception as e:
1236
+ logger.error(f"后台上传URL任务 {task_id} 失败: {e}")
1237
+ logger.error(traceback.format_exc())
1238
+ self.upload_tasks[task_id] = {
1239
+ "status": "failed",
1240
+ "result": None,
1241
+ "error": str(e),
1242
+ }
1243
+ if task_id in self.upload_progress:
1244
+ self.upload_progress[task_id]["status"] = "failed"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: AstrBot
3
- Version: 4.5.8
3
+ Version: 4.6.0
4
4
  Summary: Easy-to-use multi-platform LLM chatbot and development framework
5
5
  License-File: LICENSE
6
6
  Keywords: Astrbot,Astrbot Module,Astrbot Plugin
@@ -26,7 +26,7 @@ Requires-Dist: dingtalk-stream>=0.22.1
26
26
  Requires-Dist: docstring-parser>=0.16
27
27
  Requires-Dist: faiss-cpu==1.10.0
28
28
  Requires-Dist: filelock>=3.18.0
29
- Requires-Dist: google-genai>=1.14.0
29
+ Requires-Dist: google-genai<1.51.0,>=1.14.0
30
30
  Requires-Dist: jieba>=0.42.1
31
31
  Requires-Dist: lark-oapi>=1.4.15
32
32
  Requires-Dist: lxml-html-clean>=0.4.2
@@ -52,6 +52,7 @@ Requires-Dist: slack-sdk>=3.35.0
52
52
  Requires-Dist: sqlalchemy[asyncio]>=2.0.41
53
53
  Requires-Dist: sqlmodel>=0.0.24
54
54
  Requires-Dist: telegramify-markdown>=0.5.1
55
+ Requires-Dist: tenacity>=9.1.2
55
56
  Requires-Dist: watchfiles>=1.0.5
56
57
  Requires-Dist: websockets>=15.0.1
57
58
  Requires-Dist: wechatpy>=1.8.18
@@ -102,7 +103,7 @@ AstrBot 是一个开源的一站式 Agent 聊天机器人平台及开发框架
102
103
  4. **插件扩展**。深度优化的插件机制,支持[开发插件](https://astrbot.app/dev/plugin.html)扩展功能,社区插件生态丰富。
103
104
  5. **WebUI**。可视化配置和管理机器人,功能齐全。
104
105
 
105
- ## 部署方式
106
+ ## 部署方式
106
107
 
107
108
  #### Docker 部署(推荐 🥳)
108
109
 
@@ -26,7 +26,7 @@ astrbot/core/astr_agent_run_util.py,sha256=QQyyy649GgdcRHkdGg0N1U2yACn5O5kMj_pX2
26
26
  astrbot/core/astr_agent_tool_exec.py,sha256=jNaUEYJHJ42BT8DveBQ1YZ3lbcpq1LH3eGM6l-Lde60,8847
27
27
  astrbot/core/astrbot_config_mgr.py,sha256=SUvusfo8Qk89eNpEmduWcXuczJ9g5TBH-VOV69ax28g,8950
28
28
  astrbot/core/conversation_mgr.py,sha256=GsirCeMBmgxyaOb3hYNleF_11yyFyAER5PtpM3IUvIQ,15765
29
- astrbot/core/core_lifecycle.py,sha256=uoRlYqg33g3XgHDXFq9uOUSOEjomezidwqiA1r8z7-Q,12603
29
+ astrbot/core/core_lifecycle.py,sha256=h8MB3lfPJQhKVQ85TrAmLzcWZds6unbJDSetOZmRals,12945
30
30
  astrbot/core/event_bus.py,sha256=0rABGmFd01B5q972HS_2LQ5OFxd6iPLSyM9FbPKIgcg,2540
31
31
  astrbot/core/exceptions.py,sha256=GVCUgAjpvUHLL59MkJalFrSp_HbtliChu7XII_Px2WM,219
32
32
  astrbot/core/file_token_service.py,sha256=8X0Qyo-NPGhtxy6IcRsJg7Z2tx_ULPf_7OKvw-KBk6o,3317
@@ -40,8 +40,8 @@ astrbot/core/zip_updator.py,sha256=xBCtHl7XnlMksnS79e8j-FonfB3Lvs95rTmwoo1Z1T0,8
40
40
  astrbot/core/agent/agent.py,sha256=wquvKo18JcsJM56dwKyFFAoGhc5qLyQaeqdZ-LlZsWQ,366
41
41
  astrbot/core/agent/handoff.py,sha256=AxO0yx4Uscy0CO-3Q3fvDOfpfr3gUscLRplH7gH7-Lc,1194
42
42
  astrbot/core/agent/hooks.py,sha256=ooe9uUz7czlVt2W7jTDwkRbI-qDrOOXWjCaXtiAkrvE,830
43
- astrbot/core/agent/mcp_client.py,sha256=3N52RRlbscgLZbKwhH-lutO_cOo6ygK5cvcOQ07WGzM,9548
44
- astrbot/core/agent/message.py,sha256=YuINBqzUEHMexwiDNbZwBn7VDOUnUpITqcjmwNhtLGE,5032
43
+ astrbot/core/agent/mcp_client.py,sha256=LsOyVg_uR4Ik6d3vJQ3sfIKBG49X2IloUGn2P2jQ1AU,14085
44
+ astrbot/core/agent/message.py,sha256=kKVCGCGmbNENlWitTCGycos6uNRPuDys5jecOJDsuWQ,5336
45
45
  astrbot/core/agent/response.py,sha256=ddJABXu03Uw3b-YGTvRafFLJEGa40o93pIEz_CRTb4g,261
46
46
  astrbot/core/agent/run_context.py,sha256=h-teucYKYi5o4oTbAsIlkaa04yn2OSNC-ahIF2n6cwE,719
47
47
  astrbot/core/agent/tool.py,sha256=3F-zcADIJkACNljrlDJBZZCJwqhxFkfpgoKvg5v0TQM,9276
@@ -51,13 +51,14 @@ astrbot/core/agent/runners/base.py,sha256=5vDPiI_65ZlmVpuak-A4K2NW4uVhVD6wYRERKb
51
51
  astrbot/core/agent/runners/tool_loop_agent_runner.py,sha256=1bbuYHBz7A3U68Rl-ubG_-u_l4qjVTufkotQdBrIO8M,16781
52
52
  astrbot/core/config/__init__.py,sha256=vZjtpC7vr-IvBgSUtbS04C0wpulmCG5tPmcEP1WYE_4,172
53
53
  astrbot/core/config/astrbot_config.py,sha256=nGyvHyR9VJH9Pk0XKYyeDFVxjwbyVb9u0lIsuvpe3fg,6276
54
- astrbot/core/config/default.py,sha256=RdaNP0ECr86PC4HfgJNToZ_ccNZjh1YnkCULvqS567c,135898
55
- astrbot/core/db/__init__.py,sha256=XA1ootJl_SoMHG6sNUWNR5nj663JHvNF--WEM-hfd1o,8965
56
- astrbot/core/db/po.py,sha256=jLrmhbtqbnjZ1r7sS0WO6SZIubZr1FH04qmD64N4Y50,7845
57
- astrbot/core/db/sqlite.py,sha256=H7DOQDktJ3gRFwK0H9TFb3miJqnpx5pRFjwdTETWhWo,26520
54
+ astrbot/core/config/default.py,sha256=lA-1SepLA11TV0LzmbKW_C2kSQVXJFuX3dkrb1ACllI,136327
55
+ astrbot/core/db/__init__.py,sha256=s4oIWazGk2U1-9dkr3bvq8M4g9nwOXy4e3f53zlvAJk,10326
56
+ astrbot/core/db/po.py,sha256=w4NaoMc8112YMT3H3NBMOd0HQyuphZ5sTUjU8vZOHR8,9406
57
+ astrbot/core/db/sqlite.py,sha256=F117PS3BIss6-NuXOeTWV_8CVkSDCjqGnLf3yuftQjg,30076
58
58
  astrbot/core/db/migration/helper.py,sha256=Kogq0FLJdvWTDuAVWLT1PlTGGJcWkDMWO37KM-G8lTk,2087
59
59
  astrbot/core/db/migration/migra_3_to_4.py,sha256=hNn_tMququot1qUg3cx_nzxODxcZSlf4M_7YtBgKl2o,15277
60
60
  astrbot/core/db/migration/migra_45_to_46.py,sha256=wQk8NUiCNgmpSczO9U-OW6mMRHPWtJDlKuTCOGF8-WY,1560
61
+ astrbot/core/db/migration/migra_webchat_session.py,sha256=OXgosbb0d6cSQ-x_N_RRjLiy0SUAtUQ5GBL72xpEAH8,5249
61
62
  astrbot/core/db/migration/shared_preferences_v3.py,sha256=91zq_MrdAMF1MH5fxLaFkZO19nPNIW4gwqCCRn9u2dQ,1241
62
63
  astrbot/core/db/migration/sqlite_v3.py,sha256=pBBS5UemoVqus0aLJ5avqb3HgoN-b_S4fN5m4tBVf_U,15051
63
64
  astrbot/core/db/vec_db/base.py,sha256=0YxoCPNj_zVprLMamUj-OkUHJDlywIfdN8Q0Kpslm3A,1759
@@ -67,9 +68,10 @@ astrbot/core/db/vec_db/faiss_impl/embedding_storage.py,sha256=c4jk0y3tVsGBVI3I-x
67
68
  astrbot/core/db/vec_db/faiss_impl/sqlite_init.sql,sha256=RiF1mnAFAHtyThOsS0qjvniUF5t9Y8k-gjSlh51p2x8,681
68
69
  astrbot/core/db/vec_db/faiss_impl/vec_db.py,sha256=gZEXdHLIKx0aroD62RZjdY_L7-Twi9VrM594VlSkTuY,7094
69
70
  astrbot/core/knowledge_base/kb_db_sqlite.py,sha256=fkFqBZ1qjrPJoKjAzlckIdJriv5ky_ANQx2GIZqUSY8,10993
70
- astrbot/core/knowledge_base/kb_helper.py,sha256=FAhhmuVDErAKsZa-xqi00BpMxezVXYdTE13EaeOzKwU,12140
71
- astrbot/core/knowledge_base/kb_mgr.py,sha256=7K_RUdb49vcENFRQ2BDF6Hq3Zfx5SapXhBcETtCfbGU,9739
71
+ astrbot/core/knowledge_base/kb_helper.py,sha256=vg_PmGEbFFHQvCKJyQWd68uIdC4UGUncOnVJl7b4_qY,22666
72
+ astrbot/core/knowledge_base/kb_mgr.py,sha256=Iti0nf7MlN-r3XV-5HBHPOJkDusvM-230B0omFygqko,11117
72
73
  astrbot/core/knowledge_base/models.py,sha256=ugENK3bKXG9xP5Av0ls2kkclVVT68gB_wY2p5Q-pdjU,3982
74
+ astrbot/core/knowledge_base/prompts.py,sha256=4pn1rPvqUZY5-3SnUA0QYuI8LG8IQi0j1bDY5yjxg1c,2126
73
75
  astrbot/core/knowledge_base/chunking/__init__.py,sha256=haajNOd42ZA12a2kIdeZ31_QsTsL4rZRU5xaXJvs0Oo,155
74
76
  astrbot/core/knowledge_base/chunking/base.py,sha256=Zy5q6uA-ttPxpzbOGuFGlNlsCRWUeokMl0adQnWIZBA,471
75
77
  astrbot/core/knowledge_base/chunking/fixed_size.py,sha256=WUHJ400ZHJncAPRMkAIzgUbbuzvIwDkwzy-cORRiCSw,1559
@@ -79,6 +81,7 @@ astrbot/core/knowledge_base/parsers/base.py,sha256=4bQyCfXaQs5OFHi9fanhXshBaWkKw
79
81
  astrbot/core/knowledge_base/parsers/markitdown_parser.py,sha256=dmlQ1OwAND-e87fL227dAfumZ3CnZN29mmSQimE3naw,701
80
82
  astrbot/core/knowledge_base/parsers/pdf_parser.py,sha256=jDSyrJMwMH1VozlQNyG8agU4rP9YCNghe5OJGJxEoEY,3093
81
83
  astrbot/core/knowledge_base/parsers/text_parser.py,sha256=_lnGbZxDaFDVkv294hJmnY3JI6ybhrtZVI-8EALm5EI,1095
84
+ astrbot/core/knowledge_base/parsers/url_parser.py,sha256=q5vJQl8bscJKUtaNIHHGt4wbPv6weTB986A1C_o7TI8,3488
82
85
  astrbot/core/knowledge_base/parsers/util.py,sha256=YKtNg98vDv0d8F-RuGtkNUAYO_aQAWz2DlsVGaIMDig,396
83
86
  astrbot/core/knowledge_base/retrieval/__init__.py,sha256=Ou7mqN32YqKB99RHZTAqFHxN6ZpootzLtzUZe-Kjtw0,326
84
87
  astrbot/core/knowledge_base/retrieval/hit_stopwords.txt,sha256=8LikiRxpjLdAfJYyOQ2tUUPM9wEEZ0y3Mh_XXsxAeug,5271
@@ -99,8 +102,8 @@ astrbot/core/pipeline/content_safety_check/strategies/keywords.py,sha256=N3bR19D
99
102
  astrbot/core/pipeline/content_safety_check/strategies/strategy.py,sha256=XM2c-6apssEtAllMAI6BUXaEN_t2XINHcCoAudeKNwc,1206
100
103
  astrbot/core/pipeline/preprocess_stage/stage.py,sha256=BFaON3u4MrQUXp0ZXETU5MIvN_w0p0KJDNc9D7Y3qsY,4202
101
104
  astrbot/core/pipeline/process_stage/stage.py,sha256=yd1CpHbGzmLn-2C2QwvyAHa9WhsF7QKEqb_ojl6HJ6I,2679
102
- astrbot/core/pipeline/process_stage/utils.py,sha256=EPooTG8hs4uB8I8lMtRi23BkDjMu-7eM07v3O305po4,2593
103
- astrbot/core/pipeline/process_stage/method/llm_request.py,sha256=9H4cBgYCPDEqCNHPWVI8AHUd7WJnmSh-16-uY4-TH0w,18985
105
+ astrbot/core/pipeline/process_stage/utils.py,sha256=q4V5G0PZD5b5mPh1lM-6w79LKGpp7RR7-PqYFhWpopM,4061
106
+ astrbot/core/pipeline/process_stage/method/llm_request.py,sha256=viKwCVBIc0ccYjKHCa3pFcFIKz7AwPwTIKNNWaCfWfY,19695
104
107
  astrbot/core/pipeline/process_stage/method/star_request.py,sha256=cbZO2bcS3LIsk21DLO-V7rRrZed3fOjholafAVKDrvI,2515
105
108
  astrbot/core/pipeline/rate_limit_check/stage.py,sha256=9EVJ0zYtxATFsj7ADyWDYcSGBRqmrMiKWp1kkD9LONI,3962
106
109
  astrbot/core/pipeline/respond/stage.py,sha256=im_UrME-g-YOk9TnrDFzFeYIvzZsGBy9BDCAp5PXuNM,10738
@@ -156,18 +159,18 @@ astrbot/core/platform/sources/wecom/wecom_kf_message.py,sha256=__9zR3FCgggRDDwaE
156
159
  astrbot/core/platform/sources/wecom_ai_bot/WXBizJsonMsgCrypt.py,sha256=j6dV8PbpXzB0FNAU6JB4dB_T-aIjiKED4Ig0nBQjmCc,11406
157
160
  astrbot/core/platform/sources/wecom_ai_bot/__init__.py,sha256=WOYATxFKjq7ZIU0pf3M7MZVvW3ovxdAvXvB9PPJiSkc,435
158
161
  astrbot/core/platform/sources/wecom_ai_bot/ierror.py,sha256=6F08cRDiy3mbBLuTHgxkKIkgpXTQsNe4vnB4T1WvZe0,792
159
- astrbot/core/platform/sources/wecom_ai_bot/wecomai_adapter.py,sha256=7JVdujeCjnUH8fIfVwGkthfUt1u7Q85uiml5-33AiOQ,17444
162
+ astrbot/core/platform/sources/wecom_ai_bot/wecomai_adapter.py,sha256=ORvz6t0bU-rb__y5qxBScGHUBymItf2PnFnoCMAgI2o,17470
160
163
  astrbot/core/platform/sources/wecom_ai_bot/wecomai_api.py,sha256=ZDLQvAEQztFXgzBAamLWFFC3BPr7jEhcjEGAcqIUd9g,12008
161
- astrbot/core/platform/sources/wecom_ai_bot/wecomai_event.py,sha256=Bd3-dRPKBOTA2POWVbNUoOkX3AvNS6KVXx5RUyTb2oo,5076
162
- astrbot/core/platform/sources/wecom_ai_bot/wecomai_queue_mgr.py,sha256=fv06hqscDE5EQvXl8P3aAORppZ8RL4XcAouxmJz8o-g,4658
164
+ astrbot/core/platform/sources/wecom_ai_bot/wecomai_event.py,sha256=bo79QZtbxagBb-RhvUXOW4Xsy1deRFmDvAjzAXC-miQ,5228
165
+ astrbot/core/platform/sources/wecom_ai_bot/wecomai_queue_mgr.py,sha256=Vs1cSUe6xM145HPEUCzE5NxVWEUaIcnfx3o5TsNHcjA,4588
163
166
  astrbot/core/platform/sources/wecom_ai_bot/wecomai_server.py,sha256=hLhWV26Wa2HGBtw-eSKGq0LAeCS7HNNDnSRm7OuHJSQ,5280
164
167
  astrbot/core/platform/sources/wecom_ai_bot/wecomai_utils.py,sha256=6vTeKwrt-zXsA0Lt_7GFk7_J0IXWX-ErVvwK9VC0EDM,5427
165
168
  astrbot/core/platform/sources/weixin_official_account/weixin_offacc_adapter.py,sha256=IbOUuf9BnFjG8Dt18xNB3jKXxg09QspDBRThBHtQxtY,10659
166
169
  astrbot/core/platform/sources/weixin_official_account/weixin_offacc_event.py,sha256=_DYWTs5u3MoOKt-7eIH7fGHIpvxae2qckkceH9X9DCQ,7100
167
170
  astrbot/core/provider/__init__.py,sha256=0NVyKtTapnrUy0lkXVYWyM5KetwtDwXmTwBzqLG0MA4,142
168
171
  astrbot/core/provider/entites.py,sha256=0eYiQ-xttqFTb3WZR2b1oemdZy3d5sevELvj9FixJtE,388
169
- astrbot/core/provider/entities.py,sha256=LY0VxEXuLDwUxWJb8Gae2qjmT3UCUKNduE0qoM3ZboU,11718
170
- astrbot/core/provider/func_tool_manager.py,sha256=wJ0wFMofTV8atFKe9kGwJYlxFpAhY-g8rdsC1fa-Vrg,21014
172
+ astrbot/core/provider/entities.py,sha256=AwD8KOG8dSlfQXSc1n8gx4xv2vW4niZDiaMoO1Y_dOw,12533
173
+ astrbot/core/provider/func_tool_manager.py,sha256=28fOKbpWOxiclwfcNkmP6sHSBlK4cZKwPXyNhFjjXps,21181
171
174
  astrbot/core/provider/manager.py,sha256=OzoEniML-bxbIO1GG2IMnzVDZ-IlVGQCbBFB0MB4zZw,22592
172
175
  astrbot/core/provider/provider.py,sha256=bMJBBZzNwHhVv8dEiO1tNUclzxS78Yb01vUbceHZXKA,10680
173
176
  astrbot/core/provider/register.py,sha256=0WMYrT9vbRjeq-72HD0oRT45kJmeKA96UgSItpTJbX8,1904
@@ -181,14 +184,14 @@ astrbot/core/provider/sources/dify_source.py,sha256=w6xG9oUlhlMivYjfAufRxIj8xijm
181
184
  astrbot/core/provider/sources/edge_tts_source.py,sha256=7C04B0voPmQdeaB4u-U5Lip6qN3UAyB_yNPBYHLaxo8,4680
182
185
  astrbot/core/provider/sources/fishaudio_tts_api_source.py,sha256=P2N_dkwxx3Kk1uWae1TT4yJShj6i0Q_jTpWT1V_dLQ0,5484
183
186
  astrbot/core/provider/sources/gemini_embedding_source.py,sha256=XpTqb5rlI5z34FmrdFkpvwkk9BiuyFKcpWm6xQEHpNE,2248
184
- astrbot/core/provider/sources/gemini_source.py,sha256=A1VBbHFd8UFk21smt8Y2eUa35HT7dw2Fu9Ts_i-YrcU,30238
187
+ astrbot/core/provider/sources/gemini_source.py,sha256=msWhkuvNw4BD7-Y-HPkcNj7DZBmlxOLSK7XESB54JEI,31322
185
188
  astrbot/core/provider/sources/gemini_tts_source.py,sha256=6LJIT2aTjoZaMszjYRzDu38prsO9G5Xg7SzJmQb2TzE,2880
186
189
  astrbot/core/provider/sources/groq_source.py,sha256=NqmiQn37mrMsaTyGX25eNzMpIgkCifY-5TJO8DFzHaA,456
187
190
  astrbot/core/provider/sources/gsv_selfhosted_source.py,sha256=RYQgwCc67N7RWPaODN4sSLJZn6o5gpgk_jF_KaRnD0M,5942
188
191
  astrbot/core/provider/sources/gsvi_tts_source.py,sha256=nGGctfkzrAeTofAvB2b_VNTYHW44SzyO12B-mBWb1rY,2011
189
192
  astrbot/core/provider/sources/minimax_tts_api_source.py,sha256=qMN6iBR2V145d5BAIkjAa2pVrH5eZOHeWnd8yhemOCY,5837
190
193
  astrbot/core/provider/sources/openai_embedding_source.py,sha256=26hjOYrQ8eHHPi8wybCubtsY-UOOfGx0qcCxQ3BvjIE,1616
191
- astrbot/core/provider/sources/openai_source.py,sha256=4GvBLMv5aBzn0hBZCjORLCDROsV4PcwCK0K5XLBITik,24654
194
+ astrbot/core/provider/sources/openai_source.py,sha256=FU1xEYkoRZrc-AB6Hf6I4iHU8nbl22k0i5nhHxAKAuw,24275
192
195
  astrbot/core/provider/sources/openai_tts_api_source.py,sha256=DVviGQdBpCk6lW3LjnJHzwZr9wGkXRDNwfoQ3FYFVcs,1667
193
196
  astrbot/core/provider/sources/sensevoice_selfhosted_source.py,sha256=aG7m3HvqSdcTRJcncqFNhyz9D-TVIdjiCbGFQPhDcdM,3819
194
197
  astrbot/core/provider/sources/vllm_rerank_source.py,sha256=5mZwtOUG1w7AfqQR7AYznxL_L0HVOKq6_T2G0CrNkZg,2316
@@ -244,11 +247,11 @@ astrbot/dashboard/server.py,sha256=HiuqrnMKWOER8j6h1ZAIAONUb3DwJCEjXl7LkLFXMiI,9
244
247
  astrbot/dashboard/utils.py,sha256=KrAv0lnPaVR0bx8yevT1CLGbSNsJizlfkKkPEtVVANI,5355
245
248
  astrbot/dashboard/routes/__init__.py,sha256=IKg0EzasXsd-OleSixE54Ul5wQcBeMHzVwhhjMFZ2dE,783
246
249
  astrbot/dashboard/routes/auth.py,sha256=rYkvt3MpCY9BhWjG0DUoX3YaBkJT1Id7M2pKqTmXbvo,2946
247
- astrbot/dashboard/routes/chat.py,sha256=ME9CjZ1tKGfGYyQ719sP0hQFVcLkCJHAYDrKjonhPcU,13563
250
+ astrbot/dashboard/routes/chat.py,sha256=Mtw7tqt1xoXaPgutkJsOF2h_Sq3TZmyjSYH2acl8WkA,15032
248
251
  astrbot/dashboard/routes/config.py,sha256=DHWd56JZrtXdxuf80DIfmyFYmeOcZ6mC8aCKZc6QacA,40070
249
252
  astrbot/dashboard/routes/conversation.py,sha256=sFHgkpNDdTR9qkSOC_JfSjzkfTuv63iaMxvh52wQUzM,10773
250
253
  astrbot/dashboard/routes/file.py,sha256=gULvXP9PnVOQlyv_PCEzZQE5ptnGQEjFPvwOLxdVgb4,708
251
- astrbot/dashboard/routes/knowledge_base.py,sha256=B4q9Zkph95xcNRIluKSIgTH0mL7KjPGXp7UzJjQ4S54,39584
254
+ astrbot/dashboard/routes/knowledge_base.py,sha256=Sc03tTpfAhtA5ErofRUwERwx01_vyrWWGlposc8gdvU,45595
252
255
  astrbot/dashboard/routes/log.py,sha256=84OFiLM-Cnqf3HxFne-ykUezfnArlwH4HyY8MJxch00,2143
253
256
  astrbot/dashboard/routes/persona.py,sha256=MEcNHMxJmyvZ3ZhytI5IP7L3FSlMr1JDvdd5efN9Q-M,7833
254
257
  astrbot/dashboard/routes/plugin.py,sha256=lc50jRSRcJfpKMrT1OlFDuA7e841SSCEyEhFXiX742c,20508
@@ -259,8 +262,8 @@ astrbot/dashboard/routes/static_file.py,sha256=7KnNcOb1BVqSTft114LhGsDkfg69X2jHE
259
262
  astrbot/dashboard/routes/t2i.py,sha256=F6smxdL99MF7cRw3hqS6-2GErw8Zhsv0V0mfBUeEk-c,8931
260
263
  astrbot/dashboard/routes/tools.py,sha256=YsVFrwVIhxAI-Ikme7YPrHVnPVTkJ1IaH7n6ciREjdE,14663
261
264
  astrbot/dashboard/routes/update.py,sha256=qXiqQ_dbqRVftOzGgCQrvK8-qopVK6zKhhVVJ9SK26U,6648
262
- astrbot-4.5.8.dist-info/METADATA,sha256=tNASBEgbAu1-hgtG2NFcsbaLS9vqHYv_GS8a6rU4p3Q,10029
263
- astrbot-4.5.8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
264
- astrbot-4.5.8.dist-info/entry_points.txt,sha256=OEF09YmhBWYuViXrvTLLpstF4ccmNwDL8r7nnFD0pfI,53
265
- astrbot-4.5.8.dist-info/licenses/LICENSE,sha256=zPfQj5Mq8-gThIiBcxETr7t8gND9bZWOjTGQAr80TQI,34500
266
- astrbot-4.5.8.dist-info/RECORD,,
265
+ astrbot-4.6.0.dist-info/METADATA,sha256=xugOHJn1hx--yvwaSY3uBlEds-BOHTzEV2p7dGZ34XU,10069
266
+ astrbot-4.6.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
267
+ astrbot-4.6.0.dist-info/entry_points.txt,sha256=OEF09YmhBWYuViXrvTLLpstF4ccmNwDL8r7nnFD0pfI,53
268
+ astrbot-4.6.0.dist-info/licenses/LICENSE,sha256=zPfQj5Mq8-gThIiBcxETr7t8gND9bZWOjTGQAr80TQI,34500
269
+ astrbot-4.6.0.dist-info/RECORD,,