aiecs 1.5.1__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.
Files changed (302) hide show
  1. aiecs/__init__.py +72 -0
  2. aiecs/__main__.py +41 -0
  3. aiecs/aiecs_client.py +469 -0
  4. aiecs/application/__init__.py +10 -0
  5. aiecs/application/executors/__init__.py +10 -0
  6. aiecs/application/executors/operation_executor.py +363 -0
  7. aiecs/application/knowledge_graph/__init__.py +7 -0
  8. aiecs/application/knowledge_graph/builder/__init__.py +37 -0
  9. aiecs/application/knowledge_graph/builder/document_builder.py +375 -0
  10. aiecs/application/knowledge_graph/builder/graph_builder.py +356 -0
  11. aiecs/application/knowledge_graph/builder/schema_mapping.py +531 -0
  12. aiecs/application/knowledge_graph/builder/structured_pipeline.py +443 -0
  13. aiecs/application/knowledge_graph/builder/text_chunker.py +319 -0
  14. aiecs/application/knowledge_graph/extractors/__init__.py +27 -0
  15. aiecs/application/knowledge_graph/extractors/base.py +100 -0
  16. aiecs/application/knowledge_graph/extractors/llm_entity_extractor.py +327 -0
  17. aiecs/application/knowledge_graph/extractors/llm_relation_extractor.py +349 -0
  18. aiecs/application/knowledge_graph/extractors/ner_entity_extractor.py +244 -0
  19. aiecs/application/knowledge_graph/fusion/__init__.py +23 -0
  20. aiecs/application/knowledge_graph/fusion/entity_deduplicator.py +387 -0
  21. aiecs/application/knowledge_graph/fusion/entity_linker.py +343 -0
  22. aiecs/application/knowledge_graph/fusion/knowledge_fusion.py +580 -0
  23. aiecs/application/knowledge_graph/fusion/relation_deduplicator.py +189 -0
  24. aiecs/application/knowledge_graph/pattern_matching/__init__.py +21 -0
  25. aiecs/application/knowledge_graph/pattern_matching/pattern_matcher.py +344 -0
  26. aiecs/application/knowledge_graph/pattern_matching/query_executor.py +378 -0
  27. aiecs/application/knowledge_graph/profiling/__init__.py +12 -0
  28. aiecs/application/knowledge_graph/profiling/query_plan_visualizer.py +199 -0
  29. aiecs/application/knowledge_graph/profiling/query_profiler.py +223 -0
  30. aiecs/application/knowledge_graph/reasoning/__init__.py +27 -0
  31. aiecs/application/knowledge_graph/reasoning/evidence_synthesis.py +347 -0
  32. aiecs/application/knowledge_graph/reasoning/inference_engine.py +504 -0
  33. aiecs/application/knowledge_graph/reasoning/logic_form_parser.py +167 -0
  34. aiecs/application/knowledge_graph/reasoning/logic_parser/__init__.py +79 -0
  35. aiecs/application/knowledge_graph/reasoning/logic_parser/ast_builder.py +513 -0
  36. aiecs/application/knowledge_graph/reasoning/logic_parser/ast_nodes.py +630 -0
  37. aiecs/application/knowledge_graph/reasoning/logic_parser/ast_validator.py +654 -0
  38. aiecs/application/knowledge_graph/reasoning/logic_parser/error_handler.py +477 -0
  39. aiecs/application/knowledge_graph/reasoning/logic_parser/parser.py +390 -0
  40. aiecs/application/knowledge_graph/reasoning/logic_parser/query_context.py +217 -0
  41. aiecs/application/knowledge_graph/reasoning/logic_query_integration.py +169 -0
  42. aiecs/application/knowledge_graph/reasoning/query_planner.py +872 -0
  43. aiecs/application/knowledge_graph/reasoning/reasoning_engine.py +554 -0
  44. aiecs/application/knowledge_graph/retrieval/__init__.py +19 -0
  45. aiecs/application/knowledge_graph/retrieval/retrieval_strategies.py +596 -0
  46. aiecs/application/knowledge_graph/search/__init__.py +59 -0
  47. aiecs/application/knowledge_graph/search/hybrid_search.py +423 -0
  48. aiecs/application/knowledge_graph/search/reranker.py +295 -0
  49. aiecs/application/knowledge_graph/search/reranker_strategies.py +553 -0
  50. aiecs/application/knowledge_graph/search/text_similarity.py +398 -0
  51. aiecs/application/knowledge_graph/traversal/__init__.py +15 -0
  52. aiecs/application/knowledge_graph/traversal/enhanced_traversal.py +329 -0
  53. aiecs/application/knowledge_graph/traversal/path_scorer.py +269 -0
  54. aiecs/application/knowledge_graph/validators/__init__.py +13 -0
  55. aiecs/application/knowledge_graph/validators/relation_validator.py +189 -0
  56. aiecs/application/knowledge_graph/visualization/__init__.py +11 -0
  57. aiecs/application/knowledge_graph/visualization/graph_visualizer.py +321 -0
  58. aiecs/common/__init__.py +9 -0
  59. aiecs/common/knowledge_graph/__init__.py +17 -0
  60. aiecs/common/knowledge_graph/runnable.py +484 -0
  61. aiecs/config/__init__.py +16 -0
  62. aiecs/config/config.py +498 -0
  63. aiecs/config/graph_config.py +137 -0
  64. aiecs/config/registry.py +23 -0
  65. aiecs/core/__init__.py +46 -0
  66. aiecs/core/interface/__init__.py +34 -0
  67. aiecs/core/interface/execution_interface.py +152 -0
  68. aiecs/core/interface/storage_interface.py +171 -0
  69. aiecs/domain/__init__.py +289 -0
  70. aiecs/domain/agent/__init__.py +189 -0
  71. aiecs/domain/agent/base_agent.py +697 -0
  72. aiecs/domain/agent/exceptions.py +103 -0
  73. aiecs/domain/agent/graph_aware_mixin.py +559 -0
  74. aiecs/domain/agent/hybrid_agent.py +490 -0
  75. aiecs/domain/agent/integration/__init__.py +26 -0
  76. aiecs/domain/agent/integration/context_compressor.py +222 -0
  77. aiecs/domain/agent/integration/context_engine_adapter.py +252 -0
  78. aiecs/domain/agent/integration/retry_policy.py +219 -0
  79. aiecs/domain/agent/integration/role_config.py +213 -0
  80. aiecs/domain/agent/knowledge_aware_agent.py +646 -0
  81. aiecs/domain/agent/lifecycle.py +296 -0
  82. aiecs/domain/agent/llm_agent.py +300 -0
  83. aiecs/domain/agent/memory/__init__.py +12 -0
  84. aiecs/domain/agent/memory/conversation.py +197 -0
  85. aiecs/domain/agent/migration/__init__.py +14 -0
  86. aiecs/domain/agent/migration/conversion.py +160 -0
  87. aiecs/domain/agent/migration/legacy_wrapper.py +90 -0
  88. aiecs/domain/agent/models.py +317 -0
  89. aiecs/domain/agent/observability.py +407 -0
  90. aiecs/domain/agent/persistence.py +289 -0
  91. aiecs/domain/agent/prompts/__init__.py +29 -0
  92. aiecs/domain/agent/prompts/builder.py +161 -0
  93. aiecs/domain/agent/prompts/formatters.py +189 -0
  94. aiecs/domain/agent/prompts/template.py +255 -0
  95. aiecs/domain/agent/registry.py +260 -0
  96. aiecs/domain/agent/tool_agent.py +257 -0
  97. aiecs/domain/agent/tools/__init__.py +12 -0
  98. aiecs/domain/agent/tools/schema_generator.py +221 -0
  99. aiecs/domain/community/__init__.py +155 -0
  100. aiecs/domain/community/agent_adapter.py +477 -0
  101. aiecs/domain/community/analytics.py +481 -0
  102. aiecs/domain/community/collaborative_workflow.py +642 -0
  103. aiecs/domain/community/communication_hub.py +645 -0
  104. aiecs/domain/community/community_builder.py +320 -0
  105. aiecs/domain/community/community_integration.py +800 -0
  106. aiecs/domain/community/community_manager.py +813 -0
  107. aiecs/domain/community/decision_engine.py +879 -0
  108. aiecs/domain/community/exceptions.py +225 -0
  109. aiecs/domain/community/models/__init__.py +33 -0
  110. aiecs/domain/community/models/community_models.py +268 -0
  111. aiecs/domain/community/resource_manager.py +457 -0
  112. aiecs/domain/community/shared_context_manager.py +603 -0
  113. aiecs/domain/context/__init__.py +58 -0
  114. aiecs/domain/context/context_engine.py +989 -0
  115. aiecs/domain/context/conversation_models.py +354 -0
  116. aiecs/domain/context/graph_memory.py +467 -0
  117. aiecs/domain/execution/__init__.py +12 -0
  118. aiecs/domain/execution/model.py +57 -0
  119. aiecs/domain/knowledge_graph/__init__.py +19 -0
  120. aiecs/domain/knowledge_graph/models/__init__.py +52 -0
  121. aiecs/domain/knowledge_graph/models/entity.py +130 -0
  122. aiecs/domain/knowledge_graph/models/evidence.py +194 -0
  123. aiecs/domain/knowledge_graph/models/inference_rule.py +186 -0
  124. aiecs/domain/knowledge_graph/models/path.py +179 -0
  125. aiecs/domain/knowledge_graph/models/path_pattern.py +173 -0
  126. aiecs/domain/knowledge_graph/models/query.py +272 -0
  127. aiecs/domain/knowledge_graph/models/query_plan.py +187 -0
  128. aiecs/domain/knowledge_graph/models/relation.py +136 -0
  129. aiecs/domain/knowledge_graph/schema/__init__.py +23 -0
  130. aiecs/domain/knowledge_graph/schema/entity_type.py +135 -0
  131. aiecs/domain/knowledge_graph/schema/graph_schema.py +271 -0
  132. aiecs/domain/knowledge_graph/schema/property_schema.py +155 -0
  133. aiecs/domain/knowledge_graph/schema/relation_type.py +171 -0
  134. aiecs/domain/knowledge_graph/schema/schema_manager.py +496 -0
  135. aiecs/domain/knowledge_graph/schema/type_enums.py +205 -0
  136. aiecs/domain/task/__init__.py +13 -0
  137. aiecs/domain/task/dsl_processor.py +613 -0
  138. aiecs/domain/task/model.py +62 -0
  139. aiecs/domain/task/task_context.py +268 -0
  140. aiecs/infrastructure/__init__.py +24 -0
  141. aiecs/infrastructure/graph_storage/__init__.py +11 -0
  142. aiecs/infrastructure/graph_storage/base.py +601 -0
  143. aiecs/infrastructure/graph_storage/batch_operations.py +449 -0
  144. aiecs/infrastructure/graph_storage/cache.py +429 -0
  145. aiecs/infrastructure/graph_storage/distributed.py +226 -0
  146. aiecs/infrastructure/graph_storage/error_handling.py +390 -0
  147. aiecs/infrastructure/graph_storage/graceful_degradation.py +306 -0
  148. aiecs/infrastructure/graph_storage/health_checks.py +378 -0
  149. aiecs/infrastructure/graph_storage/in_memory.py +514 -0
  150. aiecs/infrastructure/graph_storage/index_optimization.py +483 -0
  151. aiecs/infrastructure/graph_storage/lazy_loading.py +410 -0
  152. aiecs/infrastructure/graph_storage/metrics.py +357 -0
  153. aiecs/infrastructure/graph_storage/migration.py +413 -0
  154. aiecs/infrastructure/graph_storage/pagination.py +471 -0
  155. aiecs/infrastructure/graph_storage/performance_monitoring.py +466 -0
  156. aiecs/infrastructure/graph_storage/postgres.py +871 -0
  157. aiecs/infrastructure/graph_storage/query_optimizer.py +635 -0
  158. aiecs/infrastructure/graph_storage/schema_cache.py +290 -0
  159. aiecs/infrastructure/graph_storage/sqlite.py +623 -0
  160. aiecs/infrastructure/graph_storage/streaming.py +495 -0
  161. aiecs/infrastructure/messaging/__init__.py +13 -0
  162. aiecs/infrastructure/messaging/celery_task_manager.py +383 -0
  163. aiecs/infrastructure/messaging/websocket_manager.py +298 -0
  164. aiecs/infrastructure/monitoring/__init__.py +34 -0
  165. aiecs/infrastructure/monitoring/executor_metrics.py +174 -0
  166. aiecs/infrastructure/monitoring/global_metrics_manager.py +213 -0
  167. aiecs/infrastructure/monitoring/structured_logger.py +48 -0
  168. aiecs/infrastructure/monitoring/tracing_manager.py +410 -0
  169. aiecs/infrastructure/persistence/__init__.py +24 -0
  170. aiecs/infrastructure/persistence/context_engine_client.py +187 -0
  171. aiecs/infrastructure/persistence/database_manager.py +333 -0
  172. aiecs/infrastructure/persistence/file_storage.py +754 -0
  173. aiecs/infrastructure/persistence/redis_client.py +220 -0
  174. aiecs/llm/__init__.py +86 -0
  175. aiecs/llm/callbacks/__init__.py +11 -0
  176. aiecs/llm/callbacks/custom_callbacks.py +264 -0
  177. aiecs/llm/client_factory.py +420 -0
  178. aiecs/llm/clients/__init__.py +33 -0
  179. aiecs/llm/clients/base_client.py +193 -0
  180. aiecs/llm/clients/googleai_client.py +181 -0
  181. aiecs/llm/clients/openai_client.py +131 -0
  182. aiecs/llm/clients/vertex_client.py +437 -0
  183. aiecs/llm/clients/xai_client.py +184 -0
  184. aiecs/llm/config/__init__.py +51 -0
  185. aiecs/llm/config/config_loader.py +275 -0
  186. aiecs/llm/config/config_validator.py +236 -0
  187. aiecs/llm/config/model_config.py +151 -0
  188. aiecs/llm/utils/__init__.py +10 -0
  189. aiecs/llm/utils/validate_config.py +91 -0
  190. aiecs/main.py +363 -0
  191. aiecs/scripts/__init__.py +3 -0
  192. aiecs/scripts/aid/VERSION_MANAGEMENT.md +97 -0
  193. aiecs/scripts/aid/__init__.py +19 -0
  194. aiecs/scripts/aid/version_manager.py +215 -0
  195. aiecs/scripts/dependance_check/DEPENDENCY_SYSTEM_SUMMARY.md +242 -0
  196. aiecs/scripts/dependance_check/README_DEPENDENCY_CHECKER.md +310 -0
  197. aiecs/scripts/dependance_check/__init__.py +17 -0
  198. aiecs/scripts/dependance_check/dependency_checker.py +938 -0
  199. aiecs/scripts/dependance_check/dependency_fixer.py +391 -0
  200. aiecs/scripts/dependance_check/download_nlp_data.py +396 -0
  201. aiecs/scripts/dependance_check/quick_dependency_check.py +270 -0
  202. aiecs/scripts/dependance_check/setup_nlp_data.sh +217 -0
  203. aiecs/scripts/dependance_patch/__init__.py +7 -0
  204. aiecs/scripts/dependance_patch/fix_weasel/README_WEASEL_PATCH.md +126 -0
  205. aiecs/scripts/dependance_patch/fix_weasel/__init__.py +11 -0
  206. aiecs/scripts/dependance_patch/fix_weasel/fix_weasel_validator.py +128 -0
  207. aiecs/scripts/dependance_patch/fix_weasel/fix_weasel_validator.sh +82 -0
  208. aiecs/scripts/dependance_patch/fix_weasel/patch_weasel_library.sh +188 -0
  209. aiecs/scripts/dependance_patch/fix_weasel/run_weasel_patch.sh +41 -0
  210. aiecs/scripts/tools_develop/README.md +449 -0
  211. aiecs/scripts/tools_develop/TOOL_AUTO_DISCOVERY.md +234 -0
  212. aiecs/scripts/tools_develop/__init__.py +21 -0
  213. aiecs/scripts/tools_develop/check_type_annotations.py +259 -0
  214. aiecs/scripts/tools_develop/validate_tool_schemas.py +422 -0
  215. aiecs/scripts/tools_develop/verify_tools.py +356 -0
  216. aiecs/tasks/__init__.py +1 -0
  217. aiecs/tasks/worker.py +172 -0
  218. aiecs/tools/__init__.py +299 -0
  219. aiecs/tools/apisource/__init__.py +99 -0
  220. aiecs/tools/apisource/intelligence/__init__.py +19 -0
  221. aiecs/tools/apisource/intelligence/data_fusion.py +381 -0
  222. aiecs/tools/apisource/intelligence/query_analyzer.py +413 -0
  223. aiecs/tools/apisource/intelligence/search_enhancer.py +388 -0
  224. aiecs/tools/apisource/monitoring/__init__.py +9 -0
  225. aiecs/tools/apisource/monitoring/metrics.py +303 -0
  226. aiecs/tools/apisource/providers/__init__.py +115 -0
  227. aiecs/tools/apisource/providers/base.py +664 -0
  228. aiecs/tools/apisource/providers/census.py +401 -0
  229. aiecs/tools/apisource/providers/fred.py +564 -0
  230. aiecs/tools/apisource/providers/newsapi.py +412 -0
  231. aiecs/tools/apisource/providers/worldbank.py +357 -0
  232. aiecs/tools/apisource/reliability/__init__.py +12 -0
  233. aiecs/tools/apisource/reliability/error_handler.py +375 -0
  234. aiecs/tools/apisource/reliability/fallback_strategy.py +391 -0
  235. aiecs/tools/apisource/tool.py +850 -0
  236. aiecs/tools/apisource/utils/__init__.py +9 -0
  237. aiecs/tools/apisource/utils/validators.py +338 -0
  238. aiecs/tools/base_tool.py +201 -0
  239. aiecs/tools/docs/__init__.py +121 -0
  240. aiecs/tools/docs/ai_document_orchestrator.py +599 -0
  241. aiecs/tools/docs/ai_document_writer_orchestrator.py +2403 -0
  242. aiecs/tools/docs/content_insertion_tool.py +1333 -0
  243. aiecs/tools/docs/document_creator_tool.py +1317 -0
  244. aiecs/tools/docs/document_layout_tool.py +1166 -0
  245. aiecs/tools/docs/document_parser_tool.py +994 -0
  246. aiecs/tools/docs/document_writer_tool.py +1818 -0
  247. aiecs/tools/knowledge_graph/__init__.py +17 -0
  248. aiecs/tools/knowledge_graph/graph_reasoning_tool.py +734 -0
  249. aiecs/tools/knowledge_graph/graph_search_tool.py +923 -0
  250. aiecs/tools/knowledge_graph/kg_builder_tool.py +476 -0
  251. aiecs/tools/langchain_adapter.py +542 -0
  252. aiecs/tools/schema_generator.py +275 -0
  253. aiecs/tools/search_tool/__init__.py +100 -0
  254. aiecs/tools/search_tool/analyzers.py +589 -0
  255. aiecs/tools/search_tool/cache.py +260 -0
  256. aiecs/tools/search_tool/constants.py +128 -0
  257. aiecs/tools/search_tool/context.py +216 -0
  258. aiecs/tools/search_tool/core.py +749 -0
  259. aiecs/tools/search_tool/deduplicator.py +123 -0
  260. aiecs/tools/search_tool/error_handler.py +271 -0
  261. aiecs/tools/search_tool/metrics.py +371 -0
  262. aiecs/tools/search_tool/rate_limiter.py +178 -0
  263. aiecs/tools/search_tool/schemas.py +277 -0
  264. aiecs/tools/statistics/__init__.py +80 -0
  265. aiecs/tools/statistics/ai_data_analysis_orchestrator.py +643 -0
  266. aiecs/tools/statistics/ai_insight_generator_tool.py +505 -0
  267. aiecs/tools/statistics/ai_report_orchestrator_tool.py +694 -0
  268. aiecs/tools/statistics/data_loader_tool.py +564 -0
  269. aiecs/tools/statistics/data_profiler_tool.py +658 -0
  270. aiecs/tools/statistics/data_transformer_tool.py +573 -0
  271. aiecs/tools/statistics/data_visualizer_tool.py +495 -0
  272. aiecs/tools/statistics/model_trainer_tool.py +487 -0
  273. aiecs/tools/statistics/statistical_analyzer_tool.py +459 -0
  274. aiecs/tools/task_tools/__init__.py +86 -0
  275. aiecs/tools/task_tools/chart_tool.py +732 -0
  276. aiecs/tools/task_tools/classfire_tool.py +922 -0
  277. aiecs/tools/task_tools/image_tool.py +447 -0
  278. aiecs/tools/task_tools/office_tool.py +684 -0
  279. aiecs/tools/task_tools/pandas_tool.py +635 -0
  280. aiecs/tools/task_tools/report_tool.py +635 -0
  281. aiecs/tools/task_tools/research_tool.py +392 -0
  282. aiecs/tools/task_tools/scraper_tool.py +715 -0
  283. aiecs/tools/task_tools/stats_tool.py +688 -0
  284. aiecs/tools/temp_file_manager.py +130 -0
  285. aiecs/tools/tool_executor/__init__.py +37 -0
  286. aiecs/tools/tool_executor/tool_executor.py +881 -0
  287. aiecs/utils/LLM_output_structor.py +445 -0
  288. aiecs/utils/__init__.py +34 -0
  289. aiecs/utils/base_callback.py +47 -0
  290. aiecs/utils/cache_provider.py +695 -0
  291. aiecs/utils/execution_utils.py +184 -0
  292. aiecs/utils/logging.py +1 -0
  293. aiecs/utils/prompt_loader.py +14 -0
  294. aiecs/utils/token_usage_repository.py +323 -0
  295. aiecs/ws/__init__.py +0 -0
  296. aiecs/ws/socket_server.py +52 -0
  297. aiecs-1.5.1.dist-info/METADATA +608 -0
  298. aiecs-1.5.1.dist-info/RECORD +302 -0
  299. aiecs-1.5.1.dist-info/WHEEL +5 -0
  300. aiecs-1.5.1.dist-info/entry_points.txt +10 -0
  301. aiecs-1.5.1.dist-info/licenses/LICENSE +225 -0
  302. aiecs-1.5.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,413 @@
