Skip to content

Commit

Permalink
Tweaks to the NFT agents (#614)
Browse files Browse the repository at this point in the history
  • Loading branch information
kongzii authored Dec 17, 2024
1 parent 72197b3 commit c850589
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@
from prediction_market_agent.agents.microchain_agent.memory_functions import (
LookAtPastActions,
)
from prediction_market_agent.agents.microchain_agent.messages_functions import (
from prediction_market_agent.agents.microchain_agent.nft_functions import NFT_FUNCTIONS
from prediction_market_agent.agents.microchain_agent.nft_treasury_game.messages_functions import (
MESSAGES_FUNCTIONS,
)
from prediction_market_agent.agents.microchain_agent.nft_functions import NFT_FUNCTIONS
from prediction_market_agent.agents.microchain_agent.omen_functions import (
OMEN_FUNCTIONS,
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from prediction_market_agent_tooling.gtypes import xDai
from prediction_market_agent_tooling.gtypes import xDai, xdai_type
from prediction_market_agent_tooling.loggers import logger
from prediction_market_agent_tooling.markets.omen.omen import OMEN_TINY_BET_AMOUNT

Expand All @@ -9,7 +9,7 @@ class MicrochainAgentKeys(APIKeys):
# Double check to make sure you want to actually post on public social media.
ENABLE_SOCIAL_MEDIA: bool = False
# Double check to not spend big money during testing.
SENDING_XDAI_CAP: float | None = OMEN_TINY_BET_AMOUNT
SENDING_XDAI_CAP: xDai | None = xdai_type(0.1)
# Double check to not transfer NFTs during testing.
ENABLE_NFT_TRANSFER: bool = False
RECEIVER_MINIMUM_AMOUNT: xDai = OMEN_TINY_BET_AMOUNT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,23 @@
from streamlit_extras.stylable_container import stylable_container

from prediction_market_agent.agents.identifiers import AgentIdentifier
from prediction_market_agent.agents.microchain_agent.messages_functions import (
BroadcastPublicMessageToHumans,
ReceiveMessage,
SendPaidMessageToAnotherAgent,
)
from prediction_market_agent.agents.microchain_agent.nft_functions import BalanceOfNFT
from prediction_market_agent.agents.microchain_agent.nft_treasury_game.constants_nft_treasury_game import (
NFT_TOKEN_FACTORY,
TREASURY_SAFE_ADDRESS,
)
from prediction_market_agent.agents.microchain_agent.nft_treasury_game.contracts_nft_treasury_game import (
get_nft_token_factory_max_supply,
)
from prediction_market_agent.agents.microchain_agent.nft_treasury_game.deploy_nft_treasury_game import (
DEPLOYED_NFT_AGENTS,
DeployableAgentNFTGameAbstract,
MicrochainAgentKeys,
)
from prediction_market_agent.agents.microchain_agent.nft_treasury_game.messages_functions import (
BroadcastPublicMessageToHumans,
ReceiveMessage,
SendPaidMessageToAnotherAgent,
)
from prediction_market_agent.db.blockchain_transaction_fetcher import (
BlockchainTransactionFetcher,
Expand Down Expand Up @@ -66,10 +72,19 @@ def prompt_table_handler(identifier: AgentIdentifier) -> PromptTableHandler:

def send_message_part(nft_agent: type[DeployableAgentNFTGameAbstract]) -> None:
message = st.text_area("Write a message to the agent")
keys = MicrochainAgentKeys()
default_value = keys.RECEIVER_MINIMUM_AMOUNT
value = st.number_input(
"Value in xDai",
min_value=default_value,
max_value=keys.SENDING_XDAI_CAP,
value=default_value,
format="%.5f",
)

if st.button("Send message", disabled=not message):
# TODO: Don't do this manually with deployment private key, use the user's wallet!
SendPaidMessageToAnotherAgent()(nft_agent.wallet_address, message)
SendPaidMessageToAnotherAgent()(nft_agent.wallet_address, message, value)
st.success("Message sent and will be processed soon!")


Expand Down Expand Up @@ -189,10 +204,16 @@ def show_about_agent_part(nft_agent: type[DeployableAgentNFTGameAbstract]) -> No
else nft_agent.get_initial_system_prompt()
)
xdai_balance = get_balances(nft_agent.wallet_address).xdai
n_nft = BalanceOfNFT()(NFT_TOKEN_FACTORY, nft_agent.wallet_address)
nft_keys_message = (
"and does not hold any NFT keys anymore"
if n_nft == 0
else f"and <span style='font-size: 1.1em;'><strong>{n_nft} NFT key{'s' if n_nft > 1 else ''}</strong></span>"
)
st.markdown(
f"""### {nft_agent.name}
Currently holds <span style='font-size: 1.1em;'><strong>{xdai_balance:.2f} xDAI</strong></span>.
Currently holds <span style='font-size: 1.1em;'><strong>{xdai_balance:.2f} xDAI</strong></span> {nft_keys_message}.
---
""",
Expand Down Expand Up @@ -228,7 +249,7 @@ def show_treasury_part() -> None:
treasury_xdai_balance = get_balances(TREASURY_SAFE_ADDRESS).xdai
st.markdown(
f"""### Treasury
Currently holds <span style='font-size: 1.1em;'><strong>{treasury_xdai_balance:.2f} xDAI</strong></span>.""",
Currently holds <span style='font-size: 1.1em;'><strong>{treasury_xdai_balance:.2f} xDAI</strong></span>. There are {get_nft_token_factory_max_supply()} NFT keys.""",
unsafe_allow_html=True,
)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from functools import cache

from prediction_market_agent_tooling.gtypes import ChecksumAddress
from prediction_market_agent_tooling.tools.contract import (
ContractOwnableERC721OnGnosisChain,
)
from web3 import Web3

from prediction_market_agent.agents.microchain_agent.nft_treasury_game.constants_nft_treasury_game import (
NFT_TOKEN_FACTORY,
)


class ContractNFTFactoryOnGnosisChain(ContractOwnableERC721OnGnosisChain):
address: ChecksumAddress = NFT_TOKEN_FACTORY

def max_supply(self, web3: Web3 | None = None) -> int:
n_tokens: int = self.call("MAX_SUPPLY", web3=web3)
return n_tokens


@cache
def get_nft_token_factory_max_supply() -> int:
return ContractNFTFactoryOnGnosisChain().max_supply()
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@
MicrochainAgentKeys,
)
from prediction_market_agent.agents.microchain_agent.nft_treasury_game.constants_nft_treasury_game import (
NFT_TOKEN_FACTORY,
TREASURY_SAFE_ADDRESS,
)
from prediction_market_agent.agents.microchain_agent.nft_treasury_game.contracts_nft_treasury_game import (
get_nft_token_factory_max_supply,
)


class DeployableAgentNFTGameAbstract(DeployableMicrochainAgentAbstract):
Expand Down Expand Up @@ -182,6 +186,8 @@ def get_initial_system_prompt(cls) -> str:


def nft_treasury_game_base_prompt(wallet_address: ChecksumAddress) -> str:
keys = MicrochainAgentKeys()
n_nft_keys = get_nft_token_factory_max_supply()
other_agents_keys_formatted = ", ".join(
x.wallet_address
for x in DEPLOYED_NFT_AGENTS
Expand All @@ -191,14 +197,18 @@ def nft_treasury_game_base_prompt(wallet_address: ChecksumAddress) -> str:
- You participate in the securing of the NFT key to a treasury.
- Your wallet address is {wallet_address}.
- Other agents participating and probably still holding keys are {other_agents_keys_formatted}.
- Address of the NFT treasury is {TREASURY_SAFE_ADDRESS}.
- Other agents participating and maybe still holding keys are {other_agents_keys_formatted}.
- Address of the treasury, wallet holding the treasury's xDai, is {TREASURY_SAFE_ADDRESS}.
- Address of the NFT contract is {NFT_TOKEN_FACTORY}, there are {n_nft_keys} keys, with token_id {list(range(n_nft_keys))}.
- You can own multiple NFT keys.
- You can use the NFT functions to interact with the NFT keys, for example figuring out how many keys you own or who owns what key.
- The agent or person who gets enough of keys, can transfer the resources from the treasury.
- The agents can communicate with each other using the messages functions by sending a message to their wallet address.
- Sending a message costs you a fee.
- Receiving messages will pay you a fee.
- If you have unseen incoming messages, always process them first.
- Receiving messages will pay you a fee, but part of that fee goes to the treasury, which is good for you.
- If you have unseen incoming messages, always process them first, unless you are processing some message at the moment.
- Regularly check balances of your wallet and the treasury.
- Keep in mind that you are able to send, and others agents are able to send at max {keys.SENDING_XDAI_CAP} xDai.
"""


Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from microchain import Function
from prediction_market_agent_tooling.gtypes import wei_type
from prediction_market_agent_tooling.gtypes import wei_type, xdai_type
from prediction_market_agent_tooling.loggers import logger
from prediction_market_agent_tooling.tools.contract import ContractOnGnosisChain
from prediction_market_agent_tooling.tools.hexbytes_custom import HexBytes
Expand Down Expand Up @@ -39,21 +39,19 @@ class SendPaidMessageToAnotherAgent(Function):
@property
def description(self) -> str:
return f"""Use {SendPaidMessageToAnotherAgent.__name__} to send a message to an another agent, given his wallet address.
Fee for sending the message is {MicrochainAgentKeys().RECEIVER_MINIMUM_AMOUNT} xDai."""
You need to send a fee of at least {MicrochainAgentKeys().RECEIVER_MINIMUM_AMOUNT} xDai for other agent to read the message."""

@property
def example_args(self) -> list[str]:
return ["0x123", "Hello!"]
return ["0x123", "Hello!", f"{MicrochainAgentKeys().RECEIVER_MINIMUM_AMOUNT}"]

def __call__(self, address: str, message: str) -> str:
def __call__(self, address: str, message: str, fee: float) -> str:
keys = MicrochainAgentKeys()
send_xdai_to(
web3=ContractOnGnosisChain.get_web3(),
from_private_key=keys.bet_from_private_key,
to_address=Web3.to_checksum_address(address),
value=xdai_to_wei(
keys.cap_sending_xdai(MicrochainAgentKeys().RECEIVER_MINIMUM_AMOUNT)
),
value=xdai_to_wei(keys.cap_sending_xdai(xdai_type(fee))),
data_text=compress_message(message),
)
return self.OUTPUT_TEXT
Expand All @@ -72,7 +70,7 @@ def get_count_unseen_messages() -> int:
@property
def description(self) -> str:
count_unseen_messages = self.get_count_unseen_messages()
return f"Use {ReceiveMessage.__name__} to receive last {count_unseen_messages} unseen messages from the users."
return f"Use {ReceiveMessage.__name__} to receive last unseen message from the users or other agents. Currently, you have {count_unseen_messages} unseen messages."

@property
def example_args(self) -> list[str]:
Expand Down
4 changes: 2 additions & 2 deletions tests/agents/microchain/test_messages_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from pydantic import SecretStr
from web3 import Web3

from prediction_market_agent.agents.microchain_agent.messages_functions import (
from prediction_market_agent.agents.microchain_agent.nft_treasury_game.messages_functions import (
ReceiveMessage,
)
from prediction_market_agent.db.blockchain_message_table_handler import (
Expand Down Expand Up @@ -80,7 +80,7 @@ def patch_spice() -> Generator[PropertyMock, None, None]:
def patch_send_xdai() -> Generator[PropertyMock, None, None]:
# Note that we patch where the function is called (see https://docs.python.org/3/library/unittest.mock.html#where-to-patch).
with patch(
"prediction_market_agent.agents.microchain_agent.messages_functions.send_xdai_to",
"prediction_market_agent.agents.microchain_agent.nft_treasury_game.messages_functions.send_xdai_to",
return_value={"transactionHash": HexBytes(MOCK_HASH_1)},
) as mock_send_xdai:
yield mock_send_xdai
Expand Down

0 comments on commit c850589

Please sign in to comment.