mech-client 0.8.2__py3-none-any.whl → 0.10.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.
mech_client/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """Mech client."""
2
2
 
3
- __version__ = "0.8.2"
3
+ __version__ = "0.10.0"
@@ -303,7 +303,13 @@
303
303
  {
304
304
  "indexed": false,
305
305
  "internalType": "bytes",
306
- "name": "data",
306
+ "name": "requestData",
307
+ "type": "bytes"
308
+ },
309
+ {
310
+ "indexed": false,
311
+ "internalType": "bytes",
312
+ "name": "deliveryData",
307
313
  "type": "bytes"
308
314
  }
309
315
  ],
@@ -333,7 +339,7 @@
333
339
  "type": "address"
334
340
  },
335
341
  {
336
- "indexed": true,
342
+ "indexed": false,
337
343
  "internalType": "address[]",
338
344
  "name": "requesters",
339
345
  "type": "address[]"
@@ -442,6 +448,12 @@
442
448
  "internalType": "bytes32[]",
443
449
  "name": "requestIds",
444
450
  "type": "bytes32[]"
451
+ },
452
+ {
453
+ "indexed": false,
454
+ "internalType": "bytes[]",
455
+ "name": "requestDatas",
456
+ "type": "bytes[]"
445
457
  }
446
458
  ],
447
459
  "name": "MarketplaceRequest",
mech_client/cli.py CHANGED
@@ -19,6 +19,7 @@
19
19
 
20
20
  """Mech client CLI module."""
21
21
  import json
22
+ import os
22
23
  from typing import Any, Dict, List, Optional, Tuple
23
24
 
24
25
  import click
