mech-client 0.2.8__py3-none-any.whl → 0.2.10__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.2.8"
3
+ __version__ = "0.2.10"
mech_client/cli.py CHANGED
@@ -57,12 +57,30 @@ def cli() -> None:
57
57
  ),
58
58
  help="Data verification method (on-chain/off-chain)",
59
59
  )
60
- def interact(
60
+ @click.option(
61
+ "--retries",
62
+ type=int,
63
+ help="Number of retries for sending a transaction",
64
+ )
65
+ @click.option(
66
+ "--timeout",
67
+ type=float,
68
+ help="Timeout to wait for the transaction",
69
+ )
70
+ @click.option(
71
+ "--sleep",
72
+ type=float,
73
+ help="Amount of sleep before retrying the transaction",
74
+ )
75
+ def interact( # pylint: disable=too-many-arguments
61
76
  prompt: str,
62
77
  agent_id: int,
63
78
  tool: Optional[str],
64
79
  key: Optional[str],
65
80
  confirm: Optional[str] = None,
81
+ retries: Optional[int] = None,
82
+ timeout: Optional[float] = None,
83
+ sleep: Optional[float] = None,
66
84
  ) -> None:
67
85
  """Interact with a mech specifying a prompt and tool."""
68
86
  try:
@@ -76,6 +94,9 @@ def interact(
76
94
  if confirm is not None
77
95
  else ConfirmationType.WAIT_FOR_BOTH
78
96
  ),
97
+ retries=retries,
98
+ timeout=timeout,
99
+ sleep=sleep,
79
100
  )
80
101
  except (ValueError, FileNotFoundError) as e:
81
102
  raise click.ClickException(str(e)) from e
mech_client/interact.py CHANGED
@@ -26,17 +26,19 @@ python client.py <prompt> <tool>
26
26
  """
27
27
 
28
28
  import asyncio
29
- import json
30
29
  import os
30
+ import time
31
31
  import warnings
32
+ from datetime import datetime
32
33
  from enum import Enum
33
34
  from pathlib import Path
34
- from typing import Any, List, Optional, Tuple
35
+ from typing import Any, Dict, List, Optional, Tuple
35
36
 
36
37
  import requests
37
38
  import websocket
38
39
  from aea.crypto.base import Crypto
39
40
  from aea_ledger_ethereum import EthereumApi, EthereumCrypto
41
+ from web3 import Web3
40
42
  from web3.contract import Contract as Web3Contract
41
43
 
42
44
  from mech_client.acn import (
@@ -63,6 +65,7 @@ LEDGER_CONFIG = {
63
65
  "chain_id": 100,
64
66
  "poa_chain": False,
65
67
  "default_gas_price_strategy": "eip1559",
68
+ "is_gas_estimation_enabled": False,
66
69
  }
67
70
  PRIVATE_KEY_FILE_PATH = "ethereum_private_key.txt"
68
71
 
@@ -70,7 +73,19 @@ WSS_ENDPOINT = os.getenv(
70
73
  "WEBSOCKET_ENDPOINT",
71
74
  "wss://rpc.eu-central-2.gateway.fm/ws/v4/gnosis/non-archival/mainnet",
72
75
  )
73
- GNOSISSCAN_API_URL = "https://api.gnosisscan.io/api?module=contract&action=getabi&address={contract_address}"
76
+ MANUAL_GAS_LIMIT = int(
77
+ os.getenv(
78
+ "MANUAL_GAS_LIMIT",
79
+ "100_000",
80
+ )
81
+ )
82
+ BLOCKSCOUT_API_URL = (
83
+ "https://gnosis.blockscout.com/api/v2/smart-contracts/{contract_address}"
84
+ )
85
+
86
+ MAX_RETRIES = 3
87
+ WAIT_SLEEP = 3.0
88
+ TIMEOUT = 60.0
74
89
 
75
90
  # Ignore a specific warning message
76
91
  warnings.filterwarnings("ignore", "The log with transaction hash.*")
@@ -84,20 +99,54 @@ class ConfirmationType(Enum):
84
99
  WAIT_FOR_BOTH = "wait-for-both"
85
100
 
86
101
 
87
- def get_contract(contract_address: str, ledger_api: EthereumApi) -> Web3Contract:
102
+ def calculate_topic_id(event: Dict) -> str:
103
+ """Caclulate topic ID"""
104
+ text = event["name"]
105
+ text += "("
106
+ for inp in event["inputs"]:
107
+ text += inp["type"]
108
+ text += ","
109
+ text = text[:-1]
110
+ text += ")"
111
+ return Web3.keccak(text=text).hex()
112
+
113
+
114
+ def get_event_signatures(abi: List) -> Tuple[str, str]:
115
+ """Calculate `Request` and `Deliver` event topics"""
116
+ request, deliver = "", ""
117
+ for obj in abi:
118
+ if obj["type"] != "event":
119
+ continue
120
+ if obj["name"] == "Deliver":
121
+ deliver = calculate_topic_id(event=obj)
122
+ if obj["name"] == "Request":
123
+ request = calculate_topic_id(event=obj)
124
+ return request, deliver
125
+
126
+
127
+ def get_abi(contract_address: str) -> List:
128
+ """Get contract abi"""
129
+ abi_request_url = BLOCKSCOUT_API_URL.format(contract_address=contract_address)
130
+ response = requests.get(abi_request_url).json()
131
+ return response["abi"]
132
+
133
+
134
+ def get_contract(
135
+ contract_address: str, abi: List, ledger_api: EthereumApi
136
+ ) -> Web3Contract:
88
137
  """
