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,597 @@
1
+ """
2
+ Alias Index
3
+
4
+ Provides O(1) lookup for entity aliases and abbreviations.
5
+ Supports in-memory HashMap and Redis backends with tenant isolation.
6
+ """
7
+
8
+ import asyncio
9
+ import logging
10
+ from abc import ABC, abstractmethod
11
+ from contextlib import asynccontextmanager
12
+ from dataclasses import dataclass, field
13
+ from enum import Enum
14
+ from typing import Dict, List, Optional, Set, AsyncIterator, Any
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+
19
+ class MatchType(Enum):
20
+ """Type of alias match"""
21
+ EXACT = "exact"
22
+ ALIAS = "alias"
23
+ ABBREVIATION = "abbreviation"
24
+ NORMALIZED = "normalized"
25
+
26
+
27
+ @dataclass
28
+ class AliasEntry:
29
+ """Entry in the alias index"""
30
+ entity_id: str
31
+ match_type: MatchType
32
+ original_name: Optional[str] = None # Original form before normalization
33
+ tenant_id: Optional[str] = None # Tenant ID for multi-tenant isolation
34
+
35
+
36
+ @dataclass
37
+ class TransactionState:
38
+ """State for tracking transaction operations"""
39
+ operations: List[tuple] = field(default_factory=list) # (op_type, key, value)
40
+ committed: bool = False
41
+
42
+
43
+ class AliasIndexBackend(ABC):
44
+ """Abstract base class for alias index backends"""
45
+
46
+ @abstractmethod
47
+ async def get(self, alias: str) -> Optional[AliasEntry]:
48
+ """Get entity entry for an alias"""
49
+ pass
50
+
51
+ @abstractmethod
52
+ async def set(self, alias: str, entry: AliasEntry) -> None:
53
+ """Set alias to entity mapping"""
54
+ pass
55
+
56
+ @abstractmethod
57
+ async def delete(self, alias: str) -> bool:
58
+ """Delete an alias entry. Returns True if existed."""
59
+ pass
60
+
61
+ @abstractmethod
62
+ async def get_by_entity_id(self, entity_id: str) -> List[str]:
63
+ """Get all aliases for an entity"""
64
+ pass
65
+
66
+ @abstractmethod
67
+ async def clear(self) -> None:
68
+ """Clear all entries"""
69
+ pass
70
+
71
+ @abstractmethod
72
+ async def size(self) -> int:
73
+ """Get number of entries"""
74
+ pass
75
+
76
+ @abstractmethod
77
+ @asynccontextmanager
78
+ async def transaction(self) -> AsyncIterator["TransactionContext"]:
79
+ """Start a transaction for atomic operations"""
80
+ pass
81
+
82
+
83
+ class TransactionContext:
84
+ """Context for transactional operations"""
85
+
86
+ def __init__(self, backend: AliasIndexBackend):
87
+ self.backend = backend
88
+ self.state = TransactionState()
89
+ self._rollback_data: Dict[str, Optional[AliasEntry]] = {}
90
+
91
+ async def set(self, alias: str, entry: AliasEntry) -> None:
92
+ """Set within transaction"""
93
+ # Store current value for rollback
94
+ if alias not in self._rollback_data:
95
+ self._rollback_data[alias] = await self.backend.get(alias)
96
+ self.state.operations.append(("set", alias, entry))
97
+ await self.backend.set(alias, entry)
98
+
99
+ async def delete(self, alias: str) -> bool:
100
+ """Delete within transaction"""
101
+ # Store current value for rollback
102
+ if alias not in self._rollback_data:
103
+ self._rollback_data[alias] = await self.backend.get(alias)
104
+ self.state.operations.append(("delete", alias, None))
105
+ return await self.backend.delete(alias)
106
+
107
+ async def rollback(self) -> None:
108
+ """Rollback all operations in this transaction"""
109
+ for alias, original_entry in self._rollback_data.items():
110
+ if original_entry is None:
111
+ await self.backend.delete(alias)
112
+ else:
113
+ await self.backend.set(alias, original_entry)
114
+ self.state.operations.clear()
115
+ self._rollback_data.clear()
116
+ logger.debug("Transaction rolled back")
117
+
118
+ def commit(self) -> None:
119
+ """Mark transaction as committed"""
120
+ self.state.committed = True
121
+ self._rollback_data.clear()
122
+ logger.debug(f"Transaction committed with {len(self.state.operations)} operations")
123
+
124
+
125
+ class InMemoryBackend(AliasIndexBackend):
126
+ """In-memory HashMap backend for O(1) lookup with tenant isolation"""
127
+
128
+ def __init__(self):
129
+ self._index: Dict[str, AliasEntry] = {}
130
+ self._entity_aliases: Dict[str, Set[str]] = {} # entity_id -> set of aliases
131
+ self._lock = asyncio.Lock()
132
+
133
+ def _make_key(self, alias: str, tenant_id: Optional[str] = None) -> str:
134
+ """
135
+ Create tenant-prefixed key for alias lookup.
136
+
137
+ Args:
138
+ alias: The alias string
139
+ tenant_id: Optional tenant ID for multi-tenant isolation
140
+
141
+ Returns:
142
+ Tenant-prefixed key (e.g., "tenant_123:apple" or "apple" for global)
143
+ """
144
+ normalized = alias.lower()
145
+ if tenant_id:
146
+ return f"{tenant_id}:{normalized}"
147
+ return normalized
148
+
149
+ async def get(self, alias: str) -> Optional[AliasEntry]:
150
+ """Get entity entry for an alias - O(1)"""
151
+ # For backward compatibility, try both with and without tenant prefix
152
+ # First try as-is (may contain tenant prefix already)
153
+ entry = self._index.get(alias.lower())
154
+ if entry:
155
+ return entry
156
+ # If alias contains ":", it might already be prefixed
157
+ if ":" in alias:
158
+ return self._index.get(alias.lower())
159
+ return None
160
+
161
+ async def set(self, alias: str, entry: AliasEntry) -> None:
162
+ """Set alias to entity mapping - O(1)"""
163
+ key = self._make_key(alias, entry.tenant_id)
164
+ self._index[key] = entry
165
+ # Track reverse mapping
166
+ if entry.entity_id not in self._entity_aliases:
167
+ self._entity_aliases[entry.entity_id] = set()
168
+ self._entity_aliases[entry.entity_id].add(key)
169
+
170
+ async def delete(self, alias: str) -> bool:
171
+ """Delete an alias entry - O(1)"""
172
+ key = alias.lower()
173
+ if key in self._index:
174
+ entry = self._index.pop(key)
175
+ # Update reverse mapping
176
+ if entry.entity_id in self._entity_aliases:
177
+ self._entity_aliases[entry.entity_id].discard(key)
178
+ return True
179
+ return False
180
+
181
+ async def get_by_entity_id(self, entity_id: str) -> List[str]:
182
+ """Get all aliases for an entity - O(1)"""
183
+ return list(self._entity_aliases.get(entity_id, set()))
184
+
185
+ async def clear(self) -> None:
186
+ """Clear all entries"""
187
+ self._index.clear()
188
+ self._entity_aliases.clear()
189
+
190
+ async def size(self) -> int:
191
+ """Get number of entries"""
192
+ return len(self._index)
193
+
194
+ @asynccontextmanager
195
+ async def transaction(self) -> AsyncIterator[TransactionContext]:
196
+ """Start a transaction with lock for concurrency safety"""
197
+ async with self._lock:
198
+ ctx = TransactionContext(self)
199
+ try:
200
+ yield ctx
201
+ ctx.commit()
202
+ except Exception:
203
+ await ctx.rollback()
204
+ raise
205
+
206
+
207
+ class RedisBackend(AliasIndexBackend):
208
+ """
209
+ Redis backend for large graphs or distributed deployments.
210
+
211
+ Uses Redis hashes for O(1) lookup and MULTI/EXEC for atomic transactions.
212
+ """
213
+
214
+ # Redis key prefixes
215
+ ALIAS_KEY = "alias_index:aliases" # Hash: alias -> JSON(AliasEntry)
216
+ ENTITY_KEY_PREFIX = "alias_index:entity:" # Set: entity_id -> aliases
217
+
218
+ def __init__(self, redis_client: Any = None, redis_url: Optional[str] = None):
219
+ """
220
+ Initialize Redis backend.
221
+
222
+ Args:
223
+ redis_client: Existing Redis client (async)
224
+ redis_url: Redis URL for creating new client
225
+ """
226
+ self._client = redis_client
227
+ self._redis_url = redis_url
228
+ self._initialized = False
229
+
230
+ async def _ensure_client(self) -> None:
231
+ """Ensure Redis client is initialized"""
232
+ if self._initialized:
233
+ return
234
+
235
+ if self._client is None:
236
+ try:
237
+ import redis.asyncio as redis
238
+ self._client = redis.from_url(
239
+ self._redis_url or "redis://localhost:6379",
240
+ decode_responses=True
241
+ )
242
+ except ImportError:
243
+ raise ImportError(
244
+ "redis package required for Redis backend. "
245
+ "Install with: pip install redis"
246
+ )
247
+ self._initialized = True
248
+
249
+ def _make_key(self, alias: str, tenant_id: Optional[str] = None) -> str:
250
+ """
251
+ Create tenant-prefixed key for alias lookup.
252
+
253
+ Args:
254
+ alias: The alias string
255
+ tenant_id: Optional tenant ID for multi-tenant isolation
256
+
257
+ Returns:
258
+ Tenant-prefixed key (e.g., "tenant_123:apple" or "apple" for global)
259
+ """
260
+ normalized = alias.lower()
261
+ if tenant_id:
262
+ return f"{tenant_id}:{normalized}"
263
+ return normalized
264
+
265
+ async def get(self, alias: str) -> Optional[AliasEntry]:
266
+ """Get entity entry for an alias - O(1)"""
267
+ await self._ensure_client()
268
+ import json
269
+
270
+ # Try to get with the key as-is (may already be prefixed)
271
+ data = await self._client.hget(self.ALIAS_KEY, alias.lower())
272
+ if data:
273
+ entry_dict = json.loads(data)
274
+ return AliasEntry(
275
+ entity_id=entry_dict["entity_id"],
276
+ match_type=MatchType(entry_dict["match_type"]),
277
+ original_name=entry_dict.get("original_name"),
278
+ tenant_id=entry_dict.get("tenant_id")
279
+ )
280
+ return None
281
+
282
+ async def set(self, alias: str, entry: AliasEntry) -> None:
283
+ """Set alias to entity mapping - O(1)"""
284
+ await self._ensure_client()
285
+ import json
286
+
287
+ key = self._make_key(alias, entry.tenant_id)
288
+ entry_dict = {
289
+ "entity_id": entry.entity_id,
290
+ "match_type": entry.match_type.value,
291
+ "original_name": entry.original_name,
292
+ "tenant_id": entry.tenant_id
293
+ }
294
+ await self._client.hset(self.ALIAS_KEY, key, json.dumps(entry_dict))
295
+ # Track reverse mapping
296
+ await self._client.sadd(f"{self.ENTITY_KEY_PREFIX}{entry.entity_id}", key)
297
+
298
+ async def delete(self, alias: str) -> bool:
299
+ """Delete an alias entry - O(1)"""
300
+ await self._ensure_client()
301
+
302
+ key = alias.lower()
303
+ # Get entry first to update reverse mapping
304
+ entry = await self.get(alias)
305
+ if entry:
306
+ await self._client.hdel(self.ALIAS_KEY, key)
307
+ await self._client.srem(f"{self.ENTITY_KEY_PREFIX}{entry.entity_id}", key)
308
+ return True
309
+ return False
310
+
311
+ async def get_by_entity_id(self, entity_id: str) -> List[str]:
312
+ """Get all aliases for an entity - O(1)"""
313
+ await self._ensure_client()
314
+ members = await self._client.smembers(f"{self.ENTITY_KEY_PREFIX}{entity_id}")
315
+ return list(members) if members else []
316
+
317
+ async def clear(self) -> None:
318
+ """Clear all entries"""
319
+ await self._ensure_client()
320
+ # Get all entity keys to delete
321
+ cursor = 0
322
+ keys_to_delete = [self.ALIAS_KEY]
323
+ while True:
324
+ cursor, keys = await self._client.scan(
325
+ cursor, match=f"{self.ENTITY_KEY_PREFIX}*", count=100
326
+ )
327
+ keys_to_delete.extend(keys)
328
+ if cursor == 0:
329
+ break
330
+ if keys_to_delete:
331
+ await self._client.delete(*keys_to_delete)
332
+
333
+ async def size(self) -> int:
334
+ """Get number of entries"""
335
+ await self._ensure_client()
336
+ return await self._client.hlen(self.ALIAS_KEY)
337
+
338
+ @asynccontextmanager
339
+ async def transaction(self) -> AsyncIterator[TransactionContext]:
340
+ """
341
+ Start a Redis transaction using MULTI/EXEC.
342
+
343
+ Note: For true atomicity, operations are collected and executed
344
+ together. Rollback restores previous state.
345
+ """
346
+ await self._ensure_client()
347
+ ctx = TransactionContext(self)
348
+ try:
349
+ yield ctx
350
+ ctx.commit()
351
+ except Exception:
352
+ await ctx.rollback()
353
+ raise
354
+
355
+
356
+ class AliasIndex:
357
+ """
358
+ High-level alias index with O(1) lookup.
359
+
360
+ Supports automatic backend selection based on graph size:
361
+ - In-memory HashMap for small-medium graphs (<100K entities)
362
+ - Redis for large graphs or distributed deployments
363
+
364
+ Example:
365
+ ```python
366
+ # Create with auto-detection
367
+ index = AliasIndex()
368
+
369
+ # Or specify backend
370
+ index = AliasIndex(backend="redis", redis_url="redis://localhost:6379")
371
+
372
+ # Add aliases
373
+ await index.add_alias("Albert Einstein", "person_123", MatchType.EXACT)
374
+ await index.add_alias("A. Einstein", "person_123", MatchType.ALIAS)
375
+ await index.add_alias("Einstein", "person_123", MatchType.ALIAS)
376
+
377
+ # Lookup - O(1)
378
+ entry = await index.lookup("a. einstein")
379
+ assert entry.entity_id == "person_123"
380
+
381
+ # Atomic merge
382
+ async with index.transaction() as tx:
383
+ await tx.delete("old_alias")
384
+ await tx.set("new_alias", AliasEntry(...))
385
+ ```
386
+ """
387
+
388
+ # Threshold for auto-switching to Redis backend
389
+ AUTO_REDIS_THRESHOLD = 100_000
390
+
391
+ def __init__(
392
+ self,
393
+ backend: Optional[str] = None,
394
+ redis_url: Optional[str] = None,
395
+ redis_client: Any = None,
396
+ auto_redis_threshold: int = AUTO_REDIS_THRESHOLD,
397
+ ):
398
+ """
399
+ Initialize alias index.
400
+
401
+ Args:
402
+ backend: "memory" or "redis". If None, auto-detects.
403
+ redis_url: Redis URL for Redis backend
404
+ redis_client: Existing Redis client
405
+ auto_redis_threshold: Entity count threshold for auto-switching to Redis
406
+ """
407
+ self._backend_type = backend
408
+ self._redis_url = redis_url
409
+ self._redis_client = redis_client
410
+ self._auto_redis_threshold = auto_redis_threshold
411
+ self._backend: Optional[AliasIndexBackend] = None
412
+ self._lock = asyncio.Lock()
413
+
414
+ async def _get_backend(self) -> AliasIndexBackend:
415
+ """Get or create backend"""
416
+ if self._backend is None:
417
+ if self._backend_type == "redis":
418
+ self._backend = RedisBackend(
419
+ redis_client=self._redis_client,
420
+ redis_url=self._redis_url
421
+ )
422
+ else:
423
+ # Default to in-memory
424
+ self._backend = InMemoryBackend()
425
+ return self._backend
426
+
427
+ async def lookup(
428
+ self, alias: str, tenant_id: Optional[str] = None
429
+ ) -> Optional[AliasEntry]:
430
+ """
431
+ Look up an alias - O(1).
432
+
433
+ **Tenant Isolation**: When tenant_id is provided, lookup uses tenant-prefixed
434
+ keys to ensure isolation between tenants.
435
+
436
+ Args:
437
+ alias: The alias to look up (case-insensitive)
438
+ tenant_id: Optional tenant ID for multi-tenant isolation
439
+
440
+ Returns:
441
+ AliasEntry if found, None otherwise
442
+ """
443
+ backend = await self._get_backend()
444
+ # Create tenant-prefixed key if tenant_id provided
445
+ if tenant_id:
446
+ key = f"{tenant_id}:{alias.lower()}"
447
+ else:
448
+ key = alias.lower()
449
+ return await backend.get(key)
450
+
451
+ async def add_alias(
452
+ self,
453
+ alias: str,
454
+ entity_id: str,
455
+ match_type: MatchType = MatchType.ALIAS,
456
+ original_name: Optional[str] = None,
457
+ tenant_id: Optional[str] = None,
458
+ ) -> None:
459
+ """
460
+ Add an alias for an entity.
461
+
462
+ **Tenant Isolation**: When tenant_id is provided, the alias is stored with
463
+ a tenant-prefixed key to ensure isolation.
464
+
465
+ Args:
466
+ alias: The alias string
467
+ entity_id: ID of the entity this alias refers to
468
+ match_type: Type of match (exact, alias, abbreviation, normalized)
469
+ original_name: Original form before normalization
470
+ tenant_id: Optional tenant ID for multi-tenant isolation
471
+ """
472
+ backend = await self._get_backend()
473
+ entry = AliasEntry(
474
+ entity_id=entity_id,
475
+ match_type=match_type,
476
+ original_name=original_name,
477
+ tenant_id=tenant_id
478
+ )
479
+ await backend.set(alias, entry)
480
+
481
+ async def remove_alias(
482
+ self, alias: str, tenant_id: Optional[str] = None
483
+ ) -> bool:
484
+ """
485
+ Remove an alias.
486
+
487
+ **Tenant Isolation**: When tenant_id is provided, removes the alias from
488
+ the tenant-specific namespace.
489
+
490
+ Args:
491
+ alias: The alias to remove
492
+ tenant_id: Optional tenant ID for multi-tenant isolation
493
+
494
+ Returns:
495
+ True if alias existed and was removed
496
+ """
497
+ backend = await self._get_backend()
498
+ # Create tenant-prefixed key if tenant_id provided
499
+ if tenant_id:
500
+ key = f"{tenant_id}:{alias.lower()}"
501
+ else:
502
+ key = alias.lower()
503
+ return await backend.delete(key)
504
+
505
+ async def get_entity_aliases(self, entity_id: str) -> List[str]:
506
+ """
507
+ Get all aliases for an entity.
508
+
509
+ Args:
510
+ entity_id: The entity ID
511
+
512
+ Returns:
513
+ List of aliases for this entity
514
+ """
515
+ backend = await self._get_backend()
516
+ return await backend.get_by_entity_id(entity_id)
517
+
518
+ async def remove_entity_aliases(self, entity_id: str) -> int:
519
+ """
520
+ Remove all aliases for an entity.
521
+
522
+ Args:
523
+ entity_id: The entity ID
524
+
525
+ Returns:
526
+ Number of aliases removed
527
+ """
528
+ backend = await self._get_backend()
529
+ aliases = await backend.get_by_entity_id(entity_id)
530
+ for alias in aliases:
531
+ await backend.delete(alias)
532
+ return len(aliases)
533
+
534
+ @asynccontextmanager
535
+ async def transaction(self) -> AsyncIterator[TransactionContext]:
536
+ """
537
+ Start a transaction for atomic operations.
538
+
539
+ Use for merge operations that need to delete old aliases
540
+ and insert new aliases atomically.
541
+
542
+ Example:
543
+ ```python
544
+ async with index.transaction() as tx:
545
+ await tx.delete("old_alias_1")
546
+ await tx.delete("old_alias_2")
547
+ await tx.set("new_alias", AliasEntry(...))
548
+ # All operations committed atomically
549
+ ```
550
+ """
551
+ backend = await self._get_backend()
552
+ async with backend.transaction() as ctx:
553
+ yield ctx
554
+
555
+ async def batch_load(
556
+ self,
557
+ entries: List[tuple], # List of (alias, entity_id, match_type)
558
+ ) -> int:
559
+ """
560
+ Batch load aliases for initial index building.
561
+
562
+ Args:
563
+ entries: List of (alias, entity_id, match_type) tuples
564
+
565
+ Returns:
566
+ Number of entries loaded
567
+ """
568
+ backend = await self._get_backend()
569
+ count = 0
570
+ for alias, entity_id, match_type in entries:
571
+ entry = AliasEntry(entity_id=entity_id, match_type=match_type)
572
+ await backend.set(alias, entry)
573
+ count += 1
574
+ return count
575
+
576
+ async def clear(self) -> None:
577
+ """Clear all entries from the index"""
578
+ backend = await self._get_backend()
579
+ await backend.clear()
580
+
581
+ async def size(self) -> int:
582
+ """Get number of entries in the index"""
583
+ backend = await self._get_backend()
584
+ return await backend.size()
585
+
586
+ async def should_use_redis(self, entity_count: int) -> bool:
587
+ """
588
+ Check if Redis backend should be used based on entity count.
589
+
590
+ Args:
591
+ entity_count: Number of entities in the graph
592
+
593
+ Returns:
594
+ True if Redis is recommended
595
+ """
596
+ return entity_count >= self._auto_redis_threshold
597
+