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