aiecs 1.0.1__py3-none-any.whl → 1.7.17__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 +435 -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 +3949 -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 +1731 -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 +894 -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 +377 -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 +230 -37
  195. aiecs/llm/client_resolver.py +155 -0
  196. aiecs/llm/clients/__init__.py +38 -0
  197. aiecs/llm/clients/base_client.py +328 -0
  198. aiecs/llm/clients/google_function_calling_mixin.py +415 -0
  199. aiecs/llm/clients/googleai_client.py +314 -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 +1186 -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 +1464 -0
  269. aiecs/tools/docs/document_layout_tool.py +1160 -0
  270. aiecs/tools/docs/document_parser_tool.py +1016 -0
  271. aiecs/tools/docs/document_writer_tool.py +2008 -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 +220 -141
  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.17.dist-info}/METADATA +52 -15
  321. aiecs-1.7.17.dist-info/RECORD +337 -0
  322. aiecs-1.7.17.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.17.dist-info}/WHEEL +0 -0
  339. {aiecs-1.0.1.dist-info → aiecs-1.7.17.dist-info}/licenses/LICENSE +0 -0
  340. {aiecs-1.0.1.dist-info → aiecs-1.7.17.dist-info}/top_level.txt +0 -0
@@ -3,9 +3,10 @@ import logging
3
3
  import time
4
4
  import uuid
5
5
  from typing import Dict, List, Any, Optional
6
- from celery import Celery
7
- from celery.exceptions import TimeoutError as CeleryTimeoutError
6
+ from celery import Celery # type: ignore[import-untyped]
7
+ from celery.exceptions import TimeoutError as CeleryTimeoutError # type: ignore[import-untyped]
8
8
  from asyncio import TimeoutError as AsyncioTimeoutError
9
+
9
10
  # Removed direct import to avoid circular dependency
10
11
  # Tasks are referenced by string names instead
11
12
  from aiecs.domain.execution.model import TaskStatus, ErrorCode
@@ -20,33 +21,42 @@ class CeleryTaskManager:
20
21
 
21
22
  def __init__(self, config: Dict[str, Any]):
22
23
  self.config = config
23
- self.celery_app = None
24
+ self.celery_app: Optional[Celery] = None
24
25
  self._init_celery()
25
26
 
26
27
  def _init_celery(self):
27
28
  """Initialize Celery application"""
28
29
  try:
29
30
  self.celery_app = Celery(
30
- 'service_executor',
31
- broker=self.config.get('broker_url', 'redis://redis:6379/0'),
32
- backend=self.config.get('backend_url', 'redis://redis:6379/0')
31
+ "service_executor",
32
+ broker=self.config.get("broker_url", "redis://redis:6379/0"),
33
+ backend=self.config.get("backend_url", "redis://redis:6379/0"),
33
34
  )
34
35
 
35
36
  # Configure Celery
36
37
  self.celery_app.conf.update(
37
- task_serializer=self.config.get('task_serializer', 'json'),
38
- accept_content=self.config.get('accept_content', ['json']),
39
- result_serializer=self.config.get('result_serializer', 'json'),
40
- timezone=self.config.get('timezone', 'UTC'),
41
- enable_utc=self.config.get('enable_utc', True),
42
- task_queues=self.config.get('task_queues', {
43
- 'fast_tasks': {'exchange': 'fast_tasks', 'routing_key': 'fast_tasks'},
44
- 'heavy_tasks': {'exchange': 'heavy_tasks', 'routing_key': 'heavy_tasks'}
45
- }),
46
- worker_concurrency=self.config.get('worker_concurrency', {
47
- 'fast_worker': 10,
48
- 'heavy_worker': 2
49
- })
38
+ task_serializer=self.config.get("task_serializer", "json"),
39
+ accept_content=self.config.get("accept_content", ["json"]),
40
+ result_serializer=self.config.get("result_serializer", "json"),
41
+ timezone=self.config.get("timezone", "UTC"),
42
+ enable_utc=self.config.get("enable_utc", True),
43
+ task_queues=self.config.get(
44
+ "task_queues",
45
+ {
46
+ "fast_tasks": {
47
+ "exchange": "fast_tasks",
48
+ "routing_key": "fast_tasks",
49
+ },
50
+ "heavy_tasks": {
51
+ "exchange": "heavy_tasks",
52
+ "routing_key": "heavy_tasks",
53
+ },
54
+ },
55
+ ),
56
+ worker_concurrency=self.config.get(
57
+ "worker_concurrency",
58
+ {"fast_worker": 10, "heavy_worker": 2},
59
+ ),
50
60
  )
