aiecs 1.2.1__py3-none-any.whl → 1.3.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.

Potentially problematic release.


This version of aiecs might be problematic. Click here for more details.

Files changed (56) hide show
  1. aiecs/__init__.py +1 -1
  2. aiecs/config/config.py +2 -1
  3. aiecs/llm/clients/vertex_client.py +5 -0
  4. aiecs/main.py +2 -2
  5. aiecs/scripts/tools_develop/README.md +111 -2
  6. aiecs/scripts/tools_develop/TOOL_AUTO_DISCOVERY.md +234 -0
  7. aiecs/scripts/tools_develop/validate_tool_schemas.py +80 -21
  8. aiecs/scripts/tools_develop/verify_tools.py +347 -0
  9. aiecs/tools/__init__.py +94 -30
  10. aiecs/tools/apisource/__init__.py +106 -0
  11. aiecs/tools/apisource/intelligence/__init__.py +20 -0
  12. aiecs/tools/apisource/intelligence/data_fusion.py +378 -0
  13. aiecs/tools/apisource/intelligence/query_analyzer.py +387 -0
  14. aiecs/tools/apisource/intelligence/search_enhancer.py +384 -0
  15. aiecs/tools/apisource/monitoring/__init__.py +12 -0
  16. aiecs/tools/apisource/monitoring/metrics.py +308 -0
  17. aiecs/tools/apisource/providers/__init__.py +114 -0
  18. aiecs/tools/apisource/providers/base.py +684 -0
  19. aiecs/tools/apisource/providers/census.py +412 -0
  20. aiecs/tools/apisource/providers/fred.py +575 -0
  21. aiecs/tools/apisource/providers/newsapi.py +402 -0
  22. aiecs/tools/apisource/providers/worldbank.py +346 -0
  23. aiecs/tools/apisource/reliability/__init__.py +14 -0
  24. aiecs/tools/apisource/reliability/error_handler.py +362 -0
  25. aiecs/tools/apisource/reliability/fallback_strategy.py +420 -0
  26. aiecs/tools/apisource/tool.py +814 -0
  27. aiecs/tools/apisource/utils/__init__.py +12 -0
  28. aiecs/tools/apisource/utils/validators.py +343 -0
  29. aiecs/tools/langchain_adapter.py +95 -17
  30. aiecs/tools/search_tool/__init__.py +102 -0
  31. aiecs/tools/search_tool/analyzers.py +583 -0
  32. aiecs/tools/search_tool/cache.py +280 -0
  33. aiecs/tools/search_tool/constants.py +127 -0
  34. aiecs/tools/search_tool/context.py +219 -0
  35. aiecs/tools/search_tool/core.py +773 -0
  36. aiecs/tools/search_tool/deduplicator.py +123 -0
  37. aiecs/tools/search_tool/error_handler.py +257 -0
  38. aiecs/tools/search_tool/metrics.py +375 -0
  39. aiecs/tools/search_tool/rate_limiter.py +177 -0
  40. aiecs/tools/search_tool/schemas.py +297 -0
  41. aiecs/tools/statistics/data_loader_tool.py +2 -2
  42. aiecs/tools/statistics/data_transformer_tool.py +1 -1
  43. aiecs/tools/task_tools/__init__.py +8 -8
  44. aiecs/tools/task_tools/report_tool.py +1 -1
  45. aiecs/tools/tool_executor/__init__.py +2 -0
  46. aiecs/tools/tool_executor/tool_executor.py +284 -14
  47. aiecs/utils/__init__.py +11 -0
  48. aiecs/utils/cache_provider.py +698 -0
  49. aiecs/utils/execution_utils.py +5 -5
  50. {aiecs-1.2.1.dist-info → aiecs-1.3.1.dist-info}/METADATA +1 -1
  51. {aiecs-1.2.1.dist-info → aiecs-1.3.1.dist-info}/RECORD +55 -23
  52. aiecs/tools/task_tools/search_tool.py +0 -1123
  53. {aiecs-1.2.1.dist-info → aiecs-1.3.1.dist-info}/WHEEL +0 -0
  54. {aiecs-1.2.1.dist-info → aiecs-1.3.1.dist-info}/entry_points.txt +0 -0
  55. {aiecs-1.2.1.dist-info → aiecs-1.3.1.dist-info}/licenses/LICENSE +0 -0
  56. {aiecs-1.2.1.dist-info → aiecs-1.3.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,346 @@
1
+ """
2
+ World Bank API Provider
3
+
4
+ Provides access to World Bank development indicators and data.
5
+ Supports country data, indicators, and time series queries.
6
+
7
+ API Documentation: https://datahelpdesk.worldbank.org/knowledgebase/articles/889392-about-the-indicators-api-documentation
8
+ """
9
+
10
+ import logging
11
+ from typing import Any, Dict, List, Optional, Tuple
12
+
13
+ from aiecs.tools.apisource.providers.base import BaseAPIProvider, expose_operation
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+ # Optional HTTP client
18
+ try:
19
+ import requests
20
+ REQUESTS_AVAILABLE = True
21
+ except ImportError:
22
+ REQUESTS_AVAILABLE = False
23
+
24
+
25
+ class WorldBankProvider(BaseAPIProvider):
26
+ """
27
+ World Bank API provider for development indicators and country data.
28
+
29
+ Provides access to:
30
+ - Economic indicators (GDP, inflation, trade, etc.)
31
+ - Social indicators (education, health, population)
32
+ - Environmental data
33
+ - Country-specific statistics
34
+ """
35
+
36
+ BASE_URL = "https://api.worldbank.org/v2"
37
+
38
+ @property
39
+ def name(self) -> str:
40
+ return "worldbank"
41
+
42
+ @property
43
+ def description(self) -> str:
44
+ return "World Bank API for global development indicators and country statistics"
45
+
46
+ @property
47
+ def supported_operations(self) -> List[str]:
48
+ return [
49
+ 'get_indicator',
50
+ 'search_indicators',
51
+ 'get_country_data',
52
+ 'list_countries',
53
+ 'list_indicators'
54
+ ]
55
+
56
+ def validate_params(self, operation: str, params: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
57
+ """Validate parameters for World Bank operations"""
58
+
59
+ if operation == 'get_indicator':
60
+ if 'indicator_code' not in params:
61
+ return False, "Missing required parameter: indicator_code"
62
+ if 'country_code' not in params:
63
+ return False, "Missing required parameter: country_code"
64
+
65
+ elif operation == 'get_country_data':
66
+ if 'country_code' not in params:
67
+ return False, "Missing required parameter: country_code"
68
+
69
+ elif operation == 'search_indicators':
70
+ if 'search_text' not in params:
71
+ return False, "Missing required parameter: search_text"
72
+
73
+ return True, None
74
+
75
+ # Exposed operations for AI agent visibility
76
+
77
+ @expose_operation(
78
+ operation_name='get_indicator',
79
+ description='Get World Bank development indicator data for a specific country and indicator'
80
+ )
81
+ def get_indicator(
82
+ self,
83
+ indicator_code: str,
84
+ country_code: str,
85
+ start_year: Optional[int] = None,
86
+ end_year: Optional[int] = None
87
+ ) -> Dict[str, Any]:
88
+ """
89
+ Get World Bank indicator data.
90
+
91
+ Args:
92
+ indicator_code: World Bank indicator code (e.g., 'NY.GDP.MKTP.CD', 'SP.POP.TOTL')
93
+ country_code: ISO 3-letter country code (e.g., 'USA', 'CHN', 'GBR')
94
+ start_year: Start year for data range
95
+ end_year: End year for data range
96
+
97
+ Returns:
98
+ Dictionary containing indicator data and metadata
99
+ """
100
+ params = {
101
+ 'indicator_code': indicator_code,
102
+ 'country_code': country_code
103
+ }
104
+ if start_year:
105
+ params['start_year'] = start_year
106
+ if end_year:
107
+ params['end_year'] = end_year
108
+
109
+ return self.execute('get_indicator', params)
110
+
111
+ @expose_operation(
112
+ operation_name='search_indicators',
113
+ description='Search for World Bank indicators by keywords'
114
+ )
115
+ def search_indicators(
116
+ self,
117
+ search_text: str,
118
+ limit: Optional[int] = None
119
+ ) -> Dict[str, Any]:
120
+ """
121
+ Search for World Bank indicators.
122
+
123
+ Args:
124
+ search_text: Search keywords (e.g., 'GDP', 'population', 'education')
125
+ limit: Maximum number of results to return
126
+
127
+ Returns:
128
+ Dictionary containing search results and metadata
129
+ """
130
+ params = {'search_text': search_text}
131
+ if limit:
132
+ params['limit'] = limit
133
+
134
+ return self.execute('search_indicators', params)
135
+
136
+ @expose_operation(
137
+ operation_name='get_country_data',
138
+ description='Get general information and statistics about a specific country'
139
+ )
140
+ def get_country_data(self, country_code: str) -> Dict[str, Any]:
141
+ """
142
+ Get country data and metadata.
143
+
144
+ Args:
145
+ country_code: ISO 3-letter country code (e.g., 'USA', 'CHN')
146
+
147
+ Returns:
148
+ Dictionary containing country information
149
+ """
150
+ return self.execute('get_country_data', {'country_code': country_code})
151
+
152
+ @expose_operation(
153
+ operation_name='list_countries',
154
+ description='List all available countries in the World Bank database'
155
+ )
156
+ def list_countries(self) -> Dict[str, Any]:
157
+ """
158
+ List all available countries.
159
+
160
+ Returns:
161
+ Dictionary containing list of countries
162
+ """
163
+ return self.execute('list_countries', {})
164
+
165
+ @expose_operation(
166
+ operation_name='list_indicators',
167
+ description='List all available World Bank indicators'
168
+ )
169
+ def list_indicators(self, limit: Optional[int] = None) -> Dict[str, Any]:
170
+ """
171
+ List all available indicators.
172
+
173
+ Args:
174
+ limit: Maximum number of indicators to return
175
+
176
+ Returns:
177
+ Dictionary containing list of indicators
178
+ """
179
+ params = {}
180
+ if limit:
181
+ params['limit'] = limit
182
+
183
+ return self.execute('list_indicators', params)
184
+
185
+ def fetch(self, operation: str, params: Dict[str, Any]) -> Dict[str, Any]:
186
+ """Fetch data from World Bank API"""
187
+
188
+ if not REQUESTS_AVAILABLE:
189
+ raise ImportError("requests library is required for World Bank provider")
190
+
191
+ # World Bank API doesn't require API key for most operations
192
+ timeout = self.config.get('timeout', 30)
193
+
194
+ # Build endpoint based on operation
195
+ if operation == 'get_indicator':
196
+ country = params['country_code']
197
+ indicator = params['indicator_code']
198
+ endpoint = f"{self.BASE_URL}/country/{country}/indicator/{indicator}"
199
+ query_params = {'format': 'json'}
200
+
201
+ # Optional parameters
202
+ if 'date' in params:
203
+ query_params['date'] = params['date']
204
+ if 'per_page' in params:
205
+ query_params['per_page'] = params['per_page']
206
+
207
+ elif operation == 'get_country_data':
208
+ country = params['country_code']
209
+ endpoint = f"{self.BASE_URL}/country/{country}"
210
+ query_params = {'format': 'json'}
211
+
212
+ elif operation == 'list_countries':
213
+ endpoint = f"{self.BASE_URL}/country"
214
+ query_params = {'format': 'json', 'per_page': params.get('per_page', 100)}
215
+
216
+ elif operation == 'list_indicators':
217
+ endpoint = f"{self.BASE_URL}/indicator"
218
+ query_params = {'format': 'json', 'per_page': params.get('per_page', 100)}
219
+
220
+ elif operation == 'search_indicators':
221
+ # World Bank doesn't have direct search, so we list and filter
222
+ endpoint = f"{self.BASE_URL}/indicator"
223
+ query_params = {'format': 'json', 'per_page': 1000}
224
+
225
+ else:
226
+ raise ValueError(f"Unknown operation: {operation}")
227
+
228
+ # Make API request
229
+ try:
230
+ response = requests.get(
231
+ endpoint,
232
+ params=query_params,
233
+ timeout=timeout
234
+ )
235
+ response.raise_for_status()
236
+
237
+ data = response.json()
238
+
239
+ # World Bank API returns [metadata, data]
240
+ if isinstance(data, list) and len(data) > 1:
241
+ result_data = data[1]
242
+ else:
243
+ result_data = data
244
+
245
+ # Filter for search operation
246
+ if operation == 'search_indicators' and result_data:
247
+ search_text = params['search_text'].lower()
248
+ filtered = [
249
+ item for item in result_data
250
+ if search_text in str(item.get('name', '')).lower() or
251
+ search_text in str(item.get('sourceNote', '')).lower()
252
+ ]
253
+ result_data = filtered[:params.get('limit', 20)]
254
+
255
+ return self._format_response(
256
+ operation=operation,
257
+ data=result_data,
258
+ source=f"World Bank API - {endpoint}"
259
+ )
260
+
261
+ except requests.exceptions.RequestException as e:
262
+ self.logger.error(f"World Bank API request failed: {e}")
263
+ raise Exception(f"World Bank API request failed: {str(e)}")
264
+
265
+ def get_operation_schema(self, operation: str) -> Optional[Dict[str, Any]]:
266
+ """Get detailed schema for World Bank operations"""
267
+
268
+ schemas = {
269
+ 'get_indicator': {
270
+ 'description': 'Get World Bank development indicator data',
271
+ 'parameters': {
272
+ 'indicator_code': {
273
+ 'type': 'string',
274
+ 'required': True,
275
+ 'description': 'World Bank indicator code',
276
+ 'examples': ['NY.GDP.MKTP.CD', 'SP.POP.TOTL', 'SE.PRM.ENRR']
277
+ },
278
+ 'country_code': {
279
+ 'type': 'string',
280
+ 'required': True,
281
+ 'description': 'ISO 3-letter country code',
282
+ 'examples': ['USA', 'CHN', 'GBR', 'IND']
283
+ },
284
+ 'start_year': {
285
+ 'type': 'integer',
286
+ 'required': False,
287
+ 'description': 'Start year for data range',
288
+ 'examples': [2010, 2015, 2020]
289
+ },
290
+ 'end_year': {
291
+ 'type': 'integer',
292
+ 'required': False,
293
+ 'description': 'End year for data range',
294
+ 'examples': [2020, 2023, 2025]
295
+ }
296
+ }
297
+ },
298
+ 'search_indicators': {
299
+ 'description': 'Search for World Bank indicators by keywords',
300
+ 'parameters': {
301
+ 'search_text': {
302
+ 'type': 'string',
303
+ 'required': True,
304
+ 'description': 'Search keywords',
305
+ 'examples': ['GDP', 'population', 'education', 'health']
306
+ },
307
+ 'limit': {
308
+ 'type': 'integer',
309
+ 'required': False,
310
+ 'description': 'Maximum number of results',
311
+ 'examples': [10, 20, 50],
312
+ 'default': 20
313
+ }
314
+ }
315
+ },
316
+ 'get_country_data': {
317
+ 'description': 'Get country information and metadata',
318
+ 'parameters': {
319
+ 'country_code': {
320
+ 'type': 'string',
321
+ 'required': True,
322
+ 'description': 'ISO 3-letter country code',
323
+ 'examples': ['USA', 'CHN', 'GBR']
324
+ }
325
+ }
326
+ },
327
+ 'list_countries': {
328
+ 'description': 'List all available countries',
329
+ 'parameters': {}
330
+ },
331
+ 'list_indicators': {
332
+ 'description': 'List all available indicators',
333
+ 'parameters': {
334
+ 'limit': {
335
+ 'type': 'integer',
336
+ 'required': False,
337
+ 'description': 'Maximum number of indicators',
338
+ 'examples': [50, 100, 200],
339
+ 'default': 100
340
+ }
341
+ }
342
+ }
343
+ }
344
+
345
+ return schemas.get(operation)
346
+
@@ -0,0 +1,14 @@
1
+ """
2
+ Reliability Module
3
+
4
+ Contains error handling and fallback strategy components.
5
+ """
6
+
7
+ from aiecs.tools.apisource.reliability.error_handler import SmartErrorHandler
8
+ from aiecs.tools.apisource.reliability.fallback_strategy import FallbackStrategy
9
+
10
+ __all__ = [
11
+ 'SmartErrorHandler',
12
+ 'FallbackStrategy'
13
+ ]
14
+