mech-client 0.2.15__tar.gz → 0.2.17__tar.gz
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-0.2.15 → mech_client-0.2.17}/PKG-INFO +151 -5
- {mech_client-0.2.15 → mech_client-0.2.17}/README.md +149 -4
- mech_client-0.2.17/mech_client/__init__.py +3 -0
- mech_client-0.2.17/mech_client/cli.py +290 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/interact.py +15 -13
- mech_client-0.2.17/mech_client/mech_tool_management.py +205 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/pyproject.toml +2 -1
- mech_client-0.2.15/mech_client/__init__.py +0 -3
- mech_client-0.2.15/mech_client/cli.py +0 -158
- {mech_client-0.2.15 → mech_client-0.2.17}/LICENSE +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/acn.py +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/configs/mechs.json +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/__init__.py +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/acn/README.md +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/acn/__init__.py +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/acn/acn.proto +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/acn/acn_pb2.py +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/acn/custom_types.py +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/acn/dialogues.py +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/acn/message.py +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/acn/protocol.yaml +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/acn/serialization.py +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/acn/tests/__init__.py +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/acn/tests/test_acn.py +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/acn/tests/test_acn_dialogues.py +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/acn/tests/test_acn_messages.py +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/acn_data_share/README.md +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/acn_data_share/__init__.py +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/acn_data_share/acn_data_share.proto +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/acn_data_share/acn_data_share_pb2.py +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/acn_data_share/dialogues.py +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/acn_data_share/message.py +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/acn_data_share/protocol.yaml +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/acn_data_share/serialization.py +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/acn_data_share/tests/test_acn_data_share_dialogues.py +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/acn_data_share/tests/test_acn_data_share_messages.py +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/p2p_libp2p_client/README.md +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/p2p_libp2p_client/__init__.py +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/p2p_libp2p_client/connection.py +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/p2p_libp2p_client/connection.yaml +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/prompt_to_ipfs.py +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/push_to_ipfs.py +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/subgraph.py +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/to_png.py +0 -0
- {mech_client-0.2.15 → mech_client-0.2.17}/mech_client/wss.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: mech-client
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.17
|
|
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,108 @@ 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> --chain-config <chain_config>
|
|
230
|
+
```
|
|
231
|
+
Example usage:
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
mechx tool-description "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> --chain-config <chain_config>
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Example usage:
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
mechx tool-io-schema "6-prediction-offline" --chain-config gnosis
|
|
254
|
+
```
|
|
255
|
+
You will see an output like this:
|
|
256
|
+
```bash
|
|
257
|
+
Tool Details:
|
|
258
|
+
+---------------------------+-----------------------------------------------+
|
|
259
|
+
| Tool Name | Tool Description |
|
|
260
|
+
+===========================+===============================================+
|
|
261
|
+
| OpenAI Prediction Offline | Makes a prediction using OpenAI GPT-3.5 Turbo |
|
|
262
|
+
+---------------------------+-----------------------------------------------+
|
|
263
|
+
Input Schema:
|
|
264
|
+
+-------------+----------------------------------+
|
|
265
|
+
| Field | Value |
|
|
266
|
+
+=============+==================================+
|
|
267
|
+
| type | text |
|
|
268
|
+
+-------------+----------------------------------+
|
|
269
|
+
| description | The text to make a prediction on |
|
|
270
|
+
+-------------+----------------------------------+
|
|
271
|
+
Output Schema:
|
|
272
|
+
+-----------+---------+-----------------------------------------------+
|
|
273
|
+
| Field | Type | Description |
|
|
274
|
+
+===========+=========+===============================================+
|
|
275
|
+
| requestId | integer | Unique identifier for the request |
|
|
276
|
+
+-----------+---------+-----------------------------------------------+
|
|
277
|
+
| result | string | Result information in JSON format as a string |
|
|
278
|
+
+-----------+---------+-----------------------------------------------+
|
|
279
|
+
| prompt | string | Prompt used for probability estimation. |
|
|
280
|
+
+-----------+---------+-----------------------------------------------+
|
|
281
|
+
```
|
|
282
|
+
|
|
176
283
|
> **:pencil2: Note** <br />
|
|
177
284
|
> **If you encounter an "Out of gas" error when executing the Mech Client, you will need to increase the gas limit, e.g.,**
|
|
178
285
|
>
|
|
@@ -235,6 +342,45 @@ You can also use the Mech Client as a library on your Python project.
|
|
|
235
342
|
print(result)
|
|
236
343
|
```
|
|
237
344
|
|
|
345
|
+
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.
|
|
346
|
+
|
|
347
|
+
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.
|
|
348
|
+
|
|
349
|
+
2. Create a Python script `fetch_tools_script.py`:
|
|
350
|
+
|
|
351
|
+
```bash
|
|
352
|
+
touch fetch_tools_script.py
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
3. Edit `fetch_tools_script.py` as follows:
|
|
356
|
+
|
|
357
|
+
```python
|
|
358
|
+
from mech_client.mech_tool_management import get_tools_for_agents, get_tool_description, get_tool_io_schema
|
|
359
|
+
|
|
360
|
+
# Fetching tools for a specific agent or all agents
|
|
361
|
+
agent_id = 6 # Specify the agent ID or set to None to fetch tools for all agents
|
|
362
|
+
chain_config = "gnosis" # Specify the chain configuration
|
|
363
|
+
tools = get_tools_for_agents(agent_id=agent_id, chain_config=chain_config)
|
|
364
|
+
print(f"Tools for agent {agent_id}:", tools)
|
|
365
|
+
|
|
366
|
+
# Assuming you know the tool name, construct the unique identifier
|
|
367
|
+
tool_name = "claude-prediction-offline" # Example tool name
|
|
368
|
+
unique_identifier = f"{agent_id}-{tool_name}" # Construct the unique identifier
|
|
369
|
+
|
|
370
|
+
# Fetching description and I/O schema for a specific tool using the unique identifier
|
|
371
|
+
description = get_tool_description(unique_identifier, chain_config)
|
|
372
|
+
print(f"Description for {unique_identifier}:", description)
|
|
373
|
+
|
|
374
|
+
io_schema = get_tool_io_schema(unique_identifier, chain_config)
|
|
375
|
+
print(f"Input/Output Schema for {unique_identifier}:", io_schema)
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
This script will:
|
|
379
|
+
- Fetch and print the tools available for a specified agent or for all agents if `agent_id` is set to `None`.
|
|
380
|
+
- Construct the unique identifier for a tool using the format `agentId-toolName`.
|
|
381
|
+
- Retrieve and display the description of a specific tool using its unique identifier.
|
|
382
|
+
- Retrieve and display the input and output schema of a specific tool using its unique identifier.
|
|
383
|
+
|
|
238
384
|
## Developer installation
|
|
239
385
|
|
|
240
386
|
To setup the development environment for this project, clone the repository and run the following commands:
|
|
@@ -48,10 +48,14 @@ Options:
|
|
|
48
48
|
--help Show this message and exit.
|
|
49
49
|
|
|
50
50
|
Commands:
|
|
51
|
-
interact
|
|
52
|
-
prompt-to-ipfs
|
|
53
|
-
push-to-ipfs
|
|
54
|
-
to-png
|
|
51
|
+
interact Interact with a mech specifying a prompt and tool.
|
|
52
|
+
prompt-to-ipfs Upload a prompt and tool to IPFS as metadata.
|
|
53
|
+
push-to-ipfs Upload a file to IPFS.
|
|
54
|
+
to-png Convert a stability AI API's diffusion model output.
|
|
55
|
+
tools-for-agents List tools available for all agents or a specific agent.
|
|
56
|
+
tool-description Get the description of a specific tool.
|
|
57
|
+
tool_io_schema Get the input/output schema of a specific tool.
|
|
58
|
+
|
|
55
59
|
```
|
|
56
60
|
|
|
57
61
|
### Set up the EOA and private key
|
|
@@ -152,6 +156,108 @@ Data arrived: https://gateway.autonolas.tech/ipfs/f01701220a462120d5bb03f406fa5e
|
|
|
152
156
|
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'}}
|
|
153
157
|
```
|
|
154
158
|
|
|
159
|
+
|
|
160
|
+
### List tools available for agents
|
|
161
|
+
|
|
162
|
+
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.
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
mechx tools-for-agents
|
|
166
|
+
```
|
|
167
|
+
```bash
|
|
168
|
+
You will see an output like this:
|
|
169
|
+
+------------+---------------------------------------------+-----------------------------------------------+
|
|
170
|
+
| Agent ID | Tool Name | UniqueIdentifier |
|
|
171
|
+
+============+=============================================+===============================================+
|
|
172
|
+
| 3 | claude-prediction-offline | 3-claude-prediction-offline |
|
|
173
|
+
+------------+---------------------------------------------+-----------------------------------------------+
|
|
174
|
+
| 3 | claude-prediction-online | 3-claude-prediction-online |
|
|
175
|
+
+------------+---------------------------------------------+-----------------------------------------------+
|
|
176
|
+
| 3 | deepmind-optimization | 3-deepmind-optimization |
|
|
177
|
+
+------------+---------------------------------------------+-----------------------------------------------+
|
|
178
|
+
| 3 | deepmind-optimization-strong | 3-deepmind-optimization-strong |
|
|
179
|
+
+------------+---------------------------------------------+-----------------------------------------------+
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
mechx tools-for-agents --agent-id "agent_id"
|
|
184
|
+
```
|
|
185
|
+
Eaxmple usage
|
|
186
|
+
```bash
|
|
187
|
+
mechx tools-for-agents --agent-id 6
|
|
188
|
+
```
|
|
189
|
+
```bash
|
|
190
|
+
You will see an output like this:
|
|
191
|
+
+---------------------------------------------+-----------------------------------------------+
|
|
192
|
+
| Tool Name | Unique Identifier |
|
|
193
|
+
+=============================================+===============================================+
|
|
194
|
+
| claude-prediction-offline | 6-claude-prediction-offline |
|
|
195
|
+
+---------------------------------------------+-----------------------------------------------+
|
|
196
|
+
| claude-prediction-online | 6-claude-prediction-online |
|
|
197
|
+
+---------------------------------------------+-----------------------------------------------+
|
|
198
|
+
| deepmind-optimization | 6-deepmind-optimization |
|
|
199
|
+
+---------------------------------------------+-----------------------------------------------+
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Get Tool Description
|
|
203
|
+
|
|
204
|
+
To get the description of a specific tool, use the `tool-description` command. You need to specify the unique identifier of the tool.
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
mechx tool-description <unique_identifier> --chain-config <chain_config>
|
|
208
|
+
```
|
|
209
|
+
Example usage:
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
mechx tool-description "6-claude-prediction-offline" --chain-config gnosis
|
|
213
|
+
```
|
|
214
|
+
You will see an output like this:
|
|
215
|
+
```bash
|
|
216
|
+
Description for tool 6-claude-prediction-offline: Makes a prediction using Claude
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
### Get Tool Input/Output Schema
|
|
221
|
+
|
|
222
|
+
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.
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
mechx tool-io-schema <unique_identifier> --chain-config <chain_config>
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Example usage:
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
mechx tool-io-schema "6-prediction-offline" --chain-config gnosis
|
|
232
|
+
```
|
|
233
|
+
You will see an output like this:
|
|
234
|
+
```bash
|
|
235
|
+
Tool Details:
|
|
236
|
+
+---------------------------+-----------------------------------------------+
|
|
237
|
+
| Tool Name | Tool Description |
|
|
238
|
+
+===========================+===============================================+
|
|
239
|
+
| OpenAI Prediction Offline | Makes a prediction using OpenAI GPT-3.5 Turbo |
|
|
240
|
+
+---------------------------+-----------------------------------------------+
|
|
241
|
+
Input Schema:
|
|
242
|
+
+-------------+----------------------------------+
|
|
243
|
+
| Field | Value |
|
|
244
|
+
+=============+==================================+
|
|
245
|
+
| type | text |
|
|
246
|
+
+-------------+----------------------------------+
|
|
247
|
+
| description | The text to make a prediction on |
|
|
248
|
+
+-------------+----------------------------------+
|
|
249
|
+
Output Schema:
|
|
250
|
+
+-----------+---------+-----------------------------------------------+
|
|
251
|
+
| Field | Type | Description |
|
|
252
|
+
+===========+=========+===============================================+
|
|
253
|
+
| requestId | integer | Unique identifier for the request |
|
|
254
|
+
+-----------+---------+-----------------------------------------------+
|
|
255
|
+
| result | string | Result information in JSON format as a string |
|
|
256
|
+
+-----------+---------+-----------------------------------------------+
|
|
257
|
+
| prompt | string | Prompt used for probability estimation. |
|
|
258
|
+
+-----------+---------+-----------------------------------------------+
|
|
259
|
+
```
|
|
260
|
+
|
|
155
261
|
> **:pencil2: Note** <br />
|
|
156
262
|
> **If you encounter an "Out of gas" error when executing the Mech Client, you will need to increase the gas limit, e.g.,**
|
|
157
263
|
>
|
|
@@ -214,6 +320,45 @@ You can also use the Mech Client as a library on your Python project.
|
|
|
214
320
|
print(result)
|
|
215
321
|
```
|
|
216
322
|
|
|
323
|
+
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.
|
|
324
|
+
|
|
325
|
+
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.
|
|
326
|
+
|
|
327
|
+
2. Create a Python script `fetch_tools_script.py`:
|
|
328
|
+
|
|
329
|
+
```bash
|
|
330
|
+
touch fetch_tools_script.py
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
3. Edit `fetch_tools_script.py` as follows:
|
|
334
|
+
|
|
335
|
+
```python
|
|
336
|
+
from mech_client.mech_tool_management import get_tools_for_agents, get_tool_description, get_tool_io_schema
|
|
337
|
+
|
|
338
|
+
# Fetching tools for a specific agent or all agents
|
|
339
|
+
agent_id = 6 # Specify the agent ID or set to None to fetch tools for all agents
|
|
340
|
+
chain_config = "gnosis" # Specify the chain configuration
|
|
341
|
+
tools = get_tools_for_agents(agent_id=agent_id, chain_config=chain_config)
|
|
342
|
+
print(f"Tools for agent {agent_id}:", tools)
|
|
343
|
+
|
|
344
|
+
# Assuming you know the tool name, construct the unique identifier
|
|
345
|
+
tool_name = "claude-prediction-offline" # Example tool name
|
|
346
|
+
unique_identifier = f"{agent_id}-{tool_name}" # Construct the unique identifier
|
|
347
|
+
|
|
348
|
+
# Fetching description and I/O schema for a specific tool using the unique identifier
|
|
349
|
+
description = get_tool_description(unique_identifier, chain_config)
|
|
350
|
+
print(f"Description for {unique_identifier}:", description)
|
|
351
|
+
|
|
352
|
+
io_schema = get_tool_io_schema(unique_identifier, chain_config)
|
|
353
|
+
print(f"Input/Output Schema for {unique_identifier}:", io_schema)
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
This script will:
|
|
357
|
+
- Fetch and print the tools available for a specified agent or for all agents if `agent_id` is set to `None`.
|
|
358
|
+
- Construct the unique identifier for a tool using the format `agentId-toolName`.
|
|
359
|
+
- Retrieve and display the description of a specific tool using its unique identifier.
|
|
360
|
+
- Retrieve and display the input and output schema of a specific tool using its unique identifier.
|
|
361
|
+
|
|
217
362
|
## Developer installation
|
|
218
363
|
|
|
219
364
|
To setup the development environment for this project, clone the repository and run the following commands:
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# ------------------------------------------------------------------------------
|
|
3
|
+
#
|
|
4
|
+
# Copyright 2023 Valory AG
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
#
|
|
18
|
+
# ------------------------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
"""Mech client CLI module."""
|
|
21
|
+
import json
|
|
22
|
+
from typing import Any, Dict, List, Optional, Tuple
|
|
23
|
+
|
|
24
|
+
import click
|
|
25
|
+
from tabulate import tabulate # type: ignore
|
|
26
|
+
|
|
27
|
+
from mech_client import __version__
|
|
28
|
+
from mech_client.interact import ConfirmationType
|
|
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
|
+
)
|
|
35
|
+
from mech_client.prompt_to_ipfs import main as prompt_to_ipfs_main
|
|
36
|
+
from mech_client.push_to_ipfs import main as push_to_ipfs_main
|
|
37
|
+
from mech_client.to_png import main as to_png_main
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@click.group(name="mechx") # type: ignore
|
|
41
|
+
@click.version_option(__version__, prog_name="mechx")
|
|
42
|
+
def cli() -> None:
|
|
43
|
+
"""Command-line tool for interacting with mechs."""
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@click.command()
|
|
47
|
+
@click.argument("prompt")
|
|
48
|
+
@click.argument("agent_id", type=int)
|
|
49
|
+
@click.option(
|
|
50
|
+
"--key",
|
|
51
|
+
type=click.Path(exists=True, file_okay=True, dir_okay=False),
|
|
52
|
+
help="Path to private key to use for request minting",
|
|
53
|
+
)
|
|
54
|
+
@click.option(
|
|
55
|
+
"--tool",
|
|
56
|
+
type=str,
|
|
57
|
+
help="Name of the tool to be used",
|
|
58
|
+
)
|
|
59
|
+
@click.option(
|
|
60
|
+
"--extra-attribute",
|
|
61
|
+
type=str,
|
|
62
|
+
multiple=True,
|
|
63
|
+
help="Extra attribute (key=value) to be included in the request metadata",
|
|
64
|
+
metavar="KEY=VALUE",
|
|
65
|
+
)
|
|
66
|
+
@click.option(
|
|
67
|
+
"--confirm",
|
|
68
|
+
type=click.Choice(
|
|
69
|
+
choices=(ConfirmationType.OFF_CHAIN.value, ConfirmationType.ON_CHAIN.value)
|
|
70
|
+
),
|
|
71
|
+
help="Data verification method (on-chain/off-chain)",
|
|
72
|
+
)
|
|
73
|
+
@click.option(
|
|
74
|
+
"--retries",
|
|
75
|
+
type=int,
|
|
76
|
+
help="Number of retries for sending a transaction",
|
|
77
|
+
)
|
|
78
|
+
@click.option(
|
|
79
|
+
"--timeout",
|
|
80
|
+
type=float,
|
|
81
|
+
help="Timeout to wait for the transaction",
|
|
82
|
+
)
|
|
83
|
+
@click.option(
|
|
84
|
+
"--sleep",
|
|
85
|
+
type=float,
|
|
86
|
+
help="Amount of sleep before retrying the transaction",
|
|
87
|
+
)
|
|
88
|
+
@click.option(
|
|
89
|
+
"--chain-config",
|
|
90
|
+
type=str,
|
|
91
|
+
help="Id of the mech's chain configuration (stored configs/mechs.json)",
|
|
92
|
+
)
|
|
93
|
+
def interact( # pylint: disable=too-many-arguments
|
|
94
|
+
prompt: str,
|
|
95
|
+
agent_id: int,
|
|
96
|
+
key: Optional[str],
|
|
97
|
+
tool: Optional[str],
|
|
98
|
+
extra_attribute: Optional[List[str]] = None,
|
|
99
|
+
confirm: Optional[str] = None,
|
|
100
|
+
retries: Optional[int] = None,
|
|
101
|
+
timeout: Optional[float] = None,
|
|
102
|
+
sleep: Optional[float] = None,
|
|
103
|
+
chain_config: Optional[str] = None,
|
|
104
|
+
) -> None:
|
|
105
|
+
"""Interact with a mech specifying a prompt and tool."""
|
|
106
|
+
try:
|
|
107
|
+
extra_attributes_dict: Dict[str, Any] = {}
|
|
108
|
+
if extra_attribute:
|
|
109
|
+
for pair in extra_attribute:
|
|
110
|
+
k, v = pair.split("=")
|
|
111
|
+
extra_attributes_dict[k] = v
|
|
112
|
+
|
|
113
|
+
interact_(
|
|
114
|
+
prompt=prompt,
|
|
115
|
+
agent_id=agent_id,
|
|
116
|
+
private_key_path=key,
|
|
117
|
+
tool=tool,
|
|
118
|
+
extra_attributes=extra_attributes_dict,
|
|
119
|
+
confirmation_type=(
|
|
120
|
+
ConfirmationType(confirm)
|
|
121
|
+
if confirm is not None
|
|
122
|
+
else ConfirmationType.WAIT_FOR_BOTH
|
|
123
|
+
),
|
|
124
|
+
retries=retries,
|
|
125
|
+
timeout=timeout,
|
|
126
|
+
sleep=sleep,
|
|
127
|
+
chain_config=chain_config,
|
|
128
|
+
)
|
|
129
|
+
except (ValueError, FileNotFoundError) as e:
|
|
130
|
+
raise click.ClickException(str(e)) from e
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
@click.command()
|
|
134
|
+
@click.argument("prompt")
|
|
135
|
+
@click.argument("tool")
|
|
136
|
+
def prompt_to_ipfs(prompt: str, tool: str) -> None:
|
|
137
|
+
"""Upload a prompt and tool to IPFS as metadata."""
|
|
138
|
+
prompt_to_ipfs_main(prompt=prompt, tool=tool)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
@click.command()
|
|
142
|
+
@click.argument("file_path")
|
|
143
|
+
def push_to_ipfs(file_path: str) -> None:
|
|
144
|
+
"""Upload a file to IPFS."""
|
|
145
|
+
push_to_ipfs_main(file_path=file_path)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
@click.command()
|
|
149
|
+
@click.argument("ipfs_hash")
|
|
150
|
+
@click.argument("path")
|
|
151
|
+
@click.argument("request_id")
|
|
152
|
+
def to_png(ipfs_hash: str, path: str, request_id: str) -> None:
|
|
153
|
+
"""Convert a stability AI API's diffusion model output into a PNG format."""
|
|
154
|
+
to_png_main(ipfs_hash, path, request_id)
|
|
155
|
+
|
|
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", "Mech Marketplace Support"]
|
|
171
|
+
data: List[Tuple[str, ...]] = [
|
|
172
|
+
(
|
|
173
|
+
str(tool["tool_name"]),
|
|
174
|
+
str(tool["unique_identifier"]),
|
|
175
|
+
"✓" if bool(tool["is_marketplace_supported"]) else "✗",
|
|
176
|
+
)
|
|
177
|
+
for tool in result["tools"]
|
|
178
|
+
]
|
|
179
|
+
else:
|
|
180
|
+
headers = [
|
|
181
|
+
"Agent ID",
|
|
182
|
+
"Tool Name",
|
|
183
|
+
"Unique Identifier",
|
|
184
|
+
"Mech Marketplace Support",
|
|
185
|
+
]
|
|
186
|
+
|
|
187
|
+
data = [
|
|
188
|
+
(
|
|
189
|
+
str(agent_id),
|
|
190
|
+
tool["tool_name"],
|
|
191
|
+
tool["unique_identifier"],
|
|
192
|
+
(
|
|
193
|
+
"✓"
|
|
194
|
+
if bool(
|
|
195
|
+
tool["is_marketplace_supported"],
|
|
196
|
+
)
|
|
197
|
+
else "✗"
|
|
198
|
+
),
|
|
199
|
+
)
|
|
200
|
+
for agent_id, _ in result["agent_tools_map"].items()
|
|
201
|
+
for tool in result["all_tools_with_identifiers"]
|
|
202
|
+
if tool["unique_identifier"].startswith(f"{agent_id}-")
|
|
203
|
+
]
|
|
204
|
+
|
|
205
|
+
click.echo(tabulate(data, headers=headers, tablefmt="grid"))
|
|
206
|
+
except (KeyError, TypeError) as e:
|
|
207
|
+
click.echo(f"Error processing tool data: {str(e)}")
|
|
208
|
+
except json.JSONDecodeError as e:
|
|
209
|
+
click.echo(f"Error decoding JSON response: {str(e)}")
|
|
210
|
+
except IOError as e:
|
|
211
|
+
click.echo(f"Network or I/O error: {str(e)}")
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
@click.command(name="tool-description")
|
|
215
|
+
@click.argument("tool_id")
|
|
216
|
+
@click.option("--chain-config", default="gnosis", help="Chain configuration to use.")
|
|
217
|
+
def tool_description(tool_id: str, chain_config: str) -> None:
|
|
218
|
+
"""Fetch and display the description of a specific tool."""
|
|
219
|
+
try:
|
|
220
|
+
description = get_tool_description(tool_id, chain_config)
|
|
221
|
+
click.echo(f"Description for tool {tool_id}: {description}")
|
|
222
|
+
except KeyError as e:
|
|
223
|
+
click.echo(f"Tool not found or missing description: {str(e)}")
|
|
224
|
+
except json.JSONDecodeError as e:
|
|
225
|
+
click.echo(f"Error decoding JSON response: {str(e)}")
|
|
226
|
+
except IOError as e:
|
|
227
|
+
click.echo(f"Network or I/O error: {str(e)}")
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
@click.command(name="tool-io-schema")
|
|
231
|
+
@click.argument("tool_id")
|
|
232
|
+
@click.option("--chain-config", default="gnosis", help="Chain configuration to use.")
|
|
233
|
+
def tool_io_schema(tool_id: str, chain_config: str) -> None:
|
|
234
|
+
"""Fetch and display the tool's name and description along with the input/output schema for a specific tool."""
|
|
235
|
+
try:
|
|
236
|
+
result = get_tool_io_schema(tool_id, chain_config)
|
|
237
|
+
|
|
238
|
+
name = result["name"]
|
|
239
|
+
description = result["description"]
|
|
240
|
+
# Prepare data for tabulation
|
|
241
|
+
input_schema = [(key, result["input"][key]) for key in result["input"]]
|
|
242
|
+
|
|
243
|
+
# Handling nested output schema
|
|
244
|
+
output_schema = []
|
|
245
|
+
if "properties" in result["output"]["schema"]:
|
|
246
|
+
for key, value in result["output"]["schema"]["properties"].items():
|
|
247
|
+
output_schema.append((key, value["type"], value.get("description", "")))
|
|
248
|
+
|
|
249
|
+
# Display tool details in tabulated format
|
|
250
|
+
click.echo("Tool Details:")
|
|
251
|
+
click.echo(
|
|
252
|
+
tabulate(
|
|
253
|
+
[
|
|
254
|
+
[
|
|
255
|
+
name,
|
|
256
|
+
description,
|
|
257
|
+
]
|
|
258
|
+
],
|
|
259
|
+
headers=["Tool Name", "Tool Description"],
|
|
260
|
+
tablefmt="grid",
|
|
261
|
+
)
|
|
262
|
+
)
|
|
263
|
+
# Display schemas in tabulated format
|
|
264
|
+
click.echo("Input Schema:")
|
|
265
|
+
click.echo(tabulate(input_schema, headers=["Field", "Value"], tablefmt="grid"))
|
|
266
|
+
click.echo("Output Schema:")
|
|
267
|
+
click.echo(
|
|
268
|
+
tabulate(
|
|
269
|
+
output_schema, headers=["Field", "Type", "Description"], tablefmt="grid"
|
|
270
|
+
)
|
|
271
|
+
)
|
|
272
|
+
except KeyError as e:
|
|
273
|
+
click.echo(f"Error accessing schema data: {str(e)}")
|
|
274
|
+
except json.JSONDecodeError as e:
|
|
275
|
+
click.echo(f"Error decoding JSON response: {str(e)}")
|
|
276
|
+
except IOError as e:
|
|
277
|
+
click.echo(f"Network or I/O error: {str(e)}")
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
cli.add_command(interact)
|
|
281
|
+
cli.add_command(prompt_to_ipfs)
|
|
282
|
+
cli.add_command(push_to_ipfs)
|
|
283
|
+
cli.add_command(to_png)
|
|
284
|
+
cli.add_command(tools_for_agents)
|
|
285
|
+
cli.add_command(tool_io_schema)
|
|
286
|
+
cli.add_command(tool_description)
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
if __name__ == "__main__":
|
|
290
|
+
cli()
|
|
@@ -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,18 +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("Chain configuration:")
|
|
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)
|
|
167
166
|
|
|
168
|
-
print(f" - Chain ID: {chain_config}")
|
|
169
|
-
print(f" - Gas limit: {mech_config.gas_limit}")
|
|
170
|
-
print(f" - Contract ABI URL: {mech_config.contract_abi_url}")
|
|
171
|
-
print(f" - Transation URL: {mech_config.transaction_url}")
|
|
172
|
-
print(f" - Subgraph URL: {mech_config.subgraph_url}")
|
|
173
|
-
print("")
|
|
174
|
-
|
|
175
167
|
return mech_config
|
|
176
168
|
|
|
177
169
|
|
|
@@ -303,12 +295,16 @@ def verify_or_retrieve_tool(
|
|
|
303
295
|
:return: The result of the verification or retrieval.
|
|
304
296
|
:rtype: str
|
|
305
297
|
"""
|
|
306
|
-
|
|
298
|
+
# Fetch tools, possibly including metadata
|
|
299
|
+
tools_data = fetch_tools(
|
|
307
300
|
agent_id=agent_id,
|
|
308
301
|
ledger_api=ledger_api,
|
|
309
302
|
agent_registry_contract=agent_registry_contract,
|
|
310
303
|
contract_abi_url=contract_abi_url,
|
|
304
|
+
include_metadata=False, # Ensure this is False to only get the list of tools
|
|
311
305
|
)
|
|
306
|
+
# Ensure only the list of tools is used
|
|
307
|
+
available_tools = tools_data if isinstance(tools_data, list) else tools_data[0]
|
|
312
308
|
if tool is not None and tool not in available_tools:
|
|
313
309
|
raise ValueError(
|
|
314
310
|
f"Provided tool `{tool}` not in the list of available tools; Available tools={available_tools}"
|
|
@@ -323,8 +319,9 @@ def fetch_tools(
|
|
|
323
319
|
ledger_api: EthereumApi,
|
|
324
320
|
agent_registry_contract: str,
|
|
325
321
|
contract_abi_url: str,
|
|
326
|
-
|
|
327
|
-
|
|
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."""
|
|
328
325
|
mech_registry = get_contract(
|
|
329
326
|
contract_address=agent_registry_contract,
|
|
330
327
|
abi=get_abi(agent_registry_contract, contract_abi_url),
|
|
@@ -332,7 +329,12 @@ def fetch_tools(
|
|
|
332
329
|
)
|
|
333
330
|
token_uri = mech_registry.functions.tokenURI(agent_id).call()
|
|
334
331
|
response = requests.get(token_uri).json()
|
|
335
|
-
|
|
332
|
+
tools = response.get("tools", [])
|
|
333
|
+
|
|
334
|
+
if include_metadata:
|
|
335
|
+
tool_metadata = response.get("toolMetadata", {})
|
|
336
|
+
return tools, tool_metadata
|
|
337
|
+
return tools
|
|
336
338
|
|
|
337
339
|
|
|
338
340
|
def send_request( # pylint: disable=too-many-arguments,too-many-locals
|
|
@@ -0,0 +1,205 @@
|
|
|
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", include_metadata: bool = False
|
|
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
|
+
:param include_metadata: To include tools metadata or not (default is False)
|
|
46
|
+
: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.
|
|
47
|
+
"""
|
|
48
|
+
try:
|
|
49
|
+
# Get the mech configuration
|
|
50
|
+
mech_config = get_mech_config(chain_config)
|
|
51
|
+
ledger_config = mech_config.ledger_config
|
|
52
|
+
|
|
53
|
+
# Setup Ethereum API
|
|
54
|
+
ledger_api = EthereumApi(**asdict(ledger_config))
|
|
55
|
+
|
|
56
|
+
# Fetch tools for the given agent ID
|
|
57
|
+
return fetch_tools(
|
|
58
|
+
agent_id=agent_id,
|
|
59
|
+
ledger_api=ledger_api,
|
|
60
|
+
agent_registry_contract=mech_config.agent_registry_contract,
|
|
61
|
+
contract_abi_url=mech_config.contract_abi_url,
|
|
62
|
+
include_metadata=include_metadata,
|
|
63
|
+
)
|
|
64
|
+
except (requests.exceptions.RequestException, json.JSONDecodeError, KeyError) as e:
|
|
65
|
+
print(f"An error occurred while fetching tools for agent {agent_id}: {e}")
|
|
66
|
+
return None
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def get_tools_for_agents(
|
|
70
|
+
agent_id: Optional[int] = None, chain_config: str = "gnosis"
|
|
71
|
+
) -> Dict[str, Any]:
|
|
72
|
+
"""
|
|
73
|
+
Retrieve tools for specified agents or all agents if no specific agent is provided.
|
|
74
|
+
|
|
75
|
+
:param agent_id: Optional; specific agent ID to fetch tools for.
|
|
76
|
+
:param chain_config: The chain configuration to use.
|
|
77
|
+
:return: Dictionary of tools with identifiers or a mapping of agent IDs to tools.
|
|
78
|
+
"""
|
|
79
|
+
try:
|
|
80
|
+
total_supply = get_total_supply(chain_config)
|
|
81
|
+
|
|
82
|
+
if agent_id is not None:
|
|
83
|
+
result = get_agent_tools(agent_id, chain_config, True)
|
|
84
|
+
|
|
85
|
+
if result is not None:
|
|
86
|
+
(tools, tool_metadata) = result
|
|
87
|
+
|
|
88
|
+
if isinstance(tools, list) and isinstance(tool_metadata, dict):
|
|
89
|
+
tools_with_ids = [
|
|
90
|
+
{
|
|
91
|
+
"tool_name": tool,
|
|
92
|
+
"unique_identifier": f"{agent_id}-{tool}",
|
|
93
|
+
"is_marketplace_supported": (
|
|
94
|
+
tool_metadata.get(tool, {}).get(
|
|
95
|
+
"isMechMarketplaceSupported", None
|
|
96
|
+
)
|
|
97
|
+
),
|
|
98
|
+
}
|
|
99
|
+
for tool in tools
|
|
100
|
+
]
|
|
101
|
+
else:
|
|
102
|
+
tools_with_ids = []
|
|
103
|
+
return {"agent_id": agent_id, "tools": tools_with_ids}
|
|
104
|
+
|
|
105
|
+
all_tools_with_ids = []
|
|
106
|
+
agent_tools_map = {}
|
|
107
|
+
|
|
108
|
+
for current_agent_id in range(1, total_supply + 1):
|
|
109
|
+
result = get_agent_tools(current_agent_id, chain_config, True)
|
|
110
|
+
if result is not None:
|
|
111
|
+
(tools, tool_metadata) = result
|
|
112
|
+
|
|
113
|
+
if isinstance(tools, list) and isinstance(tool_metadata, dict):
|
|
114
|
+
tools_with_ids = [
|
|
115
|
+
{
|
|
116
|
+
"tool_name": tool,
|
|
117
|
+
"unique_identifier": f"{current_agent_id}-{tool}",
|
|
118
|
+
"is_marketplace_supported": (
|
|
119
|
+
tool_metadata.get(tool, {}).get(
|
|
120
|
+
"isMechMarketplaceSupported", None
|
|
121
|
+
)
|
|
122
|
+
),
|
|
123
|
+
}
|
|
124
|
+
for tool in tools
|
|
125
|
+
]
|
|
126
|
+
agent_tools_map[current_agent_id] = tools
|
|
127
|
+
all_tools_with_ids.extend(tools_with_ids)
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
"all_tools_with_identifiers": all_tools_with_ids,
|
|
131
|
+
"agent_tools_map": agent_tools_map,
|
|
132
|
+
}
|
|
133
|
+
except Exception as e:
|
|
134
|
+
print(f"Error in get_tools_for_agents: {str(e)}")
|
|
135
|
+
raise
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def get_tool_description(unique_identifier: str, chain_config: str = "gnosis") -> str:
|
|
139
|
+
"""
|
|
140
|
+
Fetch the description of a specific tool based on a unique identifier.
|
|
141
|
+
|
|
142
|
+
:param unique_identifier: The unique identifier for the tool.
|
|
143
|
+
:param chain_config: The chain configuration to use.
|
|
144
|
+
:return: Description of the tool or a default message if not available.
|
|
145
|
+
"""
|
|
146
|
+
parts = unique_identifier.split("-")
|
|
147
|
+
agent_id = int(parts[0])
|
|
148
|
+
tool_name = "-".join(parts[1:])
|
|
149
|
+
|
|
150
|
+
# Get the mech configuration
|
|
151
|
+
mech_config = get_mech_config(chain_config)
|
|
152
|
+
ledger_api = EthereumApi(**asdict(mech_config.ledger_config))
|
|
153
|
+
|
|
154
|
+
tools_result = fetch_tools(
|
|
155
|
+
agent_id=agent_id,
|
|
156
|
+
ledger_api=ledger_api,
|
|
157
|
+
agent_registry_contract=mech_config.agent_registry_contract,
|
|
158
|
+
contract_abi_url=mech_config.contract_abi_url,
|
|
159
|
+
include_metadata=True,
|
|
160
|
+
)
|
|
161
|
+
if isinstance(tools_result, tuple) and len(tools_result) == 2:
|
|
162
|
+
_, tool_metadata = tools_result
|
|
163
|
+
tool_info = tool_metadata.get(tool_name, {})
|
|
164
|
+
if isinstance(tool_info, dict):
|
|
165
|
+
return tool_info.get("description", "Description not available")
|
|
166
|
+
return "Description not available"
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def get_tool_io_schema(
|
|
170
|
+
unique_identifier: str, chain_config: str = "gnosis"
|
|
171
|
+
) -> Dict[str, Any]:
|
|
172
|
+
"""
|
|
173
|
+
Fetch the input and output schema along with tool name and description of a specific tool based on a unique identifier.
|
|
174
|
+
|
|
175
|
+
:param unique_identifier: The unique identifier for the tool.
|
|
176
|
+
:param chain_config: The chain configuration to use.
|
|
177
|
+
:return: Dictionary containing name, description, input and output schemas.
|
|
178
|
+
"""
|
|
179
|
+
parts = unique_identifier.split("-")
|
|
180
|
+
agent_id = int(parts[0])
|
|
181
|
+
tool_name = "-".join(parts[1:])
|
|
182
|
+
|
|
183
|
+
# Get the mech configuration
|
|
184
|
+
mech_config = get_mech_config(chain_config)
|
|
185
|
+
ledger_api = EthereumApi(**asdict(mech_config.ledger_config))
|
|
186
|
+
|
|
187
|
+
tools_result = fetch_tools(
|
|
188
|
+
agent_id=agent_id,
|
|
189
|
+
ledger_api=ledger_api,
|
|
190
|
+
agent_registry_contract=mech_config.agent_registry_contract,
|
|
191
|
+
contract_abi_url=mech_config.contract_abi_url,
|
|
192
|
+
include_metadata=True,
|
|
193
|
+
)
|
|
194
|
+
if isinstance(tools_result, tuple) and len(tools_result) == 2:
|
|
195
|
+
_, tool_metadata = tools_result
|
|
196
|
+
tool_info = tool_metadata.get(tool_name, {})
|
|
197
|
+
if isinstance(tool_info, dict):
|
|
198
|
+
return {
|
|
199
|
+
"name": tool_info.get("name", {}),
|
|
200
|
+
"description": tool_info.get("description", {}),
|
|
201
|
+
"input": tool_info.get("input", {}),
|
|
202
|
+
"output": tool_info.get("output", {}),
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return {"input": {}, "output": {}}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "mech-client"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.17"
|
|
4
4
|
description = "Basic client to interact with a mech"
|
|
5
5
|
authors = ["David Minarsch <david.minarsch@googlemail.com>"]
|
|
6
6
|
readme = "README.md"
|
|
@@ -33,6 +33,7 @@ open-aea-ledger-cosmos = "^1.53.0"
|
|
|
33
33
|
gql = ">=3.4.1"
|
|
34
34
|
asn1crypto = ">=1.4.0,<1.5.0"
|
|
35
35
|
websocket-client = ">=0.32.0,<1"
|
|
36
|
+
tabulate = "^0.9.0"
|
|
36
37
|
|
|
37
38
|
[tool.poetry.scripts]
|
|
38
39
|
mechx = "mech_client.cli:cli"
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
# ------------------------------------------------------------------------------
|
|
3
|
-
#
|
|
4
|
-
# Copyright 2023 Valory AG
|
|
5
|
-
#
|
|
6
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
-
# you may not use this file except in compliance with the License.
|
|
8
|
-
# You may obtain a copy of the License at
|
|
9
|
-
#
|
|
10
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
-
#
|
|
12
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
-
# See the License for the specific language governing permissions and
|
|
16
|
-
# limitations under the License.
|
|
17
|
-
#
|
|
18
|
-
# ------------------------------------------------------------------------------
|
|
19
|
-
|
|
20
|
-
"""Mech client CLI module."""
|
|
21
|
-
|
|
22
|
-
from typing import Any, Dict, List, Optional
|
|
23
|
-
|
|
24
|
-
import click
|
|
25
|
-
|
|
26
|
-
from mech_client import __version__
|
|
27
|
-
from mech_client.interact import ConfirmationType
|
|
28
|
-
from mech_client.interact import interact as interact_
|
|
29
|
-
from mech_client.prompt_to_ipfs import main as prompt_to_ipfs_main
|
|
30
|
-
from mech_client.push_to_ipfs import main as push_to_ipfs_main
|
|
31
|
-
from mech_client.to_png import main as to_png_main
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
@click.group(name="mechx") # type: ignore
|
|
35
|
-
@click.version_option(__version__, prog_name="mechx")
|
|
36
|
-
def cli() -> None:
|
|
37
|
-
"""Command-line tool for interacting with mechs."""
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
@click.command()
|
|
41
|
-
@click.argument("prompt")
|
|
42
|
-
@click.argument("agent_id", type=int)
|
|
43
|
-
@click.option(
|
|
44
|
-
"--key",
|
|
45
|
-
type=click.Path(exists=True, file_okay=True, dir_okay=False),
|
|
46
|
-
help="Path to private key to use for request minting",
|
|
47
|
-
)
|
|
48
|
-
@click.option(
|
|
49
|
-
"--tool",
|
|
50
|
-
type=str,
|
|
51
|
-
help="Name of the tool to be used",
|
|
52
|
-
)
|
|
53
|
-
@click.option(
|
|
54
|
-
"--extra-attribute",
|
|
55
|
-
type=str,
|
|
56
|
-
multiple=True,
|
|
57
|
-
help="Extra attribute (key=value) to be included in the request metadata",
|
|
58
|
-
metavar="KEY=VALUE",
|
|
59
|
-
)
|
|
60
|
-
@click.option(
|
|
61
|
-
"--confirm",
|
|
62
|
-
type=click.Choice(
|
|
63
|
-
choices=(ConfirmationType.OFF_CHAIN.value, ConfirmationType.ON_CHAIN.value)
|
|
64
|
-
),
|
|
65
|
-
help="Data verification method (on-chain/off-chain)",
|
|
66
|
-
)
|
|
67
|
-
@click.option(
|
|
68
|
-
"--retries",
|
|
69
|
-
type=int,
|
|
70
|
-
help="Number of retries for sending a transaction",
|
|
71
|
-
)
|
|
72
|
-
@click.option(
|
|
73
|
-
"--timeout",
|
|
74
|
-
type=float,
|
|
75
|
-
help="Timeout to wait for the transaction",
|
|
76
|
-
)
|
|
77
|
-
@click.option(
|
|
78
|
-
"--sleep",
|
|
79
|
-
type=float,
|
|
80
|
-
help="Amount of sleep before retrying the transaction",
|
|
81
|
-
)
|
|
82
|
-
@click.option(
|
|
83
|
-
"--chain-config",
|
|
84
|
-
type=str,
|
|
85
|
-
help="Id of the mech's chain configuration (stored configs/mechs.json)",
|
|
86
|
-
)
|
|
87
|
-
def interact( # pylint: disable=too-many-arguments
|
|
88
|
-
prompt: str,
|
|
89
|
-
agent_id: int,
|
|
90
|
-
key: Optional[str],
|
|
91
|
-
tool: Optional[str],
|
|
92
|
-
extra_attribute: Optional[List[str]] = None,
|
|
93
|
-
confirm: Optional[str] = None,
|
|
94
|
-
retries: Optional[int] = None,
|
|
95
|
-
timeout: Optional[float] = None,
|
|
96
|
-
sleep: Optional[float] = None,
|
|
97
|
-
chain_config: Optional[str] = None,
|
|
98
|
-
) -> None:
|
|
99
|
-
"""Interact with a mech specifying a prompt and tool."""
|
|
100
|
-
try:
|
|
101
|
-
extra_attributes_dict: Dict[str, Any] = {}
|
|
102
|
-
if extra_attribute:
|
|
103
|
-
for pair in extra_attribute:
|
|
104
|
-
k, v = pair.split("=")
|
|
105
|
-
extra_attributes_dict[k] = v
|
|
106
|
-
|
|
107
|
-
interact_(
|
|
108
|
-
prompt=prompt,
|
|
109
|
-
agent_id=agent_id,
|
|
110
|
-
private_key_path=key,
|
|
111
|
-
tool=tool,
|
|
112
|
-
extra_attributes=extra_attributes_dict,
|
|
113
|
-
confirmation_type=(
|
|
114
|
-
ConfirmationType(confirm)
|
|
115
|
-
if confirm is not None
|
|
116
|
-
else ConfirmationType.WAIT_FOR_BOTH
|
|
117
|
-
),
|
|
118
|
-
retries=retries,
|
|
119
|
-
timeout=timeout,
|
|
120
|
-
sleep=sleep,
|
|
121
|
-
chain_config=chain_config,
|
|
122
|
-
)
|
|
123
|
-
except (ValueError, FileNotFoundError) as e:
|
|
124
|
-
raise click.ClickException(str(e)) from e
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
@click.command()
|
|
128
|
-
@click.argument("prompt")
|
|
129
|
-
@click.argument("tool")
|
|
130
|
-
def prompt_to_ipfs(prompt: str, tool: str) -> None:
|
|
131
|
-
"""Upload a prompt and tool to IPFS as metadata."""
|
|
132
|
-
prompt_to_ipfs_main(prompt=prompt, tool=tool)
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
@click.command()
|
|
136
|
-
@click.argument("file_path")
|
|
137
|
-
def push_to_ipfs(file_path: str) -> None:
|
|
138
|
-
"""Upload a file to IPFS."""
|
|
139
|
-
push_to_ipfs_main(file_path=file_path)
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
@click.command()
|
|
143
|
-
@click.argument("ipfs_hash")
|
|
144
|
-
@click.argument("path")
|
|
145
|
-
@click.argument("request_id")
|
|
146
|
-
def to_png(ipfs_hash: str, path: str, request_id: str) -> None:
|
|
147
|
-
"""Convert a stability AI API's diffusion model output into a PNG format."""
|
|
148
|
-
to_png_main(ipfs_hash, path, request_id)
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
cli.add_command(interact)
|
|
152
|
-
cli.add_command(prompt_to_ipfs)
|
|
153
|
-
cli.add_command(push_to_ipfs)
|
|
154
|
-
cli.add_command(to_png)
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
if __name__ == "__main__":
|
|
158
|
-
cli()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/acn/tests/test_acn_dialogues.py
RENAMED
|
File without changes
|
{mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/acn/tests/test_acn_messages.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/acn_data_share/acn_data_share.proto
RENAMED
|
File without changes
|
{mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/acn_data_share/acn_data_share_pb2.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/acn_data_share/serialization.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/p2p_libp2p_client/connection.py
RENAMED
|
File without changes
|
{mech_client-0.2.15 → mech_client-0.2.17}/mech_client/helpers/p2p_libp2p_client/connection.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|