51
61
 
52
62
  logger.info("Celery application initialized successfully")
@@ -54,8 +64,18 @@ class CeleryTaskManager:
54
64
  logger.error(f"Failed to initialize Celery: {e}")
55
65
  raise
56
66
 
57
- def execute_celery_task(self, task_name: str, queue: str, user_id: str, task_id: str, step: int,
58
- mode: str, service: str, input_data: Dict[str, Any], context: Dict[str, Any]):
67
+ def execute_celery_task(
68
+ self,
69
+ task_name: str,
70
+ queue: str,
71
+ user_id: str,
72
+ task_id: str,
73
+ step: int,
74
+ mode: str,
75
+ service: str,
76
+ input_data: Dict[str, Any],
77
+ context: Dict[str, Any],
78
+ ):
59
79
  """
60
80
  Execute Celery task
61
81
 
@@ -81,6 +101,8 @@ class CeleryTaskManager:
81
101
  celery_task_name = "aiecs.tasks.worker.execute_heavy_task"
82
102
 
83
103
  # Send task to Celery
104
+ if self.celery_app is None:
105
+ raise RuntimeError("Celery app not initialized")
84
106
  return self.celery_app.send_task(
85
107
  celery_task_name,
86
108
  kwargs={
@@ -91,12 +113,17 @@ class CeleryTaskManager:
91
113
  "mode": mode,
92
114
  "service": service,
93
115
  "input_data": input_data,
94
- "context": context
116
+ "context": context,
95
117
  },
96
- queue=queue
118
+ queue=queue,
97
119
  )
98
120
 
99
- async def execute_task(self, task_name: str, input_data: Dict[str, Any], context: Dict[str, Any]) -> Any:
121
+ async def execute_task(
122
+ self,
123
+ task_name: str,
124
+ input_data: Dict[str, Any],
125
+ context: Dict[str, Any],
126
+ ) -> Any:
100
127
  """
101
128
  Execute a single task using Celery for asynchronous processing