1
+ """
2
+ Query Intent Analysis and Enhancement
3
+
4
+ Provides intelligent query understanding and parameter auto-completion:
5
+ - Detect query intent (time_series, comparison, search, metadata)
6
+ - Extract entities (economic indicators, countries, etc.)
7
+ - Parse time ranges and geographic scope
8
+ - Suggest appropriate providers and operations
9
+ - Auto-complete missing parameters based on intent
10
+ """
11
+
12
+ import logging
13
+ import re
14
+ from typing import Any, Dict, List, Optional
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+
19
+ class QueryIntentAnalyzer:
20
+ """
21
+ Analyzes query intent to help route requests and optimize parameters.
22
+ """
23
+
24
+ # Intent keywords
25
+ INTENT_KEYWORDS = {
26
+ "time_series": [
27
+ "trend",
28
+ "over time",
29
+ "historical",
30
+ "series",
31
+ "change",
32
+ "growth",
33
+ "history",
34
+ ],
35
+ "comparison": [
36
+ "compare",
37
+ "versus",
38
+ "vs",
39
+ "difference",
40
+ "between",
41
+ "against",
42
+ "relative to",
43
+ ],
44
+ "search": [
45
+ "search",
46
+ "find",
47
+ "look for",
48
+ "list",
49
+ "show me",
50
+ "what are",
51
+ ],
52
+ "metadata": [
53
+ "info",
54
+ "information",
55
+ "about",
56
+ "describe",
57
+ "details",
58
+ "metadata",
59
+ ],
60
+ "recent": [
61
+ "recent",
62
+ "latest",
63
+ "current",
64
+ "now",
65
+ "today",
66
+ "this week",
67
+ "this month",
68
+ ],
69
+ "forecast": ["forecast", "predict", "future", "project", "estimate"],
70
+ }
71
+
72
+ # Economic indicators mapping
73
+ ECONOMIC_INDICATORS = {
74
+ "gdp": {
75
+ "keywords": ["gdp", "gross domestic product", "economic output"],
76
+ "providers": ["fred", "worldbank"],
77
+ "fred_series": ["GDP", "GDPC1"],
78
+ "wb_indicator": "NY.GDP.MKTP.CD",
79
+ },
80
+ "unemployment": {
81
+ "keywords": ["unemployment", "jobless", "labor force"],
82
+ "providers": ["fred"],
83
+ "fred_series": ["UNRATE", "UNEMPLOY"],
84
+ },
85
+ "inflation": {
86
+ "keywords": ["inflation", "cpi", "consumer price", "price index"],
87
+ "providers": ["fred", "worldbank"],
88
+ "fred_series": ["CPIAUCSL", "CPILFESL"],
89
+ "wb_indicator": "FP.CPI.TOTL",
90
+ },
91
+ "interest_rate": {
92
+ "keywords": [
93
+ "interest rate",
94
+ "fed rate",
95
+ "federal funds",
96
+ "treasury",
97
+ ],
98
+ "providers": ["fred"],
99
+ "fred_series": ["DFF", "DGS10", "DGS30"],
100
+ },
101
+ "population": {
102
+ "keywords": ["population", "demographic", "people count"],
103
+ "providers": ["census", "worldbank"],
104
+ "wb_indicator": "SP.POP.TOTL",
105
+ },
106
+ "trade": {
107
+ "keywords": ["trade", "export", "import", "trade balance"],
108
+ "providers": ["fred", "worldbank"],
109
+ "fred_series": ["BOPGSTB"],
110
+ "wb_indicator": "NE.EXP.GNFS.CD",
111
+ },
112
+ }
113
+
114
+ # Country codes and names
115
+ COUNTRIES = {
116
+ "us": ["us", "usa", "united states", "america"],
117
+ "uk": ["uk", "united kingdom", "britain"],
118
+ "china": ["china", "cn"],
119
+ "japan": ["japan", "jp"],
120
+ "germany": ["germany", "de"],
121
+ "france": ["france", "fr"],
122
+ "india": ["india", "in"],
123
+ "canada": ["canada", "ca"],
124
+ }
125
+
126
+ def analyze_intent(self, query_text: str) -> Dict[str, Any]:
127
+ """
128
+ Analyze query intent and extract key information.
129
+
130
+ Args:
131
+ query_text: Natural language query string
132
+
133
+ Returns:
134
+ Dictionary with:
135
+ - intent_type: Primary intent (time_series, comparison, search, etc.)
136
+ - entities: Extracted entities (indicators, countries, etc.)
137
+ - time_range: Extracted time information
138
+ - geographic_scope: Geographic context
139
+ - suggested_providers: Recommended providers
140
+ - suggested_operations: Recommended operations
141
+ - confidence: Confidence score (0-1)
142
+ """
143
+ query_lower = query_text.lower()
144
+
145
+ intent_result = {
146
+ "intent_type": "search", # Default
147
+ "entities": [],
148
+ "time_range": None,
149
+ "geographic_scope": None,
150
+ "suggested_providers": [],
151
+ "suggested_operations": [],
152
+ "confidence": 0.0,
153
+ "keywords_matched": [],
154
+ }
155
+
156
+ # Detect intent type
157
+ intent_scores = {}
158
+ for intent_type, keywords in self.INTENT_KEYWORDS.items():
159
+ score = sum(1 for kw in keywords if kw in query_lower)
160
+ if score > 0:
161
+ intent_scores[intent_type] = score
162
+
163
+ if intent_scores:
164
+ # Primary intent is the one with highest score
165
+ primary_intent = max(intent_scores.items(), key=lambda x: x[1])
166
+ intent_result["intent_type"] = primary_intent[0]
167
+ intent_result["confidence"] += 0.3
168
+
169
+ # Extract economic indicators
170
+ for indicator_name, indicator_info in self.ECONOMIC_INDICATORS.items():
171
+ for keyword in indicator_info["keywords"]:
172
+ if keyword in query_lower:
173
+ intent_result["entities"].append(
174
+ {
175
+ "type": "indicator",
176
+ "name": indicator_name,
177
+ "matched_keyword": keyword,
178
+ }
179
+ )
180
+ intent_result["suggested_providers"].extend(indicator_info["providers"])
181
+ intent_result["confidence"] += 0.2
182
+ intent_result["keywords_matched"].append(keyword)
183
+ break
184
+
185
+ # Extract countries
186
+ for country_code, country_names in self.COUNTRIES.items():
187
+ for country_name in country_names:
188
+ if country_name in query_lower:
189
+ intent_result["geographic_scope"] = country_code.upper()
190
+ intent_result["confidence"] += 0.2
191
+ break
192
+
193
+ # Extract time range
194
+ time_info = self._extract_time_range(query_lower)
195
+ if time_info:
196
+ intent_result["time_range"] = time_info
197
+ intent_result["confidence"] += 0.2
198
+
199
+ # Suggest operations based on intent
200
+ intent_result["suggested_operations"] = self._suggest_operations(
201
+ intent_result["intent_type"], intent_result["suggested_providers"]
202
+ )
203
+
204
+ # Remove duplicates from providers
205
+ intent_result["suggested_providers"] = list(set(intent_result["suggested_providers"]))
206
+
207
+ # Cap confidence at 1.0
208
+ intent_result["confidence"] = min(1.0, intent_result["confidence"])
209
+
210
+ return intent_result
211
+
212
+ def _extract_time_range(self, query_lower: str) -> Optional[Dict[str, Any]]:
213
+ """
214
+ Extract time range information from query.
215
+
216
+ Args:
217
+ query_lower: Lowercase query string
218
+
219
+ Returns:
220
+ Dictionary with start_date, end_date, or None
221
+ """
222
+ time_range = {}
223
+
224
+ # Look for year patterns (4 digits)
225
+ year_pattern = r"\b(19|20)\d{2}\b"
226
+ years = re.findall(year_pattern, query_lower)
227
+
228
+ if len(years) >= 2:
229
+ # Found multiple years
230
+ years_int = sorted([int(y) for y in years])
231
+ time_range["start_date"] = f"{years_int[0]}-01-01"
232
+ time_range["end_date"] = f"{years_int[-1]}-12-31"
233
+ time_range["type"] = "explicit_range"
234
+ elif len(years) == 1:
235
+ # Single year mentioned
236
+ year = int(years[0])
237
+ time_range["start_date"] = f"{year}-01-01"
238
+ time_range["end_date"] = f"{year}-12-31"
239
+ time_range["type"] = "single_year"
240
+
241
+ # Look for relative time expressions
242
+ if "last" in query_lower or "past" in query_lower:
243
+ # Extract number
244
+ number_pattern = r"(last|past)\s+(\d+)\s+(year|month|day|week)"
245
+ match = re.search(number_pattern, query_lower)
246
+ if match:
247
+ quantity = int(match.group(2))
248
+ unit = match.group(3)
249
+ time_range["type"] = "relative"
250
+ time_range["quantity"] = quantity
251
+ time_range["unit"] = unit
252
+
253
+ return time_range if time_range else None
254
+
255
+ def _suggest_operations(self, intent_type: str, providers: List[str]) -> List[Dict[str, str]]:
256
+ """
257
+ Suggest appropriate operations based on intent and providers.
258
+
259
+ Args:
260
+ intent_type: Detected intent type
261
+ providers: List of suggested providers
262
+
263
+ Returns:
264
+ List of {provider, operation} dictionaries
265
+ """
266
+ suggestions = []
267
+
268
+ for provider in providers:
269
+ if intent_type == "time_series":
270
+ if provider == "fred":
271
+ suggestions.append(
272
+ {
273
+ "provider": "fred",
274
+ "operation": "get_series_observations",
275
+ }
276
+ )
277
+ elif provider == "worldbank":
278
+ suggestions.append({"provider": "worldbank", "operation": "get_indicator"})
279
+
280
+ elif intent_type == "search":
281
+ if provider == "fred":
282
+ suggestions.append({"provider": "fred", "operation": "search_series"})
283
+ elif provider == "worldbank":
284
+ suggestions.append(
285
+ {
286
+ "provider": "worldbank",
287
+ "operation": "search_indicators",
288
+ }
289
+ )
290
+ elif provider == "newsapi":
291
+ suggestions.append(
292
+ {
293
+ "provider": "newsapi",
294
+ "operation": "search_everything",
295
+ }
296
+ )
297
+
298
+ elif intent_type == "metadata":
299
+ if provider == "fred":
300
+ suggestions.append({"provider": "fred", "operation": "get_series_info"})
301
+
302
+ return suggestions
303
+
304
+
305
+ class QueryEnhancer:
306
+ """
307
+ Enhances queries by auto-completing parameters based on intent.
308
+ """
309
+
310
+ def __init__(self, intent_analyzer: Optional[QueryIntentAnalyzer] = None):
311
+ """
312
+ Initialize query enhancer.
313
+
314
+ Args:
315
+ intent_analyzer: Intent analyzer instance (creates new if not provided)
316
+ """
317
+ self.intent_analyzer = intent_analyzer or QueryIntentAnalyzer()
318
+
319
+ def auto_complete_params(
320
+ self,
321
+ provider: str,
322
+ operation: str,
323
+ params: Dict[str, Any],
324
+ query_text: Optional[str] = None,
325
+ ) -> Dict[str, Any]:
326
+ """
327
+ Auto-complete missing parameters based on query intent.
328
+
329
+ Args:
330
+ provider: Provider name
331
+ operation: Operation name
332
+ params: Current parameters
333
+ query_text: Optional natural language query for intent analysis
334
+
335
+ Returns:
336
+ Enhanced parameters dictionary
337
+ """
338
+ completed_params = params.copy()
339
+
340
+ # Analyze intent if query text provided
341
+ intent = None
342
+ if query_text:
343
+ intent = self.intent_analyzer.analyze_intent(query_text)
344
+
345
+ # Add time range parameters if detected and not present
346
+ if intent and intent.get("time_range") and provider == "fred":
347
+ time_range = intent["time_range"]
348
+ if time_range.get("type") in ["explicit_range", "single_year"]:
349
+ if "observation_start" not in params and "start_date" in time_range:
350
+ completed_params["observation_start"] = time_range["start_date"]
351
+ if "observation_end" not in params and "end_date" in time_range:
352
+ completed_params["observation_end"] = time_range["end_date"]
353
+
354
+ # Add reasonable limits if not specified
355
+ if "limit" not in params and "page_size" not in params:
356
+ if intent and intent.get("intent_type") == "time_series":
357
+ # Time series typically need more data
358
+ if provider == "fred":
359
+ # FRED API max is 100000, but 1000 is reasonable default
360
+ completed_params["limit"] = 1000
361
+ elif provider == "worldbank":
362
+ completed_params["per_page"] = 1000
363
+ else:
364
+ # Search results typically need fewer
365
+ if provider == "fred":
366
+ completed_params["limit"] = 20
367
+ elif provider == "worldbank":
368
+ completed_params["limit"] = 20
369
+ elif provider == "newsapi":
370
+ completed_params["page_size"] = 10
371
+
372
+ # Add sort order for time series
373
+ if intent and intent.get("intent_type") == "time_series":
374
+ if provider == "fred" and "sort_order" not in params:
375
+ completed_params["sort_order"] = "desc" # Most recent first
376
+
377
+ # Add country code if detected and needed
378
+ if intent and intent.get("geographic_scope"):
379
+ if provider == "worldbank" and "country_code" not in params:
380
+ completed_params["country_code"] = intent["geographic_scope"]
381
+
382
+ return completed_params
383
+
384
+ def enhance_query_text(self, query_text: str, provider: str) -> str:
385
+ """
386
+ Enhance query text for better search results.
387
+
388
+ Args:
389
+ query_text: Original query text
390
+ provider: Target provider
391
+
392
+ Returns:
393
+ Enhanced query text
394
+ """
395
+ # Analyze intent
396
+ intent = self.intent_analyzer.analyze_intent(query_text)
397
+
398
+ # For searches, add indicator-specific terms
399
+ enhanced = query_text
400
+
401
+ if provider == "fred" and intent.get("entities"):
402
+ # Add FRED series IDs if we recognize the indicator
403
+ for entity in intent["entities"]:
404
+ if entity["type"] == "indicator":
405
+ indicator_name = entity["name"]
406
+ indicator_info = QueryIntentAnalyzer.ECONOMIC_INDICATORS.get(indicator_name, {})
407
+ if "fred_series" in indicator_info:
408
+ # Add common series IDs to improve search
409
+ series_ids = " ".join(indicator_info["fred_series"])
410
+ enhanced = f"{query_text} {series_ids}"
411
+ break
412
+
413
+ return enhanced