aigroup-econ-mcp 0.4.2__py3-none-any.whl → 1.4.3__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 (119) hide show
  1. .gitignore +253 -0
  2. PKG-INFO +710 -0
  3. README.md +672 -0
  4. __init__.py +14 -0
  5. aigroup_econ_mcp-1.4.3.dist-info/METADATA +710 -0
  6. aigroup_econ_mcp-1.4.3.dist-info/RECORD +92 -0
  7. aigroup_econ_mcp-1.4.3.dist-info/entry_points.txt +2 -0
  8. aigroup_econ_mcp-1.4.3.dist-info/licenses/LICENSE +21 -0
  9. cli.py +28 -0
  10. econometrics/README.md +18 -0
  11. econometrics/__init__.py +191 -0
  12. econometrics/advanced_methods/modern_computing_machine_learning/__init__.py +0 -0
  13. econometrics/basic_parametric_estimation/__init__.py +31 -0
  14. econometrics/basic_parametric_estimation/gmm/__init__.py +13 -0
  15. econometrics/basic_parametric_estimation/gmm/gmm_model.py +256 -0
  16. econometrics/basic_parametric_estimation/mle/__init__.py +13 -0
  17. econometrics/basic_parametric_estimation/mle/mle_model.py +241 -0
  18. econometrics/basic_parametric_estimation/ols/__init__.py +13 -0
  19. econometrics/basic_parametric_estimation/ols/ols_model.py +141 -0
  20. econometrics/causal_inference/causal_identification_strategy/__init__.py +0 -0
  21. econometrics/missing_data/missing_data_measurement_error/__init__.py +0 -0
  22. econometrics/model_specification_diagnostics_robust_inference/README.md +173 -0
  23. econometrics/model_specification_diagnostics_robust_inference/__init__.py +78 -0
  24. econometrics/model_specification_diagnostics_robust_inference/diagnostic_tests/__init__.py +20 -0
  25. econometrics/model_specification_diagnostics_robust_inference/diagnostic_tests/diagnostic_tests_model.py +149 -0
  26. econometrics/model_specification_diagnostics_robust_inference/generalized_least_squares/__init__.py +15 -0
  27. econometrics/model_specification_diagnostics_robust_inference/generalized_least_squares/gls_model.py +130 -0
  28. econometrics/model_specification_diagnostics_robust_inference/model_selection/__init__.py +18 -0
  29. econometrics/model_specification_diagnostics_robust_inference/model_selection/model_selection_model.py +286 -0
  30. econometrics/model_specification_diagnostics_robust_inference/regularization/__init__.py +15 -0
  31. econometrics/model_specification_diagnostics_robust_inference/regularization/regularization_model.py +177 -0
  32. econometrics/model_specification_diagnostics_robust_inference/robust_errors/__init__.py +15 -0
  33. econometrics/model_specification_diagnostics_robust_inference/robust_errors/robust_errors_model.py +122 -0
  34. econometrics/model_specification_diagnostics_robust_inference/simultaneous_equations/__init__.py +15 -0
  35. econometrics/model_specification_diagnostics_robust_inference/simultaneous_equations/simultaneous_equations_model.py +246 -0
  36. econometrics/model_specification_diagnostics_robust_inference/weighted_least_squares/__init__.py +15 -0
  37. econometrics/model_specification_diagnostics_robust_inference/weighted_least_squares/wls_model.py +127 -0
  38. econometrics/nonparametric/nonparametric_semiparametric_methods/__init__.py +0 -0
  39. econometrics/spatial_econometrics/spatial_econometrics_new/__init__.py +0 -0
  40. econometrics/specific_data_modeling/micro_discrete_limited_data/__init__.py +0 -0
  41. econometrics/specific_data_modeling/survival_duration_data/__init__.py +0 -0
  42. econometrics/specific_data_modeling/time_series_panel_data/__init__.py +143 -0
  43. econometrics/specific_data_modeling/time_series_panel_data/arima_model.py +104 -0
  44. econometrics/specific_data_modeling/time_series_panel_data/cointegration_vecm.py +334 -0
  45. econometrics/specific_data_modeling/time_series_panel_data/dynamic_panel_models.py +653 -0
  46. econometrics/specific_data_modeling/time_series_panel_data/exponential_smoothing.py +176 -0
  47. econometrics/specific_data_modeling/time_series_panel_data/garch_model.py +198 -0
  48. econometrics/specific_data_modeling/time_series_panel_data/panel_diagnostics.py +125 -0
  49. econometrics/specific_data_modeling/time_series_panel_data/panel_var.py +60 -0
  50. econometrics/specific_data_modeling/time_series_panel_data/structural_break_tests.py +87 -0
  51. econometrics/specific_data_modeling/time_series_panel_data/time_varying_parameter_models.py +106 -0
  52. econometrics/specific_data_modeling/time_series_panel_data/unit_root_tests.py +204 -0
  53. econometrics/specific_data_modeling/time_series_panel_data/var_svar_model.py +372 -0
  54. econometrics/statistical_inference/statistical_inference_techniques/__init__.py +0 -0
  55. econometrics/statistics/distribution_decomposition_methods/__init__.py +0 -0
  56. econometrics/tests/basic_parametric_estimation_tests/__init__.py +3 -0
  57. econometrics/tests/basic_parametric_estimation_tests/test_gmm.py +128 -0
  58. econometrics/tests/basic_parametric_estimation_tests/test_mle.py +127 -0
  59. econometrics/tests/basic_parametric_estimation_tests/test_ols.py +100 -0
  60. econometrics/tests/model_specification_diagnostics_tests/__init__.py +3 -0
  61. econometrics/tests/model_specification_diagnostics_tests/test_diagnostic_tests.py +86 -0
  62. econometrics/tests/model_specification_diagnostics_tests/test_robust_errors.py +89 -0
  63. econometrics/tests/specific_data_modeling_tests/__init__.py +3 -0
  64. econometrics/tests/specific_data_modeling_tests/test_arima.py +98 -0
  65. econometrics/tests/specific_data_modeling_tests/test_dynamic_panel.py +198 -0
  66. econometrics/tests/specific_data_modeling_tests/test_exponential_smoothing.py +105 -0
  67. econometrics/tests/specific_data_modeling_tests/test_garch.py +118 -0
  68. econometrics/tests/specific_data_modeling_tests/test_unit_root.py +156 -0
  69. econometrics/tests/specific_data_modeling_tests/test_var.py +124 -0
  70. prompts/__init__.py +0 -0
  71. prompts/analysis_guides.py +43 -0
  72. pyproject.toml +78 -0
  73. resources/MCP_MASTER_GUIDE.md +422 -0
  74. resources/MCP_TOOLS_DATA_FORMAT_GUIDE.md +185 -0
  75. resources/__init__.py +0 -0
  76. server.py +83 -0
  77. tools/README.md +88 -0
  78. tools/__init__.py +45 -0
  79. tools/data_loader.py +213 -0
  80. tools/decorators.py +38 -0
  81. tools/econometrics_adapter.py +286 -0
  82. tools/mcp_tool_groups/__init__.py +1 -0
  83. tools/mcp_tool_groups/basic_parametric_tools.py +173 -0
  84. tools/mcp_tool_groups/model_specification_tools.py +402 -0
  85. tools/mcp_tool_groups/time_series_tools.py +494 -0
  86. tools/mcp_tools_registry.py +114 -0
  87. tools/model_specification_adapter.py +369 -0
  88. tools/output_formatter.py +563 -0
  89. tools/time_series_panel_data_adapter.py +858 -0
  90. tools/time_series_panel_data_tools.py +65 -0
  91. aigroup_econ_mcp/__init__.py +0 -19
  92. aigroup_econ_mcp/cli.py +0 -82
  93. aigroup_econ_mcp/config.py +0 -561
  94. aigroup_econ_mcp/server.py +0 -452
  95. aigroup_econ_mcp/tools/__init__.py +0 -18
  96. aigroup_econ_mcp/tools/base.py +0 -470
  97. aigroup_econ_mcp/tools/cache.py +0 -533
  98. aigroup_econ_mcp/tools/data_loader.py +0 -171
  99. aigroup_econ_mcp/tools/file_parser.py +0 -829
  100. aigroup_econ_mcp/tools/machine_learning.py +0 -60
  101. aigroup_econ_mcp/tools/ml_ensemble.py +0 -210
  102. aigroup_econ_mcp/tools/ml_evaluation.py +0 -272
  103. aigroup_econ_mcp/tools/ml_models.py +0 -54
  104. aigroup_econ_mcp/tools/ml_regularization.py +0 -172
  105. aigroup_econ_mcp/tools/monitoring.py +0 -555
  106. aigroup_econ_mcp/tools/optimized_example.py +0 -229
  107. aigroup_econ_mcp/tools/panel_data.py +0 -553
  108. aigroup_econ_mcp/tools/regression.py +0 -214
  109. aigroup_econ_mcp/tools/statistics.py +0 -154
  110. aigroup_econ_mcp/tools/time_series.py +0 -667
  111. aigroup_econ_mcp/tools/timeout.py +0 -283
  112. aigroup_econ_mcp/tools/tool_handlers.py +0 -378
  113. aigroup_econ_mcp/tools/tool_registry.py +0 -170
  114. aigroup_econ_mcp/tools/validation.py +0 -482
  115. aigroup_econ_mcp-0.4.2.dist-info/METADATA +0 -360
  116. aigroup_econ_mcp-0.4.2.dist-info/RECORD +0 -29
  117. aigroup_econ_mcp-0.4.2.dist-info/entry_points.txt +0 -2
  118. /aigroup_econ_mcp-0.4.2.dist-info/licenses/LICENSE → /LICENSE +0 -0
  119. {aigroup_econ_mcp-0.4.2.dist-info → aigroup_econ_mcp-1.4.3.dist-info}/WHEEL +0 -0