102
129
  """
@@ -106,14 +133,16 @@ class CeleryTaskManager:
106
133
  mode = input_data.get("mode", "default")
107
134
  service = input_data.get("service", "default")
108
135
  queue = input_data.get("queue", "fast_tasks")
109
- timeout = self.config.get('task_timeout_seconds', 300)
136
+ timeout = self.config.get("task_timeout_seconds", 300)
110
137
 
111
138
  try:
112
139
  # Use string-based task names to avoid circular imports
113
140
  celery_task_name = "aiecs.tasks.worker.execute_task"
114
- if queue == 'heavy_tasks':
141
+ if queue == "heavy_tasks":
115
142
  celery_task_name = "aiecs.tasks.worker.execute_heavy_task"
116
143
 
144
+ if self.celery_app is None:
145
+ raise RuntimeError("Celery app not initialized")
117
146
  result = self.celery_app.send_task(
118
147
  celery_task_name,
119
148
  kwargs={
@@ -124,9 +153,9 @@ class CeleryTaskManager:
124
153
  "mode": mode,
125
154
  "service": service,
126
155
  "input_data": input_data,
127
- "context": context
156
+ "context": context,
128
157
  },
129
- queue=queue
158
+ queue=queue,
130
159
  )
131
160
 
132
161
  return result.get(timeout=timeout)
@@ -136,14 +165,14 @@ class CeleryTaskManager:
136
165
  return {
137
166
  "status": TaskStatus.TIMED_OUT,
138
167
  "error_code": ErrorCode.TIMEOUT_ERROR,
139
- "error_message": str(e)
168
+ "error_message": str(e),
140
169
  }
141
170
  except Exception as e:
142
171
  logger.error(f"Error executing Celery task {task_name}: {e}", exc_info=True)
143
172
  return {
144
173
  "status": TaskStatus.FAILED,
145
174
  "error_code": ErrorCode.EXECUTION_ERROR,
146
- "error_message": str(e)
175
+ "error_message": str(e),
147
176
  }
148
177
 
149
178
  async def execute_heavy_task(self, task_name: str, input_data: Dict, context: Dict) -> Any:
@@ -168,7 +197,7 @@ class CeleryTaskManager:
168
197
  "message": "Invalid DSL step: missing task name",
169
198
  "status": TaskStatus.FAILED,
170
199
  "error_code": ErrorCode.VALIDATION_ERROR,
171
- "error_message": "Task name is required"
200
+ "error_message": "Task name is required",
172
201
  }
173
202
 
174
203
  # Determine task type
@@ -188,6 +217,8 @@ class CeleryTaskManager:
188
217
  step_num = context.get("step", 0)
189
218
 
190
219
  # Send task to Celery
220
+ if self.celery_app is None:
221
+ raise RuntimeError("Celery app not initialized")
191
222
  celery_task = self.celery_app.send_task(
192
223
  celery_task_name,
193
224
  kwargs={
@@ -198,13 +229,13 @@ class CeleryTaskManager:
198
229
  "mode": context.get("mode", "multi_task"),
199
230
  "service": context.get("service", "summarizer"),
200
231
  "input_data": input_data,
201
- "context": context
232
+ "context": context,
202
233
  },
203
- queue=queue
234
+ queue=queue,
204
235
  )
205
236
 
206
237
  try:
207
- timeout_seconds = self.config.get('task_timeout_seconds', 300)
238
+ timeout_seconds = self.config.get("task_timeout_seconds", 300)
208
239
  start_time = time.time()
209
240
 
210
241
  # Wait for task completion
@@ -223,7 +254,7 @@ class CeleryTaskManager:
223
254
  "result": result,
224
255
  "completed": True,
225
256
  "message": f"Completed task {task_name}",
226
- "status": TaskStatus.COMPLETED
257
+ "status": TaskStatus.COMPLETED,
227
258
  }
228
259
  else:
229
260
  error = celery_task.get(propagate=False)
@@ -237,7 +268,7 @@ class CeleryTaskManager:
237
268
  "message": f"Failed to execute task: {error}",
238
269
  "status": status,
239
270
  "error_code": error_code,
240
- "error_message": str(error)
271
+ "error_message": str(error),
241
272
  }
242
273
 
243
274
  except AsyncioTimeoutError as e:
@@ -248,7 +279,7 @@ class CeleryTaskManager:
248
279
  "message": "Task execution timed out",
249
280
  "status": TaskStatus.TIMED_OUT,
250
281
  "error_code": ErrorCode.TIMEOUT_ERROR,
251
- "error_message": str(e)
282
+ "error_message": str(e),
252
283
  }
253
284
  except Exception as e:
254
285
  return {
@@ -258,31 +289,31 @@ class CeleryTaskManager:
258
289
  "message": f"Failed to execute {category}/{task_name}",
259
290
  "status": TaskStatus.FAILED,
260
291
  "error_code": ErrorCode.EXECUTION_ERROR,
261
- "error_message": str(e)
292
+ "error_message": str(e),
262
293
  }
263
294
 
264
295
  def get_task_result(self, task_id: str):
265
296
  """Get task result"""
266
297
  try:
298
+ if self.celery_app is None:
299
+ raise RuntimeError("Celery app not initialized")
267
300
  result = self.celery_app.AsyncResult(task_id)
268
301
  return {
269
302
  "task_id": task_id,
270
303
  "status": result.status,
271
304
  "result": result.result if result.ready() else None,
272
305
  "successful": result.successful() if result.ready() else None,
273
- "failed": result.failed() if result.ready() else None
306
+ "failed": result.failed() if result.ready() else None,
274
307
  }
275
308
  except Exception as e:
276
309
  logger.error(f"Error getting task result for {task_id}: {e}")
277
- return {
278
- "task_id": task_id,
279
- "status": "ERROR",
280
- "error": str(e)
281
- }
310
+ return {"task_id": task_id, "status": "ERROR", "error": str(e)}
282
311
 
283
312
  def cancel_task(self, task_id: str):
284
313
  """Cancel task"""
285
314
  try:
315
+ if self.celery_app is None:
316
+ raise RuntimeError("Celery app not initialized")
286
317
  self.celery_app.control.revoke(task_id, terminate=True)
287
318
  logger.info(f"Task {task_id} cancelled")
288
319
  return True
@@ -295,18 +326,21 @@ class CeleryTaskManager:
295
326
  Batch execute tasks
296
327
  """