@@ -156,6 +157,12 @@ def interact( # pylint: disable=too-many-arguments,too-many-locals
156
157
  use_offchain = use_offchain or False
157
158
  use_prepaid = use_prepaid or use_offchain
158
159
 
160
+ mech_offchain_url = os.getenv("MECHX_MECH_OFFCHAIN_URL")
161
+ if use_offchain and not mech_offchain_url:
162
+ raise Exception(
163
+ "To use offchain requests, please set MECHX_MECH_OFFCHAIN_URL"
164
+ )
165
+
159
166
  if agent_id is None:
160
167
  if len(prompts) != len(tools):
161
168
  raise ClickException(
@@ -167,6 +174,7 @@ def interact( # pylint: disable=too-many-arguments,too-many-locals
167
174
  priority_mech=priority_mech,
168
175
  use_prepaid=use_prepaid,
169
176
  use_offchain=use_offchain,
177
+ mech_offchain_url=mech_offchain_url,
170
178
  private_key_path=key,
171
179
  tools=tools,
172
180
  extra_attributes=extra_attributes_dict,
@@ -50,6 +50,7 @@ from mech_client.interact import (
50
50
  get_event_signatures,
51
51
  get_mech_config,
52
52
  )
53
+ from mech_client.mech_marketplace_tool_management import get_mech_tools
53
54
  from mech_client.prompt_to_ipfs import push_metadata_to_ipfs
54
55
  from mech_client.wss import (
55
56
  register_event_handlers,
@@ -74,6 +75,8 @@ class PaymentType(Enum):
74
75
 
75
76
 
76
77
  IPFS_URL_TEMPLATE = "https://gateway.autonolas.tech/ipfs/f01701220{}"
78
+ MECH_OFFCHAIN_REQUEST_ENDPOINT = "send_signed_requests"
79
+ MECH_OFFCHAIN_DELIVER_ENDPOINT = "fetch_offchain_info"
77
80
  ABI_DIR_PATH = Path(__file__).parent / "abis"
78
81
  IMECH_ABI_PATH = ABI_DIR_PATH / "IMech.json"
79
82
  ITOKEN_ABI_PATH = ABI_DIR_PATH / "IToken.json"
@@ -252,6 +255,9 @@ def fetch_requester_nvm_subscription_balance(
252
255
  nvm_balance_tracker_contract = get_contract(
253
256
  contract_address=mech_payment_balance_tracker, abi=abi, ledger_api=ledger_api
254
257
  )
258
+ requester_balance_tracker_balance = (
259
+ nvm_balance_tracker_contract.functions.mapRequesterBalances(requester).call()
260
+ )
255
261
  subscription_nft_address = (
256
262
  nvm_balance_tracker_contract.functions.subscriptionNFT().call()
257
263
  )
@@ -269,7 +275,7 @@ def fetch_requester_nvm_subscription_balance(
269
275
  requester, subscription_id
270
276
  ).call()
271
277
 
272
- return requester_balance
278
+ return requester_balance_tracker_balance + requester_balance
273
279
 
274
280
 
275
281
  def send_marketplace_request( # pylint: disable=too-many-arguments,too-many-locals
@@ -389,6 +395,7 @@ def send_marketplace_request( # pylint: disable=too-many-arguments,too-many-loc
389
395
  def send_offchain_marketplace_request( # pylint: disable=too-many-arguments,too-many-locals
390
396
  crypto: EthereumCrypto,
391
397
  marketplace_contract: Web3Contract,
398
+ mech_offchain_url: str,
392
399
  prompt: str,
393
400
  tool: str,
394
401
  method_args_data: MechMarketplaceRequestConfig,
@@ -405,6 +412,8 @@ def send_offchain_marketplace_request( # pylint: disable=too-many-arguments,too
405
412
  :type crypto: EthereumCrypto
406
413
  :param marketplace_contract: The mech marketplace contract instance.
407
414
  :type marketplace_contract: Web3Contract
415
+ :param mech_offchain_url: mech url to connect to.
416
+ :type mech_offchain_url: str
408
417
  :param prompt: The request prompt.
409
418
  :type prompt: str
410
419
  :param tool: The requested tool.
@@ -469,9 +478,9 @@ def send_offchain_marketplace_request( # pylint: disable=too-many-arguments,too
469
478
  "nonce": nonce,
470
479
  "ipfs_data": ipfs_data,
471
480
  }
472
- # @todo changed hardcoded url
481
+ url = mech_offchain_url + MECH_OFFCHAIN_REQUEST_ENDPOINT
473
482
  response = requests.post(
474
- "http://localhost:8000/send_signed_requests",
483
+ url=url,
475
484
  data=payload,
476
485
  headers={"Content-Type": "application/json"},
477
486
  ).json()
@@ -562,10 +571,12 @@ def wait_for_marketplace_data_url( # pylint: disable=too-many-arguments, unused
562
571
  return result
563
572
 
564
573
 
565
- def wait_for_offchain_marketplace_data(request_id: str) -> Any:
574
+ def wait_for_offchain_marketplace_data(mech_offchain_url: str, request_id: str) -> Any:
566
575
  """
567
576
  Watches for data off-chain on mech.
568
577
 
578
+ :param mech_offchain_url: mech url to connect to.
579
+ :type mech_offchain_url: str
569
580
  :param request_id: The ID of the request.
570
581
  :type request_id: str
571
582
  :return: The data returned by the mech.
@@ -573,15 +584,17 @@ def wait_for_offchain_marketplace_data(request_id: str) -> Any:
573
584
  """
574
585
  while True:
575
586
  try:
576
- # @todo change hardcoded url
587
+ url = mech_offchain_url + MECH_OFFCHAIN_DELIVER_ENDPOINT
577
588
  response = requests.get(
578
- "http://localhost:8000/fetch_offchain_info",
589
+ url=url,
579
590
  data={"request_id": request_id},
580
591
  ).json()
581
592
  if response:
582
593
  return response
594
+
595
+ time.sleep(WAIT_SLEEP)
583
596
  except Exception: # pylint: disable=broad-except
584
- time.sleep(1)
597
+ time.sleep(WAIT_SLEEP)
585
598
 
586
599
 
587
600
  def check_prepaid_balances(
@@ -633,11 +646,36 @@ def check_prepaid_balances(
633
646
  sys.exit(1)
634
647
 
635
648
 
649
+ def verify_tools(tools: tuple, service_id: int, chain_config: Optional[str]) -> None:
650
+ """
651
+ Verifies user supplied tool(s) with the mech's metadata
652
+
653
+ :param tools: The user supplied tools.
654
+ :type tools: tuple
655
+ :param service_id: Service id of the mech.
656
+ :type service_id: int
657
+ :param chain_config: Id of the mech's chain configuration (stored configs/mechs.json)
658
+ :type chain_config: str
659
+ :rtype: None
660
+ """
661
+ mech_tools_data = get_mech_tools(service_id=service_id, chain_config=chain_config)
662
+ if not mech_tools_data:
663
+ raise ValueError("Error while fetching mech tools data")
664
+
665
+ mech_tools = mech_tools_data.get("tools", [])
666
+ invalid_tools = [tool for tool in tools if tool not in mech_tools]
667
+ if invalid_tools:
668
+ raise ValueError(
669
+ f"Tool(s) {invalid_tools} not found in mech tools: {mech_tools}"
670
+ )
671
+
672
+
636
673
  def marketplace_interact( # pylint: disable=too-many-arguments, too-many-locals, too-many-statements, too-many-return-statements
637
674
  prompts: tuple,
638
675
  priority_mech: str,
639
676
  use_prepaid: bool = False,
640
677
  use_offchain: bool = False,
678
+ mech_offchain_url: str = "",
641
679
  tools: tuple = (),
642
680
  extra_attributes: Optional[Dict[str, Any]] = None,
643
681
  private_key_path: Optional[str] = None,
@@ -658,6 +696,8 @@ def marketplace_interact( # pylint: disable=too-many-arguments, too-many-locals
658
696
  :type use_prepaid: bool
659
697
  :param use_offchain: Whether to use offchain model or not.
660
698
  :type use_offchain: bool
699
+ :param mech_offchain_url: mech url to connect to.
700
+ :type mech_offchain_url: str
661
701
  :param tools: The tools to interact with (optional).
662
702
  :type tools: tuple
663
703
  :param extra_attributes: Extra attributes to be included in the request metadata (optional).
@@ -732,7 +772,7 @@ def marketplace_interact( # pylint: disable=too-many-arguments, too-many-locals
732
772
  )
733
773
  (
734
774
  payment_type,
735
- _,
775
+ service_id,
736
776
  max_delivery_rate,
737
777
  mech_payment_balance_tracker,
738
778
  mech_contract,
@@ -744,6 +784,8 @@ def marketplace_interact( # pylint: disable=too-many-arguments, too-many-locals
744
784
  mech_marketplace_request_config.delivery_rate = max_delivery_rate
745
785
  mech_marketplace_request_config.payment_type = payment_type
746
786
 
787
+ verify_tools(tools, service_id, chain_config)
788
+
747
789
  with open(IMECH_ABI_PATH, encoding="utf-8") as f:
748
790
  abi = json.load(f)
749
791
 
@@ -792,22 +834,29 @@ def marketplace_interact( # pylint: disable=too-many-arguments, too-many-locals
792
834
  max_delivery_rate,
793
835
  )
794
836
 
795
- if payment_type in [PaymentType.NATIVE_NVM.value, PaymentType.TOKEN_NVM.value]:
837
+ is_nvm_mech = payment_type in [
838
+ PaymentType.NATIVE_NVM.value,
839
+ PaymentType.TOKEN_NVM.value,
840
+ ]
841
+ if is_nvm_mech:
796
842
  nvm_mech_type = PaymentType(payment_type).name.lower()
797
843
  print(
798
844
  f"{nvm_mech_type} Nevermined Mech detected, subscription credits to be used"
799
845
  )
800
846
  requester = crypto.address
801
- requester_balance = fetch_requester_nvm_subscription_balance(
847
+ requester_total_balance_before = fetch_requester_nvm_subscription_balance(
802
848
  requester, ledger_api, mech_payment_balance_tracker, payment_type
803
849
  )
804
- if requester_balance < price:
850
+ if requester_total_balance_before < price:
805
851
  print(
806
- f" - Sender Subscription balance low. Needed: {price}, Actual: {requester_balance}"
852
+ f" - Sender Subscription balance low. Needed: {price}, Actual: {requester_total_balance_before}"
807
853
  )
808
854
  print(f" - Sender Address: {requester}")
809
855
  sys.exit(1)
810
856
 
857
+ print(
858
+ f" - Sender Subscription balance before request: {requester_total_balance_before}"
859
+ )
811
860
  # set price 0 to not send any msg.value in request transaction for nvm type mech
812
861
  price = 0
813
862
 
@@ -868,6 +917,19 @@ def marketplace_interact( # pylint: disable=too-many-arguments, too-many-locals
868
917
  )
869
918
 
870
919
  if data_url:
920
+ if is_nvm_mech:
921
+ requester_total_balance_after = (
922
+ fetch_requester_nvm_subscription_balance(
923
+ requester,
924
+ ledger_api,
925
+ mech_payment_balance_tracker,
926
+ payment_type,
927
+ )
928
+ )
929
+ print(
930
+ f" - Sender Subscription balance after delivery: {requester_total_balance_after}"
931
+ )
932
+
871
933
  print(f" - Data arrived: {data_url}")
872
934
  data = requests.get(f"{data_url}/{request_id_int}", timeout=30).json()
873
935
  print(" - Data from agent:")
@@ -882,6 +944,7 @@ def marketplace_interact( # pylint: disable=too-many-arguments, too-many-locals
882
944
  response = send_offchain_marketplace_request(
883
945
  crypto=crypto,
884
946
  marketplace_contract=mech_marketplace_contract,
947
+ mech_offchain_url=mech_offchain_url,
885
948
  prompt=prompts[0],
886
949
  tool=tools[0],
887
950
  method_args_data=mech_marketplace_request_config,
@@ -910,6 +973,7 @@ def marketplace_interact( # pylint: disable=too-many-arguments, too-many-locals
910
973
 
911
974
  for request_id in request_ids:
912
975
  data = wait_for_offchain_marketplace_data(
976
+ mech_offchain_url=mech_offchain_url,
913
977
  request_id=request_id,
914
978
  )
915
979
 
@@ -7,8 +7,9 @@ from typing import Any, Dict, List, Optional, Tuple
7
7
 
8
8
  import requests
9
9
  from aea_ledger_ethereum import EthereumApi
10
+ from web3.constants import ADDRESS_ZERO
10
11
 
11
- from mech_client.marketplace_interact import ADDRESS_ZERO, get_contract, get_mech_config
12
+ from mech_client.interact import get_contract, get_mech_config
12
13
 
13
14
 
14
15
  ABI_DIR_PATH = Path(__file__).parent / "abis"
@@ -58,7 +59,7 @@ def fetch_tools(
58
59
 
59
60
 
60
61
  def get_mech_tools(
61
- service_id: int, chain_config: str = DEFAULT_CONFIG
62
+ service_id: int, chain_config: Optional[str] = DEFAULT_CONFIG
62
63
  ) -> Optional[Dict[str, Any]]:
63
64
  """
64
65
  Fetch tools for a given mech's service ID.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mech-client
3
- Version: 0.8.2
3
+ Version: 0.10.0
4
4
  Summary: Basic client to interact with a mech
5
5
  License: Apache-2.0
6
6
  Author: David Minarsch
@@ -237,6 +237,16 @@ Additionally to other options which are the same as for legacy Mechs, this usage
237
237
 
238
238
  `--use-prepaid <bool>`: use the prepaid method to send requests to a Mech via the Mech Marketplace. Defaults to False. <br>
239
239
  `--use-offchain <bool>`: use the off-chain method to send requests to a Mech via the Mech Marketplace. Defaults to False.
240
+ > To use offchain requests using `--use-offchain` flag, export the `MECHX_MECH_OFFCHAIN_URL` env variable before sending requests. For example if you want to connect to a mech running locally, you can do the following
241
+ ```bash
242
+ export MECHX_MECH_OFFCHAIN_URL="http://localhost:8000/"
243
+ ```
244
+ If you want to use a Valory mech for offchain requests, below is the list of mechs and their address and offchain urls.
245
+
246
+ | Service ID | Priority Mech Address | Offchain URL |
247
+ | :---: | :---: | :---: |
248
+ | 2182 | 0xB3C6319962484602b00d5587e965946890b82101 | https://d19715222af5b940.agent.propel.autonolas.tech/ |
249
+
240
250
 
241
251
  The Mech Client can also be used to send batch requests. There are couple of different ways to achieve this:
242
252
 
@@ -1,4 +1,4 @@
1
- mech_client/__init__.py,sha256=Pkp7D9ID9xxFUuGrdGofoB2cTeMVMTpQeST3H0GcIps,42
1
+ mech_client/__init__.py,sha256=zubatTm13iBIEOwOE74QFlqg6tpFL5v53x4lS6XYY0U,43
2
2
  mech_client/abis/AgentMech.json,sha256=IEbs_xBGunBu5h-uT5DvIty8Zw412QoPI46S_DUMYNw,18082
3
3
  mech_client/abis/AgentRegistry.json,sha256=2qmXeFINZWz9pyOma6Bq67kMDSUI1lD7WvgHLwuETD8,24723
4
4
  mech_client/abis/AgreementStoreManager.base.json,sha256=_ljdIZcfFGmFzBHUTfhA4X0382ZHHpkdr_CziTwUETo,34360
@@ -17,7 +17,7 @@ mech_client/abis/IMech.json,sha256=km0NMRyqBYh3jBQwPJCispsRfPwqNJ67kkZwYjuJci4,3
17
17
  mech_client/abis/IToken.json,sha256=VrzR6Rr1DmrUzy5DygN1rKm6df4ir2KGdWsunZnuRKo,19637
18
18
  mech_client/abis/LockPaymentCondition.base.json,sha256=mGOi_xYyH7gCzLyWu7nk_Ta46tpLNxoPAgbjQvKNQtA,43424
19
19
  mech_client/abis/LockPaymentCondition.gnosis.json,sha256=ofYQo6JYSE_7Q4LPHxoOZI2qFMddSWcfVoCW-6k9KnY,43424
20
- mech_client/abis/MechMarketplace.json,sha256=auKTxPTi07yD98Gz2RuwH1Gq5qRCyy8-C7QBNj3uto8,32104
20
+ mech_client/abis/MechMarketplace.json,sha256=KPnF-H_UATb3wdb_7o6ky_hSp5xwgvckD-QqylsWJLg,32468
21
21
  mech_client/abis/NFTSalesTemplate.base.json,sha256=blheE2NNxCt3ttklcsAF9WrIcnsvywAZ8jICjGVl4lQ,37995
22
22
  mech_client/abis/NFTSalesTemplate.gnosis.json,sha256=6fKoxvTSQWOGQq_Yik09R8JTMRxXIPgoOC_HSAf5A7Q,37995
23
23
  mech_client/abis/NeverminedConfig.base.json,sha256=0p_GV87fsBvlN6VNDm_T1ykjzD4yZKlR9-jDpo1_RRU,21221
@@ -30,7 +30,7 @@ mech_client/abis/SubscriptionToken.base.json,sha256=5StPEyfRvDMTqtQPO-KakXXZqobX
30
30
  mech_client/abis/TransferNFTCondition.base.json,sha256=71O_3itHBz9qPtoTLev8_a7KxlcQfIZSfxK2562lkqw,42540
31
31
  mech_client/abis/TransferNFTCondition.gnosis.json,sha256=-huhxV54eoNY8mR9WtQdmSgQDgaKiUi0PULJ4HEshWw,42540
32
32
  mech_client/acn.py,sha256=Rj_jLPvJ5loDQfGbu3a_O24cJC4SwIErLceSz_zVYS8,5356
33
- mech_client/cli.py,sha256=XezX27Y0VdnUq8HmHF6HxyhPmsC91YuLSuqAoi41UrE,17655
33
+ mech_client/cli.py,sha256=CgpembCl3JTubCgUYw7-one6cuge8YlUTHfoIkhbZu4,17957
34
34
  mech_client/configs/mechs.json,sha256=Zv8JrY6yvNsSxTP7RchvR1yz2k3yjYUZkuSILnPbWzg,5445
35
35
  mech_client/fetch_ipfs_hash.py,sha256=tg_hYVf4deXl89x3SOBrGFUthaSeN_Vg_OHDtfjdbp4,2752
36
36
  mech_client/helpers/__init__.py,sha256=nmQig1EqBQ9EMOpgdykP3a6_2NWcoVH3-lnyHP5n0ws,1196
@@ -62,8 +62,8 @@ mech_client/helpers/p2p_libp2p_client/__init__.py,sha256=-GOP3D_JnmXTDomrMLCbnRk
62
62
  mech_client/helpers/p2p_libp2p_client/connection.py,sha256=b5jfcUeSoNrUw8DOSTCbK4DTi-N8bf2_pdogUOz0ep0,28606
63
63
  mech_client/helpers/p2p_libp2p_client/connection.yaml,sha256=nMiHnU_dv9EFjVNqZ-0SAnoATfadJSad-JsbDvk97Mk,1790
64
64
  mech_client/interact.py,sha256=52UW5NysSTIC--APLpJde8VvrruWeYFCFzO02uRQpwc,21288
65
- mech_client/marketplace_interact.py,sha256=rRIHYLzuaXYW7vh4fvNh9KBbUY4tgoavmMxFaPg0Rkw,33045
66
- mech_client/mech_marketplace_tool_management.py,sha256=q_cXyJGI1rLXKB_Ds21eQLCzUhTYE9BHN48wqIw0w6g,7341
65
+ mech_client/marketplace_interact.py,sha256=24louKzqpgDVYmuOIwZQzIVnZwPLXhkF2LPSQVrEuvE,35554
66
+ mech_client/mech_marketplace_tool_management.py,sha256=G1O0ajbeltRM5FpqPfmn2C4QRrwqf5HfWKUH2VKn6UA,7365
67
67
  mech_client/mech_tool_management.py,sha256=NQFmVzzGZsIkeHokDPWXGHwa8u-pyQIMPR1Q5H81bKw,7806
68
68
  mech_client/prompt_to_ipfs.py,sha256=XqSIBko15MEkpWOQNT97fRI6jNxMF5EDBDEPOJFdhyk,2533
69
69
  mech_client/push_to_ipfs.py,sha256=IfvgaPU79N_ZmCPF9d7sPCYz2uduZH0KjT_HQ2LHXoQ,2059
@@ -92,8 +92,8 @@ scripts/nvm_subscription/manager.py,sha256=y0Qh0aVAmOPB4Ytt93alIarSvhrQpC-lRYNAY
92
92
  scripts/nvm_subscription/resources/networks.json,sha256=xH0P3YkgkMTkQdahVKO0kI9m6ybJ67iwHApstUlfRmw,2359
93
93
  scripts/utils.py,sha256=lXjY3s1HvNHT2fXm2fBpZtVvlQaqW288Y2S-s3rpSDM,3248
94
94
  scripts/whitelist.py,sha256=-TF4fcojBmF6a7fXleBk96DvJ-xWkNGoN0s_8r8J20Q,289
95
- mech_client-0.8.2.dist-info/LICENSE,sha256=mdBDB-mWKV5Cz4ejBzBiKqan6Z8zVLAh9xwM64O2FW4,11339
96
- mech_client-0.8.2.dist-info/METADATA,sha256=SUPx34q_S9D-15xJ8rGTgwPTBiZ7VL5VvBCkWKayBPA,25165
97
- mech_client-0.8.2.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
98
- mech_client-0.8.2.dist-info/entry_points.txt,sha256=SbRMRsayzD8XfNXhgwPuXEqQsdZ5Bw9XDPnUuaDExyY,45
99
- mech_client-0.8.2.dist-info/RECORD,,
95
+ mech_client-0.10.0.dist-info/LICENSE,sha256=mdBDB-mWKV5Cz4ejBzBiKqan6Z8zVLAh9xwM64O2FW4,11339
96
+ mech_client-0.10.0.dist-info/METADATA,sha256=wXMRgH_HN3Kg0yt4k9rsfySvc6XL-TmQkyqKQ-3rtto,25936
97
+ mech_client-0.10.0.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
98
+ mech_client-0.10.0.dist-info/entry_points.txt,sha256=SbRMRsayzD8XfNXhgwPuXEqQsdZ5Bw9XDPnUuaDExyY,45
99
+ mech_client-0.10.0.dist-info/RECORD,,