aiecs 1.5.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 (302) hide show
  1. aiecs/__init__.py +72 -0
  2. aiecs/__main__.py +41 -0
  3. aiecs/aiecs_client.py +469 -0
  4. aiecs/application/__init__.py +10 -0
  5. aiecs/application/executors/__init__.py +10 -0
  6. aiecs/application/executors/operation_executor.py +363 -0
  7. aiecs/application/knowledge_graph/__init__.py +7 -0
  8. aiecs/application/knowledge_graph/builder/__init__.py +37 -0
  9. aiecs/application/knowledge_graph/builder/document_builder.py +375 -0
  10. aiecs/application/knowledge_graph/builder/graph_builder.py +356 -0
  11. aiecs/application/knowledge_graph/builder/schema_mapping.py +531 -0
  12. aiecs/application/knowledge_graph/builder/structured_pipeline.py +443 -0
  13. aiecs/application/knowledge_graph/builder/text_chunker.py +319 -0
  14. aiecs/application/knowledge_graph/extractors/__init__.py +27 -0
  15. aiecs/application/knowledge_graph/extractors/base.py +100 -0
  16. aiecs/application/knowledge_graph/extractors/llm_entity_extractor.py +327 -0
  17. aiecs/application/knowledge_graph/extractors/llm_relation_extractor.py +349 -0
  18. aiecs/application/knowledge_graph/extractors/ner_entity_extractor.py +244 -0
  19. aiecs/application/knowledge_graph/fusion/__init__.py +23 -0
  20. aiecs/application/knowledge_graph/fusion/entity_deduplicator.py +387 -0
  21. aiecs/application/knowledge_graph/fusion/entity_linker.py +343 -0
  22. aiecs/application/knowledge_graph/fusion/knowledge_fusion.py +580 -0
  23. aiecs/application/knowledge_graph/fusion/relation_deduplicator.py +189 -0
  24. aiecs/application/knowledge_graph/pattern_matching/__init__.py +21 -0
  25. aiecs/application/knowledge_graph/pattern_matching/pattern_matcher.py +344 -0
  26. aiecs/application/knowledge_graph/pattern_matching/query_executor.py +378 -0
  27. aiecs/application/knowledge_graph/profiling/__init__.py +12 -0
  28. aiecs/application/knowledge_graph/profiling/query_plan_visualizer.py +199 -0
  29. aiecs/application/knowledge_graph/profiling/query_profiler.py +223 -0
  30. aiecs/application/knowledge_graph/reasoning/__init__.py +27 -0
  31. aiecs/application/knowledge_graph/reasoning/evidence_synthesis.py +347 -0
  32. aiecs/application/knowledge_graph/reasoning/inference_engine.py +504 -0
  33. aiecs/application/knowledge_graph/reasoning/logic_form_parser.py +167 -0
  34. aiecs/application/knowledge_graph/reasoning/logic_parser/__init__.py +79 -0
  35. aiecs/application/knowledge_graph/reasoning/logic_parser/ast_builder.py +513 -0
  36. aiecs/application/knowledge_graph/reasoning/logic_parser/ast_nodes.py +630 -0
  37. aiecs/application/knowledge_graph/reasoning/logic_parser/ast_validator.py +654 -0
  38. aiecs/application/knowledge_graph/reasoning/logic_parser/error_handler.py +477 -0
  39. aiecs/application/knowledge_graph/reasoning/logic_parser/parser.py +390 -0
  40. aiecs/application/knowledge_graph/reasoning/logic_parser/query_context.py +217 -0
  41. aiecs/application/knowledge_graph/reasoning/logic_query_integration.py +169 -0
  42. aiecs/application/knowledge_graph/reasoning/query_planner.py +872 -0
  43. aiecs/application/knowledge_graph/reasoning/reasoning_engine.py +554 -0
  44. aiecs/application/knowledge_graph/retrieval/__init__.py +19 -0
  45. aiecs/application/knowledge_graph/retrieval/retrieval_strategies.py +596 -0
  46. aiecs/application/knowledge_graph/search/__init__.py +59 -0
  47. aiecs/application/knowledge_graph/search/hybrid_search.py +423 -0
  48. aiecs/application/knowledge_graph/search/reranker.py +295 -0
  49. aiecs/application/knowledge_graph/search/reranker_strategies.py +553 -0
  50. aiecs/application/knowledge_graph/search/text_similarity.py +398 -0
  51. aiecs/application/knowledge_graph/traversal/__init__.py +15 -0
  52. aiecs/application/knowledge_graph/traversal/enhanced_traversal.py +329 -0
  53. aiecs/application/knowledge_graph/traversal/path_scorer.py +269 -0
  54. aiecs/application/knowledge_graph/validators/__init__.py +13 -0
  55. aiecs/application/knowledge_graph/validators/relation_validator.py +189 -0
  56. aiecs/application/knowledge_graph/visualization/__init__.py +11 -0
  57. aiecs/application/knowledge_graph/visualization/graph_visualizer.py +321 -0
  58. aiecs/common/__init__.py +9 -0
  59. aiecs/common/knowledge_graph/__init__.py +17 -0
  60. aiecs/common/knowledge_graph/runnable.py +484 -0
  61. aiecs/config/__init__.py +16 -0
  62. aiecs/config/config.py +498 -0
  63. aiecs/config/graph_config.py +137 -0
  64. aiecs/config/registry.py +23 -0
  65. aiecs/core/__init__.py +46 -0
  66. aiecs/core/interface/__init__.py +34 -0
  67. aiecs/core/interface/execution_interface.py +152 -0
  68. aiecs/core/interface/storage_interface.py +171 -0
  69. aiecs/domain/__init__.py +289 -0
  70. aiecs/domain/agent/__init__.py +189 -0
  71. aiecs/domain/agent/base_agent.py +697 -0
  72. aiecs/domain/agent/exceptions.py +103 -0
  73. aiecs/domain/agent/graph_aware_mixin.py +559 -0
  74. aiecs/domain/agent/hybrid_agent.py +490 -0
  75. aiecs/domain/agent/integration/__init__.py +26 -0
  76. aiecs/domain/agent/integration/context_compressor.py +222 -0
  77. aiecs/domain/agent/integration/context_engine_adapter.py +252 -0
  78. aiecs/domain/agent/integration/retry_policy.py +219 -0
  79. aiecs/domain/agent/integration/role_config.py +213 -0
  80. aiecs/domain/agent/knowledge_aware_agent.py +646 -0
  81. aiecs/domain/agent/lifecycle.py +296 -0
  82. aiecs/domain/agent/llm_agent.py +300 -0
  83. aiecs/domain/agent/memory/__init__.py +12 -0
  84. aiecs/domain/agent/memory/conversation.py +197 -0
  85. aiecs/domain/agent/migration/__init__.py +14 -0
  86. aiecs/domain/agent/migration/conversion.py +160 -0
  87. aiecs/domain/agent/migration/legacy_wrapper.py +90 -0
  88. aiecs/domain/agent/models.py +317 -0
  89. aiecs/domain/agent/observability.py +407 -0
  90. aiecs/domain/agent/persistence.py +289 -0
  91. aiecs/domain/agent/prompts/__init__.py +29 -0
  92. aiecs/domain/agent/prompts/builder.py +161 -0
  93. aiecs/domain/agent/prompts/formatters.py +189 -0
  94. aiecs/domain/agent/prompts/template.py +255 -0
  95. aiecs/domain/agent/registry.py +260 -0
  96. aiecs/domain/agent/tool_agent.py +257 -0
  97. aiecs/domain/agent/tools/__init__.py +12 -0
  98. aiecs/domain/agent/tools/schema_generator.py +221 -0
  99. aiecs/domain/community/__init__.py +155 -0
  100. aiecs/domain/community/agent_adapter.py +477 -0
  101. aiecs/domain/community/analytics.py +481 -0
  102. aiecs/domain/community/collaborative_workflow.py +642 -0
  103. aiecs/domain/community/communication_hub.py +645 -0
  104. aiecs/domain/community/community_builder.py +320 -0
  105. aiecs/domain/community/community_integration.py +800 -0
  106. aiecs/domain/community/community_manager.py +813 -0
  107. aiecs/domain/community/decision_engine.py +879 -0
  108. aiecs/domain/community/exceptions.py +225 -0
  109. aiecs/domain/community/models/__init__.py +33 -0
  110. aiecs/domain/community/models/community_models.py +268 -0
  111. aiecs/domain/community/resource_manager.py +457 -0
  112. aiecs/domain/community/shared_context_manager.py +603 -0
  113. aiecs/domain/context/__init__.py +58 -0
  114. aiecs/domain/context/context_engine.py +989 -0
  115. aiecs/domain/context/conversation_models.py +354 -0
  116. aiecs/domain/context/graph_memory.py +467 -0
  117. aiecs/domain/execution/__init__.py +12 -0
  118. aiecs/domain/execution/model.py +57 -0
  119. aiecs/domain/knowledge_graph/__init__.py +19 -0
  120. aiecs/domain/knowledge_graph/models/__init__.py +52 -0
  121. aiecs/domain/knowledge_graph/models/entity.py +130 -0
  122. aiecs/domain/knowledge_graph/models/evidence.py +194 -0
  123. aiecs/domain/knowledge_graph/models/inference_rule.py +186 -0
  124. aiecs/domain/knowledge_graph/models/path.py +179 -0
  125. aiecs/domain/knowledge_graph/models/path_pattern.py +173 -0
  126. aiecs/domain/knowledge_graph/models/query.py +272 -0
  127. aiecs/domain/knowledge_graph/models/query_plan.py +187 -0
  128. aiecs/domain/knowledge_graph/models/relation.py +136 -0
  129. aiecs/domain/knowledge_graph/schema/__init__.py +23 -0
  130. aiecs/domain/knowledge_graph/schema/entity_type.py +135 -0
  131. aiecs/domain/knowledge_graph/schema/graph_schema.py +271 -0
  132. aiecs/domain/knowledge_graph/schema/property_schema.py +155 -0
  133. aiecs/domain/knowledge_graph/schema/relation_type.py +171 -0
  134. aiecs/domain/knowledge_graph/schema/schema_manager.py +496 -0
  135. aiecs/domain/knowledge_graph/schema/type_enums.py +205 -0
  136. aiecs/domain/task/__init__.py +13 -0
  137. aiecs/domain/task/dsl_processor.py +613 -0
  138. aiecs/domain/task/model.py +62 -0
  139. aiecs/domain/task/task_context.py +268 -0
  140. aiecs/infrastructure/__init__.py +24 -0
  141. aiecs/infrastructure/graph_storage/__init__.py +11 -0
  142. aiecs/infrastructure/graph_storage/base.py +601 -0
  143. aiecs/infrastructure/graph_storage/batch_operations.py +449 -0
  144. aiecs/infrastructure/graph_storage/cache.py +429 -0
  145. aiecs/infrastructure/graph_storage/distributed.py +226 -0
  146. aiecs/infrastructure/graph_storage/error_handling.py +390 -0
  147. aiecs/infrastructure/graph_storage/graceful_degradation.py +306 -0
  148. aiecs/infrastructure/graph_storage/health_checks.py +378 -0
  149. aiecs/infrastructure/graph_storage/in_memory.py +514 -0
  150. aiecs/infrastructure/graph_storage/index_optimization.py +483 -0
  151. aiecs/infrastructure/graph_storage/lazy_loading.py +410 -0
  152. aiecs/infrastructure/graph_storage/metrics.py +357 -0
  153. aiecs/infrastructure/graph_storage/migration.py +413 -0
  154. aiecs/infrastructure/graph_storage/pagination.py +471 -0
  155. aiecs/infrastructure/graph_storage/performance_monitoring.py +466 -0
  156. aiecs/infrastructure/graph_storage/postgres.py +871 -0
  157. aiecs/infrastructure/graph_storage/query_optimizer.py +635 -0
  158. aiecs/infrastructure/graph_storage/schema_cache.py +290 -0
  159. aiecs/infrastructure/graph_storage/sqlite.py +623 -0
  160. aiecs/infrastructure/graph_storage/streaming.py +495 -0
  161. aiecs/infrastructure/messaging/__init__.py +13 -0
  162. aiecs/infrastructure/messaging/celery_task_manager.py +383 -0
  163. aiecs/infrastructure/messaging/websocket_manager.py +298 -0
  164. aiecs/infrastructure/monitoring/__init__.py +34 -0
  165. aiecs/infrastructure/monitoring/executor_metrics.py +174 -0
  166. aiecs/infrastructure/monitoring/global_metrics_manager.py +213 -0
  167. aiecs/infrastructure/monitoring/structured_logger.py +48 -0
  168. aiecs/infrastructure/monitoring/tracing_manager.py +410 -0
  169. aiecs/infrastructure/persistence/__init__.py +24 -0
  170. aiecs/infrastructure/persistence/context_engine_client.py +187 -0
  171. aiecs/infrastructure/persistence/database_manager.py +333 -0
  172. aiecs/infrastructure/persistence/file_storage.py +754 -0
  173. aiecs/infrastructure/persistence/redis_client.py +220 -0
  174. aiecs/llm/__init__.py +86 -0
  175. aiecs/llm/callbacks/__init__.py +11 -0
  176. aiecs/llm/callbacks/custom_callbacks.py +264 -0
  177. aiecs/llm/client_factory.py +420 -0
  178. aiecs/llm/clients/__init__.py +33 -0
  179. aiecs/llm/clients/base_client.py +193 -0
  180. aiecs/llm/clients/googleai_client.py +181 -0
  181. aiecs/llm/clients/openai_client.py +131 -0
  182. aiecs/llm/clients/vertex_client.py +437 -0
  183. aiecs/llm/clients/xai_client.py +184 -0
  184. aiecs/llm/config/__init__.py +51 -0
  185. aiecs/llm/config/config_loader.py +275 -0
  186. aiecs/llm/config/config_validator.py +236 -0
  187. aiecs/llm/config/model_config.py +151 -0
  188. aiecs/llm/utils/__init__.py +10 -0
  189. aiecs/llm/utils/validate_config.py +91 -0
  190. aiecs/main.py +363 -0
  191. aiecs/scripts/__init__.py +3 -0
  192. aiecs/scripts/aid/VERSION_MANAGEMENT.md +97 -0
  193. aiecs/scripts/aid/__init__.py +19 -0
  194. aiecs/scripts/aid/version_manager.py +215 -0
  195. aiecs/scripts/dependance_check/DEPENDENCY_SYSTEM_SUMMARY.md +242 -0
  196. aiecs/scripts/dependance_check/README_DEPENDENCY_CHECKER.md +310 -0
  197. aiecs/scripts/dependance_check/__init__.py +17 -0
  198. aiecs/scripts/dependance_check/dependency_checker.py +938 -0
  199. aiecs/scripts/dependance_check/dependency_fixer.py +391 -0
  200. aiecs/scripts/dependance_check/download_nlp_data.py +396 -0
  201. aiecs/scripts/dependance_check/quick_dependency_check.py +270 -0
  202. aiecs/scripts/dependance_check/setup_nlp_data.sh +217 -0
  203. aiecs/scripts/dependance_patch/__init__.py +7 -0
  204. aiecs/scripts/dependance_patch/fix_weasel/README_WEASEL_PATCH.md +126 -0
  205. aiecs/scripts/dependance_patch/fix_weasel/__init__.py +11 -0
  206. aiecs/scripts/dependance_patch/fix_weasel/fix_weasel_validator.py +128 -0
  207. aiecs/scripts/dependance_patch/fix_weasel/fix_weasel_validator.sh +82 -0
  208. aiecs/scripts/dependance_patch/fix_weasel/patch_weasel_library.sh +188 -0
  209. aiecs/scripts/dependance_patch/fix_weasel/run_weasel_patch.sh +41 -0
  210. aiecs/scripts/tools_develop/README.md +449 -0
  211. aiecs/scripts/tools_develop/TOOL_AUTO_DISCOVERY.md +234 -0
  212. aiecs/scripts/tools_develop/__init__.py +21 -0
  213. aiecs/scripts/tools_develop/check_type_annotations.py +259 -0
  214. aiecs/scripts/tools_develop/validate_tool_schemas.py +422 -0
  215. aiecs/scripts/tools_develop/verify_tools.py +356 -0
  216. aiecs/tasks/__init__.py +1 -0
  217. aiecs/tasks/worker.py +172 -0
  218. aiecs/tools/__init__.py +299 -0
  219. aiecs/tools/apisource/__init__.py +99 -0
  220. aiecs/tools/apisource/intelligence/__init__.py +19 -0
  221. aiecs/tools/apisource/intelligence/data_fusion.py +381 -0
  222. aiecs/tools/apisource/intelligence/query_analyzer.py +413 -0
  223. aiecs/tools/apisource/intelligence/search_enhancer.py +388 -0
  224. aiecs/tools/apisource/monitoring/__init__.py +9 -0
  225. aiecs/tools/apisource/monitoring/metrics.py +303 -0
  226. aiecs/tools/apisource/providers/__init__.py +115 -0
  227. aiecs/tools/apisource/providers/base.py +664 -0
  228. aiecs/tools/apisource/providers/census.py +401 -0
  229. aiecs/tools/apisource/providers/fred.py +564 -0
  230. aiecs/tools/apisource/providers/newsapi.py +412 -0
  231. aiecs/tools/apisource/providers/worldbank.py +357 -0
  232. aiecs/tools/apisource/reliability/__init__.py +12 -0
  233. aiecs/tools/apisource/reliability/error_handler.py +375 -0
  234. aiecs/tools/apisource/reliability/fallback_strategy.py +391 -0
  235. aiecs/tools/apisource/tool.py +850 -0
  236. aiecs/tools/apisource/utils/__init__.py +9 -0
  237. aiecs/tools/apisource/utils/validators.py +338 -0
  238. aiecs/tools/base_tool.py +201 -0
  239. aiecs/tools/docs/__init__.py +121 -0
  240. aiecs/tools/docs/ai_document_orchestrator.py +599 -0
  241. aiecs/tools/docs/ai_document_writer_orchestrator.py +2403 -0
  242. aiecs/tools/docs/content_insertion_tool.py +1333 -0
  243. aiecs/tools/docs/document_creator_tool.py +1317 -0
  244. aiecs/tools/docs/document_layout_tool.py +1166 -0
  245. aiecs/tools/docs/document_parser_tool.py +994 -0
  246. aiecs/tools/docs/document_writer_tool.py +1818 -0
  247. aiecs/tools/knowledge_graph/__init__.py +17 -0
  248. aiecs/tools/knowledge_graph/graph_reasoning_tool.py +734 -0
  249. aiecs/tools/knowledge_graph/graph_search_tool.py +923 -0
  250. aiecs/tools/knowledge_graph/kg_builder_tool.py +476 -0
  251. aiecs/tools/langchain_adapter.py +542 -0
  252. aiecs/tools/schema_generator.py +275 -0
  253. aiecs/tools/search_tool/__init__.py +100 -0
  254. aiecs/tools/search_tool/analyzers.py +589 -0
  255. aiecs/tools/search_tool/cache.py +260 -0
  256. aiecs/tools/search_tool/constants.py +128 -0
  257. aiecs/tools/search_tool/context.py +216 -0
  258. aiecs/tools/search_tool/core.py +749 -0
  259. aiecs/tools/search_tool/deduplicator.py +123 -0
  260. aiecs/tools/search_tool/error_handler.py +271 -0
  261. aiecs/tools/search_tool/metrics.py +371 -0
  262. aiecs/tools/search_tool/rate_limiter.py +178 -0
  263. aiecs/tools/search_tool/schemas.py +277 -0
  264. aiecs/tools/statistics/__init__.py +80 -0
  265. aiecs/tools/statistics/ai_data_analysis_orchestrator.py +643 -0
  266. aiecs/tools/statistics/ai_insight_generator_tool.py +505 -0
  267. aiecs/tools/statistics/ai_report_orchestrator_tool.py +694 -0
  268. aiecs/tools/statistics/data_loader_tool.py +564 -0
  269. aiecs/tools/statistics/data_profiler_tool.py +658 -0
  270. aiecs/tools/statistics/data_transformer_tool.py +573 -0
  271. aiecs/tools/statistics/data_visualizer_tool.py +495 -0
  272. aiecs/tools/statistics/model_trainer_tool.py +487 -0
  273. aiecs/tools/statistics/statistical_analyzer_tool.py +459 -0
  274. aiecs/tools/task_tools/__init__.py +86 -0
  275. aiecs/tools/task_tools/chart_tool.py +732 -0
  276. aiecs/tools/task_tools/classfire_tool.py +922 -0
  277. aiecs/tools/task_tools/image_tool.py +447 -0
  278. aiecs/tools/task_tools/office_tool.py +684 -0
  279. aiecs/tools/task_tools/pandas_tool.py +635 -0
  280. aiecs/tools/task_tools/report_tool.py +635 -0
  281. aiecs/tools/task_tools/research_tool.py +392 -0
  282. aiecs/tools/task_tools/scraper_tool.py +715 -0
  283. aiecs/tools/task_tools/stats_tool.py +688 -0
  284. aiecs/tools/temp_file_manager.py +130 -0
  285. aiecs/tools/tool_executor/__init__.py +37 -0
  286. aiecs/tools/tool_executor/tool_executor.py +881 -0
  287. aiecs/utils/LLM_output_structor.py +445 -0
  288. aiecs/utils/__init__.py +34 -0
  289. aiecs/utils/base_callback.py +47 -0
  290. aiecs/utils/cache_provider.py +695 -0
  291. aiecs/utils/execution_utils.py +184 -0
  292. aiecs/utils/logging.py +1 -0
  293. aiecs/utils/prompt_loader.py +14 -0
  294. aiecs/utils/token_usage_repository.py +323 -0
  295. aiecs/ws/__init__.py +0 -0
  296. aiecs/ws/socket_server.py +52 -0
  297. aiecs-1.5.1.dist-info/METADATA +608 -0
  298. aiecs-1.5.1.dist-info/RECORD +302 -0
  299. aiecs-1.5.1.dist-info/WHEEL +5 -0
  300. aiecs-1.5.1.dist-info/entry_points.txt +10 -0
  301. aiecs-1.5.1.dist-info/licenses/LICENSE +225 -0
  302. aiecs-1.5.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,542 @@