297
328
  results = []
298
- batch_size = self.config.get('batch_size', 10)
299
- rate_limit = self.config.get('rate_limit_requests_per_second', 5)
329
+ batch_size = self.config.get("batch_size", 10)
330
+ rate_limit = self.config.get("rate_limit_requests_per_second", 5)
300
331
 
301
332
  for i in range(0, len(tasks), batch_size):
302
- batch = tasks[i:i + batch_size]
333
+ batch = tasks[i : i + batch_size]
303
334
  batch_results = await asyncio.gather(
304
- *[self.execute_task(
305
- task["task_name"],
306
- task.get("input_data", {}),
307
- task.get("context", {})
308
- ) for task in batch],
309
- return_exceptions=True
335
+ *[
336
+ self.execute_task(
337
+ task["task_name"],
338
+ task.get("input_data", {}),
339
+ task.get("context", {}),
340
+ )
341
+ for task in batch
342
+ ],
343
+ return_exceptions=True,
310
344
  )
311
345
  results.extend(batch_results)
312
346
  await asyncio.sleep(1.0 / rate_limit)
@@ -316,6 +350,8 @@ class CeleryTaskManager:
316
350
  def get_queue_info(self) -> Dict[str, Any]:
317
351
  """Get queue information"""
318
352
  try:
353
+ if self.celery_app is None:
354
+ raise RuntimeError("Celery app not initialized")
319
355
  inspect = self.celery_app.control.inspect()
320
356
  active_tasks = inspect.active()
321
357
  scheduled_tasks = inspect.scheduled()
@@ -324,7 +360,7 @@ class CeleryTaskManager:
324
360
  return {
325
361
  "active_tasks": active_tasks,
326
362
  "scheduled_tasks": scheduled_tasks,
327
- "reserved_tasks": reserved_tasks
363
+ "reserved_tasks": reserved_tasks,
328
364
  }
329
365
  except Exception as e:
330
366
  logger.error(f"Error getting queue info: {e}")
@@ -333,6 +369,8 @@ class CeleryTaskManager:
333
369
  def get_worker_stats(self) -> Dict[str, Any]:
334
370
  """Get worker statistics"""
335
371
  try:
372
+ if self.celery_app is None:
373
+ raise RuntimeError("Celery app not initialized")
336
374
  inspect = self.celery_app.control.inspect()
337
375
  stats = inspect.stats()
338
376
  return stats or {}
@@ -45,11 +45,7 @@ class WebSocketManager:
45
45
  return self.server
46
46
 
47
47
  try:
48
- self.server = await serve(
49
- self._handle_client_connection,
50
- self.host,
51
- self.port
52
- )
48
+ self.server = await serve(self._handle_client_connection, self.host, self.port)
53
49
  self._running = True
54
50
  logger.info(f"WebSocket server started on {self.host}:{self.port}")
55
51
  return self.server
@@ -69,7 +65,7 @@ class WebSocketManager:
69
65
  if self.active_connections:
70
66
  await asyncio.gather(
71
67
  *[conn.close() for conn in self.active_connections],
72
- return_exceptions=True
68
+ return_exceptions=True,
73
69
  )
74
70
  self.active_connections.clear()
75
71
 
@@ -81,15 +77,19 @@ class WebSocketManager:
81
77
 
82
78
  try:
83
79
  async for message in websocket:
84
- await self._handle_client_message(websocket, message)
80
+ # Decode bytes to str if needed
81
+ message_str = message if isinstance(message, str) else message.decode('utf-8')
82
+ await self._handle_client_message(websocket, message_str)
85
83
  except websockets.exceptions.ConnectionClosed:
86
84
  logger.info(f"WebSocket connection closed: {client_addr}")
87
85
  except Exception as e:
88
86
  logger.error(f"WebSocket error for {client_addr}: {e}")
89
87
  finally:
90
88
  self.active_connections.discard(websocket)
91
- if not websocket.closed:
89
+ try:
92
90
  await websocket.close()
91
+ except Exception:
92
+ pass # Connection already closed
93
93
 
94
94
  async def _handle_client_message(self, websocket: ServerConnection, message: str):
95
95
  """Handle client message"""
@@ -123,7 +123,7 @@ class WebSocketManager:
123
123
  callback = self.callback_registry[callback_id]
