traia-iatp 0.1.2__py3-none-any.whl → 0.1.67__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.
- traia_iatp/__init__.py +105 -8
- traia_iatp/cli/main.py +85 -1
- traia_iatp/client/__init__.py +28 -3
- traia_iatp/client/crewai_a2a_tools.py +32 -12
- traia_iatp/client/d402_a2a_client.py +348 -0
- traia_iatp/contracts/__init__.py +11 -0
- traia_iatp/contracts/data/abis/contract-abis-localhost.json +4091 -0
- traia_iatp/contracts/data/abis/contract-abis-sepolia.json +4890 -0
- traia_iatp/contracts/data/addresses/contract-addresses.json +17 -0
- traia_iatp/contracts/data/addresses/contract-proxies.json +12 -0
- traia_iatp/contracts/iatp_contracts_config.py +263 -0
- traia_iatp/contracts/wallet_creator.py +369 -0
- traia_iatp/core/models.py +17 -3
- traia_iatp/d402/MIDDLEWARE_ARCHITECTURE.md +205 -0
- traia_iatp/d402/PRICE_BUILDER_USAGE.md +249 -0
- traia_iatp/d402/README.md +489 -0
- traia_iatp/d402/__init__.py +54 -0
- traia_iatp/d402/asgi_wrapper.py +469 -0
- traia_iatp/d402/chains.py +102 -0
- traia_iatp/d402/client.py +150 -0
- traia_iatp/d402/clients/__init__.py +7 -0
- traia_iatp/d402/clients/base.py +218 -0
- traia_iatp/d402/clients/httpx.py +266 -0
- traia_iatp/d402/common.py +114 -0
- traia_iatp/d402/encoding.py +28 -0
- traia_iatp/d402/examples/client_example.py +197 -0
- traia_iatp/d402/examples/server_example.py +171 -0
- traia_iatp/d402/facilitator.py +481 -0
- traia_iatp/d402/mcp_middleware.py +296 -0
- traia_iatp/d402/models.py +116 -0
- traia_iatp/d402/networks.py +98 -0
- traia_iatp/d402/path.py +43 -0
- traia_iatp/d402/payment_introspection.py +126 -0
- traia_iatp/d402/payment_signing.py +183 -0
- traia_iatp/d402/price_builder.py +164 -0
- traia_iatp/d402/servers/__init__.py +61 -0
- traia_iatp/d402/servers/base.py +139 -0
- traia_iatp/d402/servers/example_general_server.py +140 -0
- traia_iatp/d402/servers/fastapi.py +253 -0
- traia_iatp/d402/servers/mcp.py +304 -0
- traia_iatp/d402/servers/starlette.py +878 -0
- traia_iatp/d402/starlette_middleware.py +529 -0
- traia_iatp/d402/types.py +300 -0
- traia_iatp/mcp/D402_MCP_ADAPTER_FLOW.md +357 -0
- traia_iatp/mcp/__init__.py +3 -0
- traia_iatp/mcp/d402_mcp_tool_adapter.py +526 -0
- traia_iatp/mcp/mcp_agent_template.py +78 -13
- traia_iatp/mcp/templates/Dockerfile.j2 +27 -4
- traia_iatp/mcp/templates/README.md.j2 +104 -8
- traia_iatp/mcp/templates/cursor-rules.md.j2 +194 -0
- traia_iatp/mcp/templates/deployment_params.json.j2 +1 -2
- traia_iatp/mcp/templates/docker-compose.yml.j2 +13 -3
- traia_iatp/mcp/templates/env.example.j2 +60 -0
- traia_iatp/mcp/templates/mcp_health_check.py.j2 +2 -2
- traia_iatp/mcp/templates/pyproject.toml.j2 +11 -5
- traia_iatp/mcp/templates/pyrightconfig.json.j2 +22 -0
- traia_iatp/mcp/templates/run_local_docker.sh.j2 +320 -10
- traia_iatp/mcp/templates/server.py.j2 +174 -197
- traia_iatp/mcp/traia_mcp_adapter.py +182 -20
- traia_iatp/registry/__init__.py +47 -12
- traia_iatp/registry/atlas_search_indexes.json +108 -54
- traia_iatp/registry/iatp_search_api.py +169 -39
- traia_iatp/registry/mongodb_registry.py +241 -69
- traia_iatp/registry/readmes/EMBEDDINGS_SETUP.md +1 -1
- traia_iatp/registry/readmes/IATP_SEARCH_API_GUIDE.md +8 -8
- traia_iatp/registry/readmes/MONGODB_X509_AUTH.md +1 -1
- traia_iatp/registry/readmes/README.md +3 -3
- traia_iatp/registry/readmes/REFACTORING_SUMMARY.md +6 -6
- traia_iatp/scripts/__init__.py +2 -0
- traia_iatp/scripts/create_wallet.py +244 -0
- traia_iatp/server/a2a_server.py +22 -7
- traia_iatp/server/iatp_server_template_generator.py +23 -0
- traia_iatp/server/templates/.dockerignore.j2 +48 -0
- traia_iatp/server/templates/Dockerfile.j2 +23 -1
- traia_iatp/server/templates/README.md +2 -2
- traia_iatp/server/templates/README.md.j2 +5 -5
- traia_iatp/server/templates/__main__.py.j2 +374 -66
- traia_iatp/server/templates/agent.py.j2 +12 -11
- traia_iatp/server/templates/agent_config.json.j2 +3 -3
- traia_iatp/server/templates/agent_executor.py.j2 +45 -27
- traia_iatp/server/templates/env.example.j2 +32 -4
- traia_iatp/server/templates/gitignore.j2 +7 -0
- traia_iatp/server/templates/pyproject.toml.j2 +13 -12
- traia_iatp/server/templates/run_local_docker.sh.j2 +143 -11
- traia_iatp/server/templates/server.py.j2 +197 -10
- traia_iatp/special_agencies/registry_search_agency.py +1 -1
- traia_iatp/utils/iatp_utils.py +6 -6
- traia_iatp-0.1.67.dist-info/METADATA +320 -0
- traia_iatp-0.1.67.dist-info/RECORD +117 -0
- traia_iatp-0.1.2.dist-info/METADATA +0 -414
- traia_iatp-0.1.2.dist-info/RECORD +0 -72
- {traia_iatp-0.1.2.dist-info → traia_iatp-0.1.67.dist-info}/WHEEL +0 -0
- {traia_iatp-0.1.2.dist-info → traia_iatp-0.1.67.dist-info}/entry_points.txt +0 -0
- {traia_iatp-0.1.2.dist-info → traia_iatp-0.1.67.dist-info}/licenses/LICENSE +0 -0
- {traia_iatp-0.1.2.dist-info → traia_iatp-0.1.67.dist-info}/top_level.txt +0 -0
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
Traia MCP Adapter
|
|
4
4
|
|
|
5
5
|
A custom MCP adapter that extends CrewAI's MCPServerAdapter to support
|
|
6
|
-
passing headers (like Authorization) to streamable-http MCP servers.
|
|
6
|
+
passing headers (like Authorization) and x402 payment protocol to streamable-http MCP servers.
|
|
7
7
|
|
|
8
|
-
This adapter transparently handles
|
|
9
|
-
|
|
8
|
+
This adapter transparently handles:
|
|
9
|
+
- Authenticated connections (via headers)
|
|
10
|
+
- Payment-based connections (via x402/d402 protocol)
|
|
11
|
+
- Standard connections (no auth or payment)
|
|
10
12
|
"""
|
|
11
13
|
|
|
12
14
|
import logging
|
|
@@ -19,6 +21,15 @@ from crewai.tools import BaseTool
|
|
|
19
21
|
|
|
20
22
|
logger = logging.getLogger(__name__)
|
|
21
23
|
|
|
24
|
+
# Try to import d402 payment hooks from IATP
|
|
25
|
+
try:
|
|
26
|
+
from eth_account import Account
|
|
27
|
+
from traia_iatp.d402.clients.httpx import d402_payment_hooks
|
|
28
|
+
D402_AVAILABLE = True
|
|
29
|
+
except ImportError:
|
|
30
|
+
D402_AVAILABLE = False
|
|
31
|
+
logger.warning("d402 payment hooks not available. Ensure traia_iatp.d402 is installed.")
|
|
32
|
+
|
|
22
33
|
|
|
23
34
|
class TraiaMCPAdapter(MCPServerAdapter):
|
|
24
35
|
"""
|
|
@@ -55,31 +66,53 @@ class TraiaMCPAdapter(MCPServerAdapter):
|
|
|
55
66
|
*tool_names: str
|
|
56
67
|
):
|
|
57
68
|
"""
|
|
58
|
-
Initialize the adapter with optional header support.
|
|
69
|
+
Initialize the adapter with optional header and x402 payment support.
|
|
59
70
|
|
|
60
71
|
Args:
|
|
61
72
|
server_params: Server configuration. For streamable-http, can include:
|
|
62
73
|
- url: The MCP server URL
|
|
63
74
|
- transport: "streamable-http"
|
|
64
75
|
- headers: Optional dict of headers to include in requests
|
|
76
|
+
- x402_account: Optional eth_account.Account for x402 payments
|
|
77
|
+
- x402_max_value: Optional max payment value
|
|
65
78
|
*tool_names: Optional tool names to filter
|
|
66
79
|
"""
|
|
67
80
|
# Handle dict params
|
|
68
81
|
if isinstance(server_params, dict):
|
|
69
|
-
# Extract headers if present (don't modify original)
|
|
82
|
+
# Extract headers and d402 config if present (don't modify original)
|
|
70
83
|
server_params_copy = server_params.copy()
|
|
71
84
|
self._auth_headers = server_params_copy.pop("headers", {})
|
|
85
|
+
self._d402_account = server_params_copy.pop("d402_account", None)
|
|
86
|
+
self._d402_max_value = server_params_copy.pop("d402_max_value", None)
|
|
87
|
+
|
|
88
|
+
# IMPORTANT: Also remove any x402_* parameters that shouldn't go to MCP library
|
|
89
|
+
# The MCP library's streamablehttp_client() doesn't accept these
|
|
90
|
+
server_params_copy.pop("x402_account", None)
|
|
91
|
+
server_params_copy.pop("x402_max_value", None)
|
|
72
92
|
|
|
73
|
-
|
|
93
|
+
# Determine connection mode
|
|
94
|
+
if self._d402_account and D402_AVAILABLE:
|
|
95
|
+
logger.info("💳 TraiaMCPAdapter: d402 payment protocol enabled")
|
|
96
|
+
logger.info(f" Client account: {self._d402_account.address}")
|
|
97
|
+
logger.info(f" Max value: {self._d402_max_value}")
|
|
98
|
+
logger.info(" Applying httpx monkey-patch for d402 hooks...")
|
|
99
|
+
# Apply d402 payment hooks patch
|
|
100
|
+
self._apply_d402_patch()
|
|
101
|
+
logger.info(" ✅ Monkey-patch applied - ALL new httpx clients will have d402 hooks")
|
|
102
|
+
elif self._auth_headers:
|
|
74
103
|
logger.info(f"TraiaMCPAdapter: Headers configured: {list(self._auth_headers.keys())}")
|
|
75
|
-
# Apply
|
|
104
|
+
# Apply header injection patch
|
|
76
105
|
self._apply_httpx_patch()
|
|
77
106
|
|
|
78
|
-
# Pass clean params to parent
|
|
107
|
+
# Pass clean params to parent - this will create the MCP client
|
|
108
|
+
logger.info(" Creating parent MCPServerAdapter...")
|
|
79
109
|
super().__init__(server_params_copy, *tool_names)
|
|
110
|
+
logger.info(" ✅ Parent MCPServerAdapter created")
|
|
80
111
|
else:
|
|
81
|
-
# Non-dict params, no headers possible
|
|
112
|
+
# Non-dict params, no headers or payment possible
|
|
82
113
|
self._auth_headers = {}
|
|
114
|
+
self._d402_account = None
|
|
115
|
+
self._d402_max_value = None
|
|
83
116
|
super().__init__(server_params, *tool_names)
|
|
84
117
|
|
|
85
118
|
def _apply_httpx_patch(self):
|
|
@@ -107,7 +140,56 @@ class TraiaMCPAdapter(MCPServerAdapter):
|
|
|
107
140
|
# Apply the patch
|
|
108
141
|
httpx.AsyncClient.__init__ = patched_init
|
|
109
142
|
self._original_httpx_init = original_init
|
|
110
|
-
logger.debug("Applied httpx.AsyncClient monkey patch")
|
|
143
|
+
logger.debug("Applied httpx.AsyncClient monkey patch for headers")
|
|
144
|
+
|
|
145
|
+
def _apply_d402_patch(self):
|
|
146
|
+
"""Monkey-patch httpx.AsyncClient to add d402 payment hooks."""
|
|
147
|
+
if not D402_AVAILABLE:
|
|
148
|
+
raise ImportError("d402 payment hooks not available. Ensure traia_iatp.d402 is installed.")
|
|
149
|
+
|
|
150
|
+
original_init = httpx.AsyncClient.__init__
|
|
151
|
+
d402_account = self._d402_account # Keep variable name for compatibility
|
|
152
|
+
d402_max_value = self._d402_max_value
|
|
153
|
+
|
|
154
|
+
@wraps(original_init)
|
|
155
|
+
def patched_init(client_self, *args, **kwargs):
|
|
156
|
+
# Log client creation
|
|
157
|
+
import traceback
|
|
158
|
+
creation_stack = ''.join(traceback.format_stack()[-4:-1])
|
|
159
|
+
logger.info(f"🔨 httpx.AsyncClient.__init__ called")
|
|
160
|
+
logger.debug(f" Creation stack: {creation_stack}")
|
|
161
|
+
|
|
162
|
+
# Call original init first
|
|
163
|
+
original_init(client_self, *args, **kwargs)
|
|
164
|
+
|
|
165
|
+
# Add d402 payment hooks to the client
|
|
166
|
+
if d402_account:
|
|
167
|
+
try:
|
|
168
|
+
hooks = d402_payment_hooks(d402_account, max_value=d402_max_value)
|
|
169
|
+
# Merge with existing hooks if any
|
|
170
|
+
if hasattr(client_self, 'event_hooks') and client_self.event_hooks:
|
|
171
|
+
# Merge hooks
|
|
172
|
+
for event_type, handlers in hooks.items():
|
|
173
|
+
if event_type in client_self.event_hooks:
|
|
174
|
+
client_self.event_hooks[event_type].extend(handlers)
|
|
175
|
+
else:
|
|
176
|
+
client_self.event_hooks[event_type] = handlers
|
|
177
|
+
else:
|
|
178
|
+
client_self.event_hooks = hooks
|
|
179
|
+
|
|
180
|
+
logger.info(f"✅ Applied d402 payment hooks to httpx.AsyncClient")
|
|
181
|
+
logger.info(f" Account: {d402_account.address[:10]}...")
|
|
182
|
+
logger.info(f" Hooks: {list(hooks.keys())}")
|
|
183
|
+
except Exception as e:
|
|
184
|
+
logger.error(f"❌ Failed to apply d402 hooks: {e}")
|
|
185
|
+
import traceback
|
|
186
|
+
logger.error(traceback.format_exc())
|
|
187
|
+
raise
|
|
188
|
+
|
|
189
|
+
# Apply the patch
|
|
190
|
+
httpx.AsyncClient.__init__ = patched_init
|
|
191
|
+
self._original_httpx_init = original_init
|
|
192
|
+
logger.debug("Applied httpx.AsyncClient monkey patch for d402 payments")
|
|
111
193
|
|
|
112
194
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
113
195
|
"""Exit context manager and restore original httpx if patched."""
|
|
@@ -121,7 +203,9 @@ class TraiaMCPAdapter(MCPServerAdapter):
|
|
|
121
203
|
|
|
122
204
|
def __enter__(self) -> List[BaseTool]:
|
|
123
205
|
"""Enter context manager."""
|
|
124
|
-
if self.
|
|
206
|
+
if self._d402_account:
|
|
207
|
+
logger.debug(f"TraiaMCPAdapter: Using d402 payment connection")
|
|
208
|
+
elif self._auth_headers:
|
|
125
209
|
logger.debug(f"TraiaMCPAdapter: Using authenticated connection")
|
|
126
210
|
|
|
127
211
|
return super().__enter__()
|
|
@@ -131,29 +215,45 @@ def create_mcp_adapter(
|
|
|
131
215
|
url: str,
|
|
132
216
|
headers: Optional[Dict[str, str]] = None,
|
|
133
217
|
transport: str = "streamable-http",
|
|
134
|
-
tool_names: Optional[List[str]] = None
|
|
218
|
+
tool_names: Optional[List[str]] = None,
|
|
219
|
+
x402_account: Optional[Any] = None,
|
|
220
|
+
x402_max_value: Optional[int] = None
|
|
135
221
|
) -> TraiaMCPAdapter:
|
|
136
222
|
"""
|
|
137
|
-
Create a Traia MCP adapter with optional headers.
|
|
223
|
+
Create a Traia MCP adapter with optional headers and/or d402 payment support.
|
|
138
224
|
|
|
139
225
|
Args:
|
|
140
226
|
url: MCP server URL
|
|
141
227
|
headers: Optional dictionary of headers to include in requests
|
|
142
228
|
transport: Transport type (default: streamable-http)
|
|
143
229
|
tool_names: Optional list of tool names to filter
|
|
230
|
+
x402_account: Optional eth_account.Account for d402 payment protocol
|
|
231
|
+
x402_max_value: Optional maximum payment value in base units.
|
|
232
|
+
Typically, each MCP server uses one primary token, so this limit
|
|
233
|
+
applies to all endpoints using that token. Set based on the token's
|
|
234
|
+
base units (e.g., USDC with 6 decimals: $1.00 = 1_000_000).
|
|
144
235
|
|
|
145
236
|
Returns:
|
|
146
|
-
TraiaMCPAdapter configured with or
|
|
237
|
+
TraiaMCPAdapter configured with headers and/or d402 payments
|
|
147
238
|
|
|
148
239
|
Example:
|
|
149
240
|
```python
|
|
150
|
-
# With headers
|
|
241
|
+
# With headers (authenticated)
|
|
151
242
|
adapter = create_mcp_adapter(
|
|
152
243
|
url="https://news-mcp.example.com/mcp",
|
|
153
244
|
headers={"Authorization": "Bearer YOUR_API_KEY"}
|
|
154
245
|
)
|
|
155
246
|
|
|
156
|
-
#
|
|
247
|
+
# With d402 payments
|
|
248
|
+
from eth_account import Account
|
|
249
|
+
account = Account.from_key("0x...")
|
|
250
|
+
adapter = create_mcp_adapter(
|
|
251
|
+
url="https://news-mcp.example.com/mcp",
|
|
252
|
+
x402_account=account,
|
|
253
|
+
x402_max_value=1_000_000 # $1.00 in USDC (6 decimals)
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
# Without headers or payment (standard)
|
|
157
257
|
adapter = create_mcp_adapter(
|
|
158
258
|
url="https://news-mcp.example.com/mcp"
|
|
159
259
|
)
|
|
@@ -170,6 +270,11 @@ def create_mcp_adapter(
|
|
|
170
270
|
if headers:
|
|
171
271
|
server_params["headers"] = headers
|
|
172
272
|
|
|
273
|
+
if x402_account:
|
|
274
|
+
server_params["d402_account"] = x402_account # Use d402_ internally
|
|
275
|
+
if x402_max_value is not None:
|
|
276
|
+
server_params["d402_max_value"] = x402_max_value # Use d402_ internally
|
|
277
|
+
|
|
173
278
|
if tool_names:
|
|
174
279
|
return TraiaMCPAdapter(server_params, *tool_names)
|
|
175
280
|
else:
|
|
@@ -219,6 +324,62 @@ def create_mcp_adapter_with_auth(
|
|
|
219
324
|
return create_mcp_adapter(url, headers, transport, tool_names)
|
|
220
325
|
|
|
221
326
|
|
|
327
|
+
def create_mcp_adapter_with_x402(
|
|
328
|
+
url: str,
|
|
329
|
+
account: Any,
|
|
330
|
+
max_value: Optional[int] = None,
|
|
331
|
+
transport: str = "streamable-http",
|
|
332
|
+
tool_names: Optional[List[str]] = None
|
|
333
|
+
) -> TraiaMCPAdapter:
|
|
334
|
+
"""
|
|
335
|
+
Create a Traia MCP adapter with d402 payment protocol support.
|
|
336
|
+
|
|
337
|
+
Note: Function name uses "x402" for backward compatibility, but it uses
|
|
338
|
+
the d402 implementation from traia_iatp.d402.
|
|
339
|
+
|
|
340
|
+
Args:
|
|
341
|
+
url: MCP server URL
|
|
342
|
+
account: eth_account.Account instance for signing payments
|
|
343
|
+
max_value: Optional maximum allowed payment amount in base units.
|
|
344
|
+
Typically, each MCP server uses one primary token, so this limit
|
|
345
|
+
applies to all endpoints using that token. Set based on the token's
|
|
346
|
+
base units (e.g., USDC with 6 decimals: $1.00 = 1_000_000).
|
|
347
|
+
transport: Transport type (default: streamable-http)
|
|
348
|
+
tool_names: Optional list of tool names to filter
|
|
349
|
+
|
|
350
|
+
Returns:
|
|
351
|
+
TraiaMCPAdapter configured with d402 payment hooks
|
|
352
|
+
|
|
353
|
+
Example:
|
|
354
|
+
```python
|
|
355
|
+
from eth_account import Account
|
|
356
|
+
|
|
357
|
+
account = Account.from_key("0x...")
|
|
358
|
+
adapter = create_mcp_adapter_with_x402(
|
|
359
|
+
url="https://news-mcp.example.com/mcp",
|
|
360
|
+
account=account,
|
|
361
|
+
max_value=1_000_000 # $1.00 in USDC (6 decimals) - adjust for your server's token
|
|
362
|
+
)
|
|
363
|
+
|
|
364
|
+
with adapter as tools:
|
|
365
|
+
# Tools will automatically handle 402 Payment Required responses
|
|
366
|
+
agent = Agent(tools=tools)
|
|
367
|
+
```
|
|
368
|
+
"""
|
|
369
|
+
if not D402_AVAILABLE:
|
|
370
|
+
raise ImportError(
|
|
371
|
+
"d402 payment hooks not available. Ensure traia_iatp.d402 is installed."
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
return create_mcp_adapter(
|
|
375
|
+
url=url,
|
|
376
|
+
transport=transport,
|
|
377
|
+
tool_names=tool_names,
|
|
378
|
+
x402_account=account, # Function param uses x402 for backward compat
|
|
379
|
+
x402_max_value=max_value # Will be converted to d402 internally
|
|
380
|
+
)
|
|
381
|
+
|
|
382
|
+
|
|
222
383
|
# Backwards compatibility aliases
|
|
223
384
|
HeaderMCPAdapter = TraiaMCPAdapter
|
|
224
385
|
create_mcp_adapter_with_headers = create_mcp_adapter
|
|
@@ -236,7 +397,7 @@ all HTTP requests when using streamable-http transport.
|
|
|
236
397
|
Basic Usage
|
|
237
398
|
-----------
|
|
238
399
|
```python
|
|
239
|
-
from
|
|
400
|
+
from traia_iatp.mcp import TraiaMCPAdapter
|
|
240
401
|
|
|
241
402
|
# Standard connection (no authentication)
|
|
242
403
|
server_params = {
|
|
@@ -264,7 +425,7 @@ with TraiaMCPAdapter(server_params) as tools:
|
|
|
264
425
|
Using Helper Functions
|
|
265
426
|
----------------------
|
|
266
427
|
```python
|
|
267
|
-
from
|
|
428
|
+
from traia_iatp.mcp import create_mcp_adapter_with_auth
|
|
268
429
|
|
|
269
430
|
# Create authenticated adapter
|
|
270
431
|
adapter = create_mcp_adapter_with_auth(
|
|
@@ -321,8 +482,8 @@ class AuthMiddleware(Middleware):
|
|
|
321
482
|
token = auth[7:].strip() if auth.lower().startswith("bearer ") else None
|
|
322
483
|
|
|
323
484
|
if not token:
|
|
324
|
-
# Check
|
|
325
|
-
token = request.headers.get("
|
|
485
|
+
# Check x-api-key header as alternative (case-insensitive)
|
|
486
|
+
token = request.headers.get("x-api-key", "")
|
|
326
487
|
|
|
327
488
|
if token:
|
|
328
489
|
# Store the API key in the context state
|
|
@@ -376,6 +537,7 @@ __all__ = [
|
|
|
376
537
|
'HeaderMCPAdapter', # Alias for backward compatibility
|
|
377
538
|
'create_mcp_adapter',
|
|
378
539
|
'create_mcp_adapter_with_auth',
|
|
540
|
+
'create_mcp_adapter_with_x402',
|
|
379
541
|
'create_mcp_adapter_with_headers', # Alias
|
|
380
542
|
'USAGE_GUIDE'
|
|
381
543
|
]
|
traia_iatp/registry/__init__.py
CHANGED
|
@@ -1,16 +1,37 @@
|
|
|
1
|
-
"""IATP registry module for managing utility agents and MCP servers."""
|
|
1
|
+
"""IATP registry module for managing utility agents and MCP servers with lazy loading."""
|
|
2
2
|
|
|
3
|
-
from
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
# Type hints for IDEs and type checkers (not loaded at runtime)
|
|
6
|
+
if TYPE_CHECKING:
|
|
7
|
+
from .mongodb_registry import UtilityAgentRegistry, MCPServerRegistry
|
|
8
|
+
from .iatp_search_api import (
|
|
9
|
+
find_utility_agent,
|
|
10
|
+
list_utility_agents,
|
|
11
|
+
search_utility_agents,
|
|
12
|
+
find_mcp_server,
|
|
13
|
+
list_mcp_servers,
|
|
14
|
+
search_mcp_servers,
|
|
15
|
+
get_mcp_server
|
|
16
|
+
)
|
|
17
|
+
from .embeddings import get_embedding_service
|
|
18
|
+
|
|
19
|
+
# Lazy imports to avoid loading heavy dependencies (OpenAI, Cohere, etc.) unless needed
|
|
20
|
+
_LAZY_IMPORTS = {
|
|
21
|
+
# Registry classes (write operations)
|
|
22
|
+
"UtilityAgentRegistry": ".mongodb_registry",
|
|
23
|
+
"MCPServerRegistry": ".mongodb_registry",
|
|
24
|
+
# Search API functions (lightweight, no heavy deps)
|
|
25
|
+
"find_utility_agent": ".iatp_search_api",
|
|
26
|
+
"list_utility_agents": ".iatp_search_api",
|
|
27
|
+
"search_utility_agents": ".iatp_search_api",
|
|
28
|
+
"find_mcp_server": ".iatp_search_api",
|
|
29
|
+
"list_mcp_servers": ".iatp_search_api",
|
|
30
|
+
"search_mcp_servers": ".iatp_search_api",
|
|
31
|
+
"get_mcp_server": ".iatp_search_api",
|
|
32
|
+
# Embedding service (HEAVY - OpenAI/Cohere, only load if vector search is used)
|
|
33
|
+
"get_embedding_service": ".embeddings",
|
|
34
|
+
}
|
|
14
35
|
|
|
15
36
|
__all__ = [
|
|
16
37
|
"UtilityAgentRegistry",
|
|
@@ -24,3 +45,17 @@ __all__ = [
|
|
|
24
45
|
"get_mcp_server",
|
|
25
46
|
"get_embedding_service",
|
|
26
47
|
]
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def __getattr__(name: str):
|
|
51
|
+
"""Lazy import mechanism to load modules only when accessed."""
|
|
52
|
+
if name in _LAZY_IMPORTS:
|
|
53
|
+
from importlib import import_module
|
|
54
|
+
module_path = _LAZY_IMPORTS[name]
|
|
55
|
+
module = import_module(module_path, package=__package__)
|
|
56
|
+
attr = getattr(module, name)
|
|
57
|
+
# Cache the imported attribute
|
|
58
|
+
globals()[name] = attr
|
|
59
|
+
return attr
|
|
60
|
+
|
|
61
|
+
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
|
|
@@ -6,43 +6,70 @@
|
|
|
6
6
|
"mappings": {
|
|
7
7
|
"dynamic": false,
|
|
8
8
|
"fields": {
|
|
9
|
-
"name": {
|
|
10
|
-
"type": "string",
|
|
11
|
-
"analyzer": "lucene.standard"
|
|
12
|
-
},
|
|
13
|
-
"description": {
|
|
14
|
-
"type": "string",
|
|
15
|
-
"analyzer": "lucene.standard"
|
|
16
|
-
},
|
|
17
|
-
"tags": {
|
|
18
|
-
"type": "string",
|
|
19
|
-
"analyzer": "lucene.standard"
|
|
20
|
-
},
|
|
21
9
|
"capabilities": {
|
|
22
|
-
"
|
|
23
|
-
"
|
|
10
|
+
"analyzer": "lucene.standard",
|
|
11
|
+
"type": "string"
|
|
24
12
|
},
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
13
|
+
"description": {
|
|
14
|
+
"analyzer": "lucene.standard",
|
|
15
|
+
"type": "string"
|
|
28
16
|
},
|
|
17
|
+
"name": [
|
|
18
|
+
{
|
|
19
|
+
"analyzer": "lucene.standard",
|
|
20
|
+
"type": "string"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"foldDiacritics": true,
|
|
24
|
+
"maxGrams": 15,
|
|
25
|
+
"minGrams": 2,
|
|
26
|
+
"tokenization": "edgeGram",
|
|
27
|
+
"type": "autocomplete"
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
"search_text": [
|
|
31
|
+
{
|
|
32
|
+
"analyzer": "lucene.standard",
|
|
33
|
+
"type": "string"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"foldDiacritics": true,
|
|
37
|
+
"maxGrams": 15,
|
|
38
|
+
"minGrams": 2,
|
|
39
|
+
"tokenization": "edgeGram",
|
|
40
|
+
"type": "autocomplete"
|
|
41
|
+
}
|
|
42
|
+
],
|
|
29
43
|
"skills": {
|
|
30
|
-
"type": "document",
|
|
31
44
|
"fields": {
|
|
32
|
-
"name": {
|
|
33
|
-
"type": "string",
|
|
34
|
-
"analyzer": "lucene.standard"
|
|
35
|
-
},
|
|
36
45
|
"description": {
|
|
37
|
-
"
|
|
38
|
-
"
|
|
46
|
+
"analyzer": "lucene.standard",
|
|
47
|
+
"type": "string"
|
|
48
|
+
},
|
|
49
|
+
"name": {
|
|
50
|
+
"analyzer": "lucene.standard",
|
|
51
|
+
"type": "string"
|
|
39
52
|
},
|
|
40
53
|
"tags": {
|
|
41
|
-
"
|
|
42
|
-
"
|
|
54
|
+
"analyzer": "lucene.standard",
|
|
55
|
+
"type": "string"
|
|
43
56
|
}
|
|
57
|
+
},
|
|
58
|
+
"type": "document"
|
|
59
|
+
},
|
|
60
|
+
"tags": [
|
|
61
|
+
{
|
|
62
|
+
"analyzer": "lucene.standard",
|
|
63
|
+
"type": "string"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"foldDiacritics": true,
|
|
67
|
+
"maxGrams": 15,
|
|
68
|
+
"minGrams": 2,
|
|
69
|
+
"tokenization": "edgeGram",
|
|
70
|
+
"type": "autocomplete"
|
|
44
71
|
}
|
|
45
|
-
|
|
72
|
+
]
|
|
46
73
|
}
|
|
47
74
|
}
|
|
48
75
|
}
|
|
@@ -54,43 +81,70 @@
|
|
|
54
81
|
"mappings": {
|
|
55
82
|
"dynamic": false,
|
|
56
83
|
"fields": {
|
|
57
|
-
"name": {
|
|
58
|
-
"type": "string",
|
|
59
|
-
"analyzer": "lucene.standard"
|
|
60
|
-
},
|
|
61
|
-
"description": {
|
|
62
|
-
"type": "string",
|
|
63
|
-
"analyzer": "lucene.standard"
|
|
64
|
-
},
|
|
65
|
-
"tags": {
|
|
66
|
-
"type": "string",
|
|
67
|
-
"analyzer": "lucene.standard"
|
|
68
|
-
},
|
|
69
84
|
"capabilities": {
|
|
70
|
-
"
|
|
71
|
-
"
|
|
85
|
+
"analyzer": "lucene.standard",
|
|
86
|
+
"type": "string"
|
|
72
87
|
},
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
"
|
|
88
|
+
"description": {
|
|
89
|
+
"analyzer": "lucene.standard",
|
|
90
|
+
"type": "string"
|
|
76
91
|
},
|
|
92
|
+
"name": [
|
|
93
|
+
{
|
|
94
|
+
"analyzer": "lucene.standard",
|
|
95
|
+
"type": "string"
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"foldDiacritics": true,
|
|
99
|
+
"maxGrams": 15,
|
|
100
|
+
"minGrams": 2,
|
|
101
|
+
"tokenization": "edgeGram",
|
|
102
|
+
"type": "autocomplete"
|
|
103
|
+
}
|
|
104
|
+
],
|
|
105
|
+
"search_text": [
|
|
106
|
+
{
|
|
107
|
+
"analyzer": "lucene.standard",
|
|
108
|
+
"type": "string"
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"foldDiacritics": true,
|
|
112
|
+
"maxGrams": 15,
|
|
113
|
+
"minGrams": 2,
|
|
114
|
+
"tokenization": "edgeGram",
|
|
115
|
+
"type": "autocomplete"
|
|
116
|
+
}
|
|
117
|
+
],
|
|
77
118
|
"skills": {
|
|
78
|
-
"type": "document",
|
|
79
119
|
"fields": {
|
|
80
|
-
"name": {
|
|
81
|
-
"type": "string",
|
|
82
|
-
"analyzer": "lucene.standard"
|
|
83
|
-
},
|
|
84
120
|
"description": {
|
|
85
|
-
"
|
|
86
|
-
"
|
|
121
|
+
"analyzer": "lucene.standard",
|
|
122
|
+
"type": "string"
|
|
123
|
+
},
|
|
124
|
+
"name": {
|
|
125
|
+
"analyzer": "lucene.standard",
|
|
126
|
+
"type": "string"
|
|
87
127
|
},
|
|
88
128
|
"tags": {
|
|
89
|
-
"
|
|
90
|
-
"
|
|
129
|
+
"analyzer": "lucene.standard",
|
|
130
|
+
"type": "string"
|
|
91
131
|
}
|
|
132
|
+
},
|
|
133
|
+
"type": "document"
|
|
134
|
+
},
|
|
135
|
+
"tags": [
|
|
136
|
+
{
|
|
137
|
+
"analyzer": "lucene.standard",
|
|
138
|
+
"type": "string"
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"foldDiacritics": true,
|
|
142
|
+
"maxGrams": 15,
|
|
143
|
+
"minGrams": 2,
|
|
144
|
+
"tokenization": "edgeGram",
|
|
145
|
+
"type": "autocomplete"
|
|
92
146
|
}
|
|
93
|
-
|
|
147
|
+
]
|
|
94
148
|
}
|
|
95
149
|
}
|
|
96
150
|
}
|