@@ -0,0 +1,402 @@
1
+ """
2
+ 模型规范、诊断和稳健推断工具组
3
+ 包含诊断检验、GLS、WLS、稳健标准误、模型选择、正则化、联立方程等方法
4
+ """
5
+
6
+ from typing import List, Optional, Union, Dict, Any
7
+ from mcp.server.fastmcp import Context
8
+ from mcp.server.session import ServerSession
9
+
10
+ from ..mcp_tools_registry import ToolGroup
11
+ from ..econometrics_adapter import (
12
+ diagnostic_tests_adapter,
13
+ gls_adapter,
14
+ wls_adapter,
15
+ robust_errors_adapter,
16
+ model_selection_adapter,
17
+ regularization_adapter,
18
+ simultaneous_equations_adapter
19
+ )
20
+
21
+
22
+ class ModelSpecificationTools(ToolGroup):
23
+ """模型规范、诊断和稳健推断工具组"""
24
+
25
+ name = "MODEL SPECIFICATION, DIAGNOSTICS & ROBUST INFERENCE"
26
+ description = "模型规范检验、诊断测试和稳健推断方法工具"
27
+ version = "2.0.0"
28
+
29
+ @classmethod
30
+ def get_tools(cls) -> List[Dict[str, Any]]:
31
+ """返回工具列表"""
32
+ return [
33
+ {
34
+ "name": "model_diagnostic_tests",
35
+ "handler": cls.diagnostic_tests_tool,
36
+ "description": "Model Diagnostic Tests (Heteroskedasticity, Autocorrelation, Normality, VIF)"
37
+ },
38
+ {
39
+ "name": "generalized_least_squares",
40
+ "handler": cls.gls_tool,
41
+ "description": "Generalized Least Squares (GLS) Regression"
42
+ },
43
+ {
44
+ "name": "weighted_least_squares",
45
+ "handler": cls.wls_tool,
46
+ "description": "Weighted Least Squares (WLS) Regression"
47
+ },
48
+ {
49
+ "name": "robust_errors_regression",
50
+ "handler": cls.robust_errors_tool,
51
+ "description": "Robust Standard Errors Regression (Heteroskedasticity-Robust)"
52
+ },
53
+ {
54
+ "name": "model_selection_criteria",
55
+ "handler": cls.model_selection_tool,
56
+ "description": "Model Selection Criteria (AIC, BIC, HQIC, Cross-Validation)"
57
+ },
58
+ {
59
+ "name": "regularized_regression",
60
+ "handler": cls.regularization_tool,
61
+ "description": "Regularized Regression (Ridge, LASSO, Elastic Net)"
62
+ },
63
+ {
64
+ "name": "simultaneous_equations_model",
65
+ "handler": cls.simultaneous_equations_tool,
66
+ "description": "Simultaneous Equations Model (2SLS)"
67
+ }
68
+ ]
69
+
70
+ @classmethod
71
+ def get_help_text(cls) -> str:
72
+ """返回帮助文档"""
73
+ return """
74
+ 15. Model Diagnostic Tests (model_diagnostic_tests)
75
+ - Heteroskedasticity: Breusch-Pagan, White tests
76
+ - Autocorrelation: Durbin-Watson test
77
+ - Normality: Jarque-Bera test
78
+ - Multicollinearity: VIF calculation
79
+ - Comprehensive model diagnostics
80
+
81
+ 16. Generalized Least Squares (generalized_least_squares)
82
+ - GLS: Handle heteroskedasticity and autocorrelation
83
+ - Covariance matrix: User-specified or estimated
84
+ - Efficient: More efficient than OLS under GLS assumptions
85
+
86
+ 17. Weighted Least Squares (weighted_least_squares)
87
+ - WLS: Handle heteroskedasticity with known weights
88
+ - Weights: Inverse of variance or other weighting schemes
89
+ - Applications: Survey data, grouped data
90
+
91
+ 18. Robust Standard Errors (robust_errors_regression)
92
+ - Heteroskedasticity-robust: HC0, HC1, HC2, HC3
93
+ - Inference: Valid inference under heteroskedasticity
94
+ - Applications: Cross-sectional data with heteroskedasticity
95
+
96
+ 19. Model Selection Criteria (model_selection_criteria)
97
+ - Information criteria: AIC, BIC, HQIC
98
+ - Cross-validation: K-fold, leave-one-out
99
+ - Granger causality: Test for causality in time series
100
+ - Model comparison: Select best model specification
101
+
102
+ 20. Regularized Regression (regularized_regression)
103
+ - Ridge regression: L2 penalty for multicollinearity
104
+ - LASSO: L1 penalty for variable selection
105
+ - Elastic Net: Combined L1 and L2 penalties
106
+ - Applications: High-dimensional data, feature selection
107
+
108
+ 21. Simultaneous Equations Model (simultaneous_equations_model)
109
+ - 2SLS: Two-stage least squares for simultaneous equations
110
+ - Endogeneity: Handle endogenous regressors
111
+ - Instrumental variables: Valid instruments required
112
+ - Applications: Supply-demand models, macroeconomic models
113
+ """
114
+
115
+ @staticmethod
116
+ async def diagnostic_tests_tool(
117
+ y_data: Optional[List[float]] = None,
118
+ x_data: Optional[Union[List[float], List[List[float]]]] = None,
119
+ file_path: Optional[str] = None,
120
+ feature_names: Optional[List[str]] = None,
121
+ constant: bool = True,
122
+ output_format: str = "json",
123
+ save_path: Optional[str] = None,
124
+ ctx: Context[ServerSession, None] = None
125
+ ) -> str:
126
+ """Model Diagnostic Tests"""
127
+ try:
128
+ if ctx:
129
+ await ctx.info("Starting model diagnostic tests...")
130
+
131
+ result = diagnostic_tests_adapter(
132
+ y_data=y_data,
133
+ x_data=x_data,
134
+ file_path=file_path,
135
+ feature_names=feature_names,
136
+ constant=constant,
137
+ output_format=output_format,
138
+ save_path=save_path
139
+ )
140
+
141
+ if ctx:
142
+ await ctx.info("Model diagnostic tests complete")
143
+
144
+ return result
145
+ except Exception as e:
146
+ if ctx:
147
+ await ctx.error(f"Error: {str(e)}")
148
+ raise
149
+
150
+ @staticmethod
151
+ async def gls_tool(
152
+ y_data: Optional[List[float]] = None,
153
+ x_data: Optional[Union[List[float], List[List[float]]]] = None,
154
+ file_path: Optional[str] = None,
155
+ sigma: Optional[List[List[float]]] = None,
156
+ feature_names: Optional[List[str]] = None,
157
+ constant: bool = True,
158
+ confidence_level: float = 0.95,
159
+ output_format: str = "json",
160
+ save_path: Optional[str] = None,
161
+ ctx: Context[ServerSession, None] = None
162
+ ) -> str:
163
+ """Generalized Least Squares Regression"""
164
+ try:
165
+ if ctx:
166
+ await ctx.info("Starting GLS regression...")
167
+
168
+ result = gls_adapter(
169
+ y_data=y_data,
170
+ x_data=x_data,
171
+ file_path=file_path,
172
+ sigma=sigma,
173
+ feature_names=feature_names,
174
+ constant=constant,
175
+ confidence_level=confidence_level,
176
+ output_format=output_format,
177
+ save_path=save_path
178
+ )
179
+
180
+ if ctx:
181
+ await ctx.info("GLS regression complete")
182
+
183
+ return result
184
+ except Exception as e:
185
+ if ctx:
186
+ await ctx.error(f"Error: {str(e)}")
187
+ raise
188
+
189
+ @staticmethod
190
+ async def wls_tool(
191
+ y_data: Optional[List[float]] = None,
192
+ x_data: Optional[Union[List[float], List[List[float]]]] = None,
193
+ file_path: Optional[str] = None,
194
+ weights: Optional[List[float]] = None,
195
+ feature_names: Optional[List[str]] = None,
196
+ constant: bool = True,
197
+ confidence_level: float = 0.95,
198
+ output_format: str = "json",
199
+ save_path: Optional[str] = None,
200
+ ctx: Context[ServerSession, None] = None
201
+ ) -> str:
202
+ """Weighted Least Squares Regression"""
203
+ try:
204
+ if ctx:
205
+ await ctx.info("Starting WLS regression...")
206
+
207
+ result = wls_adapter(
208
+ y_data=y_data,
209
+ x_data=x_data,
210
+ file_path=file_path,
211
+ weights=weights,
212
+ feature_names=feature_names,
213
+ constant=constant,
214
+ confidence_level=confidence_level,
215
+ output_format=output_format,
216
+ save_path=save_path
217
+ )
218
+
219
+ if ctx:
220
+ await ctx.info("WLS regression complete")
221
+
222
+ return result
223
+ except Exception as e:
224
+ if ctx:
225
+ await ctx.error(f"Error: {str(e)}")
226
+ raise
227
+
228
+ @staticmethod
229
+ async def robust_errors_tool(
230
+ y_data: Optional[List[float]] = None,
231
+ x_data: Optional[Union[List[float], List[List[float]]]] = None,
232
+ file_path: Optional[str] = None,
233
+ feature_names: Optional[List[str]] = None,
234
+ constant: bool = True,
235
+ confidence_level: float = 0.95,
236
+ cov_type: str = "HC1",
237
+ output_format: str = "json",
238
+ save_path: Optional[str] = None,
239
+ ctx: Context[ServerSession, None] = None
240
+ ) -> str:
241
+ """Robust Standard Errors Regression"""
242
+ try:
243
+ if ctx:
244
+ await ctx.info("Starting robust errors regression...")
245
+
246
+ result = robust_errors_adapter(
247
+ y_data=y_data,
248
+ x_data=x_data,
249
+ file_path=file_path,
250
+ feature_names=feature_names,
251
+ constant=constant,
252
+ confidence_level=confidence_level,
253
+ cov_type=cov_type,
254
+ output_format=output_format,
255
+ save_path=save_path
256
+ )
257
+
258
+ if ctx:
259
+ await ctx.info("Robust errors regression complete")
260
+
261
+ return result
262
+ except Exception as e:
263
+ if ctx:
264
+ await ctx.error(f"Error: {str(e)}")
265
+ raise
266
+
267
+ @staticmethod
268
+ async def model_selection_tool(
269
+ y_data: Optional[List[float]] = None,
270
+ x_data: Optional[Union[List[float], List[List[float]]]] = None,
271
+ file_path: Optional[str] = None,
272
+ feature_names: Optional[List[str]] = None,
273
+ constant: bool = True,
274
+ cv_folds: Optional[int] = None,
275
+ output_format: str = "json",
276
+ save_path: Optional[str] = None,
277
+ ctx: Context[ServerSession, None] = None
278
+ ) -> str:
279
+ """Model Selection Criteria"""
280
+ try:
281
+ if ctx:
282
+ await ctx.info("Starting model selection analysis...")
283
+
284
+ result = model_selection_adapter(
285
+ y_data=y_data,
286
+ x_data=x_data,
287
+ file_path=file_path,
288
+ feature_names=feature_names,
289
+ constant=constant,
290
+ cv_folds=cv_folds,
291
+ output_format=output_format,
292
+ save_path=save_path
293
+ )
294
+
295
+ if ctx:
296
+ await ctx.info("Model selection analysis complete")
297
+
298
+ return result
299
+ except Exception as e:
300
+ if ctx:
301
+ await ctx.error(f"Error: {str(e)}")
302
+ raise
303
+
304
+ @staticmethod
305
+ async def regularization_tool(
306
+ y_data: Optional[List[float]] = None,
307
+ x_data: Optional[Union[List[float], List[List[float]]]] = None,
308
+ file_path: Optional[str] = None,
309
+ method: str = "ridge",
310
+ alpha: float = 1.0,
311
+ l1_ratio: float = 0.5,
312
+ feature_names: Optional[List[str]] = None,
313
+ fit_intercept: bool = True,
314
+ output_format: str = "json",
315
+ save_path: Optional[str] = None,
316
+ ctx: Context[ServerSession, None] = None
317
+ ) -> str:
318
+ """Regularized Regression"""
319
+ try:
320
+ if ctx:
321
+ await ctx.info(f"Starting {method} regularized regression...")
322
+
323
+ result = regularization_adapter(
324
+ y_data=y_data,
325
+ x_data=x_data,
326
+ file_path=file_path,
327
+ method=method,
328
+ alpha=alpha,
329
+ l1_ratio=l1_ratio,
330
+ feature_names=feature_names,
331
+ fit_intercept=fit_intercept,
332
+ output_format=output_format,
333
+ save_path=save_path
334
+ )
335
+
336
+ if ctx:
337
+ await ctx.info(f"{method} regularized regression complete")
338
+
339
+ return result
340
+ except Exception as e:
341
+ if ctx:
342
+ await ctx.error(f"Error: {str(e)}")
343
+ raise
344
+
345
+ @staticmethod
346
+ async def simultaneous_equations_tool(
347
+ y_data: Optional[List[List[float]]] = None,
348
+ x_data: Optional[List[List[float]]] = None,
349
+ file_path: Optional[str] = None,
350
+ instruments: Optional[List[List[float]]] = None,
351
+ equation_names: Optional[List[str]] = None,
352
+ instrument_names: Optional[List[str]] = None,
353
+ constant: bool = True,
354
+ output_format: str = "json",
355
+ save_path: Optional[str] = None,
356
+ ctx: Context[ServerSession, None] = None
357
+ ) -> str:
358
+ """
359
+ Simultaneous Equations Model (2SLS)
360
+
361
+ 数据格式说明:
362
+ - y_data: 因变量数据,二维列表,每个子列表代表一个方程的因变量时间序列
363
+ - x_data: 自变量数据,二维列表,每个子列表代表一个观测的所有自变量值
364
+ - instruments: 工具变量数据,二维列表,每个子列表代表一个观测的所有工具变量值
365
+
366
+ 重要: 所有数据的观测数量必须相同
367
+
368
+ 示例调用:
369
+ {
370
+ "y_data": [[1.0, 1.2, 1.4, 1.6], [2.0, 2.2, 2.4, 2.6]],
371
+ "x_data": [[1.5, 2.5], [1.7, 2.7], [1.9, 2.9], [2.1, 3.1]],
372
+ "instruments": [[1.8, 2.8], [2.0, 3.0], [2.2, 3.2], [2.4, 3.4]],
373
+ "equation_names": ["Demand", "Supply"],
374
+ "instrument_names": ["Income", "Price"],
375
+ "constant": true,
376
+ "output_format": "json"
377
+ }
378
+ """
379
+ try:
380
+ if ctx:
381
+ await ctx.info("Starting simultaneous equations model analysis...")
382
+
383
+ result = simultaneous_equations_adapter(
384
+ y_data=y_data,
385
+ x_data=x_data,
386
+ file_path=file_path,
387
+ instruments=instruments,
388
+ equation_names=equation_names,
389
+ instrument_names=instrument_names,
390
+ constant=constant,
391
+ output_format=output_format,
392
+ save_path=save_path
393
+ )
394
+
395
+ if ctx:
396
+ await ctx.info("Simultaneous equations model analysis complete")
397
+
398
+ return result
399
+ except Exception as e:
400
+ if ctx:
401
+ await ctx.error(f"Error: {str(e)}")
402
+ raise