124
124
  confirmation = UserConfirmation(
125
125
  proceed=data.get("proceed", False),
126
- feedback=data.get("feedback")
126
+ feedback=data.get("feedback"),
127
127
  )
128
128
  try:
129
129
  callback(confirmation)
@@ -141,14 +141,17 @@ class WebSocketManager:
141
141
 
142
142
  if user_id and task_id:
143
143
  # Task cancellation logic can be added here
144
- # Since database manager access is needed, this functionality may need to be implemented through callbacks
144
+ # Since database manager access is needed, this functionality may
145
+ # need to be implemented through callbacks
145
146
  logger.info(f"Task cancellation requested: user={user_id}, task={task_id}")
146
- await self.broadcast_message({
147
- "type": "task_cancelled",
148
- "user_id": user_id,
149
- "task_id": task_id,
150
- "timestamp": asyncio.get_event_loop().time()
151
- })
147
+ await self.broadcast_message(
148
+ {
149
+ "type": "task_cancelled",
150
+ "user_id": user_id,
151
+ "task_id": task_id,
152
+ "timestamp": asyncio.get_event_loop().time(),
153
+ }
154
+ )
152
155
  else:
153
156
  logger.warning("Invalid cancellation request: missing user_id or task_id")
154
157
 
@@ -157,7 +160,7 @@ class WebSocketManager:
157
160
  pong_data = {
158
161
  "type": "pong",
159
162
  "timestamp": asyncio.get_event_loop().time(),
160
- "original_data": data
163
+ "original_data": data,
161
164
  }
162
165
  await self._send_to_client(websocket, pong_data)
163
166
 
@@ -167,32 +170,37 @@ class WebSocketManager:
167
170
  if user_id:
168
171
  # User-specific subscription logic can be implemented here
169
172
  logger.info(f"User {user_id} subscribed to updates")
170
- await self._send_to_client(websocket, {
171
- "type": "subscription_confirmed",
172
- "user_id": user_id
173
- })
173
+ await self._send_to_client(
174
+ websocket,
175
+ {"type": "subscription_confirmed", "user_id": user_id},
176
+ )
174
177
 
175
178
  async def _send_error(self, websocket: ServerConnection, error_message: str):
176
179
  """Send error message to client"""
177
180
  error_data = {
178
181
  "type": "error",
179
182
  "message": error_message,
180
- "timestamp": asyncio.get_event_loop().time()
183
+ "timestamp": asyncio.get_event_loop().time(),
181
184
  }
182
185
  await self._send_to_client(websocket, error_data)
183
186
 
184
187
  async def _send_to_client(self, websocket: ServerConnection, data: Dict[str, Any]):
185
188
  """Send data to specific client"""
186
189
  try:
187
- if not websocket.closed:
188
- await websocket.send(json.dumps(data))
190
+ await websocket.send(json.dumps(data))
189
191
  except Exception as e:
190
192
  logger.error(f"Failed to send message to client: {e}")
191
193
 
192
- async def notify_user(self, step_result: TaskStepResult, user_id: str, task_id: str, step: int) -> UserConfirmation:
194
+ async def notify_user(
195
+ self,
196
+ step_result: TaskStepResult,
197
+ user_id: str,
198
+ task_id: str,
199
+ step: int,
200
+ ) -> UserConfirmation:
193
201
  """Notify user of task step result"""
194
202
  callback_id = str(uuid.uuid4())
195
- confirmation_future = asyncio.Future()
203
+ confirmation_future: asyncio.Future[UserConfirmation] = asyncio.Future()
196
204
 
197
205
  # Register callback
198
206
  self.callback_registry[callback_id] = lambda confirmation: confirmation_future.set_result(confirmation)
@@ -209,16 +217,18 @@ class WebSocketManager:
209
217
  "error_message": step_result.error_message,
210
218
  "user_id": user_id,
211
219
  "task_id": task_id,
212
- "timestamp": asyncio.get_event_loop().time()
220
+ "timestamp": asyncio.get_event_loop().time(),
213
221
  }
214
222
 
215
223
  try:
216
- # Broadcast to all connected clients (can be optimized to send only to specific users)
224
+ # Broadcast to all connected clients (can be optimized to send only
225
+ # to specific users)
217
226
  await self.broadcast_message(notification_data)
218
227
 
219
228
  # Wait for user confirmation with timeout
