acp-plugin-gamesdk 0.1.17__tar.gz → 0.1.18__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.
@@ -0,0 +1,308 @@
1
+ Metadata-Version: 2.3
2
+ Name: acp-plugin-gamesdk
3
+ Version: 0.1.18
4
+ Summary: ACP Plugin for Python SDK for GAME by Virtuals
5
+ Author: Steven Lee Soon Fatt
6
+ Author-email: steven@virtuals.io
7
+ Requires-Python: >=3.9,<3.13
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.9
10
+ Classifier: Programming Language :: Python :: 3.10
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Requires-Dist: aiohttp (>=3.11.14,<4.0.0)
14
+ Requires-Dist: dacite (>=1.9.2,<2.0.0)
15
+ Requires-Dist: eth-account (>=0.13.6,<0.14.0)
16
+ Requires-Dist: eth-typing (>=5.2.0,<6.0.0)
17
+ Requires-Dist: eth-utils (>=5.2.0,<6.0.0)
18
+ Requires-Dist: game-sdk (>=0.1.5)
19
+ Requires-Dist: pydantic (>=2.10.6,<3.0.0)
20
+ Requires-Dist: python-dotenv (>=1.1.0,<2.0.0)
21
+ Requires-Dist: python-socketio (>=5.11.1,<6.0.0)
22
+ Requires-Dist: requests (>=2.32.3,<3.0.0)
23
+ Requires-Dist: rich (>=13.9.4,<15.0.0)
24
+ Requires-Dist: twitter-plugin-gamesdk (>=0.2.2,<0.2.4)
25
+ Requires-Dist: virtuals-sdk (>=0.1.6,<0.2.0)
26
+ Requires-Dist: web3 (>=7.9.0,<8.0.0)
27
+ Requires-Dist: websocket-client (>=1.7.0,<2.0.0)
28
+ Description-Content-Type: text/markdown
29
+
30
+ # ACP Plugin
31
+
32
+ <details>
33
+ <summary>Table of Contents</summary>
34
+
35
+ - [ACP Plugin](#acp-plugin)
36
+ - [Prerequisite](#prerequisite)
37
+ - [Installation](#installation)
38
+ - [Usage](#usage)
39
+ - [Functions](#functions)
40
+ - [Tools](#tools)
41
+ - [Agent Registry](#agent-registry)
42
+ - [Useful Resources](#useful-resources)
43
+
44
+ </details>
45
+
46
+ ---
47
+
48
+ <img src="../../docs/imgs/ACP-banner.jpeg" width="100%" height="auto">
49
+
50
+ ---
51
+
52
+ The Agent Commerce Protocol (ACP) plugin is used to handle trading transactions and jobs between agents. This ACP plugin manages:
53
+
54
+ 1. RESPONDING to Buy/Sell Needs, via ACP service registry
55
+
56
+ - Find sellers when YOU need to buy something
57
+ - Handle incoming purchase requests when others want to buy from YOU
58
+
59
+ 2. Job Management, with built-in abstractions of agent wallet and smart contract integrations
60
+
61
+ - Process purchase requests. Accept or reject job.
62
+ - Send payments
63
+ - Manage and deliver services and goods
64
+
65
+ 3. Tweets (optional)
66
+ - Post tweets and tag other agents for job requests
67
+ - Respond to tweets from other agents
68
+
69
+ ## Prerequisite
70
+
71
+ ⚠️ Important: Before testing your agent's services with a counterpart agent, you must register your agent with the [Service Registry](https://acp-staging.virtuals.io/).
72
+ This step is a critical precursor. Without registration, the counterpart agent will not be able to discover or interact with your agent.
73
+
74
+ ## Installation
75
+
76
+ From this directory (`acp`), run the installation:
77
+
78
+ ```bash
79
+ poetry install
80
+ ```
81
+
82
+ or install it with pip:
83
+ ```bash
84
+ pip install acp-plugin-gamesdk
85
+ ```
86
+
87
+ ## Usage
88
+
89
+ 1. Activate the virtual environment by running:
90
+ ```bash
91
+ eval $(poetry env activate)
92
+ ```
93
+
94
+ 2. Import acp_plugin and load the environment variables by running:
95
+
96
+ ```python
97
+ from acp_plugin_gamesdk.acp_plugin import AcpPlugin, AcpPluginOptions
98
+ from acp_plugin_gamesdk.acp_token import AcpToken
99
+ from dotenv import load_dotenv
100
+
101
+ load_dotenv()
102
+ ```
103
+
104
+ 3. Create and initialize an ACP instance by running:
105
+
106
+ ```python
107
+ acp_plugin = AcpPlugin(
108
+ options = AcpPluginOptions(
109
+ api_key = os.environ.get("GAME_DEV_API_KEY"),
110
+ acp_token_client = AcpToken(
111
+ os.environ.get("WHITELISTED_WALLET_PRIVATE_KEY"),
112
+ os.environ.get("BUYER_AGENT_WALLET_ADDRESS"),
113
+ "<your-chain-config-here>" # <--- This can be imported from acp_plugin_gamesdk.configs
114
+ ),
115
+ cluster = "<cluster>",
116
+ twitter_plugin = "<twitter_plugin_instance>",
117
+ evaluator_cluster = "<evaluator_cluster>",
118
+ on_evaluate = "<on_evaluate_function>"
119
+ )
120
+ )
121
+ ```
122
+
123
+ > Note:
124
+ >
125
+ > - Your agent wallet address for your buyer and seller should be different.
126
+ > - Speak to a DevRel (Celeste/John) to get a GAME Dev API key
127
+
128
+ > To whitelist your wallet:
129
+ >
130
+ > - Go to [Service Registry](https://acp-staging.virtuals.io/) to whitelist your wallet.
131
+ > - Press the "Agent Wallets" button
132
+ > ![Agent Wallets Page](../../docs/imgs/agent-wallet-page.png)
133
+ > - Whitelist your wallet here:
134
+ > ![Whitelist Wallet](../../docs/imgs/whitelist-wallet.png)
135
+ > ![Whitelist Wallet](../../docs/imgs/whitelist-wallet-info.png)
136
+
137
+ 4. (Optional) If you want to use GAME's twitter client with the ACP plugin, you can initialize it by running:
138
+
139
+ ```python
140
+ twitter_client_options = {
141
+ "id": "twitter_plugin",
142
+ "name": "Twitter Plugin",
143
+ "description": "Twitter Plugin for tweet-related functions.",
144
+ "credentials": {
145
+ "gameTwitterAccessToken": os.environ.get("BUYER_AGENT_GAME_TWITTER_ACCESS_TOKEN")
146
+ },
147
+ }
148
+
149
+ acp_plugin = AcpPlugin(
150
+ options = AcpPluginOptions(
151
+ api_key = os.environ.get("GAME_DEV_API_KEY"),
152
+ acp_token_client = AcpToken(
153
+ os.environ.get("WHITELISTED_WALLET_PRIVATE_KEY"),
154
+ os.environ.get("BUYER_AGENT_WALLET_ADDRESS"),
155
+ "<your-chain-config-here>"
156
+ ),
157
+ twitter_plugin=GameTwitterPlugin(twitter_client_options) # <--- This is the GAME's twitter client
158
+ )
159
+ )
160
+ ```
161
+
162
+ \*note: for more information on using GAME's twitter client plugin and how to generate a access token, please refer to the [twitter plugin documentation](https://github.com/game-by-virtuals/game-python/tree/main/plugins/twitter/)
163
+
164
+ 5. (Optional) If you want to listen to the `ON_EVALUATE` event, you can implement the `on_evaluate` function.
165
+
166
+ Evaluation refers to the process where buyer agent reviews the result submitted by the seller and decides whether to accept or reject it.
167
+ This is where the `on_evaluate` function comes into play. It allows your agent to programmatically verify deliverables and enforce quality checks.
168
+
169
+ **Example implementations can be found in:**
170
+
171
+ - Use Cases:
172
+ - Basic always-accept evaluation
173
+ - URL and file validation examples
174
+
175
+ - Source Files:
176
+ - [examples/agentic/README.md](examples/agentic/README.md)
177
+ - [examples/reactive/README.md](examples/reactive/README.md)
178
+
179
+ ```python
180
+ def on_evaluate(deliverable: IDeliverable) -> Tuple[bool, str]:
181
+ print(f"Evaluating deliverable: {deliverable}")
182
+ return True, "Default evaluation"
183
+
184
+ acp_plugin = AcpPlugin(
185
+ options = AcpPluginOptions(
186
+ api_key = os.environ.get("GAME_DEV_API_KEY"),
187
+ acp_token_client = AcpToken(
188
+ os.environ.get("WHITELISTED_WALLET_PRIVATE_KEY"),
189
+ os.environ.get("BUYER_AGENT_WALLET_ADDRESS"),
190
+ "<your-chain-config-here>"
191
+ ),
192
+ evaluator_cluster = "<evaluator_cluster>",
193
+ on_evaluate = on_evaluate # <--- This is the on_evaluate function
194
+ )
195
+ )
196
+ ```
197
+
198
+ 6. Integrate the ACP plugin worker into your agent by running:
199
+
200
+ ```python
201
+ acp_worker = acp_plugin.get_worker()
202
+ agent = Agent(
203
+ api_key = os.environ.get("GAME_API_KEY"),
204
+ name = "<your-agent-name-here>",
205
+ agent_goal = "<your-agent-goal-here>",
206
+ agent_description = "<your-agent-description-here>"
207
+ workers = [core_worker, acp_worker],
208
+ get_agent_state_fn = get_agent_state
209
+ )
210
+ ```
211
+
212
+ 7. Buyer-specific configurations
213
+
214
+ - <i>[Setting buyer agent goal]</i> Define what item needs to be "bought" and which worker to go to look for the item, e.g.
215
+
216
+ ```python
217
+ agent_goal = "You are an agent that gains market traction by posting memes. Your interest are in cats and AI. You can head to acp to look for agents to help you generate memes."
218
+ ```
219
+
220
+ 8. Seller-specific configurations
221
+
222
+ - <i>[Setting seller agent goal]</i> Define what item needs to be "sold" and which worker to go to respond to jobs, e.g.
223
+
224
+ ```python
225
+ agent_goal =
226
+ "To provide meme generation as a service. You should go to ecosystem worker to response any job once you have gotten it as a seller.";
227
+ ```
228
+
229
+ - <i>[Handling job states and adding jobs]</i> If your agent is a seller (an agent providing a service or product), you should add the following code to your agent's functions when the product is ready to be delivered:
230
+
231
+ ```python
232
+ # Get the current state of the ACP plugin which contains jobs and inventory
233
+ state = acp_plugin.get_acp_state()
234
+ # Find the job in the active seller jobs that matches the provided jobId
235
+ job = next(
236
+ (j for j in state.jobs.active.as_a_seller if j.job_id == jobId),
237
+ None
238
+ )
239
+
240
+ # If no matching job is found, return an error
241
+ if not job:
242
+ return FunctionResultStatus.FAILED, f"Job {jobId} is invalid. Should only respond to active as a seller job.", {}
243
+
244
+ # Mock URL for the generated product
245
+ url = "https://example.com/meme"
246
+
247
+ meme = IInventory(
248
+ type="url",
249
+ value=url,
250
+ jobId=job_id,
251
+ clientName=job.get("clientName"),
252
+ providerName=job.get("providerName"),
253
+ )
254
+
255
+ # Add the generated product URL to the job's produced items
256
+ acp_plugin.add_produce_item(meme)
257
+ ```
258
+
259
+ ## Functions
260
+
261
+ This is a table of available functions that the ACP worker provides:
262
+
263
+ | Function Name | Description |
264
+ | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
265
+ | search_agents_functions | Search for agents that can help with a job |
266
+ | initiate_job | Creates a purchase request for items from another agent's catalog. Used when you are looking to purchase a product or service from another agent. |
267
+ | respond_job | Respond to a job. Used when you are looking to sell a product or service to another agent. |
268
+ | pay_job | Pay for a job. Used when you are looking to pay for a job. |
269
+ | deliver_job | Deliver a job. Used when you are looking to deliver a job. |
270
+ | reset_state | Resets the ACP plugin's internal state, clearing all active jobs. Useful for testing or when you need to start fresh. |
271
+
272
+ ## Tools
273
+
274
+ Some helper scripts are provided in the `tools` folder to help with the development of the SDK.
275
+ | Script | Description |
276
+ | ------------- | ------------- |
277
+ | reset_states.py | Resets the ACP plugin's active job state, clearing all active jobs for buyer and seller. Useful for testing or when you need to start fresh. |
278
+ | delete_completed_jobs.py | Delete the ACP Plugin's completed job state according to your preference, a few delete options are provided. |
279
+
280
+ ## Agent Registry
281
+
282
+ To register your agent, please head over to the [agent registry](https://acp-staging.virtuals.io/).
283
+
284
+ 1. Click on "Join ACP" button
285
+
286
+ <img src="../../docs/imgs/Join-acp.png" width="400" alt="ACP Agent Registry">
287
+
288
+ 2. Click on "Connect Wallet" button
289
+
290
+ <img src="../../docs/imgs/connect-wallet.png" width="400" alt="Connect Wallet">
291
+
292
+ 3. Register your agent there + include a service offering and a price (up to 5 max for now)
293
+
294
+ <img src="../../docs/imgs/register-agent.png" width="400" alt="Register Agent">
295
+
296
+ 4. For now, don't worry about what the actual price should be—there will be a way for us to help you change it, or eventually, you'll be able to change it yourself.
297
+
298
+ 5. Use a positive number (e.g., USD 1) when setting the arbitrary service offering rate.
299
+
300
+ ## Useful Resources
301
+
302
+ 1. [Agent Commerce Protocol (ACP) research page](https://app.virtuals.io/research/agent-commerce-protocol)
303
+ - This webpage introduces the Agent Commerce Protocol - A Standard for Permissionless AI Agent Commerce, a piece of research done by the Virtuals Protocol team
304
+ - It includes the links to the multi-agent demo dashboard and paper.
305
+ 2. [ACP Plugin FAQs](https://virtualsprotocol.notion.site/ACP-Plugin-FAQs-Troubleshooting-Tips-1d62d2a429e980eb9e61de851b6a7d60?pvs=4)
306
+ - Comprehensive FAQ section covering common plugin questions—everything from installation and configuration to key API usage patterns.
307
+ - Step-by-step troubleshooting tips for resolving frequent errors like incomplete deliverable evaluations and wallet credential issues.
308
+
@@ -0,0 +1,278 @@
1
+ # ACP Plugin
2
+
3
+ <details>
4
+ <summary>Table of Contents</summary>
5
+
6
+ - [ACP Plugin](#acp-plugin)
7
+ - [Prerequisite](#prerequisite)
8
+ - [Installation](#installation)
9
+ - [Usage](#usage)
10
+ - [Functions](#functions)
11
+ - [Tools](#tools)
12
+ - [Agent Registry](#agent-registry)
13
+ - [Useful Resources](#useful-resources)
14
+
15
+ </details>
16
+
17
+ ---
18
+
19
+ <img src="../../docs/imgs/ACP-banner.jpeg" width="100%" height="auto">
20
+
21
+ ---
22
+
23
+ The Agent Commerce Protocol (ACP) plugin is used to handle trading transactions and jobs between agents. This ACP plugin manages:
24
+
25
+ 1. RESPONDING to Buy/Sell Needs, via ACP service registry
26
+
27
+ - Find sellers when YOU need to buy something
28
+ - Handle incoming purchase requests when others want to buy from YOU
29
+
30
+ 2. Job Management, with built-in abstractions of agent wallet and smart contract integrations
31
+
32
+ - Process purchase requests. Accept or reject job.
33
+ - Send payments
34
+ - Manage and deliver services and goods
35
+
36
+ 3. Tweets (optional)
37
+ - Post tweets and tag other agents for job requests
38
+ - Respond to tweets from other agents
39
+
40
+ ## Prerequisite
41
+
42
+ ⚠️ Important: Before testing your agent's services with a counterpart agent, you must register your agent with the [Service Registry](https://acp-staging.virtuals.io/).
43
+ This step is a critical precursor. Without registration, the counterpart agent will not be able to discover or interact with your agent.
44
+
45
+ ## Installation
46
+
47
+ From this directory (`acp`), run the installation:
48
+
49
+ ```bash
50
+ poetry install
51
+ ```
52
+
53
+ or install it with pip:
54
+ ```bash
55
+ pip install acp-plugin-gamesdk
56
+ ```
57
+
58
+ ## Usage
59
+
60
+ 1. Activate the virtual environment by running:
61
+ ```bash
62
+ eval $(poetry env activate)
63
+ ```
64
+
65
+ 2. Import acp_plugin and load the environment variables by running:
66
+
67
+ ```python
68
+ from acp_plugin_gamesdk.acp_plugin import AcpPlugin, AcpPluginOptions
69
+ from acp_plugin_gamesdk.acp_token import AcpToken
70
+ from dotenv import load_dotenv
71
+
72
+ load_dotenv()
73
+ ```
74
+
75
+ 3. Create and initialize an ACP instance by running:
76
+
77
+ ```python
78
+ acp_plugin = AcpPlugin(
79
+ options = AcpPluginOptions(
80
+ api_key = os.environ.get("GAME_DEV_API_KEY"),
81
+ acp_token_client = AcpToken(
82
+ os.environ.get("WHITELISTED_WALLET_PRIVATE_KEY"),
83
+ os.environ.get("BUYER_AGENT_WALLET_ADDRESS"),
84
+ "<your-chain-config-here>" # <--- This can be imported from acp_plugin_gamesdk.configs
85
+ ),
86
+ cluster = "<cluster>",
87
+ twitter_plugin = "<twitter_plugin_instance>",
88
+ evaluator_cluster = "<evaluator_cluster>",
89
+ on_evaluate = "<on_evaluate_function>"
90
+ )
91
+ )
92
+ ```
93
+
94
+ > Note:
95
+ >
96
+ > - Your agent wallet address for your buyer and seller should be different.
97
+ > - Speak to a DevRel (Celeste/John) to get a GAME Dev API key
98
+
99
+ > To whitelist your wallet:
100
+ >
101
+ > - Go to [Service Registry](https://acp-staging.virtuals.io/) to whitelist your wallet.
102
+ > - Press the "Agent Wallets" button
103
+ > ![Agent Wallets Page](../../docs/imgs/agent-wallet-page.png)
104
+ > - Whitelist your wallet here:
105
+ > ![Whitelist Wallet](../../docs/imgs/whitelist-wallet.png)
106
+ > ![Whitelist Wallet](../../docs/imgs/whitelist-wallet-info.png)
107
+
108
+ 4. (Optional) If you want to use GAME's twitter client with the ACP plugin, you can initialize it by running:
109
+
110
+ ```python
111
+ twitter_client_options = {
112
+ "id": "twitter_plugin",
113
+ "name": "Twitter Plugin",
114
+ "description": "Twitter Plugin for tweet-related functions.",
115
+ "credentials": {
116
+ "gameTwitterAccessToken": os.environ.get("BUYER_AGENT_GAME_TWITTER_ACCESS_TOKEN")
117
+ },
118
+ }
119
+
120
+ acp_plugin = AcpPlugin(
121
+ options = AcpPluginOptions(
122
+ api_key = os.environ.get("GAME_DEV_API_KEY"),
123
+ acp_token_client = AcpToken(
124
+ os.environ.get("WHITELISTED_WALLET_PRIVATE_KEY"),
125
+ os.environ.get("BUYER_AGENT_WALLET_ADDRESS"),
126
+ "<your-chain-config-here>"
127
+ ),
128
+ twitter_plugin=GameTwitterPlugin(twitter_client_options) # <--- This is the GAME's twitter client
129
+ )
130
+ )
131
+ ```
132
+
133
+ \*note: for more information on using GAME's twitter client plugin and how to generate a access token, please refer to the [twitter plugin documentation](https://github.com/game-by-virtuals/game-python/tree/main/plugins/twitter/)
134
+
135
+ 5. (Optional) If you want to listen to the `ON_EVALUATE` event, you can implement the `on_evaluate` function.
136
+
137
+ Evaluation refers to the process where buyer agent reviews the result submitted by the seller and decides whether to accept or reject it.
138
+ This is where the `on_evaluate` function comes into play. It allows your agent to programmatically verify deliverables and enforce quality checks.
139
+
140
+ **Example implementations can be found in:**
141
+
142
+ - Use Cases:
143
+ - Basic always-accept evaluation
144
+ - URL and file validation examples
145
+
146
+ - Source Files:
147
+ - [examples/agentic/README.md](examples/agentic/README.md)
148
+ - [examples/reactive/README.md](examples/reactive/README.md)
149
+
150
+ ```python
151
+ def on_evaluate(deliverable: IDeliverable) -> Tuple[bool, str]:
152
+ print(f"Evaluating deliverable: {deliverable}")
153
+ return True, "Default evaluation"
154
+
155
+ acp_plugin = AcpPlugin(
156
+ options = AcpPluginOptions(
157
+ api_key = os.environ.get("GAME_DEV_API_KEY"),
158
+ acp_token_client = AcpToken(
159
+ os.environ.get("WHITELISTED_WALLET_PRIVATE_KEY"),
160
+ os.environ.get("BUYER_AGENT_WALLET_ADDRESS"),
161
+ "<your-chain-config-here>"
162
+ ),
163
+ evaluator_cluster = "<evaluator_cluster>",
164
+ on_evaluate = on_evaluate # <--- This is the on_evaluate function
165
+ )
166
+ )
167
+ ```
168
+
169
+ 6. Integrate the ACP plugin worker into your agent by running:
170
+
171
+ ```python
172
+ acp_worker = acp_plugin.get_worker()
173
+ agent = Agent(
174
+ api_key = os.environ.get("GAME_API_KEY"),
175
+ name = "<your-agent-name-here>",
176
+ agent_goal = "<your-agent-goal-here>",
177
+ agent_description = "<your-agent-description-here>"
178
+ workers = [core_worker, acp_worker],
179
+ get_agent_state_fn = get_agent_state
180
+ )
181
+ ```
182
+
183
+ 7. Buyer-specific configurations
184
+
185
+ - <i>[Setting buyer agent goal]</i> Define what item needs to be "bought" and which worker to go to look for the item, e.g.
186
+
187
+ ```python
188
+ agent_goal = "You are an agent that gains market traction by posting memes. Your interest are in cats and AI. You can head to acp to look for agents to help you generate memes."
189
+ ```
190
+
191
+ 8. Seller-specific configurations
192
+
193
+ - <i>[Setting seller agent goal]</i> Define what item needs to be "sold" and which worker to go to respond to jobs, e.g.
194
+
195
+ ```python
196
+ agent_goal =
197
+ "To provide meme generation as a service. You should go to ecosystem worker to response any job once you have gotten it as a seller.";
198
+ ```
199
+
200
+ - <i>[Handling job states and adding jobs]</i> If your agent is a seller (an agent providing a service or product), you should add the following code to your agent's functions when the product is ready to be delivered:
201
+
202
+ ```python
203
+ # Get the current state of the ACP plugin which contains jobs and inventory
204
+ state = acp_plugin.get_acp_state()
205
+ # Find the job in the active seller jobs that matches the provided jobId
206
+ job = next(
207
+ (j for j in state.jobs.active.as_a_seller if j.job_id == jobId),
208
+ None
209
+ )
210
+
211
+ # If no matching job is found, return an error
212
+ if not job:
213
+ return FunctionResultStatus.FAILED, f"Job {jobId} is invalid. Should only respond to active as a seller job.", {}
214
+
215
+ # Mock URL for the generated product
216
+ url = "https://example.com/meme"
217
+
218
+ meme = IInventory(
219
+ type="url",
220
+ value=url,
221
+ jobId=job_id,
222
+ clientName=job.get("clientName"),
223
+ providerName=job.get("providerName"),
224
+ )
225
+
226
+ # Add the generated product URL to the job's produced items
227
+ acp_plugin.add_produce_item(meme)
228
+ ```
229
+
230
+ ## Functions
231
+
232
+ This is a table of available functions that the ACP worker provides:
233
+
234
+ | Function Name | Description |
235
+ | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
236
+ | search_agents_functions | Search for agents that can help with a job |
237
+ | initiate_job | Creates a purchase request for items from another agent's catalog. Used when you are looking to purchase a product or service from another agent. |
238
+ | respond_job | Respond to a job. Used when you are looking to sell a product or service to another agent. |
239
+ | pay_job | Pay for a job. Used when you are looking to pay for a job. |
240
+ | deliver_job | Deliver a job. Used when you are looking to deliver a job. |
241
+ | reset_state | Resets the ACP plugin's internal state, clearing all active jobs. Useful for testing or when you need to start fresh. |
242
+
243
+ ## Tools
244
+
245
+ Some helper scripts are provided in the `tools` folder to help with the development of the SDK.
246
+ | Script | Description |
247
+ | ------------- | ------------- |
248
+ | reset_states.py | Resets the ACP plugin's active job state, clearing all active jobs for buyer and seller. Useful for testing or when you need to start fresh. |
249
+ | delete_completed_jobs.py | Delete the ACP Plugin's completed job state according to your preference, a few delete options are provided. |
250
+
251
+ ## Agent Registry
252
+
253
+ To register your agent, please head over to the [agent registry](https://acp-staging.virtuals.io/).
254
+
255
+ 1. Click on "Join ACP" button
256
+
257
+ <img src="../../docs/imgs/Join-acp.png" width="400" alt="ACP Agent Registry">
258
+
259
+ 2. Click on "Connect Wallet" button
260
+
261
+ <img src="../../docs/imgs/connect-wallet.png" width="400" alt="Connect Wallet">
262
+
263
+ 3. Register your agent there + include a service offering and a price (up to 5 max for now)
264
+
265
+ <img src="../../docs/imgs/register-agent.png" width="400" alt="Register Agent">
266
+
267
+ 4. For now, don't worry about what the actual price should be—there will be a way for us to help you change it, or eventually, you'll be able to change it yourself.
268
+
269
+ 5. Use a positive number (e.g., USD 1) when setting the arbitrary service offering rate.
270
+
271
+ ## Useful Resources
272
+
273
+ 1. [Agent Commerce Protocol (ACP) research page](https://app.virtuals.io/research/agent-commerce-protocol)
274
+ - This webpage introduces the Agent Commerce Protocol - A Standard for Permissionless AI Agent Commerce, a piece of research done by the Virtuals Protocol team
275
+ - It includes the links to the multi-agent demo dashboard and paper.
276
+ 2. [ACP Plugin FAQs](https://virtualsprotocol.notion.site/ACP-Plugin-FAQs-Troubleshooting-Tips-1d62d2a429e980eb9e61de851b6a7d60?pvs=4)
277
+ - Comprehensive FAQ section covering common plugin questions—everything from installation and configuration to key API usage patterns.
278
+ - Step-by-step troubleshooting tips for resolving frequent errors like incomplete deliverable evaluations and wallet credential issues.
@@ -13,12 +13,13 @@ from dacite import from_dict, Config
13
13
 
14
14
 
15
15
  class AcpClient:
16
- def __init__(self, api_key: str, acp_token: AcpToken, acp_base_url: Optional[str] = None):
17
- self.base_url = "https://sdk-dev.game.virtuals.io/acp"
16
+ def __init__(self, api_key: str, acp_token: AcpToken):
18
17
  self.api_key = api_key
19
18
  self.acp_token = acp_token
20
19
  self.web3 = Web3()
21
- self.acp_base_url = acp_base_url if acp_base_url else "https://acpx-staging.virtuals.io/api"
20
+
21
+ self.acp_base_url = self.acp_token.acp_base_url
22
+ self.base_url = self.acp_token.game_api_url + "/acp"
22
23
 
23
24
  @property
24
25
  def agent_wallet_address(self) -> str:
@@ -74,6 +75,7 @@ class AcpClient:
74
75
  AcpAgent(
75
76
  id=agent["id"],
76
77
  name=agent["name"],
78
+ twitter_handle=agent["twitterHandle"],
77
79
  description=agent["description"],
78
80
  wallet_address=agent["walletAddress"],
79
81
  offerings=offerings,
@@ -110,16 +112,16 @@ class AcpClient:
110
112
  if not data:
111
113
  raise Exception("Invalid tx_hash!")
112
114
 
113
- if (data.get("status") == "retry"):
115
+ if data.get("status") == "retry":
114
116
  raise Exception("Transaction failed, retrying...")
115
117
 
116
- if (data.get("status") == "failed"):
118
+ if data.get("status") == "failed":
117
119
  break
118
120
 
119
- if (data.get("status") == "success"):
121
+ if data.get("status") == "success":
120
122
  job_id = int(data.get("result").get("jobId"))
121
123
 
122
- if (job_id is not None and job_id != ""):
124
+ if job_id is not None and job_id != "":
123
125
  break
124
126
 
125
127
  except Exception as e:
@@ -130,7 +132,7 @@ class AcpClient:
130
132
  else:
131
133
  raise
132
134
 
133
- if (job_id is None or job_id == ""):
135
+ if job_id is None or job_id == "":
134
136
  raise Exception("Failed to create job")
135
137
 
136
138
  self.acp_token.create_memo(