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.

Files changed (340) hide show
  1. aiecs/__init__.py +13 -16
  2. aiecs/__main__.py +7 -7
  3. aiecs/aiecs_client.py +269 -75
  4. aiecs/application/executors/operation_executor.py +79 -54
  5. aiecs/application/knowledge_graph/__init__.py +7 -0
  6. aiecs/application/knowledge_graph/builder/__init__.py +37 -0
  7. aiecs/application/knowledge_graph/builder/data_quality.py +302 -0
  8. aiecs/application/knowledge_graph/builder/data_reshaping.py +293 -0
  9. aiecs/application/knowledge_graph/builder/document_builder.py +369 -0
  10. aiecs/application/knowledge_graph/builder/graph_builder.py +490 -0
  11. aiecs/application/knowledge_graph/builder/import_optimizer.py +396 -0
  12. aiecs/application/knowledge_graph/builder/schema_inference.py +462 -0
  13. aiecs/application/knowledge_graph/builder/schema_mapping.py +563 -0
  14. aiecs/application/knowledge_graph/builder/structured_pipeline.py +1384 -0
  15. aiecs/application/knowledge_graph/builder/text_chunker.py +317 -0
  16. aiecs/application/knowledge_graph/extractors/__init__.py +27 -0
  17. aiecs/application/knowledge_graph/extractors/base.py +98 -0
  18. aiecs/application/knowledge_graph/extractors/llm_entity_extractor.py +422 -0
  19. aiecs/application/knowledge_graph/extractors/llm_relation_extractor.py +347 -0
  20. aiecs/application/knowledge_graph/extractors/ner_entity_extractor.py +241 -0
  21. aiecs/application/knowledge_graph/fusion/__init__.py +78 -0
  22. aiecs/application/knowledge_graph/fusion/ab_testing.py +395 -0
  23. aiecs/application/knowledge_graph/fusion/abbreviation_expander.py +327 -0
  24. aiecs/application/knowledge_graph/fusion/alias_index.py +597 -0
  25. aiecs/application/knowledge_graph/fusion/alias_matcher.py +384 -0
  26. aiecs/application/knowledge_graph/fusion/cache_coordinator.py +343 -0
  27. aiecs/application/knowledge_graph/fusion/entity_deduplicator.py +433 -0
  28. aiecs/application/knowledge_graph/fusion/entity_linker.py +511 -0
  29. aiecs/application/knowledge_graph/fusion/evaluation_dataset.py +240 -0
  30. aiecs/application/knowledge_graph/fusion/knowledge_fusion.py +632 -0
  31. aiecs/application/knowledge_graph/fusion/matching_config.py +489 -0
  32. aiecs/application/knowledge_graph/fusion/name_normalizer.py +352 -0
  33. aiecs/application/knowledge_graph/fusion/relation_deduplicator.py +183 -0
  34. aiecs/application/knowledge_graph/fusion/semantic_name_matcher.py +464 -0
  35. aiecs/application/knowledge_graph/fusion/similarity_pipeline.py +534 -0
  36. aiecs/application/knowledge_graph/pattern_matching/__init__.py +21 -0
  37. aiecs/application/knowledge_graph/pattern_matching/pattern_matcher.py +342 -0
  38. aiecs/application/knowledge_graph/pattern_matching/query_executor.py +366 -0
  39. aiecs/application/knowledge_graph/profiling/__init__.py +12 -0
  40. aiecs/application/knowledge_graph/profiling/query_plan_visualizer.py +195 -0
  41. aiecs/application/knowledge_graph/profiling/query_profiler.py +223 -0
  42. aiecs/application/knowledge_graph/reasoning/__init__.py +27 -0
  43. aiecs/application/knowledge_graph/reasoning/evidence_synthesis.py +341 -0
  44. aiecs/application/knowledge_graph/reasoning/inference_engine.py +500 -0
  45. aiecs/application/knowledge_graph/reasoning/logic_form_parser.py +163 -0
  46. aiecs/application/knowledge_graph/reasoning/logic_parser/__init__.py +79 -0
  47. aiecs/application/knowledge_graph/reasoning/logic_parser/ast_builder.py +513 -0
  48. aiecs/application/knowledge_graph/reasoning/logic_parser/ast_nodes.py +913 -0
  49. aiecs/application/knowledge_graph/reasoning/logic_parser/ast_validator.py +866 -0
  50. aiecs/application/knowledge_graph/reasoning/logic_parser/error_handler.py +475 -0
  51. aiecs/application/knowledge_graph/reasoning/logic_parser/parser.py +396 -0
  52. aiecs/application/knowledge_graph/reasoning/logic_parser/query_context.py +208 -0
  53. aiecs/application/knowledge_graph/reasoning/logic_query_integration.py +170 -0
  54. aiecs/application/knowledge_graph/reasoning/query_planner.py +855 -0
  55. aiecs/application/knowledge_graph/reasoning/reasoning_engine.py +518 -0
  56. aiecs/application/knowledge_graph/retrieval/__init__.py +27 -0
  57. aiecs/application/knowledge_graph/retrieval/query_intent_classifier.py +211 -0
  58. aiecs/application/knowledge_graph/retrieval/retrieval_strategies.py +592 -0
  59. aiecs/application/knowledge_graph/retrieval/strategy_types.py +23 -0
  60. aiecs/application/knowledge_graph/search/__init__.py +59 -0
  61. aiecs/application/knowledge_graph/search/hybrid_search.py +457 -0
  62. aiecs/application/knowledge_graph/search/reranker.py +293 -0
  63. aiecs/application/knowledge_graph/search/reranker_strategies.py +535 -0
  64. aiecs/application/knowledge_graph/search/text_similarity.py +392 -0
  65. aiecs/application/knowledge_graph/traversal/__init__.py +15 -0
  66. aiecs/application/knowledge_graph/traversal/enhanced_traversal.py +305 -0
  67. aiecs/application/knowledge_graph/traversal/path_scorer.py +271 -0
  68. aiecs/application/knowledge_graph/validators/__init__.py +13 -0
  69. aiecs/application/knowledge_graph/validators/relation_validator.py +239 -0
  70. aiecs/application/knowledge_graph/visualization/__init__.py +11 -0
  71. aiecs/application/knowledge_graph/visualization/graph_visualizer.py +313 -0
  72. aiecs/common/__init__.py +9 -0
  73. aiecs/common/knowledge_graph/__init__.py +17 -0
  74. aiecs/common/knowledge_graph/runnable.py +471 -0
  75. aiecs/config/__init__.py +20 -5
  76. aiecs/config/config.py +762 -31
  77. aiecs/config/graph_config.py +131 -0
  78. aiecs/config/tool_config.py +399 -0
  79. aiecs/core/__init__.py +29 -13
  80. aiecs/core/interface/__init__.py +2 -2
  81. aiecs/core/interface/execution_interface.py +22 -22
  82. aiecs/core/interface/storage_interface.py +37 -88
  83. aiecs/core/registry/__init__.py +31 -0
  84. aiecs/core/registry/service_registry.py +92 -0
  85. aiecs/domain/__init__.py +270 -1
  86. aiecs/domain/agent/__init__.py +191 -0
  87. aiecs/domain/agent/base_agent.py +3870 -0
  88. aiecs/domain/agent/exceptions.py +99 -0
  89. aiecs/domain/agent/graph_aware_mixin.py +569 -0
  90. aiecs/domain/agent/hybrid_agent.py +1435 -0
  91. aiecs/domain/agent/integration/__init__.py +29 -0
  92. aiecs/domain/agent/integration/context_compressor.py +216 -0
  93. aiecs/domain/agent/integration/context_engine_adapter.py +587 -0
  94. aiecs/domain/agent/integration/protocols.py +281 -0
  95. aiecs/domain/agent/integration/retry_policy.py +218 -0
  96. aiecs/domain/agent/integration/role_config.py +213 -0
  97. aiecs/domain/agent/knowledge_aware_agent.py +1892 -0
  98. aiecs/domain/agent/lifecycle.py +291 -0
  99. aiecs/domain/agent/llm_agent.py +692 -0
  100. aiecs/domain/agent/memory/__init__.py +12 -0
  101. aiecs/domain/agent/memory/conversation.py +1124 -0
  102. aiecs/domain/agent/migration/__init__.py +14 -0
  103. aiecs/domain/agent/migration/conversion.py +163 -0
  104. aiecs/domain/agent/migration/legacy_wrapper.py +86 -0
  105. aiecs/domain/agent/models.py +884 -0
  106. aiecs/domain/agent/observability.py +479 -0
  107. aiecs/domain/agent/persistence.py +449 -0
  108. aiecs/domain/agent/prompts/__init__.py +29 -0
  109. aiecs/domain/agent/prompts/builder.py +159 -0
  110. aiecs/domain/agent/prompts/formatters.py +187 -0
  111. aiecs/domain/agent/prompts/template.py +255 -0
  112. aiecs/domain/agent/registry.py +253 -0
  113. aiecs/domain/agent/tool_agent.py +444 -0
  114. aiecs/domain/agent/tools/__init__.py +15 -0
  115. aiecs/domain/agent/tools/schema_generator.py +364 -0
  116. aiecs/domain/community/__init__.py +155 -0
  117. aiecs/domain/community/agent_adapter.py +469 -0
  118. aiecs/domain/community/analytics.py +432 -0
  119. aiecs/domain/community/collaborative_workflow.py +648 -0
  120. aiecs/domain/community/communication_hub.py +634 -0
  121. aiecs/domain/community/community_builder.py +320 -0
  122. aiecs/domain/community/community_integration.py +796 -0
  123. aiecs/domain/community/community_manager.py +803 -0
  124. aiecs/domain/community/decision_engine.py +849 -0
  125. aiecs/domain/community/exceptions.py +231 -0
  126. aiecs/domain/community/models/__init__.py +33 -0
  127. aiecs/domain/community/models/community_models.py +234 -0
  128. aiecs/domain/community/resource_manager.py +461 -0
  129. aiecs/domain/community/shared_context_manager.py +589 -0
  130. aiecs/domain/context/__init__.py +40 -10
  131. aiecs/domain/context/context_engine.py +1910 -0
  132. aiecs/domain/context/conversation_models.py +87 -53
  133. aiecs/domain/context/graph_memory.py +582 -0
  134. aiecs/domain/execution/model.py +12 -4
  135. aiecs/domain/knowledge_graph/__init__.py +19 -0
  136. aiecs/domain/knowledge_graph/models/__init__.py +52 -0
  137. aiecs/domain/knowledge_graph/models/entity.py +148 -0
  138. aiecs/domain/knowledge_graph/models/evidence.py +178 -0
  139. aiecs/domain/knowledge_graph/models/inference_rule.py +184 -0
  140. aiecs/domain/knowledge_graph/models/path.py +171 -0
  141. aiecs/domain/knowledge_graph/models/path_pattern.py +171 -0
  142. aiecs/domain/knowledge_graph/models/query.py +261 -0
  143. aiecs/domain/knowledge_graph/models/query_plan.py +181 -0
  144. aiecs/domain/knowledge_graph/models/relation.py +202 -0
  145. aiecs/domain/knowledge_graph/schema/__init__.py +23 -0
  146. aiecs/domain/knowledge_graph/schema/entity_type.py +131 -0
  147. aiecs/domain/knowledge_graph/schema/graph_schema.py +253 -0
  148. aiecs/domain/knowledge_graph/schema/property_schema.py +143 -0
  149. aiecs/domain/knowledge_graph/schema/relation_type.py +163 -0
  150. aiecs/domain/knowledge_graph/schema/schema_manager.py +691 -0
  151. aiecs/domain/knowledge_graph/schema/type_enums.py +209 -0
  152. aiecs/domain/task/dsl_processor.py +172 -56
  153. aiecs/domain/task/model.py +20 -8
  154. aiecs/domain/task/task_context.py +27 -24
  155. aiecs/infrastructure/__init__.py +0 -2
  156. aiecs/infrastructure/graph_storage/__init__.py +11 -0
  157. aiecs/infrastructure/graph_storage/base.py +837 -0
  158. aiecs/infrastructure/graph_storage/batch_operations.py +458 -0
  159. aiecs/infrastructure/graph_storage/cache.py +424 -0
  160. aiecs/infrastructure/graph_storage/distributed.py +223 -0
  161. aiecs/infrastructure/graph_storage/error_handling.py +380 -0
  162. aiecs/infrastructure/graph_storage/graceful_degradation.py +294 -0
  163. aiecs/infrastructure/graph_storage/health_checks.py +378 -0
  164. aiecs/infrastructure/graph_storage/in_memory.py +1197 -0
  165. aiecs/infrastructure/graph_storage/index_optimization.py +446 -0
  166. aiecs/infrastructure/graph_storage/lazy_loading.py +431 -0
  167. aiecs/infrastructure/graph_storage/metrics.py +344 -0
  168. aiecs/infrastructure/graph_storage/migration.py +400 -0
  169. aiecs/infrastructure/graph_storage/pagination.py +483 -0
  170. aiecs/infrastructure/graph_storage/performance_monitoring.py +456 -0
  171. aiecs/infrastructure/graph_storage/postgres.py +1563 -0
  172. aiecs/infrastructure/graph_storage/property_storage.py +353 -0
  173. aiecs/infrastructure/graph_storage/protocols.py +76 -0
  174. aiecs/infrastructure/graph_storage/query_optimizer.py +642 -0
  175. aiecs/infrastructure/graph_storage/schema_cache.py +290 -0
  176. aiecs/infrastructure/graph_storage/sqlite.py +1373 -0
  177. aiecs/infrastructure/graph_storage/streaming.py +487 -0
  178. aiecs/infrastructure/graph_storage/tenant.py +412 -0
  179. aiecs/infrastructure/messaging/celery_task_manager.py +92 -54
  180. aiecs/infrastructure/messaging/websocket_manager.py +51 -35
  181. aiecs/infrastructure/monitoring/__init__.py +22 -0
  182. aiecs/infrastructure/monitoring/executor_metrics.py +45 -11
  183. aiecs/infrastructure/monitoring/global_metrics_manager.py +212 -0
  184. aiecs/infrastructure/monitoring/structured_logger.py +3 -7
  185. aiecs/infrastructure/monitoring/tracing_manager.py +63 -35
  186. aiecs/infrastructure/persistence/__init__.py +14 -1
  187. aiecs/infrastructure/persistence/context_engine_client.py +184 -0
  188. aiecs/infrastructure/persistence/database_manager.py +67 -43
  189. aiecs/infrastructure/persistence/file_storage.py +180 -103
  190. aiecs/infrastructure/persistence/redis_client.py +74 -21
  191. aiecs/llm/__init__.py +73 -25
  192. aiecs/llm/callbacks/__init__.py +11 -0
  193. aiecs/llm/{custom_callbacks.py → callbacks/custom_callbacks.py} +26 -19
  194. aiecs/llm/client_factory.py +224 -36
  195. aiecs/llm/client_resolver.py +155 -0
  196. aiecs/llm/clients/__init__.py +38 -0
  197. aiecs/llm/clients/base_client.py +324 -0
  198. aiecs/llm/clients/google_function_calling_mixin.py +457 -0
  199. aiecs/llm/clients/googleai_client.py +241 -0
  200. aiecs/llm/clients/openai_client.py +158 -0
  201. aiecs/llm/clients/openai_compatible_mixin.py +367 -0
  202. aiecs/llm/clients/vertex_client.py +897 -0
  203. aiecs/llm/clients/xai_client.py +201 -0
  204. aiecs/llm/config/__init__.py +51 -0
  205. aiecs/llm/config/config_loader.py +272 -0
  206. aiecs/llm/config/config_validator.py +206 -0
  207. aiecs/llm/config/model_config.py +143 -0
  208. aiecs/llm/protocols.py +149 -0
  209. aiecs/llm/utils/__init__.py +10 -0
  210. aiecs/llm/utils/validate_config.py +89 -0
  211. aiecs/main.py +140 -121
  212. aiecs/scripts/aid/VERSION_MANAGEMENT.md +138 -0
  213. aiecs/scripts/aid/__init__.py +19 -0
  214. aiecs/scripts/aid/module_checker.py +499 -0
  215. aiecs/scripts/aid/version_manager.py +235 -0
  216. aiecs/scripts/{DEPENDENCY_SYSTEM_SUMMARY.md → dependance_check/DEPENDENCY_SYSTEM_SUMMARY.md} +1 -0
  217. aiecs/scripts/{README_DEPENDENCY_CHECKER.md → dependance_check/README_DEPENDENCY_CHECKER.md} +1 -0
  218. aiecs/scripts/dependance_check/__init__.py +15 -0
  219. aiecs/scripts/dependance_check/dependency_checker.py +1835 -0
  220. aiecs/scripts/{dependency_fixer.py → dependance_check/dependency_fixer.py} +192 -90
  221. aiecs/scripts/{download_nlp_data.py → dependance_check/download_nlp_data.py} +203 -71
  222. aiecs/scripts/dependance_patch/__init__.py +7 -0
  223. aiecs/scripts/dependance_patch/fix_weasel/__init__.py +11 -0
  224. aiecs/scripts/{fix_weasel_validator.py → dependance_patch/fix_weasel/fix_weasel_validator.py} +21 -14
  225. aiecs/scripts/{patch_weasel_library.sh → dependance_patch/fix_weasel/patch_weasel_library.sh} +1 -1
  226. aiecs/scripts/knowledge_graph/__init__.py +3 -0
  227. aiecs/scripts/knowledge_graph/run_threshold_experiments.py +212 -0
  228. aiecs/scripts/migrations/multi_tenancy/README.md +142 -0
  229. aiecs/scripts/tools_develop/README.md +671 -0
  230. aiecs/scripts/tools_develop/README_CONFIG_CHECKER.md +273 -0
  231. aiecs/scripts/tools_develop/TOOLS_CONFIG_GUIDE.md +1287 -0
  232. aiecs/scripts/tools_develop/TOOL_AUTO_DISCOVERY.md +234 -0
  233. aiecs/scripts/tools_develop/__init__.py +21 -0
  234. aiecs/scripts/tools_develop/check_all_tools_config.py +548 -0
  235. aiecs/scripts/tools_develop/check_type_annotations.py +257 -0
  236. aiecs/scripts/tools_develop/pre-commit-schema-coverage.sh +66 -0
  237. aiecs/scripts/tools_develop/schema_coverage.py +511 -0
  238. aiecs/scripts/tools_develop/validate_tool_schemas.py +475 -0
  239. aiecs/scripts/tools_develop/verify_executor_config_fix.py +98 -0
  240. aiecs/scripts/tools_develop/verify_tools.py +352 -0
  241. aiecs/tasks/__init__.py +0 -1
  242. aiecs/tasks/worker.py +115 -47
  243. aiecs/tools/__init__.py +194 -72
  244. aiecs/tools/apisource/__init__.py +99 -0
  245. aiecs/tools/apisource/intelligence/__init__.py +19 -0
  246. aiecs/tools/apisource/intelligence/data_fusion.py +632 -0
  247. aiecs/tools/apisource/intelligence/query_analyzer.py +417 -0
  248. aiecs/tools/apisource/intelligence/search_enhancer.py +385 -0
  249. aiecs/tools/apisource/monitoring/__init__.py +9 -0
  250. aiecs/tools/apisource/monitoring/metrics.py +330 -0
  251. aiecs/tools/apisource/providers/__init__.py +112 -0
  252. aiecs/tools/apisource/providers/base.py +671 -0
  253. aiecs/tools/apisource/providers/census.py +397 -0
  254. aiecs/tools/apisource/providers/fred.py +535 -0
  255. aiecs/tools/apisource/providers/newsapi.py +409 -0
  256. aiecs/tools/apisource/providers/worldbank.py +352 -0
  257. aiecs/tools/apisource/reliability/__init__.py +12 -0
  258. aiecs/tools/apisource/reliability/error_handler.py +363 -0
  259. aiecs/tools/apisource/reliability/fallback_strategy.py +376 -0
  260. aiecs/tools/apisource/tool.py +832 -0
  261. aiecs/tools/apisource/utils/__init__.py +9 -0
  262. aiecs/tools/apisource/utils/validators.py +334 -0
  263. aiecs/tools/base_tool.py +415 -21
  264. aiecs/tools/docs/__init__.py +121 -0
  265. aiecs/tools/docs/ai_document_orchestrator.py +607 -0
  266. aiecs/tools/docs/ai_document_writer_orchestrator.py +2350 -0
  267. aiecs/tools/docs/content_insertion_tool.py +1320 -0
  268. aiecs/tools/docs/document_creator_tool.py +1323 -0
  269. aiecs/tools/docs/document_layout_tool.py +1160 -0
  270. aiecs/tools/docs/document_parser_tool.py +1011 -0
  271. aiecs/tools/docs/document_writer_tool.py +1829 -0
  272. aiecs/tools/knowledge_graph/__init__.py +17 -0
  273. aiecs/tools/knowledge_graph/graph_reasoning_tool.py +807 -0
  274. aiecs/tools/knowledge_graph/graph_search_tool.py +944 -0
  275. aiecs/tools/knowledge_graph/kg_builder_tool.py +524 -0
  276. aiecs/tools/langchain_adapter.py +300 -138
  277. aiecs/tools/schema_generator.py +455 -0
  278. aiecs/tools/search_tool/__init__.py +100 -0
  279. aiecs/tools/search_tool/analyzers.py +581 -0
  280. aiecs/tools/search_tool/cache.py +264 -0
  281. aiecs/tools/search_tool/constants.py +128 -0
  282. aiecs/tools/search_tool/context.py +224 -0
  283. aiecs/tools/search_tool/core.py +778 -0
  284. aiecs/tools/search_tool/deduplicator.py +119 -0
  285. aiecs/tools/search_tool/error_handler.py +242 -0
  286. aiecs/tools/search_tool/metrics.py +343 -0
  287. aiecs/tools/search_tool/rate_limiter.py +172 -0
  288. aiecs/tools/search_tool/schemas.py +275 -0
  289. aiecs/tools/statistics/__init__.py +80 -0
  290. aiecs/tools/statistics/ai_data_analysis_orchestrator.py +646 -0
  291. aiecs/tools/statistics/ai_insight_generator_tool.py +508 -0
  292. aiecs/tools/statistics/ai_report_orchestrator_tool.py +684 -0
  293. aiecs/tools/statistics/data_loader_tool.py +555 -0
  294. aiecs/tools/statistics/data_profiler_tool.py +638 -0
  295. aiecs/tools/statistics/data_transformer_tool.py +580 -0
  296. aiecs/tools/statistics/data_visualizer_tool.py +498 -0
  297. aiecs/tools/statistics/model_trainer_tool.py +507 -0
  298. aiecs/tools/statistics/statistical_analyzer_tool.py +472 -0
  299. aiecs/tools/task_tools/__init__.py +49 -36
  300. aiecs/tools/task_tools/chart_tool.py +200 -184
  301. aiecs/tools/task_tools/classfire_tool.py +268 -267
  302. aiecs/tools/task_tools/image_tool.py +175 -131
  303. aiecs/tools/task_tools/office_tool.py +226 -146
  304. aiecs/tools/task_tools/pandas_tool.py +477 -121
  305. aiecs/tools/task_tools/report_tool.py +390 -142
  306. aiecs/tools/task_tools/research_tool.py +149 -79
  307. aiecs/tools/task_tools/scraper_tool.py +339 -145
  308. aiecs/tools/task_tools/stats_tool.py +448 -209
  309. aiecs/tools/temp_file_manager.py +26 -24
  310. aiecs/tools/tool_executor/__init__.py +18 -16
  311. aiecs/tools/tool_executor/tool_executor.py +364 -52
  312. aiecs/utils/LLM_output_structor.py +74 -48
  313. aiecs/utils/__init__.py +14 -3
  314. aiecs/utils/base_callback.py +0 -3
  315. aiecs/utils/cache_provider.py +696 -0
  316. aiecs/utils/execution_utils.py +50 -31
  317. aiecs/utils/prompt_loader.py +1 -0
  318. aiecs/utils/token_usage_repository.py +37 -11
  319. aiecs/ws/socket_server.py +14 -4
  320. {aiecs-1.0.1.dist-info → aiecs-1.7.6.dist-info}/METADATA +52 -15
  321. aiecs-1.7.6.dist-info/RECORD +337 -0
  322. aiecs-1.7.6.dist-info/entry_points.txt +13 -0
  323. aiecs/config/registry.py +0 -19
  324. aiecs/domain/context/content_engine.py +0 -982
  325. aiecs/llm/base_client.py +0 -99
  326. aiecs/llm/openai_client.py +0 -125
  327. aiecs/llm/vertex_client.py +0 -186
  328. aiecs/llm/xai_client.py +0 -184
  329. aiecs/scripts/dependency_checker.py +0 -857
  330. aiecs/scripts/quick_dependency_check.py +0 -269
  331. aiecs/tools/task_tools/search_api.py +0 -7
  332. aiecs-1.0.1.dist-info/RECORD +0 -90
  333. aiecs-1.0.1.dist-info/entry_points.txt +0 -7
  334. /aiecs/scripts/{setup_nlp_data.sh → dependance_check/setup_nlp_data.sh} +0 -0
  335. /aiecs/scripts/{README_WEASEL_PATCH.md → dependance_patch/fix_weasel/README_WEASEL_PATCH.md} +0 -0
  336. /aiecs/scripts/{fix_weasel_validator.sh → dependance_patch/fix_weasel/fix_weasel_validator.sh} +0 -0
  337. /aiecs/scripts/{run_weasel_patch.sh → dependance_patch/fix_weasel/run_weasel_patch.sh} +0 -0
  338. {aiecs-1.0.1.dist-info → aiecs-1.7.6.dist-info}/WHEEL +0 -0
  339. {aiecs-1.0.1.dist-info → aiecs-1.7.6.dist-info}/licenses/LICENSE +0 -0
  340. {aiecs-1.0.1.dist-info → aiecs-1.7.6.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,642 @@
1
+ """
2
+ Query Optimizer
3
+
4
+ Advanced query optimization for knowledge graph queries.
5
+ """
6
+
7
+ from typing import List, Dict, Any, Optional, Set, Tuple
8
+ from dataclasses import dataclass, field
9
+ from enum import Enum
10
+ import logging
11
+
12
+ from aiecs.domain.knowledge_graph.models.query_plan import QueryPlan, QueryStep
13
+ from aiecs.domain.knowledge_graph.models.query import QueryType
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+
18
+ class OptimizationRule(str, Enum):
19
+ """Query optimization rules"""
20
+
21
+ PREDICATE_PUSHDOWN = "predicate_pushdown"
22
+ JOIN_REORDERING = "join_reordering"
23
+ REDUNDANT_ELIMINATION = "redundant_elimination"
24
+ FILTER_EARLY = "filter_early"
25
+ COST_BASED = "cost_based"
26
+
27
+
28
+ @dataclass
29
+ class QueryStatistics:
30
+ """
31
+ Query execution statistics for cost estimation
32
+
33
+ Attributes:
34
+ entity_count: Estimated number of entities in graph
35
+ relation_count: Estimated number of relations in graph
36
+ avg_degree: Average node degree (connections per entity)
37
+ entity_type_counts: Count of entities per type
38
+ relation_type_counts: Count of relations per type
39
+ """
40
+
41
+ entity_count: int = 1000
42
+ relation_count: int = 5000
43
+ avg_degree: float = 5.0
44
+ entity_type_counts: Dict[str, int] = field(default_factory=dict)
45
+ relation_type_counts: Dict[str, int] = field(default_factory=dict)
46
+
47
+ def get_selectivity(self, entity_type: Optional[str] = None) -> float:
48
+ """
49
+ Estimate selectivity (fraction of entities matching filter)
50
+
51
+ Args:
52
+ entity_type: Entity type filter
53
+
54
+ Returns:
55
+ Selectivity estimate (0.0-1.0)
56
+ """
57
+ if entity_type and entity_type in self.entity_type_counts:
58
+ return self.entity_type_counts[entity_type] / max(self.entity_count, 1)
59
+ return 1.0 # No filter = all entities
60
+
61
+
62
+ @dataclass
63
+ class OptimizationResult:
64
+ """
65
+ Result of query optimization
66
+
67
+ Attributes:
68
+ original_plan: Original query plan
69
+ optimized_plan: Optimized query plan
70
+ rules_applied: List of optimization rules applied
71
+ estimated_cost_reduction: Estimated cost reduction (0.0-1.0)
72
+ explanation: Human-readable explanation of optimizations
73
+ """
74
+
75
+ original_plan: QueryPlan
76
+ optimized_plan: QueryPlan
77
+ rules_applied: List[str] = field(default_factory=list)
78
+ estimated_cost_reduction: float = 0.0
79
+ explanation: str = ""
80
+
81
+
82
+ class QueryOptimizer:
83
+ """
84
+ Advanced Query Optimizer
85
+
86
+ Optimizes query execution plans using various optimization techniques:
87
+ - Predicate push-down: Move filters earlier in execution
88
+ - Join reordering: Reorder multi-hop queries for efficiency
89
+ - Redundant operation elimination: Remove duplicate operations
90
+ - Cost-based optimization: Choose execution order based on cost estimates
91
+
92
+ Example:
93
+ ```python
94
+ optimizer = QueryOptimizer(statistics=stats)
95
+
96
+ # Optimize a query plan
97
+ result = optimizer.optimize(plan)
98
+
99
+ print(f"Cost reduction: {result.estimated_cost_reduction:.1%}")
100
+ print(f"Rules applied: {result.rules_applied}")
101
+ ```
102
+ """
103
+
104
+ def __init__(
105
+ self,
106
+ statistics: Optional[QueryStatistics] = None,
107
+ enable_rules: Optional[List[OptimizationRule]] = None,
108
+ ):
109
+ """
110
+ Initialize query optimizer
111
+
112
+ Args:
113
+ statistics: Query statistics for cost estimation
114
+ enable_rules: List of optimization rules to enable (None = all)
115
+ """
116
+ self.statistics = statistics or QueryStatistics()
117
+ self.enable_rules = enable_rules or list(OptimizationRule)
118
+ self._optimization_count = 0
119
+
120
+ def optimize(self, plan: QueryPlan) -> OptimizationResult:
121
+ """
122
+ Optimize a query execution plan
123
+
124
+ Args:
125
+ plan: Original query plan
126
+
127
+ Returns:
128
+ Optimization result with optimized plan
129
+ """
130
+ if plan.optimized:
131
+ logger.debug(f"Plan {plan.plan_id} already optimized")
132
+ return OptimizationResult(
133
+ original_plan=plan,
134
+ optimized_plan=plan,
135
+ explanation="Plan already optimized",
136
+ )
137
+
138
+ original_cost = plan.total_estimated_cost
139
+ optimized_steps = list(plan.steps)
140
+ rules_applied = []
141
+
142
+ # Apply optimization rules in order
143
+ if OptimizationRule.REDUNDANT_ELIMINATION in self.enable_rules:
144
+ optimized_steps, eliminated = self._eliminate_redundant_operations(optimized_steps)
145
+ if eliminated > 0:
146
+ rules_applied.append(f"redundant_elimination (removed {eliminated} ops)")
147
+
148
+ if OptimizationRule.PREDICATE_PUSHDOWN in self.enable_rules:
149
+ optimized_steps, pushed = self._push_down_predicates(optimized_steps)
150
+ if pushed > 0:
151
+ rules_applied.append(f"predicate_pushdown (pushed {pushed} filters)")
152
+
153
+ if OptimizationRule.JOIN_REORDERING in self.enable_rules:
154
+ optimized_steps = self._reorder_joins(optimized_steps)
155
+ rules_applied.append("join_reordering")
156
+
157
+ if OptimizationRule.COST_BASED in self.enable_rules:
158
+ optimized_steps = self._cost_based_reordering(optimized_steps)
159
+ rules_applied.append("cost_based_reordering")
160
+
161
+ # Create optimized plan
162
+ optimized_plan = QueryPlan(
163
+ plan_id=plan.plan_id,
164
+ original_query=plan.original_query,
165
+ steps=optimized_steps,
166
+ optimized=True,
167
+ explanation=plan.explanation,
168
+ metadata=plan.metadata,
169
+ )
170
+ optimized_plan.total_estimated_cost = optimized_plan.calculate_total_cost()
171
+
172
+ # Calculate cost reduction
173
+ cost_reduction = 0.0
174
+ if original_cost > 0:
175
+ cost_reduction = (original_cost - optimized_plan.total_estimated_cost) / original_cost
176
+
177
+ self._optimization_count += 1
178
+
179
+ explanation = self._generate_explanation(plan, optimized_plan, rules_applied, cost_reduction)
180
+
181
+ return OptimizationResult(
182
+ original_plan=plan,
183
+ optimized_plan=optimized_plan,
184
+ rules_applied=rules_applied,
185
+ estimated_cost_reduction=cost_reduction,
186
+ explanation=explanation,
187
+ )
188
+
189
+ def _eliminate_redundant_operations(self, steps: List[QueryStep]) -> Tuple[List[QueryStep], int]:
190
+ """
191
+ Eliminate redundant operations
192
+
193
+ Args:
194
+ steps: Query steps
195
+
196
+ Returns:
197
+ Tuple of (optimized steps, number of operations eliminated)
198
+ """
199
+ seen_operations: Dict[str, QueryStep] = {}
200
+ optimized = []
201
+ eliminated = 0
202
+
203
+ for step in steps:
204
+ # Create a signature for this operation
205
+ signature = self._get_operation_signature(step)
206
+
207
+ if signature in seen_operations:
208
+ # Redundant operation - update dependencies to point to
209
+ # original
210
+ original_step = seen_operations[signature]
211
+
212
+ # Update other steps that depend on this redundant step
213
+ for other_step in steps:
214
+ if step.step_id in other_step.depends_on:
215
+ # Replace dependency with original step
216
+ other_step.depends_on = [(original_step.step_id if dep == step.step_id else dep) for dep in other_step.depends_on]
217
+
218
+ eliminated += 1
219
+ logger.debug(f"Eliminated redundant operation: {step.step_id} -> {original_step.step_id}")
220
+ else:
221
+ seen_operations[signature] = step
222
+ optimized.append(step)
223
+
224
+ return optimized, eliminated
225
+
226
+ def _get_operation_signature(self, step: QueryStep) -> str:
227
+ """
228
+ Get a signature for an operation to detect duplicates
229
+
230
+ Args:
231
+ step: Query step
232
+
233
+ Returns:
234
+ Signature string
235
+ """
236
+ query = step.query
237
+ parts = [
238
+ str(step.operation),
239
+ str(query.query_type),
240
+ str(query.entity_id or ""),
241
+ str(query.entity_type or ""),
242
+ str(query.relation_type or ""),
243
+ str(sorted(query.properties.items()) if query.properties else ""),
244
+ ]
245
+ return "|".join(parts)
246
+
247
+ def _push_down_predicates(self, steps: List[QueryStep]) -> Tuple[List[QueryStep], int]:
248
+ """
249
+ Push predicates (filters) earlier in execution
250
+
251
+ Strategy: Move property filters to the earliest possible step
252
+
253
+ Args:
254
+ steps: Query steps
255
+
256
+ Returns:
257
+ Tuple of (optimized steps, number of predicates pushed)
258
+ """
259
+ pushed_count = 0
260
+
261
+ # Find filter steps
262
+ for i, step in enumerate(steps):
263
+ if not step.query.properties:
264
+ continue
265
+
266
+ # Check if we can push this filter to an earlier step
267
+ for j in range(i):
268
+ earlier_step = steps[j]
269
+
270
+ # Can only push to steps this one depends on
271
+ if earlier_step.step_id not in step.depends_on:
272
+ continue
273
+
274
+ # Check if filter is applicable to earlier step
275
+ if self._can_apply_filter(earlier_step, step.query.properties):
276
+ # Move filter to earlier step
277
+ earlier_step.query.properties.update(step.query.properties)
278
+ step.query.properties = {}
279
+ pushed_count += 1
280
+ logger.debug(f"Pushed filter from {step.step_id} to {earlier_step.step_id}")
281
+ break
282
+
283
+ return steps, pushed_count
284
+
285
+ def _can_apply_filter(self, step: QueryStep, properties: Dict[str, Any]) -> bool:
286
+ """
287
+ Check if a filter can be applied to a step
288
+
289
+ Args:
290
+ step: Query step
291
+ properties: Property filters
292
+
293
+ Returns:
294
+ True if filter can be applied
295
+ """
296
+ # Can apply filters to entity lookup and vector search
297
+ return step.query.query_type in [
298
+ QueryType.ENTITY_LOOKUP,
299
+ QueryType.VECTOR_SEARCH,
300
+ QueryType.TRAVERSAL,
301
+ ]
302
+
303
+ def _reorder_joins(self, steps: List[QueryStep]) -> List[QueryStep]:
304
+ """
305
+ Reorder join operations (multi-hop queries) for efficiency
306
+
307
+ Strategy: Execute most selective operations first
308
+
309
+ Args:
310
+ steps: Query steps
311
+
312
+ Returns:
313
+ Reordered steps
314
+ """
315
+ # Group steps by dependency level
316
+ levels = self._get_dependency_levels(steps)
317
+
318
+ reordered = []
319
+ for level_steps in levels:
320
+ # Sort by selectivity (most selective first)
321
+ sorted_level = sorted(level_steps, key=lambda s: self._estimate_selectivity(s))
322
+ reordered.extend(sorted_level)
323
+
324
+ return reordered
325
+
326
+ def _estimate_selectivity(self, step: QueryStep) -> float:
327
+ """
328
+ Estimate selectivity of a query step (fraction of results returned)
329
+
330
+ Lower selectivity = fewer results = should execute first
331
+
332
+ Args:
333
+ step: Query step
334
+
335
+ Returns:
336
+ Selectivity estimate (0.0-1.0)
337
+ """
338
+ query = step.query
339
+ selectivity = 1.0
340
+
341
+ # Entity type filter
342
+ if query.entity_type:
343
+ selectivity *= self.statistics.get_selectivity(query.entity_type)
344
+
345
+ # Property filters
346
+ if query.properties:
347
+ # Each property filter reduces selectivity
348
+ selectivity *= 0.5 ** len(query.properties)
349
+
350
+ # Score threshold
351
+ if query.score_threshold > 0:
352
+ selectivity *= 1.0 - query.score_threshold
353
+
354
+ # Max results limit
355
+ if query.max_results:
356
+ # Estimate based on total entity count
357
+ limit_selectivity = query.max_results / max(self.statistics.entity_count, 1)
358
+ selectivity = min(selectivity, limit_selectivity)
359
+
360
+ return selectivity
361
+
362
+ def _cost_based_reordering(self, steps: List[QueryStep]) -> List[QueryStep]:
363
+ """
364
+ Reorder steps based on estimated cost
365
+
366
+ Strategy: Execute cheaper operations first within each dependency level
367
+
368
+ Args:
369
+ steps: Query steps
370
+
371
+ Returns:
372
+ Reordered steps
373
+ """
374
+ levels = self._get_dependency_levels(steps)
375
+
376
+ reordered = []
377
+ for level_steps in levels:
378
+ # Sort by estimated cost (ascending)
379
+ sorted_level = sorted(level_steps, key=lambda s: self._estimate_step_cost(s))
380
+ reordered.extend(sorted_level)
381
+
382
+ return reordered
383
+
384
+ def _estimate_step_cost(self, step: QueryStep) -> float:
385
+ """
386
+ Estimate execution cost of a query step
387
+
388
+ Args:
389
+ step: Query step
390
+
391
+ Returns:
392
+ Estimated cost (higher = more expensive)
393
+ """
394
+ query = step.query
395
+ base_cost = step.estimated_cost
396
+
397
+ # Adjust based on query type
398
+ if query.query_type == QueryType.VECTOR_SEARCH:
399
+ # Vector search is expensive
400
+ base_cost *= 2.0
401
+ elif query.query_type == QueryType.PATH_FINDING:
402
+ # Path finding is very expensive
403
+ base_cost *= 3.0
404
+ elif query.query_type == QueryType.TRAVERSAL:
405
+ # Traversal cost depends on depth
406
+ base_cost *= 1.0 + query.max_depth * 0.5
407
+
408
+ # Adjust based on expected result size
409
+ selectivity = self._estimate_selectivity(step)
410
+ expected_results = selectivity * self.statistics.entity_count
411
+
412
+ # More results = higher cost
413
+ base_cost *= 1.0 + expected_results / 1000.0
414
+
415
+ return base_cost
416
+
417
+ def _get_dependency_levels(self, steps: List[QueryStep]) -> List[List[QueryStep]]:
418
+ """
419
+ Group steps by dependency level
420
+
421
+ Args:
422
+ steps: Query steps
423
+
424
+ Returns:
425
+ List of lists, where each inner list contains steps at the same dependency level
426
+ """
427
+ levels: List[List[QueryStep]] = []
428
+ remaining = list(steps)
429
+ completed: Set[str] = set()
430
+
431
+ while remaining:
432
+ # Find steps with all dependencies satisfied
433
+ current_level = [step for step in remaining if all(dep in completed for dep in step.depends_on)]
434
+
435
+ if not current_level:
436
+ # Circular dependency or error
437
+ logger.warning("Circular dependency detected in query plan")
438
+ break
439
+
440
+ levels.append(current_level)
441
+
442
+ # Mark these steps as completed
443
+ for step in current_level:
444
+ completed.add(step.step_id)
445
+ remaining.remove(step)
446
+
447
+ return levels
448
+
449
+ def _generate_explanation(
450
+ self,
451
+ original_plan: QueryPlan,
452
+ optimized_plan: QueryPlan,
453
+ rules_applied: List[str],
454
+ cost_reduction: float,
455
+ ) -> str:
456
+ """
457
+ Generate human-readable explanation of optimizations
458
+
459
+ Args:
460
+ original_plan: Original query plan
461
+ optimized_plan: Optimized query plan
462
+ rules_applied: List of rules applied
463
+ cost_reduction: Estimated cost reduction
464
+
465
+ Returns:
466
+ Explanation string
467
+ """
468
+ parts = [
469
+ f"Optimized query plan {original_plan.plan_id}:",
470
+ f"- Original cost: {original_plan.total_estimated_cost:.3f}",
471
+ f"- Optimized cost: {optimized_plan.total_estimated_cost:.3f}",
472
+ f"- Cost reduction: {cost_reduction:.1%}",
473
+ f"- Steps: {len(original_plan.steps)} -> {len(optimized_plan.steps)}",
474
+ ]
475
+
476
+ if rules_applied:
477
+ parts.append(f"- Rules applied: {', '.join(rules_applied)}")
478
+
479
+ return "\n".join(parts)
480
+
481
+ def update_statistics(self, statistics: QueryStatistics) -> None:
482
+ """
483
+ Update query statistics
484
+
485
+ Args:
486
+ statistics: New query statistics
487
+ """
488
+ self.statistics = statistics
489
+ logger.info(f"Updated query statistics: {statistics.entity_count} entities, {statistics.relation_count} relations")
490
+
491
+ def get_optimization_count(self) -> int:
492
+ """Get number of optimizations performed"""
493
+ return self._optimization_count
494
+
495
+ def __repr__(self) -> str:
496
+ return f"QueryOptimizer(rules={len(self.enable_rules)}, optimizations={self._optimization_count})"
497
+
498
+
499
+ class QueryStatisticsCollector:
500
+ """
501
+ Collects query execution statistics for cost estimation
502
+
503
+ Tracks:
504
+ - Entity and relation counts
505
+ - Entity/relation type distributions
506
+ - Average node degree
507
+ - Query execution times
508
+
509
+ Example:
510
+ ```python
511
+ collector = QueryStatisticsCollector()
512
+
513
+ # Collect from graph store
514
+ stats = collector.collect_from_graph_store(graph_store)
515
+
516
+ # Use for optimization
517
+ optimizer = QueryOptimizer(statistics=stats)
518
+ ```
519
+ """
520
+
521
+ def __init__(self) -> None:
522
+ """Initialize statistics collector"""
523
+ self._execution_times: List[float] = []
524
+
525
+ def collect_from_graph_store(self, graph_store) -> QueryStatistics:
526
+ """
527
+ Collect statistics from a graph store
528
+
529
+ Args:
530
+ graph_store: Graph store instance
531
+
532
+ Returns:
533
+ Query statistics
534
+ """
535
+ from aiecs.infrastructure.graph_storage.base import GraphStore # type: ignore[import-untyped]
536
+
537
+ # Use duck typing to check if graph_store has required attributes
538
+ # Some graph stores may not expose entities/relations directly
539
+ if not hasattr(graph_store, 'entities') or not hasattr(graph_store, 'relations'):
540
+ # Try to use isinstance check as fallback
541
+ try:
542
+ from aiecs.infrastructure.graph_storage.base import GraphStore as GS
543
+ if not isinstance(graph_store, GS):
544
+ logger.debug("Graph store does not expose entities/relations attributes, skipping statistics collection")
545
+ return QueryStatistics()
546
+ except Exception:
547
+ logger.debug("Could not validate graph store type, skipping statistics collection")
548
+ return QueryStatistics()
549
+
550
+ # Count entities and relations
551
+ try:
552
+ entity_count = len(graph_store.entities)
553
+ relation_count = len(graph_store.relations)
554
+ except (AttributeError, TypeError):
555
+ logger.debug("Graph store entities/relations not accessible, skipping statistics collection")
556
+ return QueryStatistics()
557
+
558
+ # Count by type
559
+ entity_type_counts: Dict[str, int] = {}
560
+ for entity in graph_store.entities.values():
561
+ entity_type = entity.entity_type
562
+ entity_type_counts[entity_type] = entity_type_counts.get(entity_type, 0) + 1
563
+
564
+ relation_type_counts: Dict[str, int] = {}
565
+ for relation in graph_store.relations.values():
566
+ relation_type = relation.relation_type
567
+ relation_type_counts[relation_type] = relation_type_counts.get(relation_type, 0) + 1
568
+
569
+ # Calculate average degree by counting relations per entity
570
+ # We count each relation for both source (outgoing) and target (incoming)
571
+ outgoing_counts: Dict[str, int] = {}
572
+ incoming_counts: Dict[str, int] = {}
573
+ for relation in graph_store.relations.values():
574
+ source_id = relation.source_id
575
+ target_id = relation.target_id
576
+ outgoing_counts[source_id] = outgoing_counts.get(source_id, 0) + 1
577
+ incoming_counts[target_id] = incoming_counts.get(target_id, 0) + 1
578
+
579
+ degree_sum = 0
580
+ for entity_id in graph_store.entities:
581
+ outgoing = outgoing_counts.get(entity_id, 0)
582
+ incoming = incoming_counts.get(entity_id, 0)
583
+ degree_sum += outgoing + incoming
584
+
585
+ avg_degree = degree_sum / max(entity_count, 1)
586
+
587
+ stats = QueryStatistics(
588
+ entity_count=entity_count,
589
+ relation_count=relation_count,
590
+ avg_degree=avg_degree,
591
+ entity_type_counts=entity_type_counts,
592
+ relation_type_counts=relation_type_counts,
593
+ )
594
+
595
+ logger.info(f"Collected statistics: {entity_count} entities, {relation_count} relations, avg degree {avg_degree:.1f}")
596
+
597
+ return stats
598
+
599
+ def record_execution_time(self, execution_time_ms: float) -> None:
600
+ """
601
+ Record query execution time
602
+
603
+ Args:
604
+ execution_time_ms: Execution time in milliseconds
605
+ """
606
+ self._execution_times.append(execution_time_ms)
607
+
608
+ # Keep only last 1000 executions
609
+ if len(self._execution_times) > 1000:
610
+ self._execution_times = self._execution_times[-1000:]
611
+
612
+ def get_average_execution_time(self) -> float:
613
+ """
614
+ Get average query execution time
615
+
616
+ Returns:
617
+ Average execution time in milliseconds
618
+ """
619
+ if not self._execution_times:
620
+ return 0.0
621
+ return sum(self._execution_times) / len(self._execution_times)
622
+
623
+ def get_execution_percentile(self, percentile: float) -> float:
624
+ """
625
+ Get execution time percentile
626
+
627
+ Args:
628
+ percentile: Percentile (0.0-1.0)
629
+
630
+ Returns:
631
+ Execution time at percentile
632
+ """
633
+ if not self._execution_times:
634
+ return 0.0
635
+
636
+ sorted_times = sorted(self._execution_times)
637
+ index = int(len(sorted_times) * percentile)
638
+ return sorted_times[min(index, len(sorted_times) - 1)]
639
+
640
+ def reset(self) -> None:
641
+ """Reset collected statistics"""
642
+ self._execution_times = []