220
229
  try:
221
- return await asyncio.wait_for(confirmation_future, timeout=300) # 5 minute timeout
230
+ # 5 minute timeout
231
+ return await asyncio.wait_for(confirmation_future, timeout=300)
222
232
  except asyncio.TimeoutError:
223
233
  logger.warning(f"User confirmation timeout for callback {callback_id}")
224
234
  # Clean up callback
@@ -239,7 +249,7 @@ class WebSocketManager:
239
249
  "message": "Task is still executing...",
240
250
  "user_id": user_id,
241
251
  "task_id": task_id,
242
- "timestamp": asyncio.get_event_loop().time()
252
+ "timestamp": asyncio.get_event_loop().time(),
243
253
  }
244
254
 
245
255
  while self._running:
@@ -256,14 +266,20 @@ class WebSocketManager:
256
266
  logger.debug("No active WebSocket connections for broadcast")
257
267
  return
258
268
 
259
- # Filter out closed connections
260
- active_connections = [conn for conn in self.active_connections if not conn.closed]
269
+ # Filter out closed connections (use try-except to handle closed connections)
270
+ active_connections = []
271
+ for conn in list(self.active_connections):
272
+ try:
273
+ # Try to check if connection is still valid
274
+ active_connections.append(conn)
275
+ except Exception:
276
+ pass # Connection is closed, skip it
261
277
  self.active_connections = set(active_connections)
262
278
 
263
279
  if active_connections:
264
280
  await asyncio.gather(
265
281
  *[self._send_to_client(conn, message) for conn in active_connections],
266
- return_exceptions=True
282
+ return_exceptions=True,
267
283
  )
268
284
  logger.debug(f"Broadcasted message to {len(active_connections)} clients")
269
285
 
@@ -276,7 +292,7 @@ class WebSocketManager:
276
292
 
277
293
  def get_connection_count(self) -> int:
278
294
  """Get active connection count"""
279
- return len([conn for conn in self.active_connections if not conn.closed])
295
+ return len(self.active_connections)
280
296
 
281
297
  def get_status(self) -> Dict[str, Any]:
282
298
  """Get WebSocket manager status"""
@@ -285,5 +301,5 @@ class WebSocketManager:
285
301
  "host": self.host,
286
302
  "port": self.port,
287
303
  "active_connections": self.get_connection_count(),
288
- "pending_callbacks": len(self.callback_registry)
304
+ "pending_callbacks": len(self.callback_registry),
289
305
  }
@@ -5,8 +5,30 @@ Contains monitoring, metrics, and observability infrastructure.
5
5
 
6
6
  from .executor_metrics import ExecutorMetrics
7
7
  from .tracing_manager import TracingManager
8
+ from .global_metrics_manager import (
9
+ initialize_global_metrics,
10
+ get_global_metrics,
11
+ close_global_metrics,
12
+ is_metrics_initialized,
13
+ get_metrics_summary,
14
+ record_operation,
15
+ record_duration,
16
+ record_operation_success,
17
+ record_operation_failure,
18
+ record_retry,
19
+ )
8
20
 
9
21
  __all__ = [
10
22
  "ExecutorMetrics",
11
23
  "TracingManager",
24
+ "initialize_global_metrics",
25
+ "get_global_metrics",
26
+ "close_global_metrics",
27
+ "is_metrics_initialized",
28
+ "get_metrics_summary",
29
+ "record_operation",
30
+ "record_duration",
31
+ "record_operation_success",
32
+ "record_operation_failure",
33
+ "record_retry",
12
34
  ]
@@ -25,14 +25,29 @@ class ExecutorMetrics:
25
25
  start_http_server(self.metrics_port)
