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.
Files changed (95) hide show
  1. traia_iatp/__init__.py +105 -8
  2. traia_iatp/cli/main.py +85 -1
  3. traia_iatp/client/__init__.py +28 -3
  4. traia_iatp/client/crewai_a2a_tools.py +32 -12
  5. traia_iatp/client/d402_a2a_client.py +348 -0
  6. traia_iatp/contracts/__init__.py +11 -0
  7. traia_iatp/contracts/data/abis/contract-abis-localhost.json +4091 -0
  8. traia_iatp/contracts/data/abis/contract-abis-sepolia.json +4890 -0
  9. traia_iatp/contracts/data/addresses/contract-addresses.json +17 -0
  10. traia_iatp/contracts/data/addresses/contract-proxies.json +12 -0
  11. traia_iatp/contracts/iatp_contracts_config.py +263 -0
  12. traia_iatp/contracts/wallet_creator.py +369 -0
  13. traia_iatp/core/models.py +17 -3
  14. traia_iatp/d402/MIDDLEWARE_ARCHITECTURE.md +205 -0
  15. traia_iatp/d402/PRICE_BUILDER_USAGE.md +249 -0
  16. traia_iatp/d402/README.md +489 -0
  17. traia_iatp/d402/__init__.py +54 -0
  18. traia_iatp/d402/asgi_wrapper.py +469 -0
  19. traia_iatp/d402/chains.py +102 -0
  20. traia_iatp/d402/client.py +150 -0
  21. traia_iatp/d402/clients/__init__.py +7 -0
  22. traia_iatp/d402/clients/base.py +218 -0
  23. traia_iatp/d402/clients/httpx.py +266 -0
  24. traia_iatp/d402/common.py +114 -0
  25. traia_iatp/d402/encoding.py +28 -0
  26. traia_iatp/d402/examples/client_example.py +197 -0
  27. traia_iatp/d402/examples/server_example.py +171 -0
  28. traia_iatp/d402/facilitator.py +481 -0
  29. traia_iatp/d402/mcp_middleware.py +296 -0
  30. traia_iatp/d402/models.py +116 -0
  31. traia_iatp/d402/networks.py +98 -0
  32. traia_iatp/d402/path.py +43 -0
  33. traia_iatp/d402/payment_introspection.py +126 -0
  34. traia_iatp/d402/payment_signing.py +183 -0
  35. traia_iatp/d402/price_builder.py +164 -0
  36. traia_iatp/d402/servers/__init__.py +61 -0
  37. traia_iatp/d402/servers/base.py +139 -0
  38. traia_iatp/d402/servers/example_general_server.py +140 -0
  39. traia_iatp/d402/servers/fastapi.py +253 -0
  40. traia_iatp/d402/servers/mcp.py +304 -0
  41. traia_iatp/d402/servers/starlette.py +878 -0
  42. traia_iatp/d402/starlette_middleware.py +529 -0
  43. traia_iatp/d402/types.py +300 -0
  44. traia_iatp/mcp/D402_MCP_ADAPTER_FLOW.md +357 -0
  45. traia_iatp/mcp/__init__.py +3 -0
  46. traia_iatp/mcp/d402_mcp_tool_adapter.py +526 -0
  47. traia_iatp/mcp/mcp_agent_template.py +78 -13
  48. traia_iatp/mcp/templates/Dockerfile.j2 +27 -4
  49. traia_iatp/mcp/templates/README.md.j2 +104 -8
  50. traia_iatp/mcp/templates/cursor-rules.md.j2 +194 -0
  51. traia_iatp/mcp/templates/deployment_params.json.j2 +1 -2
  52. traia_iatp/mcp/templates/docker-compose.yml.j2 +13 -3
  53. traia_iatp/mcp/templates/env.example.j2 +60 -0
  54. traia_iatp/mcp/templates/mcp_health_check.py.j2 +2 -2
  55. traia_iatp/mcp/templates/pyproject.toml.j2 +11 -5
  56. traia_iatp/mcp/templates/pyrightconfig.json.j2 +22 -0
  57. traia_iatp/mcp/templates/run_local_docker.sh.j2 +320 -10
  58. traia_iatp/mcp/templates/server.py.j2 +174 -197
  59. traia_iatp/mcp/traia_mcp_adapter.py +182 -20
  60. traia_iatp/registry/__init__.py +47 -12
  61. traia_iatp/registry/atlas_search_indexes.json +108 -54
  62. traia_iatp/registry/iatp_search_api.py +169 -39
  63. traia_iatp/registry/mongodb_registry.py +241 -69
  64. traia_iatp/registry/readmes/EMBEDDINGS_SETUP.md +1 -1
  65. traia_iatp/registry/readmes/IATP_SEARCH_API_GUIDE.md +8 -8
  66. traia_iatp/registry/readmes/MONGODB_X509_AUTH.md +1 -1
  67. traia_iatp/registry/readmes/README.md +3 -3
  68. traia_iatp/registry/readmes/REFACTORING_SUMMARY.md +6 -6
  69. traia_iatp/scripts/__init__.py +2 -0
  70. traia_iatp/scripts/create_wallet.py +244 -0
  71. traia_iatp/server/a2a_server.py +22 -7
  72. traia_iatp/server/iatp_server_template_generator.py +23 -0
  73. traia_iatp/server/templates/.dockerignore.j2 +48 -0
  74. traia_iatp/server/templates/Dockerfile.j2 +23 -1
  75. traia_iatp/server/templates/README.md +2 -2
  76. traia_iatp/server/templates/README.md.j2 +5 -5
  77. traia_iatp/server/templates/__main__.py.j2 +374 -66
  78. traia_iatp/server/templates/agent.py.j2 +12 -11
  79. traia_iatp/server/templates/agent_config.json.j2 +3 -3
  80. traia_iatp/server/templates/agent_executor.py.j2 +45 -27
  81. traia_iatp/server/templates/env.example.j2 +32 -4
  82. traia_iatp/server/templates/gitignore.j2 +7 -0
  83. traia_iatp/server/templates/pyproject.toml.j2 +13 -12
  84. traia_iatp/server/templates/run_local_docker.sh.j2 +143 -11
  85. traia_iatp/server/templates/server.py.j2 +197 -10
  86. traia_iatp/special_agencies/registry_search_agency.py +1 -1
  87. traia_iatp/utils/iatp_utils.py +6 -6
  88. traia_iatp-0.1.67.dist-info/METADATA +320 -0
  89. traia_iatp-0.1.67.dist-info/RECORD +117 -0
  90. traia_iatp-0.1.2.dist-info/METADATA +0 -414
  91. traia_iatp-0.1.2.dist-info/RECORD +0 -72
  92. {traia_iatp-0.1.2.dist-info → traia_iatp-0.1.67.dist-info}/WHEEL +0 -0
  93. {traia_iatp-0.1.2.dist-info → traia_iatp-0.1.67.dist-info}/entry_points.txt +0 -0
  94. {traia_iatp-0.1.2.dist-info → traia_iatp-0.1.67.dist-info}/licenses/LICENSE +0 -0
  95. {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 both authenticated and non-authenticated
9
- MCP connections by injecting headers when provided.
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
- if self._auth_headers:
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 monkey patch before parent initialization
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._auth_headers:
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 without headers
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
- # Without headers
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 iatp.mcp import TraiaMCPAdapter
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 iatp.mcp import create_mcp_adapter_with_auth
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 X-API-KEY header as alternative
325
- token = request.headers.get("X-API-KEY", "")
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
  ]
