mech-client 0.4.0__py3-none-any.whl → 0.7.0__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 (34) hide show
  1. mech_client/__init__.py +1 -1
  2. mech_client/abis/AgentMech.json +718 -0
  3. mech_client/abis/AgentRegistry.json +1037 -0
  4. mech_client/abis/AgreementStoreManager.base.json +766 -0
  5. mech_client/abis/AgreementStoreManager.gnosis.json +766 -0
  6. mech_client/abis/DIDRegistry.base.json +2476 -0
  7. mech_client/abis/DIDRegistry.gnosis.json +2476 -0
  8. mech_client/abis/EscrowPaymentCondition.base.json +717 -0
  9. mech_client/abis/EscrowPaymentCondition.gnosis.json +717 -0
  10. mech_client/abis/LockPaymentCondition.base.json +874 -0
  11. mech_client/abis/LockPaymentCondition.gnosis.json +874 -0
  12. mech_client/abis/NFTSalesTemplate.base.json +698 -0
  13. mech_client/abis/NFTSalesTemplate.gnosis.json +698 -0
  14. mech_client/abis/NeverminedConfig.base.json +587 -0
  15. mech_client/abis/NeverminedConfig.gnosis.json +587 -0
  16. mech_client/abis/SubscriptionNFT.base.json +300 -0
  17. mech_client/abis/SubscriptionNFT.gnosis.json +300 -0
  18. mech_client/abis/SubscriptionProvider.base.json +294 -0
  19. mech_client/abis/SubscriptionProvider.gnosis.json +294 -0
  20. mech_client/abis/SubscriptionToken.base.json +1393 -0
  21. mech_client/abis/TransferNFTCondition.base.json +1062 -0
  22. mech_client/abis/TransferNFTCondition.gnosis.json +1062 -0
  23. mech_client/cli.py +99 -10
  24. mech_client/configs/mechs.json +1 -7
  25. mech_client/interact.py +14 -39
  26. mech_client/marketplace_interact.py +130 -90
  27. mech_client/mech_tool_management.py +11 -5
  28. mech_client/subgraph.py +21 -35
  29. mech_client/wss.py +7 -6
  30. {mech_client-0.4.0.dist-info → mech_client-0.7.0.dist-info}/METADATA +53 -19
  31. {mech_client-0.4.0.dist-info → mech_client-0.7.0.dist-info}/RECORD +34 -13
  32. {mech_client-0.4.0.dist-info → mech_client-0.7.0.dist-info}/LICENSE +0 -0
  33. {mech_client-0.4.0.dist-info → mech_client-0.7.0.dist-info}/WHEEL +0 -0
  34. {mech_client-0.4.0.dist-info → mech_client-0.7.0.dist-info}/entry_points.txt +0 -0
mech_client/cli.py CHANGED
@@ -22,6 +22,7 @@ import json
22
22
  from typing import Any, Dict, List, Optional, Tuple
23
23
 
24
24
  import click
25
+ from click import ClickException
25
26
  from tabulate import tabulate # type: ignore
26
27
 
27
28
  from mech_client import __version__