89
138
  Returns a contract instance.
90
139
 
91
140
  :param contract_address: The address of the contract.
92
141
  :type contract_address: str
142
+ :param abi: ABI Object
143
+ :type abi: List
93
144
  :param ledger_api: The Ethereum API used for interacting with the ledger.
94
145
  :type ledger_api: EthereumApi
95
146
  :return: The contract instance.
96
147
  :rtype: Web3Contract
97
148
  """
98
- abi_request_url = GNOSISSCAN_API_URL.format(contract_address=contract_address)
99
- response = requests.get(abi_request_url).json()
100
- abi = json.loads(response["result"])
149
+
101
150
  return ledger_api.get_contract_instance(
102
151
  {"abi": abi, "bytecode": "0x"}, contract_address
103
152
  )
@@ -172,20 +221,25 @@ def verify_or_retrieve_tool(
172
221
  def fetch_tools(agent_id: int, ledger_api: EthereumApi) -> List[str]:
173
222
  """Fetch tools for specified agent ID."""
174
223
  mech_registry = get_contract(
175
- contract_address=AGENT_REGISTRY_CONTRACT, ledger_api=ledger_api
224
+ contract_address=AGENT_REGISTRY_CONTRACT,
225
+ abi=get_abi(AGENT_REGISTRY_CONTRACT),
226
+ ledger_api=ledger_api,
176
227
  )
177
228
  token_uri = mech_registry.functions.tokenURI(agent_id).call()
178
229
  response = requests.get(token_uri).json()
179
230
  return response["tools"]
180
231
 
181
232
 
182
- def send_request( # pylint: disable=too-many-arguments
233
+ def send_request( # pylint: disable=too-many-arguments,too-many-locals
183
234
  crypto: EthereumCrypto,
184
235
  ledger_api: EthereumApi,
185
236
  mech_contract: Web3Contract,
186
237
  prompt: str,
187
238
  tool: str,
188
239
  price: int = 10_000_000_000_000_000,
240
+ retries: Optional[int] = None,
241
+ timeout: Optional[float] = None,
242
+ sleep: Optional[float] = None,
189
243
  ) -> None:
190
244
  """
191
245
  Sends a request to the mech.
