Skip to content

Commit d1a4a59

Browse files
authored
Merge pull request #164 from game-by-virtuals/acp-plugin/yang-improve-docs
[ACP Plugin] Improve Examples and README Files
2 parents a77e870 + 8951d7c commit d1a4a59

13 files changed

Lines changed: 844 additions & 737 deletions

File tree

-163 KB
Binary file not shown.

plugins/acp/README.md

Lines changed: 152 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,6 @@
2020

2121
---
2222

23-
> **Note:** This plugin is currently undergoing updates. Some features and documentation may change in upcoming releases.
24-
>
25-
> These aspects are still in progress:
26-
>
27-
> 1. **Evaluation phase** - In V1 of the ACP plugin, there is a possibility that deliverables from the job provider may not be fully passed on to the job poster due to incomplete evaluation.
28-
>
29-
> 2. **Wallet functionality** - Currently, you need to use your own wallet address and private key.
30-
3123
The Agent Commerce Protocol (ACP) plugin is used to handle trading transactions and jobs between agents. This ACP plugin manages:
3224

3325
1. RESPONDING to Buy/Sell Needs, via ACP service registry
@@ -47,7 +39,7 @@ The Agent Commerce Protocol (ACP) plugin is used to handle trading transactions
4739

4840
## Prerequisite
4941

50-
⚠️⚠️⚠️ Important: Before testing your agents services with a counterpart agent, you must register your agent with the [Service Registry](https://acp-staging.virtuals.io/).
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/).
5143
This step is a critical precursor. Without registration, the counterpart agent will not be able to discover or interact with your agent.
5244

5345
## Installation
@@ -58,178 +50,185 @@ From this directory (`acp`), run the installation:
5850
poetry install
5951
```
6052

53+
or install it with pip:
54+
```bash
55+
pip install acp-plugin-gamesdk
56+
```
57+
6158
## Usage
6259

6360
1. Activate the virtual environment by running:
61+
```bash
62+
eval $(poetry env activate)
63+
```
6464

65-
```bash
66-
eval $(poetry env activate)
67-
```
65+
2. Import acp_plugin and load the environment variables by running:
6866

69-
2. Import acp_plugin by running:
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
7071
71-
```python
72-
from acp_plugin_gamesdk.acp_plugin import AcpPlugin, AdNetworkPluginOptions
73-
from acp_plugin_gamesdk.acp_token import AcpToken
74-
```
72+
load_dotenv()
73+
```
7574

7675
3. Create and initialize an ACP instance by running:
7776

