aigroup-econ-mcp 1.4.3__py3-none-any.whl → 2.0.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.
Files changed (97) hide show
  1. PKG-INFO +344 -322
  2. README.md +335 -320
  3. __init__.py +1 -1
  4. aigroup_econ_mcp-2.0.1.dist-info/METADATA +732 -0
  5. aigroup_econ_mcp-2.0.1.dist-info/RECORD +170 -0
  6. cli.py +4 -0
  7. econometrics/advanced_methods/modern_computing_machine_learning/__init__.py +30 -0
  8. econometrics/advanced_methods/modern_computing_machine_learning/causal_forest.py +253 -0
  9. econometrics/advanced_methods/modern_computing_machine_learning/double_ml.py +268 -0
  10. econometrics/advanced_methods/modern_computing_machine_learning/gradient_boosting.py +249 -0
  11. econometrics/advanced_methods/modern_computing_machine_learning/hierarchical_clustering.py +243 -0
  12. econometrics/advanced_methods/modern_computing_machine_learning/kmeans_clustering.py +293 -0
  13. econometrics/advanced_methods/modern_computing_machine_learning/neural_network.py +264 -0
  14. econometrics/advanced_methods/modern_computing_machine_learning/random_forest.py +195 -0
  15. econometrics/advanced_methods/modern_computing_machine_learning/support_vector_machine.py +226 -0
  16. econometrics/advanced_methods/modern_computing_machine_learning/test_all_modules.py +329 -0
  17. econometrics/advanced_methods/modern_computing_machine_learning/test_report.md +107 -0
  18. econometrics/causal_inference/__init__.py +66 -0
  19. econometrics/causal_inference/causal_identification_strategy/__init__.py +104 -0
  20. econometrics/causal_inference/causal_identification_strategy/control_function.py +112 -0
  21. econometrics/causal_inference/causal_identification_strategy/difference_in_differences.py +107 -0
  22. econometrics/causal_inference/causal_identification_strategy/event_study.py +119 -0
  23. econometrics/causal_inference/causal_identification_strategy/first_difference.py +89 -0
  24. econometrics/causal_inference/causal_identification_strategy/fixed_effects.py +103 -0
  25. econometrics/causal_inference/causal_identification_strategy/hausman_test.py +69 -0
  26. econometrics/causal_inference/causal_identification_strategy/instrumental_variables.py +145 -0
  27. econometrics/causal_inference/causal_identification_strategy/mediation_analysis.py +121 -0
  28. econometrics/causal_inference/causal_identification_strategy/moderation_analysis.py +109 -0
  29. econometrics/causal_inference/causal_identification_strategy/propensity_score_matching.py +140 -0
  30. econometrics/causal_inference/causal_identification_strategy/random_effects.py +100 -0
  31. econometrics/causal_inference/causal_identification_strategy/regression_discontinuity.py +98 -0
  32. econometrics/causal_inference/causal_identification_strategy/synthetic_control.py +111 -0
  33. econometrics/causal_inference/causal_identification_strategy/triple_difference.py +86 -0
  34. econometrics/distribution_analysis/__init__.py +28 -0
  35. econometrics/distribution_analysis/oaxaca_blinder.py +184 -0
  36. econometrics/distribution_analysis/time_series_decomposition.py +152 -0
  37. econometrics/distribution_analysis/variance_decomposition.py +179 -0
  38. econometrics/missing_data/__init__.py +18 -0
  39. econometrics/missing_data/imputation_methods.py +219 -0
  40. econometrics/nonparametric/__init__.py +35 -0
  41. econometrics/nonparametric/gam_model.py +117 -0
  42. econometrics/nonparametric/kernel_regression.py +161 -0
  43. econometrics/nonparametric/quantile_regression.py +249 -0
  44. econometrics/nonparametric/spline_regression.py +100 -0
  45. econometrics/spatial_econometrics/__init__.py +68 -0
  46. econometrics/spatial_econometrics/geographically_weighted_regression.py +211 -0
  47. econometrics/spatial_econometrics/gwr_simple.py +154 -0
  48. econometrics/spatial_econometrics/spatial_autocorrelation.py +356 -0
  49. econometrics/spatial_econometrics/spatial_durbin_model.py +177 -0
  50. econometrics/spatial_econometrics/spatial_regression.py +315 -0
  51. econometrics/spatial_econometrics/spatial_weights.py +226 -0
  52. econometrics/specific_data_modeling/micro_discrete_limited_data/README.md +164 -0
  53. econometrics/specific_data_modeling/micro_discrete_limited_data/__init__.py +40 -0
  54. econometrics/specific_data_modeling/micro_discrete_limited_data/count_data_models.py +311 -0
  55. econometrics/specific_data_modeling/micro_discrete_limited_data/discrete_choice_models.py +294 -0
  56. econometrics/specific_data_modeling/micro_discrete_limited_data/limited_dependent_variable_models.py +282 -0
  57. econometrics/statistical_inference/__init__.py +21 -0
  58. econometrics/statistical_inference/bootstrap_methods.py +162 -0
  59. econometrics/statistical_inference/permutation_test.py +177 -0
  60. econometrics/survival_analysis/__init__.py +18 -0
  61. econometrics/survival_analysis/survival_models.py +259 -0
  62. econometrics/tests/causal_inference_tests/__init__.py +3 -0
  63. econometrics/tests/causal_inference_tests/detailed_test.py +441 -0
  64. econometrics/tests/causal_inference_tests/test_all_methods.py +418 -0
  65. econometrics/tests/causal_inference_tests/test_causal_identification_strategy.py +202 -0
  66. econometrics/tests/causal_inference_tests/test_difference_in_differences.py +53 -0
  67. econometrics/tests/causal_inference_tests/test_instrumental_variables.py +44 -0
  68. econometrics/tests/specific_data_modeling_tests/test_micro_discrete_limited_data.py +189 -0
  69. econometrics//321/206/320/254/320/272/321/205/342/225/235/320/220/321/205/320/237/320/241/321/205/320/264/320/267/321/207/342/226/222/342/225/227/321/204/342/225/235/320/250/321/205/320/225/320/230/321/207/342/225/221/320/267/321/205/320/230/320/226/321/206/320/256/320/240.md +544 -0
  70. pyproject.toml +9 -2
  71. server.py +15 -1
  72. tools/__init__.py +75 -1
  73. tools/causal_inference_adapter.py +658 -0
  74. tools/distribution_analysis_adapter.py +121 -0
  75. tools/gwr_simple_adapter.py +54 -0
  76. tools/machine_learning_adapter.py +567 -0
  77. tools/mcp_tool_groups/__init__.py +15 -1
  78. tools/mcp_tool_groups/causal_inference_tools.py +643 -0
  79. tools/mcp_tool_groups/distribution_analysis_tools.py +169 -0
  80. tools/mcp_tool_groups/machine_learning_tools.py +422 -0
  81. tools/mcp_tool_groups/microecon_tools.py +325 -0
  82. tools/mcp_tool_groups/missing_data_tools.py +117 -0
  83. tools/mcp_tool_groups/nonparametric_tools.py +225 -0
  84. tools/mcp_tool_groups/spatial_econometrics_tools.py +323 -0
  85. tools/mcp_tool_groups/statistical_inference_tools.py +131 -0
  86. tools/mcp_tools_registry.py +13 -3
  87. tools/microecon_adapter.py +412 -0
  88. tools/missing_data_adapter.py +73 -0
  89. tools/nonparametric_adapter.py +190 -0
  90. tools/spatial_econometrics_adapter.py +318 -0
  91. tools/statistical_inference_adapter.py +90 -0
  92. tools/survival_analysis_adapter.py +46 -0
  93. aigroup_econ_mcp-1.4.3.dist-info/METADATA +0 -710
  94. aigroup_econ_mcp-1.4.3.dist-info/RECORD +0 -92
  95. {aigroup_econ_mcp-1.4.3.dist-info → aigroup_econ_mcp-2.0.1.dist-info}/WHEEL +0 -0
  96. {aigroup_econ_mcp-1.4.3.dist-info → aigroup_econ_mcp-2.0.1.dist-info}/entry_points.txt +0 -0
  97. {aigroup_econ_mcp-1.4.3.dist-info → aigroup_econ_mcp-2.0.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,323 @@
1
+ """
2
+ 空间计量经济学工具组
3
+ 包含空间权重、空间自相关检验和空间回归模型
4
+ """
5
+
6
+ from typing import List, Optional, Dict, Any, Tuple
7
+ from mcp.server.fastmcp import Context
8
+ from mcp.server.session import ServerSession
9
+
10
+ from ..mcp_tools_registry import ToolGroup
11
+ from ..spatial_econometrics_adapter import (
12
+ spatial_weights_adapter,
13
+ morans_i_adapter,
14
+ gearys_c_adapter,
15
+ local_moran_adapter,
16
+ spatial_regression_adapter,
17
+ gwr_adapter
18
+ )
19
+
20
+
21
+ class SpatialEconometricsTools(ToolGroup):
22
+ """空间计量经济学工具组"""
23
+
24
+ name = "SPATIAL ECONOMETRICS"
25
+ description = "空间计量经济学分析工具"
26
+ version = "1.0.0"
27
+
28
+ @classmethod
29
+ def get_tools(cls) -> List[Dict[str, Any]]:
30
+ """返回工具列表"""
31
+ return [
32
+ {
33
+ "name": "spatial_weights_matrix",
34
+ "handler": cls.spatial_weights_tool,
35
+ "description": "Spatial Weights Matrix Construction"
36
+ },
37
+ {
38
+ "name": "spatial_morans_i_test",
39
+ "handler": cls.morans_i_tool,
40
+ "description": "Moran's I Spatial Autocorrelation Test"
41
+ },
42
+ {
43
+ "name": "spatial_gearys_c_test",
44
+ "handler": cls.gearys_c_tool,
45
+ "description": "Geary's C Spatial Autocorrelation Test"
46
+ },
47
+ {
48
+ "name": "spatial_local_moran_lisa",
49
+ "handler": cls.local_moran_tool,
50
+ "description": "Local Moran's I (LISA) Analysis"
51
+ },
52
+ {
53
+ "name": "spatial_regression_model",
54
+ "handler": cls.spatial_regression_tool,
55
+ "description": "Spatial Regression Models (SAR/SEM/SDM)"
56
+ },
57
+ {
58
+ "name": "spatial_gwr_model",
59
+ "handler": cls.gwr_tool,
60
+ "description": "Geographically Weighted Regression (GWR)"
61
+ }
62
+ ]
63
+
64
+ @classmethod
65
+ def get_help_text(cls) -> str:
66
+ """返回帮助文档"""
67
+ return """
68
+ 空间计量经济学工具组 - 6个工具
69
+
70
+ 1. Spatial Weights Matrix (spatial_weights_matrix)
71
+ - 空间权重矩阵构建
72
+ - 支持类型: Queen, Rook, KNN, Distance Band, Kernel
73
+ - 基于: libpysal库
74
+
75
+ 2. Moran's I Test (spatial_morans_i_test)
76
+ - Moran's I空间自相关检验
77
+ - 全局空间聚集性分析
78
+ - 基于: esda库
79
+
80
+ 3. Geary's C Test (spatial_gearys_c_test)
81
+ - Geary's C空间自相关检验
82
+ - 另一种全局空间相关性度量
83
+ - 基于: esda库
84
+
85
+ 4. Local Moran's I - LISA (spatial_local_moran_lisa)
86
+ - 局部空间自相关分析
87
+ - 识别HH, LL, HL, LH聚类
88
+ - 基于: esda库
89
+
90
+ 5. Spatial Regression (spatial_regression_model)
91
+ - 空间滞后模型 (SAR)
92
+ - 空间误差模型 (SEM)
93
+ - 空间杜宾模型 (SDM)
94
+ - 基于: spreg库
95
+
96
+ 6. Geographically Weighted Regression (spatial_gwr_model)
97
+ - 地理加权回归
98
+ - 局部回归系数估计
99
+ - 捕捉空间异质性
100
+ - 基于: mgwr库
101
+ """
102
+
103
+ @staticmethod
104
+ async def spatial_weights_tool(
105
+ coordinates: Optional[List[Tuple[float, float]]] = None,
106
+ adjacency_matrix: Optional[List[List[int]]] = None,
107
+ weight_type: str = "queen",
108
+ k: int = 4,
109
+ distance_threshold: Optional[float] = None,
110
+ bandwidth: Optional[float] = None,
111
+ kernel_type: str = "triangular",
112
+ row_standardize: bool = True,
113
+ output_format: str = "json",
114
+ save_path: Optional[str] = None,
115
+ ctx: Context[ServerSession, None] = None
116
+ ) -> str:
117
+ """空间权重矩阵构建"""
118
+ try:
119
+ if ctx:
120
+ await ctx.info(f"Starting spatial weights construction ({weight_type})...")
121
+
122
+ result = spatial_weights_adapter(
123
+ coordinates=coordinates,
124
+ adjacency_matrix=adjacency_matrix,
125
+ weight_type=weight_type,
126
+ k=k,
127
+ distance_threshold=distance_threshold,
128
+ bandwidth=bandwidth,
129
+ kernel_type=kernel_type,
130
+ row_standardize=row_standardize,
131
+ output_format=output_format,
132
+ save_path=save_path
133
+ )
134
+
135
+ if ctx:
136
+ await ctx.info("Spatial weights construction complete")
137
+
138
+ return result
139
+ except Exception as e:
140
+ if ctx:
141
+ await ctx.error(f"Error: {str(e)}")
142
+ raise
143
+
144
+ @staticmethod
145
+ async def morans_i_tool(
146
+ values: List[float],
147
+ neighbors: dict,
148
+ weights: Optional[dict] = None,
149
+ permutations: int = 999,
150
+ two_tailed: bool = True,
151
+ output_format: str = "json",
152
+ save_path: Optional[str] = None,
153
+ ctx: Context[ServerSession, None] = None
154
+ ) -> str:
155
+ """Moran's I空间自相关检验"""
156
+ try:
157
+ if ctx:
158
+ await ctx.info("Starting Moran's I test...")
159
+
160
+ result = morans_i_adapter(
161
+ values=values,
162
+ neighbors=neighbors,
163
+ weights=weights,
164
+ permutations=permutations,
165
+ two_tailed=two_tailed,
166
+ output_format=output_format,
167
+ save_path=save_path
168
+ )
169
+
170
+ if ctx:
171
+ await ctx.info("Moran's I test complete")
172
+
173
+ return result
174
+ except Exception as e:
175
+ if ctx:
176
+ await ctx.error(f"Error: {str(e)}")
177
+ raise
178
+
179
+ @staticmethod
180
+ async def gearys_c_tool(
181
+ values: List[float],
182
+ neighbors: dict,
183
+ weights: Optional[dict] = None,
184
+ permutations: int = 999,
185
+ output_format: str = "json",
186
+ save_path: Optional[str] = None,
187
+ ctx: Context[ServerSession, None] = None
188
+ ) -> str:
189
+ """Geary's C空间自相关检验"""
190
+ try:
191
+ if ctx:
192
+ await ctx.info("Starting Geary's C test...")
193
+
194
+ result = gearys_c_adapter(
195
+ values=values,
196
+ neighbors=neighbors,
197
+ weights=weights,
198
+ permutations=permutations,
199
+ output_format=output_format,
200
+ save_path=save_path
201
+ )
202
+
203
+ if ctx:
204
+ await ctx.info("Geary's C test complete")
205
+
206
+ return result
207
+ except Exception as e:
208
+ if ctx:
209
+ await ctx.error(f"Error: {str(e)}")
210
+ raise
211
+
212
+ @staticmethod
213
+ async def local_moran_tool(
214
+ values: List[float],
215
+ neighbors: dict,
216
+ weights: Optional[dict] = None,
217
+ permutations: int = 999,
218
+ significance_level: float = 0.05,
219
+ output_format: str = "json",
220
+ save_path: Optional[str] = None,
221
+ ctx: Context[ServerSession, None] = None
222
+ ) -> str:
223
+ """局部Moran's I (LISA) 分析"""
224
+ try:
225
+ if ctx:
226
+ await ctx.info("Starting Local Moran's I (LISA) analysis...")
227
+
228
+ result = local_moran_adapter(
229
+ values=values,
230
+ neighbors=neighbors,
231
+ weights=weights,
232
+ permutations=permutations,
233
+ significance_level=significance_level,
234
+ output_format=output_format,
235
+ save_path=save_path
236
+ )
237
+
238
+ if ctx:
239
+ await ctx.info("Local Moran's I analysis complete")
240
+
241
+ return result
242
+ except Exception as e:
243
+ if ctx:
244
+ await ctx.error(f"Error: {str(e)}")
245
+ raise
246
+
247
+ @staticmethod
248
+ async def spatial_regression_tool(
249
+ y_data: List[float],
250
+ x_data: List[List[float]],
251
+ neighbors: dict,
252
+ weights: Optional[dict] = None,
253
+ feature_names: Optional[List[str]] = None,
254
+ model_type: str = "sar",
255
+ method: str = "ml",
256
+ output_format: str = "json",
257
+ save_path: Optional[str] = None,
258
+ ctx: Context[ServerSession, None] = None
259
+ ) -> str:
260
+ """空间回归模型(SAR/SEM/SDM)"""
261
+ try:
262
+ if ctx:
263
+ await ctx.info(f"Starting {model_type.upper()} spatial regression ({method.upper()})...")
264
+
265
+ result = spatial_regression_adapter(
266
+ y_data=y_data,
267
+ x_data=x_data,
268
+ neighbors=neighbors,
269
+ weights=weights,
270
+ feature_names=feature_names,
271
+ model_type=model_type,
272
+ method=method,
273
+ output_format=output_format,
274
+ save_path=save_path
275
+ )
276
+
277
+ if ctx:
278
+ await ctx.info(f"{model_type.upper()} spatial regression complete")
279
+
280
+ return result
281
+ except Exception as e:
282
+ if ctx:
283
+ await ctx.error(f"Error: {str(e)}")
284
+ raise
285
+
286
+ @staticmethod
287
+ async def gwr_tool(
288
+ y_data: List[float],
289
+ x_data: List[List[float]],
290
+ coordinates: List[Tuple[float, float]],
291
+ feature_names: Optional[List[str]] = None,
292
+ kernel_type: str = "bisquare",
293
+ bandwidth: Optional[float] = None,
294
+ fixed: bool = False,
295
+ output_format: str = "json",
296
+ save_path: Optional[str] = None,
297
+ ctx: Context[ServerSession, None] = None
298
+ ) -> str:
299
+ """地理加权回归 (GWR)"""
300
+ try:
301
+ if ctx:
302
+ await ctx.info(f"Starting GWR analysis ({kernel_type} kernel)...")
303
+
304
+ result = gwr_adapter(
305
+ y_data=y_data,
306
+ x_data=x_data,
307
+ coordinates=coordinates,
308
+ feature_names=feature_names,
309
+ kernel_type=kernel_type,
310
+ bandwidth=bandwidth,
311
+ fixed=fixed,
312
+ output_format=output_format,
313
+ save_path=save_path
314
+ )
315
+
316
+ if ctx:
317
+ await ctx.info("GWR analysis complete")
318
+
319
+ return result
320
+ except Exception as e:
321
+ if ctx:
322
+ await ctx.error(f"Error: {str(e)}")
323
+ raise
@@ -0,0 +1,131 @@
1
+ """
2
+ 统计推断技术工具组
3
+ 包含Bootstrap和置换检验
4
+ """
5
+
6
+ from typing import List, Optional, 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 ..statistical_inference_adapter import (
12
+ bootstrap_adapter,
13
+ permutation_test_adapter
14
+ )
15
+
16
+
17
+ class StatisticalInferenceTools(ToolGroup):
18
+ """统计推断技术工具组"""
19
+
20
+ name = "STATISTICAL INFERENCE TECHNIQUES"
21
+ description = "统计推断和重采样方法工具"
22
+ version = "1.0.0"
23
+
24
+ @classmethod
25
+ def get_tools(cls) -> List[Dict[str, Any]]:
26
+ """返回工具列表"""
27
+ return [
28
+ {
29
+ "name": "inference_bootstrap",
30
+ "handler": cls.bootstrap_tool,
31
+ "description": "Bootstrap Resampling Inference"
32
+ },
33
+ {
34
+ "name": "inference_permutation_test",
35
+ "handler": cls.permutation_test_tool,
36
+ "description": "Permutation Test (Nonparametric)"
37
+ }
38
+ ]
39
+
40
+ @classmethod
41
+ def get_help_text(cls) -> str:
42
+ """返回帮助文档"""
43
+ return """
44
+ 统计推断技术工具组 - 2个工具
45
+
46
+ 1. Bootstrap Inference (inference_bootstrap)
47
+ - Bootstrap重采样推断
48
+ - 置信区间估计
49
+ - 支持多种统计量和置信区间方法
50
+ - 基于: scipy.stats
51
+
52
+ 2. Permutation Test (inference_permutation_test)
53
+ - 置换检验(非参数)
54
+ - 两样本比较
55
+ - 均值/中位数/方差比检验
56
+ - 基于: scipy.stats
57
+ """
58
+
59
+ @staticmethod
60
+ async def bootstrap_tool(
61
+ data: List[float],
62
+ statistic_func: str = "mean",
63
+ n_bootstrap: int = 1000,
64
+ confidence_level: float = 0.95,
65
+ method: str = "percentile",
66
+ random_state: Optional[int] = None,
67
+ output_format: str = "json",
68
+ save_path: Optional[str] = None,
69
+ ctx: Context[ServerSession, None] = None
70
+ ) -> str:
71
+ """Bootstrap重采样推断"""
72
+ try:
73
+ if ctx:
74
+ await ctx.info(f"Starting Bootstrap inference ({statistic_func})...")
75
+
76
+ result = bootstrap_adapter(
77
+ data=data,
78
+ statistic_func=statistic_func,
79
+ n_bootstrap=n_bootstrap,
80
+ confidence_level=confidence_level,
81
+ method=method,
82
+ random_state=random_state,
83
+ output_format=output_format,
84
+ save_path=save_path
85
+ )
86
+
87
+ if ctx:
88
+ await ctx.info("Bootstrap inference complete")
89
+
90
+ return result
91
+ except Exception as e:
92
+ if ctx:
93
+ await ctx.error(f"Error: {str(e)}")
94
+ raise
95
+
96
+ @staticmethod
97
+ async def permutation_test_tool(
98
+ sample_a: List[float],
99
+ sample_b: List[float],
100
+ test_type: str = "mean_difference",
101
+ alternative: str = "two-sided",
102
+ n_permutations: int = 10000,
103
+ random_state: Optional[int] = None,
104
+ output_format: str = "json",
105
+ save_path: Optional[str] = None,
106
+ ctx: Context[ServerSession, None] = None
107
+ ) -> str:
108
+ """置换检验"""
109
+ try:
110
+ if ctx:
111
+ await ctx.info(f"Starting permutation test ({test_type})...")
112
+
113
+ result = permutation_test_adapter(
114
+ sample_a=sample_a,
115
+ sample_b=sample_b,
116
+ test_type=test_type,
117
+ alternative=alternative,
118
+ n_permutations=n_permutations,
119
+ random_state=random_state,
120
+ output_format=output_format,
121
+ save_path=save_path
122
+ )
123
+
124
+ if ctx:
125
+ await ctx.info("Permutation test complete")
126
+
127
+ return result
128
+ except Exception as e:
129
+ if ctx:
130
+ await ctx.error(f"Error: {str(e)}")
131
+ raise
@@ -67,27 +67,37 @@ class ToolRegistry:
67
67
  # 扫描 mcp_tool_groups 目录
68
68
  groups_dir = Path(base_path) / "mcp_tool_groups"
69
69
  if not groups_dir.exists():
70
+ print(f"工具组目录不存在: {groups_dir}")
70
71
  return
71
72
 
73
+ print(f"扫描工具组目录: {groups_dir}")
74
+
72
75
  # 导入所有工具组模块
73
76
  for module_file in groups_dir.glob("*_tools.py"):
74
77
  module_name = module_file.stem
78
+ print(f"发现工具组模块: {module_name}")
75
79
  try:
76
80
  module = importlib.import_module(f"tools.mcp_tool_groups.{module_name}")
77
81
 
78
82
  # 查找工具组类
83
+ found_groups = []
79
84
  for name, obj in inspect.getmembers(module):
80
- if (inspect.isclass(obj) and
81
- issubclass(obj, ToolGroup) and
85
+ if (inspect.isclass(obj) and
86
+ issubclass(obj, ToolGroup) and
82
87
  obj != ToolGroup and
83
88
  hasattr(obj, 'get_tools')):
84
89
 
90
+ found_groups.append(name)
85
91
  # 实例化并注册
86
92
  group_instance = obj()
87
93
  self.register_group(group_instance)
94
+ print(f" 注册工具组: {name}")
95
+
96
+ if not found_groups:
97
+ print(f" 在模块 {module_name} 中未找到工具组类")
88
98
 
89
99
  except Exception as e:
90
- print(f"Failed to load tool group from {module_name}: {e}")
100
+ print(f"加载工具组 {module_name} 失败: {e}")
91
101
 
92
102
  def get_all_tools(self) -> Dict[str, Dict[str, Any]]:
93
103
  """获取所有已注册的工具"""