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
@@ -0,0 +1,696 @@
1
+ """
2
+ Cache Provider Interface and Implementations
3
+
4
+ 提供统一的缓存接口,支持多种缓存策略和存储后端。
5
+ 所有缓存实现都应该实现 ICacheProvider 接口,以便与 ToolExecutor 和其他组件集成。
6
+
7
+ Architecture:
8
+ ICacheProvider (Interface)
9
+ ├── LRUCacheProvider (Default: wraps ExecutionUtils)
10
+ ├── DualLayerCacheProvider (L1: Memory + L2: Custom)
11
+ └── Custom implementations (e.g., IntelligentCacheProvider)
12
+
13
+ Usage:
14
+ # Use default LRU cache
15
+ from aiecs.utils.cache_provider import LRUCacheProvider
16
+ cache = LRUCacheProvider(execution_utils)
17
+
18
+ # Use dual-layer cache
19
+ from aiecs.utils.cache_provider import DualLayerCacheProvider
20
+ cache = DualLayerCacheProvider(l1_provider, l2_provider)
21
+ """
22
+
23
+ from abc import ABC, abstractmethod
24
+ from typing import Any, Dict, Optional
25
+ import logging
26
+ import threading
27
+
28
+ logger = logging.getLogger(__name__)
29
+
30
+
31
+ class ICacheProvider(ABC):
32
+ """
33
+ 缓存提供者接口
34
+
35
+ 所有缓存实现都应该实现这个接口,以便与 ToolExecutor 和其他组件集成。
36
+ 这个接口定义了缓存的核心操作:获取、设置、失效和统计。
37
+
38
+ 支持同步和异步两种接口:
39
+ - 同步接口 (get, set, invalidate): 用于向后兼容和简单场景
40
+ - 异步接口 (get_async, set_async, invalidate_async): 用于异步操作和高性能场景
41
+
42
+ Example:
43
+ class MyCacheProvider(ICacheProvider):
44
+ def get(self, key: str) -> Optional[Any]:
45
+ # 实现同步获取逻辑
46
+ pass
47
+
48
+ async def get_async(self, key: str) -> Optional[Any]:
49
+ # 实现异步获取逻辑
50
+ pass
51
+
52
+ def set(self, key: str, value: Any, ttl: Optional[int] = None):
53
+ # 实现同步设置逻辑
54
+ pass
55
+
56
+ async def set_async(self, key: str, value: Any, ttl: Optional[int] = None):
57
+ # 实现异步设置逻辑
58
+ pass
59
+ """
60
+
61
+ @abstractmethod
62
+ def get(self, key: str) -> Optional[Any]:
63
+ """
64
+ 获取缓存值(同步接口)
65
+
66
+ Args:
67
+ key: 缓存键
68
+
69
+ Returns:
70
+ 缓存的值,如果不存在或已过期则返回 None
71
+ """
72
+
73
+ @abstractmethod
74
+ def set(self, key: str, value: Any, ttl: Optional[int] = None):
75
+ """
76
+ 设置缓存值(同步接口)
77
+
78
+ Args:
79
+ key: 缓存键
80
+ value: 要缓存的值
81
+ ttl: 过期时间(秒),None 表示使用默认 TTL
82
+ """
83
+
84
+ @abstractmethod
85
+ def invalidate(self, key: str):
86
+ """
87
+ 使缓存失效(同步接口)
88
+
89
+ Args:
90
+ key: 缓存键
91
+ """
92
+
93
+ @abstractmethod
94
+ def get_stats(self) -> Dict[str, Any]:
95
+ """
96
+ 获取缓存统计信息
97
+
98
+ Returns:
99
+ 包含缓存统计的字典,至少应包含:
100
+ - type: 缓存类型
101
+ - hits: 命中次数(可选)
102
+ - misses: 未命中次数(可选)
103
+ - hit_rate: 命中率(可选)
104
+ """
105
+
106
+ def clear(self):
107
+ """
108
+ 清空所有缓存(可选实现)
109
+
110
+ 默认实现为空操作,子类可以根据需要覆盖。
111
+ """
112
+
113
+ # Async interface (optional, with default implementations)
114
+ async def get_async(self, key: str) -> Optional[Any]:
115
+ """
116
+ 获取缓存值(异步接口)
117
+
118
+ 默认实现调用同步方法。子类应该覆盖此方法以提供真正的异步实现。
119
+
120
+ Args:
121
+ key: 缓存键
122
+
123
+ Returns:
124
+ 缓存的值,如果不存在或已过期则返回 None
125
+ """
126
+ return self.get(key)
127
+
128
+ async def set_async(self, key: str, value: Any, ttl: Optional[int] = None):
129
+ """
130
+ 设置缓存值(异步接口)
131
+
132
+ 默认实现调用同步方法。子类应该覆盖此方法以提供真正的异步实现。
133
+
134
+ Args:
135
+ key: 缓存键
136
+ value: 要缓存的值
137
+ ttl: 过期时间(秒),None 表示使用默认 TTL
138
+ """
139
+ self.set(key, value, ttl)
140
+
141
+ async def invalidate_async(self, key: str):
142
+ """
143
+ 使缓存失效(异步接口)
144
+
145
+ 默认实现调用同步方法。子类应该覆盖此方法以提供真正的异步实现。
146
+
147
+ Args:
148
+ key: 缓存键
149
+ """
150
+ self.invalidate(key)
151
+
152
+
153
+ class LRUCacheProvider(ICacheProvider):
154
+ """
155
+ 基于 ExecutionUtils 的 LRU 缓存提供者
156
+
157
+ 这是默认的缓存实现,包装了现有的 ExecutionUtils 缓存逻辑。
158
+ 使用 LRU (Least Recently Used) 淘汰策略和 TTL 过期机制。
159
+
160
+ Features:
161
+ - LRU 淘汰策略
162
+ - TTL 过期机制
163
+ - 线程安全
164
+ - 内存缓存
165
+
166
+ Example:
167
+ from aiecs.utils.execution_utils import ExecutionUtils
168
+ from aiecs.utils.cache_provider import LRUCacheProvider
169
+
170
+ execution_utils = ExecutionUtils(cache_size=100, cache_ttl=3600)
171
+ cache = LRUCacheProvider(execution_utils)
172
+
173
+ # 使用缓存
174
+ cache.set("key1", "value1", ttl=300)
175
+ value = cache.get("key1")
176
+ """
177
+
178
+ def __init__(self, execution_utils):
179
+ """
180
+ 初始化 LRU 缓存提供者
181
+
182
+ Args:
183
+ execution_utils: ExecutionUtils 实例
184
+ """
185
+ self.execution_utils = execution_utils
186
+ self._hits = 0
187
+ self._misses = 0
188
+
189
+ def get(self, key: str) -> Optional[Any]:
190
+ """从 ExecutionUtils 缓存获取值"""
191
+ result = self.execution_utils.get_from_cache(key)
192
+ if result is not None:
193
+ self._hits += 1
194
+ logger.debug(f"Cache hit: {key}")
195
+ else:
196
+ self._misses += 1
197
+ logger.debug(f"Cache miss: {key}")
198
+ return result
199
+
200
+ def set(self, key: str, value: Any, ttl: Optional[int] = None):
201
+ """设置值到 ExecutionUtils 缓存"""
202
+ self.execution_utils.add_to_cache(key, value, ttl)
203
+ logger.debug(f"Cache set: {key} (ttl={ttl})")
204
+
205
+ def invalidate(self, key: str):
206
+ """
207
+ 使缓存失效
208
+
209
+ ExecutionUtils 没有直接的 invalidate 方法,
210
+ 通过直接删除缓存条目来实现。
211
+ """
212
+ if hasattr(self.execution_utils, "_cache") and self.execution_utils._cache:
213
+ with self.execution_utils._cache_lock:
214
+ if key in self.execution_utils._cache:
215
+ del self.execution_utils._cache[key]
216
+ logger.debug(f"Cache invalidated: {key}")
217
+ if key in self.execution_utils._cache_ttl_dict:
218
+ del self.execution_utils._cache_ttl_dict[key]
219
+
220
+ def get_stats(self) -> Dict[str, Any]:
221
+ """获取缓存统计"""
222
+ cache_size = 0
223
+ if hasattr(self.execution_utils, "_cache") and self.execution_utils._cache:
224
+ cache_size = len(self.execution_utils._cache)
225
+
226
+ total_requests = self._hits + self._misses
227
+ hit_rate = self._hits / total_requests if total_requests > 0 else 0.0
228
+
229
+ return {
230
+ "type": "lru",
231
+ "backend": "memory",
232
+ "size": cache_size,
233
+ "max_size": self.execution_utils.cache_size,
234
+ "hits": self._hits,
235
+ "misses": self._misses,
236
+ "hit_rate": hit_rate,
237
+ }
238
+
239
+ def clear(self):
240
+ """清空所有缓存"""
241
+ if hasattr(self.execution_utils, "_cache") and self.execution_utils._cache:
242
+ with self.execution_utils._cache_lock:
243
+ self.execution_utils._cache.clear()
244
+ self.execution_utils._cache_ttl_dict.clear()
245
+ logger.info("LRU cache cleared")
246
+
247
+
248
+ class DualLayerCacheProvider(ICacheProvider):
249
+ """
250
+ 双层缓存提供者
251
+
252
+ 实现两层缓存架构:
253
+ - L1: 快速内存缓存(通常是 LRUCacheProvider)
254
+ - L2: 智能缓存(如 Redis + Intent-aware TTL)
255
+
256
+ 缓存策略:
257
+ 1. 读取时先查 L1,命中则直接返回
258
+ 2. L1 未命中则查 L2,命中则回填 L1
259
+ 3. 写入时同时写入 L1 和 L2
260
+
261
+ 这是为 SearchTool 等需要高级缓存策略的工具设计的。
262
+
263
+ Example:
264
+ from aiecs.utils.cache_provider import DualLayerCacheProvider, LRUCacheProvider
265
+
266
+ l1_cache = LRUCacheProvider(execution_utils)
267
+ l2_cache = IntelligentCacheProvider(redis_client)
268
+
269
+ dual_cache = DualLayerCacheProvider(
270
+ l1_provider=l1_cache,
271
+ l2_provider=l2_cache,
272
+ l1_ttl=300 # L1 缓存 5 分钟
273
+ )
274
+
275
+ # 使用双层缓存
276
+ dual_cache.set("key1", "value1") # 写入 L1 和 L2
277
+ value = dual_cache.get("key1") # 先查 L1,再查 L2
278
+ """
279
+
280
+ def __init__(
281
+ self,
282
+ l1_provider: ICacheProvider,
283
+ l2_provider: ICacheProvider,
284
+ l1_ttl: int = 300,
285
+ ):
286
+ """
287
+ 初始化双层缓存
288
+
289
+ Args:
290
+ l1_provider: L1 缓存提供者(通常是 LRUCacheProvider)
291
+ l2_provider: L2 缓存提供者(如 IntelligentCacheProvider)
292
+ l1_ttl: L1 缓存的 TTL(秒),默认 5 分钟
293
+ """
294
+ self.l1 = l1_provider
295
+ self.l2 = l2_provider
296
+ self.l1_ttl = l1_ttl
297
+ self._l1_hits = 0
298
+ self._l2_hits = 0
299
+ self._misses = 0
300
+
301
+ def get(self, key: str) -> Optional[Any]:
302
+ """
303
+ 双层缓存获取
304
+
305
+ 1. 先查 L1 缓存
306
+ 2. L1 未命中则查 L2 缓存
307
+ 3. L2 命中则回填 L1
308
+ """
309
+ # 尝试 L1
310
+ result = self.l1.get(key)
311
+ if result is not None:
312
+ self._l1_hits += 1
313
+ logger.debug(f"L1 cache hit: {key}")
314
+ return result
315
+
316
+ # 尝试 L2
317
+ result = self.l2.get(key)
318
+ if result is not None:
319
+ self._l2_hits += 1
320
+ logger.debug(f"L2 cache hit: {key}, warming L1")
321
+ # 回填 L1(使用较短的 TTL)
322
+ self.l1.set(key, result, ttl=self.l1_ttl)
323
+ return result
324
+
325
+ self._misses += 1
326
+ logger.debug(f"Cache miss (L1 + L2): {key}")
327
+ return None
328
+
329
+ def set(self, key: str, value: Any, ttl: Optional[int] = None):
330
+ """
331
+ 双层缓存设置
332
+
333
+ 同时写入 L1 和 L2:
334
+ - L2 使用传入的 TTL(可能是智能计算的)
335
+ - L1 使用固定的短 TTL
336
+ """
337
+ # 写入 L2(使用智能 TTL)
338
+ self.l2.set(key, value, ttl)
339
+ logger.debug(f"L2 cache set: {key} (ttl={ttl})")
340
+
341
+ # 写入 L1(使用短 TTL)
342
+ self.l1.set(key, value, ttl=self.l1_ttl)
343
+ logger.debug(f"L1 cache set: {key} (ttl={self.l1_ttl})")
344
+
345
+ def invalidate(self, key: str):
346
+ """使两层缓存都失效"""
347
+ self.l1.invalidate(key)
348
+ self.l2.invalidate(key)
349
+ logger.debug(f"Cache invalidated (L1 + L2): {key}")
350
+
351
+ def get_stats(self) -> Dict[str, Any]:
352
+ """获取双层缓存统计"""
353
+ l1_stats = self.l1.get_stats()
354
+ l2_stats = self.l2.get_stats()
355
+
356
+ total_hits = self._l1_hits + self._l2_hits
357
+ total_requests = total_hits + self._misses
358
+
359
+ return {
360
+ "type": "dual_layer",
361
+ "l1": l1_stats,
362
+ "l2": l2_stats,
363
+ "l1_hits": self._l1_hits,
364
+ "l2_hits": self._l2_hits,
365
+ "misses": self._misses,
366
+ "total_requests": total_requests,
367
+ "hit_rate": (total_hits / total_requests if total_requests > 0 else 0.0),
368
+ "l1_hit_rate": (self._l1_hits / total_requests if total_requests > 0 else 0.0),
369
+ "l2_hit_rate": (self._l2_hits / total_requests if total_requests > 0 else 0.0),
370
+ }
371
+
372
+ def clear(self):
373
+ """清空两层缓存"""
374
+ self.l1.clear()
375
+ self.l2.clear()
376
+ logger.info("Dual-layer cache cleared")
377
+
378
+ # Async interface
379
+ async def get_async(self, key: str) -> Optional[Any]:
380
+ """
381
+ 双层缓存异步获取
382
+
383
+ 1. 先查 L1 缓存(同步)
384
+ 2. L1 未命中则查 L2 缓存(异步)
385
+ 3. L2 命中则回填 L1
386
+ """
387
+ # 尝试 L1 (同步)
388
+ result = self.l1.get(key)
389
+ if result is not None:
390
+ self._l1_hits += 1
391
+ logger.debug(f"L1 cache hit (async): {key}")
392
+ return result
393
+
394
+ # 尝试 L2 (异步)
395
+ result = await self.l2.get_async(key)
396
+ if result is not None:
397
+ self._l2_hits += 1
398
+ logger.debug(f"L2 cache hit (async): {key}, warming L1")
399
+ # 回填 L1(使用较短的 TTL)
400
+ self.l1.set(key, result, ttl=self.l1_ttl)
401
+ return result
402
+
403
+ self._misses += 1
404
+ logger.debug(f"Cache miss (L1 + L2, async): {key}")
405
+ return None
406
+
407
+ async def set_async(self, key: str, value: Any, ttl: Optional[int] = None):
408
+ """
409
+ 双层缓存异步设置
410
+
411
+ 同时写入 L1 和 L2:
412
+ - L2 使用传入的 TTL(可能是智能计算的)- 异步写入
413
+ - L1 使用固定的短 TTL - 同步写入
414
+ """
415
+ # 写入 L2(异步,使用智能 TTL)
416
+ await self.l2.set_async(key, value, ttl)
417
+ logger.debug(f"L2 cache set (async): {key} (ttl={ttl})")
418
+
419
+ # 写入 L1(同步,使用短 TTL)
420
+ self.l1.set(key, value, ttl=self.l1_ttl)
421
+ logger.debug(f"L1 cache set (async): {key} (ttl={self.l1_ttl})")
422
+
423
+ async def invalidate_async(self, key: str):
424
+ """使两层缓存都失效(异步)"""
425
+ self.l1.invalidate(key)
426
+ await self.l2.invalidate_async(key)
427
+ logger.debug(f"Cache invalidated (L1 + L2, async): {key}")
428
+
429
+ async def clear_async(self):
430
+ """异步清空两层缓存"""
431
+ self.l1.clear()
432
+ if hasattr(self.l2, "clear_async"):
433
+ await self.l2.clear_async()
434
+ else:
435
+ self.l2.clear()
436
+ logger.info("Dual-layer cache cleared (async)")
437
+
438
+
439
+ class RedisCacheProvider(ICacheProvider):
440
+ """
441
+ 基于全局 Redis 的缓存提供者
442
+
443
+ 使用全局 RedisClient 单例,避免重复创建连接池。
444
+ 适用于需要持久化缓存或分布式缓存共享的场景。
445
+
446
+ Features:
447
+ - 使用全局 Redis 单例
448
+ - 持久化缓存
449
+ - 分布式共享
450
+ - 支持 TTL
451
+
452
+ Example:
453
+ from aiecs.utils.cache_provider import RedisCacheProvider
454
+
455
+ # 使用全局 Redis 客户端
456
+ cache = await RedisCacheProvider.create(
457
+ prefix="my_app:",
458
+ default_ttl=3600
459
+ )
460
+
461
+ # 使用缓存
462
+ await cache.set_async("key1", "value1", ttl=300)
463
+ value = await cache.get_async("key1")
464
+
465
+ Note:
466
+ - 需要先调用 initialize_redis_client() 初始化全局 Redis
467
+ - 提供同步接口(使用内存回退)和异步接口(使用 Redis)
468
+ """
469
+
470
+ _instance: Optional["RedisCacheProvider"] = None
471
+ _lock = threading.Lock()
472
+
473
+ def __init__(self, redis_client, prefix: str = "", default_ttl: int = 3600):
474
+ """
475
+ 初始化 Redis 缓存提供者
476
+
477
+ Args:
478
+ redis_client: RedisClient 实例
479
+ prefix: 缓存键前缀
480
+ default_ttl: 默认 TTL(秒)
481
+ """
482
+ self.redis_client = redis_client
483
+ self.prefix = prefix
484
+ self.default_ttl = default_ttl
485
+ self._sync_cache: Dict[str, Any] = {} # 同步接口的内存回退
486
+ self._hits = 0
487
+ self._misses = 0
488
+
489
+ @classmethod
490
+ async def create(
491
+ cls,
492
+ prefix: str = "",
493
+ default_ttl: int = 3600,
494
+ use_singleton: bool = True,
495
+ ) -> "RedisCacheProvider":
496
+ """
497
+ 创建 RedisCacheProvider 实例
498
+
499
+ Args:
500
+ prefix: 缓存键前缀
501
+ default_ttl: 默认 TTL(秒)
502
+ use_singleton: 是否使用单例模式
503
+
504
+ Returns:
505
+ RedisCacheProvider 实例
506
+
507
+ Raises:
508
+ RuntimeError: 如果全局 Redis 客户端未初始化
509
+ """
510
+ if use_singleton and cls._instance is not None:
511
+ return cls._instance
512
+
513
+ try:
514
+ # get_redis_client may not be available in all installations
515
+ from aiecs.infrastructure.persistence import get_redis_client # type: ignore[attr-defined]
516
+
517
+ redis_client = await get_redis_client()
518
+
519
+ instance = cls(redis_client, prefix, default_ttl)
520
+
521
+ if use_singleton:
522
+ with cls._lock:
523
+ cls._instance = instance
524
+
525
+ logger.info(f"RedisCacheProvider created (prefix={prefix}, ttl={default_ttl})")
526
+ return instance
527
+
528
+ except Exception as e:
529
+ logger.error(f"Failed to create RedisCacheProvider: {e}")
530
+ raise
531
+
532
+ def _make_key(self, key: str) -> str:
533
+ """生成带前缀的缓存键"""
534
+ return f"{self.prefix}{key}"
535
+
536
+ # 同步接口(ICacheProvider 要求)
537
+ def get(self, key: str) -> Optional[Any]:
538
+ """
539
+ 同步获取(使用内存回退)
540
+
541
+ Note: 对于 Redis 操作,建议使用 get_async()
542
+ """
543
+ result = self._sync_cache.get(key)
544
+ if result is not None:
545
+ self._hits += 1
546
+ else:
547
+ self._misses += 1
548
+ return result
549
+
550
+ def set(self, key: str, value: Any, ttl: Optional[int] = None):
551
+ """
552
+ 同步设置(使用内存回退)
553
+
554
+ Note: 对于 Redis 操作,建议使用 set_async()
555
+ """
556
+ self._sync_cache[key] = value
557
+
558
+ def invalidate(self, key: str):
559
+ """同步失效(使用内存回退)"""
560
+ if key in self._sync_cache:
561
+ del self._sync_cache[key]
562
+
563
+ # 异步接口(推荐使用)
564
+ async def get_async(self, key: str) -> Optional[Any]:
565
+ """
566
+ 异步获取缓存值
567
+
568
+ Args:
569
+ key: 缓存键
570
+
571
+ Returns:
572
+ 缓存的值,如果不存在或已过期则返回 None
573
+ """
574
+ try:
575
+ redis = await self.redis_client.get_client()
576
+ full_key = self._make_key(key)
577
+
578
+ value = await redis.get(full_key)
579
+ if value is not None:
580
+ self._hits += 1
581
+ logger.debug(f"Redis cache hit: {key}")
582
+ # 尝试反序列化 JSON
583
+ try:
584
+ import json
585
+
586
+ return json.loads(value)
587
+ except (json.JSONDecodeError, TypeError):
588
+ return value
589
+ else:
590
+ self._misses += 1
591
+ logger.debug(f"Redis cache miss: {key}")
592
+ return None
593
+
594
+ except Exception as e:
595
+ logger.warning(f"Redis get error for key {key}: {e}")
596
+ self._misses += 1
597
+ return None
598
+
599
+ async def set_async(self, key: str, value: Any, ttl: Optional[int] = None):
600
+ """
601
+ 异步设置缓存值
602
+
603
+ Args:
604
+ key: 缓存键
605
+ value: 要缓存的值
606
+ ttl: 过期时间(秒),None 表示使用默认 TTL
607
+ """
608
+ try:
609
+ redis = await self.redis_client.get_client()
610
+ full_key = self._make_key(key)
611
+ ttl = ttl if ttl is not None else self.default_ttl
612
+
613
+ # 序列化为 JSON
614
+ import json
615
+
616
+ try:
617
+ serialized_value = json.dumps(value)
618
+ except (TypeError, ValueError):
619
+ serialized_value = str(value)
620
+
621
+ if ttl > 0:
622
+ await redis.setex(full_key, ttl, serialized_value)
623
+ else:
624
+ await redis.set(full_key, serialized_value)
625
+
626
+ logger.debug(f"Redis cache set: {key} (ttl={ttl})")
627
+
628
+ except Exception as e:
629
+ logger.warning(f"Redis set error for key {key}: {e}")
630
+
631
+ async def invalidate_async(self, key: str):
632
+ """
633
+ 异步使缓存失效
634
+
635
+ Args:
636
+ key: 缓存键
637
+ """
638
+ try:
639
+ redis = await self.redis_client.get_client()
640
+ full_key = self._make_key(key)
641
+ await redis.delete(full_key)
642
+ logger.debug(f"Redis cache invalidated: {key}")
643
+
644
+ except Exception as e:
645
+ logger.warning(f"Redis invalidate error for key {key}: {e}")
646
+
647
+ def get_stats(self) -> Dict[str, Any]:
648
+ """获取缓存统计"""
649
+ total_requests = self._hits + self._misses
650
+ hit_rate = self._hits / total_requests if total_requests > 0 else 0.0
651
+
652
+ return {
653
+ "type": "redis",
654
+ "backend": "redis",
655
+ "prefix": self.prefix,
656
+ "default_ttl": self.default_ttl,
657
+ "hits": self._hits,
658
+ "misses": self._misses,
659
+ "hit_rate": hit_rate,
660
+ "sync_cache_size": len(self._sync_cache),
661
+ }
662
+
663
+ def clear(self):
664
+ """清空同步缓存(Redis 缓存需要使用 clear_async)"""
665
+ self._sync_cache.clear()
666
+
667
+ async def clear_async(self, pattern: Optional[str] = None):
668
+ """
669
+ 异步清空缓存
670
+
671
+ Args:
672
+ pattern: 键模式,None 表示清空所有带前缀的键
673
+ """
674
+ try:
675
+ redis = await self.redis_client.get_client()
676
+ pattern = pattern or f"{self.prefix}*"
677
+
678
+ keys_to_delete = []
679
+ async for key in redis.scan_iter(match=pattern):
680
+ keys_to_delete.append(key)
681
+
682
+ if keys_to_delete:
683
+ await redis.delete(*keys_to_delete)
684
+ logger.info(f"Redis cache cleared: {len(keys_to_delete)} keys deleted")
685
+
686
+ except Exception as e:
687
+ logger.warning(f"Redis clear error: {e}")
688
+
689
+
690
+ # 导出接口和实现
691
+ __all__ = [
692
+ "ICacheProvider",
693
+ "LRUCacheProvider",
694
+ "DualLayerCacheProvider",
695
+ "RedisCacheProvider",
696
+ ]