@@ -38,6 +39,9 @@ from mech_client.mech_tool_management import (
38
39
  from mech_client.prompt_to_ipfs import main as prompt_to_ipfs_main
39
40
  from mech_client.push_to_ipfs import main as push_to_ipfs_main
40
41
  from mech_client.to_png import main as to_png_main
42
+ from scripts.deposit_native import main as deposit_native_main
43
+ from scripts.deposit_token import main as deposit_token_main
44
+ from scripts.nvm_subscribe import main as nvm_subscribe_main
41
45
 
42
46
 
43
47
  @click.group(name="mechx") # type: ignore
@@ -47,7 +51,13 @@ def cli() -> None:
47
51
 
48
52
 
49
53
  @click.command()
50
- @click.argument("prompt")
54
+ @click.option(
55
+ "--prompts",
56
+ type=str,
57
+ multiple=True,
58
+ required=True,
59
+ help="One or more prompts to send as a request. Can be repeated.",
60
+ )
51
61
  @click.option("--agent_id", type=int, help="Id of the agent to be used")
52
62
  @click.option(
53
63
  "--priority-mech",
@@ -70,9 +80,10 @@ def cli() -> None:
70
80
  help="Path to private key to use for request minting",
71
81
  )
72
82
  @click.option(
73
- "--tool",
83
+ "--tools",
74
84
  type=str,
75
- help="Name of the tool to be used",
85
+ multiple=True,
86
+ help="One or more tools to be used. Can be repeated.",
76
87
  )
77
88
  @click.option(
78
89
  "--extra-attribute",
@@ -109,13 +120,13 @@ def cli() -> None:
109
120
  help="Id of the mech's chain configuration (stored configs/mechs.json)",
110
121
  )
111
122
  def interact( # pylint: disable=too-many-arguments,too-many-locals
112
- prompt: str,
123
+ prompts: tuple,
113
124
  agent_id: int,
114
125
  priority_mech: str,
115
126
  use_prepaid: bool,
116
127
  use_offchain: bool,
117
128
  key: Optional[str],
118
- tool: Optional[str],
129
+ tools: Optional[tuple],
119
130
  extra_attribute: Optional[List[str]] = None,
120
131
  confirm: Optional[str] = None,
121
132
  retries: Optional[int] = None,
@@ -135,13 +146,18 @@ def interact( # pylint: disable=too-many-arguments,too-many-locals
135
146
  use_prepaid = use_prepaid or use_offchain
136
147
 
137
148
  if agent_id is None:
149
+ if len(prompts) != len(tools):
150
+ raise ClickException(
151
+ f"The number of prompts ({len(prompts)}) must match the number of tools ({len(tools)})"
152
+ )
153
+
138
154
  marketplace_interact_(
139
- prompt=prompt,
155
+ prompts=prompts,
140
156
  priority_mech=priority_mech,
141
157
  use_prepaid=use_prepaid,
142
158
  use_offchain=use_offchain,
143
159
  private_key_path=key,
144
- tool=tool,
160
+ tools=tools,
145
161
  extra_attributes=extra_attributes_dict,
146
162
  confirmation_type=(
147
163
  ConfirmationType(confirm)
@@ -165,11 +181,16 @@ def interact( # pylint: disable=too-many-arguments,too-many-locals
165
181
  "Offchain model can only be used for marketplace requests"
166
182
  )
167
183
 
184
+ if len(prompts) > 1:
185
+ raise ClickException(
186
+ f"Error: Batch prompts ({len(prompts)}) not supported for legacy mechs"
187
+ )
188
+
168
189
  interact_(
169
- prompt=prompt,
190
+ prompt=prompts[0],
170
191
  agent_id=agent_id,
171
192
  private_key_path=key,
172
- tool=tool,
193
+ tool=tools[0] if tools else None,
173
194
  extra_attributes=extra_attributes_dict,
174
195
  confirmation_type=(
175
196
  ConfirmationType(confirm)
@@ -182,7 +203,7 @@ def interact( # pylint: disable=too-many-arguments,too-many-locals
182
203
  chain_config=chain_config,
183
204
  )
184
205
  except (ValueError, FileNotFoundError, Exception) as e:
185
- raise click.ClickException(str(e)) from e
206
+ raise ClickException(str(e)) from e
186
207
 
187
208
 
188
209
  @click.command()
@@ -332,6 +353,71 @@ def tool_io_schema(tool_id: str, chain_config: str) -> None:
332
353
  click.echo(f"Network or I/O error: {str(e)}")
333
354
 
334
355
 
356
+ @click.command(name="deposit-native")
357
+ @click.argument("amount_to_deposit")
358
+ @click.option(
359
+ "--chain-config",
360
+ type=str,
361
+ help="Id of the mech's chain configuration (stored configs/mechs.json)",
362
+ )
363
+ @click.option(
364
+ "--key",
365
+ type=click.Path(exists=True, file_okay=True, dir_okay=False),
366
+ help="Path to private key to use for deposit",
367
+ )
368
+ def deposit_native(
369
+ amount_to_deposit: str,
370
+ key: Optional[str],
371
+ chain_config: Optional[str] = None,
372
+ ) -> None:
373
+ """Deposits Native balance for prepaid requests."""
374
+ deposit_native_main(
375
+ amount=amount_to_deposit, private_key_path=key, chain_config=chain_config
376
+ )
377
+
378
+
379
+ @click.command(name="deposit-token")
380
+ @click.argument("amount_to_deposit")
381
+ @click.option(
382
+ "--chain-config",
383
+ type=str,
384
+ help="Id of the mech's chain configuration (stored configs/mechs.json)",
385
+ )
386
+ @click.option(
387
+ "--key",
388
+ type=click.Path(exists=True, file_okay=True, dir_okay=False),
389
+ help="Path to private key to use for deposit",
390
+ )
391
+ def deposit_token(
392
+ amount_to_deposit: str,
393
+ key: Optional[str],
394
+ chain_config: Optional[str] = None,
395
+ ) -> None:
396
+ """Deposits Token balance for prepaid requests."""
397
+ deposit_token_main(
398
+ amount=amount_to_deposit, private_key_path=key, chain_config=chain_config
399
+ )
400
+
401
+
402
+ @click.command(name="purchase-nvm-subscription")
403
+ @click.option(
404
+ "--chain-config",
405
+ type=str,
406
+ help="Id of the mech's chain configuration (stored configs/mechs.json)",
407
+ )
408
+ @click.option(
409
+ "--key",
410
+ type=click.Path(exists=True, file_okay=True, dir_okay=False),
411
+ help="Path to private key to use for deposit",
412
+ )
413
+ def nvm_subscribe(
414
+ key: str,
415
+ chain_config: str,
416
+ ) -> None:
417
+ """Allows to purchase nvm subscription for nvm mech requests."""
418
+ nvm_subscribe_main(private_key_path=key, chain_config=chain_config)
419
+
420
+
335
421
  cli.add_command(interact)
336
422
  cli.add_command(prompt_to_ipfs)
337
423
  cli.add_command(push_to_ipfs)
@@ -339,6 +425,9 @@ cli.add_command(to_png)
339
425
  cli.add_command(tools_for_agents)
340
426
  cli.add_command(tool_io_schema)
341
427
  cli.add_command(tool_description)
428
+ cli.add_command(deposit_native)
429
+ cli.add_command(deposit_token)
430
+ cli.add_command(nvm_subscribe)
342
431
 
343
432
 
344
433
  if __name__ == "__main__":
@@ -14,9 +14,8 @@
14
14
  },
15
15
  "gas_limit": 500000,
16
16
  "price": 10000000000000000,
17
- "contract_abi_url": "https://api.gnosisscan.io/api?module=contract&action=getabi&address={contract_address}&apikey={api_key}",
18
17
  "transaction_url": "https://gnosisscan.io/tx/{transaction_digest}",
19
- "subgraph_url": "https://api.studio.thegraph.com/query/57238/mech/version/latest"
18
+ "subgraph_url": ""
20
19
  },
21
20
  "arbitrum": {
22
21
  "agent_registry_contract": "0xa4799B083E0068732456EF45ff9fe5c683658327",
@@ -33,7 +32,6 @@
33
32
  },
34
33
  "gas_limit": 100000,
35
34
  "price": 3000000000000,
36
- "contract_abi_url": "https://api.arbiscan.io/api?module=contract&action=getabi&address={contract_address}",
37
35
  "transaction_url": "https://arbiscan.io/tx/{transaction_digest}",
38
36
  "subgraph_url": ""
39
37
  },
@@ -52,7 +50,6 @@
52
50
  },
53
51
  "gas_limit": 100000,
54
52
  "price": 10000000000000000,
55
- "contract_abi_url": "https://api.polygonscan.com/api?module=contract&action=getabi&address={contract_address}",
56
53
  "transaction_url": "https://polygonscan.com/tx/{transaction_digest}",
57
54
  "subgraph_url": ""
58
55
  },
@@ -71,7 +68,6 @@
71
68
  },
72
69
  "gas_limit": 500000,
73
70
  "price": 3000000000000,
74
- "contract_abi_url": "https://api.basescan.org/api?module=contract&action=getabi&address={contract_address}&apikey={api_key}",
75
71
  "transaction_url": "https://basescan.org/tx/{transaction_digest}",
76
72
  "subgraph_url": ""
77
73
  },
