AstrBot 4.11.4__py3-none-any.whl → 4.12.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 (40) hide show
  1. astrbot/cli/__init__.py +1 -1
  2. astrbot/core/agent/runners/tool_loop_agent_runner.py +10 -8
  3. astrbot/core/config/default.py +66 -2
  4. astrbot/core/db/__init__.py +84 -2
  5. astrbot/core/db/po.py +65 -0
  6. astrbot/core/db/sqlite.py +225 -4
  7. astrbot/core/pipeline/process_stage/method/agent_sub_stages/internal.py +103 -49
  8. astrbot/core/pipeline/process_stage/utils.py +40 -0
  9. astrbot/core/platform/sources/discord/discord_platform_adapter.py +2 -0
  10. astrbot/core/platform/sources/telegram/tg_adapter.py +2 -0
  11. astrbot/core/platform/sources/webchat/webchat_adapter.py +3 -2
  12. astrbot/core/platform/sources/webchat/webchat_event.py +17 -4
  13. astrbot/core/provider/sources/anthropic_source.py +44 -0
  14. astrbot/core/sandbox/booters/base.py +31 -0
  15. astrbot/core/sandbox/booters/boxlite.py +186 -0
  16. astrbot/core/sandbox/booters/shipyard.py +67 -0
  17. astrbot/core/sandbox/olayer/__init__.py +5 -0
  18. astrbot/core/sandbox/olayer/filesystem.py +33 -0
  19. astrbot/core/sandbox/olayer/python.py +19 -0
  20. astrbot/core/sandbox/olayer/shell.py +21 -0
  21. astrbot/core/sandbox/sandbox_client.py +52 -0
  22. astrbot/core/sandbox/tools/__init__.py +10 -0
  23. astrbot/core/sandbox/tools/fs.py +188 -0
  24. astrbot/core/sandbox/tools/python.py +74 -0
  25. astrbot/core/sandbox/tools/shell.py +55 -0
  26. astrbot/core/star/context.py +162 -44
  27. astrbot/dashboard/routes/__init__.py +2 -0
  28. astrbot/dashboard/routes/chat.py +40 -12
  29. astrbot/dashboard/routes/chatui_project.py +245 -0
  30. astrbot/dashboard/routes/session_management.py +545 -0
  31. astrbot/dashboard/server.py +1 -0
  32. {astrbot-4.11.4.dist-info → astrbot-4.12.0.dist-info}/METADATA +2 -1
  33. {astrbot-4.11.4.dist-info → astrbot-4.12.0.dist-info}/RECORD +36 -27
  34. astrbot/builtin_stars/python_interpreter/main.py +0 -536
  35. astrbot/builtin_stars/python_interpreter/metadata.yaml +0 -4
  36. astrbot/builtin_stars/python_interpreter/requirements.txt +0 -1
  37. astrbot/builtin_stars/python_interpreter/shared/api.py +0 -22
  38. {astrbot-4.11.4.dist-info → astrbot-4.12.0.dist-info}/WHEEL +0 -0
  39. {astrbot-4.11.4.dist-info → astrbot-4.12.0.dist-info}/entry_points.txt +0 -0
  40. {astrbot-4.11.4.dist-info → astrbot-4.12.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,245 @@
1
+ from quart import g, request
2
+
3
+ from astrbot.core.db import BaseDatabase
4
+
5
+ from .route import Response, Route, RouteContext
6
+
7
+
8
+ class ChatUIProjectRoute(Route):
9
+ def __init__(self, context: RouteContext, db: BaseDatabase) -> None:
10
+ super().__init__(context)
11
+ self.routes = {
12
+ "/chatui_project/create": ("POST", self.create_project),
13
+ "/chatui_project/list": ("GET", self.list_projects),
14
+ "/chatui_project/get": ("GET", self.get_project),
15
+ "/chatui_project/update": ("POST", self.update_chatui_project),
16
+ "/chatui_project/delete": ("GET", self.delete_project),
17
+ "/chatui_project/add_session": ("POST", self.add_session_to_project),
18
+ "/chatui_project/remove_session": (
19
+ "POST",
20
+ self.remove_session_from_project,
21
+ ),
22
+ "/chatui_project/get_sessions": ("GET", self.get_project_sessions),
23
+ }
24
+ self.db = db
25
+ self.register_routes()
26
+
27
+ async def create_project(self):
28
+ """Create a new ChatUI project."""
29
+ username = g.get("username", "guest")
30
+ post_data = await request.json
31
+
32
+ title = post_data.get("title")
33
+ emoji = post_data.get("emoji", "📁")
34
+ description = post_data.get("description")
35
+
36
+ if not title:
37
+ return Response().error("Missing key: title").__dict__
38
+
39
+ project = await self.db.create_chatui_project(
40
+ creator=username,
41
+ title=title,
42
+ emoji=emoji,
43
+ description=description,
44
+ )
45
+
46
+ return (
47
+ Response()
48
+ .ok(
49
+ data={
50
+ "project_id": project.project_id,
51
+ "title": project.title,
52
+ "emoji": project.emoji,
53
+ "description": project.description,
54
+ "created_at": project.created_at.astimezone().isoformat(),
55
+ "updated_at": project.updated_at.astimezone().isoformat(),
56
+ }
57
+ )
58
+ .__dict__
59
+ )
60
+
61
+ async def list_projects(self):
62
+ """Get all ChatUI projects for the current user."""
63
+ username = g.get("username", "guest")
64
+
65
+ projects = await self.db.get_chatui_projects_by_creator(creator=username)
66
+
67
+ projects_data = [
68
+ {
69
+ "project_id": project.project_id,
70
+ "title": project.title,
71
+ "emoji": project.emoji,
72
+ "description": project.description,
73
+ "created_at": project.created_at.astimezone().isoformat(),
74
+ "updated_at": project.updated_at.astimezone().isoformat(),
75
+ }
76
+ for project in projects
77
+ ]
78
+
79
+ return Response().ok(data=projects_data).__dict__
80
+
81
+ async def get_project(self):
82
+ """Get a specific ChatUI project."""
83
+ project_id = request.args.get("project_id")
84
+ if not project_id:
85
+ return Response().error("Missing key: project_id").__dict__
86
+
87
+ username = g.get("username", "guest")
88
+
89
+ project = await self.db.get_chatui_project_by_id(project_id)
90
+ if not project:
91
+ return Response().error(f"Project {project_id} not found").__dict__
92
+
93
+ # Verify ownership
94
+ if project.creator != username:
95
+ return Response().error("Permission denied").__dict__
96
+
97
+ return (
98
+ Response()
99
+ .ok(
100
+ data={
101
+ "project_id": project.project_id,
102
+ "title": project.title,
103
+ "emoji": project.emoji,
104
+ "description": project.description,
105
+ "created_at": project.created_at.astimezone().isoformat(),
106
+ "updated_at": project.updated_at.astimezone().isoformat(),
107
+ }
108
+ )
109
+ .__dict__
110
+ )
111
+
112
+ async def update_chatui_project(self):
113
+ """Update a ChatUI project."""
114
+ post_data = await request.json
115
+
116
+ project_id = post_data.get("project_id")
117
+ title = post_data.get("title")
118
+ emoji = post_data.get("emoji")
119
+ description = post_data.get("description")
120
+
121
+ if not project_id:
122
+ return Response().error("Missing key: project_id").__dict__
123
+
124
+ username = g.get("username", "guest")
125
+
126
+ # Verify ownership
127
+ project = await self.db.get_chatui_project_by_id(project_id)
128
+ if not project:
129
+ return Response().error(f"Project {project_id} not found").__dict__
130
+ if project.creator != username:
131
+ return Response().error("Permission denied").__dict__
132
+
133
+ await self.db.update_chatui_project(
134
+ project_id=project_id,
135
+ title=title,
136
+ emoji=emoji,
137
+ description=description,
138
+ )
139
+
140
+ return Response().ok().__dict__
141
+
142
+ async def delete_project(self):
143
+ """Delete a ChatUI project."""
144
+ project_id = request.args.get("project_id")
145
+ if not project_id:
146
+ return Response().error("Missing key: project_id").__dict__
147
+
148
+ username = g.get("username", "guest")
149
+
150
+ # Verify ownership
151
+ project = await self.db.get_chatui_project_by_id(project_id)
152
+ if not project:
153
+ return Response().error(f"Project {project_id} not found").__dict__
154
+ if project.creator != username:
155
+ return Response().error("Permission denied").__dict__
156
+
157
+ await self.db.delete_chatui_project(project_id)
158
+
159
+ return Response().ok().__dict__
160
+
161
+ async def add_session_to_project(self):
162
+ """Add a session to a project."""
163
+ post_data = await request.json
164
+
165
+ session_id = post_data.get("session_id")
166
+ project_id = post_data.get("project_id")
167
+
168
+ if not session_id:
169
+ return Response().error("Missing key: session_id").__dict__
170
+ if not project_id:
171
+ return Response().error("Missing key: project_id").__dict__
172
+
173
+ username = g.get("username", "guest")
174
+
175
+ # Verify project ownership
176
+ project = await self.db.get_chatui_project_by_id(project_id)
177
+ if not project:
178
+ return Response().error(f"Project {project_id} not found").__dict__
179
+ if project.creator != username:
180
+ return Response().error("Permission denied").__dict__
181
+
182
+ # Verify session ownership
183
+ session = await self.db.get_platform_session_by_id(session_id)
184
+ if not session:
185
+ return Response().error(f"Session {session_id} not found").__dict__
186
+ if session.creator != username:
187
+ return Response().error("Permission denied").__dict__
188
+
189
+ await self.db.add_session_to_project(session_id, project_id)
190
+
191
+ return Response().ok().__dict__
192
+
193
+ async def remove_session_from_project(self):
194
+ """Remove a session from its project."""
195
+ post_data = await request.json
196
+
197
+ session_id = post_data.get("session_id")
198
+
199
+ if not session_id:
200
+ return Response().error("Missing key: session_id").__dict__
201
+
202
+ username = g.get("username", "guest")
203
+
204
+ # Verify session ownership
205
+ session = await self.db.get_platform_session_by_id(session_id)
206
+ if not session:
207
+ return Response().error(f"Session {session_id} not found").__dict__
208
+ if session.creator != username:
209
+ return Response().error("Permission denied").__dict__
210
+
211
+ await self.db.remove_session_from_project(session_id)
212
+
213
+ return Response().ok().__dict__
214
+
215
+ async def get_project_sessions(self):
216
+ """Get all sessions in a project."""
217
+ project_id = request.args.get("project_id")
218
+ if not project_id:
219
+ return Response().error("Missing key: project_id").__dict__
220
+
221
+ username = g.get("username", "guest")
222
+
223
+ # Verify project ownership
224
+ project = await self.db.get_chatui_project_by_id(project_id)
225
+ if not project:
226
+ return Response().error(f"Project {project_id} not found").__dict__
227
+ if project.creator != username:
228
+ return Response().error("Permission denied").__dict__
229
+
230
+ sessions = await self.db.get_project_sessions(project_id)
231
+
232
+ sessions_data = [
233
+ {
234
+ "session_id": session.session_id,
235
+ "platform_id": session.platform_id,
236
+ "creator": session.creator,
237
+ "display_name": session.display_name,
238
+ "is_group": session.is_group,
239
+ "created_at": session.created_at.astimezone().isoformat(),
240
+ "updated_at": session.updated_at.astimezone().isoformat(),
241
+ }
242
+ for session in sessions
243
+ ]
244
+
245
+ return Response().ok(data=sessions_data).__dict__