1
+ """
2
+ Langchain Adapter: Converts BaseTool and its sub-functions into Langchain ReAct Agent compatible tool collections
3
+
4
+ Main Features:
5
+ 1. Automatically discover all operation methods of BaseTool
6
+ 2. Create independent Langchain Tool for each operation
7
+ 3. Maintain all original functionality features (caching, validation, security, etc.)
8
+ 4. Support synchronous and asynchronous execution
9
+ """
10
+
11
+ import inspect
12
+ import logging
13
+ from typing import Any, Dict, List, Optional, Type
14
+ from pydantic import BaseModel
15
+
16
+ # Import schema generator
17
+ from aiecs.tools.schema_generator import generate_schema_from_method
18
+
19
+ try:
20
+ from langchain.tools import BaseTool as LangchainBaseTool
21
+ from langchain.callbacks.manager import (
22
+ CallbackManagerForToolRun,
23
+ AsyncCallbackManagerForToolRun,
24
+ )
25
+
26
+ LANGCHAIN_AVAILABLE = True
27
+ except ImportError:
28
+ # If langchain is not installed, create simple base class for type checking
29
+ class LangchainBaseTool:
30
+ pass
31
+
32
+ CallbackManagerForToolRun = None
33
+ AsyncCallbackManagerForToolRun = None
34
+ LANGCHAIN_AVAILABLE = False
35
+
36
+ from aiecs.tools.base_tool import BaseTool
37
+ from aiecs.tools import get_tool, list_tools, TOOL_CLASSES
38
+
39
+ logger = logging.getLogger(__name__)
40
+
41
+
42
+ class LangchainToolAdapter(LangchainBaseTool):
43
+ """
44
+ Langchain tool adapter for single operation
45
+
46
+ Wraps one operation method of BaseTool as an independent Langchain tool.
47
+ Supports both tool-level operations and provider-level operations.
48
+ """
49
+
50
+ # Define class attributes
51
+ name: str = ""
52
+ description: str = ""
53
+ base_tool_name: str = ""
54
+ operation_name: str = ""
55
+ operation_schema: Optional[Type[BaseModel]] = None
56
+ is_provider_operation: bool = False
57
+ provider_name: Optional[str] = None
58
+ method_name: Optional[str] = None
59
+
60
+ def __init__(
61
+ self,
62
+ base_tool_name: str,
63
+ operation_name: str,
64
+ operation_schema: Optional[Type[BaseModel]] = None,
65
+ description: Optional[str] = None,
66
+ is_provider_operation: bool = False,
67
+ provider_name: Optional[str] = None,
68
+ method_name: Optional[str] = None,
69
+ ):
70
+ """
71
+ Initialize adapter
72
+
73
+ Args:
74
+ base_tool_name: Original tool name
75
+ operation_name: Operation name
76
+ operation_schema: Pydantic Schema for the operation
77
+ description: Tool description
78
+ is_provider_operation: Whether this is a provider-level operation
79
+ provider_name: Provider name (for provider operations)
80
+ method_name: Original method name (for provider operations)
81
+ """
82
+ # Construct tool name and description
83
+ tool_name = f"{base_tool_name}_{operation_name}"
84
+ tool_description = (
85
+ description or f"Execute {operation_name} operation from {base_tool_name} tool"
86
+ )
87
+
88
+ # Initialize parent class with all required fields
89
+ super().__init__(
90
+ name=tool_name,
91
+ description=tool_description,
92
+ base_tool_name=base_tool_name,
93
+ operation_name=operation_name,
94
+ operation_schema=operation_schema,
95
+ args_schema=operation_schema,
96
+ is_provider_operation=is_provider_operation,
97
+ provider_name=provider_name,
98
+ method_name=method_name,
99
+ )
100
+
101
+ def _run(
102
+ self,
103
+ run_manager: Optional[CallbackManagerForToolRun] = None,
104
+ **kwargs: Any,
105
+ ) -> Any:
106
+ """Execute operation synchronously"""
107
+ try:
108
+ # Get original tool instance
109
+ base_tool = get_tool(self.base_tool_name)
110
+
111
+ # Handle provider operations differently
112
+ if self.is_provider_operation:
113
+ # For provider operations, call the query method with provider
114
+ # and operation
115
+ result = base_tool.run(
116
+ "query",
117
+ provider=self.provider_name,
118
+ operation=self.method_name,
119
+ params=kwargs,
120
+ )
121
+ else:
122
+ # For tool-level operations, call directly
123
+ result = base_tool.run(self.operation_name, **kwargs)
124
+
125
+ logger.info(f"Successfully executed {self.name} with result type: {type(result)}")
126
+ return result
127
+
128
+ except Exception as e:
129
+ logger.error(f"Error executing {self.name}: {str(e)}")
130
+ raise
131
+
132
+ async def _arun(
133
+ self,
134
+ run_manager: Optional[AsyncCallbackManagerForToolRun] = None,
135
+ **kwargs: Any,
136
+ ) -> Any:
137
+ """Execute operation asynchronously"""
138
+ try:
139
+ # Get original tool instance
140
+ base_tool = get_tool(self.base_tool_name)
141
+
142
+ # Execute asynchronous operation
143
+ result = await base_tool.run_async(self.operation_name, **kwargs)
144
+
145
+ logger.info(f"Successfully executed {self.name} async with result type: {type(result)}")
146
+ return result
147
+
148
+ except Exception as e:
149
+ logger.error(f"Error executing {self.name} async: {str(e)}")
150
+ raise
151
+
152
+
153
+ class ToolRegistry:
154
+ """Tool Registry: Manages conversion from BaseTool to Langchain tools"""
155
+
156
+ def __init__(self):
157
+ self._langchain_tools: Dict[str, LangchainToolAdapter] = {}
158
+
159
+ def discover_operations(self, base_tool_class: Type[BaseTool]) -> List[Dict[str, Any]]:
160
+ """
161
+ Discover all operation methods and Schemas of BaseTool class.
162
+
163
+ Enhanced to support provider-level operations for tools like APISourceTool
164
+ that expose fine-grained operations from underlying providers.
165
+
166
+ Args:
167
+ base_tool_class: BaseTool subclass
168
+
169
+ Returns:
170
+ List of operation information, including method names, Schemas, descriptions, etc.
171
+ """
172
+ operations = []
173
+
174
+ # 1. Discover tool-level operations (existing logic)
175
+ tool_operations = self._discover_tool_operations(base_tool_class)
176
+ operations.extend(tool_operations)
177
+
178
+ # 2. Discover provider-level operations (new logic)
179
+ if hasattr(base_tool_class, "_discover_provider_operations"):
180
+ try:
181
+ provider_operations = base_tool_class._discover_provider_operations()
182
+
183
+ # Convert provider operations to the expected format
184
+ for provider_op in provider_operations:
185
+ operation_info = {
186
+ "name": provider_op["name"],
187
+ "method": None, # Will be handled specially in create_langchain_tools
188
+ "schema": provider_op["schema"],
189
+ "description": provider_op["description"],
190
+ "is_async": False,
191
+ "is_provider_operation": True, # Mark as provider operation
192
+ "provider_name": provider_op.get("provider_name"),
193
+ "method_name": provider_op.get("method_name"),
194
+ }
195
+ operations.append(operation_info)
196
+ logger.debug(f"Added provider operation: {provider_op['name']}")
197
+
198
+ logger.info(
199
+ f"Discovered {len(provider_operations)} provider operations for {base_tool_class.__name__}"
200
+ )
201
+
202
+ except Exception as e:
203
+ logger.warning(
204
+ f"Error discovering provider operations for {base_tool_class.__name__}: {e}"
205
+ )
206
+
207
+ return operations
208
+
209
+ def _discover_tool_operations(self, base_tool_class: Type[BaseTool]) -> List[Dict[str, Any]]:
210
+ """
211
+ Discover tool-level operations (original logic extracted to separate method).
212
+
213
+ Args:
214
+ base_tool_class: BaseTool subclass
215
+
216
+ Returns:
217
+ List of tool-level operation information
218
+ """
219
+ operations = []
220
+
221
+ # Get all Schema classes
222
+ # Build a mapping from normalized names to Schema classes
223
+ # Check both class-level and module-level schemas
224
+ schemas = {}
225
+
226
+ # 1. Check class-level schemas (e.g., ChartTool)
227
+ for attr_name in dir(base_tool_class):
228
+ attr = getattr(base_tool_class, attr_name)
229
+ if (
230
+ isinstance(attr, type)
231
+ and issubclass(attr, BaseModel)
232
+ and attr.__name__.endswith("Schema")
233
+ ):
234
+ # Normalize: remove 'Schema' suffix, convert to lowercase,
235
+ # remove underscores
236
+ schema_base_name = attr.__name__.replace("Schema", "")
237
+ normalized_name = schema_base_name.replace("_", "").lower()
238
+ schemas[normalized_name] = attr
239
+ logger.debug(
240
+ f"Found class-level schema {attr.__name__} -> normalized: {normalized_name}"
241
+ )
242
+
243
+ # 2. Check module-level schemas (e.g., ImageTool)
244
+ tool_module = inspect.getmodule(base_tool_class)
245
+ if tool_module:
246
+ for attr_name in dir(tool_module):
247
+ if attr_name.startswith("_"):
248
+ continue
249
+ attr = getattr(tool_module, attr_name)
250
+ if (
251
+ isinstance(attr, type)
252
+ and issubclass(attr, BaseModel)
253
+ and attr.__name__.endswith("Schema")
254
+ ):
255
+ # Skip if already found at class level
256
+ schema_base_name = attr.__name__.replace("Schema", "")
257
+ normalized_name = schema_base_name.replace("_", "").lower()
258
+ if normalized_name not in schemas:
259
+ schemas[normalized_name] = attr
260
+ logger.debug(
261
+ f"Found module-level schema {attr.__name__} -> normalized: {normalized_name}"
262
+ )
263
+
264
+ # Get all public methods
265
+ for method_name in dir(base_tool_class):
266
+ if method_name.startswith("_"):
267
+ continue
268
+
269
+ method = getattr(base_tool_class, method_name)
270
+ if not callable(method):
271
+ continue
272
+
273
+ # Skip base class methods and Schema classes themselves
274
+ if method_name in ["run", "run_async", "run_batch"]:
275
+ continue
276
+
277
+ # Skip if it's a class (like Config or Schema classes)
278
+ if isinstance(method, type):
279
+ continue
280
+
281
+ # Normalize method name: remove underscores and convert to
282
+ # lowercase
283
+ normalized_method_name = method_name.replace("_", "").lower()
284
+
285
+ # Try to find matching schema
286
+ matching_schema = schemas.get(normalized_method_name)
287
+
288
+ if matching_schema:
289
+ logger.debug(
290
+ f"Matched method {method_name} with manual schema {matching_schema.__name__}"
291
+ )
292
+ else:
293
+ # Auto-generate schema if not found
294
+ auto_schema = generate_schema_from_method(method, method_name)
295
+ if auto_schema:
296
+ matching_schema = auto_schema
297
+ logger.debug(
298
+ f"Auto-generated schema for method {method_name}: {auto_schema.__name__}"
299
+ )
300
+ else:
301
+ logger.debug(f"No schema found or generated for method {method_name}")
302
+
303
+ # Get method information
304
+ operation_info = {
305
+ "name": method_name,
306
+ "method": method,
307
+ "schema": matching_schema,
308
+ "description": inspect.getdoc(method) or f"Execute {method_name} operation",
309
+ "is_async": inspect.iscoroutinefunction(method),
310
+ "is_provider_operation": False, # Mark as tool-level operation
311
+ }
312
+
313
+ operations.append(operation_info)
314
+
315
+ return operations
316
+
317
+ def _extract_description(
318
+ self,
319
+ method,
320
+ base_tool_name: str,
321
+ operation_name: str,
322
+ schema: Optional[Type[BaseModel]] = None,
323
+ ) -> str:
324
+ """Extract detailed description from method docstring and schema"""
325
+ doc = inspect.getdoc(method)
326
+
327
+ # Base description
328
+ if doc:
329
+ base_desc = doc.split("\n")[0].strip()
330
+ else:
331
+ base_desc = f"Execute {operation_name} operation"
332
+
333
+ # Enhanced description - add specific tool functionality description
334
+ enhanced_desc = f"{base_desc}"
335
+
336
+ # Add specific descriptions based on tool name and operation
337
+ if base_tool_name == "chart":
338
+ if operation_name == "read_data":
339
+ enhanced_desc = "Read and analyze data files in multiple formats (CSV, Excel, JSON, Parquet, etc.). Returns data structure summary, preview, and optional export functionality."
340
+ elif operation_name == "visualize":
341
+ enhanced_desc = "Create data visualizations including histograms, scatter plots, bar charts, line charts, heatmaps, and pair plots. Supports customizable styling, colors, and high-resolution output."
342
+ elif operation_name == "export_data":
343
+ enhanced_desc = "Export data to various formats (JSON, CSV, HTML, Excel, Markdown) with optional variable selection and path customization."
344
+ elif base_tool_name == "pandas":
345
+ enhanced_desc = f"Pandas data manipulation: {base_desc}. Supports DataFrame operations with built-in validation and error handling."
346
+ elif base_tool_name == "stats":
347
+ enhanced_desc = f"Statistical analysis: {base_desc}. Provides statistical tests, regression analysis, and data preprocessing capabilities."
348
+
349
+ # Add parameter information
350
+ if schema:
351
+ try:
352
+ fields = schema.__fields__ if hasattr(schema, "__fields__") else {}
353
+ if fields:
354
+ required_params = [
355
+ name for name, field in fields.items() if field.is_required()
356
+ ]
357
+ optional_params = [
358
+ name for name, field in fields.items() if not field.is_required()
359
+ ]
360
+
361
+ param_desc = ""
362
+ if required_params:
363
+ param_desc += f" Required: {', '.join(required_params)}."
364
+ if optional_params:
365
+ param_desc += f" Optional: {', '.join(optional_params)}."
366
+
367
+ enhanced_desc += param_desc
368
+ except Exception:
369
+ pass
370
+
371
+ return enhanced_desc
372
+
373
+ def create_langchain_tools(self, tool_name: str) -> List[LangchainToolAdapter]:
374
+ """
375
+ Create all Langchain adapters for specified tool
376
+
377
+ Args:
378
+ tool_name: Tool name
379
+
380
+ Returns:
381
+ List of Langchain tool adapters
382
+ """
383
+ if not LANGCHAIN_AVAILABLE:
384
+ raise ImportError("langchain is not installed. Please install it to use this adapter.")
385
+
386
+ if tool_name not in TOOL_CLASSES:
387
+ raise ValueError(f"Tool '{tool_name}' not found in registry")
388
+
389
+ base_tool_class = TOOL_CLASSES[tool_name]
390
+ operations = self.discover_operations(base_tool_class)
391
+
392
+ langchain_tools = []
393
+ for op_info in operations:
394
+ # Generate enhanced description
395
+ # For provider operations, use the description directly
396
+ if op_info.get("is_provider_operation", False):
397
+ enhanced_description = op_info["description"]
398
+ else:
399
+ enhanced_description = self._extract_description(
400
+ op_info["method"],
401
+ tool_name,
402
+ op_info["name"],
403
+ op_info["schema"],
404
+ )
405
+
406
+ # Create adapter with provider operation support
407
+ adapter = LangchainToolAdapter(
408
+ base_tool_name=tool_name,
409
+ operation_name=op_info["name"],
410
+ operation_schema=op_info["schema"],
411
+ description=enhanced_description,
412
+ is_provider_operation=op_info.get("is_provider_operation", False),
413
+ provider_name=op_info.get("provider_name"),
414
+ method_name=op_info.get("method_name"),
415
+ )
416
+
417
+ langchain_tools.append(adapter)
418
+ self._langchain_tools[adapter.name] = adapter
419
+
420
+ logger.info(f"Created {len(langchain_tools)} Langchain tools for {tool_name}")
421
+ return langchain_tools
422
+
423
+ def create_all_langchain_tools(self) -> List[LangchainToolAdapter]:
424
+ """
425
+ Create Langchain adapters for all registered BaseTools
426
+
427
+ Returns:
428
+ List of all Langchain tool adapters
429
+ """
430
+ all_tools = []
431
+
432
+ # list_tools() returns a list of dicts, extract tool names
433
+ tool_infos = list_tools()
434
+ for tool_info in tool_infos:
435
+ tool_name = tool_info["name"]
436
+ try:
437
+ tools = self.create_langchain_tools(tool_name)
438
+ all_tools.extend(tools)
439
+ except Exception as e:
440
+ logger.error(f"Failed to create Langchain tools for {tool_name}: {e}")
441
+
442
+ logger.info(
443
+ f"Created total {len(all_tools)} Langchain tools from {len(tool_infos)} base tools"
444
+ )
445
+ return all_tools
446
+
447
+ def get_tool(self, name: str) -> Optional[LangchainToolAdapter]:
448
+ """Get Langchain tool with specified name"""
449
+ return self._langchain_tools.get(name)
450
+
451
+ def list_langchain_tools(self) -> List[str]:
452
+ """List all Langchain tool names"""
453
+ return list(self._langchain_tools.keys())
454
+
455
+
456
+ # Global registry instance
457
+ tool_registry = ToolRegistry()
458
+
459
+
460
+ def get_langchain_tools(
461
+ tool_names: Optional[List[str]] = None,
462
+ ) -> List[LangchainToolAdapter]:
463
+ """
464
+ Get Langchain tool collection
465
+
466
+ Args:
467
+ tool_names: List of tool names to convert, None means convert all tools
468
+
469
+ Returns:
470
+ List of Langchain tool adapters
471
+ """
472
+ if tool_names is None:
473
+ return tool_registry.create_all_langchain_tools()
474
+
475
+ all_tools = []
476
+ for tool_name in tool_names:
477
+ tools = tool_registry.create_langchain_tools(tool_name)
478
+ all_tools.extend(tools)
479
+
480
+ return all_tools
481
+
482
+
483
+ def create_react_agent_tools() -> List[LangchainToolAdapter]:
484
+ """
485
+ Create complete tool collection for ReAct Agent
486
+
487
+ Returns:
488
+ List of adapted Langchain tools
489
+ """
490
+ return get_langchain_tools()
491
+
492
+
493
+ def create_tool_calling_agent_tools() -> List[LangchainToolAdapter]:
494
+ """
495
+ Create complete tool collection for Tool Calling Agent
496
+
497
+ Returns:
498
+ List of adapted Langchain tools optimized for tool calling
499
+ """
500
+ return get_langchain_tools()
501
+
502
+
503
+ # Compatibility check functionality
504
+
505
+
506
+ def check_langchain_compatibility() -> Dict[str, Any]:
507
+ """
508
+ Check compatibility between current environment and Langchain
509
+
510
+ Returns:
511
+ Compatibility check results
512
+ """
513
+ result = {
514
+ "langchain_available": LANGCHAIN_AVAILABLE,
515
+ "total_base_tools": len(list_tools()),
516
+ "compatible_tools": [],
517
+ "incompatible_tools": [],
518
+ "total_operations": 0,
519
+ }
520
+
521
+ if not LANGCHAIN_AVAILABLE:
522
+ result["error"] = "Langchain not installed"
523
+ return result
524
+
525
+ for tool_name in list_tools():
526
+ try:
527
+ tool_class = TOOL_CLASSES[tool_name]
528
+ operations = tool_registry.discover_operations(tool_class)
529
+
530
+ result["compatible_tools"].append(
531
+ {
532
+ "name": tool_name,
533
+ "operations_count": len(operations),
534
+ "operations": [op["name"] for op in operations],
535
+ }
536
+ )
537
+ result["total_operations"] += len(operations)
538
+
539
+ except Exception as e:
540
+ result["incompatible_tools"].append({"name": tool_name, "error": str(e)})
541
+
542
+ return result