@@ -202,28 +256,58 @@ def send_request( # pylint: disable=too-many-arguments
202
256
  :type tool: str
203
257
  :param price: The price for the request (default: 10_000_000_000_000_000).
204
258
  :type price: int
259
+ :param retries: Number of retries for sending a transaction
260
+ :type retries: int
261
+ :param timeout: Timeout to wait for the transaction
262
+ :type timeout: float
263
+ :param sleep: Amount of sleep before retrying the transaction
264
+ :type sleep: float
205
265
  """
206
266
  v1_file_hash_hex_truncated, v1_file_hash_hex = push_metadata_to_ipfs(prompt, tool)
207
267
  print(f"Prompt uploaded: https://gateway.autonolas.tech/ipfs/{v1_file_hash_hex}")
208
268
  method_name = "request"
209
269
  methord_args = {"data": v1_file_hash_hex_truncated}
210
- tx_args = {"sender_address": crypto.address, "value": price}
211
- raw_transaction = ledger_api.build_transaction(
212
- contract_instance=mech_contract,
213
- method_name=method_name,
214
- method_args=methord_args,
215
- tx_args=tx_args,
216
- )
217
- raw_transaction["gas"] = 50_000
218
- signed_transaction = crypto.sign_transaction(raw_transaction)
219
- transaction_digest = ledger_api.send_signed_transaction(signed_transaction)
220
- print(f"Transaction sent: https://gnosisscan.io/tx/{transaction_digest}")
221
-
222
-
223
- def wait_for_data_url(
270
+ tx_args = {
271
+ "sender_address": crypto.address,
272
+ "value": price,
273
+ "gas": MANUAL_GAS_LIMIT,
274
+ }
275
+
276
+ tries = 0
277
+ retries = retries or MAX_RETRIES
278
+ timeout = timeout or TIMEOUT
279
+ sleep = sleep or WAIT_SLEEP
280
+ deadline = datetime.now().timestamp() + timeout
281
+
282
+ while tries < retries and datetime.now().timestamp() < deadline:
283
+ tries += 1
284
+ try:
285
+ raw_transaction = ledger_api.build_transaction(
286
+ contract_instance=mech_contract,
287
+ method_name=method_name,
288
+ method_args=methord_args,
289
+ tx_args=tx_args,
290
+ raise_on_try=True,
291
+ )
292
+ signed_transaction = crypto.sign_transaction(raw_transaction)
293
+ transaction_digest = ledger_api.send_signed_transaction(
294
+ signed_transaction,
295
+ raise_on_try=True,
296
+ )
297
+ print(f"Transaction sent: https://gnosisscan.io/tx/{transaction_digest}")
298
+ return
299
+ except Exception as e: # pylint: disable=broad-except
300
+ print(
301
+ f"Error occured while sending the transaction: {e}; Retrying in {sleep}"
302
+ )
303
+ time.sleep(sleep)
304
+
305
+
306
+ def wait_for_data_url( # pylint: disable=too-many-arguments
224
307
  request_id: str,
225
308
  wss: websocket.WebSocket,
226
309
  mech_contract: Web3Contract,
310
+ deliver_signature: str,
227
311
  ledger_api: EthereumApi,
228
312
  crypto: Crypto,
229
313
  ) -> Any:
@@ -236,6 +320,8 @@ def wait_for_data_url(
236
320
  :type wss: websocket.WebSocket
237
321
  :param mech_contract: The mech contract instance.
238
322
  :type mech_contract: Web3Contract
323
+ :param deliver_signature: Topic signature for Deliver event
324
+ :type deliver_signature: str
239
325
  :param ledger_api: The Ethereum API used for interacting with the ledger.
240
326
  :type ledger_api: EthereumApi
241
327
  :param crypto: The cryptographic object.
@@ -250,6 +336,7 @@ def wait_for_data_url(
250
336
  request_id=request_id,
251
337
  wss=wss,
252
338
  mech_contract=mech_contract,
339
+ deliver_signature=deliver_signature,
253
340
  ledger_api=ledger_api,
254
341
  loop=loop,
255
342
  )
@@ -269,12 +356,15 @@ def wait_for_data_url(
269
356
  return result
270
357
 
271
358
 
272
- def interact(
359
+ def interact( # pylint: disable=too-many-arguments,too-many-locals
273
360
  prompt: str,
274
361
  agent_id: int,
275
362
  tool: Optional[str] = None,
276
363
  private_key_path: Optional[str] = None,
277
364
  confirmation_type: ConfirmationType = ConfirmationType.WAIT_FOR_BOTH,
365
+ retries: Optional[int] = None,
366
+ timeout: Optional[float] = None,
367
+ sleep: Optional[float] = None,
278
368
  ) -> Any:
279
369
  """
280
370
  Interact with agent mech contract.
@@ -290,9 +380,15 @@ def interact(
290
380
  :param confirmation_type: The confirmation type for the interaction (default: ConfirmationType.WAIT_FOR_BOTH).
291
381
  :type confirmation_type: ConfirmationType
292
382
  :return: The data received from on-chain/off-chain.
383
+ :param retries: Number of retries for sending a transaction
384
+ :type retries: int
385
+ :param timeout: Timeout to wait for the transaction
386
+ :type timeout: float
387
+ :param sleep: Amount of sleep before retrying the transaction
388
+ :type sleep: float
293
389
  :rtype: Any
294
390
  """
295
- contract_address = query_agent_address(agent_id=agent_id)
391
+ contract_address = query_agent_address(agent_id=agent_id, timeout=timeout)
296
392
  if contract_address is None:
297
393
  raise ValueError(f"Agent with ID {agent_id} does not exist!")
298
394
 
@@ -307,19 +403,33 @@ def interact(
307
403
  ledger_api = EthereumApi(**LEDGER_CONFIG)
308
404
 
309
405
  tool = verify_or_retrieve_tool(agent_id=agent_id, ledger_api=ledger_api, tool=tool)
406
+ abi = get_abi(contract_address=contract_address)
310
407
  mech_contract = get_contract(
311
- contract_address=contract_address, ledger_api=ledger_api
408
+ contract_address=contract_address, abi=abi, ledger_api=ledger_api
409
+ )
410
+ request_event_signature, deliver_event_signature = get_event_signatures(abi=abi)
411
+ register_event_handlers(
412
+ wss=wss,
413
+ contract_address=contract_address,
414
+ crypto=crypto,
415
+ request_signature=request_event_signature,
416
+ deliver_signature=deliver_event_signature,
312
417
  )
313
- register_event_handlers(wss=wss, contract_address=contract_address, crypto=crypto)
314
418
  send_request(
315
419
  crypto=crypto,
316
420
  ledger_api=ledger_api,
317
421
  mech_contract=mech_contract,
318
422
  prompt=prompt,
319
423
  tool=tool,
424
+ retries=retries,
425
+ timeout=timeout,
426
+ sleep=sleep,
320
427
  )
321
428
  request_id = watch_for_request_id(
322
- wss=wss, mech_contract=mech_contract, ledger_api=ledger_api
429
+ wss=wss,
430
+ mech_contract=mech_contract,
431
+ ledger_api=ledger_api,
432
+ request_signature=request_event_signature,
323
433
  )
324
434
  print(f"Created on-chain request with ID {request_id}")
325
435
  if confirmation_type == ConfirmationType.OFF_CHAIN:
@@ -328,6 +438,7 @@ def interact(
328
438
  data_url = watch_for_data_url_from_wss_sync(
329
439
  request_id=request_id,
330
440
  wss=wss,
441
+ deliver_signature=deliver_event_signature,
331
442
  mech_contract=mech_contract,
332
443
  ledger_api=ledger_api,
333
444
  )
@@ -336,6 +447,7 @@ def interact(
336
447
  request_id=request_id,
337
448
  wss=wss,
338
449
  mech_contract=mech_contract,
450
+ deliver_signature=deliver_event_signature,
339
451
  ledger_api=ledger_api,
340
452
  crypto=crypto,
341
453
  )
mech_client/subgraph.py CHANGED
@@ -37,16 +37,22 @@ AGENT_QUERY_TEMPLATE = Template(
37
37
  )
38
38
 
39
39
 
40
- def query_agent_address(agent_id: int) -> Optional[str]:
40
+ def query_agent_address(
41
+ agent_id: int, timeout: Optional[float] = None
42
+ ) -> Optional[str]:
41
43
  """
42
44
  Query agent address from subgraph.
43
45
 
44
46
  :param agent_id: The ID of the agent.
47
+ :param timeout: Timeout for the request.
45
48
  :type agent_id: int
46
49
  :return: The agent address if found, None otherwise.
47
50
  :rtype: Optional[str]
48
51
  """
49
- client = Client(transport=AIOHTTPTransport(url=MECH_SUBGRAPH_URL))
52
+ client = Client(
53
+ transport=AIOHTTPTransport(url=MECH_SUBGRAPH_URL),
54
+ execute_timeout=timeout or 30.0,
55
+ )
50
56
  response = client.execute(
51
57
  document=gql(
52
58
  request_string=AGENT_QUERY_TEMPLATE.substitute({"agent_id": agent_id})
mech_client/wss.py CHANGED
@@ -31,16 +31,12 @@ from aea_ledger_ethereum import EthereumApi
31
31
  from web3.contract import Contract as Web3Contract
32
32
 
33
33
 
34
- EVENT_SIGNATURE_REQUEST = (
35
- "0x4bda649efe6b98b0f9c1d5e859c29e20910f45c66dabfe6fad4a4881f7faf9cc"
36
- )
37
- EVENT_SIGNATURE_DELIVER = (
38
- "0x3ec84da2cdc1ce60c063642b69ff2e65f3b69787a2b90443457ba274e51e7c72"
39
- )
40
-
41
-
42
34
  def register_event_handlers(
43
- wss: websocket.WebSocket, contract_address: str, crypto: Crypto
35
+ wss: websocket.WebSocket,
36
+ contract_address: str,
37
+ crypto: Crypto,
38
+ request_signature: str,
39
+ deliver_signature: str,
44
40
  ) -> None:
45
41
  """
46
42
  Register event handlers.
@@ -51,6 +47,10 @@ def register_event_handlers(
51
47
  :type contract_address: str
52
48
  :param crypto: The cryptographic object.
53
49
  :type crypto: Crypto
50
+ :param request_signature: Topic signature for Request event
51
+ :type request_signature: str
52
+ :param deliver_signature: Topic signature for Deliver event
53
+ :type deliver_signature: str
54
54
  """
55
55
 
56
56
  subscription_request = {
@@ -62,7 +62,7 @@ def register_event_handlers(
62
62
  {
63
63
  "address": contract_address,
64
64
  "topics": [
65
- EVENT_SIGNATURE_REQUEST,
65
+ request_signature,
66
66
  ["0x" + "0" * 24 + crypto.address[2:]],
67
67
  ],
68
68
  },
@@ -79,7 +79,7 @@ def register_event_handlers(
79
79
  "method": "eth_subscribe",
80
80
  "params": [
81
81
  "logs",
82
- {"address": contract_address, "topics": [EVENT_SIGNATURE_DELIVER]},
82
+ {"address": contract_address, "topics": [deliver_signature]},
83
83
  ],
84
84
  }
85
85
  content = bytes(json.dumps(subscription_deliver), "utf-8")
@@ -109,10 +109,11 @@ def wait_for_receipt(tx_hash: str, ledger_api: EthereumApi) -> Dict:
109
109
  time.sleep(1)
110
110
 
111
111
 
112
- def watch_for_request_id(
112
+ def watch_for_request_id( # pylint: disable=too-many-arguments
113
113
  wss: websocket.WebSocket,
114
114
  mech_contract: Web3Contract,
115
115
  ledger_api: EthereumApi,
116
+ request_signature: str,
116
117
  ) -> str:
117
118
  """
118
119
  Watches for events on mech.
@@ -124,6 +125,8 @@ def watch_for_request_id(
124
125
  :param ledger_api: The Ethereum API used for interacting with the ledger.
125
126
  :type ledger_api: EthereumApi
126
127
  :return: The requested ID.
128
+ :param request_signature: Topic signature for Request event
129
+ :type request_signature: str
127
130
  :rtype: str
128
131
  """
129
132
  while True:
@@ -132,7 +135,7 @@ def watch_for_request_id(
132
135
  tx_hash = data["params"]["result"]["transactionHash"]
133
136
  tx_receipt = wait_for_receipt(tx_hash=tx_hash, ledger_api=ledger_api)
134
137
  event_signature = tx_receipt["logs"][0]["topics"][0].hex()
135
- if event_signature != EVENT_SIGNATURE_REQUEST:
138
+ if event_signature != request_signature:
136
139
  continue
137
140
 
138
141
  rich_logs = mech_contract.events.Request().process_receipt(tx_receipt)
@@ -140,10 +143,11 @@ def watch_for_request_id(
140
143
  return request_id
141
144
 
142
145
 
143
- async def watch_for_data_url_from_wss(
146
+ async def watch_for_data_url_from_wss( # pylint: disable=too-many-arguments
144
147
  request_id: str,
145
148
  wss: websocket.WebSocket,
146
149
  mech_contract: Web3Contract,
150
+ deliver_signature: str,
147
151
  ledger_api: EthereumApi,
148
152
  loop: asyncio.AbstractEventLoop,
149
153
  ) -> Any:
@@ -156,6 +160,8 @@ async def watch_for_data_url_from_wss(
156
160
  :type wss: websocket.WebSocket
157
161
  :param mech_contract: The mech contract instance.
158
162
  :type mech_contract: Web3Contract
163
+ :param deliver_signature: Topic signature for Deliver event
164
+ :type deliver_signature: str
159
165
  :param ledger_api: The Ethereum API used for interacting with the ledger.
160
166
  :type ledger_api: EthereumApi
161
167
  :param loop: The event loop used for asynchronous operations.
@@ -172,7 +178,7 @@ async def watch_for_data_url_from_wss(
172
178
  executor, wait_for_receipt, tx_hash, ledger_api
173
179
  )
174
180
  event_signature = tx_receipt["logs"][0]["topics"][0].hex()
175
- if event_signature != EVENT_SIGNATURE_DELIVER:
181
+ if event_signature != deliver_signature:
176
182
  continue
177
183
 
178
184
  rich_logs = mech_contract.events.Deliver().process_receipt(tx_receipt)
@@ -186,6 +192,7 @@ def watch_for_data_url_from_wss_sync(
186
192
  request_id: str,
187
193
  wss: websocket.WebSocket,
188
194
  mech_contract: Web3Contract,
195
+ deliver_signature: str,
189
196
  ledger_api: EthereumApi,
190
197
  ) -> Any:
191
198
  """
@@ -197,6 +204,8 @@ def watch_for_data_url_from_wss_sync(
197
204
  :type wss: websocket.WebSocket
198
205
  :param mech_contract: The mech contract instance.
199
206
  :type mech_contract: Web3Contract
207
+ :param deliver_signature: Topic signature for Deliver event
208
+ :type deliver_signature: str
200
209
  :param ledger_api: The Ethereum API used for interacting with the ledger.
201
210
  :type ledger_api: EthereumApi
202
211
  :return: The data received from on-chain.
@@ -208,6 +217,7 @@ def watch_for_data_url_from_wss_sync(
208
217
  request_id=request_id,
209
218
  wss=wss,
210
219
  mech_contract=mech_contract,
220
+ deliver_signature=deliver_signature,
211
221
  ledger_api=ledger_api,
212
222
  loop=loop,
213
223
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mech-client
3
- Version: 0.2.8
3
+ Version: 0.2.10
4
4
  Summary: Basic client to interact with a mech
5
5
  License: Apache-2.0
6
6
  Author: David Minarsch
@@ -12,10 +12,10 @@ Classifier: Programming Language :: Python :: 3.10
12
12
  Classifier: Programming Language :: Python :: 3.11
13
13
  Requires-Dist: asn1crypto (>=1.4.0,<1.5.0)
14
14
  Requires-Dist: gql (>=3.4.1)
15
- Requires-Dist: open-aea-cli-ipfs (>=1.42.0)
16
- Requires-Dist: open-aea-ledger-cosmos (>=1.42.0)
17
- Requires-Dist: open-aea-ledger-ethereum (>=1.42.0)
18
- Requires-Dist: open-aea[cli] (>=1.42.0)
15
+ Requires-Dist: open-aea-cli-ipfs (==1.50.0)
16
+ Requires-Dist: open-aea-ledger-cosmos (==1.50.0)
17
+ Requires-Dist: open-aea-ledger-ethereum (==1.50.0)
18
+ Requires-Dist: open-aea[cli] (==1.50.0)
19
19
  Requires-Dist: websocket-client (>=0.32.0,<1)
20
20
  Description-Content-Type: text/markdown
21
21
 
@@ -54,7 +54,7 @@ Commands:
54
54
  push-to-ipfs Upload a file to IPFS.
55
55
  ```
56
56
 
57
- ## Usage:
57
+ ## CLI Usage:
58
58
 
59
59
  First, create a private key in file `ethereum_private_key.txt` with this command:
60
60
 
@@ -63,6 +63,12 @@ aea generate-key ethereum
63
63
  ```
64
64
  Ensure the private key carries funds on Gnosis Chain.
65
65
 
66
+ A keyfile is just a file with your ethereum private key as a hex-string, example:
67
+ ```
68
+ 0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcd
69
+ ```
70
+ In case you add your own, make sure you don't have any extra characters in the file, like newlines or spaces.
71
+
66
72
  Second, run the following command to instruct the mech with `<prompt>` and `<agent_id>`:
67
73
 
68
74
  ```bash
@@ -115,6 +121,32 @@ Data arrived: https://gateway.autonolas.tech/ipfs/f0170122069b55e077430a00f3cbc3
115
121
  Data from agent: {'requestId': 81653153529124597849081567361606842861262371002932574194580478443414142139857, 'result': "\n\nA summer breeze, so sweet,\nA gentle reminder of summer's heat.\nThe sky so blue, no cloud in sight,\nA perfect day, a wondrous sight."}
116
122
  ```
117
123
 
124
+ ## Programmatic Usage:
125
+
126
+ ```python
127
+ from mech_client.interact import interact, ConfirmationType
128
+
129
+ prompt_text = 'Will gnosis pay reach 100k cards in 2024?'
130
+ agent_id = 3
131
+ tool_name = "prediction-online"
132
+
133
+ result = interact(
134
+ prompt=prompt_text,
135
+ agent_id=agent_id,
136
+ tool=tool_name,
137
+ confirmation_type=ConfirmationType.ON_CHAIN,
138
+ private_key_path='PATH_HERE'
139
+ )
140
+ print(result)
141
+ ```
142
+
143
+ # Developer installation
144
+ To setup the development environment, run the following commands:
145
+
146
+ ```bash
147
+ poetry install && poetry shell
148
+ ```
149
+
118
150
  ## Release guide:
119
151
 
120
152
  - Bump versions in `pyproject.toml` and `mech_client/__init__.py`
@@ -122,4 +154,5 @@ Data from agent: {'requestId': 8165315352912459784908156736160684286126237100293
122
154
  - `rm -rf dist`
123
155
  - `autonomy packages sync --update-packages`
124
156
  - `make eject-packages`
125
- - then `poetry publish --build --username=<username> --password=<password>`.
157
+ - then create release PR and tag release
158
+
@@ -1,6 +1,6 @@
1
- mech_client/__init__.py,sha256=zScl2uD2b1N1qtPpabcvd0JkACm5pwnP3QnNgdKxeUg,42
1
+ mech_client/__init__.py,sha256=No9VVJJY-aVrNiGRM83B1m0Bb-fXIOl_diX4tfBS_BM,43
2
2
  mech_client/acn.py,sha256=Cz93ykB8Vavd6QSEBnoNv0wylfw2RLOqqu7fIYo4YRY,5790
3
- mech_client/cli.py,sha256=7zwX-LhWIKK9o0I4L0WCCTWSdQLGvHFQvCpnti9wuKw,3359
3
+ mech_client/cli.py,sha256=e6trIN_uoprbvxz41A-x2aUu8kxlyxTAfYv_yZzxmOU,3897
4
4
  mech_client/helpers/__init__.py,sha256=f13zpwGDaKQUjML-5Iq66rRfzg8IS5UNK5I8gBr7w54,1028
5
5
  mech_client/helpers/acn/README.md,sha256=WMXR2Lk0IpWjr3vpZ8cxcTHk4gwsx4wC06UPkwj9dbQ,1641
6
6
  mech_client/helpers/acn/__init__.py,sha256=72WrGEDIuYKvlWQnTajFQ9bNrDy2sFfTYDP62he4doI,1141
@@ -29,14 +29,14 @@ mech_client/helpers/p2p_libp2p_client/README.md,sha256=6x9s6P7TdKkcvAS1wMFHXRz4a
29
29
  mech_client/helpers/p2p_libp2p_client/__init__.py,sha256=-GOP3D_JnmXTDomrMLCbnRk7vRQmihIqTYvyIPzx-q4,879
30
30
  mech_client/helpers/p2p_libp2p_client/connection.py,sha256=pvfHtI-NhgDbay1wLNit6m8InH4c0p00c3hQo0I2jwQ,27887
31
31
  mech_client/helpers/p2p_libp2p_client/connection.yaml,sha256=giYV5FwwugD7ha9IqFHJtvs-Oz1jC5og9rpkstrTqoc,1763
32
- mech_client/interact.py,sha256=1dKQ8xvHKx3aGbciHjVe1YoJSkFgwMw2LLRsGBCRLIA,11558
32
+ mech_client/interact.py,sha256=Dy0WiiATpp6jdPe5iJ14UzXAnRz13GbNjn_UOHugs8Y,14925
33
33
  mech_client/prompt_to_ipfs.py,sha256=IR0NHBd-f4p9bj_HuindJSwrGcc08fdBxavJmpo6GKA,2250
34
34
  mech_client/push_to_ipfs.py,sha256=IfvgaPU79N_ZmCPF9d7sPCYz2uduZH0KjT_HQ2LHXoQ,2059
35
- mech_client/subgraph.py,sha256=1ja0tTUVpTNGmmyXPPBHd-IJSxZgjQWlIEYWVN1iHEM,1815
35
+ mech_client/subgraph.py,sha256=QR9yAxGSDQJDl3J3PeOwUYLMnCNMQyF4UZlNVTAKoMw,1955
36
36
  mech_client/to_png.py,sha256=pjUcFJ63MJj_r73eqnfqCWMtlpsrj6H4ZmgvIEmRcFw,2581
37
- mech_client/wss.py,sha256=k7zhdhg7-EjsNsWv27RZN8rfjlCYxVqTCaqRKHWMIEQ,6826
38
- mech_client-0.2.8.dist-info/LICENSE,sha256=mdBDB-mWKV5Cz4ejBzBiKqan6Z8zVLAh9xwM64O2FW4,11339
39
- mech_client-0.2.8.dist-info/METADATA,sha256=kwCeQQAkkcyvL0wKAI4LtjyMFkhRxfWOePt5D2UUxXQ,4823
40
- mech_client-0.2.8.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
41
- mech_client-0.2.8.dist-info/entry_points.txt,sha256=SbRMRsayzD8XfNXhgwPuXEqQsdZ5Bw9XDPnUuaDExyY,45
42
- mech_client-0.2.8.dist-info/RECORD,,
37
+ mech_client/wss.py,sha256=a9aKz1WADxjx67zH8I48w9L_z8J1N2xWRrBrtyk-UjY,7353
38
+ mech_client-0.2.10.dist-info/LICENSE,sha256=mdBDB-mWKV5Cz4ejBzBiKqan6Z8zVLAh9xwM64O2FW4,11339
39
+ mech_client-0.2.10.dist-info/METADATA,sha256=bPnUfuqr6OX-vv73FqH-Z0Ssnadk0Z8HX5TeMRQCruY,5583
40
+ mech_client-0.2.10.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
41
+ mech_client-0.2.10.dist-info/entry_points.txt,sha256=SbRMRsayzD8XfNXhgwPuXEqQsdZ5Bw9XDPnUuaDExyY,45
42
+ mech_client-0.2.10.dist-info/RECORD,,