@@ -90,7 +86,6 @@
90
86
  },
91
87
  "gas_limit": 250000,
92
88
  "price": 10000000000000000,
93
- "contract_abi_url": "https://api.celoscan.io/api?module=contract&action=getabi&address={contract_address}",
94
89
  "transaction_url": "https://celoscan.io/tx/{transaction_digest}",
95
90
  "subgraph_url": ""
96
91
  },
@@ -109,7 +104,6 @@
109
104
  },
110
105
  "gas_limit": 100000,
111
106
  "price": 3000000000000,
112
- "contract_abi_url": "https://api-optimistic.etherscan.io/api?module=contract&action=getabi&address={contract_address}",
113
107
  "transaction_url": "https://optimistic.etherscan.io/tx/{transaction_digest}",
114
108
  "subgraph_url": ""
115
109
  }
mech_client/interact.py CHANGED
@@ -28,7 +28,6 @@ python client.py <prompt> <tool>
28
28
  import asyncio
29
29
  import json
30
30
  import os
31
- import sys
32
31
  import time
33
32
  import warnings
34
33
  from dataclasses import asdict, dataclass, field
@@ -56,6 +55,9 @@ from mech_client.wss import (
56
55
 
57
56
  PRIVATE_KEY_FILE_PATH = "ethereum_private_key.txt"
58
57
  MECH_CONFIGS = Path(__file__).parent / "configs" / "mechs.json"
58
+ ABI_DIR_PATH = Path(__file__).parent / "abis"
59
+ AGENT_REGISTRY_ABI_PATH = ABI_DIR_PATH / "AgentRegistry.json"
60
+ AGENT_MECH_ABI_PATH = ABI_DIR_PATH / "AgentMech.json"
59
61
 
60
62
  MAX_RETRIES = 3
61
63
  WAIT_SLEEP = 3.0
@@ -122,7 +124,6 @@ class MechConfig: # pylint: disable=too-many-instance-attributes
122
124
  wss_endpoint: str
123
125
  ledger_config: LedgerConfig
124
126
  gas_limit: int
125
- contract_abi_url: str
126
127
  transaction_url: str
127
128
  subgraph_url: str
128
129
  price: int
@@ -151,10 +152,6 @@ class MechConfig: # pylint: disable=too-many-instance-attributes
151
152
  if gas_limit:
152
153
  self.gas_limit = int(gas_limit)
153
154
 
154
- contract_abi_url = os.getenv("MECHX_CONTRACT_ABI_URL")
155
- if contract_abi_url:
156
- self.contract_abi_url = contract_abi_url
157
-
158
155
  transaction_url = os.getenv("MECHX_TRANSACTION_URL")
159
156
  if transaction_url:
160
157
  self.transaction_url = transaction_url
@@ -163,13 +160,6 @@ class MechConfig: # pylint: disable=too-many-instance-attributes
163
160
  if subgraph_url:
164
161
  self.subgraph_url = subgraph_url
165
162
 
166
- api_key = os.getenv("MECHX_API_KEY")
167
- if api_key:
168
- updated_contract_abi_url = self.contract_abi_url.replace(
169
- "{api_key}", api_key
170
- )
171
- self.contract_abi_url = updated_contract_abi_url
172
-
173
163
 
174
164
  class ConfirmationType(Enum):
175
165
  """Verification type."""
@@ -222,20 +212,10 @@ def get_event_signatures(abi: List) -> Tuple[str, str]:
222
212
  return request, deliver
223
213
 
224
214
 
225
- def get_abi(contract_address: str, contract_abi_url: str) -> List:
215
+ def get_abi(contract_abi_path: Path) -> List:
226
216
  """Get contract abi"""
227
- abi_request_url = contract_abi_url.format(contract_address=contract_address)
228
- response = requests.get(abi_request_url).json()
229
-
230
- if "result" in response:
231
- result = response["result"]
232
- try:
233
- abi = json.loads(result)
234
- except json.JSONDecodeError:
235
- print("Error: Failed to parse 'result' field as JSON")
236
- sys.exit(1)
237
- else:
238
- abi = response.get("abi")
217
+ with open(contract_abi_path, encoding="utf-8") as f:
218
+ abi = json.load(f)
239
219
 
240
220
  return abi if abi else []
241
221
 
@@ -306,7 +286,7 @@ def verify_or_retrieve_tool(
306
286
  agent_id: int,
307
287
  ledger_api: EthereumApi,
308
288
  agent_registry_contract: str,
309
- contract_abi_url: str,
289
+ contract_abi_path: Path,
310
290
  tool: Optional[str] = None,
311
291
  ) -> str:
312
292
  """
@@ -318,8 +298,8 @@ def verify_or_retrieve_tool(
318
298
  :type ledger_api: EthereumApi
319
299
  :param agent_registry_contract: Agent registry contract address.
320
300
  :type agent_registry_contract: str
321
- :param contract_abi_url: Block explorer URL.
322
- :type contract_abi_url: str
301
+ :param contract_abi_path: Path to agent registry abi.
302
+ :type contract_abi_path: Path
323
303
  :param tool: The tool to verify or retrieve (optional).
324
304
  :type tool: Optional[str]
325
305
  :return: The result of the verification or retrieval.
@@ -330,7 +310,7 @@ def verify_or_retrieve_tool(
330
310
  agent_id=agent_id,
331
311
  ledger_api=ledger_api,
332
312
  agent_registry_contract=agent_registry_contract,
333
- contract_abi_url=contract_abi_url,
313
+ contract_abi_path=contract_abi_path,
334
314
  include_metadata=False, # Ensure this is False to only get the list of tools
335
315
  )
336
316
  # Ensure only the list of tools is used
@@ -348,13 +328,13 @@ def fetch_tools(
348
328
  agent_id: int,
349
329
  ledger_api: EthereumApi,
350
330
  agent_registry_contract: str,
351
- contract_abi_url: str,
331
+ contract_abi_path: Path,
352
332
  include_metadata: bool = False,
353
333
  ) -> Union[List[str], Tuple[List[str], Dict[str, Any]]]:
354
334
  """Fetch tools for specified agent ID, optionally include metadata."""
355
335
  mech_registry = get_contract(
356
336
  contract_address=agent_registry_contract,
357
- abi=get_abi(agent_registry_contract, contract_abi_url),
337
+ abi=get_abi(contract_abi_path),
358
338
  ledger_api=ledger_api,
359
339
  )
360
340
  token_uri = mech_registry.functions.tokenURI(agent_id).call()
@@ -577,8 +557,6 @@ def interact( # pylint: disable=too-many-arguments,too-many-locals
577
557
  ledger_config = mech_config.ledger_config
578
558
  contract_address = query_agent_address(
579
559
  agent_id=agent_id,
580
- timeout=timeout,
581
- url=mech_config.subgraph_url,
582
560
  chain_config=chain_config,
583
561
  )
584
562
  if contract_address is None:
@@ -599,12 +577,9 @@ def interact( # pylint: disable=too-many-arguments,too-many-locals
599
577
  ledger_api=ledger_api,
600
578
  tool=tool,
601
579
  agent_registry_contract=mech_config.agent_registry_contract,
602
- contract_abi_url=mech_config.contract_abi_url,
603
- )
604
- abi = get_abi(
605
- contract_address=contract_address,
606
- contract_abi_url=mech_config.contract_abi_url,
580
+ contract_abi_path=AGENT_REGISTRY_ABI_PATH,
607
581
  )
582
+ abi = get_abi(AGENT_MECH_ABI_PATH)
608
583
  mech_contract = get_contract(
609
584
  contract_address=contract_address, abi=abi, ledger_api=ledger_api
610
585
  )