AstrBot 4.0.0b5__py3-none-any.whl → 4.1.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.
- astrbot/api/event/filter/__init__.py +2 -0
- astrbot/core/config/default.py +73 -3
- astrbot/core/initial_loader.py +4 -1
- astrbot/core/message/components.py +59 -50
- astrbot/core/pipeline/result_decorate/stage.py +5 -1
- astrbot/core/platform/manager.py +25 -3
- astrbot/core/platform/sources/aiocqhttp/aiocqhttp_platform_adapter.py +11 -4
- astrbot/core/platform/sources/satori/satori_adapter.py +482 -0
- astrbot/core/platform/sources/satori/satori_event.py +221 -0
- astrbot/core/platform/sources/telegram/tg_adapter.py +0 -1
- astrbot/core/provider/sources/openai_source.py +12 -5
- astrbot/core/provider/sources/vllm_rerank_source.py +6 -0
- astrbot/core/star/__init__.py +7 -5
- astrbot/core/star/filter/command.py +9 -3
- astrbot/core/star/filter/platform_adapter_type.py +3 -0
- astrbot/core/star/register/__init__.py +2 -0
- astrbot/core/star/register/star_handler.py +18 -4
- astrbot/core/star/star_handler.py +9 -1
- astrbot/core/star/star_tools.py +116 -21
- astrbot/core/utils/t2i/network_strategy.py +11 -18
- astrbot/core/utils/t2i/renderer.py +8 -2
- astrbot/core/utils/t2i/template/astrbot_powershell.html +184 -0
- astrbot/core/utils/t2i/template_manager.py +112 -0
- astrbot/dashboard/routes/chat.py +6 -1
- astrbot/dashboard/routes/config.py +10 -49
- astrbot/dashboard/routes/route.py +19 -2
- astrbot/dashboard/routes/t2i.py +230 -0
- astrbot/dashboard/server.py +13 -4
- {astrbot-4.0.0b5.dist-info → astrbot-4.1.0.dist-info}/METADATA +39 -52
- {astrbot-4.0.0b5.dist-info → astrbot-4.1.0.dist-info}/RECORD +33 -28
- {astrbot-4.0.0b5.dist-info → astrbot-4.1.0.dist-info}/WHEEL +0 -0
- {astrbot-4.0.0b5.dist-info → astrbot-4.1.0.dist-info}/entry_points.txt +0 -0
- {astrbot-4.0.0b5.dist-info → astrbot-4.1.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import typing
|
|
2
2
|
import traceback
|
|
3
3
|
import os
|
|
4
|
+
import copy
|
|
4
5
|
from .route import Route, Response, RouteContext
|
|
5
6
|
from astrbot.core.provider.entities import ProviderType
|
|
6
7
|
from quart import request
|
|
@@ -16,11 +17,10 @@ from astrbot.core.core_lifecycle import AstrBotCoreLifecycle
|
|
|
16
17
|
from astrbot.core.platform.register import platform_registry
|
|
17
18
|
from astrbot.core.provider.register import provider_registry
|
|
18
19
|
from astrbot.core.star.star import star_registry
|
|
19
|
-
from astrbot.core import logger
|
|
20
|
+
from astrbot.core import logger
|
|
20
21
|
from astrbot.core.provider import Provider
|
|
21
22
|
from astrbot.core.provider.provider import RerankProvider
|
|
22
23
|
import asyncio
|
|
23
|
-
from astrbot.core.utils.t2i.network_strategy import CUSTOM_T2I_TEMPLATE_PATH
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
def try_cast(value: str, type_: str):
|
|
@@ -156,6 +156,7 @@ def save_config(post_config: dict, config: AstrBotConfig, is_core: bool = False)
|
|
|
156
156
|
raise ValueError(f"验证配置时出现异常: {e}")
|
|
157
157
|
if errors:
|
|
158
158
|
raise ValueError(f"格式校验未通过: {errors}")
|
|
159
|
+
|
|
159
160
|
config.save_config(post_config)
|
|
160
161
|
|
|
161
162
|
|
|
@@ -186,56 +187,9 @@ class ConfigRoute(Route):
|
|
|
186
187
|
"/config/provider/check_one": ("GET", self.check_one_provider_status),
|
|
187
188
|
"/config/provider/list": ("GET", self.get_provider_config_list),
|
|
188
189
|
"/config/provider/model_list": ("GET", self.get_provider_model_list),
|
|
189
|
-
"/config/astrbot/t2i-template/get": ("GET", self.get_t2i_template),
|
|
190
|
-
"/config/astrbot/t2i-template/save": ("POST", self.post_t2i_template),
|
|
191
|
-
"/config/astrbot/t2i-template/delete": ("DELETE", self.delete_t2i_template),
|
|
192
190
|
}
|
|
193
191
|
self.register_routes()
|
|
194
192
|
|
|
195
|
-
async def get_t2i_template(self):
|
|
196
|
-
"""获取 T2I 模板"""
|
|
197
|
-
try:
|
|
198
|
-
template = await html_renderer.network_strategy.get_template()
|
|
199
|
-
has_custom_template = os.path.exists(CUSTOM_T2I_TEMPLATE_PATH)
|
|
200
|
-
return (
|
|
201
|
-
Response()
|
|
202
|
-
.ok({"template": template, "has_custom_template": has_custom_template})
|
|
203
|
-
.__dict__
|
|
204
|
-
)
|
|
205
|
-
except Exception as e:
|
|
206
|
-
logger.error(traceback.format_exc())
|
|
207
|
-
return Response().error(f"获取模板失败: {str(e)}").__dict__
|
|
208
|
-
|
|
209
|
-
async def post_t2i_template(self):
|
|
210
|
-
"""保存 T2I 模板"""
|
|
211
|
-
try:
|
|
212
|
-
post_data = await request.json
|
|
213
|
-
if not post_data or "template" not in post_data:
|
|
214
|
-
return Response().error("缺少模板内容").__dict__
|
|
215
|
-
|
|
216
|
-
template_content = post_data["template"]
|
|
217
|
-
|
|
218
|
-
# 保存自定义模板到文件
|
|
219
|
-
with open(CUSTOM_T2I_TEMPLATE_PATH, "w", encoding="utf-8") as f:
|
|
220
|
-
f.write(template_content)
|
|
221
|
-
|
|
222
|
-
return Response().ok(message="模板保存成功").__dict__
|
|
223
|
-
except Exception as e:
|
|
224
|
-
logger.error(traceback.format_exc())
|
|
225
|
-
return Response().error(f"保存模板失败: {str(e)}").__dict__
|
|
226
|
-
|
|
227
|
-
async def delete_t2i_template(self):
|
|
228
|
-
"""删除自定义 T2I 模板,恢复默认模板"""
|
|
229
|
-
try:
|
|
230
|
-
if os.path.exists(CUSTOM_T2I_TEMPLATE_PATH):
|
|
231
|
-
os.remove(CUSTOM_T2I_TEMPLATE_PATH)
|
|
232
|
-
return Response().ok(message="已恢复默认模板").__dict__
|
|
233
|
-
else:
|
|
234
|
-
return Response().ok(message="未找到自定义模板文件").__dict__
|
|
235
|
-
except Exception as e:
|
|
236
|
-
logger.error(traceback.format_exc())
|
|
237
|
-
return Response().error(f"删除模板失败: {str(e)}").__dict__
|
|
238
|
-
|
|
239
193
|
async def get_abconf_list(self):
|
|
240
194
|
"""获取所有 AstrBot 配置文件的列表"""
|
|
241
195
|
abconf_list = self.acm.get_conf_list()
|
|
@@ -766,6 +720,13 @@ class ConfigRoute(Route):
|
|
|
766
720
|
if conf_id not in self.acm.confs:
|
|
767
721
|
raise ValueError(f"配置文件 {conf_id} 不存在")
|
|
768
722
|
astrbot_config = self.acm.confs[conf_id]
|
|
723
|
+
|
|
724
|
+
# 保留服务端的 t2i_active_template 值
|
|
725
|
+
if "t2i_active_template" in astrbot_config:
|
|
726
|
+
post_configs["t2i_active_template"] = astrbot_config[
|
|
727
|
+
"t2i_active_template"
|
|
728
|
+
]
|
|
729
|
+
|
|
769
730
|
save_config(post_configs, astrbot_config, is_core=True)
|
|
770
731
|
except Exception as e:
|
|
771
732
|
raise e
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from astrbot.core import logger
|
|
1
2
|
from astrbot.core.config.astrbot_config import AstrBotConfig
|
|
2
3
|
from dataclasses import dataclass
|
|
3
4
|
from quart import Quart
|
|
@@ -15,8 +16,24 @@ class Route:
|
|
|
15
16
|
self.config = context.config
|
|
16
17
|
|
|
17
18
|
def register_routes(self):
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
def _add_rule(path, method, func):
|
|
20
|
+
# 统一添加 /api 前缀
|
|
21
|
+
full_path = f"/api{path}"
|
|
22
|
+
self.app.add_url_rule(full_path, view_func=func, methods=[method])
|
|
23
|
+
|
|
24
|
+
# 兼容字典和列表两种格式
|
|
25
|
+
routes_to_register = (
|
|
26
|
+
self.routes.items() if isinstance(self.routes, dict) else self.routes
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
for route, definition in routes_to_register:
|
|
30
|
+
# 兼容一个路由多个方法
|
|
31
|
+
if isinstance(definition, list):
|
|
32
|
+
for method, func in definition:
|
|
33
|
+
_add_rule(route, method, func)
|
|
34
|
+
else:
|
|
35
|
+
method, func = definition
|
|
36
|
+
_add_rule(route, method, func)
|
|
20
37
|
|
|
21
38
|
|
|
22
39
|
@dataclass
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# astrbot/dashboard/routes/t2i.py
|
|
2
|
+
|
|
3
|
+
from dataclasses import asdict
|
|
4
|
+
from quart import jsonify, request
|
|
5
|
+
|
|
6
|
+
from astrbot.core import logger
|
|
7
|
+
from astrbot.core.core_lifecycle import AstrBotCoreLifecycle
|
|
8
|
+
from astrbot.core.utils.t2i.template_manager import TemplateManager
|
|
9
|
+
from .route import Response, Route, RouteContext
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class T2iRoute(Route):
|
|
13
|
+
def __init__(self, context: RouteContext, core_lifecycle: AstrBotCoreLifecycle):
|
|
14
|
+
super().__init__(context)
|
|
15
|
+
self.core_lifecycle = core_lifecycle
|
|
16
|
+
self.config = core_lifecycle.astrbot_config
|
|
17
|
+
self.manager = TemplateManager()
|
|
18
|
+
# 使用列表保证路由注册顺序,避免 /<name> 路由优先匹配 /reset_default
|
|
19
|
+
self.routes = [
|
|
20
|
+
("/t2i/templates", ("GET", self.list_templates)),
|
|
21
|
+
("/t2i/templates/active", ("GET", self.get_active_template)),
|
|
22
|
+
("/t2i/templates/create", ("POST", self.create_template)),
|
|
23
|
+
("/t2i/templates/reset_default", ("POST", self.reset_default_template)),
|
|
24
|
+
("/t2i/templates/set_active", ("POST", self.set_active_template)),
|
|
25
|
+
# 动态路由应该在静态路由之后注册
|
|
26
|
+
(
|
|
27
|
+
"/t2i/templates/<name>",
|
|
28
|
+
[
|
|
29
|
+
("GET", self.get_template),
|
|
30
|
+
("PUT", self.update_template),
|
|
31
|
+
("DELETE", self.delete_template),
|
|
32
|
+
],
|
|
33
|
+
),
|
|
34
|
+
]
|
|
35
|
+
self.register_routes()
|
|
36
|
+
|
|
37
|
+
async def list_templates(self):
|
|
38
|
+
"""获取所有T2I模板列表"""
|
|
39
|
+
try:
|
|
40
|
+
templates = self.manager.list_templates()
|
|
41
|
+
return jsonify(asdict(Response().ok(data=templates)))
|
|
42
|
+
except Exception as e:
|
|
43
|
+
response = jsonify(asdict(Response().error(str(e))))
|
|
44
|
+
response.status_code = 500
|
|
45
|
+
return response
|
|
46
|
+
|
|
47
|
+
async def get_active_template(self):
|
|
48
|
+
"""获取当前激活的T2I模板"""
|
|
49
|
+
try:
|
|
50
|
+
active_template = self.config.get("t2i_active_template", "base")
|
|
51
|
+
return jsonify(
|
|
52
|
+
asdict(Response().ok(data={"active_template": active_template}))
|
|
53
|
+
)
|
|
54
|
+
except Exception as e:
|
|
55
|
+
logger.error("Error in get_active_template", exc_info=True)
|
|
56
|
+
response = jsonify(asdict(Response().error(str(e))))
|
|
57
|
+
response.status_code = 500
|
|
58
|
+
return response
|
|
59
|
+
|
|
60
|
+
async def get_template(self, name: str):
|
|
61
|
+
"""获取指定名称的T2I模板内容"""
|
|
62
|
+
try:
|
|
63
|
+
content = self.manager.get_template(name)
|
|
64
|
+
return jsonify(
|
|
65
|
+
asdict(Response().ok(data={"name": name, "content": content}))
|
|
66
|
+
)
|
|
67
|
+
except FileNotFoundError:
|
|
68
|
+
response = jsonify(asdict(Response().error("Template not found")))
|
|
69
|
+
response.status_code = 404
|
|
70
|
+
return response
|
|
71
|
+
except Exception as e:
|
|
72
|
+
response = jsonify(asdict(Response().error(str(e))))
|
|
73
|
+
response.status_code = 500
|
|
74
|
+
return response
|
|
75
|
+
|
|
76
|
+
async def create_template(self):
|
|
77
|
+
"""创建一个新的T2I模板"""
|
|
78
|
+
try:
|
|
79
|
+
data = await request.json
|
|
80
|
+
name = data.get("name")
|
|
81
|
+
content = data.get("content")
|
|
82
|
+
if not name or not content:
|
|
83
|
+
response = jsonify(
|
|
84
|
+
asdict(Response().error("Name and content are required."))
|
|
85
|
+
)
|
|
86
|
+
response.status_code = 400
|
|
87
|
+
return response
|
|
88
|
+
name = name.strip()
|
|
89
|
+
|
|
90
|
+
self.manager.create_template(name, content)
|
|
91
|
+
response = jsonify(
|
|
92
|
+
asdict(
|
|
93
|
+
Response().ok(
|
|
94
|
+
data={"name": name}, message="Template created successfully."
|
|
95
|
+
)
|
|
96
|
+
)
|
|
97
|
+
)
|
|
98
|
+
response.status_code = 201
|
|
99
|
+
return response
|
|
100
|
+
except FileExistsError:
|
|
101
|
+
response = jsonify(
|
|
102
|
+
asdict(Response().error("Template with this name already exists."))
|
|
103
|
+
)
|
|
104
|
+
response.status_code = 409
|
|
105
|
+
return response
|
|
106
|
+
except ValueError as e:
|
|
107
|
+
response = jsonify(asdict(Response().error(str(e))))
|
|
108
|
+
response.status_code = 400
|
|
109
|
+
return response
|
|
110
|
+
except Exception as e:
|
|
111
|
+
response = jsonify(asdict(Response().error(str(e))))
|
|
112
|
+
response.status_code = 500
|
|
113
|
+
return response
|
|
114
|
+
|
|
115
|
+
async def update_template(self, name: str):
|
|
116
|
+
"""更新一个已存在的T2I模板"""
|
|
117
|
+
try:
|
|
118
|
+
name = name.strip()
|
|
119
|
+
data = await request.json
|
|
120
|
+
content = data.get("content")
|
|
121
|
+
if content is None:
|
|
122
|
+
response = jsonify(asdict(Response().error("Content is required.")))
|
|
123
|
+
response.status_code = 400
|
|
124
|
+
return response
|
|
125
|
+
|
|
126
|
+
self.manager.update_template(name, content)
|
|
127
|
+
|
|
128
|
+
# 检查更新的是否为当前激活的模板,如果是,则热重载
|
|
129
|
+
active_template = self.config.get("t2i_active_template", "base")
|
|
130
|
+
if name == active_template:
|
|
131
|
+
await self.core_lifecycle.reload_pipeline_scheduler("default")
|
|
132
|
+
message = f"模板 '{name}' 已更新并重新加载。"
|
|
133
|
+
else:
|
|
134
|
+
message = f"模板 '{name}' 已更新。"
|
|
135
|
+
|
|
136
|
+
return jsonify(asdict(Response().ok(data={"name": name}, message=message)))
|
|
137
|
+
except ValueError as e:
|
|
138
|
+
response = jsonify(asdict(Response().error(str(e))))
|
|
139
|
+
response.status_code = 400
|
|
140
|
+
return response
|
|
141
|
+
except Exception as e:
|
|
142
|
+
response = jsonify(asdict(Response().error(str(e))))
|
|
143
|
+
response.status_code = 500
|
|
144
|
+
return response
|
|
145
|
+
|
|
146
|
+
async def delete_template(self, name: str):
|
|
147
|
+
"""删除一个T2I模板"""
|
|
148
|
+
try:
|
|
149
|
+
name = name.strip()
|
|
150
|
+
self.manager.delete_template(name)
|
|
151
|
+
return jsonify(
|
|
152
|
+
asdict(Response().ok(message="Template deleted successfully."))
|
|
153
|
+
)
|
|
154
|
+
except FileNotFoundError:
|
|
155
|
+
response = jsonify(asdict(Response().error("Template not found.")))
|
|
156
|
+
response.status_code = 404
|
|
157
|
+
return response
|
|
158
|
+
except ValueError as e:
|
|
159
|
+
response = jsonify(asdict(Response().error(str(e))))
|
|
160
|
+
response.status_code = 400
|
|
161
|
+
return response
|
|
162
|
+
except Exception as e:
|
|
163
|
+
response = jsonify(asdict(Response().error(str(e))))
|
|
164
|
+
response.status_code = 500
|
|
165
|
+
return response
|
|
166
|
+
|
|
167
|
+
async def set_active_template(self):
|
|
168
|
+
"""设置当前活动的T2I模板"""
|
|
169
|
+
try:
|
|
170
|
+
data = await request.json
|
|
171
|
+
name = data.get("name")
|
|
172
|
+
if not name:
|
|
173
|
+
response = jsonify(asdict(Response().error("模板名称(name)不能为空。")))
|
|
174
|
+
response.status_code = 400
|
|
175
|
+
return response
|
|
176
|
+
|
|
177
|
+
# 验证模板文件是否存在
|
|
178
|
+
self.manager.get_template(name)
|
|
179
|
+
|
|
180
|
+
# 更新配置
|
|
181
|
+
config = self.config
|
|
182
|
+
config["t2i_active_template"] = name
|
|
183
|
+
config.save_config(config)
|
|
184
|
+
|
|
185
|
+
# 热重载以应用更改
|
|
186
|
+
await self.core_lifecycle.reload_pipeline_scheduler("default")
|
|
187
|
+
|
|
188
|
+
return jsonify(asdict(Response().ok(message=f"模板 '{name}' 已成功应用。")))
|
|
189
|
+
|
|
190
|
+
except FileNotFoundError:
|
|
191
|
+
response = jsonify(
|
|
192
|
+
asdict(Response().error(f"模板 '{name}' 不存在,无法应用。"))
|
|
193
|
+
)
|
|
194
|
+
response.status_code = 404
|
|
195
|
+
return response
|
|
196
|
+
except Exception as e:
|
|
197
|
+
logger.error("Error in set_active_template", exc_info=True)
|
|
198
|
+
response = jsonify(asdict(Response().error(str(e))))
|
|
199
|
+
response.status_code = 500
|
|
200
|
+
return response
|
|
201
|
+
|
|
202
|
+
async def reset_default_template(self):
|
|
203
|
+
"""重置默认的'base'模板"""
|
|
204
|
+
try:
|
|
205
|
+
self.manager.reset_default_template()
|
|
206
|
+
|
|
207
|
+
# 更新配置,将激活模板也重置为'base'
|
|
208
|
+
config = self.config
|
|
209
|
+
config["t2i_active_template"] = "base"
|
|
210
|
+
config.save_config(config)
|
|
211
|
+
|
|
212
|
+
# 热重载以应用更改
|
|
213
|
+
await self.core_lifecycle.reload_pipeline_scheduler("default")
|
|
214
|
+
|
|
215
|
+
return jsonify(
|
|
216
|
+
asdict(
|
|
217
|
+
Response().ok(
|
|
218
|
+
message="Default template has been reset and activated."
|
|
219
|
+
)
|
|
220
|
+
)
|
|
221
|
+
)
|
|
222
|
+
except FileNotFoundError as e:
|
|
223
|
+
response = jsonify(asdict(Response().error(str(e))))
|
|
224
|
+
response.status_code = 404
|
|
225
|
+
return response
|
|
226
|
+
except Exception as e:
|
|
227
|
+
logger.error("Error in reset_default_template", exc_info=True)
|
|
228
|
+
response = jsonify(asdict(Response().error(str(e))))
|
|
229
|
+
response.status_code = 500
|
|
230
|
+
return response
|
astrbot/dashboard/server.py
CHANGED
|
@@ -18,6 +18,7 @@ from astrbot.core.utils.io import get_local_ip_addresses
|
|
|
18
18
|
from .routes import *
|
|
19
19
|
from .routes.route import Response, RouteContext
|
|
20
20
|
from .routes.session_management import SessionManagementRoute
|
|
21
|
+
from .routes.t2i import T2iRoute
|
|
21
22
|
|
|
22
23
|
APP: Quart = None
|
|
23
24
|
|
|
@@ -28,10 +29,19 @@ class AstrBotDashboard:
|
|
|
28
29
|
core_lifecycle: AstrBotCoreLifecycle,
|
|
29
30
|
db: BaseDatabase,
|
|
30
31
|
shutdown_event: asyncio.Event,
|
|
32
|
+
webui_dir: str | None = None,
|
|
31
33
|
) -> None:
|
|
32
34
|
self.core_lifecycle = core_lifecycle
|
|
33
35
|
self.config = core_lifecycle.astrbot_config
|
|
34
|
-
|
|
36
|
+
|
|
37
|
+
# 参数指定webui目录
|
|
38
|
+
if webui_dir and os.path.exists(webui_dir):
|
|
39
|
+
self.data_path = os.path.abspath(webui_dir)
|
|
40
|
+
else:
|
|
41
|
+
self.data_path = os.path.abspath(
|
|
42
|
+
os.path.join(get_astrbot_data_path(), "dist")
|
|
43
|
+
)
|
|
44
|
+
|
|
35
45
|
self.app = Quart("dashboard", static_folder=self.data_path, static_url_path="/")
|
|
36
46
|
APP = self.app # noqa
|
|
37
47
|
self.app.config["MAX_CONTENT_LENGTH"] = (
|
|
@@ -60,9 +70,8 @@ class AstrBotDashboard:
|
|
|
60
70
|
self.session_management_route = SessionManagementRoute(
|
|
61
71
|
self.context, db, core_lifecycle
|
|
62
72
|
)
|
|
63
|
-
self.persona_route = PersonaRoute(
|
|
64
|
-
|
|
65
|
-
)
|
|
73
|
+
self.persona_route = PersonaRoute(self.context, db, core_lifecycle)
|
|
74
|
+
self.t2i_route = T2iRoute(self.context, core_lifecycle)
|
|
66
75
|
|
|
67
76
|
self.app.add_url_rule(
|
|
68
77
|
"/api/plug/<path:subpath>",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: AstrBot
|
|
3
|
-
Version: 4.0
|
|
3
|
+
Version: 4.1.0
|
|
4
4
|
Summary: 易上手的多平台 LLM 聊天机器人及开发框架
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -58,8 +58,6 @@ Description-Content-Type: text/markdown
|
|
|
58
58
|
|
|
59
59
|
<div align="center">
|
|
60
60
|
|
|
61
|
-
_✨ 易上手的多平台 LLM 聊天机器人及开发框架 ✨_
|
|
62
|
-
|
|
63
61
|
<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>
|
|
64
62
|
|
|
65
63
|
[](https://github.com/Soulter/AstrBot/releases/latest)
|
|
@@ -68,7 +66,6 @@ _✨ 易上手的多平台 LLM 聊天机器人及开发框架 ✨_
|
|
|
68
66
|
<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>
|
|
69
67
|
<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>
|
|
70
68
|
[](https://wakatime.com/badge/user/915e5316-99c6-4563-a483-ef186cf000c9/project/018e705a-a1a7-409a-a849-3013485e6c8e)
|
|
71
|
-

|
|
72
69
|

|
|
73
70
|
|
|
74
71
|
<a href="https://github.com/Soulter/AstrBot/blob/master/README_en.md">English</a> |
|
|
@@ -79,7 +76,7 @@ _✨ 易上手的多平台 LLM 聊天机器人及开发框架 ✨_
|
|
|
79
76
|
|
|
80
77
|
AstrBot 是一个开源的一站式 Agentic 聊天机器人平台及开发框架。
|
|
81
78
|
|
|
82
|
-
##
|
|
79
|
+
## 主要功能
|
|
83
80
|
|
|
84
81
|
1. **大模型对话**。支持接入多种大模型服务。支持多模态、工具调用、MCP、原生知识库、人设等功能。
|
|
85
82
|
2. **多消息平台支持**。支持接入 QQ、企业微信、微信公众号、飞书、Telegram、钉钉、Discord、KOOK 等平台。支持速率限制、白名单、百度内容审核。
|
|
@@ -87,7 +84,7 @@ AstrBot 是一个开源的一站式 Agentic 聊天机器人平台及开发框架
|
|
|
87
84
|
4. **插件扩展**。深度优化的插件机制,支持[开发插件](https://astrbot.app/dev/plugin.html)扩展功能,社区插件生态丰富。
|
|
88
85
|
5. **WebUI**。可视化配置和管理机器人,功能齐全。
|
|
89
86
|
|
|
90
|
-
##
|
|
87
|
+
## 部署方式
|
|
91
88
|
|
|
92
89
|
#### Docker 部署
|
|
93
90
|
|
|
@@ -131,9 +128,7 @@ AstrBot 已由雨云官方上架至云应用平台,可一键部署。
|
|
|
131
128
|
|
|
132
129
|
#### 手动部署
|
|
133
130
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
首先,安装 uv:
|
|
131
|
+
首先安装 uv:
|
|
137
132
|
|
|
138
133
|
```bash
|
|
139
134
|
pip install uv
|
|
@@ -148,6 +143,26 @@ uv run main.py
|
|
|
148
143
|
|
|
149
144
|
或者请参阅官方文档 [通过源码部署 AstrBot](https://astrbot.app/deploy/astrbot/cli.html) 。
|
|
150
145
|
|
|
146
|
+
## 🌍 社区
|
|
147
|
+
|
|
148
|
+
### QQ 群组
|
|
149
|
+
|
|
150
|
+
- 1 群:322154837
|
|
151
|
+
- 3 群:630166526
|
|
152
|
+
- 5 群:822130018
|
|
153
|
+
- 6 群:753075035
|
|
154
|
+
- 开发者群:975206796
|
|
155
|
+
- 开发者群(备份):295657329
|
|
156
|
+
|
|
157
|
+
### Telegram 群组
|
|
158
|
+
|
|
159
|
+
<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>
|
|
160
|
+
|
|
161
|
+
### Discord 群组
|
|
162
|
+
|
|
163
|
+
<a href="https://discord.gg/hAVk6tgV36"><img alt="Discord_community" src="https://img.shields.io/badge/Discord-AstrBot-purple?style=for-the-badge&color=76bad9"></a>
|
|
164
|
+
|
|
165
|
+
|
|
151
166
|
## ⚡ 消息平台支持情况
|
|
152
167
|
|
|
153
168
|
| 平台 | 支持性 |
|
|
@@ -164,22 +179,18 @@ uv run main.py
|
|
|
164
179
|
| Discord | ✔ |
|
|
165
180
|
| [KOOK](https://github.com/wuyan1003/astrbot_plugin_kook_adapter) | ✔ |
|
|
166
181
|
| [VoceChat](https://github.com/HikariFroya/astrbot_plugin_vocechat) | ✔ |
|
|
167
|
-
| 微信对话开放平台 | 🚧 |
|
|
168
|
-
| WhatsApp | 🚧 |
|
|
169
|
-
| 小爱音响 | 🚧 |
|
|
170
182
|
|
|
171
183
|
## ⚡ 提供商支持情况
|
|
172
184
|
|
|
173
185
|
| 名称 | 支持性 | 类型 | 备注 |
|
|
174
186
|
| -------- | ------- | ------- | ------- |
|
|
175
|
-
| OpenAI
|
|
176
|
-
|
|
|
177
|
-
| Google Gemini
|
|
187
|
+
| OpenAI | ✔ | 文本生成 | 支持任何兼容 OpenAI API 的服务 |
|
|
188
|
+
| Anthropic | ✔ | 文本生成 | |
|
|
189
|
+
| Google Gemini | ✔ | 文本生成 | |
|
|
178
190
|
| Dify | ✔ | LLMOps | |
|
|
179
191
|
| 阿里云百炼应用 | ✔ | LLMOps | |
|
|
180
192
|
| Ollama | ✔ | 模型加载器 | 本地部署 DeepSeek、Llama 等开源语言模型 |
|
|
181
193
|
| LM Studio | ✔ | 模型加载器 | 本地部署 DeepSeek、Llama 等开源语言模型 |
|
|
182
|
-
| LLMTuner | ✔ | 模型加载器 | 本地加载 lora 等微调模型 |
|
|
183
194
|
| [优云智算](https://www.compshare.cn/?ytag=GPU_YY-gh_astrbot&referral_code=FV7DcGowN4hB5UuXKgpE74) | ✔ | 模型 API 及算力服务平台 | |
|
|
184
195
|
| [302.AI](https://share.302.ai/rr1M3l) | ✔ | 模型 API 服务平台 | |
|
|
185
196
|
| 硅基流动 | ✔ | 模型 API 服务平台 | |
|
|
@@ -195,7 +206,6 @@ uv run main.py
|
|
|
195
206
|
| 阿里云百炼 TTS | ✔ | 文本转语音 | |
|
|
196
207
|
| Azure TTS | ✔ | 文本转语音 | Microsoft Azure TTS |
|
|
197
208
|
|
|
198
|
-
|
|
199
209
|
## ❤️ 贡献
|
|
200
210
|
|
|
201
211
|
欢迎任何 Issues/Pull Requests!只需要将你的更改提交到此项目 :)
|
|
@@ -214,38 +224,6 @@ pip install pre-commit
|
|
|
214
224
|
pre-commit install
|
|
215
225
|
```
|
|
216
226
|
|
|
217
|
-
## 🌟 支持
|
|
218
|
-
|
|
219
|
-
- Star 这个项目!
|
|
220
|
-
- 在[爱发电](https://afdian.com/a/soulter)支持我!
|
|
221
|
-
|
|
222
|
-
## ✨ Demo
|
|
223
|
-
|
|
224
|
-
<details><summary>👉 点击展开多张 Demo 截图 👈</summary>
|
|
225
|
-
|
|
226
|
-
<div align='center'>
|
|
227
|
-
|
|
228
|
-
<img src="https://github.com/user-attachments/assets/4ee688d9-467d-45c8-99d6-368f9a8a92d8" width="600">
|
|
229
|
-
|
|
230
|
-
_✨基于 Docker 的沙箱化代码执行器(Beta 测试)✨_
|
|
231
|
-
|
|
232
|
-
<img src="https://github.com/user-attachments/assets/0378f407-6079-4f64-ae4c-e97ab20611d2" height=500>
|
|
233
|
-
|
|
234
|
-
_✨ 多模态、网页搜索、长文本转图片(可配置) ✨_
|
|
235
|
-
|
|
236
|
-
<img src="https://github.com/user-attachments/assets/e137a9e1-340a-4bf2-bb2b-771132780735" height=150>
|
|
237
|
-
<img src="https://github.com/user-attachments/assets/480f5e82-cf6a-4955-a869-0d73137aa6e1" height=150>
|
|
238
|
-
|
|
239
|
-
_✨ 插件系统——部分插件展示 ✨_
|
|
240
|
-
|
|
241
|
-
<img src="https://github.com/user-attachments/assets/0cdbf564-2f59-4da5-b524-ce0e7ef3d978" width=600>
|
|
242
|
-
|
|
243
|
-
_✨ WebUI ✨_
|
|
244
|
-
|
|
245
|
-
</div>
|
|
246
|
-
|
|
247
|
-
</details>
|
|
248
|
-
|
|
249
227
|
|
|
250
228
|
## ❤️ Special Thanks
|
|
251
229
|
|
|
@@ -255,10 +233,18 @@ _✨ WebUI ✨_
|
|
|
255
233
|
<img src="https://contrib.rocks/image?repo=AstrBotDevs/AstrBot" />
|
|
256
234
|
</a>
|
|
257
235
|
|
|
258
|
-
|
|
236
|
+
此外,本项目的诞生离不开以下开源项目的帮助:
|
|
259
237
|
|
|
260
238
|
- [NapNeko/NapCatQQ](https://github.com/NapNeko/NapCatQQ) - 伟大的猫猫框架
|
|
261
|
-
|
|
239
|
+
|
|
240
|
+
另外,一些同类型其他的活跃开源 Bot 项目:
|
|
241
|
+
|
|
242
|
+
- [nonebot/nonebot2](https://github.com/nonebot/nonebot2) - 扩展性极强的 Bot 框架
|
|
243
|
+
- [koishijs/koishi](https://github.com/koishijs/koishi) - 扩展性极强的 Bot 框架
|
|
244
|
+
- [MaiM-with-u/MaiBot](https://github.com/MaiM-with-u/MaiBot) - 注重拟人功能的 ChatBot
|
|
245
|
+
- [langbot-app/LangBot](https://github.com/langbot-app/LangBot) - 功能丰富的 Bot 平台
|
|
246
|
+
- [LroMiose/nekro-agent](https://github.com/KroMiose/nekro-agent) - 注重 Agent 的 ChatBot
|
|
247
|
+
- [zhenxun-org/zhenxun_bot](https://github.com/zhenxun-org/zhenxun_bot) - 功能完善的 ChatBot
|
|
262
248
|
|
|
263
249
|
## ⭐ Star History
|
|
264
250
|
|
|
@@ -271,7 +257,8 @@ _✨ WebUI ✨_
|
|
|
271
257
|
|
|
272
258
|
</div>
|
|
273
259
|
|
|
274
|
-
|
|
260
|
+
|
|
261
|
+
</details>
|
|
275
262
|
|
|
276
263
|
|
|
277
264
|
_私は、高性能ですから!_
|