-
Notifications
You must be signed in to change notification settings - Fork 92
Expand file tree
/
Copy pathbuyer.py
More file actions
192 lines (165 loc) · 6.87 KB
/
buyer.py
File metadata and controls
192 lines (165 loc) · 6.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
import os
from typing import Tuple
from game_sdk.game.agent import Agent, WorkerConfig
from game_sdk.game.custom_types import Argument, Function, FunctionResultStatus
from acp_plugin_gamesdk.interface import AcpJob, IDeliverable, AcpJobPhasesDesc,AcpState
from acp_plugin_gamesdk.acp_plugin import AcpPlugin, AcpPluginOptions
from acp_plugin_gamesdk.acp_token import AcpToken
from dacite import from_dict
from dacite.config import Config
from acp_plugin_gamesdk.configs import BASE_SEPOLIA_CONFIG
from rich import print, box
from rich.panel import Panel
from dotenv import load_dotenv
# GAME Twitter Plugin import
from twitter_plugin_gamesdk.game_twitter_plugin import GameTwitterPlugin
# Native Twitter Plugin import
# from twitter_plugin_gamesdk.twitter_plugin import TwitterPlugin
load_dotenv()
def on_evaluate(deliverable: IDeliverable) -> Tuple[bool, str]:
print(f"Evaluating deliverable: {deliverable}")
return True, "Default evaluation"
# GAME Twitter Plugin options
options = {
"id": "twitter_plugin",
"name": "Twitter Plugin",
"description": "Twitter Plugin for tweet-related functions.",
"credentials": {
"gameTwitterAccessToken": os.environ.get("BUYER_AGENT_GAME_TWITTER_ACCESS_TOKEN")
},
}
# Native Twitter Plugin options
# options = {
# "id": "twitter_plugin",
# "name": "Twitter Plugin",
# "description": "Twitter Plugin for tweet-related functions.",
# "credentials": {
# "bearerToken": os.environ.get("BUYER_AGENT_TWITTER_BEARER_TOKEN"),
# "apiKey": os.environ.get("BUYER_AGENT_TWITTER_API_KEY"),
# "apiSecretKey": os.environ.get("BUYER_AGENT_TWITTER_API_SECRET_KEY"),
# "accessToken": os.environ.get("BUYER_AGENT_TWITTER_ACCESS_TOKEN"),
# "accessTokenSecret": os.environ.get("BUYER_AGENT_TWITTER_ACCESS_TOKEN_SECRET"),
# },
# }
def buyer():
# upon phase change, the buyer agent will respond to the transaction
def on_phase_change(job: AcpJob) -> None:
if job.phase != AcpJobPhasesDesc.REJECTED:
print(f"Job phase is rejected.")
return
out = ""
out += f"Buyer agent is reacting to job:\n{job}\n\n"
if "getAgentByWalletAddress" in job and job["getAgentByWalletAddress"] is not None:
provider_agent = job["getAgentByWalletAddress"](job["providerAddress"])
print("Provider Agent Twitter Handle:", provider_agent.twitter_handle)
worker = buyer_agent.get_worker("acp_worker")
# Get the ACP worker and run task to respond to the job
worker.run(
f"Respond to the following transaction: {job}",
)
out += "Buyer agent has responded to the job\n"
print(Panel(out, title="🔁 Reaction", box=box.ROUNDED, title_align="left", border_style="red"))
acp_plugin = AcpPlugin(
options=AcpPluginOptions(
api_key=os.environ.get("GAME_DEV_API_KEY"),
acp_token_client=AcpToken(
os.environ.get("WHITELISTED_WALLET_PRIVATE_KEY"),
os.environ.get("BUYER_AGENT_WALLET_ADDRESS"),
BASE_SEPOLIA_CONFIG
),
on_evaluate=on_evaluate,
on_phase_change=on_phase_change,
# GAME Twitter Plugin
twitter_plugin=GameTwitterPlugin(options),
# Native Twitter Plugin
# twitter_plugin=TwitterPlugin(options),
)
)
def get_agent_state(_: None, _e: None) -> dict:
state = acp_plugin.get_acp_state()
return state
def post_tweet(content: str, reasoning: str) -> Tuple[FunctionResultStatus, str, dict]:
if acp_plugin.twitter_plugin is not None:
post_tweet_fn = acp_plugin.twitter_plugin.get_function('post_tweet')
post_tweet_fn(content)
return FunctionResultStatus.DONE, "Tweet has been posted", {}
return FunctionResultStatus.FAILED, "Twitter plugin is not initialized", {}
core_worker = WorkerConfig(
id="core-worker",
worker_description="This worker is to post tweet",
action_space=[
Function(
fn_name="post_tweet",
fn_description="This function is to post tweet",
args=[
Argument(
name="content",
type="string",
description="The content of the tweet"
),
Argument(
name="reasoning",
type="string",
description="The reasoning of the tweet"
)
],
executable=post_tweet
)
],
get_state_fn=get_agent_state
)
acp_worker = acp_plugin.get_worker(
{
"functions": [
acp_plugin.search_agents_functions,
acp_plugin.initiate_job
]
}
)
agent = Agent(
api_key=os.environ.get("GAME_API_KEY"),
name="Virtuals",
agent_goal="Finding the best meme to do tweet posting",
agent_description=f"""
Agent that gain market traction by posting meme. Your interest are in cats and AI.
You can head to acp to look for agents to help you generating meme.
Do not look for a relevant validator to validate the deliverable.
{acp_plugin.agent_description}
""",
workers=[core_worker, acp_worker],
get_agent_state_fn=get_agent_state
)
# Buyer agent is meant to handle payments
buyer_worker = acp_plugin.get_worker(
{
"functions": [
acp_plugin.pay_job
]
}
)
buyer_agent = Agent(
api_key=os.environ.get("GAME_API_KEY"),
name="Buyer",
agent_goal="Perform and complete transaction with seller",
agent_description=f"""
Agent that gain market traction by posting meme. Your interest are in cats and AI.
You can head to acp to look for agents to help you generating meme.
Do not look for a relevant validator to validate the deliverable.
{acp_plugin.agent_description}
""",
workers=[buyer_worker],
get_agent_state_fn=get_agent_state
)
buyer_agent.compile()
agent.compile()
while True:
print("🟢"*40)
init_state = from_dict(data_class=AcpState, data=agent.agent_state, config=Config(type_hooks={AcpJobPhasesDesc: AcpJobPhasesDesc}))
print(Panel(f"{init_state}", title="Initial Agent State", box=box.ROUNDED, title_align="left"))
agent.step()
end_state = from_dict(data_class=AcpState, data=agent.agent_state, config=Config(type_hooks={AcpJobPhasesDesc: AcpJobPhasesDesc}))
print(Panel(f"{end_state}", title="End Agent State", box=box.ROUNDED, title_align="left"))
print("🔴"*40)
input("\nPress any key to continue...\n")
if __name__ == "__main__":
buyer()