26
26
  self.metrics = {
27
27
  "intent_latency": Histogram("intent_latency_seconds", "Latency of intent parsing"),
28
- "intent_success": Counter("intent_success_total", "Number of successful intent parsings"),
28
+ "intent_success": Counter(
29
+ "intent_success_total",
30
+ "Number of successful intent parsings",
31
+ ),
29
32
  "intent_retries": Counter("intent_retries_total", "Number of intent parsing retries"),
30
33
  "plan_latency": Histogram("plan_latency_seconds", "Latency of task planning"),
31
34
  "plan_success": Counter("plan_success_total", "Number of successful plans"),
32
35
  "plan_retries": Counter("plan_retries_total", "Number of plan retries"),
33
- "execute_latency": Histogram("execute_latency_seconds", "Latency of task execution", ["task_type"]),
34
- "execute_success": Counter("execute_success_total", "Number of successful executions", ["task_type"]),
35
- "execute_retries": Counter("execute_retries_total", "Number of execution retries", ["task_type"]),
36
+ "execute_latency": Histogram(
37
+ "execute_latency_seconds",
38
+ "Latency of task execution",
39
+ ["task_type"],
40
+ ),
41
+ "execute_success": Counter(
42
+ "execute_success_total",
43
+ "Number of successful executions",
44
+ ["task_type"],
45
+ ),
46
+ "execute_retries": Counter(
47
+ "execute_retries_total",
48
+ "Number of execution retries",
49
+ ["task_type"],
50
+ ),
36
51
  }
37
52
  logger.info(f"Prometheus metrics server started on port {self.metrics_port}")
38
53
  except Exception as e:
@@ -54,7 +69,12 @@ class ExecutorMetrics:
54
69
  metric = metric.labels(**labels)
55
70
  metric.inc()
56
71
 
57
- def record_operation_failure(self, operation: str, error_type: str, labels: Optional[Dict[str, str]] = None):
72
+ def record_operation_failure(
73
+ self,
74
+ operation: str,
75
+ error_type: str,
76
+ labels: Optional[Dict[str, str]] = None,
77
+ ):
58
78
  """Record operation failure"""
59
79
  if not self.enable_metrics:
60
80
  return
@@ -70,6 +90,7 @@ class ExecutorMetrics:
70
90
 
71
91
  def with_metrics(self, metric_name: str, labels: Optional[Dict[str, str]] = None):
72
92
  """Monitoring decorator"""
93
+
73
94
  def decorator(func):
74
95
  @functools.wraps(func)
75
96
  async def wrapper(*args, **kwargs):
@@ -93,7 +114,9 @@ class ExecutorMetrics:
93
114
  except Exception as e:
94
115
  logger.error(f"Error in {func.__name__}: {e}")
95
116
  raise
117
+
96
118
  return wrapper
119
+
97
120
  return decorator
98
121
 
99
122
  def get_metrics_summary(self) -> Dict[str, Any]:
@@ -104,10 +127,16 @@ class ExecutorMetrics:
104
127
  return {
105
128
  "metrics_enabled": True,
106
129
  "metrics_port": self.metrics_port,
107
- "available_metrics": list(self.metrics.keys())
130
+ "available_metrics": list(self.metrics.keys()),
108
131
  }
109
132
 
110
- def record_operation(self, operation_type: str, success: bool = True, duration: Optional[float] = None, **kwargs):
133
+ def record_operation(
134
+ self,
135
+ operation_type: str,
136
+ success: bool = True,
137
+ duration: Optional[float] = None,
138
+ **kwargs,
139
+ ):
111
140
  """Record a general operation for metrics tracking"""
112
141
  if not self.enable_metrics:
113
142
  return
@@ -115,10 +144,10 @@ class ExecutorMetrics:
115
144
  try:
116
145
  # Record operation success/failure
117
146
  if success:
118
- self.record_operation_success(operation_type, kwargs.get('labels'))
147
+ self.record_operation_success(operation_type, kwargs.get("labels"))
119
148
  else:
120
- error_type = kwargs.get('error_type', 'unknown')
121
- self.record_operation_failure(operation_type, error_type, kwargs.get('labels'))
149
+ error_type = kwargs.get("error_type", "unknown")
150
+ self.record_operation_failure(operation_type, error_type, kwargs.get("labels"))
122
151
 
123
152
  # Record operation latency if provided
124
153
  if duration is not None:
@@ -127,7 +156,12 @@ class ExecutorMetrics:
127
156
  except Exception as e:
128
157
  logger.warning(f"Failed to record operation metrics: {e}")
129
158
 
130
- def record_duration(self, operation: str, duration: float, labels: Optional[Dict[str, str]] = None):
159
+ def record_duration(
160
+ self,
161
+ operation: str,
162
+ duration: float,
163
+ labels: Optional[Dict[str, str]] = None,
164
+ ):
131
165
  """Record operation duration for metrics tracking"""
132
166
  if not self.enable_metrics:
133
167
  return