AstrBot 4.3.5__py3-none-any.whl → 4.5.1__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/core/agent/runners/tool_loop_agent_runner.py +31 -2
- astrbot/core/astrbot_config_mgr.py +23 -51
- astrbot/core/config/default.py +132 -12
- astrbot/core/conversation_mgr.py +36 -1
- astrbot/core/core_lifecycle.py +24 -5
- astrbot/core/db/migration/helper.py +6 -3
- astrbot/core/db/migration/migra_45_to_46.py +44 -0
- astrbot/core/db/vec_db/base.py +33 -2
- astrbot/core/db/vec_db/faiss_impl/document_storage.py +310 -52
- astrbot/core/db/vec_db/faiss_impl/embedding_storage.py +31 -3
- astrbot/core/db/vec_db/faiss_impl/vec_db.py +81 -23
- astrbot/core/file_token_service.py +6 -1
- astrbot/core/initial_loader.py +6 -3
- astrbot/core/knowledge_base/chunking/__init__.py +11 -0
- astrbot/core/knowledge_base/chunking/base.py +24 -0
- astrbot/core/knowledge_base/chunking/fixed_size.py +57 -0
- astrbot/core/knowledge_base/chunking/recursive.py +155 -0
- astrbot/core/knowledge_base/kb_db_sqlite.py +299 -0
- astrbot/core/knowledge_base/kb_helper.py +348 -0
- astrbot/core/knowledge_base/kb_mgr.py +287 -0
- astrbot/core/knowledge_base/models.py +114 -0
- astrbot/core/knowledge_base/parsers/__init__.py +15 -0
- astrbot/core/knowledge_base/parsers/base.py +50 -0
- astrbot/core/knowledge_base/parsers/markitdown_parser.py +25 -0
- astrbot/core/knowledge_base/parsers/pdf_parser.py +100 -0
- astrbot/core/knowledge_base/parsers/text_parser.py +41 -0
- astrbot/core/knowledge_base/parsers/util.py +13 -0
- astrbot/core/knowledge_base/retrieval/__init__.py +16 -0
- astrbot/core/knowledge_base/retrieval/hit_stopwords.txt +767 -0
- astrbot/core/knowledge_base/retrieval/manager.py +273 -0
- astrbot/core/knowledge_base/retrieval/rank_fusion.py +138 -0
- astrbot/core/knowledge_base/retrieval/sparse_retriever.py +130 -0
- astrbot/core/pipeline/process_stage/method/llm_request.py +29 -7
- astrbot/core/pipeline/process_stage/utils.py +80 -0
- astrbot/core/platform/astr_message_event.py +8 -7
- astrbot/core/platform/sources/dingtalk/dingtalk_adapter.py +5 -2
- astrbot/core/platform/sources/misskey/misskey_adapter.py +380 -44
- astrbot/core/platform/sources/misskey/misskey_api.py +581 -45
- astrbot/core/platform/sources/misskey/misskey_event.py +76 -41
- astrbot/core/platform/sources/misskey/misskey_utils.py +254 -43
- astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_server.py +2 -1
- astrbot/core/platform/sources/satori/satori_adapter.py +27 -1
- astrbot/core/platform/sources/satori/satori_event.py +270 -99
- astrbot/core/provider/manager.py +22 -9
- astrbot/core/provider/provider.py +67 -0
- astrbot/core/provider/sources/anthropic_source.py +4 -4
- astrbot/core/provider/sources/dashscope_source.py +10 -9
- astrbot/core/provider/sources/dify_source.py +6 -8
- astrbot/core/provider/sources/gemini_embedding_source.py +1 -2
- astrbot/core/provider/sources/openai_embedding_source.py +1 -2
- astrbot/core/provider/sources/openai_source.py +43 -15
- astrbot/core/provider/sources/openai_tts_api_source.py +1 -1
- astrbot/core/provider/sources/xinference_rerank_source.py +108 -0
- astrbot/core/provider/sources/xinference_stt_provider.py +187 -0
- astrbot/core/star/context.py +19 -13
- astrbot/core/star/star.py +6 -0
- astrbot/core/star/star_manager.py +13 -7
- astrbot/core/umop_config_router.py +81 -0
- astrbot/core/updator.py +1 -1
- astrbot/core/utils/io.py +23 -12
- astrbot/dashboard/routes/__init__.py +2 -0
- astrbot/dashboard/routes/config.py +137 -9
- astrbot/dashboard/routes/knowledge_base.py +1065 -0
- astrbot/dashboard/routes/plugin.py +24 -5
- astrbot/dashboard/routes/update.py +1 -1
- astrbot/dashboard/server.py +6 -0
- astrbot/dashboard/utils.py +161 -0
- {astrbot-4.3.5.dist-info → astrbot-4.5.1.dist-info}/METADATA +30 -13
- {astrbot-4.3.5.dist-info → astrbot-4.5.1.dist-info}/RECORD +72 -46
- {astrbot-4.3.5.dist-info → astrbot-4.5.1.dist-info}/WHEEL +0 -0
- {astrbot-4.3.5.dist-info → astrbot-4.5.1.dist-info}/entry_points.txt +0 -0
- {astrbot-4.3.5.dist-info → astrbot-4.5.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -8,7 +8,7 @@ import ssl
|
|
|
8
8
|
import certifi
|
|
9
9
|
|
|
10
10
|
from .route import Route, Response, RouteContext
|
|
11
|
-
from astrbot.core import logger
|
|
11
|
+
from astrbot.core import logger, file_token_service
|
|
12
12
|
from quart import request
|
|
13
13
|
from astrbot.core.star.star_manager import PluginManager
|
|
14
14
|
from astrbot.core.core_lifecycle import AstrBotCoreLifecycle
|
|
@@ -54,6 +54,8 @@ class PluginRoute(Route):
|
|
|
54
54
|
EventType.OnAfterMessageSentEvent: "发送消息后",
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
self._logo_cache = {}
|
|
58
|
+
|
|
57
59
|
async def reload_plugins(self):
|
|
58
60
|
if DEMO_MODE:
|
|
59
61
|
return (
|
|
@@ -147,7 +149,7 @@ class PluginRoute(Route):
|
|
|
147
149
|
return False
|
|
148
150
|
|
|
149
151
|
# 加载缓存文件
|
|
150
|
-
with open(cache_file,
|
|
152
|
+
with open(cache_file, encoding="utf-8") as f:
|
|
151
153
|
cache_data = json.load(f)
|
|
152
154
|
|
|
153
155
|
cached_md5 = cache_data.get("md5")
|
|
@@ -197,7 +199,7 @@ class PluginRoute(Route):
|
|
|
197
199
|
"""加载本地缓存的插件市场数据"""
|
|
198
200
|
try:
|
|
199
201
|
if os.path.exists(cache_file):
|
|
200
|
-
with open(cache_file,
|
|
202
|
+
with open(cache_file, encoding="utf-8") as f:
|
|
201
203
|
cache_data = json.load(f)
|
|
202
204
|
# 检查缓存是否有效
|
|
203
205
|
if "data" in cache_data and "timestamp" in cache_data:
|
|
@@ -209,7 +211,7 @@ class PluginRoute(Route):
|
|
|
209
211
|
logger.warning(f"加载插件市场缓存失败: {e}")
|
|
210
212
|
return None
|
|
211
213
|
|
|
212
|
-
def _save_plugin_cache(self, cache_file: str, data, md5: str = None):
|
|
214
|
+
def _save_plugin_cache(self, cache_file: str, data, md5: str | None = None):
|
|
213
215
|
"""保存插件市场数据到本地缓存"""
|
|
214
216
|
try:
|
|
215
217
|
# 确保目录存在
|
|
@@ -227,12 +229,27 @@ class PluginRoute(Route):
|
|
|
227
229
|
except Exception as e:
|
|
228
230
|
logger.warning(f"保存插件市场缓存失败: {e}")
|
|
229
231
|
|
|
232
|
+
async def get_plugin_logo_token(self, logo_path: str):
|
|
233
|
+
try:
|
|
234
|
+
if token := self._logo_cache.get(logo_path):
|
|
235
|
+
if not await file_token_service.check_token_expired(token):
|
|
236
|
+
return self._logo_cache[logo_path]
|
|
237
|
+
token = await file_token_service.register_file(logo_path, timeout=300)
|
|
238
|
+
self._logo_cache[logo_path] = token
|
|
239
|
+
return token
|
|
240
|
+
except Exception as e:
|
|
241
|
+
logger.warning(f"获取插件 Logo 失败: {e}")
|
|
242
|
+
return None
|
|
243
|
+
|
|
230
244
|
async def get_plugins(self):
|
|
231
245
|
_plugin_resp = []
|
|
232
246
|
plugin_name = request.args.get("name")
|
|
233
247
|
for plugin in self.plugin_manager.context.get_all_stars():
|
|
234
248
|
if plugin_name and plugin.name != plugin_name:
|
|
235
249
|
continue
|
|
250
|
+
logo_url = None
|
|
251
|
+
if plugin.logo_path:
|
|
252
|
+
logo_url = await self.get_plugin_logo_token(plugin.logo_path)
|
|
236
253
|
_t = {
|
|
237
254
|
"name": plugin.name,
|
|
238
255
|
"repo": "" if plugin.repo is None else plugin.repo,
|
|
@@ -245,6 +262,8 @@ class PluginRoute(Route):
|
|
|
245
262
|
"handlers": await self.get_plugin_handlers_info(
|
|
246
263
|
plugin.star_handler_full_names
|
|
247
264
|
),
|
|
265
|
+
"display_name": plugin.display_name,
|
|
266
|
+
"logo": f"/api/file/{logo_url}" if logo_url else None,
|
|
248
267
|
}
|
|
249
268
|
_plugin_resp.append(_t)
|
|
250
269
|
return (
|
|
@@ -469,7 +488,7 @@ class PluginRoute(Route):
|
|
|
469
488
|
return Response().error(f"插件 {plugin_name} 没有README文件").__dict__
|
|
470
489
|
|
|
471
490
|
try:
|
|
472
|
-
with open(readme_path,
|
|
491
|
+
with open(readme_path, encoding="utf-8") as f:
|
|
473
492
|
readme_content = f.read()
|
|
474
493
|
|
|
475
494
|
return (
|
|
@@ -67,7 +67,7 @@ class UpdateRoute(Route):
|
|
|
67
67
|
"version": f"v{VERSION}",
|
|
68
68
|
"has_new_version": ret is not None,
|
|
69
69
|
"dashboard_version": dv,
|
|
70
|
-
"dashboard_has_new_version": dv and dv != f"v{VERSION}",
|
|
70
|
+
"dashboard_has_new_version": bool(dv and dv != f"v{VERSION}"),
|
|
71
71
|
},
|
|
72
72
|
).__dict__
|
|
73
73
|
except Exception as e:
|
astrbot/dashboard/server.py
CHANGED
|
@@ -72,6 +72,7 @@ class AstrBotDashboard:
|
|
|
72
72
|
)
|
|
73
73
|
self.persona_route = PersonaRoute(self.context, db, core_lifecycle)
|
|
74
74
|
self.t2i_route = T2iRoute(self.context, core_lifecycle)
|
|
75
|
+
self.kb_route = KnowledgeBaseRoute(self.context, core_lifecycle)
|
|
75
76
|
|
|
76
77
|
self.app.add_url_rule(
|
|
77
78
|
"/api/plug/<path:subpath>",
|
|
@@ -177,6 +178,11 @@ class AstrBotDashboard:
|
|
|
177
178
|
else:
|
|
178
179
|
port = self.core_lifecycle.astrbot_config["dashboard"].get("port", 6185)
|
|
179
180
|
host = self.core_lifecycle.astrbot_config["dashboard"].get("host", "0.0.0.0")
|
|
181
|
+
enable = self.core_lifecycle.astrbot_config["dashboard"].get("enable", True)
|
|
182
|
+
|
|
183
|
+
if not enable:
|
|
184
|
+
logger.info("WebUI 已被禁用")
|
|
185
|
+
return
|
|
180
186
|
|
|
181
187
|
logger.info(f"正在启动 WebUI, 监听地址: http://{host}:{port}")
|
|
182
188
|
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
import os
|
|
3
|
+
import traceback
|
|
4
|
+
from io import BytesIO
|
|
5
|
+
from astrbot.api import logger
|
|
6
|
+
from astrbot.core.knowledge_base.kb_helper import KBHelper
|
|
7
|
+
from astrbot.core.knowledge_base.kb_mgr import KnowledgeBaseManager
|
|
8
|
+
from astrbot.core.db.vec_db.faiss_impl import FaissVecDB
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
async def generate_tsne_visualization(
|
|
12
|
+
query: str, kb_names: list[str], kb_manager: KnowledgeBaseManager
|
|
13
|
+
) -> str | None:
|
|
14
|
+
"""生成 t-SNE 可视化图片
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
query: 查询文本
|
|
18
|
+
kb_names: 知识库名称列表
|
|
19
|
+
kb_manager: 知识库管理器
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
图片路径或 None
|
|
23
|
+
"""
|
|
24
|
+
try:
|
|
25
|
+
import faiss
|
|
26
|
+
import numpy as np
|
|
27
|
+
import matplotlib
|
|
28
|
+
|
|
29
|
+
matplotlib.use("Agg") # 使用非交互式后端
|
|
30
|
+
import matplotlib.pyplot as plt
|
|
31
|
+
from sklearn.manifold import TSNE
|
|
32
|
+
except ImportError as e:
|
|
33
|
+
raise Exception(
|
|
34
|
+
"缺少必要的库以生成 t-SNE 可视化。请安装 matplotlib 和 scikit-learn: {e}"
|
|
35
|
+
) from e
|
|
36
|
+
|
|
37
|
+
try:
|
|
38
|
+
# 获取第一个知识库的向量数据
|
|
39
|
+
kb_helper: KBHelper | None = None
|
|
40
|
+
for kb_name in kb_names:
|
|
41
|
+
kb_helper = await kb_manager.get_kb_by_name(kb_name)
|
|
42
|
+
if kb_helper:
|
|
43
|
+
break
|
|
44
|
+
|
|
45
|
+
if not kb_helper:
|
|
46
|
+
logger.warning("未找到知识库")
|
|
47
|
+
return None
|
|
48
|
+
|
|
49
|
+
kb = kb_helper.kb
|
|
50
|
+
index_path = f"data/knowledge_base/{kb.kb_id}/index.faiss"
|
|
51
|
+
|
|
52
|
+
# 读取 FAISS 索引
|
|
53
|
+
if not os.path.exists(index_path):
|
|
54
|
+
logger.warning(f"FAISS 索引不存在: {index_path}")
|
|
55
|
+
return None
|
|
56
|
+
|
|
57
|
+
index = faiss.read_index(index_path)
|
|
58
|
+
|
|
59
|
+
if index.ntotal == 0:
|
|
60
|
+
logger.warning("索引为空")
|
|
61
|
+
return None
|
|
62
|
+
|
|
63
|
+
# 提取所有向量
|
|
64
|
+
logger.info(f"提取 {index.ntotal} 个向量用于可视化...")
|
|
65
|
+
if isinstance(index, faiss.IndexIDMap):
|
|
66
|
+
base_index = faiss.downcast_index(index.index)
|
|
67
|
+
if hasattr(base_index, "reconstruct_n"):
|
|
68
|
+
vectors = base_index.reconstruct_n(0, index.ntotal)
|
|
69
|
+
else:
|
|
70
|
+
vectors = np.zeros((index.ntotal, index.d), dtype=np.float32)
|
|
71
|
+
for i in range(index.ntotal):
|
|
72
|
+
base_index.reconstruct(i, vectors[i])
|
|
73
|
+
elif hasattr(index, "reconstruct_n"):
|
|
74
|
+
vectors = index.reconstruct_n(0, index.ntotal)
|
|
75
|
+
else:
|
|
76
|
+
vectors = np.zeros((index.ntotal, index.d), dtype=np.float32)
|
|
77
|
+
for i in range(index.ntotal):
|
|
78
|
+
index.reconstruct(i, vectors[i])
|
|
79
|
+
|
|
80
|
+
# 获取查询向量
|
|
81
|
+
vec_db: FaissVecDB = kb_helper.vec_db # type: ignore
|
|
82
|
+
embedding_provider = vec_db.embedding_provider
|
|
83
|
+
query_embedding = await embedding_provider.get_embedding(query)
|
|
84
|
+
query_vector = np.array([query_embedding], dtype=np.float32)
|
|
85
|
+
|
|
86
|
+
# 合并所有向量和查询向量
|
|
87
|
+
all_vectors = np.vstack([vectors, query_vector])
|
|
88
|
+
|
|
89
|
+
# t-SNE 降维
|
|
90
|
+
logger.info("开始 t-SNE 降维...")
|
|
91
|
+
perplexity = min(30, all_vectors.shape[0] - 1)
|
|
92
|
+
tsne = TSNE(n_components=2, random_state=42, perplexity=perplexity)
|
|
93
|
+
vectors_2d = tsne.fit_transform(all_vectors)
|
|
94
|
+
|
|
95
|
+
# 分离知识库向量和查询向量
|
|
96
|
+
kb_vectors_2d = vectors_2d[:-1]
|
|
97
|
+
query_vector_2d = vectors_2d[-1]
|
|
98
|
+
|
|
99
|
+
# 可视化
|
|
100
|
+
logger.info("生成可视化图表...")
|
|
101
|
+
plt.figure(figsize=(14, 10))
|
|
102
|
+
|
|
103
|
+
# 绘制知识库向量
|
|
104
|
+
scatter = plt.scatter(
|
|
105
|
+
kb_vectors_2d[:, 0],
|
|
106
|
+
kb_vectors_2d[:, 1],
|
|
107
|
+
alpha=0.5,
|
|
108
|
+
s=40,
|
|
109
|
+
c=range(len(kb_vectors_2d)),
|
|
110
|
+
cmap="viridis",
|
|
111
|
+
label="Knowledge Base Vectors",
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
# 绘制查询向量(红色 X)
|
|
115
|
+
plt.scatter(
|
|
116
|
+
query_vector_2d[0],
|
|
117
|
+
query_vector_2d[1],
|
|
118
|
+
c="red",
|
|
119
|
+
s=300,
|
|
120
|
+
marker="X",
|
|
121
|
+
edgecolors="black",
|
|
122
|
+
linewidths=2,
|
|
123
|
+
label="Query",
|
|
124
|
+
zorder=5,
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
# 添加查询文本标注
|
|
128
|
+
plt.annotate(
|
|
129
|
+
"Query",
|
|
130
|
+
(query_vector_2d[0], query_vector_2d[1]),
|
|
131
|
+
xytext=(10, 10),
|
|
132
|
+
textcoords="offset points",
|
|
133
|
+
fontsize=10,
|
|
134
|
+
bbox={"boxstyle": "round,pad=0.5", "fc": "yellow", "alpha": 0.7},
|
|
135
|
+
arrowprops={"arrowstyle": "->", "connectionstyle": "arc3,rad=0"},
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
plt.colorbar(scatter, label="Vector Index")
|
|
139
|
+
plt.title(
|
|
140
|
+
f"t-SNE Visualization: Query in Knowledge Base\n"
|
|
141
|
+
f"({index.ntotal} vectors, {index.d} dimensions, KB: {kb.kb_name})",
|
|
142
|
+
fontsize=14,
|
|
143
|
+
pad=20,
|
|
144
|
+
)
|
|
145
|
+
plt.xlabel("t-SNE Dimension 1", fontsize=12)
|
|
146
|
+
plt.ylabel("t-SNE Dimension 2", fontsize=12)
|
|
147
|
+
plt.grid(True, alpha=0.3)
|
|
148
|
+
plt.legend(fontsize=10, loc="upper right")
|
|
149
|
+
|
|
150
|
+
# base64 编码图片返回
|
|
151
|
+
buffer = BytesIO()
|
|
152
|
+
plt.savefig(buffer, format="png", dpi=150, bbox_inches="tight")
|
|
153
|
+
plt.close()
|
|
154
|
+
buffer.seek(0)
|
|
155
|
+
img_base64 = base64.b64encode(buffer.read()).decode("utf-8")
|
|
156
|
+
return img_base64
|
|
157
|
+
|
|
158
|
+
except Exception as e:
|
|
159
|
+
logger.error(f"生成 t-SNE 可视化时出错: {e}")
|
|
160
|
+
logger.error(traceback.format_exc())
|
|
161
|
+
return None
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: AstrBot
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.5.1
|
|
4
4
|
Summary: 易上手的多平台 LLM 聊天机器人及开发框架
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Requires-Python: >=3.10
|
|
7
7
|
Requires-Dist: aiocqhttp>=1.4.4
|
|
8
8
|
Requires-Dist: aiodocker>=0.24.0
|
|
9
|
+
Requires-Dist: aiofiles>=25.1.0
|
|
9
10
|
Requires-Dist: aiohttp>=3.11.18
|
|
10
11
|
Requires-Dist: aiosqlite>=0.21.0
|
|
11
12
|
Requires-Dist: anthropic>=0.51.0
|
|
@@ -25,10 +26,11 @@ Requires-Dist: docstring-parser>=0.16
|
|
|
25
26
|
Requires-Dist: faiss-cpu==1.10.0
|
|
26
27
|
Requires-Dist: filelock>=3.18.0
|
|
27
28
|
Requires-Dist: google-genai>=1.14.0
|
|
29
|
+
Requires-Dist: jieba>=0.42.1
|
|
28
30
|
Requires-Dist: lark-oapi>=1.4.15
|
|
29
31
|
Requires-Dist: lxml-html-clean>=0.4.2
|
|
32
|
+
Requires-Dist: markitdown-no-magika[docx,xls,xlsx]>=0.1.2
|
|
30
33
|
Requires-Dist: mcp>=1.8.0
|
|
31
|
-
Requires-Dist: mi-googlesearch-python==1.3.0.post1
|
|
32
34
|
Requires-Dist: openai>=1.78.0
|
|
33
35
|
Requires-Dist: ormsgpack>=1.9.1
|
|
34
36
|
Requires-Dist: pillow>=11.2.1
|
|
@@ -38,9 +40,11 @@ Requires-Dist: py-cord>=2.6.1
|
|
|
38
40
|
Requires-Dist: pydantic~=2.10.3
|
|
39
41
|
Requires-Dist: pydub>=0.25.1
|
|
40
42
|
Requires-Dist: pyjwt>=2.10.1
|
|
43
|
+
Requires-Dist: pypdf>=6.1.1
|
|
41
44
|
Requires-Dist: python-telegram-bot>=22.0
|
|
42
45
|
Requires-Dist: qq-botpy>=1.2.1
|
|
43
46
|
Requires-Dist: quart>=0.20.0
|
|
47
|
+
Requires-Dist: rank-bm25>=0.2.2
|
|
44
48
|
Requires-Dist: readability-lxml>=0.8.4.1
|
|
45
49
|
Requires-Dist: silk-python>=0.2.6
|
|
46
50
|
Requires-Dist: slack-sdk>=3.35.0
|
|
@@ -50,6 +54,7 @@ Requires-Dist: telegramify-markdown>=0.5.1
|
|
|
50
54
|
Requires-Dist: watchfiles>=1.0.5
|
|
51
55
|
Requires-Dist: websockets>=15.0.1
|
|
52
56
|
Requires-Dist: wechatpy>=1.8.18
|
|
57
|
+
Requires-Dist: xinference-client
|
|
53
58
|
Description-Content-Type: text/markdown
|
|
54
59
|
|
|
55
60
|

|
|
@@ -58,21 +63,32 @@ Description-Content-Type: text/markdown
|
|
|
58
63
|
|
|
59
64
|
<div align="center">
|
|
60
65
|
|
|
66
|
+
<br>
|
|
67
|
+
|
|
68
|
+
<div>
|
|
61
69
|
<a href="https://trendshift.io/repositories/12875" target="_blank"><img src="https://trendshift.io/api/badge/repositories/12875" alt="Soulter%2FAstrBot | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
|
|
70
|
+
<a href="https://hellogithub.com/repository/AstrBotDevs/AstrBot" target="_blank"><img src="https://api.hellogithub.com/v1/widgets/recommend.svg?rid=d127d50cd5e54c5382328acc3bb25483&claim_uid=ZO9by7qCXgSd6Lp&t=1" alt="Featured|HelloGitHub" style="width: 250px; height: 54px;" width="250" height="54" /></a>
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
<br>
|
|
62
74
|
|
|
63
|
-
|
|
75
|
+
<div>
|
|
76
|
+
<img src="https://img.shields.io/github/v/release/AstrBotDevs/AstrBot?style=for-the-badge&color=76bad9" href="https://github.com/AstrBotDevs/AstrBot/releases/latest">
|
|
64
77
|
<img src="https://img.shields.io/badge/python-3.10+-blue.svg?style=for-the-badge&color=76bad9" alt="python">
|
|
65
78
|
<a href="https://hub.docker.com/r/soulter/astrbot"><img alt="Docker pull" src="https://img.shields.io/docker/pulls/soulter/astrbot.svg?style=for-the-badge&color=76bad9"/></a>
|
|
66
|
-
<a
|
|
67
|
-
<a
|
|
68
|
-
|
|
79
|
+
<a href="https://qm.qq.com/cgi-bin/qm/qr?k=wtbaNx7EioxeaqS9z7RQWVXPIxg2zYr7&jump_from=webapi&authKey=vlqnv/AV2DbJEvGIcxdlNSpfxVy+8vVqijgreRdnVKOaydpc+YSw4MctmEbr0k5"><img alt="QQ_community" src="https://img.shields.io/badge/QQ群-775869627-purple?style=for-the-badge&color=76bad9"></a>
|
|
80
|
+
<a href="https://t.me/+hAsD2Ebl5as3NmY1"><img alt="Telegram_community" src="https://img.shields.io/badge/Telegram-AstrBot-purple?style=for-the-badge&color=76bad9"></a>
|
|
81
|
+
<img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fapi.soulter.top%2Fastrbot%2Fplugin-num&query=%24.result&suffix=%E4%B8%AA&style=for-the-badge&label=%E6%8F%92%E4%BB%B6%E5%B8%82%E5%9C%BA&cacheSeconds=3600">
|
|
82
|
+
</div>
|
|
83
|
+
|
|
84
|
+
<br>
|
|
69
85
|
|
|
70
|
-
<a href="https://github.com/
|
|
71
|
-
<a href="https://github.com/
|
|
86
|
+
<a href="https://github.com/AstrBotDevs/AstrBot/blob/master/README_en.md">English</a> |
|
|
87
|
+
<a href="https://github.com/AstrBotDevs/AstrBot/blob/master/README_ja.md">日本語</a> |
|
|
72
88
|
<a href="https://astrbot.app/">文档</a> |
|
|
73
89
|
<a href="https://blog.astrbot.app/">Blog</a> |
|
|
74
90
|
<a href="https://astrbot.featurebase.app/roadmap">路线图</a> |
|
|
75
|
-
<a href="https://github.com/
|
|
91
|
+
<a href="https://github.com/AstrBotDevs/AstrBot/issues">问题提交</a>
|
|
76
92
|
</div>
|
|
77
93
|
|
|
78
94
|
AstrBot 是一个开源的一站式 Agent 聊天机器人平台及开发框架。
|
|
@@ -115,7 +131,7 @@ AstrBot 已由雨云官方上架至云应用平台,可一键部署。
|
|
|
115
131
|
|
|
116
132
|
社区贡献的部署方式。
|
|
117
133
|
|
|
118
|
-
[](https://repl.it/github/AstrBotDevs/AstrBot)
|
|
119
135
|
|
|
120
136
|
#### Windows 一键安装器部署
|
|
121
137
|
|
|
@@ -172,6 +188,7 @@ uv run main.py
|
|
|
172
188
|
| QQ(OneBot) | ✔ |
|
|
173
189
|
| Telegram | ✔ |
|
|
174
190
|
| 企微应用 | ✔ |
|
|
191
|
+
| 企微智能机器人 | ✔ |
|
|
175
192
|
| 微信客服 | ✔ |
|
|
176
193
|
| 微信公众号 | ✔ |
|
|
177
194
|
| 飞书 | ✔ |
|
|
@@ -180,7 +197,6 @@ uv run main.py
|
|
|
180
197
|
| Discord | ✔ |
|
|
181
198
|
| Satori | ✔ |
|
|
182
199
|
| Misskey | ✔ |
|
|
183
|
-
| 企微智能机器人 | 将支持 |
|
|
184
200
|
| Whatsapp | 将支持 |
|
|
185
201
|
| LINE | 将支持 |
|
|
186
202
|
|
|
@@ -191,6 +207,7 @@ uv run main.py
|
|
|
191
207
|
| [KOOK](https://github.com/wuyan1003/astrbot_plugin_kook_adapter) | ✔ |
|
|
192
208
|
| [VoceChat](https://github.com/HikariFroya/astrbot_plugin_vocechat) | ✔ |
|
|
193
209
|
| [Bilibili 私信](https://github.com/Hina-Chat/astrbot_plugin_bilibili_adapter) | ✔ |
|
|
210
|
+
| [wxauto](https://github.com/luosheng520qaq/wxauto-repost-onebotv11) | ✔ |
|
|
194
211
|
|
|
195
212
|
## ⚡ 提供商支持情况
|
|
196
213
|
|
|
@@ -252,7 +269,7 @@ uv run main.py
|
|
|
252
269
|
AstrBot 使用 `ruff` 进行代码格式化和检查。
|
|
253
270
|
|
|
254
271
|
```bash
|
|
255
|
-
git clone https://github.com/
|
|
272
|
+
git clone https://github.com/AstrBotDevs/AstrBot
|
|
256
273
|
pip install pre-commit
|
|
257
274
|
pre-commit install
|
|
258
275
|
```
|
|
@@ -276,7 +293,7 @@ pre-commit install
|
|
|
276
293
|
|
|
277
294
|
<div align="center">
|
|
278
295
|
|
|
279
|
-
[](https://star-history.com/#astrbotdevs/astrbot&Date)
|
|
280
297
|
|
|
281
298
|
</div>
|
|
282
299
|
|