mech-client 0.2.14__py3-none-any.whl → 0.2.16__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 +1 -1
- mech_client/cli.py +95 -2
- mech_client/interact.py +35 -15
- mech_client/mech_tool_management.py +181 -0
- {mech_client-0.2.14.dist-info → mech_client-0.2.16.dist-info}/METADATA +145 -5
- {mech_client-0.2.14.dist-info → mech_client-0.2.16.dist-info}/RECORD +9 -8
- {mech_client-0.2.14.dist-info → mech_client-0.2.16.dist-info}/LICENSE +0 -0
- {mech_client-0.2.14.dist-info → mech_client-0.2.16.dist-info}/WHEEL +0 -0
- {mech_client-0.2.14.dist-info → mech_client-0.2.16.dist-info}/entry_points.txt +0 -0
mech_client/__init__.py
CHANGED
mech_client/cli.py
CHANGED
|
@@ -18,14 +18,20 @@
|
|
|
18
18
|
# ------------------------------------------------------------------------------
|
|
19
19
|
|
|
20
20
|
"""Mech client CLI module."""
|
|
21
|
-
|
|
22
|
-
from typing import Any, Dict, List, Optional
|
|
21
|
+
import json
|
|
22
|
+
from typing import Any, Dict, List, Optional, Tuple
|
|
23
23
|
|
|
24
24
|
import click
|
|
25
|
+
from tabulate import tabulate # type: ignore
|
|
25
26
|
|
|
26
27
|
from mech_client import __version__
|
|
27
28
|
from mech_client.interact import ConfirmationType
|
|
28
29
|
from mech_client.interact import interact as interact_
|
|
30
|
+
from mech_client.mech_tool_management import (
|
|
31
|
+
get_tool_description,
|
|
32
|
+
get_tool_io_schema,
|
|
33
|
+
get_tools_for_agents,
|
|
34
|
+
)
|
|
29
35
|
from mech_client.prompt_to_ipfs import main as prompt_to_ipfs_main
|
|
30
36
|
from mech_client.push_to_ipfs import main as push_to_ipfs_main
|
|
31
37
|
from mech_client.to_png import main as to_png_main
|
|
@@ -148,10 +154,97 @@ def to_png(ipfs_hash: str, path: str, request_id: str) -> None:
|
|
|
148
154
|
to_png_main(ipfs_hash, path, request_id)
|
|
149
155
|
|
|
150
156
|
|
|
157
|
+
@click.command(name="tools-for-agents")
|
|
158
|
+
@click.option(
|
|
159
|
+
"--agent-id",
|
|
160
|
+
type=int,
|
|
161
|
+
help="Agent ID to fetch tools for. If not provided, fetches for all agents.",
|
|
162
|
+
)
|
|
163
|
+
@click.option("--chain-config", default="gnosis", help="Chain configuration to use.")
|
|
164
|
+
def tools_for_agents(agent_id: Optional[int], chain_config: str) -> None:
|
|
165
|
+
"""Fetch and display tools for agents."""
|
|
166
|
+
try:
|
|
167
|
+
result = get_tools_for_agents(agent_id, chain_config)
|
|
168
|
+
|
|
169
|
+
if agent_id is not None:
|
|
170
|
+
headers = ["Tool Name", "Unique Identifier"]
|
|
171
|
+
data: List[Tuple[str, ...]] = [
|
|
172
|
+
(str(tool["tool_name"]), str(tool["unique_identifier"]))
|
|
173
|
+
for tool in result["tools"]
|
|
174
|
+
]
|
|
175
|
+
else:
|
|
176
|
+
headers = ["Agent ID", "Tool Name", "Unique Identifier"]
|
|
177
|
+
data = [
|
|
178
|
+
(str(agent_id), str(tool_name), f"{agent_id}-{tool_name}")
|
|
179
|
+
for agent_id, tools in result["agent_tools_map"].items()
|
|
180
|
+
for tool_name in tools
|
|
181
|
+
]
|
|
182
|
+
|
|
183
|
+
click.echo(tabulate(data, headers=headers, tablefmt="grid"))
|
|
184
|
+
except (KeyError, TypeError) as e:
|
|
185
|
+
click.echo(f"Error processing tool data: {str(e)}")
|
|
186
|
+
except json.JSONDecodeError as e:
|
|
187
|
+
click.echo(f"Error decoding JSON response: {str(e)}")
|
|
188
|
+
except IOError as e:
|
|
189
|
+
click.echo(f"Network or I/O error: {str(e)}")
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
@click.command(name="tool-description")
|
|
193
|
+
@click.argument("tool_id")
|
|
194
|
+
@click.option("--chain-config", default="gnosis", help="Chain configuration to use.")
|
|
195
|
+
def tool_description(tool_id: str, chain_config: str) -> None:
|
|
196
|
+
"""Fetch and display the description of a specific tool."""
|
|
197
|
+
try:
|
|
198
|
+
description = get_tool_description(tool_id, chain_config)
|
|
199
|
+
click.echo(f"Description for tool {tool_id}: {description}")
|
|
200
|
+
except KeyError as e:
|
|
201
|
+
click.echo(f"Tool not found or missing description: {str(e)}")
|
|
202
|
+
except json.JSONDecodeError as e:
|
|
203
|
+
click.echo(f"Error decoding JSON response: {str(e)}")
|
|
204
|
+
except IOError as e:
|
|
205
|
+
click.echo(f"Network or I/O error: {str(e)}")
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
@click.command(name="tool-io-schema")
|
|
209
|
+
@click.argument("tool_id")
|
|
210
|
+
@click.option("--chain-config", default="gnosis", help="Chain configuration to use.")
|
|
211
|
+
def tool_io_schema(tool_id: str, chain_config: str) -> None:
|
|
212
|
+
"""Fetch and display the input/output schema for a specific tool."""
|
|
213
|
+
try:
|
|
214
|
+
io_schema = get_tool_io_schema(tool_id, chain_config)
|
|
215
|
+
# Prepare data for tabulation
|
|
216
|
+
input_schema = [(key, io_schema["input"][key]) for key in io_schema["input"]]
|
|
217
|
+
|
|
218
|
+
# Handling nested output schema
|
|
219
|
+
output_schema = []
|
|
220
|
+
if "properties" in io_schema["output"]["schema"]:
|
|
221
|
+
for key, value in io_schema["output"]["schema"]["properties"].items():
|
|
222
|
+
output_schema.append((key, value["type"], value.get("description", "")))
|
|
223
|
+
|
|
224
|
+
# Display schemas in tabulated format
|
|
225
|
+
click.echo("Input Schema:")
|
|
226
|
+
click.echo(tabulate(input_schema, headers=["Field", "Value"], tablefmt="grid"))
|
|
227
|
+
click.echo("Output Schema:")
|
|
228
|
+
click.echo(
|
|
229
|
+
tabulate(
|
|
230
|
+
output_schema, headers=["Field", "Type", "Description"], tablefmt="grid"
|
|
231
|
+
)
|
|
232
|
+
)
|
|
233
|
+
except KeyError as e:
|
|
234
|
+
click.echo(f"Error accessing schema data: {str(e)}")
|
|
235
|
+
except json.JSONDecodeError as e:
|
|
236
|
+
click.echo(f"Error decoding JSON response: {str(e)}")
|
|
237
|
+
except IOError as e:
|
|
238
|
+
click.echo(f"Network or I/O error: {str(e)}")
|
|
239
|
+
|
|
240
|
+
|
|
151
241
|
cli.add_command(interact)
|
|
152
242
|
cli.add_command(prompt_to_ipfs)
|
|
153
243
|
cli.add_command(push_to_ipfs)
|
|
154
244
|
cli.add_command(to_png)
|
|
245
|
+
cli.add_command(tools_for_agents)
|
|
246
|
+
cli.add_command(tool_io_schema)
|
|
247
|
+
cli.add_command(tool_description)
|
|
155
248
|
|
|
156
249
|
|
|
157
250
|
if __name__ == "__main__":
|
mech_client/interact.py
CHANGED
|
@@ -35,7 +35,7 @@ from dataclasses import asdict, dataclass
|
|
|
35
35
|
from datetime import datetime
|
|
36
36
|
from enum import Enum
|
|
37
37
|
from pathlib import Path
|
|
38
|
-
from typing import Any, Dict, List, Optional, Tuple
|
|
38
|
+
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
39
39
|
|
|
40
40
|
import requests
|
|
41
41
|
import websocket
|
|
@@ -160,10 +160,10 @@ def get_mech_config(chain_config: Optional[str] = None) -> MechConfig:
|
|
|
160
160
|
if chain_config is None:
|
|
161
161
|
chain_config = next(iter(data))
|
|
162
162
|
|
|
163
|
-
print(f"Chain configuration: {chain_config}")
|
|
164
163
|
entry = data[chain_config].copy()
|
|
165
164
|
ledger_config = LedgerConfig(**entry.pop("ledger_config"))
|
|
166
165
|
mech_config = MechConfig(**entry, ledger_config=ledger_config)
|
|
166
|
+
|
|
167
167
|
return mech_config
|
|
168
168
|
|
|
169
169
|
|
|
@@ -295,12 +295,16 @@ def verify_or_retrieve_tool(
|
|
|
295
295
|
:return: The result of the verification or retrieval.
|
|
296
296
|
:rtype: str
|
|
297
297
|
"""
|
|
298
|
-
|
|
298
|
+
# Fetch tools, possibly including metadata
|
|
299
|
+
tools_data = fetch_tools(
|
|
299
300
|
agent_id=agent_id,
|
|
300
301
|
ledger_api=ledger_api,
|
|
301
302
|
agent_registry_contract=agent_registry_contract,
|
|
302
303
|
contract_abi_url=contract_abi_url,
|
|
304
|
+
include_metadata=False, # Ensure this is False to only get the list of tools
|
|
303
305
|
)
|
|
306
|
+
# Ensure only the list of tools is used
|
|
307
|
+
available_tools = tools_data if isinstance(tools_data, list) else tools_data[0]
|
|
304
308
|
if tool is not None and tool not in available_tools:
|
|
305
309
|
raise ValueError(
|
|
306
310
|
f"Provided tool `{tool}` not in the list of available tools; Available tools={available_tools}"
|
|
@@ -315,8 +319,9 @@ def fetch_tools(
|
|
|
315
319
|
ledger_api: EthereumApi,
|
|
316
320
|
agent_registry_contract: str,
|
|
317
321
|
contract_abi_url: str,
|
|
318
|
-
|
|
319
|
-
|
|
322
|
+
include_metadata: bool = False,
|
|
323
|
+
) -> Union[List[str], Tuple[List[str], Dict[str, Any]]]:
|
|
324
|
+
"""Fetch tools for specified agent ID, optionally include metadata."""
|
|
320
325
|
mech_registry = get_contract(
|
|
321
326
|
contract_address=agent_registry_contract,
|
|
322
327
|
abi=get_abi(agent_registry_contract, contract_abi_url),
|
|
@@ -324,7 +329,12 @@ def fetch_tools(
|
|
|
324
329
|
)
|
|
325
330
|
token_uri = mech_registry.functions.tokenURI(agent_id).call()
|
|
326
331
|
response = requests.get(token_uri).json()
|
|
327
|
-
|
|
332
|
+
tools = response.get("tools", [])
|
|
333
|
+
|
|
334
|
+
if include_metadata:
|
|
335
|
+
tool_metadata = response.get("toolMetadata", {})
|
|
336
|
+
return tools, tool_metadata
|
|
337
|
+
return tools
|
|
328
338
|
|
|
329
339
|
|
|
330
340
|
def send_request( # pylint: disable=too-many-arguments,too-many-locals
|
|
@@ -371,7 +381,9 @@ def send_request( # pylint: disable=too-many-arguments,too-many-locals
|
|
|
371
381
|
v1_file_hash_hex_truncated, v1_file_hash_hex = push_metadata_to_ipfs(
|
|
372
382
|
prompt, tool, extra_attributes
|
|
373
383
|
)
|
|
374
|
-
print(
|
|
384
|
+
print(
|
|
385
|
+
f" - Prompt uploaded: https://gateway.autonolas.tech/ipfs/{v1_file_hash_hex}"
|
|
386
|
+
)
|
|
375
387
|
method_name = "request"
|
|
376
388
|
methord_args = {"data": v1_file_hash_hex_truncated}
|
|
377
389
|
tx_args = {
|
|
@@ -573,7 +585,7 @@ def interact( # pylint: disable=too-many-arguments,too-many-locals
|
|
|
573
585
|
request_signature=request_event_signature,
|
|
574
586
|
deliver_signature=deliver_event_signature,
|
|
575
587
|
)
|
|
576
|
-
print("Sending request...")
|
|
588
|
+
print("Sending Mech request...")
|
|
577
589
|
transaction_digest = send_request(
|
|
578
590
|
crypto=crypto,
|
|
579
591
|
ledger_api=ledger_api,
|
|
@@ -586,19 +598,26 @@ def interact( # pylint: disable=too-many-arguments,too-many-locals
|
|
|
586
598
|
timeout=timeout,
|
|
587
599
|
sleep=sleep,
|
|
588
600
|
)
|
|
601
|
+
|
|
602
|
+
if not transaction_digest:
|
|
603
|
+
print("Unable to send request")
|
|
604
|
+
return None
|
|
605
|
+
|
|
589
606
|
transaction_url_formatted = mech_config.transaction_url.format(
|
|
590
607
|
transaction_digest=transaction_digest
|
|
591
608
|
)
|
|
592
|
-
print(f"Transaction sent: {transaction_url_formatted}")
|
|
593
|
-
print("Waiting for transaction receipt...")
|
|
609
|
+
print(f" - Transaction sent: {transaction_url_formatted}")
|
|
610
|
+
print(" - Waiting for transaction receipt...")
|
|
594
611
|
request_id = watch_for_request_id(
|
|
595
612
|
wss=wss,
|
|
596
613
|
mech_contract=mech_contract,
|
|
597
614
|
ledger_api=ledger_api,
|
|
598
615
|
request_signature=request_event_signature,
|
|
599
616
|
)
|
|
600
|
-
print(f"Created on-chain request with ID {request_id}")
|
|
601
|
-
print("
|
|
617
|
+
print(f" - Created on-chain request with ID {request_id}")
|
|
618
|
+
print("")
|
|
619
|
+
|
|
620
|
+
print("Waiting for Mech deliver...")
|
|
602
621
|
data_url = wait_for_data_url(
|
|
603
622
|
request_id=request_id,
|
|
604
623
|
wss=wss,
|
|
@@ -610,8 +629,9 @@ def interact( # pylint: disable=too-many-arguments,too-many-locals
|
|
|
610
629
|
confirmation_type=confirmation_type,
|
|
611
630
|
)
|
|
612
631
|
if data_url:
|
|
613
|
-
print(f"Data arrived: {data_url}")
|
|
614
|
-
data = requests.get(f"{data_url}/{request_id}").json()
|
|
615
|
-
print(
|
|
632
|
+
print(f" - Data arrived: {data_url}")
|
|
633
|
+
data = requests.get(f"{data_url}/{request_id}", timeout=30).json()
|
|
634
|
+
print(" - Data from agent:")
|
|
635
|
+
print(json.dumps(data, indent=2))
|
|
616
636
|
return data
|
|
617
637
|
return None
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"""Module for managing mechanical tools and their interactions with blockchain."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from dataclasses import asdict
|
|
5
|
+
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
6
|
+
|
|
7
|
+
import requests
|
|
8
|
+
from aea_ledger_ethereum import EthereumApi
|
|
9
|
+
|
|
10
|
+
from mech_client.interact import fetch_tools, get_abi, get_contract, get_mech_config
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def get_total_supply(chain_config: str = "gnosis") -> int:
|
|
14
|
+
"""
|
|
15
|
+
Fetches the total supply of tokens from a contract using the chain configuration.
|
|
16
|
+
|
|
17
|
+
:param chain_config: The chain configuration to use.
|
|
18
|
+
:type chain_config: str
|
|
19
|
+
:return: The total supply of tokens.
|
|
20
|
+
:rtype: int
|
|
21
|
+
"""
|
|
22
|
+
# Get the mech configuration
|
|
23
|
+
mech_config = get_mech_config(chain_config)
|
|
24
|
+
ledger_config = mech_config.ledger_config
|
|
25
|
+
|
|
26
|
+
# Setup Ethereum API
|
|
27
|
+
ledger_api = EthereumApi(**asdict(ledger_config))
|
|
28
|
+
|
|
29
|
+
# Fetch ABI and create contract instance
|
|
30
|
+
abi = get_abi(mech_config.agent_registry_contract, mech_config.contract_abi_url)
|
|
31
|
+
contract = get_contract(mech_config.agent_registry_contract, abi, ledger_api)
|
|
32
|
+
|
|
33
|
+
# Call the totalSupply function
|
|
34
|
+
return contract.functions.totalSupply().call()
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def get_agent_tools(
|
|
38
|
+
agent_id: int, chain_config: str = "gnosis"
|
|
39
|
+
) -> Optional[Union[List[str], Tuple[List[str], Dict[str, Any]]]]:
|
|
40
|
+
"""
|
|
41
|
+
Fetch tools for a given agent ID.
|
|
42
|
+
|
|
43
|
+
:param agent_id: The ID of the agent.
|
|
44
|
+
:param chain_config: The chain configuration to use (default is "gnosis").
|
|
45
|
+
:return: A list of tools if successful, or a tuple of (list of tools, metadata) if metadata is included, or None if an error occurs.
|
|
46
|
+
"""
|
|
47
|
+
try:
|
|
48
|
+
# Get the mech configuration
|
|
49
|
+
mech_config = get_mech_config(chain_config)
|
|
50
|
+
ledger_config = mech_config.ledger_config
|
|
51
|
+
|
|
52
|
+
# Setup Ethereum API
|
|
53
|
+
ledger_api = EthereumApi(**asdict(ledger_config))
|
|
54
|
+
|
|
55
|
+
# Fetch tools for the given agent ID
|
|
56
|
+
return fetch_tools(
|
|
57
|
+
agent_id=agent_id,
|
|
58
|
+
ledger_api=ledger_api,
|
|
59
|
+
agent_registry_contract=mech_config.agent_registry_contract,
|
|
60
|
+
contract_abi_url=mech_config.contract_abi_url,
|
|
61
|
+
)
|
|
62
|
+
except (requests.exceptions.RequestException, json.JSONDecodeError, KeyError) as e:
|
|
63
|
+
print(f"An error occurred while fetching tools for agent {agent_id}: {e}")
|
|
64
|
+
return None
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def get_tools_for_agents(
|
|
68
|
+
agent_id: Optional[int] = None, chain_config: str = "gnosis"
|
|
69
|
+
) -> Dict[str, Any]:
|
|
70
|
+
"""
|
|
71
|
+
Retrieve tools for specified agents or all agents if no specific agent is provided.
|
|
72
|
+
|
|
73
|
+
:param agent_id: Optional; specific agent ID to fetch tools for.
|
|
74
|
+
:param chain_config: The chain configuration to use.
|
|
75
|
+
:return: Dictionary of tools with identifiers or a mapping of agent IDs to tools.
|
|
76
|
+
"""
|
|
77
|
+
try:
|
|
78
|
+
total_supply = get_total_supply(chain_config)
|
|
79
|
+
|
|
80
|
+
if agent_id is not None:
|
|
81
|
+
tools = get_agent_tools(agent_id, chain_config)
|
|
82
|
+
if isinstance(tools, list):
|
|
83
|
+
tools_with_ids = [
|
|
84
|
+
{"tool_name": tool, "unique_identifier": f"{agent_id}-{tool}"}
|
|
85
|
+
for tool in tools
|
|
86
|
+
]
|
|
87
|
+
else:
|
|
88
|
+
tools_with_ids = []
|
|
89
|
+
return {"agent_id": agent_id, "tools": tools_with_ids}
|
|
90
|
+
|
|
91
|
+
all_tools_with_ids = []
|
|
92
|
+
agent_tools_map = {}
|
|
93
|
+
|
|
94
|
+
for current_agent_id in range(1, total_supply + 1):
|
|
95
|
+
tools = get_agent_tools(current_agent_id, chain_config)
|
|
96
|
+
if isinstance(tools, list):
|
|
97
|
+
tools_with_ids = [
|
|
98
|
+
{
|
|
99
|
+
"tool_name": tool,
|
|
100
|
+
"unique_identifier": f"{current_agent_id}-{tool}",
|
|
101
|
+
}
|
|
102
|
+
for tool in tools
|
|
103
|
+
]
|
|
104
|
+
agent_tools_map[current_agent_id] = tools
|
|
105
|
+
all_tools_with_ids.extend(tools_with_ids)
|
|
106
|
+
|
|
107
|
+
return {
|
|
108
|
+
"all_tools_with_identifiers": all_tools_with_ids,
|
|
109
|
+
"agent_tools_map": agent_tools_map,
|
|
110
|
+
}
|
|
111
|
+
except Exception as e:
|
|
112
|
+
print(f"Error in get_tools_for_agents: {str(e)}")
|
|
113
|
+
raise
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def get_tool_description(unique_identifier: str, chain_config: str = "gnosis") -> str:
|
|
117
|
+
"""
|
|
118
|
+
Fetch the description of a specific tool based on a unique identifier.
|
|
119
|
+
|
|
120
|
+
:param unique_identifier: The unique identifier for the tool.
|
|
121
|
+
:param chain_config: The chain configuration to use.
|
|
122
|
+
:return: Description of the tool or a default message if not available.
|
|
123
|
+
"""
|
|
124
|
+
parts = unique_identifier.split("-")
|
|
125
|
+
agent_id = int(parts[0])
|
|
126
|
+
tool_name = "-".join(parts[1:])
|
|
127
|
+
|
|
128
|
+
# Get the mech configuration
|
|
129
|
+
mech_config = get_mech_config(chain_config)
|
|
130
|
+
ledger_api = EthereumApi(**asdict(mech_config.ledger_config))
|
|
131
|
+
|
|
132
|
+
tools_result = fetch_tools(
|
|
133
|
+
agent_id=agent_id,
|
|
134
|
+
ledger_api=ledger_api,
|
|
135
|
+
agent_registry_contract=mech_config.agent_registry_contract,
|
|
136
|
+
contract_abi_url=mech_config.contract_abi_url,
|
|
137
|
+
include_metadata=True,
|
|
138
|
+
)
|
|
139
|
+
if isinstance(tools_result, tuple) and len(tools_result) == 2:
|
|
140
|
+
_, tool_metadata = tools_result
|
|
141
|
+
tool_info = tool_metadata.get(tool_name, {})
|
|
142
|
+
if isinstance(tool_info, dict):
|
|
143
|
+
return tool_info.get("description", "Description not available")
|
|
144
|
+
return "Description not available"
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def get_tool_io_schema(
|
|
148
|
+
unique_identifier: str, chain_config: str = "gnosis"
|
|
149
|
+
) -> Dict[str, Any]:
|
|
150
|
+
"""
|
|
151
|
+
Fetch the input and output schema of a specific tool based on a unique identifier.
|
|
152
|
+
|
|
153
|
+
:param unique_identifier: The unique identifier for the tool.
|
|
154
|
+
:param chain_config: The chain configuration to use.
|
|
155
|
+
:return: Dictionary containing input and output schemas.
|
|
156
|
+
"""
|
|
157
|
+
parts = unique_identifier.split("-")
|
|
158
|
+
agent_id = int(parts[0])
|
|
159
|
+
tool_name = "-".join(parts[1:])
|
|
160
|
+
|
|
161
|
+
# Get the mech configuration
|
|
162
|
+
mech_config = get_mech_config(chain_config)
|
|
163
|
+
ledger_api = EthereumApi(**asdict(mech_config.ledger_config))
|
|
164
|
+
|
|
165
|
+
tools_result = fetch_tools(
|
|
166
|
+
agent_id=agent_id,
|
|
167
|
+
ledger_api=ledger_api,
|
|
168
|
+
agent_registry_contract=mech_config.agent_registry_contract,
|
|
169
|
+
contract_abi_url=mech_config.contract_abi_url,
|
|
170
|
+
include_metadata=True,
|
|
171
|
+
)
|
|
172
|
+
if isinstance(tools_result, tuple) and len(tools_result) == 2:
|
|
173
|
+
_, tool_metadata = tools_result
|
|
174
|
+
tool_info = tool_metadata.get(tool_name, {})
|
|
175
|
+
if isinstance(tool_info, dict):
|
|
176
|
+
return {
|
|
177
|
+
"input": tool_info.get("input", {}),
|
|
178
|
+
"output": tool_info.get("output", {}),
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return {"input": {}, "output": {}}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: mech-client
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.16
|
|
4
4
|
Summary: Basic client to interact with a mech
|
|
5
5
|
License: Apache-2.0
|
|
6
6
|
Author: David Minarsch
|
|
@@ -16,6 +16,7 @@ Requires-Dist: open-aea-cli-ipfs (>=1.53.0,<2.0.0)
|
|
|
16
16
|
Requires-Dist: open-aea-ledger-cosmos (>=1.53.0,<2.0.0)
|
|
17
17
|
Requires-Dist: open-aea-ledger-ethereum (>=1.53.0,<2.0.0)
|
|
18
18
|
Requires-Dist: open-aea[cli] (>=1.53.0,<2.0.0)
|
|
19
|
+
Requires-Dist: tabulate (>=0.9.0,<0.10.0)
|
|
19
20
|
Requires-Dist: websocket-client (>=0.32.0,<1)
|
|
20
21
|
Description-Content-Type: text/markdown
|
|
21
22
|
|
|
@@ -69,10 +70,14 @@ Options:
|
|
|
69
70
|
--help Show this message and exit.
|
|
70
71
|
|
|
71
72
|
Commands:
|
|
72
|
-
interact
|
|
73
|
-
prompt-to-ipfs
|
|
74
|
-
push-to-ipfs
|
|
75
|
-
to-png
|
|
73
|
+
interact Interact with a mech specifying a prompt and tool.
|
|
74
|
+
prompt-to-ipfs Upload a prompt and tool to IPFS as metadata.
|
|
75
|
+
push-to-ipfs Upload a file to IPFS.
|
|
76
|
+
to-png Convert a stability AI API's diffusion model output.
|
|
77
|
+
tools-for-agents List tools available for all agents or a specific agent.
|
|
78
|
+
tool-description Get the description of a specific tool.
|
|
79
|
+
tool_io_schema Get the input/output schema of a specific tool.
|
|
80
|
+
|
|
76
81
|
```
|
|
77
82
|
|
|
78
83
|
### Set up the EOA and private key
|
|
@@ -173,6 +178,102 @@ Data arrived: https://gateway.autonolas.tech/ipfs/f01701220a462120d5bb03f406fa5e
|
|
|
173
178
|
Data from agent: {'requestId': 100407405856633966395081711430940962809568685031934329025999216833965518452765, 'result': "In a world of chaos and strife,\nThere's beauty in the simplest of life.\nA gentle breeze whispers through the trees,\nAnd birds sing melodies with ease.\n\nThe sun sets in a fiery hue,\nPainting the sky in shades of blue.\nStars twinkle in the darkness above,\nGuiding us with their light and love.\n\nSo take a moment to pause and see,\nThe wonders of this world so free.\nEmbrace the joy that each day brings,\nAnd let your heart soar on gentle wings.", 'prompt': 'write a short poem', 'cost_dict': {}, 'metadata': {'model': None, 'tool': 'openai-gpt-3.5-turbo'}}
|
|
174
179
|
```
|
|
175
180
|
|
|
181
|
+
|
|
182
|
+
### List tools available for agents
|
|
183
|
+
|
|
184
|
+
To list the tools available for a specific agent or for all agents, use the `tools-for-agents` command. You can specify an agent ID to get tools for a specific agent, or omit it to list tools for all agents.
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
mechx tools-for-agents
|
|
188
|
+
```
|
|
189
|
+
```bash
|
|
190
|
+
You will see an output like this:
|
|
191
|
+
+------------+---------------------------------------------+-----------------------------------------------+
|
|
192
|
+
| Agent ID | Tool Name | UniqueIdentifier |
|
|
193
|
+
+============+=============================================+===============================================+
|
|
194
|
+
| 3 | claude-prediction-offline | 3-claude-prediction-offline |
|
|
195
|
+
+------------+---------------------------------------------+-----------------------------------------------+
|
|
196
|
+
| 3 | claude-prediction-online | 3-claude-prediction-online |
|
|
197
|
+
+------------+---------------------------------------------+-----------------------------------------------+
|
|
198
|
+
| 3 | deepmind-optimization | 3-deepmind-optimization |
|
|
199
|
+
+------------+---------------------------------------------+-----------------------------------------------+
|
|
200
|
+
| 3 | deepmind-optimization-strong | 3-deepmind-optimization-strong |
|
|
201
|
+
+------------+---------------------------------------------+-----------------------------------------------+
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
mechx tools-for-agents --agent-id "agent_id"
|
|
206
|
+
```
|
|
207
|
+
Eaxmple usage
|
|
208
|
+
```bash
|
|
209
|
+
mechx tools-for-agents --agent-id 6
|
|
210
|
+
```
|
|
211
|
+
```bash
|
|
212
|
+
You will see an output like this:
|
|
213
|
+
+---------------------------------------------+-----------------------------------------------+
|
|
214
|
+
| Tool Name | Unique Identifier |
|
|
215
|
+
+=============================================+===============================================+
|
|
216
|
+
| claude-prediction-offline | 6-claude-prediction-offline |
|
|
217
|
+
+---------------------------------------------+-----------------------------------------------+
|
|
218
|
+
| claude-prediction-online | 6-claude-prediction-online |
|
|
219
|
+
+---------------------------------------------+-----------------------------------------------+
|
|
220
|
+
| deepmind-optimization | 6-deepmind-optimization |
|
|
221
|
+
+---------------------------------------------+-----------------------------------------------+
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### Get Tool Description
|
|
225
|
+
|
|
226
|
+
To get the description of a specific tool, use the `tool-description` command. You need to specify the unique identifier of the tool.
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
mechx tool-description --unique-identifier <unique_identifier> --chain-config <chain_config>
|
|
230
|
+
```
|
|
231
|
+
Example usage:
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
mechx tool-description --unique-identifier "6-claude-prediction-offline" --chain-config gnosis
|
|
235
|
+
```
|
|
236
|
+
You will see an output like this:
|
|
237
|
+
```bash
|
|
238
|
+
Description for tool 6-claude-prediction-offline: Makes a prediction using Claude
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
### Get Tool Input/Output Schema
|
|
243
|
+
|
|
244
|
+
To get the input/output schema of a specific tool, use the `tool_io_schema` command. You need to specify the unique identifier of the tool.
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
mechx tool-io-schema --unique-identifier <unique_identifier> --chain-config <chain_config>
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Example usage:
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
mechx tool-io-schema --unique-identifier "6-prediction-offline" --chain-config gnosis
|
|
254
|
+
```
|
|
255
|
+
You will see an output like this:
|
|
256
|
+
```bash
|
|
257
|
+
Input Schema:
|
|
258
|
+
+-------------+----------------------------------+
|
|
259
|
+
| Field | Value |
|
|
260
|
+
+=============+==================================+
|
|
261
|
+
| type | text |
|
|
262
|
+
+-------------+----------------------------------+
|
|
263
|
+
| description | The text to make a prediction on |
|
|
264
|
+
+-------------+----------------------------------+
|
|
265
|
+
Output Schema:
|
|
266
|
+
+-----------+---------+-----------------------------------------------+
|
|
267
|
+
| Field | Type | Description |
|
|
268
|
+
+===========+=========+===============================================+
|
|
269
|
+
| requestId | integer | Unique identifier for the request |
|
|
270
|
+
+-----------+---------+-----------------------------------------------+
|
|
271
|
+
| result | string | Result information in JSON format as a string |
|
|
272
|
+
+-----------+---------+-----------------------------------------------+
|
|
273
|
+
| prompt | string | Prompt used for probability estimation. |
|
|
274
|
+
+-----------+---------+-----------------------------------------------+
|
|
275
|
+
```
|
|
276
|
+
|
|
176
277
|
> **:pencil2: Note** <br />
|
|
177
278
|
> **If you encounter an "Out of gas" error when executing the Mech Client, you will need to increase the gas limit, e.g.,**
|
|
178
279
|
>
|
|
@@ -235,6 +336,45 @@ You can also use the Mech Client as a library on your Python project.
|
|
|
235
336
|
print(result)
|
|
236
337
|
```
|
|
237
338
|
|
|
339
|
+
You can also use the Mech Client to programmatically fetch tools for agents in your Python project, as well as retrieve descriptions and input/output schemas for specific tools given their unique identifier.
|
|
340
|
+
|
|
341
|
+
1. Set up the private key as specified [above](#set-up-the-private-key). Store the resulting key file (e.g., `ethereum_private_key.txt`) in a convenient and secure location.
|
|
342
|
+
|
|
343
|
+
2. Create a Python script `fetch_tools_script.py`:
|
|
344
|
+
|
|
345
|
+
```bash
|
|
346
|
+
touch fetch_tools_script.py
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
3. Edit `fetch_tools_script.py` as follows:
|
|
350
|
+
|
|
351
|
+
```python
|
|
352
|
+
from mech_client.mech_tool_management import get_tools_for_agents, get_tool_description, get_tool_io_schema
|
|
353
|
+
|
|
354
|
+
# Fetching tools for a specific agent or all agents
|
|
355
|
+
agent_id = 6 # Specify the agent ID or set to None to fetch tools for all agents
|
|
356
|
+
chain_config = "gnosis" # Specify the chain configuration
|
|
357
|
+
tools = get_tools_for_agents(agent_id=agent_id, chain_config=chain_config)
|
|
358
|
+
print(f"Tools for agent {agent_id}:", tools)
|
|
359
|
+
|
|
360
|
+
# Assuming you know the tool name, construct the unique identifier
|
|
361
|
+
tool_name = "claude-prediction-offline" # Example tool name
|
|
362
|
+
unique_identifier = f"{agent_id}-{tool_name}" # Construct the unique identifier
|
|
363
|
+
|
|
364
|
+
# Fetching description and I/O schema for a specific tool using the unique identifier
|
|
365
|
+
description = get_tool_description(unique_identifier, chain_config)
|
|
366
|
+
print(f"Description for {unique_identifier}:", description)
|
|
367
|
+
|
|
368
|
+
io_schema = get_tool_io_schema(unique_identifier, chain_config)
|
|
369
|
+
print(f"Input/Output Schema for {unique_identifier}:", io_schema)
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
This script will:
|
|
373
|
+
- Fetch and print the tools available for a specified agent or for all agents if `agent_id` is set to `None`.
|
|
374
|
+
- Construct the unique identifier for a tool using the format `agentId-toolName`.
|
|
375
|
+
- Retrieve and display the description of a specific tool using its unique identifier.
|
|
376
|
+
- Retrieve and display the input and output schema of a specific tool using its unique identifier.
|
|
377
|
+
|
|
238
378
|
## Developer installation
|
|
239
379
|
|
|
240
380
|
To setup the development environment for this project, clone the repository and run the following commands:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
mech_client/__init__.py,sha256=
|
|
1
|
+
mech_client/__init__.py,sha256=82jc8W2nwk575i4bZvj6qpAoJEn_97PMQSlAM7ma8u0,43
|
|
2
2
|
mech_client/acn.py,sha256=Rj_jLPvJ5loDQfGbu3a_O24cJC4SwIErLceSz_zVYS8,5356
|
|
3
|
-
mech_client/cli.py,sha256=
|
|
3
|
+
mech_client/cli.py,sha256=87ZBQAbzWpuf6s59FnBa4YO2eyDCyTOG22V54408MiY,8377
|
|
4
4
|
mech_client/configs/mechs.json,sha256=IABnne1lWi62l84Hzqh3XrP659uPKme2k32yAI0HBrg,4488
|
|
5
5
|
mech_client/helpers/__init__.py,sha256=f13zpwGDaKQUjML-5Iq66rRfzg8IS5UNK5I8gBr7w54,1028
|
|
6
6
|
mech_client/helpers/acn/README.md,sha256=WMXR2Lk0IpWjr3vpZ8cxcTHk4gwsx4wC06UPkwj9dbQ,1641
|
|
@@ -30,14 +30,15 @@ mech_client/helpers/p2p_libp2p_client/README.md,sha256=6x9s6P7TdKkcvAS1wMFHXRz4a
|
|
|
30
30
|
mech_client/helpers/p2p_libp2p_client/__init__.py,sha256=-GOP3D_JnmXTDomrMLCbnRk7vRQmihIqTYvyIPzx-q4,879
|
|
31
31
|
mech_client/helpers/p2p_libp2p_client/connection.py,sha256=pvfHtI-NhgDbay1wLNit6m8InH4c0p00c3hQo0I2jwQ,27887
|
|
32
32
|
mech_client/helpers/p2p_libp2p_client/connection.yaml,sha256=giYV5FwwugD7ha9IqFHJtvs-Oz1jC5og9rpkstrTqoc,1763
|
|
33
|
-
mech_client/interact.py,sha256=
|
|
33
|
+
mech_client/interact.py,sha256=DOlUQBrfJKdDlfPnQ10tC8uAFTjlC3FGHOkPI2E_BYg,20846
|
|
34
|
+
mech_client/mech_tool_management.py,sha256=_nOa8FLaow2XyztxnEMT9sJSlZEhUidmG8dFdR1lfV8,6550
|
|
34
35
|
mech_client/prompt_to_ipfs.py,sha256=XqSIBko15MEkpWOQNT97fRI6jNxMF5EDBDEPOJFdhyk,2533
|
|
35
36
|
mech_client/push_to_ipfs.py,sha256=IfvgaPU79N_ZmCPF9d7sPCYz2uduZH0KjT_HQ2LHXoQ,2059
|
|
36
37
|
mech_client/subgraph.py,sha256=4vY6QFyUVs15gS0SvanJbvAxb3aie07IuxQnfMMnStc,4931
|
|
37
38
|
mech_client/to_png.py,sha256=pjUcFJ63MJj_r73eqnfqCWMtlpsrj6H4ZmgvIEmRcFw,2581
|
|
38
39
|
mech_client/wss.py,sha256=hRInQjjsyOrs8dmgBb2VpJvpNt6Tx0aEiY3OhOPQvIs,6600
|
|
39
|
-
mech_client-0.2.
|
|
40
|
-
mech_client-0.2.
|
|
41
|
-
mech_client-0.2.
|
|
42
|
-
mech_client-0.2.
|
|
43
|
-
mech_client-0.2.
|
|
40
|
+
mech_client-0.2.16.dist-info/LICENSE,sha256=mdBDB-mWKV5Cz4ejBzBiKqan6Z8zVLAh9xwM64O2FW4,11339
|
|
41
|
+
mech_client-0.2.16.dist-info/METADATA,sha256=RKWiEjr5xeovuc4sIDI633vmOd4M7oBStQdzjoSBPB0,17358
|
|
42
|
+
mech_client-0.2.16.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
|
|
43
|
+
mech_client-0.2.16.dist-info/entry_points.txt,sha256=SbRMRsayzD8XfNXhgwPuXEqQsdZ5Bw9XDPnUuaDExyY,45
|
|
44
|
+
mech_client-0.2.16.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|