aiecs 1.2.2__py3-none-any.whl → 1.3.3__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.
- aiecs/__init__.py +1 -1
- aiecs/llm/clients/vertex_client.py +22 -2
- aiecs/main.py +2 -2
- aiecs/scripts/tools_develop/README.md +111 -2
- aiecs/scripts/tools_develop/TOOL_AUTO_DISCOVERY.md +234 -0
- aiecs/scripts/tools_develop/validate_tool_schemas.py +80 -21
- aiecs/scripts/tools_develop/verify_tools.py +347 -0
- aiecs/tools/__init__.py +94 -30
- aiecs/tools/apisource/__init__.py +106 -0
- aiecs/tools/apisource/intelligence/__init__.py +20 -0
- aiecs/tools/apisource/intelligence/data_fusion.py +378 -0
- aiecs/tools/apisource/intelligence/query_analyzer.py +387 -0
- aiecs/tools/apisource/intelligence/search_enhancer.py +384 -0
- aiecs/tools/apisource/monitoring/__init__.py +12 -0
- aiecs/tools/apisource/monitoring/metrics.py +308 -0
- aiecs/tools/apisource/providers/__init__.py +114 -0
- aiecs/tools/apisource/providers/base.py +684 -0
- aiecs/tools/apisource/providers/census.py +412 -0
- aiecs/tools/apisource/providers/fred.py +575 -0
- aiecs/tools/apisource/providers/newsapi.py +402 -0
- aiecs/tools/apisource/providers/worldbank.py +346 -0
- aiecs/tools/apisource/reliability/__init__.py +14 -0
- aiecs/tools/apisource/reliability/error_handler.py +362 -0
- aiecs/tools/apisource/reliability/fallback_strategy.py +420 -0
- aiecs/tools/apisource/tool.py +814 -0
- aiecs/tools/apisource/utils/__init__.py +12 -0
- aiecs/tools/apisource/utils/validators.py +343 -0
- aiecs/tools/langchain_adapter.py +95 -17
- aiecs/tools/search_tool/__init__.py +102 -0
- aiecs/tools/search_tool/analyzers.py +583 -0
- aiecs/tools/search_tool/cache.py +280 -0
- aiecs/tools/search_tool/constants.py +127 -0
- aiecs/tools/search_tool/context.py +219 -0
- aiecs/tools/search_tool/core.py +773 -0
- aiecs/tools/search_tool/deduplicator.py +123 -0
- aiecs/tools/search_tool/error_handler.py +257 -0
- aiecs/tools/search_tool/metrics.py +375 -0
- aiecs/tools/search_tool/rate_limiter.py +177 -0
- aiecs/tools/search_tool/schemas.py +297 -0
- aiecs/tools/statistics/data_loader_tool.py +2 -2
- aiecs/tools/statistics/data_transformer_tool.py +1 -1
- aiecs/tools/task_tools/__init__.py +8 -8
- aiecs/tools/task_tools/report_tool.py +1 -1
- aiecs/tools/tool_executor/__init__.py +2 -0
- aiecs/tools/tool_executor/tool_executor.py +284 -14
- aiecs/utils/__init__.py +11 -0
- aiecs/utils/cache_provider.py +698 -0
- aiecs/utils/execution_utils.py +5 -5
- {aiecs-1.2.2.dist-info → aiecs-1.3.3.dist-info}/METADATA +1 -1
- {aiecs-1.2.2.dist-info → aiecs-1.3.3.dist-info}/RECORD +54 -22
- aiecs/tools/task_tools/search_tool.py +0 -1123
- {aiecs-1.2.2.dist-info → aiecs-1.3.3.dist-info}/WHEEL +0 -0
- {aiecs-1.2.2.dist-info → aiecs-1.3.3.dist-info}/entry_points.txt +0 -0
- {aiecs-1.2.2.dist-info → aiecs-1.3.3.dist-info}/licenses/LICENSE +0 -0
- {aiecs-1.2.2.dist-info → aiecs-1.3.3.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
|
+
|