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,343 @@
1
+ """
2
+ Enhanced Metrics Collection
3
+
4
+ This module provides comprehensive performance and quality metrics tracking
5
+ for the search tool.
6
+ """
7
+
8
+ from datetime import datetime
9
+ from typing import Any, Dict, List, Optional
10
+
11
+
12
+ class EnhancedMetrics:
13
+ """Comprehensive metrics collection for search operations"""
14
+
15
+ def __init__(self):
16
+ """Initialize enhanced metrics"""
17
+ self.metrics = {
18
+ # Basic counters
19
+ "requests": {
20
+ "total": 0,
21
+ "successful": 0,
22
+ "failed": 0,
23
+ "cached": 0,
24
+ },
25
+ # Performance metrics
26
+ "performance": {
27
+ "response_times_ms": [], # Recent 100
28
+ "avg_response_time_ms": 0,
29
+ "p50_response_time_ms": 0,
30
+ "p95_response_time_ms": 0,
31
+ "p99_response_time_ms": 0,
32
+ "slowest_query": None,
33
+ "fastest_query": None,
34
+ },
35
+ # Quality metrics
36
+ "quality": {
37
+ "avg_results_per_query": 0,
38
+ "avg_quality_score": 0,
39
+ "high_quality_results_pct": 0,
40
+ "queries_with_no_results": 0,
41
+ },
42
+ # Error analysis
43
+ "errors": {
44
+ "by_type": {},
45
+ "recent_errors": [], # Recent 10
46
+ "error_rate": 0.0,
47
+ },
48
+ # Cache efficiency
49
+ "cache": {
50
+ "hit_rate": 0.0,
51
+ "total_hits": 0,
52
+ "total_misses": 0,
53
+ "avg_age_seconds": 0,
54
+ },
55
+ # Rate limiting
56
+ "rate_limiting": {
57
+ "throttled_requests": 0,
58
+ "avg_wait_time_ms": 0,
59
+ "quota_utilization_pct": 0,
60
+ },
61
+ # Query patterns
62
+ "patterns": {
63
+ "top_query_types": {},
64
+ "top_domains_returned": {},
65
+ "avg_query_length": 0,
66
+ },
67
+ }
68
+
69
+ def record_search(
70
+ self,
71
+ query: str,
72
+ search_type: str,
73
+ results: List[Dict[str, Any]],
74
+ response_time_ms: float,
75
+ cached: bool = False,
76
+ error: Optional[Exception] = None,
77
+ ):
78
+ """
79
+ Record a search operation.
80
+
81
+ Args:
82
+ query: Search query
83
+ search_type: Type of search performed
84
+ results: Search results
85
+ response_time_ms: Response time in milliseconds
86
+ cached: Whether result was from cache
87
+ error: Error if search failed
88
+ """
89
+ # Update request counts
90
+ self.metrics["requests"]["total"] += 1
91
+
92
+ if error:
93
+ self.metrics["requests"]["failed"] += 1
94
+ self._record_error(error)
95
+ else:
96
+ self.metrics["requests"]["successful"] += 1
97
+
98
+ if cached:
99
+ self.metrics["requests"]["cached"] += 1
100
+ self.metrics["cache"]["total_hits"] += 1
101
+ else:
102
+ self.metrics["cache"]["total_misses"] += 1
103
+
104
+ # Update performance metrics
105
+ self.metrics["performance"]["response_times_ms"].append(response_time_ms)
106
+ if len(self.metrics["performance"]["response_times_ms"]) > 100:
107
+ self.metrics["performance"]["response_times_ms"].pop(0)
108
+
109
+ self._update_percentiles()
110
+
111
+ # Track slowest/fastest queries
112
+ if not self.metrics["performance"]["slowest_query"] or response_time_ms > self.metrics["performance"]["slowest_query"]["time"]:
113
+ self.metrics["performance"]["slowest_query"] = {
114
+ "query": query,
115
+ "time": response_time_ms,
116
+ "type": search_type,
117
+ }
118
+
119
+ if not self.metrics["performance"]["fastest_query"] or response_time_ms < self.metrics["performance"]["fastest_query"]["time"]:
120
+ self.metrics["performance"]["fastest_query"] = {
121
+ "query": query,
122
+ "time": response_time_ms,
123
+ "type": search_type,
124
+ }
125
+
126
+ # Update quality metrics
127
+ if results:
128
+ result_count = len(results)
129
+
130
+ # Calculate average quality
131
+ avg_quality = sum(r.get("_quality", {}).get("quality_score", 0.5) for r in results) / result_count
132
+
133
+ # Count high quality results
134
+ high_quality_count = sum(1 for r in results if r.get("_quality", {}).get("quality_score", 0) > 0.75)
135
+
136
+ # Update running averages
137
+ total = self.metrics["requests"]["successful"]
138
+
139
+ current_avg_results = self.metrics["quality"]["avg_results_per_query"]
140
+ self.metrics["quality"]["avg_results_per_query"] = (current_avg_results * (total - 1) + result_count) / total
141
+
142
+ current_avg_quality = self.metrics["quality"]["avg_quality_score"]
143
+ self.metrics["quality"]["avg_quality_score"] = (current_avg_quality * (total - 1) + avg_quality) / total
144
+
145
+ current_high_pct = self.metrics["quality"]["high_quality_results_pct"]
146
+ high_pct = high_quality_count / result_count
147
+ self.metrics["quality"]["high_quality_results_pct"] = (current_high_pct * (total - 1) + high_pct) / total
148
+ else:
149
+ self.metrics["quality"]["queries_with_no_results"] += 1
150
+
151
+ # Update query patterns
152
+ query_type = self._detect_query_type(query)
153
+ self.metrics["patterns"]["top_query_types"][query_type] = self.metrics["patterns"]["top_query_types"].get(query_type, 0) + 1
154
+
155
+ # Track returned domains
156
+ for result in results:
157
+ domain = result.get("displayLink", "unknown")
158
+ self.metrics["patterns"]["top_domains_returned"][domain] = self.metrics["patterns"]["top_domains_returned"].get(domain, 0) + 1
159
+
160
+ # Update average query length
161
+ total = self.metrics["requests"]["total"]
162
+ current_avg_len = self.metrics["patterns"]["avg_query_length"]
163
+ self.metrics["patterns"]["avg_query_length"] = (current_avg_len * (total - 1) + len(query.split())) / total
164
+
165
+ # Update cache hit rate
166
+ total_cache_requests = self.metrics["cache"]["total_hits"] + self.metrics["cache"]["total_misses"]
167
+ if total_cache_requests > 0:
168
+ self.metrics["cache"]["hit_rate"] = self.metrics["cache"]["total_hits"] / total_cache_requests
169
+
170
+ def _update_percentiles(self):
171
+ """Update response time percentiles"""
172
+ times = sorted(self.metrics["performance"]["response_times_ms"])
173
+ if not times:
174
+ return
175
+
176
+ self.metrics["performance"]["avg_response_time_ms"] = sum(times) / len(times)
177
+ self.metrics["performance"]["p50_response_time_ms"] = times[len(times) // 2]
178
+ self.metrics["performance"]["p95_response_time_ms"] = times[int(len(times) * 0.95)]
179
+ self.metrics["performance"]["p99_response_time_ms"] = times[int(len(times) * 0.99)]
180
+
181
+ def _record_error(self, error: Exception):
182
+ """Record an error"""
183
+ error_type = type(error).__name__
184
+
185
+ self.metrics["errors"]["by_type"][error_type] = self.metrics["errors"]["by_type"].get(error_type, 0) + 1
186
+
187
+ self.metrics["errors"]["recent_errors"].append(
188
+ {
189
+ "type": error_type,
190
+ "message": str(error),
191
+ "timestamp": datetime.utcnow().isoformat(),
192
+ }
193
+ )
194
+
195
+ if len(self.metrics["errors"]["recent_errors"]) > 10:
196
+ self.metrics["errors"]["recent_errors"].pop(0)
197
+
198
+ # Update error rate
199
+ total = self.metrics["requests"]["total"]
200
+ failed = self.metrics["requests"]["failed"]
201
+ self.metrics["errors"]["error_rate"] = failed / total if total > 0 else 0
202
+
203
+ def _detect_query_type(self, query: str) -> str:
204
+ """Detect query type from query text"""
205
+ query_lower = query.lower()
206
+
207
+ if any(kw in query_lower for kw in ["how to", "tutorial", "guide"]):
208
+ return "how_to"
209
+ elif any(kw in query_lower for kw in ["what is", "define", "meaning"]):
210
+ return "definition"
211
+ elif any(kw in query_lower for kw in ["vs", "versus", "compare"]):
212
+ return "comparison"
213
+ elif any(kw in query_lower for kw in ["latest", "news", "recent"]):
214
+ return "news"
215
+ else:
216
+ return "general"
217
+
218
+ def get_health_score(self) -> float:
219
+ """
220
+ Calculate system health score (0-1).
221
+
222
+ Returns:
223
+ Health score based on success rate, performance, quality, and cache efficiency
224
+ """
225
+ total = self.metrics["requests"]["total"]
226
+ if total == 0:
227
+ return 1.0
228
+
229
+ # Success rate score (40%)
230
+ success_rate = self.metrics["requests"]["successful"] / total
231
+ success_score = success_rate * 0.4
232
+
233
+ # Performance score (25%)
234
+ avg_time = self.metrics["performance"]["avg_response_time_ms"]
235
+ # < 500ms excellent, > 3000ms poor
236
+ performance_score = max(0, min(1, (3000 - avg_time) / 2500)) * 0.25
237
+
238
+ # Quality score (25%)
239
+ quality_score = self.metrics["quality"]["avg_quality_score"] * 0.25
240
+
241
+ # Cache efficiency score (10%)
242
+ cache_score = self.metrics["cache"]["hit_rate"] * 0.1
243
+
244
+ return success_score + performance_score + quality_score + cache_score
245
+
246
+ def generate_report(self) -> str:
247
+ """
248
+ Generate human-readable metrics report.
249
+
250
+ Returns:
251
+ Formatted report string
252
+ """
253
+ health = self.get_health_score()
254
+ total = self.metrics["requests"]["total"]
255
+
256
+ if total == 0:
257
+ return "No search operations recorded yet."
258
+
259
+ health_indicator = "✅" if health > 0.8 else "⚠️" if health > 0.6 else "❌"
260
+
261
+ # Format top error types
262
+ top_errors = sorted(
263
+ self.metrics["errors"]["by_type"].items(),
264
+ key=lambda x: x[1],
265
+ reverse=True,
266
+ )[:3]
267
+ error_str = ", ".join(f"{k}({v})" for k, v in top_errors) if top_errors else "None"
268
+
269
+ # Format top query types
270
+ top_types = sorted(
271
+ self.metrics["patterns"]["top_query_types"].items(),
272
+ key=lambda x: x[1],
273
+ reverse=True,
274
+ )[:3]
275
+ types_str = ", ".join(f"{k}({v})" for k, v in top_types)
276
+
277
+ # Format top domains
278
+ top_domains = sorted(
279
+ self.metrics["patterns"]["top_domains_returned"].items(),
280
+ key=lambda x: x[1],
281
+ reverse=True,
282
+ )[:5]
283
+ domains_str = ", ".join(f"{k}({v})" for k, v in top_domains)
284
+
285
+ # Extract slowest query info
286
+ slowest_query = self.metrics["performance"]["slowest_query"]
287
+ slowest_query_str = "N/A"
288
+ slowest_time_str = "0ms"
289
+ if slowest_query:
290
+ slowest_query_str = slowest_query["query"]
291
+ slowest_time_str = f"{slowest_query['time']:.0f}ms"
292
+
293
+ report = f"""
294
+ Search Tool Performance Report
295
+ {'='*50}
296
+
297
+ Overall Health Score: {health:.2%} {health_indicator}
298
+
299
+ Requests:
300
+ Total: {total}
301
+ Successful: {self.metrics['requests']['successful']} ({self.metrics['requests']['successful']/total:.1%})
302
+ Failed: {self.metrics['requests']['failed']}
303
+ Cached: {self.metrics['requests']['cached']}
304
+
305
+ Performance:
306
+ Avg Response: {self.metrics['performance']['avg_response_time_ms']:.0f}ms
307
+ P95 Response: {self.metrics['performance']['p95_response_time_ms']:.0f}ms
308
+ Slowest: {slowest_query_str} ({slowest_time_str})
309
+
310
+ Quality:
311
+ Avg Results/Query: {self.metrics['quality']['avg_results_per_query']:.1f}
312
+ Avg Quality Score: {self.metrics['quality']['avg_quality_score']:.2f}
313
+ High Quality %: {self.metrics['quality']['high_quality_results_pct']:.1%}
314
+ No Results: {self.metrics['quality']['queries_with_no_results']}
315
+
316
+ Cache:
317
+ Hit Rate: {self.metrics['cache']['hit_rate']:.1%}
318
+ Hits: {self.metrics['cache']['total_hits']}
319
+ Misses: {self.metrics['cache']['total_misses']}
320
+
321
+ Errors:
322
+ Error Rate: {self.metrics['errors']['error_rate']:.1%}
323
+ Top Types: {error_str}
324
+
325
+ Query Patterns:
326
+ Top Types: {types_str}
327
+ Avg Query Length: {self.metrics['patterns']['avg_query_length']:.1f} words
328
+ Top Domains: {domains_str}
329
+ """
330
+ return report
331
+
332
+ def get_metrics(self) -> Dict[str, Any]:
333
+ """
334
+ Get all metrics.
335
+
336
+ Returns:
337
+ Complete metrics dictionary
338
+ """
339
+ return self.metrics.copy()
340
+
341
+ def reset(self):
342
+ """Reset all metrics"""
343
+ self.__init__()
@@ -0,0 +1,172 @@
1
+ """
2
+ Rate Limiting and Circuit Breaker Components
3
+
4
+ This module implements rate limiting using token bucket algorithm and
5
+ circuit breaker pattern for API resilience.
6
+ """
7
+
8
+ import time
9
+ from collections import deque
10
+ from threading import Lock
11
+ from typing import Optional
12
+
13
+ from .constants import CircuitState, RateLimitError, CircuitBreakerOpenError
14
+
15
+
16
+ # ============================================================================
17
+ # Rate Limiter
18
+ # ============================================================================
19
+
20
+
21
+ class RateLimiter:
22
+ """
23
+ Token bucket rate limiter for API requests.
24
+
25
+ Implements a token bucket algorithm to limit the rate of API requests
26
+ and prevent quota exhaustion.
27
+ """
28
+
29
+ def __init__(self, max_requests: int, time_window: int):
30
+ """
31
+ Initialize rate limiter.
32
+
33
+ Args:
34
+ max_requests: Maximum number of requests allowed
35
+ time_window: Time window in seconds
36
+ """
37
+ self.max_requests = max_requests
38
+ self.time_window = time_window
39
+ self.tokens = max_requests
40
+ self.last_update = time.time()
41
+ self.lock = Lock()
42
+ self.request_history: deque = deque()
43
+
44
+ def _refill_tokens(self):
45
+ """Refill tokens based on elapsed time"""
46
+ now = time.time()
47
+ time_passed = now - self.last_update
48
+
49
+ # Refill tokens proportionally to time passed
50
+ refill_rate = self.max_requests / self.time_window
51
+ tokens_to_add = time_passed * refill_rate
52
+
53
+ self.tokens = min(self.max_requests, self.tokens + tokens_to_add)
54
+ self.last_update = now
55
+
56
+ def acquire(self, tokens: int = 1) -> bool:
57
+ """
58
+ Attempt to acquire tokens.
59
+
60
+ Args:
61
+ tokens: Number of tokens to acquire
62
+
63
+ Returns:
64
+ True if tokens acquired, False otherwise
65
+
66
+ Raises:
67
+ RateLimitError: If rate limit is exceeded
68
+ """
69
+ with self.lock:
70
+ self._refill_tokens()
71
+
72
+ # Clean up old request history
73
+ cutoff_time = time.time() - self.time_window
74
+ while self.request_history and self.request_history[0] < cutoff_time:
75
+ self.request_history.popleft()
76
+
77
+ # Check if we have enough tokens
78
+ if self.tokens >= tokens:
79
+ self.tokens -= tokens
80
+ self.request_history.append(time.time())
81
+ return True
82
+ else:
83
+ # Calculate wait time
84
+ wait_time = (tokens - self.tokens) / (self.max_requests / self.time_window)
85
+ raise RateLimitError(f"Rate limit exceeded. {len(self.request_history)} requests in last " f"{self.time_window}s. Wait {wait_time:.1f}s before retrying.")
86
+
87
+ def get_remaining_quota(self) -> int:
88
+ """Get remaining quota"""
89
+ with self.lock:
90
+ self._refill_tokens()
91
+ return int(self.tokens)
92
+
93
+
94
+ # ============================================================================
95
+ # Circuit Breaker
96
+ # ============================================================================
97
+
98
+
99
+ class CircuitBreaker:
100
+ """
101
+ Circuit breaker pattern implementation for API resilience.
102
+
103
+ Implements a circuit breaker to prevent cascading failures when
104
+ the API is experiencing issues.
105
+ """
106
+
107
+ def __init__(self, failure_threshold: int, timeout: int):
108
+ """
109
+ Initialize circuit breaker.
110
+
111
+ Args:
112
+ failure_threshold: Number of failures before opening circuit
113
+ timeout: Timeout in seconds before trying half-open state
114
+ """
115
+ self.failure_threshold = failure_threshold
116
+ self.timeout = timeout
117
+ self.failure_count = 0
118
+ self.last_failure_time: Optional[float] = None
119
+ self.state = CircuitState.CLOSED
120
+ self.lock = Lock()
121
+
122
+ def call(self, func, *args, **kwargs):
123
+ """
124
+ Execute function with circuit breaker protection.
125
+
126
+ Args:
127
+ func: Function to execute
128
+ *args: Positional arguments
129
+ **kwargs: Keyword arguments
130
+
131
+ Returns:
132
+ Function result
133
+
134
+ Raises:
135
+ CircuitBreakerOpenError: If circuit is open
136
+ """
137
+ with self.lock:
138
+ if self.state == CircuitState.OPEN:
139
+ # Check if timeout has passed
140
+ if time.time() - self.last_failure_time >= self.timeout:
141
+ self.state = CircuitState.HALF_OPEN
142
+ self.failure_count = 0
143
+ else:
144
+ raise CircuitBreakerOpenError(f"Circuit breaker is OPEN. Retry after " f"{self.timeout - (time.time() - self.last_failure_time):.1f}s")
145
+
146
+ try:
147
+ result = func(*args, **kwargs)
148
+ self._on_success()
149
+ return result
150
+ except Exception as e:
151
+ self._on_failure()
152
+ raise e
153
+
154
+ def _on_success(self):
155
+ """Handle successful call"""
156
+ with self.lock:
157
+ if self.state == CircuitState.HALF_OPEN:
158
+ self.state = CircuitState.CLOSED
159
+ self.failure_count = 0
160
+
161
+ def _on_failure(self):
162
+ """Handle failed call"""
163
+ with self.lock:
164
+ self.failure_count += 1
165
+ self.last_failure_time = time.time()
166
+
167
+ if self.failure_count >= self.failure_threshold:
168
+ self.state = CircuitState.OPEN
169
+
170
+ def get_state(self) -> str:
171
+ """Get current circuit state"""
172
+ return self.state.value