78-
```python
79-
acp_plugin = AcpPlugin(
80-
options = AcpPluginOptions(
81-
api_key = "<your-GAME-dev-api-key-here>",
82-
acp_token_client = AcpToken(
83-
"<your-whitelisted-wallet-private-key>",
84-
"<your-agent-wallet-address>",
85-
"<your-chain-here>",
86-
"<your-acp-base-url>"
87-
),
88-
cluster = "<cluster>",
89-
twitter_plugin = "<twitter_plugin_instance>",
90-
evaluator_cluster = "<evaluator_cluster>",
91-
on_evaluate = "<on_evaluate_function>"
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-here>",
85+
"<your-acp-base-url>"
86+
),
87+
cluster = "<cluster>",
88+
twitter_plugin = "<twitter_plugin_instance>",
89+
evaluator_cluster = "<evaluator_cluster>",
90+
on_evaluate = "<on_evaluate_function>"
91+
)
9292
)
93-
)
94-
```
95-
96-
> Note:
97-
>
98-
> - Your agent wallet address for your buyer and seller should be different.
99-
> - Speak to a DevRel (Celeste/John) to get a GAME Dev API key
100-
101-
> To Whitelist your Wallet:
102-
>
103-
> - Go to [Service Registry](https://acp-staging.virtuals.io/) page to whitelist your wallet.
104-
> - Press the Agent Wallet page
105-
> ![Agent Wallet Page](../../docs/imgs/agent-wallet-page.png)
106-
> - Whitelist your wallet here:
107-
> ![Whitelist Wallet](../../docs/imgs/whitelist-wallet.png) > ![Whitelist Wallet](../../docs/imgs/whitelist-wallet-info.png)
108-
> - This is where you can get your session entity key ID:
109-
> ![Session Entity ID](../../docs/imgs/session-entity-id-location.png)
93+
```
94+
95+
> Note:
96+
>
97+
> - Your agent wallet address for your buyer and seller should be different.
98+
> - Speak to a DevRel (Celeste/John) to get a GAME Dev API key
99+
100+
> To whitelist your wallet:
101+
>
102+
> - Go to [Service Registry](https://acp-staging.virtuals.io/) to whitelist your wallet.
103+
> - Press the "Agent Wallets" button
104+
> ![Agent Wallets Page](../../docs/imgs/agent-wallet-page.png)
105+
> - Whitelist your wallet here:
106+
> ![Whitelist Wallet](../../docs/imgs/whitelist-wallet.png)
107+
> ![Whitelist Wallet](../../docs/imgs/whitelist-wallet-info.png)
110108

111109
4. (Optional) If you want to use GAME's twitter client with the ACP plugin, you can initialize it by running:
112110
113-
```python
114-
twitter_client_options = {
115-
"id": "test_game_twitter_plugin",
116-
"name": "Test GAME Twitter Plugin",
117-
"description": "An example GAME Twitter Plugin for testing.",
118-
"credentials": {
119-
"gameTwitterAccessToken": os.environ.get("GAME_TWITTER_ACCESS_TOKEN")
120-
},
121-
}
122-
123-
acp_plugin = AcpPlugin(
124-
options = AcpPluginOptions(
125-
api_key = "<your-GAME-dev-api-key-here>",
126-
acp_token_client = AcpToken(
127-
"<your-whitelisted-wallet-private-key>",
128-
"<your-agent-wallet-address>",
129-
"<your-chain-here>",
130-
"<your-acp-base-url>"
131-
),
132-
twitter_plugin=GameTwitterPlugin(twitter_client_options) # <--- This is the GAME's twitter client
111+
```python
112+
twitter_client_options = {
113+
"id": "twitter_plugin",
114+
"name": "Twitter Plugin",
115+
"description": "Twitter Plugin for tweet-related functions.",
116+
"credentials": {
117+
"gameTwitterAccessToken": os.environ.get("BUYER_AGENT_GAME_TWITTER_ACCESS_TOKEN")
118+
},
119+
}
120+
121+
acp_plugin = AcpPlugin(
122+
options = AcpPluginOptions(
123+
api_key = os.environ.get("GAME_DEV_API_KEY"),
124+
acp_token_client = AcpToken(
125+
os.environ.get("WHITELISTED_WALLET_PRIVATE_KEY"),
126+
os.environ.get("BUYER_AGENT_WALLET_ADDRESS"),
127+
"<your-chain-here>",
128+
"<your-acp-base-url>"
129+
),
130+
twitter_plugin=GameTwitterPlugin(twitter_client_options) # <--- This is the GAME's twitter client
131+
)
133132
)
134-
)
135-
```
133+
```
136134

137-
\*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/)
135+
\*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/)
138136
139137
5. (Optional) If you want to listen to the `ON_EVALUATE` event, you can implement the `on_evaluate` function.
140138
141-
142-
Evaluation refers to the process where buyer agent reviews the result submitted by the seller and decides whether to accept or reject it.
143-
This is where the `on_evaluate` function comes into play. It allows your agent to programmatically verify deliverables and enforce quality checks.
144-
145-
🔍 **Example implementations can be found in:**
146-
147-
Use Cases:
148-
- Basic always-accept evaluation
149-
- URL and file validation examples
150-
151-
Source Files:
152-
- [examples/agentic/README.md](examples/agentic/README.md)
153-
- [examples/reactive/README.md](examples/reactive/README.md)
154-
155-
```python
156-
def on_evaluate(deliverable: IDeliverable) -> Tuple[bool, str]:
157-
print(f"Evaluating deliverable: {deliverable}")
158-
return True, "Default evaluation"
159-
```
160-
161-
```python
162-
acp_plugin = AcpPlugin(
163-
options = AcpPluginOptions(
164-
api_key = "<your-GAME-dev-api-key-here>",
165-
acp_token_client = AcpToken(
166-
"<your-whitelisted-wallet-private-key>",
167-
"<your-agent-wallet-address>",
168-
"<your-chain-here>",
169-
"<your-acp-base-url>"
170-
),
171-
evaluator_cluster = "<evaluator_cluster>",
172-
on_evaluate = on_evaluate # <--- This is the on_evaluate function
139+
Evaluation refers to the process where buyer agent reviews the result submitted by the seller and decides whether to accept or reject it.
140+
This is where the `on_evaluate` function comes into play. It allows your agent to programmatically verify deliverables and enforce quality checks.
141+
142+
**Example implementations can be found in:**
143+
144+
- Use Cases:
145+
- Basic always-accept evaluation
146+
- URL and file validation examples
147+
148+
- Source Files:
149+
- [examples/agentic/README.md](examples/agentic/README.md)
150+
- [examples/reactive/README.md](examples/reactive/README.md)
151+
152+
```python
153+
def on_evaluate(deliverable: IDeliverable) -> Tuple[bool, str]:
154+
print(f"Evaluating deliverable: {deliverable}")
155+
return True, "Default evaluation"
156+
157+
acp_plugin = AcpPlugin(
158+
options = AcpPluginOptions(
159+
api_key = os.environ.get("GAME_DEV_API_KEY"),
160+
acp_token_client = AcpToken(
161+
os.environ.get("WHITELISTED_WALLET_PRIVATE_KEY"),
162+
os.environ.get("BUYER_AGENT_WALLET_ADDRESS"),
163+
"<your-chain-here>",
164+
"<your-acp-base-url>"
165+
),
166+
evaluator_cluster = "<evaluator_cluster>",
167+
on_evaluate = on_evaluate # <--- This is the on_evaluate function
168+
)
173169
)
174-
)
175-
```
170+
```
176171
177172
6. Integrate the ACP plugin worker into your agent by running:
178173
179-
```python
180-
acp_worker = acp_plugin.get_worker()
181-
agent = Agent(
182-
api_key = ("<your-GAME-api-key-here>",
183-
name = "<your-agent-name-here>",
184-
agent_goal = "<your-agent-goal-here>",
185-
agent_description = "<your-agent-description-here>"
186-
workers = [core_worker, acp_worker],
187-
get_agent_state_fn = get_agent_state
188-
)
189-
```
174+
```python
175+
acp_worker = acp_plugin.get_worker()
176+
agent = Agent(
177+
api_key = os.environ.get("GAME_API_KEY"),
178+
name = "<your-agent-name-here>",
179+
agent_goal = "<your-agent-goal-here>",
180+
agent_description = "<your-agent-description-here>"
181+
workers = [core_worker, acp_worker],
182+
get_agent_state_fn = get_agent_state
183+
)
184+
```
190185
191186
7. Buyer-specific configurations
192187
193188
- <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.
194189
195-
```python
196-
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."
197-
```
190+
```python
191+
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."
192+
```
198193
199194
8. Seller-specific configurations
200195
201196
- <i>[Setting seller agent goal]</i> Define what item needs to be "sold" and which worker to go to respond to jobs, e.g.
202197
203-
```typescript
204-
agent_goal =
205-
"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.";
206-
```
198+
```python
199+
agent_goal =
200+
"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.";
201+
```
207202
208203
- <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:
209204

210-
```python
211-
# Get the current state of the ACP plugin which contains jobs and inventory
212-
state = acp_plugin.get_acp_state()
213-
# Find the job in the active seller jobs that matches the provided jobId
214-
job = next(
215-
(j for j in state.jobs.active.as_a_seller if j.job_id == jobId),
216-
None
217-
)
218-
219-
# If no matching job is found, return an error
220-
if not job:
221-
return FunctionResultStatus.FAILED, f"Job {jobId} is invalid. Should only respond to active as a seller job.", {}
222-
223-
# Mock URL for the generated product
224-
url = "http://example.com/meme"
225-
226-
# Add the generated product URL to the job's produced items
227-
acp_plugin.add_produce_item({
228-
"jobId": jobId,
229-
"type": "url",
230-
"value": url
231-
})
232-
```
205+
```python
206+
# Get the current state of the ACP plugin which contains jobs and inventory
207+
state = acp_plugin.get_acp_state()
208+
# Find the job in the active seller jobs that matches the provided jobId
209+
job = next(
210+
(j for j in state.jobs.active.as_a_seller if j.job_id == jobId),
211+
None
212+
)
213+
214+
# If no matching job is found, return an error
215+
if not job:
216+
return FunctionResultStatus.FAILED, f"Job {jobId} is invalid. Should only respond to active as a seller job.", {}
217+
218+
# Mock URL for the generated product
219+
url = "https://example.com/meme"
220+
221+
meme = IInventory(
222+
type="url",
223+
value=url,
224+
jobId=job_id,
225+
clientName=job.get("clientName"),
226+
providerName=job.get("providerName"),
227+
)
228+
229+
# Add the generated product URL to the job's produced items
230+
acp_plugin.add_produce_item(meme)
231+
```
233232
234233
## Functions
235234
@@ -249,23 +248,24 @@ This is a table of available functions that the ACP worker provides:
249248
Some helper scripts are provided in the `tools` folder to help with the development of the SDK.
250249
| Script | Description |
251250
| ------------- | ------------- |
252-
| reset_states.py | Resets the ACP plugin's internal state, clearing all active jobs for buyer and seller, based on their ACP tokens. Useful for testing or when you need to start fresh. |
251+
| 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. |
252+
| delete_completed_jobs.py | Delete the ACP Plugin's completed job state according to your preference, a few delete options are provided. |
253253
254254
## Agent Registry
255255
256256
To register your agent, please head over to the [agent registry](https://acp-staging.virtuals.io/).
257257
258258
1. Click on "Join ACP" button
259259
260-
<img src="../../docs/imgs/Join-acp.png" width="400" alt="ACP Agent Registry">
260+
<img src="../../docs/imgs/Join-acp.png" width="400" alt="ACP Agent Registry">
261261
262262
2. Click on "Connect Wallet" button
263263
264-
<img src="../../docs/imgs/connect-wallet.png" width="400" alt="Connect Wallet">
264+
<img src="../../docs/imgs/connect-wallet.png" width="400" alt="Connect Wallet">
265265
266266
3. Register your agent there + include a service offering and a price (up to 5 max for now)
267267
268-
<img src="../../docs/imgs/register-agent.png" width="400" alt="Register Agent">
268+
<img src="../../docs/imgs/register-agent.png" width="400" alt="Register Agent">
269269
270270
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.
271271
@@ -277,3 +277,5 @@ To register your agent, please head over to the [agent registry](https://acp-sta
277277
- This webpage introduces the Agent Commerce Protocol - A Standard for Permissionless AI Agent Commerce, a piece of research done by the Virtuals Protocol team
278278
- It includes the links to the multi-agent demo dashboard and paper.
279279
2. [ACP Plugin FAQs](https://virtualsprotocol.notion.site/ACP-Plugin-FAQs-Troubleshooting-Tips-1d62d2a429e980eb9e61de851b6a7d60?pvs=4)
280+
- Comprehensive FAQ section covering common plugin questions—everything from installation and configuration to key API usage patterns.
281+
- Step-by-step troubleshooting tips for resolving frequent errors like incomplete deliverable evaluations and wallet credential issues.

0 commit comments

Comments
 (0)