agentscope-runtime 1.0.0b2__py3-none-any.whl → 1.0.2__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.
- agentscope_runtime/adapters/agentscope/message.py +78 -10
- agentscope_runtime/adapters/agentscope/stream.py +155 -101
- agentscope_runtime/adapters/agentscope/tool/tool.py +1 -3
- agentscope_runtime/adapters/agno/__init__.py +0 -0
- agentscope_runtime/adapters/agno/message.py +30 -0
- agentscope_runtime/adapters/agno/stream.py +122 -0
- agentscope_runtime/adapters/langgraph/__init__.py +12 -0
- agentscope_runtime/adapters/langgraph/message.py +257 -0
- agentscope_runtime/adapters/langgraph/stream.py +205 -0
- agentscope_runtime/cli/__init__.py +7 -0
- agentscope_runtime/cli/cli.py +63 -0
- agentscope_runtime/cli/commands/__init__.py +2 -0
- agentscope_runtime/cli/commands/chat.py +815 -0
- agentscope_runtime/cli/commands/deploy.py +1062 -0
- agentscope_runtime/cli/commands/invoke.py +58 -0
- agentscope_runtime/cli/commands/list_cmd.py +103 -0
- agentscope_runtime/cli/commands/run.py +176 -0
- agentscope_runtime/cli/commands/sandbox.py +128 -0
- agentscope_runtime/cli/commands/status.py +60 -0
- agentscope_runtime/cli/commands/stop.py +185 -0
- agentscope_runtime/cli/commands/web.py +166 -0
- agentscope_runtime/cli/loaders/__init__.py +6 -0
- agentscope_runtime/cli/loaders/agent_loader.py +295 -0
- agentscope_runtime/cli/state/__init__.py +10 -0
- agentscope_runtime/cli/utils/__init__.py +18 -0
- agentscope_runtime/cli/utils/console.py +378 -0
- agentscope_runtime/cli/utils/validators.py +118 -0
- agentscope_runtime/engine/app/agent_app.py +15 -5
- agentscope_runtime/engine/deployers/__init__.py +1 -0
- agentscope_runtime/engine/deployers/agentrun_deployer.py +154 -24
- agentscope_runtime/engine/deployers/base.py +27 -2
- agentscope_runtime/engine/deployers/kubernetes_deployer.py +158 -31
- agentscope_runtime/engine/deployers/local_deployer.py +188 -25
- agentscope_runtime/engine/deployers/modelstudio_deployer.py +109 -18
- agentscope_runtime/engine/deployers/state/__init__.py +9 -0
- agentscope_runtime/engine/deployers/state/manager.py +388 -0
- agentscope_runtime/engine/deployers/state/schema.py +96 -0
- agentscope_runtime/engine/deployers/utils/build_cache.py +736 -0
- agentscope_runtime/engine/deployers/utils/detached_app.py +105 -30
- agentscope_runtime/engine/deployers/utils/docker_image_utils/docker_image_builder.py +31 -10
- agentscope_runtime/engine/deployers/utils/docker_image_utils/dockerfile_generator.py +15 -8
- agentscope_runtime/engine/deployers/utils/docker_image_utils/image_factory.py +30 -2
- agentscope_runtime/engine/deployers/utils/k8s_utils.py +241 -0
- agentscope_runtime/engine/deployers/utils/package.py +56 -6
- agentscope_runtime/engine/deployers/utils/service_utils/fastapi_factory.py +68 -9
- agentscope_runtime/engine/deployers/utils/service_utils/process_manager.py +155 -5
- agentscope_runtime/engine/deployers/utils/wheel_packager.py +107 -123
- agentscope_runtime/engine/runner.py +32 -12
- agentscope_runtime/engine/schemas/agent_schemas.py +21 -7
- agentscope_runtime/engine/schemas/exception.py +580 -0
- agentscope_runtime/engine/services/agent_state/__init__.py +2 -0
- agentscope_runtime/engine/services/agent_state/state_service_factory.py +55 -0
- agentscope_runtime/engine/services/memory/__init__.py +2 -0
- agentscope_runtime/engine/services/memory/memory_service_factory.py +126 -0
- agentscope_runtime/engine/services/sandbox/__init__.py +2 -0
- agentscope_runtime/engine/services/sandbox/sandbox_service_factory.py +49 -0
- agentscope_runtime/engine/services/service_factory.py +119 -0
- agentscope_runtime/engine/services/session_history/__init__.py +2 -0
- agentscope_runtime/engine/services/session_history/session_history_service_factory.py +73 -0
- agentscope_runtime/engine/services/utils/tablestore_service_utils.py +35 -10
- agentscope_runtime/engine/tracing/wrapper.py +49 -31
- agentscope_runtime/sandbox/box/mobile/mobile_sandbox.py +113 -39
- agentscope_runtime/sandbox/box/shared/routers/mcp_utils.py +20 -4
- agentscope_runtime/sandbox/utils.py +2 -0
- agentscope_runtime/version.py +1 -1
- {agentscope_runtime-1.0.0b2.dist-info → agentscope_runtime-1.0.2.dist-info}/METADATA +82 -11
- {agentscope_runtime-1.0.0b2.dist-info → agentscope_runtime-1.0.2.dist-info}/RECORD +71 -36
- {agentscope_runtime-1.0.0b2.dist-info → agentscope_runtime-1.0.2.dist-info}/entry_points.txt +1 -0
- {agentscope_runtime-1.0.0b2.dist-info → agentscope_runtime-1.0.2.dist-info}/WHEEL +0 -0
- {agentscope_runtime-1.0.0b2.dist-info → agentscope_runtime-1.0.2.dist-info}/licenses/LICENSE +0 -0
- {agentscope_runtime-1.0.0b2.dist-info → agentscope_runtime-1.0.2.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,580 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Business System Exception Definitions
|
|
4
|
+
Provides a three-level exception structure:
|
|
5
|
+
Base Class -> HTTP Status Exceptions -> Business Exceptions
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Any, Dict, Optional
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class AppBaseException(Exception):
|
|
12
|
+
"""
|
|
13
|
+
Business exception base class
|
|
14
|
+
|
|
15
|
+
Attributes:
|
|
16
|
+
status: HTTP status code, aligned with standard HTTP status codes
|
|
17
|
+
code: Business error code, used for business logic distinction
|
|
18
|
+
message: Error message
|
|
19
|
+
details: Additional error details
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(
|
|
23
|
+
self,
|
|
24
|
+
status: int,
|
|
25
|
+
code: str,
|
|
26
|
+
message: str,
|
|
27
|
+
details: Optional[Dict[str, Any]] = None,
|
|
28
|
+
):
|
|
29
|
+
"""
|
|
30
|
+
Initialize the exception
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
status: HTTP status code
|
|
34
|
+
code: Business error code
|
|
35
|
+
message: Error message
|
|
36
|
+
details: Additional details
|
|
37
|
+
"""
|
|
38
|
+
super().__init__(message)
|
|
39
|
+
self.status = status
|
|
40
|
+
self.code = code
|
|
41
|
+
self.message = message
|
|
42
|
+
self.details = details or {}
|
|
43
|
+
|
|
44
|
+
def __str__(self) -> str:
|
|
45
|
+
"""String representation"""
|
|
46
|
+
return f"[{self.status}] {self.code}: {self.message}"
|
|
47
|
+
|
|
48
|
+
def __repr__(self) -> str:
|
|
49
|
+
"""Detailed representation"""
|
|
50
|
+
return (
|
|
51
|
+
f"{self.__class__.__name__}(status={self.status}, code="
|
|
52
|
+
f"'{self.code}', message='{self.message}')"
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
56
|
+
"""Convert to a dictionary"""
|
|
57
|
+
return {
|
|
58
|
+
"status": self.status,
|
|
59
|
+
"code": self.code,
|
|
60
|
+
"message": self.message,
|
|
61
|
+
"details": self.details,
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
# ==================== HTTP Status Exceptions ====================
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class BadRequestException(AppBaseException):
|
|
69
|
+
"""400 Bad Request - Client request error"""
|
|
70
|
+
|
|
71
|
+
def __init__(
|
|
72
|
+
self,
|
|
73
|
+
code: str,
|
|
74
|
+
message: str,
|
|
75
|
+
details: Optional[Dict[str, Any]] = None,
|
|
76
|
+
):
|
|
77
|
+
super().__init__(400, code, message, details)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class UnauthorizedException(AppBaseException):
|
|
81
|
+
"""401 Unauthorized"""
|
|
82
|
+
|
|
83
|
+
def __init__(
|
|
84
|
+
self,
|
|
85
|
+
code: str,
|
|
86
|
+
message: str,
|
|
87
|
+
details: Optional[Dict[str, Any]] = None,
|
|
88
|
+
):
|
|
89
|
+
super().__init__(401, code, message, details)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class ForbiddenException(AppBaseException):
|
|
93
|
+
"""403 Forbidden - Access denied"""
|
|
94
|
+
|
|
95
|
+
def __init__(
|
|
96
|
+
self,
|
|
97
|
+
code: str,
|
|
98
|
+
message: str,
|
|
99
|
+
details: Optional[Dict[str, Any]] = None,
|
|
100
|
+
):
|
|
101
|
+
super().__init__(403, code, message, details)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class NotFoundException(AppBaseException):
|
|
105
|
+
"""404 Not Found - Resource does not exist"""
|
|
106
|
+
|
|
107
|
+
def __init__(
|
|
108
|
+
self,
|
|
109
|
+
code: str,
|
|
110
|
+
message: str,
|
|
111
|
+
details: Optional[Dict[str, Any]] = None,
|
|
112
|
+
):
|
|
113
|
+
super().__init__(404, code, message, details)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class MethodNotAllowedException(AppBaseException):
|
|
117
|
+
"""405 Method Not Allowed"""
|
|
118
|
+
|
|
119
|
+
def __init__(
|
|
120
|
+
self,
|
|
121
|
+
code: str,
|
|
122
|
+
message: str,
|
|
123
|
+
details: Optional[Dict[str, Any]] = None,
|
|
124
|
+
):
|
|
125
|
+
super().__init__(405, code, message, details)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class ConflictException(AppBaseException):
|
|
129
|
+
"""409 Conflict"""
|
|
130
|
+
|
|
131
|
+
def __init__(
|
|
132
|
+
self,
|
|
133
|
+
code: str,
|
|
134
|
+
message: str,
|
|
135
|
+
details: Optional[Dict[str, Any]] = None,
|
|
136
|
+
):
|
|
137
|
+
super().__init__(409, code, message, details)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class UnprocessableEntityException(AppBaseException):
|
|
141
|
+
"""422 Unprocessable Entity"""
|
|
142
|
+
|
|
143
|
+
def __init__(
|
|
144
|
+
self,
|
|
145
|
+
code: str,
|
|
146
|
+
message: str,
|
|
147
|
+
details: Optional[Dict[str, Any]] = None,
|
|
148
|
+
):
|
|
149
|
+
super().__init__(422, code, message, details)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
class TooManyRequestsException(AppBaseException):
|
|
153
|
+
"""429 Too Many Requests"""
|
|
154
|
+
|
|
155
|
+
def __init__(
|
|
156
|
+
self,
|
|
157
|
+
code: str,
|
|
158
|
+
message: str,
|
|
159
|
+
details: Optional[Dict[str, Any]] = None,
|
|
160
|
+
):
|
|
161
|
+
super().__init__(429, code, message, details)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
class InternalServerErrorException(AppBaseException):
|
|
165
|
+
"""500 Internal Server Error"""
|
|
166
|
+
|
|
167
|
+
def __init__(
|
|
168
|
+
self,
|
|
169
|
+
code: str,
|
|
170
|
+
message: str,
|
|
171
|
+
details: Optional[Dict[str, Any]] = None,
|
|
172
|
+
):
|
|
173
|
+
super().__init__(500, code, message, details)
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
class BadGatewayException(AppBaseException):
|
|
177
|
+
"""502 Bad Gateway"""
|
|
178
|
+
|
|
179
|
+
def __init__(
|
|
180
|
+
self,
|
|
181
|
+
code: str,
|
|
182
|
+
message: str,
|
|
183
|
+
details: Optional[Dict[str, Any]] = None,
|
|
184
|
+
):
|
|
185
|
+
super().__init__(502, code, message, details)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
class ServiceUnavailableException(AppBaseException):
|
|
189
|
+
"""503 Service Unavailable"""
|
|
190
|
+
|
|
191
|
+
def __init__(
|
|
192
|
+
self,
|
|
193
|
+
code: str,
|
|
194
|
+
message: str,
|
|
195
|
+
details: Optional[Dict[str, Any]] = None,
|
|
196
|
+
):
|
|
197
|
+
super().__init__(503, code, message, details)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
class GatewayTimeoutException(AppBaseException):
|
|
201
|
+
"""504 Gateway Timeout"""
|
|
202
|
+
|
|
203
|
+
def __init__(
|
|
204
|
+
self,
|
|
205
|
+
code: str,
|
|
206
|
+
message: str,
|
|
207
|
+
details: Optional[Dict[str, Any]] = None,
|
|
208
|
+
):
|
|
209
|
+
super().__init__(504, code, message, details)
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
# ==================== Business Exceptions ====================
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
# Authentication-related exceptions
|
|
216
|
+
class AuthenticationException(UnauthorizedException):
|
|
217
|
+
"""Authentication failed"""
|
|
218
|
+
|
|
219
|
+
def __init__(
|
|
220
|
+
self,
|
|
221
|
+
message: str = "Authentication failed",
|
|
222
|
+
details: Optional[Dict[str, Any]] = None,
|
|
223
|
+
):
|
|
224
|
+
super().__init__("AUTH_FAILED", message, details)
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
class TokenExpiredException(UnauthorizedException):
|
|
228
|
+
"""Token expired"""
|
|
229
|
+
|
|
230
|
+
def __init__(
|
|
231
|
+
self,
|
|
232
|
+
message: str = "Token has expired",
|
|
233
|
+
details: Optional[Dict[str, Any]] = None,
|
|
234
|
+
):
|
|
235
|
+
super().__init__("TOKEN_EXPIRED", message, details)
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
class InvalidTokenException(UnauthorizedException):
|
|
239
|
+
"""Invalid token"""
|
|
240
|
+
|
|
241
|
+
def __init__(
|
|
242
|
+
self,
|
|
243
|
+
message: str = "Invalid token",
|
|
244
|
+
details: Optional[Dict[str, Any]] = None,
|
|
245
|
+
):
|
|
246
|
+
super().__init__("INVALID_TOKEN", message, details)
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
# Permission-related exceptions
|
|
250
|
+
class PermissionDeniedException(ForbiddenException):
|
|
251
|
+
"""Permission denied"""
|
|
252
|
+
|
|
253
|
+
def __init__(
|
|
254
|
+
self,
|
|
255
|
+
message: str = "Permission denied",
|
|
256
|
+
details: Optional[Dict[str, Any]] = None,
|
|
257
|
+
):
|
|
258
|
+
super().__init__("PERMISSION_DENIED", message, details)
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
class AccessDeniedException(ForbiddenException):
|
|
262
|
+
"""Access denied"""
|
|
263
|
+
|
|
264
|
+
def __init__(
|
|
265
|
+
self,
|
|
266
|
+
message: str = "Access denied",
|
|
267
|
+
details: Optional[Dict[str, Any]] = None,
|
|
268
|
+
):
|
|
269
|
+
super().__init__("ACCESS_DENIED", message, details)
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
# Resource-related exceptions
|
|
273
|
+
class ResourceNotFoundException(NotFoundException):
|
|
274
|
+
"""Resource not found"""
|
|
275
|
+
|
|
276
|
+
def __init__(
|
|
277
|
+
self,
|
|
278
|
+
resource_type: str,
|
|
279
|
+
resource_id: str,
|
|
280
|
+
details: Optional[Dict[str, Any]] = None,
|
|
281
|
+
):
|
|
282
|
+
message = f"{resource_type} not found: {resource_id}"
|
|
283
|
+
super().__init__("RESOURCE_NOT_FOUND", message, details)
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
class UserNotFoundException(NotFoundException):
|
|
287
|
+
"""User not found"""
|
|
288
|
+
|
|
289
|
+
def __init__(self, user_id: str, details: Optional[Dict[str, Any]] = None):
|
|
290
|
+
message = f"User not found: {user_id}"
|
|
291
|
+
super().__init__("USER_NOT_FOUND", message, details)
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
class TaskNotFoundException(NotFoundException):
|
|
295
|
+
"""Task not found"""
|
|
296
|
+
|
|
297
|
+
def __init__(self, task_id: str, details: Optional[Dict[str, Any]] = None):
|
|
298
|
+
message = f"Task not found: {task_id}"
|
|
299
|
+
super().__init__("TASK_NOT_FOUND", message, details)
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
# Parameter-related exceptions
|
|
303
|
+
class InvalidParameterException(BadRequestException):
|
|
304
|
+
"""Invalid parameter"""
|
|
305
|
+
|
|
306
|
+
def __init__(
|
|
307
|
+
self,
|
|
308
|
+
parameter: str,
|
|
309
|
+
message: str = None,
|
|
310
|
+
details: Optional[Dict[str, Any]] = None,
|
|
311
|
+
):
|
|
312
|
+
if message is None:
|
|
313
|
+
message = f"Invalid parameter: {parameter}"
|
|
314
|
+
super().__init__("INVALID_PARAMETER", message, details)
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
class MissingParameterException(BadRequestException):
|
|
318
|
+
"""Missing parameter"""
|
|
319
|
+
|
|
320
|
+
def __init__(
|
|
321
|
+
self,
|
|
322
|
+
parameter: str,
|
|
323
|
+
details: Optional[Dict[str, Any]] = None,
|
|
324
|
+
):
|
|
325
|
+
message = f"Missing required parameter: {parameter}"
|
|
326
|
+
super().__init__("MISSING_PARAMETER", message, details)
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
class ParameterValidationException(BadRequestException):
|
|
330
|
+
"""Parameter validation error"""
|
|
331
|
+
|
|
332
|
+
def __init__(
|
|
333
|
+
self,
|
|
334
|
+
parameter: str,
|
|
335
|
+
validation_error: str,
|
|
336
|
+
details: Optional[Dict[str, Any]] = None,
|
|
337
|
+
):
|
|
338
|
+
message = (
|
|
339
|
+
f"Parameter validation failed: {parameter} - {validation_error}"
|
|
340
|
+
)
|
|
341
|
+
super().__init__("PARAMETER_VALIDATION", message, details)
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
# Rate limit-related exceptions
|
|
345
|
+
class RateLimitExceededException(TooManyRequestsException):
|
|
346
|
+
"""Rate limit exceeded"""
|
|
347
|
+
|
|
348
|
+
def __init__(
|
|
349
|
+
self,
|
|
350
|
+
operation: str,
|
|
351
|
+
retry_after: int = 60,
|
|
352
|
+
details: Optional[Dict[str, Any]] = None,
|
|
353
|
+
):
|
|
354
|
+
message = (
|
|
355
|
+
f"Operation {operation} is too frequent, please retry "
|
|
356
|
+
f"after {retry_after} seconds"
|
|
357
|
+
)
|
|
358
|
+
super().__init__("RATE_LIMIT_EXCEEDED", message, details)
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
# Business logic exceptions
|
|
362
|
+
class BusinessLogicException(UnprocessableEntityException):
|
|
363
|
+
"""Business logic exception"""
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
class WorkflowException(BusinessLogicException):
|
|
367
|
+
"""Workflow error"""
|
|
368
|
+
|
|
369
|
+
def __init__(self, message: str, details: Optional[Dict[str, Any]] = None):
|
|
370
|
+
super().__init__("WORKFLOW_ERROR", message, details)
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
class AgentException(BusinessLogicException):
|
|
374
|
+
"""Agent error"""
|
|
375
|
+
|
|
376
|
+
def __init__(self, message: str, details: Optional[Dict[str, Any]] = None):
|
|
377
|
+
super().__init__("AGENT_ERROR", message, details)
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
class ResponseException(BusinessLogicException):
|
|
381
|
+
"""Response error"""
|
|
382
|
+
|
|
383
|
+
def __init__(self, message: str, details: Optional[Dict[str, Any]] = None):
|
|
384
|
+
super().__init__("RESPONSE_ERROR", message, details)
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
# System-related exceptions
|
|
388
|
+
class SystemException(InternalServerErrorException):
|
|
389
|
+
"""System exception"""
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
class DatabaseException(SystemException):
|
|
393
|
+
"""Database error"""
|
|
394
|
+
|
|
395
|
+
def __init__(self, message: str, details: Optional[Dict[str, Any]] = None):
|
|
396
|
+
super().__init__("DATABASE_ERROR", message, details)
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
class RedisException(SystemException):
|
|
400
|
+
"""Redis error"""
|
|
401
|
+
|
|
402
|
+
def __init__(self, message: str, details: Optional[Dict[str, Any]] = None):
|
|
403
|
+
super().__init__("REDIS_ERROR", message, details)
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
class ExternalServiceException(SystemException):
|
|
407
|
+
"""External service error"""
|
|
408
|
+
|
|
409
|
+
def __init__(
|
|
410
|
+
self,
|
|
411
|
+
service_name: str,
|
|
412
|
+
message: str,
|
|
413
|
+
details: Optional[Dict[str, Any]] = None,
|
|
414
|
+
):
|
|
415
|
+
full_message = f"External service {service_name} error: {message}"
|
|
416
|
+
super().__init__("EXTERNAL_SERVICE_ERROR", full_message, details)
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
# Configuration-related exceptions
|
|
420
|
+
class ConfigurationException(InternalServerErrorException):
|
|
421
|
+
"""Configuration error"""
|
|
422
|
+
|
|
423
|
+
def __init__(
|
|
424
|
+
self,
|
|
425
|
+
config_key: str,
|
|
426
|
+
message: str = None,
|
|
427
|
+
details: Optional[Dict[str, Any]] = None,
|
|
428
|
+
):
|
|
429
|
+
if message is None:
|
|
430
|
+
message = f"Configuration error: {config_key}"
|
|
431
|
+
super().__init__("CONFIGURATION_ERROR", message, details)
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
# Network-related exceptions
|
|
435
|
+
class NetworkException(ServiceUnavailableException):
|
|
436
|
+
"""Network error"""
|
|
437
|
+
|
|
438
|
+
def __init__(self, message: str, details: Optional[Dict[str, Any]] = None):
|
|
439
|
+
super().__init__("NETWORK_ERROR", message, details)
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
class TimeoutException(GatewayTimeoutException):
|
|
443
|
+
"""Timeout error"""
|
|
444
|
+
|
|
445
|
+
def __init__(
|
|
446
|
+
self,
|
|
447
|
+
operation: str,
|
|
448
|
+
timeout: int,
|
|
449
|
+
details: Optional[Dict[str, Any]] = None,
|
|
450
|
+
):
|
|
451
|
+
message = (
|
|
452
|
+
f"Operation {operation} timed out, timeout limit:"
|
|
453
|
+
f" {timeout} seconds"
|
|
454
|
+
)
|
|
455
|
+
super().__init__("TIMEOUT", message, details)
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
# ==================== Agent runtime related Exceptions ====================
|
|
459
|
+
class AgentRuntimeErrorException(BusinessLogicException):
|
|
460
|
+
"""
|
|
461
|
+
Base class for agent runtime error exceptions (HTTP 422 - Unprocessable
|
|
462
|
+
Entity)
|
|
463
|
+
"""
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
class ToolExecutionException(AgentRuntimeErrorException):
|
|
467
|
+
"""Error occurred during tool execution"""
|
|
468
|
+
|
|
469
|
+
def __init__(self, details: Optional[Dict[str, Any]] = None):
|
|
470
|
+
super().__init__(
|
|
471
|
+
"TOOL_EXECUTION_FAILED",
|
|
472
|
+
"Error occurred during tool execution",
|
|
473
|
+
details,
|
|
474
|
+
)
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
class ToolNotFoundException(AgentRuntimeErrorException):
|
|
478
|
+
"""Specified tool not found"""
|
|
479
|
+
|
|
480
|
+
def __init__(
|
|
481
|
+
self,
|
|
482
|
+
tool_name: str,
|
|
483
|
+
details: Optional[Dict[str, Any]] = None,
|
|
484
|
+
):
|
|
485
|
+
message = f"Tool not found: {tool_name}"
|
|
486
|
+
super().__init__("TOOL_NOT_FOUND", message, details)
|
|
487
|
+
|
|
488
|
+
|
|
489
|
+
class MCPConnectionException(AgentRuntimeErrorException):
|
|
490
|
+
"""Failed to connect to MCP service"""
|
|
491
|
+
|
|
492
|
+
def __init__(self, details: Optional[Dict[str, Any]] = None):
|
|
493
|
+
super().__init__(
|
|
494
|
+
"MCP_CONNECTION_FAILED",
|
|
495
|
+
"Failed to connect to MCP service",
|
|
496
|
+
details,
|
|
497
|
+
)
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
class MCPProtocolException(AgentRuntimeErrorException):
|
|
501
|
+
"""Invalid MCP protocol message format"""
|
|
502
|
+
|
|
503
|
+
def __init__(self, details: Optional[Dict[str, Any]] = None):
|
|
504
|
+
super().__init__(
|
|
505
|
+
"MCP_PROTOCOL_ERROR",
|
|
506
|
+
"Invalid MCP protocol message format",
|
|
507
|
+
details,
|
|
508
|
+
)
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
class ModelExecutionException(AgentRuntimeErrorException):
|
|
512
|
+
"""Error occurred during model execution"""
|
|
513
|
+
|
|
514
|
+
def __init__(
|
|
515
|
+
self,
|
|
516
|
+
model_name: str,
|
|
517
|
+
details: Optional[Dict[str, Any]] = None,
|
|
518
|
+
):
|
|
519
|
+
message = f"Error occurred during execution of model: {model_name}"
|
|
520
|
+
super().__init__("MODEL_EXECUTION_FAILED", message, details)
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
class ModelTimeoutException(AgentRuntimeErrorException):
|
|
524
|
+
"""Model inference timed out"""
|
|
525
|
+
|
|
526
|
+
def __init__(
|
|
527
|
+
self,
|
|
528
|
+
model_name: str,
|
|
529
|
+
timeout: int,
|
|
530
|
+
details: Optional[Dict[str, Any]] = None,
|
|
531
|
+
):
|
|
532
|
+
message = (
|
|
533
|
+
f"Model inference timed out: {model_name}, timeout limit:"
|
|
534
|
+
f" {timeout} seconds"
|
|
535
|
+
)
|
|
536
|
+
super().__init__("MODEL_TIMEOUT", message, details)
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
class ModelNotFoundException(AgentRuntimeErrorException):
|
|
540
|
+
"""Specified model not found"""
|
|
541
|
+
|
|
542
|
+
def __init__(
|
|
543
|
+
self,
|
|
544
|
+
model_name: str,
|
|
545
|
+
details: Optional[Dict[str, Any]] = None,
|
|
546
|
+
):
|
|
547
|
+
message = f"Model not found: {model_name}"
|
|
548
|
+
super().__init__("MODEL_NOT_FOUND", message, details)
|
|
549
|
+
|
|
550
|
+
|
|
551
|
+
class UnauthorizedModelAccessException(AgentRuntimeErrorException):
|
|
552
|
+
"""Unauthorized access to model"""
|
|
553
|
+
|
|
554
|
+
def __init__(
|
|
555
|
+
self,
|
|
556
|
+
model_name: str,
|
|
557
|
+
details: Optional[Dict[str, Any]] = None,
|
|
558
|
+
):
|
|
559
|
+
message = f"Unauthorized access to model: {model_name}"
|
|
560
|
+
super().__init__("MODEL_UNAUTHORIZED_ACCESS", message, details)
|
|
561
|
+
|
|
562
|
+
|
|
563
|
+
class UnknownAgentException(AgentRuntimeErrorException):
|
|
564
|
+
"""Generic agent error with no specific classification"""
|
|
565
|
+
|
|
566
|
+
def __init__(
|
|
567
|
+
self,
|
|
568
|
+
original_exception: Optional[Exception] = None,
|
|
569
|
+
details: Optional[Dict[str, Any]] = None,
|
|
570
|
+
):
|
|
571
|
+
message = "Unknown agent error" + (
|
|
572
|
+
f": {type(original_exception).__name__}: {str(original_exception)}"
|
|
573
|
+
if original_exception is not None
|
|
574
|
+
else ""
|
|
575
|
+
)
|
|
576
|
+
super().__init__(
|
|
577
|
+
"AGENT_UNKNOWN_ERROR",
|
|
578
|
+
message,
|
|
579
|
+
details,
|
|
580
|
+
)
|
|
@@ -5,6 +5,7 @@ from ....common.utils.lazy_loader import install_lazy_loader
|
|
|
5
5
|
if TYPE_CHECKING:
|
|
6
6
|
from .state_service import StateService, InMemoryStateService
|
|
7
7
|
from .redis_state_service import RedisStateService
|
|
8
|
+
from .state_service_factory import StateServiceFactory
|
|
8
9
|
|
|
9
10
|
install_lazy_loader(
|
|
10
11
|
globals(),
|
|
@@ -12,5 +13,6 @@ install_lazy_loader(
|
|
|
12
13
|
"StateService": ".state_service",
|
|
13
14
|
"InMemoryStateService": ".state_service",
|
|
14
15
|
"RedisStateService": ".redis_state_service",
|
|
16
|
+
"StateServiceFactory": ".state_service_factory",
|
|
15
17
|
},
|
|
16
18
|
)
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
from typing import Callable, Dict
|
|
4
|
+
|
|
5
|
+
from ..service_factory import ServiceFactory
|
|
6
|
+
from .state_service import StateService, InMemoryStateService
|
|
7
|
+
from .redis_state_service import RedisStateService
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class StateServiceFactory(ServiceFactory[StateService]):
|
|
11
|
+
"""
|
|
12
|
+
Factory for StateService, supports both environment variables and kwargs
|
|
13
|
+
parameters.
|
|
14
|
+
|
|
15
|
+
Usage examples:
|
|
16
|
+
1. Start with environment variables only:
|
|
17
|
+
export STATE_BACKEND=redis
|
|
18
|
+
export STATE_REDIS_REDIS_URL="redis://localhost:6379/5"
|
|
19
|
+
service = await StateServiceFactory.create()
|
|
20
|
+
|
|
21
|
+
2. Override environment variables with arguments:
|
|
22
|
+
export STATE_BACKEND=redis
|
|
23
|
+
export STATE_REDIS_REDIS_URL="redis://localhost:6379/5"
|
|
24
|
+
service = await StateServiceFactory.create(
|
|
25
|
+
redis_url="redis://otherhost:6379/1"
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
3. User-defined backend:
|
|
29
|
+
from my_backend import PostgresStateService
|
|
30
|
+
StateServiceFactory.register_backend(
|
|
31
|
+
"postgres",
|
|
32
|
+
PostgresStateService,
|
|
33
|
+
)
|
|
34
|
+
export STATE_BACKEND=postgres
|
|
35
|
+
export STATE_POSTGRES_DSN="postgresql://user:pass@localhost/db"
|
|
36
|
+
service = await StateServiceFactory.create()
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
_registry: Dict[str, Callable[..., StateService]] = {}
|
|
40
|
+
_env_prefix = "STATE_"
|
|
41
|
+
_default_backend = "in_memory"
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
StateServiceFactory.register_backend(
|
|
45
|
+
"in_memory",
|
|
46
|
+
lambda **kwargs: InMemoryStateService(),
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
StateServiceFactory.register_backend(
|
|
50
|
+
"redis",
|
|
51
|
+
lambda **kwargs: RedisStateService(
|
|
52
|
+
redis_url=kwargs.get("redis_url", "redis://localhost:6379/0"),
|
|
53
|
+
redis_client=kwargs.get("redis_client"),
|
|
54
|
+
),
|
|
55
|
+
)
|
|
@@ -9,6 +9,7 @@ if TYPE_CHECKING:
|
|
|
9
9
|
from .reme_personal_memory_service import ReMePersonalMemoryService
|
|
10
10
|
from .mem0_memory_service import Mem0MemoryService
|
|
11
11
|
from .tablestore_memory_service import TablestoreMemoryService
|
|
12
|
+
from .memory_service_factory import MemoryServiceFactory
|
|
12
13
|
|
|
13
14
|
install_lazy_loader(
|
|
14
15
|
globals(),
|
|
@@ -20,5 +21,6 @@ install_lazy_loader(
|
|
|
20
21
|
"ReMePersonalMemoryService": ".reme_personal_memory_service",
|
|
21
22
|
"Mem0MemoryService": ".mem0_memory_service",
|
|
22
23
|
"TablestoreMemoryService": ".tablestore_memory_service",
|
|
24
|
+
"MemoryServiceFactory": ".memory_service_factory",
|
|
23
25
|
},
|
|
24
26
|
)
|