@@ -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 .mongodb_registry import UtilityAgentRegistry, MCPServerRegistry
4
- from .iatp_search_api import (
5
- find_utility_agent,
6
- list_utility_agents,
7
- search_utility_agents,
8
- find_mcp_server,
9
- list_mcp_servers,
10
- search_mcp_servers,
11
- get_mcp_server
12
- )
13
- from .embeddings import get_embedding_service
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
- "type": "string",
23
- "analyzer": "lucene.standard"
10
+ "analyzer": "lucene.standard",
11
+ "type": "string"
24
12
  },
25
- "search_text": {
26
- "type": "string",
27
- "analyzer": "lucene.standard"
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
- "type": "string",
38
- "analyzer": "lucene.standard"
46
+ "analyzer": "lucene.standard",
47
+ "type": "string"
48
+ },
49
+ "name": {
50
+ "analyzer": "lucene.standard",
51
+ "type": "string"
39
52
  },
40
53
  "tags": {
41
- "type": "string",
42
- "analyzer": "lucene.standard"
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
- "type": "string",
71
- "analyzer": "lucene.standard"
85
+ "analyzer": "lucene.standard",
86
+ "type": "string"
72
87
  },
73
- "search_text": {
74
- "type": "string",
75
- "analyzer": "lucene.standard"
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
- "type": "string",
86
- "analyzer": "lucene.standard"
121
+ "analyzer": "lucene.standard",
122
+ "type": "string"
123
+ },
124
+ "name": {
125
+ "analyzer": "lucene.standard",
126
+ "type": "string"
87
127
  },
88
128
  "tags": {
89
- "type": "string",
90
- "analyzer": "lucene.standard"
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
  }